From 67c5d3ea86cfaad45c0150b96949dbcb6729b4d0 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期一, 13 七月 2026 11:58:11 +0800
Subject: [PATCH] 1.仓储物流-库存可用量管理
---
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/vo/MesWmProductSalesRespVO.java | 6
docs/stock_available_quantity_integration.md | 96 ++++++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/salesnotice/vo/MesWmSalesNoticeRespVO.java | 6
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockReserveBizTypeEnum.java | 38 ++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/salesnotice/MesWmSalesNoticeController.java | 14
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/salesnotice/MesWmSalesNoticeDO.java | 2
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java | 29 +
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/materialstock/MesWmMaterialStockMapper.java | 34 ++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productsales/MesWmProductSalesDO.java | 2
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stockreserve/MesWmStockReserveService.java | 73 +++++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockReserveStatusEnum.java | 36 ++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnsales/MesWmReturnSalesController.java | 14
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/stockreserve/MesWmStockReserveMapper.java | 64 ++++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/materialstock/MesWmMaterialStockDO.java | 12
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/stockreserve/MesWmStockReserveDO.java | 83 +++++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnsales/vo/MesWmReturnSalesRespVO.java | 8
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stockreserve/MesWmStockReserveServiceImpl.java | 152 ++++++++++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/MesWmProductSalesController.java | 14
yudao-module-mes/pom.xml | 7
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/vo/MesWmMaterialStockRespVO.java | 16 +
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnsales/MesWmReturnSalesDO.java | 3
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java | 30 ++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/MesWmMaterialStockController.java | 6
.claude/rules/frontend-doc-generation.md | 49 ++-
24 files changed, 730 insertions(+), 64 deletions(-)
diff --git a/.claude/rules/frontend-doc-generation.md b/.claude/rules/frontend-doc-generation.md
index 56922b4..c9e3663 100644
--- a/.claude/rules/frontend-doc-generation.md
+++ b/.claude/rules/frontend-doc-generation.md
@@ -11,13 +11,24 @@
鍚庣鎺ュ彛鍙樻洿鏃讹紝**涓嶇敓鎴愬墠绔唬鐮�**锛屽彧鐢熸垚鍓嶇鑱旇皟鏂规鏂囨。锛岃緭鍑哄埌 `docs/` 鐩綍銆�
+## 绂佹鍐呭
+
+- 鉂� 绂佹鍐� Vue 妯℃澘浠g爜锛坄<el-table-column>`銆乣<el-form-item>` 绛夛級
+- 鉂� 绂佹鍐� JavaScript/TypeScript 浠g爜锛堟柟娉曘�佸嚱鏁般�侀�昏緫鍒ゆ柇绛夛級
+- 鉂� 绂佹鍐� CSS 鏍峰紡浠g爜
+- 鉂� 绂佹鍐欏墠绔粍浠朵娇鐢ㄧず渚�
+
## 鑱旇皟鏂规鍐呭瑕佹眰
+鏂囨。搴斿彧鍖呭惈浠ヤ笅鍐呭锛�
+
- **API 璇存槑**锛氳矾寰勩�佹柟娉曘�佽姹傚弬鏁般�佸搷搴旀牸寮�
-- **娑夊強鐨勫墠绔〉闈�**锛氬垪鍑洪渶瑕佷慨鏀圭殑椤甸潰
+- **娑夊強鐨勫墠绔〉闈�**锛氬垪鍑洪渶瑕佷慨鏀圭殑椤甸潰鍚嶇О
- **鏁版嵁甯﹀叆璇存槑**锛氶噸鐐瑰己璋冧俊鎭浣曚粠涓婁竴姝ュ甫鍏ワ紙濡傞噰璐鍗� -> 鍒拌揣閫氱煡 -> 閲囪喘鍏ュ簱锛�
- **鎺ュ彛璋冪敤鏃跺簭**锛氳鏄庝綍鏃惰皟鐢ㄥ摢涓帴鍙h幏鍙栧叧鑱旀暟鎹�
-- **琛ㄥ崟瀛楁鏄犲皠**锛氭槑纭摢浜涘瓧娈典粠涓婃父鏁版嵁鑷姩濉厖锛屽摢浜涢渶瑕佺敤鎴锋墜鍔ㄨ緭鍏�
+- **瀛楁灞曠ず瑙勫垯**锛氱敤琛ㄦ牸璇存槑瀛楁灞曠ず浣嶇疆鍜岃鏄庯紝涓嶅啓浠g爜
+- **涓氬姟瑙勫垯璇存槑**锛氱敤鏂囧瓧鎴栬〃鏍艰鏄庝笟鍔¢�昏緫
+- **娉ㄦ剰浜嬮」**锛氶渶瑕佸墠绔敞鎰忕殑杈圭晫鎯呭喌
## 鏂囨。妯℃澘
@@ -46,26 +57,34 @@
|------|------|------|------|
| xxx | String | 鏄� | xxx |
-**鍝嶅簲锛�** `{ "code": 200, "msg": "鎿嶄綔鎴愬姛" }`
+**鍝嶅簲瀛楁鏂板锛�**
-## 鍓嶇瀹炵幇瑕佺偣
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| xxx | String | xxx |
-### 1. 鏁版嵁鑾峰彇鏃舵満
+**鍝嶅簲绀轰緥锛�**
-- 椤甸潰鎵撳紑鏃惰皟鐢� XXX 鎺ュ彛鑾峰彇閲囪喘璁㈠崟淇℃伅
-- 閫夋嫨閲囪喘璁㈠崟鍚庯紝璋冪敤 YYY 鎺ュ彛鑾峰彇鐗╂枡鏄庣粏
+```json
+{
+ "code": 0,
+ "data": {}
+}
+```
-### 2. 瀛楁鑷姩濉厖瑙勫垯
+## 瀛楁灞曠ず瑙勫垯
-| 鐩爣瀛楁 | 鏁版嵁鏉ユ簮 | 濉厖鏃舵満 |
-|----------|----------|----------|
-| 鐗╂枡缂栫爜 | 閲囪喘璁㈠崟琛�.itemCode | 閫夋嫨璁㈠崟琛屽悗 |
-| 鐗╂枡鍚嶇О | 閲囪喘璁㈠崟琛�.itemName | 閫夋嫨璁㈠崟琛屽悗 |
+| 瀛楁 | 灞曠ず浣嶇疆 | 璇存槑 |
+|------|----------|------|
+| 瀛楁A | 鍒楄〃銆佽鎯� | 璇存槑 |
+| 瀛楁B | 璇︽儏 | 璇存槑 |
-### 3. 鐢ㄦ埛鍙紪杈戝瓧娈�
+## 涓氬姟瑙勫垯璇存槑
-- 瀛楁A锛氱敤鎴峰彲淇敼
-- 瀛楁B锛氱敤鎴峰彲淇敼
+| 鍦烘櫙 | 瑙勫垯 |
+|------|------|
+| 鍦烘櫙1 | 瑙勫垯璇存槑 |
+| 鍦烘櫙2 | 瑙勫垯璇存槑 |
## 娉ㄦ剰浜嬮」
diff --git a/docs/stock_available_quantity_integration.md b/docs/stock_available_quantity_integration.md
new file mode 100644
index 0000000..ee074f6
--- /dev/null
+++ b/docs/stock_available_quantity_integration.md
@@ -0,0 +1,96 @@
+# 搴撳瓨鍙敤閲忕鐞� - 鍓嶇鑱旇皟鏂规
+
+## 娑夊強椤甸潰
+
+- 搴撳瓨鐜版湁閲忛〉闈�
+
+## 涓氬姟娴佺▼涓庢暟鎹甫鍏�
+
+鏈涓哄簱瀛樺彴璐﹀瓧娈垫墿灞曪紝鏃犺法椤甸潰鏁版嵁娴佽浆銆�
+
+## API
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | /mes/wm/material-stock/page | 搴撳瓨鍙拌处鍒嗛〉鏌ヨ |
+| GET | /mes/wm/material-stock/get | 鍗曟潯搴撳瓨鏌ヨ |
+
+**鍝嶅簲瀛楁鏂板锛�**
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| frozenQuantity | Decimal | 鍐荤粨鏁伴噺 |
+| reservedQuantity | Decimal | 鍗犵敤閲忥紙宸插垎閰嶅緟鍑哄簱锛� |
+| inTransitQuantity | Decimal | 鍦ㄩ�旈噺锛堣皟鎷ㄥ湪閫旓級 |
+| availableQuantity | Decimal | 鍙敤閲忥紙鍚庣璁$畻锛氬湪搴撴暟閲� - 鍐荤粨鏁伴噺 - 鍗犵敤閲忥級 |
+
+**鍝嶅簲绀轰緥锛�**
+
+```json
+{
+ "code": 0,
+ "data": {
+ "list": [
+ {
+ "id": 1,
+ "itemCode": "M001",
+ "itemName": "閽㈡澘",
+ "quantity": 100.00,
+ "frozenQuantity": 10.00,
+ "reservedQuantity": 20.00,
+ "inTransitQuantity": 5.00,
+ "availableQuantity": 70.00
+ }
+ ],
+ "total": 1
+ }
+}
+```
+
+## 鍓嶇瀹炵幇瑕佺偣
+
+### 1. 鏁版嵁鑾峰彇鏃舵満
+
+- 椤甸潰鎵撳紑鏃惰皟鐢ㄥ簱瀛樺彴璐︽煡璇㈡帴鍙o紝鍝嶅簲涓凡鍖呭惈鏂板瀛楁
+- 鏃犻渶棰濆鎺ュ彛璋冪敤
+
+### 2. 瀛楁灞曠ず瑙勫垯
+
+| 瀛楁 | 灞曠ず浣嶇疆 | 璇存槑 |
+|------|----------|------|
+| 鍦ㄥ簱鏁伴噺 | 鍒楄〃銆佽鎯� | 鐜版湁瀛楁锛屼繚鎸佷笉鍙� |
+| 鍐荤粨鏁伴噺 | 鍒楄〃銆佽鎯� | 鏂板瀛楁锛屽彲鑳戒负 null 鏃舵樉绀� 0 |
+| 鍗犵敤閲� | 鍒楄〃銆佽鎯� | 鏂板瀛楁锛屽彲鑳戒负 null 鏃舵樉绀� 0 |
+| 鍦ㄩ�旈噺 | 鍒楄〃銆佽鎯� | 鏂板瀛楁锛屽彲鑳戒负 null 鏃舵樉绀� 0 |
+| 鍙敤閲� | 鍒楄〃銆佽鎯� | 鍚庣宸茶绠楋紝鐩存帴灞曠ず锛涗负璐熸暟鏃跺缓璁珮浜彁绀� |
+
+### 3. 鐢ㄦ埛鍙紪杈戝瓧娈�
+
+鏃犳柊澧炲彲缂栬緫瀛楁锛屾湰娆′粎涓哄睍绀虹被瀛楁鎵╁睍銆�
+
+## 涓氬姟瑙勫垯璇存槑
+
+### 1. 鍚勫瓧娈靛惈涔�
+
+| 瀛楁 | 鍚箟 |
+|------|------|
+| 鍦ㄥ簱鏁伴噺 | 浠撳簱涓疄闄呭瓨鍦ㄧ殑搴撳瓨 |
+| 鍐荤粨鏁伴噺 | 鍥犵洏鐐广�佽川妫�绛夊師鍥犺鍐荤粨鐨勫簱瀛� |
+| 鍗犵敤閲� | 宸插垎閰嶅緟鍑哄簱鐨勬暟閲忥紙鎷h揣鍚庢湭鍑哄簱锛� |
+| 鍦ㄩ�旈噺 | 璋冩嫧鍦ㄩ�旓紙婧愪粨搴撳凡鍑哄簱锛岀洰鏍囦粨搴撴湭鍏ュ簱锛� |
+| 鍙敤閲� | 瀹為檯鍙敤浜庡垎閰嶇殑搴撳瓨 |
+
+### 2. 鍗犵敤閲忎骇鐢熶笌閲婃斁鍦烘櫙
+
+| 鍦烘櫙 | 鏃舵満 | 褰卞搷 |
+|------|------|------|
+| 閿�鍞嚭搴撴嫞璐� | 鎷h揣鎿嶄綔鏃� | 鍗犵敤閲忓鍔狅紝鍙敤閲忓噺灏� |
+| 鐢熶骇棰嗘枡鎷h揣 | 鎷h揣鎿嶄綔鏃� | 鍗犵敤閲忓鍔狅紝鍙敤閲忓噺灏� |
+| 鍑哄簱瀹屾垚 | 鎵ц鍑哄簱鏃� | 鍗犵敤閲忓噺灏戯紝鍦ㄥ簱鏁伴噺鍑忓皯 |
+| 鍗曟嵁鍙栨秷 | 鍙栨秷鍑哄簱鍗曟椂 | 鍗犵敤閲忛噴鏀撅紝鍙敤閲忔仮澶� |
+
+## 娉ㄦ剰浜嬮」
+
+- 鏂板瀛楁鍦ㄥ巻鍙叉暟鎹腑鍙兘涓� null锛屽墠绔睍绀烘椂闇�鍋氱┖鍊煎鐞嗭紝榛樿鏄剧ず 0
+- 鍙敤閲忕敱鍚庣璁$畻锛屽墠绔洿鎺ヤ娇鐢紝鏃犻渶鑷璁$畻
+- 瀵煎嚭 Excel 宸插寘鍚柊瀛楁锛屾棤闇�棰濆澶勭悊
\ No newline at end of file
diff --git a/yudao-module-mes/pom.xml b/yudao-module-mes/pom.xml
index 74c0908..4f6e41f 100644
--- a/yudao-module-mes/pom.xml
+++ b/yudao-module-mes/pom.xml
@@ -31,6 +31,13 @@
<version>${revision}</version>
</dependency>
+ <!-- CRM 瀹㈡埛绠$悊 API -->
+ <dependency>
+ <groupId>cn.iocoder.boot</groupId>
+ <artifactId>yudao-module-crm-api</artifactId>
+ <version>${revision}</version>
+ </dependency>
+
<!-- BPM 宸ヤ綔娴� API -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/MesWmMaterialStockController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/MesWmMaterialStockController.java
index 16ce9b8..a665b66 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/MesWmMaterialStockController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/MesWmMaterialStockController.java
@@ -36,6 +36,7 @@
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
+import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -141,6 +142,11 @@
area -> vo.setAreaName(area.getName()));
MapUtils.findAndThen(vendorMap, vo.getVendorId(),
vendor -> vo.setVendorName(vendor.getName()));
+ // 璁$畻鍙敤閲� = 鍦ㄥ簱鏁伴噺 - 鍐荤粨鏁伴噺 - 鍗犵敤閲�
+ BigDecimal quantity = vo.getQuantity() != null ? vo.getQuantity() : BigDecimal.ZERO;
+ BigDecimal frozenQty = vo.getFrozenQuantity() != null ? vo.getFrozenQuantity() : BigDecimal.ZERO;
+ BigDecimal reservedQty = vo.getReservedQuantity() != null ? vo.getReservedQuantity() : BigDecimal.ZERO;
+ vo.setAvailableQuantity(quantity.subtract(frozenQty).subtract(reservedQty));
});
}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/vo/MesWmMaterialStockRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/vo/MesWmMaterialStockRespVO.java
index 03349b3..8552e20 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/vo/MesWmMaterialStockRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/vo/MesWmMaterialStockRespVO.java
@@ -81,6 +81,22 @@
@ExcelProperty("鍦ㄥ簱鏁伴噺")
private BigDecimal quantity;
+ @Schema(description = "鍐荤粨鏁伴噺", example = "10.0000")
+ @ExcelProperty("鍐荤粨鏁伴噺")
+ private BigDecimal frozenQuantity;
+
+ @Schema(description = "鍗犵敤閲忥紙宸插垎閰嶅緟鍑哄簱锛�", example = "20.0000")
+ @ExcelProperty("鍗犵敤閲�")
+ private BigDecimal reservedQuantity;
+
+ @Schema(description = "鍦ㄩ�旈噺锛堣皟鎷ㄥ湪閫旓級", example = "5.0000")
+ @ExcelProperty("鍦ㄩ�旈噺")
+ private BigDecimal inTransitQuantity;
+
+ @Schema(description = "鍙敤閲忥紙鍦ㄥ簱鏁伴噺 - 鍐荤粨鏁伴噺 - 鍗犵敤閲忥級", example = "70.0000")
+ @ExcelProperty("鍙敤閲�")
+ private BigDecimal availableQuantity;
+
@Schema(description = "鍏ュ簱鏃堕棿")
@ExcelProperty("鍏ュ簱鏃堕棿")
private LocalDateTime receiptTime;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/MesWmProductSalesController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/MesWmProductSalesController.java
index cdd84a8..21ed7b7 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/MesWmProductSalesController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/MesWmProductSalesController.java
@@ -8,14 +8,14 @@
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi;
+import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesSaveReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesShippingReqVO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.client.MesMdClientDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.salesnotice.MesWmSalesNoticeDO;
-import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService;
import cn.iocoder.yudao.module.mes.service.wm.productsales.MesWmProductSalesService;
import cn.iocoder.yudao.module.mes.service.wm.salesnotice.MesWmSalesNoticeService;
import io.swagger.v3.oas.annotations.Operation;
@@ -44,7 +44,7 @@
@Resource
private MesWmProductSalesService productSalesService;
@Resource
- private MesMdClientService clientService;
+ private CrmCustomerApi crmCustomerApi;
@Resource
private MesWmSalesNoticeService salesNoticeService;
@@ -164,17 +164,17 @@
return Collections.emptyList();
}
// 1. 鑾峰緱鍏宠仈鏁版嵁
- Map<Long, MesMdClientDO> clientMap = clientService.getClientMap(
+ Map<Long, CrmCustomerRespDTO> customerMap = crmCustomerApi.getCustomerMap(
convertSet(list, MesWmProductSalesDO::getClientId));
Map<Long, MesWmSalesNoticeDO> noticeMap = salesNoticeService.getSalesNoticeMap(
convertSet(list, MesWmProductSalesDO::getNoticeId));
// 2. 鏋勫缓缁撴灉
return BeanUtils.toBean(list, MesWmProductSalesRespVO.class, vo -> {
- MapUtils.findAndThen(clientMap, vo.getClientId(), client ->
- vo.setClientName(client.getName()).setClientCode(client.getCode()));
+ MapUtils.findAndThen(customerMap, vo.getClientId(), customer ->
+ vo.setClientName(customer.getName()));
MapUtils.findAndThen(noticeMap, vo.getNoticeId(),
notice -> vo.setNoticeCode(notice.getCode()));
});
}
-}
+}
\ No newline at end of file
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/vo/MesWmProductSalesRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/vo/MesWmProductSalesRespVO.java
index 4d67b5e..5fc1d88 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/vo/MesWmProductSalesRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/vo/MesWmProductSalesRespVO.java
@@ -46,10 +46,6 @@
@ExcelProperty("鍙戣揣閫氱煡鍗曠紪鍙�")
private String noticeCode;
- @Schema(description = "瀹㈡埛缂栫爜", example = "C001")
- @ExcelProperty("瀹㈡埛缂栫爜")
- private String clientCode;
-
@Schema(description = "鏀惰揣浜�", example = "寮犱笁")
@ExcelProperty("鏀惰揣浜�")
private String contactName;
@@ -82,4 +78,4 @@
@ExcelProperty("鍒涘缓鏃堕棿")
private LocalDateTime createTime;
-}
+}
\ No newline at end of file
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnsales/MesWmReturnSalesController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnsales/MesWmReturnSalesController.java
index 074e7b1..3738d85 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnsales/MesWmReturnSalesController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnsales/MesWmReturnSalesController.java
@@ -8,12 +8,12 @@
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi;
+import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.MesWmReturnSalesPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.MesWmReturnSalesRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.MesWmReturnSalesSaveReqVO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.client.MesMdClientDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesDO;
-import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService;
import cn.iocoder.yudao.module.mes.service.wm.returnsales.MesWmReturnSalesService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -43,7 +43,7 @@
@Resource
private MesWmReturnSalesService returnSalesService;
@Resource
- private MesMdClientService clientService;
+ private CrmCustomerApi crmCustomerApi;
@PostMapping("/create")
@Operation(summary = "鍒涘缓閿�鍞��璐у崟")
@@ -153,12 +153,12 @@
return Collections.emptyList();
}
// 1. 鑾峰緱鍏宠仈鏁版嵁
- Map<Long, MesMdClientDO> clientMap = clientService.getClientMap(
+ Map<Long, CrmCustomerRespDTO> customerMap = crmCustomerApi.getCustomerMap(
convertSet(list, MesWmReturnSalesDO::getClientId));
// 2. 鏋勫缓缁撴灉
return BeanUtils.toBean(list, MesWmReturnSalesRespVO.class, vo ->
- MapUtils.findAndThen(clientMap, vo.getClientId(), client ->
- vo.setClientCode(client.getCode()).setClientName(client.getName()).setClientNickname(client.getNickname())));
+ MapUtils.findAndThen(customerMap, vo.getClientId(), customer ->
+ vo.setClientName(customer.getName())));
}
-}
+}
\ No newline at end of file
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnsales/vo/MesWmReturnSalesRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnsales/vo/MesWmReturnSalesRespVO.java
index c2f11b0..14b8f86 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnsales/vo/MesWmReturnSalesRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnsales/vo/MesWmReturnSalesRespVO.java
@@ -29,14 +29,8 @@
@Schema(description = "瀹㈡埛 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long clientId;
- @Schema(description = "瀹㈡埛缂栫爜", example = "C001")
- private String clientCode;
-
@Schema(description = "瀹㈡埛鍚嶇О", example = "XX瀹㈡埛")
private String clientName;
-
- @Schema(description = "瀹㈡埛绠�绉�", example = "XX")
- private String clientNickname;
@Schema(description = "閫�璐ф棩鏈�")
private LocalDateTime returnDate;
@@ -53,4 +47,4 @@
@Schema(description = "鍒涘缓鏃堕棿", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
-}
+}
\ No newline at end of file
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/salesnotice/MesWmSalesNoticeController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/salesnotice/MesWmSalesNoticeController.java
index 07c0e03..53d0b5a 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/salesnotice/MesWmSalesNoticeController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/salesnotice/MesWmSalesNoticeController.java
@@ -8,12 +8,12 @@
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi;
+import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.salesnotice.vo.MesWmSalesNoticePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.salesnotice.vo.MesWmSalesNoticeRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.salesnotice.vo.MesWmSalesNoticeSaveReqVO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.client.MesMdClientDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.salesnotice.MesWmSalesNoticeDO;
-import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService;
import cn.iocoder.yudao.module.mes.service.wm.salesnotice.MesWmSalesNoticeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -43,7 +43,7 @@
@Resource
private MesWmSalesNoticeService salesNoticeService;
@Resource
- private MesMdClientService clientService;
+ private CrmCustomerApi crmCustomerApi;
@PostMapping("/create")
@Operation(summary = "鍒涘缓鍙戣揣閫氱煡鍗�")
@@ -126,13 +126,13 @@
return Collections.emptyList();
}
// 1. 鑾峰緱鍏宠仈鏁版嵁
- Map<Long, MesMdClientDO> clientMap = clientService.getClientMap(
+ Map<Long, CrmCustomerRespDTO> customerMap = crmCustomerApi.getCustomerMap(
convertSet(list, MesWmSalesNoticeDO::getClientId));
// 2. 鏋勫缓缁撴灉
return BeanUtils.toBean(list, MesWmSalesNoticeRespVO.class, vo -> {
- MapUtils.findAndThen(clientMap, vo.getClientId(), client ->
- vo.setClientCode(client.getCode()).setClientName(client.getName()));
+ MapUtils.findAndThen(customerMap, vo.getClientId(), customer ->
+ vo.setClientName(customer.getName()));
});
}
-}
+}
\ No newline at end of file
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/salesnotice/vo/MesWmSalesNoticeRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/salesnotice/vo/MesWmSalesNoticeRespVO.java
index 7d09503..05dda66 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/salesnotice/vo/MesWmSalesNoticeRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/salesnotice/vo/MesWmSalesNoticeRespVO.java
@@ -27,10 +27,6 @@
@Schema(description = "瀹㈡埛缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long clientId;
- @Schema(description = "瀹㈡埛缂栫爜", example = "C001")
- @ExcelProperty("瀹㈡埛缂栫爜")
- private String clientCode;
-
@Schema(description = "瀹㈡埛鍚嶇О", example = "鏌愬鎴�")
@ExcelProperty("瀹㈡埛鍚嶇О")
private String clientName;
@@ -70,4 +66,4 @@
@ExcelProperty("鍒涘缓鏃堕棿")
private LocalDateTime createTime;
-}
+}
\ No newline at end of file
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/materialstock/MesWmMaterialStockDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/materialstock/MesWmMaterialStockDO.java
index 95b7c5f..95b8d30 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/materialstock/MesWmMaterialStockDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/materialstock/MesWmMaterialStockDO.java
@@ -95,6 +95,18 @@
*/
private BigDecimal quantity;
/**
+ * 鍐荤粨鏁伴噺锛堢洏鐐广�佽川妫�绛夊喕缁擄級
+ */
+ private BigDecimal frozenQuantity;
+ /**
+ * 鍗犵敤閲忥紙宸插垎閰嶅緟鍑哄簱锛�
+ */
+ private BigDecimal reservedQuantity;
+ /**
+ * 鍦ㄩ�旈噺锛堣皟鎷ㄥ湪閫旓級
+ */
+ private BigDecimal inTransitQuantity;
+ /**
* 鍏ュ簱鏃堕棿
*/
private LocalDateTime receiptTime;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productsales/MesWmProductSalesDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productsales/MesWmProductSalesDO.java
index 14f265f..c7982f2 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productsales/MesWmProductSalesDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productsales/MesWmProductSalesDO.java
@@ -43,7 +43,7 @@
/**
* 瀹㈡埛ID
*
- * 鍏宠仈 {@link MesMdClientDO#getId()}
+ * 鍏宠仈 CRM 瀹㈡埛 {@link cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO#getId()}
*/
private Long clientId;
/**
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnsales/MesWmReturnSalesDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnsales/MesWmReturnSalesDO.java
index 679a81b..baa5daa 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnsales/MesWmReturnSalesDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnsales/MesWmReturnSalesDO.java
@@ -1,7 +1,6 @@
package cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.client.MesMdClientDO;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnSalesStatusEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
@@ -46,7 +45,7 @@
/**
* 瀹㈡埛 ID
*
- * 鍏宠仈 {@link MesMdClientDO#getId()}
+ * 鍏宠仈 CRM 瀹㈡埛 {@link cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO#getId()}
*/
private Long clientId;
/**
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/salesnotice/MesWmSalesNoticeDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/salesnotice/MesWmSalesNoticeDO.java
index 1281884..665d5b2 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/salesnotice/MesWmSalesNoticeDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/salesnotice/MesWmSalesNoticeDO.java
@@ -43,7 +43,7 @@
/**
* 瀹㈡埛缂栧彿
*
- * 鍏宠仈 {@link MesMdClientDO#getId()}
+ * 鍏宠仈 CRM 瀹㈡埛 {@link cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO#getId()}
*/
private Long clientId;
/**
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/stockreserve/MesWmStockReserveDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/stockreserve/MesWmStockReserveDO.java
new file mode 100644
index 0000000..0996274
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/stockreserve/MesWmStockReserveDO.java
@@ -0,0 +1,83 @@
+package cn.iocoder.yudao.module.mes.dal.dataobject.wm.stockreserve;
+
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockReserveBizTypeEnum;
+import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockReserveStatusEnum;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+
+import java.math.BigDecimal;
+
+/**
+ * MES 搴撳瓨鍗犵敤璁板綍 DO
+ */
+@TableName("mes_wm_stock_reserve")
+@KeySequence("mes_wm_stock_reserve_seq")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class MesWmStockReserveDO extends BaseDO {
+
+ /**
+ * 缂栧彿
+ */
+ @TableId
+ private Long id;
+
+ /**
+ * 搴撳瓨璁板綍ID
+ *
+ * 鍏宠仈 {@link cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO#getId()}
+ */
+ private Long materialStockId;
+
+ /**
+ * 涓氬姟绫诲瀷
+ *
+ * 鏋氫妇 {@link MesWmStockReserveBizTypeEnum}
+ */
+ private Integer bizType;
+
+ /**
+ * 涓氬姟鍗曟嵁ID
+ */
+ private Long bizId;
+
+ /**
+ * 涓氬姟鍗曞彿
+ */
+ private String bizCode;
+
+ /**
+ * 涓氬姟鍗曟嵁琛孖D
+ */
+ private Long bizLineId;
+
+ /**
+ * 鐗╂枡ID
+ */
+ private Long itemId;
+
+ /**
+ * 鍗犵敤鏁伴噺
+ */
+ private BigDecimal quantity;
+
+ /**
+ * 鐘舵��
+ *
+ * 鏋氫妇 {@link MesWmStockReserveStatusEnum}
+ */
+ private Integer status;
+
+ /**
+ * 澶囨敞
+ */
+ private String remark;
+
+}
\ No newline at end of file
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/materialstock/MesWmMaterialStockMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/materialstock/MesWmMaterialStockMapper.java
index a22847d..fa1bda7 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/materialstock/MesWmMaterialStockMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/materialstock/MesWmMaterialStockMapper.java
@@ -86,6 +86,40 @@
}
/**
+ * 澧為噺鏇存柊搴撳瓨鍗犵敤閲�
+ *
+ * @param id 搴撳瓨璁板綍缂栧彿
+ * @param count 鍙樺姩鏁伴噺锛堟鏁�=澧炲姞鍗犵敤锛岃礋鏁�=鍑忓皯鍗犵敤锛�
+ * @param checkFlag 鏄惁鏍¢獙鍙敤閲忓厖瓒筹紙涓� true 鏃跺崰鐢ㄤ笉鍏佽瓒呰繃鍙敤閲忥級
+ * @return 褰卞搷琛屾暟
+ */
+ default int updateReservedQuantity(Long id, BigDecimal count, boolean checkFlag) {
+ LambdaUpdateWrapper<MesWmMaterialStockDO> updateWrapper = new LambdaUpdateWrapper<MesWmMaterialStockDO>()
+ .eq(MesWmMaterialStockDO::getId, id)
+ .setSql("reserved_quantity = reserved_quantity + " + count);
+ if (checkFlag && count.compareTo(BigDecimal.ZERO) > 0) {
+ // 鏍¢獙鍙敤閲忓厖瓒筹細quantity - frozen_quantity - reserved_quantity >= count
+ updateWrapper.setSql("reserved_quantity = reserved_quantity + " + count +
+ " WHERE quantity - IFNULL(frozen_quantity, 0) - IFNULL(reserved_quantity, 0) >= " + count);
+ }
+ return update(null, updateWrapper);
+ }
+
+ /**
+ * 澧為噺鏇存柊搴撳瓨鍦ㄩ�旈噺
+ *
+ * @param id 搴撳瓨璁板綍缂栧彿
+ * @param count 鍙樺姩鏁伴噺锛堟鏁�=澧炲姞鍦ㄩ�旓紝璐熸暟=鍑忓皯鍦ㄩ�旓級
+ * @return 褰卞搷琛屾暟
+ */
+ default int updateInTransitQuantity(Long id, BigDecimal count) {
+ LambdaUpdateWrapper<MesWmMaterialStockDO> updateWrapper = new LambdaUpdateWrapper<MesWmMaterialStockDO>()
+ .eq(MesWmMaterialStockDO::getId, id)
+ .setSql("in_transit_quantity = in_transit_quantity + " + count);
+ return update(null, updateWrapper);
+ }
+
+ /**
* 鎸夌粍鍚堥敭鏌ヨ搴撳瓨璁板綍
*
* 鍞竴閿細(itemId, warehouseId, locationId, areaId, batchId, vendorId)
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/stockreserve/MesWmStockReserveMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/stockreserve/MesWmStockReserveMapper.java
new file mode 100644
index 0000000..d4664bd
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/stockreserve/MesWmStockReserveMapper.java
@@ -0,0 +1,64 @@
+package cn.iocoder.yudao.module.mes.dal.mysql.wm.stockreserve;
+
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stockreserve.MesWmStockReserveDO;
+import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockReserveStatusEnum;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * MES 搴撳瓨鍗犵敤璁板綍 Mapper
+ */
+@Mapper
+public interface MesWmStockReserveMapper extends BaseMapperX<MesWmStockReserveDO> {
+
+ /**
+ * 鏌ヨ鎸囧畾涓氬姟鍗曟嵁鐨勫崰鐢ㄨ褰�
+ */
+ default List<MesWmStockReserveDO> selectListByBiz(Integer bizType, Long bizId) {
+ return selectList(new LambdaQueryWrapperX<MesWmStockReserveDO>()
+ .eq(MesWmStockReserveDO::getBizType, bizType)
+ .eq(MesWmStockReserveDO::getBizId, bizId));
+ }
+
+ /**
+ * 鏌ヨ鎸囧畾涓氬姟鍗曟嵁鐨勫崰鐢ㄤ腑璁板綍
+ */
+ default List<MesWmStockReserveDO> selectReservingListByBiz(Integer bizType, Long bizId) {
+ return selectList(new LambdaQueryWrapperX<MesWmStockReserveDO>()
+ .eq(MesWmStockReserveDO::getBizType, bizType)
+ .eq(MesWmStockReserveDO::getBizId, bizId)
+ .eq(MesWmStockReserveDO::getStatus, MesWmStockReserveStatusEnum.RESERVING.getStatus()));
+ }
+
+ /**
+ * 鏌ヨ鎸囧畾搴撳瓨璁板綍鐨勫崰鐢ㄤ腑璁板綍
+ */
+ default List<MesWmStockReserveDO> selectReservingListByMaterialStockId(Long materialStockId) {
+ return selectList(new LambdaQueryWrapperX<MesWmStockReserveDO>()
+ .eq(MesWmStockReserveDO::getMaterialStockId, materialStockId)
+ .eq(MesWmStockReserveDO::getStatus, MesWmStockReserveStatusEnum.RESERVING.getStatus()));
+ }
+
+ /**
+ * 鏌ヨ鎸囧畾鐗╂枡鍦ㄦ寚瀹氫粨搴撶殑鍗犵敤鏁伴噺姹囨��
+ */
+ @Select("SELECT IFNULL(SUM(sr.quantity), 0) FROM mes_wm_stock_reserve sr " +
+ "INNER JOIN mes_wm_material_stock ms ON sr.material_stock_id = ms.id " +
+ "WHERE sr.deleted = 0 AND sr.status = 1 AND ms.deleted = 0 " +
+ "AND sr.item_id = #{itemId} AND ms.warehouse_id = #{warehouseId}")
+ BigDecimal sumReservedQuantityByItemAndWarehouse(@Param("itemId") Long itemId, @Param("warehouseId") Long warehouseId);
+
+ /**
+ * 鏌ヨ鎸囧畾鐗╂枡鐨勫崰鐢ㄦ暟閲忔眹鎬�
+ */
+ @Select("SELECT IFNULL(SUM(quantity), 0) FROM mes_wm_stock_reserve " +
+ "WHERE deleted = 0 AND status = 1 AND item_id = #{itemId}")
+ BigDecimal sumReservedQuantityByItem(@Param("itemId") Long itemId);
+
+}
\ No newline at end of file
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockReserveBizTypeEnum.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockReserveBizTypeEnum.java
new file mode 100644
index 0000000..c021bdb
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockReserveBizTypeEnum.java
@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 搴撳瓨鍗犵敤涓氬姟绫诲瀷鏋氫妇
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmStockReserveBizTypeEnum implements ArrayValuable<Integer> {
+
+ PRODUCT_SALES(1, "閿�鍞嚭搴�"),
+ PRODUCT_ISSUE(2, "鐢熶骇棰嗘枡"),
+ OUTSOURCE_ISSUE(3, "澶栧崗鍙戞枡"),
+ MISC_ISSUE(4, "鏉傞」鍑哄簱"),
+ TRANSFER(5, "杞Щ璋冩嫧");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmStockReserveBizTypeEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 绫诲瀷鍊�
+ */
+ private final Integer type;
+ /**
+ * 绫诲瀷鍚�
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockReserveStatusEnum.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockReserveStatusEnum.java
new file mode 100644
index 0000000..2872f1a
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockReserveStatusEnum.java
@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 搴撳瓨鍗犵敤鐘舵�佹灇涓�
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmStockReserveStatusEnum implements ArrayValuable<Integer> {
+
+ RESERVING(1, "鍗犵敤涓�"),
+ RELEASED(2, "宸查噴鏀�"),
+ OUTBOUND(3, "宸插嚭搴�");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmStockReserveStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 鐘舵�佸��
+ */
+ private final Integer status;
+ /**
+ * 鐘舵�佸悕
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java
index e794078..b193252 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java
@@ -14,9 +14,11 @@
import cn.iocoder.yudao.module.mes.dal.mysql.wm.productissue.MesWmProductIssueMapper;
import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductIssueStatusEnum;
+import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockReserveBizTypeEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
+import cn.iocoder.yudao.module.mes.service.wm.stockreserve.MesWmStockReserveService;
import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
@@ -63,6 +65,8 @@
private MesWmWarehouseLocationService locationService;
@Resource
private MesWmWarehouseAreaService areaService;
+ @Resource
+ private MesWmStockReserveService stockReserveService;
@Override
@Transactional(rollbackFor = Exception.class)
@@ -143,6 +147,22 @@
throw exception(WM_PRODUCT_ISSUE_DETAIL_QUANTITY_MISMATCH);
}
+ // 鍒涘缓搴撳瓨鍗犵敤锛堟寜鏄庣粏鍗犵敤搴撳瓨锛�
+ List<MesWmProductIssueDetailDO> details = issueDetailService.getProductIssueDetailListByIssueId(id);
+ for (MesWmProductIssueDetailDO detail : details) {
+ if (detail.getMaterialStockId() != null && detail.getQuantity() != null) {
+ stockReserveService.createReserve(
+ detail.getMaterialStockId(),
+ MesWmStockReserveBizTypeEnum.PRODUCT_ISSUE.getType(),
+ id,
+ issue.getCode(),
+ detail.getId(),
+ detail.getItemId(),
+ detail.getQuantity()
+ );
+ }
+ }
+
// 鎵ц鎷h揣锛堝緟鎷h揣 鈫� 寰呮墽琛岄鍑猴級
issueMapper.updateById(new MesWmProductIssueDO()
.setId(id).setStatus(MesWmProductIssueStatusEnum.APPROVED.getStatus()));
@@ -166,10 +186,13 @@
throw exception(WM_PRODUCT_ISSUE_DETAIL_QUANTITY_MISMATCH);
}
- // 2. 閬嶅巻鎵�鏈夋槑缁嗭紝鍒涘缓搴撳瓨浜嬪姟锛堟墸鍑忓簱瀛� + 璁板綍娴佹按锛�
+ // 2. 纭鍗犵敤杞嚭搴擄紙閲婃斁鍗犵敤閲忥級
+ stockReserveService.confirmReserveToOutbound(MesWmStockReserveBizTypeEnum.PRODUCT_ISSUE.getType(), id);
+
+ // 3. 閬嶅巻鎵�鏈夋槑缁嗭紝鍒涘缓搴撳瓨浜嬪姟锛堟墸鍑忓簱瀛� + 璁板綍娴佹按锛�
createTransactionList(issue);
- // 3. 鏇存柊鍑哄簱鍗曠姸鎬� + 棰嗘枡鏃ユ湡
+ // 4. 鏇存柊鍑哄簱鍗曠姸鎬� + 棰嗘枡鏃ユ湡
issueMapper.updateById(new MesWmProductIssueDO()
.setId(id).setStatus(MesWmProductIssueStatusEnum.FINISHED.getStatus())
.setIssueDate(LocalDateTime.now()));
@@ -216,6 +239,9 @@
throw exception(WM_PRODUCT_ISSUE_CANCEL_NOT_ALLOWED);
}
+ // 閲婃斁搴撳瓨鍗犵敤
+ stockReserveService.releaseReserve(MesWmStockReserveBizTypeEnum.PRODUCT_ISSUE.getType(), id);
+
// 鍙栨秷
issueMapper.updateById(new MesWmProductIssueDO()
.setId(id).setStatus(MesWmProductIssueStatusEnum.CANCELED.getStatus()));
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java
index 1694b78..baec481 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java
@@ -18,10 +18,12 @@
import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductSalesStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmSalesNoticeStatusEnum;
+import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockReserveBizTypeEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService;
import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
import cn.iocoder.yudao.module.mes.service.wm.salesnotice.MesWmSalesNoticeService;
+import cn.iocoder.yudao.module.mes.service.wm.stockreserve.MesWmStockReserveService;
import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
import cn.iocoder.yudao.module.erp.api.sale.ErpSaleOrderApi;
@@ -61,6 +63,8 @@
private MesWmTransactionService wmTransactionService;
@Resource
private MesWmMaterialStockService materialStockService;
+ @Resource
+ private MesWmStockReserveService stockReserveService;
@Resource
private ErpSaleOrderApi saleOrderApi;
@@ -181,7 +185,7 @@
if (CollUtil.isEmpty(details)) {
throw exception(WM_PRODUCT_SALES_DETAILS_EMPTY);
}
- // 鏍¢獙搴撳瓨鍏呰冻
+ // 鏍¢獙搴撳瓨鍏呰冻骞跺垱寤哄崰鐢�
for (MesWmProductSalesDetailDO detail : details) {
materialStockService.validateSelectedStock(
detail.getMaterialStockId(),
@@ -191,6 +195,16 @@
detail.getWarehouseId(),
detail.getLocationId(),
detail.getAreaId(),
+ detail.getQuantity()
+ );
+ // 鍒涘缓搴撳瓨鍗犵敤
+ stockReserveService.createReserve(
+ detail.getMaterialStockId(),
+ MesWmStockReserveBizTypeEnum.PRODUCT_SALES.getType(),
+ id,
+ sales.getCode(),
+ detail.getId(),
+ detail.getItemId(),
detail.getQuantity()
);
}
@@ -227,19 +241,22 @@
throw exception(WM_PRODUCT_SALES_CANNOT_FINISH);
}
- // 2. 閬嶅巻鎵�鏈夋槑缁嗭紝鍒涘缓搴撳瓨浜嬪姟锛堟墸鍑忓簱瀛� + 璁板綍娴佹按锛�
+ // 2. 纭鍗犵敤杞嚭搴擄紙閲婃斁鍗犵敤閲忥級
+ stockReserveService.confirmReserveToOutbound(MesWmStockReserveBizTypeEnum.PRODUCT_SALES.getType(), id);
+
+ // 3. 閬嶅巻鎵�鏈夋槑缁嗭紝鍒涘缓搴撳瓨浜嬪姟锛堟墸鍑忓簱瀛� + 璁板綍娴佹按锛�
createTransactionList(sales);
- // 3. 鏇存柊鍑哄簱鍗曠姸鎬�
+ // 4. 鏇存柊鍑哄簱鍗曠姸鎬�
productSalesMapper.updateById(new MesWmProductSalesDO()
.setId(id).setStatus(MesWmProductSalesStatusEnum.FINISHED.getStatus()));
- // 4. 鏇存柊鍏宠仈鐨勫彂璐ч�氱煡鍗曠姸鎬�
+ // 5. 鏇存柊鍏宠仈鐨勫彂璐ч�氱煡鍗曠姸鎬�
if (sales.getNoticeId() != null) {
salesNoticeService.finishSalesNotice(sales.getNoticeId());
}
- // 5. 鍥炲啓 ERP 閿�鍞鍗曠殑鍑哄簱鏁伴噺鍜岀姸鎬�
+ // 6. 鍥炲啓 ERP 閿�鍞鍗曠殑鍑哄簱鏁伴噺鍜岀姸鎬�
updateErpSaleOrderOutCount(sales);
}
@@ -296,6 +313,8 @@
MesWmProductSalesStatusEnum.CANCELED.getStatus())) {
throw exception(WM_PRODUCT_SALES_CANNOT_CANCEL);
}
+ // 閲婃斁搴撳瓨鍗犵敤
+ stockReserveService.releaseReserve(MesWmStockReserveBizTypeEnum.PRODUCT_SALES.getType(), id);
// 鍙栨秷
productSalesMapper.updateById(new MesWmProductSalesDO()
.setId(id).setStatus(MesWmProductSalesStatusEnum.CANCELED.getStatus()));
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stockreserve/MesWmStockReserveService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stockreserve/MesWmStockReserveService.java
new file mode 100644
index 0000000..f575c39
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stockreserve/MesWmStockReserveService.java
@@ -0,0 +1,73 @@
+package cn.iocoder.yudao.module.mes.service.wm.stockreserve;
+
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stockreserve.MesWmStockReserveDO;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * MES 搴撳瓨鍗犵敤 Service 鎺ュ彛
+ */
+public interface MesWmStockReserveService {
+
+ /**
+ * 鍒涘缓搴撳瓨鍗犵敤
+ *
+ * @param materialStockId 搴撳瓨璁板綍ID
+ * @param bizType 涓氬姟绫诲瀷
+ * @param bizId 涓氬姟鍗曟嵁ID
+ * @param bizCode 涓氬姟鍗曞彿
+ * @param bizLineId 涓氬姟鍗曟嵁琛孖D
+ * @param itemId 鐗╂枡ID
+ * @param quantity 鍗犵敤鏁伴噺
+ */
+ void createReserve(Long materialStockId, Integer bizType, Long bizId, String bizCode, Long bizLineId, Long itemId, BigDecimal quantity);
+
+ /**
+ * 鎵归噺鍒涘缓搴撳瓨鍗犵敤
+ *
+ * @param reserves 鍗犵敤淇℃伅鍒楄〃
+ */
+ void createReserveBatch(List<ReserveInfo> reserves);
+
+ /**
+ * 閲婃斁搴撳瓨鍗犵敤锛堝彇娑堝崟鎹椂锛�
+ *
+ * @param bizType 涓氬姟绫诲瀷
+ * @param bizId 涓氬姟鍗曟嵁ID
+ */
+ void releaseReserve(Integer bizType, Long bizId);
+
+ /**
+ * 纭鍗犵敤杞嚭搴擄紙鎵ц鍑哄簱鏃讹級
+ * 鏇存柊鍗犵敤璁板綍鐘舵�佷负宸插嚭搴擄紝骞舵墸鍑忓簱瀛樺崰鐢ㄩ噺瀛楁
+ *
+ * @param bizType 涓氬姟绫诲瀷
+ * @param bizId 涓氬姟鍗曟嵁ID
+ */
+ void confirmReserveToOutbound(Integer bizType, Long bizId);
+
+ /**
+ * 鏌ヨ鎸囧畾涓氬姟鍗曟嵁鐨勫崰鐢ㄨ褰�
+ *
+ * @param bizType 涓氬姟绫诲瀷
+ * @param bizId 涓氬姟鍗曟嵁ID
+ * @return 鍗犵敤璁板綍鍒楄〃
+ */
+ List<MesWmStockReserveDO> getReserveListByBiz(Integer bizType, Long bizId);
+
+ /**
+ * 鏌ヨ鎸囧畾鐗╂枡鐨勫崰鐢ㄦ暟閲忔眹鎬�
+ *
+ * @param itemId 鐗╂枡ID
+ * @param warehouseId 浠撳簱ID锛堝彲閫夛級
+ * @return 鍗犵敤鏁伴噺
+ */
+ BigDecimal sumReservedQuantity(Long itemId, Long warehouseId);
+
+ /**
+ * 鍗犵敤淇℃伅
+ */
+ record ReserveInfo(Long materialStockId, Integer bizType, Long bizId, String bizCode, Long bizLineId, Long itemId, BigDecimal quantity) {}
+
+}
\ No newline at end of file
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stockreserve/MesWmStockReserveServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stockreserve/MesWmStockReserveServiceImpl.java
new file mode 100644
index 0000000..e210bb6
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stockreserve/MesWmStockReserveServiceImpl.java
@@ -0,0 +1,152 @@
+package cn.iocoder.yudao.module.mes.service.wm.stockreserve;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stockreserve.MesWmStockReserveDO;
+import cn.iocoder.yudao.module.mes.dal.mysql.wm.materialstock.MesWmMaterialStockMapper;
+import cn.iocoder.yudao.module.mes.dal.mysql.wm.stockreserve.MesWmStockReserveMapper;
+import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockReserveStatusEnum;
+import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.validation.annotation.Validated;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
+
+/**
+ * MES 搴撳瓨鍗犵敤 Service 瀹炵幇绫�
+ */
+@Service
+@Validated
+@Slf4j
+public class MesWmStockReserveServiceImpl implements MesWmStockReserveService {
+
+ @Resource
+ private MesWmStockReserveMapper stockReserveMapper;
+
+ @Resource
+ private MesWmMaterialStockMapper materialStockMapper;
+
+ @Resource
+ private MesWmMaterialStockService materialStockService;
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void createReserve(Long materialStockId, Integer bizType, Long bizId, String bizCode, Long bizLineId, Long itemId, BigDecimal quantity) {
+ // 1. 鏍¢獙搴撳瓨璁板綍瀛樺湪
+ MesWmMaterialStockDO stock = materialStockService.getMaterialStock(materialStockId);
+ if (stock == null) {
+ throw exception(WM_MATERIAL_STOCK_NOT_EXISTS);
+ }
+
+ // 2. 鏍¢獙鍙敤閲忓厖瓒筹紙鍦ㄥ簱鏁伴噺 - 鍐荤粨鏁伴噺 - 宸插崰鐢ㄩ噺 >= 鏈鍗犵敤鏁伴噺锛�
+ BigDecimal availableQty = stock.getQuantity()
+ .subtract(stock.getFrozenQuantity() != null ? stock.getFrozenQuantity() : BigDecimal.ZERO)
+ .subtract(stock.getReservedQuantity() != null ? stock.getReservedQuantity() : BigDecimal.ZERO);
+ if (availableQty.compareTo(quantity) < 0) {
+ throw exception(WM_MATERIAL_STOCK_INSUFFICIENT);
+ }
+
+ // 3. 鍒涘缓鍗犵敤璁板綍
+ MesWmStockReserveDO reserve = MesWmStockReserveDO.builder()
+ .materialStockId(materialStockId)
+ .bizType(bizType)
+ .bizId(bizId)
+ .bizCode(bizCode)
+ .bizLineId(bizLineId)
+ .itemId(itemId)
+ .quantity(quantity)
+ .status(MesWmStockReserveStatusEnum.RESERVING.getStatus())
+ .build();
+ stockReserveMapper.insert(reserve);
+
+ // 4. 鏇存柊搴撳瓨鍗犵敤閲忓瓧娈碉紙绱姞锛�
+ int updatedRows = materialStockMapper.updateReservedQuantity(materialStockId, quantity, true);
+ if (updatedRows == 0) {
+ throw exception(WM_MATERIAL_STOCK_INSUFFICIENT);
+ }
+
+ log.info("[createReserve] 鍒涘缓搴撳瓨鍗犵敤鎴愬姛锛宮aterialStockId={}, bizType={}, bizId={}, quantity={}",
+ materialStockId, bizType, bizId, quantity);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void createReserveBatch(List<ReserveInfo> reserves) {
+ if (CollUtil.isEmpty(reserves)) {
+ return;
+ }
+ for (ReserveInfo reserve : reserves) {
+ createReserve(reserve.materialStockId(), reserve.bizType(), reserve.bizId(),
+ reserve.bizCode(), reserve.bizLineId(), reserve.itemId(), reserve.quantity());
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void releaseReserve(Integer bizType, Long bizId) {
+ // 1. 鏌ヨ鍗犵敤涓殑璁板綍
+ List<MesWmStockReserveDO> reserveList = stockReserveMapper.selectReservingListByBiz(bizType, bizId);
+ if (CollUtil.isEmpty(reserveList)) {
+ log.warn("[releaseReserve] 鏈壘鍒板崰鐢ㄨ褰曪紝bizType={}, bizId={}", bizType, bizId);
+ return;
+ }
+
+ // 2. 鏇存柊鍗犵敤璁板綍鐘舵�佷负宸查噴鏀撅紝骞舵墸鍑忓簱瀛樺崰鐢ㄩ噺瀛楁
+ for (MesWmStockReserveDO reserve : reserveList) {
+ // 2.1 鏇存柊鍗犵敤璁板綍鐘舵��
+ stockReserveMapper.updateById(new MesWmStockReserveDO()
+ .setId(reserve.getId())
+ .setStatus(MesWmStockReserveStatusEnum.RELEASED.getStatus()));
+
+ // 2.2 鎵e噺搴撳瓨鍗犵敤閲忥紙璐熸暟琛ㄧず鍑忓皯锛�
+ materialStockMapper.updateReservedQuantity(reserve.getMaterialStockId(), reserve.getQuantity().negate(), false);
+ }
+
+ log.info("[releaseReserve] 閲婃斁搴撳瓨鍗犵敤鎴愬姛锛宐izType={}, bizId={}, count={}", bizType, bizId, reserveList.size());
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void confirmReserveToOutbound(Integer bizType, Long bizId) {
+ // 1. 鏌ヨ鍗犵敤涓殑璁板綍
+ List<MesWmStockReserveDO> reserveList = stockReserveMapper.selectReservingListByBiz(bizType, bizId);
+ if (CollUtil.isEmpty(reserveList)) {
+ log.warn("[confirmReserveToOutbound] 鏈壘鍒板崰鐢ㄨ褰曪紝bizType={}, bizId={}", bizType, bizId);
+ return;
+ }
+
+ // 2. 鏇存柊鍗犵敤璁板綍鐘舵�佷负宸插嚭搴擄紝骞舵墸鍑忓簱瀛樺崰鐢ㄩ噺瀛楁
+ for (MesWmStockReserveDO reserve : reserveList) {
+ // 2.1 鏇存柊鍗犵敤璁板綍鐘舵��
+ stockReserveMapper.updateById(new MesWmStockReserveDO()
+ .setId(reserve.getId())
+ .setStatus(MesWmStockReserveStatusEnum.OUTBOUND.getStatus()));
+
+ // 2.2 鎵e噺搴撳瓨鍗犵敤閲忥紙璐熸暟琛ㄧず鍑忓皯锛�
+ materialStockMapper.updateReservedQuantity(reserve.getMaterialStockId(), reserve.getQuantity().negate(), false);
+ }
+
+ log.info("[confirmReserveToOutbound] 纭鍗犵敤杞嚭搴撴垚鍔燂紝bizType={}, bizId={}, count={}", bizType, bizId, reserveList.size());
+ }
+
+ @Override
+ public List<MesWmStockReserveDO> getReserveListByBiz(Integer bizType, Long bizId) {
+ return stockReserveMapper.selectListByBiz(bizType, bizId);
+ }
+
+ @Override
+ public BigDecimal sumReservedQuantity(Long itemId, Long warehouseId) {
+ if (warehouseId != null) {
+ return stockReserveMapper.sumReservedQuantityByItemAndWarehouse(itemId, warehouseId);
+ }
+ return stockReserveMapper.sumReservedQuantityByItem(itemId);
+ }
+
+}
\ No newline at end of file
--
Gitblit v1.9.3