feat(erp): 采购台账改造与采购退货增强
采购台账(原采购订单):
- 新增采购类型、合同号(手工输入,不自动生成)、项目名称、付款日期、付款方式字段
- 明细行快照产品编号(MDM 物料编码),列表/详情/导出展示
- 支持从销售订单、生产工单带入来源单号与明细
- 付款日期必填;付款日期与订单日期账期超 30 天前端标红提醒
- 销售订单新增收款日期,同口径 30 天提醒
- 菜单名称统一改为「采购台账」,权限串保持不变
采购退货:
- 新增 BPM 审批流程(采购 → 质量 → 仓库),状态新增「审批中」
- 附件统一走 system_storage_attachment
- 处理方式支持退款 / 换货:退款生成负数冲红付款单;换货自动生成到货通知单并逐行 IQC,重新入库质检
- 创建时从采购订单快照合同号,完成时回写采购订单退货数量
配套:
- 新增 sql/mysql/20261104_purchase_ledger.sql、20261104_return_vendor_approval.sql
- 按规则全量重新生成 docs/sql/config_export_all_20261104.sql
- 更新前端联调文档与业务可视化图
Co-Authored-By: Claude Code <noreply@anthropic.com>
| | |
| | | {"name": "询价æ¯ä»·", "module": "ä¾åºå管ç", "table": "srm_inquiry", "doc": "XJç¼å·ï¼è稿0â已转订å20â已忶30(10询价ä¸ä¸ºåå²ç¶æ)ï¼æ°å¢/ç¼è¾æ¶ä¸å¹¶å½å
¥äº§åè¡Ãåä¸ä¾åºåæ¥ä»·(srm_inquiry_quote)å¹¶é宿¯ä¸ªäº§åç䏿 ä¾åºåï¼æ éåç¬çæ¥ä»·/æ¯ä»·æ¥éª¤ï¼ç¡®è®¤åæä¸æ ä¾åºåæåçæéè´è®¢åèç¨¿å¹¶è®°å½ srm_inquiry_order", "upstream": ["ä¾åºå", "ä¸»æ°æ®(ç©æ)"], "downstream": ["éè´è®¢å(è稿)"], "keywords": "询价 æ¯ä»· æ¥ä»· 䏿 inquiry quote"}, |
| | | {"name": "ææ ä¿è¯é", "module": "ä¾åºå管ç", "table": "srm_bid_bond", "doc": "BZç¼å·å°è´¦ï¼å
³èä¾åºå/询价å/éè´è®¢åï¼è®°å½ä¿è¯ééé¢ãç¼´çº³æ¥æãæ¯å¦ä¸æ ãéåç¶æ(0æªé1é¨å2å·²é3æ éé)/éåéé¢/é忥æ", "upstream": ["ä¾åºå", "询价æ¯ä»·", "éè´è®¢å"], "downstream": ["ä¾åºå徿¥(åè)"], "keywords": "ææ ä¿è¯é 䏿 éå bid bond"}, |
| | | {"name": "éè´ç³è¯·", "module": "è¿éå", "table": "erp_purchase_request", "doc": "CGSQç¼å·ï¼BPM 审æ¹ï¼éè¿åæä¾åºåèªå¨çæè®¢å", "upstream": ["ç产缺å£(人工)"], "downstream": ["éè´è®¢å"], "keywords": "éè´ç³è¯· è¯·è´ request"}, |
| | | {"name": "éè´è®¢å", "module": "è¿éå", "table": "erp_purchase_order", "doc": "CGDDç¼å·ï¼BPM 审æ¹(è稿0â审æ¹ä¸15âå·²å®¡æ ¸20)ï¼å
¥åºç¶æ:æª0é¨å1å
¨é¨2ï¼æ¥æºå¯ä¸ºéè´ç³è¯·æè¯¢ä»·æ¯ä»·ç¡®è®¤çæçè稿(æ¥æºåå·å溯)ï¼å价为å«ç¨åä»·ï¼ä»·ç¨å计=åä»·Ãæ°éï¼ç¨é¢ä»å«ç¨éé¢ä¸åç®(ä¸åé¢å¤å ç¨)", "upstream": ["éè´ç³è¯·", "询价æ¯ä»·(ç¡®è®¤ä¸æ )"], "downstream": ["å°è´§éç¥", "éè´æ¥ç¥¨", "ä¾åºåéè´§(约æç©æ)", "ä¾åºå徿¥"], "keywords": "éè´è®¢å purchase"}, |
| | | {"name": "éè´è®¢å", "module": "è¿éå", "table": "erp_purchase_order", "doc": "èååãéè´å°è´¦ãï¼CGDDç¼å·ï¼BPM 审æ¹(è稿0â审æ¹ä¸15âå·²å®¡æ ¸20)ï¼å
¥åºç¶æ:æª0é¨å1å
¨é¨2ï¼è¡¨å¤´å«éè´ç±»å(ç产/åå
¬ç¨å/å
¶ä»)ãååå·(æå·¥è¾å
¥ä¸èªå¨çæ)ã项ç®åç§°ã仿¬¾æ¥æ(å¿
å¡«ï¼è¶
30å¤©è´¦ææ çº¢)ã仿¬¾æ¹å¼(çµæ±/æ±ç¥¨/ç°é/ææºæ¯ä»)ï¼æç»äº§åç¼å·å¿«ç
§ MDM ç©æç¼ç ï¼æ¥æºå¯ä¸ºéè´ç³è¯·ã询价æ¯ä»·ç¡®è®¤çæçè稿æéå®è®¢å/ç产工å(æ¥æºåå·å溯)ï¼å价为å«ç¨åä»·ï¼ä»·ç¨å计=åä»·Ãæ°éï¼ç¨é¢ä»å«ç¨éé¢ä¸åç®(ä¸åé¢å¤å ç¨)", "upstream": ["éè´ç³è¯·", "询价æ¯ä»·(ç¡®è®¤ä¸æ )"], "downstream": ["å°è´§éç¥", "éè´æ¥ç¥¨", "ä¾åºåéè´§(约æç©æ)", "ä¾åºå徿¥"], "keywords": "éè´è®¢å purchase"}, |
| | | {"name": "éè´æ¥ç¥¨", "module": "è¿éå", "table": "erp_purchase_invoice", "doc": "FPDç¼å·ï¼AI OCR é¢å¡«ï¼ç´¯è®¡â¤è®¢åæ»ä»·ï¼ä»æ¬¾åçåç½®ï¼ä¾åºå徿¥å³ä¾§å±ç¤ºå¼ç¥¨éé¢/å·²ä»/å©ä½åºä»", "upstream": ["éè´è®¢å"], "downstream": ["仿¬¾å", "ä¾åºå徿¥"], "keywords": "æ¥ç¥¨ å票 éè´å票"}, |
| | | {"name": "仿¬¾å", "module": "è´¢å¡", "table": "erp_finance_payment", "doc": "FKDç¼å·ï¼å¿
é¡»å
³èæ¥ç¥¨+éä»¶ï¼ç´¯è®¡â¤æ¥ç¥¨éé¢ï¼BPM 审æ¹", "upstream": ["éè´æ¥ç¥¨"], "downstream": ["ç»ç®è´¦æ·", "ä¾åºå徿¥"], "keywords": "仿¬¾ åºä» payment"}, |
| | | {"name": "ä¾åºå徿¥", "module": "è¿éå", "table": "æ ç¬ç«è¡¨(èåè§å¾)", "doc": "æä¾åºå+æ¶é´èå´èåéè´è®¢å/æ¥ç¥¨/仿¬¾ï¼æ±æ»ç´¯è®¡éè´é¢ã累计å¼ç¥¨é¢ãç´¯è®¡ä»æ¬¾é¢ãæªä»ä½é¢ï¼å·¦ä¾§è®¢åè¡å«å·²å¼ç¥¨/æªå¼ç¥¨éé¢ï¼å³ä¾§æ¥ç¥¨è¡å«å¼ç¥¨éé¢/å·²ä»/å©ä½åºä»", "upstream": ["éè´è®¢å", "éè´æ¥ç¥¨", "仿¬¾å"], "downstream": [], "keywords": "ä¾åºå徿¥ 对账 å¼ç¥¨éé¢ åºä» statement"}, |
| | |
| | | {"name": "çäº§é¢æå", "module": "ä»å¨", "table": "mes_wm_product_issue", "doc": "è稿0âå¾
æ£è´§2âå¾
æ§è¡3â宿4ï¼åºå-", "upstream": ["ç产工å"], "downstream": ["åºåå°è´¦"], "keywords": "颿 issue"}, |
| | | {"name": "éå®åºåºå", "module": "ä»å¨", "table": "mes_wm_product_sales", "doc": "åè´§éç¥å®¡æ ¸åçæï¼æäº¤âOQCæ£æµâæ£è´§âåè¿10âå¾
æ§è¡3â宿4ï¼ååéå®è®¢ååºåºæ°ä¸ç¶æ", "upstream": ["åè´§éç¥", "éå®è®¢å"], "downstream": ["åºåå°è´¦", "OQC"], "keywords": "éå®åºåº åè´§ åºåºå sales"}, |
| | | {"name": "éå®éè´§å", "module": "ä»å¨", "table": "mes_wm_return_sales", "doc": "è稿âå¾
æ£éª(RQC)âå¾
䏿¶âå¾
å
¥åºâ宿ï¼å®åä¸æå·¥ä¸¤æ¥æº", "upstream": ["å®åéè´§ç³è¯·"], "downstream": ["åºåå°è´¦", "RQC"], "keywords": "éå®éè´§ éè´§å
¥åº"}, |
| | | {"name": "ä¾åºåéè´§å", "module": "ä»å¨", "table": "mes_wm_return_vendor", "doc": "IQC ä¸åæ ¼éè´§åèµ·ï¼å¾
æ£è´§âå¾
æ§è¡â宿ï¼åºå-", "upstream": ["IQC"], "downstream": ["åºåå°è´¦", "éè´è®¢å(returnCount)"], "keywords": "ä¾åºåéè´§ éæ éè´§ vendor"}, |
| | | {"name": "ä¾åºåéè´§å", "module": "ä»å¨", "table": "mes_wm_return_vendor", "doc": "è´¨éé¨åèµ·éè´§ï¼è稿0â审æ¹ä¸1(BPMï¼éè´âè´¨éâä»åº)âå¾
æ£è´§2âå¾
æ§è¡éè´§3â宿4ï¼å¯åæ¶5ï¼åºå-ï¼ä¸ä¼ éä»¶èµ° storage-attachmentï¼å¤çæ¹å¼ 1鿬¾(宿åèªå¨çæè´æ°å²çº¢ä»æ¬¾å) / 2æ¢è´§(宿åèªå¨çæå¾
è´¨æ£å°è´§éç¥åå¹¶å建 IQCï¼éæ°å
¥åºè´¨æ£)ï¼ååå·ä»éè´è®¢åå¿«ç
§", "upstream": ["IQC", "éè´è®¢å(ååå·)"], "downstream": ["åºåå°è´¦", "éè´è®¢å(returnCount)", "仿¬¾å(å²çº¢)", "å°è´§éç¥(æ¢è´§)"], "keywords": "ä¾åºåéè´§ éæ éè´§ vendor"}, |
| | | {"name": "è°æ¨å", "module": "ä»å¨", "table": "mes_wm_transfer", "doc": "å
é¨/å¤é¨è°æ¨ï¼æå¯¹ MOVE_OUT+MOVE_IN äºå¡ï¼å¨éæ°é", "upstream": [], "downstream": ["åºåå°è´¦"], "keywords": "è°æ¨ ç§»åº transfer"}, |
| | | {"name": "çç¹ä»»å¡", "module": "ä»å¨", "table": "mes_wm_stock_taking_task", "doc": "éæ/卿çç¹ï¼è¡ç»æ:æ£å¸¸/çç(ADJUST_IN)/çäº(ADJUST_OUT)ï¼å¯å»ç»åºåãç²ç", "upstream": ["åºåå°è´¦"], "downstream": ["åºåå°è´¦(è°æ´)"], "keywords": "çç¹ çç çäº stock taking"}, |
| | | {"name": "åºåå°è´¦", "module": "ä»å¨", "table": "mes_wm_material_stock", "doc": "ç©æÃä»åºÃåºåºÃåºä½Ãæ¹æ¬¡Ãä¾åºåå
å
ç»ï¼æ°é/å»ç»/å ç¨/å¨éåé", "upstream": ["å
¨é¨å
¥åºå"], "downstream": ["å
¨é¨åºåºå", "äºå¡æµæ°´"], "keywords": "åºå å°è´¦ stock å¯ç¨é"}, |
| | |
| | | S2 -.-> S5 |
| | | C1[éè´ç³è¯· CGSQ·è稿0â审æ¹ä¸10] -->|æäº¤BPM| C2{审æ¹} |
| | | C2 -->|驳å30âå¯éç½®åè稿| C1 |
| | | C2 -->|éè¿20䏿ä¾åºå·èªå¨çæ| C3[éè´è®¢å CGDD·审æ¹ä¸15âå·²å®¡æ ¸20] |
| | | C2 -->|éè¿20䏿ä¾åºå·èªå¨çæ| C3[éè´å°è´¦ CGDD·éè´ç±»å/ååå·/项ç®/仿¬¾æ¥æ/仿¬¾æ¹å¼Â·å®¡æ¹ä¸15âå·²å®¡æ ¸20] |
| | | C2 -->|éè¿20æ ä¾åºå| C4[æå¨æå®ä¾åºåçæè®¢å] |
| | | C4 --> C3 |
| | | C3 -->|确认æ¶è´§| C5[å°è´§éç¥å·è稿0âå¾
è´¨æ£2âå¾
å
¥åº3â宿4] |
| | | C5 -->|ç©æéæ£éªÂ·èªå¨å建| C6[IQC æ¥ææ£éª] |
| | | C6 -->|åæ ¼1æç¹é2 å¯å
¥åº| C7[éè´å
¥åºå·è稿0âå¾
䏿¶2âå¾
æ§è¡3â宿4] |
| | | C6 -->|ä¸åæ ¼éè´§3| C8[ä¾åºåé货·å¾
æ£è´§âå¾
æ§è¡âå®æÂ·åºåæ£å] |
| | | C6 -->|ä¸åæ ¼éè´§3| C8[ä¾åºåé货·è稿â审æ¹ä¸(BPM éè´âè´¨éâä»åº)âå¾
æ£è´§âå¾
æ§è¡âå®æÂ·åºåæ£å<br/>鿬¾âè´æ°å²çº¢ä»æ¬¾åï¼æ¢è´§âå°è´§éç¥+IQC éæ°å
¥åº] |
| | | C6 -->|ä¸åæ ¼æ¥åº4| C9[NCR ä¸åæ ¼åå¤ç½®] |
| | | C7 -->|åå inCount ä¸ inStatus æªå
¥åº0é¨å1å
¨é¨2| C3 |
| | | C7 -->|ååç³è¯·æç» inCount| C1 |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- ============================================= |
| | | -- éè´å°è´¦æ¹é + éå®è®¢åæ¶æ¬¾æ¥æ |
| | | -- ç®æ åºï¼mom-ntshï¼MySQL 8.4ï¼ |
| | | -- 说æï¼ |
| | | -- 1. èæ¬å¯é夿§è¡ï¼åç¨ information_schema 颿£æ¥ + PREPAREï¼åå
¸/èåç¨å
æ¥åæ |
| | | -- 2. ä¸å
å« tenant_idï¼æ¬é¡¹ç®ä¸ä½¿ç¨å¤ç§æ·ï¼ |
| | | -- 3. åå²éè´å payment_date å
许为空ï¼ç¼è¾æ¶ç±åç«¯è¦æ±è¡¥å¡« |
| | | -- ============================================= |
| | | |
| | | -- --------------------------------------------- |
| | | -- ä¸ãerp_purchase_order éè´å°è´¦è¡¨å¤´å段 |
| | | -- --------------------------------------------- |
| | | |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'erp_purchase_order' AND column_name = 'purchase_type'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE erp_purchase_order ADD COLUMN purchase_type TINYINT NULL COMMENT ''éè´ç±»åï¼1ç产 2åå
¬ç¨å 3å
¶ä»'' AFTER remark', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| | | |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'erp_purchase_order' AND column_name = 'contract_no'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE erp_purchase_order ADD COLUMN contract_no VARCHAR(64) NULL COMMENT ''ååå·ï¼å®¢æ·æå·¥è¾å
¥ï¼ä¸èªå¨çæï¼'' AFTER purchase_type', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| | | |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'erp_purchase_order' AND column_name = 'project_name'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE erp_purchase_order ADD COLUMN project_name VARCHAR(255) NULL COMMENT ''项ç®åç§°ï¼éå¿
å¡«ï¼'' AFTER contract_no', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| | | |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'erp_purchase_order' AND column_name = 'payment_date'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE erp_purchase_order ADD COLUMN payment_date DATETIME NULL COMMENT ''仿¬¾æ¥æ'' AFTER project_name', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| | | |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'erp_purchase_order' AND column_name = 'payment_method'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE erp_purchase_order ADD COLUMN payment_method TINYINT NULL COMMENT ''仿¬¾æ¹å¼ï¼1çµæ± 2æ±ç¥¨ 3ç°é 4ææºæ¯ä»'' AFTER payment_date', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| | | |
| | | -- --------------------------------------------- |
| | | -- äºãerp_purchase_order_items 产åç¼å·ï¼MDM ç©æç¼ç å¿«ç
§ï¼ |
| | | -- --------------------------------------------- |
| | | |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'erp_purchase_order_items' AND column_name = 'product_code'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE erp_purchase_order_items ADD COLUMN product_code VARCHAR(64) NULL COMMENT ''产åç¼å·ï¼MDM ç©æç¼ç å¿«ç
§ï¼'' AFTER product_id', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| | | |
| | | -- --------------------------------------------- |
| | | -- ä¸ãerp_sale_order æ¶æ¬¾æ¥æ |
| | | -- --------------------------------------------- |
| | | |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'erp_sale_order' AND column_name = 'receipt_date'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE erp_sale_order ADD COLUMN receipt_date DATETIME NULL COMMENT ''æ¶æ¬¾æ¥æ'' AFTER order_time', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| | | |
| | | -- --------------------------------------------- |
| | | -- åãåå
¸ï¼éè´ç±»åã仿¬¾æ¹å¼ |
| | | -- --------------------------------------------- |
| | | |
| | | INSERT INTO system_dict_type (name, type, status, remark) |
| | | SELECT 'ERP éè´ç±»å', 'erp_purchase_type', 0, 'éè´å°è´¦-éè´ç±»åï¼1ç产 2åå
¬ç¨å 3å
¶ä»' |
| | | FROM DUAL |
| | | WHERE NOT EXISTS (SELECT 1 FROM system_dict_type WHERE type = 'erp_purchase_type' AND deleted = 0); |
| | | |
| | | INSERT INTO system_dict_type (name, type, status, remark) |
| | | SELECT 'ERP 仿¬¾æ¹å¼', 'erp_payment_method', 0, 'éè´å°è´¦-仿¬¾æ¹å¼ï¼1çµæ± 2æ±ç¥¨ 3ç°é 4ææºæ¯ä»' |
| | | FROM DUAL |
| | | WHERE NOT EXISTS (SELECT 1 FROM system_dict_type WHERE type = 'erp_payment_method' AND deleted = 0); |
| | | |
| | | INSERT INTO system_dict_data (sort, label, value, dict_type, status, color_type, css_class) |
| | | SELECT 0, 'ç产', '1', 'erp_purchase_type', 0, '', '' |
| | | FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM system_dict_data WHERE dict_type = 'erp_purchase_type' AND value = '1' AND deleted = 0); |
| | | INSERT INTO system_dict_data (sort, label, value, dict_type, status, color_type, css_class) |
| | | SELECT 1, 'åå
¬ç¨å', '2', 'erp_purchase_type', 0, '', '' |
| | | FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM system_dict_data WHERE dict_type = 'erp_purchase_type' AND value = '2' AND deleted = 0); |
| | | INSERT INTO system_dict_data (sort, label, value, dict_type, status, color_type, css_class) |
| | | SELECT 2, 'å
¶ä»', '3', 'erp_purchase_type', 0, '', '' |
| | | FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM system_dict_data WHERE dict_type = 'erp_purchase_type' AND value = '3' AND deleted = 0); |
| | | |
| | | INSERT INTO system_dict_data (sort, label, value, dict_type, status, color_type, css_class) |
| | | SELECT 0, 'çµæ±', '1', 'erp_payment_method', 0, '', '' |
| | | FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM system_dict_data WHERE dict_type = 'erp_payment_method' AND value = '1' AND deleted = 0); |
| | | INSERT INTO system_dict_data (sort, label, value, dict_type, status, color_type, css_class) |
| | | SELECT 1, 'æ±ç¥¨', '2', 'erp_payment_method', 0, '', '' |
| | | FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM system_dict_data WHERE dict_type = 'erp_payment_method' AND value = '2' AND deleted = 0); |
| | | INSERT INTO system_dict_data (sort, label, value, dict_type, status, color_type, css_class) |
| | | SELECT 2, 'ç°é', '3', 'erp_payment_method', 0, '', '' |
| | | FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM system_dict_data WHERE dict_type = 'erp_payment_method' AND value = '3' AND deleted = 0); |
| | | INSERT INTO system_dict_data (sort, label, value, dict_type, status, color_type, css_class) |
| | | SELECT 3, 'ææºæ¯ä»', '4', 'erp_payment_method', 0, '', '' |
| | | FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM system_dict_data WHERE dict_type = 'erp_payment_method' AND value = '4' AND deleted = 0); |
| | | |
| | | -- --------------------------------------------- |
| | | -- äºãèååç§°ï¼éè´è®¢å -> éè´å°è´¦ï¼æéä¸²ä¿æä¸åï¼é¿å
è§è²æé失æï¼ |
| | | -- --------------------------------------------- |
| | | |
| | | UPDATE system_menu SET name = 'éè´å°è´¦' WHERE id = 2666; |
| | | UPDATE system_menu SET name = 'éè´å°è´¦å建' WHERE id = 2668; |
| | | UPDATE system_menu SET name = 'éè´å°è´¦æ´æ°' WHERE id = 2669; |
| | | UPDATE system_menu SET name = 'éè´å°è´¦å é¤' WHERE id = 2670; |
| | | UPDATE system_menu SET name = 'éè´å°è´¦å¯¼åº' WHERE id = 2671; |
| | | UPDATE system_menu SET name = 'éè´å°è´¦å®¡æ¹' WHERE id = 2672; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- ============================================= |
| | | -- éè´éè´§å¢å¼ºï¼BPM å®¡æ¹ + éä»¶ + 鿬¾/æ¢è´§ + è´¢å¡å²çº¢ |
| | | -- ç®æ åºï¼mom-ntshï¼MySQL 8.4ï¼ |
| | | -- 说æï¼ |
| | | -- 1. èæ¬å¯é夿§è¡ï¼åç¨ information_schema 颿£æ¥ + PREPAREï¼åå
¸/èåç¨å
æ¥åæ |
| | | -- 2. ä¸å
å« tenant_idï¼æ¬é¡¹ç®ä¸ä½¿ç¨å¤ç§æ·ï¼ |
| | | -- 3. 人工åç½®ï¼éå¨ BPM åå°å建并å叿µç¨æ¨¡å purchase_return_vendor_approve |
| | | -- ï¼èç¹ï¼è´¨éé¨åèµ· -> éè´é¨å®¡æ¹ -> è´¨éé¨å®¡æ¹ -> ä»åºå®¡æ¹ï¼ï¼å¦åæäº¤å®¡æ¹æ¶ä¼æç¤ºæªåå¸ |
| | | -- ============================================= |
| | | |
| | | -- --------------------------------------------- |
| | | -- ä¸ãmes_wm_return_vendor 审æ¹ä¸è´¹ç¨å段 |
| | | -- --------------------------------------------- |
| | | |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'mes_wm_return_vendor' AND column_name = 'process_instance_id'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE mes_wm_return_vendor ADD COLUMN process_instance_id VARCHAR(64) NULL COMMENT ''BPMæµç¨å®ä¾ID'' AFTER status', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| | | |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'mes_wm_return_vendor' AND column_name = 'process_definition_key'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE mes_wm_return_vendor ADD COLUMN process_definition_key VARCHAR(64) NULL COMMENT ''BPMæµç¨å®ä¹Key'' AFTER process_instance_id', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| | | |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'mes_wm_return_vendor' AND column_name = 'contract_no'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE mes_wm_return_vendor ADD COLUMN contract_no VARCHAR(64) NULL COMMENT ''éè´ååå·ï¼å建æ¶ä»éè´è®¢åå¿«ç
§ï¼'' AFTER purchase_order_id', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| | | |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'mes_wm_return_vendor' AND column_name = 'handle_type'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE mes_wm_return_vendor ADD COLUMN handle_type TINYINT NULL COMMENT ''å¤çæ¹å¼ï¼1鿬¾ 2æ¢è´§'' AFTER remark', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| | | |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'mes_wm_return_vendor' AND column_name = 'refund_amount'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE mes_wm_return_vendor ADD COLUMN refund_amount DECIMAL(24,6) NULL COMMENT ''鿬¾éé¢ï¼é»è®¤æéè´åä»·Ãéè´§æ°é计ç®ï¼å¯ä¿®æ¹ï¼'' AFTER handle_type', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| | | |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'mes_wm_return_vendor' AND column_name = 'red_flush_payment_id'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE mes_wm_return_vendor ADD COLUMN red_flush_payment_id BIGINT NULL COMMENT ''è´æ°å²çº¢ä»æ¬¾åID'' AFTER refund_amount', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| | | |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'mes_wm_return_vendor' AND column_name = 'replacement_notice_id'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE mes_wm_return_vendor ADD COLUMN replacement_notice_id BIGINT NULL COMMENT ''æ¢è´§å°è´§éç¥åID'' AFTER red_flush_payment_id', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| | | |
| | | -- --------------------------------------------- |
| | | -- äºãerp_finance_payment å²çº¢æ¥æºå段 |
| | | -- --------------------------------------------- |
| | | |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'erp_finance_payment' AND column_name = 'source_type'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE erp_finance_payment ADD COLUMN source_type TINYINT NOT NULL DEFAULT 1 COMMENT ''æ¥æºç±»åï¼1æ®é仿¬¾ 2éè´éè´§å²çº¢'' AFTER remark', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| | | |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'erp_finance_payment' AND column_name = 'source_id'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE erp_finance_payment ADD COLUMN source_id BIGINT NULL COMMENT ''æ¥æºåæ®IDï¼éè´éè´§åï¼'' AFTER source_type', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| | | |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'erp_finance_payment' AND column_name = 'source_no'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE erp_finance_payment ADD COLUMN source_no VARCHAR(64) NULL COMMENT ''æ¥æºåå·'' AFTER source_id', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| | | |
| | | -- invoice_id éå
许为空ï¼å²çº¢å䏿¥ç¥¨ï¼ï¼ä»
å½å½å为 NOT NULL æ¶æ MODIFY |
| | | SET @nullable = (SELECT is_nullable FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'erp_finance_payment' AND column_name = 'invoice_id'); |
| | | SET @sql = IF(@nullable = 'NO', |
| | | 'ALTER TABLE erp_finance_payment MODIFY COLUMN invoice_id BIGINT NULL COMMENT ''å
³èçæ¥ç¥¨ç¼å·''', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| | | |
| | | -- --------------------------------------------- |
| | | -- ä¸ãåå
¸ï¼éè´§å¤çæ¹å¼ï¼éè´§ç¶æè¡¥ã审æ¹ä¸ã |
| | | -- --------------------------------------------- |
| | | |
| | | INSERT INTO system_dict_type (name, type, status, remark) |
| | | SELECT 'MES ä¾åºåéè´§å¤çæ¹å¼', 'mes_wm_return_vendor_handle_type', 0, 'éè´éè´§-å¤çæ¹å¼ï¼1鿬¾ 2æ¢è´§' |
| | | FROM DUAL |
| | | WHERE NOT EXISTS (SELECT 1 FROM system_dict_type WHERE type = 'mes_wm_return_vendor_handle_type' AND deleted = 0); |
| | | |
| | | INSERT INTO system_dict_data (sort, label, value, dict_type, status, color_type, css_class) |
| | | SELECT 0, '鿬¾', '1', 'mes_wm_return_vendor_handle_type', 0, '', '' |
| | | FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM system_dict_data WHERE dict_type = 'mes_wm_return_vendor_handle_type' AND value = '1' AND deleted = 0); |
| | | INSERT INTO system_dict_data (sort, label, value, dict_type, status, color_type, css_class) |
| | | SELECT 1, 'æ¢è´§', '2', 'mes_wm_return_vendor_handle_type', 0, '', '' |
| | | FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM system_dict_data WHERE dict_type = 'mes_wm_return_vendor_handle_type' AND value = '2' AND deleted = 0); |
| | | |
| | | -- éè´§ç¶ææ°å¢ã审æ¹ä¸ãï¼ç¶æå¼ 1ï¼å¤ç¨ CONFIRMEDï¼åå² 0/2/3/4/5 å®å
¨ä¸å¨ï¼ |
| | | INSERT INTO system_dict_data (sort, label, value, dict_type, status, color_type, css_class) |
| | | SELECT 1, '审æ¹ä¸', '1', 'mes_wm_return_vendor_status', 0, '', '' |
| | | FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM system_dict_data WHERE dict_type = 'mes_wm_return_vendor_status' AND value = '1' AND deleted = 0); |
| | | |
| | | -- --------------------------------------------- |
| | | -- åãèåï¼éè´éè´§æ°å¢ãæäº¤å®¡æ¹ãæé® |
| | | -- --------------------------------------------- |
| | | |
| | | INSERT INTO system_menu (id, name, permission, type, sort, parent_id, path, icon, component, status, visible, keep_alive, always_show) |
| | | SELECT 5837, 'ä¾åºåéè´§æäº¤å®¡æ¹', 'mes:wm-return-vendor:submit-approval', 3, 7, 5830, '', '', '', 0, 1, 1, 1 |
| | | FROM DUAL |
| | | WHERE NOT EXISTS (SELECT 1 FROM system_menu WHERE id = 5837); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.api.finance; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.module.erp.api.finance.dto.ErpFinancePaymentRedFlushCreateReqDTO; |
| | | import cn.iocoder.yudao.module.erp.api.finance.dto.ErpFinancePaymentRespDTO; |
| | | |
| | | /** |
| | | * ERP 仿¬¾å API æ¥å£ |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | public interface ErpFinancePaymentApi { |
| | | |
| | | String PREFIX = "/rpc-api/erp/finance-payment"; |
| | | |
| | | /** |
| | | * å建éè´éè´§è´æ°å²çº¢ä»æ¬¾å |
| | | * |
| | | * è¯¥åæ®ä¸æ ¡éªæ¥ç¥¨ãç´æ¥ç½®ä¸ºå·²å®¡æ ¸ï¼éé¢æè´æ°å
¥è´¦ã |
| | | * |
| | | * @param reqDTO åå»ºä¿¡æ¯ |
| | | * @return 仿¬¾åç¼å· |
| | | */ |
| | | CommonResult<Long> createRedFlushPayment(ErpFinancePaymentRedFlushCreateReqDTO reqDTO); |
| | | |
| | | /** |
| | | * è·å¾ä»æ¬¾å |
| | | * |
| | | * @param id 仿¬¾åç¼å· |
| | | * @return 仿¬¾å |
| | | */ |
| | | CommonResult<ErpFinancePaymentRespDTO> getFinancePayment(Long id); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.api.finance.dto; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | @Schema(description = "RPC æå¡ - ERP éè´éè´§è´æ°å²çº¢ä»æ¬¾åå建 Request DTO") |
| | | @Data |
| | | public class ErpFinancePaymentRedFlushCreateReqDTO { |
| | | |
| | | @Schema(description = "ä¾åºåç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private Long supplierId; |
| | | |
| | | @Schema(description = "仿¬¾è´¦æ·åç§°", example = "åºæ¬æ·") |
| | | private String accountName; |
| | | |
| | | @Schema(description = "鿬¾éé¢ï¼æ£æ°ï¼æå¡ç«¯æè´æ°å
¥è´¦ï¼", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000.00") |
| | | private BigDecimal refundAmount; |
| | | |
| | | @Schema(description = "æ¥æºåæ®ç¼å·ï¼ä¾åºåéè´§åç¼å·ï¼", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private Long sourceId; |
| | | |
| | | @Schema(description = "æ¥æºåå·ï¼ä¾åºåéè´§åå·ï¼", requiredMode = Schema.RequiredMode.REQUIRED, example = "RV2026110001") |
| | | private String sourceNo; |
| | | |
| | | @Schema(description = "è´¢å¡äººåç¼å·", example = "1") |
| | | private Long financeUserId; |
| | | |
| | | @Schema(description = "夿³¨", example = "ä¾åºåéè´§å²çº¢") |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.api.finance.dto; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | @Schema(description = "RPC æå¡ - ERP 仿¬¾å Response DTO") |
| | | @Data |
| | | public class ErpFinancePaymentRespDTO { |
| | | |
| | | @Schema(description = "仿¬¾åç¼å·", example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "仿¬¾åå·", example = "FKD2026110001") |
| | | private String no; |
| | | |
| | | @Schema(description = "仿¬¾ç¶æ", example = "20") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "æ¥æºç±»åï¼1æ®é仿¬¾ 2éè´éè´§å²çº¢", example = "2") |
| | | private Integer sourceType; |
| | | |
| | | @Schema(description = "æ¥æºåæ®ç¼å·", example = "1") |
| | | private Long sourceId; |
| | | |
| | | @Schema(description = "æ¥æºåå·", example = "RV2026110001") |
| | | private String sourceNo; |
| | | |
| | | @Schema(description = "å®ä»éé¢ï¼åä½ï¼å
ï¼å²çº¢åä¸ºè´æ°ï¼", example = "-1000.00") |
| | | private BigDecimal paymentPrice; |
| | | |
| | | } |
| | |
| | | CommonResult<Boolean> updateOrderItemInCount(Long orderItemId, BigDecimal inCount); |
| | | |
| | | /** |
| | | * ç´¯å éè´è®¢åæç»çéè´§æ°é |
| | | * |
| | | * ç¨äºä¾åºåéè´§å®æåååéè´è®¢åçå·²éè´§æ°éï¼å¹çç±è°ç¨æ¹ç¶ææºä¿è¯ã |
| | | * |
| | | * @param orderItemId æç»ç¼å· |
| | | * @param returnCount éè´§æ°éå¢éï¼æ£æ°ï¼ |
| | | */ |
| | | CommonResult<Boolean> updateOrderItemReturnCount(Long orderItemId, BigDecimal returnCount); |
| | | |
| | | /** |
| | | * æ´æ°éè´è®¢åçå
¥åºç¶æ |
| | | * |
| | | * æ ¹æ®æç»å
¥åºæ°éèªå¨è®¡ç®è®¢åç¶æï¼ |
| | |
| | | @Schema(description = "å·²å
¥åºæ°é") |
| | | private BigDecimal inCount; |
| | | |
| | | @Schema(description = "ååå·ï¼æå·¥è¾å
¥ï¼ä¸èªå¨çæï¼", example = "HT2026110001") |
| | | private String contractNo; |
| | | |
| | | @Schema(description = "éè´ç±»åï¼1ç产 2åå
¬ç¨å 3å
¶ä»", example = "1") |
| | | private Integer purchaseType; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.api.finance; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.erp.api.finance.dto.ErpFinancePaymentRedFlushCreateReqDTO; |
| | | import cn.iocoder.yudao.module.erp.api.finance.dto.ErpFinancePaymentRespDTO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentDO; |
| | | import cn.iocoder.yudao.module.erp.service.finance.ErpFinancePaymentService; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | |
| | | /** |
| | | * ERP 仿¬¾å API å®ç°ç±» |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @RestController |
| | | @RequestMapping(ErpFinancePaymentApi.PREFIX) |
| | | @Validated |
| | | public class ErpFinancePaymentApiImpl implements ErpFinancePaymentApi { |
| | | |
| | | @Resource |
| | | private ErpFinancePaymentService financePaymentService; |
| | | |
| | | @Override |
| | | public CommonResult<Long> createRedFlushPayment(ErpFinancePaymentRedFlushCreateReqDTO reqDTO) { |
| | | return success(financePaymentService.createRedFlushPayment(reqDTO)); |
| | | } |
| | | |
| | | @Override |
| | | public CommonResult<ErpFinancePaymentRespDTO> getFinancePayment(Long id) { |
| | | ErpFinancePaymentDO payment = financePaymentService.getFinancePayment(id); |
| | | return success(BeanUtils.toBean(payment, ErpFinancePaymentRespDTO.class)); |
| | | } |
| | | |
| | | } |
| | |
| | | @Resource |
| | | private ErpPurchaseOrderItemMapper purchaseOrderItemMapper; |
| | | |
| | | @Resource |
| | | private cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseOrderMapper purchaseOrderMapper; |
| | | |
| | | @Override |
| | | public CommonResult<ErpPurchaseOrderRespDTO> getPurchaseOrder(Long id) { |
| | | ErpPurchaseOrderDO order = purchaseOrderService.getPurchaseOrder(id); |
| | |
| | | } |
| | | |
| | | @Override |
| | | public CommonResult<Boolean> updateOrderItemReturnCount(Long orderItemId, BigDecimal returnCount) { |
| | | if (orderItemId == null || returnCount == null) { |
| | | return success(false); |
| | | } |
| | | ErpPurchaseOrderItemDO item = purchaseOrderItemMapper.selectById(orderItemId); |
| | | if (item == null) { |
| | | return success(false); |
| | | } |
| | | // ç´¯å éè´§æ°é |
| | | BigDecimal oldReturnCount = item.getReturnCount() != null ? item.getReturnCount() : BigDecimal.ZERO; |
| | | BigDecimal newReturnCount = oldReturnCount.add(returnCount); |
| | | purchaseOrderItemMapper.updateById(new ErpPurchaseOrderItemDO() |
| | | .setId(orderItemId) |
| | | .setReturnCount(newReturnCount)); |
| | | // åæ¥æ´æ°è®¢å级éè´§æ°éï¼æè®¢å䏿ææç»çéè´§æ°éæ±åï¼é¿å
åªä¼ åæ¡æå
¶å®è¡æ¸
é¶ |
| | | BigDecimal totalReturnCount = purchaseOrderItemMapper.selectListByOrderId(item.getOrderId()).stream() |
| | | .map(orderItem -> orderItem.getReturnCount() != null ? orderItem.getReturnCount() : BigDecimal.ZERO) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | purchaseOrderMapper.updateById(new ErpPurchaseOrderDO() |
| | | .setId(item.getOrderId()) |
| | | .setReturnCount(totalReturnCount)); |
| | | return success(true); |
| | | } |
| | | |
| | | @Override |
| | | public CommonResult<Boolean> updateOrderInStatus(Long orderId) { |
| | | if (orderId == null) { |
| | | return success(false); |
| | |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentItemDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInvoiceDO; |
| | | import cn.iocoder.yudao.module.erp.enums.finance.ErpFinancePaymentSourceTypeEnum; |
| | | import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi; |
| | | import cn.iocoder.yudao.module.srm.api.supplier.dto.SrmSupplierRespDTO; |
| | | import cn.iocoder.yudao.module.erp.service.finance.ErpFinancePaymentService; |
| | |
| | | ErpPurchaseInvoiceRespVO invoiceFinal = invoiceVO; |
| | | return BeanUtils.toBean(payment, ErpFinancePaymentRespVO.class, financePaymentVO -> |
| | | financePaymentVO.setInvoice(invoiceFinal) |
| | | .setSourceTypeName(resolveSourceTypeName(payment.getSourceType())) |
| | | .setItems(BeanUtils.toBean(paymentItemList, ErpFinancePaymentRespVO.Item.class)) |
| | | .setAttachmentList(storageAttachmentApi.listAttachments("erp_finance_payment", payment.getId()))); |
| | | } |
| | |
| | | ExcelUtils.write(response, "仿¬¾å.xls", "æ°æ®", ErpFinancePaymentRespVO.class, list); |
| | | } |
| | | |
| | | private String resolveSourceTypeName(Integer sourceType) { |
| | | ErpFinancePaymentSourceTypeEnum sourceTypeEnum = ErpFinancePaymentSourceTypeEnum.valueOf(sourceType); |
| | | return sourceTypeEnum != null ? sourceTypeEnum.getName() : null; |
| | | } |
| | | |
| | | private PageResult<ErpFinancePaymentRespVO> buildFinancePaymentVOPageResult(PageResult<ErpFinancePaymentDO> pageResult) { |
| | | if (CollUtil.isEmpty(pageResult.getList())) { |
| | | return PageResult.empty(pageResult.getTotal()); |
| | |
| | | // 2. å¼å§æ¼æ¥ |
| | | return BeanUtils.toBean(pageResult, ErpFinancePaymentRespVO.class, payment -> { |
| | | payment.setItems(BeanUtils.toBean(financePaymentItemMap.get(payment.getId()), ErpFinancePaymentRespVO.Item.class)); |
| | | payment.setSourceTypeName(resolveSourceTypeName(payment.getSourceType())); |
| | | MapUtils.findAndThen(supplierMap, payment.getSupplierId(), supplier -> payment.setSupplierName(supplier.getName())); |
| | | MapUtils.findAndThen(userMap, Long.parseLong(payment.getCreator()), user -> payment.setCreatorName(user.getNickname())); |
| | | MapUtils.findAndThen(userMap, payment.getFinanceUserId(), user -> payment.setFinanceUserName(user.getNickname())); |
| | |
| | | @Schema(description = "ä¸å¡ç¼å·", example = "123") |
| | | private String bizNo; |
| | | |
| | | @Schema(description = "æ¥æºç±»åï¼1æ®é仿¬¾ 2éè´éè´§å²çº¢", example = "2") |
| | | private Integer sourceType; |
| | | |
| | | @Schema(description = "æ¥æºåå·", example = "RV2026110001") |
| | | private String sourceNo; |
| | | |
| | | } |
| | |
| | | @Schema(description = "夿³¨", example = "ä½ ç") |
| | | private String remark; |
| | | |
| | | @Schema(description = "æ¥æºç±»åï¼1æ®é仿¬¾ 2éè´éè´§å²çº¢", example = "1") |
| | | private Integer sourceType; |
| | | @Schema(description = "æ¥æºç±»ååç§°", example = "æ®é仿¬¾") |
| | | private String sourceTypeName; |
| | | @Schema(description = "æ¥æºåæ®ç¼å·", example = "1024") |
| | | private Long sourceId; |
| | | @Schema(description = "æ¥æºåå·", example = "RV2026110001") |
| | | private String sourceNo; |
| | | |
| | | @Schema(description = "éä»¶å表") |
| | | private List<StorageBlobRespDTO> attachmentList; |
| | | |
| | |
| | | package cn.iocoder.yudao.module.erp.controller.admin.purchase; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | |
| | | convertSet(purchaseOrderItemList, ErpPurchaseOrderItemDO::getProductId)); |
| | | Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureMap( |
| | | convertSet(purchaseOrderItemList, ErpPurchaseOrderItemDO::getProductUnitId)); |
| | | return success(BeanUtils.toBean(purchaseOrder, ErpPurchaseOrderRespVO.class, purchaseOrderVO -> |
| | | purchaseOrderVO.setItems(BeanUtils.toBean(purchaseOrderItemList, ErpPurchaseOrderRespVO.Item.class, item -> { |
| | | // åºåä¿¡æ¯æä¸æ¥è¯¢ï¼ä»å¨ç©æµæ¨¡åï¼ |
| | | item.setStockCount(BigDecimal.ZERO); |
| | | MapUtils.findAndThen(itemMap, item.getProductId(), mdmItem -> item.setProductName(mdmItem.getName()) |
| | | .setProductBarCode(mdmItem.getBarCode())); |
| | | MapUtils.findAndThen(unitMeasureMap, item.getProductUnitId(), unit -> |
| | | item.setProductUnitName(unit.getName())); |
| | | })).setAttachmentList(storageAttachmentApi.listAttachments("erp_purchase_order", id)) |
| | | .setSourceTypeName(ErpPurchaseOrderSourceTypeEnum.WORK_ORDER.getType() |
| | | .equals(purchaseOrder.getSourceType()) ? "ç产工å" : null))); |
| | | return success(BeanUtils.toBean(purchaseOrder, ErpPurchaseOrderRespVO.class, purchaseOrderVO -> { |
| | | purchaseOrderVO.setItems(BeanUtils.toBean(purchaseOrderItemList, ErpPurchaseOrderRespVO.Item.class, item -> { |
| | | // åºåä¿¡æ¯æä¸æ¥è¯¢ï¼ä»å¨ç©æµæ¨¡åï¼ |
| | | item.setStockCount(BigDecimal.ZERO); |
| | | MapUtils.findAndThen(itemMap, item.getProductId(), mdmItem -> item.setProductName(mdmItem.getName()) |
| | | .setProductBarCode(mdmItem.getBarCode())); |
| | | MapUtils.findAndThen(unitMeasureMap, item.getProductUnitId(), unit -> |
| | | item.setProductUnitName(unit.getName())); |
| | | // 产åç¼å·ï¼ä¼å
åæç»è¡å¿«ç
§ï¼å岿°æ®åé MDM ç©æç¼ç |
| | | if (StrUtil.isBlank(item.getProductCode())) { |
| | | MapUtils.findAndThen(itemMap, item.getProductId(), mdmItem -> item.setProductCode(mdmItem.getCode())); |
| | | } |
| | | })); |
| | | purchaseOrderVO.setAttachmentList(storageAttachmentApi.listAttachments("erp_purchase_order", id)); |
| | | purchaseOrderVO.setSourceTypeName(resolveSourceTypeName(purchaseOrder.getSourceType())); |
| | | purchaseOrderVO.setProductCodes(CollUtil.join(purchaseOrderVO.getItems(), "ï¼", |
| | | ErpPurchaseOrderRespVO.Item::getProductCode)); |
| | | })); |
| | | } |
| | | |
| | | @GetMapping("/page") |
| | |
| | | return success(true); |
| | | } |
| | | |
| | | /** |
| | | * è§£ææ¥æºç±»ååç§° |
| | | */ |
| | | private String resolveSourceTypeName(Integer sourceType) { |
| | | if (sourceType == null) { |
| | | return null; |
| | | } |
| | | return Arrays.stream(ErpPurchaseOrderSourceTypeEnum.values()) |
| | | .filter(item -> item.getType().equals(sourceType)) |
| | | .map(ErpPurchaseOrderSourceTypeEnum::getName).findFirst().orElse(null); |
| | | } |
| | | |
| | | private PageResult<ErpPurchaseOrderRespVO> buildPurchaseOrderVOPageResult(PageResult<ErpPurchaseOrderDO> pageResult) { |
| | | if (CollUtil.isEmpty(pageResult.getList())) { |
| | | return PageResult.empty(pageResult.getTotal()); |
| | |
| | | .setProductBarCode(mdmItem.getBarCode())); |
| | | MapUtils.findAndThen(unitMeasureMap, item.getProductUnitId(), unit -> |
| | | item.setProductUnitName(unit.getName())); |
| | | if (StrUtil.isBlank(item.getProductCode())) { |
| | | MapUtils.findAndThen(itemMap, item.getProductId(), mdmItem -> item.setProductCode(mdmItem.getCode())); |
| | | } |
| | | })); |
| | | purchaseOrder.setProductNames(CollUtil.join(purchaseOrder.getItems(), "ï¼", ErpPurchaseOrderRespVO.Item::getProductName)); |
| | | purchaseOrder.setProductCodes(CollUtil.join(purchaseOrder.getItems(), "ï¼", ErpPurchaseOrderRespVO.Item::getProductCode)); |
| | | MapUtils.findAndThen(supplierMap, purchaseOrder.getSupplierId(), supplier -> purchaseOrder.setSupplierName(supplier.getName())); |
| | | MapUtils.findAndThen(userMap, Long.parseLong(purchaseOrder.getCreator()), user -> purchaseOrder.setCreatorName(user.getNickname())); |
| | | purchaseOrder.setSourceTypeName(ErpPurchaseOrderSourceTypeEnum.WORK_ORDER.getType() |
| | | .equals(purchaseOrder.getSourceType()) ? "ç产工å" : null); |
| | | purchaseOrder.setSourceTypeName(resolveSourceTypeName(purchaseOrder.getSourceType())); |
| | | // å©ä½å¯å¼ç¥¨éé¢ = è®¢åæ»éé¢ - å·²æ¥ç¥¨éé¢ |
| | | purchaseOrder.setRemainInvoicePrice(purchaseOrder.getTotalPrice().subtract( |
| | | invoicePriceSumMap.getOrDefault(purchaseOrder.getId(), BigDecimal.ZERO))); |
| | |
| | | @Schema(description = "éè´æ¶é´ï¼æ ¼å¼å¦ 2026-01-01 10:00:00ï¼ç空åå½åæ¶é´") |
| | | private String orderTime; |
| | | |
| | | @ExcelProperty("éè´ç±»å") |
| | | @Schema(description = "éè´ç±»åï¼ç产 / åå
¬ç¨å / å
¶ä»ï¼ç空ä¸å¡«") |
| | | private String purchaseType; |
| | | |
| | | @ExcelProperty("ååå·") |
| | | @Schema(description = "ååå·ï¼æå·¥å¡«åï¼ç³»ç»ä¸èªå¨çæï¼") |
| | | private String contractNo; |
| | | |
| | | @ExcelProperty("项ç®åç§°") |
| | | @Schema(description = "项ç®åç§°ï¼éå¿
å¡«") |
| | | private String projectName; |
| | | |
| | | @ExcelProperty("仿¬¾æ¥æ") |
| | | @Schema(description = "仿¬¾æ¥æï¼æ ¼å¼å¦ 2026-01-01 10:00:00ï¼å¯¼å
¥å
许ç空ï¼åç»ç¼è¾æ¶è¡¥å¡«") |
| | | private String paymentDate; |
| | | |
| | | @ExcelProperty("仿¬¾æ¹å¼") |
| | | @Schema(description = "仿¬¾æ¹å¼ï¼çµæ± / æ±ç¥¨ / ç°é / ææºæ¯ä»ï¼ç空ä¸å¡«") |
| | | private String paymentMethod; |
| | | |
| | | @ExcelProperty("产åç¼ç ") |
| | | @Schema(description = "产åï¼ç©æï¼ç¼ç ", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private String productCode; |
| | |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime[] orderTime; |
| | | |
| | | @Schema(description = "éè´ç±»åï¼1ç产 2åå
¬ç¨å 3å
¶ä»", example = "1") |
| | | private Integer purchaseType; |
| | | |
| | | @Schema(description = "ååå·", example = "HT2026110001") |
| | | private String contractNo; |
| | | |
| | | @Schema(description = "仿¬¾æ¥æ") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime[] paymentDate; |
| | | |
| | | @Schema(description = "仿¬¾æ¹å¼ï¼1çµæ± 2æ±ç¥¨ 3ç°é 4ææºæ¯ä»", example = "1") |
| | | private Integer paymentMethod; |
| | | |
| | | @Schema(description = "夿³¨", example = "ä½ ç") |
| | | private String remark; |
| | | |
| | |
| | | @ExcelProperty("éè´æ¶é´") |
| | | private LocalDateTime orderTime; |
| | | |
| | | // ========== éè´å°è´¦ ========== |
| | | |
| | | @Schema(description = "éè´ç±»åï¼1ç产 2åå
¬ç¨å 3å
¶ä»", example = "1") |
| | | @ExcelProperty(value = "éè´ç±»å", converter = DictConvert.class) |
| | | @DictFormat(DictTypeConstants.PURCHASE_TYPE) |
| | | private Integer purchaseType; |
| | | |
| | | @Schema(description = "ååå·ï¼å®¢æ·æå·¥è¾å
¥ï¼ä¸èªå¨çæï¼", example = "HT2026110001") |
| | | @ExcelProperty("ååå·") |
| | | private String contractNo; |
| | | |
| | | @Schema(description = "项ç®åç§°ï¼éå¿
å¡«ï¼", example = "1å·äº§çº¿æ¹é ") |
| | | @ExcelProperty("项ç®åç§°") |
| | | private String projectName; |
| | | |
| | | @Schema(description = "仿¬¾æ¥æ") |
| | | @ExcelProperty("仿¬¾æ¥æ") |
| | | private LocalDateTime paymentDate; |
| | | |
| | | @Schema(description = "仿¬¾æ¹å¼ï¼1çµæ± 2æ±ç¥¨ 3ç°é 4ææºæ¯ä»", example = "1") |
| | | @ExcelProperty(value = "仿¬¾æ¹å¼", converter = DictConvert.class) |
| | | @DictFormat(DictTypeConstants.PAYMENT_METHOD) |
| | | private Integer paymentMethod; |
| | | |
| | | @Schema(description = "å计æ°é", requiredMode = Schema.RequiredMode.REQUIRED, example = "15663") |
| | | @ExcelProperty("å计æ°é") |
| | | private BigDecimal totalCount; |
| | |
| | | @ExcelProperty("产åä¿¡æ¯") |
| | | private String productNames; |
| | | |
| | | @Schema(description = "产åç¼å·ä¿¡æ¯", example = "MDM001ï¼MDM002") |
| | | @ExcelProperty("产åç¼å·") |
| | | private String productCodes; |
| | | |
| | | // ========== éè´å
¥åº ========== |
| | | |
| | | @Schema(description = "éè´å
¥åºæ°é", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") |
| | |
| | | @Schema(description = "产åç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113") |
| | | private Long productId; |
| | | |
| | | @Schema(description = "产åç¼å·ï¼MDM ç©æç¼ç ï¼", example = "MDM001") |
| | | private String productCode; |
| | | |
| | | @Schema(description = "产ååä½åä½", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113") |
| | | private Long productUnitId; |
| | | |
| | |
| | | @Schema(description = "ç¨é¢ï¼åä½ï¼å
", example = "100.00") |
| | | private BigDecimal taxPrice; |
| | | |
| | | @Schema(description = "å计产åéé¢ï¼åä½ï¼å
", example = "100.00") |
| | | private BigDecimal totalProductPrice; |
| | | |
| | | @Schema(description = "ä»·ç¨å计ï¼åä½ï¼å
", example = "100.00") |
| | | private BigDecimal totalPrice; |
| | | |
| | | @Schema(description = "夿³¨", example = "é便") |
| | | private String remark; |
| | | |
| | |
| | | @NotNull(message = "éè´æ¶é´ä¸è½ä¸ºç©º") |
| | | private LocalDateTime orderTime; |
| | | |
| | | @Schema(description = "éè´ç±»åï¼1ç产 2åå
¬ç¨å 3å
¶ä»", example = "1") |
| | | private Integer purchaseType; |
| | | |
| | | @Schema(description = "ååå·ï¼å®¢æ·æå·¥è¾å
¥ï¼ä¸èªå¨çæï¼", example = "HT2026110001") |
| | | private String contractNo; |
| | | |
| | | @Schema(description = "项ç®åç§°ï¼éå¿
å¡«ï¼", example = "1å·äº§çº¿æ¹é ") |
| | | private String projectName; |
| | | |
| | | @Schema(description = "仿¬¾æ¥æ", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @NotNull(message = "仿¬¾æ¥æä¸è½ä¸ºç©ºï¼è¯·éæ©ä»æ¬¾æ¥æååä¿å") |
| | | private LocalDateTime paymentDate; |
| | | |
| | | @Schema(description = "仿¬¾æ¹å¼ï¼1çµæ± 2æ±ç¥¨ 3ç°é 4ææºæ¯ä»", example = "1") |
| | | private Integer paymentMethod; |
| | | |
| | | @Schema(description = "伿 çï¼ç¾åæ¯", requiredMode = Schema.RequiredMode.REQUIRED, example = "99.88") |
| | | private BigDecimal discountPercent; |
| | | |
| | |
| | | @NotNull(message = "产åç¼å·ä¸è½ä¸ºç©º") |
| | | private Long productId; |
| | | |
| | | @Schema(description = "产åç¼å·ï¼MDM ç©æç¼ç å¿«ç
§ï¼", example = "MDM001") |
| | | private String productCode; |
| | | |
| | | @Schema(description = "产ååä½åä½", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113") |
| | | @NotNull(message = "产ååä½åä½ä¸è½ä¸ºç©º") |
| | | private Long productUnitId; |
| | |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime[] orderTime; |
| | | |
| | | @Schema(description = "æ¶æ¬¾æ¥æ") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime[] receiptDate; |
| | | |
| | | @Schema(description = "夿³¨", example = "ä½ ç") |
| | | private String remark; |
| | | |
| | |
| | | @ExcelProperty("ä¸åæ¶é´") |
| | | private LocalDateTime orderTime; |
| | | |
| | | @Schema(description = "æ¶æ¬¾æ¥æï¼ç¨äº 30 天账ææéï¼") |
| | | @ExcelProperty("æ¶æ¬¾æ¥æ") |
| | | private LocalDateTime receiptDate; |
| | | |
| | | @Schema(description = "å计æ°é", requiredMode = Schema.RequiredMode.REQUIRED, example = "15663") |
| | | @ExcelProperty("å计æ°é") |
| | | private BigDecimal totalCount; |
| | |
| | | @NotNull(message = "ä¸åæ¶é´ä¸è½ä¸ºç©º") |
| | | private LocalDateTime orderTime; |
| | | |
| | | @Schema(description = "æ¶æ¬¾æ¥æï¼ç¨äº 30 天账ææéï¼") |
| | | private LocalDateTime receiptDate; |
| | | |
| | | @Schema(description = "éå®åç¼å·", example = "1888") |
| | | private Long saleUserId; |
| | | |
| | |
| | | */ |
| | | private String remark; |
| | | |
| | | /** |
| | | * æ¥æºç±»å |
| | | * |
| | | * æä¸¾ {@link cn.iocoder.yudao.module.erp.enums.finance.ErpFinancePaymentSourceTypeEnum} |
| | | */ |
| | | private Integer sourceType; |
| | | /** |
| | | * æ¥æºåæ®ç¼å· |
| | | * |
| | | * éè´éè´§å²çº¢æ¶ï¼ä¸ºä¾åºåéè´§åç¼å· |
| | | */ |
| | | private Long sourceId; |
| | | /** |
| | | * æ¥æºåå· |
| | | */ |
| | | private String sourceNo; |
| | | |
| | | } |
| | |
| | | */ |
| | | private LocalDateTime orderTime; |
| | | |
| | | // ========== éè´å°è´¦ ========== |
| | | /** |
| | | * éè´ç±»å |
| | | * |
| | | * æä¸¾ {@link cn.iocoder.yudao.module.erp.enums.ErpPurchaseTypeEnum} |
| | | */ |
| | | private Integer purchaseType; |
| | | /** |
| | | * ååå·ï¼å®¢æ·æå·¥è¾å
¥ï¼ä¸èªå¨çæï¼ |
| | | */ |
| | | private String contractNo; |
| | | /** |
| | | * 项ç®åç§°ï¼éå¿
å¡«ï¼ |
| | | */ |
| | | private String projectName; |
| | | /** |
| | | * 仿¬¾æ¥æ |
| | | */ |
| | | private LocalDateTime paymentDate; |
| | | /** |
| | | * 仿¬¾æ¹å¼ |
| | | * |
| | | * æä¸¾ {@link cn.iocoder.yudao.module.erp.enums.ErpPaymentMethodEnum} |
| | | */ |
| | | private Integer paymentMethod; |
| | | |
| | | /** |
| | | * å计æ°é |
| | | */ |
| | |
| | | */ |
| | | private Long productId; |
| | | /** |
| | | * 产åç¼å·ï¼MDM ç©æç¼ç å¿«ç
§ï¼ |
| | | * |
| | | * å
³è {@link cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO#getCode()} |
| | | */ |
| | | private String productCode; |
| | | /** |
| | | * 计éåä½ç¼å· |
| | | * |
| | | * å
³è {@link cn.iocoder.yudao.module.mdm.api.unitmeasure.dto.MdmUnitMeasureRespDTO#getId()} |
| | |
| | | private LocalDateTime orderTime; |
| | | |
| | | /** |
| | | * æ¶æ¬¾æ¥æï¼ç¨äº 30 天账ææéï¼ |
| | | */ |
| | | private LocalDateTime receiptDate; |
| | | |
| | | /** |
| | | * å计æ°é |
| | | */ |
| | | private BigDecimal totalCount; |
| | |
| | | .likeIfPresent(ErpFinancePaymentDO::getAccountName, reqVO.getAccountName()) |
| | | .eqIfPresent(ErpFinancePaymentDO::getStatus, reqVO.getStatus()) |
| | | .likeIfPresent(ErpFinancePaymentDO::getRemark, reqVO.getRemark()) |
| | | .eqIfPresent(ErpFinancePaymentDO::getSourceType, reqVO.getSourceType()) |
| | | .likeIfPresent(ErpFinancePaymentDO::getSourceNo, reqVO.getSourceNo()) |
| | | .orderByDesc(ErpFinancePaymentDO::getId); |
| | | if (reqVO.getBizNo() != null) { |
| | | query.leftJoin(ErpFinancePaymentItemDO.class, ErpFinancePaymentItemDO::getPaymentId, ErpFinancePaymentDO::getId) |
| | |
| | | .likeIfPresent(ErpPurchaseOrderDO::getNo, reqVO.getNo()) |
| | | .eqIfPresent(ErpPurchaseOrderDO::getSupplierId, reqVO.getSupplierId()) |
| | | .betweenIfPresent(ErpPurchaseOrderDO::getOrderTime, reqVO.getOrderTime()) |
| | | .eqIfPresent(ErpPurchaseOrderDO::getPurchaseType, reqVO.getPurchaseType()) |
| | | .likeIfPresent(ErpPurchaseOrderDO::getContractNo, reqVO.getContractNo()) |
| | | .betweenIfPresent(ErpPurchaseOrderDO::getPaymentDate, reqVO.getPaymentDate()) |
| | | .eqIfPresent(ErpPurchaseOrderDO::getPaymentMethod, reqVO.getPaymentMethod()) |
| | | .eqIfPresent(ErpPurchaseOrderDO::getStatus, reqVO.getStatus()) |
| | | .likeIfPresent(ErpPurchaseOrderDO::getRemark, reqVO.getRemark()) |
| | | .eqIfPresent(ErpPurchaseOrderDO::getCreator, reqVO.getCreator()) |
| | |
| | | .likeIfPresent(ErpSaleOrderDO::getNo, reqVO.getNo()) |
| | | .eqIfPresent(ErpSaleOrderDO::getCustomerId, reqVO.getCustomerId()) |
| | | .betweenIfPresent(ErpSaleOrderDO::getOrderTime, reqVO.getOrderTime()) |
| | | .betweenIfPresent(ErpSaleOrderDO::getReceiptDate, reqVO.getReceiptDate()) |
| | | .eqIfPresent(ErpSaleOrderDO::getStatus, reqVO.getStatus()) |
| | | .eqIfPresent(ErpSaleOrderDO::getOutStatus, reqVO.getOutStatus()) |
| | | .eqIfPresent(ErpSaleOrderDO::getProductionStatus, reqVO.getProductionStatus()) |
| | |
| | | .likeIfPresent(ErpSaleOrderDO::getNo, reqVO.getNo()) |
| | | .eqIfPresent(ErpSaleOrderDO::getCustomerId, reqVO.getCustomerId()) |
| | | .betweenIfPresent(ErpSaleOrderDO::getOrderTime, reqVO.getOrderTime()) |
| | | .betweenIfPresent(ErpSaleOrderDO::getReceiptDate, reqVO.getReceiptDate()) |
| | | .eqIfPresent(ErpSaleOrderDO::getStatus, reqVO.getStatus()) |
| | | .eqIfPresent(ErpSaleOrderDO::getOutStatus, reqVO.getOutStatus()) |
| | | .eqIfPresent(ErpSaleOrderDO::getProductionStatus, reqVO.getProductionStatus()) |
| | |
| | | |
| | | String AUDIT_STATUS = "erp_audit_status"; // å®¡æ ¸ç¶æ |
| | | String STOCK_RECORD_BIZ_TYPE = "erp_stock_record_biz_type"; // åºåæç»çä¸å¡ç±»å |
| | | String PURCHASE_TYPE = "erp_purchase_type"; // éè´å°è´¦çéè´ç±»å |
| | | String PAYMENT_METHOD = "erp_payment_method"; // éè´å°è´¦ç仿¬¾æ¹å¼ |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.enums; |
| | | |
| | | import cn.iocoder.yudao.framework.common.core.ArrayValuable; |
| | | import lombok.Getter; |
| | | import lombok.RequiredArgsConstructor; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * ERP 仿¬¾æ¹å¼æä¸¾ï¼éè´å°è´¦ï¼ |
| | | * |
| | | * åå
¸ {@link DictTypeConstants#PAYMENT_METHOD} |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Getter |
| | | public enum ErpPaymentMethodEnum implements ArrayValuable<Integer> { |
| | | |
| | | WIRE_TRANSFER(1, "çµæ±"), |
| | | DRAFT(2, "æ±ç¥¨"), |
| | | CASH(3, "ç°é"), |
| | | MOBILE_PAY(4, "ææºæ¯ä»"); |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()) |
| | | .map(ErpPaymentMethodEnum::getType).toArray(Integer[]::new); |
| | | |
| | | /** |
| | | * ç±»åå¼ |
| | | */ |
| | | private final Integer type; |
| | | /** |
| | | * ç±»åå |
| | | */ |
| | | private final String name; |
| | | |
| | | @Override |
| | | public Integer[] array() { |
| | | return ARRAYS; |
| | | } |
| | | |
| | | /** |
| | | * å¤æç±»å弿¯å¦åæ³ï¼ä¸ºç©ºè§ä¸ºæªéæ©ï¼åæ³ï¼ |
| | | */ |
| | | public static boolean isValid(Integer type) { |
| | | if (type == null) { |
| | | return true; |
| | | } |
| | | return Arrays.stream(values()).anyMatch(item -> Objects.equals(item.getType(), type)); |
| | | } |
| | | |
| | | } |
| | |
| | | public enum ErpPurchaseOrderSourceTypeEnum implements ArrayValuable<Integer> { |
| | | |
| | | WORK_ORDER(1, "ç产工å"), |
| | | SRM_INQUIRY(2, "SRM询价"); |
| | | SRM_INQUIRY(2, "SRM询价"), |
| | | SALE_ORDER(3, "éå®è®¢å"); |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()) |
| | | .map(ErpPurchaseOrderSourceTypeEnum::getType).toArray(Integer[]::new); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.enums; |
| | | |
| | | import cn.iocoder.yudao.framework.common.core.ArrayValuable; |
| | | import lombok.Getter; |
| | | import lombok.RequiredArgsConstructor; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * ERP éè´ç±»åæä¸¾ï¼éè´å°è´¦ï¼ |
| | | * |
| | | * åå
¸ {@link DictTypeConstants#PURCHASE_TYPE} |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Getter |
| | | public enum ErpPurchaseTypeEnum implements ArrayValuable<Integer> { |
| | | |
| | | PRODUCTION(1, "ç产"), |
| | | OFFICE(2, "åå
¬ç¨å"), |
| | | OTHER(3, "å
¶ä»"); |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()) |
| | | .map(ErpPurchaseTypeEnum::getType).toArray(Integer[]::new); |
| | | |
| | | /** |
| | | * ç±»åå¼ |
| | | */ |
| | | private final Integer type; |
| | | /** |
| | | * ç±»åå |
| | | */ |
| | | private final String name; |
| | | |
| | | @Override |
| | | public Integer[] array() { |
| | | return ARRAYS; |
| | | } |
| | | |
| | | /** |
| | | * å¤æç±»å弿¯å¦åæ³ï¼ä¸ºç©ºè§ä¸ºæªéæ©ï¼åæ³ï¼ |
| | | */ |
| | | public static boolean isValid(Integer type) { |
| | | if (type == null) { |
| | | return true; |
| | | } |
| | | return Arrays.stream(values()).anyMatch(item -> Objects.equals(item.getType(), type)); |
| | | } |
| | | |
| | | } |
| | |
| | | ErrorCode PURCHASE_ORDER_BPM_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_030_101_012, "éè´å®¡æ ¸åç±»ä¸æ²¡æå¯ç¨çæµç¨æ¨¡åï¼è¯·å
å建并å叿µç¨"); |
| | | ErrorCode PURCHASE_ORDER_SUBMIT_FAIL_STATUS = new ErrorCode(1_030_101_013, "æäº¤å®¡æ¹å¤±è´¥ï¼åªææªå®¡æ ¸ç¶æçéè´è®¢åæè½æäº¤"); |
| | | ErrorCode PURCHASE_ORDER_ALL_IN = new ErrorCode(1_030_101_014, "éè´è®¢åå·²å
¨é¨å
¥åºï¼æ é确认æ¶è´§"); |
| | | ErrorCode PURCHASE_ORDER_PAYMENT_DATE_REQUIRED = new ErrorCode(1_030_101_015, "仿¬¾æ¥æä¸è½ä¸ºç©ºï¼è¯·éæ©ä»æ¬¾æ¥æååä¿å"); |
| | | ErrorCode PURCHASE_ORDER_PURCHASE_TYPE_INVALID = new ErrorCode(1_030_101_016, "éè´ç±»å({})ä¸åæ³ï¼åªè½éæ©ï¼1ç产ã2åå
¬ç¨åã3å
¶ä»"); |
| | | ErrorCode PURCHASE_ORDER_PAYMENT_METHOD_INVALID = new ErrorCode(1_030_101_017, "仿¬¾æ¹å¼({})ä¸åæ³ï¼åªè½éæ©ï¼1çµæ±ã2æ±ç¥¨ã3ç°éã4ææºæ¯ä»"); |
| | | ErrorCode PURCHASE_ORDER_ITEM_PRODUCT_CODE_MISSING = new ErrorCode(1_030_101_018, "ç©æ[{}]æªç»´æ¤ MDM ç©æç¼ç ï¼è¯·å
å¨ MDM ç©ææ¡£æ¡è¡¥å
ç¼ç ååä¿å"); |
| | | |
| | | // ========== ERP éè´å
¥åºï¼1-030-102-000ï¼ ========== |
| | | ErrorCode PURCHASE_IN_NOT_EXISTS = new ErrorCode(1_030_102_000, "éè´å
¥åºåä¸åå¨"); |
| | |
| | | ErrorCode FINANCE_PAYMENT_BPM_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_030_601_013, "仿¬¾å审æ¹åç±»ä¸æ²¡æå¯ç¨çæµç¨æ¨¡åï¼è¯·å
å建并å叿µç¨"); |
| | | ErrorCode FINANCE_PAYMENT_UPDATE_FAIL_APPROVING = new ErrorCode(1_030_601_014, "仿¬¾å({})审æ¹ä¸ï¼æ æ³ä¿®æ¹"); |
| | | ErrorCode FINANCE_PAYMENT_DELETE_FAIL_APPROVING = new ErrorCode(1_030_601_015, "仿¬¾å({})审æ¹ä¸ï¼æ æ³å é¤"); |
| | | ErrorCode FINANCE_PAYMENT_RED_FLUSH_AMOUNT_INVALID = new ErrorCode(1_030_601_016, "çæéè´éè´§å²çº¢å失败ï¼é款éé¢å¿
é¡»å¤§äº 0ï¼å½å为[{}]ï¼è¯·æ ¸å¯¹éè´§æ°éä¸éè´åä»·ååçæ"); |
| | | ErrorCode FINANCE_PAYMENT_RED_FLUSH_SOURCE_REQUIRED = new ErrorCode(1_030_601_017, "çæéè´éè´§å²çº¢åå¤±è´¥ï¼æªæä¾æ¥æºéè´§åï¼åæ®ç¼å·æåå·ä¸ºç©ºï¼ï¼è¯·ä»ä¾åºåéè´§å页é¢åèµ·å²çº¢"); |
| | | ErrorCode FINANCE_PAYMENT_RED_FLUSH_SUPPLIER_REQUIRED = new ErrorCode(1_030_601_018, "çæéè´éè´§å²çº¢åå¤±è´¥ï¼æªæä¾ä¾åºåç¼å·ï¼è¯·ç¡®è®¤éè´§å已鿩ä¾åºå"); |
| | | |
| | | // ========== ERP æ¶æ¬¾å 1-030-602-000 ========== |
| | | ErrorCode FINANCE_RECEIPT_NOT_EXISTS = new ErrorCode(1_030_602_000, "æ¶æ¬¾åä¸åå¨"); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.enums.finance; |
| | | |
| | | import cn.iocoder.yudao.framework.common.core.ArrayValuable; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * ERP 仿¬¾åæ¥æºç±»åæä¸¾ |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum ErpFinancePaymentSourceTypeEnum implements ArrayValuable<Integer> { |
| | | |
| | | NORMAL(1, "æ®é仿¬¾"), |
| | | PURCHASE_RETURN_RED_FLUSH(2, "éè´éè´§å²çº¢"); |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()) |
| | | .map(ErpFinancePaymentSourceTypeEnum::getType).toArray(Integer[]::new); |
| | | |
| | | /** |
| | | * ç±»å |
| | | */ |
| | | private final Integer type; |
| | | /** |
| | | * åç§° |
| | | */ |
| | | private final String name; |
| | | |
| | | @Override |
| | | public Integer[] array() { |
| | | return ARRAYS; |
| | | } |
| | | |
| | | public static ErpFinancePaymentSourceTypeEnum valueOf(Integer type) { |
| | | if (type == null) { |
| | | return null; |
| | | } |
| | | return Arrays.stream(values()).filter(item -> item.getType().equals(type)) |
| | | .findFirst().orElse(null); |
| | | } |
| | | |
| | | } |
| | |
| | | package cn.iocoder.yudao.module.erp.service.finance; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.erp.api.finance.dto.ErpFinancePaymentRedFlushCreateReqDTO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment.ErpFinancePaymentPageReqVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment.ErpFinancePaymentSaveReqVO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentDO; |
| | |
| | | void deleteFinancePayment(List<Long> ids); |
| | | |
| | | /** |
| | | * å建éè´éè´§è´æ°å²çº¢ä»æ¬¾å |
| | | * |
| | | * è¯¥åæ®ä¸æ ¡éªæ¥ç¥¨ãä¸å ç¨æ¥ç¥¨å¯ä»éé¢ï¼ç´æ¥ç½®ä¸ºå·²å®¡æ ¸ï¼éé¢æè´æ°å
¥è´¦ã |
| | | * å䏿¥æºéè´§åéå¤è°ç¨æ¶ï¼è¿åå·²çæçå²çº¢åç¼å·ï¼å¹çï¼ã |
| | | * |
| | | * @param reqDTO åå»ºä¿¡æ¯ |
| | | * @return 仿¬¾åç¼å· |
| | | */ |
| | | Long createRedFlushPayment(ErpFinancePaymentRedFlushCreateReqDTO reqDTO); |
| | | |
| | | /** |
| | | * è·å¾ä»æ¬¾å |
| | | * |
| | | * @param id ç¼å· |
| | |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.erp.api.finance.dto.ErpFinancePaymentRedFlushCreateReqDTO; |
| | | import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; |
| | | import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; |
| | | import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO; |
| | |
| | | import cn.iocoder.yudao.module.erp.dal.mysql.finance.ErpFinancePaymentMapper; |
| | | import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO; |
| | | import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; |
| | | import cn.iocoder.yudao.module.erp.enums.common.ErpBizTypeEnum; |
| | | import cn.iocoder.yudao.module.erp.enums.finance.ErpFinancePaymentSourceTypeEnum; |
| | | import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseInvoiceService; |
| | | import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseInvoiceServiceImpl; |
| | | import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService; |
| | |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.util.*; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createRedFlushPayment(ErpFinancePaymentRedFlushCreateReqDTO reqDTO) { |
| | | // 1.1 æ ¡éªæ¥æºåæ®ï¼å²çº¢åå¿
é¡»è½è¿½æº¯å°éè´§å |
| | | if (reqDTO.getSourceId() == null || StrUtil.isBlank(reqDTO.getSourceNo())) { |
| | | throw exception(FINANCE_PAYMENT_RED_FLUSH_SOURCE_REQUIRED); |
| | | } |
| | | // 1.2 æ ¡éªä¾åºå |
| | | if (reqDTO.getSupplierId() == null) { |
| | | throw exception(FINANCE_PAYMENT_RED_FLUSH_SUPPLIER_REQUIRED); |
| | | } |
| | | supplierService.validateSupplier(reqDTO.getSupplierId()); |
| | | // 1.3 æ ¡éªé款éé¢ |
| | | if (reqDTO.getRefundAmount() == null || reqDTO.getRefundAmount().compareTo(BigDecimal.ZERO) <= 0) { |
| | | throw exception(FINANCE_PAYMENT_RED_FLUSH_AMOUNT_INVALID, reqDTO.getRefundAmount()); |
| | | } |
| | | // 1.4 æ ¡éªè´¢å¡äººå |
| | | if (reqDTO.getFinanceUserId() != null) { |
| | | adminUserApi.validateUser(reqDTO.getFinanceUserId()); |
| | | } |
| | | // 1.5 å¹çï¼å䏿¥æºéè´§ååªå
许çæä¸å¼ å²çº¢å |
| | | ErpFinancePaymentDO existing = financePaymentMapper.selectOne(new LambdaQueryWrapperX<ErpFinancePaymentDO>() |
| | | .eq(ErpFinancePaymentDO::getSourceType, |
| | | ErpFinancePaymentSourceTypeEnum.PURCHASE_RETURN_RED_FLUSH.getType()) |
| | | .eq(ErpFinancePaymentDO::getSourceId, reqDTO.getSourceId())); |
| | | if (existing != null) { |
| | | log.info("[createRedFlushPayment][éè´§å({}) å·²åå¨å²çº¢å({})ï¼ç´æ¥å¤ç¨]", |
| | | reqDTO.getSourceNo(), existing.getNo()); |
| | | return existing.getId(); |
| | | } |
| | | |
| | | // 2.1 çæä»æ¬¾åå· |
| | | String no = noRedisDAO.generate(ErpNoRedisDAO.FINANCE_PAYMENT_NO_PREFIX); |
| | | if (financePaymentMapper.selectByNo(no) != null) { |
| | | throw exception(FINANCE_PAYMENT_NO_EXISTS); |
| | | } |
| | | // 2.2 éé¢æè´æ°å
¥è´¦ |
| | | BigDecimal negativeAmount = reqDTO.getRefundAmount().negate(); |
| | | ErpFinancePaymentDO payment = new ErpFinancePaymentDO() |
| | | .setNo(no) |
| | | .setStatus(ErpAuditStatus.APPROVE.getStatus()) |
| | | .setPaymentTime(LocalDateTime.now()) |
| | | .setFinanceUserId(reqDTO.getFinanceUserId()) |
| | | .setSupplierId(reqDTO.getSupplierId()) |
| | | .setAccountName(reqDTO.getAccountName()) |
| | | .setTotalPrice(negativeAmount) |
| | | .setDiscountPrice(BigDecimal.ZERO) |
| | | .setPaymentPrice(negativeAmount) |
| | | .setRemark(StrUtil.blankToDefault(reqDTO.getRemark(), "éè´éè´§å²çº¢")) |
| | | .setSourceType(ErpFinancePaymentSourceTypeEnum.PURCHASE_RETURN_RED_FLUSH.getType()) |
| | | .setSourceId(reqDTO.getSourceId()) |
| | | .setSourceNo(reqDTO.getSourceNo()); |
| | | financePaymentMapper.insert(payment); |
| | | |
| | | // 3. æå
¥ä»æ¬¾é¡¹ï¼ä¸å¡ç±»åï¼éè´éè´§ï¼ |
| | | financePaymentItemMapper.insert(new ErpFinancePaymentItemDO() |
| | | .setPaymentId(payment.getId()) |
| | | .setBizType(ErpBizTypeEnum.PURCHASE_RETURN.getType()) |
| | | .setBizId(reqDTO.getSourceId()) |
| | | .setBizNo(reqDTO.getSourceNo()) |
| | | .setTotalPrice(negativeAmount) |
| | | .setPaidPrice(BigDecimal.ZERO) |
| | | .setPaymentPrice(negativeAmount) |
| | | .setRemark(StrUtil.blankToDefault(reqDTO.getRemark(), "éè´éè´§å²çº¢"))); |
| | | return payment.getId(); |
| | | } |
| | | |
| | | @Override |
| | | public ErpFinancePaymentDO getFinancePayment(Long id) { |
| | | return financePaymentMapper.selectById(id); |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseRequestMapper; |
| | | import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO; |
| | | import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; |
| | | import cn.iocoder.yudao.module.erp.enums.ErpPaymentMethodEnum; |
| | | import cn.iocoder.yudao.module.erp.enums.ErpPurchaseOrderInStatusEnum; |
| | | import cn.iocoder.yudao.module.erp.enums.ErpPurchaseTypeEnum; |
| | | import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService; |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; |
| | |
| | | public Long createPurchaseOrder(ErpPurchaseOrderSaveReqVO createReqVO, boolean submit) { |
| | | // 1.1 æ ¡éªè®¢åé¡¹çæææ§ |
| | | List<ErpPurchaseOrderItemDO> purchaseOrderItems = validatePurchaseOrderItems(createReqVO.getItems()); |
| | | // 1.1.1 æ ¡éªéè´å°è´¦å段 |
| | | validateLedgerFields(createReqVO); |
| | | // 1.2 æ ¡éªä¾åºå |
| | | supplierService.validateSupplier(createReqVO.getSupplierId()); |
| | | // 1.3 æ ¡éªç»ç®è´¦æ· |
| | |
| | | } |
| | | // 1.4 æ ¡éªè®¢åé¡¹çæææ§ |
| | | List<ErpPurchaseOrderItemDO> purchaseOrderItems = validatePurchaseOrderItems(updateReqVO.getItems()); |
| | | // 1.5 æ ¡éªéè´å°è´¦å段 |
| | | validateLedgerFields(updateReqVO); |
| | | |
| | | // 2.1 æ´æ°è®¢å |
| | | ErpPurchaseOrderDO updateObj = BeanUtils.toBean(updateReqVO, ErpPurchaseOrderDO.class); |
| | |
| | | } |
| | | ErpPurchaseOrderSaveReqVO.Item itemVO = new ErpPurchaseOrderSaveReqVO.Item(); |
| | | itemVO.setProductId(item.getId()); |
| | | itemVO.setProductCode(item.getCode()); |
| | | itemVO.setProductUnitId(item.getUnitMeasureId()); |
| | | itemVO.setProductPrice(row.getProductPrice() == null ? BigDecimal.ZERO : row.getProductPrice()); |
| | | itemVO.setCount(row.getCount()); |
| | |
| | | purchaseOrder.setNo(no); |
| | | purchaseOrder.setSupplierId(supplierId); |
| | | purchaseOrder.setOrderTime(parseImportOrderTime(head.getOrderTime())); |
| | | purchaseOrder.setPurchaseType(parsePurchaseType(head.getPurchaseType())); |
| | | purchaseOrder.setContractNo(StrUtil.trimToNull(head.getContractNo())); |
| | | purchaseOrder.setProjectName(StrUtil.trimToNull(head.getProjectName())); |
| | | purchaseOrder.setPaymentDate(parseImportDateTime(head.getPaymentDate(), "仿¬¾æ¥æ")); |
| | | purchaseOrder.setPaymentMethod(parsePaymentMethod(head.getPaymentMethod())); |
| | | purchaseOrder.setRemark(head.getRemark()); |
| | | purchaseOrder.setStatus(Boolean.TRUE.equals(directApprove) |
| | | ? ErpAuditStatus.APPROVE.getStatus() : ErpAuditStatus.PROCESS.getStatus()); |
| | |
| | | * è§£æå¯¼å
¥çéè´æ¶é´ï¼å
¼å®¹å¤ç§å¸¸è§æ ¼å¼ï¼ä¸ºç©ºåå½åæ¶é´ |
| | | */ |
| | | private LocalDateTime parseImportOrderTime(String text) { |
| | | LocalDateTime value = parseImportDateTime(text, "éè´æ¶é´"); |
| | | return value != null ? value : LocalDateTime.now(); |
| | | } |
| | | |
| | | /** |
| | | * è§£æå¯¼å
¥çæ¥ææ¶é´ï¼å
¼å®¹å¤ç§å¸¸è§æ ¼å¼ï¼ä¸ºç©ºè¿å null |
| | | */ |
| | | private LocalDateTime parseImportDateTime(String text, String fieldName) { |
| | | if (StrUtil.isBlank(text)) { |
| | | return LocalDateTime.now(); |
| | | return null; |
| | | } |
| | | String value = text.trim(); |
| | | for (String pattern : new String[]{"yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy/MM/dd HH:mm:ss"}) { |
| | |
| | | // ç»§ç»å°è¯ä¸ä¸ä¸ªæ ¼å¼ |
| | | } |
| | | } |
| | | throw new IllegalArgumentException("éè´æ¶é´æ ¼å¼ä¸æ£ç¡®ï¼" + text + "ï¼ç¤ºä¾ 2026-01-01 10:00:00"); |
| | | throw new IllegalArgumentException(fieldName + "æ ¼å¼ä¸æ£ç¡®ï¼" + text + "ï¼ç¤ºä¾ 2026-01-01 10:00:00"); |
| | | } |
| | | |
| | | /** |
| | | * è§£æå¯¼å
¥çéè´ç±»ååç§°ï¼ä¸ºç©ºææ æ³è¯å«è¿å null |
| | | */ |
| | | private Integer parsePurchaseType(String text) { |
| | | if (StrUtil.isBlank(text)) { |
| | | return null; |
| | | } |
| | | String value = text.trim(); |
| | | return Arrays.stream(ErpPurchaseTypeEnum.values()) |
| | | .filter(item -> item.getName().equals(value)) |
| | | .map(ErpPurchaseTypeEnum::getType).findFirst().orElse(null); |
| | | } |
| | | |
| | | /** |
| | | * è§£æå¯¼å
¥ç仿¬¾æ¹å¼åç§°ï¼ä¸ºç©ºææ æ³è¯å«è¿å null |
| | | */ |
| | | private Integer parsePaymentMethod(String text) { |
| | | if (StrUtil.isBlank(text)) { |
| | | return null; |
| | | } |
| | | String value = text.trim(); |
| | | return Arrays.stream(ErpPaymentMethodEnum.values()) |
| | | .filter(item -> item.getName().equals(value)) |
| | | .map(ErpPaymentMethodEnum::getType).findFirst().orElse(null); |
| | | } |
| | | |
| | | /** |
| | |
| | | |
| | | private List<ErpPurchaseOrderItemDO> validatePurchaseOrderItems(List<ErpPurchaseOrderSaveReqVO.Item> list) { |
| | | // 转å为 ErpPurchaseOrderItemDO å表ï¼äº§åéªè¯å·²ç§»é¤ï¼ |
| | | return convertList(list, o -> BeanUtils.toBean(o, ErpPurchaseOrderItemDO.class, item -> { |
| | | List<ErpPurchaseOrderItemDO> items = convertList(list, o -> BeanUtils.toBean(o, ErpPurchaseOrderItemDO.class, item -> { |
| | | item.setTotalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount())); |
| | | if (item.getTotalPrice() == null) { |
| | | return; |
| | |
| | | item.setTaxPrice(MoneyUtils.taxPriceIncluded(item.getTotalPrice(), item.getTaxPercent())); |
| | | } |
| | | })); |
| | | // éè´å°è´¦ï¼äº§åç¼å·å MDM ç©æç¼ç å¿«ç
§ï¼ä¿è¯å表/导åºå¯ç´æ¥å±ç¤º |
| | | fillProductCode(items); |
| | | return items; |
| | | } |
| | | |
| | | /** |
| | | * åå¡«æç»è¡ç产åç¼å·ï¼MDM ç©æç¼ç ï¼ |
| | | */ |
| | | private void fillProductCode(List<ErpPurchaseOrderItemDO> items) { |
| | | if (CollUtil.isEmpty(items)) { |
| | | return; |
| | | } |
| | | Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap( |
| | | convertSet(items, ErpPurchaseOrderItemDO::getProductId)); |
| | | items.forEach(item -> { |
| | | MdmItemRespDTO mdmItem = itemMap.get(item.getProductId()); |
| | | if (mdmItem == null) { |
| | | return; |
| | | } |
| | | if (StrUtil.isBlank(mdmItem.getCode())) { |
| | | throw exception(PURCHASE_ORDER_ITEM_PRODUCT_CODE_MISSING, |
| | | StrUtil.blankToDefault(mdmItem.getName(), "ID=" + mdmItem.getId())); |
| | | } |
| | | item.setProductCode(mdmItem.getCode()); |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éªéè´å°è´¦å段ï¼éè´ç±»åã仿¬¾æ¹å¼ï¼ |
| | | */ |
| | | private void validateLedgerFields(ErpPurchaseOrderSaveReqVO reqVO) { |
| | | if (!ErpPurchaseTypeEnum.isValid(reqVO.getPurchaseType())) { |
| | | throw exception(PURCHASE_ORDER_PURCHASE_TYPE_INVALID, reqVO.getPurchaseType()); |
| | | } |
| | | if (!ErpPaymentMethodEnum.isValid(reqVO.getPaymentMethod())) { |
| | | throw exception(PURCHASE_ORDER_PAYMENT_METHOD_INVALID, reqVO.getPaymentMethod()); |
| | | } |
| | | } |
| | | |
| | | private void updatePurchaseOrderItemList(Long id, List<ErpPurchaseOrderItemDO> newList) { |
| | |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.MesWmReturnVendorSaveReqVO; |
| | | import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi; |
| | | import cn.iocoder.yudao.module.srm.api.supplier.dto.SrmSupplierRespDTO; |
| | | import cn.iocoder.yudao.module.erp.api.finance.ErpFinancePaymentApi; |
| | | import cn.iocoder.yudao.module.erp.api.finance.dto.ErpFinancePaymentRespDTO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorDO; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnVendorStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.service.wm.arrivalnotice.MesWmArrivalNoticeService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.returnvendor.MesWmReturnVendorService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.returnvendor.MesWmReturnVendorServiceImpl; |
| | | import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi; |
| | | import cn.iocoder.yudao.module.system.api.storage.dto.StorageBlobRespDTO; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.Arrays; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | |
| | | private MesWmReturnVendorService returnVendorService; |
| | | @Resource |
| | | private SrmSupplierApi srmSupplierApi; |
| | | @Resource |
| | | private StorageAttachmentApi storageAttachmentApi; |
| | | @Resource |
| | | private ErpFinancePaymentApi financePaymentApi; |
| | | @Resource |
| | | private MesWmArrivalNoticeService arrivalNoticeService; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建ä¾åºåéè´§å") |
| | |
| | | return success(true); |
| | | } |
| | | |
| | | @PutMapping("/submit-approval") |
| | | @Operation(summary = "æäº¤ä¾åºåéè´§å审æ¹", description = "èµ° BPM æµç¨ï¼éè´ -> è´¨é -> ä»åº") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true) |
| | | @Parameter(name = "processDefinitionKey", description = "æµç¨å®ä¹ Key", required = true, example = "purchase_return_vendor_approve") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-return-vendor:submit-approval')") |
| | | public CommonResult<Boolean> submitReturnVendorApproval(@RequestParam("id") Long id, |
| | | @RequestParam("processDefinitionKey") String processDefinitionKey) { |
| | | returnVendorService.submitReturnVendorApproval(id, processDefinitionKey); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/attachments") |
| | | @Operation(summary = "è·å¾ä¾åºåéè´§åéä»¶å表") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true) |
| | | public CommonResult<List<StorageBlobRespDTO>> getReturnVendorAttachments(@RequestParam("id") Long id) { |
| | | return success(storageAttachmentApi.listAttachments( |
| | | MesWmReturnVendorServiceImpl.RETURN_VENDOR_RECORD_TYPE, id)); |
| | | } |
| | | |
| | | @PostMapping("/red-flush") |
| | | @Operation(summary = "çæéè´éè´§è´æ°å²çº¢ä»æ¬¾å", description = "å¹çï¼å·²çæåç´æ¥è¿åå·²æå²çº¢åç¼å·") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true) |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-return-vendor:finish')") |
| | | public CommonResult<Long> createRedFlushPayment(@RequestParam("id") Long id) { |
| | | return success(returnVendorService.createRedFlushPayment(id)); |
| | | } |
| | | |
| | | @PostMapping("/replacement-notice") |
| | | @Operation(summary = "çææ¢è´§å°è´§éç¥å", description = "å¹çï¼å·²çæåç´æ¥è¿åå·²æå°è´§éç¥åç¼å·") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true) |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-return-vendor:finish')") |
| | | public CommonResult<Long> createReplacementNotice(@RequestParam("id") Long id) { |
| | | return success(returnVendorService.createReplacementNotice(id)); |
| | | } |
| | | |
| | | @PutMapping("/stock") |
| | | @Operation(summary = "æ§è¡æ£è´§") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true) |
| | |
| | | convertSet(list, MesWmReturnVendorDO::getVendorId)).getCheckedData().stream() |
| | | .collect(java.util.stream.Collectors.toMap(SrmSupplierRespDTO::getId, s -> s)); |
| | | // 2. æå»ºç»æ |
| | | return BeanUtils.toBean(list, MesWmReturnVendorRespVO.class, vo -> |
| | | MapUtils.findAndThen(vendorMap, vo.getVendorId(), vendor -> { |
| | | vo.setVendorName(vendor.getName()); |
| | | vo.setVendorCode(vendor.getCode()); |
| | | })); |
| | | return BeanUtils.toBean(list, MesWmReturnVendorRespVO.class, vo -> { |
| | | MapUtils.findAndThen(vendorMap, vo.getVendorId(), vendor -> { |
| | | vo.setVendorName(vendor.getName()); |
| | | vo.setVendorCode(vendor.getCode()); |
| | | }); |
| | | vo.setStatusName(resolveStatusName(vo.getStatus())); |
| | | vo.setAttachmentList(storageAttachmentApi.listAttachments( |
| | | MesWmReturnVendorServiceImpl.RETURN_VENDOR_RECORD_TYPE, vo.getId())); |
| | | // å²çº¢åå· / æ¢è´§å°è´§åå·ï¼ä»
å¨å·²çææ¶æ¥è¯¢ï¼ |
| | | if (vo.getRedFlushPaymentId() != null) { |
| | | ErpFinancePaymentRespDTO payment = financePaymentApi |
| | | .getFinancePayment(vo.getRedFlushPaymentId()).getCheckedData(); |
| | | if (payment != null) { |
| | | vo.setRedFlushPaymentNo(payment.getNo()); |
| | | } |
| | | } |
| | | if (vo.getReplacementNoticeId() != null) { |
| | | MesWmArrivalNoticeDO notice = arrivalNoticeService.getArrivalNotice(vo.getReplacementNoticeId()); |
| | | if (notice != null) { |
| | | vo.setReplacementNoticeCode(notice.getCode()); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | |
| | | private String resolveStatusName(Integer status) { |
| | | MesWmReturnVendorStatusEnum statusEnum = Arrays.stream(MesWmReturnVendorStatusEnum.values()) |
| | | .filter(item -> item.getStatus().equals(status)).findFirst().orElse(null); |
| | | return statusEnum != null ? statusEnum.getName() : null; |
| | | } |
| | | |
| | | } |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo; |
| | | |
| | | import cn.iocoder.yudao.module.system.api.storage.dto.StorageBlobRespDTO; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | @Schema(description = "管çåå° - MES ä¾åºåéè´§å Response VO") |
| | | @Data |
| | |
| | | @Schema(description = "éè´§åå ", example = "è´¨éä¸åæ ¼") |
| | | private String returnReason; |
| | | |
| | | @Schema(description = "éè´ååå·", example = "HT2026110001") |
| | | private String contractNo; |
| | | |
| | | @Schema(description = "å¤çæ¹å¼ï¼1鿬¾ 2æ¢è´§", example = "1") |
| | | private Integer handleType; |
| | | |
| | | @Schema(description = "鿬¾éé¢", example = "1000.00") |
| | | private BigDecimal refundAmount; |
| | | |
| | | @Schema(description = "è´æ°å²çº¢ä»æ¬¾åç¼å·", example = "1") |
| | | private Long redFlushPaymentId; |
| | | |
| | | @Schema(description = "è´æ°å²çº¢ä»æ¬¾åå·", example = "FKD2026110001") |
| | | private String redFlushPaymentNo; |
| | | |
| | | @Schema(description = "æ¢è´§å°è´§éç¥åç¼å·", example = "1") |
| | | private Long replacementNoticeId; |
| | | |
| | | @Schema(description = "æ¢è´§å°è´§éç¥åå·", example = "AN2026110001") |
| | | private String replacementNoticeCode; |
| | | |
| | | @Schema(description = "BPM æµç¨å®ä¾ç¼å·") |
| | | private String processInstanceId; |
| | | |
| | | @Schema(description = "éä»¶å表") |
| | | private List<StorageBlobRespDTO> attachmentList; |
| | | |
| | | @Schema(description = "ç©æµåå·", example = "SF1234567890") |
| | | private String transportCode; |
| | | |
| | |
| | | @Schema(description = "ç¶æ", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "ç¶æåç§°", example = "审æ¹ä¸") |
| | | private String statusName; |
| | | |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | private String remark; |
| | | |
| | |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | @Schema(description = "管çåå° - MES ä¾åºåéè´§åæ°å¢/ä¿®æ¹ Request VO") |
| | | @Data |
| | |
| | | @Schema(description = "éè´§åå ", example = "è´¨éä¸åæ ¼") |
| | | private String returnReason; |
| | | |
| | | @Schema(description = "å¤çæ¹å¼ï¼1鿬¾ 2æ¢è´§", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "å¤çæ¹å¼ä¸è½ä¸ºç©ºï¼1鿬¾ 2æ¢è´§") |
| | | private Integer handleType; |
| | | |
| | | @Schema(description = "鿬¾éé¢ï¼å¤çæ¹å¼=鿬¾æ¶å¡«åï¼ä¸ºç©ºæ¶æéè´åä»·Ãéè´§æ°é计ç®ï¼", example = "1000.00") |
| | | private BigDecimal refundAmount; |
| | | |
| | | @Schema(description = "éè´ååå·ï¼åªè¯»ï¼å建æ¶ä»éè´è®¢åå¿«ç
§ï¼", example = "HT2026110001") |
| | | private String contractNo; |
| | | |
| | | @Schema(description = "éä»¶ blobId å表", example = "[1, 2, 3]") |
| | | private List<Long> blobIds; |
| | | |
| | | @Schema(description = "ç©æµåå·", example = "SF1234567890") |
| | | private String transportCode; |
| | | |
| | |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import cn.iocoder.yudao.module.mes.enums.DictTypeConstants; |
| | | |
| | |
| | | */ |
| | | private String purchaseOrderCode; |
| | | /** |
| | | * éè´ååå·ï¼å建æ¶ä»éè´è®¢åå¿«ç
§ï¼æ¢è´§å
¥åºæ²¿ç¨ï¼ |
| | | */ |
| | | private String contractNo; |
| | | /** |
| | | * ä¾åºå ID |
| | | * |
| | | * å
³è ERP ä¾åºå {@link cn.iocoder.yudao.module.erp.api.purchase.dto.ErpSupplierRespDTO#getId()} |
| | |
| | | */ |
| | | private String remark; |
| | | |
| | | // ========== å®¡æ¹ ========== |
| | | /** |
| | | * BPM æµç¨å®ä¾ç¼å· |
| | | */ |
| | | private String processInstanceId; |
| | | /** |
| | | * BPM æµç¨å®ä¹ Key |
| | | */ |
| | | private String processDefinitionKey; |
| | | |
| | | // ========== è´¹ç¨ä¿¡æ¯ ========== |
| | | /** |
| | | * å¤çæ¹å¼ |
| | | * |
| | | * æä¸¾ {@link cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnVendorHandleTypeEnum} |
| | | */ |
| | | private Integer handleType; |
| | | /** |
| | | * 鿬¾éé¢ï¼é»è®¤æéè´åä»· à éè´§æ°é计ç®ï¼å¯ä¿®æ¹ï¼ |
| | | */ |
| | | private BigDecimal refundAmount; |
| | | /** |
| | | * è´æ°å²çº¢ä»æ¬¾åç¼å·ï¼é款æ¶çæï¼å
³è ERP 仿¬¾åï¼ |
| | | */ |
| | | private Long redFlushPaymentId; |
| | | /** |
| | | * æ¢è´§å°è´§éç¥åç¼å·ï¼æ¢è´§æ¶çæï¼å
³è MES å°è´§éç¥åï¼ |
| | | */ |
| | | private Long replacementNoticeId; |
| | | |
| | | } |
| | |
| | | String MES_WM_OUTSOURCE_ISSUE_STATUS = "mes_wm_outsource_issue_status"; // MES å§å¤åºåºç¶æ |
| | | String MES_WM_PRODUCT_ISSUE_STATUS = "mes_wm_product_issue_status"; // MES çäº§é¢æç¶æ |
| | | String MES_WM_RETURN_VENDOR_STATUS = "mes_wm_return_vendor_status"; // MES ä¾åºåéè´§åç¶æ |
| | | String MES_WM_RETURN_VENDOR_HANDLE_TYPE = "mes_wm_return_vendor_handle_type"; // MES ä¾åºåéè´§å¤çæ¹å¼ |
| | | |
| | | // ========== ä»å¨ç§»åºä¸çç¹ (WM Transfer) ========== |
| | | String MES_WM_TRANSFER_STATUS = "mes_wm_transfer_status"; // MES 转移åç¶æ |
| | |
| | | ErrorCode WM_RETURN_VENDOR_PURCHASE_ORDER_REQUIRED = new ErrorCode(1_040_711_008, "请å
éæ©éè´è®¢å"); |
| | | ErrorCode WM_RETURN_VENDOR_PURCHASE_ORDER_NO_ITEM = new ErrorCode(1_040_711_009, "éè´è®¢åæ æç»æ°æ®ï¼æ æ³å¸¦å
¥ç©æ"); |
| | | ErrorCode WM_RETURN_VENDOR_ITEM_NOT_IN_PURCHASE_ORDER = new ErrorCode(1_040_711_010, "éè´§ç©æä¸å¨æå
³èéè´è®¢åå
ï¼æ æ³æ·»å "); |
| | | ErrorCode WM_RETURN_VENDOR_APPROVE_PROCESS_NOT_PUBLISHED = new ErrorCode(1_040_711_011, "éè´éè´§å®¡æ¹æµç¨[{}]æªåå¸ï¼è¯·è系管çåå¨ BPM åå°å叿µç¨æ¨¡åååæäº¤"); |
| | | ErrorCode WM_RETURN_VENDOR_HANDLE_TYPE_INVALID = new ErrorCode(1_040_711_012, "ä¾åºåéè´§åå¤çæ¹å¼ä¸æ£ç¡®ï¼å½å为[{}]ï¼ä»
æ¯æ 1鿬¾ / 2æ¢è´§ï¼è¯·ä¿®æ¹å¤çæ¹å¼ååæä½"); |
| | | ErrorCode WM_RETURN_VENDOR_REFUND_AMOUNT_REQUIRED = new ErrorCode(1_040_711_013, "æ æ³èªå¨è®¡ç®é款éé¢ï¼éè´§å[{}]æªå
³èéè´è®¢åï¼æéè´§ç©æ[{}]æªå¹é
å°éè´è®¢åæç»ã请å¨éè´§åå¡«å鿬¾éé¢åå宿éè´§"); |
| | | ErrorCode WM_RETURN_VENDOR_FINISHED_REQUIRED = new ErrorCode(1_040_711_014, "ä¾åºåéè´§å[{}]å½åç¶æä¸º[{}]ï¼åªæå·²å®æçéè´§åæè½æ§è¡è¯¥æä½"); |
| | | |
| | | // ========== MES ä»åºç®¡ç-äº§åæ¶è´§åï¼1-040-712-000ï¼ ========== |
| | | ErrorCode WM_PRODUCT_RECPT_NOT_EXISTS = new ErrorCode(1_040_712_000, "äº§åæ¶è´§åä¸åå¨"); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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 ä¾åºåéè´§å¤çæ¹å¼æä¸¾ |
| | | * |
| | | * åå
¸ {@link cn.iocoder.yudao.module.mes.enums.DictTypeConstants#MES_WM_RETURN_VENDOR_HANDLE_TYPE} |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum MesWmReturnVendorHandleTypeEnum implements ArrayValuable<Integer> { |
| | | |
| | | REFUND(1, "鿬¾"), |
| | | REPLACEMENT(2, "æ¢è´§"); |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()) |
| | | .map(MesWmReturnVendorHandleTypeEnum::getType).toArray(Integer[]::new); |
| | | |
| | | /** |
| | | * ç±»åå¼ |
| | | */ |
| | | private final Integer type; |
| | | /** |
| | | * ç±»åå |
| | | */ |
| | | private final String name; |
| | | |
| | | @Override |
| | | public Integer[] array() { |
| | | return ARRAYS; |
| | | } |
| | | |
| | | public static MesWmReturnVendorHandleTypeEnum valueOf(Integer type) { |
| | | return Arrays.stream(values()).filter(item -> item.getType().equals(type)) |
| | | .findFirst().orElse(null); |
| | | } |
| | | |
| | | public static boolean isValid(Integer type) { |
| | | return valueOf(type) != null; |
| | | } |
| | | |
| | | } |
| | |
| | | */ |
| | | PREPARE(MesOrderStatusConstants.PREPARE, "è稿"), |
| | | /** |
| | | * 审æ¹ä¸ï¼BPMï¼ |
| | | * |
| | | * å¯¹åº MesWmReturnVendorService#submitReturnVendorApproval æ¹æ³ |
| | | * å¤ç¨ CONFIRMED(1) çç¶æå¼ï¼å岿°æ®ä¸è¿ç§» |
| | | */ |
| | | BPM_APPROVING(MesOrderStatusConstants.CONFIRMED, "审æ¹ä¸"), |
| | | /** |
| | | * å¾
æ£è´§ |
| | | * |
| | | * å¯¹åº MesWmReturnVendorService#submitReturnVendor æ¹æ³ |
| | |
| | | */ |
| | | Long generateArrivalNoticeFromPurchaseOrder(Long purchaseOrderId); |
| | | |
| | | /** |
| | | * æ ¹æ®ä¾åºåéè´§åçæãæ¢è´§å°è´§éç¥åãï¼éæ°å
¥åº + éæ°è´¨æ£ï¼å
³èåéè´ååï¼ |
| | | * |
| | | * è¯¥åæ®ä¸èµ°éè´è®¢åå¯ä¸æ§æ ¡éªï¼å
许åä¸éè´è®¢ååå¨å¤å¼ å°è´§éç¥åã |
| | | * çæåç¶æä¸ºå¾
è´¨æ£ï¼å¹¶éè¡èªå¨å建 IQC æ£éªåã |
| | | * |
| | | * @param returnVendorId ä¾åºåéè´§åç¼å· |
| | | * @return çæçå°è´§éç¥åç¼å· |
| | | */ |
| | | Long createReplacementArrivalNotice(Long returnVendorId); |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.arrivalnotice.vo.MesWmArrivalNoticeSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeLineDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorLineDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.wm.arrivalnotice.MesWmArrivalNoticeMapper; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnvendor.MesWmReturnVendorLineMapper; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnvendor.MesWmReturnVendorMapper; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmArrivalNoticeStatusEnum; |
| | | import cn.iocoder.yudao.module.erp.api.purchase.ErpPurchaseOrderApi; |
| | | import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi; |
| | |
| | | import java.math.BigDecimal; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; |
| | |
| | | |
| | | @Resource |
| | | private MesWmArrivalNoticeLineService arrivalNoticeLineService; |
| | | |
| | | @Resource |
| | | private MesWmReturnVendorMapper returnVendorMapper; |
| | | @Resource |
| | | private MesWmReturnVendorLineMapper returnVendorLineMapper; |
| | | |
| | | @Resource |
| | | private SrmSupplierApi srmSupplierApi; |
| | |
| | | return notice.getId(); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createReplacementArrivalNotice(Long returnVendorId) { |
| | | // 1. æ ¡éªéè´§å |
| | | MesWmReturnVendorDO returnVendor = returnVendorMapper.selectById(returnVendorId); |
| | | if (returnVendor == null) { |
| | | throw exception(WM_RETURN_VENDOR_NOT_EXISTS); |
| | | } |
| | | if (returnVendor.getPurchaseOrderId() == null) { |
| | | throw exception(WM_RETURN_VENDOR_PURCHASE_ORDER_REQUIRED); |
| | | } |
| | | List<MesWmReturnVendorLineDO> returnLines = returnVendorLineMapper.selectListByReturnId(returnVendorId); |
| | | if (CollUtil.isEmpty(returnLines)) { |
| | | throw exception(WM_RETURN_VENDOR_NO_LINE); |
| | | } |
| | | |
| | | // 2. è·åéè´è®¢åæç»ï¼ç¨äºæç©æå¹é
éè´è®¢åæç»ç¼å·ï¼ä¿è¯å
¥åºåè½ååå
¥åº/éè´§æ°éï¼ |
| | | Map<Long, Long> purchaseOrderItemIdMap = new HashMap<>(); |
| | | List<ErpPurchaseOrderItemRespDTO> orderItems = purchaseOrderApi |
| | | .getPurchaseOrderItemList(returnVendor.getPurchaseOrderId()).getCheckedData(); |
| | | if (CollUtil.isNotEmpty(orderItems)) { |
| | | orderItems.stream() |
| | | .filter(item -> item.getProductId() != null) |
| | | .forEach(item -> purchaseOrderItemIdMap.putIfAbsent(item.getProductId(), item.getId())); |
| | | } |
| | | |
| | | // 3. å建å°è´§éç¥å主表ï¼ç¶æç´æ¥ç½®ä¸ºå¾
è´¨æ£ |
| | | MesWmArrivalNoticeDO notice = new MesWmArrivalNoticeDO(); |
| | | notice.setCode(generateArrivalNoticeCode()); |
| | | notice.setName(returnVendor.getCode() + "æ¢è´§å°è´§"); |
| | | notice.setPurchaseOrderId(returnVendor.getPurchaseOrderId()); |
| | | notice.setPurchaseOrderCode(returnVendor.getPurchaseOrderCode()); |
| | | notice.setVendorId(returnVendor.getVendorId()); |
| | | notice.setArrivalDate(java.time.LocalDateTime.now()); |
| | | notice.setStatus(MesWmArrivalNoticeStatusEnum.PENDING_QC.getStatus()); |
| | | notice.setRemark("ä¾åºåéè´§å[" + returnVendor.getCode() + "]æ¢è´§éæ°å
¥åºï¼ååå·[" |
| | | + returnVendor.getContractNo() + "]"); |
| | | arrivalNoticeMapper.insert(notice); |
| | | |
| | | // 4. éåéè´§è¡å建å°è´§éç¥åè¡ï¼å
¨é¨æ è®°éè¦è´¨æ£ |
| | | for (MesWmReturnVendorLineDO returnLine : returnLines) { |
| | | MesWmArrivalNoticeLineDO line = new MesWmArrivalNoticeLineDO(); |
| | | line.setNoticeId(notice.getId()); |
| | | line.setPurchaseOrderItemId(purchaseOrderItemIdMap.get(returnLine.getItemId())); |
| | | line.setItemId(returnLine.getItemId()); |
| | | line.setArrivalQuantity(returnLine.getQuantity()); |
| | | line.setIqcCheckFlag(true); |
| | | arrivalNoticeLineService.createArrivalNoticeLineFromPurchaseOrderItem(line); |
| | | } |
| | | |
| | | // 5. éè¡èªå¨å建 IQC æ£éªå |
| | | List<MesWmArrivalNoticeLineDO> lines = arrivalNoticeLineService.getArrivalNoticeLineListByNoticeId(notice.getId()); |
| | | for (MesWmArrivalNoticeLineDO line : lines) { |
| | | Long iqcId = iqcService.createIqcFromArrivalNotice( |
| | | notice.getId(), line, notice.getCode(), notice.getVendorId()); |
| | | arrivalNoticeLineService.updateArrivalNoticeLineIqcId(line.getId(), iqcId); |
| | | log.info("[createReplacementArrivalNotice][æ¢è´§å°è´§éç¥å({}) è¡({}) èªå¨å建 IQC æ£éªå({})]", |
| | | notice.getId(), line.getId(), iqcId); |
| | | } |
| | | return notice.getId(); |
| | | } |
| | | |
| | | /** |
| | | * çæå°è´§éç¥åç¼ç |
| | | */ |
| | |
| | | void submitReturnVendor(Long id); |
| | | |
| | | /** |
| | | * æäº¤ä¾åºåéè´§å审æ¹ï¼è稿 -> 审æ¹ä¸ï¼ï¼èµ° BPM æµç¨ï¼éè´ -> è´¨é -> ä»åº |
| | | * |
| | | * @param id ç¼å· |
| | | * @param processDefinitionKey æµç¨å®ä¹ç Key |
| | | */ |
| | | void submitReturnVendorApproval(Long id, String processDefinitionKey); |
| | | |
| | | /** |
| | | * æ´æ°ä¾åºåéè´§åç审æ¹ç¶æï¼ç± BPM æµç¨å®ä¾çåè°è§¦åï¼ |
| | | * |
| | | * @param id ç¼å· |
| | | * @param bpmResult BPM 审æ¹ç»æ |
| | | */ |
| | | void updateReturnVendorAuditStatus(Long id, Integer bpmResult); |
| | | |
| | | /** |
| | | * æ§è¡æ£è´§ï¼å¾
æ£è´§ -> å¾
æ§è¡éè´§ï¼ |
| | | * |
| | | * @param id ç¼å· |
| | |
| | | void finishReturnVendor(Long id); |
| | | |
| | | /** |
| | | * çæéè´éè´§è´æ°å²çº¢ä»æ¬¾åï¼å¹çï¼å·²çæåç´æ¥è¿åï¼ |
| | | * |
| | | * @param id éè´§åç¼å· |
| | | * @return 仿¬¾åç¼å· |
| | | */ |
| | | Long createRedFlushPayment(Long id); |
| | | |
| | | /** |
| | | * çææ¢è´§å°è´§éç¥åï¼å¹çï¼å·²çæåç´æ¥è¿åï¼ï¼èµ° å°è´§éç¥ -> IQC -> éè´å
¥åº é¾è·¯ |
| | | * |
| | | * @param id éè´§åç¼å· |
| | | * @return å°è´§éç¥åç¼å· |
| | | */ |
| | | Long createReplacementNotice(Long id); |
| | | |
| | | /** |
| | | * åæ¶ä¾åºåéè´§åï¼ä»»æé已宿/å·²åæ¶ç¶æ -> å·²åæ¶ï¼ |
| | | * |
| | | * @param id ç¼å· |
| | |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.common.exception.ServiceException; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; |
| | | import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; |
| | | import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.MesWmReturnVendorPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.MesWmReturnVendorSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.line.MesWmReturnVendorLineSaveReqVO; |
| | |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorLineDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnvendor.MesWmReturnVendorMapper; |
| | | import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnVendorHandleTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnVendorStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum; |
| | | import cn.iocoder.yudao.module.erp.api.finance.ErpFinancePaymentApi; |
| | | import cn.iocoder.yudao.module.erp.api.finance.dto.ErpFinancePaymentRedFlushCreateReqDTO; |
| | | import cn.iocoder.yudao.module.erp.api.purchase.ErpPurchaseOrderApi; |
| | | import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderItemRespDTO; |
| | | import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderRespDTO; |
| | | import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi; |
| | | import cn.iocoder.yudao.module.mes.service.wm.arrivalnotice.MesWmArrivalNoticeService; |
| | | 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.system.api.storage.StorageAttachmentApi; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.security.core.Authentication; |
| | | import org.springframework.security.core.context.SecurityContextHolder; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.util.HashMap; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | |
| | | @Service |
| | | @Validated |
| | | public class MesWmReturnVendorServiceImpl implements MesWmReturnVendorService { |
| | | |
| | | /** |
| | | * éä»¶ä¸å¡ç±»åï¼MES ä¾åºåéè´§å |
| | | */ |
| | | public static final String RETURN_VENDOR_RECORD_TYPE = "mes_wm_return_vendor"; |
| | | |
| | | @Resource |
| | | private MesWmReturnVendorMapper returnVendorMapper; |
| | |
| | | private MesWmTransactionService wmTransactionService; |
| | | @Resource |
| | | private ErpPurchaseOrderApi purchaseOrderApi; |
| | | @Resource |
| | | private ErpFinancePaymentApi financePaymentApi; |
| | | @Resource |
| | | private MesWmArrivalNoticeService arrivalNoticeService; |
| | | @Resource |
| | | private StorageAttachmentApi storageAttachmentApi; |
| | | @Resource |
| | | private BpmProcessInstanceApi processInstanceApi; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createReturnVendor(MesWmReturnVendorSaveReqVO createReqVO) { |
| | | // 1. æ ¡éªæ°æ® |
| | | validateReturnVendorSaveData(createReqVO); |
| | | // 1.1. è¥éè´è®¢åå·ä¸ºç©ºä½å
³èäºéè´è®¢åï¼åä» ERP éè´è®¢åè¡¥é½è®¢åå· |
| | | fillPurchaseOrderCode(createReqVO); |
| | | // 1.1. è¥éè´è®¢åå·ä¸ºç©ºä½å
³èäºéè´è®¢åï¼åä» ERP éè´è®¢åè¡¥é½è®¢åå·ãååå· |
| | | fillFromPurchaseOrder(createReqVO); |
| | | |
| | | // 2. æå
¥ä¸»è¡¨ |
| | | MesWmReturnVendorDO returnVendor = BeanUtils.toBean(createReqVO, MesWmReturnVendorDO.class); |
| | |
| | | if (returnVendor.getPurchaseOrderId() != null) { |
| | | autoImportLinesFromLinkedOrder(returnVendor.getId(), false); |
| | | } |
| | | // 2.2. ç»å®éä»¶ï¼è´¨éé¨åèµ·éè´§æ¶ä¸ä¼ çæ£éªæ¥åãç
§ççï¼ |
| | | storageAttachmentApi.bindAttachments("file", RETURN_VENDOR_RECORD_TYPE, |
| | | returnVendor.getId(), createReqVO.getBlobIds()); |
| | | return returnVendor.getId(); |
| | | } |
| | | |
| | |
| | | public void updateReturnVendor(MesWmReturnVendorSaveReqVO updateReqVO) { |
| | | // 1. æ ¡éªæ°æ®ï¼å«åå¨ + èç¨¿ç¶æï¼ |
| | | MesWmReturnVendorDO oldReturnVendor = validateReturnVendorSaveData(updateReqVO); |
| | | // 1.1. è¥éè´è®¢åå·ä¸ºç©ºä½å
³èäºéè´è®¢åï¼åä» ERP éè´è®¢åè¡¥é½è®¢åå· |
| | | fillPurchaseOrderCode(updateReqVO); |
| | | // 1.1. è¥éè´è®¢åå·ä¸ºç©ºä½å
³èäºéè´è®¢åï¼åä» ERP éè´è®¢åè¡¥é½è®¢åå·ãååå· |
| | | fillFromPurchaseOrder(updateReqVO); |
| | | |
| | | Long oldPurchaseOrderId = oldReturnVendor != null ? oldReturnVendor.getPurchaseOrderId() : null; |
| | | Long newPurchaseOrderId = updateReqVO.getPurchaseOrderId(); |
| | |
| | | if (newPurchaseOrderId != null) { |
| | | autoImportLinesFromLinkedOrder(updateReqVO.getId(), purchaseOrderChanged); |
| | | } |
| | | |
| | | // 4. å¢éæ´æ°éä»¶ï¼åªå¤çæ°å¢/å é¤ï¼æªä¼ blobIds æ¶ä¸å¨ç°æéä»¶ï¼ |
| | | storageAttachmentApi.updateAttachments("file", RETURN_VENDOR_RECORD_TYPE, |
| | | updateReqVO.getId(), updateReqVO.getBlobIds()); |
| | | } |
| | | |
| | | /** |
| | | * å½éè´è®¢åå·ä¸ºç©ºãä½å
³èäºéè´è®¢åæ¶ï¼ä» ERP éè´è®¢åè¡¥é½éè´è®¢åå· |
| | | * å
³èäºéè´è®¢åæ¶ï¼ä» ERP éè´è®¢åè¡¥é½éè´è®¢åå·ãååå·ï¼ååå·åªåå¿«ç
§ï¼ä¸å
许æå·¥çæï¼ |
| | | */ |
| | | private void fillPurchaseOrderCode(MesWmReturnVendorSaveReqVO reqVO) { |
| | | private void fillFromPurchaseOrder(MesWmReturnVendorSaveReqVO reqVO) { |
| | | if (reqVO == null || reqVO.getPurchaseOrderId() == null) { |
| | | return; |
| | | } |
| | | if (cn.hutool.core.util.StrUtil.isNotBlank(reqVO.getPurchaseOrderCode())) { |
| | | return; |
| | | } |
| | | ErpPurchaseOrderRespDTO purchaseOrder = |
| | | purchaseOrderApi.getPurchaseOrder(reqVO.getPurchaseOrderId()).getCheckedData(); |
| | | if (purchaseOrder != null) { |
| | | if (purchaseOrder == null) { |
| | | return; |
| | | } |
| | | if (StrUtil.isBlank(reqVO.getPurchaseOrderCode())) { |
| | | reqVO.setPurchaseOrderCode(purchaseOrder.getNo()); |
| | | } |
| | | if (StrUtil.isBlank(reqVO.getContractNo())) { |
| | | reqVO.setContractNo(purchaseOrder.getContractNo()); |
| | | } |
| | | } |
| | | |
| | |
| | | returnVendorDetailService.deleteReturnVendorDetailByReturnId(id); |
| | | // 2.2 级èå é¤è¡ |
| | | returnVendorLineService.deleteReturnVendorLineByReturnId(id); |
| | | // 2.3 å é¤ä¸»è¡¨ |
| | | // 2.3 å é¤éä»¶ |
| | | storageAttachmentApi.deleteAttachmentsByRecord(RETURN_VENDOR_RECORD_TYPE, id); |
| | | // 2.4 å é¤ä¸»è¡¨ |
| | | returnVendorMapper.deleteById(id); |
| | | } |
| | | |
| | |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void submitReturnVendorApproval(Long id, String processDefinitionKey) { |
| | | // 1. æ ¡éªåå¨ + èç¨¿ç¶æ + è³å°ä¸æ¡è¡ |
| | | validateReturnVendorExistsAndPrepare(id); |
| | | if (CollUtil.isEmpty(returnVendorLineService.getReturnVendorLineListByReturnId(id))) { |
| | | throw exception(WM_RETURN_VENDOR_NO_LINE); |
| | | } |
| | | |
| | | // 2. å
¨å±å
审æ¹ï¼ç´æ¥ç½®ä¸ºãå¾
æ£è´§ãï¼æ éæµç¨æ¨¡å |
| | | if (processInstanceApi.isGlobalAutoApprove()) { |
| | | returnVendorMapper.updateById(new MesWmReturnVendorDO() |
| | | .setId(id) |
| | | .setStatus(MesWmReturnVendorStatusEnum.APPROVING.getStatus()) |
| | | .setProcessDefinitionKey(processDefinitionKey) |
| | | .setProcessInstanceId("")); |
| | | return; |
| | | } |
| | | |
| | | // 3. å建 BPM æµç¨å®ä¾ï¼æµç¨æªå叿¶ç»åºæç¡®æç¤º |
| | | String processInstanceId; |
| | | try { |
| | | processInstanceId = processInstanceApi.createProcessInstance(getCurrentUserId(), |
| | | new BpmProcessInstanceCreateReqDTO() |
| | | .setProcessDefinitionKey(processDefinitionKey) |
| | | .setBusinessKey(String.valueOf(id))); |
| | | } catch (ServiceException ex) { |
| | | if (cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NOT_EXISTS |
| | | .getCode().equals(ex.getCode())) { |
| | | throw exception(WM_RETURN_VENDOR_APPROVE_PROCESS_NOT_PUBLISHED, processDefinitionKey); |
| | | } |
| | | throw ex; |
| | | } |
| | | |
| | | // 4. æ´æ°éè´§åç¶æä¸ºå®¡æ¹ä¸ |
| | | returnVendorMapper.updateById(new MesWmReturnVendorDO() |
| | | .setId(id) |
| | | .setStatus(MesWmReturnVendorStatusEnum.BPM_APPROVING.getStatus()) |
| | | .setProcessDefinitionKey(processDefinitionKey) |
| | | .setProcessInstanceId(processInstanceId)); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updateReturnVendorAuditStatus(Long id, Integer bpmResult) { |
| | | // 1. æ ¡éªåå¨ + 审æ¹ä¸ |
| | | MesWmReturnVendorDO returnVendor = validateReturnVendorExists(id); |
| | | if (!MesWmReturnVendorStatusEnum.BPM_APPROVING.getStatus().equals(returnVendor.getStatus())) { |
| | | return; |
| | | } |
| | | |
| | | // 2. æ ¹æ®å®¡æ¹ç»ææ´æ°ç¶æï¼éè¿ -> å¾
æ£è´§ï¼é©³å -> è稿ï¼åæ¶ -> 已忶 |
| | | Integer newStatus = convertBpmResultToReturnVendorStatus(bpmResult); |
| | | if (newStatus != null) { |
| | | returnVendorMapper.updateById(new MesWmReturnVendorDO().setId(id).setStatus(newStatus)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è½¬æ¢ BPM 审æ¹ç»æä¸ºä¾åºåéè´§åç¶æ |
| | | */ |
| | | private Integer convertBpmResultToReturnVendorStatus(Integer bpmResult) { |
| | | if (cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum.APPROVE.getStatus().equals(bpmResult)) { |
| | | return MesWmReturnVendorStatusEnum.APPROVING.getStatus(); |
| | | } |
| | | if (cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum.REJECT.getStatus().equals(bpmResult)) { |
| | | return MesWmReturnVendorStatusEnum.PREPARE.getStatus(); |
| | | } |
| | | if (cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum.CANCEL.getStatus().equals(bpmResult)) { |
| | | return MesWmReturnVendorStatusEnum.CANCELED.getStatus(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void stockReturnVendor(Long id) { |
| | | // æ ¡éªåå¨ |
| | | MesWmReturnVendorDO returnVendor = validateReturnVendorExists(id); |
| | |
| | | throw exception(WM_RETURN_VENDOR_NO_DETAIL); |
| | | } |
| | | |
| | | // 1.3 æ ¡éªå¤çæ¹å¼ï¼é款 / æ¢è´§ï¼ |
| | | if (!MesWmReturnVendorHandleTypeEnum.isValid(returnVendor.getHandleType())) { |
| | | throw exception(WM_RETURN_VENDOR_HANDLE_TYPE_INVALID, returnVendor.getHandleType()); |
| | | } |
| | | |
| | | // 2. éåæææç»ï¼å建åºåäºå¡ï¼æ£ååºå + è®°å½æµæ°´ï¼ |
| | | createTransactionList(returnVendor, details); |
| | | |
| | | // 3. æ´æ°éè´§åç¶æ |
| | | // 3. ååéè´è®¢åè¡çå·²éè´§æ°éï¼æç©æå¹é
éè´è®¢åæç»ï¼ |
| | | writeBackPurchaseOrderReturnCount(returnVendor); |
| | | |
| | | // 4. å
ç½®ä¸ºå·²å®æï¼ä¿è¯éå¤è°ç¨ä¼è¢«ç¶ææ ¡éªæ¦æªï¼å¹çï¼ |
| | | returnVendorMapper.updateById(new MesWmReturnVendorDO() |
| | | .setId(id).setStatus(MesWmReturnVendorStatusEnum.FINISHED.getStatus())); |
| | | |
| | | // 5. è´¹ç¨å¤çï¼é款 -> è´æ°å²çº¢ä»æ¬¾åï¼æ¢è´§ -> æ¢è´§å°è´§éç¥åï¼éæ°å
¥åº + éæ°è´¨æ£ï¼ |
| | | if (MesWmReturnVendorHandleTypeEnum.REFUND.getType().equals(returnVendor.getHandleType())) { |
| | | createRedFlushPayment(id); |
| | | } else if (MesWmReturnVendorHandleTypeEnum.REPLACEMENT.getType().equals(returnVendor.getHandleType())) { |
| | | createReplacementNotice(id); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æéè´§æ°éå¢éååå°å
³èéè´è®¢åçæç»è¡ï¼å¹¶åæ¥è®¢å级éè´§æ°é |
| | | */ |
| | | private void writeBackPurchaseOrderReturnCount(MesWmReturnVendorDO returnVendor) { |
| | | if (returnVendor.getPurchaseOrderId() == null) { |
| | | return; |
| | | } |
| | | List<MesWmReturnVendorLineDO> lines = returnVendorLineService.getReturnVendorLineListByReturnId(returnVendor.getId()); |
| | | if (CollUtil.isEmpty(lines)) { |
| | | return; |
| | | } |
| | | List<ErpPurchaseOrderItemRespDTO> orderItems = purchaseOrderApi |
| | | .getPurchaseOrderItemList(returnVendor.getPurchaseOrderId()).getCheckedData(); |
| | | if (CollUtil.isEmpty(orderItems)) { |
| | | return; |
| | | } |
| | | Map<Long, Long> purchaseOrderItemIdMap = new HashMap<>(); |
| | | orderItems.stream() |
| | | .filter(item -> item.getProductId() != null) |
| | | .forEach(item -> purchaseOrderItemIdMap.putIfAbsent(item.getProductId(), item.getId())); |
| | | for (MesWmReturnVendorLineDO line : lines) { |
| | | Long purchaseOrderItemId = purchaseOrderItemIdMap.get(line.getItemId()); |
| | | if (purchaseOrderItemId == null || line.getQuantity() == null) { |
| | | continue; |
| | | } |
| | | purchaseOrderApi.updateOrderItemReturnCount(purchaseOrderItemId, line.getQuantity()); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createRedFlushPayment(Long id) { |
| | | // 1. æ ¡éªåå¨ + 已宿 + å¤çæ¹å¼ä¸ºé款 |
| | | MesWmReturnVendorDO returnVendor = validateReturnVendorFinished(id); |
| | | if (!MesWmReturnVendorHandleTypeEnum.REFUND.getType().equals(returnVendor.getHandleType())) { |
| | | throw exception(WM_RETURN_VENDOR_HANDLE_TYPE_INVALID, returnVendor.getHandleType()); |
| | | } |
| | | // 2. å¹çï¼å·²çæè¿å²çº¢åç´æ¥è¿å |
| | | if (returnVendor.getRedFlushPaymentId() != null) { |
| | | return returnVendor.getRedFlushPaymentId(); |
| | | } |
| | | // 3. 计ç®é款éé¢ï¼æªå¡«åæ¶æéè´åä»· à éè´§æ°éï¼ |
| | | BigDecimal refundAmount = resolveRefundAmount(returnVendor); |
| | | |
| | | // 4. çæè´æ°å²çº¢ä»æ¬¾å |
| | | Long paymentId = financePaymentApi.createRedFlushPayment(new ErpFinancePaymentRedFlushCreateReqDTO() |
| | | .setSupplierId(returnVendor.getVendorId()) |
| | | .setRefundAmount(refundAmount) |
| | | .setSourceId(returnVendor.getId()) |
| | | .setSourceNo(returnVendor.getCode()) |
| | | .setFinanceUserId(getCurrentUserId()) |
| | | .setRemark("ä¾åºåéè´§å[" + returnVendor.getCode() + "]鿬¾å²çº¢ï¼ååå·[" + returnVendor.getContractNo() + "]")) |
| | | .getCheckedData(); |
| | | |
| | | // 5. ååå²çº¢åå·ä¸æç»é款éé¢ |
| | | returnVendorMapper.updateById(new MesWmReturnVendorDO() |
| | | .setId(id).setRefundAmount(refundAmount).setRedFlushPaymentId(paymentId)); |
| | | return paymentId; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createReplacementNotice(Long id) { |
| | | // 1. æ ¡éªåå¨ + 已宿 + å¤çæ¹å¼ä¸ºæ¢è´§ |
| | | MesWmReturnVendorDO returnVendor = validateReturnVendorFinished(id); |
| | | if (!MesWmReturnVendorHandleTypeEnum.REPLACEMENT.getType().equals(returnVendor.getHandleType())) { |
| | | throw exception(WM_RETURN_VENDOR_HANDLE_TYPE_INVALID, returnVendor.getHandleType()); |
| | | } |
| | | // 2. å¹çï¼å·²çæè¿æ¢è´§å°è´§åç´æ¥è¿å |
| | | if (returnVendor.getReplacementNoticeId() != null) { |
| | | return returnVendor.getReplacementNoticeId(); |
| | | } |
| | | |
| | | // 3. çææ¢è´§å°è´§éç¥åï¼å¾
è´¨æ£ï¼è¡èªå¨å建 IQCï¼ |
| | | Long noticeId = arrivalNoticeService.createReplacementArrivalNotice(id); |
| | | |
| | | // 4. ååå°è´§éç¥åç¼å· |
| | | returnVendorMapper.updateById(new MesWmReturnVendorDO() |
| | | .setId(id).setReplacementNoticeId(noticeId)); |
| | | return noticeId; |
| | | } |
| | | |
| | | /** |
| | | * è§£æé款éé¢ï¼ä¼å
å忮填åå¼ï¼æªå¡«åæ¶æãéè´åä»· à éè´§æ°éãéè¡ç´¯å |
| | | */ |
| | | private BigDecimal resolveRefundAmount(MesWmReturnVendorDO returnVendor) { |
| | | if (returnVendor.getRefundAmount() != null |
| | | && returnVendor.getRefundAmount().compareTo(BigDecimal.ZERO) > 0) { |
| | | return returnVendor.getRefundAmount(); |
| | | } |
| | | if (returnVendor.getPurchaseOrderId() == null) { |
| | | throw exception(WM_RETURN_VENDOR_REFUND_AMOUNT_REQUIRED, |
| | | returnVendor.getCode(), "æªå
³èéè´è®¢å"); |
| | | } |
| | | List<ErpPurchaseOrderItemRespDTO> orderItems = purchaseOrderApi |
| | | .getPurchaseOrderItemList(returnVendor.getPurchaseOrderId()).getCheckedData(); |
| | | Map<Long, BigDecimal> priceMap = new HashMap<>(); |
| | | if (CollUtil.isNotEmpty(orderItems)) { |
| | | orderItems.stream().filter(item -> item.getProductId() != null) |
| | | .forEach(item -> priceMap.putIfAbsent(item.getProductId(), item.getProductPrice())); |
| | | } |
| | | List<MesWmReturnVendorLineDO> lines = returnVendorLineService.getReturnVendorLineListByReturnId(returnVendor.getId()); |
| | | if (CollUtil.isEmpty(lines)) { |
| | | throw exception(WM_RETURN_VENDOR_NO_LINE); |
| | | } |
| | | BigDecimal total = BigDecimal.ZERO; |
| | | for (MesWmReturnVendorLineDO line : lines) { |
| | | BigDecimal price = priceMap.get(line.getItemId()); |
| | | if (price == null) { |
| | | throw exception(WM_RETURN_VENDOR_REFUND_AMOUNT_REQUIRED, |
| | | returnVendor.getCode(), "ç©æID=" + line.getItemId() + " æªå¹é
å°éè´åä»·"); |
| | | } |
| | | BigDecimal quantity = line.getQuantity() != null ? line.getQuantity() : BigDecimal.ZERO; |
| | | total = total.add(price.multiply(quantity)); |
| | | } |
| | | if (total.compareTo(BigDecimal.ZERO) <= 0) { |
| | | throw exception(WM_RETURN_VENDOR_REFUND_AMOUNT_REQUIRED, |
| | | returnVendor.getCode(), "éè´åä»· à éè´§æ°éå计为 0"); |
| | | } |
| | | return total; |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éªéè´§ååå¨ä¸å·²å®æï¼è´¹ç¨ç±»æä½ä»
å¨å®æåéè´§å䏿§è¡ï¼ |
| | | */ |
| | | private MesWmReturnVendorDO validateReturnVendorFinished(Long id) { |
| | | MesWmReturnVendorDO returnVendor = validateReturnVendorExists(id); |
| | | if (!MesWmReturnVendorStatusEnum.FINISHED.getStatus().equals(returnVendor.getStatus())) { |
| | | throw exception(WM_RETURN_VENDOR_FINISHED_REQUIRED, returnVendor.getCode(), |
| | | resolveStatusName(returnVendor.getStatus())); |
| | | } |
| | | return returnVendor; |
| | | } |
| | | |
| | | /** |
| | | * ç¶æå¼è½¬åç§°ï¼è§£æå¤±è´¥åé为 ID å符串 |
| | | */ |
| | | private String resolveStatusName(Integer status) { |
| | | for (MesWmReturnVendorStatusEnum value : MesWmReturnVendorStatusEnum.values()) { |
| | | if (value.getStatus().equals(status)) { |
| | | return value.getName(); |
| | | } |
| | | } |
| | | return "ID=" + status; |
| | | } |
| | | |
| | | /** |
| | | * è·åå½åç¨æ·ç¼å·ï¼BPM æµç¨å起人ãè´¢å¡äººåï¼ |
| | | */ |
| | | private Long getCurrentUserId() { |
| | | Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); |
| | | if (authentication != null && authentication.getPrincipal() instanceof Long) { |
| | | return (Long) authentication.getPrincipal(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private void createTransactionList(MesWmReturnVendorDO returnVendor, List<MesWmReturnVendorDetailDO> details) { |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.wm.returnvendor.listener; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnvendor.MesWmReturnVendorMapper; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnVendorStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.service.wm.returnvendor.MesWmReturnVendorService; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * ä¾åºåéè´§å BPM 审æ¹ç¶æçå¬å¨ |
| | | * |
| | | * çå¬ BPM æµç¨å®ä¾ç¶æåæ´äºä»¶ï¼æ´æ°ä¾åºåéè´§åï¼å®¡æ¹æµç¨ï¼éè´ -> è´¨é -> ä»åºï¼ç审æ¹ç¶æ |
| | | */ |
| | | @Component |
| | | @Slf4j |
| | | public class MesWmReturnVendorStatusListener { |
| | | |
| | | @Resource |
| | | private MesWmReturnVendorService returnVendorService; |
| | | |
| | | @Resource |
| | | private MesWmReturnVendorMapper returnVendorMapper; |
| | | |
| | | @EventListener |
| | | public void onApplicationEvent(BpmProcessInstanceStatusEvent event) { |
| | | // 1. è§£æä¸å¡ä¸»é® |
| | | Long returnVendorId; |
| | | try { |
| | | returnVendorId = Long.parseLong(event.getBusinessKey()); |
| | | } catch (NumberFormatException e) { |
| | | log.warn("[onApplicationEvent] ä¸å¡ä¸»é®({}) 䏿¯ææçä¾åºåéè´§åç¼å·", event.getBusinessKey()); |
| | | return; |
| | | } |
| | | |
| | | // 2. æ ¡éªéè´§ååå¨ |
| | | MesWmReturnVendorDO returnVendor = returnVendorMapper.selectById(returnVendorId); |
| | | if (returnVendor == null) { |
| | | return; |
| | | } |
| | | |
| | | // 3. æ ¡éªæµç¨å®ä¾å¹é
ï¼é¿å
å
¶å®ä¸å¡çæµç¨åè°è¯¯æ´æ°æ¬åæ® |
| | | if (StrUtil.isBlank(returnVendor.getProcessInstanceId()) |
| | | || !returnVendor.getProcessInstanceId().equals(event.getId())) { |
| | | log.warn("[onApplicationEvent] éè´§å({}) çæµç¨å®ä¾({}) ä¸äºä»¶({}) ä¸å¹é
ï¼å¿½ç¥", |
| | | returnVendorId, returnVendor.getProcessInstanceId(), event.getId()); |
| | | return; |
| | | } |
| | | |
| | | // 4. æ ¡éªéè´§åç¶æä¸ºå®¡æ¹ä¸ |
| | | if (!MesWmReturnVendorStatusEnum.BPM_APPROVING.getStatus().equals(returnVendor.getStatus())) { |
| | | log.warn("[onApplicationEvent] éè´§å({}) ä¸å¤äºå®¡æ¹ä¸ç¶æï¼å½åç¶æï¼{}", returnVendorId, returnVendor.getStatus()); |
| | | return; |
| | | } |
| | | |
| | | // 5. æ´æ°éè´§å审æ¹ç¶æ |
| | | returnVendorService.updateReturnVendorAuditStatus(returnVendorId, event.getStatus()); |
| | | log.info("[onApplicationEvent] éè´§å({}) 审æ¹ç¶ææ´æ°å®æï¼BPM ç¶æï¼{}", returnVendorId, event.getStatus()); |
| | | } |
| | | |
| | | } |