From fe64e0bbc83ab7e89cbe0d6a9f779a4ac3919608 Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期一, 21 九月 2026 11:13:58 +0800
Subject: [PATCH] fix: 销售订单未下发/发货则可以进行编辑

---
 src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java |   53 +++++++++++++++--
 src/main/resources/mapper/sales/SalesLedgerMapper.xml                         |   16 +++++
 src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java           |   28 +++++----
 src/main/java/com/ruoyi/sales/mapper/SalesLedgerMapper.java                   |    9 +++
 src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java        |   12 ++++
 src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java                |    9 +++
 6 files changed, 107 insertions(+), 20 deletions(-)

diff --git a/src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java b/src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
index 33ab62f..048cffc 100644
--- a/src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
+++ b/src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
@@ -14,6 +14,7 @@
 import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.framework.web.page.TableDataInfo;
 import com.ruoyi.sales.dto.SalesLedgerDto;
+import com.ruoyi.sales.dto.SalesLedgerEditFlagDto;
 import com.ruoyi.sales.pojo.SalesLedger;
 import com.ruoyi.sales.service.ICommonFileService;
 import com.ruoyi.sales.service.ISalesLedgerService;
@@ -246,23 +247,20 @@
         //  鑾峰彇褰撳墠椤垫墍鏈夊彴璐﹁褰曠殑 ID 闆嗗悎
         List<Long> salesLedgerIds = iPage.getRecords().stream().map(SalesLedger::getId).collect(Collectors.toList());
 
-
-
-
-        //  杞崲鍥炴鏁版嵁, key 涓哄彴璐D, value 涓鸿鍙拌处鐨勬�诲洖娆鹃噾棰�
-        Map<Long, BigDecimal> receiptTotals = new HashMap<>();
-
+        //  鎵归噺鏌ヨ姣忎釜鍙拌处鐨勭紪杈戦檺鍒舵爣璁帮細鏄惁鍚渶瑕佺敓浜х殑浜у搧銆佺敓浜ц鍒掓槸鍚﹀凡涓嬪彂銆佹槸鍚﹀凡鍙戣揣
+        Map<Long, SalesLedgerEditFlagDto> editFlags = salesLedgerService.getEditFlags(salesLedgerIds);
 
         for (SalesLedgerVo salesLedgerVo : iPage.getRecords()) {
             Long ledgerId = salesLedgerVo.getId();
-            // 鍚堝悓鎬婚噾棰�
-            BigDecimal contractAmount = salesLedgerVo.getContractAmount() == null ? BigDecimal.ZERO : salesLedgerVo.getContractAmount();
-            // 寮�绁ㄦ�婚鍜屽洖娆炬�婚
-            BigDecimal receiptPaymentAmountTotal = receiptTotals.getOrDefault(ledgerId, BigDecimal.ZERO);
+            SalesLedgerEditFlagDto editFlag = editFlags.get(ledgerId);
+            boolean needsProduction = isFlagTrue(editFlag == null ? null : editFlag.getNeedsProduction());
+            boolean planIssued = isFlagTrue(editFlag == null ? null : editFlag.getPlanIssued());
+            boolean shipped = isFlagTrue(editFlag == null ? null : editFlag.getShipped());
 
-            //  濡傛灉宸茬粡鏈夎繃寮�绁ㄦ垨鍥炴鎿嶄綔,鍒欎笉鍏佽缂栬緫
-            boolean hasReceiptOperation = receiptPaymentAmountTotal.compareTo(BigDecimal.ZERO) > 0;
-            salesLedgerVo.setIsEdit(hasReceiptOperation);
+            //  闇�瑕佺敓浜х殑璁㈠崟锛氱敓浜ц鍒掑凡涓嬪彂锛堝惈閮ㄥ垎涓嬪彂锛夊垯涓嶅厑璁哥紪杈�
+            //  璧板簱瀛樼殑璁㈠崟锛氬凡鍙戣揣鍒欎笉鍏佽缂栬緫锛屽惁鍒欏彲浠ョ紪杈�
+            salesLedgerVo.setIsEdit(needsProduction ? !planIssued : !shipped);
+            salesLedgerVo.setHasProductionRecord(planIssued);
 
             salesLedgerVo.setStorageBlobVOs(fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum.FILE, RecordTypeEnum.SALES_LEDGER, ledgerId));
         }
