9 天以前 2e84a447af471fe5ada907c28849838a6bc3a340
1.仓储物流-转移产品模块
已添加10个文件
已修改75个文件
2897 ■■■■ 文件已修改
.claude/settings.local.json 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/SALES_SHIPMENT_OUT_API_SUMMARY.md 652 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/material_stock_adjust.md 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/sales_notice_to_product_sales.md 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/sales_outbound_flow.md 293 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/arrivalnotice/MesWmArrivalNoticeLineController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/MesWmBatchController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemconsume/MesWmItemConsumeLineController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/MesWmItemReceiptDetailController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/MesWmItemReceiptLineController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/MesWmMaterialStockController.java 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/vo/MesWmMaterialStockAdjustReqVO.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/MesWmMiscIssueLineController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/MesWmMiscReceiptLineController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/outsourceissue/MesWmOutsourceIssueDetailController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/outsourceissue/MesWmOutsourceIssueLineController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/outsourcereceipt/MesWmOutsourceReceiptDetailController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/outsourcereceipt/MesWmOutsourceReceiptLineController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/packages/MesWmPackageController.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/packages/MesWmPackageLineController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/MesWmProductIssueDetailController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/MesWmProductIssueLineController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productproduce/MesWmProductProduceLineController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productreceipt/MesWmProductReceiptController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productreceipt/MesWmProductReceiptDetailController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productreceipt/MesWmProductReceiptLineController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/MesWmProductSalesDetailController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/MesWmProductSalesLineController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/MesWmReturnIssueDetailController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/MesWmReturnIssueLineController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnsales/MesWmReturnSalesDetailController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnsales/MesWmReturnSalesLineController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/MesWmReturnVendorDetailController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/MesWmReturnVendorLineController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/salesnotice/MesWmSalesNoticeController.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/salesnotice/MesWmSalesNoticeLineController.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/salesnotice/vo/MesWmSalesNoticePageReqVO.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/salesnotice/vo/MesWmSalesNoticeRespVO.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/salesnotice/vo/line/MesWmSalesNoticeLineRespVO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/MesWmSnController.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/MesWmStockTakingTaskLineController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/MesWmStockTakingTaskResultController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transfer/MesWmTransferDetailController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transfer/MesWmTransferLineController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/mdm/MesMdmItemDO.java 211 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/salesnotice/MesWmSalesNoticeDO.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/salesnotice/MesWmSalesNoticeLineDO.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/mdm/MesMdmItemMapper.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/salesnotice/MesWmSalesNoticeMapper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/DictTypeConstants.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/MesBizTypeConstants.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmOutStatusEnum.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/mdm/MesMdmItemService.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/mdm/MesMdmItemServiceImpl.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeLineServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/batch/MesWmBatchServiceImpl.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockService.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImpl.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueLineServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptLineServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/outsourceissue/MesWmOutsourceIssueDetailServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/outsourceissue/MesWmOutsourceIssueLineServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/outsourcereceipt/MesWmOutsourceReceiptDetailServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/outsourcereceipt/MesWmOutsourceReceiptLineServiceImpl.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/outsourcereceipt/MesWmOutsourceReceiptServiceImpl.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/packages/MesWmPackageLineServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueLineServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productreceipt/MesWmProductReceiptLineServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesDetailServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesLineServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueLineServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueServiceImpl.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesLineServiceImpl.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesServiceImpl.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorDetailServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorLineServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/salesnotice/MesWmSalesNoticeLineServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/salesnotice/MesWmSalesNoticeService.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/salesnotice/MesWmSalesNoticeServiceImpl.java 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/sn/MesWmSnServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/MesWmTransactionServiceImpl.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transfer/MesWmTransferLineServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.claude/settings.local.json
@@ -23,7 +23,14 @@
      "Bash(mysql *)",
      "mcp__designcomputer-mysql_mcp_server__execute_sql",
      "mcp__designcomputer-mysql_mcp_server__get_schema_info",
      "mcp__designcomputer-mysql_mcp_server__get_table_sample"
      "mcp__designcomputer-mysql_mcp_server__get_table_sample",
      "Bash(mvn clean *)",
      "Bash(python3)",
      "Bash(cat)",
      "Bash(chmod +x /tmp/fix_controller.sh)",
      "Bash(/tmp/fix_controller.sh)",
      "Bash(chmod +x /tmp/fix2.sh)",
      "Bash(/tmp/fix2.sh)"
    ],
    "deny": [
      "Bash(rm -rf *)",
docs/SALES_SHIPMENT_OUT_API_SUMMARY.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,652 @@
# é”€å”®å‘货出库流程 - API接口与字段汇总
## æµç¨‹å›¾
```
┌─────────────┐    â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”    â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”    â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”
│  é”€å”®è®¢å•   â”‚───>│ å‘货通知单  â”‚───>│ é”€å”®å‡ºåº“单  â”‚───>│  å‡ºåº“完成   â”‚
│ (ERP模块)   â”‚    â”‚  (MES模块)  â”‚    â”‚  (MES模块)  â”‚    â”‚  çŠ¶æ€å›žå†™   â”‚
└─────────────┘    â””─────────────┘    â””─────────────┘    â””─────────────┘
       â”‚                  â”‚                  â”‚                  â”‚
       â–¼                  â–¼                  â–¼                  â–¼
  å‡ºåº“状态同步      å‡ºåº“状态同步       æ‰§è¡Œå‡ºåº“           çŠ¶æ€å›žå†™ä¸Šæ¸¸
```
---
## ä¸€ã€é”€å”®è®¢å• (ERP模块)
**文件路径:** `src/api/erp/sale/order/index.ts`
### æŸ¥è¯¢æŽ¥å£
| æ–¹æ³• | è·¯å¾„ | è¯´æ˜Ž |
|------|------|------|
| GET | `/erp/sale-order/page` | åˆ†é¡µæŸ¥è¯¢ |
| GET | `/erp/sale-order/get?id={id}` | è¯¦æƒ…查询 |
| GET | `/erp/sale-order/item/list-by-order-id?orderId={orderId}` | æŸ¥è¯¢è®¢å•明细列表 |
### æŽ¥å£å®šä¹‰
```typescript
export namespace ErpSaleOrderApi {
  /** é”€å”®è®¢å•信息 */
  export interface SaleOrder {
    id?: number;              // è®¢å•ID
    no: string;               // é”€å”®è®¢å•号
    customerId: number;       // å®¢æˆ·ID
    customerName?: string;    // å®¢æˆ·åç§°
    orderTime: Date;          // è®¢å•æ—¶é—´
    totalCount: number;       // åˆè®¡æ•°é‡
    totalPrice: number;       // åˆè®¡é‡‘额
    status: number;           // çŠ¶æ€ï¼š10-未审核, 20-已审核, 30-已作废
    outStatus?: number;       // å‡ºåº“状态:0-未出库, 1-部分出库, 2-全部出库
    outCount: number;         // é”€å”®å‡ºåº“数量
    inCount?: number;         // é‡‡è´­å…¥åº“数量
    returnCount: number;      // é”€å”®é€€è´§æ•°é‡
    items?: SaleOrderItem[];  // é”€å”®è®¢å•明细
  }
  /** é”€å”®è®¢å•明细 */
  export interface SaleOrderItem {
    id?: number;              // æ˜Žç»†ID
    seq?: number;             // åºå·
    orderId?: number;         // è®¢å•ID
    productId?: number;       // äº§å“ID
    productName?: string;     // äº§å“åç§°
    productBarCode?: string;  // äº§å“æ¡ç 
    productUnitName?: string; // å•位
    productPrice?: number;    // å•ä»·
    count?: number;           // æ•°é‡
    outCount?: number;        // å‡ºåº“数量
    taxPercent?: number;      // ç¨Žçއ
    taxPrice?: number;        // ç¨Žé¢
    remark?: string;          // å¤‡æ³¨
  }
}
```
### çŠ¶æ€æžšä¸¾
```typescript
// é”€å”®è®¢å•状态
const SaleOrderStatus = {
  UN_AUDITED: 10,    // æœªå®¡æ ¸
  AUDITED: 20,       // å·²å®¡æ ¸
  CANCELLED: 30,     // å·²ä½œåºŸ
}
// é”€å”®è®¢å•出库状态
const SaleOrderOutStatus = {
  NONE: 0,           // æœªå‡ºåº“
  PARTIAL: 1,        // éƒ¨åˆ†å‡ºåº“
  ALL: 2,            // å…¨éƒ¨å‡ºåº“
}
```
---
## äºŒã€å‘货通知单 (MES模块)
**文件路径:** `src/api/mes/wm/salesnotice/index.ts`
### æŸ¥è¯¢æŽ¥å£
| æ–¹æ³• | è·¯å¾„ | è¯´æ˜Ž |
|------|------|------|
| GET | `/mes/wm/sales-notice/page` | åˆ†é¡µæŸ¥è¯¢ |
| GET | `/mes/wm/sales-notice/get?id={id}` | è¯¦æƒ…查询 |
| POST | `/mes/wm/sales-notice/create` | åˆ›å»º |
| PUT | `/mes/wm/sales-notice/update` | ä¿®æ”¹ |
| DELETE | `/mes/wm/sales-notice/delete?id={id}` | åˆ é™¤ |
| PUT | `/mes/wm/sales-notice/submit?id={id}` | æäº¤ |
| POST | `/mes/wm/sales-notice/generate-from-sale-order` | ä»Žé”€å”®è®¢å•生成 |
| POST | `/mes/wm/sales-notice/generate-product-sales` | ç”Ÿæˆé”€å”®å‡ºåº“单 |
### æŽ¥å£å®šä¹‰
```typescript
export namespace MesWmSalesNoticeApi {
  /** å‘货通知单 */
  export interface SalesNotice {
    id?: number;                    // é€šçŸ¥å•ID
    code?: string;                  // é€šçŸ¥å•号
    name?: string;                  // é€šçŸ¥å•名称
    saleOrderId?: number;           // é”€å”®è®¢å•ID
    saleOrderCode?: string;         // é”€å”®è®¢å•号
    clientId?: number;              // å®¢æˆ·ID
    clientName?: string;            // å®¢æˆ·åç§°
    salesDate?: Date;               // å‘货日期
    recipientName?: string;         // æ”¶è´§äºº
    recipientTelephone?: string;    // è”系方式
    recipientAddress?: string;      // æ”¶è´§åœ°å€
    status?: number;                // å•据状态:0-草稿, 20-待出库, 30-已完成
    outStatus?: number;             // å‡ºåº“状态:0-未出库, 1-部分出库, 2-全部出库
    remark?: string;                // å¤‡æ³¨
    createTime?: Date;              // åˆ›å»ºæ—¶é—´
  }
  /** åˆ›å»º/修改请求 */
  export interface SalesNoticeSaveReq {
    id?: number;                    // é€šçŸ¥å•ID(修改时必填)
    code: string;                   // é€šçŸ¥å•号
    name: string;                   // é€šçŸ¥å•名称
    clientId: number;               // å®¢æˆ·ID
    saleOrderId?: number;           // é”€å”®è®¢å•ID
    saleOrderCode?: string;         // é”€å”®è®¢å•号
    salesDate: Date;                // å‘货日期
    recipientName?: string;         // æ”¶è´§äºº
    recipientTelephone?: string;    // è”系方式
    recipientAddress?: string;      // æ”¶è´§åœ°å€
    remark?: string;                // å¤‡æ³¨
  }
}
/** æŸ¥è¯¢åˆ†é¡µ */
export function getSalesNoticePage(params: PageParam): Promise<PageResult<SalesNotice>>
/** æŸ¥è¯¢è¯¦æƒ… */
export function getSalesNotice(id: number): Promise<SalesNotice>
/** åˆ›å»ºå‘货通知单 */
export function createSalesNotice(data: SalesNoticeSaveReq): Promise<number>
/** ä¿®æ”¹å‘货通知单 */
export function updateSalesNotice(data: SalesNoticeSaveReq): Promise<boolean>
/** åˆ é™¤å‘货通知单 */
export function deleteSalesNotice(id: number): Promise<boolean>
/** æäº¤å‘货通知单 */
export function submitSalesNotice(id: number): Promise<boolean>
/** ä»Žé”€å”®è®¢å•生成发货通知单 */
export function generateFromSaleOrder(saleOrderId: number): Promise<number>
/** ä»Žå‘货通知单生成销售出库单 */
export function generateProductSales(id: number): Promise<number>
```
### è¡Œè¡¨æŽ¥å£
**文件路径:** `src/api/mes/wm/salesnotice/line/index.ts`
| æ–¹æ³• | è·¯å¾„ | è¯´æ˜Ž |
|------|------|------|
| GET | `/mes/wm/sales-notice-line/page` | åˆ†é¡µæŸ¥è¯¢ |
| GET | `/mes/wm/sales-notice-line/get?id={id}` | è¯¦æƒ…查询 |
| POST | `/mes/wm/sales-notice-line/create` | åˆ›å»º |
| PUT | `/mes/wm/sales-notice-line/update` | ä¿®æ”¹ |
| DELETE | `/mes/wm/sales-notice-line/delete?id={id}` | åˆ é™¤ |
```typescript
export namespace MesWmSalesNoticeLineApi {
  /** å‘货通知单行 */
  export interface SalesNoticeLine {
    id?: number;                    // è¡ŒID
    noticeId?: number;              // é€šçŸ¥å•ID
    saleOrderItemId?: number;       // é”€å”®è®¢å•明细ID
    itemId?: number;                // ç‰©æ–™ID
    itemCode?: string;              // ç‰©æ–™ç¼–码
    itemName?: string;              // ç‰©æ–™åç§°
    specification?: string;         // è§„格型号
    unitMeasureName?: string;       // å•位
    batchId?: number;               // æ‰¹æ¬¡ID
    batchCode?: string;             // æ‰¹æ¬¡å·
    quantity?: number;              // å‘货数量
    outCount?: number;              // å·²å‡ºåº“数量
    oqcCheckFlag?: boolean;         // æ˜¯å¦æ£€éªŒ
    remark?: string;                // å¤‡æ³¨
    createTime?: Date;              // åˆ›å»ºæ—¶é—´
  }
  /** åˆ›å»º/修改请求 */
  export interface SalesNoticeLineSaveReq {
    id?: number;                    // è¡ŒID(修改时必填)
    noticeId: number;               // é€šçŸ¥å•ID
    saleOrderItemId?: number;       // é”€å”®è®¢å•明细ID
    itemId: number;                 // ç‰©æ–™ID
    batchId?: number;               // æ‰¹æ¬¡ID
    batchCode?: string;             // æ‰¹æ¬¡å·
    quantity: number;               // å‘货数量
    oqcCheckFlag?: boolean;         // æ˜¯å¦æ£€éªŒ
    remark?: string;                // å¤‡æ³¨
  }
}
```
### çŠ¶æ€æžšä¸¾
```typescript
// å‘货通知单状态
const MesWmSalesNoticeStatusEnum = {
  PREPARE: 0,        // è‰ç¨¿
  APPROVED: 20,      // å¾…出库(已审核)
  FINISHED: 30,      // å·²å®Œæˆ
}
// å‘货通知单出库状态
const MesWmSalesNoticeOutStatusEnum = {
  NONE: 0,           // æœªå‡ºåº“
  PARTIAL: 1,        // éƒ¨åˆ†å‡ºåº“
  ALL: 2,            // å…¨éƒ¨å‡ºåº“
}
```
---
## ä¸‰ã€é”€å”®å‡ºåº“单 (MES模块)
**文件路径:** `src/api/mes/wm/productsales/index.ts`
### æŸ¥è¯¢æŽ¥å£
| æ–¹æ³• | è·¯å¾„ | è¯´æ˜Ž |
|------|------|------|
| GET | `/mes/wm/product-sales/page` | åˆ†é¡µæŸ¥è¯¢ |
| GET | `/mes/wm/product-sales/get?id={id}` | è¯¦æƒ…查询 |
| POST | `/mes/wm/product-sales/create` | åˆ›å»º |
| PUT | `/mes/wm/product-sales/update` | ä¿®æ”¹ |
| DELETE | `/mes/wm/product-sales/delete?id={id}` | åˆ é™¤ |
| PUT | `/mes/wm/product-sales/submit?id={id}` | æäº¤ |
| PUT | `/mes/wm/product-sales/stock?id={id}` | æ‰§è¡Œæ‹£è´§ |
| PUT | `/mes/wm/product-sales/shipping` | å¡«å†™è¿å• |
| PUT | `/mes/wm/product-sales/finish?id={id}` | æ‰§è¡Œå‡ºåº“ |
| PUT | `/mes/wm/product-sales/cancel?id={id}` | å–消 |
| GET | `/mes/wm/product-sales/check-quantity?id={id}` | æ ¡éªŒæ•°é‡ |
### æŽ¥å£å®šä¹‰
```typescript
export namespace MesWmProductSalesApi {
  /** é”€å”®å‡ºåº“单 */
  export interface ProductSales {
    id?: number;                    // å‡ºåº“单ID
    code?: string;                  // å‡ºåº“单号
    name?: string;                  // å‡ºåº“单名称
    noticeId?: number;              // å‘货通知单ID
    noticeCode?: string;            // å‘货通知单号
    saleOrderId?: number;           // é”€å”®è®¢å•ID
    salesOrderCode?: string;        // é”€å”®è®¢å•号
    clientId?: number;              // å®¢æˆ·ID
    clientName?: string;            // å®¢æˆ·åç§°
    salesDate?: Date;               // å‡ºåº“日期
    contactName?: string;           // è”系人
    contactTelephone?: string;      // è”系电话
    contactAddress?: string;        // æ”¶è´§åœ°å€
    carrier?: string;               // æ‰¿è¿å•†
    shippingNumber?: string;        // è¿è¾“单号
    status?: number;                // å•据状态
    remark?: string;                // å¤‡æ³¨
    createTime?: Date;              // åˆ›å»ºæ—¶é—´
  }
  /** åˆ›å»º/修改请求 */
  export interface ProductSalesSaveReq {
    id?: number;                    // å‡ºåº“单ID(修改时必填)
    code: string;                   // å‡ºåº“单号
    name: string;                   // å‡ºåº“单名称
    clientId: number;               // å®¢æˆ·ID
    noticeId?: number;              // å‘货通知单ID
    saleOrderId?: number;           // é”€å”®è®¢å•ID
    salesOrderCode?: string;        // é”€å”®è®¢å•号
    salesDate?: Date;               // å‡ºåº“日期
    contactName?: string;           // è”系人
    contactTelephone?: string;      // è”系电话
    contactAddress?: string;        // æ”¶è´§åœ°å€
    remark?: string;                // å¤‡æ³¨
  }
  /** å¡«å†™è¿å•请求 */
  export interface ProductSalesShippingReq {
    id: number;                     // å‡ºåº“单ID
    carrier: string;                // æ‰¿è¿å•†
    shippingNumber: string;         // è¿è¾“单号
  }
}
/** æŸ¥è¯¢åˆ†é¡µ */
export function getProductSalesPage(params: PageParam): Promise<PageResult<ProductSales>>
/** æŸ¥è¯¢è¯¦æƒ… */
export function getProductSales(id: number): Promise<ProductSales>
/** åˆ›å»ºé”€å”®å‡ºåº“单 */
export function createProductSales(data: ProductSalesSaveReq): Promise<number>
/** ä¿®æ”¹é”€å”®å‡ºåº“单 */
export function updateProductSales(data: ProductSalesSaveReq): Promise<boolean>
/** åˆ é™¤é”€å”®å‡ºåº“单 */
export function deleteProductSales(id: number): Promise<boolean>
/** æäº¤ */
export function submitProductSales(id: number): Promise<boolean>
/** æ‰§è¡Œæ‹£è´§ */
export function stockProductSales(id: number): Promise<boolean>
/** å¡«å†™è¿å• */
export function shippingProductSales(data: ProductSalesShippingReq): Promise<boolean>
/** æ‰§è¡Œå‡ºåº“ */
export function finishProductSales(id: number): Promise<boolean>
/** å–消 */
export function cancelProductSales(id: number): Promise<boolean>
/** æ ¡éªŒæ•°é‡ */
export function checkProductSalesQuantity(id: number): Promise<boolean>
```
### è¡Œè¡¨æŽ¥å£
**文件路径:** `src/api/mes/wm/productsales/line/index.ts`
| æ–¹æ³• | è·¯å¾„ | è¯´æ˜Ž |
|------|------|------|
| GET | `/mes/wm/product-sales-line/page` | åˆ†é¡µæŸ¥è¯¢ |
| GET | `/mes/wm/product-sales-line/get?id={id}` | è¯¦æƒ…查询 |
| POST | `/mes/wm/product-sales-line/create` | åˆ›å»º |
| PUT | `/mes/wm/product-sales-line/update` | ä¿®æ”¹ |
| DELETE | `/mes/wm/product-sales-line/delete?id={id}` | åˆ é™¤ |
```typescript
export namespace MesWmProductSalesLineApi {
  /** é”€å”®å‡ºåº“单行 */
  export interface ProductSalesLine {
    id?: number;                    // è¡ŒID
    salesId?: number;               // å‡ºåº“单ID
    noticeLineId?: number;          // å‘货通知单行ID
    saleOrderItemId?: number;       // é”€å”®è®¢å•明细ID
    itemId?: number;                // ç‰©æ–™ID
    itemCode?: string;              // ç‰©æ–™ç¼–码
    itemName?: string;              // ç‰©æ–™åç§°
    specification?: string;         // è§„格型号
    unitMeasureName?: string;       // å•位
    quantity?: number;              // å‡ºåº“数量
    batchId?: number;               // æ‰¹æ¬¡ID
    batchCode?: string;             // æ‰¹æ¬¡å·
    oqcCheckFlag?: boolean;         // æ˜¯å¦æ£€éªŒ
    oqcId?: number;                 // å‡ºåŽ‚æ£€éªŒå•ID
    qualityStatus?: number;         // è´¨é‡çŠ¶æ€
    remark?: string;                // å¤‡æ³¨
    createTime?: Date;              // åˆ›å»ºæ—¶é—´
  }
  /** åˆ›å»º/修改请求 */
  export interface ProductSalesLineSaveReq {
    id?: number;                    // è¡ŒID(修改时必填)
    salesId: number;                // å‡ºåº“单ID
    noticeLineId?: number;          // å‘货通知单行ID
    saleOrderItemId?: number;       // é”€å”®è®¢å•明细ID
    itemId: number;                 // ç‰©æ–™ID
    quantity: number;               // å‡ºåº“数量
    batchId?: number;               // æ‰¹æ¬¡ID
    batchCode?: string;             // æ‰¹æ¬¡å·
    oqcCheckFlag?: boolean;         // æ˜¯å¦æ£€éªŒ
    remark?: string;                // å¤‡æ³¨
  }
}
```
### æ˜Žç»†è¡¨æŽ¥å£ï¼ˆæ‹£è´§ä¿¡æ¯ï¼‰
**文件路径:** `src/api/mes/wm/productsales/detail/index.ts`
| æ–¹æ³• | è·¯å¾„ | è¯´æ˜Ž |
|------|------|------|
| GET | `/mes/wm/product-sales-detail/page` | åˆ†é¡µæŸ¥è¯¢ |
| GET | `/mes/wm/product-sales-detail/get?id={id}` | è¯¦æƒ…查询 |
| POST | `/mes/wm/product-sales-detail/create` | åˆ›å»º |
| PUT | `/mes/wm/product-sales-detail/update` | ä¿®æ”¹ |
| DELETE | `/mes/wm/product-sales-detail/delete?id={id}` | åˆ é™¤ |
```typescript
export namespace MesWmProductSalesDetailApi {
  /** é”€å”®å‡ºåº“明细(拣货信息) */
  export interface ProductSalesDetail {
    id?: number;                    // æ˜Žç»†ID
    lineId?: number;                // å‡ºåº“单行ID
    salesId?: number;               // å‡ºåº“单ID
    itemId?: number;                // ç‰©æ–™ID
    itemCode?: string;              // ç‰©æ–™ç¼–码
    itemName?: string;              // ç‰©æ–™åç§°
    specification?: string;         // è§„格型号
    unitMeasureName?: string;       // å•位
    quantity?: number;              // æ‹£è´§æ•°é‡
    materialStockId?: number;       // åº“存记录ID
    batchId?: number;               // æ‰¹æ¬¡ID
    batchCode?: string;             // æ‰¹æ¬¡å·
    warehouseId?: number;           // ä»“库ID
    warehouseName?: string;         // ä»“库名称
    locationId?: number;            // åº“区ID
    locationName?: string;          // åº“区名称
    areaId?: number;                // åº“位ID
    areaName?: string;              // åº“位名称
    remark?: string;                // å¤‡æ³¨
    createTime?: Date;              // åˆ›å»ºæ—¶é—´
  }
  /** åˆ›å»º/修改请求 */
  export interface ProductSalesDetailSaveReq {
    id?: number;                    // æ˜Žç»†ID(修改时必填)
    lineId: number;                 // å‡ºåº“单行ID
    salesId: number;                // å‡ºåº“单ID
    itemId: number;                 // ç‰©æ–™ID
    quantity: number;               // æ‹£è´§æ•°é‡
    materialStockId?: number;       // åº“存记录ID
    batchId?: number;               // æ‰¹æ¬¡ID
    batchCode?: string;             // æ‰¹æ¬¡å·
    warehouseId: number;            // ä»“库ID
    locationId: number;             // åº“区ID
    areaId: number;                 // åº“位ID
    remark?: string;                // å¤‡æ³¨
  }
}
```
### çŠ¶æ€æžšä¸¾
```typescript
// é”€å”®å‡ºåº“单状态
const MesWmProductSalesStatusEnum = {
  PREPARE: 0,        // è‰ç¨¿
  CONFIRMED: 10,     // å¾…检测
  APPROVING: 20,     // å¾…拣货
  SHIPPING: 25,      // å¾…填写运单
  APPROVED: 30,      // å¾…执行出库
  FINISHED: 40,      // å·²å®Œæˆ
  CANCELLED: 50,     // å·²å–消
}
// è´¨é‡çŠ¶æ€
const MesWmQualityStatusEnum = {
  PENDING: 0,        // å¾…检验
  PASS: 1,           // åˆæ ¼
  FAIL: 2,           // ä¸åˆæ ¼
}
```
---
## å››ã€å­—段映射关系
### 4.1 é”€å”®è®¢å• â†’ å‘货通知单
| é”€å”®è®¢å•字段 | å‘货通知单字段 | è¯´æ˜Ž |
|-------------|---------------|------|
| `id` | `saleOrderId` | é”€å”®è®¢å•ID |
| `no` | `saleOrderCode` | é”€å”®è®¢å•号 |
| `customerId` | `clientId` | å®¢æˆ·ID |
| `customerName` | `clientName` | å®¢æˆ·åç§° |
### 4.2 å‘货通知单 â†’ é”€å”®å‡ºåº“单
| å‘货通知单字段 | é”€å”®å‡ºåº“单字段 | è¯´æ˜Ž |
|---------------|---------------|------|
| `id` | `noticeId` | å‘货通知单ID |
| `code` | `noticeCode` | å‘货通知单号 |
| `saleOrderId` | `saleOrderId` | é”€å”®è®¢å•ID |
| `saleOrderCode` | `salesOrderCode` | é”€å”®è®¢å•号 |
| `clientId` | `clientId` | å®¢æˆ·ID |
| `clientName` | `clientName` | å®¢æˆ·åç§° |
| `recipientName` | `contactName` | æ”¶è´§äººâ†’联系人 |
| `recipientTelephone` | `contactTelephone` | è”系电话 |
| `recipientAddress` | `contactAddress` | æ”¶è´§åœ°å€ |
| `salesDate` | `salesDate` | å‡ºåº“日期 |
### 4.3 å‘货通知单行 â†’ é”€å”®å‡ºåº“单行
| å‘货通知单行字段 | é”€å”®å‡ºåº“单行字段 | è¯´æ˜Ž |
|-----------------|-----------------|------|
| `id` | `noticeLineId` | å‘货通知单行ID |
| `saleOrderItemId` | `saleOrderItemId` | é”€å”®è®¢å•明细ID |
| `itemId` | `itemId` | ç‰©æ–™ID |
| `quantity` | `quantity` | å‡ºåº“数量 |
| `batchId` | `batchId` | æ‰¹æ¬¡ID |
| `batchCode` | `batchCode` | æ‰¹æ¬¡å· |
| `oqcCheckFlag` | `oqcCheckFlag` | æ˜¯å¦æ£€éªŒ |
---
## äº”、状态流转
### 5.1 å•据状态流转
```
销售订单:未审核 â†’ å·²å®¡æ ¸ â†’ [出库状态同步]
                â†“
发货通知单:草稿 â†’ å¾…出库 â†’ [部分出库/全部出库] â†’ å·²å®Œæˆ
                              â†“
                        é”€å”®å‡ºåº“单:草稿 â†’ æäº¤ â†’ æ‹£è´§ â†’ å‘è´§ â†’ æ‰§è¡Œå‡ºåº“
                                                    â†“
                                              [状态回写上游]
```
### 5.2 å‡ºåº“状态更新时机
| è§¦å‘动作 | æ›´æ–°å•据 | æ›´æ–°å†…容 |
|---------|---------|---------|
| é”€å”®å‡ºåº“单执行出库 | å‘货通知单行 | `outCount` ç´¯åŠ  |
| é”€å”®å‡ºåº“单执行出库 | å‘货通知单 | `outStatus` æ›´æ–° |
| é”€å”®å‡ºåº“单执行出库 | é”€å”®è®¢å•行 | `outCount` ç´¯åŠ  |
| é”€å”®å‡ºåº“单执行出库 | é”€å”®è®¢å• | `outStatus` æ›´æ–° |
### 5.3 é”€å”®å‡ºåº“单完整状态流转
```
┌─────────────────────────────────────────────────────────────────────┐
│                           é”€å”®å‡ºåº“单状态流转                           â”‚
├─────────────────────────────────────────────────────────────────────┤
│                                                                     â”‚
│   è‰ç¨¿(PREPARE:0)                                                    â”‚
│       â”‚                                                             â”‚
│       â”‚ æäº¤                                                         â”‚
│       â–¼                                                             â”‚
│   â”Œâ”€â”€â”€â”´â”€â”€â”€â”                                                         â”‚
│   â”‚       â”‚                                                         â”‚
│   â”‚       â”‚ æœ‰OQC检验行    â”€â”€â”€â–º  å¾…检测(CONFIRMED:10)                â”‚
│   â”‚       â”‚                       â”‚                                 â”‚
│   â”‚       â”‚                       â”‚ OQC检验完成                      â”‚
│   â”‚       â”‚                       â–¼                                 â”‚
│   â”‚       â”‚                     å¾…拣货(APPROVING:20) â—„──┐            â”‚
│   â”‚       â”‚                                             â”‚            â”‚
│   â”‚       â”‚ æ— OQC检验行  â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”˜            â”‚
│   â”‚       â”‚                                                          â”‚
│   â””───┬───┘                                                         â”‚
│       â”‚                                                             â”‚
│       â”‚ æ‰§è¡Œæ‹£è´§                                                     â”‚
│       â–¼                                                             â”‚
│   å¾…填写运单(SHIPPING:25)                                            â”‚
│       â”‚                                                             â”‚
│       â”‚ å¡«å†™è¿å•                                                     â”‚
│       â–¼                                                             â”‚
│   å¾…执行出库(APPROVED:30)                                            â”‚
│       â”‚                                                             â”‚
│       â”‚ æ‰§è¡Œå‡ºåº“                                                     â”‚
│       â–¼                                                             â”‚
│   å·²å®Œæˆ(FINISHED:40)                                                â”‚
│                                                                     â”‚
│   ä»»æ„çŠ¶æ€ â”€â”€å–消──► å·²å–消(CANCELLED:50)                              â”‚
│                                                                     â”‚
└─────────────────────────────────────────────────────────────────────┘
```
---
## å…­ã€å‰ç«¯é¡µé¢è·¯å¾„
| é¡µé¢ | è·¯å¾„ | æ–‡ä»¶ |
|------|------|------|
| é”€å”®è®¢å•列表 | `/erp/sale/order` | `src/views/erp/sale/order/index.vue` |
| å‘货通知单列表 | `/wls/sales-notice` | `src/views/wls/salesnotice/index.vue` |
| é”€å”®å‡ºåº“单列表 | `/wls/product-sales` | `src/views/wls/productsales/index.vue` |
---
## ä¸ƒã€ç”ŸæˆæŽ¥å£è°ƒç”¨é“¾
```typescript
// 1. é”€å”®è®¢å•生成发货通知单
const noticeId = await generateFromSaleOrder(saleOrderId);
// 2. å‘货通知单生成销售出库单
const productSalesId = await generateProductSales(noticeId);
// 3. é”€å”®å‡ºåº“单提交
await submitProductSales(productSalesId);
// 4. æ‰§è¡Œæ‹£è´§ï¼ˆéœ€è¦å…ˆæ·»åŠ æ‹£è´§æ˜Žç»†ï¼‰
await stockProductSales(productSalesId);
// 5. å¡«å†™è¿å•
await shippingProductSales({ id: productSalesId, carrier: '顺丰', shippingNumber: 'SF123' });
// 6. æ‰§è¡Œå‡ºåº“(会自动回写状态到发货通知单和销售订单)
await finishProductSales(productSalesId);
```
---
## å…«ã€å…³é”®ä¸šåŠ¡è§„åˆ™
### 8.1 ç”Ÿæˆè§„则
| åœºæ™¯ | è§„则 |
|------|------|
| å‘货通知单生成条件 | é”€å”®è®¢å•状态为"已审核" |
| é”€å”®å‡ºåº“单生成条件 | å‘货通知单状态为"待出库" |
| ç”ŸæˆåŽçŠ¶æ€ | å‡ä¸º"草稿"状态,需要提交后才能流转 |
### 8.2 å‡ºåº“完成后的状态回写
| å›žå†™å¯¹è±¡ | å›žå†™å†…容 |
|---------|---------|
| å‘货通知单行 | `outCount += å®žé™…出库数量` |
| å‘货通知单 | `outStatus = è®¡ç®—结果(0/1/2)` |
| å‘货通知单 | å¦‚æžœ `outStatus === 2`(全部出库),则 `status = 30`(已完成) |
| ERP销售订单行 | `outCount += å®žé™…出库数量` |
| ERP销售订单 | `outStatus = è®¡ç®—结果(0/1/2)` |
### 8.3 å‡ºåº“数量计算逻辑
```typescript
// è®¡ç®—出库状态
function calculateOutStatus(lines: SalesNoticeLine[]): number {
  let allOut = true;
  let anyOut = false;
  for (const line of lines) {
    const quantity = line.quantity || 0;
    const outCount = line.outCount || 0;
    if (outCount > 0) anyOut = true;
    if (outCount < quantity) allOut = false;
  }
  if (allOut) return 2;  // å…¨éƒ¨å‡ºåº“
  if (anyOut) return 1;  // éƒ¨åˆ†å‡ºåº“
  return 0;              // æœªå‡ºåº“
}
```
docs/material_stock_adjust.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,113 @@
# åº“存现有量自定义出入库 - å‰ç«¯è”调方案
## æ¶‰åŠé¡µé¢
- åº“存现有量列表页
- åº“存调整弹窗/对话框
## ä¸šåŠ¡åœºæ™¯
库存现有量模块新增自定义出入库功能,用于:
- åº“存盘点调整
- åº“存损耗/报溢
- æ‰‹åŠ¨å…¥åº“/出库
- å…¶ä»–非业务单据驱动的库存变动
## æ–°å¢ž API
### åº“存调整(自定义出入库)
| æ–¹æ³• | è·¯å¾„ | è¯´æ˜Ž |
|------|------|------|
| POST | /mes/wm/material-stock/adjust | åº“存调整(正数=入库,负数=出库) |
**请求参数:**
| å‚æ•° | ç±»åž‹ | å¿…å¡« | è¯´æ˜Ž |
|------|------|------|------|
| itemId | Long | æ˜¯ | ç‰©æ–™ID |
| warehouseId | Long | æ˜¯ | ä»“库ID |
| locationId | Long | æ˜¯ | åº“区ID |
| areaId | Long | æ˜¯ | åº“位ID |
| batchId | Long | å¦ | æ‰¹æ¬¡ID |
| batchCode | String | å¦ | æ‰¹æ¬¡å· |
| vendorId | Long | å¦ | ä¾›åº”商ID |
| quantity | BigDecimal | æ˜¯ | è°ƒæ•´æ•°é‡ï¼ˆæ­£æ•°=入库,负数=出库) |
| reason | String | å¦ | è°ƒæ•´åŽŸå›  |
**响应:**
```json
{
  "code": 0,
  "data": 123,  // åº“存记录ID
  "msg": "操作成功"
}
```
## å‰ç«¯ä¿®æ”¹ç‚¹
### 1. åº“存现有量列表页
在列表页工具栏添加"库存调整"按钮:
**按钮逻辑:**
1. ç‚¹å‡»æ‰“开库存调整弹窗
2. å¼¹çª—内填写调整信息
### 2. åº“存调整弹窗
**表单字段:**
| å­—段 | ç±»åž‹ | å¿…å¡« | è¯´æ˜Ž |
|------|------|------|------|
| ç‰©æ–™ | é€‰æ‹©å™¨ | æ˜¯ | å¼¹å‡ºç‰©æ–™é€‰æ‹©å¯¹è¯æ¡† |
| ä»“库 | é€‰æ‹©å™¨ | æ˜¯ | ä¸‹æ‹‰é€‰æ‹©ä»“库 |
| åº“区 | é€‰æ‹©å™¨ | æ˜¯ | æ ¹æ®ä»“库联动加载库区 |
| åº“位 | é€‰æ‹©å™¨ | æ˜¯ | æ ¹æ®åº“区联动加载库位 |
| æ‰¹æ¬¡ | é€‰æ‹©å™¨ | å¦ | å¼¹å‡ºæ‰¹æ¬¡é€‰æ‹©å¯¹è¯æ¡†ï¼ˆå¦‚果物料启用批次管理) |
| ä¾›åº”商 | é€‰æ‹©å™¨ | å¦ | ä¸‹æ‹‰é€‰æ‹©ä¾›åº”商 |
| è°ƒæ•´æ•°é‡ | æ•°å­—输入 | æ˜¯ | æ­£æ•°=入库,负数=出库 |
| è°ƒæ•´åŽŸå›  | æ–‡æœ¬è¾“å…¥ | å¦ | å¡«å†™è°ƒæ•´åŽŸå›  |
**联动逻辑:**
1. é€‰æ‹©ä»“库后,加载该仓库下的库区列表
2. é€‰æ‹©åº“区后,加载该库区下的库位列表
3. é€‰æ‹©ç‰©æ–™åŽï¼š
   - å¦‚果物料启用批次管理(batchCode=true),批次字段显示并必填
   - å¦‚果物料未启用批次管理,批次字段隐藏
