From 928f17024c89d224da33e4cf7778615345ac9941 Mon Sep 17 00:00:00 2001
From: zss <zss@example.com>
Date: 星期三, 29 四月 2026 09:53:10 +0800
Subject: [PATCH] feat(procurement): 增加产品自定义入库功能及缺货信息支持

---
 src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java    |    7 ++
 src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java          |    2 
 src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml                  |   77 +++++++++++++++++--------
 src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java |   38 ++++++++++--
 src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordStorage.java             |   12 ++++
 src/main/java/com/ruoyi/procurementrecord/dto/Details.java                               |   11 +++
 6 files changed, 115 insertions(+), 32 deletions(-)

diff --git a/src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java b/src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java
index 7fb7b44..26c1873 100644
--- a/src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java
+++ b/src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java
@@ -44,6 +44,13 @@
         return AjaxResult.success(procurementRecordService.add(procurementDto));
     }
 
+    @PostMapping("/addProduct")
+    @Log(title = "鍏ュ簱绠$悊-浜у搧鍏ュ簱", businessType = BusinessType.INSERT)
+    @Transactional
+    public AjaxResult addProduct(@RequestBody Details detail) {
+        return AjaxResult.success(procurementRecordService.addProduct(detail));
+    }
+
     @PostMapping("/update")
     @Log(title = "閲囪喘鍏ュ簱-鍏ュ簱绠$悊-淇敼鍏ュ簱", businessType = BusinessType.UPDATE)
     @Transactional
diff --git a/src/main/java/com/ruoyi/procurementrecord/dto/Details.java b/src/main/java/com/ruoyi/procurementrecord/dto/Details.java
index b2e5a21..b9d7dbc 100644
--- a/src/main/java/com/ruoyi/procurementrecord/dto/Details.java
+++ b/src/main/java/com/ruoyi/procurementrecord/dto/Details.java
@@ -13,4 +13,15 @@
     private Integer id;
     private BigDecimal inboundQuantity;
     private BigDecimal warnNum;
+    private Long productModelId;
+
+    /**
+     * 缂鸿揣鏁伴噺
+     */
+    private BigDecimal outStockQuantity;
+
+    /**
+     * 缂鸿揣鎯呭喌
+     */
+    private String shortageDescription;
 }
diff --git a/src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordStorage.java b/src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordStorage.java
index 28cee3c..7c4df40 100644
--- a/src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordStorage.java
+++ b/src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordStorage.java
@@ -46,6 +46,16 @@
 //    private BigDecimal minStock;
 
     /**
+     * 缂鸿揣鏁伴噺
+     */
+    private BigDecimal outStockQuantity;
+
+    /**
+     * 缂鸿揣鎯呭喌
+     */
+    private String shortageDescription;
+
+    /**
      * 鍏ュ簱鐢ㄦ埛
      */
     private String createBy;
@@ -76,4 +86,6 @@
      */
     @TableField(fill = FieldFill.INSERT)
     private Long tenantId;
+
+    private Long productModelId;
 }
diff --git a/src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java b/src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java
index 79603ae..aee2727 100644
--- a/src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java
+++ b/src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java
@@ -34,4 +34,6 @@
     void exportCopy(HttpServletResponse response);
 
     Map<String, Object> getReportList(Page page, ProcurementPageDto procurementDto);
+
+    int addProduct(Details detail);
 }
diff --git a/src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java b/src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java
index 1675069..8bf0cad 100644
--- a/src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java
+++ b/src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java
@@ -10,8 +10,8 @@
 import com.ruoyi.procurementrecord.dto.*;
 import com.ruoyi.procurementrecord.mapper.ProcurementRecordMapper;
 import com.ruoyi.procurementrecord.mapper.ProcurementRecordOutMapper;
-import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage;
 import com.ruoyi.procurementrecord.pojo.ProcurementRecordOut;
+import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage;
 import com.ruoyi.procurementrecord.service.ProcurementRecordService;
 import com.ruoyi.project.system.domain.SysUser;
 import com.ruoyi.project.system.mapper.SysUserMapper;
@@ -24,10 +24,12 @@
 
 import javax.servlet.http.HttpServletResponse;
 import java.math.BigDecimal;
