diff --git a/oms_web/oms_vue/src/api/finance/receive.js b/oms_web/oms_vue/src/api/finance/receive.js new file mode 100644 index 00000000..d87a193e --- /dev/null +++ b/oms_web/oms_vue/src/api/finance/receive.js @@ -0,0 +1,75 @@ +import request from '@/utils/request' +import {tansParams} from "@/utils/ruoyi" + +// 查询收款单列表 +export function listReceive(query) { + return request({ + url: '/finance/receipt/list', + method: 'get', + data: tansParams(query) + }) +} + +// 查询收款单详细 +export function getReceive(id) { + return request({ + url: '/finance/receipt/' + id, + method: 'get' + }) +} + +// 查询收款单附件 +export function getReceiveAttachments(id, params) { + return request({ + url: `/finance/receipt/attachment/${id}`, + method: 'get', + params + }) +} + +// 上传收款单附件 +export function uploadReceiveAttachment(data) { + return request({ + url: '/finance/receipt/uploadReceipt', + method: 'post', + headers: { + 'Content-Type': 'multipart/form-data' + }, + data: data, + needLoading: true + }); +} + +// 申请红冲 +export function redRush(id) { + return request({ + url: '/finance/receipt/applyRefund/' + id, + method: 'get' + }) +} + +// 退回收款单 +export function returnReceive(id) { + return request({ + url: '/finance/receipt/returnReceivable/' + id, + method: 'delete' + }) +} + +// 新增收款单 (Calls Receivable Merge Logic) +export function mergeReceivable(data) { + return request({ + url: '/finance/receivable/mergeAndInitiateReceipt', + method: 'post', + data: data, + needLoading: true + }) +} +export function addReceipt(data) { + return request({ + url: '/finance/receipt/insert', + method: 'post', + data: data, + needLoading: true + }) +} diff --git a/oms_web/oms_vue/src/views/approve/finance/pdfUtils.js b/oms_web/oms_vue/src/views/approve/finance/pdfUtils.js new file mode 100644 index 00000000..88425966 --- /dev/null +++ b/oms_web/oms_vue/src/views/approve/finance/pdfUtils.js @@ -0,0 +1,63 @@ +import html2canvas from 'html2canvas'; +import jsPDF from 'jspdf'; + +/** + * 导出指定DOM元素为PDF + * @param {HTMLElement} element - 要导出的DOM元素 + * @param {string} fileName - 导出的文件名 + * @returns {Promise} + */ +export async function exportElementToPDF(element, fileName) { + const disabledElements = []; + try { + // 移除所有输入框的 disabled 属性,以便在PDF中正确显示 + element.querySelectorAll('input:disabled, textarea:disabled').forEach(el => { + disabledElements.push(el); + el.disabled = false; + }); + + // 使用html2canvas捕获内容 + const canvas = await html2canvas(element, { + scale: 2, // 提高清晰度 + useCORS: true, // 允许跨域图片 + logging: false, // 关闭日志 + backgroundColor: '#F8F5F0' // 设置背景色 + }); + + // 计算PDF页面尺寸 + const imgWidth = 210; // A4纸宽度(mm) + const pageHeight = 297; // A4纸高度(mm) + const imgHeight = (canvas.height * imgWidth) / canvas.width; + let heightLeft = imgHeight; + + // 创建PDF + const pdf = new jsPDF('p', 'mm', 'a4'); + let position = 0; + + // 将canvas转换为图片 + const imgData = canvas.toDataURL('image/jpeg'); + + // 添加第一页 + pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight); + heightLeft -= pageHeight; + + // 如果内容超过一页,添加更多页 + while (heightLeft > 0) { + position = heightLeft - imgHeight; + pdf.addPage(); + pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight); + heightLeft -= pageHeight; + } + + // 保存PDF + pdf.save(fileName); + } catch (error) { + console.error('PDF导出失败:', error); + throw error; + } finally { + // 恢复之前移除的 disabled 属性 + disabledElements.forEach(el => { + el.disabled = true; + }); + } +} diff --git a/oms_web/oms_vue/src/views/finance/receive/components/AddForm.vue b/oms_web/oms_vue/src/views/finance/receive/components/AddForm.vue new file mode 100644 index 00000000..4b4f38f9 --- /dev/null +++ b/oms_web/oms_vue/src/views/finance/receive/components/AddForm.vue @@ -0,0 +1,482 @@ + + + + + diff --git a/oms_web/oms_vue/src/views/finance/receive/components/DetailDrawer.vue b/oms_web/oms_vue/src/views/finance/receive/components/DetailDrawer.vue new file mode 100644 index 00000000..69e2a5e7 --- /dev/null +++ b/oms_web/oms_vue/src/views/finance/receive/components/DetailDrawer.vue @@ -0,0 +1,163 @@ + + + + + diff --git a/oms_web/oms_vue/src/views/finance/receive/components/ReceiveDialog.vue b/oms_web/oms_vue/src/views/finance/receive/components/ReceiveDialog.vue new file mode 100644 index 00000000..0547f328 --- /dev/null +++ b/oms_web/oms_vue/src/views/finance/receive/components/ReceiveDialog.vue @@ -0,0 +1,486 @@ + + + + + diff --git a/oms_web/oms_vue/src/views/finance/receive/index.vue b/oms_web/oms_vue/src/views/finance/receive/index.vue new file mode 100644 index 00000000..6085ea7b --- /dev/null +++ b/oms_web/oms_vue/src/views/finance/receive/index.vue @@ -0,0 +1,346 @@ + + + diff --git a/oms_web/oms_vue/src/views/finance/writeoff/ticket/WriteOffDetailDrawer.vue b/oms_web/oms_vue/src/views/finance/writeoff/ticket/WriteOffDetailDrawer.vue new file mode 100644 index 00000000..84a402c8 --- /dev/null +++ b/oms_web/oms_vue/src/views/finance/writeoff/ticket/WriteOffDetailDrawer.vue @@ -0,0 +1,90 @@ + + + + + diff --git a/oms_web/oms_vue/src/views/finance/writeoff/ticket/writeoffRecord.vue b/oms_web/oms_vue/src/views/finance/writeoff/ticket/writeoffRecord.vue new file mode 100644 index 00000000..79fcc64a --- /dev/null +++ b/oms_web/oms_vue/src/views/finance/writeoff/ticket/writeoffRecord.vue @@ -0,0 +1,234 @@ + + + diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/controller/OmsReceiptBillController.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/controller/OmsReceiptBillController.java index 5db4f458..2822ac22 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/controller/OmsReceiptBillController.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/controller/OmsReceiptBillController.java @@ -1,10 +1,13 @@ package com.ruoyi.sip.controller; +import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; import com.ruoyi.sip.domain.OmsReceiptBill; import com.ruoyi.sip.service.IOmsReceiptBillService; +import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.web.bind.annotation.*; import org.springframework.beans.factory.annotation.Autowired; @@ -18,7 +21,7 @@ import java.util.List; */ @RestController -@RequestMapping("omsReceiptBill") +@RequestMapping("/finance/receipt") public class OmsReceiptBillController extends BaseController { @Autowired @@ -67,4 +70,25 @@ public class OmsReceiptBillController extends BaseController { public AjaxResult batchRemove(@PathVariable("ids") Long[] ids) { return AjaxResult.success(omsReceiptBillService.batchRemove(ids)); } + + + @RequiresPermissions("finance:receipt:return") + @Log(title = "退回付款单", businessType = BusinessType.UPDATE) + @DeleteMapping("/returnReceivable/{id}") + @ResponseBody + public AjaxResult returnReceivable(@PathVariable("id") Long id) + { + try { + // 验证付款单ID + if (id == null) { + return AjaxResult.error("付款单ID不能为空"); + } + + // 调用服务层方法处理退回逻辑 + return omsReceiptBillService.returnPaymentBill(id); + } catch (Exception e) { + logger.error("退回付款单失败", e); + return AjaxResult.error("操作失败:" + e.getMessage()); + } + } } diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceiptBill.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceiptBill.java index c664ca95..ee8e540c 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceiptBill.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceiptBill.java @@ -2,8 +2,10 @@ package com.ruoyi.sip.domain; import java.math.BigDecimal; import java.util.Date; +import java.util.List; +import com.ruoyi.sip.domain.dto.ReceiptDetailDTO; import lombok.Data; import lombok.Getter; @@ -52,11 +54,17 @@ public class OmsReceiptBill { */ private String orderCode; + /** + * 剩余金额 + */ + + private BigDecimal remainingAmount; /** * 含税总价 */ private BigDecimal totalPriceWithTax; + /** * 未税总价 */ @@ -152,6 +160,7 @@ public class OmsReceiptBill { * 是否已申请退款 0:未退款 1:已申请退款 */ private String refundStatus; + private List detailDTOList; @Getter public enum ReceiptBillTypeEnum { diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceivableBill.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceivableBill.java index 0f4236b7..2f925dee 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceivableBill.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceivableBill.java @@ -53,7 +53,7 @@ public class OmsReceivableBill extends BaseEntity @Excel(name = "产品类型") private String productType; private String productCode; - + private BigDecimal remainingAmount; /** 含税总价 */ @Excel(name = "含税总价") private BigDecimal totalPriceWithTax; diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceivableReceiptDetail.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceivableReceiptDetail.java index c35ca8e4..7aebe91c 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceivableReceiptDetail.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceivableReceiptDetail.java @@ -34,6 +34,7 @@ public class OmsReceivableReceiptDetail extends BaseEntity /** 应收单ID */ @Excel(name = "应收单ID") private Long receivableBillId; + private List receivableBillIdList; /** 实际收款时间 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @@ -64,6 +65,8 @@ public class OmsReceivableReceiptDetail extends BaseEntity private OmsFinAttachment finAttachment; private Date actualReceiptTime; private String receiptStatus; + private BigDecimal paymentAmountWithoutTax; + private BigDecimal paymentAmountTax; @Getter public enum ReceivableDetailTypeEnum { diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/dto/ReceiptDetailDTO.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/dto/ReceiptDetailDTO.java new file mode 100644 index 00000000..162ca0b4 --- /dev/null +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/dto/ReceiptDetailDTO.java @@ -0,0 +1,38 @@ +package com.ruoyi.sip.domain.dto; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 付款单关联的应付单明细DTO + * + * @author ruoyi + * @date 2024-12-08 + */ +@Data +public class ReceiptDetailDTO { + + /** 项目编号 */ + private String projectCode; + + /** 项目名称 */ + private String projectName; + private String productType; + + /** 采购应付单编号 */ + private String receivableBillCode; + + /** 应付单含税总价 */ + private BigDecimal totalPriceWithTax; + + /** 本次付款金额 */ + private BigDecimal receiptAmount; + + /** 本次付款比例 */ + private BigDecimal receiptRate; + private String partnerName; + private String partnerCode; + private Date createTime; +} diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsReceiptBillMapper.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsReceiptBillMapper.java index f70c4671..ce1f932b 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsReceiptBillMapper.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsReceiptBillMapper.java @@ -48,4 +48,7 @@ public interface OmsReceiptBillMapper { int selectMaxCodeByPrefix(String codePrefix); + List listRemainingAmountByPartnerCodeList(List collect); + + void clearRelationReceivable(String receiptBillCode); } diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsReceivableReceiptDetailMapper.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsReceivableReceiptDetailMapper.java index 333123eb..136cda09 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsReceivableReceiptDetailMapper.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsReceivableReceiptDetailMapper.java @@ -2,6 +2,7 @@ package com.ruoyi.sip.mapper; import java.util.List; import com.ruoyi.sip.domain.OmsReceivableReceiptDetail; +import com.ruoyi.sip.domain.dto.ReceiptDetailDTO; /** * 应收单收款明细Mapper接口 @@ -62,4 +63,6 @@ public interface OmsReceivableReceiptDetailMapper List list(OmsReceivableReceiptDetail omsReceivableReceiptDetail); List selectByPaymentPlanIds(List allReceiptPlanIds); + + List listReceivableByReceiptBillCode(List receiptBillCode); } \ No newline at end of file diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsReceiptBillService.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsReceiptBillService.java index e8829960..d4a862ee 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsReceiptBillService.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsReceiptBillService.java @@ -1,5 +1,6 @@ package com.ruoyi.sip.service; +import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.sip.domain.OmsReceiptBill; import java.util.List; @@ -42,6 +43,9 @@ public interface IOmsReceiptBillService { */ int batchRemove(Long[] ids); + List listRemainingAmountByPartnerCodeList(List collect); + + AjaxResult returnPaymentBill(Long id); } diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsReceivableReceiptDetailService.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsReceivableReceiptDetailService.java index 522b085a..b10adad0 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsReceivableReceiptDetailService.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsReceivableReceiptDetailService.java @@ -4,6 +4,7 @@ import java.util.List; import com.ruoyi.sip.domain.OmsPayablePaymentDetail; import com.ruoyi.sip.domain.OmsReceivableReceiptDetail; +import com.ruoyi.sip.domain.dto.ReceiptDetailDTO; /** * 应收单收款明细Service接口 @@ -66,4 +67,8 @@ public interface IOmsReceivableReceiptDetailService List selectReceiptPlanByIds(List allReceiptPlanIds); List listByReceivableBillIdList(List idList); + + List listReceivableByReceiptBillCode(String receiptBillCode); + + List listByReceiptBillCode(String receiptBillCode); } \ No newline at end of file diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceiptBillServiceImpl.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceiptBillServiceImpl.java index 8ba6a29c..c69175a6 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceiptBillServiceImpl.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceiptBillServiceImpl.java @@ -1,18 +1,28 @@ package com.ruoyi.sip.service.impl; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUtil; +import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.enums.ApproveStatusEnum; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.ShiroUtils; +import com.ruoyi.sip.domain.OmsPayablePaymentDetail; import com.ruoyi.sip.domain.OmsPaymentBill; import com.ruoyi.sip.domain.OmsReceiptBill; +import com.ruoyi.sip.domain.OmsReceivableReceiptDetail; +import com.ruoyi.sip.domain.dto.ReceiptDetailDTO; import com.ruoyi.sip.mapper.OmsReceiptBillMapper; import com.ruoyi.sip.service.IOmsReceiptBillService; +import com.ruoyi.sip.service.IOmsReceivableBillService; +import com.ruoyi.sip.service.IOmsReceivableReceiptDetailService; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; /** * @Author ch @@ -25,7 +35,10 @@ public class OmsReceiptBillServiceImpl implements IOmsReceiptBillService { @Resource private OmsReceiptBillMapper omsReceiptBillMapper; - + @Autowired + private IOmsReceivableReceiptDetailService omsReceivableReceiptDetailService; + @Autowired + private IOmsReceivableBillService receivableBillService; /** * 查询列表数据 @@ -41,7 +54,10 @@ public class OmsReceiptBillServiceImpl implements IOmsReceiptBillService { @Override public OmsReceiptBill queryById(Long id) { - return omsReceiptBillMapper.queryById(id); + OmsReceiptBill receiptBill = omsReceiptBillMapper.queryById(id); + List receiptDetailDTOS = omsReceivableReceiptDetailService.listReceivableByReceiptBillCode(receiptBill.getReceiptBillCode()); + receiptBill.setDetailDTOList(receiptDetailDTOS); + return receiptBill; } @@ -87,6 +103,47 @@ public class OmsReceiptBillServiceImpl implements IOmsReceiptBillService { return omsReceiptBillMapper.batchRemove(ids); } + @Override + public List listRemainingAmountByPartnerCodeList(List collect) { + return omsReceiptBillMapper.listRemainingAmountByPartnerCodeList(collect); + } + + @Override + public AjaxResult returnPaymentBill(Long id) { + try { + // 1. 验证付款单是否存在 + OmsReceiptBill receiptBill = omsReceiptBillMapper.queryById(id); + if (receiptBill == null) { + return AjaxResult.error("付款单不存在"); + } + + // 2. 检查付款单类型,只有FROM_PAYABLE类型的付款单才能退回 + if (!OmsReceiptBill.ReceiptBillTypeEnum.FROM_RECEIVABLE.getCode().equals(receiptBill.getReceiptBillType())) { + return AjaxResult.error("只有由应收单合并生成的收款单才能执行退回操作"); + } + List detailList = omsReceivableReceiptDetailService.listByReceiptBillCode(receiptBill.getReceiptBillCode()); + // 3. 清楚关联 + omsReceiptBillMapper.clearRelationReceivable(receiptBill.getReceiptBillCode()); + + + // 6. 删除付款单记录 + int result = omsReceiptBillMapper.deleteById(id); + if (result <= 0) { + throw new RuntimeException("删除付款单失败"); + } + + if (CollUtil.isNotEmpty(detailList)) { + receivableBillService.updateReceiptAmount(detailList.stream().map(OmsReceivableReceiptDetail::getReceivableBillId).distinct().collect(Collectors.toList())); + } + + + return AjaxResult.success("付款单退回成功!"); + + } catch (Exception e) { + throw new RuntimeException("退回付款单操作失败:" + e.getMessage(), e); + } + } + } diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceivableBillServiceImpl.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceivableBillServiceImpl.java index 89086467..4dc2fdea 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceivableBillServiceImpl.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceivableBillServiceImpl.java @@ -1,9 +1,10 @@ package com.ruoyi.sip.service.impl; import java.math.BigDecimal; +import java.util.Collections; import java.util.List; -import java.util.Comparator; import java.util.Map; +import java.util.function.Function; import java.util.stream.Collectors; import cn.hutool.core.collection.CollUtil; @@ -11,10 +12,10 @@ import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUtil; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.PageUtils; import com.ruoyi.common.utils.ShiroUtils; import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.sip.domain.*; -import com.ruoyi.sip.domain.dto.MergedInvoiceDataDto; import com.ruoyi.sip.domain.dto.MergedReceviableReceiptDataDto; import com.ruoyi.sip.domain.dto.ReceivableOrderReceiptDto; import com.ruoyi.sip.service.*; @@ -75,7 +76,17 @@ public class OmsReceivableBillServiceImpl implements IOmsReceivableBillService @Override public List selectOmsReceivableBillList(OmsReceivableBill omsReceivableBill) { - return omsReceivableBillMapper.selectOmsReceivableBillList(omsReceivableBill); + List receivableBills = omsReceivableBillMapper.selectOmsReceivableBillList(omsReceivableBill); + if (CollUtil.isNotEmpty(receivableBills)) { + PageUtils.clearPage(); + List receiptBills = receiptBillService.listRemainingAmountByPartnerCodeList(receivableBills.stream().map(OmsReceivableBill::getPartnerCode).collect(Collectors.toList())); + Map decimalMap = receiptBills.stream().filter(item -> item.getRemainingAmount() != null) + .collect(Collectors.toMap(OmsReceiptBill::getPartnerCode, OmsReceiptBill::getRemainingAmount, BigDecimal::add)); + for (OmsReceivableBill payableBill : receivableBills) { + payableBill.setReceivedAmount(decimalMap.getOrDefault(payableBill.getPartnerCode(), BigDecimal.ZERO)); + } + } + return receivableBills; } @@ -142,13 +153,13 @@ public class OmsReceivableBillServiceImpl implements IOmsReceivableBillService // Fetch bills once for (ReceivableOrderReceiptDto order : dto.getReceivableBills()) { + BigDecimal taxRate = order.getTaxRate(); + if (taxRate == null || taxRate.compareTo(BigDecimal.ZERO) < 0) { + // 如果税率为空或小于0,则默认为0.13 + taxRate = new BigDecimal(defaultTax); + } for (OmsReceivableReceiptPlan plan : order.getReceiptPlans()) { // 计算每个 plan 的未税金额 = planAmount / (1 + 税率),保留两位小数 - BigDecimal taxRate = order.getTaxRate(); - if (taxRate == null || taxRate.compareTo(BigDecimal.ZERO) < 0) { - // 如果税率为空或小于0,则默认为0.13 - taxRate = new BigDecimal(defaultTax); - } // 计算未税金额 = planAmount / (1 + 税率) BigDecimal divisor = BigDecimal.ONE.add(taxRate); BigDecimal planWithoutTax = plan.getPlanAmount().divide(divisor, 2, java.math.RoundingMode.HALF_UP); @@ -192,6 +203,11 @@ public class OmsReceivableBillServiceImpl implements IOmsReceivableBillService // 遍历所有计划并检查是否有已开票的记录 for (ReceivableOrderReceiptDto receivableOrderDto : dto.getReceivableBills()) { + BigDecimal taxRate = receivableOrderDto.getTaxRate(); + if (taxRate == null || taxRate.compareTo(BigDecimal.ZERO) < 0) { + // 如果税率为空或小于0,则默认为0.13 + taxRate = new BigDecimal(defaultTax); + } for (OmsReceivableReceiptPlan plan : receivableOrderDto.getReceiptPlans()) { // 检查是否存在已开票的记录 OmsReceivableReceiptDetail existingDetail = existingDetailsMap.get(plan.getId()); @@ -210,6 +226,8 @@ public class OmsReceivableBillServiceImpl implements IOmsReceivableBillService detail.setReceiptAmount(plan.getPlanAmount()); detail.setReceiptRate(plan.getPlanRate()); detail.setReceiptTime(plan.getPlanReceiptDate()); + detail.setPaymentAmountWithoutTax(plan.getPlanAmount().divide(BigDecimal.ONE.add(taxRate), 2, java.math.RoundingMode.HALF_UP)); + detail.setPaymentAmountTax(detail.getReceiptAmount().subtract(detail.getPaymentAmountWithoutTax())); detail.setRemark(plan.getRemark()); detail.setCreateBy(ShiroUtils.getUserId().toString()); detail.setReceivableDetailType(OmsReceivableReceiptDetail.ReceivableDetailTypeEnum.NORMAL_RECEIPT.getCode()); @@ -287,23 +305,40 @@ public class OmsReceivableBillServiceImpl implements IOmsReceivableBillService } List omsReceivableReceiptDetailList = detailService.listByReceivableBillIdList(idList); - Map> planMap = omsReceivableReceiptDetailList.stream().collect(Collectors.groupingBy(OmsReceivableReceiptDetail::getReceivableBillId, - Collectors.groupingBy( - item -> item.getReceiptStatus() == null ? OmsReceiptBill.ReceiptStatusEnum.WAIT_PAYMENT.getCode() : item.getReceiptStatus(), - Collectors.reducing( - BigDecimal.ZERO, - detail -> (detail.getReceiptAmount()!=null) ? detail.getReceiptAmount() : BigDecimal.ZERO, - BigDecimal::add - )))); + + Map> planMap = omsReceivableReceiptDetailList.stream().collect(Collectors.groupingBy( + OmsReceivableReceiptDetail::getReceivableBillId, + Collectors.toMap( + OmsReceivableReceiptDetail::getReceiptPlanId, + Function.identity(), + (d1, d2) -> d1.getCreateTime().after(d2.getCreateTime()) ? d1 : d2 + ) + )); + for (OmsReceivableBill bill : receivableBills) { - Map amountMap = planMap.get(bill.getId()); - if (CollUtil.isNotEmpty(amountMap)) { - //已付金额 = 已付款金额-退款金额 - bill.setReceivedAmount(amountMap.getOrDefault(OmsReceiptBill.ReceiptStatusEnum.PAYMENT.getCode(), BigDecimal.ZERO) - .subtract(amountMap.getOrDefault(OmsReceiptBill.ReceiptStatusEnum.REFUNDED.getCode(), BigDecimal.ZERO))); - //未付金额=总金额-已付金额-付款中金额 - bill.setUnreceivedAmount(bill.getTotalPriceWithTax().subtract(bill.getReceivedAmount()) - .subtract(amountMap.getOrDefault(OmsReceiptBill.ReceiptStatusEnum.WAIT_PAYMENT.getCode(), BigDecimal.ZERO))); + Map paymentDetailMap = + planMap.getOrDefault(bill.getId(), Collections.emptyMap()); + if (CollUtil.isNotEmpty(paymentDetailMap)) { + Map amountMap = + paymentDetailMap.values().stream() + .filter(d -> d.getReceiptAmount() != null) + .collect(Collectors.toMap( + OmsReceivableReceiptDetail::getReceiptStatus, + OmsReceivableReceiptDetail::getReceiptAmount, + BigDecimal::add + )); + // 4. 金额计算(集中处理,逻辑更清晰) + BigDecimal paidAmount = amountMap + .getOrDefault(OmsReceiptBill.ReceiptStatusEnum.PAYMENT.getCode(), BigDecimal.ZERO) + .add(amountMap.getOrDefault( + OmsReceiptBill.ReceiptStatusEnum.REFUNDED.getCode(), BigDecimal.ZERO)); + + BigDecimal waitPayAmount = + amountMap.getOrDefault( + OmsReceiptBill.ReceiptStatusEnum.WAIT_PAYMENT.getCode(), BigDecimal.ZERO); + bill.setReceivedAmount(paidAmount); + bill.setUnreceivedAmount(bill.getTotalPriceWithTax() .subtract(paidAmount) + .subtract(waitPayAmount)); } OmsReceivableReceiptPlan lastReceiptPlan = receiptPlanService.firstUnPayPlan(bill.getId()); bill.setLastReceiptPlanId(lastReceiptPlan == null ? -1 : lastReceiptPlan.getId()); @@ -364,11 +399,11 @@ public class OmsReceivableBillServiceImpl implements IOmsReceivableBillService } /** - * 生成应收单编号 SKY+YYMMdd+当日序列号 + * 生成应收单编号 XYS+YYMMdd+当日序列号 * @return 应收单编号 */ private String generateReceivableBillCode() { - String prefix = "SKY"; + String prefix = "XYS"; // 查询当天已有的最大序列号 String codePrefix = prefix + DateUtil.format(DateUtil.date(), DatePattern.PURE_DATE_PATTERN); int maxSequence = omsReceivableBillMapper.selectMaxCodeByPrefix(codePrefix); diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceivableReceiptDetailServiceImpl.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceivableReceiptDetailServiceImpl.java index 19c8c394..464a0847 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceivableReceiptDetailServiceImpl.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceivableReceiptDetailServiceImpl.java @@ -1,5 +1,6 @@ package com.ruoyi.sip.service.impl; +import java.math.BigDecimal; import java.util.Collections; import java.util.List; import java.util.Map; @@ -9,6 +10,8 @@ import java.util.stream.Collectors; import cn.hutool.core.collection.CollUtil; import com.ruoyi.sip.domain.OmsFinAttachment; import com.ruoyi.sip.domain.OmsPayablePaymentDetail; +import com.ruoyi.sip.domain.dto.PaymentBillPayableDetailDTO; +import com.ruoyi.sip.domain.dto.ReceiptDetailDTO; import com.ruoyi.sip.service.IOmsFinAttachmentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -130,9 +133,27 @@ public class OmsReceivableReceiptDetailServiceImpl implements IOmsReceivableRece public List listByReceivableBillIdList(List idList) { if (CollUtil.isNotEmpty(idList)){ OmsReceivableReceiptDetail omsReceivableReceiptDetail = new OmsReceivableReceiptDetail(); - omsReceivableReceiptDetail.setIdList(idList); - return omsReceivableReceiptDetailMapper.selectOmsReceivableReceiptDetailList(omsReceivableReceiptDetail); + omsReceivableReceiptDetail.setReceivableBillIdList(idList); + return omsReceivableReceiptDetailMapper.list(omsReceivableReceiptDetail); } return Collections.emptyList(); } + + @Override + public List listReceivableByReceiptBillCode(String receiptBillCode) { + List receiptDetailDTOS = omsReceivableReceiptDetailMapper.listReceivableByReceiptBillCode(Collections.singletonList(receiptBillCode)); + for (ReceiptDetailDTO detailDTO : receiptDetailDTOS) { + detailDTO.setReceiptRate(detailDTO.getReceiptAmount() + .divide(detailDTO.getTotalPriceWithTax(),4,java.math.RoundingMode.HALF_UP) + .multiply(new BigDecimal("100"))); + } + return receiptDetailDTOS; + } + + @Override + public List listByReceiptBillCode(String receiptBillCode) { + OmsReceivableReceiptDetail omsReceivableReceiptDetail = new OmsReceivableReceiptDetail(); + omsReceivableReceiptDetail.setReceiptBillCode(receiptBillCode); + return omsReceivableReceiptDetailMapper.list(omsReceivableReceiptDetail); + } } \ No newline at end of file diff --git a/ruoyi-sip/src/main/resources/mapper/OmsReceiptBill/OmsReceiptBillMapper.xml b/ruoyi-sip/src/main/resources/mapper/OmsReceiptBill/OmsReceiptBillMapper.xml index 36a68c20..68871264 100644 --- a/ruoyi-sip/src/main/resources/mapper/OmsReceiptBill/OmsReceiptBillMapper.xml +++ b/ruoyi-sip/src/main/resources/mapper/OmsReceiptBill/OmsReceiptBillMapper.xml @@ -31,109 +31,115 @@ + - - id, receipt_bill_code, receipt_bill_type, receipt_time, actual_receipt_time, partner_code, order_code, total_price_with_tax, total_price_without_tax, tax_amount, create_by, create_time, update_by, update_time, remark, del_flag, project_code, project_name, receipt_status, approve_status, approve_node, approve_time, receipt_method, receipt_account_name, receipt_bank_number, receipt_bank_open_address, bank_number, refund_status + + select + t1.id, t1.receipt_bill_code, t1.receipt_bill_type, t1.receipt_time, t1.actual_receipt_time, t1.partner_code, + t1.order_code, t1.total_price_with_tax, t1.total_price_without_tax, t1.tax_amount, t1.create_by, t1.create_time, t1.update_by, t1.update_time, t1.remark, t1.del_flag, t1.project_code, t1.project_name, t1.receipt_status, t1.approve_status, t1.approve_node, t1.approve_time, t1.receipt_method, t1.receipt_account_name, t1.receipt_bank_number, t1.receipt_bank_open_address, t1.bank_number, t1.refund_status, + t1.remaining_amount,t2.partner_name + from oms_receipt_bill t1 + left join partner_info t2 on t1.partner_code=t2.partner_code - SELECT id, receipt_bill_code, receipt_bill_type, @@ -161,7 +167,8 @@ receipt_bank_number, receipt_bank_open_address, bank_number, - refund_status + refund_status, + remaining_amount FROM oms_receipt_bill WHERE id = #{id} LIMIT 1 @@ -171,6 +178,18 @@ FROM oms_receipt_bill WHERE receipt_bill_code LIKE CONCAT(#{prefix}, '%') + @@ -258,6 +277,9 @@ refund_status, + + remaining_amount, + @@ -341,6 +363,9 @@ #{refundStatus}, + + #{remainingAmount}, + @@ -429,6 +454,9 @@ refund_status = #{refundStatus}, + + remaining_amount = #{remainingAmount}, + WHERE id = #{id} @@ -447,6 +475,9 @@ #{id} + + delete from oms_receivable_receipt_detail where receipt_bill_code=#{code} + diff --git a/ruoyi-sip/src/main/resources/mapper/sip/OmsReceivableReceiptDetailMapper.xml b/ruoyi-sip/src/main/resources/mapper/sip/OmsReceivableReceiptDetailMapper.xml index 69c26b13..99ca470d 100644 --- a/ruoyi-sip/src/main/resources/mapper/sip/OmsReceivableReceiptDetailMapper.xml +++ b/ruoyi-sip/src/main/resources/mapper/sip/OmsReceivableReceiptDetailMapper.xml @@ -18,10 +18,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + - select id, receipt_plan_id, receivable_bill_id, receipt_time, receipt_amount, receipt_rate, receipt_bill_code, remark, create_time, create_by, update_time, receivable_detail_type + select id, receipt_plan_id, receivable_bill_id, receipt_time, receipt_amount, receipt_rate, receipt_bill_code, remark, create_time, create_by, update_time, receivable_detail_type, payment_amount_without_tax, payment_amount_tax from oms_receivable_receipt_detail @@ -47,10 +49,23 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + insert into oms_receivable_receipt_detail @@ -82,6 +111,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" create_by, update_time, update_by, + payment_amount_without_tax, + payment_amount_tax, #{receiptPlanId}, @@ -96,6 +127,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{createBy}, #{updateTime}, #{updateBy}, + #{paymentAmountWithoutTax}, + #{paymentAmountTax}, @@ -112,6 +145,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" remark = #{remark}, update_time = #{updateTime}, update_by = #{updateBy}, + payment_amount_without_tax = #{paymentAmountWithoutTax}, + payment_amount_tax = #{paymentAmountTax}, where id = #{id}