@@ -291,4 +289,8 @@
         }
         return AjaxResult.success(data);
     }
+
+    private boolean isFlagTrue(Integer flag) {
+        return flag != null && flag == 1;
+    }
 }
diff --git a/src/main/java/com/ruoyi/sales/mapper/SalesLedgerMapper.java b/src/main/java/com/ruoyi/sales/mapper/SalesLedgerMapper.java
index 0270328..625d615 100644
--- a/src/main/java/com/ruoyi/sales/mapper/SalesLedgerMapper.java
+++ b/src/main/java/com/ruoyi/sales/mapper/SalesLedgerMapper.java
@@ -8,6 +8,7 @@
 import com.ruoyi.home.dto.IncomeExpenseAnalysisDto;
 import com.ruoyi.purchase.vo.PurchaseReportVo;
 import com.ruoyi.sales.dto.SalesLedgerDto;
+import com.ruoyi.sales.dto.SalesLedgerEditFlagDto;
 import com.ruoyi.sales.dto.SalesTrendDto;
 import com.ruoyi.sales.dto.StatisticsTableDto;
 import com.ruoyi.sales.pojo.SalesLedger;
@@ -91,4 +92,12 @@
 
     IPage<PurchaseReportVo> selectPurchaseReportVoPage(Page page, @Param("customerName") String customerName);
 
+    /**
+     * 鎵归噺鏌ヨ閿�鍞彴璐︾殑缂栬緫闄愬埗鏍囪
+     *
+     * @param ids 閿�鍞彴璐d闆嗗悎
+     * @return 姣忎釜鍙拌处鐨勯渶瑕佺敓浜�/鐢熶骇璁″垝宸蹭笅鍙�/宸插彂璐ф爣璁�
+     */
+    List<SalesLedgerEditFlagDto> selectEditFlags(@Param("ids") List<Long> ids);
+
 }
diff --git a/src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java b/src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java
index bffc3d4..1e448ef 100644
--- a/src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java
+++ b/src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java
@@ -9,6 +9,7 @@
 import com.ruoyi.sales.dto.LossProductModelDto;
 import com.ruoyi.sales.dto.MonthlyAmountDto;
 import com.ruoyi.sales.dto.SalesLedgerDto;
+import com.ruoyi.sales.dto.SalesLedgerEditFlagDto;
 import com.ruoyi.sales.pojo.SalesLedger;
 import com.ruoyi.sales.pojo.SalesLedgerProduct;
 import com.ruoyi.sales.vo.SalesLedgerVo;
@@ -58,4 +59,12 @@
     IPage<SalesLedgerDto> listSalesLedger(SalesLedgerDto salesLedgerDto, Page page);
 
     Map<String, Object> getPrintData(Long id);
+
+    /**
+     * 鎵归噺鏌ヨ閿�鍞彴璐︾殑缂栬緫闄愬埗鏍囪锛宬ey涓洪攢鍞彴璐d
+     *
+     * @param ids 閿�鍞彴璐d闆嗗悎
+     * @return 缂栬緫闄愬埗鏍囪
+     */
+    Map<Long, SalesLedgerEditFlagDto> getEditFlags(List<Long> ids);
 }
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
index 28ce78a..38013f1 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -4,6 +4,7 @@
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.AmountUtils;
 import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.procurementrecord.utils.StockUtils;
