From 641206421e76861db238ecf24094b2a04e7c6371 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期三, 26 八月 2026 15:50:26 +0800
Subject: [PATCH] feat(account): 新增付款和回款功能并优化生产计划下发规则

---
 src/main/java/com/ruoyi/production/service/impl/ProductionPlanServiceImpl.java |   95 ++++++++---------------------------------------
 1 files changed, 16 insertions(+), 79 deletions(-)

diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionPlanServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionPlanServiceImpl.java
index 8c885cd..b3f424d 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionPlanServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionPlanServiceImpl.java
@@ -61,9 +61,8 @@
      * 鍚堝苟鐢熶骇璁″垝骞朵笅鍙戠敓浜ц鍗曘��
      * 绾︽潫锛�
      * 1. 浠呭厑璁稿悓涓�浜у搧鍨嬪彿鐨勮鍒掑悎骞讹紱
-     * 2. 宸蹭笅鍙戞垨閮ㄥ垎涓嬪彂鐨勮鍒掍笉鍏佽鍐嶆鍚堝苟锛�
-     * 3. 涓嬪彂鏁伴噺涓嶈兘澶т簬鎵�閫夎鍒掑墿浣欓渶姹傛�婚噺锛�
-     * 4. 涓嬪彂鏃剁粺涓�璋冪敤 ProductionOrderService.saveProductionOrder锛岀‘淇濆悗缁伐鑹�/BOM/棰嗘枡閫昏緫涓�鑷淬��
+     * 2. 涓嬪彂鏁伴噺鍙彈杈撳叆鏁伴噺鍜屽熀纭�鏁版嵁鏍¢獙绾︽潫锛�
+     * 3. 涓嬪彂鏃剁粺涓�璋冪敤 ProductionOrderService.saveProductionOrder锛岀‘淇濆悗缁伐鑹�/BOM/棰嗘枡閫昏緫涓�鑷淬��
      */
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -101,48 +100,18 @@
             throw new BaseException("鍚堝苟澶辫触锛屾墍閫夌敓浜ц鍒掔殑浜у搧鍨嬪彿涓嶄竴鑷�");
         }
 
-        // 宸蹭笅鍙戞垨閮ㄥ垎涓嬪彂鐨勮鍒掍笉鍏佽鍐嶆鍚堝苟
-        boolean hasIssuedPlan = planLists.stream()
-                .anyMatch(item -> item.getStatus() != null
-                        && (item.getStatus() == PLAN_STATUS_PARTIAL || item.getStatus() == PLAN_STATUS_ISSUED));
-        if (hasIssuedPlan) {
-            throw new BaseException("鍚堝苟澶辫触锛屾墍閫夌敓浜ц鍒掑瓨鍦ㄥ凡涓嬪彂鎴栭儴鍒嗕笅鍙戠殑鏁版嵁");
-        }
-
-        // 璁$畻鏈鍙笅鍙戠殑鍓╀綑闇�姹傛�婚噺
-        BigDecimal totalRequiredQuantity = planLists.stream()
-                .map(this::resolveRemainingQuantity)
-                .reduce(BigDecimal.ZERO, BigDecimal::add);
-        if (totalRequiredQuantity.compareTo(BigDecimal.ZERO) <= 0) {
-            throw new ServiceException("涓嬪彂澶辫触锛屾墍閫夌敓浜ц鍒掑墿浣欓渶姹傛�婚噺蹇呴』澶т簬0");
-        }
-
         // 鏍¢獙涓嬪彂鏁伴噺
         BigDecimal assignedQuantity = productionPlanDto.getTotalAssignedQuantity();
         if (assignedQuantity == null || assignedQuantity.compareTo(BigDecimal.ZERO) <= 0) {
             throw new ServiceException("涓嬪彂澶辫触锛屼笅鍙戞暟閲忓繀椤诲ぇ浜�0");
         }
-        if (assignedQuantity.compareTo(totalRequiredQuantity) > 0) {
-            throw new ServiceException("涓嬪彂澶辫触锛屼笅鍙戞暟閲忎笉鑳藉ぇ浜庤鍒掑墿浣欓渶姹傛�婚噺");
-        }
 
-        // 鎸夎鍒掗『搴忓垎鎽婁笅鍙戞暟閲忥紝鏀堕泦瀹為檯鍙備笌涓嬪彂鐨勮鍒� ID
-        BigDecimal remainingForOrderBind = assignedQuantity;
-        List<Long> issuedPlanIds = new ArrayList<>();
-        for (ProductionPlanDto plan : planLists) {
-            BigDecimal remainingQuantity = resolveRemainingQuantity(plan);
-            if (remainingForOrderBind.compareTo(BigDecimal.ZERO) <= 0 || remainingQuantity.compareTo(BigDecimal.ZERO) <= 0) {
-                continue;
-            }
-            BigDecimal issueForThisPlan = remainingForOrderBind.min(remainingQuantity);
-            remainingForOrderBind = remainingForOrderBind.subtract(issueForThisPlan);
-            if (issueForThisPlan.compareTo(BigDecimal.ZERO) > 0) {
-                issuedPlanIds.add(plan.getId());
-            }
-        }
-        if (issuedPlanIds.isEmpty()) {
-            throw new ServiceException("涓嬪彂澶辫触锛屾棤鍙笅鍙戞暟閲�");
-        }
+        // 鏈涓嬪彂鏁伴噺涓嶅啀鎸夐渶姹傞噺闄愬埗锛屾墍鏈夐�変腑璁″垝鍏卞悓浣滀负璁㈠崟鏉ユ簮
+        List<Long> issuedPlanIds = planLists.stream()
+                .map(ProductionPlanDto::getId)
+                .filter(Objects::nonNull)
+                .distinct()
+                .collect(Collectors.toList());
 
         // 鐢熸垚鐢熶骇璁㈠崟涓诲崟锛屽苟缁戝畾鏈涓嬪彂鍏宠仈鐨勮鍒�
         ProductionOrder productionOrder = new ProductionOrder();
