package com.changhong.epc.form.service.budget.tool.impl;
|
|
import com.changhong.epc.bean.form.FormType;
|
import com.changhong.epc.bean.form.budget.PersionBackMoney;
|
import com.changhong.epc.bean.tenant.cost.CostFromMapping;
|
import com.changhong.epc.bean.tenant.system.SystemForm;
|
import com.changhong.epc.constter.base.BaseConst;
|
import com.changhong.epc.form.mapper.tenant.FormDataMapper;
|
import com.changhong.epc.form.mapper.tenant.log.PersionBackMoneyMapper;
|
import com.changhong.epc.form.service.budget.impl.GetConstant;
|
import com.changhong.epc.form.service.budget.tool.UpdateBudgetFactory;
|
import com.changhong.epc.form.service.budget.tool.entity.UpdateBudgetEntity;
|
import com.changhong.epc.form.service.field.FormFieldService;
|
import com.codingapi.tx.annotation.TxTransaction;
|
import com.iemsoft.framework.cloud.core.thread.Keys;
|
import com.iemsoft.framework.cloud.core.thread.ThreadData;
|
import com.iemsoft.framework.cloud.core.tools.Assert;
|
import com.iemsoft.framework.cloud.core.tools.JSONTool;
|
import com.iemsoft.framework.cloud.core.tools.ObjectUtil;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.math.NumberUtils;
|
import org.springframework.context.annotation.Scope;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.ui.ModelMap;
|
|
import javax.annotation.Resource;
|
import java.math.BigDecimal;
|
import java.text.ParseException;
|
import java.text.SimpleDateFormat;
|
import java.util.Date;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Objects;
|
|
/**
|
* 报销扣减预算
|
*/
|
@Service(UpdateBudgetFactory.BX_TYPE)
|
@Slf4j
|
@Scope("prototype")
|
public class ExpendBudgetUpdate extends AbstractUpdateBudget implements BaseConst {
|
|
private UpdateBudgetEntity applyEntity;
|
|
private Map<String, Object> applyInfo;
|
// 主表数据集合
|
private Map<String, Object> expendInfo;
|
|
private Map<String, Object> budgetChildInfo;
|
|
private double budgetMoney;
|
|
@Resource
|
private PersionBackMoneyMapper persionBackMoneyMapper;
|
|
@Resource
|
private FormDataMapper formDataMapper;
|
|
@Resource(name = "formFieldService")
|
private FormFieldService formFieldService;
|
|
// 子表单后缀
|
private static String PAYINFO = "_payinfo";
|
|
// 本次报销数据集合
|
private List<Map<String, Object>> list;
|
|
// 对应报销人的借款记录
|
private List<Map<String, Object>> borrowList;
|
|
//判断是否有子表单
|
private Integer count;
|
|
|
@Override
|
public void checkBudget(UpdateBudgetEntity updateBudgetEntity) {
|
this.expendInfo = getFormInfo(updateBudgetEntity);
|
this.applyEntity = getApplyInfo(
|
NumberUtils.createInteger(Objects.toString(this.expendInfo.get(EXPEND_COST_TYPE), "0")));
|
if (this.applyEntity == null) {
|
// 报销-预算
|
Integer budgetId = getParentId(this.expendInfo);
|
if (budgetId == null) {
|
log.warn("{}, 关联预算单id为空!", updateBudgetEntity);
|
return;
|
}
|
addLock(budgetId);
|
this.budgetChildInfo = getFormInfo(getFormId(SystemForm.BUDGET_FORM_ID), BUDGET_SUB_FROM, budgetId);
|
Assert.condition(budgetChildInfo == null, BUDGET_INVALID);
|
if (this.expendInfo.get(EXPEND_USE_MONEY) == null
|
|| this.budgetChildInfo.get(BUDGET_ITEM_BALANCE) == null) {
|
log.warn("{}, 报销金额:{}, 预算余额:{}"
|
, updateBudgetEntity
|
, this.expendInfo.get(EXPEND_USE_MONEY)
|
, this.budgetChildInfo.get(BUDGET_ITEM_BALANCE));
|
return;
|
}
|
this.budgetMoney = toDouble(this.budgetChildInfo.get(BUDGET_ITEM_BALANCE))
|
- toDouble(this.expendInfo.get(EXPEND_USE_MONEY));
|
Assert.condition(this.budgetMoney < 0, BUDGET_MONEY_NOT_ENOUGH);
|
} else {
|
// 报销-申请-预算
|
Integer applyId = getParentId(this.expendInfo);
|
if (applyId == null) {
|
log.warn("{}, 关联申请单id为空!", updateBudgetEntity);
|
return;
|
}
|
this.applyEntity.setDataRowNum(applyId);
|
this.applyInfo = getFormInfo(this.applyEntity);
|
Assert.condition(applyInfo == null, APPLY_INVALID);
|
Integer budgetId = getParentId(this.applyInfo);
|
if (budgetId == null) {
|
log.warn("{}, 关联预算单id为空!", updateBudgetEntity);
|
return;
|
}
|
addLock(budgetId);
|
this.budgetChildInfo = getFormInfo(getFormId(SystemForm.BUDGET_FORM_ID), BUDGET_SUB_FROM, budgetId);
|
Assert.condition(budgetChildInfo == null, BUDGET_INVALID);
|
if (this.expendInfo.get(EXPEND_USE_MONEY) == null
|
|| this.budgetChildInfo.get(BUDGET_ITEM_BALANCE) == null
|
|| this.applyInfo.get(APPLY_USE_MONEY) == null) {
|
log.warn("{}, 报销金额:{}, 预算余额:{}, 申请金额:{}"
|
, updateBudgetEntity
|
, this.expendInfo.get(EXPEND_USE_MONEY)
|
, this.budgetChildInfo.get(BUDGET_ITEM_BALANCE)
|
, this.applyInfo.get(APPLY_USE_MONEY));
|
return;
|
}
|
Assert.condition((this.budgetMoney = (toDouble(this.budgetChildInfo.get(BUDGET_ITEM_BALANCE))
|
+ toDouble(this.applyInfo.get(APPLY_USE_MONEY))
|
- toDouble(this.expendInfo.get(EXPEND_USE_MONEY)))) < 0, BUDGET_MONEY_NOT_ENOUGH);
|
//申请状态回写,只能被占用一次
|
updateData(this.applyEntity.getFormId(), null
|
, this.applyEntity.getDataRowNum()
|
, new ModelMap(PROCESS_FLAG, 1));
|
}
|
String childForm = updateBudgetEntity.getFormId() + PAYINFO;
|
count = formDataMapper.selectTableExist(childForm);
|
//如果有子表单
|
if (count > 0) {
|
// 判断金额是否合适
|
// 冲抵金额
|
Double money = this.persionMoney(updateBudgetEntity);
|
// 借款金额
|
Double borowMoney = this.allBorrowMoney();
|
//如果冲抵金额大于0,并且借款金额等于0或者冲抵金额大于了借款金额报错
|
if (money > 0) {
|
log.debug("本次冲抵金额为:" + money.toString());
|
Assert.condition(BigDecimal.valueOf(borowMoney).compareTo(BigDecimal.valueOf(0)) == 0 || money > borowMoney, PERSION_COST_OUT);
|
}
|
}
|
}
|
|
@Override
|
@TxTransaction
|
@Transactional
|
public void updateBudget(UpdateBudgetEntity updateBudgetEntity) {
|
super.updateBudget(updateBudgetEntity);
|
checkBudget(updateBudgetEntity);
|
if (ObjectUtil.empty(this.budgetChildInfo) || this.expendInfo.get(EXPEND_USE_MONEY) == null
|
|| this.budgetChildInfo.get(BUDGET_ITEM_BALANCE) == null
|
|| (this.applyInfo != null && this.applyInfo.get(APPLY_USE_MONEY) == null)) {
|
// account(updateBudgetEntity.getFormId(), ThreadData.get(Keys.TENANT_ID), Objects.toString(updateBudgetEntity.getDataRowNum(), ""));
|
return;
|
}
|
checkMoney(this.budgetMoney);
|
|
if (ObjectUtil.empty(applyInfo)) {
|
addBudgetLogMoney(this.budgetChildInfo, budgetMoney, updateBudgetEntity.getFormId(), this.expendInfo,
|
toDouble(expendInfo.get(EXPEND_USE_MONEY)));
|
} else {
|
addBudgetLogMoney(this.budgetChildInfo, budgetMoney
|
|
, updateBudgetEntity.getFormId(), this.expendInfo, toDouble(expendInfo.get(EXPEND_USE_MONEY))
|
|
, applyEntity.getFormId(), this.applyInfo, toDouble(this.applyInfo.get(APPLY_USE_MONEY)));
|
//回写借款金额
|
Object amountMoney = this.expendInfo.get(AMOUNTREPAYMENTS);
|
log.debug("当前报销单:" + JSONTool.toJson(this.expendInfo));
|
log.debug("还款金额为:" + amountMoney);
|
if (amountMoney != null && !Objects.equals("", amountMoney)) {
|
log.debug("报销还款金额回写-------->");
|
updateData(applyEntity.getFormId(), null, applyEntity.getDataRowNum()
|
, new ModelMap(ALREADYREPAID, amountMoney));
|
}
|
}
|
//formatDouble(formBaseEntity);
|
updateData(getFormId(SystemForm.BUDGET_FORM_ID), BUDGET_SUB_FROM, getDataRowNum(this.budgetChildInfo),
|
new ModelMap(BUDGET_ITEM_BALANCE, format(this.budgetMoney, getFormBase(getFormId(SystemForm.BUDGET_FORM_ID)), BUDGET_ITEM_BALANCE)));
|
|
}
|
|
|
@Override
|
public void flowAfterCall(UpdateBudgetEntity updateBudgetEntity) {
|
this.expendInfo = getFormInfo(updateBudgetEntity);
|
this.applyEntity = getApplyInfo(
|
NumberUtils.createInteger(Objects.toString(this.expendInfo.get(EXPEND_COST_TYPE), "0")));
|
if (this.applyEntity == null) {
|
// 报销-预算
|
Integer budgetId = getParentId(this.expendInfo);
|
if (budgetId == null) {
|
return;
|
}
|
delLock(budgetId);
|
} else {
|
// 报销-申请-预算
|
Integer applyId = getParentId(this.expendInfo);
|
if (applyId == null) {
|
return;
|
}
|
this.applyEntity.setDataRowNum(applyId);
|
this.applyInfo = getFormInfo(this.applyEntity);
|
Integer budgetId = getParentId(this.applyInfo);
|
if (budgetId == null) {
|
return;
|
}
|
delLock(budgetId);
|
}
|
account(updateBudgetEntity.getFormId(), ThreadData.get(Keys.TENANT_ID), Objects.toString(updateBudgetEntity.getDataRowNum(), ""));
|
// 调用报销单个人冲抵的方法判断
|
this.getPersionCostById(updateBudgetEntity);
|
}
|
|
@Override
|
public void rollback(UpdateBudgetEntity updateBudgetEntity) {
|
super.rollback(updateBudgetEntity);
|
this.expendInfo = getFormInfo(updateBudgetEntity);
|
this.applyEntity = getApplyInfo(
|
NumberUtils.createInteger(Objects.toString(this.expendInfo.get(EXPEND_COST_TYPE), "0")));
|
if (this.applyEntity == null) {
|
// 报销-预算
|
Integer budgetId = getParentId(this.expendInfo);
|
if (budgetId == null) {
|
log.warn("{}, 关联预算单id为空!", updateBudgetEntity);
|
return;
|
}
|
addLock(budgetId);
|
this.budgetChildInfo = getFormInfo(getFormId(SystemForm.BUDGET_FORM_ID), BUDGET_SUB_FROM, budgetId);
|
Assert.condition(budgetChildInfo == null, BUDGET_INVALID);
|
if (this.expendInfo.get(EXPEND_USE_MONEY) == null
|
|| this.budgetChildInfo.get(BUDGET_ITEM_BALANCE) == null) {
|
log.warn("{}, 报销金额:{}, 预算余额:{}"
|
, updateBudgetEntity
|
, this.expendInfo.get(EXPEND_USE_MONEY)
|
, this.budgetChildInfo.get(BUDGET_ITEM_BALANCE));
|
return;
|
}
|
this.budgetMoney = toDouble(this.budgetChildInfo.get(BUDGET_ITEM_BALANCE))
|
+ toDouble(this.expendInfo.get(EXPEND_USE_MONEY));
|
|
addBudgetLogMoney(this.budgetChildInfo, budgetMoney, updateBudgetEntity.getFormId(), this.expendInfo,
|
toDouble(expendInfo.get(EXPEND_USE_MONEY)));
|
} else {
|
// 报销-申请-预算
|
Integer applyId = getParentId(this.expendInfo);
|
if (applyId == null) {
|
log.warn("{}, 关联申请单id为空!", updateBudgetEntity);
|
return;
|
}
|
this.applyEntity.setDataRowNum(applyId);
|
this.applyInfo = getFormInfo(this.applyEntity);
|
Assert.condition(applyInfo == null, APPLY_INVALID);
|
Integer budgetId = getParentId(this.applyInfo);
|
if (budgetId == null) {
|
log.warn("{}, 关联预算单id为空!", updateBudgetEntity);
|
return;
|
}
|
addLock(budgetId);
|
this.budgetChildInfo = getFormInfo(getFormId(SystemForm.BUDGET_FORM_ID), BUDGET_SUB_FROM, budgetId);
|
Assert.condition(budgetChildInfo == null, BUDGET_INVALID);
|
if (this.expendInfo.get(EXPEND_USE_MONEY) == null
|
|| this.budgetChildInfo.get(BUDGET_ITEM_BALANCE) == null
|
|| this.applyInfo.get(APPLY_USE_MONEY) == null) {
|
log.warn("{}, 报销金额:{}, 预算余额:{}, 申请金额:{}"
|
, updateBudgetEntity
|
, this.expendInfo.get(EXPEND_USE_MONEY)
|
, this.budgetChildInfo.get(BUDGET_ITEM_BALANCE)
|
, this.applyInfo.get(APPLY_USE_MONEY));
|
return;
|
}
|
this.budgetMoney = (toDouble(this.budgetChildInfo.get(BUDGET_ITEM_BALANCE))
|
- toDouble(this.expendInfo.get(EXPEND_USE_MONEY))
|
+ toDouble(this.applyInfo.get(APPLY_USE_MONEY)));
|
|
addBudgetLogMoney(this.budgetChildInfo, budgetMoney
|
|
, updateBudgetEntity.getFormId(), this.expendInfo, toDouble(expendInfo.get(EXPEND_USE_MONEY))
|
|
, applyEntity.getFormId(), this.applyInfo, toDouble(this.applyInfo.get(APPLY_USE_MONEY)));
|
|
//回写借款金额
|
Object amountMoney = this.expendInfo.get(AMOUNTREPAYMENTS);
|
// log.debug("当前报销单:"+ JSONTool.toJson(this.expendInfo));
|
// log.debug("还款金额为:"+amountMoney);
|
if (amountMoney != null && !Objects.equals("", amountMoney)) {
|
// log.debug("报销还款金额回写-------->");
|
updateData(applyEntity.getFormId(), null, applyEntity.getDataRowNum()
|
, new ModelMap(ALREADYREPAID, 0));
|
// ,new ModelMap(ALREADYREPAID,amountMoney));
|
}
|
}
|
|
updateData(getFormId(SystemForm.BUDGET_FORM_ID), BUDGET_SUB_FROM, getDataRowNum(this.budgetChildInfo),
|
new ModelMap(BUDGET_ITEM_BALANCE, format(this.budgetMoney, getFormBase(getFormId(SystemForm.BUDGET_FORM_ID)), BUDGET_ITEM_BALANCE)));
|
}
|
|
@Override
|
public FormType getFormType() {
|
return FormType.BX;
|
}
|
|
public UpdateBudgetEntity getApplyInfo(Integer cType) {
|
String formId = null;
|
for (CostFromMapping costFromMapping : this.costFromMappings) {
|
if (Objects.equals(costFromMapping.getType(), FormType.SQ.toString())
|
&& Objects.equals(costFromMapping.getCtId(), cType)) {
|
formId = costFromMapping.getFId();
|
break;
|
}
|
}
|
if (formId == null) {
|
return null;
|
}
|
UpdateBudgetEntity updateBudgetEntity = new UpdateBudgetEntity();
|
updateBudgetEntity.setFormId(formId);
|
return updateBudgetEntity;
|
}
|
|
/**
|
* 如果为个人抵扣报销进入此方法
|
*/
|
public void getPersionCostById(UpdateBudgetEntity updateBudgetEntity) {
|
// 本次冲抵的所有的金额
|
Double money = this.persionMoney(updateBudgetEntity);
|
if (count > 0 && money > 0) {
|
// 借款单Id
|
String formId = getFormId(SystemForm.LOAN_FORM_ID);
|
if (ObjectUtil.empty(formId)) {
|
return;
|
}
|
// 不为空说明此人有借款
|
if (Objects.nonNull(borrowList) && borrowList.size() > 0) {
|
Double price = 0.0;
|
for (Map<String, Object> pb : borrowList) {
|
// 未还金额- 个人冲抵金额=判断借款单是否还完
|
price = Double.parseDouble(Objects.toString(pb.get(OUTSTANDING_AMOUNT), "0")) - money;
|
// 情况1 .本次抵扣正好还清借款
|
if (price >= 0) {
|
// 已还款金额=冲抵金额+已还金额
|
Double price2 = Double.parseDouble(Objects.toString(pb.get(ALREADY_REPAID), "0")) + money;
|
this.crudBorrowAndPersion(formId, money, price2, pb);
|
break;
|
}
|
// 冲抵还死第一条记录
|
if (price < 0) {
|
// 本条记录的冲抵金额
|
money = Double.parseDouble(Objects.toString(pb.get(OUTSTANDING_AMOUNT), "0"));
|
// 已还款金额=借款总金额
|
Double price2 = Double.parseDouble(Objects.toString(pb.get(APPLICATION_AMOUNT), "0"));
|
this.crudBorrowAndPersion(formId, money, price2, pb);
|
money = -price;
|
}
|
}
|
|
}
|
|
}
|
}
|
|
/**
|
* @param money 当前冲抵金额
|
* @param price 已还款金额
|
* @param pb 借款单数据 更新借款表
|
*/
|
public void crudBorrowAndPersion(String formId, Double money, Double price, Map<String, Object> pb) {
|
// 借款数据行号
|
Integer dataNum = Integer.parseInt(Objects.toString(pb.get(DATAROWNUMBER), "0"));
|
PersionBackMoney persionBackMoney = new PersionBackMoney();
|
persionBackMoney.initParam();
|
// 当前还款金额
|
persionBackMoney.setPayMoney(money);
|
persionBackMoney.setDataRowNum(dataNum);
|
persionBackMoney.setFormId(formId);
|
// 借款单没有币种
|
// persionBackMoney.setMoneyType();
|
persionBackMoney.setTendantId(Objects.toString(ThreadData.get(TENANT_ID)));
|
persionBackMoney.setDepartment(Objects.toString(pb.get(DEPARTMENT)));
|
String borrowTime = pb.get(CREATEDATETIME).toString();
|
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
try {
|
persionBackMoney.setBorrowDate(formatter.parse(borrowTime));
|
} catch (ParseException e) {
|
// System.err.println(e.getMessage());
|
}
|
String openId = Objects.toString(pb.get(LOANPEOPLE));
|
persionBackMoney.setStaffId(openId);
|
persionBackMoney.setPosition(Objects.toString(pb.get(EMPLOYEE_POSITION)));
|
persionBackMoney.setPayDate(new Date());
|
// 未还总金额
|
persionBackMoney.setPayAllmoney(Double.parseDouble(Objects.toString(pb.get(APPLICATION_AMOUNT), "0")) - price);
|
persionBackMoney.setBorrowMoney(Double.parseDouble(Objects.toString(pb.get(APPLICATION_AMOUNT), "0")));
|
// 支付方式(1000000.个人抵扣2.其他的方式)
|
persionBackMoney.setPaymentMethod(GetConstant.getConstant(PERSION_COST_RETURN));
|
persionBackMoney.setOpenId(openId);
|
// 更新操作
|
persionBackMoneyMapper.insert(persionBackMoney);
|
/**
|
* 冲抵的日志
|
* 日志对象还款单
|
* 原始内容:未还款总金额
|
* 变更来源内容:冲抵金额 money
|
* */
|
if (ObjectUtil.empty(applyInfo)) {
|
addBudgetLogMoney(this.budgetChildInfo, budgetMoney, formId, this.expendInfo,
|
toDouble(expendInfo.get(EXPEND_USE_MONEY)));
|
} else {
|
addBudgetLogMoney(this.budgetChildInfo, budgetMoney
|
|
, formId, this.expendInfo, money
|
|
, applyEntity.getFormId(), this.applyInfo, toDouble(this.applyInfo.get(APPLY_USE_MONEY)));
|
}
|
|
|
// 更新借款单
|
updateData(formId, null, dataNum,
|
// 已还金额
|
new ModelMap(ALREADY_REPAID, format(price, getFormBase(formId), ALREADY_REPAID)).addAttribute(OUTSTANDING_AMOUNT,
|
// 未还金额
|
format((Double.parseDouble(Objects.toString(pb.get(APPLICATION_AMOUNT), "0")) - price), getFormBase(formId), OUTSTANDING_AMOUNT)));
|
}
|
|
/**
|
* 返回个人冲抵的金额
|
*/
|
public Double persionMoney(UpdateBudgetEntity updateBudgetEntity) {
|
// 个人冲抵金额
|
Double money = 0.0;
|
// 个人冲抵判断值
|
String keys = GetConstant.getConstant(PERSION_COST_RETURN);
|
// 报销子表单表名
|
String formName2 = updateBudgetEntity.getFormId() + PAYINFO;
|
// 主表表名
|
String formName = updateBudgetEntity.getFormId();
|
// 查询对应的报销单数据
|
list = formDataMapper.getPersionCostReturn(updateBudgetEntity.getDataRowNum(), formName, formName2);
|
for (Map<String, Object> m : list) {
|
// 个人冲抵暂定为“10000000”(页面显示现金)
|
if (Objects.equals(m.get(PAYWAY), keys) && StringUtils.isNotBlank(m.get(NETMONEY).toString())) {
|
// NETMONEY,支付金额key值
|
money += Double.parseDouble(Objects.toString(m.get(NETMONEY), "0"));
|
}
|
}
|
return money;
|
}
|
|
/**
|
* 全部借款金额
|
*/
|
public Double allBorrowMoney() {
|
String formId = getFormId(SystemForm.LOAN_FORM_ID);
|
Double borrowMoney = 0.0;
|
if (ObjectUtil.empty(formId)) {
|
return borrowMoney;
|
}
|
String openId = list.get(0).get(REIMBURSE_MAN).toString();
|
// 借款数据
|
borrowList = formDataMapper.getBorrowMoney(openId, formId);
|
for (Map<String, Object> m : borrowList) {
|
borrowMoney += Double.parseDouble(Objects.toString(m.get(OUTSTANDING_AMOUNT), "0"));
|
}
|
log.debug("当前借款金额为:" + borrowMoney.toString());
|
return borrowMoney;
|
}
|
|
}
|