@@ -38,6 +39,7 @@
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
@@ -177,12 +179,9 @@
             result = salesLedgerProductMapper.insert(salesLedgerProduct);
             addProductionData(salesLedgerProduct);
         } else {
-            //鏌ヨ鍘熸湰鐨勪骇鍝佸瀷鍙穒d
             result = salesLedgerProductMapper.updateById(salesLedgerProduct);
-            /*鍒犻櫎瀵瑰簲鐨勭敓浜ф暟鎹苟閲嶆柊鏂板*/
-            deleteProductionData(Arrays.asList(salesLedgerProduct.getId()));
-
-            addProductionData(salesLedgerProduct);
+            /*鍚屾瀵瑰簲鐨勭敓浜ф暟鎹細璁″垝鏈笅鍙戞椂鍘熷湴鏇存柊闇�姹傛暟閲忥紝淇濈暀鐢熶骇璁″垝鍙�*/
+            syncProductionData(salesLedgerProduct);
         }
 
         // 濡傛灉鎻掑叆鎴栨洿鏂版垚鍔燂紝骞朵笖鏈� salesLedgerId锛屾墠缁х画鏇存柊涓昏〃閲戦
@@ -238,6 +237,38 @@
     }
 
     /**
+     * 鍚屾鐢熶骇鏁版嵁
+     * 闇�瑕佺敓浜э細鐢熶骇璁″垝宸蹭笅鍙戞椂绂佹淇敼锛涙湭涓嬪彂鏃跺師鍦版洿鏂伴渶姹傛暟閲忥紝淇濈暀鐢熶骇璁″垝鍙凤紱
+     * 鏀逛负璧板簱瀛橈細鍒犻櫎鏈笅鍙戠殑鐢熶骇璁″垝銆�
+     */
+    public void syncProductionData(SalesLedgerProduct salesLedgerProduct) {
+        if (salesLedgerProduct.getId() == null) {
+            return;
+        }
+        List<ProductionPlan> productionPlans = listProductionData(salesLedgerProduct.getId());
+        if (CollectionUtils.isEmpty(productionPlans)) {
+            //鍘熸潵涓嶉渶瑕佺敓浜э紝鐜板湪鏀逛负闇�瑕佺敓浜э紝琛ュ缓鐢熶骇璁″垝
+            if (Boolean.TRUE.equals(salesLedgerProduct.getIsProduction())) {
+                addProductionData(salesLedgerProduct);
+            }
+            return;
+        }
+        //鏀逛负璧板簱瀛橈紝鍒犻櫎鏈笅鍙戠殑鐢熶骇璁″垝
+        if (!Boolean.TRUE.equals(salesLedgerProduct.getIsProduction())) {
+            deleteProductionData(Collections.singletonList(salesLedgerProduct.getId()));
+            return;
+        }
+        if (productionPlans.stream().anyMatch(plan -> plan.getStatus() != null && plan.getStatus() != 0)) {
+            throw new ServiceException("鐢熶骇璁″垝宸蹭笅鍙戯紝涓嶈兘淇敼璇ラ攢鍞骇鍝�");
+        }
+        for (ProductionPlan productionPlan : productionPlans) {
+            productionPlan.setQtyRequired(salesLedgerProduct.getQuantity());
+            productionPlan.setProductModelId(salesLedgerProduct.getProductModelId());
+            productionPlanMapper.updateById(productionPlan);
+        }
+    }
+
+    /**
      * 鍒犻櫎鐢熶骇璁″垝
      */
     public void deleteProductionData(List<Long> productIds) {
@@ -246,12 +277,12 @@
         }
         List<ProductionPlan> productionPlans = productionPlanMapper.selectList(
                 new LambdaQueryWrapper<ProductionPlan>()
-                        .in(ProductionPlan::getSalesLedgerProductId, productIds.stream().map(Long::intValue).collect(Collectors.toList())));
+                        .in(ProductionPlan::getSalesLedgerProductId, productIds));
         if (CollectionUtils.isEmpty(productionPlans)) {
             return;
         }
         //濡傛灉鐢熶骇璁″垝宸蹭笅鍙戝垯涓嶈兘鍒犻櫎
