Merge pull request 'develop' (#200) from develop into master

Reviewed-on: http://git.xdadan.loc/tanex/emis-service/pulls/200
This commit is contained in:
heyu 2025-10-17 15:05:11 +08:00
commit 9b6a675b6d
6 changed files with 365 additions and 16 deletions

View File

@ -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();

View File

@ -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("操作成功");
}
/**
* 再次申请
*/

View File

@ -128,4 +128,20 @@ public interface EmisWriteoffApplyMapper extends BaseMapper<EmisWriteoffApply> {
* @return 结果
*/
public int reapply(EmisWriteoffApply emisWriteoffApply);
/**
* 财务中心审核撤销
*
* @param emisWriteoffApply
* @return 结果
*/
public int auditCenterRevoke(EmisWriteoffApply emisWriteoffApply);
/**
* 总部确认撤销
*
* @param emisWriteoffApply
* @return 结果
*/
public int auditHeadquartersRevoke(EmisWriteoffApply emisWriteoffApply);
}

View File

@ -127,4 +127,22 @@ public interface IEmisWriteoffApplyService {
*/
public List<EmisWriteoffApplyDetail> selectEmisWriteoffApplyDetailListByBillCodes(List<String> billCodes);
/**
* 财务中心审核撤销(支持单个和批量)
* 撤销财务中心审核通过的所有操作,将状态回退到待审核状态
*
* @param emisWriteoffApply 销账申请(单个操作时传入完整对象,批量操作时传入包含ids的对象)
* @return 结果
*/
public int auditCenterRevoke(EmisWriteoffApply emisWriteoffApply) throws EmisBizError;
/**
* 总部确认撤销(支持单个和批量)
* 撤销总部确认的所有操作,将状态回退到财务中心已审核状态
*
* @param emisWriteoffApply 销账申请(单个操作时传入完整对象,批量操作时传入包含ids的对象)
* @return 结果
*/
public int auditHeadquartersRevoke(EmisWriteoffApply emisWriteoffApply) throws EmisBizError;
}

View File

@ -361,8 +361,16 @@ public class EmisWriteoffApplyServiceImpl extends EmisBaseService implements IEm
throw new EmisBizError("已审核/已撤销");
}
// 获取完整的申请数据(包括明细和关联信息)进行校验
List<EmisWriteoffApplyDetail> detailList = emisWriteoffApplyDetailMapper
.selectEmisWriteoffApplyDetailListByApplyIdWithDetails(existingApply.getId());
existingApply.setDetailList(detailList);
// 验证销账金额
validateWriteoffAmount(existingApply);
// 先更新相关业务数据(在更新审核状态之前进行验证和更新)
List<EmisWriteoffApplyDetail> 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<EmisWriteoffApplyDetail> detailList = emisWriteoffApplyDetailMapper
.selectEmisWriteoffApplyDetailListByApplyId(existingApply.getId());
if (!CollectionUtils.isEmpty(detailList)) {
// 按settleBillNo分组处理明细
Map<String, List<EmisWriteoffApplyDetail>> 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<EmisWriteoffApplyDetail> 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<EmisWriteoffApplyDetail> detailList = emisWriteoffApplyDetailMapper
.selectEmisWriteoffApplyDetailListByApplyId(existingApply.getId());
if (!CollectionUtils.isEmpty(detailList)) {
// 按settleBillNo分组处理明细
Map<String, List<EmisWriteoffApplyDetail>> 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());
}
}
}

View File

@ -321,6 +321,33 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where id = #{id}
</update>
<update id="auditCenterRevoke" parameterType="EmisWriteoffApply">
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>
<update id="auditHeadquartersRevoke" parameterType="EmisWriteoffApply">
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}
</update>
<!-- 根据运单号查询运单、结算账单、结算子账单信息的ResultMap -->
<resultMap type="EmisWriteoffApplyDetail" id="EmisWriteoffApplyDetailWithDetailsResult">
<id property="id" column="id"/>