-import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 /**
@@ -65,18 +67,18 @@
             List<ProcurementRecordStorage> collect1 = procurementRecordStorages.stream()
                     .filter(procurementRecordStorage -> procurementRecordStorage.getSalesLedgerProductId().equals(dto.getId()))
                     .collect(Collectors.toList());
-            
+
             // 濡傛灉娌℃湁鐩稿叧鐨勫叆搴撹褰曪紝璺宠繃璇ユ潯鏁版嵁
             if(CollectionUtils.isEmpty(collect1)){
                 dto.setQuantity0(dto.getQuantity());
                 continue;
             }
-            
+
             // 璁$畻宸插叆搴撴暟閲忔�诲拰锛屽苟璁剧疆寰呭叆搴撴暟閲�
             BigDecimal totalInboundNum = collect1.stream()
                     .map(ProcurementRecordStorage::getInboundNum)
                     .reduce(BigDecimal.ZERO, BigDecimal::add);
-            
+
             // 寰呭叆搴撴暟閲� = 鎬绘暟閲� - 宸插叆搴撴暟閲�
             dto.setQuantity0(dto.getQuantity().subtract(totalInboundNum));
         }
@@ -370,6 +372,30 @@
     }
 
     @Override
+    public int addProduct(Details detail) {
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+
+        ProcurementRecordStorage.ProcurementRecordStorageBuilder builder = ProcurementRecordStorage.builder()
+                .id(detail.getId())
+                .inboundBatches("绗�1鎵规")
+                .inboundNum(detail.getInboundQuantity())
+                .warnNum(detail.getWarnNum())
+                .outStockQuantity(detail.getOutStockQuantity())
+                .shortageDescription(detail.getShortageDescription())
+                .productModelId(detail.getProductModelId())
+                .updateTime(LocalDateTime.now())
+                .updateUser(loginUser.getUserId());
+        if (detail.getId() == null) {
+            builder.createTime(LocalDateTime.now())
+                    .createUser(loginUser.getUserId())
+                    .createBy(loginUser.getNickName());
+        }
+
+        boolean success = this.saveOrUpdate(builder.build());
+        return success ? 1 : 0;
+    }
+
+    @Override
     public IPage<ProcurementPageDto> listPage(Page page, ProcurementPageDto procurementDto) {
         IPage<ProcurementPageDto> procurementPageDtoIPage = procurementRecordMapper.listPage(page, procurementDto);
         List<ProcurementPageDto> procurementPageDtos = procurementPageDtoIPage.getRecords();
diff --git a/src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml b/src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml
index b303d28..88324b1 100644
--- a/src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml
+++ b/src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml
@@ -29,37 +29,48 @@
         group by t2.id
     </select>
     <select id="listPage" resultType="com.ruoyi.procurementrecord.dto.ProcurementPageDto">
-        select
+         select
         t3.supplier_name,
         t3.purchase_contract_number,
-        t2.product_category,
+        case when t2.product_category is null then t5.product_name
+        else t2.product_category end as productCategory,
         t1.id,
         t1.sales_ledger_product_id,
+        t1.product_model_id,
         t1.create_user,
-        t2.specification_model,
-        t2.product_model_id,
-        t2.unit,
+        case when t2.specification_model is null then t4.model
+        else t2.specification_model end as specificationModel,
+        case when t2.unit is null then t4.unit
+        else t2.unit end as unit,
         t2.tax_rate,
         t2.tax_inclusive_unit_price,
         (t1.inbound_num * t2.tax_inclusive_unit_price) as taxInclusiveTotalPrice,
-        (t1.inbound_num * t2.tax_inclusive_unit_price - t1.inbound_num * t2.tax_inclusive_unit_price * t2.tax_rate / 100) as taxExclusiveTotalPrice,
+        (t1.inbound_num * t2.tax_inclusive_unit_price - t1.inbound_num * t2.tax_inclusive_unit_price * t2.tax_rate /
+        100) as taxExclusiveTotalPrice,
         t1.inbound_batches,
         t1.inbound_num,
         t1.inbound_num as inboundNum0,
         t1.create_time,
         t1.update_time,
         t1.create_by,
-        ifnull(t1.warn_num, t2.warn_num) as warnNum
-        from  procurement_record_storage t1
-                  left join sales_ledger_product t2 on t2.id = t1.sales_ledger_product_id
-                  left join purchase_ledger t3 on t3.id = t2.sales_ledger_id
+         ifnull(t1.warn_num, t2.warn_num) as warnNum,
+        t1.out_stock_quantity as outStockQuantity,
+        t1.shortage_description as shortageDescription
+        from procurement_record_storage t1
+        left join sales_ledger_product t2 on t2.id = t1.sales_ledger_product_id
+        left join purchase_ledger t3 on t3.id = t2.sales_ledger_id
+        left join product_model t4 on t4.id = t1.product_model_id
+        left join product t5 on t5.id = t4.product_id
         <where>
             1 = 1
             <if test="req.supplierName != null and req.supplierName != ''">
-                and t3.supplier_name like  concat('%',#{req.supplierName},'%')
+                and t3.supplier_name like concat('%',#{req.supplierName},'%')
             </if>
             <if test="req.timeStr != null and req.timeStr != ''">
-                and t1.create_time like  concat('%',#{req.timeStr},'%')
+                and t1.create_time like concat('%',#{req.timeStr},'%')
+            </if>
+            <if test="req.productModelId != null">
+                and t1.product_model_id = #{req.productModelId}
             </if>
         </where>
     </select>
@@ -87,41 +98,47 @@
                   left join purchase_ledger t3 on t3.id = t2.sales_ledger_id
     </select>
     <select id="listPageCopy" resultType="com.ruoyi.procurementrecord.dto.ProcurementPageDtoCopy">
-        select
-        t3.supplier_name,
+         select
+        t3.supplier_name as supplierName,
         t3.purchase_contract_number,
-        t2.product_category,
-        t1.id,
+        case when t2.product_category is null then t5.product_name
+        else t2.product_category end as productCategory,
+        max(t1.id) as id,
         t1.sales_ledger_product_id,
         t1.create_user,
-        t2.specification_model,
-        t2.unit,
+        case when t2.specification_model is null then t4.model
+        else t2.specification_model end as specificationModel,
+        case when t2.unit is null then t4.unit
+        else t2.unit end as unit,
         t2.min_stock,
         t2.tax_rate,
         t2.tax_inclusive_unit_price,
         t2.tax_inclusive_total_price,
         t2.tax_exclusive_total_price,
-        t1.inbound_batches,
+        group_concat(t1.inbound_batches) as inbound_batches,
         sum(t1.inbound_num) as inboundNum,
         sum(t1.inbound_num) as inboundNum0,
-        t1.inbound_num as totalInboundNum,
-        t1.create_time,
-        t1.update_time,
+        sum(t1.inbound_num) as totalInboundNum,
+        max(t1.create_time) as create_time,
+        max(t1.update_time) as update_time,
         t1.create_by,
         ifnull(t1.warn_num, t2.warn_num) as warnNum
         from  procurement_record_storage t1
         left join sales_ledger_product t2 on t2.id = t1.sales_ledger_product_id
         left join purchase_ledger t3 on t3.id = t2.sales_ledger_id
+        left join product_model t4 on t4.id = t1.product_model_id
+        left join product t5 on t5.id = t4.product_id
         <where>
             1 = 1
             <if test="req.supplierName != null and req.supplierName != ''">
-                and t3.supplier_name like  concat('%',#{req.supplierName},'%')
+                and t3.supplier_name like concat('%',#{req.supplierName},'%')
             </if>
             <if test="req.timeStr != null and req.timeStr != ''">
-                and t1.create_time like  concat('%',#{req.timeStr},'%')
+                and t1.create_time like concat('%',#{req.timeStr},'%')
             </if>
             <if test="req.reportDate != null">
-                and t1.create_time >= #{req.reportDate} and t1.create_time &lt; DATE_ADD(#{req.reportDate}, INTERVAL 1 DAY)
+                and t1.create_time >= #{req.reportDate} and t1.create_time &lt; DATE_ADD(#{req.reportDate}, INTERVAL 1
+                DAY)
             </if>
             <if test="req.startMonth != null">
                 and t1.create_time >= #{req.startMonth}
@@ -136,7 +153,15 @@
                 and t1.create_time &lt;= #{req.endDate}
             </if>
         </where>
-        group by t3.supplier_name,t2.product_category,t2.specification_model
+        group by
+        t3.supplier_name,
+        t3.purchase_contract_number,
+        productCategory,
+        specificationModel,
+        unit
+        order by
+        (t3.supplier_name IS NULL) DESC,
+        t3.supplier_name ASC
     </select>
     <select id="listCopy" resultType="com.ruoyi.procurementrecord.dto.ProcurementPageDtoCopy">
         select

--
Gitblit v1.9.3