diff --git a/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisCustomsLevelController.java b/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisCustomsLevelController.java index 80ed34e37..419a45cbd 100644 --- a/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisCustomsLevelController.java +++ b/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisCustomsLevelController.java @@ -36,7 +36,7 @@ public class EmisCustomsLevelController extends EmisBaseController { /** * 查询报关清关级别维护列表 */ - @PreAuthorize("@ss.hasPermi('emis:emisCustomsLevel:list')") +// @PreAuthorize("@ss.hasPermi('emis:emisCustomsLevel:list')") @GetMapping("/list") public TableDataInfo list(EmisCustomsLevel emisCustomsLevel) { startPage(); diff --git a/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisWriteoffApplyController.java b/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisWriteoffApplyController.java index 4a9205390..09a8f5041 100644 --- a/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisWriteoffApplyController.java +++ b/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisWriteoffApplyController.java @@ -30,7 +30,6 @@ import java.util.Arrays; import java.util.List; import java.math.BigDecimal; import java.util.stream.Collectors; -import java.util.Map; /** * 销账申请Controller @@ -373,6 +372,66 @@ public class EmisWriteoffApplyController extends EmisBaseController { return AjaxResult.success("操作成功"); } + /** + * 财务中心审核撤销 + */ + @PreAuthorize("@ss.hasPermi('emis:writeoffApply:centerRevoke')") + @Log(title = "财务中心审核撤销", businessType = BusinessType.UPDATE) + @PostMapping("/auditCenterRevoke/{ids}") + public AjaxResult auditCenterRevoke(@PathVariable Long[] ids) { + if (ids != null && ids.length > 0) { + for (int i = 0; i < ids.length; i++) { + try { + long id = ids[i]; + EmisWriteoffApply emisWriteoffApply = new EmisWriteoffApply(); + emisWriteoffApply.setId(id); + + emisWriteoffApplyService.auditCenterRevoke(emisWriteoffApply); + + } catch (Exception ex) { + ex.printStackTrace(); + // 返回子定义异常 + if (ex instanceof EmisBizError) { + return AjaxResult.error(ex.getMessage(), ((EmisBizError) ex).getErrorCode()); + } + + return AjaxResult.error("撤销异常,联系客服"); + } + } + } + return AjaxResult.success("操作成功"); + } + + /** + * 总部确认撤销 + */ + @PreAuthorize("@ss.hasPermi('emis:writeoffApply:headquartersRevoke')") + @Log(title = "总部确认撤销", businessType = BusinessType.UPDATE) + @PostMapping("/auditHeadquartersRevoke/{ids}") + public AjaxResult auditHeadquartersRevoke(@PathVariable Long[] ids) { + if (ids != null && ids.length > 0) { + for (int i = 0; i < ids.length; i++) { + try { + long id = ids[i]; + EmisWriteoffApply emisWriteoffApply = new EmisWriteoffApply(); + emisWriteoffApply.setId(id); + + emisWriteoffApplyService.auditHeadquartersRevoke(emisWriteoffApply); + + } catch (Exception ex) { + ex.printStackTrace(); + // 返回子定义异常 + if (ex instanceof EmisBizError) { + return AjaxResult.error(ex.getMessage(), ((EmisBizError) ex).getErrorCode()); + } + + return AjaxResult.error("撤销异常,联系客服"); + } + } + } + return AjaxResult.success("操作成功"); + } + /** * 再次申请 */ diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/mapper/EmisWriteoffApplyMapper.java b/emis-biz/src/main/java/com/xdadan/erp/emis/mapper/EmisWriteoffApplyMapper.java index 41501aedd..6409a2edd 100644 --- a/emis-biz/src/main/java/com/xdadan/erp/emis/mapper/EmisWriteoffApplyMapper.java +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/mapper/EmisWriteoffApplyMapper.java @@ -128,4 +128,20 @@ public interface EmisWriteoffApplyMapper extends BaseMapper { * @return 结果 */ public int reapply(EmisWriteoffApply emisWriteoffApply); + + /** + * 财务中心审核撤销 + * + * @param emisWriteoffApply + * @return 结果 + */ + public int auditCenterRevoke(EmisWriteoffApply emisWriteoffApply); + + /** + * 总部确认撤销 + * + * @param emisWriteoffApply + * @return 结果 + */ + public int auditHeadquartersRevoke(EmisWriteoffApply emisWriteoffApply); } diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/service/IEmisWriteoffApplyService.java b/emis-biz/src/main/java/com/xdadan/erp/emis/service/IEmisWriteoffApplyService.java index cf9db2796..6820682e9 100644 --- a/emis-biz/src/main/java/com/xdadan/erp/emis/service/IEmisWriteoffApplyService.java +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/IEmisWriteoffApplyService.java @@ -127,4 +127,22 @@ public interface IEmisWriteoffApplyService { */ public List selectEmisWriteoffApplyDetailListByBillCodes(List billCodes); + /** + * 财务中心审核撤销(支持单个和批量) + * 撤销财务中心审核通过的所有操作,将状态回退到待审核状态 + * + * @param emisWriteoffApply 销账申请(单个操作时传入完整对象,批量操作时传入包含ids的对象) + * @return 结果 + */ + public int auditCenterRevoke(EmisWriteoffApply emisWriteoffApply) throws EmisBizError; + + /** + * 总部确认撤销(支持单个和批量) + * 撤销总部确认的所有操作,将状态回退到财务中心已审核状态 + * + * @param emisWriteoffApply 销账申请(单个操作时传入完整对象,批量操作时传入包含ids的对象) + * @return 结果 + */ + public int auditHeadquartersRevoke(EmisWriteoffApply emisWriteoffApply) throws EmisBizError; + } diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisWriteoffApplyServiceImpl.java b/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisWriteoffApplyServiceImpl.java index 351d185ad..b54a79766 100644 --- a/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisWriteoffApplyServiceImpl.java +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisWriteoffApplyServiceImpl.java @@ -361,8 +361,16 @@ public class EmisWriteoffApplyServiceImpl extends EmisBaseService implements IEm throw new EmisBizError("已审核/已撤销"); } + // 获取完整的申请数据(包括明细和关联信息)进行校验 + List detailList = emisWriteoffApplyDetailMapper + .selectEmisWriteoffApplyDetailListByApplyIdWithDetails(existingApply.getId()); + existingApply.setDetailList(detailList); + + // 验证销账金额 + validateWriteoffAmount(existingApply); + // 先更新相关业务数据(在更新审核状态之前进行验证和更新) - List detailList = updateRelatedBusinessData(existingApply, true); + detailList = updateRelatedBusinessData(existingApply, true); // 更新运单的付款状态 updateWaybillPaymentStatus(existingApply, detailList, true); @@ -465,6 +473,21 @@ public class EmisWriteoffApplyServiceImpl extends EmisBaseService implements IEm throw new EmisBizError("已驳回,无法确认"); } + // 获取申请明细,更新核销状态 + List detailList = emisWriteoffApplyDetailMapper + .selectEmisWriteoffApplyDetailListByApplyId(existingApply.getId()); + if (!CollectionUtils.isEmpty(detailList)) { + // 按settleBillNo分组处理明细 + Map> groupedDetails = detailList.stream() + .filter(detail -> StringUtil.isNotBlank(detail.getSettleBillNo())) + .collect(java.util.stream.Collectors.groupingBy(EmisWriteoffApplyDetail::getSettleBillNo)); + + // 更新每个结算账单的核销状态 + for (String settleBillNo : groupedDetails.keySet()) { + updateSettleBillChargeStatus(settleBillNo); + } + } + // 设置确认信息 SysUser currentUser = SecurityUtils.getLoginUser().getUser(); emisWriteoffApply.setBlHeadquartersConfirmed(WriteoffApplyStatus.HEADQUARTERS_CONFIRMED.statusCode); @@ -811,14 +834,13 @@ public class EmisWriteoffApplyServiceImpl extends EmisBaseService implements IEm updateBill.setPaymentStatus("0"); // 未付款 } else if (newRecedMoney.compareTo(recMoney) >= 0) { updateBill.setPaymentStatus("1"); // 已付款 - updateBill.setChargeStatus("1"); // 已核销 } else { updateBill.setPaymentStatus("2"); // 部分付款 } emisSettleBillMapper.updateEmisSettleBill(updateBill); - log.info("结算账单收款状态更新成功,账单号: {}, 新已收金额: {}, 收款状态: {}, 核销状态: {}", - settleBillNo, newRecedMoney, updateBill.getPaymentStatus(), updateBill.getChargeStatus()); + log.info("结算账单收款状态更新成功,账单号: {}, 新已收金额: {}, 收款状态: {}", + settleBillNo, newRecedMoney, updateBill.getPaymentStatus()); } else { // 拒绝销账申请,减少已收金额 BigDecimal currentRecedMoney = settleBill.getRecedMoney() != null ? settleBill.getRecedMoney() @@ -837,13 +859,10 @@ public class EmisWriteoffApplyServiceImpl extends EmisBaseService implements IEm BigDecimal recMoney = settleBill.getRecMoney() != null ? settleBill.getRecMoney() : BigDecimal.ZERO; if (newRecedMoney.compareTo(BigDecimal.ZERO) == 0) { updateBill.setPaymentStatus("0"); // 未付款 - updateBill.setChargeStatus("0"); // 未核销 } else if (newRecedMoney.compareTo(recMoney) >= 0) { updateBill.setPaymentStatus("1"); // 已付款 - updateBill.setChargeStatus("1"); // 已核销 } else { updateBill.setPaymentStatus("2"); // 部分付款 - updateBill.setChargeStatus("0"); // 未核销 } emisSettleBillMapper.updateEmisSettleBill(updateBill); @@ -856,6 +875,45 @@ public class EmisWriteoffApplyServiceImpl extends EmisBaseService implements IEm } } + /** + * 更新结算账单的核销状态(仅在总部确认时调用) + */ + private void updateSettleBillChargeStatus(String settleBillNo) throws EmisBizError { + try { + log.info("更新结算账单核销状态,账单号: {}", settleBillNo); + + // 获取结算账单信息 + EmisSettleBill settleBill = emisSettleBillMapper.selectSettleBillBySettleBillNo(settleBillNo); + if (settleBill == null) { + log.warn("结算账单不存在,账单号: {}", settleBillNo); + return; + } + + // 更新结算账单的核销状态 + EmisSettleBill updateBill = new EmisSettleBill(); + updateBill.setId(settleBill.getId()); + + // 根据已收金额和应收金额比较,设置核销状态 + BigDecimal recedMoney = settleBill.getRecedMoney() != null ? settleBill.getRecedMoney() : BigDecimal.ZERO; + BigDecimal recMoney = settleBill.getRecMoney() != null ? settleBill.getRecMoney() : BigDecimal.ZERO; + + if (recedMoney.compareTo(BigDecimal.ZERO) == 0) { + updateBill.setChargeStatus("0"); // 未核销 + } else if (recedMoney.compareTo(recMoney) >= 0) { + updateBill.setChargeStatus("1"); // 已核销 + } else { + updateBill.setChargeStatus("0"); // 未核销 + } + + emisSettleBillMapper.updateEmisSettleBill(updateBill); + log.info("结算账单核销状态更新成功,账单号: {}, 已收金额: {}, 应收金额: {}, 核销状态: {}", + settleBillNo, recedMoney, recMoney, updateBill.getChargeStatus()); + } catch (Exception e) { + log.error("更新结算账单核销状态失败,账单号: {}", settleBillNo, e); + throw new EmisBizError("更新结算账单核销状态失败:" + e.getMessage()); + } + } + /** * 回退相关业务数据 * @@ -937,13 +995,13 @@ public class EmisWriteoffApplyServiceImpl extends EmisBaseService implements IEm BigDecimal recMoney = settleBill.getRecMoney() != null ? settleBill.getRecMoney() : BigDecimal.ZERO; if (newRecedMoney.compareTo(BigDecimal.ZERO) == 0) { updateBill.setPaymentStatus("0"); // 未付款 - updateBill.setChargeStatus("0"); // 未核销 + // updateBill.setChargeStatus("0"); // 未核销 } else if (newRecedMoney.compareTo(recMoney) >= 0) { updateBill.setPaymentStatus("1"); // 已付款 - updateBill.setChargeStatus("1"); // 已核销 + // updateBill.setChargeStatus("1"); // 已核销 } else { updateBill.setPaymentStatus("2"); // 部分付款 - updateBill.setChargeStatus("0"); // 未核销 + // updateBill.setChargeStatus("0"); // 未核销 } emisSettleBillMapper.updateEmisSettleBill(updateBill); @@ -1193,10 +1251,18 @@ public class EmisWriteoffApplyServiceImpl extends EmisBaseService implements IEm title = operatorName + "驳回了您的销账申请,申请编号:" + apply.getApplyNo() + ",驳回原因:" + (StringUtils.hasText(rejectReason) ? rejectReason : "无"); break; + case "centerRevoke": + title = operatorName + "撤销了财务中心对您的销账申请的审核,申请编号:" + apply.getApplyNo() + + ",销账金额:" + apply.getWriteoffAmount(); + break; case "headquartersReject": title = operatorName + "驳回了您的销账申请,申请编号:" + apply.getApplyNo() + ",驳回原因:" + (StringUtils.hasText(rejectReason) ? rejectReason : "无"); break; + case "headquartersRevoke": + title = operatorName + "撤销了总部对您的销账申请的确认,申请编号:" + apply.getApplyNo() + + ",销账金额:" + apply.getWriteoffAmount(); + break; default: log.warn("未知的操作类型:{}", actionType); return; @@ -1205,10 +1271,17 @@ public class EmisWriteoffApplyServiceImpl extends EmisBaseService implements IEm // 发送通知给申请人 sendNoticeToEmpUser(apply.getApplyManCode(), title, message, applyPath); - // 如果是总部驳回,还需要通知财务中心审批人员 - if ("headquartersReject".equals(actionType) && StringUtils.hasText(apply.getCenterConfirmManCode())) { - String centerTitle = "您审核通过的销账申请被" + operatorName + "驳回,申请编号:" + apply.getApplyNo() + - ",驳回原因:" + (StringUtils.hasText(rejectReason) ? rejectReason : "无"); + // 如果是总部驳回或总部撤销,还需要通知财务中心审批人员 + if (("headquartersReject".equals(actionType) || "headquartersRevoke".equals(actionType)) + && StringUtils.hasText(apply.getCenterConfirmManCode())) { + String centerTitle; + if ("headquartersReject".equals(actionType)) { + centerTitle = "您审核通过的销账申请被" + operatorName + "驳回,申请编号:" + apply.getApplyNo() + + ",驳回原因:" + (StringUtils.hasText(rejectReason) ? rejectReason : "无"); + } else { + centerTitle = "您审核通过的销账申请被" + operatorName + "撤销确认,申请编号:" + apply.getApplyNo() + + ",销账金额:" + apply.getWriteoffAmount(); + } sendNoticeToEmpUser(apply.getCenterConfirmManCode(), centerTitle, "", checkPath); } @@ -1594,4 +1667,160 @@ public class EmisWriteoffApplyServiceImpl extends EmisBaseService implements IEm } } + /** + * 财务中心审核撤销 + * 撤销财务中心审核通过的所有操作,将状态回退到待审核状态 + * + * @param emisWriteoffApply 销账申请 + * @return 结果 + */ + @Override + @Transactional + public int auditCenterRevoke(EmisWriteoffApply emisWriteoffApply) throws EmisBizError { + try { + // 检查申请状态 + EmisWriteoffApply existingApply = emisWriteoffApplyMapper + .selectEmisWriteoffApplyById(emisWriteoffApply.getId()); + if (existingApply == null) { + throw new EmisBizError("申请不存在"); + } + if (!WriteoffApplyStatus.CENTER_APPROVED.statusCode.equals(existingApply.getBlCenterConfirmed())) { + throw new EmisBizError("只有财务中心已审核通过的申请才能撤销"); + } + + // 先回退相关业务数据(在更新审核状态之前进行回退) + List detailList = rollbackRelatedBusinessData(existingApply); + + // 更新运单的付款状态 + updateWaybillPaymentStatus(existingApply, detailList, false); + + // 重算并更新月结客户额度和现金客户额度 + updateCreditLimits(existingApply, detailList); + + // 更新相关开票记录的收款金额和付款状态(回退) + updateInvoiceRecordPaymentStatus(existingApply, detailList, false); + + // 删除收款记录 + deleteSettlePayRecord(existingApply); + + // 所有业务数据回退成功后,再更新审核状态 + emisWriteoffApply.setBlCenterConfirmed(WriteoffApplyStatus.CENTER_PENDING.statusCode); + emisWriteoffApply.setCenterConfirmManCode(null); + emisWriteoffApply.setCenterConfirmManName(null); + emisWriteoffApply.setCenterConfirmDate(null); + emisWriteoffApply.setCenterConfirmNote(null); + emisWriteoffApply.setCenterRejectReason(null); + emisWriteoffApply.setPayId(null); // 清空收款记录支付ID + + // 更新申请状态 + int result = emisWriteoffApplyMapper.auditCenterRevoke(emisWriteoffApply); + + // 发送通知给申请人 + // sendWriteoffApplyNotification(existingApply, "centerRevoke", null); + + return result; + } catch (Exception e) { + log.error("财务中心审核撤销失败", e); + throw new EmisBizError("财务中心审核撤销失败:" + e.getMessage()); + } + } + + /** + * 总部确认撤销 + * 撤销总部确认的所有操作,将状态回退到财务中心已审核状态 + * + * @param emisWriteoffApply 销账申请 + * @return 结果 + */ + @Override + @Transactional + public int auditHeadquartersRevoke(EmisWriteoffApply emisWriteoffApply) throws EmisBizError { + try { + // 检查申请状态 + EmisWriteoffApply existingApply = emisWriteoffApplyMapper + .selectEmisWriteoffApplyById(emisWriteoffApply.getId()); + if (existingApply == null) { + throw new EmisBizError("申请不存在"); + } + if (!WriteoffApplyStatus.HEADQUARTERS_CONFIRMED.statusCode + .equals(existingApply.getBlHeadquartersConfirmed())) { + throw new EmisBizError("只有总部已确认的申请才能撤销"); + } + + // 获取申请明细,回退核销状态 + List detailList = emisWriteoffApplyDetailMapper + .selectEmisWriteoffApplyDetailListByApplyId(existingApply.getId()); + if (!CollectionUtils.isEmpty(detailList)) { + // 按settleBillNo分组处理明细 + Map> groupedDetails = detailList.stream() + .filter(detail -> StringUtil.isNotBlank(detail.getSettleBillNo())) + .collect(java.util.stream.Collectors.groupingBy(EmisWriteoffApplyDetail::getSettleBillNo)); + + // 回退每个结算账单的核销状态 + for (String settleBillNo : groupedDetails.keySet()) { + rollbackSettleBillChargeStatus(settleBillNo); + } + } + + // 设置撤销信息 + emisWriteoffApply.setBlHeadquartersConfirmed(WriteoffApplyStatus.CENTER_PENDING.statusCode); + emisWriteoffApply.setHeadquartersConfirmManCode(null); + emisWriteoffApply.setHeadquartersConfirmManName(null); + emisWriteoffApply.setHeadquartersConfirmDate(null); + emisWriteoffApply.setHeadquartersConfirmNote(null); + emisWriteoffApply.setHeadquartersRejectReason(null); + + // 更新申请状态 + int result = emisWriteoffApplyMapper.auditHeadquartersRevoke(emisWriteoffApply); + + // 发送通知给申请人和财务中心审批人员 + // sendWriteoffApplyNotification(existingApply, "headquartersRevoke", null); + + return result; + } catch (Exception e) { + log.error("总部确认撤销失败", e); + throw new EmisBizError("总部确认撤销失败:" + e.getMessage()); + } + } + + /** + * 回退结算账单的核销状态 + */ + private void rollbackSettleBillChargeStatus(String settleBillNo) throws EmisBizError { + try { + log.info("回退结算账单核销状态,账单号: {}", settleBillNo); + + // 获取结算账单信息 + EmisSettleBill settleBill = emisSettleBillMapper.selectSettleBillBySettleBillNo(settleBillNo); + if (settleBill == null) { + log.warn("结算账单不存在,账单号: {}", settleBillNo); + return; + } + + // 更新结算账单的核销状态 + EmisSettleBill updateBill = new EmisSettleBill(); + updateBill.setId(settleBill.getId()); + + // 根据已收金额和应收金额比较,设置核销状态 + BigDecimal recedMoney = settleBill.getRecedMoney() != null ? settleBill.getRecedMoney() : BigDecimal.ZERO; + BigDecimal recMoney = settleBill.getRecMoney() != null ? settleBill.getRecMoney() : BigDecimal.ZERO; + + // if (recedMoney.compareTo(BigDecimal.ZERO) == 0) { + // updateBill.setChargeStatus("0"); // 未核销 + // } else if (recedMoney.compareTo(recMoney) >= 0) { + // updateBill.setChargeStatus("1"); // 已核销 + // } else { + // updateBill.setChargeStatus("0"); // 未核销 + // } + + updateBill.setChargeStatus("0"); // 未核销 + emisSettleBillMapper.updateEmisSettleBill(updateBill); + log.info("结算账单核销状态回退成功,账单号: {}, 已收金额: {}, 应收金额: {}, 核销状态: {}", + settleBillNo, recedMoney, recMoney, updateBill.getChargeStatus()); + } catch (Exception e) { + log.error("回退结算账单核销状态失败,账单号: {}", settleBillNo, e); + throw new EmisBizError("回退结算账单核销状态失败:" + e.getMessage()); + } + } + } diff --git a/emis-biz/src/main/resources/mapper/EmisWriteoffApplyMapper.xml b/emis-biz/src/main/resources/mapper/EmisWriteoffApplyMapper.xml index 230241246..5728e4b58 100644 --- a/emis-biz/src/main/resources/mapper/EmisWriteoffApplyMapper.xml +++ b/emis-biz/src/main/resources/mapper/EmisWriteoffApplyMapper.xml @@ -321,6 +321,33 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where id = #{id} + + update emis_writeoff_apply set + bl_center_confirmed = #{blCenterConfirmed}, + center_confirm_man_code = #{centerConfirmManCode}, + center_confirm_man_name = #{centerConfirmManName}, + center_confirm_date = #{centerConfirmDate}, + center_confirm_note = #{centerConfirmNote}, + center_reject_reason = #{centerRejectReason}, + pay_id = #{payId}, + update_by = #{updateBy}, + update_time = #{updateTime} + where id = #{id} + + + + update emis_writeoff_apply set + bl_headquarters_confirmed = #{blHeadquartersConfirmed}, + headquarters_confirm_man_code = #{headquartersConfirmManCode}, + headquarters_confirm_man_name = #{headquartersConfirmManName}, + headquarters_confirm_date = #{headquartersConfirmDate}, + headquarters_confirm_note = #{headquartersConfirmNote}, + headquarters_reject_reason = #{headquartersRejectReason}, + update_by = #{updateBy}, + update_time = #{updateTime} + where id = #{id} + +