**提交逻辑:**
1. æ ¡éªŒå¿…填字段
2. è°ƒç”¨ API `/mes/wm/material-stock/adjust`
3. æˆåŠŸåŽæç¤º"调整成功",刷新列表页
4. å¤±è´¥æ—¶æ˜¾ç¤ºé”™è¯¯ä¿¡æ¯
## ä¸šåŠ¡è§„åˆ™è¯´æ˜Ž
| åœºæ™¯ | è§„则 |
|------|------|
| å…¥åº“(quantity > 0) | è‡ªåŠ¨åˆ›å»ºåº“å­˜è®°å½•ï¼ˆå¦‚æžœä¸å­˜åœ¨ï¼‰ï¼Œå¢žåŠ åº“å­˜æ•°é‡ |
| å‡ºåº“(quantity < 0) | æ ¡éªŒåº“存记录存在且数量充足,扣减库存数量 |
| æ‰¹æ¬¡ç®¡ç† | ç‰©æ–™å¯ç”¨æ‰¹æ¬¡ç®¡ç†æ—¶ï¼Œå¿…须选择批次 |
| åº“位混放 | æ ¹æ®åº“位配置的混放规则校验 |
## åº“存事务流水
调整操作会自动生成库存事务流水:
| å­—段 | å…¥åº“ | å‡ºåº“ |
|------|------|------|
| type | IN (入库) | OUT (出库) |
| bizType | WM_STOCK_ADJUST_IN (126) | WM_STOCK_ADJUST_OUT (127) |
| bizId | åº“存记录ID | åº“存记录ID |
| bizCode | STOCK_ADJUST_{库存ID} | STOCK_ADJUST_{库存ID} |
## æ³¨æ„äº‹é¡¹
- è°ƒæ•´æ•°é‡ä¸èƒ½ä¸º0
- å‡ºåº“时必须保证库存充足
- è°ƒæ•´æ“ä½œä¼šè®°å½•库存事务流水,便于追溯
- å»ºè®®åœ¨è°ƒæ•´åŽŸå› ä¸­å¡«å†™è¯¦ç»†çš„è°ƒæ•´åŽŸå› ï¼Œä¾¿äºŽåŽç»­æŸ¥è¯¢å’Œå®¡è®¡
docs/sales_notice_to_product_sales.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,153 @@
# å‘货通知单生成销售出库单 - å‰ç«¯è”调方案
## æ¶‰åŠé¡µé¢
- å‘货通知单列表页
- å‘货通知单详情页
- é”€å”®å‡ºåº“单列表页
- é”€å”®å‡ºåº“单详情页
## ä¸šåŠ¡æµç¨‹
```
销售订单 â†’ å‘货通知单 â†’ é”€å”®å‡ºåº“单 â†’ å‡ºåº“完成
   â†“            â†“             â†“            â†“
出库状态同步  å‡ºåº“状态同步   æ‰§è¡Œå‡ºåº“    çŠ¶æ€å›žå†™ä¸Šæ¸¸
```
**状态同步规则:**
| è§¦å‘动作 | ä¸Šæ¸¸å•据 | æ›´æ–°å†…容 |
|----------|----------|----------|
| é”€å”®å‡ºåº“单执行出库 | å‘货通知单行 | ç´¯åŠ  outCount(已出库数量) |
| é”€å”®å‡ºåº“单执行出库 | å‘货通知单 | æ›´æ–° outStatus(出库状态),全部出库时 status å˜ä¸º"已完成" |
| é”€å”®å‡ºåº“单执行出库 | ERP销售订单行 | ç´¯åŠ  outCount(出库数量) |
| é”€å”®å‡ºåº“单执行出库 | ERP销售订单 | æ›´æ–° outStatus(出库状态) |
**数据带入规则:**
| æºå•据 | ç›®æ ‡å•据 | å¸¦å…¥å­—段 |
|--------|----------|----------|
| å‘货通知单 | é”€å”®å‡ºåº“单 | å®¢æˆ·ã€é”€å”®è®¢å•号、收货人、联系电话、收货地址 |
| å‘货通知单行 | é”€å”®å‡ºåº“单行 | ç‰©æ–™ã€æ•°é‡ã€æ‰¹æ¬¡ã€æ˜¯å¦æ£€éªŒ |
## æ–°å¢ž API
### ä»Žå‘货通知单生成销售出库单
| æ–¹æ³• | è·¯å¾„ | è¯´æ˜Ž |
|------|------|------|
| POST | /mes/wm/sales-notice/generate-product-sales | ä»Žå‘货通知单生成销售出库单 |
**请求参数:**
| å‚æ•° | ç±»åž‹ | å¿…å¡« | è¯´æ˜Ž |
|------|------|------|------|
| id | Long | æ˜¯ | å‘货通知单ID(Query参数) |
**响应:**
```json
{
  "code": 0,
  "data": 123,  // æ–°ç”Ÿæˆçš„销售出库单ID
  "msg": "操作成功"
}
```
## æ–°å¢žå­—段
### å‘货通知单主表新增字段
| å­—段 | ç±»åž‹ | è¯´æ˜Ž |
|------|------|------|
| outStatus | Integer | å‡ºåº“状态:0-未出库,1-部分出库,2-全部出库 |
### å‘货通知单行新增字段
| å­—段 | ç±»åž‹ | è¯´æ˜Ž |
|------|------|------|
| outCount | Decimal | å·²å‡ºåº“数量 |
## å‰ç«¯ä¿®æ”¹ç‚¹
### 1. å‘货通知单列表页/详情页
在"待出库"状态的发货通知单上添加"生成出库单"按钮:
**按钮显示条件:**
- å•据状态 = å¾…出库(status = 20)
**按钮点击逻辑:**
1. è°ƒç”¨ API `/mes/wm/sales-notice/generate-product-sales?id={noticeId}`
2. æˆåŠŸåŽæç¤º"生成成功",跳转到销售出库单详情页
3. å¤±è´¥æ—¶æ˜¾ç¤ºé”™è¯¯ä¿¡æ¯
**列表显示新增:**
- å‡ºåº“状态列:显示"未出库"/"部分出库"/"全部出库"
### 2. å‘货通知单行列表
**显示新增:**
- å·²å‡ºåº“数量列:显示每行的已出库数量
- å‡ºåº“进度列:显示 å·²å‡ºåº“数量/总数量 çš„进度条或文字
### 3. é”€å”®å‡ºåº“单详情页
从发货通知单生成的销售出库单,以下字段已自动填充:
- åŸºæœ¬ä¿¡æ¯ï¼šå‡ºåº“单号、客户、销售订单号、出库日期
- æ”¶è´§ä¿¡æ¯ï¼šè”系人、联系电话、收货地址
- è¡Œä¿¡æ¯ï¼šç‰©æ–™ã€æ•°é‡ã€æ‰¹æ¬¡ã€æ˜¯å¦æ£€éªŒ
**注意:** æ‹£è´§æ˜Žç»†éœ€è¦æ‰‹åŠ¨æ·»åŠ 
## å­—段映射表
### ä¸»è¡¨å­—段映射
| å‘货通知单字段 | é”€å”®å‡ºåº“单字段 | è¯´æ˜Ž |
|----------------|----------------|------|
| clientId | clientId | å®¢æˆ·ID |
| saleOrderId | saleOrderId | é”€å”®è®¢å•ID |
| saleOrderCode | salesOrderCode | é”€å”®è®¢å•号 |
| salesDate | salesDate | å‡ºåº“日期 |
| recipientName | contactName | æ”¶è´§äºº â†’ è”系人 |
| recipientTelephone | contactTelephone | è”系电话 |
| recipientAddress | contactAddress | æ”¶è´§åœ°å€ |
### è¡Œè¡¨å­—段映射
| å‘货通知单行字段 | é”€å”®å‡ºåº“单行字段 | è¯´æ˜Ž |
|------------------|------------------|------|
| saleOrderItemId | saleOrderItemId | é”€å”®è®¢å•明细ID |
| itemId | itemId | ç‰©æ–™ID |
| quantity | quantity | å‡ºåº“数量 |
| batchId | batchId | æ‰¹æ¬¡ID |
| batchCode | batchCode | æ‰¹æ¬¡å· |
| oqcCheckFlag | oqcCheckFlag | æ˜¯å¦æ£€éªŒ |
## ä¸šåŠ¡è§„åˆ™è¯´æ˜Ž
| åœºæ™¯ | è§„则 |
|------|------|
| ç”Ÿæˆæ¡ä»¶ | å‘货通知单状态必须为"待出库" |
| ç”ŸæˆåŽçŠ¶æ€ | é”€å”®å‡ºåº“单状态为"草稿" |
| å…³è”关系 | é”€å”®å‡ºåº“单的 noticeId å…³è”发货通知单的 id |
| å‡ºåº“完成 | ç´¯åŠ å‘è´§é€šçŸ¥å•è¡Œçš„ outCount,计算主单 outStatus |
| å…¨éƒ¨å‡ºåº“ | å‘货通知单 outStatus=2 æ—¶ï¼Œstatus è‡ªåŠ¨å˜ä¸º"已完成" |
## å‡ºåº“状态枚举
| å€¼ | åç§° | è¯´æ˜Ž |
|----|------|------|
| 0 | æœªå‡ºåº“ | æ‰€æœ‰è¡Œçš„ outCount = 0 |
| 1 | éƒ¨åˆ†å‡ºåº“ | éƒ¨åˆ†è¡Œå·²å‡ºåº“,或部分数量已出库 |
| 2 | å…¨éƒ¨å‡ºåº“ | æ‰€æœ‰è¡Œçš„ outCount >= quantity |
## æ³¨æ„äº‹é¡¹
- ä¸€ä¸ªå‘货通知单可以生成多个销售出库单(部分出库场景)
- ç”Ÿæˆçš„销售出库单为草稿状态,需要提交后才能执行拣货、出库操作
- æ‹£è´§æ˜Žç»†éœ€è¦æ‰‹åŠ¨æ·»åŠ ï¼ŒæŒ‡å®šä»Žå“ªä¸ªä»“åº“ã€åº“åŒºã€åº“ä½æ‹£è´§
- å¦‚果发货通知单行有"是否检验"标识,销售出库单提交后会进入"待检测"状态
- å‡ºåº“完成后会自动同步状态到发货通知单和 ERP é”€å”®è®¢å•
docs/sales_outbound_flow.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,293 @@
# é”€å”®å‡ºåº“流程数据带入与查询方案
## ä¸€ã€æ•´ä½“流程
```
┌─────────────┐    â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”    â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”    â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”
│  é”€å”®è®¢å•   â”‚───>│ å‘货通知单  â”‚───>│ é”€å”®å‡ºåº“单  â”‚───>│  å‡ºåº“完成   â”‚
│ (ERP模块)   â”‚    â”‚  (MES模块)  â”‚    â”‚  (MES模块)  â”‚    â”‚  çŠ¶æ€å›žå†™   â”‚
└─────────────┘    â””─────────────┘    â””─────────────┘    â””─────────────┘
       â”‚                  â”‚                  â”‚                  â”‚
       â–¼                  â–¼                  â–¼                  â–¼
  å‡ºåº“状态同步      å‡ºåº“状态同步       æ‰§è¡Œå‡ºåº“           çŠ¶æ€å›žå†™ä¸Šæ¸¸
```
## äºŒã€å•据层级结构
### 1. å‘货通知单(mes_wm_sales_notice)
| å±‚级 | è¡¨å | è¯´æ˜Ž |
|------|------|------|
| ä¸»è¡¨ | mes_wm_sales_notice | å‘货通知单基本信息 |
| è¡Œè¡¨ | mes_wm_sales_notice_line | æŒ‰ç‰©æ–™ç»´åº¦çš„发货明细 |
### 2. é”€å”®å‡ºåº“单(mes_wm_product_sales)
| å±‚级 | è¡¨å | è¯´æ˜Ž |
|------|------|------|
| ä¸»è¡¨ | mes_wm_product_sales | å‡ºåº“单基本信息 |
| è¡Œè¡¨ | mes_wm_product_sales_line | æŒ‰ç‰©æ–™/批次维度的出库行 |
| æ˜Žç»†è¡¨ | mes_wm_product_sales_detail | æ‹£è´§æ˜Žç»†ï¼Œå…·ä½“仓库/库区/库位 |
## ä¸‰ã€ä¸Šä¸‹æ¸¸æ•°æ®å¸¦å…¥è§„则
### 1. é”€å”®è®¢å• â†’ å‘货通知单
**主表带入:**
| é”€å”®è®¢å•字段 | å‘货通知单字段 | è¯´æ˜Ž |
|-------------|---------------|------|
| id | saleOrderId | é”€å”®è®¢å•ID |
| no | saleOrderCode | é”€å”®è®¢å•号 |
| customerId | clientId | å®¢æˆ·ID |
**行表带入:**
| é”€å”®è®¢å•明细字段 | å‘货通知单行字段 | è¯´æ˜Ž |
|-----------------|-----------------|------|
| id | saleOrderItemId | é”€å”®è®¢å•明细ID |
| productId | itemId | ç‰©æ–™ID |
| count | quantity | å‘货数量 |
**API è°ƒç”¨ï¼š**
- `ErpSaleOrderApi.getSaleOrder(saleOrderId)` - èŽ·å–é”€å”®è®¢å•ä¿¡æ¯
- `ErpSaleOrderApi.getSaleOrderItemList(saleOrderId)` - èŽ·å–é”€å”®è®¢å•æ˜Žç»†åˆ—è¡¨
### 2. å‘货通知单 â†’ é”€å”®å‡ºåº“单
**主表带入:**
| å‘货通知单字段 | é”€å”®å‡ºåº“单字段 | è¯´æ˜Ž |
|---------------|---------------|------|
| id | noticeId | å‘货通知单ID |
| clientId | clientId | å®¢æˆ·ID |
| saleOrderId | saleOrderId | é”€å”®è®¢å•ID |
| saleOrderCode | salesOrderCode | é”€å”®è®¢å•号 |
| salesDate | salesDate | å‡ºåº“日期 |
| recipientName | contactName | æ”¶è´§äºº â†’ è”系人 |
| recipientTelephone | contactTelephone | è”系电话 |
| recipientAddress | contactAddress | æ”¶è´§åœ°å€ |
**行表带入:**
| å‘货通知单行字段 | é”€å”®å‡ºåº“单行字段 | è¯´æ˜Ž |
|-----------------|-----------------|------|
| id | noticeLineId | å‘货通知单行ID |
| saleOrderItemId | saleOrderItemId | é”€å”®è®¢å•明细ID |
| itemId | itemId | ç‰©æ–™ID |
| quantity | quantity | å‡ºåº“数量 |
| batchId | batchId | æ‰¹æ¬¡ID |
| batchCode | batchCode | æ‰¹æ¬¡å· |
| oqcCheckFlag | oqcCheckFlag | æ˜¯å¦æ£€éªŒ |
**注意:**
- é”€å”®å‡ºåº“单明细表(拣货信息)需要手动添加
- ä¸€ä¸ªå‘货通知单可以生成多个销售出库单(部分出库场景)
## å››ã€çŠ¶æ€åŒæ­¥æœºåˆ¶
### 1. å‡ºåº“完成时的状态回写
**触发时机:** é”€å”®å‡ºåº“单执行出库(finishProductSales)
**回写流程:**
```
销售出库单行.noticeLineId â†’ å‘货通知单行.outCount(累加)
                                â†“
                        è®¡ç®—发货通知单.outStatus
                                â†“
                    å…¨éƒ¨å‡ºåº“æ—¶ â†’ å‘货通知单.status = å·²å®Œæˆ
                                â†“
销售出库单行.saleOrderItemId â†’ ERP销售订单明细.outCount(累加)
                                â†“
                        è®¡ç®—ERP销售订单.outStatus
```
### 2. å‡ºåº“状态枚举
| å€¼ | åç§° | è¯´æ˜Ž |
|----|------|------|
| 0 | æœªå‡ºåº“ | æ‰€æœ‰è¡Œçš„ outCount = 0 |
| 1 | éƒ¨åˆ†å‡ºåº“ | éƒ¨åˆ†è¡Œå·²å‡ºåº“,或部分数量已出库 |
| 2 | å…¨éƒ¨å‡ºåº“ | æ‰€æœ‰è¡Œçš„ outCount >= quantity |
## äº”、关联信息查询
### 1. å‘货通知单查询时
**需要查询的关联数据:**
| å…³è”对象 | API/方法 | ç”¨é€” |
|---------|---------|------|
| å®¢æˆ·ä¿¡æ¯ | CrmCustomerApi.getCustomerMap(clientIds) | æ˜¾ç¤ºå®¢æˆ·åç§° |
| é”€å”®è®¢å• | ErpSaleOrderApi.getSaleOrder(saleOrderId) | æ˜¾ç¤ºè®¢å•信息 |
### 2. é”€å”®å‡ºåº“单查询时
**需要查询的关联数据:**
| å…³è”对象 | API/方法 | ç”¨é€” |
|---------|---------|------|
| å®¢æˆ·ä¿¡æ¯ | CrmCustomerApi.getCustomerMap(clientIds) | æ˜¾ç¤ºå®¢æˆ·åç§° |
| å‘货通知单 | SalesNoticeService.getSalesNoticeMap(noticeIds) | æ˜¾ç¤ºé€šçŸ¥å•编码 |
| ç‰©æ–™ä¿¡æ¯ | MesMdItemService.getItemMap(itemIds) | æ˜¾ç¤ºç‰©æ–™ç¼–码、名称、规格型号 |
| æ‰¹æ¬¡ä¿¡æ¯ | MesWmBatchService.getBatchMap(batchIds) | æ˜¾ç¤ºæ‰¹æ¬¡å·ã€ç”Ÿäº§æ—¥æœŸ |
| ä»“库信息 | MesWmWarehouseService.getWarehouseMap(warehouseIds) | æ˜¾ç¤ºä»“库名称 |
| åº“区信息 | MesWmWarehouseLocationService.getLocationMap(locationIds) | æ˜¾ç¤ºåº“区名称 |
| åº“位信息 | MesWmWarehouseAreaService.getAreaMap(areaIds) | æ˜¾ç¤ºåº“位名称 |
### 3. ç‰©æ–™ä¿¡æ¯æŸ¥è¯¢ API
```java
// èŽ·å–ç‰©æ–™åŸºæœ¬ä¿¡æ¯
MesMdItemDO item = itemService.getItem(itemId);
// æ‰¹é‡èŽ·å–ç‰©æ–™ä¿¡æ¯
Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(itemIds);
// æ ¡éªŒç‰©æ–™å­˜åœ¨ä¸”启用
itemService.validateItemExistsAndEnable(itemId);
```
**物料关键信息:**
| å­—段 | è¯´æ˜Ž |
|------|------|
| id | ç‰©æ–™ID |
| code | ç‰©æ–™ç¼–码 |
| name | ç‰©æ–™åç§° |
| spec | è§„格型号 |
| unitId | ä¸»å•位ID |
| unitCode | ä¸»å•位编码 |
| batchCode | æ˜¯å¦æ‰¹æ¬¡ç®¡ç† |
| qualityFlag | æ˜¯å¦è´¨æ£€ |
## å…­ã€API æŽ¥å£æ¸…单
### 1. å‘货通知单 API
| æ–¹æ³• | è·¯å¾„ | è¯´æ˜Ž |
|------|------|------|
| POST | /mes/wm/sales-notice/create | åˆ›å»ºå‘货通知单 |
| PUT | /mes/wm/sales-notice/update | ä¿®æ”¹å‘货通知单 |
| DELETE | /mes/wm/sales-notice/delete | åˆ é™¤å‘货通知单 |
| GET | /mes/wm/sales-notice/get | èŽ·å–å‘è´§é€šçŸ¥å•è¯¦æƒ… |
| GET | /mes/wm/sales-notice/page | åˆ†é¡µæŸ¥è¯¢å‘货通知单 |
| PUT | /mes/wm/sales-notice/submit | æäº¤å‘货通知单 |
| POST | /mes/wm/sales-notice/generate-from-sale-order | ä»Žé”€å”®è®¢å•生成 |
| POST | /mes/wm/sales-notice/generate-product-sales | ç”Ÿæˆé”€å”®å‡ºåº“单 |
### 2. é”€å”®å‡ºåº“单 API
| æ–¹æ³• | è·¯å¾„ | è¯´æ˜Ž |
|------|------|------|
| POST | /mes/wm/product-sales/create | åˆ›å»ºé”€å”®å‡ºåº“单 |
| PUT | /mes/wm/product-sales/update | ä¿®æ”¹é”€å”®å‡ºåº“单 |
| DELETE | /mes/wm/product-sales/delete | åˆ é™¤é”€å”®å‡ºåº“单 |
| GET | /mes/wm/product-sales/get | èŽ·å–é”€å”®å‡ºåº“å•è¯¦æƒ… |
| GET | /mes/wm/product-sales/page | åˆ†é¡µæŸ¥è¯¢é”€å”®å‡ºåº“单 |
| PUT | /mes/wm/product-sales/submit | æäº¤é”€å”®å‡ºåº“单 |
| PUT | /mes/wm/product-sales/stock | æ‰§è¡Œæ‹£è´§ |
| PUT | /mes/wm/product-sales/shipping | å¡«å†™è¿å• |
| PUT | /mes/wm/product-sales/finish | æ‰§è¡Œå‡ºåº“ |
| PUT | /mes/wm/product-sales/cancel | å–消销售出库单 |
## ä¸ƒã€å‰ç«¯å±•示字段
### 1. å‘货通知单列表
| å­—段 | æ¥æº | è¯´æ˜Ž |
|------|------|------|
| code | mes_wm_sales_notice | é€šçŸ¥å•编码 |
| name | mes_wm_sales_notice | é€šçŸ¥å•名称 |
| clientName | crm_customer | å®¢æˆ·åç§°ï¼ˆå…³è”查询) |
| saleOrderCode | mes_wm_sales_notice | é”€å”®è®¢å•号 |
| salesDate | mes_wm_sales_notice | å‘货日期 |
| status | mes_wm_sales_notice | å•据状态 |
| outStatus | mes_wm_sales_notice | å‡ºåº“状态 |
### 2. å‘货通知单行列表
| å­—段 | æ¥æº | è¯´æ˜Ž |
|------|------|------|
| itemCode | mes_md_item | ç‰©æ–™ç¼–码(关联查询) |
| itemName | mes_md_item | ç‰©æ–™åç§°ï¼ˆå…³è”查询) |
| itemSpec | mes_md_item | è§„格型号(关联查询) |
| batchCode | mes_wm_sales_notice_line | æ‰¹æ¬¡å· |
| quantity | mes_wm_sales_notice_line | å‘货数量 |
| outCount | mes_wm_sales_notice_line | å·²å‡ºåº“数量 |
| outProgress | è®¡ç®— | å‡ºåº“进度 = outCount / quantity |
| oqcCheckFlag | mes_wm_sales_notice_line | æ˜¯å¦æ£€éªŒ |
### 3. é”€å”®å‡ºåº“单列表
| å­—段 | æ¥æº | è¯´æ˜Ž |
|------|------|------|
| code | mes_wm_product_sales | å‡ºåº“单编码 |
| name | mes_wm_product_sales | å‡ºåº“单名称 |
| clientName | crm_customer | å®¢æˆ·åç§°ï¼ˆå…³è”查询) |
| noticeCode | mes_wm_sales_notice | é€šçŸ¥å•编码(关联查询) |
| salesOrderCode | mes_wm_product_sales | é”€å”®è®¢å•号 |
| salesDate | mes_wm_product_sales | å‡ºåº“日期 |
| contactName | mes_wm_product_sales | è”系人 |
| contactTelephone | mes_wm_product_sales | è”系电话 |
| status | mes_wm_product_sales | å•据状态 |
### 4. é”€å”®å‡ºåº“单行列表
| å­—段 | æ¥æº | è¯´æ˜Ž |
|------|------|------|
| itemCode | mes_md_item | ç‰©æ–™ç¼–码(关联查询) |
| itemName | mes_md_item | ç‰©æ–™åç§°ï¼ˆå…³è”查询) |
| batchCode | mes_wm_product_sales_line | æ‰¹æ¬¡å· |
| quantity | mes_wm_product_sales_line | å‡ºåº“数量 |
| oqcCheckFlag | mes_wm_product_sales_line | æ˜¯å¦æ£€éªŒ |
| qualityStatus | mes_wm_product_sales_line | è´¨é‡çŠ¶æ€ |
### 5. é”€å”®å‡ºåº“明细列表(拣货信息)
| å­—段 | æ¥æº | è¯´æ˜Ž |
|------|------|------|
| itemCode | mes_md_item | ç‰©æ–™ç¼–码(关联查询) |
| batchCode | mes_wm_product_sales_detail | æ‰¹æ¬¡å· |
| quantity | mes_wm_product_sales_detail | æ‹£è´§æ•°é‡ |
| warehouseName | mes_wm_warehouse | ä»“库名称(关联查询) |
| locationName | mes_wm_warehouse_location | åº“区名称(关联查询) |
| areaName | mes_wm_warehouse_area | åº“位名称(关联查询) |
## å…«ã€ä¸šåŠ¡è§„åˆ™
### 1. ç”Ÿæˆè§„则
| åœºæ™¯ | è§„则 |
|------|------|
| å‘货通知单生成条件 | é”€å”®è®¢å•状态为"已审核" |
| é”€å”®å‡ºåº“单生成条件 | å‘货通知单状态为"待出库" |
| ç”ŸæˆåŽçŠ¶æ€ | å‡ä¸º"草稿"状态,需要提交后才能流转 |
### 2. æäº¤æ ¡éªŒ
| å•据 | æ ¡éªŒè§„则 |
|------|---------|
| å‘货通知单 | è‡³å°‘有一条行记录 |
| é”€å”®å‡ºåº“单 | è‡³å°‘有一条行记录,每行出库数量 > 0 |
### 3. å‡ºåº“流程
```
草稿 â†’ æäº¤ â†’ å¾…拣货 â†’ æ‹£è´§ â†’ å¾…填写运单 â†’ å¡«å†™è¿å• â†’ å¾…出库 â†’ æ‰§è¡Œå‡ºåº“ â†’ å·²å®Œæˆ
              â†‘                                                    â†“
              â””──────────── å¦‚果需要OQC检验 â†â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”˜
                               è‰ç¨¿ â†’ æäº¤ â†’ å¾…检测 â†’ OQC检验完成 â†’ å¾…拣货
```
### 4. çŠ¶æ€å›žå†™è§„åˆ™
| è§¦å‘动作 | å›žå†™å¯¹è±¡ | å›žå†™å†…容 |
|---------|---------|---------|
| æ‰§è¡Œå‡ºåº“ | å‘货通知单行 | outCount += å®žé™…出库数量 |
| æ‰§è¡Œå‡ºåº“ | å‘货通知单 | outStatus = è®¡ç®—结果 |
| æ‰§è¡Œå‡ºåº“ | å‘货通知单 | å¦‚æžœ outStatus=全部出库,则 status=已完成 |
| æ‰§è¡Œå‡ºåº“ | ERP销售订单明细 | outCount += å®žé™…出库数量 |
| æ‰§è¡Œå‡ºåº“ | ERP销售订单 | outStatus = è®¡ç®—结果 |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/arrivalnotice/MesWmArrivalNoticeLineController.java
@@ -8,12 +8,14 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.arrivalnotice.vo.line.MesWmArrivalNoticeLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.arrivalnotice.vo.line.MesWmArrivalNoticeLineRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.arrivalnotice.vo.line.MesWmArrivalNoticeLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.qc.iqc.MesQcIqcDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeLineDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.qc.iqc.MesQcIqcService;
import cn.iocoder.yudao.module.mes.service.wm.arrivalnotice.MesWmArrivalNoticeLineService;
import io.swagger.v3.oas.annotations.Operation;
@@ -28,6 +30,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -41,9 +44,9 @@
    @Resource
    private MesWmArrivalNoticeLineService arrivalNoticeLineService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private MesQcIqcService iqcService;