-        if (productionPlans.stream().anyMatch(productionPlan -> productionPlan.getStatus() != 0)) {
+        if (productionPlans.stream().anyMatch(productionPlan -> productionPlan.getStatus() != null && productionPlan.getStatus() != 0)) {
             throw new RuntimeException("鐢熶骇璁″垝宸蹭笅鍙戯紝涓嶈兘鍒犻櫎璇ラ攢鍞骇鍝�");
         }
         List<Long> ids = productionPlans.stream().map(ProductionPlan::getId).collect(Collectors.toList());
@@ -259,6 +290,14 @@
     }
 
     /**
+     * 鏌ヨ閿�鍞骇鍝佸搴旂殑鐢熶骇璁″垝
+     */
+    private List<ProductionPlan> listProductionData(Long productId) {
+        return productionPlanMapper.selectList(new LambdaQueryWrapper<ProductionPlan>()
+                .eq(ProductionPlan::getSalesLedgerProductId, productId));
+    }
+
+    /**
      * 閫氱敤鏂规硶锛氭牴鎹富琛↖D鍜屽瓙琛ㄥ垪琛紝鏇存柊涓昏〃鐨勫悎鍚岄噾棰�
      */
     public <T, S> void updateMainContractAmount(
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
index 50975fd..170bd12 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -800,4 +800,16 @@
         result.put("ledger", ledger);
         return result;
     }
+
+    @Override
+    public Map<Long, SalesLedgerEditFlagDto> getEditFlags(List<Long> ids) {
+        if (CollectionUtils.isEmpty(ids)) {
+            return new HashMap<>();
+        }
+        List<SalesLedgerEditFlagDto> flags = salesLedgerMapper.selectEditFlags(ids);
+        return flags.stream().collect(Collectors.toMap(
+                SalesLedgerEditFlagDto::getSalesLedgerId,
+                Function.identity(),
+                (existing, replacement) -> existing));
+    }
 }
diff --git a/src/main/resources/mapper/sales/SalesLedgerMapper.xml b/src/main/resources/mapper/sales/SalesLedgerMapper.xml
index 8b41173..21efa49 100644
--- a/src/main/resources/mapper/sales/SalesLedgerMapper.xml
+++ b/src/main/resources/mapper/sales/SalesLedgerMapper.xml
@@ -147,6 +147,22 @@
         order by sl.execution_date desc
     </select>
 
+    <select id="selectEditFlags" resultType="com.ruoyi.sales.dto.SalesLedgerEditFlagDto">
+        SELECT T1.id AS salesLedgerId,
+        MAX(CASE WHEN T2.is_production = 1 THEN 1 ELSE 0 END) AS needsProduction,
+        MAX(CASE WHEN T3.status IS NOT NULL AND T3.status &lt;&gt; 0 THEN 1 ELSE 0 END) AS planIssued,
+        MAX(CASE WHEN T4.status IN ('瀹℃牳閫氳繃', '宸插彂璐�') THEN 1 ELSE 0 END) AS shipped
+        FROM sales_ledger T1
+        LEFT JOIN sales_ledger_product T2 ON T2.sales_ledger_id = T1.id AND T2.type = 1
+        LEFT JOIN production_plan T3 ON T3.sales_ledger_product_id = T2.id
+        LEFT JOIN shipping_info T4 ON T4.sales_ledger_product_id = T2.id
+        WHERE T1.id IN
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+        GROUP BY T1.id
+    </select>
+
     <select id="selectPurchaseReportVoPage" resultType="com.ruoyi.purchase.vo.PurchaseReportVo">
         select sl.sales_contract_no customerContractNo,
                c.customer_name,

--
Gitblit v1.9.3