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/account/service/impl/purchase/AccountPurchasePaymentServiceImpl.java | 63 ++++
src/main/resources/mapper/account/purchase/AccountPurchasePaymentMapper.xml | 8
src/main/resources/mapper/basic/CustomerMapper.xml | 22 +
src/main/resources/mapper/account/sales/AccountSalesCollectionMapper.xml | 8
src/main/resources/mapper/basic/SupplierManageMapper.xml | 32 +
.mcp.json | 21 +
src/main/java/com/ruoyi/account/service/sales/AccountSalesCollectionService.java | 9
src/main/java/com/ruoyi/basic/pojo/SupplierManage.java | 4
sql/product-inventory-management-new-pro.sql | 1
src/main/java/com/ruoyi/account/service/impl/sales/AccountSalesCollectionServiceImpl.java | 44 +++
src/main/java/com/ruoyi/sales/controller/MetricStatisticsController.java | 12
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml | 2
src/main/java/com/ruoyi/basic/excel/SupplierManageExcelDto.java | 3
src/main/java/com/ruoyi/production/service/impl/ProductionPlanServiceImpl.java | 94 +------
src/main/java/com/ruoyi/account/mapper/purchase/AccountPurchasePaymentMapper.java | 2
src/main/java/com/ruoyi/purchase/controller/AccountingReportController.java | 11
src/main/java/com/ruoyi/purchase/dto/SavePaymentDto.java | 35 ++
src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java | 3
src/main/resources/application-dev.yml | 2
doc/20260826_生产计划与销售发货数量规则前端联调文档.md | 331 +++++++++++++++++++++++++
src/main/java/com/ruoyi/sales/dto/SaveReceiptPaymentDto.java | 35 ++
src/main/java/com/ruoyi/account/mapper/sales/AccountSalesCollectionMapper.java | 2
src/main/java/com/ruoyi/account/service/purchase/AccountPurchasePaymentService.java | 9
23 files changed, 648 insertions(+), 105 deletions(-)
diff --git a/.mcp.json b/.mcp.json
new file mode 100644
index 0000000..88094b6
--- /dev/null
+++ b/.mcp.json
@@ -0,0 +1,21 @@
+{
+ "mcpServers": {
+ "mysql": {
+ "type": "stdio",
+ "command": "npx",
+ "args": [
+ "@benborla29/mcp-server-mysql"
+ ],
+ "env": {
+ "MYSQL_HOST": "127.0.0.1",
+ "MYSQL_PORT": "3306",
+ "MYSQL_USER": "root",
+ "MYSQL_PASS": "123456",
+ "MYSQL_DB": "product-inventory-management-new-pro",
+ "ALLOW_INSERT_OPERATION": "false",
+ "ALLOW_UPDATE_OPERATION": "false",
+ "ALLOW_DELETE_OPERATION": "false"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git "a/doc/20260826_\347\224\237\344\272\247\350\256\241\345\210\222\344\270\216\351\224\200\345\224\256\345\217\221\350\264\247\346\225\260\351\207\217\350\247\204\345\210\231\345\211\215\347\253\257\350\201\224\350\260\203\346\226\207\346\241\243.md" "b/doc/20260826_\347\224\237\344\272\247\350\256\241\345\210\222\344\270\216\351\224\200\345\224\256\345\217\221\350\264\247\346\225\260\351\207\217\350\247\204\345\210\231\345\211\215\347\253\257\350\201\224\350\260\203\346\226\207\346\241\243.md"
new file mode 100644
index 0000000..ad73a4e
--- /dev/null
+++ "b/doc/20260826_\347\224\237\344\272\247\350\256\241\345\210\222\344\270\216\351\224\200\345\224\256\345\217\221\350\264\247\346\225\260\351\207\217\350\247\204\345\210\231\345\211\215\347\253\257\350\201\224\350\260\203\346\226\207\346\241\243.md"
@@ -0,0 +1,331 @@
+# 鐢熶骇璁″垝涓庨攢鍞彂璐ф暟閲忚鍒欏墠绔仈璋冩枃妗�
+
+鏇存柊鏃堕棿锛�2026-08-26
+
+## 1. 鏈璋冩暣姒傝堪
+
+### 1.1 鐢熶骇璁″垝涓嬪彂
+
+鐢熶骇璁″垝涓嬪彂涓嶅啀鍙椾互涓嬭鍒欓檺鍒讹細
+
+- 涓嶅啀闄愬埗鏈涓嬪彂鏁伴噺涓嶈兘瓒呰繃闇�姹傛暟閲忓墿浣欓噺銆�
+- 宸蹭笅鍙戞暟閲忚揪鍒伴渶姹傛暟閲忓悗锛屼粛鍙互缁х画涓嬪彂銆�
+- `quantityIssued` 鍏佽绱瓒呰繃 `qtyRequired`銆�
+
+浠嶇劧淇濈暀浠ヤ笅鏍¢獙锛�
+
+- 鑷冲皯閫夋嫨涓�涓敓浜ц鍒掋��
+- `totalAssignedQuantity` 蹇呴』澶т簬 0銆�
+- 閫夋嫨鐨勭敓浜ц鍒掑繀椤诲瓨鍦ㄣ��
+- 鍚堝苟涓嬪彂鐨勭敓浜ц鍒掑繀椤诲睘浜庡悓涓�涓骇鍝佸瀷鍙枫��
+
+### 1.2 閿�鍞彂璐�
+
+閿�鍞彂璐т笉鍐嶅彈浠ヤ笅瑙勫垯闄愬埗锛�
+
+- 涓嶅啀鍙楅攢鍞骇鍝� `quantity` 闄愬埗銆�
+- 涓嶅啀鍙楀凡鍙戣揣鏁伴噺闄愬埗銆�
+- 涓嶅啀鍙楀緟瀹℃壒鍙戣揣鏁伴噺闄愬埗銆�
+- 閿�鍞骇鍝佸凡鏄剧ず鈥滃凡鍙戣揣鈥濆悗锛屼粛鍙互缁х画鎻愪氦鍙戣揣銆�
+
+閿�鍞彂璐т粛鐒跺繀椤绘弧瓒冲簱瀛樻牎楠岋細
+
+```text
+鍙敤搴撳瓨 = 搴撳瓨鏁伴噺 - 鍐荤粨搴撳瓨 - 寰呭嚭搴撴暟閲�
+```
+
+鍙戣揣鏁伴噺瓒呰繃鍙敤搴撳瓨鏃讹紝鎺ュ彛浠嶇劧杩斿洖澶辫触銆�
+
+## 2. 閫氱敤鍝嶅簲
+
+鎴愬姛鍝嶅簲绀轰緥锛�
+
+```json
+{
+ "code": 200,
+ "msg": "鎿嶄綔鎴愬姛",
+ "data": true
+}
+```
+
+澶辫触鍝嶅簲绀轰緥锛�
+
+```json
+{
+ "code": 500,
+ "msg": "涓嬪彂澶辫触锛屼笅鍙戞暟閲忓繀椤诲ぇ浜�0",
+ "data": null
+}
+```
+
+## 3. 鐢熶骇璁″垝涓嬪彂
+
+### 3.1 鎺ュ彛鍦板潃
+
+```text
+POST /productionPlan/combine
+```
+
+### 3.2 璇锋眰浣�
+
+```json
+{
+ "ids": [101, 102],
+ "totalAssignedQuantity": 500,
+ "planCompleteTime": "2026-08-30"
+}
+```
+
+瀛楁璇存槑锛�
+
+| 瀛楁 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+| --- | --- | --- | --- |
+| `ids` | `number[]` | 鏄� | 瑕佷笅鍙戠殑鐢熶骇璁″垝 ID 闆嗗悎锛屽缓璁墠绔幓閲� |
+| `totalAssignedQuantity` | `number` | 鏄� | 鏈鎬荤敓浜ф暟閲忥紝鍙渶澶т簬 0锛屼笉鍐嶄笌闇�姹傚墿浣欐暟閲忔瘮杈� |
+| `planCompleteTime` | `string` | 鍚� | 璁″垝瀹屾垚鏃ユ湡锛屾牸寮� `yyyy-MM-dd` |
+
+### 3.3 鍓嶇澶勭悊瑕佹眰
+
+1. 涓嬪彂鏁伴噺杈撳叆妗嗗彧鏍¢獙澶т簬 0锛屼笉瑕佸啀璁剧疆鈥滃墿浣欓渶姹傛�婚噺鈥濅綔涓烘渶澶у�笺��
+2. 鐢熶骇璁″垝 `status=2` 鐨勮褰曞厑璁稿啀娆″嬀閫夊拰涓嬪彂銆�
+3. 涓嶈鍥犱负 `quantityIssued >= qtyRequired` 绂佺敤涓嬪彂鎸夐挳銆�
+4. 涓嬪彂鎴愬姛鍚庡埛鏂扮敓浜ц鍒掑垪琛ㄥ拰鐢熶骇璁㈠崟鍒楄〃銆�
+5. `quantityIssued` 鍙兘澶т簬 `qtyRequired`锛屽墠绔笉瑕佸仛瓒呴噺鎴柇鎴栧紓甯告彁绀恒��
+6. 浠嶇劧绂佹閫夋嫨涓嶅悓浜у搧鍨嬪彿鐨勮鍒掕繘琛屽悎骞朵笅鍙戯紝鍚庣浼氬啀娆℃牎楠屻��
+
+### 3.4 鐢熶骇璁″垝鐘舵��
+
+| 鐘舵�佸�� | 鍚箟 |
+| --- | --- |
+| `0` | 鏈笅鍙� |
+| `1` | 閮ㄥ垎涓嬪彂 |
+| `2` | 宸蹭笅鍙� |
+
+娉ㄦ剰锛氱姸鎬� `2` 鐜板湪鍙〃绀哄師闇�姹傛暟閲忓凡瀹屾垚锛屼笉浠h〃璇ヨ鍒掍笉鑳藉啀娆′笅鍙戙�傜姸鎬佷负 `2` 鐨勮鍒掑啀娆′笅鍙戝悗锛岀姸鎬佷粛鍙兘淇濇寔 `2`锛屽悓鏃� `quantityIssued` 浼氱户缁疮璁°��
+
+### 3.5 鑱旇皟鍦烘櫙
+
+#### 鍦烘櫙涓�锛氫笅鍙戞暟閲忚秴杩囬渶姹傛暟閲�
+
+鍋囪锛�
+
+- 闇�姹傛暟閲忥細100
+- 宸蹭笅鍙戞暟閲忥細100
+- 鏈涓嬪彂鏁伴噺锛�20
+
+璇锋眰锛�
+
+```json
+{
+ "ids": [101],
+ "totalAssignedQuantity": 20
+}
+```
+
+棰勬湡锛�
+
+- 璇锋眰鎴愬姛銆�
+- 鏂板缓鐢熶骇璁㈠崟鏁伴噺涓� 20銆�
+- 鐢熶骇璁″垝 `quantityIssued` 鏇存柊涓� 120銆�
+- 涓嶈繑鍥炩�滀笉鑳藉ぇ浜庤鍒掑墿浣欓渶姹傛�婚噺鈥濄��
+
+#### 鍦烘櫙浜岋細涓�娆¢�夋嫨澶氫釜鍚屽瀷鍙疯鍒�
+
+```json
+{
+ "ids": [101, 102, 103],
+ "totalAssignedQuantity": 500
+}
+```
+
+棰勬湡鐢熶骇璁㈠崟鐨勬�绘暟閲忎负 500锛屼笉鍐嶆牴鎹悇璁″垝闇�姹傛暟閲忔埅鏂��
+
+#### 鍦烘櫙涓夛細閫夋嫨涓嶅悓鍨嬪彿璁″垝
+
+璇锋眰浠嶇劧澶辫触锛屾彁绀烘墍閫夌敓浜ц鍒掔殑浜у搧鍨嬪彿涓嶄竴鑷淬�傝鏍¢獙娌℃湁鍙栨秷銆�
+
+## 4. 閿�鍞骇鍝佸垪琛�
+
+閿�鍞骇鍝佸垪琛ㄤ腑鐨� `noQuantity` 涓嶅啀琛ㄧず閿�鍞鍗曞墿浣欏彲鍙戞暟閲忋��
+
+鍚庣杩斿洖锛�
+
+```json
+{
+ "quantity": 10,
+ "shippedQuantity": 10,
+ "pendingApprovalQuantity": 0,
+ "noQuantity": null
+}
+```
+
+瀛楁璇存槑锛�
+
+| 瀛楁 | 璇存槑 |
+| --- | --- |
+| `quantity` | 閿�鍞骇鍝佸師濮嬫暟閲忥紝浠呯敤浜庨攢鍞笟鍔″睍绀猴紝涓嶄綔涓哄彂璐ф暟閲忎笂闄� |
+| `shippedQuantity` | 宸插彂璐ф暟閲忥紝浠呯敤浜庣粺璁″睍绀� |
+| `pendingApprovalQuantity` | 寰呭鏍告垨瀹℃牳涓殑鍙戣揣鏁伴噺锛屼粎鐢ㄤ簬缁熻灞曠ず |
+| `noQuantity` | 涓嶅啀鎻愪緵閿�鍞墿浣欏彲鍙戞暟閲忥紝鍊间负 `null` |
+
+鍓嶇娉ㄦ剰锛�
+
+- 涓嶈浣跨敤 `noQuantity` 浣滀负鍙戣揣鏁伴噺杈撳叆妗嗙殑 `max`銆�
+- 涓嶈鍥犱负 `noQuantity <= 0` 绂佺敤鍙戣揣鎸夐挳銆�
+- 涓嶈鐢� `quantity - shippedQuantity - pendingApprovalQuantity` 閲嶆柊璁$畻鍙戣揣涓婇檺銆�
+- 鍙戣揣鏁伴噺杈撳叆妗嗙殑鏈�澶у�煎簲鐢卞疄闄呭簱瀛樹俊鎭垨鐢ㄦ埛閫夋嫨鐨勫簱瀛樻壒娆″喅瀹氥��
+- `shippingStatus` 浠嶅彲鐢ㄤ簬灞曠ず锛屼絾涓嶈兘浣滀负鏄惁鍏佽缁х画鍙戣揣鐨勭‖鎬ф潯浠躲��
+
+## 5. 鏂板閿�鍞彂璐�
+
+### 5.1 鎺ュ彛鍦板潃
+
+```text
+POST /shippingInfo/add
+```
+
+### 5.2 璇锋眰浣撶ず渚�
+
+```json
+{
+ "salesLedgerId": 2001,
+ "salesLedgerProductId": 3001,
+ "type": "閿�鍞彂璐�",
+ "batchNoDetailList": [
+ {
+ "productModelId": 501,
+ "batchNo": "BATCH-20260826-001",
+ "quantity": 30
+ }
+ ],
+ "storageBlobDTOs": []
+}
+```
+
+瀛楁璇存槑锛�
+
+| 瀛楁 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+| --- | --- | --- | --- |
+| `salesLedgerId` | `number` | 鎸変笟鍔� | 閿�鍞彴璐� ID |
+| `salesLedgerProductId` | `number` | 寤鸿浼犲叆 | 閿�鍞彴璐︿骇鍝� ID锛岀敤浜庡叧鑱旈攢鍞骇鍝佸強閲嶅鎻愪氦鏍¢獙 |
+| `type` | `string` | 鍚� | 鍙戣揣绫诲瀷 |
+| `batchNoDetailList` | `array` | 鏄� | 鍙戣揣鎵规鏄庣粏 |
+| `batchNoDetailList[].productModelId` | `number` | 鏄� | 浜у搧鍨嬪彿 ID |
+| `batchNoDetailList[].batchNo` | `string` | 鏄� | 搴撳瓨鎵规鍙� |
+| `batchNoDetailList[].quantity` | `number` | 鏄� | 鏈壒娆″彂璐ф暟閲� |
+| `storageBlobDTOs` | `array` | 鍚� | 闄勪欢鍒楄〃锛屾病鏈夐檮浠舵椂浼犵┖鏁扮粍 |
+
+### 5.3 閲嶈瑙勫垯
+
+1. 鍙戣揣鏁伴噺鍙互澶т簬閿�鍞骇鍝佸墿浣欐暟閲忋��
+2. 姣忎釜鎵规閮藉繀椤诲瓨鍦ㄥ簱瀛樿褰曘��
+3. 姣忎釜鎵规鐨勫彂璐ф暟閲忎笉鑳借秴杩囪鎵规鍙敤搴撳瓨銆�
+4. 鍙敤搴撳瓨浼氭墸闄ゅ喕缁撳簱瀛樺拰宸叉湁寰呭嚭搴撴暟閲忋��
+5. 鍚屼竴閿�鍞骇鍝佸凡鏈夆�滃緟瀹℃牳鈥濇垨鈥滃鏍镐腑鈥濆彂璐ц褰曟椂锛屼粛涓嶅厑璁搁噸澶嶆彁浜ゃ��
+6. 鏂板鎴愬姛鍚庯紝鍙戣揣鍗曡繘鍏ュ鎵规祦绋嬶紝閫氬父鐘舵�佷负鈥滃鏍镐腑鈥濄��
+
+搴撳瓨涓嶈冻鏃跺彲鑳借繑鍥烇細
+
+```text
+搴撳瓨璁板綍涓嶅瓨鍦�
+```
+
+鎴栵細
+
+```text
+鐢宠鏁伴噺瓒呰繃鍙敤搴撳瓨锛屽綋鍓嶅彲鐢ㄥ簱瀛樹负锛歺xx
+```
+
+### 5.4 鑱旇皟鍦烘櫙
+
+#### 鍦烘櫙涓�锛氶攢鍞暟閲忓凡鍙戝畬锛屼絾搴撳瓨鍏呰冻
+
+鍋囪锛�
+
+- 閿�鍞暟閲忥細10
+- 宸插彂璐ф暟閲忥細10
+- 褰撳墠鎵规鍙敤搴撳瓨锛�30
+- 鏈鍙戣揣鏁伴噺锛�20
+
+棰勬湡锛�
+
+- `/shippingInfo/add` 璇锋眰鍏佽鎻愪氦銆�
+- 涓嶅洜涓洪攢鍞暟閲忓凡鐢ㄥ畬鑰屽け璐ャ��
+- 鍚庣画浠嶆寜鐓у鎵规祦绋嬪鐞嗐��
+
+#### 鍦烘櫙浜岋細閿�鍞暟閲忔湭鍙戝畬锛屼絾搴撳瓨涓嶈冻
+
+鍋囪锛�
+
+- 閿�鍞墿浣欐暟閲忥細100
+- 褰撳墠鎵规鍙敤搴撳瓨锛�5
+- 鏈鍙戣揣鏁伴噺锛�6
+
+棰勬湡锛�
+
+- 璇锋眰澶辫触銆�
+- 杩斿洖搴撳瓨涓嶈冻淇℃伅銆�
+- 涓嶅簲璁や负閿�鍞墿浣欐暟閲忚冻澶熷氨鍏佽鍙戣揣銆�
+
+#### 鍦烘櫙涓夛細澶氫釜搴撳瓨鎵规
+
+```json
+{
+ "salesLedgerProductId": 3001,
+ "batchNoDetailList": [
+ {
+ "productModelId": 501,
+ "batchNo": "BATCH-A",
+ "quantity": 10
+ },
+ {
+ "productModelId": 501,
+ "batchNo": "BATCH-B",
+ "quantity": 15
+ }
+ ]
+}
+```
+
+姣忎釜鎵规鐙珛鏍¢獙搴撳瓨锛涗换鎰忎竴涓壒娆″簱瀛樹笉瓒虫椂锛屾暣娆¤姹傚け璐ュ苟鍥炴粴銆�
+
+## 6. 瀹℃壒閫氳繃鍚庣‘璁ゅ彂璐�
+
+### 6.1 鎺ュ彛鍦板潃
+
+```text
+POST /shippingInfo/deductStock
+```
+
+### 6.2 璇锋眰浣撶ず渚�
+
+```json
+{
+ "id": 4001,
+ "expressCompany": "椤轰赴",
+ "expressNumber": "SF1234567890",
+ "shippingCarNumber": "鑻廇12345",
+ "shippingDate": "2026-08-26"
+}
+```
+
+璇存槑锛�
+
+- `id` 涓哄彂璐у崟 ID锛屽繀濉��
+- 鎺ュ彛浼氬啀娆℃寜鍙戣揣鏄庣粏鏍¢獙搴撳瓨銆�
+- 鎴愬姛鍚庡彂璐у崟鐘舵�佹洿鏂颁负鈥滃凡鍙戣揣鈥濄��
+- 褰撳墠鎺ュ彛涓嶄細鏍规嵁閿�鍞骇鍝佸師濮嬫暟閲忛檺鍒跺彂璐с��
+- 宸茬粡鏄�滃凡鍙戣揣鈥濈姸鎬佹椂锛屼笉浼氶噸澶嶆墸鍑忓簱瀛樸��
+
+## 7. 鍓嶇鑱旇皟妫�鏌ユ竻鍗�
+
+- [ ] 鐢熶骇璁″垝涓嬪彂鏁伴噺杈撳叆妗嗕笉鍐嶇粦瀹氶渶姹傚墿浣欓噺鏈�澶у�笺��
+- [ ] 鐘舵�佷负 `2` 鐨勭敓浜ц鍒掍粛鍙�夋嫨涓嬪彂銆�
+- [ ] 鐢熶骇璁″垝涓嬪彂鎴愬姛鍚庡厑璁� `quantityIssued > qtyRequired` 灞曠ず銆�
+- [ ] 閿�鍞骇鍝佸垪琛ㄤ笉浣跨敤 `noQuantity` 闄愬埗鍙戣揣鏁伴噺銆�
+- [ ] `noQuantity=null` 鏃堕〉闈笉鏄剧ず涓衡�滀笉鍙彂璐р�濄��
+- [ ] 閿�鍞骇鍝佺姸鎬佲�滃凡鍙戣揣鈥濅笉鍐嶇洿鎺ョ鐢ㄥ彂璐ф搷浣溿��
+- [ ] 鍙戣揣鏁伴噺鏀圭敱搴撳瓨鎵规鍙敤閲忔帶鍒躲��
+- [ ] 搴撳瓨涓嶈冻鏃舵纭睍绀哄悗绔敊璇俊鎭��
+- [ ] 鍚屼竴閿�鍞骇鍝佸緟瀹℃牳/瀹℃牳涓噸澶嶆彁浜や粛鎸夊悗绔彁绀哄鐞嗐��
+- [ ] 鐢熶骇璁″垝銆侀攢鍞彂璐ф彁浜ゆ垚鍔熷悗鍒锋柊鍒楄〃鏁版嵁銆�
diff --git a/sql/product-inventory-management-new-pro.sql b/sql/product-inventory-management-new-pro.sql
index 2752b38..ea5813b 100644
--- a/sql/product-inventory-management-new-pro.sql
+++ b/sql/product-inventory-management-new-pro.sql
@@ -4895,6 +4895,7 @@
`company_phone` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鍏徃鐢佃瘽',
`bank_account_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '寮�鎴疯',
`bank_account_num` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '璐﹀彿',
+ `bank_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '閾惰仈琛屽彿',
`contact_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鑱旂郴浜�',
`contact_user_phone` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '鑱旂郴鐢佃瘽',
`maintain_user_id` bigint NULL DEFAULT NULL COMMENT '缁存姢浜篒D',
diff --git a/src/main/java/com/ruoyi/account/mapper/purchase/AccountPurchasePaymentMapper.java b/src/main/java/com/ruoyi/account/mapper/purchase/AccountPurchasePaymentMapper.java
index f687c74..df2faa8 100644
--- a/src/main/java/com/ruoyi/account/mapper/purchase/AccountPurchasePaymentMapper.java
+++ b/src/main/java/com/ruoyi/account/mapper/purchase/AccountPurchasePaymentMapper.java
@@ -26,4 +26,6 @@
IPage<AccountPurchasePaymentVo> listPageAccountPurchasePayment(Page page, @Param("req") AccountPurchasePaymentDto accountPurchasePaymentDto);
List<IncomeExpenseAnalysisDto> selectPayment(@Param("startStr") String startStr, @Param("endStr") String endStr, @Param("dateFormat") String dateFormat);
+
+ List<Long> selectStockInRecordIdsByPurchaseLedgerId(@Param("purchaseLedgerId") Long purchaseLedgerId);
}
diff --git a/src/main/java/com/ruoyi/account/mapper/sales/AccountSalesCollectionMapper.java b/src/main/java/com/ruoyi/account/mapper/sales/AccountSalesCollectionMapper.java
index 2f1cf6e..3052047 100644
--- a/src/main/java/com/ruoyi/account/mapper/sales/AccountSalesCollectionMapper.java
+++ b/src/main/java/com/ruoyi/account/mapper/sales/AccountSalesCollectionMapper.java
@@ -32,4 +32,6 @@
List<SalesOutboundVo> getOutboundBatchesByCustomer(@Param("customerId") Integer customerId);
List<IncomeExpenseAnalysisDto> selectIncomeStats(@Param("startStr") String startStr, @Param("endStr") String endStr, @Param("dateFormat") String dateFormat);
+
+ List<Long> selectStockOutRecordIdsBySalesLedgerId(@Param("salesLedgerId") Long salesLedgerId);
}
diff --git a/src/main/java/com/ruoyi/account/service/impl/purchase/AccountPurchasePaymentServiceImpl.java b/src/main/java/com/ruoyi/account/service/impl/purchase/AccountPurchasePaymentServiceImpl.java
index b9953a0..4535525 100644
--- a/src/main/java/com/ruoyi/account/service/impl/purchase/AccountPurchasePaymentServiceImpl.java
+++ b/src/main/java/com/ruoyi/account/service/impl/purchase/AccountPurchasePaymentServiceImpl.java
@@ -1,10 +1,11 @@
package com.ruoyi.account.service.impl.purchase;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import com.ruoyi.account.bean.dto.purchase.AccountPurchasePaymentDto;
import com.ruoyi.account.bean.vo.purchase.AccountPurchasePaymentVo;
import com.ruoyi.account.mapper.AccountStatementDetailsMapper;
@@ -17,15 +18,20 @@
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.purchase.dto.SavePaymentDto;
+import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
+import com.ruoyi.purchase.pojo.PurchaseLedger;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Random;
+import java.util.stream.Collectors;
/**
* <p>
@@ -43,6 +49,7 @@
private final AccountPurchasePaymentMapper accountPurchasePaymentMapper;
private final AccountStatementDetailsMapper accountStatementDetailsMapper;
private final AccountPaymentApplicationMapper accountPaymentApplicationMapper;
+ private final PurchaseLedgerMapper purchaseLedgerMapper;
@Override
public IPage<AccountPurchasePaymentVo> listPageAccountPurchasePayment(Page page, AccountPurchasePaymentDto accountPurchasePaymentDto) {
@@ -84,6 +91,60 @@
return removeByIds(ids);
}
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public boolean savePayment(SavePaymentDto dto) {
+ if (dto.getPaymentDate() == null) {
+ throw new ServiceException("璇烽�夋嫨浠樻鏃ユ湡");
+ }
+ if (dto.getPaymentAmount() == null || dto.getPaymentAmount().compareTo(BigDecimal.valueOf(0.01)) < 0) {
+ throw new ServiceException("璇疯緭鍏ヤ粯娆鹃噾棰�");
+ }
+ if (StringUtils.isEmpty(dto.getPurchaseContractNumber())) {
+ throw new ServiceException("閲囪喘鍚堝悓鍙蜂笉鑳戒负绌�");
+ }
+ if (dto.getSupplierId() == null) {
+ throw new ServiceException("渚涘簲鍟嗕笉鑳戒负绌�");
+ }
+
+ PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectOne(new LambdaQueryWrapper<PurchaseLedger>()
+ .eq(PurchaseLedger::getPurchaseContractNumber, dto.getPurchaseContractNumber()));
+ if (purchaseLedger == null) {
+ throw new ServiceException("閲囪喘鍚堝悓涓嶅瓨鍦�");
+ }
+ if (purchaseLedger.getSupplierId() == null || purchaseLedger.getSupplierId().longValue() != dto.getSupplierId().longValue()) {
+ throw new ServiceException("渚涘簲鍟嗕笌鍚堝悓涓嶅尮閰�");
+ }
+
+ List<Long> stockInRecordIds = accountPurchasePaymentMapper.selectStockInRecordIdsByPurchaseLedgerId(purchaseLedger.getId());
+
+ AccountPaymentApplication application = new AccountPaymentApplication();
+ application.setSupplierId(dto.getSupplierId().intValue());
+ application.setStockInRecordIds(stockInRecordIds.stream().map(String::valueOf).collect(Collectors.joining(",")));
+ application.setInvoiceApplicationNo(genPaymentApplicationNo());
+ application.setPaymentMethod(dto.getPaymentMethod());
+ application.setPaymentContent(dto.getPurchaseContractNumber());
+ application.setApplyDate(dto.getPaymentDate());
+ application.setRemark(dto.getRemark());
+ application.setStatus(1);
+ application.setPaymentAmount(dto.getPaymentAmount());
+ accountPaymentApplicationMapper.insert(application);
+
+ AccountPurchasePayment payment = new AccountPurchasePayment();
+ payment.setAccountPaymentApplicationId(application.getId());
+ payment.setSupplierId(dto.getSupplierId().intValue());
+ payment.setPaymentDate(dto.getPaymentDate());
+ payment.setPaymentMethod(dto.getPaymentMethod());
+ payment.setPaymentAmount(dto.getPaymentAmount());
+ payment.setPaymentNumber(genAccountPurchasePaymentNo());
+ payment.setRemark(dto.getRemark());
+ return save(payment);
+ }
+
+ private String genPaymentApplicationNo() {
+ return "FK" + LocalDateTime.now().format(CODE_TIME_FORMATTER) + new Random().nextInt(10);
+ }
+
private String genAccountPurchasePaymentNo() {
return "SK" + LocalDateTime.now().format(CODE_TIME_FORMATTER) + new Random().nextInt(10);
}
diff --git a/src/main/java/com/ruoyi/account/service/impl/sales/AccountSalesCollectionServiceImpl.java b/src/main/java/com/ruoyi/account/service/impl/sales/AccountSalesCollectionServiceImpl.java
index 45900d7..6980280 100644
--- a/src/main/java/com/ruoyi/account/service/impl/sales/AccountSalesCollectionServiceImpl.java
+++ b/src/main/java/com/ruoyi/account/service/impl/sales/AccountSalesCollectionServiceImpl.java
@@ -1,5 +1,6 @@
package com.ruoyi.account.service.impl.sales;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -16,13 +17,16 @@
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.sales.dto.SaveReceiptPaymentDto;
+import com.ruoyi.sales.mapper.SalesLedgerMapper;
+import com.ruoyi.sales.pojo.SalesLedger;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
+import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
-import java.util.Arrays;
import java.util.List;
import java.util.Random;
@@ -40,6 +44,7 @@
private final AccountSalesCollectionMapper accountSalesCollectionMapper;
private final AccountStatementDetailsMapper accountStatementDetailsMapper;
+ private final SalesLedgerMapper salesLedgerMapper;
private static final DateTimeFormatter CODE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyMMddHHmmss");
@@ -90,6 +95,43 @@
return accountSalesCollectionMapper.getOutboundBatchesByCustomer(customerId);
}
+ @Override
+ public boolean saveReceiptPayment(SaveReceiptPaymentDto dto) {
+ if (dto.getPaymentDate() == null) {
+ throw new ServiceException("璇烽�夋嫨鍥炴鏃ユ湡");
+ }
+ if (dto.getPaymentAmount() == null || dto.getPaymentAmount().compareTo(BigDecimal.valueOf(0.01)) < 0) {
+ throw new ServiceException("璇疯緭鍏ュ洖娆鹃噾棰�");
+ }
+ if (StringUtils.isEmpty(dto.getSalesContractNo())) {
+ throw new ServiceException("閿�鍞悎鍚屽彿涓嶈兘涓虹┖");
+ }
+ if (dto.getCustomerId() == null) {
+ throw new ServiceException("瀹㈡埛涓嶈兘涓虹┖");
+ }
+
+ SalesLedger salesLedger = salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>()
+ .eq(SalesLedger::getSalesContractNo, dto.getSalesContractNo()));
+ if (salesLedger == null) {
+ throw new ServiceException("閿�鍞悎鍚屼笉瀛樺湪");
+ }
+ if (salesLedger.getCustomerId() == null || salesLedger.getCustomerId().longValue() != dto.getCustomerId().longValue()) {
+ throw new ServiceException("瀹㈡埛涓庡悎鍚屼笉鍖归厤");
+ }
+
+ List<Long> stockOutRecordIds = accountSalesCollectionMapper.selectStockOutRecordIdsBySalesLedgerId(salesLedger.getId());
+
+ AccountSalesCollection collection = new AccountSalesCollection();
+ collection.setCustomerId(dto.getCustomerId().intValue());
+ collection.setStockOutRecordIds(stockOutRecordIds.stream().map(String::valueOf).collect(java.util.stream.Collectors.joining(",")));
+ collection.setCollectionDate(dto.getPaymentDate());
+ collection.setCollectionAmount(dto.getPaymentAmount());
+ collection.setCollectionMethod(dto.getPaymentMethod());
+ collection.setCollectionNumber(genAccountSalesCollectionNo());
+ collection.setRemark(dto.getRemark());
+ return save(collection);
+ }
+
private String genAccountSalesCollectionNo() {
return "SK" + LocalDateTime.now().format(CODE_TIME_FORMATTER) + new Random().nextInt(10);
}
diff --git a/src/main/java/com/ruoyi/account/service/purchase/AccountPurchasePaymentService.java b/src/main/java/com/ruoyi/account/service/purchase/AccountPurchasePaymentService.java
index 018a497..42eda98 100644
--- a/src/main/java/com/ruoyi/account/service/purchase/AccountPurchasePaymentService.java
+++ b/src/main/java/com/ruoyi/account/service/purchase/AccountPurchasePaymentService.java
@@ -5,6 +5,7 @@
import com.ruoyi.account.bean.dto.purchase.AccountPurchasePaymentDto;
import com.ruoyi.account.bean.vo.purchase.AccountPurchasePaymentVo;
import com.ruoyi.account.pojo.purchase.AccountPurchasePayment;
+import com.ruoyi.purchase.dto.SavePaymentDto;
import com.baomidou.mybatisplus.extension.service.IService;
import jakarta.servlet.http.HttpServletResponse;
@@ -27,4 +28,12 @@
void exportAccountPurchasePayment(HttpServletResponse response, AccountPurchasePaymentDto accountPurchasePaymentDto);
boolean deleteAccountPurchasePayment(List<Long> ids);
+
+ /**
+ * 閲囪喘绠$悊--渚涘簲鍟嗗線鏉� 鏂板浠樻
+ *
+ * @param dto 浠樻璇锋眰鍙傛暟
+ * @return 鏄惁鎴愬姛
+ */
+ boolean savePayment(SavePaymentDto dto);
}
diff --git a/src/main/java/com/ruoyi/account/service/sales/AccountSalesCollectionService.java b/src/main/java/com/ruoyi/account/service/sales/AccountSalesCollectionService.java
index d5172fb..af24a9c 100644
--- a/src/main/java/com/ruoyi/account/service/sales/AccountSalesCollectionService.java
+++ b/src/main/java/com/ruoyi/account/service/sales/AccountSalesCollectionService.java
@@ -6,6 +6,7 @@
import com.ruoyi.account.bean.vo.sales.AccountSalesCollectionVo;
import com.ruoyi.account.bean.vo.sales.SalesOutboundVo;
import com.ruoyi.account.pojo.sales.AccountSalesCollection;
+import com.ruoyi.sales.dto.SaveReceiptPaymentDto;
import com.baomidou.mybatisplus.extension.service.IService;
import jakarta.servlet.http.HttpServletResponse;
@@ -30,4 +31,12 @@
boolean deleteAccountSalesCollection(List<Long> ids);
List<SalesOutboundVo> getOutboundBatchesByCustomer(Integer customerId);
+
+ /**
+ * 钀ラ攢绠$悊--瀹㈡埛寰�鏉� 鏂板鍥炴
+ *
+ * @param dto 鍥炴璇锋眰鍙傛暟
+ * @return 鏄惁鎴愬姛
+ */
+ boolean saveReceiptPayment(SaveReceiptPaymentDto dto);
}
diff --git a/src/main/java/com/ruoyi/basic/excel/SupplierManageExcelDto.java b/src/main/java/com/ruoyi/basic/excel/SupplierManageExcelDto.java
index 87b197f..5128452 100644
--- a/src/main/java/com/ruoyi/basic/excel/SupplierManageExcelDto.java
+++ b/src/main/java/com/ruoyi/basic/excel/SupplierManageExcelDto.java
@@ -30,6 +30,9 @@
@Excel(name = "璐﹀彿")
private String bankAccountNum;
+ @Excel(name = "閾惰仈琛屽彿")
+ private String bankCode;
+
@Excel(name = "鑱旂郴浜�")
private String contactUserName;
diff --git a/src/main/java/com/ruoyi/basic/pojo/SupplierManage.java b/src/main/java/com/ruoyi/basic/pojo/SupplierManage.java
index fa10c92..e3bdf27 100644
--- a/src/main/java/com/ruoyi/basic/pojo/SupplierManage.java
+++ b/src/main/java/com/ruoyi/basic/pojo/SupplierManage.java
@@ -40,6 +40,10 @@
@Excel(name = "璐﹀彿")
private String bankAccountNum;
+ @Schema(description = "閾惰仈琛屽彿")
+ @Excel(name = "閾惰仈琛屽彿")
+ private String bankCode;
+
@Schema(description = "鑱旂郴浜�")
@Excel(name = "鑱旂郴浜�")
private String contactUserName;
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java
index 95c7344..f64d44f 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java
@@ -666,9 +666,6 @@
if (productModelIds.size() > 1) {
throw new ServiceException("鎵�閫夌敓浜ц鍒掑繀椤诲睘浜庡悓涓�浜у搧瑙勬牸");
}
- if (productionPlans.stream().anyMatch(item -> item.getStatus() != null && item.getStatus() == 2)) {
- throw new ServiceException("鎵�閫夌敓浜ц鍒掑凡涓嬪彂");
- }
ProductionPlan firstPlan = mainPlan;
if (productionOrder.getProductModelId() == null) {
productionOrder.setProductModelId(firstPlan.getProductModelId());
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 53b1ee9..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,49 +100,18 @@
throw new BaseException("鍚堝苟澶辫触锛屾墍閫夌敓浜ц鍒掔殑浜у搧鍨嬪彿涓嶄竴鑷�");
}
- // 浠呪�滃凡涓嬪彂鈥濊鍒掍笉鍏佽鍐嶆鍙備笌鍚堝苟涓嬪彂锛�
- // 鈥滃緟涓嬪彂/閮ㄥ垎涓嬪彂鈥濆厑璁哥户缁笅鍙戝墿浣欐暟閲忋��
- boolean hasFullyIssuedPlan = planLists.stream()
- .anyMatch(item -> item.getStatus() != null
- && item.getStatus() == PLAN_STATUS_ISSUED);
- if (hasFullyIssuedPlan) {
- 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();
@@ -155,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);
@@ -455,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);
}
/**
diff --git a/src/main/java/com/ruoyi/purchase/controller/AccountingReportController.java b/src/main/java/com/ruoyi/purchase/controller/AccountingReportController.java
index 798112b..9647b05 100644
--- a/src/main/java/com/ruoyi/purchase/controller/AccountingReportController.java
+++ b/src/main/java/com/ruoyi/purchase/controller/AccountingReportController.java
@@ -1,11 +1,13 @@
package com.ruoyi.purchase.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.account.service.purchase.AccountPurchasePaymentService;
import com.ruoyi.basic.service.ISupplierService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.purchase.dto.SavePaymentDto;
import com.ruoyi.purchase.dto.VatDto;
import com.ruoyi.purchase.service.PurchaseReportService;
import com.ruoyi.purchase.vo.PurchaseReportVo;
@@ -15,6 +17,7 @@
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -28,6 +31,7 @@
private final ISupplierService supplierService;
private final PurchaseReportService purchaseReportService;
+ private final AccountPurchasePaymentService accountPurchasePaymentService;
@GetMapping("/list")
@@ -74,4 +78,11 @@
public R supplierTransactionsDetails(Page page, Long supplierId) {
return R.ok(supplierService.supplierTransactionsDetails(page,supplierId));
}
+
+ @PostMapping("/savePayment")
+ @Log(title = "鏂板浠樻", businessType = BusinessType.INSERT)
+ @Operation(summary = "鏂板浠樻")
+ public R savePayment(@RequestBody SavePaymentDto dto) {
+ return R.ok(accountPurchasePaymentService.savePayment(dto));
+ }
}
diff --git a/src/main/java/com/ruoyi/purchase/dto/SavePaymentDto.java b/src/main/java/com/ruoyi/purchase/dto/SavePaymentDto.java
new file mode 100644
index 0000000..7c1acce
--- /dev/null
+++ b/src/main/java/com/ruoyi/purchase/dto/SavePaymentDto.java
@@ -0,0 +1,35 @@
+package com.ruoyi.purchase.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+
+/**
+ * 閲囪喘绠$悊--渚涘簲鍟嗗線鏉� 鏂板浠樻璇锋眰鍙傛暟
+ */
+@Data
+@Schema(name = "SavePaymentDto", description = "鏂板浠樻璇锋眰鍙傛暟")
+public class SavePaymentDto {
+
+ @Schema(description = "渚涘簲鍟咺D")
+ private Long supplierId;
+
+ @Schema(description = "閲囪喘鍚堝悓鍙�")
+ private String purchaseContractNumber;
+
+ @Schema(description = "浠樻鏃ユ湡")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private LocalDate paymentDate;
+
+ @Schema(description = "浠樻閲戦")
+ private BigDecimal paymentAmount;
+
+ @Schema(description = "浠樻鏂瑰紡")
+ private String paymentMethod;
+
+ @Schema(description = "澶囨敞")
+ private String remark;
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/sales/controller/MetricStatisticsController.java b/src/main/java/com/ruoyi/sales/controller/MetricStatisticsController.java
index 577508a..4572af1 100644
--- a/src/main/java/com/ruoyi/sales/controller/MetricStatisticsController.java
+++ b/src/main/java/com/ruoyi/sales/controller/MetricStatisticsController.java
@@ -1,18 +1,22 @@
package com.ruoyi.sales.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.account.service.sales.AccountSalesCollectionService;
import com.ruoyi.basic.service.ICustomerService;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.sales.dto.SaveReceiptPaymentDto;
import com.ruoyi.sales.dto.StatisticsTableDto;
import com.ruoyi.sales.service.impl.MetricStatisticsServiceImpl;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -28,6 +32,7 @@
private final MetricStatisticsServiceImpl metricStatisticsService;
private final ICustomerService customerService;
+ private final AccountSalesCollectionService accountSalesCollectionService;
@Operation(summary = "澶撮儴鎬昏")
@GetMapping("/total")
@@ -55,4 +60,11 @@
return R.ok(customerService.customewTransactionsDetails(page,customerId));
}
+ @PostMapping("/saveReceiptPayment")
+ @Log(title = "鏂板鍥炴", businessType = BusinessType.INSERT)
+ @Operation(summary = "鏂板鍥炴")
+ public R saveReceiptPayment(@RequestBody SaveReceiptPaymentDto dto) {
+ return R.ok(accountSalesCollectionService.saveReceiptPayment(dto));
+ }
+
}
diff --git a/src/main/java/com/ruoyi/sales/dto/SaveReceiptPaymentDto.java b/src/main/java/com/ruoyi/sales/dto/SaveReceiptPaymentDto.java
new file mode 100644
index 0000000..7a83b6c
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/dto/SaveReceiptPaymentDto.java
@@ -0,0 +1,35 @@
+package com.ruoyi.sales.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+
+/**
+ * 钀ラ攢绠$悊--瀹㈡埛寰�鏉� 鏂板鍥炴璇锋眰鍙傛暟
+ */
+@Data
+@Schema(name = "SaveReceiptPaymentDto", description = "鏂板鍥炴璇锋眰鍙傛暟")
+public class SaveReceiptPaymentDto {
+
+ @Schema(description = "瀹㈡埛ID")
+ private Long customerId;
+
+ @Schema(description = "閿�鍞悎鍚屽彿")
+ private String salesContractNo;
+
+ @Schema(description = "鍥炴鏃ユ湡")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private LocalDate paymentDate;
+
+ @Schema(description = "鍥炴閲戦")
+ private BigDecimal paymentAmount;
+
+ @Schema(description = "鍥炴鏂瑰紡")
+ private String paymentMethod;
+
+ @Schema(description = "澶囨敞")
+ private String remark;
+}
\ No newline at end of file
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
index e5e2f9a..9b3c225 100644
--- a/src/main/resources/application-dev.yml
+++ b/src/main/resources/application-dev.yml
@@ -74,7 +74,7 @@
druid:
# 涓诲簱鏁版嵁婧�
master:
- url: jdbc:mysql://localhost:3306/product-inventory-management-bdpro?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+ url: jdbc:mysql://localhost:3306/product-inventory-management?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 123456
# 浠庡簱鏁版嵁婧�
diff --git a/src/main/resources/mapper/account/purchase/AccountPurchasePaymentMapper.xml b/src/main/resources/mapper/account/purchase/AccountPurchasePaymentMapper.xml
index ed247e5..77e07c5 100644
--- a/src/main/resources/mapper/account/purchase/AccountPurchasePaymentMapper.xml
+++ b/src/main/resources/mapper/account/purchase/AccountPurchasePaymentMapper.xml
@@ -54,5 +54,13 @@
GROUP BY dateStr
ORDER BY dateStr
</select>
+ <select id="selectStockInRecordIdsByPurchaseLedgerId" resultType="java.lang.Long">
+ SELECT sir.id
+ FROM stock_in_record sir
+ LEFT JOIN quality_inspect qi ON sir.record_type = 10 AND sir.record_id = qi.id
+ WHERE sir.approval_status = 1
+ AND sir.record_type IN ('7','10')
+ AND IF(sir.record_type = 7, sir.record_id, qi.purchase_ledger_id) = #{purchaseLedgerId}
+ </select>
</mapper>
diff --git a/src/main/resources/mapper/account/sales/AccountSalesCollectionMapper.xml b/src/main/resources/mapper/account/sales/AccountSalesCollectionMapper.xml
index 6a35890..e0e394d 100644
--- a/src/main/resources/mapper/account/sales/AccountSalesCollectionMapper.xml
+++ b/src/main/resources/mapper/account/sales/AccountSalesCollectionMapper.xml
@@ -112,5 +112,13 @@
GROUP BY dateStr
ORDER BY dateStr
</select>
+ <select id="selectStockOutRecordIdsBySalesLedgerId" resultType="java.lang.Long">
+ SELECT sor.id
+ FROM stock_out_record sor
+ JOIN shipping_info s ON sor.record_id = s.id
+ WHERE s.sales_ledger_id = #{salesLedgerId}
+ AND sor.record_type = '13'
+ AND sor.approval_status = 1
+ </select>
</mapper>
diff --git a/src/main/resources/mapper/basic/CustomerMapper.xml b/src/main/resources/mapper/basic/CustomerMapper.xml
index c69d89c..27cf2f4 100644
--- a/src/main/resources/mapper/basic/CustomerMapper.xml
+++ b/src/main/resources/mapper/basic/CustomerMapper.xml
@@ -177,14 +177,20 @@
left join (
select
sl.id,
- sum(ascc.collection_amount) as receiptPaymentAmount
- from account_sales_collection ascc
- left join stock_out_record sor on FIND_IN_SET(sor.id, ascc.stock_out_record_ids) > 0
- left join shipping_info s on sor.record_id = s.id
- LEFT JOIN sales_ledger sl ON s.sales_ledger_id = sl.id
- WHERE sor.record_type='13'
- and sor.approval_status=1
- group by sl.id
+ sum(t.collection_amount) as receiptPaymentAmount
+ from (
+ select
+ ascc.collection_amount,
+ s.sales_ledger_id
+ from account_sales_collection ascc
+ left join stock_out_record sor on FIND_IN_SET(sor.id, ascc.stock_out_record_ids) > 0
+ left join shipping_info s on sor.record_id = s.id
+ where sor.record_type='13'
+ and sor.approval_status=1
+ group by ascc.id, s.sales_ledger_id
+ ) t
+ left join sales_ledger sl on t.sales_ledger_id = sl.id
+ group by sl.id
)T1 on T1.id = sl.id
left join (
select sl.id,
diff --git a/src/main/resources/mapper/basic/SupplierManageMapper.xml b/src/main/resources/mapper/basic/SupplierManageMapper.xml
index 63bdf7e..2bc6fbd 100644
--- a/src/main/resources/mapper/basic/SupplierManageMapper.xml
+++ b/src/main/resources/mapper/basic/SupplierManageMapper.xml
@@ -13,6 +13,7 @@
T1.company_phone,
T1.bank_account_name,
T1.bank_account_num,
+ T1.bank_code,
T1.contact_user_name,
T1.contact_user_phone,
T1.maintain_user_id,
@@ -47,6 +48,7 @@
T1.company_phone,
T1.bank_account_name,
T1.bank_account_num,
+ T1.bank_code,
T1.contact_user_name,
T1.contact_user_phone,
T1.maintain_user_id,
@@ -106,17 +108,25 @@
left join (
select
pl.id,
- sum(app.payment_amount) as paymentAmount
- from account_purchase_payment app
- left join account_payment_application apa on app.account_payment_application_id = apa.id
- left join stock_in_record sir on FIND_IN_SET(sir.id, apa.stock_in_record_ids) > 0
- -- 10 绫诲瀷鎵嶅叧鑱旇川妫�琛�
- LEFT JOIN quality_inspect qi ON sir.record_type = 10 AND sir.record_id = qi.id
- -- 鍔ㄦ�佸叧鑱旈噰璐紙鑷姩閫傞厤 7 鍜� 10锛�
- LEFT JOIN purchase_ledger pl
- ON pl.id = IF(sir.record_type = 7, sir.record_id, qi.purchase_ledger_id)
- WHERE sir.approval_status = 1
- AND sir.record_type IN ('7','10')
+ sum(t.payment_amount) as paymentAmount
+ from (
+ select
+ app.id,
+ app.payment_amount,
+ pl.id as purchase_ledger_id
+ from account_purchase_payment app
+ left join account_payment_application apa on app.account_payment_application_id = apa.id
+ left join stock_in_record sir on FIND_IN_SET(sir.id, apa.stock_in_record_ids) > 0
+ -- 10 绫诲瀷鎵嶅叧鑱旇川妫�琛�
+ LEFT JOIN quality_inspect qi ON sir.record_type = 10 AND sir.record_id = qi.id
+ -- 鍔ㄦ�佸叧鑱旈噰璐紙鑷姩閫傞厤 7 鍜� 10锛�
+ LEFT JOIN purchase_ledger pl
+ ON pl.id = IF(sir.record_type = 7, sir.record_id, qi.purchase_ledger_id)
+ WHERE sir.approval_status = 1
+ AND sir.record_type IN ('7','10')
+ group by app.id, pl.id
+ ) t
+ left join purchase_ledger pl on t.purchase_ledger_id = pl.id
group by pl.id
)T1 on T1.id = pl.id
left join (
diff --git a/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml b/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
index 9e6839f..4ea9439 100644
--- a/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
+++ b/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
@@ -33,7 +33,7 @@
WHEN (IFNULL(t2.qualitity, 0) - IFNULL(t2.locked_quantity, 0)) >0 THEN 1
ELSE 0
END as has_sufficient_stock,
- (IFNULL(T1.quantity, 0) - IFNULL(t3.shipped_quantity, 0) - IFNULL(t5.pending_approval_quantity, 0)) as no_quantity,
+ NULL as no_quantity,
IFNULL(t3.shipped_quantity, 0) as shipped_quantity,
IFNULL(t6.return_quantity, 0) as return_quantity,
IFNULL(t4.approved_stock_in_num, 0) as approved_stock_in_num,
--
Gitblit v1.9.3