@@ -99,10 +102,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmArrivalNoticeLineDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                        convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        Map<Long, MesQcIqcDO> iqcMap = iqcService.getIqcMap(
                convertSet(list, MesWmArrivalNoticeLineDO::getIqcId));
        // 2. æž„建结果
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/MesWmBatchController.java
@@ -8,8 +8,9 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchRespVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.client.MesMdClientDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.vendor.MesMdVendorDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
@@ -17,8 +18,9 @@
import cn.iocoder.yudao.module.mes.dal.dataobject.tm.tool.MesTmToolDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO;
import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.md.vendor.MesMdVendorService;
import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
@@ -40,6 +42,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -53,9 +56,9 @@
    @Resource
    private MesWmBatchService batchService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private MesMdVendorService vendorService;
    @Resource
@@ -111,7 +114,7 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmBatchDO::getItemId));
        Map<Long, MesMdVendorDO> vendorMap = vendorService.getVendorMap(
                convertSet(list, MesWmBatchDO::getVendorId));
@@ -125,8 +128,9 @@
                convertSet(list, MesWmBatchDO::getWorkstationId));
        Map<Long, MesTmToolDO> toolMap = toolService.getToolMap(
                convertSet(list, MesWmBatchDO::getToolId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        // 2. æž„建结果
        return BeanUtils.toBean(list, MesWmBatchRespVO.class, vo -> {
            MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemconsume/MesWmItemConsumeLineController.java
@@ -5,11 +5,13 @@
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.itemconsume.vo.MesWmItemConsumeLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.itemconsume.vo.MesWmItemConsumeLineRespVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeLineDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.itemconsume.MesWmItemConsumeLineService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -22,6 +24,7 @@
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -36,9 +39,9 @@
    @Resource
    private MesWmItemConsumeLineService itemConsumeLineService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @GetMapping("/page")
    @Operation(summary = "根据报工编号分页获取消耗行列表")
@@ -50,10 +53,11 @@
                itemConsumeLineService.getItemConsumeLinePage(pageReqVO);
        PageResult<MesWmItemConsumeLineRespVO> voPage = BeanUtils.toBean(pageResult, MesWmItemConsumeLineRespVO.class);
        // 2. æ‹¼æŽ¥ç‰©æ–™ä¿¡æ¯
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(pageResult.getList(), MesWmItemConsumeLineDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        for (MesWmItemConsumeLineRespVO vo : voPage.getList()) {
            findAndThen(itemMap, vo.getItemId(), item -> {
                vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification());
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/MesWmItemReceiptDetailController.java
@@ -6,14 +6,16 @@
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.detail.MesWmItemReceiptDetailRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.detail.MesWmItemReceiptDetailSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.itemreceipt.MesWmItemReceiptDetailService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
@@ -30,6 +32,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -43,9 +46,9 @@
    @Resource
    private MesWmItemReceiptDetailService itemReceiptDetailService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private MesWmWarehouseService warehouseService;
    @Resource
@@ -106,10 +109,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmItemReceiptDetailDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
                convertSet(list, MesWmItemReceiptDetailDO::getWarehouseId));
        Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap(
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/MesWmItemReceiptLineController.java
@@ -8,12 +8,14 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.line.MesWmItemReceiptLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.line.MesWmItemReceiptLineRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.line.MesWmItemReceiptLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptLineDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.itemreceipt.MesWmItemReceiptLineService;
import cn.iocoder.yudao.module.mes.service.wm.itemreceipt.MesWmItemReceiptService;
import io.swagger.v3.oas.annotations.Operation;
@@ -28,6 +30,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -41,9 +44,9 @@
    @Resource
    private MesWmItemReceiptLineService itemReceiptLineService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private MesWmItemReceiptService itemReceiptService;
@@ -99,10 +102,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmItemReceiptLineDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        Map<Long, MesWmItemReceiptDO> receiptMap = itemReceiptService.getItemReceiptMap(
                convertSet(list, MesWmItemReceiptLineDO::getReceiptId));
        // 2. æž„建结果
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/MesWmMaterialStockController.java
@@ -8,18 +8,21 @@
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.wm.materialstock.vo.MesWmMaterialStockAdjustReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockFreezeReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.vendor.MesMdVendorDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.md.vendor.MesMdVendorService;
import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
@@ -40,6 +43,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -54,9 +58,9 @@
    @Resource
    private MesWmMaterialStockService materialStockService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private MesWmWarehouseService warehouseService;
    @Resource
@@ -96,6 +100,13 @@
        return success(true);
    }
    @PostMapping("/adjust")
    @Operation(summary = "库存调整(自定义出入库)")
    @PreAuthorize("@ss.hasPermission('mes:wm-material-stock:adjust')")
    public CommonResult<Long> adjustMaterialStock(@Valid @RequestBody MesWmMaterialStockAdjustReqVO reqVO) {
        return success(materialStockService.adjustMaterialStock(reqVO));
    }
    @GetMapping("/export-excel")
    @Operation(summary = "导出库存台账 Excel")
    @PreAuthorize("@ss.hasPermission('mes:wm-material-stock:export')")
@@ -115,10 +126,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmMaterialStockDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
                convertSet(list, MesWmMaterialStockDO::getWarehouseId));
        Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap(
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/vo/MesWmMaterialStockAdjustReqVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
package cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.math.BigDecimal;
/**
 * åº“存调整(自定义出入库)Request VO
 */
@Schema(description = "管理后台 - åº“存调整 Request VO")
@Data
public class MesWmMaterialStockAdjustReqVO {
    @Schema(description = "物料ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
    @NotNull(message = "物料ID不能为空")
    private Long itemId;
    @Schema(description = "仓库ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
    @NotNull(message = "仓库ID不能为空")
    private Long warehouseId;
    @Schema(description = "库区ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
    @NotNull(message = "库区ID不能为空")
    private Long locationId;
    @Schema(description = "库位ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
    @NotNull(message = "库位ID不能为空")
    private Long areaId;
    @Schema(description = "批次ID", example = "1")
    private Long batchId;
    @Schema(description = "批次号", example = "BATCH001")
    private String batchCode;
    @Schema(description = "供应商ID", example = "1")
    private Long vendorId;
    @Schema(description = "调整数量(正数=入库,负数=出库)", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
    @NotNull(message = "调整数量不能为空")
    private BigDecimal quantity;
    @Schema(description = "调整原因", example = "盘点调整")
    private String reason;
}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/MesWmMiscIssueLineController.java
@@ -8,14 +8,16 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.miscissue.vo.line.MesWmMiscIssueLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.miscissue.vo.line.MesWmMiscIssueLineRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.miscissue.vo.line.MesWmMiscIssueLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.miscissue.MesWmMiscIssueLineDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.miscissue.MesWmMiscIssueLineService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
@@ -32,6 +34,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -45,9 +48,9 @@
    @Resource
    private MesWmMiscIssueLineService miscIssueLineService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private MesWmWarehouseService warehouseService;
    @Resource
@@ -107,10 +110,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmMiscIssueLineDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
                convertSet(list, MesWmMiscIssueLineDO::getWarehouseId));
        Map<Long, MesWmWarehouseLocationDO> locationMap = warehouseLocationService.getWarehouseLocationMap(
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/MesWmMiscReceiptLineController.java
@@ -20,18 +20,21 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
@@ -45,9 +48,9 @@
    @Resource
    private MesWmMiscReceiptLineService miscReceiptLineService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private MesWmWarehouseService warehouseService;
    @Resource
@@ -115,10 +118,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmMiscReceiptLineDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
                convertSet(list, MesWmMiscReceiptLineDO::getWarehouseId));
        Map<Long, MesWmWarehouseLocationDO> locationMap = warehouseLocationService.getWarehouseLocationMap(
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/outsourceissue/MesWmOutsourceIssueDetailController.java
@@ -6,14 +6,16 @@
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.outsourceissue.vo.detail.MesWmOutsourceIssueDetailRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.outsourceissue.vo.detail.MesWmOutsourceIssueDetailSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.outsourceissue.MesWmOutsourceIssueDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.outsourceissue.MesWmOutsourceIssueDetailService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
@@ -30,6 +32,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -43,9 +46,9 @@
    @Resource
    private MesWmOutsourceIssueDetailService outsourceIssueDetailService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private MesWmWarehouseService warehouseService;
    @Resource
@@ -106,10 +109,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmOutsourceIssueDetailDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
                convertSet(list, MesWmOutsourceIssueDetailDO::getWarehouseId));
        Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap(
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/outsourceissue/MesWmOutsourceIssueLineController.java
@@ -8,12 +8,14 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.outsourceissue.vo.line.MesWmOutsourceIssueLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.outsourceissue.vo.line.MesWmOutsourceIssueLineRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.outsourceissue.vo.line.MesWmOutsourceIssueLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.outsourceissue.MesWmOutsourceIssueLineDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.batch.MesWmBatchService;
import cn.iocoder.yudao.module.mes.service.wm.outsourceissue.MesWmOutsourceIssueLineService;
import io.swagger.v3.oas.annotations.Operation;
@@ -28,6 +30,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.Set;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -43,9 +46,9 @@
    @Resource
    private MesWmOutsourceIssueLineService outsourceIssueLineService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private MesWmBatchService batchService;
@@ -111,10 +114,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmOutsourceIssueLineDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        // 1.2 èŽ·å¾—æ‰¹æ¬¡æ•°æ®
        Set<Long> batchIds = convertSet(list, MesWmOutsourceIssueLineDO::getBatchId);
        batchIds.remove(null);
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/outsourcereceipt/MesWmOutsourceReceiptDetailController.java
@@ -6,14 +6,16 @@
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.outsourcereceipt.vo.detail.MesWmOutsourceReceiptDetailRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.outsourcereceipt.vo.detail.MesWmOutsourceReceiptDetailSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.outsourcereceipt.MesWmOutsourceReceiptDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.outsourcereceipt.MesWmOutsourceReceiptDetailService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
@@ -30,6 +32,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -43,9 +46,9 @@
    @Resource
    private MesWmOutsourceReceiptDetailService detailService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private MesWmWarehouseService warehouseService;
    @Resource
@@ -106,10 +109,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmOutsourceReceiptDetailDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
                convertSet(list, MesWmOutsourceReceiptDetailDO::getWarehouseId));
        Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap(
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/outsourcereceipt/MesWmOutsourceReceiptLineController.java
@@ -8,11 +8,13 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.outsourcereceipt.vo.line.MesWmOutsourceReceiptLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.outsourcereceipt.vo.line.MesWmOutsourceReceiptLineRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.outsourcereceipt.vo.line.MesWmOutsourceReceiptLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.outsourcereceipt.MesWmOutsourceReceiptLineDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.outsourcereceipt.MesWmOutsourceReceiptLineService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -26,6 +28,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -39,9 +42,9 @@
    @Resource
    private MesWmOutsourceReceiptLineService receiptLineService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @PostMapping("/create")
    @Operation(summary = "创建外协入库单行")
@@ -95,10 +98,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmOutsourceReceiptLineDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        // 2. æž„建结果
        return BeanUtils.toBean(list, MesWmOutsourceReceiptLineRespVO.class, vo -> {
            MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/packages/MesWmPackageController.java
@@ -9,11 +9,13 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.packages.vo.MesWmPackageRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.packages.vo.MesWmPackageSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.client.MesMdClientDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.packages.MesWmPackageDO;
import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mes.service.wm.packages.MesWmPackageService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import io.swagger.v3.oas.annotations.Operation;
@@ -26,6 +28,7 @@
import org.springframework.web.bind.annotation.*;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -43,7 +46,7 @@
    @Resource
    private MesMdClientService clientService;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private AdminUserApi adminUserApi;
@@ -131,8 +134,9 @@
        Map<Long, MesMdClientDO> clientMap = clientService.getClientMap(
                convertSet(list, MesWmPackageDO::getClientId));
        // æ‰¹é‡æŸ¥è¯¢è®¡é‡å•位(尺寸 + é‡é‡ï¼‰
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSetByFlatMap(list, p -> Stream.of(p.getSizeUnitId(), p.getWeightUnitId())));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSetByFlatMap(list, p -> Stream.of(p.getSizeUnitId(), p.getWeightUnitId()))).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        // æ‰¹é‡æŸ¥è¯¢æ£€æŸ¥å‘˜
        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
                convertSet(list, MesWmPackageDO::getInspectorUserId));
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/packages/MesWmPackageLineController.java
@@ -8,12 +8,14 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.packages.vo.line.MesWmPackageLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.packages.vo.line.MesWmPackageLineRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.packages.vo.line.MesWmPackageLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.packages.MesWmPackageLineDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
import cn.iocoder.yudao.module.mes.service.wm.packages.MesWmPackageLineService;
import io.swagger.v3.oas.annotations.Operation;
@@ -28,6 +30,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -41,9 +44,9 @@
        @Resource
        private MesWmPackageLineService packageLineService;
        @Resource
        private MesMdItemService itemService;
        private MdmItemApi mdmItemApi;
        @Resource
        private MesMdUnitMeasureService unitMeasureService;
        private MdmUnitMeasureApi mdmUnitMeasureApi;
        @Resource
        private MesProWorkOrderService workOrderService;
@@ -99,11 +102,12 @@
                        return Collections.emptyList();
                }
                // æ‰¹é‡æŸ¥è¯¢ç‰©æ–™
                Map<Long, MesMdItemDO> itemMap = itemService
                Map<Long, MdmItemRespDTO> itemMap = mdmItemApi
                                .getItemMap(convertSet(list, MesWmPackageLineDO::getItemId));
                // æ‰¹é‡æŸ¥è¯¢è®¡é‡å•位
                Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
                Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
                // æ‰¹é‡æŸ¥è¯¢å·¥å•
                Map<Long, MesProWorkOrderDO> workOrderMap = workOrderService.getWorkOrderMap(
                                convertSet(list, MesWmPackageLineDO::getWorkOrderId));
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/MesWmProductIssueDetailController.java
@@ -6,14 +6,16 @@
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.detail.MesWmProductIssueDetailRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.detail.MesWmProductIssueDetailSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.productissue.MesWmProductIssueDetailService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
@@ -30,6 +32,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -43,9 +46,9 @@
    @Resource
    private MesWmProductIssueDetailService issueDetailService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private MesWmWarehouseService warehouseService;
    @Resource
@@ -106,10 +109,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmProductIssueDetailDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
                convertSet(list, MesWmProductIssueDetailDO::getWarehouseId));
        Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap(
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/MesWmProductIssueLineController.java
@@ -8,11 +8,13 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.line.MesWmProductIssueLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.line.MesWmProductIssueLineRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.line.MesWmProductIssueLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueLineDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.productissue.MesWmProductIssueLineService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -26,6 +28,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -39,9 +42,9 @@
    @Resource
    private MesWmProductIssueLineService issueLineService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @PostMapping("/create")
    @Operation(summary = "创建领料出库单行")
@@ -105,10 +108,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmProductIssueLineDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        // 2. æž„建结果
        return BeanUtils.toBean(list, MesWmProductIssueLineRespVO.class, vo -> {
            MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productproduce/MesWmProductProduceLineController.java
@@ -7,11 +7,13 @@
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productproduce.vo.MesWmProductProduceLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productproduce.vo.MesWmProductProduceLineRespVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productproduce.MesWmProductProduceLineDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.productproduce.MesWmProductProduceLineService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -26,6 +28,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -39,9 +42,9 @@
    @Resource
    private MesWmProductProduceLineService productProduceLineService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @GetMapping("/page")
    @Operation(summary = "获得生产入库单行分页")
@@ -60,10 +63,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmProductProduceLineDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        // 2. æž„建结果
        return BeanUtils.toBean(list, MesWmProductProduceLineRespVO.class, vo -> {
            MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productreceipt/MesWmProductReceiptController.java
@@ -11,12 +11,14 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.productreceipt.vo.MesWmProductReceiptPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productreceipt.vo.MesWmProductReceiptRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productreceipt.vo.MesWmProductReceiptSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productreceipt.MesWmProductReceiptDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
import cn.iocoder.yudao.module.mes.service.wm.productreceipt.MesWmProductReceiptService;
import io.swagger.v3.oas.annotations.Operation;
@@ -33,6 +35,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -49,9 +52,9 @@
    @Resource
    private MesProWorkOrderService workOrderService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @PostMapping("/create")
    @Operation(summary = "创建产品收货单")
@@ -163,10 +166,11 @@
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesProWorkOrderDO> workOrderMap = workOrderService.getWorkOrderMap(
                convertSet(list, MesWmProductReceiptDO::getWorkOrderId));
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmProductReceiptDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        // 2. æž„建结果
        return BeanUtils.toBean(list, MesWmProductReceiptRespVO.class, vo -> {
            MapUtils.findAndThen(workOrderMap, vo.getWorkOrderId(),
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productreceipt/MesWmProductReceiptDetailController.java
@@ -6,14 +6,16 @@
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productreceipt.vo.detail.MesWmProductReceiptDetailRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productreceipt.vo.detail.MesWmProductReceiptDetailSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productreceipt.MesWmProductReceiptDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.productreceipt.MesWmProductReceiptDetailService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
@@ -30,6 +32,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -43,9 +46,9 @@
    @Resource
    private MesWmProductReceiptDetailService productReceiptDetailService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private MesWmWarehouseService warehouseService;
    @Resource
@@ -106,10 +109,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmProductReceiptDetailDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
                convertSet(list, MesWmProductReceiptDetailDO::getWarehouseId));
        Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap(
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productreceipt/MesWmProductReceiptLineController.java
@@ -8,11 +8,13 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.productreceipt.vo.line.MesWmProductReceiptLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productreceipt.vo.line.MesWmProductReceiptLineRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productreceipt.vo.line.MesWmProductReceiptLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productreceipt.MesWmProductReceiptLineDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.productreceipt.MesWmProductReceiptLineService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -26,6 +28,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -39,9 +42,9 @@
    @Resource
    private MesWmProductReceiptLineService productReceiptLineService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @PostMapping("/create")
    @Operation(summary = "创建产品收货单行")
@@ -95,10 +98,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmProductReceiptLineDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        // 2. æž„建结果
        return BeanUtils.toBean(list, MesWmProductReceiptLineRespVO.class, vo -> {
            MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/MesWmProductSalesDetailController.java
@@ -6,14 +6,16 @@
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.detail.MesWmProductSalesDetailRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.detail.MesWmProductSalesDetailSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.productsales.MesWmProductSalesDetailService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
@@ -30,6 +32,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -43,9 +46,9 @@
    @Resource
    private MesWmProductSalesDetailService productSalesDetailService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private MesWmWarehouseService warehouseService;
    @Resource
@@ -106,10 +109,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmProductSalesDetailDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
                convertSet(list, MesWmProductSalesDetailDO::getWarehouseId));
        Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap(
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/MesWmProductSalesLineController.java
@@ -8,12 +8,14 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesWmProductSalesLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesWmProductSalesLineRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesWmProductSalesLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.productsales.MesWmProductSalesLineService;
import io.swagger.v3.oas.annotations.Operation;
@@ -28,6 +30,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -41,9 +44,9 @@
    @Resource
    private MesWmProductSalesLineService productSalesLineService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @PostMapping("/create")
@@ -98,10 +101,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmProductSalesLineDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                        convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        // 2. æž„建结果
        return BeanUtils.toBean(list, MesWmProductSalesLineRespVO.class, vo -> {
            MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/MesWmReturnIssueDetailController.java
@@ -6,14 +6,16 @@
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.detail.MesWmReturnIssueDetailRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.detail.MesWmReturnIssueDetailSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.returnissue.MesWmReturnIssueDetailService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
@@ -30,6 +32,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -43,9 +46,9 @@
    @Resource
    private MesWmReturnIssueDetailService issueDetailService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private MesWmWarehouseService warehouseService;
    @Resource
@@ -106,10 +109,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmReturnIssueDetailDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
                convertSet(list, MesWmReturnIssueDetailDO::getWarehouseId));
        Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap(
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/MesWmReturnIssueLineController.java
@@ -8,11 +8,13 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.line.MesWmReturnIssueLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.line.MesWmReturnIssueLineRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.line.MesWmReturnIssueLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLineDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.returnissue.MesWmReturnIssueLineService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -26,6 +28,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -39,9 +42,9 @@
    @Resource
    private MesWmReturnIssueLineService issueLineService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @PostMapping("/create")
    @Operation(summary = "创建生产退料单行")
@@ -105,10 +108,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmReturnIssueLineDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        // 2. æž„建结果
        return BeanUtils.toBean(list, MesWmReturnIssueLineRespVO.class, vo -> {
            MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnsales/MesWmReturnSalesDetailController.java
@@ -6,14 +6,16 @@
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.detail.MesWmReturnSalesDetailRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.detail.MesWmReturnSalesDetailSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.returnsales.MesWmReturnSalesDetailService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
@@ -30,6 +32,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -43,9 +46,9 @@
    @Resource
    private MesWmReturnSalesDetailService returnSalesDetailService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private MesWmWarehouseService warehouseService;
    @Resource
@@ -106,10 +109,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmReturnSalesDetailDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
                convertSet(list, MesWmReturnSalesDetailDO::getWarehouseId));
        Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap(
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnsales/MesWmReturnSalesLineController.java
@@ -8,11 +8,13 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.line.MesWmReturnSalesLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.line.MesWmReturnSalesLineRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.line.MesWmReturnSalesLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesLineDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.returnsales.MesWmReturnSalesLineService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -26,6 +28,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -39,9 +42,9 @@
    @Resource
    private MesWmReturnSalesLineService returnSalesLineService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @PostMapping("/create")
    @Operation(summary = "创建销售退货单行")
@@ -105,10 +108,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmReturnSalesLineDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        // 2. æž„建结果
        return BeanUtils.toBean(list, MesWmReturnSalesLineRespVO.class, vo ->
                MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/MesWmReturnVendorDetailController.java
@@ -6,14 +6,16 @@
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.detail.MesWmReturnVendorDetailRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.detail.MesWmReturnVendorDetailSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.returnvendor.MesWmReturnVendorDetailService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
@@ -30,6 +32,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -43,9 +46,9 @@
    @Resource
    private MesWmReturnVendorDetailService returnVendorDetailService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private MesWmWarehouseService warehouseService;
    @Resource
@@ -106,10 +109,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmReturnVendorDetailDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
                convertSet(list, MesWmReturnVendorDetailDO::getWarehouseId));
        Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap(
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/MesWmReturnVendorLineController.java
@@ -8,11 +8,13 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.line.MesWmReturnVendorLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.line.MesWmReturnVendorLineRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.line.MesWmReturnVendorLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorLineDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.returnvendor.MesWmReturnVendorLineService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -26,6 +28,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -39,9 +42,9 @@
    @Resource
    private MesWmReturnVendorLineService returnVendorLineService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @PostMapping("/create")
    @Operation(summary = "创建供应商退货单行")
@@ -105,10 +108,11 @@
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmReturnVendorLineDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        // 2. æž„建结果
        return BeanUtils.toBean(list, MesWmReturnVendorLineRespVO.class, vo -> {
            MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/salesnotice/MesWmSalesNoticeController.java
@@ -113,12 +113,20 @@
    @PostMapping("/generate-from-sale-order")
    @Operation(summary = "从销售订单生成发货通知单")
    @Parameter(name = "saleOrderId", description = "销售订单ID", required = true)
    @PreAuthorize("@ss.hasPermission('mes:wm-sales-notice:create')")
    public CommonResult<Long> generateFromSaleOrder(@RequestParam("saleOrderId") Long saleOrderId) {
    public CommonResult<Long> generateFromSaleOrder(@RequestBody Map<String, Long> params) {
        Long saleOrderId = params.get("saleOrderId");
        return success(salesNoticeService.generateSalesNoticeFromSaleOrder(saleOrderId));
    }
    @PostMapping("/generate-product-sales")
    @Operation(summary = "从发货通知单生成销售出库单")
    @Parameter(name = "id", description = "发货通知单编号", required = true)
    @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:create')")
    public CommonResult<Long> generateProductSales(@RequestParam("id") Long id) {
        return success(salesNoticeService.generateProductSalesFromNotice(id));
    }
    // ==================== æ‹¼æŽ¥ VO ====================
    private List<MesWmSalesNoticeRespVO> buildRespVOList(List<MesWmSalesNoticeDO> list) {
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/salesnotice/MesWmSalesNoticeLineController.java
@@ -5,14 +5,14 @@
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
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;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.salesnotice.vo.line.MesWmSalesNoticeLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.salesnotice.vo.line.MesWmSalesNoticeLineRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.salesnotice.vo.line.MesWmSalesNoticeLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.salesnotice.MesWmSalesNoticeLineDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mes.service.wm.salesnotice.MesWmSalesNoticeLineService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -26,6 +26,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -39,9 +40,9 @@
    @Resource
    private MesWmSalesNoticeLineService salesNoticeLineService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @PostMapping("/create")
    @Operation(summary = "创建发货通知单行")
@@ -94,11 +95,12 @@
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        // 1. èŽ·å¾—å…³è”æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        // 1. èŽ·å¾—å…³è”æ•°æ® - ä½¿ç”¨ MDM API èŽ·å–ç‰©æ–™ä¿¡æ¯
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmSalesNoticeLineDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                        convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(java.util.stream.Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        // 2. æž„建结果
        return BeanUtils.toBean(list, MesWmSalesNoticeLineRespVO.class, vo -> {
            MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/salesnotice/vo/MesWmSalesNoticePageReqVO.java
@@ -19,7 +19,7 @@
    private String name;
    @Schema(description = "销售订单编号", example = "SO202603010001")
    private String salesOrderCode;
    private String saleOrderCode;
    @Schema(description = "客户编号", example = "1")
    private Long clientId;
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/salesnotice/vo/MesWmSalesNoticeRespVO.java
@@ -58,6 +58,10 @@
    @ExcelProperty("状态")
    private Integer status;
    @Schema(description = "出库状态", example = "0")
    @ExcelProperty("出库状态")
    private Integer outStatus;
    @Schema(description = "备注", example = "备注")
    @ExcelProperty("备注")
    private String remark;
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/salesnotice/vo/line/MesWmSalesNoticeLineRespVO.java
@@ -43,6 +43,9 @@
    @Schema(description = "发货数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
    private BigDecimal quantity;
    @Schema(description = "已出库数量", example = "50.00")
    private BigDecimal outCount;
    @Schema(description = "是否检验", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
    private Boolean oqcCheckFlag;
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/sn/MesWmSnController.java
@@ -12,10 +12,12 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnGroupRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnRespVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
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;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.sn.MesWmSnService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -31,6 +33,7 @@
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -45,9 +48,9 @@
    @Resource
    private MesWmSnService snService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @PostMapping("/generate")
    @Operation(summary = "生成 SN ç ")
@@ -117,9 +120,10 @@
        if (CollUtil.isEmpty(list)) {
            return;
        }
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(convertSet(list, MesWmSnGroupRespVO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(convertSet(list, MesWmSnGroupRespVO::getItemId));
        Map<Long, MdmUnitMeasureRespDTO> unitMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        list.forEach(vo -> MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
            vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification());
            MapUtils.findAndThen(unitMap, item.getUnitMeasureId(), unit -> vo.setUnitName(unit.getName()));
@@ -130,9 +134,10 @@
        if (CollUtil.isEmpty(list)) {
            return;
        }
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(convertSet(list, MesWmSnRespVO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(convertSet(list, MesWmSnRespVO::getItemId));
        Map<Long, MdmUnitMeasureRespDTO> unitMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        list.forEach(vo -> MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
            vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification());
            MapUtils.findAndThen(unitMap, item.getUnitMeasureId(), unit -> vo.setUnitName(unit.getName()));
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/MesWmStockTakingTaskLineController.java
@@ -7,14 +7,16 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.line.MesWmStockTakingTaskLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.line.MesWmStockTakingTaskLineRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.line.MesWmStockTakingTaskLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskLineDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.stocktaking.task.MesWmStockTakingTaskLineService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
@@ -31,6 +33,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -45,9 +48,9 @@
    @Resource
    private MesWmStockTakingTaskLineService stockTakingTaskLineService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private MesWmWarehouseService warehouseService;
    @Resource
@@ -116,9 +119,10 @@
            return Collections.emptyList();
        }
        // æŸ¥è¯¢å…³è”数据
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(convertSet(list, MesWmStockTakingTaskLineDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(convertSet(list, MesWmStockTakingTaskLineDO::getItemId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
                convertSet(list, MesWmStockTakingTaskLineDO::getWarehouseId));
        Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap(
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/MesWmStockTakingTaskResultController.java
@@ -8,14 +8,16 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.result.MesWmStockTakingTaskResultPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.result.MesWmStockTakingTaskResultRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.result.MesWmStockTakingTaskResultSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskResultDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.stocktaking.task.MesWmStockTakingTaskResultService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
@@ -33,6 +35,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -46,9 +49,9 @@
    @Resource
    private MesWmStockTakingTaskResultService stockTakingTaskResultService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private MesWmWarehouseService warehouseService;
    @Resource
@@ -112,10 +115,11 @@
            return Collections.emptyList();
        }
        // æŸ¥è¯¢å…³è”数据
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, MesWmStockTakingTaskResultDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
                convertSet(list, MesWmStockTakingTaskResultDO::getWarehouseId));
        Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap(
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transfer/MesWmTransferDetailController.java
@@ -6,14 +6,16 @@
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.transfer.vo.detail.MesWmTransferDetailRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.transfer.vo.detail.MesWmTransferDetailSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transfer.MesWmTransferDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.transfer.MesWmTransferDetailService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
@@ -30,6 +32,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -43,9 +46,9 @@
    @Resource
    private MesWmTransferDetailService transferDetailService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private MesWmWarehouseService warehouseService;
    @Resource
@@ -106,9 +109,10 @@
            return Collections.emptyList();
        }
        // æŸ¥è¯¢ç›¸å…³æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(convertSet(list, MesWmTransferDetailDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(convertSet(list, MesWmTransferDetailDO::getItemId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
                convertSet(list, MesWmTransferDetailDO::getToWarehouseId));
        Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap(
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transfer/MesWmTransferLineController.java
@@ -6,14 +6,16 @@
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.transfer.vo.line.MesWmTransferLineRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.transfer.vo.line.MesWmTransferLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transfer.MesWmTransferLineDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.transfer.MesWmTransferLineService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
@@ -30,6 +32,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -43,9 +46,9 @@
    @Resource
    private MesWmTransferLineService transferLineService;
    @Resource
    private MesMdItemService itemService;
    private MdmItemApi mdmItemApi;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    private MdmUnitMeasureApi mdmUnitMeasureApi;
    @Resource
    private MesWmWarehouseService warehouseService;
    @Resource
@@ -105,9 +108,10 @@
            return Collections.emptyList();
        }
        // æŸ¥è¯¢ç›¸å…³æ•°æ®
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(convertSet(list, MesWmTransferLineDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(convertSet(list, MesWmTransferLineDO::getItemId));
        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
                .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
        Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
                convertSet(list, MesWmTransferLineDO::getFromWarehouseId));
        Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap(
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/mdm/MesMdmItemDO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,211 @@
package cn.iocoder.yudao.module.mes.dal.dataobject.mdm;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
 * MDM ç‰©æ–™ DO
 *
 * æ˜ å°„ mdm_item è¡¨
 */
@TableName("mdm_item")
@KeySequence("mdm_item_seq")
@Data
@EqualsAndHashCode
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MesMdmItemDO {
    /**
     * ç‰©æ–™ç¼–号
     */
    @TableId
    private Long id;
    /**
     * ç‰©æ–™ç¼–码
     */
    private String code;
    /**
     * ç‰©æ–™åç§°
     */
    private String name;
    /**
     * ç‰©æ–™æ¡ç 
     */
    private String barCode;
    /**
     * è§„格型号
     */
    private String specification;
    /**
     * ç‰©æ–™åˆ†ç±»ç¼–号
     */
    private Long categoryId;
    /**
     * è®¡é‡å•位编号
     */
    private Long unitMeasureId;
    /**
     * è¾…单位1编号
     */
    private Long unitMeasureId2;
    /**
     * è¾…单位1换算比率
     */
    private BigDecimal unitMeasureRate1;
    /**
     * è¾…单位2编号
     */
    private Long unitMeasureId3;
    /**
     * è¾…单位2换算比率
     */
    private BigDecimal unitMeasureRate2;
    /**
     * é»˜è®¤ä»“库编号
     */
    private Long warehouseId;
    /**
     * é»˜è®¤ä»“库编码
     */
    private String warehouseCode;
    /**
     * å“ç‰Œç¼–号
     */
    private Long brandId;
    /**
     * ç‰©æ–™ç±»åž‹ï¼ˆ1:物料 2:产品 3:半成品)
     */
    private Integer itemType;
    /**
     * çŠ¶æ€ï¼ˆ0正常 1停用)
     */
    private Integer status;
    /**
     * é‡‡è´­ä»·
     */
    private BigDecimal purchasePrice;
    /**
     * é”€å”®ä»·
     */
    private BigDecimal salesPrice;
    /**
     * æˆæœ¬ä»·
     */
    private BigDecimal costPrice;
    /**
     * æœ€ä½Žä»·
     */
    private BigDecimal minPrice;
    /**
     * å®‰å…¨åº“å­˜
     */
    private BigDecimal safetyStock;
    /**
     * æœ€ä½Žåº“存量
     */
    private BigDecimal minStock;
    /**
     * æœ€é«˜åº“存量
     */
    private BigDecimal maxStock;
    /**
     * æœ€å°è®¢è´§é‡
     */
    private BigDecimal minOrderQty;
    /**
     * é‡‡è´­æå‰æœŸï¼ˆå¤©ï¼‰
     */
    private Integer leadTime;
    /**
     * æ˜¯å¦æ‰¹æ¬¡ç®¡ç†
     */
    private Boolean isBatchManaged;
    /**
     * æ˜¯å¦åºåˆ—号管理
     */
    private Boolean isSerialManaged;
    /**
     * æ¡ç è§„则ID
     */
    private Long barcodeRuleId;
    /**
     * ä¿è´¨æœŸå¤©æ•°
     */
    private Integer expiryDay;
    /**
     * æ˜¯å¦é«˜å€¼ç‰©æ–™
     */
    private Boolean highValue;
    /**
     * é‡é‡(kg)
     */
    private BigDecimal weight;
    /**
     * å¤‡æ³¨
     */
    private String remark;
    /**
     * åˆ›å»ºè€…
     */
    private String creator;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    private LocalDateTime createTime;
    /**
     * æ›´æ–°è€…
     */
    private String updater;
    /**
     * æ›´æ–°æ—¶é—´
     */
    private LocalDateTime updateTime;
    /**
     * æ˜¯å¦åˆ é™¤
     */
    private Boolean deleted;
}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/salesnotice/MesWmSalesNoticeDO.java
@@ -37,10 +37,6 @@
     */
    private String name;
    /**
     * é”€å”®è®¢å•编号
     */
    private String salesOrderCode;
    /**
     * å®¢æˆ·ç¼–号
     *
     * å…³è” CRM å®¢æˆ· {@link cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO#getId()}
@@ -78,6 +74,13 @@
     */
    private Integer status;
    /**
     * å‡ºåº“状态
     *
     * å­—å…¸ {@link DictTypeConstants#MES_WM_OUT_STATUS}
     * æžšä¸¾ {@link cn.iocoder.yudao.module.mes.enums.wm.MesWmOutStatusEnum}
     */
    private Integer outStatus;
    /**
     * å¤‡æ³¨
     */
    private String remark;
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/salesnotice/MesWmSalesNoticeLineDO.java
@@ -61,6 +61,10 @@
     */
    private BigDecimal quantity;
    /**
     * å·²å‡ºåº“数量
     */
    private BigDecimal outCount;
    /**
     * æ˜¯å¦æ£€éªŒ
     */
    private Boolean oqcCheckFlag;
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/mdm/MesMdmItemMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package cn.iocoder.yudao.module.mes.dal.mysql.mdm;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.Collection;
import java.util.List;
/**
 * MDM ç‰©æ–™ Mapper
 */
@Mapper
public interface MesMdmItemMapper extends BaseMapperX<MesMdmItemDO> {
    default MesMdmItemDO selectByCode(String code) {
        return selectOne(MesMdmItemDO::getCode, code);
    }
    default List<MesMdmItemDO> selectListByIds(Collection<Long> ids) {
        return selectList(MesMdmItemDO::getId, ids);
    }
}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/salesnotice/MesWmSalesNoticeMapper.java
@@ -17,7 +17,7 @@
        return selectPage(reqVO, new LambdaQueryWrapperX<MesWmSalesNoticeDO>()
                .likeIfPresent(MesWmSalesNoticeDO::getCode, reqVO.getCode())
                .likeIfPresent(MesWmSalesNoticeDO::getName, reqVO.getName())
                .likeIfPresent(MesWmSalesNoticeDO::getSalesOrderCode, reqVO.getSalesOrderCode())
                .likeIfPresent(MesWmSalesNoticeDO::getSaleOrderCode, reqVO.getSaleOrderCode())
                .eqIfPresent(MesWmSalesNoticeDO::getClientId, reqVO.getClientId())
                .eqIfPresent(MesWmSalesNoticeDO::getStatus, reqVO.getStatus())
                .orderByDesc(MesWmSalesNoticeDO::getId));
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/DictTypeConstants.java
@@ -51,6 +51,7 @@
    String MES_WM_MISC_ISSUE_TYPE = "mes_wm_misc_issue_type"; // MES æ‚项出库类型
    String MES_WM_MISC_ISSUE_STATUS = "mes_wm_misc_issue_status"; // MES æ‚项出库单状态
    String MES_WM_SALES_NOTICE_STATUS = "mes_wm_sales_notice_status"; // MES å‘货通知单状态
    String MES_WM_OUT_STATUS = "mes_wm_out_status"; // MES å‡ºåº“状态
    String MES_WM_PRODUCT_SALES_STATUS = "mes_wm_product_sales_status"; // MES é”€å”®å‡ºåº“单状态
    String MES_WM_OUTSOURCE_ISSUE_STATUS = "mes_wm_outsource_issue_status"; // MES å§”外出库状态
    String MES_WM_PRODUCT_ISSUE_STATUS = "mes_wm_product_issue_status"; // MES ç”Ÿäº§é¢†æ–™çŠ¶æ€
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
@@ -438,6 +438,7 @@
    ErrorCode WM_TRANSACTION_BATCH_NOT_EXISTS = new ErrorCode(1_040_703_012, "批次记录不存在");
    ErrorCode WM_MATERIAL_STOCK_REQUIRED = new ErrorCode(1_040_703_013, "库存记录不能为空");
    ErrorCode WM_MATERIAL_STOCK_SELECTION_MISMATCH = new ErrorCode(1_040_703_014, "库存记录与提交的物料、批次或库位信息不一致");
    ErrorCode WM_MATERIAL_STOCK_QUANTITY_INVALID = new ErrorCode(1_040_703_015, "调整数量不能为空或零");
    // ========== MES ä»“库管理-到货通知单(1-040-704-000) ==========
    ErrorCode WM_ARRIVAL_NOTICE_NOT_EXISTS = new ErrorCode(1_040_704_000, "到货通知单不存在");
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/MesBizTypeConstants.java
@@ -47,6 +47,8 @@
    public static final int WM_ITEM_CONSUME = 123; // ç”Ÿäº§æ¶ˆè€—:MesWmItemConsumeDO
    public static final int WM_PRODUCT_PRODUCE = 124; // äº§å“äº§å‡ºï¼šMesWmProductProduceDO
    public static final int WM_RETURN_VENDOR = 125; // ä¾›åº”商退货出库:MesWmReturnVendorDO
    public static final int WM_STOCK_ADJUST_IN = 126; // åº“存调整入库(自定义入库)
    public static final int WM_STOCK_ADJUST_OUT = 127; // åº“存调整出库(自定义出库)
    // ========== CAL æŽ’班模块 [200, 300) ==========
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmOutStatusEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.mes.enums.wm;
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
 * MES å‡ºåº“状态枚举
 */
@Getter
@AllArgsConstructor
public enum MesWmOutStatusEnum implements ArrayValuable<Integer> {
    NOT_OUT(0, "未出库"),
    PART_OUT(1, "部分出库"),
    ALL_OUT(2, "全部出库");
    public static final Integer[] ARRAYS = Arrays.stream(values())
            .map(MesWmOutStatusEnum::getStatus).toArray(Integer[]::new);
    private final Integer status;
    private final String name;
    @Override
    public Integer[] array() {
        return ARRAYS;
    }
}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/mdm/MesMdmItemService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,60 @@
package cn.iocoder.yudao.module.mes.service.mdm;
import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
/**
 * MDM ç‰©æ–™ Service æŽ¥å£
 *
 * ä¸“门用于查询 mdm_item è¡¨
 */
public interface MesMdmItemService {
    /**
     * èŽ·å¾—ç‰©æ–™
     *
     * @param id ç¼–号
     * @return ç‰©æ–™
     */
    MesMdmItemDO getItem(Long id);
    /**
     * æ ¡éªŒç‰©æ–™å­˜åœ¨
     *
     * @param id ç¼–号
     * @return ç‰©æ–™
     */
    MesMdmItemDO validateItemExists(Long id);
    /**
     * æ ¡éªŒç‰©æ–™å­˜åœ¨ä¸”启用
     *
     * @param id ç¼–号
     * @return ç‰©æ–™
     */
    MesMdmItemDO validateItemExistsAndEnable(Long id);
    /**
     * èŽ·å¾—ç‰©æ–™åˆ—è¡¨
     *
     * @param ids ç¼–号数组
     * @return ç‰©æ–™åˆ—表
     */
    List<MesMdmItemDO> getItemList(Collection<Long> ids);
    /**
     * èŽ·å¾—ç‰©æ–™ Map
     *
     * @param ids ç¼–号数组
     * @return ç‰©æ–™ Map
     */
    default Map<Long, MesMdmItemDO> getItemMap(Collection<Long> ids) {
        return convertMap(getItemList(ids), MesMdmItemDO::getId);
    }
}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/mdm/MesMdmItemServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,60 @@
package cn.iocoder.yudao.module.mes.service.mdm;
import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
import cn.iocoder.yudao.module.mes.dal.mysql.mdm.MesMdmItemMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.MD_ITEM_NOT_EXISTS;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.MD_ITEM_IS_DISABLE;
/**
 * MDM ç‰©æ–™ Service å®žçŽ°ç±»
 *
 * ä¸“门用于查询 mdm_item è¡¨
 */
@Service
@Validated
public class MesMdmItemServiceImpl implements MesMdmItemService {
    @Resource
    private MesMdmItemMapper mesMdmItemMapper;
    @Override
    public MesMdmItemDO getItem(Long id) {
        return mesMdmItemMapper.selectById(id);
    }
    @Override
    public MesMdmItemDO validateItemExists(Long id) {
        MesMdmItemDO item = mesMdmItemMapper.selectById(id);
        if (item == null) {
            throw exception(MD_ITEM_NOT_EXISTS);
        }
        return item;
    }
    @Override
    public MesMdmItemDO validateItemExistsAndEnable(Long id) {
        MesMdmItemDO item = validateItemExists(id);
        if (item.getStatus() != null && item.getStatus() == 1) {
            throw exception(MD_ITEM_IS_DISABLE);
        }
        return item;
    }
    @Override
    public List<MesMdmItemDO> getItemList(Collection<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return Collections.emptyList();
        }
        return mesMdmItemMapper.selectListByIds(ids);
    }
}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeLineServiceImpl.java
@@ -8,7 +8,7 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.arrivalnotice.vo.line.MesWmArrivalNoticeLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.arrivalnotice.MesWmArrivalNoticeLineMapper;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@@ -34,7 +34,7 @@
    @Lazy
    private MesWmArrivalNoticeService arrivalNoticeService;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Override
    public Long createArrivalNoticeLine(MesWmArrivalNoticeLineSaveReqVO createReqVO) {
@@ -66,7 +66,7 @@
        // æ ¡éªŒçˆ¶å•据存在且为草稿状态
        arrivalNoticeService.validateArrivalNoticeExistsAndDraft(reqVO.getNoticeId());
        // æ ¡éªŒç‰©æ–™å­˜åœ¨
        itemService.validateItemExistsAndEnable(reqVO.getItemId());
        mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
    }
    /**
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeServiceImpl.java
@@ -14,7 +14,7 @@
import cn.iocoder.yudao.module.erp.api.purchase.ErpPurchaseOrderApi;
import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderRespDTO;
import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderItemRespDTO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -49,7 +49,7 @@
    private ErpPurchaseOrderApi purchaseOrderApi;
    @Resource
    private MesMdItemService mdItemService;
    private MesMdmItemService mdmItemService;
    @Override
    public Long createArrivalNotice(MesWmArrivalNoticeSaveReqVO createReqVO) {
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/batch/MesWmBatchServiceImpl.java
@@ -6,14 +6,14 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchGenerateReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchPageReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemBatchConfigDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.batch.MesWmBatchMapper;
import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum;
import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemBatchConfigService;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.wm.barcode.MesWmBarcodeService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
@@ -48,7 +48,7 @@
    private MesWmBatchMapper batchMapper;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    private MesMdItemBatchConfigService itemBatchConfigService;
    @Resource
@@ -75,8 +75,8 @@
    @Transactional(rollbackFor = Exception.class)
    public MesWmBatchDO getOrGenerateBatchCode(MesWmBatchGenerateReqVO reqVO) {
        // 1.1 æŸ¥è¯¢ç‰©æ–™ä¿¡æ¯ï¼Œæ£€æŸ¥æ˜¯å¦å¯ç”¨æ‰¹æ¬¡ç®¡ç†
        MesMdItemDO item = itemService.validateItemExists(reqVO.getItemId());
        if (Boolean.FALSE.equals(item.getBatchFlag())) {
        MesMdmItemDO item = mdmItemService.validateItemExists(reqVO.getItemId());
        if (Boolean.FALSE.equals(item.getIsBatchManaged())) {
            // æœªå¯ç”¨æ‰¹æ¬¡ç®¡ç†ï¼Œè¿”回 null
            return null;
        }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockService.java
@@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.mes.service.wm.materialstock;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockAdjustReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockFreezeReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockListReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockPageReqVO;
@@ -148,4 +149,12 @@
    MesWmMaterialStockDO validateSelectedStock(Long materialStockId, Long itemId, Long batchId, String batchCode,
                                               Long warehouseId, Long locationId, Long areaId, BigDecimal quantity);
    /**
     * åº“存调整(自定义出入库)
     *
     * @param reqVO è°ƒæ•´è¯·æ±‚
     * @return åº“存事务流水ID
     */
    Long adjustMaterialStock(@Valid MesWmMaterialStockAdjustReqVO reqVO);
}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImpl.java
@@ -5,22 +5,28 @@
import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockAdjustReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockFreezeReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockListReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockPageReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.materialstock.MesWmMaterialStockMapper;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemTypeService;
import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.math.BigDecimal;
@@ -42,7 +48,7 @@
    private MesWmMaterialStockMapper materialStockMapper;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    private MesMdItemTypeService itemTypeService;
    @Resource
@@ -50,6 +56,9 @@
    @Resource
    @Lazy
    private MesWmWarehouseService warehouseService;
    @Resource
    @Lazy
    private MesWmTransactionService wmTransactionService;
    @Override
    public MesWmMaterialStockDO getMaterialStock(Long id) {
@@ -156,9 +165,9 @@
        }
        // 2. ä¸å­˜åœ¨åˆ™æ–°å»º
        MesMdItemDO item = itemService.validateItemExists(itemId);
        MesMdmItemDO item = mdmItemService.validateItemExists(itemId);
        MesWmMaterialStockDO newStock = MesWmMaterialStockDO.builder()
                .itemId(itemId).itemTypeId(item.getItemTypeId())
                .itemId(itemId).itemTypeId(item.getCategoryId())
                .warehouseId(warehouseId).locationId(locationId).areaId(areaId)
                .batchId(batchId).batchCode(batchCode).vendorId(vendorId)
                .quantity(BigDecimal.ZERO) // åˆå§‹æ•°é‡ä¸º 0,由 updateMaterialStockQuantity æ›´æ–°
@@ -232,4 +241,58 @@
        return stock;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long adjustMaterialStock(MesWmMaterialStockAdjustReqVO reqVO) {
        // 1. æ ¡éªŒç‰©æ–™å­˜åœ¨ä¸”启用
        MesMdmItemDO item = mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
        // 2. åˆ¤æ–­æ˜¯å…¥åº“还是出库
        BigDecimal quantity = reqVO.getQuantity();
        if (quantity == null || quantity.compareTo(BigDecimal.ZERO) == 0) {
            throw exception(WM_MATERIAL_STOCK_QUANTITY_INVALID);
        }
        boolean isInbound = quantity.compareTo(BigDecimal.ZERO) > 0;
        int bizType = isInbound ? MesBizTypeConstants.WM_STOCK_ADJUST_IN : MesBizTypeConstants.WM_STOCK_ADJUST_OUT;
        // 3. æ ¡éªŒåº“位混放规则
        checkAreaMixingRule(reqVO.getAreaId(), reqVO.getItemId(), reqVO.getBatchId());
        // 4. èŽ·å–æˆ–åˆ›å»ºåº“å­˜è®°å½•
        MesWmMaterialStockDO stock = getOrCreateMaterialStock(
                reqVO.getItemId(),
                reqVO.getWarehouseId(),
                reqVO.getLocationId(),
                reqVO.getAreaId(),
                reqVO.getBatchId(),
                reqVO.getBatchCode(),
                reqVO.getVendorId(),
                LocalDateTime.now()
        );
        // 5. æ›´æ–°åº“存数量(出库时校验库存充足)
        updateMaterialStockQuantity(stock.getId(), quantity, !isInbound);
        // 6. åˆ›å»ºåº“存事务流水
        MesWmTransactionSaveReqDTO transaction = new MesWmTransactionSaveReqDTO()
                .setType(isInbound ? MesWmTransactionTypeEnum.IN.getType() : MesWmTransactionTypeEnum.OUT.getType())
                .setBizType(bizType)
                .setBizId(stock.getId())
                .setBizCode("STOCK_ADJUST_" + stock.getId())
                .setBizLineId(stock.getId())
                .setItemId(reqVO.getItemId())
                .setQuantity(quantity)
                .setBatchId(reqVO.getBatchId())
                .setBatchCode(reqVO.getBatchCode())
                .setWarehouseId(reqVO.getWarehouseId())
                .setLocationId(reqVO.getLocationId())
                .setAreaId(reqVO.getAreaId())
                .setVendorId(reqVO.getVendorId())
                .setReceiptTime(LocalDateTime.now())
                .setCheckFlag(!isInbound);
        wmTransactionService.createTransaction(transaction);
        return stock.getId();
    }
}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueLineServiceImpl.java
@@ -6,7 +6,7 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.miscissue.vo.line.MesWmMiscIssueLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.miscissue.MesWmMiscIssueLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.miscissue.MesWmMiscIssueLineMapper;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
@@ -36,7 +36,7 @@
    @Lazy
    private MesWmMiscIssueDetailService miscIssueDetailService;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    private MesWmWarehouseAreaService warehouseAreaService;
@@ -129,7 +129,7 @@
        // æ ¡éªŒçˆ¶å•据存在且为可编辑状态
        miscIssueService.validateMiscIssueEditable(issueId);
        // æ ¡éªŒç‰©æ–™å­˜åœ¨
        itemService.validateItemExistsAndEnable(reqVO.getItemId());
        mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
        // æ ¡éªŒä»“库、库区、库位的父子关系
        warehouseAreaService.validateWarehouseAreaExists(reqVO.getWarehouseId(),
                reqVO.getLocationId(), reqVO.getAreaId());
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptLineServiceImpl.java
@@ -6,7 +6,7 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.miscreceipt.vo.line.MesWmMiscReceiptLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.miscreceipt.MesWmMiscReceiptLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.miscreceipt.MesWmMiscReceiptLineMapper;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
@@ -36,7 +36,7 @@
    @Lazy
    private MesWmMiscReceiptDetailService miscReceiptDetailService;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    private MesWmWarehouseAreaService warehouseAreaService;
@@ -125,7 +125,7 @@
        // æ ¡éªŒçˆ¶å•据存在且为可编辑状态
        miscReceiptService.validateMiscReceiptEditable(reqVO.getReceiptId());
        // æ ¡éªŒç‰©æ–™å­˜åœ¨
        itemService.validateItemExistsAndEnable(reqVO.getItemId());
        mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
        // æ ¡éªŒä»“库层级关系(仓库 - åº“位 - åº“区)
        warehouseAreaService.validateWarehouseAreaExists(reqVO.getWarehouseId(),
                reqVO.getLocationId(), reqVO.getAreaId());
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/outsourceissue/MesWmOutsourceIssueDetailServiceImpl.java
@@ -6,7 +6,7 @@
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.outsourceissue.MesWmOutsourceIssueDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.outsourceissue.MesWmOutsourceIssueLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.outsourceissue.MesWmOutsourceIssueDetailMapper;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import jakarta.annotation.Resource;
@@ -35,7 +35,7 @@
    @Lazy
    private MesWmOutsourceIssueLineService outsourceIssueLineService;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    private MesWmWarehouseAreaService warehouseAreaService;
    @Resource
@@ -113,7 +113,7 @@
            throw exception(WM_OUTSOURCE_ISSUE_DETAIL_LINE_NOT_MATCH);
        }
        // æ ¡éªŒç‰©æ–™å­˜åœ¨
        itemService.validateItemExistsAndEnable(saveReqVO.getItemId());
        mdmItemService.validateItemExistsAndEnable(saveReqVO.getItemId());
        if (ObjUtil.notEqual(line.getItemId(), saveReqVO.getItemId())) {
            throw exception(WM_OUTSOURCE_ISSUE_DETAIL_ITEM_MISMATCH);
        }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/outsourceissue/MesWmOutsourceIssueLineServiceImpl.java
@@ -11,7 +11,7 @@
import cn.iocoder.yudao.module.mes.dal.mysql.wm.outsourceissue.MesWmOutsourceIssueLineMapper;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderBomDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderBomService;
import cn.iocoder.yudao.module.mes.service.wm.batch.MesWmBatchService;
import jakarta.annotation.Resource;
@@ -44,7 +44,7 @@
    @Lazy
    private MesWmOutsourceIssueService outsourceIssueService;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    private MesWmBatchService batchService;
    @Resource
@@ -121,7 +121,7 @@
            throw exception(WM_OUTSOURCE_ISSUE_NOT_EXISTS);
        }
        // æ ¡éªŒå…³è”的物料存在
        itemService.validateItemExistsAndEnable(saveReqVO.getItemId());
        mdmItemService.validateItemExistsAndEnable(saveReqVO.getItemId());
        // æ ¡éªŒç‰©æ–™æ˜¯å¦åœ¨å·¥å• BOM ä¸­
        validateItemInWorkOrderBom(issue.getWorkOrderId(), saveReqVO.getItemId());
    }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/outsourcereceipt/MesWmOutsourceReceiptDetailServiceImpl.java
@@ -4,7 +4,7 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.outsourcereceipt.vo.detail.MesWmOutsourceReceiptDetailSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.outsourcereceipt.MesWmOutsourceReceiptDetailDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.outsourcereceipt.MesWmOutsourceReceiptDetailMapper;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
@@ -26,7 +26,7 @@
    private MesWmOutsourceReceiptDetailMapper detailMapper;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    private MesWmWarehouseAreaService areaService;
@@ -91,7 +91,7 @@
     */
    private void validateDetailSaveData(MesWmOutsourceReceiptDetailSaveReqVO reqVO) {
        // æ ¡éªŒç‰©æ–™å­˜åœ¨
        itemService.validateItemExistsAndEnable(reqVO.getItemId());
        mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
        // æ ¡éªŒä»“库、库区、库位的层级关系
        areaService.validateWarehouseAreaExists(reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId());
    }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/outsourcereceipt/MesWmOutsourceReceiptLineServiceImpl.java
@@ -11,7 +11,7 @@
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.outsourcereceipt.MesWmOutsourceReceiptLineMapper;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
import cn.iocoder.yudao.module.mes.service.wm.batch.MesWmBatchService;
import jakarta.annotation.Resource;
@@ -36,7 +36,7 @@
    private MesWmOutsourceReceiptLineMapper lineMapper;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    @Lazy
    private MesWmOutsourceReceiptDetailService outsourceReceiptDetailService;
@@ -52,7 +52,7 @@
    @Override
    public Long createOutsourceReceiptLine(MesWmOutsourceReceiptLineSaveReqVO createReqVO) {
        // æ ¡éªŒç‰©æ–™å­˜åœ¨
        itemService.validateItemExistsAndEnable(createReqVO.getItemId());
        mdmItemService.validateItemExistsAndEnable(createReqVO.getItemId());
        // æ’å…¥
        MesWmOutsourceReceiptLineDO line = BeanUtils.toBean(createReqVO, MesWmOutsourceReceiptLineDO.class);
@@ -72,7 +72,7 @@
        // æ ¡éªŒå­˜åœ¨
        validateOutsourceReceiptLineExists(updateReqVO.getId());
        // æ ¡éªŒç‰©æ–™å­˜åœ¨
        itemService.validateItemExistsAndEnable(updateReqVO.getItemId());
        mdmItemService.validateItemExistsAndEnable(updateReqVO.getItemId());
        // æ›´æ–°
        MesWmOutsourceReceiptLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmOutsourceReceiptLineDO.class);
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/outsourcereceipt/MesWmOutsourceReceiptServiceImpl.java
@@ -10,7 +10,7 @@
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.outsourcereceipt.vo.MesWmOutsourceReceiptPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.outsourcereceipt.vo.MesWmOutsourceReceiptSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.outsourcereceipt.MesWmOutsourceReceiptDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.outsourcereceipt.MesWmOutsourceReceiptDetailDO;
@@ -20,7 +20,7 @@
import cn.iocoder.yudao.module.mes.enums.wm.MesWmOutsourceReceiptStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.md.vendor.MesMdVendorService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
@@ -58,7 +58,7 @@
    @Resource
    private MesMdVendorService vendorService;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    private MesProWorkOrderService workOrderService;
@@ -160,7 +160,7 @@
                        MesWmOutsourceReceiptDetailDO::getQuantity, BigDecimal::add, BigDecimal.ZERO);
                // å¯¹æ¯”行数量与明细总数量,不满足直接抛出
                if (line.getQuantity().compareTo(totalDetailQuantity) > 0) {
                    MesMdItemDO item = itemService.validateItemExistsAndEnable(line.getItemId());
                    MesMdmItemDO item = mdmItemService.validateItemExistsAndEnable(line.getItemId());
                    throw exception(WM_OUTSOURCE_RECEIPT_DETAIL_QUANTITY_MISMATCH,
                            item.getCode() + " " + item.getName() + " æœªå®Œæˆä¸Šæž¶");
                }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/packages/MesWmPackageLineServiceImpl.java
@@ -6,7 +6,7 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.packages.vo.line.MesWmPackageLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.packages.MesWmPackageLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.packages.MesWmPackageLineMapper;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
@@ -34,7 +34,7 @@
    @Lazy
    private MesWmPackageService packageService;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    private MesProWorkOrderService workOrderService;
@@ -101,7 +101,7 @@
        // æ ¡éªŒè£…箱单状态为草稿
        packageService.validatePackageStatusDraft(reqVO.getPackageId());
        // æ ¡éªŒäº§å“ç‰©æ–™å­˜åœ¨
        itemService.validateItemExistsAndEnable(reqVO.getItemId());
        mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
        // æ ¡éªŒå·¥å•已确认
        workOrderService.validateWorkOrderConfirmed(reqVO.getWorkOrderId());
    }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueLineServiceImpl.java
@@ -9,7 +9,7 @@
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.productissue.MesWmProductIssueLineMapper;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderBomService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
@@ -36,7 +36,7 @@
    @Lazy
    private MesWmProductIssueService issueService;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    private MesProWorkOrderBomService workOrderBomService;
    @Resource
@@ -114,7 +114,7 @@
        // æ ¡éªŒç‰©æ–™åœ¨å·¥å• BOM ä¸­
        validateItemInWorkOrderBom(reqVO.getIssueId(), reqVO.getItemId());
        // æ ¡éªŒç‰©æ–™å­˜åœ¨
        itemService.validateItemExistsAndEnable(reqVO.getItemId());
        mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
    }
    private void validateItemInWorkOrderBom(Long issueId, Long itemId) {
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productreceipt/MesWmProductReceiptLineServiceImpl.java
@@ -6,7 +6,7 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.productreceipt.vo.line.MesWmProductReceiptLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productreceipt.MesWmProductReceiptLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.productreceipt.MesWmProductReceiptLineMapper;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@@ -34,7 +34,7 @@
    @Resource
    private MesWmProductReceiptDetailService productReceiptDetailService;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Override
    public Long createProductReceiptLine(MesWmProductReceiptLineSaveReqVO createReqVO) {
@@ -109,7 +109,7 @@
        // æ ¡éªŒçˆ¶å•据存在且为可编辑状态
        productReceiptService.validateProductReceiptEditable(reqVO.getReceiptId());
        // æ ¡éªŒç‰©æ–™å­˜åœ¨
        itemService.validateItemExistsAndEnable(reqVO.getItemId());
        mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
    }
}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesDetailServiceImpl.java
@@ -6,7 +6,7 @@
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesDetailMapper;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import jakarta.annotation.Resource;
@@ -32,7 +32,7 @@
    private MesWmProductSalesDetailMapper productSalesDetailMapper;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    @Lazy
    private MesWmProductSalesLineService productSalesLineService;
@@ -115,7 +115,7 @@
            throw exception(WM_PRODUCT_SALES_DETAIL_LINE_NOT_MATCH);
        }
        // æ ¡éªŒç‰©æ–™å­˜åœ¨
        itemService.validateItemExistsAndEnable(reqVO.getItemId());
        mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
        if (ObjUtil.notEqual(line.getItemId(), reqVO.getItemId())) {
            throw exception(WM_PRODUCT_SALES_DETAIL_ITEM_MISMATCH);
        }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesLineServiceImpl.java
@@ -12,7 +12,7 @@
import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesLineMapper;
import cn.iocoder.yudao.module.mes.enums.qc.MesQcCheckResultEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.wm.batch.MesWmBatchService;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.salesnotice.MesWmSalesNoticeLineDO;
@@ -47,7 +47,7 @@
    @Resource
    private MesWmProductSalesDetailService productSalesDetailService;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    private MesWmBatchService batchService;
    @Resource
@@ -153,7 +153,7 @@
        // æ ¡éªŒä¸»å•存在且为草稿状态
        MesWmProductSalesDO sales = productSalesService.validateProductSalesExistsAndDraft(reqVO.getSalesId());
        // æ ¡éªŒç‰©æ–™å­˜åœ¨
        itemService.validateItemExistsAndEnable(reqVO.getItemId());
        mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
        // æ ¡éªŒå…³è”发货通知单行(存在性 + å½’属 + å­—段一致性)
        validateSalesNoticeLine(sales, reqVO);
        // æ ¹æ® batchCode è§£æž batchId
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java
@@ -251,9 +251,9 @@
        productSalesMapper.updateById(new MesWmProductSalesDO()
                .setId(id).setStatus(MesWmProductSalesStatusEnum.FINISHED.getStatus()));
        // 5. æ›´æ–°å…³è”的发货通知单状态
        // 5. æ›´æ–°å…³è”的发货通知单出库数量和状态
        if (sales.getNoticeId() != null) {
            salesNoticeService.finishSalesNotice(sales.getNoticeId());
            updateSalesNoticeOutCount(sales);
        }
        // 6. å›žå†™ ERP é”€å”®è®¢å•的出库数量和状态
@@ -261,6 +261,23 @@
    }
    /**
     * æ›´æ–°å‘货通知单的出库数量和状态
     */
    private void updateSalesNoticeOutCount(MesWmProductSalesDO sales) {
        // èŽ·å–å‡ºåº“å•è¡Œ
        List<MesWmProductSalesLineDO> lines = productSalesLineService.getProductSalesLineListBySalesId(sales.getId());
        if (CollUtil.isEmpty(lines)) {
            return;
        }
        // éåŽ†è¡Œï¼ŒæŒ‰ noticeLineId æ›´æ–°å‡ºåº“数量
        for (MesWmProductSalesLineDO line : lines) {
            if (line.getNoticeLineId() != null && line.getQuantity() != null) {
                salesNoticeService.updateSalesNoticeLineOutCount(line.getNoticeLineId(), line.getQuantity());
            }
        }
    }
    /**
     * å›žå†™ ERP é”€å”®è®¢å•的出库数量和状态
     */
    private void updateErpSaleOrderOutCount(MesWmProductSalesDO sales) {
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueLineServiceImpl.java
@@ -12,7 +12,7 @@
import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnIssueStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnIssueTypeEnum;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@@ -39,7 +39,7 @@
    @Lazy
    private MesWmReturnIssueService issueService;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    @Lazy
    private MesWmReturnIssueDetailService issueDetailService;
@@ -117,7 +117,7 @@
        // æ ¡éªŒçˆ¶æ•°æ®å­˜åœ¨ + è‰ç¨¿çŠ¶æ€
        MesWmReturnIssueDO issue = issueService.validateReturnIssueExistsAndPrepare(reqVO.getIssueId());
        // æ ¡éªŒç‰©æ–™å­˜åœ¨
        itemService.validateItemExistsAndEnable(reqVO.getItemId());
        mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
        return issue;
    }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueServiceImpl.java
@@ -9,7 +9,7 @@
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.MesWmReturnIssuePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.MesWmReturnIssueSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLineDO;
@@ -18,7 +18,7 @@
import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnIssueStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
@@ -61,7 +61,7 @@
    @Resource
    private MesProWorkOrderService workOrderService;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    private MesWmTransactionService wmTransactionService;
    @Resource
@@ -168,7 +168,7 @@
                        MesWmReturnIssueDetailDO::getQuantity, BigDecimal::add, BigDecimal.ZERO);
                // å¯¹æ¯”行数量与明细总数量,不满足直接抛出
                if (line.getQuantity().compareTo(totalDetailQuantity) > 0) {
                    MesMdItemDO item = itemService.validateItemExistsAndEnable(line.getItemId());
                    MesMdmItemDO item = mdmItemService.validateItemExistsAndEnable(line.getItemId());
                    throw exception(WM_RETURN_ISSUE_DETAIL_QUANTITY_MISMATCH,
                            item.getCode() + " " + item.getName() + " æœªå®Œæˆä¸Šæž¶");
                }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesLineServiceImpl.java
@@ -6,13 +6,13 @@
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.line.MesWmReturnSalesLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.line.MesWmReturnSalesLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesLineDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnsales.MesWmReturnSalesLineMapper;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnSalesStatusEnum;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.wm.batch.MesWmBatchService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
@@ -43,7 +43,7 @@
    @Lazy
    private MesWmReturnSalesService returnSalesService;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    private MesWmBatchService batchService;
    @Resource
@@ -155,9 +155,9 @@
     * @param batchId  æ‰¹æ¬¡ID
     */
    private void validateItemBatchManagement(Long returnId, Long itemId, Long batchId) {
        MesMdItemDO item = itemService.validateItemExistsAndEnable(itemId);
        MesMdmItemDO item = mdmItemService.validateItemExistsAndEnable(itemId);
        // å¦‚果物料启用了批次管理,则必须选择批次
        if (Boolean.TRUE.equals(item.getBatchFlag()) && batchId == null) {
        if (Boolean.TRUE.equals(item.getIsBatchManaged()) && batchId == null) {
            throw exception(MD_ITEM_BATCH_REQUIRED);
        }
        // æ ¡éªŒæ‰¹æ¬¡å­˜åœ¨ä¸”属于当前物料和客户
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesServiceImpl.java
@@ -9,7 +9,7 @@
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.MesWmReturnSalesPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.MesWmReturnSalesSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesLineDO;
@@ -19,7 +19,7 @@
import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnSalesStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
import jakarta.annotation.Resource;
@@ -55,7 +55,7 @@
    @Resource
    private MesMdClientService clientService;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    private MesWmTransactionService wmTransactionService;
@@ -170,7 +170,7 @@
                        MesWmReturnSalesDetailDO::getQuantity, BigDecimal::add, BigDecimal.ZERO);
                // å¯¹æ¯”行数量与明细总数量,不满足直接抛出
                if (line.getQuantity().compareTo(totalDetailQuantity) > 0) {
                    MesMdItemDO item = itemService.validateItemExistsAndEnable(line.getItemId());
                    MesMdmItemDO item = mdmItemService.validateItemExistsAndEnable(line.getItemId());
                    throw exception(WM_RETURN_SALES_DETAIL_QUANTITY_MISMATCH,
                            item.getCode() + " " + item.getName() + " æœªå®Œæˆä¸Šæž¶");
                }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorDetailServiceImpl.java
@@ -6,7 +6,7 @@
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnvendor.MesWmReturnVendorDetailMapper;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import jakarta.annotation.Resource;
@@ -33,7 +33,7 @@
    @Lazy
    private MesWmReturnVendorLineService returnVendorLineService;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    private MesWmMaterialStockService materialStockService;
    @Resource
@@ -72,7 +72,7 @@
            throw exception(WM_RETURN_VENDOR_DETAIL_LINE_NOT_MATCH);
        }
        // æ ¡éªŒç‰©æ–™å­˜åœ¨
        itemService.validateItemExistsAndEnable(reqVO.getItemId());
        mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
        // æ ¡éªŒç‰©æ–™ä¸Žè¡Œç‰©æ–™ä¸€è‡´
        validateItemConsistency(reqVO.getItemId(), line);
        // æ ¡éªŒåº“位存在
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorLineServiceImpl.java
@@ -7,7 +7,7 @@
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorLineDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnvendor.MesWmReturnVendorLineMapper;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.wm.batch.MesWmBatchService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
@@ -37,7 +37,7 @@
    @Lazy
    private MesWmReturnVendorDetailService returnVendorDetailService;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    private MesWmBatchService batchService;
@@ -113,7 +113,7 @@
        // æ ¡éªŒçˆ¶æ•°æ®å­˜åœ¨ä¸”为草稿状态
        MesWmReturnVendorDO returnVendor = returnVendorService.validateReturnVendorExistsAndPrepare(reqVO.getReturnId());
        // æ ¡éªŒç‰©æ–™å­˜åœ¨
        itemService.validateItemExistsAndEnable(reqVO.getItemId());
        mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
        // æ ¡éªŒæ‰¹æ¬¡å­˜åœ¨ä¸”属于当前物料和供应商
        if (reqVO.getBatchId() != null) {
            batchService.validateBatchExists(reqVO.getBatchId(), reqVO.getItemId(), null, returnVendor.getVendorId());
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/salesnotice/MesWmSalesNoticeLineServiceImpl.java
@@ -10,7 +10,7 @@
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.salesnotice.MesWmSalesNoticeDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.salesnotice.MesWmSalesNoticeLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.salesnotice.MesWmSalesNoticeLineMapper;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.wm.batch.MesWmBatchService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
@@ -39,7 +39,7 @@
    @Resource
    private MesWmBatchService batchService;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Override
    public Long createSalesNoticeLine(MesWmSalesNoticeLineSaveReqVO createReqVO) {
@@ -122,7 +122,7 @@
        validateNoticeStatusDraft(reqVO.getNoticeId());
        // æ ¡éªŒç‰©æ–™å­˜åœ¨
        if (reqVO.getItemId() != null) {
            itemService.validateItemExistsAndEnable(reqVO.getItemId());
            mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
        }
    }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/salesnotice/MesWmSalesNoticeService.java
@@ -98,9 +98,35 @@
    /**
     * å®Œæˆå‘货通知单(出库完成后调用)
     * ç´¯åŠ å‡ºåº“æ•°é‡å¹¶è®¡ç®—å‡ºåº“çŠ¶æ€
     *
     * @param id ç¼–号
     * @deprecated è¯·ä½¿ç”¨ {@link #updateSalesNoticeOutCount(Long, java.math.BigDecimal)}
     */
    @Deprecated
    void finishSalesNotice(Long id);
    /**
     * æ›´æ–°å‘货通知单行的出库数量
     *
     * @param noticeLineId å‘货通知单行ID
     * @param outCount     å‡ºåº“数量
     */
    void updateSalesNoticeLineOutCount(Long noticeLineId, java.math.BigDecimal outCount);
    /**
     * æ›´æ–°å‘货通知单的出库状态
     *
     * @param noticeId å‘货通知单ID
     */
    void updateSalesNoticeOutStatus(Long noticeId);
    /**
     * ä»Žå‘货通知单生成销售出库单
     *
     * @param noticeId å‘货通知单ID
     * @return é”€å”®å‡ºåº“单ID
     */
    Long generateProductSalesFromNotice(Long noticeId);
}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/salesnotice/MesWmSalesNoticeServiceImpl.java
@@ -6,9 +6,16 @@
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.salesnotice.vo.MesWmSalesNoticePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.salesnotice.vo.MesWmSalesNoticeSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.salesnotice.MesWmSalesNoticeDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.salesnotice.MesWmSalesNoticeLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesLineMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.salesnotice.MesWmSalesNoticeMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.salesnotice.MesWmSalesNoticeLineMapper;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmOutStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductSalesStatusEnum;
import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService;
import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService;
import cn.iocoder.yudao.module.erp.api.sale.ErpSaleOrderApi;
@@ -20,6 +27,7 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -48,6 +56,13 @@
    private ErpSaleOrderApi saleOrderApi;
    @Resource
    private MesMdAutoCodeRecordService autoCodeRecordService;
    @Resource
    private MesWmProductSalesMapper productSalesMapper;
    @Resource
    private MesWmProductSalesLineMapper productSalesLineMapper;
    @Resource
    private MesWmSalesNoticeLineMapper salesNoticeLineMapper;
    @Override
    public Long createSalesNotice(MesWmSalesNoticeSaveReqVO createReqVO) {
@@ -202,11 +217,137 @@
    @Override
    public void finishSalesNotice(Long id) {
        // æ ¡éªŒå­˜åœ¨
        MesWmSalesNoticeDO notice = validateSalesNoticeExists(id);
        // æ›´æ–°çŠ¶æ€ä¸ºå·²å®Œæˆ
        // å·²åºŸå¼ƒï¼Œä¿ç•™å…¼å®¹æ€§
        updateSalesNoticeOutStatus(id);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSalesNoticeLineOutCount(Long noticeLineId, BigDecimal outCount) {
        if (noticeLineId == null || outCount == null) {
            return;
        }
        // 1. èŽ·å–å‘è´§é€šçŸ¥å•è¡Œ
        MesWmSalesNoticeLineDO line = salesNoticeLineMapper.selectById(noticeLineId);
        if (line == null) {
            return;
        }
        // 2. ç´¯åŠ å‡ºåº“æ•°é‡
        BigDecimal newOutCount = (line.getOutCount() != null ? line.getOutCount() : BigDecimal.ZERO).add(outCount);
        // 3. æ›´æ–°è¡Œ
        salesNoticeLineMapper.updateById(new MesWmSalesNoticeLineDO()
                .setId(noticeLineId)
                .setOutCount(newOutCount));
        // 4. æ›´æ–°ä¸»å•出库状态
        updateSalesNoticeOutStatus(line.getNoticeId());
    }
    @Override
    public void updateSalesNoticeOutStatus(Long noticeId) {
        if (noticeId == null) {
            return;
        }
        // 1. èŽ·å–å‘è´§é€šçŸ¥å•
        MesWmSalesNoticeDO notice = salesNoticeMapper.selectById(noticeId);
        if (notice == null) {
            return;
        }
        // 2. èŽ·å–å‘è´§é€šçŸ¥å•è¡Œ
        List<MesWmSalesNoticeLineDO> lines = salesNoticeLineMapper.selectListByNoticeId(noticeId);
        if (CollUtil.isEmpty(lines)) {
            return;
        }
        // 3. è®¡ç®—出库状态
        int outStatus = calculateOutStatus(lines);
        // 4. æ›´æ–°å‡ºåº“状态
        salesNoticeMapper.updateById(new MesWmSalesNoticeDO()
                .setId(id).setStatus(FINISHED.getStatus()));
                .setId(noticeId)
                .setOutStatus(outStatus));
        // 5. å¦‚果全部出库,更新单据状态为已完成
        if (outStatus == MesWmOutStatusEnum.ALL_OUT.getStatus()) {
            salesNoticeMapper.updateById(new MesWmSalesNoticeDO()
                    .setId(noticeId)
                    .setStatus(FINISHED.getStatus()));
        }
    }
    /**
     * è®¡ç®—出库状态
     */
    private int calculateOutStatus(List<MesWmSalesNoticeLineDO> lines) {
        boolean allOut = true;
        boolean anyOut = false;
        for (MesWmSalesNoticeLineDO line : lines) {
            BigDecimal quantity = line.getQuantity() != null ? line.getQuantity() : BigDecimal.ZERO;
            BigDecimal outCount = line.getOutCount() != null ? line.getOutCount() : BigDecimal.ZERO;
            if (outCount.compareTo(BigDecimal.ZERO) > 0) {
                anyOut = true;
            }
            if (outCount.compareTo(quantity) < 0) {
                allOut = false;
            }
        }
        if (allOut) {
            return MesWmOutStatusEnum.ALL_OUT.getStatus();
        } else if (anyOut) {
            return MesWmOutStatusEnum.PART_OUT.getStatus();
        } else {
            return MesWmOutStatusEnum.NOT_OUT.getStatus();
        }
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long generateProductSalesFromNotice(Long noticeId) {
        // 1. æ ¡éªŒå‘货通知单存在且为待出库状态
        MesWmSalesNoticeDO notice = validateSalesNoticeExists(noticeId);
        if (ObjUtil.notEqual(APPROVED.getStatus(), notice.getStatus())) {
            throw exception(WM_SALES_NOTICE_STATUS_NOT_APPROVED);
        }
        // 2. èŽ·å–å‘è´§é€šçŸ¥å•è¡Œ
        List<MesWmSalesNoticeLineDO> noticeLines = salesNoticeLineService.getSalesNoticeLineListByNoticeId(noticeId);
        if (CollUtil.isEmpty(noticeLines)) {
            throw exception(WM_SALES_NOTICE_LINE_EMPTY);
        }
        // 3. ç”Ÿæˆé”€å”®å‡ºåº“单编码
        String code = autoCodeRecordService.generateAutoCode("WM_PRODUCT_SALES_CODE", null);
        // 4. åˆ›å»ºé”€å”®å‡ºåº“单主表
        MesWmProductSalesDO productSales = new MesWmProductSalesDO();
        productSales.setCode(code);
        productSales.setName("发货通知单[" + notice.getCode() + "]出库");
        productSales.setClientId(notice.getClientId());
        productSales.setSaleOrderId(notice.getSaleOrderId());
        productSales.setSalesOrderCode(notice.getSaleOrderCode());
        productSales.setNoticeId(noticeId);
        productSales.setSalesDate(notice.getSalesDate());
        // æ”¶è´§ä¿¡æ¯ä»Žå‘货通知单带入
        productSales.setContactName(notice.getRecipientName());
        productSales.setContactTelephone(notice.getRecipientTelephone());
        productSales.setContactAddress(notice.getRecipientAddress());
        productSales.setStatus(MesWmProductSalesStatusEnum.PREPARE.getStatus());
        productSalesMapper.insert(productSales);
        // 5. éåŽ†å‘è´§é€šçŸ¥å•è¡Œåˆ›å»ºé”€å”®å‡ºåº“å•è¡Œ
        for (MesWmSalesNoticeLineDO noticeLine : noticeLines) {
            MesWmProductSalesLineDO salesLine = new MesWmProductSalesLineDO();
            salesLine.setSalesId(productSales.getId());
            salesLine.setSaleOrderItemId(noticeLine.getSaleOrderItemId());
            salesLine.setNoticeLineId(noticeLine.getId());
            salesLine.setItemId(noticeLine.getItemId());
            salesLine.setQuantity(noticeLine.getQuantity());
            salesLine.setBatchId(noticeLine.getBatchId());
            salesLine.setBatchCode(noticeLine.getBatchCode());
            salesLine.setOqcCheckFlag(noticeLine.getOqcCheckFlag());
            productSalesLineMapper.insert(salesLine);
        }
        return productSales.getId();
    }
}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/sn/MesWmSnServiceImpl.java
@@ -11,7 +11,7 @@
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.autocode.MesMdAutoCodeRecordService;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
import cn.iocoder.yudao.module.mes.service.wm.barcode.MesWmBarcodeService;
import jakarta.annotation.Resource;
@@ -41,7 +41,7 @@
    @Resource
    private MesMdAutoCodeRecordService autoCodeRecordService;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    private MesProWorkOrderService workOrderService;
    @Resource
@@ -51,7 +51,7 @@
    @Transactional(rollbackFor = Exception.class)
    public void generateSnCodes(MesWmSnGenerateReqVO reqVO) {
        // æ ¡éªŒç‰©æ–™æ˜¯å¦å­˜åœ¨
        itemService.validateItemExists(reqVO.getItemId());
        mdmItemService.validateItemExists(reqVO.getItemId());
        // æ ¡éªŒå·¥å•是否存在
        if (reqVO.getWorkOrderId() != null) {
            workOrderService.validateWorkOrderExists(reqVO.getWorkOrderId());
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/MesWmTransactionServiceImpl.java
@@ -4,7 +4,7 @@
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transaction.MesWmTransactionDO;
@@ -13,7 +13,7 @@
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.transaction.MesWmTransactionMapper;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.wm.batch.MesWmBatchService;
import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
@@ -47,7 +47,7 @@
    @Resource
    private MesWmBatchService batchService;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    private MesWmWarehouseService warehouseService;
    @Resource
@@ -144,8 +144,8 @@
        }
        // 2. å…¥åº“时:启用批次管理的物料,必须传递批次号
        if (inbound) {
            MesMdItemDO item = itemService.validateItemExists(reqDTO.getItemId());
            if (Boolean.TRUE.equals(item.getBatchFlag())) {
            MesMdmItemDO item = mdmItemService.validateItemExists(reqDTO.getItemId());
            if (Boolean.TRUE.equals(item.getIsBatchManaged())) {
                if (StrUtil.isEmpty(reqDTO.getBatchCode()) && reqDTO.getBatchId() == null) {
                    throw exception(WM_TRANSACTION_BATCH_REQUIRED);
                }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transfer/MesWmTransferLineServiceImpl.java
@@ -5,7 +5,7 @@
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transfer.MesWmTransferLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.transfer.MesWmTransferLineMapper;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import jakarta.annotation.Resource;
@@ -38,7 +38,7 @@
    @Lazy
    private MesWmTransferDetailService transferDetailService;
    @Resource
    private MesMdItemService itemService;
    private MesMdmItemService mdmItemService;
    @Resource
    private MesWmWarehouseAreaService warehouseAreaService;
    @Resource
@@ -109,7 +109,7 @@
        // æ ¡éªŒçˆ¶æ•°æ®å¯ç¼–辑
        transferService.validateTransferEditable(reqVO.getTransferId());
        // æ ¡éªŒäº§å“å­˜åœ¨
        itemService.validateItemExistsAndEnable(reqVO.getItemId());
        mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
        // æ ¡éªŒæ¥æºä»“库、库区、库位的关联关系
        warehouseAreaService.validateWarehouseAreaExists(reqVO.getFromWarehouseId(),
                reqVO.getFromLocationId(), reqVO.getFromAreaId());