@@ -154,24 +123,18 @@
             throw new ServiceException("涓嬪彂澶辫触锛岀敓浜ц鍗曚繚瀛樺け璐�");
         }
 
-        // 鍥炲啓姣忔潯璁″垝鐨勭疮璁′笅鍙戦噺鍜岀姸鎬�
+        // 鍥炲啓姣忔潯璁″垝鐨勭疮璁′笅鍙戦噺鍜岀姸鎬侊紝鍏佽绱涓嬪彂閲忚秴杩囬渶姹傞噺
         BigDecimal remainingAssignedQuantity = assignedQuantity;
         List<ProductionPlan> updates = new ArrayList<>();
         for (ProductionPlanDto plan : planLists) {
-            BigDecimal requiredQuantity = Optional.ofNullable(plan.getQtyRequired()).orElse(BigDecimal.ZERO);
-            if (requiredQuantity.compareTo(BigDecimal.ZERO) < 0) {
-                requiredQuantity = BigDecimal.ZERO;
-            }
-            BigDecimal remainingQuantity = resolveRemainingQuantity(plan);
-            BigDecimal historicalIssuedQuantity = requiredQuantity.subtract(remainingQuantity);
-            BigDecimal issuedQuantity = BigDecimal.ZERO;
-            if (remainingAssignedQuantity.compareTo(BigDecimal.ZERO) > 0 && remainingQuantity.compareTo(BigDecimal.ZERO) > 0) {
-                issuedQuantity = remainingAssignedQuantity.min(remainingQuantity);
-                remainingAssignedQuantity = remainingAssignedQuantity.subtract(issuedQuantity);
-            }
+            BigDecimal historicalIssuedQuantity = Optional.ofNullable(plan.getQuantityIssued()).orElse(BigDecimal.ZERO);
+            BigDecimal issuedQuantity = remainingAssignedQuantity.min(assignedQuantity);
+            remainingAssignedQuantity = remainingAssignedQuantity.subtract(issuedQuantity);
 
             BigDecimal totalIssuedQuantity = historicalIssuedQuantity.add(issuedQuantity);
-            int planStatus = resolvePlanStatus(requiredQuantity, totalIssuedQuantity);
+            int planStatus = plan.getStatus() != null && plan.getStatus() == PLAN_STATUS_ISSUED
+                    ? PLAN_STATUS_ISSUED
+                    : resolvePlanStatus(plan.getQtyRequired(), totalIssuedQuantity);
             ProductionPlan update = new ProductionPlan();
             update.setId(plan.getId());
             update.setStatus(planStatus);
@@ -310,7 +273,7 @@
             BeanUtils.copyProperties(dto, entity);
             entity.setProductModelId(resolveProductModelId(dto, i + 2, allModels, productNameById));
             entity.setStatus(PLAN_STATUS_WAIT);
-            entity.setSource(StringUtils.isNotEmpty(dto.getSource()) ? StringUtils.trim(dto.getSource()) : "鍐呴儴");
+            entity.setSource("鍐呴儴");
             entity.setQuantityIssued(BigDecimal.ZERO);
             entity.setCreateTime(now);
             entity.setUpdateTime(now);
@@ -454,32 +417,6 @@
             }
         }
         return sequence;
-    }
-
-    /**
-     * 璁$畻鐢熶骇璁″垝鐨勫墿浣欐湭涓嬪彂鏁伴噺锛堥渶姹傞噺 - 宸蹭笅鍙戦噺锛屾渶灏忎负 0锛夈��
-     */
-    private BigDecimal resolveRemainingQuantity(ProductionPlan plan) {
-        // 绌哄璞℃寜 0 澶勭悊
-        if (plan == null) {
-            return BigDecimal.ZERO;
-        }
-        // 闇�姹傞噺涓虹┖鎴栧皬浜庣瓑浜� 0锛岃涓烘棤鍓╀綑
-        BigDecimal requiredQuantity = Optional.ofNullable(plan.getQtyRequired()).orElse(BigDecimal.ZERO);
-        if (requiredQuantity.compareTo(BigDecimal.ZERO) <= 0) {
-            return BigDecimal.ZERO;
-        }
-        // 宸蹭笅鍙戦噺涓虹┖鎴栧皬浜庣瓑浜� 0锛屽墿浣欏嵆闇�姹傞噺
-        BigDecimal issuedQuantity = Optional.ofNullable(plan.getQuantityIssued()).orElse(BigDecimal.ZERO);
-        if (issuedQuantity.compareTo(BigDecimal.ZERO) <= 0) {
-            return requiredQuantity;
-        }
-        // 宸蹭笅鍙戦噺澶т簬绛変簬闇�姹傞噺锛屽墿浣欏綊闆�
-        if (issuedQuantity.compareTo(requiredQuantity) >= 0) {
-            return BigDecimal.ZERO;
-        }
-        // 姝e父鍦烘櫙杩斿洖宸��
-        return requiredQuantity.subtract(issuedQuantity);
     }
 
     /**

--
Gitblit v1.9.3