refactor(erp): 采购申请与询价比价流程重构
- 采购申请支持由询价比价结果生成订单,新增 ErpPurchaseRequestApi 供跨模块调用
- 询价单增加审批流程与待处理列表相关字段
- 调整采购菜单排序,补充流程配置 SQL
Co-Authored-By: Claude Code <noreply@anthropic.com>
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- ============================================= |
| | | -- éè´ç³è¯·å»ä»·æ ¼ + 询价æ¯ä»· / éè´å°è´¦è¡æ¥æ¹é |
| | | -- ç®æ åºï¼mom-ntshï¼MySQL 8.4ï¼ |
| | | -- 说æï¼ |
| | | -- 1. éè´ç³è¯·ï¼è¡¨å¤´ + æç»ï¼ä¸åä¿åä»»ä½ä»·æ ¼å段ï¼ä»·æ ¼å¨è¯¢ä»·æéè´å°è´¦é¶æ®µç¡®å® |
| | | -- 2. éè´ç³è¯·å®¡æ¹éè¿åï¼ç±éè´åå³å®ãå起询价ãæãç´æ¥çæéè´å°è´¦ã |
| | | -- 3. èæ¬å¯é夿§è¡ï¼å å/å ååå
ç¨ information_schema 颿£æ¥ |
| | | -- 4. ä¸å
å« tenant_idï¼æ¬é¡¹ç®ä¸ä½¿ç¨å¤ç§æ·ï¼ |
| | | -- ============================================= |
| | | |
| | | -- --------------------------------------------- |
| | | -- ä¸ãå é¤éè´ç³è¯·è¡¨å¤´ä»·æ ¼å段 |
| | | -- --------------------------------------------- |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'erp_purchase_request' AND column_name = 'total_price'); |
| | | SET @sql = IF(@exists > 0, 'ALTER TABLE erp_purchase_request DROP COLUMN total_price', '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_request' AND column_name = 'total_product_price'); |
| | | SET @sql = IF(@exists > 0, 'ALTER TABLE erp_purchase_request DROP COLUMN total_product_price', '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_request' AND column_name = 'total_tax_price'); |
| | | SET @sql = IF(@exists > 0, 'ALTER TABLE erp_purchase_request DROP COLUMN total_tax_price', '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_request' AND column_name = 'discount_percent'); |
| | | SET @sql = IF(@exists > 0, 'ALTER TABLE erp_purchase_request DROP COLUMN discount_percent', '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_request' AND column_name = 'discount_price'); |
| | | SET @sql = IF(@exists > 0, 'ALTER TABLE erp_purchase_request DROP COLUMN discount_price', '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_request' AND column_name = 'deposit_price'); |
| | | SET @sql = IF(@exists > 0, 'ALTER TABLE erp_purchase_request DROP COLUMN deposit_price', '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_request_items' AND column_name = 'product_price'); |
| | | SET @sql = IF(@exists > 0, 'ALTER TABLE erp_purchase_request_items DROP COLUMN product_price', '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_request_items' AND column_name = 'total_price'); |
| | | SET @sql = IF(@exists > 0, 'ALTER TABLE erp_purchase_request_items DROP COLUMN total_price', '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_request_items' AND column_name = 'tax_percent'); |
| | | SET @sql = IF(@exists > 0, 'ALTER TABLE erp_purchase_request_items DROP COLUMN tax_percent', '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_request_items' AND column_name = 'tax_price'); |
| | | SET @sql = IF(@exists > 0, 'ALTER TABLE erp_purchase_request_items DROP COLUMN tax_price', '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_request' AND column_name = 'inquiry_id'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE erp_purchase_request ADD COLUMN inquiry_id BIGINT NULL COMMENT ''å
³è询价åç¼å·'' AFTER order_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_request' AND column_name = 'inquiry_no'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE erp_purchase_request ADD COLUMN inquiry_no VARCHAR(64) NULL COMMENT ''å
³è询价åå·'' AFTER inquiry_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 = 'srm_inquiry' AND column_name = 'purchase_request_id'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE srm_inquiry ADD COLUMN purchase_request_id BIGINT NULL COMMENT ''å
³èéè´ç³è¯·ç¼å·'' 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 = 'srm_inquiry' AND column_name = 'purchase_request_no'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE srm_inquiry ADD COLUMN purchase_request_no VARCHAR(64) NULL COMMENT ''å
³èéè´ç³è¯·åå·'' AFTER purchase_request_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 = 'erp_purchase_order' AND column_name = 'purchase_request_id'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE erp_purchase_order ADD COLUMN purchase_request_id BIGINT NULL COMMENT ''æ¥æºéè´ç³è¯·ç¼å·'' AFTER source_id', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| | | |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.statistics |
| | | WHERE table_schema = DATABASE() AND table_name = 'erp_purchase_order' AND index_name = 'idx_purchase_request_id'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE erp_purchase_order ADD INDEX idx_purchase_request_id (purchase_request_id)', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| | | |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.statistics |
| | | WHERE table_schema = DATABASE() AND table_name = 'srm_inquiry' AND index_name = 'idx_purchase_request_id'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE srm_inquiry ADD INDEX idx_purchase_request_id (purchase_request_id)', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- ============================================================================= |
| | | -- éè´ç®¡çèåæä¸å¡æµè½¬é¡ºåºéæ |
| | | -- ç®æ åºï¼mom-ntsh |
| | | -- 顺åºï¼éè´ç³è¯· â 询价æ¯ä»· â éè´å°è´¦ â éè´æ¥ç¥¨ â 仿¬¾ â ä¾åºå徿¥ â ä¾åºåæ¡£æ¡ |
| | | -- 说æï¼ä¾åºåæ¡£æ¡å±äºåºç¡æ¡£æ¡ï¼æ¾å¨ä¸å¡åæ®ä¹åã |
| | | -- ============================================================================= |
| | | |
| | | UPDATE system_menu |
| | | SET sort = CASE id |
| | | WHEN 602498 THEN 1 -- éè´ç³è¯· |
| | | WHEN 602620 THEN 2 -- 询价æ¯ä»· |
| | | WHEN 2666 THEN 3 -- éè´å°è´¦ |
| | | WHEN 1063110 THEN 4 -- éè´æ¥ç¥¨ |
| | | WHEN 1063116 THEN 5 -- 仿¬¾ |
| | | WHEN 602640 THEN 6 -- ä¾åºå徿¥ |
| | | WHEN 602525 THEN 7 -- ä¾åºåæ¡£æ¡ |
| | | END |
| | | WHERE id IN (602498, 602620, 2666, 1063110, 1063116, 602640, 602525) |
| | | AND deleted = 0; |
| | | |
| | | SELECT id, name, sort |
| | | FROM system_menu |
| | | WHERE parent_id = 2602 AND deleted = 0 |
| | | ORDER BY sort, id; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- ============================================================================= |
| | | -- è¡¥é¨ç½² SRM 询价åå®¡æ¹æµç¨ï¼srm_inquiry_approve |
| | | -- ç®æ åºï¼mom-ntsh |
| | | -- èæ¯ï¼SrmInquiryServiceImpl æäº¤å®¡æ ¸æ¶ä½¿ç¨æµç¨ key=srm_inquiry_approveï¼ |
| | | -- ä½ ACT_RE_PROCDEF ä¸ä¸åå¨è¯¥å®ä¹ï¼å端æäº¤æ¥ãæµç¨å®ä¹ä¸åå¨ãã |
| | | -- æ¹å¼ï¼å¤å¶éè´ç³è¯·å®¡æ¹ï¼purchase_request_approveï¼å起人 + è§è²1审æ¹ï¼æ¨¡æ¿ï¼ |
| | | -- ä»
æ¿æ¢ key 䏿¾ç¤ºåï¼ä¿æä¸éè´åæ®å®¡æ¹ä¸è´ç审æ¹äººé
ç½®ã |
| | | -- å¹çï¼key å·²åå¨åè·³è¿ï¼å¯é夿§è¡ã |
| | | -- ============================================================================= |
| | | |
| | | SET NAMES utf8mb4; |
| | | |
| | | -- æµç¨åç±»ï¼å¹çï¼ |
| | | INSERT INTO bpm_category (name, code, description, status, sort, creator, updater, deleted) |
| | | SELECT '询价å审æ¹', 'srm_inquiry_approve', '询价å审æ¹', 0, 23, '1', '1', b'0' |
| | | WHERE NOT EXISTS (SELECT 1 FROM bpm_category WHERE code = 'srm_inquiry_approve' AND deleted = b'0'); |
| | | |
| | | -- 审æ¹è¯¦æ
ä¸å¡ç»ä»¶ï¼å¹çï¼ï¼è®©å®¡æ¹è¯¦æ
页渲æè¯¢ä»·æç»èé空ç½éç¨è¡¨å |
| | | INSERT INTO bpm_business_attach |
| | | (process_definition_key, business_type, component_path, status, remark, creator, updater, deleted) |
| | | SELECT 'srm_inquiry_approve', 'srm_inquiry', '/srm/inquiry/detail/approve/index.vue', 0, |
| | | '询价å审æ¹ä¸å¡è¯¦æ
ç»ä»¶', '1', '1', b'0' |
| | | WHERE NOT EXISTS (SELECT 1 FROM bpm_business_attach |
| | | WHERE process_definition_key = 'srm_inquiry_approve' AND deleted = b'0'); |
| | | |
| | | DROP PROCEDURE IF EXISTS bpm_deploy_srm_inquiry_approve; |
| | | |
| | | DELIMITER $$ |
| | | |
| | | CREATE PROCEDURE bpm_deploy_srm_inquiry_approve() |
| | | label_deploy: BEGIN |
| | | DECLARE v_p_key VARCHAR(64) DEFAULT 'srm_inquiry_approve'; |
| | | DECLARE v_p_name VARCHAR(128) DEFAULT '询价å审æ¹'; |
| | | DECLARE v_p_category VARCHAR(64) DEFAULT 'srm_inquiry_approve'; |
| | | DECLARE v_tpl_key VARCHAR(64) DEFAULT 'purchase_request_approve'; |
| | | DECLARE v_exist INT DEFAULT 0; |
| | | DECLARE v_tpl_dep VARCHAR(64) DEFAULT NULL; |
| | | DECLARE v_tpl_name VARCHAR(255) DEFAULT NULL; |
| | | DECLARE v_dep VARCHAR(64); |
| | | DECLARE v_model_id VARCHAR(64); |
| | | DECLARE v_byte_id VARCHAR(64); |
| | | DECLARE v_procdef_id VARCHAR(64); |
| | | DECLARE v_meta TEXT; |
| | | DECLARE v_sort BIGINT; |
| | | DECLARE v_now DATETIME; |
| | | |
| | | DECLARE EXIT HANDLER FOR SQLEXCEPTION |
| | | BEGIN |
| | | ROLLBACK; |
| | | RESIGNAL; |
| | | END; |
| | | |
| | | SELECT COUNT(*) INTO v_exist FROM ACT_RE_PROCDEF WHERE KEY_ = v_p_key; |
| | | IF v_exist > 0 THEN |
| | | SELECT CONCAT('[SKIP] æµç¨å·²åå¨ï¼è·³è¿ï¼', v_p_key) AS deploy_result; |
| | | LEAVE label_deploy; |
| | | END IF; |
| | | |
| | | SELECT DEPLOYMENT_ID_ INTO v_tpl_dep FROM ACT_RE_PROCDEF |
| | | WHERE KEY_ = v_tpl_key ORDER BY VERSION_ DESC LIMIT 1; |
| | | SELECT NAME_ INTO v_tpl_name FROM ACT_RE_PROCDEF |
| | | WHERE KEY_ = v_tpl_key ORDER BY VERSION_ DESC LIMIT 1; |
| | | IF v_tpl_dep IS NULL THEN |
| | | SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'æ¨¡æ¿æµç¨ purchase_request_approve ä¸åå¨ï¼æ æ³å¤å¶'; |
| | | END IF; |
| | | |
| | | SET v_now = NOW(3); |
| | | SET v_sort = UNIX_TIMESTAMP(v_now) * 1000; |
| | | SET v_dep = REPLACE(UUID(), '-', ''); |
| | | SET v_model_id = REPLACE(UUID(), '-', ''); |
| | | SET v_byte_id = REPLACE(UUID(), '-', ''); |
| | | SET v_procdef_id = CONCAT(v_p_key, ':1:', v_dep); |
| | | |
| | | START TRANSACTION; |
| | | |
| | | -- 1) é¨ç½²è®°å½ |
| | | INSERT INTO ACT_RE_DEPLOYMENT |
| | | (ID_, NAME_, CATEGORY_, KEY_, TENANT_ID_, DEPLOY_TIME_, ENGINE_VERSION_) |
| | | VALUES |
| | | (v_dep, v_p_name, v_p_category, v_p_key, '', v_now, NULL); |
| | | |
| | | -- 2) BPMN åèï¼æ¿æ¢ key 䏿¾ç¤ºåï¼ |
| | | INSERT INTO ACT_GE_BYTEARRAY |
| | | (ID_, NAME_, DEPLOYMENT_ID_, BYTES_, GENERATED_) |
| | | SELECT |
| | | v_byte_id, |
| | | CONCAT(v_p_key, '.bpmn'), |
| | | v_dep, |
| | | CONVERT( |
| | | REPLACE( |
| | | REPLACE(CONVERT(BYTES_ USING utf8mb4), v_tpl_key, v_p_key), |
| | | v_tpl_name, v_p_name) |
| | | USING utf8mb4), |
| | | 0 |
| | | FROM ACT_GE_BYTEARRAY |
| | | WHERE DEPLOYMENT_ID_ = v_tpl_dep |
| | | AND NAME_ = CONCAT(v_tpl_key, '.bpmn'); |
| | | |
| | | -- 3) æµç¨å®ä¹ |
| | | INSERT INTO ACT_RE_PROCDEF |
| | | (ID_, REV_, CATEGORY_, NAME_, KEY_, VERSION_, DEPLOYMENT_ID_, RESOURCE_NAME_, |
| | | DGRM_RESOURCE_NAME_, DESCRIPTION_, HAS_START_FORM_KEY_, HAS_GRAPHICAL_NOTATION_, |
| | | SUSPENSION_STATE_, TENANT_ID_, ENGINE_VERSION_, DERIVED_VERSION_) |
| | | VALUES |
| | | (v_procdef_id, 1, v_p_category, v_p_name, v_p_key, 1, v_dep, CONCAT(v_p_key, '.bpmn'), |
| | | NULL, NULL, 0, 1, |
| | | 1, '', NULL, 0); |
| | | |
| | | -- 4) æµç¨æ¨¡å |
| | | SET v_meta = CONCAT( |
| | | '{"type":10,"formType":10,"sort":', v_sort, |
| | | ',"visible":true,"allowCancelRunningProcess":true,"allowWithdrawTask":false', |
| | | ',"autoApprovalType":0,"description":"","formCustomCreatePath":"","formCustomViewPath":"",', |
| | | '"formId":4,"managerUserIds":[],"startUserIds":[],"startDeptIds":[],"icon":null,', |
| | | '"processBeforeTriggerSetting":null,"processAfterTriggerSetting":null,', |
| | | '"taskBeforeTriggerSetting":null,"taskAfterTriggerSetting":null,', |
| | | '"printTemplateSetting":null,"summarySetting":null,"titleSetting":null,"processIdRule":null}'); |
| | | INSERT INTO ACT_RE_MODEL |
| | | (ID_, NAME_, KEY_, CATEGORY_, CREATE_TIME_, LAST_UPDATE_TIME_, VERSION_, META_INFO_, DEPLOYMENT_ID_, TENANT_ID_) |
| | | VALUES |
| | | (v_model_id, v_p_name, v_p_key, v_p_category, v_now, v_now, 1, v_meta, v_dep, ''); |
| | | |
| | | -- 5) æµç¨å®ä¹æ©å±ä¿¡æ¯ï¼éç¨å®¡æ¹è¡¨å id=4ï¼ |
| | | INSERT INTO bpm_process_definition_info |
| | | (process_definition_id, model_id, model_type, category, form_type, form_id, visible, sort, |
| | | allow_cancel_running_process, allow_withdraw_task, |
| | | creator, create_time, updater, update_time, deleted) |
| | | VALUES |
| | | (v_procdef_id, v_model_id, 10, v_p_category, 10, 4, 1, v_sort, |
| | | 1, 1, |
| | | '1', v_now, '1', v_now, 0); |
| | | |
| | | COMMIT; |
| | | |
| | | SELECT CONCAT('[OK] å·²é¨ç½²æ°å®¡æ ¸æµç¨ï¼', v_p_key, ' (procdef=', v_procdef_id, ')') AS deploy_result; |
| | | END$$ |
| | | |
| | | DELIMITER ; |
| | | |
| | | CALL bpm_deploy_srm_inquiry_approve(); |
| | | |
| | | -- æ ¡éª |
| | | SELECT p.KEY_, p.NAME_, p.VERSION_, p.SUSPENSION_STATE_ AS active_flag, |
| | | i.model_type, i.category, i.form_id |
| | | FROM ACT_RE_PROCDEF p |
| | | LEFT JOIN bpm_process_definition_info i ON i.process_definition_id = p.ID_ |
| | | WHERE p.KEY_ = 'srm_inquiry_approve'; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.api.purchase; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseRequestRespDTO; |
| | | |
| | | /** |
| | | * ERP éè´ç³è¯· API æ¥å£ |
| | | * |
| | | * ä¾ SRM çæ¨¡åå¨å®¡æ¹éè¿åå起询价ãååå°è´¦æ¶è°ç¨ã |
| | | */ |
| | | public interface ErpPurchaseRequestApi { |
| | | |
| | | String PREFIX = "/rpc-api/erp/purchase-request"; |
| | | |
| | | /** |
| | | * è·åéè´ç³è¯·ï¼å«æç»ï¼ |
| | | * |
| | | * @param id éè´ç³è¯·ç¼å· |
| | | * @return éè´ç³è¯· |
| | | */ |
| | | CommonResult<ErpPurchaseRequestRespDTO> getPurchaseRequest(Long id); |
| | | |
| | | /** |
| | | * ååéè´ç³è¯·å
³èç询价å |
| | | * |
| | | * @param id éè´ç³è¯·ç¼å· |
| | | * @param inquiryId 询价åç¼å· |
| | | * @param inquiryNo 询价åå· |
| | | * @return æ¯å¦æå |
| | | */ |
| | | CommonResult<Boolean> updatePurchaseRequestInquiry(Long id, Long inquiryId, String inquiryNo); |
| | | |
| | | /** |
| | | * æ¸
é¤éè´ç³è¯·å
³èç询价åï¼è¯¢ä»·åè¢«åæ¶/å é¤åï¼éè´åå¯éæ°éæ©å起询价æç´æ¥çæå°è´¦ï¼ |
| | | * |
| | | * @param id éè´ç³è¯·ç¼å· |
| | | * @return æ¯å¦æå |
| | | */ |
| | | CommonResult<Boolean> clearPurchaseRequestInquiry(Long id); |
| | | |
| | | /** |
| | | * ååéè´ç³è¯·å
³èçéè´å°è´¦ |
| | | * |
| | | * @param id éè´ç³è¯·ç¼å· |
| | | * @param orderId éè´å°è´¦ç¼å· |
| | | * @param orderNo éè´å°è´¦åå· |
| | | * @return æ¯å¦æå |
| | | */ |
| | | CommonResult<Boolean> updatePurchaseRequestOrder(Long id, Long orderId, String orderNo); |
| | | |
| | | } |
| | |
| | | @Schema(description = "æ¥æºåæ®ç¼å·", example = "1") |
| | | private Long sourceId; |
| | | |
| | | @Schema(description = "æ¥æºéè´ç³è¯·ç¼å·", example = "1") |
| | | private Long purchaseRequestId; |
| | | |
| | | @Schema(description = "夿³¨", example = "夿³¨ä¿¡æ¯") |
| | | private String remark; |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.api.purchase.dto; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * ERP éè´ç³è¯· Response DTO |
| | | * |
| | | * ä¾ SRM 询价æ¯ä»·ç模åéè¿ RPC 读åéè´ç³è¯·åå
¶æç»ã |
| | | */ |
| | | @Data |
| | | public class ErpPurchaseRequestRespDTO { |
| | | |
| | | /** |
| | | * ç¼å· |
| | | */ |
| | | private Long id; |
| | | |
| | | /** |
| | | * éè´ç³è¯·åå· |
| | | */ |
| | | private String no; |
| | | |
| | | /** |
| | | * ç¶æï¼0 æªæäº¤ 10 审æ¹ä¸ 20 å®¡æ ¸éè¿ 30 å®¡æ ¸ä¸éè¿ 40 已忶 |
| | | */ |
| | | private Integer status; |
| | | |
| | | /** |
| | | * ç³è¯·äººç¼å· |
| | | */ |
| | | private Long requestUserId; |
| | | |
| | | /** |
| | | * ç³è¯·é¨é¨ç¼å· |
| | | */ |
| | | private Long requestDeptId; |
| | | |
| | | /** |
| | | * ç³è¯·æ¶é´ |
| | | */ |
| | | private LocalDateTime requestTime; |
| | | |
| | | /** |
| | | * ç³è¯·çç± |
| | | */ |
| | | private String requestReason; |
| | | |
| | | /** |
| | | * ä¾åºåç¼å·ï¼å¯éï¼ |
| | | */ |
| | | private Long supplierId; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | /** |
| | | * å·²çæçéè´å°è´¦ç¼å· |
| | | */ |
| | | private Long orderId; |
| | | |
| | | /** |
| | | * å·²çæçéè´å°è´¦åå· |
| | | */ |
| | | private String orderNo; |
| | | |
| | | /** |
| | | * å·²åèµ·ç询价åç¼å· |
| | | */ |
| | | private Long inquiryId; |
| | | |
| | | /** |
| | | * å·²åèµ·ç询价åå· |
| | | */ |
| | | private String inquiryNo; |
| | | |
| | | /** |
| | | * ç³è¯·æç» |
| | | */ |
| | | private List<Item> items; |
| | | |
| | | @Data |
| | | public static class Item { |
| | | |
| | | /** |
| | | * æç»ç¼å· |
| | | */ |
| | | private Long id; |
| | | |
| | | /** |
| | | * 产åç¼å· |
| | | */ |
| | | private Long productId; |
| | | |
| | | /** |
| | | * 产ååä½ç¼å· |
| | | */ |
| | | private Long productUnitId; |
| | | |
| | | /** |
| | | * æ°é |
| | | */ |
| | | private BigDecimal count; |
| | | |
| | | /** |
| | | * éæ±æ¥æ |
| | | */ |
| | | private LocalDate demandTime; |
| | | |
| | | /** |
| | | * æ¯å¦éè¦æ¥ææ£éª |
| | | */ |
| | | private Boolean qcCheckFlag; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.api.purchase; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseRequestRespDTO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseRequestDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseRequestItemDO; |
| | | import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseRequestItemMapper; |
| | | import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseRequestMapper; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.util.List; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | |
| | | /** |
| | | * ERP éè´ç³è¯· API å®ç°ç±» |
| | | * |
| | | * ä¾ SRM 询价æ¯ä»·æ¨¡å读åéè´ç³è¯·ãåå询价åä¸éè´å°è´¦å
³èã |
| | | */ |
| | | @Service |
| | | @Validated |
| | | @Slf4j |
| | | public class ErpPurchaseRequestApiImpl implements ErpPurchaseRequestApi { |
| | | |
| | | @Resource |
| | | private ErpPurchaseRequestMapper purchaseRequestMapper; |
| | | @Resource |
| | | private ErpPurchaseRequestItemMapper purchaseRequestItemMapper; |
| | | |
| | | @Override |
| | | public CommonResult<ErpPurchaseRequestRespDTO> getPurchaseRequest(Long id) { |
| | | ErpPurchaseRequestDO request = purchaseRequestMapper.selectById(id); |
| | | if (request == null) { |
| | | return success(null); |
| | | } |
| | | List<ErpPurchaseRequestItemDO> items = purchaseRequestItemMapper.selectListByRequestId(id); |
| | | return success(BeanUtils.toBean(request, ErpPurchaseRequestRespDTO.class, resp -> resp |
| | | .setItems(BeanUtils.toBean(items, ErpPurchaseRequestRespDTO.Item.class)))); |
| | | } |
| | | |
| | | @Override |
| | | public CommonResult<Boolean> updatePurchaseRequestInquiry(Long id, Long inquiryId, String inquiryNo) { |
| | | purchaseRequestMapper.updateById(new ErpPurchaseRequestDO() |
| | | .setId(id) |
| | | .setInquiryId(inquiryId) |
| | | .setInquiryNo(inquiryNo)); |
| | | return success(true); |
| | | } |
| | | |
| | | @Override |
| | | public CommonResult<Boolean> clearPurchaseRequestInquiry(Long id) { |
| | | purchaseRequestMapper.update(null, new LambdaUpdateWrapper<ErpPurchaseRequestDO>() |
| | | .eq(ErpPurchaseRequestDO::getId, id) |
| | | .set(ErpPurchaseRequestDO::getInquiryId, null) |
| | | .set(ErpPurchaseRequestDO::getInquiryNo, null)); |
| | | return success(true); |
| | | } |
| | | |
| | | @Override |
| | | public CommonResult<Boolean> updatePurchaseRequestOrder(Long id, Long orderId, String orderNo) { |
| | | purchaseRequestMapper.updateById(new ErpPurchaseRequestDO() |
| | | .setId(id) |
| | | .setOrderId(orderId) |
| | | .setOrderNo(orderNo)); |
| | | return success(true); |
| | | } |
| | | |
| | | } |
| | |
| | | public void importTemplate(HttpServletResponse response) throws IOException { |
| | | List<ErpPurchaseRequestImportExcelVO> list = Arrays.asList( |
| | | ErpPurchaseRequestImportExcelVO.builder() |
| | | .no("CGSQ20260101000001").supplierName("示ä¾ä¾åºå") |
| | | .no("CGSQ20260101000001") |
| | | .requestTime("2026-01-01 10:00:00").requestReason("示ä¾ï¼ç产éè¦") |
| | | .productCode("ITEM001").productName("示ä¾äº§åA") |
| | | .count(new BigDecimal("100")).productPrice(new BigDecimal("10.00")) |
| | | .taxPercent(new BigDecimal("13")).demandTime("2026-01-10") |
| | | .qcCheckFlag("å¦").remark("示ä¾").build()); |
| | | .count(new BigDecimal("100")).demandTime("2026-01-10") |
| | | .remark("示ä¾").build()); |
| | | ExcelUtils.write(response, "éè´ç³è¯·å¯¼å
¥æ¨¡æ¿.xls", "éè´ç³è¯·", ErpPurchaseRequestImportExcelVO.class, list); |
| | | } |
| | | |
| | |
| | | @Schema(description = "æ¥æºåæ®ç¼å·", example = "48") |
| | | private Long sourceId; |
| | | |
| | | @Schema(description = "æ¥æºéè´ç³è¯·ç¼å·", example = "12") |
| | | private Long purchaseRequestId; |
| | | |
| | | @Schema(description = "æ¥æºç±»ååç§°", example = "ç产工å") |
| | | private String sourceTypeName; |
| | | |
| | |
| | | @Schema(description = "æ¥æºåæ®ç¼å·", example = "48") |
| | | private Long sourceId; |
| | | |
| | | @Schema(description = "æ¥æºéè´ç³è¯·ç¼å·", example = "1") |
| | | private Long purchaseRequestId; |
| | | |
| | | @Schema(description = "夿³¨", example = "ä½ ç") |
| | | private String remark; |
| | | |
| | |
| | | @Schema(description = "éè´ç³è¯·åå·ï¼ç空åèªå¨çæï¼ç¸åç¼å·çå¤è¡å并为åä¸å¼ ç³è¯·") |
| | | private String no; |
| | | |
| | | @ExcelProperty("ä¾åºååç§°") |
| | | @Schema(description = "ä¾åºååç§°ï¼å¯éï¼éä¸ç³»ç»å
ä¾åºååç§°æç¼ç ä¸è´ï¼") |
| | | private String supplierName; |
| | | |
| | | @ExcelProperty("ç³è¯·æ¶é´") |
| | | @Schema(description = "ç³è¯·æ¶é´ï¼æ ¼å¼å¦ 2026-01-01 10:00:00ï¼ç空åå½åæ¶é´", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private String requestTime; |
| | |
| | | @Schema(description = "äº§åæ°é", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private BigDecimal count; |
| | | |
| | | @ExcelProperty("åä»·") |
| | | @Schema(description = "产ååèåä»·ï¼ç空ååè¯¥ç©æçéè´ä»·") |
| | | private BigDecimal productPrice; |
| | | |
| | | @ExcelProperty("ç¨ç(%)") |
| | | @Schema(description = "ç¨çï¼ç¾åæ¯ï¼ä¾å¦ 13 表示 13%") |
| | | private BigDecimal taxPercent; |
| | | |
| | | @ExcelProperty("éæ±æ¥æ") |
| | | @Schema(description = "éæ±æ¥æï¼æ ¼å¼ yyyy-MM-dd") |
| | | private String demandTime; |
| | | |
| | | @ExcelProperty("æ¯å¦æ¥ææ£éª") |
| | | @Schema(description = "æ¯å¦éè¦æ¥ææ£éªï¼å¡«âæ¯â为éè¦ï¼å
¶å®ä¸ºä¸éè¦") |
| | | private String qcCheckFlag; |
| | | |
| | | @ExcelProperty("夿³¨") |
| | | @Schema(description = "夿³¨ï¼åä¸å¼ ç³è¯·åé¦è¡å¤æ³¨ä½ä¸ºæ´å夿³¨") |
| | |
| | | @Schema(description = "ä¾åºåç¼å·", example = "1") |
| | | private Long supplierId; |
| | | |
| | | @Schema(description = "å
³è询价åå·", example = "XJ2026110001") |
| | | private String inquiryNo; |
| | | |
| | | @Schema(description = "çæçéè´å°è´¦å·", example = "CGDD001") |
| | | private String orderNo; |
| | | |
| | | @Schema(description = "ç¶æ", example = "0") |
| | | private Integer status; |
| | | |
| | |
| | | @Schema(description = "å
¥åºç¶æï¼0:æªå
¥åº 1:é¨åå
¥åº 2:å
¨é¨å
¥åºï¼", example = "0") |
| | | private Integer inStatus; |
| | | |
| | | @Schema(description = "æ¯å¦æ¥è¯¢å¾
å¤çç³è¯·ï¼å®¡æ¹éè¿ä¸æªåèµ·è¯¢ä»·ãæªçæå°è´¦ï¼", example = "true") |
| | | private Boolean todo; |
| | | |
| | | } |
| | |
| | | @ExcelProperty("ä¾åºååç§°") |
| | | private String supplierName; |
| | | |
| | | @Schema(description = "å®ééé¢", example = "1000.00") |
| | | @ExcelProperty("å®ééé¢") |
| | | private BigDecimal depositPrice; |
| | | |
| | | @Schema(description = "å计æ°é", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("å计æ°é") |
| | | private BigDecimal totalCount; |
| | | |
| | | @Schema(description = "åè®¡ä»·æ ¼", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("åè®¡ä»·æ ¼") |
| | | private BigDecimal totalPrice; |
| | | |
| | | @Schema(description = "产ååç§°å表", example = "产åA,产åB") |
| | | @ExcelProperty("产ååç§°å表") |
| | |
| | | @Schema(description = "çæçéè´è®¢åå·", example = "CGDD001") |
| | | @ExcelProperty("éè´è®¢åå·") |
| | | private String orderNo; |
| | | |
| | | @Schema(description = "å
³è询价åç¼å·", example = "1") |
| | | @ExcelIgnore |
| | | private Long inquiryId; |
| | | |
| | | @Schema(description = "å
³è询价åå·", example = "XJ2026110001") |
| | | @ExcelProperty("询价åå·") |
| | | private String inquiryNo; |
| | | |
| | | @Schema(description = "å
¥åºç¶æ", example = "0") |
| | | @ExcelProperty(value = "å
¥åºç¶æ", converter = cn.iocoder.yudao.module.erp.convert.ErpPurchaseOrderInStatusConvert.class) |
| | |
| | | @Schema(description = "产ååä½åç§°", example = "个") |
| | | private String productUnitName; |
| | | |
| | | @Schema(description = "产ååèåä»·", example = "100.00") |
| | | private BigDecimal productPrice; |
| | | |
| | | @Schema(description = "æ°é", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") |
| | | private BigDecimal count; |
| | | |
| | | @Schema(description = "æ»ä»·", example = "1000.00") |
| | | private BigDecimal totalPrice; |
| | | |
| | | @Schema(description = "ç¨çï¼ç¾åæ¯", example = "13") |
| | | private BigDecimal taxPercent; |
| | | |
| | | @Schema(description = "ç¨é¢", example = "130.00") |
| | | private BigDecimal taxPrice; |
| | | |
| | | @Schema(description = "éæ±æ¥æ") |
| | | private LocalDate demandTime; |
| | |
| | | @Schema(description = "ç³è¯·çç±", example = "ç产éè¦") |
| | | private String requestReason; |
| | | |
| | | @Schema(description = "ä¾åºåç¼å·", example = "1") |
| | | @Schema(description = "ä¾åºåç¼å·ï¼å¯éï¼å®¡æ¹éè¿çæéè´å°è´¦æ¶å¯åéæ©ï¼", example = "1") |
| | | private Long supplierId; |
| | | |
| | | @Schema(description = "伿 çï¼ç¾åæ¯", example = "10") |
| | | private BigDecimal discountPercent; |
| | | |
| | | @Schema(description = "å®ééé¢", example = "1000.00") |
| | | private BigDecimal depositPrice; |
| | | |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | private String remark; |
| | |
| | | @NotNull(message = "产ååä½ä¸è½ä¸ºç©º") |
| | | private Long productUnitId; |
| | | |
| | | @Schema(description = "产ååèåä»·", example = "100.00") |
| | | private BigDecimal productPrice; |
| | | |
| | | @Schema(description = "æ°é", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") |
| | | @NotNull(message = "æ°éä¸è½ä¸ºç©º") |
| | | private BigDecimal count; |
| | | |
| | | @Schema(description = "ç¨çï¼ç¾åæ¯", example = "13") |
| | | private BigDecimal taxPercent; |
| | | |
| | | @Schema(description = "éæ±æ¥æ") |
| | | private LocalDate demandTime; |
| | |
| | | private Long sourceId; |
| | | |
| | | /** |
| | | * æ¥æºéè´ç³è¯·ç¼å· |
| | | * |
| | | * ä¸å¼ éè´ç³è¯·å¯è½å å¤ä¾åºå询价çæå¤å¼ éè´å°è´¦ï¼éè¿è¯¥å段å½é |
| | | */ |
| | | private Long purchaseRequestId; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | |
| | | private BigDecimal totalCount; |
| | | |
| | | /** |
| | | * åè®¡ä»·æ ¼ |
| | | */ |
| | | private BigDecimal totalPrice; |
| | | |
| | | /** |
| | | * å计产åä»·æ ¼ |
| | | */ |
| | | private BigDecimal totalProductPrice; |
| | | |
| | | /** |
| | | * å计ç¨é¢ |
| | | */ |
| | | private BigDecimal totalTaxPrice; |
| | | |
| | | /** |
| | | * 伿 çï¼ç¾åæ¯ |
| | | */ |
| | | private BigDecimal discountPercent; |
| | | |
| | | /** |
| | | * 伿 éé¢ |
| | | */ |
| | | private BigDecimal discountPrice; |
| | | |
| | | /** |
| | | * å®ééé¢ |
| | | */ |
| | | private BigDecimal depositPrice; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | |
| | | private String orderNo; |
| | | |
| | | /** |
| | | * å
³èç询价åç¼å· |
| | | */ |
| | | private Long inquiryId; |
| | | |
| | | /** |
| | | * å
³èç询价åå· |
| | | */ |
| | | private String inquiryNo; |
| | | |
| | | /** |
| | | * å
¥åºç¶æ |
| | | * |
| | | * 0: æªå
¥åº |
| | |
| | | private Long productUnitId; |
| | | |
| | | /** |
| | | * 产ååèåä»· |
| | | */ |
| | | private BigDecimal productPrice; |
| | | |
| | | /** |
| | | * æ°é |
| | | */ |
| | | private BigDecimal count; |
| | | |
| | | /** |
| | | * æ»ä»· |
| | | */ |
| | | private BigDecimal totalPrice; |
| | | |
| | | /** |
| | | * ç¨çï¼ç¾åæ¯ |
| | | */ |
| | | private BigDecimal taxPercent; |
| | | |
| | | /** |
| | | * ç¨é¢ |
| | | */ |
| | | private BigDecimal taxPrice; |
| | | |
| | | /** |
| | | * éæ±æ¥æ |
| | |
| | | } |
| | | |
| | | default PageResult<ErpPurchaseRequestDO> selectPage(ErpPurchaseRequestPageReqVO pageReqVO) { |
| | | return selectPage(pageReqVO, new LambdaQueryWrapperX<ErpPurchaseRequestDO>() |
| | | LambdaQueryWrapperX<ErpPurchaseRequestDO> wrapper = new LambdaQueryWrapperX<ErpPurchaseRequestDO>() |
| | | .likeIfPresent(ErpPurchaseRequestDO::getNo, pageReqVO.getNo()) |
| | | .eqIfPresent(ErpPurchaseRequestDO::getRequestUserId, pageReqVO.getRequestUserId()) |
| | | .eqIfPresent(ErpPurchaseRequestDO::getRequestDeptId, pageReqVO.getRequestDeptId()) |
| | | .eqIfPresent(ErpPurchaseRequestDO::getSupplierId, pageReqVO.getSupplierId()) |
| | | .likeIfPresent(ErpPurchaseRequestDO::getInquiryNo, pageReqVO.getInquiryNo()) |
| | | .likeIfPresent(ErpPurchaseRequestDO::getOrderNo, pageReqVO.getOrderNo()) |
| | | .eqIfPresent(ErpPurchaseRequestDO::getStatus, pageReqVO.getStatus()) |
| | | .eqIfPresent(ErpPurchaseRequestDO::getInStatus, pageReqVO.getInStatus()) |
| | | .betweenIfPresent(ErpPurchaseRequestDO::getRequestTime, pageReqVO.getRequestTime()) |
| | | .orderByDesc(ErpPurchaseRequestDO::getId)); |
| | | .betweenIfPresent(ErpPurchaseRequestDO::getRequestTime, pageReqVO.getRequestTime()); |
| | | // å¾
å¤çï¼å®¡æ¹éè¿åï¼å°æªå起询价ãä¹å°æªçæéè´å°è´¦ |
| | | if (Boolean.TRUE.equals(pageReqVO.getTodo())) { |
| | | wrapper.isNull(ErpPurchaseRequestDO::getInquiryId) |
| | | .isNull(ErpPurchaseRequestDO::getOrderId); |
| | | } |
| | | wrapper.orderByDesc(ErpPurchaseRequestDO::getId); |
| | | return selectPage(pageReqVO, wrapper); |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | WORK_ORDER(1, "ç产工å"), |
| | | SRM_INQUIRY(2, "SRM询价"), |
| | | SALE_ORDER(3, "éå®è®¢å"); |
| | | SALE_ORDER(3, "éå®è®¢å"), |
| | | PURCHASE_REQUEST(4, "éè´ç³è¯·"); |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()) |
| | | .map(ErpPurchaseOrderSourceTypeEnum::getType).toArray(Integer[]::new); |
| | |
| | | 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 ç©ææ¡£æ¡è¡¥å
ç¼ç ååä¿å"); |
| | | ErrorCode PURCHASE_ORDER_SUBMIT_SUPPLIER_REQUIRED = new ErrorCode(1_030_101_019, "æäº¤å®¡æ¹å¤±è´¥ï¼éè´å°è´¦({})æªå¡«åä¾åºåï¼è¯·å
ç¼è¾å°è´¦éæ©ä¾åºåååæäº¤"); |
| | | ErrorCode PURCHASE_ORDER_SUBMIT_PRICE_REQUIRED = new ErrorCode(1_030_101_020, "æäº¤å®¡æ¹å¤±è´¥ï¼æç»ç©æ[{}]çå价为[{}]ï¼è¯·å
å¨éè´å°è´¦æç»ä¸è¡¥å½å«ç¨åä»·ï¼å¤§äº 0ï¼ååæäº¤"); |
| | | ErrorCode PURCHASE_ORDER_SUBMIT_ITEM_REQUIRED = new ErrorCode(1_030_101_021, "æäº¤å®¡æ¹å¤±è´¥ï¼éè´å°è´¦({})没æç©ææç»ï¼è¯·å
è¡¥å
æç»ååæäº¤"); |
| | | |
| | | // ========== ERP éè´å
¥åºï¼1-030-102-000ï¼ ========== |
| | | ErrorCode PURCHASE_IN_NOT_EXISTS = new ErrorCode(1_030_102_000, "éè´å
¥åºåä¸åå¨"); |
| | |
| | | ErrorCode PURCHASE_REQUEST_BPM_CATEGORY_NOT_EXISTS = new ErrorCode(1_030_104_008, "éè´ç³è¯·å®¡æ¹åç±»ä¸åå¨ï¼è¯·å
å¨BPM模åå建éè´ç³è¯·å®¡æ¹æµç¨åç±»"); |
| | | ErrorCode PURCHASE_REQUEST_BPM_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_030_104_009, "éè´ç³è¯·å®¡æ¹åç±»ä¸æ²¡æå¯ç¨çæµç¨æ¨¡åï¼è¯·å
å建并å叿µç¨"); |
| | | ErrorCode PURCHASE_REQUEST_RESET_FAIL_NOT_REJECT = new ErrorCode(1_030_104_010, "é置失败ï¼åªæé©³åç¶æçéè´ç³è¯·åæè½éç½®"); |
| | | ErrorCode PURCHASE_REQUEST_SUPPLIER_REQUIRED = new ErrorCode(1_030_104_011, "éè´ç³è¯·åæªæå®ä¾åºåï¼æ æ³çæéè´è®¢åï¼è¯·å
ç¼è¾ç³è¯·åè¡¥å
ä¾åºå"); |
| | | ErrorCode PURCHASE_REQUEST_INQUIRY_EXISTS = new ErrorCode(1_030_104_012, "éè´ç³è¯·åå·²å起询价æ¯ä»·ï¼è¯·çå¾
询价确认ååçæéè´å°è´¦"); |
| | | |
| | | // ========== ERP éè´æ¥ç¥¨ï¼1-030-105-000ï¼ ========== |
| | | ErrorCode PURCHASE_INVOICE_NOT_EXISTS = new ErrorCode(1_030_105_000, "æ¥ç¥¨ä¸åå¨"); |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æäº¤å®¡æ¹åæ ¡éªéè´å°è´¦æ°æ®æ¯å¦å·²è¡¥é½ |
| | | * |
| | | * <p>éè´ç³è¯·ç´æ¥çæçå°è´¦åªæç©æä¸æ°éï¼é¶éé¢ãæ ä¾åºåï¼ï¼ |
| | | * éè´åéè¦å¨å°è´¦éè¡¥å½ä¾åºåãåä»·ã仿¬¾æ¥æåæè½æäº¤å®¡æ¹ãéé¡¹æ ¡éªï¼å½ä¸ç¬¬ä¸å¤å³æç¤ºå
·ä½æä¹æ¹ã</p> |
| | | * |
| | | * @param purchaseOrder éè´å°è´¦ |
| | | */ |
| | | private void validatePurchaseOrderReadyForSubmit(ErpPurchaseOrderDO purchaseOrder) { |
| | | // 2.1 ä¾åºåå¿
é |
| | | if (purchaseOrder.getSupplierId() == null) { |
| | | throw exception(PURCHASE_ORDER_SUBMIT_SUPPLIER_REQUIRED, purchaseOrder.getNo()); |
| | | } |
| | | // 2.2 仿¬¾æ¥æå¿
éï¼éè´ç³è¯·èªå¨çæçèç¨¿è®¢åæ²¡æä»æ¬¾æ¥æ |
| | | if (purchaseOrder.getPaymentDate() == null) { |
| | | throw exception(PURCHASE_ORDER_PAYMENT_DATE_REQUIRED); |
| | | } |
| | | // 2.3 æç»åä»·å¿
须补å½ï¼å¤§äº 0ï¼ |
| | | List<ErpPurchaseOrderItemDO> items = purchaseOrderItemMapper.selectListByOrderId(purchaseOrder.getId()); |
| | | if (CollUtil.isEmpty(items)) { |
| | | throw exception(PURCHASE_ORDER_SUBMIT_ITEM_REQUIRED, purchaseOrder.getNo()); |
| | | } |
| | | Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap( |
| | | convertSet(items, ErpPurchaseOrderItemDO::getProductId)); |
| | | for (ErpPurchaseOrderItemDO item : items) { |
| | | BigDecimal productPrice = item.getProductPrice(); |
| | | if (productPrice != null && productPrice.compareTo(BigDecimal.ZERO) > 0) { |
| | | continue; |
| | | } |
| | | MdmItemRespDTO itemDTO = itemMap.get(item.getProductId()); |
| | | String itemName = itemDTO != null && StrUtil.isNotBlank(itemDTO.getName()) |
| | | ? itemDTO.getName() : "ID=" + item.getProductId(); |
| | | throw exception(PURCHASE_ORDER_SUBMIT_PRICE_REQUIRED, itemName, |
| | | productPrice == null ? "æªå¡«å" : productPrice.toPlainString()); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void submitPurchaseOrder(Long id, String processDefinitionKey, Long userId) { |
| | |
| | | if (!submitable) { |
| | | throw exception(PURCHASE_ORDER_SUBMIT_FAIL_STATUS); |
| | | } |
| | | // 2. 仿¬¾æ¥æå¿
éï¼éè´ç³è¯·èªå¨çæçèç¨¿è®¢åæ²¡æä»æ¬¾æ¥æï¼æäº¤åå¿
é¡»å
ç¼è¾è¡¥é½ |
| | | if (purchaseOrder.getPaymentDate() == null) { |
| | | throw exception(PURCHASE_ORDER_PAYMENT_DATE_REQUIRED); |
| | | } |
| | | // 2. æäº¤åæ ¡éªå°è´¦æ°æ®å·²è¡¥é½ï¼éè´ç³è¯·ç´æ¥çæçèç¨¿åªæç©æä¸æ°éï¼ |
| | | // ä¾åºåãåä»·çéè¦éè´åå¨å°è´¦ä¸è¡¥å½åæè½æäº¤å®¡æ¹ |
| | | validatePurchaseOrderReadyForSubmit(purchaseOrder); |
| | | |
| | | // 3. å建 BPM æµç¨å®ä¾ |
| | | // å
¨å±å
审æ¹ï¼ä¸å¡æ ¡éªéè¿åç´æ¥æ§è¡å®¡æ¹éè¿é»è¾ï¼æ éæµç¨æ¨¡åã |
| | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils; |
| | | import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; |
| | |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; |
| | | import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; |
| | | import cn.iocoder.yudao.module.erp.enums.ErpPurchaseOrderSourceTypeEnum; |
| | | import cn.iocoder.yudao.module.erp.enums.ErpPurchaseRequestStatusEnum; |
| | | import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi; |
| | | import cn.iocoder.yudao.module.srm.api.supplier.dto.SrmSupplierRespDTO; |
| | | import cn.iocoder.yudao.module.system.api.dept.DeptApi; |
| | | import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi; |
| | | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| | |
| | | @Resource |
| | | private ErpSupplierService supplierService; |
| | | @Resource |
| | | private SrmSupplierApi srmSupplierApi; |
| | | @Resource |
| | | private MdmItemApi mdmItemApi; |
| | | |
| | | @Resource |
| | |
| | | .setStatus(ErpPurchaseRequestStatusEnum.DRAFT.getStatus()) |
| | | .setRequestUserId(userId) |
| | | .setRequestDeptId(deptId)); |
| | | calculateTotalPrice(purchaseRequest, requestItems); |
| | | calculateTotalCount(purchaseRequest, requestItems); |
| | | purchaseRequestMapper.insert(purchaseRequest); |
| | | |
| | | // 6. ç»å®éä»¶ |
| | |
| | | |
| | | // 4. æ´æ°ç³è¯·å |
| | | ErpPurchaseRequestDO updateObj = BeanUtils.toBean(updateReqVO, ErpPurchaseRequestDO.class); |
| | | calculateTotalPrice(updateObj, requestItems); |
| | | calculateTotalCount(updateObj, requestItems); |
| | | purchaseRequestMapper.updateById(updateObj); |
| | | |
| | | // 5. æ´æ°ç³è¯·æç» |
| | |
| | | return respVO; |
| | | } |
| | | |
| | | // 1. é¢çâä¾åºååç§°/ç¼ç -> ä¾åºåç¼å·âæ å°ï¼ä¾åºå为å¯éï¼ |
| | | Map<String, Long> supplierIdMap = new HashMap<>(); |
| | | CommonResult<List<SrmSupplierRespDTO>> supplierResult = srmSupplierApi.getSupplierSimpleList(); |
| | | if (supplierResult != null && CollUtil.isNotEmpty(supplierResult.getData())) { |
| | | supplierResult.getData().forEach(supplier -> { |
| | | if (StrUtil.isNotBlank(supplier.getName())) { |
| | | supplierIdMap.putIfAbsent(supplier.getName().trim(), supplier.getId()); |
| | | } |
| | | if (StrUtil.isNotBlank(supplier.getCode())) { |
| | | supplierIdMap.putIfAbsent(supplier.getCode().trim(), supplier.getId()); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | // 2. æâéè´ç³è¯·åå·âåç» |
| | | // 1. æâéè´ç³è¯·åå·âåç» |
| | | Map<String, List<ErpPurchaseRequestImportExcelVO>> groups = new LinkedHashMap<>(); |
| | | for (int i = 0; i < importList.size(); i++) { |
| | | ErpPurchaseRequestImportExcelVO row = importList.get(i); |
| | | if (row == null || (StrUtil.isBlank(row.getProductCode()) && StrUtil.isBlank(row.getSupplierName()) |
| | | && StrUtil.isBlank(row.getNo()))) { |
| | | if (row == null || (StrUtil.isBlank(row.getProductCode()) && StrUtil.isBlank(row.getNo()))) { |
| | | continue; // è·³è¿ç©ºè¡ |
| | | } |
| | | String key = StrUtil.isNotBlank(row.getNo()) ? row.getNo().trim() : "__row_" + (i + 2); |
| | | groups.computeIfAbsent(key, k -> new ArrayList<>()).add(row); |
| | | } |
| | | |
| | | // 3. éå¼ ç³è¯·å¯¼å
¥ |
| | | // 2. éå¼ ç³è¯·å¯¼å
¥ |
| | | for (Map.Entry<String, List<ErpPurchaseRequestImportExcelVO>> entry : groups.entrySet()) { |
| | | List<ErpPurchaseRequestImportExcelVO> rows = entry.getValue(); |
| | | String label = StrUtil.isNotBlank(rows.get(0).getNo()) ? rows.get(0).getNo().trim() |
| | | : "第 " + entry.getKey().substring("__row_".length()) + " è¡"; |
| | | try { |
| | | ErpPurchaseRequestDO purchaseRequest = createPurchaseRequestByImport(rows, supplierIdMap); |
| | | ErpPurchaseRequestDO purchaseRequest = createPurchaseRequestByImport(rows); |
| | | respVO.getCreateList().add(purchaseRequest.getNo()); |
| | | } catch (Exception ex) { |
| | | respVO.getFailureList().put(label, resolveImportErrorMessage(ex)); |
| | |
| | | /** |
| | | * 便®å¯¼å
¥æ°æ®å建ä¸å¼ éè´ç³è¯·ï¼å«æç»ï¼ãç³è¯·äºº/ç³è¯·é¨é¨ç±å½åç»å½ç¨æ·èªå¨å¡«å
ï¼ç¶æä¸ºâæªæäº¤(0)âã |
| | | */ |
| | | private ErpPurchaseRequestDO createPurchaseRequestByImport(List<ErpPurchaseRequestImportExcelVO> rows, |
| | | Map<String, Long> supplierIdMap) { |
| | | private ErpPurchaseRequestDO createPurchaseRequestByImport(List<ErpPurchaseRequestImportExcelVO> rows) { |
| | | ErpPurchaseRequestImportExcelVO head = rows.get(0); |
| | | |
| | | // 1. ä¾åºåï¼å¯éï¼ï¼å¡«äºåæåç§°/ç¼ç å¹é
å¹¶æ ¡éª |
| | | Long supplierId = null; |
| | | if (StrUtil.isNotBlank(head.getSupplierName())) { |
| | | supplierId = supplierIdMap.get(head.getSupplierName().trim()); |
| | | if (supplierId == null) { |
| | | throw new IllegalArgumentException("ä¾åºåä¸åå¨ï¼" + head.getSupplierName()); |
| | | } |
| | | supplierService.validateSupplier(supplierId); |
| | | } |
| | | |
| | | // 2. æç» |
| | | // 1. æç» |
| | | List<ErpPurchaseRequestSaveReqVO.Item> items = new ArrayList<>(); |
| | | for (ErpPurchaseRequestImportExcelVO row : rows) { |
| | | if (StrUtil.isBlank(row.getProductCode())) { |
| | |
| | | ErpPurchaseRequestSaveReqVO.Item itemVO = new ErpPurchaseRequestSaveReqVO.Item(); |
| | | itemVO.setProductId(item.getId()); |
| | | itemVO.setProductUnitId(item.getUnitMeasureId()); |
| | | // åä»·ï¼æªå¡«åæ¶åç©æçéè´ä»· |
| | | itemVO.setProductPrice(row.getProductPrice() != null ? row.getProductPrice() |
| | | : (item.getPurchasePrice() != null ? item.getPurchasePrice() : BigDecimal.ZERO)); |
| | | itemVO.setCount(row.getCount()); |
| | | itemVO.setTaxPercent(row.getTaxPercent()); |
| | | itemVO.setDemandTime(parseImportDate(row.getDemandTime())); |
| | | itemVO.setQcCheckFlag("æ¯".equals(StrUtil.trim(row.getQcCheckFlag()))); |
| | | itemVO.setRemark(row.getRemark()); |
| | | items.add(itemVO); |
| | | } |
| | |
| | | // 5. ç»è£
主表ï¼ç¶æä¸ºâæªæäº¤âï¼ |
| | | ErpPurchaseRequestDO purchaseRequest = new ErpPurchaseRequestDO(); |
| | | purchaseRequest.setNo(no); |
| | | purchaseRequest.setSupplierId(supplierId); |
| | | purchaseRequest.setRequestTime(parseImportDateTime(head.getRequestTime())); |
| | | purchaseRequest.setRequestReason(head.getRequestReason()); |
| | | purchaseRequest.setRemark(head.getRemark()); |
| | | purchaseRequest.setStatus(ErpPurchaseRequestStatusEnum.DRAFT.getStatus()); |
| | | purchaseRequest.setRequestUserId(userId); |
| | | purchaseRequest.setRequestDeptId(deptId); |
| | | purchaseRequest.setDepositPrice(BigDecimal.ZERO); |
| | | |
| | | List<ErpPurchaseRequestItemDO> itemDOs = validatePurchaseRequestItems(items); |
| | | calculateTotalPrice(purchaseRequest, itemDOs); |
| | | calculateTotalCount(purchaseRequest, itemDOs); |
| | | purchaseRequestMapper.insert(purchaseRequest); |
| | | itemDOs.forEach(item -> item.setRequestId(purchaseRequest.getId())); |
| | | purchaseRequestItemMapper.insertBatch(itemDOs); |
| | |
| | | return StrUtil.blankToDefault(ex.getMessage(), "导å
¥å¤±è´¥"); |
| | | } |
| | | |
| | | private void calculateTotalPrice(ErpPurchaseRequestDO purchaseRequest, List<ErpPurchaseRequestItemDO> requestItems) { |
| | | private void calculateTotalCount(ErpPurchaseRequestDO purchaseRequest, List<ErpPurchaseRequestItemDO> requestItems) { |
| | | purchaseRequest.setTotalCount(getSumValue(requestItems, ErpPurchaseRequestItemDO::getCount, BigDecimal::add)); |
| | | purchaseRequest.setTotalProductPrice(getSumValue(requestItems, ErpPurchaseRequestItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO)); |
| | | purchaseRequest.setTotalTaxPrice(getSumValue(requestItems, ErpPurchaseRequestItemDO::getTaxPrice, BigDecimal::add, BigDecimal.ZERO)); |
| | | // å价为å«ç¨åä»·ï¼ä»·ç¨å计 = åä»· * æ°éï¼ç¨é¢å·²å
å«å¨åä»·ä¸ï¼ä¸åé¢å¤å ç¨ |
| | | purchaseRequest.setTotalPrice(purchaseRequest.getTotalProductPrice()); |
| | | // 计ç®ä¼æ ä»·æ ¼ |
| | | if (purchaseRequest.getDiscountPercent() == null) { |
| | | purchaseRequest.setDiscountPercent(BigDecimal.ZERO); |
| | | } |
| | | purchaseRequest.setDiscountPrice(MoneyUtils.priceMultiplyPercent(purchaseRequest.getTotalPrice(), purchaseRequest.getDiscountPercent())); |
| | | purchaseRequest.setTotalPrice(purchaseRequest.getTotalPrice().subtract(purchaseRequest.getDiscountPrice())); |
| | | } |
| | | |
| | | private List<ErpPurchaseRequestItemDO> validatePurchaseRequestItems(List<ErpPurchaseRequestSaveReqVO.Item> list) { |
| | | return convertList(list, o -> BeanUtils.toBean(o, ErpPurchaseRequestItemDO.class, item -> { |
| | | if (item.getProductPrice() != null && item.getCount() != null) { |
| | | item.setTotalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount())); |
| | | if (item.getTaxPercent() != null) { |
| | | // å价为å«ç¨åä»·ï¼ç¨é¢ä»ä»·ç¨å计ä¸åç®ï¼è䏿¯å¨å计ä¸åå ç¨ |
| | | item.setTaxPrice(MoneyUtils.taxPriceIncluded(item.getTotalPrice(), item.getTaxPercent())); |
| | | } |
| | | return convertList(list, o -> { |
| | | ErpPurchaseRequestItemDO item = BeanUtils.toBean(o, ErpPurchaseRequestItemDO.class); |
| | | // éè´ç³è¯·ä¸åå¡«åâæ¯å¦è´¨æ£âï¼é»è®¤éè¦æ¥ææ£éªï¼çæå°è´¦åå¯å¨å°è´¦ä¸è°æ´ |
| | | if (item.getQcCheckFlag() == null) { |
| | | item.setQcCheckFlag(true); |
| | | } |
| | | })); |
| | | return item; |
| | | }); |
| | | } |
| | | |
| | | private void updatePurchaseRequestItemList(Long id, List<ErpPurchaseRequestItemDO> newList) { |
| | |
| | | } |
| | | |
| | | // 2. æ ¹æ®å®¡æ¹ç»ææ´æ°ç¶æ |
| | | // 审æ¹éè¿åä¸èªå¨çæéè´å°è´¦ï¼ç±éè´åå¨å表ä¸å³å®ãå起询价ãæãç´æ¥çæéè´å°è´¦ã |
| | | Integer newStatus = convertBpmResultToStatus(bpmResult); |
| | | if (newStatus != null) { |
| | | purchaseRequestMapper.updateById(new ErpPurchaseRequestDO() |
| | | .setId(id).setStatus(newStatus)); |
| | | } |
| | | |
| | | // 3. 审æ¹éè¿ä¸æä¾åºåï¼èªå¨çæéè´è®¢å |
| | | if (ErpPurchaseRequestStatusEnum.APPROVE.getStatus().equals(newStatus) |
| | | && purchaseRequest.getSupplierId() != null |
| | | && purchaseRequest.getOrderId() == null) { |
| | | try { |
| | | Long orderId = doGeneratePurchaseOrder(purchaseRequest); |
| | | log.info("[updatePurchaseRequestAuditStatus] éè´ç³è¯·({}) èªå¨çæéè´è®¢å({})", id, orderId); |
| | | } catch (Exception e) { |
| | | log.error("[updatePurchaseRequestAuditStatus] éè´ç³è¯·({}) èªå¨çæéè´è®¢å失败", id, e); |
| | | // 䏿åºå¼å¸¸ï¼é¿å
å½±åç¶ææ´æ° |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | if (purchaseRequest.getOrderId() != null) { |
| | | throw exception(PURCHASE_REQUEST_ORDER_EXISTS); |
| | | } |
| | | // 3. ä¾åºå以éè´ç³è¯·å为åï¼ç³è¯·æäº¤æ¶å·²ç»éè¿ä¾åºåï¼çæè®¢åä¸åè¦æ±éæ°éæ© |
| | | // å
¼å®¹æ§è°ç¨æ¹ä»æ¾å¼ä¼ supplierId çæ
åµï¼ä¼ äºåä»¥ä¼ å
¥å¼ä¸ºå |
| | | Long targetSupplierId = supplierId != null ? supplierId : purchaseRequest.getSupplierId(); |
| | | if (targetSupplierId == null) { |
| | | throw exception(PURCHASE_REQUEST_SUPPLIER_REQUIRED); |
| | | // 3. å·²å起询价çç³è¯·ï¼å¿
é¡»ç询价确认ï¼ç¡®å®ä»·æ ¼ï¼åæè½çæéè´å°è´¦ |
| | | if (purchaseRequest.getInquiryId() != null) { |
| | | throw exception(PURCHASE_REQUEST_INQUIRY_EXISTS); |
| | | } |
| | | supplierService.validateSupplier(targetSupplierId); |
| | | // 4. ä¾åºåä¸å¨è¿éç¡®å®ï¼éè´ç³è¯·æ¬èº«ä¸å¡«ä¾åºåï¼ç´æ¥çæå°è´¦æ¶ä¹å
è®¸ä¸ºç©ºï¼ |
| | | // ç±éè´åå¨éè´å°è´¦è稿éè¡¥å
ä¾åºåä¸ä»·æ ¼ååæäº¤å®¡æ¹ |
| | | Long targetSupplierId = supplierId != null ? supplierId : purchaseRequest.getSupplierId(); |
| | | if (targetSupplierId != null) { |
| | | supplierService.validateSupplier(targetSupplierId); |
| | | } |
| | | |
| | | // 4. 设置ä¾åºåå¹¶çæè®¢å |
| | | // 5. çæè®¢åï¼supplierId å¯ä¸ºç©ºï¼çå¾
å°è´¦è¡¥å
ï¼ |
| | | purchaseRequest.setSupplierId(targetSupplierId); |
| | | return doGeneratePurchaseOrder(purchaseRequest); |
| | | } |
| | |
| | | purchaseOrder.setSupplierId(purchaseRequest.getSupplierId()); |
| | | purchaseOrder.setOrderTime(purchaseRequest.getRequestTime()); |
| | | purchaseOrder.setTotalCount(purchaseRequest.getTotalCount()); |
| | | purchaseOrder.setTotalPrice(purchaseRequest.getTotalPrice()); |
| | | purchaseOrder.setTotalProductPrice(purchaseRequest.getTotalProductPrice()); |
| | | purchaseOrder.setTotalTaxPrice(purchaseRequest.getTotalTaxPrice()); |
| | | purchaseOrder.setDiscountPercent(purchaseRequest.getDiscountPercent()); |
| | | purchaseOrder.setDiscountPrice(purchaseRequest.getDiscountPrice()); |
| | | purchaseOrder.setDepositPrice(purchaseRequest.getDepositPrice() != null ? purchaseRequest.getDepositPrice() : BigDecimal.ZERO); |
| | | // éè´ç³è¯·ä¸å«ä»·æ ¼ï¼å°è´¦å
以 0 éé¢çæè稿ï¼ç±éè´åå¨å°è´¦ä¸è¡¥å½åä»·/ç¨çååæäº¤å®¡æ¹ |
| | | purchaseOrder.setTotalPrice(BigDecimal.ZERO); |
| | | purchaseOrder.setTotalProductPrice(BigDecimal.ZERO); |
| | | purchaseOrder.setTotalTaxPrice(BigDecimal.ZERO); |
| | | purchaseOrder.setDiscountPercent(BigDecimal.ZERO); |
| | | purchaseOrder.setDiscountPrice(BigDecimal.ZERO); |
| | | purchaseOrder.setDepositPrice(BigDecimal.ZERO); |
| | | purchaseOrder.setSourceType(ErpPurchaseOrderSourceTypeEnum.PURCHASE_REQUEST.getType()); |
| | | purchaseOrder.setSourceId(purchaseRequest.getId()); |
| | | purchaseOrder.setSourceNo(purchaseRequest.getNo()); |
| | | purchaseOrder.setPurchaseRequestId(purchaseRequest.getId()); |
| | | purchaseOrder.setRemark(purchaseRequest.getRemark()); |
| | | purchaseOrder.setInCount(BigDecimal.ZERO); |
| | | purchaseOrder.setInStatus(0); |
| | |
| | | orderItem.setRequestItemId(item.getId()); // å
³èéè´ç³è¯·æç» |
| | | orderItem.setProductId(item.getProductId()); |
| | | orderItem.setProductUnitId(item.getProductUnitId()); |
| | | orderItem.setProductPrice(item.getProductPrice()); |
| | | // åä»·/ç¨çå¾
éè´åå¨å°è´¦ä¸è¡¥å½ï¼å
æ 0 ä¿å |
| | | orderItem.setProductPrice(BigDecimal.ZERO); |
| | | orderItem.setCount(item.getCount()); |
| | | orderItem.setTotalPrice(item.getTotalPrice()); |
| | | orderItem.setTaxPercent(item.getTaxPercent()); |
| | | orderItem.setTaxPrice(item.getTaxPrice()); |
| | | orderItem.setTotalPrice(BigDecimal.ZERO); |
| | | orderItem.setTaxPercent(BigDecimal.ZERO); |
| | | orderItem.setTaxPrice(BigDecimal.ZERO); |
| | | orderItem.setRemark(item.getRemark()); |
| | | orderItem.setInCount(BigDecimal.ZERO); |
| | | // æ¯å¦è´¨æ£ä¸éè´ç³è¯·ä¿æä¸è´ï¼æç»æªæç¡®æ è®°æ¶é»è®¤ä¸ºãæ¯ãï¼åå²ç³è¯·åå¯è½ä¸º nullï¼ |
| | |
| | | return success(inquiryService.createInquiry(createReqVO)); |
| | | } |
| | | |
| | | @PostMapping("/create-from-request") |
| | | @Operation(summary = "ç±éè´ç³è¯·å起询价") |
| | | @Parameter(name = "requestId", description = "éè´ç³è¯·ç¼å·", required = true) |
| | | @PreAuthorize("@ss.hasPermission('srm:inquiry:create')") |
| | | public CommonResult<Long> createInquiryFromPurchaseRequest(@RequestParam("requestId") Long requestId) { |
| | | return success(inquiryService.createInquiryFromPurchaseRequest(requestId)); |
| | | } |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "æ´æ°è¯¢ä»·åï¼ä»
è稿ï¼") |
| | | @PreAuthorize("@ss.hasPermission('srm:inquiry:update')") |
| | |
| | | private Integer status; |
| | | private String processInstanceId; |
| | | |
| | | @Schema(description = "å
³èéè´ç³è¯·ç¼å·") |
| | | private Long purchaseRequestId; |
| | | |
| | | @Schema(description = "å
³èéè´ç³è¯·åå·") |
| | | private String purchaseRequestNo; |
| | | |
| | | @Schema(description = "è¯¢ä»·æ¥æ") |
| | | private LocalDate inquiryDate; |
| | | |
| | |
| | | private Long purchaserUserId; |
| | | private String remark; |
| | | private String processInstanceId; |
| | | /** |
| | | * å
³èéè´ç³è¯·ç¼å· |
| | | */ |
| | | private Long purchaseRequestId; |
| | | /** |
| | | * å
³èéè´ç³è¯·åå· |
| | | */ |
| | | private String purchaseRequestNo; |
| | | |
| | | } |
| | |
| | | ErrorCode INQUIRY_ALREADY_CONFIRMED = new ErrorCode(1_040_600_014, "询价å已被确认转订åï¼è¯·å·æ°åæ¥ç"); |
| | | ErrorCode INQUIRY_ORDER_GENERATE_FAIL = new ErrorCode(1_040_600_015, "询价åçæéè´è®¢å失败"); |
| | | ErrorCode INQUIRY_NO_GENERATE_FAIL = new ErrorCode(1_040_600_016, "询价åå·çæå¤±è´¥"); |
| | | ErrorCode INQUIRY_PURCHASE_REQUEST_NOT_EXISTS = new ErrorCode(1_040_600_017, "éè´ç³è¯·ä¸åå¨"); |
| | | ErrorCode INQUIRY_PURCHASE_REQUEST_NOT_APPROVED = new ErrorCode(1_040_600_018, "éè´ç³è¯·å®¡æ ¸éè¿åæè½å起询价"); |
| | | ErrorCode INQUIRY_PURCHASE_REQUEST_HAS_ORDER = new ErrorCode(1_040_600_019, "éè´ç³è¯·å·²çæéè´å°è´¦ï¼æ æ³åå起询价"); |
| | | ErrorCode INQUIRY_PURCHASE_REQUEST_HAS_INQUIRY = new ErrorCode(1_040_600_020, "éè´ç³è¯·å·²åèµ·è¿è¯¢ä»·ï¼è¯·å¿é夿ä½"); |
| | | ErrorCode INQUIRY_PURCHASE_REQUEST_ITEM_EMPTY = new ErrorCode(1_040_600_021, "éè´ç³è¯·æ²¡ææç»ï¼æ æ³å起询价"); |
| | | |
| | | } |
| | |
| | | |
| | | Long createInquiry(@Valid SrmInquirySaveReqVO createReqVO); |
| | | |
| | | /** |
| | | * ç±éè´ç³è¯·åèµ·è¯¢ä»·ï¼æç³è¯·æç»çæè¯¢ä»·åè稿ï¼å¹¶ååéè´ç³è¯·ç询价åå
³è |
| | | * |
| | | * @param purchaseRequestId éè´ç³è¯·ç¼å· |
| | | * @return 询价åç¼å· |
| | | */ |
| | | Long createInquiryFromPurchaseRequest(Long purchaseRequestId); |
| | | |
| | | void updateInquiry(@Valid SrmInquirySaveReqVO updateReqVO); |
| | | |
| | | void deleteInquiry(Long id); |
| | |
| | | import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; |
| | | import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum; |
| | | import cn.iocoder.yudao.module.erp.api.purchase.ErpPurchaseOrderApi; |
| | | import cn.iocoder.yudao.module.erp.api.purchase.ErpPurchaseRequestApi; |
| | | import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderCreateReqDTO; |
| | | import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderRespDTO; |
| | | import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseRequestRespDTO; |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; |
| | | import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi; |
| | |
| | | |
| | | private static final DateTimeFormatter NO_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyyMM"); |
| | | |
| | | /** |
| | | * éè´ç³è¯·ãå®¡æ ¸éè¿ãç¶æå¼ï¼ä¸ ERP 模å ErpPurchaseRequestStatusEnum.APPROVE ä¿æä¸è´ |
| | | */ |
| | | private static final Integer PURCHASE_REQUEST_STATUS_APPROVED = 20; |
| | | |
| | | @Resource |
| | | private SrmInquiryMapper inquiryMapper; |
| | | @Resource |
| | |
| | | private MdmUnitMeasureApi mdmUnitMeasureApi; |
| | | @Resource |
| | | private ErpPurchaseOrderApi erpPurchaseOrderApi; |
| | | @Resource |
| | | private ErpPurchaseRequestApi erpPurchaseRequestApi; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | |
| | | createReqVO.getSuppliers().stream() |
| | | .map(SrmInquirySaveReqVO.Supplier::getSupplierId) |
| | | .collect(Collectors.toSet())); |
| | | return inquiry.getId(); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createInquiryFromPurchaseRequest(Long purchaseRequestId) { |
| | | ErpPurchaseRequestRespDTO purchaseRequest = erpPurchaseRequestApi |
| | | .getPurchaseRequest(purchaseRequestId).getCheckedData(); |
| | | if (purchaseRequest == null) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.INQUIRY_PURCHASE_REQUEST_NOT_EXISTS); |
| | | } |
| | | if (!PURCHASE_REQUEST_STATUS_APPROVED.equals(purchaseRequest.getStatus())) { |
| | | throw new ServiceException(ErrorCodeConstants.INQUIRY_PURCHASE_REQUEST_NOT_APPROVED.getCode(), |
| | | "éè´ç³è¯·ã" + purchaseRequest.getNo() + "ãå½åç¶æä¸æ¯ãå®¡æ ¸éè¿ãï¼æ æ³å起询价ã" |
| | | + "请å
å¨éè´ç³è¯·ä¸å®æå®¡æ¹ï¼å®¡æ¹éè¿ååå起询价ã"); |
| | | } |
| | | if (purchaseRequest.getOrderId() != null) { |
| | | throw new ServiceException(ErrorCodeConstants.INQUIRY_PURCHASE_REQUEST_HAS_ORDER.getCode(), |
| | | "éè´ç³è¯·ã" + purchaseRequest.getNo() + "ãå·²çæéè´å°è´¦ã" |
| | | + StrUtil.blankToDefault(purchaseRequest.getOrderNo(), "ID=" + purchaseRequest.getOrderId()) |
| | | + "ãï¼æ æ³åå起询价ã请å°éè´å°è´¦ä¸æ¥çä»·æ ¼æç»ã"); |
| | | } |
| | | SrmInquiryDO linkedInquiry = purchaseRequest.getInquiryId() != null |
| | | ? inquiryMapper.selectById(purchaseRequest.getInquiryId()) : null; |
| | | if (linkedInquiry != null |
| | | && !InquiryStatusEnum.CANCELLED.getStatus().equals(linkedInquiry.getStatus())) { |
| | | throw new ServiceException(ErrorCodeConstants.INQUIRY_PURCHASE_REQUEST_HAS_INQUIRY.getCode(), |
| | | "éè´ç³è¯·ã" + purchaseRequest.getNo() + "ãå·²åèµ·è¿è¯¢ä»·ã" |
| | | + StrUtil.blankToDefault(purchaseRequest.getInquiryNo(), "ID=" + purchaseRequest.getInquiryId()) |
| | | + "ãï¼è¯·ç´æ¥æå¼è¯¥è¯¢ä»·åç»§ç»å¤çï¼ä¸è¦éå¤åèµ·ã"); |
| | | } |
| | | List<ErpPurchaseRequestRespDTO.Item> requestItems = purchaseRequest.getItems(); |
| | | if (CollUtil.isEmpty(requestItems)) { |
| | | throw new ServiceException(ErrorCodeConstants.INQUIRY_PURCHASE_REQUEST_ITEM_EMPTY.getCode(), |
| | | "éè´ç³è¯·ã" + purchaseRequest.getNo() + "ãæ²¡ææç»è¡ï¼æ æ³å起询价ã请åå°éè´ç³è¯·è¡¥å
æç»ååè¯ã"); |
| | | } |
| | | |
| | | SrmInquiryDO inquiry = new SrmInquiryDO(); |
| | | inquiry.setNo(generateInquiryNo()); |
| | | inquiry.setTitle("éè´ç³è¯·ã" + purchaseRequest.getNo() + "ã询价"); |
| | | inquiry.setStatus(InquiryStatusEnum.DRAFT.getStatus()); |
| | | inquiry.setInquiryDate(LocalDate.now()); |
| | | inquiry.setPurchaserUserId(getLoginUserId()); |
| | | inquiry.setRemark("ç±éè´ç³è¯·ã" + purchaseRequest.getNo() + "ãåèµ·"); |
| | | inquiry.setPurchaseRequestId(purchaseRequest.getId()); |
| | | inquiry.setPurchaseRequestNo(purchaseRequest.getNo()); |
| | | inquiryMapper.insert(inquiry); |
| | | |
| | | List<SrmInquirySaveReqVO.Item> itemVOs = new ArrayList<>(); |
| | | Set<Long> productIds = new HashSet<>(); |
| | | for (ErpPurchaseRequestRespDTO.Item requestItem : requestItems) { |
| | | if (!productIds.add(requestItem.getProductId())) { |
| | | throw new ServiceException(ErrorCodeConstants.INQUIRY_PURCHASE_REQUEST_ITEM_EMPTY.getCode(), |
| | | "éè´ç³è¯·ã" + purchaseRequest.getNo() + "ãä¸äº§åã" |
| | | + resolveItemName(requestItem.getProductId()) + "ãåå¨å¤è¡æç»ï¼æ æ³ç´æ¥å起询价ã" |
| | | + "请å
å¨éè´ç³è¯·ä¸åå¹¶åä¸äº§åçæ°éååè¯ã"); |
| | | } |
| | | SrmInquirySaveReqVO.Item itemVO = new SrmInquirySaveReqVO.Item(); |
| | | itemVO.setProductId(requestItem.getProductId()); |
| | | itemVO.setProductUnitId(requestItem.getProductUnitId()); |
| | | itemVO.setQuantity(requestItem.getCount()); |
| | | itemVO.setRemark(requestItem.getRemark()); |
| | | itemVOs.add(itemVO); |
| | | } |
| | | saveItems(inquiry.getId(), itemVOs); |
| | | |
| | | erpPurchaseRequestApi.updatePurchaseRequestInquiry(purchaseRequest.getId(), inquiry.getId(), inquiry.getNo()); |
| | | return inquiry.getId(); |
| | | } |
| | | |
| | |
| | | inquirySupplierMapper.deleteByInquiryId(id); |
| | | inquiryQuoteMapper.deleteByInquiryId(id); |
| | | inquiryMapper.deleteById(id); |
| | | clearPurchaseRequestLink(inquiry); |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | inquiryMapper.updateById(new SrmInquiryDO() |
| | | .setId(id).setStatus(InquiryStatusEnum.CANCELLED.getStatus())); |
| | | // è¯¢ä»·åæ¶åè§£é¤éè´ç³è¯·å
³èï¼éè´åå¯éæ°éæ©ãå起询价ãæãç´æ¥çæå°è´¦ã |
| | | clearPurchaseRequestLink(inquiry); |
| | | } |
| | | |
| | | @Override |
| | |
| | | createReqDTO.setSourceType(2); |
| | | createReqDTO.setSourceNo(inquiry.getNo()); |
| | | createReqDTO.setSourceId(inquiry.getId()); |
| | | createReqDTO.setPurchaseRequestId(inquiry.getPurchaseRequestId()); |
| | | createReqDTO.setRemark("SRM询价èªå¨çæï¼è¯¢ä»·åå·ï¼" + inquiry.getNo()); |
| | | createReqDTO.setItems(orderItems); |
| | | |
| | |
| | | orderResult.setPurchaseOrderId(purchaseOrderId); |
| | | orderResult.setPurchaseOrderNo(purchaseOrderNo); |
| | | orders.add(orderResult); |
| | | } |
| | | |
| | | // 3.1 è¯¢ä»·åæ¥æºäºéè´ç³è¯·æ¶ï¼ååéè´ç³è¯·å
³èçéè´å°è´¦ |
| | | // ä¸ä¸ªè¯¢ä»·åå¯è½æä¸æ ä¾åºåææå¤å¼ å°è´¦ï¼éè´ç³è¯·åªè®°å½ç¬¬ä¸å¼ ï¼å®æ´æ¸
åå¯éè¿å°è´¦çéè´ç³è¯·åæ®µåæ¥ |
| | | if (inquiry.getPurchaseRequestId() != null && CollUtil.isNotEmpty(orders)) { |
| | | SrmInquiryConfirmRespVO.Order firstOrder = orders.get(0); |
| | | if (orders.size() > 1) { |
| | | log.info("[confirmInquiry] 询价å({}) 为éè´ç³è¯·({}) çæ {} å¼ å°è´¦ï¼éè´ç³è¯·ä»
ååé¦å¼ å°è´¦({})", |
| | | inquiry.getNo(), inquiry.getPurchaseRequestNo(), orders.size(), firstOrder.getPurchaseOrderNo()); |
| | | } |
| | | try { |
| | | erpPurchaseRequestApi.updatePurchaseRequestOrder(inquiry.getPurchaseRequestId(), |
| | | firstOrder.getPurchaseOrderId(), firstOrder.getPurchaseOrderNo()); |
| | | } catch (Exception ex) { |
| | | log.error("[confirmInquiry] 询价å({}) ååéè´ç³è¯·({}) å
³èå°è´¦å¤±è´¥", |
| | | inquiry.getNo(), inquiry.getPurchaseRequestNo(), ex); |
| | | throw new ServiceException(ErrorCodeConstants.INQUIRY_ORDER_GENERATE_FAIL.getCode(), |
| | | "询价åã" + inquiry.getNo() + "ãå·²çæéè´å°è´¦ã" |
| | | + StrUtil.blankToDefault(firstOrder.getPurchaseOrderNo(), "ID=" + firstOrder.getPurchaseOrderId()) |
| | | + "ãï¼ä½ååéè´ç³è¯·ã" + inquiry.getPurchaseRequestNo() + "ã失败ï¼" + ex.getMessage() |
| | | + "ã请å°éè´ç³è¯·ä¸æ ¸å¯¹å
³èå°è´¦ï¼æè系管çåå¤çã"); |
| | | } |
| | | } |
| | | |
| | | // 4. æ´æ°è¯¢ä»·å为已转订åï¼ç¶ææ¡ä»¶æ´æ°ï¼é¿å
å¹¶åéå¤çæï¼ |
| | |
| | | "询价åå·å¨å¤æ¬¡å°è¯åä»éå¤ï¼è¯·ç¨åéè¯ã"); |
| | | } |
| | | |
| | | /** |
| | | * 询价åè¢«åæ¶/å 餿¶ï¼è§£é¤å¯¹éè´ç³è¯·çå
³èï¼è®©éè´åå¯éæ°éæ©ãå起询价ãæãç´æ¥çæå°è´¦ãã |
| | | * è§£é¤å¤±è´¥åªè®°å½æ¥å¿ï¼ä¸é»æåæ¶æä½ï¼å起询价æ¶ä¼åæè¯¢ä»·åç¶æåå
åºå¤æã |
| | | */ |
| | | private void clearPurchaseRequestLink(SrmInquiryDO inquiry) { |
| | | if (inquiry.getPurchaseRequestId() == null) { |
| | | return; |
| | | } |
| | | try { |
| | | erpPurchaseRequestApi.clearPurchaseRequestInquiry(inquiry.getPurchaseRequestId()); |
| | | } catch (Exception ex) { |
| | | log.warn("[clearPurchaseRequestLink] 询价å({}) è§£é¤éè´ç³è¯·({}) å
³è失败ï¼è¯·äººå·¥æ ¸å¯¹", |
| | | inquiry.getNo(), inquiry.getPurchaseRequestNo(), ex); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è§£æäº§ååç§°ï¼ä»
ç¨äºå¼å¸¸æç¤ºï¼è§£æå¤±è´¥æ¶åé为å¯è¯» IDï¼é¿å
äºæ¬¡å¼å¸¸ |
| | | */ |
| | | private String resolveItemName(Long productId) { |
| | | if (productId == null) { |
| | | return "æªéæ©"; |
| | | } |
| | | try { |
| | | MdmItemRespDTO item = mdmItemApi.getItem(productId).getCheckedData(); |
| | | if (item != null && StrUtil.isNotBlank(item.getName())) { |
| | | return item.getName(); |
| | | } |
| | | } catch (Exception ex) { |
| | | log.warn("[resolveItemName] æ¥è¯¢äº§å({}) å称失败", productId, ex); |
| | | } |
| | | return "ID=" + productId; |
| | | } |
| | | |
| | | private String statusName(Integer status) { |
| | | for (InquiryStatusEnum e : InquiryStatusEnum.values()) { |
| | | if (e.getStatus().equals(status)) { |