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 new file mode 100644 index 000000000..b4b316212 --- /dev/null +++ b/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisWriteoffApplyController.java @@ -0,0 +1,374 @@ +/** + * @Project: emis + * @Title: EmisWriteoffApplyController.java + * @author heyu + * @date 2025-09-15 23:39:28 + * @Copyright: ShangHai Duta 2022 All rights reserved. + * @version v1.0 + * @Description:

销账申请控制器

+ */ + +package com.xdadan.erp.web.emis; + +import com.xdadan.erp.common.annotation.Log; +import com.xdadan.erp.common.core.domain.AjaxResult; +import com.xdadan.erp.common.core.page.TableDataInfo; +import com.xdadan.erp.common.enums.BusinessType; +import com.xdadan.erp.emis.domain.EmisWriteoffApply; +import com.xdadan.erp.emis.domain.EmisWriteoffApplyDetail; +import com.xdadan.erp.emis.domain.exception.EmisBizError; +import com.xdadan.erp.emis.service.IEmisWriteoffApplyService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PathVariable; + +import java.util.Arrays; +import java.util.List; + +/** + * 销账申请Controller + * + * @author 何宇 + * @date 2025-09-16 10:00:00 + */ +@RestController +@RequestMapping("/emis/writeoffApply") +@Slf4j +public class EmisWriteoffApplyController extends EmisBaseController { + @Autowired + private IEmisWriteoffApplyService emisWriteoffApplyService; + + /** + * 查询销账申请列表 + */ + // @PreAuthorize("@ss.hasPermi('emis:writeoffApply:list')") + @GetMapping("/list") + public TableDataInfo list(EmisWriteoffApply emisWriteoffApply) { + // 处理params参数,支持运单号、账单号多选查询 + if (emisWriteoffApply.getParams() != null && emisWriteoffApply.getParams().containsKey("queryParams")) { + String queryParams = (String) emisWriteoffApply.getParams().get("queryParams"); + if (queryParams != null && !queryParams.trim().isEmpty()) { + // 清理参数,去除空行和多余空格 + String[] lines = queryParams.split("\n"); + StringBuilder cleanParams = new StringBuilder(); + for (String line : lines) { + String trimmed = line.trim(); + if (!trimmed.isEmpty()) { + if (cleanParams.length() > 0) { + cleanParams.append("\n"); + } + cleanParams.append(trimmed); + } + } + emisWriteoffApply.getParams().put("queryParams", cleanParams.toString()); + } + } + + startPage(); + List list = emisWriteoffApplyService.selectEmisWriteoffApplyList(emisWriteoffApply); + return getDataTable(list); + } + + /** + * 导出销账申请列表 + */ + @PreAuthorize("@ss.hasPermi('emis:writeoffApply:export')") + @Log(title = "销账申请", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(EmisWriteoffApply emisWriteoffApply) { + // 处理params参数,支持运单号、账单号多选查询 + if (emisWriteoffApply.getParams() != null && emisWriteoffApply.getParams().containsKey("queryParams")) { + String queryParams = (String) emisWriteoffApply.getParams().get("queryParams"); + if (queryParams != null && !queryParams.trim().isEmpty()) { + // 清理参数,去除空行和多余空格 + String[] lines = queryParams.split("\n"); + StringBuilder cleanParams = new StringBuilder(); + for (String line : lines) { + String trimmed = line.trim(); + if (!trimmed.isEmpty()) { + if (cleanParams.length() > 0) { + cleanParams.append("\n"); + } + cleanParams.append(trimmed); + } + } + emisWriteoffApply.getParams().put("queryParams", cleanParams.toString()); + } + } + + List list = emisWriteoffApplyService.selectEmisWriteoffApplyList(emisWriteoffApply); + // ExcelUtil util = new + // ExcelUtil(EmisWriteoffApply.class); + // util.exportExcel(response, list, "销账申请数据"); + log.info("导出销账申请数据,共{}条记录", list.size()); + } + + /** + * 获取销账申请详细信息 + */ + // @PreAuthorize("@ss.hasPermi('emis:writeoffApply:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) { + return AjaxResult.success(emisWriteoffApplyService.selectEmisWriteoffApplyById(id)); + } + + /** + * 新增销账申请 + */ + // @PreAuthorize("@ss.hasPermi('emis:writeoffApply:add')") + @Log(title = "销账申请", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody EmisWriteoffApply emisWriteoffApply) { + try { + return toAjax(emisWriteoffApplyService.insertEmisWriteoffApply(emisWriteoffApply)); + } catch (Exception e) { + log.error("新增销账申请失败", e); + return error("新增销账申请失败:" + e.getMessage()); + } + } + + /** + * 修改销账申请 + */ + // @PreAuthorize("@ss.hasPermi('emis:writeoffApply:edit')") + @Log(title = "销账申请", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody EmisWriteoffApply emisWriteoffApply) throws EmisBizError { + return toAjax(emisWriteoffApplyService.updateEmisWriteoffApply(emisWriteoffApply)); + } + + /** + * 删除销账申请 + * 仅支持删除已撤销的数据,审核中以及审核完成的数据不支持删除 + */ + // @PreAuthorize("@ss.hasPermi('emis:writeoffApply:remove')") + @Log(title = "销账申请", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) { + try { + return toAjax(emisWriteoffApplyService.deleteEmisWriteoffApplyByIds(ids)); + } catch (Exception e) { + log.error("删除销账申请失败", e); + return error("删除销账申请失败:" + e.getMessage()); + } + } + + /** + * 财务中心审核通过 + */ + // @PreAuthorize("@ss.hasPermi('emis:writeoffApply:centerPass')") + @Log(title = "财务中心审核通过", businessType = BusinessType.UPDATE) + @PostMapping("/auditCenterPass/{ids}") + public AjaxResult auditCenterPass(@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.auditCenterPass(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:centerReject')") + @Log(title = "财务中心审核驳回", businessType = BusinessType.UPDATE) + @PostMapping("/auditCenterReject/{ids}") + public AjaxResult auditCenterReject(@PathVariable Long[] ids, @RequestBody EmisWriteoffApply emisWriteoffApply) { + if (ids != null && ids.length > 0) { + for (int i = 0; i < ids.length; i++) { + try { + long id = ids[i]; + EmisWriteoffApply apply = new EmisWriteoffApply(); + apply.setId(id); + apply.setCenterRejectReason(emisWriteoffApply.getCenterRejectReason()); + + emisWriteoffApplyService.auditCenterReject(apply); + + } 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:headquartersConfirm')") + @Log(title = "总部确认", businessType = BusinessType.UPDATE) + @PostMapping("/auditHeadquartersConfirm/{ids}") + public AjaxResult auditHeadquartersConfirm(@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.auditHeadquartersConfirm(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:headquartersReject')") + @Log(title = "总部驳回", businessType = BusinessType.UPDATE) + @PostMapping("/auditHeadquartersReject/{ids}") + public AjaxResult auditHeadquartersReject(@PathVariable Long[] ids, + @RequestBody EmisWriteoffApply emisWriteoffApply) { + if (ids != null && ids.length > 0) { + for (int i = 0; i < ids.length; i++) { + try { + long id = ids[i]; + EmisWriteoffApply apply = new EmisWriteoffApply(); + apply.setId(id); + apply.setHeadquartersRejectReason(emisWriteoffApply.getHeadquartersRejectReason()); + + emisWriteoffApplyService.auditHeadquartersReject(apply); + + } 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:revoke')") + @Log(title = "撤销申请", businessType = BusinessType.UPDATE) + @PostMapping("/revoke/{ids}") + public AjaxResult revoke(@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.revokeApply(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:reapply')") + @Log(title = "再次申请", businessType = BusinessType.UPDATE) + @PostMapping("/reapply") + public AjaxResult reapply(@RequestBody EmisWriteoffApply emisWriteoffApply) { + try { + return toAjax(emisWriteoffApplyService.reapply(emisWriteoffApply)); + } catch (Exception e) { + log.error("再次申请失败", e); + return error("再次申请失败:" + e.getMessage()); + } + } + + /** + * 根据运单号查询运单、结算账单、结算子账单信息(返回EmisWriteoffApplyDetail列表) + */ + // @PreAuthorize("@ss.hasPermi('emis:writeoffApply:queryByBillCodes')") + @GetMapping("/queryByBillCodes") + public AjaxResult queryByBillCodes(EmisWriteoffApply emisWriteoffApply) { + try { + // 处理params参数,支持运单号、账单号多选查询 + if (emisWriteoffApply.getParams() != null && emisWriteoffApply.getParams().containsKey("queryParams")) { + String queryParams = (String) emisWriteoffApply.getParams().get("queryParams"); + if (queryParams != null && !queryParams.trim().isEmpty()) { + // 清理参数,去除空行和多余空格 + String[] lines = queryParams.split("\n"); + StringBuilder cleanParams = new StringBuilder(); + for (String line : lines) { + String trimmed = line.trim(); + if (!trimmed.isEmpty()) { + if (cleanParams.length() > 0) { + cleanParams.append("\n"); + } + cleanParams.append(trimmed); + } + } + emisWriteoffApply.getParams().put("queryParams", cleanParams.toString()); + } + } + + // 检查是否有查询参数 + if (emisWriteoffApply.getParams() == null || + !emisWriteoffApply.getParams().containsKey("queryParams") || + emisWriteoffApply.getParams().get("queryParams") == null || + emisWriteoffApply.getParams().get("queryParams").toString().trim().isEmpty()) { + return error("运单号列表不能为空"); + } + + // 从queryParams中提取运单号列表 + String queryParams = (String) emisWriteoffApply.getParams().get("queryParams"); + String[] billCodes = queryParams.split("\n"); + List billCodeList = Arrays.asList(billCodes); + + List list = emisWriteoffApplyService + .selectEmisWriteoffApplyDetailListByBillCodes(billCodeList); + return AjaxResult.success(list); + } catch (Exception e) { + log.error("根据运单号查询运单、结算账单、结算子账单信息失败", e); + return error("查询失败:" + e.getMessage()); + } + } +} diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisWriteoffApply.java b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisWriteoffApply.java new file mode 100644 index 000000000..2e824fc65 --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisWriteoffApply.java @@ -0,0 +1,167 @@ +/** + * @Project: emis + * @Title: EmisWriteoffApply.java + * @author heyu + * @date 2025-09-15 23:39:28 + * @Copyright: ShangHai Duta 2022 All rights reserved. + * @version v1.0 + * @Description:

销账申请表 实体类

+ */ + +package com.xdadan.erp.emis.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.xdadan.erp.common.annotation.Excel; +import com.xdadan.erp.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +/** + * @ClassName EmisWriteoffApply + * @Description 销账申请表 + * @author 何宇 + * @date 2025-09-16 10:00:00 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class EmisWriteoffApply extends BaseEntity { + private static final long serialVersionUID = 1L; + + /* id */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /* 申请编号 */ + @Excel(name = "申请编号") + private String applyNo; + + /* 申请人编码 */ + @Excel(name = "申请人编码") + private String applyManCode; + + /* 申请人姓名 */ + @Excel(name = "申请人") + private String applyManName; + + /* 申请站点代码 */ + @Excel(name = "申请站点代码") + private String applySiteCode; + + /* 申请站点名称 */ + @Excel(name = "申请站点") + private String applySiteName; + + /* 申请时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @Excel(name = "申请时间", dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date applyDate; + + /* 销账金额 */ + @Excel(name = "销账金额") + private BigDecimal writeoffAmount; + + /* 收款来源 1-微信支付2支付宝 3-对公 */ + private String payType; + + /* 交易时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date tradeDate; + + /* 收款人 */ + private String recipient; + + /* 申请说明 */ + @Excel(name = "申请说明") + private String applyMemo; + + /* 中心审核状态 0-未审核 1-审核通过 2-审核拒绝 3-已撤销*/ + @Excel(name = "中心审核状态") + private String blCenterConfirmed; + + /* 中心审核人编码 */ + @Excel(name = "中心审核人编码") + private String centerConfirmManCode; + + /* 中心审核人姓名 */ + @Excel(name = "中心审核人") + private String centerConfirmManName; + + /* 中心审核时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @Excel(name = "中心审核时间", dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date centerConfirmDate; + + /* 中心审核备注 */ + @Excel(name = "中心审核备注") + private String centerConfirmNote; + + /* 中心驳回原因 */ + @Excel(name = "中心驳回原因") + private String centerRejectReason; + + /* 总部审核状态 0-未审核 1-确认 2-驳回 */ + @Excel(name = "总部审核状态") + private String blHeadquartersConfirmed; + + /* 总部审核人编码 */ + @Excel(name = "总部审核人编码") + private String headquartersConfirmManCode; + + /* 总部审核人姓名 */ + @Excel(name = "总部审核人") + private String headquartersConfirmManName; + + /* 总部审核时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @Excel(name = "总部审核时间", dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date headquartersConfirmDate; + + /* 总部审核备注 */ + @Excel(name = "总部审核备注") + private String headquartersConfirmNote; + + /* 总部驳回原因 */ + @Excel(name = "总部驳回原因") + private String headquartersRejectReason; + + /* 撤销时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @Excel(name = "撤销时间", dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date revokeDate; + + /* 撤销人编码 */ + @Excel(name = "撤销人编码") + private String revokeManCode; + + /* 撤销人姓名 */ + @Excel(name = "撤销人") + private String revokeManName; + + /* 撤销原因 */ + @Excel(name = "撤销原因") + private String revokeReason; + + // 关联明细列表 + private List detailList; + + // 关联图片列表 + private List imageList; + + // 查询条件字段(只查询不入库) + @TableField(exist = false) + private String payee; // 回款联系人 + + @TableField(exist = false) + private String salesmen; // 销售联系人 + + @TableField(exist = false) + private String settleBillName; // 账单名称 + +} diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisWriteoffApplyDetail.java b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisWriteoffApplyDetail.java new file mode 100644 index 000000000..c8a4cc63e --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisWriteoffApplyDetail.java @@ -0,0 +1,70 @@ +/** + * @Project: emis + * @Title: EmisWriteoffApplyDetail.java + * @author heyu + * @date 2025-09-15 23:39:28 + * @Copyright: ShangHai Duta 2022 All rights reserved. + * @version v1.0 + * @Description:

销账申请明细表 实体类

+ */ + +package com.xdadan.erp.emis.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.xdadan.erp.common.annotation.Excel; +import com.xdadan.erp.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; + +/** + * @ClassName EmisWriteoffApplyDetail + * @Description 销账申请明细表 + * @author 何宇 + * @date 2025-19-16 10:00:00 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class EmisWriteoffApplyDetail extends BaseEntity { + private static final long serialVersionUID = 1L; + + /* id */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /* 申请ID */ + @Excel(name = "申请ID") + private Long applyId; + + /* 申请编号 */ + @Excel(name = "申请编号") + private String applyNo; + + /* 运单号 */ + @Excel(name = "运单号") + private String billCode; + + /* 申请金额 */ + @Excel(name = "申请金额") + private BigDecimal applyMoney; + + /* 账单号 */ + @Excel(name = "账单号") + private String settleBillNo; + + // 关联运单信息(只作查询) + @TableField(exist = false) + private EmisWaybill emisWaybill = new EmisWaybill(); + + // 关联结算账单信息(只作查询) + @TableField(exist = false) + private EmisSettleBill emisSettleBill = new EmisSettleBill(); + + // 关联结算子账单信息(只作查询) + @TableField(exist = false) + private EmisSettleSubBill emisSettleSubBill = new EmisSettleSubBill(); + +} diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisWriteoffApplyImage.java b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisWriteoffApplyImage.java new file mode 100644 index 000000000..26ea83656 --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisWriteoffApplyImage.java @@ -0,0 +1,74 @@ +/** + * @Project: emis + * @Title: EmisWriteoffApplyImage.java + * @author heyu + * @date 2025-09-15 23:39:28 + * @Copyright: ShangHai Duta 2022 All rights reserved. + * @version v1.0 + * @Description:

销账申请图片表 实体类

+ */ + +package com.xdadan.erp.emis.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.xdadan.erp.common.annotation.Excel; +import com.xdadan.erp.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * @ClassName EmisWriteoffApplyImage + * @Description 销账申请图片表 + * @author heyu + * @date 2025-09-16 10:00:00 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class EmisWriteoffApplyImage extends BaseEntity { + private static final long serialVersionUID = 1L; + + /* id */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /* 申请ID */ + @Excel(name = "申请ID") + private Long applyId; + + /* 申请编号 */ + @Excel(name = "申请编号") + private String applyNo; + + /* 图片名称 */ + @Excel(name = "图片名称") + private String imageName; + + /* 图片路径 */ + @Excel(name = "图片路径") + private String imagePath; + + /* 图片大小 */ + @Excel(name = "图片大小") + private Long imageSize; + + /* 图片类型 */ + @Excel(name = "图片类型") + private String imageType; + + /* 上传时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @Excel(name = "上传时间", dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date uploadDate; + + /* 上传人编码 */ + @Excel(name = "上传人编码") + private String uploadManCode; + + /* 上传人姓名 */ + @Excel(name = "上传人") + private String uploadManName; +} diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/domain/enumtype/WriteoffApplyStatus.java b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/enumtype/WriteoffApplyStatus.java new file mode 100644 index 000000000..6e3142752 --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/enumtype/WriteoffApplyStatus.java @@ -0,0 +1,32 @@ +package com.xdadan.erp.emis.domain.enumtype; + +/** + * @Project: emis + * @Title: WriteoffApplyStatus.java + * @author heyu + * @date 2025-09-15 23:39:28 + * @Copyright: ShangHai Duta 2022 All rights reserved. + * @version v1.0 + * @Description: + *

+ * 销账申请状态枚举 + *

+ */ +public enum WriteoffApplyStatus { + + CENTER_PENDING("0", "中心未审核"), + CENTER_APPROVED("1", "中心已审核"), + CENTER_REJECTED("2", "中心驳回"), + REVOKED("3", "已撤销"), + HEADQUARTERS_PENDING("0", "总部未审核"), + HEADQUARTERS_CONFIRMED("1", "总部确认"), + HEADQUARTERS_REJECTED("2", "总部驳回"); + + public String statusCode; + public String statusName; + + WriteoffApplyStatus(String statusCode, String statusName) { + this.statusCode = statusCode; + this.statusName = statusName; + } +} diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/domain/enumtype/WriteoffApplyType.java b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/enumtype/WriteoffApplyType.java new file mode 100644 index 000000000..2dba5382a --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/enumtype/WriteoffApplyType.java @@ -0,0 +1,20 @@ +package com.xdadan.erp.emis.domain.enumtype; + +/** + * 销账申请类型枚举 + */ +public enum WriteoffApplyType { + + WAYBILL("1", "运单号"), + BILL("2", "账单号"); + + public String typeCode; + public String typeName; + + WriteoffApplyType(String typeCode, String typeName) { + this.typeCode = typeCode; + this.typeName = typeName; + } +} + + diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/domain/exception/EmisBizError.java b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/exception/EmisBizError.java index 2fe422981..52719d780 100644 --- a/emis-biz/src/main/java/com/xdadan/erp/emis/domain/exception/EmisBizError.java +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/exception/EmisBizError.java @@ -11,6 +11,11 @@ public class EmisBizError extends Exception { this.errorCode = errorType.getErrorCode(); } + public EmisBizError(String errorMessage) { + super(errorMessage); + this.errorCode = "BIZ_ERROR"; + } + public String getErrorCode() { return errorCode; } diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/mapper/EmisWriteoffApplyDetailMapper.java b/emis-biz/src/main/java/com/xdadan/erp/emis/mapper/EmisWriteoffApplyDetailMapper.java new file mode 100644 index 000000000..53f90239d --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/mapper/EmisWriteoffApplyDetailMapper.java @@ -0,0 +1,107 @@ +/** + * @Project: emis + * @Title: EmisWriteoffApplyDetailMapper.java + * @author heyu + * @date 2025-09-15 23:39:28 + * @Copyright: ShangHai Doitinfo 2022 All rights reserved. + * @version v1.0 + * @Description:

销账申请明细表 Mapper 接口

+ * Warning : This file is generate by ai tools,don't edit!!! + */ +package com.xdadan.erp.emis.mapper; + +import java.util.List; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.xdadan.erp.emis.domain.EmisWriteoffApplyDetail; + +/** + * @ClassName EmisWriteoffApplyDetailMapper + * @Description + *

+ * 销账申请明细表 Mapper 接口 + *

+ * @author 何宇 + * @date 2025-09-16 10:00:00 + */ +public interface EmisWriteoffApplyDetailMapper extends BaseMapper { + /** + * 主键查询 + * + * @param id + * @return + */ + public EmisWriteoffApplyDetail selectEmisWriteoffApplyDetailById(Long id); + + /** + * 查询列表 + * + * @param emisWriteoffApplyDetail + * @return 集合 + */ + public List selectEmisWriteoffApplyDetailList( + EmisWriteoffApplyDetail emisWriteoffApplyDetail); + + /** + * 根据申请ID查询明细列表 + * + * @param applyId 申请ID + * @return 集合 + */ + public List selectEmisWriteoffApplyDetailListByApplyId(Long applyId); + + /** + * 根据申请ID查询明细列表(只包含emisWaybill、emisSettleBill、emisSettleSubBill) + * + * @param applyId 申请ID + * @return 集合 + */ + public List selectEmisWriteoffApplyDetailListByApplyIdWithDetails(Long applyId); + + /** + * 新增 + * + * @param emisWriteoffApplyDetail + * @return + */ + public int insertEmisWriteoffApplyDetail(EmisWriteoffApplyDetail emisWriteoffApplyDetail); + + /** + * 批量新增 + * + * @param emisWriteoffApplyDetailList + * @return + */ + public int insertEmisWriteoffApplyDetailBatch(List emisWriteoffApplyDetailList); + + /** + * 修改 + * + * @param emisWriteoffApplyDetail + * @return + */ + public int updateEmisWriteoffApplyDetail(EmisWriteoffApplyDetail emisWriteoffApplyDetail); + + /** + * 删除 + * + * @param id 主键 + * @return 结果 + */ + public int deleteEmisWriteoffApplyDetailById(Long id); + + /** + * 根据申请ID删除明细 + * + * @param applyId 申请ID + * @return 结果 + */ + public int deleteEmisWriteoffApplyDetailByApplyId(Long applyId); + + /** + * 批量删除 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteEmisWriteoffApplyDetailByIds(Long[] ids); +} diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/mapper/EmisWriteoffApplyImageMapper.java b/emis-biz/src/main/java/com/xdadan/erp/emis/mapper/EmisWriteoffApplyImageMapper.java new file mode 100644 index 000000000..52ac34c99 --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/mapper/EmisWriteoffApplyImageMapper.java @@ -0,0 +1,98 @@ +/** + * @Project: emis + * @Title: EmisWriteoffApplyImageMapper.java + * @author heyu + * @date 2025-09-15 23:39:28 + * @Copyright: ShangHai Doitinfo 2022 All rights reserved. + * @version v1.0 + * @Description:

销账申请图片表 Mapper 接口

+ * Warning : This file is generate by ai tools,don't edit!!! + */ +package com.xdadan.erp.emis.mapper; + +import java.util.List; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.xdadan.erp.emis.domain.EmisWriteoffApplyImage; + +/** + * @ClassName EmisWriteoffApplyImageMapper + * @Description + *

+ * 销账申请图片表 Mapper 接口 + *

+ * @author 何宇 + * @date 2025-09-16 10:00:00 + */ +public interface EmisWriteoffApplyImageMapper extends BaseMapper { + /** + * 主键查询 + * + * @param id + * @return + */ + public EmisWriteoffApplyImage selectEmisWriteoffApplyImageById(Long id); + + /** + * 查询列表 + * + * @param emisWriteoffApplyImage + * @return 集合 + */ + public List selectEmisWriteoffApplyImageList(EmisWriteoffApplyImage emisWriteoffApplyImage); + + /** + * 根据申请ID查询图片列表 + * + * @param applyId 申请ID + * @return 集合 + */ + public List selectEmisWriteoffApplyImageListByApplyId(Long applyId); + + /** + * 新增 + * + * @param emisWriteoffApplyImage + * @return + */ + public int insertEmisWriteoffApplyImage(EmisWriteoffApplyImage emisWriteoffApplyImage); + + /** + * 批量新增 + * + * @param emisWriteoffApplyImageList + * @return + */ + public int insertEmisWriteoffApplyImageBatch(List emisWriteoffApplyImageList); + + /** + * 修改 + * + * @param emisWriteoffApplyImage + * @return + */ + public int updateEmisWriteoffApplyImage(EmisWriteoffApplyImage emisWriteoffApplyImage); + + /** + * 删除 + * + * @param id 主键 + * @return 结果 + */ + public int deleteEmisWriteoffApplyImageById(Long id); + + /** + * 根据申请ID删除图片 + * + * @param applyId 申请ID + * @return 结果 + */ + public int deleteEmisWriteoffApplyImageByApplyId(Long applyId); + + /** + * 批量删除 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteEmisWriteoffApplyImageByIds(Long[] ids); +} 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 new file mode 100644 index 000000000..41501aedd --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/mapper/EmisWriteoffApplyMapper.java @@ -0,0 +1,131 @@ +/** + * @Project: emis + * @Title: EmisWriteoffApplyMapper.java + * @author heyu + * @date 2025-09-15 23:39:28 + * @Copyright: ShangHai Doitinfo 2022 All rights reserved. + * @version v1.0 + * @Description:

销账申请表 Mapper 接口

+ * Warning : This file is generate by ai tools,don't edit!!! + */ +package com.xdadan.erp.emis.mapper; + +import java.util.List; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.xdadan.erp.emis.domain.EmisWriteoffApply; +import com.xdadan.erp.emis.domain.EmisWriteoffApplyDetail; + +/** + * @ClassName EmisWriteoffApplyMapper + * @Description + *

+ * 销账申请表 Mapper 接口 + *

+ * @author 何宇 + * @date 2025-09-16 10:00:00 + */ +public interface EmisWriteoffApplyMapper extends BaseMapper { + /** + * 主键查询 + * + * @param id + * @return + */ + public EmisWriteoffApply selectEmisWriteoffApplyById(Long id); + + /** + * 查询列表 + * + * @param emisWriteoffApply + * @return 集合 + */ + public List selectEmisWriteoffApplyList(EmisWriteoffApply emisWriteoffApply); + + /** + * 新增 + * + * @param emisWriteoffApply + * @return + */ + public int insertEmisWriteoffApply(EmisWriteoffApply emisWriteoffApply); + + /** + * 修改 + * + * @param emisWriteoffApply + * @return + */ + public int updateEmisWriteoffApply(EmisWriteoffApply emisWriteoffApply); + + /** + * 删除 + * + * @param id 主键 + * @return 结果 + */ + public int deleteEmisWriteoffApplyById(Long id); + + /** + * 批量删除 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteEmisWriteoffApplyByIds(Long[] ids); + + /** + * 财务中心审核通过 + * + * @param emisWriteoffApply + * @return 结果 + */ + public int auditCenterPass(EmisWriteoffApply emisWriteoffApply); + + /** + * 根据运单号查询运单、结算账单、结算子账单信息(返回EmisWriteoffApplyDetail列表) + * + * @param billCodes 运单号列表 + * @return 销账申请明细集合 + */ + public List selectEmisWriteoffApplyDetailListByBillCodes(List billCodes); + + /** + * 财务中心审核驳回 + * + * @param emisWriteoffApply + * @return 结果 + */ + public int auditCenterReject(EmisWriteoffApply emisWriteoffApply); + + /** + * 总部确认 + * + * @param emisWriteoffApply + * @return 结果 + */ + public int auditHeadquartersConfirm(EmisWriteoffApply emisWriteoffApply); + + /** + * 总部驳回 + * + * @param emisWriteoffApply + * @return 结果 + */ + public int auditHeadquartersReject(EmisWriteoffApply emisWriteoffApply); + + /** + * 撤销申请 + * + * @param emisWriteoffApply + * @return 结果 + */ + public int revokeApply(EmisWriteoffApply emisWriteoffApply); + + /** + * 再次申请 + * + * @param emisWriteoffApply + * @return 结果 + */ + public int reapply(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 new file mode 100644 index 000000000..cf9db2796 --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/IEmisWriteoffApplyService.java @@ -0,0 +1,130 @@ +/** + * @Project: emis + * @Title: IEmisWriteoffApplyService.java + * @author heyu + * @date 2025-09-15 23:39:28 + * @Copyright: ShangHai Duta 2022 All rights reserved. + * @version v1.0 + * @Description:

销账申请表 服务类接口

+ */ +package com.xdadan.erp.emis.service; + +import java.util.List; +import com.xdadan.erp.emis.domain.EmisWriteoffApply; +import com.xdadan.erp.emis.domain.EmisWriteoffApplyDetail; +import com.xdadan.erp.emis.domain.exception.EmisBizError; + +/** + * @ClassName IEmisWriteoffApplyService + * @Description 销账申请表 + * @author 何宇 + * @date 2025-09-16 10:00:00 + */ +public interface IEmisWriteoffApplyService { + /** + * 主键查询 + * + * @param id + * @return + */ + public EmisWriteoffApply selectEmisWriteoffApplyById(Long id); + + /** + * 查询销账申请列表 + * + * @param emisWriteoffApply 销账申请 + * @return 销账申请集合 + */ + public List selectEmisWriteoffApplyList(EmisWriteoffApply emisWriteoffApply); + + /** + * 新增销账申请 + * + * @param emisWriteoffApply 销账申请 + * @return 结果 + */ + public int insertEmisWriteoffApply(EmisWriteoffApply emisWriteoffApply) throws EmisBizError; + + /** + * 修改销账申请 + * + * @param emisWriteoffApply 销账申请 + * @return 结果 + */ + public int updateEmisWriteoffApply(EmisWriteoffApply emisWriteoffApply) throws EmisBizError; + + /** + * 批量删除销账申请 + * 仅支持删除已撤销的数据,审核中以及审核完成的数据不支持删除 + * + * @param ids 需要删除的销账申请主键集合 + * @return 结果 + */ + public int deleteEmisWriteoffApplyByIds(Long[] ids) throws EmisBizError; + + /** + * 删除销账申请信息 + * 仅支持删除已撤销的数据,审核中以及审核完成的数据不支持删除 + * + * @param id 销账申请主键 + * @return 结果 + */ + public int deleteEmisWriteoffApplyById(Long id) throws EmisBizError; + + /** + * 财务中心审核通过(支持单个和批量) + * + * @param emisWriteoffApply 销账申请(单个操作时传入完整对象,批量操作时传入包含ids的对象) + * @return 结果 + */ + public int auditCenterPass(EmisWriteoffApply emisWriteoffApply) throws EmisBizError; + + /** + * 财务中心审核驳回(支持单个和批量) + * + * @param emisWriteoffApply 销账申请(单个操作时传入完整对象,批量操作时传入包含ids的对象) + * @return 结果 + */ + public int auditCenterReject(EmisWriteoffApply emisWriteoffApply) throws EmisBizError; + + /** + * 总部确认(支持单个和批量) + * + * @param emisWriteoffApply 销账申请(单个操作时传入完整对象,批量操作时传入包含ids的对象) + * @return 结果 + */ + public int auditHeadquartersConfirm(EmisWriteoffApply emisWriteoffApply) throws EmisBizError; + + /** + * 总部驳回(支持单个和批量) + * + * @param emisWriteoffApply 销账申请(单个操作时传入完整对象,批量操作时传入包含ids的对象) + * @return 结果 + */ + public int auditHeadquartersReject(EmisWriteoffApply emisWriteoffApply) throws EmisBizError; + + /** + * 撤销申请(支持单个和批量) + * + * @param emisWriteoffApply 销账申请(单个操作时传入完整对象,批量操作时传入包含ids的对象) + * @return 结果 + */ + public int revokeApply(EmisWriteoffApply emisWriteoffApply) throws EmisBizError; + + /** + * 再次申请 + * + * @param emisWriteoffApply 销账申请 + * @return 结果 + */ + public int reapply(EmisWriteoffApply emisWriteoffApply) throws EmisBizError; + + /** + * 根据运单号查询运单、结算账单、结算子账单信息(返回EmisWriteoffApplyDetail列表) + * + * @param billCodes 运单号列表 + * @return 销账申请明细集合 + */ + public List selectEmisWriteoffApplyDetailListByBillCodes(List billCodes); + +} 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 new file mode 100644 index 000000000..e9165894c --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisWriteoffApplyServiceImpl.java @@ -0,0 +1,1110 @@ +/** + * @Project: emis + * @Title: EmisWriteoffApplyServiceImpl.java + * @author heyu + * @date 2025-09-15 23:39:28 + * @Copyright: ShangHai Duta 2022 All rights reserved. + * @version v1.0 + * @Description:

销账申请表 实体类

+ */ + +package com.xdadan.erp.emis.service.impl; + +import java.math.BigDecimal; +import java.util.*; +import java.util.HashSet; +import java.util.Set; + +import com.xdadan.erp.common.core.domain.entity.SysUser; +import com.xdadan.erp.common.utils.SecurityUtils; +import com.xdadan.erp.emis.domain.*; +import com.xdadan.erp.emis.domain.enumtype.WriteoffApplyStatus; +import com.xdadan.erp.emis.domain.exception.EmisBizError; +import com.xdadan.erp.emis.mapper.*; +import com.xdadan.erp.emis.service.*; +import jodd.util.StringUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * 销账申请Service业务层处理 + * + * @author 何宇 + * @date 2025-09-16 10:00:00 + */ +@Service +@Slf4j +public class EmisWriteoffApplyServiceImpl implements IEmisWriteoffApplyService { + @Autowired + private EmisWriteoffApplyMapper emisWriteoffApplyMapper; + + @Autowired + private EmisWriteoffApplyDetailMapper emisWriteoffApplyDetailMapper; + + @Autowired + private EmisWriteoffApplyImageMapper emisWriteoffApplyImageMapper; + + @Autowired + private EmisWaybillMapper emisWaybillMapper; + + @Autowired + private EmisSettleSubBillMapper emisSettleSubBillMapper; + + @Autowired + private EmisSettleBillMapper emisSettleBillMapper; + + // 以下Mapper用于关联业务数据处理,暂时注释避免编译警告 + // @Autowired + // private EmisSettlePayRecordMapper emisSettlePayRecordMapper; + + @Autowired + private IEmisCreditCustomerService emisCreditCustomerService; + + @Autowired + private IEmisCreditSalesmenService emisCreditSalesmenService; + + /** + * 查询销账申请 + * + * @param id 销账申请主键 + * @return 销账申请 + */ + @Override + public EmisWriteoffApply selectEmisWriteoffApplyById(Long id) { + EmisWriteoffApply apply = emisWriteoffApplyMapper.selectEmisWriteoffApplyById(id); + if (apply != null) { + // 查询明细列表 + List detailList = emisWriteoffApplyDetailMapper + .selectEmisWriteoffApplyDetailListByApplyId(id); + apply.setDetailList(detailList); + + // 查询图片列表 + List imageList = emisWriteoffApplyImageMapper + .selectEmisWriteoffApplyImageListByApplyId(id); + apply.setImageList(imageList); + } + return apply; + } + + /** + * 查询销账申请列表 + * + * @param emisWriteoffApply 销账申请 + * @return 销账申请 + */ + @Override + public List selectEmisWriteoffApplyList(EmisWriteoffApply emisWriteoffApply) { + return emisWriteoffApplyMapper.selectEmisWriteoffApplyList(emisWriteoffApply); + } + + /** + * 验证销账金额 + * 销账金额 = 各个运单的applyMoney的和 + * 验证:申请金额+已收金额 <= 运单应收金额 + */ + private void validateWriteoffAmount(EmisWriteoffApply emisWriteoffApply) throws EmisBizError { + if (CollectionUtils.isEmpty(emisWriteoffApply.getDetailList())) { + throw new EmisBizError("销账申请明细不能为空"); + } + + BigDecimal totalApplyAmount = BigDecimal.ZERO; + + for (EmisWriteoffApplyDetail detail : emisWriteoffApply.getDetailList()) { + if (detail.getApplyMoney() == null) { + throw new EmisBizError("运单号 " + detail.getBillCode() + " 的申请金额不能为空"); + } + totalApplyAmount = totalApplyAmount.add(detail.getApplyMoney()); + + // 查询运单信息 + EmisWaybill waybill = emisWaybillMapper.selectEmisWaybillByBillCode(detail.getBillCode()); + if (waybill == null) { + throw new EmisBizError("运单号 " + detail.getBillCode() + " 不存在"); + } + + // 查询已收金额 + BigDecimal receivedAmount = detail.getEmisSettleSubBill().getRecedMoney(); + if (receivedAmount == null) { + receivedAmount = BigDecimal.ZERO; + } + + // 验证:申请金额 + 已收金额 <= 运单应收金额 + BigDecimal totalAmount = detail.getApplyMoney().add(receivedAmount); + if (totalAmount.compareTo(waybill.getFreight()) > 0) { + throw new EmisBizError("运单号 " + detail.getBillCode() + " 的申请金额(" + + detail.getApplyMoney() + ") + 已收金额(" + receivedAmount + ") = " + + totalAmount + " 超过运单应收金额(" + waybill.getFreight() + ")"); + } + } + + // 验证总销账金额 + if (emisWriteoffApply.getWriteoffAmount() == null || + emisWriteoffApply.getWriteoffAmount().compareTo(totalApplyAmount) != 0) { + throw new EmisBizError("销账金额(" + emisWriteoffApply.getWriteoffAmount() + + ") 必须等于各运单申请金额之和(" + totalApplyAmount + ")"); + } + } + + /** + * 新增销账申请 + * + * @param emisWriteoffApply 销账申请 + * @return 结果 + */ + @Override + @Transactional + public int insertEmisWriteoffApply(EmisWriteoffApply emisWriteoffApply) throws EmisBizError { + try { + // 先验证销账金额 + validateWriteoffAmount(emisWriteoffApply); + + // 设置申请编号 + String applyNo = generateApplyNo(); + emisWriteoffApply.setApplyNo(applyNo); + + // 设置申请人信息 + SysUser currentUser = SecurityUtils.getLoginUser().getUser(); + emisWriteoffApply.setApplyManCode(currentUser.getEmpCode()); + emisWriteoffApply.setApplyManName(currentUser.getEmpName()); + emisWriteoffApply.setApplyDate(new Date()); + + // 设置初始状态 + emisWriteoffApply.setBlCenterConfirmed(WriteoffApplyStatus.CENTER_PENDING.statusCode); + emisWriteoffApply.setBlHeadquartersConfirmed(WriteoffApplyStatus.CENTER_PENDING.statusCode); + + // 插入主表 + int result = emisWriteoffApplyMapper.insertEmisWriteoffApply(emisWriteoffApply); + + // 插入明细表 + if (CollectionUtils.isNotEmpty(emisWriteoffApply.getDetailList())) { + for (EmisWriteoffApplyDetail detail : emisWriteoffApply.getDetailList()) { + detail.setApplyId(emisWriteoffApply.getId()); + detail.setApplyNo(applyNo); + if (StringUtil.isBlank(detail.getEmisSettleSubBill().getSettleBillNo())) { + throw new EmisBizError("账单不存在"); + } + emisWriteoffApplyDetailMapper.insertEmisWriteoffApplyDetail(detail); + } + } + + // 插入图片表 + if (CollectionUtils.isNotEmpty(emisWriteoffApply.getImageList())) { + for (EmisWriteoffApplyImage image : emisWriteoffApply.getImageList()) { + image.setApplyId(emisWriteoffApply.getId()); + image.setApplyNo(applyNo); + image.setUploadManCode(currentUser.getEmpCode()); + image.setUploadManName(currentUser.getEmpName()); + image.setUploadDate(new Date()); + emisWriteoffApplyImageMapper.insertEmisWriteoffApplyImage(image); + } + } + + return result; + } catch (Exception e) { + log.error("新增销账申请失败", e); + throw new EmisBizError("新增销账申请失败:" + e.getMessage()); + } + } + + /** + * 修改销账申请 + * + * @param emisWriteoffApply 销账申请 + * @return 结果 + */ + @Override + @Transactional + public int updateEmisWriteoffApply(EmisWriteoffApply emisWriteoffApply) throws EmisBizError { + + // 先验证销账金额 + validateWriteoffAmount(emisWriteoffApply); + + // 更新主表 + int result = emisWriteoffApplyMapper.updateEmisWriteoffApply(emisWriteoffApply); + + // 更新明细表 + if (CollectionUtils.isNotEmpty(emisWriteoffApply.getDetailList())) { + // 先删除原有明细 + emisWriteoffApplyDetailMapper.deleteEmisWriteoffApplyDetailByApplyId(emisWriteoffApply.getId()); + // 重新插入明细 + for (EmisWriteoffApplyDetail detail : emisWriteoffApply.getDetailList()) { + detail.setApplyId(emisWriteoffApply.getId()); + detail.setApplyNo(emisWriteoffApply.getApplyNo()); + emisWriteoffApplyDetailMapper.insertEmisWriteoffApplyDetail(detail); + } + } + + // 更新图片表 + if (CollectionUtils.isNotEmpty(emisWriteoffApply.getImageList())) { + // 先删除原有图片 + emisWriteoffApplyImageMapper.deleteEmisWriteoffApplyImageByApplyId(emisWriteoffApply.getId()); + // 重新插入图片 + SysUser currentUser = SecurityUtils.getLoginUser().getUser(); + for (EmisWriteoffApplyImage image : emisWriteoffApply.getImageList()) { + image.setApplyId(emisWriteoffApply.getId()); + image.setApplyNo(emisWriteoffApply.getApplyNo()); + image.setUploadManCode(currentUser.getEmpCode()); + image.setUploadManName(currentUser.getEmpName()); + image.setUploadDate(new Date()); + emisWriteoffApplyImageMapper.insertEmisWriteoffApplyImage(image); + } + } + + return result; + } + + /** + * 批量删除销账申请 + * 仅支持删除已撤销的数据,审核中以及审核完成的数据不支持删除 + * + * @param ids 需要删除的销账申请主键集合 + * @return 结果 + */ + @Override + @Transactional + public int deleteEmisWriteoffApplyByIds(Long[] ids) throws EmisBizError { + // 检查每个申请的状态,只允许删除已撤销的数据 + for (Long id : ids) { + EmisWriteoffApply apply = emisWriteoffApplyMapper.selectEmisWriteoffApplyById(id); + if (apply == null) { + throw new EmisBizError("申请不存在,ID: " + id); + } + + // 检查中心审核状态,只有已撤销(3)状态才能删除 + if (!WriteoffApplyStatus.REVOKED.statusCode.equals(apply.getBlCenterConfirmed())) { + String statusName = getStatusName(apply.getBlCenterConfirmed()); + throw new EmisBizError("申请ID " + id + " 状态为" + statusName + ",仅支持删除已撤销的数据"); + } + } + + // 执行删除操作 + for (Long id : ids) { + // 删除明细 + emisWriteoffApplyDetailMapper.deleteEmisWriteoffApplyDetailByApplyId(id); + // 删除图片 + emisWriteoffApplyImageMapper.deleteEmisWriteoffApplyImageByApplyId(id); + } + return emisWriteoffApplyMapper.deleteEmisWriteoffApplyByIds(ids); + } + + /** + * 删除销账申请信息 + * 仅支持删除已撤销的数据,审核中以及审核完成的数据不支持删除 + * + * @param id 销账申请主键 + * @return 结果 + */ + @Override + @Transactional + public int deleteEmisWriteoffApplyById(Long id) throws EmisBizError { + // 检查申请状态,只允许删除已撤销的数据 + EmisWriteoffApply apply = emisWriteoffApplyMapper.selectEmisWriteoffApplyById(id); + if (apply == null) { + throw new EmisBizError("申请不存在,ID: " + id); + } + + // 检查中心审核状态,只有已撤销(3)状态才能删除 + if (!WriteoffApplyStatus.REVOKED.statusCode.equals(apply.getBlCenterConfirmed())) { + String statusName = getStatusName(apply.getBlCenterConfirmed()); + throw new EmisBizError("申请ID " + id + " 状态为" + statusName + ",仅支持删除已撤销的数据"); + } + + // 删除明细 + emisWriteoffApplyDetailMapper.deleteEmisWriteoffApplyDetailByApplyId(id); + // 删除图片 + emisWriteoffApplyImageMapper.deleteEmisWriteoffApplyImageByApplyId(id); + return emisWriteoffApplyMapper.deleteEmisWriteoffApplyById(id); + } + + /** + * 财务中心审核通过 + * + * @param emisWriteoffApply 销账申请 + * @return 结果 + */ + @Override + @Transactional + public int auditCenterPass(EmisWriteoffApply emisWriteoffApply) throws EmisBizError { + try { + // 检查申请状态 + EmisWriteoffApply existingApply = emisWriteoffApplyMapper + .selectEmisWriteoffApplyById(emisWriteoffApply.getId()); + if (existingApply == null) { + throw new EmisBizError("申请不存在"); + } + if (!WriteoffApplyStatus.CENTER_PENDING.statusCode.equals(existingApply.getBlCenterConfirmed())) { + throw new EmisBizError("已审核/已撤销"); + } + + // 设置审核信息 + SysUser currentUser = SecurityUtils.getLoginUser().getUser(); + emisWriteoffApply.setBlCenterConfirmed(WriteoffApplyStatus.CENTER_APPROVED.statusCode); + emisWriteoffApply.setCenterConfirmManCode(currentUser.getEmpCode()); + emisWriteoffApply.setCenterConfirmManName(currentUser.getEmpName()); + emisWriteoffApply.setCenterConfirmDate(new Date()); + + // 更新申请状态 + int result = emisWriteoffApplyMapper.auditCenterPass(emisWriteoffApply); + + // 更新相关业务数据 + List detailList = updateRelatedBusinessData(existingApply, true); + + // 重算并更新月结客户额度和现金客户额度 + updateCreditLimits(existingApply, detailList); + + return result; + } catch (Exception e) { + log.error("财务中心审核通过失败", e); + throw new EmisBizError("财务中心审核通过失败:" + e.getMessage()); + } + } + + /** + * 财务中心审核驳回 + * + * @param emisWriteoffApply 销账申请 + * @return 结果 + */ + @Override + @Transactional + public int auditCenterReject(EmisWriteoffApply emisWriteoffApply) throws EmisBizError { + try { + // 检查申请状态 + EmisWriteoffApply existingApply = emisWriteoffApplyMapper + .selectEmisWriteoffApplyById(emisWriteoffApply.getId()); + if (existingApply == null) { + throw new EmisBizError("申请不存在"); + } + if (!WriteoffApplyStatus.CENTER_PENDING.statusCode.equals(existingApply.getBlCenterConfirmed())) { + throw new EmisBizError("已审核/已撤销"); + } + + // 设置审核信息 + SysUser currentUser = SecurityUtils.getLoginUser().getUser(); + emisWriteoffApply.setBlCenterConfirmed(WriteoffApplyStatus.CENTER_REJECTED.statusCode); + emisWriteoffApply.setCenterConfirmManCode(currentUser.getEmpCode()); + emisWriteoffApply.setCenterConfirmManName(currentUser.getEmpName()); + emisWriteoffApply.setCenterConfirmDate(new Date()); + + // 更新申请状态 + int result = emisWriteoffApplyMapper.auditCenterReject(emisWriteoffApply); + + return result; + } catch (Exception e) { + log.error("财务中心审核驳回失败", e); + throw new EmisBizError("财务中心审核驳回失败:" + e.getMessage()); + } + } + + /** + * 总部确认 + * + * @param emisWriteoffApply 销账申请 + * @return 结果 + */ + @Override + @Transactional + public int auditHeadquartersConfirm(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("财务未审核,无法确认"); + } + if (WriteoffApplyStatus.HEADQUARTERS_CONFIRMED.statusCode + .equals(existingApply.getBlHeadquartersConfirmed())) { + throw new EmisBizError("已确认"); + } + if (WriteoffApplyStatus.HEADQUARTERS_REJECTED.statusCode + .equals(existingApply.getBlHeadquartersConfirmed())) { + throw new EmisBizError("已驳回,无法确认"); + } + + // 设置确认信息 + SysUser currentUser = SecurityUtils.getLoginUser().getUser(); + emisWriteoffApply.setBlHeadquartersConfirmed(WriteoffApplyStatus.HEADQUARTERS_CONFIRMED.statusCode); + emisWriteoffApply.setHeadquartersConfirmManCode(currentUser.getEmpCode()); + emisWriteoffApply.setHeadquartersConfirmManName(currentUser.getEmpName()); + emisWriteoffApply.setHeadquartersConfirmDate(new Date()); + + // 更新申请状态 + int result = emisWriteoffApplyMapper.auditHeadquartersConfirm(emisWriteoffApply); + + return result; + } catch (Exception e) { + log.error("总部确认失败", e); + throw new EmisBizError("总部确认失败:" + e.getMessage()); + } + } + + /** + * 总部驳回 + * + * @param emisWriteoffApply 销账申请 + * @return 结果 + */ + @Override + @Transactional + public int auditHeadquartersReject(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("财务未审核,无法确认"); + } + if (WriteoffApplyStatus.HEADQUARTERS_CONFIRMED.statusCode + .equals(existingApply.getBlHeadquartersConfirmed())) { + throw new EmisBizError("已确认,无法驳回"); + } + if (WriteoffApplyStatus.HEADQUARTERS_REJECTED.statusCode + .equals(existingApply.getBlHeadquartersConfirmed())) { + throw new EmisBizError("已驳回"); + } + + // 设置驳回信息 + SysUser currentUser = SecurityUtils.getLoginUser().getUser(); + emisWriteoffApply.setBlHeadquartersConfirmed(WriteoffApplyStatus.HEADQUARTERS_REJECTED.statusCode); + emisWriteoffApply.setHeadquartersConfirmManCode(currentUser.getEmpCode()); + emisWriteoffApply.setHeadquartersConfirmManName(currentUser.getEmpName()); + emisWriteoffApply.setHeadquartersConfirmDate(new Date()); + + // 更新申请状态 + int result = emisWriteoffApplyMapper.auditHeadquartersReject(emisWriteoffApply); + + // 回退相关业务数据 + List detailList = rollbackRelatedBusinessData(existingApply); + + // 重算并更新月结客户额度和现金客户额度 + updateCreditLimits(existingApply, detailList); + + return result; + } catch (Exception e) { + log.error("总部驳回失败", e); + throw new EmisBizError("总部驳回失败:" + e.getMessage()); + } + } + + /** + * 撤销申请 + * + * @param emisWriteoffApply 销账申请 + * @return 结果 + */ + @Override + @Transactional + public int revokeApply(EmisWriteoffApply emisWriteoffApply) throws EmisBizError { + try { + // 检查申请状态 + EmisWriteoffApply existingApply = emisWriteoffApplyMapper + .selectEmisWriteoffApplyById(emisWriteoffApply.getId()); + if (existingApply == null) { + throw new EmisBizError("申请不存在"); + } + if (!WriteoffApplyStatus.CENTER_PENDING.statusCode + .equals(existingApply.getBlCenterConfirmed()) + || !WriteoffApplyStatus.HEADQUARTERS_PENDING.statusCode + .equals(existingApply.getBlHeadquartersConfirmed())) { + throw new EmisBizError("已审核/撤销完成,无法撤销"); + } + + // 设置撤销信息 + SysUser currentUser = SecurityUtils.getLoginUser().getUser(); + emisWriteoffApply.setBlCenterConfirmed(WriteoffApplyStatus.REVOKED.statusCode); + emisWriteoffApply.setRevokeManCode(currentUser.getEmpCode()); + emisWriteoffApply.setRevokeManName(currentUser.getEmpName()); + emisWriteoffApply.setRevokeDate(new Date()); + + // 更新申请状态 + int result = emisWriteoffApplyMapper.revokeApply(emisWriteoffApply); + + return result; + } catch (Exception e) { + log.error("撤销申请失败", e); + throw new EmisBizError("撤销申请失败:" + e.getMessage()); + } + } + + /** + * 再次申请 + * + * @param emisWriteoffApply 销账申请 + * @return 结果 + */ + @Override + @Transactional + public int reapply(EmisWriteoffApply emisWriteoffApply) throws EmisBizError { + try { + // 检查申请状态 + EmisWriteoffApply existingApply = emisWriteoffApplyMapper + .selectEmisWriteoffApplyById(emisWriteoffApply.getId()); + if (existingApply == null) { + throw new EmisBizError("申请不存在"); + } + if (!WriteoffApplyStatus.REVOKED.statusCode.equals(existingApply.getBlCenterConfirmed()) && + !WriteoffApplyStatus.CENTER_REJECTED.statusCode.equals(existingApply.getBlCenterConfirmed())) { + throw new EmisBizError("申请状态不正确,无法再次申请"); + } + + // 重置状态 + emisWriteoffApply.setBlCenterConfirmed(WriteoffApplyStatus.CENTER_PENDING.statusCode); + emisWriteoffApply.setBlHeadquartersConfirmed(WriteoffApplyStatus.CENTER_PENDING.statusCode); + emisWriteoffApply.setCenterConfirmManCode(null); + emisWriteoffApply.setCenterConfirmManName(null); + emisWriteoffApply.setCenterConfirmDate(null); + emisWriteoffApply.setCenterConfirmNote(null); + emisWriteoffApply.setCenterRejectReason(null); + emisWriteoffApply.setHeadquartersConfirmManCode(null); + emisWriteoffApply.setHeadquartersConfirmManName(null); + emisWriteoffApply.setHeadquartersConfirmDate(null); + emisWriteoffApply.setHeadquartersConfirmNote(null); + emisWriteoffApply.setHeadquartersRejectReason(null); + emisWriteoffApply.setRevokeManCode(null); + emisWriteoffApply.setRevokeManName(null); + emisWriteoffApply.setRevokeDate(null); + emisWriteoffApply.setRevokeReason(null); + + // 更新申请 + int result = emisWriteoffApplyMapper.reapply(emisWriteoffApply); + + return result; + } catch (Exception e) { + log.error("再次申请失败", e); + throw new EmisBizError("再次申请失败:" + e.getMessage()); + } + } + + /** + * 生成申请编号 + */ + private String generateApplyNo() { + return "XZ" + System.currentTimeMillis(); + } + + /** + * 更新相关业务数据 + * + * @return 申请明细列表 + */ + private List updateRelatedBusinessData(EmisWriteoffApply apply, boolean isPass) + throws EmisBizError { + try { + log.info("开始更新相关业务数据,申请ID: {}, 是否通过: {}", apply.getId(), isPass); + + // 获取申请明细 + List detailList = emisWriteoffApplyDetailMapper + .selectEmisWriteoffApplyDetailListByApplyId(apply.getId()); + if (CollectionUtils.isEmpty(detailList)) { + log.warn("申请明细为空,申请ID: {}", apply.getId()); + return detailList; + } + + // 按settleBillNo分组处理明细 + Map> groupedDetails = detailList.stream() + .filter(detail -> StringUtil.isNotBlank(detail.getSettleBillNo())) + .collect(java.util.stream.Collectors.groupingBy(EmisWriteoffApplyDetail::getSettleBillNo)); + + // 处理每个结算账单的销账 + for (Map.Entry> entry : groupedDetails.entrySet()) { + String settleBillNo = entry.getKey(); + List billDetails = entry.getValue(); + + // 计算该结算账单的总申请金额 + BigDecimal totalApplyMoney = billDetails.stream() + .map(EmisWriteoffApplyDetail::getApplyMoney) + .filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + // 更新结算账单的收款状态和已收金额 + updateSettleBillPaymentStatus(settleBillNo, totalApplyMoney, isPass); + + // 处理每个明细(只支持运单号类型) + for (EmisWriteoffApplyDetail detail : billDetails) { + processWaybillWriteoff(detail, apply, isPass); + } + } + + log.info("相关业务数据更新完成,申请ID: {}", apply.getId()); + return detailList; + } catch (Exception e) { + log.error("更新相关业务数据失败,申请ID: {}", apply.getId(), e); + throw new EmisBizError("更新相关业务数据失败:" + e.getMessage()); + } + } + + /** + * 处理运单销账(唯一支持的销账类型) + */ + private void processWaybillWriteoff(EmisWriteoffApplyDetail detail, EmisWriteoffApply apply, boolean isPass) + throws EmisBizError { + String billCode = detail.getBillCode(); + if (billCode == null || billCode.trim().isEmpty()) { + return; + } + + // 获取运单信息 + EmisWaybill waybill = emisWaybillMapper.selectEmisWaybillByBillCode(billCode); + if (waybill == null) { + throw new EmisBizError("运单不存在:" + billCode); + } + + // 验证申请金额 + BigDecimal waybillAmount = waybill.getFreight(); // 运单应收金额 + BigDecimal applyAmount = detail.getApplyMoney(); // 申请销账金额(从明细获取) + BigDecimal receivedAmount = detail.getEmisSettleSubBill().getRecedMoney() != null + ? detail.getEmisSettleSubBill().getRecedMoney() + : BigDecimal.ZERO; // 已收金额 + + // 验证:申请金额 + 已收金额 <= 运单金额 + BigDecimal totalAmount = applyAmount.add(receivedAmount); + if (totalAmount.compareTo(waybillAmount) > 0) { + throw new EmisBizError("申请金额+已收金额(" + totalAmount + ")超过运单应收金额(" + waybillAmount + ")"); + } + + // 获取运单对应的子账单 + List subBillList = emisSettleSubBillMapper.selectSettleSubBillListByBillCode(billCode); + if (CollectionUtils.isEmpty(subBillList)) { + log.warn("运单{}没有对应的子账单", billCode); + return; + } + + // 更新子账单 + for (EmisSettleSubBill subBill : subBillList) { + updateSubBillForWriteoff(subBill, detail, isPass); + } + + } + + /** + * 更新子账单销账信息 + */ + private void updateSubBillForWriteoff(EmisSettleSubBill subBill, EmisWriteoffApplyDetail detail, boolean isPass) { + EmisSettleSubBill updateSubBill = new EmisSettleSubBill(); + updateSubBill.setId(subBill.getId()); + updateSubBill.setBillCode(subBill.getBillCode()); + + // 获取申请金额(从明细中获取) + BigDecimal applyMoney = detail.getApplyMoney(); + + if (isPass) { + // 审核通过:增加已收金额 + BigDecimal currentReceived = subBill.getRecedMoney() != null ? subBill.getRecedMoney() : BigDecimal.ZERO; + BigDecimal newReceived = currentReceived.add(applyMoney); + updateSubBill.setRecedMoney(newReceived); + + // 更新收款状态 + if (newReceived.compareTo(subBill.getBillFee()) >= 0) { + updateSubBill.setPaymentStatus("1"); // 已收款 + } else { + updateSubBill.setPaymentStatus("2"); // 部分收款 + } + } else { + // 审核驳回:减少已收金额 + BigDecimal currentReceived = subBill.getRecedMoney() != null ? subBill.getRecedMoney() : BigDecimal.ZERO; + BigDecimal newReceived = currentReceived.subtract(applyMoney); + if (newReceived.compareTo(BigDecimal.ZERO) < 0) { + newReceived = BigDecimal.ZERO; + } + updateSubBill.setRecedMoney(newReceived); + + // 更新收款状态 + if (newReceived.compareTo(BigDecimal.ZERO) == 0) { + updateSubBill.setPaymentStatus("0"); // 未收款 + } else if (newReceived.compareTo(subBill.getBillFee()) >= 0) { + updateSubBill.setPaymentStatus("1"); // 已收款 + } else { + updateSubBill.setPaymentStatus("2"); // 部分收款 + } + } + + emisSettleSubBillMapper.updatePayedStatus(updateSubBill); + log.info("更新子账单销账信息,运单号: {}, 已收金额: {}", subBill.getBillCode(), updateSubBill.getRecedMoney()); + } + + /** + * 更新结算账单的收款状态和已收金额 + */ + private void updateSettleBillPaymentStatus(String settleBillNo, BigDecimal applyMoney, boolean isPass) + throws EmisBizError { + try { + log.info("更新结算账单收款状态,账单号: {}, 申请金额: {}, 是否通过: {}", settleBillNo, applyMoney, isPass); + + // 获取结算账单信息 + EmisSettleBill settleBill = emisSettleBillMapper.selectSettleBillBySettleBillNo(settleBillNo); + if (settleBill == null) { + log.warn("结算账单不存在,账单号: {}", settleBillNo); + return; + } + + if (isPass) { + // 通过销账申请,增加已收金额 + BigDecimal currentRecedMoney = settleBill.getRecedMoney() != null ? settleBill.getRecedMoney() + : BigDecimal.ZERO; + BigDecimal newRecedMoney = currentRecedMoney.add(applyMoney); + + // 更新结算账单 + EmisSettleBill updateBill = new EmisSettleBill(); + updateBill.setId(settleBill.getId()); + updateBill.setRecedMoney(newRecedMoney); + + // 根据已收金额和应收金额比较,设置收款状态 + BigDecimal recMoney = settleBill.getRecMoney() != null ? settleBill.getRecMoney() : BigDecimal.ZERO; + if (newRecedMoney.compareTo(BigDecimal.ZERO) == 0) { + 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()); + } else { + // 拒绝销账申请,减少已收金额 + BigDecimal currentRecedMoney = settleBill.getRecedMoney() != null ? settleBill.getRecedMoney() + : BigDecimal.ZERO; + BigDecimal newRecedMoney = currentRecedMoney.subtract(applyMoney); + if (newRecedMoney.compareTo(BigDecimal.ZERO) < 0) { + newRecedMoney = BigDecimal.ZERO; + } + + // 更新结算账单 + EmisSettleBill updateBill = new EmisSettleBill(); + updateBill.setId(settleBill.getId()); + updateBill.setRecedMoney(newRecedMoney); + + // 根据已收金额和应收金额比较,设置收款状态 + 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); + log.info("结算账单收款状态回退成功,账单号: {}, 新已收金额: {}, 收款状态: {}, 核销状态: {}", + settleBillNo, newRecedMoney, updateBill.getPaymentStatus(), updateBill.getChargeStatus()); + } + } catch (Exception e) { + log.error("更新结算账单收款状态失败,账单号: {}", settleBillNo, e); + throw new EmisBizError("更新结算账单收款状态失败:" + e.getMessage()); + } + } + + /** + * 回退相关业务数据 + * + * @return 申请明细列表 + */ + private List rollbackRelatedBusinessData(EmisWriteoffApply apply) throws EmisBizError { + try { + log.info("开始回退相关业务数据,申请ID: {}", apply.getId()); + + // 获取申请明细 + List detailList = emisWriteoffApplyDetailMapper + .selectEmisWriteoffApplyDetailListByApplyId(apply.getId()); + if (CollectionUtils.isEmpty(detailList)) { + log.warn("申请明细为空,申请ID: {}", apply.getId()); + return detailList; + } + + // 按settleBillNo分组处理明细 + Map> groupedDetails = detailList.stream() + .filter(detail -> StringUtil.isNotBlank(detail.getSettleBillNo())) + .collect(java.util.stream.Collectors.groupingBy(EmisWriteoffApplyDetail::getSettleBillNo)); + + // 处理每个结算账单的销账回退 + for (Map.Entry> entry : groupedDetails.entrySet()) { + String settleBillNo = entry.getKey(); + List billDetails = entry.getValue(); + + // 计算该结算账单的总申请金额 + BigDecimal totalApplyMoney = billDetails.stream() + .map(EmisWriteoffApplyDetail::getApplyMoney) + .filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + // 回退结算账单的收款状态和已收金额 + rollbackSettleBillPaymentStatus(settleBillNo, totalApplyMoney); + + // 处理每个明细的回退(只支持运单号类型) + for (EmisWriteoffApplyDetail detail : billDetails) { + rollbackWaybillWriteoff(detail, apply); + } + } + + log.info("相关业务数据回退完成,申请ID: {}", apply.getId()); + return detailList; + } catch (Exception e) { + log.error("回退相关业务数据失败,申请ID: {}", apply.getId(), e); + throw new EmisBizError("回退相关业务数据失败:" + e.getMessage()); + } + } + + /** + * 回退结算账单的收款状态和已收金额 + */ + private void rollbackSettleBillPaymentStatus(String settleBillNo, BigDecimal applyMoney) throws EmisBizError { + try { + log.info("回退结算账单收款状态,账单号: {}, 申请金额: {}", settleBillNo, applyMoney); + + // 获取结算账单信息 + EmisSettleBill settleBill = emisSettleBillMapper.selectSettleBillBySettleBillNo(settleBillNo); + if (settleBill == null) { + log.warn("结算账单不存在,账单号: {}", settleBillNo); + return; + } + + // 回退销账申请,减少已收金额 + BigDecimal currentRecedMoney = settleBill.getRecedMoney() != null ? settleBill.getRecedMoney() + : BigDecimal.ZERO; + BigDecimal newRecedMoney = currentRecedMoney.subtract(applyMoney); + if (newRecedMoney.compareTo(BigDecimal.ZERO) < 0) { + newRecedMoney = BigDecimal.ZERO; + } + + // 更新结算账单 + EmisSettleBill updateBill = new EmisSettleBill(); + updateBill.setId(settleBill.getId()); + updateBill.setRecedMoney(newRecedMoney); + + // 根据已收金额和应收金额比较,设置收款状态 + 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); + log.info("结算账单收款状态回退成功,账单号: {}, 新已收金额: {}, 收款状态: {}, 核销状态: {}", + settleBillNo, newRecedMoney, updateBill.getPaymentStatus(), updateBill.getChargeStatus()); + } catch (Exception e) { + log.error("回退结算账单收款状态失败,账单号: {}", settleBillNo, e); + throw new EmisBizError("回退结算账单收款状态失败:" + e.getMessage()); + } + } + + /** + * 回退运单销账 + */ + private void rollbackWaybillWriteoff(EmisWriteoffApplyDetail detail, EmisWriteoffApply apply) throws EmisBizError { + String billCode = detail.getBillCode(); + if (billCode == null || billCode.trim().isEmpty()) { + return; + } + + // 获取运单信息 + EmisWaybill waybill = emisWaybillMapper.selectEmisWaybillByBillCode(billCode); + if (waybill == null) { + log.warn("运单不存在,运单号: {}", billCode); + return; + } + + // 获取运单对应的子账单 + List subBillList = emisSettleSubBillMapper.selectSettleSubBillListByBillCode(billCode); + if (CollectionUtils.isEmpty(subBillList)) { + log.warn("运单{}没有对应的子账单", billCode); + return; + } + + // 回退子账单 + for (EmisSettleSubBill subBill : subBillList) { + rollbackSubBillForWriteoff(subBill, detail); + } + } + + /** + * 回退子账单销账信息 + */ + private void rollbackSubBillForWriteoff(EmisSettleSubBill subBill, EmisWriteoffApplyDetail detail) { + EmisSettleSubBill updateSubBill = new EmisSettleSubBill(); + updateSubBill.setId(subBill.getId()); + updateSubBill.setBillCode(subBill.getBillCode()); + + // 获取申请金额(从明细中获取) + BigDecimal applyMoney = detail.getApplyMoney(); + + // 回退销账申请:减少已收金额 + BigDecimal currentReceived = subBill.getRecedMoney() != null ? subBill.getRecedMoney() : BigDecimal.ZERO; + BigDecimal newReceived = currentReceived.subtract(applyMoney); + if (newReceived.compareTo(BigDecimal.ZERO) < 0) { + newReceived = BigDecimal.ZERO; + } + updateSubBill.setRecedMoney(newReceived); + + // 更新收款状态 + if (newReceived.compareTo(BigDecimal.ZERO) == 0) { + updateSubBill.setPaymentStatus("0"); // 未收款 + } else if (newReceived.compareTo(subBill.getBillFee()) >= 0) { + updateSubBill.setPaymentStatus("1"); // 已收款 + } else { + updateSubBill.setPaymentStatus("2"); // 部分收款 + } + + emisSettleSubBillMapper.updatePayedStatus(updateSubBill); + log.info("回退子账单销账信息,运单号: {}, 已收金额: {}", subBill.getBillCode(), updateSubBill.getRecedMoney()); + } + + /** + * 根据运单号查询销账申请列表(只返回detailList中的emisWaybill、emisSettleBill、emisSettleSubBill) + * + * @param billCodes 运单号列表 + * @return 销账申请集合 + */ + @Override + public List selectEmisWriteoffApplyDetailListByBillCodes(List billCodes) { + if (CollectionUtils.isEmpty(billCodes)) { + return new ArrayList<>(); + } + return emisWriteoffApplyMapper.selectEmisWriteoffApplyDetailListByBillCodes(billCodes); + } + + /** + * 获取状态名称 + * + * @param statusCode 状态代码 + * @return 状态名称 + */ + private String getStatusName(String statusCode) { + if (statusCode == null) { + return "未知状态"; + } + + for (WriteoffApplyStatus status : WriteoffApplyStatus.values()) { + if (status.statusCode.equals(statusCode)) { + return status.statusName; + } + } + + return "未知状态(" + statusCode + ")"; + } + + /** + * 重算并更新月结客户额度和现金客户额度 + * + * @param apply 销账申请 + * @param detailList 申请明细列表 + */ + private void updateCreditLimits(EmisWriteoffApply apply, List detailList) { + try { + log.info("开始重算并更新信用额度,申请ID: {}", apply.getId()); + + if (CollectionUtils.isEmpty(detailList)) { + log.warn("申请明细为空,申请ID: {}", apply.getId()); + return; + } + + // 收集需要更新额度的客户和销售员信息 + Set customerCodes = new HashSet<>(); + Set salesmenCodes = new HashSet<>(); + + // 遍历明细,获取运单信息 + for (EmisWriteoffApplyDetail detail : detailList) { + if (StringUtil.isNotBlank(detail.getBillCode())) { + // 查询运单信息 + EmisWaybill waybill = emisWaybillMapper.selectEmisWaybillByBillCode(detail.getBillCode()); + if (waybill != null) { + // 收集客户代码 + if (StringUtil.isNotBlank(waybill.getCustomerCode())) { + customerCodes.add(waybill.getCustomerCode()); + } + // 收集销售员代码 + if (StringUtil.isNotBlank(waybill.getSalesmen())) { + salesmenCodes.add(waybill.getSalesmen()); + } + } + } + } + + // 更新客户信用额度 + for (String customerCode : customerCodes) { + try { + updateCustomerCreditLimit(customerCode); + } catch (Exception e) { + log.error("更新客户信用额度失败,客户代码: {}", customerCode, e); + } + } + + // 更新销售员信用额度 + for (String salesmenCode : salesmenCodes) { + try { + updateSalesmenCreditLimit(salesmenCode); + } catch (Exception e) { + log.error("更新销售员信用额度失败,销售员代码: {}", salesmenCode, e); + } + } + + log.info("信用额度重算完成,申请ID: {}", apply.getId()); + } catch (Exception e) { + log.error("重算信用额度失败,申请ID: {}", apply.getId(), e); + } + } + + /** + * 更新客户信用额度 + * + * @param customerCode 客户代码 + */ + private void updateCustomerCreditLimit(String customerCode) throws EmisBizError { + try { + // 查询客户信用额度信息 + EmisCreditCustomer query = new EmisCreditCustomer(); + query.setCustomerCode(customerCode); + List creditList = emisCreditCustomerService.selectEmisCreditCustomerList(query); + + for (EmisCreditCustomer credit : creditList) { + // 调用更新方法,这会触发额度重算 + emisCreditCustomerService.updateEmisCreditCustomer(credit); + log.info("客户信用额度更新成功,客户代码: {}", customerCode); + } + } catch (Exception e) { + log.error("更新客户信用额度失败,客户代码: {}", customerCode, e); + throw e; + } + } + + /** + * 更新销售员信用额度 + * + * @param salesmenCode 销售员代码 + */ + private void updateSalesmenCreditLimit(String salesmenCode) throws EmisBizError { + try { + // 查询销售员信用额度信息 + EmisCreditSalesmen query = new EmisCreditSalesmen(); + query.setAccCode(salesmenCode); + List creditList = emisCreditSalesmenService.selectEmisCreditSalesmenList(query); + + for (EmisCreditSalesmen credit : creditList) { + // 调用更新方法,这会触发额度重算 + emisCreditSalesmenService.updateEmisCreditSalesmen(credit); + log.info("销售员信用额度更新成功,销售员代码: {}", salesmenCode); + } + } catch (Exception e) { + log.error("更新销售员信用额度失败,销售员代码: {}", salesmenCode, e); + throw e; + } + } +} diff --git a/emis-biz/src/main/resources/mapper/EmisWriteoffApplyDetailMapper.xml b/emis-biz/src/main/resources/mapper/EmisWriteoffApplyDetailMapper.xml new file mode 100644 index 000000000..562ac31db --- /dev/null +++ b/emis-biz/src/main/resources/mapper/EmisWriteoffApplyDetailMapper.xml @@ -0,0 +1,325 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select wad.id, wad.apply_id, wad.apply_no, wad.bill_code, wad.apply_money, wad.settle_bill_no, + w.id as w_id, w.order_sn as w_order_sn, w.cust_order_id as w_cust_order_id, w.bill_code as w_bill_code, w.bill_code_sub as w_bill_code_sub, + w.order_status as w_order_status, w.waybill_status as w_waybill_status, w.order_type as w_order_type, w.order_date as w_order_date, + w.user_id as w_user_id, w.customer_code as w_customer_code, w.customer_name as w_customer_name, w.open_id as w_open_id, + w.receive_name as w_receive_name, w.receive_company as w_receive_company, w.receive_mobile as w_receive_mobile, w.receive_tel as w_receive_tel, + w.receive_country as w_receive_country, w.receive_province as w_receive_province, w.receive_city as w_receive_city, + w.receive_county as w_receive_county, w.receive_town as w_receive_town, w.receive_address as w_receive_address, w.receive_postcode as w_receive_postcode, + w.send_name as w_send_name, w.send_company as w_send_company, w.send_mobile as w_send_mobile, w.send_tel as w_send_tel, + w.send_country as w_send_country, w.send_province as w_send_province, w.send_city as w_send_city, + w.send_county as w_send_county, w.send_town as w_send_town, w.send_address as w_send_address, w.send_postcode as w_send_postcode, + w.freight as w_freight, w.salesmen as w_salesmen, w.payee as w_payee, w.payment_type as w_payment_type, w.product_type as w_product_type, + w.parcel_qty as w_parcel_qty, w.bill_weight as w_bill_weight, w.total_volume as w_total_volume, w.send_date as w_send_date, + w.dispatch_date as w_dispatch_date, w.sign_man as w_sign_man, w.sign_man_code as w_sign_man_code, + w.sign_site_code as w_sign_site_code, w.sign_date as w_sign_date, w.timezone_offset as w_timezone_offset, w.payment_status as w_payment_status, + w.payment_date as w_payment_date, w.payment_remark as w_payment_remark, w.order_remark as w_order_remark, w.data_from as w_data_from, + w.bl_special_goods as w_bl_special_goods, w.ext_info as w_ext_info, w.lading_bill_code as w_lading_bill_code, w.company_code as w_company_code, + w.departure_port as w_departure_port, w.destination_port as w_destination_port, w.box_quantity as w_box_quantity, + sb.id as sb_id, sb.settle_bill_no as sb_settle_bill_no, sb.settle_bill_name as sb_settle_bill_name, sb.settle_type as sb_settle_type, + sb.settle_start_date as sb_settle_start_date, sb.settle_end_date as sb_settle_end_date, sb.bill_month as sb_bill_month, + sb.rec_money as sb_rec_money, sb.reced_money as sb_reced_money, sb.invoiced_money as sb_invoiced_money, sb.cust_no as sb_cust_no, + sb.cust_name as sb_cust_name, sb.customer_code as sb_customer_code, sb.customer_name as sb_customer_name, sb.site_code as sb_site_code, + sb.site_name as sb_site_name, sb.satisfy_money as sb_satisfy_money, sb.allowance_money as sb_allowance_money, sb.deduction_money as sb_deduction_money, + sb.other_money as sb_other_money, sb.satisfy_reason as sb_satisfy_reason, sb.allowance_reason as sb_allowance_reason, + sb.deduction_reason as sb_deduction_reason, sb.other_reason as sb_other_reason, sb.open_bill_status as sb_open_bill_status, + sb.payment_status as sb_payment_status, sb.charge_status as sb_charge_status, sb.send_piece_sum as sb_send_piece_sum, + sb.piece_number as sb_piece_number, sb.fee_weight as sb_fee_weight, sb.uncollected_amount as sb_uncollected_amount, + sb.send_money_sum as sb_send_money_sum, sb.refund_amount as sb_refund_amount, sb.refund_money as sb_refund_money, + sb.payee as sb_payee, sb.salesmen as sb_salesmen, sb.credit_period as sb_credit_period, sb.credit_period_type as sb_credit_period_type, + sb.settle_day as sb_settle_day, sb.payment_due_date as sb_payment_due_date, sb.bl_send_oms as sb_bl_send_oms, + sb.bl_confirm_center as sb_bl_confirm_center, sb.confirm_center_date as sb_confirm_center_date, sb.confirm_center_note as sb_confirm_center_note, + sb.confirm_center_man_code as sb_confirm_center_man_code, sb.confirm_center_code as sb_confirm_center_code, + sb.bl_confirm_site as sb_bl_confirm_site, sb.confirm_site_date as sb_confirm_site_date, sb.confirm_site_man_code as sb_confirm_site_man_code, + sb.confirm_site_note as sb_confirm_site_note, sb.confirm_site_code as sb_confirm_site_code, + ssb.id as ssb_id, ssb.bill_no as ssb_bill_no, ssb.parent_bill_no as ssb_parent_bill_no, ssb.settle_bill_no as ssb_settle_bill_no, + ssb.bill_code as ssb_bill_code, ssb.bill_date as ssb_bill_date, ssb.bill_fee as ssb_bill_fee, ssb.currency as ssb_currency, + ssb.settle_type as ssb_settle_type, ssb.bl_split as ssb_bl_split, ssb.bl_merge as ssb_bl_merge, ssb.bill_month as ssb_bill_month, + ssb.cust_no as ssb_cust_no, ssb.cust_name as ssb_cust_name, ssb.customer_code as ssb_customer_code, ssb.customer_name as ssb_customer_name, + ssb.invoiced_money as ssb_invoiced_money, ssb.reced_money as ssb_reced_money, ssb.satisfy_money as ssb_satisfy_money, + ssb.allowance_money as ssb_allowance_money, ssb.deduction_money as ssb_deduction_money, ssb.other_money as ssb_other_money, + ssb.satisfy_reason as ssb_satisfy_reason, ssb.allowance_reason as ssb_allowance_reason, ssb.deduction_reason as ssb_deduction_reason, + ssb.other_reason as ssb_other_reason, ssb.open_bill_status as ssb_open_bill_status, ssb.payment_status as ssb_payment_status, + ssb.charge_status as ssb_charge_status, ssb.payee as ssb_payee, ssb.salesmen as ssb_salesmen, ssb.bl_special_quote as ssb_bl_special_quote, + ssb.bl_sensitive as ssb_bl_sensitive, ssb.bl_confirm_center as ssb_bl_confirm_center, ssb.confirm_center_date as ssb_confirm_center_date, + ssb.confirm_center_note as ssb_confirm_center_note, ssb.confirm_center_man_code as ssb_confirm_center_man_code, + ssb.confirm_center_code as ssb_confirm_center_code, ssb.bl_confirm_site as ssb_bl_confirm_site, ssb.confirm_site_date as ssb_confirm_site_date, + ssb.confirm_site_man_code as ssb_confirm_site_man_code, ssb.confirm_site_note as ssb_confirm_site_note, ssb.confirm_site_code as ssb_confirm_site_code + from emis_writeoff_apply_detail wad + left join emis_waybill w on wad.bill_code = w.bill_code + left join emis_settle_bill sb on wad.settle_bill_no = sb.settle_bill_no + left join emis_settle_sub_bill ssb on wad.bill_code = ssb.bill_code + + + + + + + + + + insert into emis_writeoff_apply_detail + + apply_id, + apply_no, + bill_code, + apply_money, + settle_bill_no, + + + #{applyId}, + #{applyNo}, + #{billCode}, + #{applyMoney}, + #{settleBillNo}, + + + + + insert into emis_writeoff_apply_detail (apply_id, apply_no, bill_code, apply_money, settle_bill_no) + values + + (#{item.applyId}, #{item.applyNo}, #{item.billCode}, #{item.applyMoney}, #{item.settleBillNo}) + + + + + update emis_writeoff_apply_detail + + apply_id = #{applyId}, + apply_no = #{applyNo}, + bill_code = #{billCode}, + apply_money = #{applyMoney}, + settle_bill_no = #{settleBillNo}, + + where id = #{id} + + + + delete from emis_writeoff_apply_detail where id = #{id} + + + + delete from emis_writeoff_apply_detail where apply_id = #{applyId} + + + + delete from emis_writeoff_apply_detail where id in + + #{id} + + + + + + + diff --git a/emis-biz/src/main/resources/mapper/EmisWriteoffApplyImageMapper.xml b/emis-biz/src/main/resources/mapper/EmisWriteoffApplyImageMapper.xml new file mode 100644 index 000000000..452234f6a --- /dev/null +++ b/emis-biz/src/main/resources/mapper/EmisWriteoffApplyImageMapper.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + select id, apply_id, apply_no, image_name, image_path, image_size, image_type, upload_date, upload_man_code, upload_man_name, create_by, create_time, update_by, update_time, remark from emis_writeoff_apply_image + + + + + + + + + + insert into emis_writeoff_apply_image + + apply_id, + apply_no, + image_name, + image_path, + image_size, + image_type, + upload_date, + upload_man_code, + upload_man_name, + create_by, + create_time, + update_by, + update_time, + remark, + + + #{applyId}, + #{applyNo}, + #{imageName}, + #{imagePath}, + #{imageSize}, + #{imageType}, + #{uploadDate}, + #{uploadManCode}, + #{uploadManName}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{remark}, + + + + + insert into emis_writeoff_apply_image (apply_id, apply_no, image_name, image_path, image_size, image_type, upload_date, upload_man_code, upload_man_name, create_by, create_time, update_by, update_time, remark) + values + + (#{item.applyId}, #{item.applyNo}, #{item.imageName}, #{item.imagePath}, #{item.imageSize}, #{item.imageType}, #{item.uploadDate}, #{item.uploadManCode}, #{item.uploadManName}, #{item.createBy}, #{item.createTime}, #{item.updateBy}, #{item.updateTime}, #{item.remark}) + + + + + update emis_writeoff_apply_image + + apply_id = #{applyId}, + apply_no = #{applyNo}, + image_name = #{imageName}, + image_path = #{imagePath}, + image_size = #{imageSize}, + image_type = #{imageType}, + upload_date = #{uploadDate}, + upload_man_code = #{uploadManCode}, + upload_man_name = #{uploadManName}, + update_by = #{updateBy}, + update_time = #{updateTime}, + remark = #{remark}, + + where id = #{id} + + + + delete from emis_writeoff_apply_image where id = #{id} + + + + delete from emis_writeoff_apply_image where apply_id = #{applyId} + + + + delete from emis_writeoff_apply_image where id in + + #{id} + + + + + diff --git a/emis-biz/src/main/resources/mapper/EmisWriteoffApplyMapper.xml b/emis-biz/src/main/resources/mapper/EmisWriteoffApplyMapper.xml new file mode 100644 index 000000000..19de1efbb --- /dev/null +++ b/emis-biz/src/main/resources/mapper/EmisWriteoffApplyMapper.xml @@ -0,0 +1,517 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, apply_no, apply_man_code, apply_man_name, apply_site_code, apply_site_name, apply_date, writeoff_amount, pay_type, trade_date, recipient, apply_memo, bl_center_confirmed, center_confirm_man_code, center_confirm_man_name, center_confirm_date, center_confirm_note, center_reject_reason, bl_headquarters_confirmed, headquarters_confirm_man_code, headquarters_confirm_man_name, headquarters_confirm_date, headquarters_confirm_note, headquarters_reject_reason, revoke_date, revoke_man_code, revoke_man_name, revoke_reason, create_by, create_time, update_by, update_time, remark from emis_writeoff_apply + + + + + + + + insert into emis_writeoff_apply + + apply_no, + apply_man_code, + apply_man_name, + apply_site_code, + apply_site_name, + apply_date, + writeoff_amount, + pay_type, + trade_date, + recipient, + apply_memo, + bl_center_confirmed, + center_confirm_man_code, + center_confirm_man_name, + center_confirm_date, + center_confirm_note, + center_reject_reason, + bl_headquarters_confirmed, + headquarters_confirm_man_code, + headquarters_confirm_man_name, + headquarters_confirm_date, + headquarters_confirm_note, + headquarters_reject_reason, + revoke_date, + revoke_man_code, + revoke_man_name, + revoke_reason, + create_by, + create_time, + update_by, + update_time, + remark, + + + #{applyNo}, + #{applyManCode}, + #{applyManName}, + #{applySiteCode}, + #{applySiteName}, + #{applyDate}, + #{writeoffAmount}, + #{payType}, + #{tradeDate}, + #{recipient}, + #{applyMemo}, + #{blCenterConfirmed}, + #{centerConfirmManCode}, + #{centerConfirmManName}, + #{centerConfirmDate}, + #{centerConfirmNote}, + #{centerRejectReason}, + #{blHeadquartersConfirmed}, + #{headquartersConfirmManCode}, + #{headquartersConfirmManName}, + #{headquartersConfirmDate}, + #{headquartersConfirmNote}, + #{headquartersRejectReason}, + #{revokeDate}, + #{revokeManCode}, + #{revokeManName}, + #{revokeReason}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{remark}, + + + + + update emis_writeoff_apply + + apply_no = #{applyNo}, + apply_man_code = #{applyManCode}, + apply_man_name = #{applyManName}, + apply_site_code = #{applySiteCode}, + apply_site_name = #{applySiteName}, + apply_date = #{applyDate}, + writeoff_amount = #{writeoffAmount}, + apply_memo = #{applyMemo}, + 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}, + 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}, + revoke_date = #{revokeDate}, + revoke_man_code = #{revokeManCode}, + revoke_man_name = #{revokeManName}, + revoke_reason = #{revokeReason}, + salesmen = #{salesmen}, + payee = #{payee}, + update_by = #{updateBy}, + update_time = #{updateTime}, + remark = #{remark}, + + where id = #{id} + + + + delete from emis_writeoff_apply where id = #{id} + + + + delete from emis_writeoff_apply where id in + + #{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}, + update_by = #{updateBy}, + update_time = #{updateTime} + 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_reject_reason = #{centerRejectReason}, + 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}, + 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_reject_reason = #{headquartersRejectReason}, + update_by = #{updateBy}, + update_time = #{updateTime} + where id = #{id} + + + + update emis_writeoff_apply set + bl_center_confirmed = #{blCenterConfirmed}, + revoke_man_code = #{revokeManCode}, + revoke_man_name = #{revokeManName}, + revoke_date = #{revokeDate}, + revoke_reason = #{revokeReason}, + update_by = #{updateBy}, + update_time = #{updateTime} + where id = #{id} + + + + update emis_writeoff_apply set + bl_center_confirmed = #{blCenterConfirmed}, + bl_headquarters_confirmed = #{blHeadquartersConfirmed}, + center_confirm_man_code = null, + center_confirm_man_name = null, + center_confirm_date = null, + center_confirm_note = null, + center_reject_reason = null, + headquarters_confirm_man_code = null, + headquarters_confirm_man_name = null, + headquarters_confirm_date = null, + headquarters_confirm_note = null, + headquarters_reject_reason = null, + revoke_man_code = null, + revoke_man_name = null, + revoke_date = null, + revoke_reason = null, + update_by = #{updateBy}, + update_time = #{updateTime} + where id = #{id} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +