diff --git a/oms_web/oms_vue/src/api/finance/payment.js b/oms_web/oms_vue/src/api/finance/payment.js index e7a2da46..4c7fcedf 100644 --- a/oms_web/oms_vue/src/api/finance/payment.js +++ b/oms_web/oms_vue/src/api/finance/payment.js @@ -104,10 +104,11 @@ export function applyPaymentApi(data) { } // 申请退款 -export function applyRefund(id) { +export function applyRefund(data) { return request({ - url: '/finance/payment/applyRefund/'+id, - method: 'get', + url: '/finance/payment/applyRefund', + method: 'post', + data: data, needLoading: true }) } diff --git a/oms_web/oms_vue/src/views/dataProcess/projectTransfer.vue b/oms_web/oms_vue/src/views/dataProcess/projectTransfer.vue index 64c17ea5..e7e4f814 100644 --- a/oms_web/oms_vue/src/views/dataProcess/projectTransfer.vue +++ b/oms_web/oms_vue/src/views/dataProcess/projectTransfer.vue @@ -122,14 +122,14 @@ - + - + 申请退款 确 定 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -377,6 +427,25 @@ export default { // 付款申请弹窗 applyPaymentOpen: false, applyPaymentForm: {}, + // 退款申请弹窗 + applyRefundOpen: false, + applyRefundTaxRate: null, + applyRefundOriginalTotalPriceWithTax: null, + applyRefundMaxAmount: null, + applyRefundCalcWithoutTax: false, + applyRefundCalcTaxAmount: false, + applyRefundForm: {}, + applyRefundRules: { + paymentMethod: [{ required: true, message: "请选择退款方式", trigger: "change" }], + payName: [{ required: true, message: "请输入账户名称", trigger: "blur" }], + payBankNumber: [{ required: true, message: "请输入银行账号", trigger: "blur" }], + payBankOpenAddress: [{ required: true, message: "请输入银行开户行", trigger: "blur" }], + bankNumber: [{ required: true, message: "请输入银行行号", trigger: "blur" }], + totalPriceWithTax: [ + { required: true, message: "请输入含税金额", trigger: "blur" }, + { validator: (rule, value, callback) => this.validateApplyRefundTotalPrice(rule, value, callback), trigger: ["blur", "change"] } + ] + } }; }, created() { @@ -393,7 +462,9 @@ export default { payBankNumber: row.payBankNumber, payBankOpenAddress: row.payBankOpenAddress, bankNumber: row.bankNumber, - totalPriceWithTax: row.totalPriceWithTax + totalPriceWithTax: row.totalPriceWithTax, + totalPriceWithoutTax: row.totalPriceWithoutTax, + taxAmount: row.taxAmount }; this.applyPaymentOpen = true; }, @@ -501,12 +572,105 @@ export default { }, /** 申请退款按钮操作 */ handleApplyRefund(row) { - this.$modal.confirm('收款单退款申请,确认提交至财务审批吗?').then(() => { - return applyRefund(row.id); - }).then(() => { - this.getList(); - this.$modal.msgSuccess("申请退款成功"); - }).catch(() => {}); + this.applyRefundTaxRate = row.taxRate || null; + this.applyRefundOriginalTotalPriceWithTax = row.totalPriceWithTax || null; + this.applyRefundMaxAmount = row.remainingRefundAmount || row.totalPriceWithTax || null; + this.applyRefundCalcWithoutTax = this.isValidRefundAmount(row.totalPriceWithoutTax); + this.applyRefundCalcTaxAmount = this.isValidRefundAmount(row.taxAmount); + this.applyRefundForm = { + id: row.id, + paymentMethod: row.paymentMethod || null, + payName: row.payName || null, + payBankNumber: row.payBankNumber || null, + payBankOpenAddress: row.payBankOpenAddress || null, + bankNumber: row.bankNumber || null, + totalPriceWithTax: row.remainingRefundAmount || row.totalPriceWithTax || null, + totalPriceWithoutTax: null, + taxAmount: null, + remark: null + }; + this.syncApplyRefundAmounts(); + this.applyRefundOpen = true; + this.$nextTick(() => { + this.$refs["applyRefundForm"] && this.$refs["applyRefundForm"].clearValidate(); + }); + }, + canApplyRefund(row) { + const remainingRefundAmount = Number(row.remainingRefundAmount); + return row.paymentBillType !== 'REFUND' + && row.paymentStatus === '2' + && ['WAIT_REFUNDED', 'PART_REFUNDED', null, undefined, ''].includes(row.refundStatus) + && !Number.isNaN(remainingRefundAmount) + && remainingRefundAmount > 0; + }, + validateApplyRefundTotalPrice(rule, value, callback) { + if (value === null || value === undefined || value === '') { + callback(); + return; + } + const currentValue = Number(value); + const maxValue = Number(this.applyRefundMaxAmount); + if (Number.isNaN(currentValue)) { + callback(new Error("含税金额格式不正确")); + return; + } + if (currentValue <= 0) { + callback(new Error("含税金额必须大于0")); + return; + } + if (!Number.isNaN(maxValue) && currentValue > maxValue) { + callback(new Error("含税金额不能大于剩余可退款金额")); + return; + } + callback(); + }, + syncApplyRefundAmounts() { + const totalPriceWithTax = Number(this.applyRefundForm.totalPriceWithTax); + const taxRate = Number(this.applyRefundTaxRate); + if (Number.isNaN(totalPriceWithTax) || this.applyRefundForm.totalPriceWithTax === '' || this.applyRefundForm.totalPriceWithTax === null) { + this.applyRefundForm.totalPriceWithoutTax = null; + this.applyRefundForm.taxAmount = null; + return; + } + if (Number.isNaN(taxRate)) { + this.applyRefundForm.totalPriceWithoutTax = this.applyRefundCalcWithoutTax ? totalPriceWithTax.toFixed(2) : null; + this.applyRefundForm.taxAmount = this.applyRefundCalcTaxAmount ? '0.00' : null; + return; + } + const taxAmount = (totalPriceWithTax * taxRate).toFixed(2); + const totalPriceWithoutTax = (totalPriceWithTax - Number(taxAmount)).toFixed(2); + this.applyRefundForm.taxAmount = this.applyRefundCalcTaxAmount ? taxAmount : null; + this.applyRefundForm.totalPriceWithoutTax = this.applyRefundCalcWithoutTax ? totalPriceWithoutTax : null; + }, + isValidRefundAmount(value) { + const amount = Number(value); + return value !== null && value !== undefined && value !== '' && !Number.isNaN(amount) && amount !== 0; + }, + submitApplyRefund() { + this.$refs["applyRefundForm"].validate(valid => { + if (!valid) { + return; + } + const submitData = { + id: this.applyRefundForm.id, + paymentMethod: this.applyRefundForm.paymentMethod, + payName: this.applyRefundForm.payName, + payBankNumber: this.applyRefundForm.payBankNumber, + payBankOpenAddress: this.applyRefundForm.payBankOpenAddress, + bankNumber: this.applyRefundForm.bankNumber, + totalPriceWithTax: this.applyRefundForm.totalPriceWithTax, + totalPriceWithoutTax: this.applyRefundForm.totalPriceWithoutTax, + taxAmount: this.applyRefundForm.taxAmount, + remark: this.applyRefundForm.remark + }; + this.$modal.confirm('付款单退款申请,确认提交至财务审批吗?').then(() => { + return applyRefund(submitData); + }).then(() => { + this.applyRefundOpen = false; + this.getList(); + this.$modal.msgSuccess("申请退款成功"); + }).catch(() => {}); + }); }, handleDelete(id){ this.$modal.confirm('确认删除该笔预付单数据吗?').then(() => { @@ -559,6 +723,10 @@ export default { if (value === null || value === undefined || value === '') return ''; return value.substring(0, 10); }, + formatTaxRate(value) { + if (value === null || value === undefined || value === '') return ''; + return `${Number(value) * 100}%`; + }, handleUpdatePaymentBillSubmit(form) { console.log(form); updatePaymentBill(form).then(response => { diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/controller/OmsPaymentBillController.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/controller/OmsPaymentBillController.java index 6265418a..f975d31c 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/controller/OmsPaymentBillController.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/controller/OmsPaymentBillController.java @@ -259,11 +259,11 @@ public class OmsPaymentBillController extends BaseController /** * 申请退款 */ - @GetMapping("/applyRefund/{id}") + @PostMapping("/applyRefund") @ResponseBody - public AjaxResult applyRefund(@PathVariable("id") Long id) { + public AjaxResult applyRefund(@RequestBody OmsPaymentBill paymentBill) { try { - return omsPaymentBillService.applyRefund(id); + return omsPaymentBillService.applyRefund(paymentBill); } catch (Exception e) { logger.error("申请退款失败", e); return AjaxResult.error("操作失败:" + e.getMessage()); diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsPaymentBill.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsPaymentBill.java index 31ff59c1..176418f0 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsPaymentBill.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsPaymentBill.java @@ -70,6 +70,9 @@ public class OmsPaymentBill extends BaseEntity @Excel(name = "税额") private BigDecimal taxAmount; + /** 税率 */ + private BigDecimal taxRate; + /** 删除标志(0代表存在 2代表删除) */ private String delFlag; @@ -130,6 +133,10 @@ public class OmsPaymentBill extends BaseEntity /** 退款状态 */ private String refundStatus; + /** 已申请退款金额 */ + private BigDecimal refundedAmount; + /** 剩余可退款金额 */ + private BigDecimal remainingRefundAmount; private String hzUserName; private Long approveUser; private Date applyTime; @@ -194,8 +201,8 @@ public class OmsPaymentBill extends BaseEntity @Getter public enum RefundStatusEnum { - /** 应付单生成 */ - REFUNDED("REFUND_APPLIED", "已申请退款"), + REFUNDED("REFUND_APPLIED", "全部退款"), + PART_REFUNDED("PART_REFUNDED", "部分退款"), WAIT_REFUNDED("WAIT_REFUNDED", "未退款") ; diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsPayablePaymentDetailMapper.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsPayablePaymentDetailMapper.java index 9289f07b..4fb46473 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsPayablePaymentDetailMapper.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsPayablePaymentDetailMapper.java @@ -7,6 +7,7 @@ import org.apache.ibatis.annotations.Param; import java.util.Date; import java.util.List; +import java.util.Map; public interface OmsPayablePaymentDetailMapper { public int insertOmsPayablePaymentDetail(OmsPayablePaymentDetail omsPayablePaymentDetail); @@ -19,6 +20,8 @@ public interface OmsPayablePaymentDetailMapper { List selectByPaymentPlanIds(@Param("paymentPlanIds") List paymentPlanIds); + List> listPaymentBillTaxRate(@Param("paymentBillCodeList") List paymentBillCodeList); + int clearWriteOffByWriteOffId(Long[] ids); List listPayableByWriteOffId(List writeOffIds); diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsPaymentBillMapper.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsPaymentBillMapper.java index 0b86293a..830fb440 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsPaymentBillMapper.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsPaymentBillMapper.java @@ -1,6 +1,7 @@ package com.ruoyi.sip.mapper; import java.util.List; +import java.util.Map; import com.ruoyi.sip.domain.OmsPaymentBill; import com.ruoyi.sip.domain.dto.PaymentBillDetailDTO; @@ -100,4 +101,7 @@ public interface OmsPaymentBillMapper List listPreResidueAmountByVendorCodeList(List collect); + List> listRefundSummaryByOriginalBillIds(@Param("originalBillIds") List originalBillIds, + @Param("excludeApproveStatus") String excludeApproveStatus); + } diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsPayablePaymentDetailService.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsPayablePaymentDetailService.java index 930461a1..9ed1c27a 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsPayablePaymentDetailService.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsPayablePaymentDetailService.java @@ -5,6 +5,7 @@ import com.ruoyi.sip.domain.dto.PaymentBillPayableDetailDTO; import com.ruoyi.sip.domain.dto.ProjectPaymentBillDto; import java.util.Date; +import java.util.Map; import java.util.List; public interface IOmsPayablePaymentDetailService { @@ -21,6 +22,8 @@ public interface IOmsPayablePaymentDetailService { List listBypaymentCode(String paymentBillCode); + Map getPaymentBillTaxRateMap(List paymentBillCodeList); + List listByWriteOffIds(Long[] ids); void insertBatch(List detailList); diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsPaymentBillService.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsPaymentBillService.java index 031cf8a0..c56ed256 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsPaymentBillService.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsPaymentBillService.java @@ -86,10 +86,10 @@ public interface IOmsPaymentBillService /** * 申请退款 * - * @param originalPaymentId 原始付款单ID + * @param omsPaymentBill 退款申请参数 * @return 结果 */ - public AjaxResult applyRefund(Long originalPaymentId); + public AjaxResult applyRefund(OmsPaymentBill omsPaymentBill); /** * 上传退款图 diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsPayablePaymentDetailServiceImpl.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsPayablePaymentDetailServiceImpl.java index a0397100..14600eeb 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsPayablePaymentDetailServiceImpl.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsPayablePaymentDetailServiceImpl.java @@ -125,6 +125,26 @@ public class OmsPayablePaymentDetailServiceImpl implements IOmsPayablePaymentDet return omsPayablePaymentDetailMapper.list(omsPayablePaymentDetail); } + @Override + public Map getPaymentBillTaxRateMap(List paymentBillCodeList) { + if (CollUtil.isEmpty(paymentBillCodeList)) { + return Collections.emptyMap(); + } + List> taxRateList = omsPayablePaymentDetailMapper.listPaymentBillTaxRate(paymentBillCodeList); + if (CollUtil.isEmpty(taxRateList)) { + return Collections.emptyMap(); + } + Map taxRateMap = new HashMap<>(); + for (Map item : taxRateList) { + Object paymentBillCode = item.get("paymentBillCode"); + Object taxRate = item.get("taxRate"); + if (paymentBillCode instanceof String) { + taxRateMap.put((String) paymentBillCode, taxRate instanceof BigDecimal ? (BigDecimal) taxRate : null); + } + } + return taxRateMap; + } + @Override public void insertBatch(List detailList) { omsPayablePaymentDetailMapper.insertBatch(detailList); diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsPaymentBillServiceImpl.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsPaymentBillServiceImpl.java index 1c01915b..224a141e 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsPaymentBillServiceImpl.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsPaymentBillServiceImpl.java @@ -86,6 +86,7 @@ public class OmsPaymentBillServiceImpl implements IOmsPaymentBillService , TodoC public OmsPaymentBill selectOmsPaymentBillById(Long id) { OmsPaymentBill omsPaymentBill = omsPaymentBillMapper.selectOmsPaymentBillById(id); + fillRefundSummary(Collections.singletonList(omsPaymentBill)); if (omsPaymentBill != null && StrUtil.isNotEmpty(omsPaymentBill.getFileId())) { List idList = StrUtil.split(omsPaymentBill.getFileId(), ',') .stream() @@ -110,7 +111,24 @@ public class OmsPaymentBillServiceImpl implements IOmsPaymentBillService , TodoC @Override public List selectOmsPaymentBillList(OmsPaymentBill omsPaymentBill) { - return omsPaymentBillMapper.selectOmsPaymentBillList(omsPaymentBill); + List paymentBillList = omsPaymentBillMapper.selectOmsPaymentBillList(omsPaymentBill); + if (CollUtil.isEmpty(paymentBillList)) { + return paymentBillList; + } + fillRefundSummary(paymentBillList); + List paymentBillCodeList = paymentBillList.stream() + .map(OmsPaymentBill::getPaymentBillCode) + .filter(StrUtil::isNotBlank) + .distinct() + .collect(Collectors.toList()); + Map taxRateMap = detailService.getPaymentBillTaxRateMap(paymentBillCodeList); + if (CollUtil.isEmpty(taxRateMap)) { + return paymentBillList; + } + for (OmsPaymentBill paymentBill : paymentBillList) { + paymentBill.setTaxRate(taxRateMap.get(paymentBill.getPaymentBillCode())); + } + return paymentBillList; } @Override @@ -256,6 +274,95 @@ public class OmsPaymentBillServiceImpl implements IOmsPaymentBillService , TodoC return paymentBillType; } + private void fillRefundSummary(List paymentBillList) { + if (CollUtil.isEmpty(paymentBillList)) { + return; + } + List originalBillIds = paymentBillList.stream() + .filter(Objects::nonNull) + .filter(item -> !OmsPaymentBill.PaymentBillTypeEnum.REFUND.getCode().equals(item.getPaymentBillType())) + .map(OmsPaymentBill::getId) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); + if (CollUtil.isEmpty(originalBillIds)) { + return; + } + Map refundedAmountMap = getRefundedAmountMap(originalBillIds); + for (OmsPaymentBill paymentBill : paymentBillList) { + if (paymentBill == null || OmsPaymentBill.PaymentBillTypeEnum.REFUND.getCode().equals(paymentBill.getPaymentBillType()) || paymentBill.getId() == null) { + continue; + } + BigDecimal totalAmount = defaultAmount(paymentBill.getTotalPriceWithTax()); + BigDecimal refundedAmount = refundedAmountMap.getOrDefault(paymentBill.getId(), BigDecimal.ZERO); + BigDecimal remainingRefundAmount = totalAmount.subtract(refundedAmount); + if (remainingRefundAmount.compareTo(BigDecimal.ZERO) < 0) { + remainingRefundAmount = BigDecimal.ZERO; + } + paymentBill.setRefundedAmount(refundedAmount); + paymentBill.setRemainingRefundAmount(remainingRefundAmount); + paymentBill.setRefundStatus(resolveRefundStatus(totalAmount, refundedAmount)); + } + } + + private Map getRefundedAmountMap(List originalBillIds) { + if (CollUtil.isEmpty(originalBillIds)) { + return Collections.emptyMap(); + } + List> summaryList = omsPaymentBillMapper.listRefundSummaryByOriginalBillIds( + originalBillIds, ApproveStatusEnum.APPROVE_REJECT.getCode()); + if (CollUtil.isEmpty(summaryList)) { + return Collections.emptyMap(); + } + Map refundedAmountMap = new HashMap<>(); + for (Map summary : summaryList) { + Object originalBillId = summary.get("originalBillId"); + Object refundedAmount = summary.get("refundedAmount"); + if (originalBillId == null) { + continue; + } + Long billId = Long.valueOf(String.valueOf(originalBillId)); + BigDecimal amount = refundedAmount instanceof BigDecimal + ? (BigDecimal) refundedAmount + : new BigDecimal(String.valueOf(refundedAmount)); + refundedAmountMap.put(billId, amount); + } + return refundedAmountMap; + } + + private void refreshOriginalBillRefundStatus(Long originalBillId) { + if (originalBillId == null) { + return; + } + OmsPaymentBill originalBill = omsPaymentBillMapper.selectOmsPaymentBillById(originalBillId); + if (originalBill == null || OmsPaymentBill.PaymentBillTypeEnum.REFUND.getCode().equals(originalBill.getPaymentBillType())) { + return; + } + BigDecimal totalAmount = defaultAmount(originalBill.getTotalPriceWithTax()); + BigDecimal refundedAmount = getRefundedAmountMap(Collections.singletonList(originalBillId)) + .getOrDefault(originalBillId, BigDecimal.ZERO); + OmsPaymentBill updateBill = new OmsPaymentBill(); + updateBill.setId(originalBillId); + updateBill.setRefundStatus(resolveRefundStatus(totalAmount, refundedAmount)); + omsPaymentBillMapper.updateOmsPaymentBill(updateBill); + } + + private BigDecimal defaultAmount(BigDecimal amount) { + return Optional.ofNullable(amount).orElse(BigDecimal.ZERO).abs(); + } + + private String resolveRefundStatus(BigDecimal totalAmount, BigDecimal refundedAmount) { + BigDecimal total = defaultAmount(totalAmount); + BigDecimal refunded = defaultAmount(refundedAmount); + if (refunded.compareTo(BigDecimal.ZERO) <= 0) { + return OmsPaymentBill.RefundStatusEnum.WAIT_REFUNDED.getCode(); + } + if (refunded.compareTo(total) < 0) { + return OmsPaymentBill.RefundStatusEnum.PART_REFUNDED.getCode(); + } + return OmsPaymentBill.RefundStatusEnum.REFUNDED.getCode(); + } + /** * 新增采购付款单 * @@ -489,10 +596,14 @@ public class OmsPaymentBillServiceImpl implements IOmsPaymentBillService , TodoC } private void handleRejectOrder(String businessKey) { + OmsPaymentBill existBill = omsPaymentBillMapper.selectOmsPaymentBillByCode(businessKey); OmsPaymentBill omsPaymentBill = new OmsPaymentBill(); omsPaymentBill.setPaymentBillCode(businessKey); omsPaymentBill.setApproveStatus(ApproveStatusEnum.APPROVE_REJECT.getCode()); omsPaymentBillMapper.updateOmsPaymentBillByCode(omsPaymentBill); + if (existBill != null && OmsPaymentBill.PaymentBillTypeEnum.REFUND.getCode().equals(existBill.getPaymentBillType())) { + refreshOriginalBillRefundStatus(existBill.getOriginalBillId()); + } } @Override @@ -554,7 +665,14 @@ public class OmsPaymentBillServiceImpl implements IOmsPaymentBillService , TodoC } @Override - public AjaxResult applyRefund(Long originalPaymentId) { + public AjaxResult applyRefund(OmsPaymentBill omsPaymentBill) { + if (omsPaymentBill == null || omsPaymentBill.getId() == null) { + return AjaxResult.error("原始付款单ID不能为空"); + } + if (omsPaymentBill.getTotalPriceWithTax() == null || omsPaymentBill.getTotalPriceWithTax().compareTo(BigDecimal.ZERO) <= 0) { + return AjaxResult.error("退款金额必须大于0"); + } + Long originalPaymentId = omsPaymentBill.getId(); // 1. 验证原始付款单 OmsPaymentBill originalBill = selectOmsPaymentBillById(originalPaymentId); if (originalBill == null) { @@ -563,24 +681,32 @@ public class OmsPaymentBillServiceImpl implements IOmsPaymentBillService , TodoC if (!OmsPaymentBill.PaymentStatusEnum.PAYMENT.getCode().equals(originalBill.getPaymentStatus())) { return AjaxResult.error("只有已付款的订单才能申请退款"); } - if (OmsPaymentBill.RefundStatusEnum.REFUNDED.getCode().equals(originalBill.getRefundStatus())) { - return AjaxResult.error("该付款单已申请过退款,请勿重复操作"); + BigDecimal originalAmount = defaultAmount(originalBill.getTotalPriceWithTax()); + BigDecimal appliedRefundAmount = getRefundedAmountMap(Collections.singletonList(originalPaymentId)) + .getOrDefault(originalPaymentId, BigDecimal.ZERO); + BigDecimal remainingRefundAmount = originalAmount.subtract(appliedRefundAmount); + if (remainingRefundAmount.compareTo(BigDecimal.ZERO) <= 0) { + return AjaxResult.error("该付款单已无可退款金额"); + } + BigDecimal currentRefundAmount = defaultAmount(omsPaymentBill.getTotalPriceWithTax()); + if (currentRefundAmount.compareTo(remainingRefundAmount) > 0) { + return AjaxResult.error("当前退款金额超出可退款金额,剩余可退款金额:" + remainingRefundAmount); } // 2. 创建新的退款单 OmsPaymentBill refundBill = new OmsPaymentBill(); // 复制属性并取反金额 - refundBill.setTotalPriceWithTax(originalBill.getTotalPriceWithTax().negate()); - refundBill.setTotalPriceWithoutTax(originalBill.getTotalPriceWithoutTax().negate()); - refundBill.setTaxAmount(originalBill.getTaxAmount().negate()); + refundBill.setTotalPriceWithTax(currentRefundAmount.negate()); + refundBill.setTotalPriceWithoutTax(defaultAmount(omsPaymentBill.getTotalPriceWithoutTax()).negate()); + refundBill.setTaxAmount(defaultAmount(omsPaymentBill.getTaxAmount()).negate()); refundBill.setVendorCode(originalBill.getVendorCode()); refundBill.setOrderCode(originalBill.getOrderCode()); - refundBill.setPayName(originalBill.getPayName()); - refundBill.setPayBankNumber(originalBill.getPayBankNumber()); - refundBill.setPayBankOpenAddress(originalBill.getPayBankOpenAddress()); - refundBill.setBankNumber(originalBill.getBankNumber()); + refundBill.setPayName(StrUtil.isNotBlank(omsPaymentBill.getPayName()) ? omsPaymentBill.getPayName() : originalBill.getPayName()); + refundBill.setPayBankNumber(StrUtil.isNotBlank(omsPaymentBill.getPayBankNumber()) ? omsPaymentBill.getPayBankNumber() : originalBill.getPayBankNumber()); + refundBill.setPayBankOpenAddress(StrUtil.isNotBlank(omsPaymentBill.getPayBankOpenAddress()) ? omsPaymentBill.getPayBankOpenAddress() : originalBill.getPayBankOpenAddress()); + refundBill.setBankNumber(StrUtil.isNotBlank(omsPaymentBill.getBankNumber()) ? omsPaymentBill.getBankNumber() : originalBill.getBankNumber()); refundBill.setPaymentBillCode(generatePaymentBillCode()); // 设置新属性 refundBill.setPaymentBillType(OmsPaymentBill.PaymentBillTypeEnum.REFUND.getCode()); @@ -588,14 +714,15 @@ public class OmsPaymentBillServiceImpl implements IOmsPaymentBillService , TodoC refundBill.setApproveStatus(ApproveStatusEnum.WAIT_APPROVE.getCode()); refundBill.setOriginalBillId(originalPaymentId); refundBill.setPaymentTime(null); - refundBill.setPaymentMethod(originalBill.getPaymentMethod()); - refundBill.setRemark("退款-关联原付款单:" + originalBill.getPaymentBillCode()); + refundBill.setPaymentMethod(StrUtil.isNotBlank(omsPaymentBill.getPaymentMethod()) ? omsPaymentBill.getPaymentMethod() : originalBill.getPaymentMethod()); + refundBill.setRemark(StrUtil.isNotBlank(omsPaymentBill.getRemark()) + ? "退款-关联原付款单:" + originalBill.getPaymentBillCode() + "," + omsPaymentBill.getRemark() + : "退款-关联原付款单:" + originalBill.getPaymentBillCode()); insertOmsPaymentBill(refundBill); // 3. 更新原始付款单状态 - originalBill.setRefundStatus(OmsPaymentBill.RefundStatusEnum.REFUNDED.getCode()); - updateOmsPaymentBill(originalBill); + refreshOriginalBillRefundStatus(originalPaymentId); //4 创建付款明细 detailService.applyRefund(originalBill.getPaymentBillCode(),refundBill.getPaymentBillCode()); //5. 开始退款审批流程 @@ -628,8 +755,8 @@ public class OmsPaymentBillServiceImpl implements IOmsPaymentBillService , TodoC // 更新付款单 - // 更新为“已付款” - paymentBill.setPaymentStatus(OmsPaymentBill.PaymentStatusEnum.PAYMENT.getCode()); + // 退款单上传退款图后,标记为已退款 + paymentBill.setPaymentStatus(OmsPaymentBill.PaymentStatusEnum.REFUNDED.getCode()); paymentBill.setActualPaymentTime(DateUtils.getNowDate()); updateOmsPaymentBill(paymentBill); if (!paymentBill.getPaymentBillType().equals(OmsPaymentBill.PaymentBillTypeEnum.PRE_PAYMENT.getCode())) { @@ -673,10 +800,7 @@ public class OmsPaymentBillServiceImpl implements IOmsPaymentBillService , TodoC // 撤销退款单 deleteOmsPaymentBillById(existBill.getId()); detailService.deleteByPaymentCode(existBill.getPaymentBillCode()); - OmsPaymentBill omsPaymentBill = new OmsPaymentBill(); - omsPaymentBill.setId(existBill.getOriginalBillId()); - omsPaymentBill.setRefundStatus(OmsPaymentBill.RefundStatusEnum.WAIT_REFUNDED.getCode()); - updateOmsPaymentBill(omsPaymentBill); + refreshOriginalBillRefundStatus(existBill.getOriginalBillId()); }else{ if (OmsPaymentBill.PaymentStatusEnum.PAYMENT.getCode().equals(existBill.getPaymentStatus())){ return AjaxResult.error("该退款单已付款成功,无法撤销"); @@ -851,8 +975,9 @@ public class OmsPaymentBillServiceImpl implements IOmsPaymentBillService , TodoC @Override public OmsPaymentBill selectOmsPaymentBillByCode(String paymentBillCode) { - - return omsPaymentBillMapper.selectOmsPaymentBillByCode(paymentBillCode); + OmsPaymentBill paymentBill = omsPaymentBillMapper.selectOmsPaymentBillByCode(paymentBillCode); + fillRefundSummary(Collections.singletonList(paymentBill)); + return paymentBill; } @Override diff --git a/ruoyi-sip/src/main/resources/mapper/finance/OmsPayablePaymentDetailMapper.xml b/ruoyi-sip/src/main/resources/mapper/finance/OmsPayablePaymentDetailMapper.xml index d654b0d2..d6afc3d3 100644 --- a/ruoyi-sip/src/main/resources/mapper/finance/OmsPayablePaymentDetailMapper.xml +++ b/ruoyi-sip/src/main/resources/mapper/finance/OmsPayablePaymentDetailMapper.xml @@ -121,6 +121,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ORDER BY t1.create_time DESC + + - \ No newline at end of file + +