From 43fc48a3a5d3dac9883f012aec3cc1dcb7cd4eb3 Mon Sep 17 00:00:00 2001 From: jiangpeng Date: Mon, 17 Aug 2026 17:50:06 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=E5=BA=94=E4=BB=98=E5=8D=95?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E6=95=B0=E6=8D=AE=E5=86=85=E5=AE=B9=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../finance/payable/components/EditForm.vue | 40 +++++-- .../com/ruoyi/sip/domain/OmsPayableBill.java | 3 + .../sip/domain/dto/PayableGoodsDetailDto.java | 32 ++++++ .../impl/OmsPayableBillServiceImpl.java | 106 ++++++++++++++++++ 4 files changed, 174 insertions(+), 7 deletions(-) create mode 100644 ruoyi-sip/src/main/java/com/ruoyi/sip/domain/dto/PayableGoodsDetailDto.java diff --git a/oms_web/oms_vue/src/views/finance/payable/components/EditForm.vue b/oms_web/oms_vue/src/views/finance/payable/components/EditForm.vue index 4f6c2271..2ecc5b0a 100644 --- a/oms_web/oms_vue/src/views/finance/payable/components/EditForm.vue +++ b/oms_web/oms_vue/src/views/finance/payable/components/EditForm.vue @@ -1,6 +1,6 @@ + + + 采购-收票单 @@ -181,11 +206,6 @@ - - - - - @@ -251,6 +271,7 @@ export default { internalVisible: this.visible, // Local copy of the visible prop activeTab: 'details', formData: {}, + loading: false, // 数据加载蒙层 paymentDetailOpen: false, paymentDetailData: {}, receiptDetailOpen: false, @@ -276,8 +297,13 @@ export default { this.$refs.ticketPlan.fetchTicketPlans(this.formData.id); }, getDetails() { + this.loading = true; getPayable(this.data.id).then(res => { this.formData = res.data; + }).catch(() => { + this.$modal.msgError("数据加载失败"); + }).finally(() => { + this.loading = false; }); }, handlePreview(attachment) { diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsPayableBill.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsPayableBill.java index 20c2fad4..6861aa61 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsPayableBill.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsPayableBill.java @@ -5,6 +5,7 @@ import java.util.Date; import java.util.List; import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.sip.domain.dto.PayableGoodsDetailDto; import lombok.*; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; @@ -119,6 +120,8 @@ public class OmsPayableBill extends BaseEntity private List detailList; private List ticketDetailList; + /** 商品明细(来源:入库单) */ + private List goodsDetailList; diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/dto/PayableGoodsDetailDto.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/dto/PayableGoodsDetailDto.java new file mode 100644 index 00000000..e109de27 --- /dev/null +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/dto/PayableGoodsDetailDto.java @@ -0,0 +1,32 @@ +package com.ruoyi.sip.domain.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 应付单商品明细DTO(来源:入库单) + * + * @author ruoyi + */ +@Data +public class PayableGoodsDetailDto { + /** 产品类型 */ + private String productType; + /** 产品编码 */ + private String productCode; + /** 产品型号 */ + private String productModel; + /** 产品描述 */ + private String productDescription; + /** 数量 */ + private Long quantity; + /** 单位 */ + private String unit; + /** 单价 */ + private BigDecimal price; + /** 税率 */ + private BigDecimal taxRate; + /** 含税小计 */ + private BigDecimal amountTotal; +} diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsPayableBillServiceImpl.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsPayableBillServiceImpl.java index 2e9f9659..0004a4d0 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsPayableBillServiceImpl.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsPayableBillServiceImpl.java @@ -13,8 +13,12 @@ import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.sip.domain.*; import com.ruoyi.sip.domain.dto.MergedPaymentDataDto; import com.ruoyi.sip.domain.dto.MergedReceiptDataDto; +import com.ruoyi.sip.domain.dto.PayableGoodsDetailDto; import com.ruoyi.sip.domain.dto.PayableOrderDto; import com.ruoyi.sip.domain.dto.PayableOrderReceiptDto; +import com.ruoyi.sip.mapper.InventoryInfoMapper; +import com.ruoyi.sip.mapper.InventoryOuterMapper; +import com.ruoyi.sip.mapper.OmsInventoryInnerMapper; import com.ruoyi.sip.mapper.OmsPayableBillMapper; import com.ruoyi.sip.mapper.OmsPayablePaymentPlanMapper; import com.ruoyi.sip.mapper.OmsPayableTicketPlanMapper; @@ -59,6 +63,15 @@ public class OmsPayableBillServiceImpl implements IOmsPayableBillService { @Autowired private IOmsPayableTicketDetailService omsPayableTicketDetailService; + + @Autowired + private OmsInventoryInnerMapper omsInventoryInnerMapper; + + @Autowired + private InventoryInfoMapper inventoryInfoMapper; + + @Autowired + private InventoryOuterMapper inventoryOuterMapper; @Value("${oms.inventory.innerTax:0.13}") private String defaultTax; /** @@ -550,10 +563,103 @@ public class OmsPayableBillServiceImpl implements IOmsPayableBillService { List omsPaymentBills = omsPaymentBillService.listPreResidueAmountByVendorCodeList(Collections.singletonList(omsPayableBill.getVendorCode())); Map decimalMap = omsPaymentBills.stream().filter(item -> item.getPreResidueAmount() != null).collect(Collectors.toMap(OmsPaymentBill::getVendorCode, OmsPaymentBill::getPreResidueAmount, BigDecimal::add)); omsPayableBill.setPreResidueAmount(decimalMap.getOrDefault(omsPayableBill.getVendorCode(), BigDecimal.ZERO)); + // 商品明细(来源:入库单) + omsPayableBill.setGoodsDetailList(queryGoodsDetailList(omsPayableBill.getInventoryCode())); return omsPayableBill; } + /** + * 通过入库/出库单号查询应付单商品明细 + * inventoryCode 可能为入库单号(inner_code)或出库单号(outer_code) + * + * @param inventoryCode 入库/出库单号 + * @return 商品明细列表 + */ + private List queryGoodsDetailList(String inventoryCode) { + if (StringUtils.isEmpty(inventoryCode)) { + return Collections.emptyList(); + } + // 入库单来源 + List inventoryInners = omsInventoryInnerMapper.selectOmsInventoryInnerByInnerCodeList(Collections.singletonList(inventoryCode)); + if (CollUtil.isNotEmpty(inventoryInners)) { + OmsInventoryInner inventoryInner = inventoryInners.get(0); + List inventoryInfoList = inventoryInfoMapper.selectInventoryInfoByInnerCodeList(Collections.singletonList(inventoryCode)); + // 产品类型为3(服务)/22(硬件维保)时 含税小计 = 单价 × 数量,其他为入库价合计 + boolean multiplyQuantity = Arrays.asList("3", "22").contains(inventoryInner.getProductType()); + BigDecimal taxRate = inventoryInner.getTaxRate() != null ? inventoryInner.getTaxRate() : defaultTaxRate(); + return buildGoodsDetailList(inventoryInner.getProductType(), taxRate, inventoryInfoList, multiplyQuantity); + } + // 出库单来源 + InventoryOuter inventoryOuter = inventoryOuterMapper.selectInventoryOuterByCode(inventoryCode); + if (inventoryOuter != null) { + List inventoryInfoList = inventoryInfoMapper.selectInventoryInfoByOuterCodeList(Collections.singletonList(inventoryCode)); + if (CollUtil.isEmpty(inventoryInfoList)) { + return Collections.emptyList(); + } + String productType = inventoryInfoList.get(0).getProductType(); + BigDecimal taxRate = inventoryInfoList.get(0).getTaxRate() != null ? inventoryInfoList.get(0).getTaxRate() : defaultTaxRate(); + // 出库单生成的应付单:含税小计直接为入库价合计,不乘数量 + return buildGoodsDetailList(productType, taxRate, inventoryInfoList, false); + } + return Collections.emptyList(); + } + + /** + * 按产品编码分组组装商品明细 + * + * @param productType 产品类型 + * @param taxRate 税率(小数) + * @param inventoryInfoList 库存明细 + * @param multiplyQuantity 是否 含税小计 = 单价 × 数量 + * @return 商品明细列表 + */ + private List buildGoodsDetailList(String productType, BigDecimal taxRate, + List inventoryInfoList, + boolean multiplyQuantity) { + if (CollUtil.isEmpty(inventoryInfoList)) { + return Collections.emptyList(); + } + // 按产品编码分组(同一单据可能存在多行SN明细) + Map> groupMap = inventoryInfoList.stream() + .filter(item -> StringUtils.isNotEmpty(item.getProductCode())) + .collect(Collectors.groupingBy(InventoryInfo::getProductCode)); + List goodsDetailList = new ArrayList<>(); + for (Map.Entry> entry : groupMap.entrySet()) { + List infos = entry.getValue(); + InventoryInfo first = infos.get(0); + PayableGoodsDetailDto dto = new PayableGoodsDetailDto(); + dto.setProductType(productType); + dto.setProductCode(entry.getKey()); + dto.setProductModel(first.getModel()); + dto.setProductDescription(first.getProductDesc()); + dto.setQuantity((long) infos.size()); + dto.setUnit("个"); + dto.setPrice(first.getInnerPrice()); + dto.setTaxRate(taxRate); + if (multiplyQuantity) { + dto.setAmountTotal(first.getInnerPrice() == null ? BigDecimal.ZERO + : first.getInnerPrice().multiply(new BigDecimal(infos.size()))); + } else { + dto.setAmountTotal(infos.stream().map(InventoryInfo::getInnerPrice).filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add)); + } + goodsDetailList.add(dto); + } + return goodsDetailList; + } + + /** + * 默认税率(小数) + */ + private BigDecimal defaultTaxRate() { + try { + return new BigDecimal(defaultTax); + } catch (Exception e) { + return new BigDecimal("0.13"); + } + } + @Override public List checkDelete(List inventoryCodeList) { return omsPayableBillMapper.checkDelete(inventoryCodeList);