feat(crm): 合同导出功能优化及状态中文展示
- 新增 CrmAuditStatusEnum.getNameByStatus 方法实现状态码到中文名称转换
- 在合同导出接口中计算未回款金额并转换审批状态为中文名称
- 修改 CrmContractRespVO 类增加审核状态名称字段和未回款金额字段
- 调整 Excel 导出字段顺序并更新字段标题为中文描述
- 从 MDM 物料控制器中移除导入相关功能代码
- 删除 MES 模块中物料导入相关的 VO 类和服务方法
- 优化 MDM 物料下拉列表返回单位名称等关联字段信息
- 从 SRM 错误码中移除物料导入空数据相关定义
- 在 SRM 模块中新增招标流程精细化状态校验错误码
- 实现 SRM 定标和评标服务中的状态流转校验逻辑
- 添加 SRM 投标截止时间检查防止逾期提交
- 在供应商分页查询中增加排除已审批选项功能
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [active]: å·¥ä¸AIæºé å¹³å° |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [active]: å·¥ä¸AIæºé å¹³å° |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [ref=f1e7]: |
| | | - complementary [ref=f1e8]: |
| | | - generic [ref=f1e9]: |
| | | - link "å·¥ä¸AIæºé å¹³å° å·¥ä¸AIæºé å¹³å°" [ref=f1e15] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - img "å·¥ä¸AIæºé å¹³å°" [ref=f1e18] |
| | | - generic [ref=f1e19]: å·¥ä¸AIæºé å¹³å° |
| | | - menu [ref=f1e22]: |
| | | - menuitem "é¦é¡µ" [ref=f1e23] [cursor=pointer] |
| | | - listitem [ref=f1e30]: |
| | | - generic [ref=f1e31] [cursor=pointer]: åºç¡æ°æ® |
| | | - listitem [ref=f1e39]: |
| | | - generic [ref=f1e40] [cursor=pointer]: éè´ç®¡ç |
| | | - listitem [ref=f1e46]: |
| | | - generic [ref=f1e47] [cursor=pointer]: è¥é管ç |
| | | - listitem [ref=f1e53]: |
| | | - generic [ref=f1e54] [cursor=pointer]: 设å¤ç®¡ç |
| | | - listitem [ref=f1e61]: |
| | | - generic [ref=f1e62] [cursor=pointer]: ä»å¨ç©æµ |
| | | - listitem [ref=f1e70]: |
| | | - generic [ref=f1e71] [cursor=pointer]: çäº§ç®¡æ§ |
| | | - listitem [ref=f1e78]: |
| | | - generic [ref=f1e79] [cursor=pointer]: è´¨é管ç |
| | | - listitem [ref=f1e85]: |
| | | - generic [ref=f1e86] [cursor=pointer]: åååå
¬ |
| | | - listitem [ref=f1e92]: |
| | | - generic [ref=f1e93] [cursor=pointer]: 人åèµæº |
| | | - listitem [ref=f1e99]: |
| | | - generic [ref=f1e100] [cursor=pointer]: å®å管ç |
| | | - listitem [ref=f1e106]: |
| | | - generic [ref=f1e107] [cursor=pointer]: åºç¡è®¾æ½ |
| | | - listitem [ref=f1e113]: |
| | | - generic [ref=f1e114] [cursor=pointer]: ç³»ç»ç®¡ç |
| | | - listitem [ref=f1e120]: |
| | | - generic [ref=f1e121] [cursor=pointer]: IM 峿¶é讯 |
| | | - generic [ref=f1e134]: |
| | | - generic [ref=f1e135]: |
| | | - banner [ref=f1e136]: |
| | | - button [ref=f1e137] [cursor=pointer] |
| | | - button [ref=f1e140] [cursor=pointer] |
| | | - navigation "breadcrumb" [ref=f1e145]: |
| | | - list [ref=f1e146]: |
| | | - listitem [ref=f1e147]: |
| | | - link [disabled] [ref=f1e148] |
| | | - generic [ref=f1e155]: |
| | | - generic [ref=f1e157] [cursor=pointer]: |
| | | - generic [ref=f1e161]: æç´¢ |
| | | - generic [ref=f1e162]: Ctrl K |
| | | - button [ref=f1e164] [cursor=pointer] |
| | | - button "dark" [ref=f1e169] [cursor=pointer] |
| | | - button [ref=f1e178] [cursor=pointer] |
| | | - button [ref=f1e184] [cursor=pointer] |
| | | - button [ref=f1e187] [cursor=pointer] |
| | | - button [ref=f1e193] [cursor=pointer]: |
| | | - button [ref=f1e195] |
| | | - button "å·¥ä½å°" [ref=f1e199] [cursor=pointer] |
| | | - button [ref=f1e203] [cursor=pointer]: |
| | | - img "èéæºç " [ref=f1e208] |
| | | - generic [ref=f1e210]: |
| | | - generic [ref=f1e211]: é¦é¡µ |
| | | - button [ref=f1e233] [cursor=pointer] |
| | | - main [ref=f1e251]: |
| | | - generic [ref=f1e254]: |
| | | - generic [ref=f1e255]: |
| | | - generic [ref=f1e256]: |
| | | - heading "ä¸åå¥½ï¼æ¬¢è¿åæ¥" [level=1] [ref=f1e257] |
| | | - paragraph [ref=f1e258]: 2026å¹´8æ3æ¥ ææä¸ |
| | | - generic [ref=f1e259]: ç³»ç»è¿è¡ä¸ |
| | | - generic [ref=f1e264]: |
| | | - generic [ref=f1e273] [cursor=pointer]: |
| | | - generic [ref=f1e274]: ç产订å |
| | | - generic [ref=f1e275]: |
| | | - generic [ref=f1e276]: "25" |
| | | - generic [ref=f1e278]: è¿è¡ä¸ |
| | | - generic [ref=f1e279]: |
| | | - text: å¾
æäº§ 15 |
| | | - generic [ref=f1e281]: "|" |
| | | - text: 已宿 5 |
| | | - generic [ref=f1e293] [cursor=pointer]: |
| | | - generic [ref=f1e294]: 仿¥äº§é |
| | | - generic [ref=f1e295]: |
| | | - generic [ref=f1e296]: "0" |
| | | - generic [ref=f1e298]: ä»¶ |
| | | - generic [ref=f1e299]: æ¨æ¥ 0 ä»¶ |
| | | - generic [ref=f1e310] [cursor=pointer]: |
| | | - generic [ref=f1e311]: è´¨éåæ ¼ç |
| | | - generic [ref=f1e312]: |
| | | - generic [ref=f1e313]: "0.0" |
| | | - generic [ref=f1e315]: "%" |
| | | - generic [ref=f1e316]: åæ ¼ 0 | ä¸è¯ 0 |
| | | - generic [ref=f1e328] [cursor=pointer]: |
| | | - generic [ref=f1e329]: 设å¤è¿è¡ç |
| | | - generic [ref=f1e330]: |
| | | - generic [ref=f1e331]: "100.0" |
| | | - generic [ref=f1e333]: "%" |
| | | - generic [ref=f1e334]: |
| | | - generic [ref=f1e335]: åæº 0 |
| | | - generic [ref=f1e336]: "|" |
| | | - generic [ref=f1e337]: ç»´æ¤ 0 |
| | | - generic [ref=f1e340]: |
| | | - generic [ref=f1e350] [cursor=pointer]: |
| | | - generic [ref=f1e351]: éè´è®¢å |
| | | - generic [ref=f1e352]: |
| | | - generic [ref=f1e353]: "14" |
| | | - generic [ref=f1e355]: ç¬ |
| | | - generic [ref=f1e356]: ERP éè´ç®¡ç |
| | | - generic [ref=f1e367] [cursor=pointer]: |
| | | - generic [ref=f1e368]: éå®è®¢å |
| | | - generic [ref=f1e369]: |
| | | - generic [ref=f1e370]: "22" |
| | | - generic [ref=f1e372]: ç¬ |
| | | - generic [ref=f1e373]: ERP éå®ç®¡ç |
| | | - generic [ref=f1e385] [cursor=pointer]: |
| | | - generic [ref=f1e386]: ç©æåºå |
| | | - generic [ref=f1e387]: |
| | | - generic [ref=f1e388]: "13" |
| | | - generic [ref=f1e390]: æ¡ |
| | | - generic [ref=f1e391]: MES åºåå°è´¦ |
| | | - generic [ref=f1e403] [cursor=pointer]: |
| | | - generic [ref=f1e404]: æçå¾
å |
| | | - generic [ref=f1e405]: |
| | | - generic [ref=f1e406]: "1" |
| | | - generic [ref=f1e408]: 项 |
| | | - generic [ref=f1e409]: BPM å¾
å®¡æ¹ |
| | | - generic [ref=f1e413]: |
| | | - heading "AI æºè½åæ" [level=3] [ref=f1e414] |
| | | - generic [ref=f1e415]: 25 个工åå¯åæ |
| | | - generic [ref=f1e416]: |
| | | - heading "ç产è¶å¿ï¼è¿7天ï¼" [level=3] [ref=f1e419] |
| | | - generic [ref=f1e424]: |
| | | - generic [ref=f1e425]: |
| | | - generic [ref=f1e431] [cursor=pointer]: |
| | | - generic [ref=f1e432]: å®ç¯å¼å« |
| | | - generic [ref=f1e433]: |
| | | - generic [ref=f1e434]: "0" |
| | | - generic [ref=f1e436]: æªå¤ç½® |
| | | - generic [ref=f1e442] [cursor=pointer]: |
| | | - generic [ref=f1e443]: 维修工å |
| | | - generic [ref=f1e444]: |
| | | - generic [ref=f1e445]: "0" |
| | | - generic [ref=f1e447]: å¾
å¤ç |
| | | - heading "å·¥åç¶æåå¸" [level=4] [ref=f1e449] |
| | | - generic [ref=f1e457]: |
| | | - heading "å¿«æ·æä½" [level=3] [ref=f1e458] |
| | | - generic [ref=f1e459]: |
| | | - generic [ref=f1e460] [cursor=pointer]: ç产工å |
| | | - generic [ref=f1e463] [cursor=pointer]: ç产æ¥å·¥ |
| | | - generic [ref=f1e466] [cursor=pointer]: è´¨æ£ç®¡ç |
| | | - generic [ref=f1e469] [cursor=pointer]: 设å¤ç¹æ£ |
| | | - generic [ref=f1e472] [cursor=pointer]: ç产æç¨ |
| | | - generic [ref=f1e475] [cursor=pointer]: å®ç¯å¼å« |
| | | - generic [ref=f1e478] [cursor=pointer]: ç©æåºå |
| | | - generic [ref=f1e481] [cursor=pointer]: å·¥èºè·¯çº¿ |
| | | - generic [ref=f1e484] [cursor=pointer]: æ°æ®æ¥è¡¨ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [ref=f2e3]: |
| | | - generic [ref=f2e6]: |
| | | - heading "æ æ³è®¿é®æ¤ç½ç«" [level=1] [ref=f2e7] |
| | | - paragraph [ref=f2e8]: |
| | | - strong [ref=f2e9]: localhost |
| | | - text: æç»äºæä»¬çè¿æ¥è¯·æ±ã |
| | | - generic [ref=f2e10]: |
| | | - paragraph [ref=f2e11]: 请è¯è¯ä»¥ä¸åæ³ï¼ |
| | | - list [ref=f2e12]: |
| | | - listitem [ref=f2e13]: æ£æ¥ç½ç»è¿æ¥ |
| | | - listitem [ref=f2e14]: |
| | | - link "æ£æ¥ä»£çæå¡å¨åé²ç«å¢" [ref=f2e15] [cursor=pointer]: |
| | | - /url: "#buttons" |
| | | - generic [ref=f2e16]: ERR_CONNECTION_REFUSED |
| | | - generic [ref=f2e17]: |
| | | - button "éæ°å è½½" [ref=f2e19] [cursor=pointer] |
| | | - button "详æ
" [ref=f2e20] [cursor=pointer] |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [active]: å·¥ä¸AIæºé å¹³å° |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [ref=f3e7]: |
| | | - complementary [ref=f3e8]: |
| | | - generic [ref=f3e9]: |
| | | - link "å·¥ä¸AIæºé å¹³å° å·¥ä¸AIæºé å¹³å°" [ref=f3e15] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - img "å·¥ä¸AIæºé å¹³å°" [ref=f3e18] |
| | | - generic [ref=f3e19]: å·¥ä¸AIæºé å¹³å° |
| | | - menu [ref=f3e22]: |
| | | - menuitem "é¦é¡µ" [ref=f3e23] [cursor=pointer] |
| | | - listitem [ref=f3e30]: |
| | | - generic [ref=f3e31] [cursor=pointer]: åºç¡æ°æ® |
| | | - listitem [ref=f3e39]: |
| | | - generic [ref=f3e40] [cursor=pointer]: éè´ç®¡ç |
| | | - listitem [ref=f3e46]: |
| | | - generic [ref=f3e47] [cursor=pointer]: è¥é管ç |
| | | - listitem [ref=f3e53]: |
| | | - generic [ref=f3e54] [cursor=pointer]: 设å¤ç®¡ç |
| | | - listitem [ref=f3e61]: |
| | | - generic [ref=f3e62] [cursor=pointer]: ä»å¨ç©æµ |
| | | - listitem [ref=f3e70]: |
| | | - generic [ref=f3e71] [cursor=pointer]: çäº§ç®¡æ§ |
| | | - listitem [ref=f3e78]: |
| | | - generic [ref=f3e79] [cursor=pointer]: è´¨é管ç |
| | | - listitem [ref=f3e85]: |
| | | - generic [ref=f3e86] [cursor=pointer]: åååå
¬ |
| | | - listitem [ref=f3e92]: |
| | | - generic [ref=f3e93] [cursor=pointer]: 人åèµæº |
| | | - listitem [ref=f3e99]: |
| | | - generic [ref=f3e100] [cursor=pointer]: å®å管ç |
| | | - listitem [ref=f3e106]: |
| | | - generic [ref=f3e107] [cursor=pointer]: åºç¡è®¾æ½ |
| | | - listitem [ref=f3e113]: |
| | | - generic [ref=f3e114] [cursor=pointer]: ç³»ç»ç®¡ç |
| | | - listitem [ref=f3e120]: |
| | | - generic [ref=f3e121] [cursor=pointer]: IM 峿¶é讯 |
| | | - generic [ref=f3e134]: |
| | | - generic [ref=f3e135]: |
| | | - banner [ref=f3e136]: |
| | | - button [ref=f3e137] [cursor=pointer] |
| | | - button [ref=f3e140] [cursor=pointer] |
| | | - navigation "breadcrumb" [ref=f3e145]: |
| | | - list [ref=f3e146]: |
| | | - listitem [ref=f3e147]: |
| | | - link [disabled] [ref=f3e148] |
| | | - generic [ref=f3e155]: |
| | | - generic [ref=f3e157] [cursor=pointer]: |
| | | - generic [ref=f3e161]: æç´¢ |
| | | - generic [ref=f3e162]: Ctrl K |
| | | - button [ref=f3e164] [cursor=pointer] |
| | | - button "dark" [ref=f3e169] [cursor=pointer] |
| | | - button [ref=f3e178] [cursor=pointer] |
| | | - button [ref=f3e184] [cursor=pointer] |
| | | - button [ref=f3e187] [cursor=pointer] |
| | | - button [ref=f3e193] [cursor=pointer]: |
| | | - button [ref=f3e195] |
| | | - button "å·¥ä½å°" [ref=f3e199] [cursor=pointer] |
| | | - button [ref=f3e203] [cursor=pointer]: |
| | | - img "èéæºç " [ref=f3e208] |
| | | - generic [ref=f3e210]: |
| | | - generic [ref=f3e211]: é¦é¡µ |
| | | - button [ref=f3e233] [cursor=pointer] |
| | | - main [ref=f3e251]: |
| | | - generic [ref=f3e254]: |
| | | - generic [ref=f3e255]: |
| | | - generic [ref=f3e256]: |
| | | - heading "ä¸åå¥½ï¼æ¬¢è¿åæ¥" [level=1] [ref=f3e257] |
| | | - paragraph [ref=f3e258]: 2026å¹´8æ3æ¥ ææä¸ |
| | | - generic [ref=f3e259]: ç³»ç»è¿è¡ä¸ |
| | | - generic [ref=f3e264]: |
| | | - generic [ref=f3e273] [cursor=pointer]: |
| | | - generic [ref=f3e274]: ç产订å |
| | | - generic [ref=f3e275]: |
| | | - generic [ref=f3e276]: "25" |
| | | - generic [ref=f3e278]: è¿è¡ä¸ |
| | | - generic [ref=f3e279]: |
| | | - text: å¾
æäº§ 15 |
| | | - generic [ref=f3e281]: "|" |
| | | - text: 已宿 5 |
| | | - generic [ref=f3e293] [cursor=pointer]: |
| | | - generic [ref=f3e294]: 仿¥äº§é |
| | | - generic [ref=f3e295]: |
| | | - generic [ref=f3e296]: "0" |
| | | - generic [ref=f3e298]: ä»¶ |
| | | - generic [ref=f3e299]: æ¨æ¥ 0 ä»¶ |
| | | - generic [ref=f3e310] [cursor=pointer]: |
| | | - generic [ref=f3e311]: è´¨éåæ ¼ç |
| | | - generic [ref=f3e312]: |
| | | - generic [ref=f3e313]: "0.0" |
| | | - generic [ref=f3e315]: "%" |
| | | - generic [ref=f3e316]: åæ ¼ 0 | ä¸è¯ 0 |
| | | - generic [ref=f3e328] [cursor=pointer]: |
| | | - generic [ref=f3e329]: 设å¤è¿è¡ç |
| | | - generic [ref=f3e330]: |
| | | - generic [ref=f3e331]: "100.0" |
| | | - generic [ref=f3e333]: "%" |
| | | - generic [ref=f3e334]: |
| | | - generic [ref=f3e335]: åæº 0 |
| | | - generic [ref=f3e336]: "|" |
| | | - generic [ref=f3e337]: ç»´æ¤ 0 |
| | | - generic [ref=f3e340]: |
| | | - generic [ref=f3e350] [cursor=pointer]: |
| | | - generic [ref=f3e351]: éè´è®¢å |
| | | - generic [ref=f3e352]: |
| | | - generic [ref=f3e353]: "14" |
| | | - generic [ref=f3e355]: ç¬ |
| | | - generic [ref=f3e356]: ERP éè´ç®¡ç |
| | | - generic [ref=f3e367] [cursor=pointer]: |
| | | - generic [ref=f3e368]: éå®è®¢å |
| | | - generic [ref=f3e369]: |
| | | - generic [ref=f3e370]: "22" |
| | | - generic [ref=f3e372]: ç¬ |
| | | - generic [ref=f3e373]: ERP éå®ç®¡ç |
| | | - generic [ref=f3e385] [cursor=pointer]: |
| | | - generic [ref=f3e386]: ç©æåºå |
| | | - generic [ref=f3e387]: |
| | | - generic [ref=f3e388]: "13" |
| | | - generic [ref=f3e390]: æ¡ |
| | | - generic [ref=f3e391]: MES åºåå°è´¦ |
| | | - generic [ref=f3e403] [cursor=pointer]: |
| | | - generic [ref=f3e404]: æçå¾
å |
| | | - generic [ref=f3e405]: |
| | | - generic [ref=f3e406]: "1" |
| | | - generic [ref=f3e408]: 项 |
| | | - generic [ref=f3e409]: BPM å¾
å®¡æ¹ |
| | | - generic [ref=f3e412]: |
| | | - generic [ref=f3e413]: |
| | | - heading "AI æºè½åæ" [level=3] [ref=f3e414] |
| | | - generic [ref=f3e415]: 25 个工åå¯åæ |
| | | - generic [ref=f3e416]: |
| | | - generic [ref=f3e424] [cursor=pointer]: |
| | | - generic [ref=f3e425]: AI ç©æé¢æµ |
| | | - generic [ref=f3e426]: 颿µç©æéæ±ä¸ç缺é£é© |
| | | - generic [ref=f3e435] [cursor=pointer]: |
| | | - generic [ref=f3e436]: AI æ¶é¿é¢æµ |
| | | - generic [ref=f3e437]: 颿µåå·¥åºçäº§èæ¶ |
| | | - generic [ref=f3e444] [cursor=pointer]: |
| | | - generic [ref=f3e445]: AI é£é©é¢æµ |
| | | - generic [ref=f3e446]: è¯å«æ½å¨ç产é£é©å¹¶ç»åºå»ºè®® |
| | | - generic [ref=f3e456] [cursor=pointer]: |
| | | - generic [ref=f3e457]: AI 交ä»è¯ä¼° |
| | | - generic [ref=f3e458]: è¯ä¼°è®¢å交ä»åæ¶çä¸å»¶æå ç´ |
| | | - generic [ref=f3e461]: |
| | | - heading "ç产è¶å¿ï¼è¿7天ï¼" [level=3] [ref=f3e464] |
| | | - generic [ref=f3e469]: |
| | | - generic [ref=f3e470]: |
| | | - generic [ref=f3e476] [cursor=pointer]: |
| | | - generic [ref=f3e477]: å®ç¯å¼å« |
| | | - generic [ref=f3e478]: |
| | | - generic [ref=f3e479]: "0" |
| | | - generic [ref=f3e481]: æªå¤ç½® |
| | | - generic [ref=f3e487] [cursor=pointer]: |
| | | - generic [ref=f3e488]: 维修工å |
| | | - generic [ref=f3e489]: |
| | | - generic [ref=f3e490]: "0" |
| | | - generic [ref=f3e492]: å¾
å¤ç |
| | | - heading "å·¥åç¶æåå¸" [level=4] [ref=f3e494] |
| | | - generic [ref=f3e502]: |
| | | - heading "å¿«æ·æä½" [level=3] [ref=f3e503] |
| | | - generic [ref=f3e504]: |
| | | - generic [ref=f3e505] [cursor=pointer]: ç产工å |
| | | - generic [ref=f3e512] [cursor=pointer]: ç产æ¥å·¥ |
| | | - generic [ref=f3e519] [cursor=pointer]: è´¨æ£ç®¡ç |
| | | - generic [ref=f3e527] [cursor=pointer]: 设å¤ç¹æ£ |
| | | - generic [ref=f3e534] [cursor=pointer]: ç产æç¨ |
| | | - generic [ref=f3e541] [cursor=pointer]: å®ç¯å¼å« |
| | | - generic [ref=f3e546] [cursor=pointer]: ç©æåºå |
| | | - generic [ref=f3e554] [cursor=pointer]: å·¥èºè·¯çº¿ |
| | | - generic [ref=f3e562] [cursor=pointer]: æ°æ®æ¥è¡¨ |
| | |
| | | import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; |
| | | import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO; |
| | | import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; |
| | | import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; |
| | | import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; |
| | |
| | | public void exportContractExcel(@Valid CrmContractPageReqVO exportReqVO, |
| | | HttpServletResponse response) throws IOException { |
| | | PageResult<CrmContractDO> pageResult = contractService.getContractPage(exportReqVO, getLoginUserId()); |
| | | List<CrmContractRespVO> list = BeanUtils.toBean(pageResult.getList(), CrmContractRespVO.class); |
| | | // è®¡ç®æªå款éé¢ã转æ¢å®¡æ¹ç¶æä¸ºä¸æ |
| | | list.forEach(vo -> { |
| | | if (vo.getTotalPrice() != null && vo.getTotalReceivablePrice() != null) { |
| | | vo.setUnReceivablePrice(vo.getTotalPrice().subtract(vo.getTotalReceivablePrice())); |
| | | } |
| | | if (vo.getAuditStatus() != null) { |
| | | vo.setAuditStatusName(CrmAuditStatusEnum.getNameByStatus(vo.getAuditStatus())); |
| | | } |
| | | }); |
| | | // å¯¼åº Excel |
| | | ExcelUtils.write(response, "åå.xls", "æ°æ®", CrmContractRespVO.class, |
| | | BeanUtils.toBean(pageResult.getList(), CrmContractRespVO.class)); |
| | | ExcelUtils.write(response, "åå.xls", "æ°æ®", CrmContractRespVO.class, list); |
| | | } |
| | | |
| | | @PutMapping("/transfer") |
| | |
| | | public class CrmContractRespVO { |
| | | |
| | | @Schema(description = "ååç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") |
| | | @ExcelProperty("ååç¼å·") |
| | | private Long id; |
| | | |
| | | @Schema(description = "åååç§°", requiredMode = Schema.RequiredMode.REQUIRED, example = "çäº") |
| | | @ExcelProperty("åååç§°") |
| | | @ExcelProperty(value = "åååç§°", index = 1) |
| | | private String name; |
| | | |
| | | @Schema(description = "ååç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "20230101") |
| | | @ExcelProperty("ååç¼å·") |
| | | @ExcelProperty(value = "ååç¼å·", index = 0) |
| | | private String no; |
| | | |
| | | @Schema(description = "客æ·ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "18336") |
| | | @ExcelProperty("客æ·ç¼å·") |
| | | private Long customerId; |
| | | @Schema(description = "客æ·åç§°", requiredMode = Schema.RequiredMode.REQUIRED, example = "18336") |
| | | @ExcelProperty("客æ·åç§°") |
| | | @ExcelProperty(value = "客æ·åç§°", index = 2) |
| | | private String customerName; |
| | | |
| | | @Schema(description = "åæºç¼å·", example = "10864") |
| | | @ExcelProperty("åæºç¼å·") |
| | | private Long businessId; |
| | | @Schema(description = "åæºåç§°", example = "10864") |
| | | @ExcelProperty("åæºåç§°") |
| | | @ExcelProperty(value = "åæºåç§°", index = 3) |
| | | private String businessName; |
| | | |
| | | @Schema(description = "æåè·è¿æ¶é´") |
| | | @ExcelProperty("æåè·è¿æ¶é´") |
| | | @ExcelProperty(value = "æåè·è¿æ¶é´", index = 14) |
| | | private LocalDateTime contactLastTime; |
| | | |
| | | @Schema(description = "è´è´£äººçç¨æ·ç¼å·", example = "25682") |
| | | @ExcelProperty("è´è´£äººçç¨æ·ç¼å·") |
| | | private Long ownerUserId; |
| | | @Schema(description = "è´è´£äººåå", example = "25682") |
| | | @ExcelProperty("è´è´£äººåå") |
| | | @ExcelProperty(value = "è´è´£äºº", index = 15) |
| | | private String ownerUserName; |
| | | @Schema(description = "è´è´£äººé¨é¨") |
| | | @ExcelProperty("è´è´£äººé¨é¨") |
| | | @ExcelProperty(value = "æå±é¨é¨", index = 16) |
| | | private String ownerUserDeptName; |
| | | |
| | | @Schema(description = "工使µç¼å·", example = "1043") |
| | | @ExcelProperty("工使µç¼å·") |
| | | private String processInstanceId; |
| | | |
| | | @Schema(description = "审æ¹ç¶æ", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") |
| | | @ExcelProperty("审æ¹ç¶æ") |
| | | private Integer auditStatus; |
| | | |
| | | @Schema(description = "ååç¶æåç§°", example = "审æ¹ä¸") |
| | | @ExcelProperty(value = "ååç¶æ", index = 20) |
| | | private String auditStatusName; |
| | | |
| | | @Schema(description = "ä¸åæ¥æ", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("ä¸åæ¥æ") |
| | | @ExcelProperty(value = "ä¸åæ¶é´", index = 6) |
| | | private LocalDateTime orderDate; |
| | | |
| | | @Schema(description = "å¼å§æ¶é´") |
| | | @ExcelProperty("å¼å§æ¶é´") |
| | | @ExcelProperty(value = "ååå¼å§æ¶é´", index = 7) |
| | | private LocalDateTime startTime; |
| | | |
| | | @Schema(description = "ç»ææ¶é´") |
| | | @ExcelProperty("ç»ææ¶é´") |
| | | @ExcelProperty(value = "ååç»ææ¶é´", index = 8) |
| | | private LocalDateTime endTime; |
| | | |
| | | @Schema(description = "äº§åæ»éé¢", example = "19510") |
| | | @ExcelProperty("äº§åæ»éé¢") |
| | | private BigDecimal totalProductPrice; |
| | | |
| | | @Schema(description = "æ´åææ£") |
| | | @ExcelProperty("æ´åææ£") |
| | | private BigDecimal discountPercent; |
| | | |
| | | @Schema(description = "ååéé¢", example = "5617") |
| | | @ExcelProperty("ååéé¢") |
| | | @ExcelProperty(value = "ååéé¢ï¼å
ï¼", index = 4) |
| | | private BigDecimal totalPrice; |
| | | |
| | | @Schema(description = "å®ééé¢ï¼åä½ï¼å
", example = "1000.00") |
| | | @ExcelProperty("å®ééé¢") |
| | | @ExcelProperty(value = "å®ééé¢ï¼å
ï¼", index = 5) |
| | | private BigDecimal depositPrice; |
| | | |
| | | @Schema(description = "已忬¾éé¢", example = "5617") |
| | | @ExcelProperty("已忬¾éé¢") |
| | | @ExcelProperty(value = "已忬¾éé¢ï¼å
ï¼", index = 12) |
| | | private BigDecimal totalReceivablePrice; |
| | | |
| | | @Schema(description = "æªå款éé¢ï¼çäº ååéé¢ - 已忬¾éé¢", example = "1000.00") |
| | | @ExcelProperty(value = "æªå款éé¢ï¼å
ï¼", index = 13) |
| | | private BigDecimal unReceivablePrice; |
| | | |
| | | @Schema(description = "å
³è ERP éå®è®¢åç¼å·", example = "12345") |
| | | private Long orderId; |
| | | @Schema(description = "ERP éå®è®¢ååå·", example = "SO001") |
| | | @ExcelProperty("éå®è®¢ååå·") |
| | | @ExcelProperty(value = "å
³è订å", index = 21) |
| | | private String orderNo; |
| | | |
| | | @Schema(description = "客æ·ç¾çº¦äººç¼å·", example = "18546") |
| | | private Long signContactId; |
| | | @Schema(description = "客æ·ç¾çº¦äºº", example = "å°è±") |
| | | @ExcelProperty("客æ·ç¾çº¦äºº") |
| | | @ExcelProperty(value = "客æ·ç¾çº¦äºº", index = 9) |
| | | private String signContactName; |
| | | |
| | | @Schema(description = "å
¬å¸ç¾çº¦äºº", example = "14036") |
| | | private Long signUserId; |
| | | @Schema(description = "å
¬å¸ç¾çº¦äºº", example = "å°æ") |
| | | @ExcelProperty("å
¬å¸ç¾çº¦äºº") |
| | | @ExcelProperty(value = "å
¬å¸ç¾çº¦äºº", index = 10) |
| | | private String signUserName; |
| | | |
| | | @Schema(description = "夿³¨", example = "ä½ ç") |
| | | @ExcelProperty("夿³¨") |
| | | @ExcelProperty(value = "夿³¨", index = 11) |
| | | private String remark; |
| | | |
| | | @Schema(description = "å建æ¶é´", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("å建æ¶é´") |
| | | @ExcelProperty(value = "å建æ¶é´", index = 18) |
| | | private LocalDateTime createTime; |
| | | |
| | | @Schema(description = "å建人", example = "25682") |
| | | @ExcelProperty("å建人") |
| | | private String creator; |
| | | |
| | | @Schema(description = "å建人åå", example = "test") |
| | | @ExcelProperty("å建人åå") |
| | | @ExcelProperty(value = "å建人", index = 19) |
| | | private String creatorName; |
| | | |
| | | @Schema(description = "æ´æ°æ¶é´", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("æ´æ°æ¶é´") |
| | | @ExcelProperty(value = "æ´æ°æ¶é´", index = 17) |
| | | private LocalDateTime updateTime; |
| | | |
| | | @Schema(description = "产åå表") |
| | |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()).map(CrmAuditStatusEnum::getStatus).toArray(Integer[]::new); |
| | | |
| | | public static String getNameByStatus(Integer status) { |
| | | if (status == null) return null; |
| | | for (CrmAuditStatusEnum e : values()) { |
| | | if (e.getStatus().equals(status)) return e.getName(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public Integer[] array() { |
| | | return ARRAYS; |
| | |
| | | @Operation(summary = "è·åç©æç²¾ç®å表ï¼å¯ç¨ç¶æï¼ç¨äºä¸æéæ©ï¼") |
| | | public CommonResult<List<MdmItemRespVO>> getItemSimpleList() { |
| | | List<MdmItemDO> list = itemService.getItemSimpleList(); |
| | | return success(BeanUtils.toBean(list, MdmItemRespVO.class)); |
| | | List<MdmItemRespVO> respList = BeanUtils.toBean(list, MdmItemRespVO.class); |
| | | // å¡«å
åä½åç§°çå
³èåæ®µï¼ç¡®ä¿ä¸æéæ©åå¯å¸¦åºåä½çä¿¡æ¯ |
| | | Map<Long, MdmUnitMeasureDO> unitMap = unitMeasureService.getUnitMeasureMap( |
| | | convertSet(respList, MdmItemRespVO::getUnitMeasureId)); |
| | | respList.forEach(resp -> { |
| | | MdmUnitMeasureDO unit = unitMap.get(resp.getUnitMeasureId()); |
| | | if (unit != null) { |
| | | resp.setUnitMeasureName(unit.getName()); |
| | | } |
| | | }); |
| | | return success(respList); |
| | | } |
| | | |
| | | /** |
| | |
| | | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemImportExcelVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemImportRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemSaveReqVO; |
| | |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.Collections; |
| | |
| | | // å¯¼åº Excel |
| | | ExcelUtils.write(response, "ç©æäº§å.xls", "æ°æ®", MesMdItemRespVO.class, |
| | | buildItemVOList(pageResult.getList())); |
| | | } |
| | | |
| | | @GetMapping("/get-import-template") |
| | | @Operation(summary = "è·å¾ç©æå¯¼å
¥æ¨¡æ¿") |
| | | public void importTemplate(HttpServletResponse response) throws IOException { |
| | | // æå¨åå»ºå¯¼åº demo |
| | | List<MesMdItemImportExcelVO> list = Collections.singletonList( |
| | | MesMdItemImportExcelVO.builder().code("ITEM001").name("èºä¸").specification("M6*20") |
| | | .unitMeasureCode("PCS").itemTypeId(1L).status(0).build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "ç©æå¯¼å
¥æ¨¡æ¿.xls", "ç©æå表", MesMdItemImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | | @Operation(summary = "导å
¥ç©æ") |
| | | @Parameters({ |
| | | @Parameter(name = "file", description = "Excel æä»¶", required = true), |
| | | @Parameter(name = "updateSupport", description = "æ¯å¦æ¯ææ´æ°ï¼é»è®¤ä¸º false", example = "true") |
| | | }) |
| | | @PreAuthorize("@ss.hasPermission('mes:md-item:import')") |
| | | public CommonResult<MesMdItemImportRespVO> importExcel(@RequestParam("file") MultipartFile file, |
| | | @RequestParam(value = "updateSupport", required = false, |
| | | defaultValue = "false") Boolean updateSupport) throws Exception { |
| | | List<MesMdItemImportExcelVO> list = ExcelUtils.read(file, MesMdItemImportExcelVO.class); |
| | | return success(itemService.importItemList(list, updateSupport)); |
| | | } |
| | | |
| | | // ==================== æ¼æ¥ VO ==================== |
| | |
| | | ErrorCode MD_ITEM_NOT_EXISTS = new ErrorCode(1_040_102_000, "ç©æä¸åå¨"); |
| | | ErrorCode MD_ITEM_CODE_DUPLICATE = new ErrorCode(1_040_102_001, "ç©æç¼ç å·²åå¨"); |
| | | ErrorCode MD_ITEM_NAME_DUPLICATE = new ErrorCode(1_040_102_002, "ç©æåç§°å·²åå¨"); |
| | | ErrorCode MD_ITEM_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_040_102_003, "导å
¥ç©ææ°æ®ä¸è½ä¸ºç©º"); |
| | | ErrorCode MD_ITEM_BATCH_REQUIRED = new ErrorCode(1_040_102_004, "å½åç©æå¯ç¨äºæ¹æ¬¡ç®¡çï¼è¯·éæ©æ¹æ¬¡"); |
| | | ErrorCode MD_ITEM_IS_DISABLE = new ErrorCode(1_040_102_005, "ç©æå·²ç¦ç¨"); |
| | | |
| | |
| | | package cn.iocoder.yudao.module.mes.service.md.item; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemImportExcelVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemImportRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; |
| | |
| | | * @return ç©ææ°é |
| | | */ |
| | | Long getItemCountByItemTypeId(Long itemTypeId); |
| | | |
| | | /** |
| | | * æ¹é导å
¥ç©æ |
| | | * |
| | | * @param importItems 导å
¥ç©æå表 |
| | | * @param updateSupport æ¯å¦æ¯ææ´æ° |
| | | * @return 导å
¥ç»æ |
| | | */ |
| | | MesMdItemImportRespVO importItemList(List<MesMdItemImportExcelVO> importItems, boolean updateSupport); |
| | | |
| | | /** |
| | | * åºäºè®¡éåä½ç¼å·ï¼è·å¾ç©ææ°é |
| | |
| | | |
| | | 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.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemImportExcelVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemImportRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemSaveReqVO; |
| | | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| | |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.md.item.MesMdItemMapper; |
| | | import cn.iocoder.yudao.module.mes.enums.md.MesMdItemTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum; |
| | | |
| | | import cn.iocoder.yudao.module.mes.enums.wm.BarcodeBizTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService; |
| | | import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService; |
| | |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.*; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| | |
| | | @Override |
| | | public Long getItemCountByUnitMeasureId(Long unitMeasureId) { |
| | | return itemMapper.selectCountByUnitMeasureId(unitMeasureId); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public MesMdItemImportRespVO importItemList(List<MesMdItemImportExcelVO> importItems, boolean updateSupport) { |
| | | // 1. åæ°æ ¡éª |
| | | if (CollUtil.isEmpty(importItems)) { |
| | | throw exception(MD_ITEM_IMPORT_LIST_IS_EMPTY); |
| | | } |
| | | |
| | | // 2. éåï¼é个å建 or æ´æ° |
| | | MesMdItemImportRespVO respVO = MesMdItemImportRespVO.builder() |
| | | .createCodes(new ArrayList<>()).updateCodes(new ArrayList<>()) |
| | | .failureCodes(new LinkedHashMap<>()).build(); |
| | | AtomicInteger index = new AtomicInteger(1); |
| | | importItems.forEach(importItem -> { |
| | | int currentIndex = index.getAndIncrement(); |
| | | // 2.1 æ ¡éªå段 |
| | | if (StrUtil.isBlank(importItem.getCode())) { |
| | | // 空ç¼ç æ¶èªå¨çæ |
| | | importItem.setCode(autoCodeRecordService.generateAutoCode(MesMdAutoCodeRuleCodeEnum.MD_ITEM_CODE.getCode())); |
| | | } |
| | | String key = importItem.getCode(); |
| | | if (StrUtil.isBlank(importItem.getName())) { |
| | | respVO.getFailureCodes().put(key, "ç©æåç§°ä¸è½ä¸ºç©º"); |
| | | return; |
| | | } |
| | | if (StrUtil.isBlank(importItem.getUnitMeasureCode())) { |
| | | respVO.getFailureCodes().put(key, "åä½ç¼ç ä¸è½ä¸ºç©º"); |
| | | return; |
| | | } |
| | | // å°åä½ç¼ç 转æ¢ä¸ºåä½ ID |
| | | MesMdUnitMeasureDO unitMeasure = unitMeasureService.getUnitMeasureByCode(importItem.getUnitMeasureCode()); |
| | | if (unitMeasure == null) { |
| | | respVO.getFailureCodes().put(key, "åä½ç¼ç [" + importItem.getUnitMeasureCode() + "]ä¸åå¨"); |
| | | return; |
| | | } |
| | | if (importItem.getItemTypeId() == null) { |
| | | respVO.getFailureCodes().put(key, "ç©æåç±»ç¼å·ä¸è½ä¸ºç©º"); |
| | | return; |
| | | } |
| | | // 2.2 æ ¡éªåç±»æ¯å¦åå¨ |
| | | try { |
| | | validateItemTypeExists(importItem.getItemTypeId()); |
| | | } catch (ServiceException ex) { |
| | | respVO.getFailureCodes().put(key, ex.getMessage()); |
| | | return; |
| | | } |
| | | |
| | | // 2.3 夿ï¼å建 or æ´æ° |
| | | MesMdItemDO existItem = itemMapper.selectByCode(importItem.getCode()); |
| | | if (existItem == null) { |
| | | // 2.3.1 å建 |
| | | try { |
| | | validateItemNameUnique(null, importItem.getName()); |
| | | } catch (ServiceException ex) { |
| | | respVO.getFailureCodes().put(key, ex.getMessage()); |
| | | return; |
| | | } |
| | | MesMdItemDO item = BeanUtils.toBean(importItem, MesMdItemDO.class); |
| | | item.setUnitMeasureId(unitMeasure.getId()); |
| | | item.setStatus(CommonStatusEnum.DISABLE.getStatus()); // é»è®¤ç¦ç¨ãä¿¡æ¯å®æåï¼åå¯ç¨ |
| | | clearStockIfNotSafe(item); |
| | | itemMapper.insert(item); |
| | | // èªå¨çææ¡ç |
| | | barcodeService.autoGenerateBarcode(BarcodeBizTypeEnum.ITEM.getValue(), |
| | | item.getId(), item.getCode(), item.getName()); |
| | | respVO.getCreateCodes().add(importItem.getCode()); |
| | | } else if (updateSupport) { |
| | | // 2.3.2 æ´æ° |
| | | try { |
| | | validateItemNameUnique(existItem.getId(), importItem.getName()); |
| | | } catch (ServiceException ex) { |
| | | respVO.getFailureCodes().put(key, ex.getMessage()); |
| | | return; |
| | | } |
| | | MesMdItemDO updateObj = BeanUtils.toBean(importItem, MesMdItemDO.class); |
| | | updateObj.setId(existItem.getId()); |
| | | updateObj.setUnitMeasureId(unitMeasure.getId()); |
| | | clearStockIfNotSafe(updateObj); |
| | | itemMapper.updateById(updateObj); |
| | | respVO.getUpdateCodes().add(importItem.getCode()); |
| | | } else { |
| | | // 䏿¯ææ´æ° |
| | | respVO.getFailureCodes().put(key, "ç©æç¼ç å·²åå¨"); |
| | | } |
| | | }); |
| | | return respVO; |
| | | } |
| | | |
| | | /** |
| | |
| | | @Schema(description = "ä»
æ¾ç¤ºå·²éè¿åå
¥å®¡æ¹çä¾åºå") |
| | | private Boolean approved; |
| | | |
| | | @Schema(description = "æé¤å·²éè¿åå
¥å®¡æ¹çä¾åºåï¼ç¨äºæ°å¢åå
¥æ¶é¿å
éå¤éæ©ï¼") |
| | | private Boolean excludeApproved; |
| | | |
| | | } |
| | |
| | | return success(true); |
| | | } |
| | | |
| | | @PutMapping("/update-info") |
| | | @Operation(summary = "é¨åæ´æ°ææ ä¿¡æ¯ï¼ä»
åå¸ä¸/ææ ä¸å¯ç¼è¾ï¼ææ 说æåèµè´¨è¦æ±ï¼") |
| | | @PreAuthorize("@ss.hasPermission('srm:tender-project:update')") |
| | | public CommonResult<Boolean> updateTenderProjectInfo(@Valid @RequestBody SrmTenderProjectPartialUpdateReqVO updateReqVO) { |
| | | tenderProjectService.updateTenderProjectPartial(updateReqVO); |
| | | return success(true); |
| | | } |
| | | |
| | | // ========== ç©æå表 ========== |
| | | |
| | | @PostMapping("/material/create") |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.srm.controller.admin.tender.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | @Schema(description = "管çåå° - SRM ææ é¡¹ç®é¨åæ´æ° Request VOï¼åå¸ä¸/ææ ä¸é¶æ®µï¼") |
| | | @Data |
| | | public class SrmTenderProjectPartialUpdateReqVO { |
| | | |
| | | @Schema(description = "项ç®ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "项ç®IDä¸è½ä¸ºç©º") |
| | | private Long id; |
| | | |
| | | @Schema(description = "ææ æè¿°", example = "æ¬æ¬¡ææ éè´é¢æä¸æ¹") |
| | | private String tenderDesc; |
| | | |
| | | @Schema(description = "èµè´¨è¦æ±", example = "éå
·å¤ISO9001认è¯") |
| | | private String qualificationRequirements; |
| | | |
| | | } |
| | |
| | | if (Boolean.TRUE.equals(reqVO.getApproved())) { |
| | | wrapper.apply("id IN (SELECT supplier_id FROM srm_supplier_apply WHERE apply_status = 40 AND supplier_id IS NOT NULL AND deleted = 0)"); |
| | | } |
| | | if (Boolean.TRUE.equals(reqVO.getExcludeApproved())) { |
| | | wrapper.apply("id NOT IN (SELECT supplier_id FROM srm_supplier_apply WHERE apply_status = 40 AND supplier_id IS NOT NULL AND deleted = 0)"); |
| | | } |
| | | return selectPage(reqVO, wrapper); |
| | | } |
| | | |
| | |
| | | .eq(SrmTenderBidDO::getBidNo, bidNo)); |
| | | } |
| | | |
| | | default long countByTenderProjectId(Long tenderProjectId) { |
| | | return selectCount(new LambdaQueryWrapperX<SrmTenderBidDO>() |
| | | .eq(SrmTenderBidDO::getTenderProjectId, tenderProjectId)); |
| | | } |
| | | |
| | | } |
| | |
| | | ErrorCode AWARD_SUPPLIER_NOT_SYNCED = new ErrorCode(1_040_500_014, "ä¾åºåæªåæ¥è³ERPï¼æ æ³çæéè´è®¢å"); |
| | | ErrorCode AWARD_QUOTE_NOT_EXISTS = new ErrorCode(1_040_500_015, "䏿 ä¾åºåæ¥ä»·ä¸åå¨"); |
| | | |
| | | // ç¶ææ ¡éªç²¾ç»åé误ç |
| | | ErrorCode TENDER_MATERIAL_LOCKED = new ErrorCode(1_040_500_022, "ç©ææ¸
åå·²éå®ï¼ä¸å
许å¢å æ¹"); |
| | | ErrorCode TENDER_BID_FORBIDDEN = new ErrorCode(1_040_500_023, "å½åç¶æä¸å
许æ°å¢ææ "); |
| | | ErrorCode TENDER_QUOTE_FORBIDDEN = new ErrorCode(1_040_500_024, "å½åç¶æä¸å
许æ¥ä»·æä½"); |
| | | ErrorCode TENDER_END_TIME_PASSED = new ErrorCode(1_040_500_025, "ææ æªæ¢æ¶é´å·²è¿ï¼ä¸å
许æ°å¢ææ "); |
| | | ErrorCode TENDER_PROJECT_LOCKED = new ErrorCode(1_040_500_026, "项ç®å·²éå®ï¼å½åç¶æä¸å
许æä½"); |
| | | ErrorCode TENDER_HAS_BIDS_CANNOT_DELETE = new ErrorCode(1_040_500_027, "å·²åå¨ææ æ°æ®ï¼ä¸å
许å é¤"); |
| | | ErrorCode TENDER_BID_FORBIDDEN_WITHDRAW = new ErrorCode(1_040_500_028, "å½åç¶æä¸å
è®¸æ¤æ "); |
| | | ErrorCode TENDER_EVALUATION_FORBIDDEN = new ErrorCode(1_040_500_029, "å½åç¶æä¸å
è®¸è¯æ æä½"); |
| | | ErrorCode TENDER_AWARD_FORBIDDEN = new ErrorCode(1_040_500_030, "å½åç¶æä¸å
è®¸å®æ æä½"); |
| | | |
| | | // ========== éç¨ ========== |
| | | ErrorCode QUOTE_MATERIAL_DUPLICATE = new ErrorCode(1_040_900_001, "è¯¥ææ å·²åå¨ç¸åç©æçæ¥ä»·"); |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.srm.enums; |
| | | |
| | | /** |
| | | * SRM æä½æ¥å¿å¸¸é |
| | | */ |
| | | public interface LogRecordConstants { |
| | | |
| | | // ======================= SRM_TENDER ææ é¡¹ç® ======================= |
| | | String LOG_TENDER_TYPE = "SRM ææ é¡¹ç®"; |
| | | String LOG_TENDER_UPDATE_SUB_TYPE = "æ´æ°ææ 项ç®"; |
| | | String LOG_TENDER_UPDATE_SUCCESS = "æ´æ°äºææ 项ç®ã{{#tenderName}}ãï¼" |
| | | + "ææ è¯´æï¼{{#oldTenderDesc}} â {{#newTenderDesc}}ï¼" |
| | | + "èµè´¨è¦æ±ï¼{{#oldQualification}} â {{#newQualification}}"; |
| | | |
| | | // ======================= SRM_BID ææ ======================= |
| | | String LOG_BID_TYPE = "SRM ææ "; |
| | | String LOG_BID_CREATE_SUB_TYPE = "åå»ºææ "; |
| | | String LOG_BID_CREATE_SUCCESS = "ä¾åºåå¯¹ææ é¡¹ç®ã{{#tenderName}}ãæäº¤äºææ ã{{#bidNo}}ã"; |
| | | String LOG_BID_WITHDRAW_SUB_TYPE = "æ¤æ "; |
| | | String LOG_BID_WITHDRAW_SUCCESS = "æ¤åäºææ ã{{#bidNo}}ã"; |
| | | |
| | | // ======================= SRM_QUOTE æ¥ä»· ======================= |
| | | String LOG_QUOTE_TYPE = "SRM æ¥ä»·"; |
| | | String LOG_QUOTE_CREATE_SUB_TYPE = "å建æ¥ä»·"; |
| | | String LOG_QUOTE_CREATE_SUCCESS = "æäº¤äºææ çä¾åºåæ¥ä»·"; |
| | | String LOG_QUOTE_UPDATE_SUB_TYPE = "æ´æ°æ¥ä»·"; |
| | | String LOG_QUOTE_UPDATE_SUCCESS = "æ´æ°äºææ çä¾åºåæ¥ä»·"; |
| | | |
| | | // ======================= SRM_EVALUATION è¯æ ======================= |
| | | String LOG_EVALUATION_TYPE = "SRM è¯æ "; |
| | | String LOG_EVALUATION_CREATE_SUB_TYPE = "åå»ºè¯æ "; |
| | | String LOG_EVALUATION_CREATE_SUCCESS = "å¯¹ææ é¡¹ç®è¿è¡äºè¯æ è¯å"; |
| | | String LOG_EVALUATION_UPDATE_SUB_TYPE = "æ´æ°è¯æ "; |
| | | String LOG_EVALUATION_UPDATE_SUCCESS = "æ´æ°äºè¯æ è®°å½"; |
| | | |
| | | // ======================= SRM_AWARD 宿 ======================= |
| | | String LOG_AWARD_TYPE = "SRM 宿 "; |
| | | String LOG_AWARD_CREATE_SUB_TYPE = "åå»ºå®æ "; |
| | | String LOG_AWARD_CREATE_SUCCESS = "å建äºå®æ ã{{#createReqVO.awardNo}}ã"; |
| | | String LOG_AWARD_APPROVE_SUB_TYPE = "审æ¹å®æ "; |
| | | String LOG_AWARD_APPROVE_SUCCESS = "审æ¹éè¿äºå®æ è®°å½"; |
| | | String LOG_AWARD_ORDER_SUB_TYPE = "çæéè´è®¢å"; |
| | | String LOG_AWARD_ORDER_SUCCESS = "宿 è®°å½çæäºéè´è®¢å"; |
| | | |
| | | } |
| | |
| | | private final Integer code; |
| | | private final String name; |
| | | |
| | | // ========== ç¶æå·¥å
·æ¹æ³ ========== |
| | | |
| | | /** DRAFT å
许å
¨å段ç¼è¾ */ |
| | | public static boolean canEditFullProject(Integer status) { |
| | | return DRAFT.getCode().equals(status); |
| | | } |
| | | |
| | | /** PUBLISHED æ BIDDING å
许é¨åç¼è¾ï¼ææ 说æãèµè´¨è¦æ±ï¼ */ |
| | | public static boolean canEditPartialProject(Integer status) { |
| | | return PUBLISHED.getCode().equals(status) || BIDDING.getCode().equals(status); |
| | | } |
| | | |
| | | /** DRAFT å
许ç¼è¾ç©ææ¸
å */ |
| | | public static boolean canEditMaterial(Integer status) { |
| | | return DRAFT.getCode().equals(status); |
| | | } |
| | | |
| | | /** PUBLISHED æ BIDDING å
许ä¾åºåææ */ |
| | | public static boolean canCreateBid(Integer status) { |
| | | return PUBLISHED.getCode().equals(status) || BIDDING.getCode().equals(status); |
| | | } |
| | | |
| | | /** PUBLISHED æ BIDDING å
许ä¾åºåæ¥ä»· */ |
| | | public static boolean canCreateOrUpdateQuote(Integer status) { |
| | | return PUBLISHED.getCode().equals(status) || BIDDING.getCode().equals(status); |
| | | } |
| | | |
| | | /** EVALUATING å
è®¸è¯æ æä½ */ |
| | | public static boolean canEvaluate(Integer status) { |
| | | return EVALUATING.getCode().equals(status); |
| | | } |
| | | |
| | | /** EVALUATING å
è®¸å®æ æä½ */ |
| | | public static boolean canAward(Integer status) { |
| | | return EVALUATING.getCode().equals(status); |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.srm.enums.BidStatusEnum; |
| | | import cn.iocoder.yudao.module.srm.enums.ErrorCodeConstants; |
| | | import cn.iocoder.yudao.module.srm.enums.TenderStatusEnum; |
| | | import com.mzt.logapi.starter.annotation.LogRecord; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | |
| | | import java.util.*; |
| | | import java.util.function.Function; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static cn.iocoder.yudao.module.srm.enums.LogRecordConstants.*; |
| | | |
| | | /** |
| | | * SRM 宿 管ç Service å®ç°ç±» |
| | |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @LogRecord(type = LOG_AWARD_TYPE, subType = LOG_AWARD_CREATE_SUB_TYPE, |
| | | bizNo = "{{#createReqVO.awardNo}}", success = LOG_AWARD_CREATE_SUCCESS) |
| | | public Long createAward(SrmBidAwardSaveReqVO createReqVO) { |
| | | // æ£æ¥ææ 项ç®ç¶æï¼ä»
EVALUATING å
许åå»ºå®æ |
| | | SrmTenderProjectDO project = tenderProjectMapper.selectById(createReqVO.getTenderProjectId()); |
| | | if (project == null || !TenderStatusEnum.canAward(project.getTenderStatus())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_AWARD_FORBIDDEN); |
| | | } |
| | | // æ ¡éªæ¯å¦å·²åå¨å®æ |
| | | SrmBidAwardDO existing = bidAwardMapper.selectByTenderProjectId(createReqVO.getTenderProjectId()); |
| | | if (existing != null) { |
| | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void deleteAward(Long id) { |
| | | SrmBidAwardDO award = validateAwardExists(id); |
| | | // ä»
å¾
审æ¹ç¶æå¯å é¤ |
| | | if (!AwardStatusEnum.PENDING_APPROVAL.getCode().equals(award.getAwardStatus())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_AWARD_FORBIDDEN); |
| | | } |
| | | bidAwardMapper.deleteById(id); |
| | | } |
| | | |
| | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void approveAward(Long id) { |
| | | SrmBidAwardDO award = validateAwardExists(id); |
| | | // æ ¡éªææ 项ç®ç¶æä¸ºè¯æ ä¸ |
| | | SrmTenderProjectDO project = tenderProjectMapper.selectById(award.getTenderProjectId()); |
| | | if (project == null || !TenderStatusEnum.canAward(project.getTenderStatus())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_AWARD_FORBIDDEN); |
| | | } |
| | | award.setAwardStatus(AwardStatusEnum.AWARDED.getCode()); |
| | | award.setApprovalTime(LocalDateTime.now()); |
| | | bidAwardMapper.updateById(award); |
| | | |
| | | // æ´æ°ææ 项ç®ç¶æä¸ºå·²å®æ |
| | | SrmTenderProjectDO project = tenderProjectMapper.selectById(award.getTenderProjectId()); |
| | | if (project != null) { |
| | | project.setTenderStatus(TenderStatusEnum.AWARDED.getCode()); |
| | | tenderProjectMapper.updateById(project); |
| | | } |
| | | project.setTenderStatus(TenderStatusEnum.AWARDED.getCode()); |
| | | tenderProjectMapper.updateById(project); |
| | | } |
| | | |
| | | @Override |
| | |
| | | SrmBidAwardDO award = validateAwardExists(id); |
| | | if (!AwardStatusEnum.AWARDED.getCode().equals(award.getAwardStatus())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.AWARD_STATUS_NOT_AWARDED); |
| | | } |
| | | // æ ¡éªææ 项ç®ç¶æä¸ºå·²å®æ |
| | | SrmTenderProjectDO project = tenderProjectMapper.selectById(award.getTenderProjectId()); |
| | | if (project == null || !TenderStatusEnum.AWARDED.getCode().equals(project.getTenderStatus())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_AWARD_FORBIDDEN); |
| | | } |
| | | |
| | | // 2. æ¥ SRM ä¾åºå |
| | |
| | | bidAwardMapper.updateById(award); |
| | | |
| | | // 9. æ´æ°ææ 项ç®ç¶æ |
| | | SrmTenderProjectDO project = tenderProjectMapper.selectById(award.getTenderProjectId()); |
| | | if (project != null) { |
| | | project.setTenderStatus(TenderStatusEnum.CLOSED.getCode()); |
| | | tenderProjectMapper.updateById(project); |
| | | } |
| | | project.setTenderStatus(TenderStatusEnum.CLOSED.getCode()); |
| | | tenderProjectMapper.updateById(project); |
| | | } |
| | | |
| | | private SrmBidAwardDO validateAwardExists(Long id) { |
| | |
| | | import cn.iocoder.yudao.module.srm.enums.ErrorCodeConstants; |
| | | import cn.iocoder.yudao.module.srm.enums.TenderStatusEnum; |
| | | import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; |
| | | import com.mzt.logapi.starter.annotation.LogRecord; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | |
| | | import java.time.LocalDateTime; |
| | | import java.util.Comparator; |
| | | import java.util.List; |
| | | |
| | | import static cn.iocoder.yudao.module.srm.enums.LogRecordConstants.*; |
| | | |
| | | /** |
| | | * SRM è¯æ 管ç Service å®ç°ç±» |
| | |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @LogRecord(type = LOG_EVALUATION_TYPE, subType = LOG_EVALUATION_CREATE_SUB_TYPE, |
| | | bizNo = "{{#createReqVO.tenderProjectId}}", success = LOG_EVALUATION_CREATE_SUCCESS) |
| | | public Long createEvaluation(SrmBidEvaluationSaveReqVO createReqVO) { |
| | | // æ£æ¥ææ 项ç®ç¶æï¼BIDDING æ EVALUATING æå
è®¸è¯æ |
| | | SrmTenderProjectDO project = tenderProjectMapper.selectById(createReqVO.getTenderProjectId()); |
| | | if (project == null) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_NOT_EXISTS); |
| | | } |
| | | Integer status = project.getTenderStatus(); |
| | | if (!TenderStatusEnum.BIDDING.getCode().equals(status) |
| | | && !TenderStatusEnum.EVALUATING.getCode().equals(status)) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_EVALUATION_FORBIDDEN); |
| | | } |
| | | |
| | | SrmBidEvaluationDO evaluation = BeanUtils.toBean(createReqVO, SrmBidEvaluationDO.class); |
| | | // 强å¶ç½®ç©º idï¼é¿å
åç«¯ä¼ å
¥å·²æ id 导è´ä¸»é®å²çªï¼ç±æ°æ®åºåºåèªå¨çæ |
| | | evaluation.setId(null); |
| | |
| | | evaluation.setEvaluationTime(LocalDateTime.now()); |
| | | bidEvaluationMapper.insert(evaluation); |
| | | // 馿¬¡è¯æ æ¶æ´æ°ææ 项ç®ç¶æä¸ºè¯æ ä¸ |
| | | SrmTenderProjectDO project = tenderProjectMapper.selectById(createReqVO.getTenderProjectId()); |
| | | if (project != null && TenderStatusEnum.BIDDING.getCode().equals(project.getTenderStatus())) { |
| | | if (TenderStatusEnum.BIDDING.getCode().equals(project.getTenderStatus())) { |
| | | project.setTenderStatus(TenderStatusEnum.EVALUATING.getCode()); |
| | | tenderProjectMapper.updateById(project); |
| | | } |
| | |
| | | SrmBidEvaluationDO existing = bidEvaluationMapper.selectById(updateReqVO.getId()); |
| | | if (existing == null) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.EVALUATION_NOT_EXISTS_TENDER); |
| | | } |
| | | // æ£æ¥ææ 项ç®ç¶æï¼ä»
EVALUATING å
è®¸æ´æ°è¯æ |
| | | SrmTenderProjectDO project = tenderProjectMapper.selectById(existing.getTenderProjectId()); |
| | | if (project == null || !TenderStatusEnum.canEvaluate(project.getTenderStatus())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_EVALUATION_FORBIDDEN); |
| | | } |
| | | SrmBidEvaluationDO evaluation = BeanUtils.toBean(updateReqVO, SrmBidEvaluationDO.class); |
| | | BigDecimal price = nvl(evaluation.getPriceScore()); |
| | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void calculateRanking(Long tenderProjectId) { |
| | | SrmTenderProjectDO project = tenderProjectMapper.selectById(tenderProjectId); |
| | | if (project == null || !TenderStatusEnum.canEvaluate(project.getTenderStatus())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_EVALUATION_FORBIDDEN); |
| | | } |
| | | List<SrmBidEvaluationDO> list = bidEvaluationMapper.selectListByTenderProjectId(tenderProjectId); |
| | | // æç»¼åè¯åéåºæå |
| | | list.sort(Comparator.comparing(e -> e.getCompositeScore() != null ? e.getCompositeScore() : BigDecimal.ZERO, Comparator.reverseOrder())); |
| | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createBidOpen(Long tenderProjectId) { |
| | | // æ ¡éªææ 项ç®åå¨ä¸ç¶æä¸ºåå¸ä¸ |
| | | SrmTenderProjectDO project = tenderProjectMapper.selectById(tenderProjectId); |
| | | if (project == null) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_NOT_EXISTS); |
| | | } |
| | | if (!TenderStatusEnum.PUBLISHED.getCode().equals(project.getTenderStatus())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_STATUS_NOT_PUBLISHED); |
| | | } |
| | | if (bidOpenMapper.selectByTenderProjectId(tenderProjectId) != null) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_STATUS_NOT_PUBLISHED); |
| | | } |
| | | // 弿 åèªå¨æ´æ°ææ 项ç®ç¶æä¸ºææ ä¸ |
| | | SrmTenderProjectDO project = tenderProjectMapper.selectById(tenderProjectId); |
| | | if (project != null && TenderStatusEnum.PUBLISHED.getCode().equals(project.getTenderStatus())) { |
| | | project.setTenderStatus(TenderStatusEnum.BIDDING.getCode()); |
| | | tenderProjectMapper.updateById(project); |
| | | } |
| | | project.setTenderStatus(TenderStatusEnum.BIDDING.getCode()); |
| | | tenderProjectMapper.updateById(project); |
| | | SrmBidOpenDO open = new SrmBidOpenDO(); |
| | | open.setTenderProjectId(tenderProjectId); |
| | | open.setOpenTime(LocalDateTime.now()); |
| | |
| | | import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.SrmTenderBidSaveReqVO; |
| | | import cn.iocoder.yudao.module.srm.dal.dataobject.SrmSupplierQuoteDO; |
| | | import cn.iocoder.yudao.module.srm.dal.dataobject.SrmTenderBidDO; |
| | | import cn.iocoder.yudao.module.srm.dal.dataobject.SrmTenderProjectDO; |
| | | import cn.iocoder.yudao.module.srm.dal.mysql.SrmSupplierApplyMapper; |
| | | import cn.iocoder.yudao.module.srm.dal.mysql.SrmSupplierQuoteMapper; |
| | | import cn.iocoder.yudao.module.srm.dal.mysql.SrmTenderBidMapper; |
| | |
| | | import cn.iocoder.yudao.module.srm.enums.ErrorCodeConstants; |
| | | import cn.iocoder.yudao.module.srm.enums.TenderStatusEnum; |
| | | import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; |
| | | import com.mzt.logapi.context.LogRecordContext; |
| | | import com.mzt.logapi.starter.annotation.LogRecord; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | import static cn.iocoder.yudao.module.srm.enums.LogRecordConstants.*; |
| | | |
| | | /** |
| | | * SRM ææ ç®¡ç Service å®ç°ç±» |
| | |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @LogRecord(type = LOG_BID_TYPE, subType = LOG_BID_CREATE_SUB_TYPE, |
| | | bizNo = "{{#createReqVO.bidNo}}", success = LOG_BID_CREATE_SUCCESS) |
| | | public Long createBid(SrmTenderBidSaveReqVO createReqVO) { |
| | | // æ ¡éªææ é¡¹ç®æ¯å¦åå¨ä¸ç¶ææ£ç¡® |
| | | validateTenderStatus(createReqVO.getTenderProjectId()); |
| | | // æ ¡éªææ 项ç®ç¶æï¼PUBLISHED/BIDDING æå
è®¸ææ ï¼ |
| | | SrmTenderProjectDO project = validateTenderStatus(createReqVO.getTenderProjectId()); |
| | | // æ£æ¥ææ æªæ¢æ¶é´ |
| | | if (project.getEndTime() != null && LocalDateTime.now().isAfter(project.getEndTime())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_END_TIME_PASSED); |
| | | } |
| | | // æ ¡éªä¾åºåæ¯å¦å·²éè¿åå
¥å®¡æ¹ |
| | | if (!supplierApplyMapper.existsApprovedBySupplierId(createReqVO.getSupplierId())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.BID_SUPPLIER_NOT_APPROVED); |
| | |
| | | bid.setBidStatus(BidStatusEnum.REGISTERED.getCode()); |
| | | bid.setBidTime(LocalDateTime.now()); |
| | | tenderBidMapper.insert(bid); |
| | | LogRecordContext.putVariable("bidNo", bid.getBidNo()); |
| | | LogRecordContext.putVariable("tenderName", project.getTenderName()); |
| | | return bid.getId(); |
| | | } |
| | | |
| | |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @LogRecord(type = LOG_BID_TYPE, subType = LOG_BID_WITHDRAW_SUB_TYPE, |
| | | bizNo = "{{#id}}", success = LOG_BID_WITHDRAW_SUCCESS) |
| | | public void withdrawBid(Long id) { |
| | | SrmTenderBidDO bid = validateBidExists(id); |
| | | // æ£æ¥ææ 项ç®ç¶æï¼ä»
PUBLISHED/BIDDING å
è®¸æ¤æ |
| | | SrmTenderProjectDO project = tenderProjectMapper.selectById(bid.getTenderProjectId()); |
| | | if (project == null || !TenderStatusEnum.canCreateOrUpdateQuote(project.getTenderStatus())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_BID_FORBIDDEN_WITHDRAW); |
| | | } |
| | | bid.setBidStatus(BidStatusEnum.WITHDRAWN.getCode()); |
| | | tenderBidMapper.updateById(bid); |
| | | // å 餿¥ä»· |
| | | supplierQuoteMapper.deleteByBidId(id); |
| | | LogRecordContext.putVariable("bidNo", bid.getBidNo()); |
| | | } |
| | | |
| | | // ========== æ¥ä»·ç®¡ç ========== |
| | | |
| | | @Override |
| | | @LogRecord(type = LOG_QUOTE_TYPE, subType = LOG_QUOTE_CREATE_SUB_TYPE, |
| | | bizNo = "{{#createReqVO.bidId}}", success = LOG_QUOTE_CREATE_SUCCESS) |
| | | public Long createQuote(SrmSupplierQuoteSaveReqVO createReqVO) { |
| | | // æ ¡éªææ ç¶æï¼æ¤æ åä¸å
许æ¥ä»·ï¼ |
| | | SrmTenderBidDO bid = validateBidNotWithdrawn(createReqVO.getBidId()); |
| | | // æ ¡éªææ 项ç®ç¶æï¼ä»
PUBLISHED/BIDDING å
许æ¥ä»· |
| | | SrmTenderProjectDO project = tenderProjectMapper.selectById(bid.getTenderProjectId()); |
| | | if (project == null || !TenderStatusEnum.canCreateOrUpdateQuote(project.getTenderStatus())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_QUOTE_FORBIDDEN); |
| | | } |
| | | // æ ¡éªå䏿æ ä¸ç©æä¸å¯é夿¥ä»· |
| | | if (supplierQuoteMapper.existsByBidAndMaterial(createReqVO.getBidId(), createReqVO.getTenderMaterialId())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.QUOTE_MATERIAL_DUPLICATE); |
| | |
| | | @Override |
| | | public void updateQuote(SrmSupplierQuoteSaveReqVO updateReqVO) { |
| | | // æ ¡éªææ ç¶æï¼æ¤æ åä¸å
许æ¥ä»·ï¼ |
| | | validateBidNotWithdrawn(updateReqVO.getBidId()); |
| | | SrmTenderBidDO bid = validateBidNotWithdrawn(updateReqVO.getBidId()); |
| | | // æ ¡éªææ 项ç®ç¶æï¼ä»
PUBLISHED/BIDDING å
许æ¥ä»· |
| | | SrmTenderProjectDO project = tenderProjectMapper.selectById(bid.getTenderProjectId()); |
| | | if (project == null || !TenderStatusEnum.canCreateOrUpdateQuote(project.getTenderStatus())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_QUOTE_FORBIDDEN); |
| | | } |
| | | // æ ¡éªå䏿æ ä¸ç©æä¸å¯é夿¥ä»·ï¼æé¤èªèº«ï¼ |
| | | SrmSupplierQuoteDO existing = supplierQuoteMapper.selectById(updateReqVO.getId()); |
| | | if (existing != null && !existing.getTenderMaterialId().equals(updateReqVO.getTenderMaterialId())) { |
| | |
| | | return bid; |
| | | } |
| | | |
| | | private void validateTenderStatus(Long tenderProjectId) { |
| | | if (tenderProjectMapper.selectById(tenderProjectId) == null) { |
| | | private SrmTenderProjectDO validateTenderStatus(Long tenderProjectId) { |
| | | SrmTenderProjectDO project = tenderProjectMapper.selectById(tenderProjectId); |
| | | if (project == null) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_NOT_EXISTS); |
| | | } |
| | | if (!TenderStatusEnum.canCreateBid(project.getTenderStatus())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_BID_FORBIDDEN); |
| | | } |
| | | return project; |
| | | } |
| | | } |
| | |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.SrmTenderProjectPageReqVO; |
| | | import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.SrmTenderProjectPartialUpdateReqVO; |
| | | import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.SrmTenderProjectSaveReqVO; |
| | | import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.SrmTenderMaterialSaveReqVO; |
| | | import cn.iocoder.yudao.module.srm.dal.dataobject.SrmTenderMaterialDO; |
| | |
| | | |
| | | Long createTenderProject(@Valid SrmTenderProjectSaveReqVO createReqVO); |
| | | void updateTenderProject(@Valid SrmTenderProjectSaveReqVO updateReqVO); |
| | | void updateTenderProjectPartial(@Valid SrmTenderProjectPartialUpdateReqVO updateReqVO); |
| | | void deleteTenderProject(Long id); |
| | | SrmTenderProjectDO getTenderProject(Long id); |
| | | PageResult<SrmTenderProjectDO> getTenderProjectPage(SrmTenderProjectPageReqVO pageReqVO); |
| | |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.SrmTenderMaterialSaveReqVO; |
| | | import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.SrmTenderProjectPageReqVO; |
| | | import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.SrmTenderProjectPartialUpdateReqVO; |
| | | import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.SrmTenderProjectSaveReqVO; |
| | | import cn.iocoder.yudao.module.srm.dal.dataobject.SrmBidAwardDO; |
| | | import cn.iocoder.yudao.module.srm.dal.dataobject.SrmTenderMaterialDO; |
| | | import cn.iocoder.yudao.module.srm.dal.dataobject.SrmTenderProjectDO; |
| | | import cn.iocoder.yudao.module.srm.dal.mysql.SrmBidAwardMapper; |
| | | import cn.iocoder.yudao.module.srm.dal.mysql.SrmTenderBidMapper; |
| | | import cn.iocoder.yudao.module.srm.dal.mysql.SrmTenderMaterialMapper; |
| | | import cn.iocoder.yudao.module.srm.dal.mysql.SrmTenderProjectMapper; |
| | | import cn.iocoder.yudao.module.srm.enums.AwardStatusEnum; |
| | | import cn.iocoder.yudao.module.srm.enums.ErrorCodeConstants; |
| | | import cn.iocoder.yudao.module.srm.enums.TenderStatusEnum; |
| | | import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; |
| | | import com.mzt.logapi.context.LogRecordContext; |
| | | import com.mzt.logapi.starter.annotation.LogRecord; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.validation.annotation.Validated; |
| | |
| | | import java.util.Map; |
| | | import java.util.function.Function; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static cn.iocoder.yudao.module.srm.enums.LogRecordConstants.*; |
| | | |
| | | @Service |
| | | @Validated |
| | |
| | | private SrmTenderMaterialMapper tenderMaterialMapper; |
| | | @Resource |
| | | private SrmBidAwardMapper bidAwardMapper; |
| | | @Resource |
| | | private SrmTenderBidMapper tenderBidMapper; |
| | | |
| | | @Override |
| | | public Long createTenderProject(SrmTenderProjectSaveReqVO createReqVO) { |
| | |
| | | } |
| | | |
| | | @Override |
| | | @LogRecord(type = LOG_TENDER_TYPE, subType = LOG_TENDER_UPDATE_SUB_TYPE, |
| | | bizNo = "{{#updateReqVO.id}}", success = LOG_TENDER_UPDATE_SUCCESS) |
| | | public void updateTenderProject(SrmTenderProjectSaveReqVO updateReqVO) { |
| | | SrmTenderProjectDO project = validateTenderExists(updateReqVO.getId()); |
| | | if (!TenderStatusEnum.DRAFT.getCode().equals(project.getTenderStatus())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_STATUS_NOT_DRAFT); |
| | | Integer status = project.getTenderStatus(); |
| | | |
| | | // èç¨¿ç¶æï¼å
¨å段å¯ç¼è¾ |
| | | if (TenderStatusEnum.canEditFullProject(status)) { |
| | | SrmTenderProjectDO updateObj = BeanUtils.toBean(updateReqVO, SrmTenderProjectDO.class); |
| | | updateObj.setTenderStatus(status); // ç¶æä¸å
许åç«¯ä¼ å
¥è¦ç |
| | | tenderProjectMapper.updateById(updateObj); |
| | | LogRecordContext.putVariable("tenderName", project.getTenderName()); |
| | | LogRecordContext.putVariable("oldTenderDesc", project.getTenderDesc()); |
| | | LogRecordContext.putVariable("newTenderDesc", updateReqVO.getTenderDesc()); |
| | | LogRecordContext.putVariable("oldQualification", project.getQualificationRequirements()); |
| | | LogRecordContext.putVariable("newQualification", updateReqVO.getQualificationRequirements()); |
| | | return; |
| | | } |
| | | SrmTenderProjectDO updateObj = BeanUtils.toBean(updateReqVO, SrmTenderProjectDO.class); |
| | | tenderProjectMapper.updateById(updateObj); |
| | | |
| | | // åå¸ä¸/ææ ä¸ï¼ä»
å
è®¸ä¿®æ¹ææ 说æåèµè´¨è¦æ± |
| | | if (TenderStatusEnum.canEditPartialProject(status)) { |
| | | SrmTenderProjectDO updateObj = new SrmTenderProjectDO(); |
| | | updateObj.setId(updateReqVO.getId()); |
| | | updateObj.setTenderDesc(updateReqVO.getTenderDesc()); |
| | | updateObj.setQualificationRequirements(updateReqVO.getQualificationRequirements()); |
| | | tenderProjectMapper.updateById(updateObj); |
| | | LogRecordContext.putVariable("tenderName", project.getTenderName()); |
| | | LogRecordContext.putVariable("oldTenderDesc", project.getTenderDesc()); |
| | | LogRecordContext.putVariable("newTenderDesc", updateReqVO.getTenderDesc()); |
| | | LogRecordContext.putVariable("oldQualification", project.getQualificationRequirements()); |
| | | LogRecordContext.putVariable("newQualification", updateReqVO.getQualificationRequirements()); |
| | | return; |
| | | } |
| | | |
| | | // å
¶ä»ç¶æï¼ä¸å
许ç¼è¾ |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_PROJECT_LOCKED); |
| | | } |
| | | |
| | | @Override |
| | |
| | | SrmTenderProjectDO project = validateTenderExists(id); |
| | | if (!TenderStatusEnum.DRAFT.getCode().equals(project.getTenderStatus())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_STATUS_NOT_DRAFT); |
| | | } |
| | | // æ£æ¥æ¯å¦å·²æææ æ°æ® |
| | | if (tenderBidMapper.countByTenderProjectId(id) > 0) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_HAS_BIDS_CANNOT_DELETE); |
| | | } |
| | | tenderMaterialMapper.deleteByTenderProjectId(id); |
| | | tenderProjectMapper.deleteById(id); |
| | |
| | | if (TenderStatusEnum.CLOSED.getCode().equals(project.getTenderStatus())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_STATUS_ALREADY_CLOSED); |
| | | } |
| | | // èç¨¿ç¶æä¸å
è®¸ç´æ¥å
³é |
| | | if (TenderStatusEnum.DRAFT.getCode().equals(project.getTenderStatus())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_PROJECT_LOCKED); |
| | | } |
| | | project.setTenderStatus(TenderStatusEnum.CLOSED.getCode()); |
| | | tenderProjectMapper.updateById(project); |
| | | } |
| | |
| | | tenderProjectMapper.updateById(project); |
| | | } |
| | | |
| | | @Override |
| | | @LogRecord(type = LOG_TENDER_TYPE, subType = LOG_TENDER_UPDATE_SUB_TYPE, |
| | | bizNo = "{{#updateReqVO.id}}", success = LOG_TENDER_UPDATE_SUCCESS) |
| | | public void updateTenderProjectPartial(SrmTenderProjectPartialUpdateReqVO updateReqVO) { |
| | | SrmTenderProjectDO project = validateTenderExists(updateReqVO.getId()); |
| | | if (!TenderStatusEnum.canEditPartialProject(project.getTenderStatus())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_PROJECT_LOCKED); |
| | | } |
| | | SrmTenderProjectDO updateObj = new SrmTenderProjectDO(); |
| | | updateObj.setId(updateReqVO.getId()); |
| | | updateObj.setTenderDesc(updateReqVO.getTenderDesc()); |
| | | updateObj.setQualificationRequirements(updateReqVO.getQualificationRequirements()); |
| | | tenderProjectMapper.updateById(updateObj); |
| | | LogRecordContext.putVariable("tenderName", project.getTenderName()); |
| | | LogRecordContext.putVariable("oldTenderDesc", project.getTenderDesc()); |
| | | LogRecordContext.putVariable("newTenderDesc", updateReqVO.getTenderDesc()); |
| | | LogRecordContext.putVariable("oldQualification", project.getQualificationRequirements()); |
| | | LogRecordContext.putVariable("newQualification", updateReqVO.getQualificationRequirements()); |
| | | } |
| | | |
| | | // ========== ç©æå表 ========== |
| | | |
| | | @Override |
| | | public void createMaterial(SrmTenderMaterialSaveReqVO createReqVO) { |
| | | SrmTenderProjectDO project = validateTenderExists(createReqVO.getTenderProjectId()); |
| | | if (!TenderStatusEnum.canEditMaterial(project.getTenderStatus())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_MATERIAL_LOCKED); |
| | | } |
| | | SrmTenderMaterialDO material = BeanUtils.toBean(createReqVO, SrmTenderMaterialDO.class); |
| | | tenderMaterialMapper.insert(material); |
| | | } |
| | | |
| | | @Override |
| | | public void updateMaterial(SrmTenderMaterialSaveReqVO updateReqVO) { |
| | | SrmTenderMaterialDO existing = tenderMaterialMapper.selectById(updateReqVO.getId()); |
| | | if (existing != null) { |
| | | SrmTenderProjectDO project = tenderProjectMapper.selectById(existing.getTenderProjectId()); |
| | | if (project != null && !TenderStatusEnum.canEditMaterial(project.getTenderStatus())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_MATERIAL_LOCKED); |
| | | } |
| | | } |
| | | SrmTenderMaterialDO updateObj = BeanUtils.toBean(updateReqVO, SrmTenderMaterialDO.class); |
| | | tenderMaterialMapper.updateById(updateObj); |
| | | } |
| | | |
| | | @Override |
| | | public void deleteMaterial(Long id) { |
| | | SrmTenderMaterialDO material = tenderMaterialMapper.selectById(id); |
| | | if (material != null) { |
| | | SrmTenderProjectDO project = tenderProjectMapper.selectById(material.getTenderProjectId()); |
| | | if (project != null && !TenderStatusEnum.canEditMaterial(project.getTenderStatus())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_MATERIAL_LOCKED); |
| | | } |
| | | } |
| | | tenderMaterialMapper.deleteById(id); |
| | | } |
| | | |