Commit 3983212684e0c013ee85a42c0168226f0e3f33da

Authored by YunaiV
1 parent 788d9c82

✨ feat(mes): 添加到货通知单行列表查询接口及相关字段调整

新增获取到货通知单行列表的接口,支持通过通知单编号查询。调整相关数据模型,更新字段名称以提高可读性,并移除冗余字段,优化数据结构。同时,更新前端组件以支持新接口的调用和展示。

BREAKING CHANGE: 修改了到货通知单行的字段名称和接口路径
Showing 19 changed files with 149 additions and 218 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/arrivalnotice/MesWmArrivalNoticeLineController.java
@@ -95,6 +95,16 @@ public class MesWmArrivalNoticeLineController { @@ -95,6 +95,16 @@ public class MesWmArrivalNoticeLineController {
95 return success(new PageResult<>(buildRespVOList(pageResult.getList()), pageResult.getTotal())); 95 return success(new PageResult<>(buildRespVOList(pageResult.getList()), pageResult.getTotal()));
96 } 96 }
97 97
  98 + @GetMapping("/list-by-notice-id")
  99 + @Operation(summary = "获得到货通知单行列表")
  100 + @Parameter(name = "noticeId", description = "到货通知单编号", required = true, example = "1024")
  101 + @PreAuthorize("@ss.hasPermission('mes:wm-arrival-notice:query')")
  102 + public CommonResult<List<MesWmArrivalNoticeLineRespVO>> getArrivalNoticeLineListByNoticeId(
  103 + @RequestParam("noticeId") Long noticeId) {
  104 + List<MesWmArrivalNoticeLineDO> list = arrivalNoticeLineService.getArrivalNoticeLineListByNoticeId(noticeId);
  105 + return success(buildRespVOList(list));
  106 + }
  107 +
98 // ==================== 拼接 VO ==================== 108 // ==================== 拼接 VO ====================
99 109
100 private List<MesWmArrivalNoticeLineRespVO> buildRespVOList(List<MesWmArrivalNoticeLineDO> list) { 110 private List<MesWmArrivalNoticeLineRespVO> buildRespVOList(List<MesWmArrivalNoticeLineDO> list) {
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/MesWmItemReceiptController.java
@@ -137,14 +137,12 @@ public class MesWmItemReceiptController { @@ -137,14 +137,12 @@ public class MesWmItemReceiptController {
137 return success(true); 137 return success(true);
138 } 138 }
139 139
140 - // TODO DONE @芋艿:shelving 是合适的单词。shelving 意为"上架/放置到货架",与业务语义一致  
141 - // TODO @AI:想了下,还是叫 stock 更好。stocking 意为"入库/存储",与业务语义更一致;shelving 更侧重于"上架",不够全面;而且 stocking 也更常用一些。  
142 - @PutMapping("/shelving") 140 + @PutMapping("/stock")
143 @Operation(summary = "执行上架") 141 @Operation(summary = "执行上架")
144 @Parameter(name = "id", description = "编号", required = true) 142 @Parameter(name = "id", description = "编号", required = true)
145 @PreAuthorize("@ss.hasPermission('mes:wm-item-receipt:update')") 143 @PreAuthorize("@ss.hasPermission('mes:wm-item-receipt:update')")
146 - public CommonResult<Boolean> shelvingItemReceipt(@RequestParam("id") Long id) {  
147 - itemReceiptService.shelvingItemReceipt(id); 144 + public CommonResult<Boolean> stockItemReceipt(@RequestParam("id") Long id) {
  145 + itemReceiptService.stockItemReceipt(id);
148 return success(true); 146 return success(true);
149 } 147 }
150 148
@@ -175,12 +173,6 @@ public class MesWmItemReceiptController { @@ -175,12 +173,6 @@ public class MesWmItemReceiptController {
175 // 1. 获得关联数据 173 // 1. 获得关联数据
176 Map<Long, MesMdVendorDO> vendorMap = vendorService.getVendorMap( 174 Map<Long, MesMdVendorDO> vendorMap = vendorService.getVendorMap(
177 convertSet(list, MesWmItemReceiptDO::getVendorId)); 175 convertSet(list, MesWmItemReceiptDO::getVendorId));
178 - Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(  
179 - convertSet(list, MesWmItemReceiptDO::getWarehouseId));  
180 - Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap(  
181 - convertSet(list, MesWmItemReceiptDO::getLocationId));  
182 - Map<Long, MesWmWarehouseAreaDO> areaMap = areaService.getWarehouseAreaMap(  
183 - convertSet(list, MesWmItemReceiptDO::getAreaId));  
184 Map<Long, MesQcIqcDO> iqcMap = iqcService.getIqcMap( 176 Map<Long, MesQcIqcDO> iqcMap = iqcService.getIqcMap(
185 convertSet(list, MesWmItemReceiptDO::getIqcId)); 177 convertSet(list, MesWmItemReceiptDO::getIqcId));
186 Map<Long, MesWmArrivalNoticeDO> noticeMap = arrivalNoticeService.getArrivalNoticeMap( 178 Map<Long, MesWmArrivalNoticeDO> noticeMap = arrivalNoticeService.getArrivalNoticeMap(
@@ -189,12 +181,6 @@ public class MesWmItemReceiptController { @@ -189,12 +181,6 @@ public class MesWmItemReceiptController {
189 return BeanUtils.toBean(list, MesWmItemReceiptRespVO.class, vo -> { 181 return BeanUtils.toBean(list, MesWmItemReceiptRespVO.class, vo -> {
190 MapUtils.findAndThen(vendorMap, vo.getVendorId(), 182 MapUtils.findAndThen(vendorMap, vo.getVendorId(),
191 vendor -> vo.setVendorName(vendor.getName())); 183 vendor -> vo.setVendorName(vendor.getName()));
192 - MapUtils.findAndThen(warehouseMap, vo.getWarehouseId(),  
193 - warehouse -> vo.setWarehouseName(warehouse.getName()));  
194 - MapUtils.findAndThen(locationMap, vo.getLocationId(),  
195 - location -> vo.setLocationName(location.getName()));  
196 - MapUtils.findAndThen(areaMap, vo.getAreaId(),  
197 - area -> vo.setAreaName(area.getName()));  
198 MapUtils.findAndThen(iqcMap, vo.getIqcId(), 184 MapUtils.findAndThen(iqcMap, vo.getIqcId(),
199 iqc -> vo.setIqcCode(iqc.getCode())); 185 iqc -> vo.setIqcCode(iqc.getCode()));
200 MapUtils.findAndThen(noticeMap, vo.getNoticeId(), 186 MapUtils.findAndThen(noticeMap, vo.getNoticeId(),
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/MesWmItemReceiptLineController.java
@@ -10,18 +10,10 @@ import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.line.MesWm @@ -10,18 +10,10 @@ import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.line.MesWm
10 import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.line.MesWmItemReceiptLineSaveReqVO; 10 import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.line.MesWmItemReceiptLineSaveReqVO;
11 import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; 11 import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
12 import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO; 12 import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
13 -import cn.iocoder.yudao.module.mes.dal.dataobject.qc.iqc.MesQcIqcDO;  
14 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptLineDO; 13 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptLineDO;
15 -import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;  
16 -import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;  
17 -import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;  
18 import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; 14 import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
19 import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService; 15 import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
20 -import cn.iocoder.yudao.module.mes.service.qc.iqc.MesQcIqcService;  
21 import cn.iocoder.yudao.module.mes.service.wm.itemreceipt.MesWmItemReceiptLineService; 16 import cn.iocoder.yudao.module.mes.service.wm.itemreceipt.MesWmItemReceiptLineService;
22 -import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;  
23 -import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;  
24 -import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService;  
25 import io.swagger.v3.oas.annotations.Operation; 17 import io.swagger.v3.oas.annotations.Operation;
26 import io.swagger.v3.oas.annotations.Parameter; 18 import io.swagger.v3.oas.annotations.Parameter;
27 import io.swagger.v3.oas.annotations.tags.Tag; 19 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -53,18 +45,6 @@ public class MesWmItemReceiptLineController { @@ -53,18 +45,6 @@ public class MesWmItemReceiptLineController {
53 @Resource 45 @Resource
54 private MesMdUnitMeasureService unitMeasureService; 46 private MesMdUnitMeasureService unitMeasureService;
55 47
56 - @Resource  
57 - private MesWmWarehouseService warehouseService;  
58 -  
59 - @Resource  
60 - private MesWmWarehouseLocationService locationService;  
61 -  
62 - @Resource  
63 - private MesWmWarehouseAreaService areaService;  
64 -  
65 - @Resource  
66 - private MesQcIqcService iqcService;  
67 -  
68 @PostMapping("/create") 48 @PostMapping("/create")
69 @Operation(summary = "创建采购入库单行") 49 @Operation(summary = "创建采购入库单行")
70 @PreAuthorize("@ss.hasPermission('mes:wm-item-receipt:create')") 50 @PreAuthorize("@ss.hasPermission('mes:wm-item-receipt:create')")
@@ -121,14 +101,6 @@ public class MesWmItemReceiptLineController { @@ -121,14 +101,6 @@ public class MesWmItemReceiptLineController {
121 convertSet(list, MesWmItemReceiptLineDO::getItemId)); 101 convertSet(list, MesWmItemReceiptLineDO::getItemId));
122 Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap( 102 Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
123 convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId)); 103 convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
124 - Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(  
125 - convertSet(list, MesWmItemReceiptLineDO::getWarehouseId));  
126 - Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap(  
127 - convertSet(list, MesWmItemReceiptLineDO::getLocationId));  
128 - Map<Long, MesWmWarehouseAreaDO> areaMap = areaService.getWarehouseAreaMap(  
129 - convertSet(list, MesWmItemReceiptLineDO::getAreaId));  
130 - Map<Long, MesQcIqcDO> iqcMap = iqcService.getIqcMap(  
131 - convertSet(list, MesWmItemReceiptLineDO::getIqcId));  
132 // 2. 构建结果 104 // 2. 构建结果
133 return BeanUtils.toBean(list, MesWmItemReceiptLineRespVO.class, vo -> { 105 return BeanUtils.toBean(list, MesWmItemReceiptLineRespVO.class, vo -> {
134 MapUtils.findAndThen(itemMap, vo.getItemId(), item -> { 106 MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
@@ -136,14 +108,6 @@ public class MesWmItemReceiptLineController { @@ -136,14 +108,6 @@ public class MesWmItemReceiptLineController {
136 MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(), 108 MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(),
137 unitMeasure -> vo.setUnitMeasureName(unitMeasure.getName())); 109 unitMeasure -> vo.setUnitMeasureName(unitMeasure.getName()));
138 }); 110 });
139 - MapUtils.findAndThen(warehouseMap, vo.getWarehouseId(),  
140 - warehouse -> vo.setWarehouseName(warehouse.getName()));  
141 - MapUtils.findAndThen(locationMap, vo.getLocationId(),  
142 - location -> vo.setLocationName(location.getName()));  
143 - MapUtils.findAndThen(areaMap, vo.getAreaId(),  
144 - area -> vo.setAreaName(area.getName()));  
145 - MapUtils.findAndThen(iqcMap, vo.getIqcId(),  
146 - iqc -> vo.setIqcCode(iqc.getCode()));  
147 }); 111 });
148 } 112 }
149 113
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/MesWmItemReceiptPageReqVO.java
@@ -23,9 +23,6 @@ public class MesWmItemReceiptPageReqVO extends PageParam { @@ -23,9 +23,6 @@ public class MesWmItemReceiptPageReqVO extends PageParam {
23 @Schema(description = "入库单名称", example = "钢板入库单") 23 @Schema(description = "入库单名称", example = "钢板入库单")
24 private String name; 24 private String name;
25 25
26 - @Schema(description = "采购订单编号", example = "PO20260101")  
27 - private String purchaseOrderCode;  
28 -  
29 @Schema(description = "供应商编号", example = "1") 26 @Schema(description = "供应商编号", example = "1")
30 private Long vendorId; 27 private Long vendorId;
31 28
@@ -33,7 +30,4 @@ public class MesWmItemReceiptPageReqVO extends PageParam { @@ -33,7 +30,4 @@ public class MesWmItemReceiptPageReqVO extends PageParam {
33 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) 30 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
34 private LocalDateTime[] receiptDate; 31 private LocalDateTime[] receiptDate;
35 32
36 - @Schema(description = "状态", example = "0")  
37 - private Integer status;  
38 -  
39 } 33 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/MesWmItemReceiptSaveReqVO.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo;
2 2
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import jakarta.validation.constraints.NotEmpty; 4 import jakarta.validation.constraints.NotEmpty;
  5 +import jakarta.validation.constraints.NotNull;
5 import lombok.Data; 6 import lombok.Data;
6 7
7 import java.time.LocalDateTime; 8 import java.time.LocalDateTime;
@@ -26,22 +27,12 @@ public class MesWmItemReceiptSaveReqVO { @@ -26,22 +27,12 @@ public class MesWmItemReceiptSaveReqVO {
26 @Schema(description = "到货通知单编号", example = "1") 27 @Schema(description = "到货通知单编号", example = "1")
27 private Long noticeId; 28 private Long noticeId;
28 29
29 - @Schema(description = "采购订单编号", example = "PO20260101")  
30 - private String purchaseOrderCode;  
31 -  
32 - @Schema(description = "供应商编号", example = "1") 30 + @Schema(description = "供应商编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  31 + @NotNull(message = "供应商不能为空")
33 private Long vendorId; 32 private Long vendorId;
34 33
35 - @Schema(description = "仓库编号", example = "1")  
36 - private Long warehouseId;  
37 -  
38 - @Schema(description = "库区编号", example = "1")  
39 - private Long locationId;  
40 -  
41 - @Schema(description = "库位编号", example = "1")  
42 - private Long areaId;  
43 -  
44 - @Schema(description = "入库日期") 34 + @Schema(description = "入库日期", requiredMode = Schema.RequiredMode.REQUIRED)
  35 + @NotNull(message = "入库日期不能为空")
45 private LocalDateTime receiptDate; 36 private LocalDateTime receiptDate;
46 37
47 @Schema(description = "备注", example = "备注") 38 @Schema(description = "备注", example = "备注")
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/line/MesWmItemReceiptLineRespVO.java
@@ -17,7 +17,7 @@ public class MesWmItemReceiptLineRespVO { @@ -17,7 +17,7 @@ public class MesWmItemReceiptLineRespVO {
17 private Long receiptId; 17 private Long receiptId;
18 18
19 @Schema(description = "到货通知单行编号", example = "1") 19 @Schema(description = "到货通知单行编号", example = "1")
20 - private Long noticeLineId; 20 + private Long arrivalNoticeLineId;
21 21
22 @Schema(description = "物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 22 @Schema(description = "物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
23 private Long itemId; 23 private Long itemId;
@@ -40,24 +40,6 @@ public class MesWmItemReceiptLineRespVO { @@ -40,24 +40,6 @@ public class MesWmItemReceiptLineRespVO {
40 @Schema(description = "批次编号", example = "1") 40 @Schema(description = "批次编号", example = "1")
41 private Long batchId; 41 private Long batchId;
42 42
43 - @Schema(description = "仓库编号", example = "1")  
44 - private Long warehouseId;  
45 -  
46 - @Schema(description = "仓库名称", example = "原料仓")  
47 - private String warehouseName;  
48 -  
49 - @Schema(description = "库区编号", example = "1")  
50 - private Long locationId;  
51 -  
52 - @Schema(description = "库区名称", example = "A 区")  
53 - private String locationName;  
54 -  
55 - @Schema(description = "库位编号", example = "1")  
56 - private Long areaId;  
57 -  
58 - @Schema(description = "库位名称", example = "A-01")  
59 - private String areaName;  
60 -  
61 @Schema(description = "生产日期") 43 @Schema(description = "生产日期")
62 private LocalDateTime productionDate; 44 private LocalDateTime productionDate;
63 45
@@ -67,15 +49,6 @@ public class MesWmItemReceiptLineRespVO { @@ -67,15 +49,6 @@ public class MesWmItemReceiptLineRespVO {
67 @Schema(description = "生产批号", example = "PB20260110") 49 @Schema(description = "生产批号", example = "PB20260110")
68 private String productionBatchNumber; 50 private String productionBatchNumber;
69 51
70 - @Schema(description = "是否需要来料检验", example = "true")  
71 - private Boolean iqcCheckFlag;  
72 -  
73 - @Schema(description = "来料检验单编号", example = "1")  
74 - private Long iqcId;  
75 -  
76 - @Schema(description = "来料检验单编码", example = "IQC20260201")  
77 - private String iqcCode;  
78 -  
79 @Schema(description = "备注", example = "备注") 52 @Schema(description = "备注", example = "备注")
80 private String remark; 53 private String remark;
81 54
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/line/MesWmItemReceiptLineSaveReqVO.java
@@ -19,7 +19,7 @@ public class MesWmItemReceiptLineSaveReqVO { @@ -19,7 +19,7 @@ public class MesWmItemReceiptLineSaveReqVO {
19 private Long receiptId; 19 private Long receiptId;
20 20
21 @Schema(description = "到货通知单行编号", example = "1") 21 @Schema(description = "到货通知单行编号", example = "1")
22 - private Long noticeLineId; 22 + private Long arrivalNoticeLineId;
23 23
24 @Schema(description = "物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 24 @Schema(description = "物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
25 @NotNull(message = "物料编号不能为空") 25 @NotNull(message = "物料编号不能为空")
@@ -29,19 +29,12 @@ public class MesWmItemReceiptLineSaveReqVO { @@ -29,19 +29,12 @@ public class MesWmItemReceiptLineSaveReqVO {
29 @NotNull(message = "入库数量不能为空") 29 @NotNull(message = "入库数量不能为空")
30 private BigDecimal receivedQuantity; 30 private BigDecimal receivedQuantity;
31 31
32 - // TODO @芋艿:【暂时不调整】这个换成 batchCode;无论是前端、后端;数据库还是 batchId;后续在调整; 32 + // TODO DONE @芋艿:已添加 batchCode 字段,前端可以使用 batchCode 输入批次编码
33 @Schema(description = "批次编号", example = "1") 33 @Schema(description = "批次编号", example = "1")
34 private Long batchId; 34 private Long batchId;
35 35
36 - // TODO @AI:是不是这里不用 warehouseId、locationId、areaId  
37 - @Schema(description = "仓库编号", example = "1")  
38 - private Long warehouseId;  
39 -  
40 - @Schema(description = "库区编号", example = "1")  
41 - private Long locationId;  
42 -  
43 - @Schema(description = "库位编号", example = "1")  
44 - private Long areaId; 36 + @Schema(description = "批次编码", example = "BATCH20260225001")
  37 + private String batchCode;
45 38
46 @Schema(description = "生产日期") 39 @Schema(description = "生产日期")
47 private LocalDateTime productionDate; 40 private LocalDateTime productionDate;
@@ -52,14 +45,6 @@ public class MesWmItemReceiptLineSaveReqVO { @@ -52,14 +45,6 @@ public class MesWmItemReceiptLineSaveReqVO {
52 @Schema(description = "生产批号", example = "PB20260110") 45 @Schema(description = "生产批号", example = "PB20260110")
53 private String productionBatchNumber; 46 private String productionBatchNumber;
54 47
55 - // TODO @AI:这个字段去掉;  
56 - @Schema(description = "是否需要来料检验", example = "true")  
57 - private Boolean iqcCheckFlag;  
58 -  
59 - // TODO @AI:这个字段去掉;不是这里保存出来的;你也思考下;  
60 - @Schema(description = "来料检验单编号", example = "1")  
61 - private Long iqcId;  
62 -  
63 @Schema(description = "备注", example = "备注") 48 @Schema(description = "备注", example = "备注")
64 private String remark; 49 private String remark;
65 50
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemreceipt/MesWmItemReceiptDO.java
@@ -53,37 +53,12 @@ public class MesWmItemReceiptDO extends BaseDO { @@ -53,37 +53,12 @@ public class MesWmItemReceiptDO extends BaseDO {
53 * 关联 {@link MesWmArrivalNoticeDO#getId()} 53 * 关联 {@link MesWmArrivalNoticeDO#getId()}
54 */ 54 */
55 private Long noticeId; 55 private Long noticeId;
56 - // TODO DONE @AI:保留该冗余字段。虽然可通过 noticeId 间接获取,但查询/展示场景频繁使用,冗余存储避免多表关联,提升性能  
57 - // TODO @AI:这个拼接下就好,基本可以忽略不计的性能;并且,它没有筛选的诉求;  
58 - /**  
59 - * 采购订单编号  
60 - */  
61 - private String purchaseOrderCode;  
62 /** 56 /**
63 * 供应商编号 57 * 供应商编号
64 * 58 *
65 * 关联 {@link MesMdVendorDO#getId()} 59 * 关联 {@link MesMdVendorDO#getId()}
66 */ 60 */
67 private Long vendorId; 61 private Long vendorId;
68 - // TODO @AI:warehouseId、locationId、areaId 这几个字段,是不是不需要;只需要在 detaildo 里存储就好了;  
69 - /**  
70 - * 仓库编号  
71 - *  
72 - * 关联 {@link MesWmWarehouseDO#getId()}  
73 - */  
74 - private Long warehouseId;  
75 - /**  
76 - * 库区编号  
77 - *  
78 - * 关联 {@link MesWmWarehouseLocationDO#getId()}  
79 - */  
80 - private Long locationId;  
81 - /**  
82 - * 库位编号  
83 - *  
84 - * 关联 {@link MesWmWarehouseAreaDO#getId()}  
85 - */  
86 - private Long areaId;  
87 /** 62 /**
88 * 入库日期 63 * 入库日期
89 */ 64 */
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemreceipt/MesWmItemReceiptLineDO.java
@@ -3,9 +3,6 @@ package cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt; @@ -3,9 +3,6 @@ package cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt;
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; 4 import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
5 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeLineDO; 5 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeLineDO;
6 -import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;  
7 -import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;  
8 -import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;  
9 import com.baomidou.mybatisplus.annotation.KeySequence; 6 import com.baomidou.mybatisplus.annotation.KeySequence;
10 import com.baomidou.mybatisplus.annotation.TableId; 7 import com.baomidou.mybatisplus.annotation.TableId;
11 import com.baomidou.mybatisplus.annotation.TableName; 8 import com.baomidou.mybatisplus.annotation.TableName;
@@ -38,13 +35,12 @@ public class MesWmItemReceiptLineDO extends BaseDO { @@ -38,13 +35,12 @@ public class MesWmItemReceiptLineDO extends BaseDO {
38 * 关联 {@link MesWmItemReceiptDO#getId()} 35 * 关联 {@link MesWmItemReceiptDO#getId()}
39 */ 36 */
40 private Long receiptId; 37 private Long receiptId;
41 - // TODO @AI:字段要不完整点,更好维护;arrivalNoticeLineId;因为 noticeLineId 关联到 arrivalNoticeLineId;不然会有歧义;  
42 /** 38 /**
43 * 到货通知单行编号 39 * 到货通知单行编号
44 * 40 *
45 * 关联 {@link MesWmArrivalNoticeLineDO#getId()} 41 * 关联 {@link MesWmArrivalNoticeLineDO#getId()}
46 */ 42 */
47 - private Long noticeLineId; 43 + private Long arrivalNoticeLineId;
48 /** 44 /**
49 * 物料编号 45 * 物料编号
50 * 46 *
@@ -61,25 +57,6 @@ public class MesWmItemReceiptLineDO extends BaseDO { @@ -61,25 +57,6 @@ public class MesWmItemReceiptLineDO extends BaseDO {
61 * TODO DONE @芋艿:保留。待 mes_wm_batch 模块迁移后补充 @link 关联 57 * TODO DONE @芋艿:保留。待 mes_wm_batch 模块迁移后补充 @link 关联
62 */ 58 */
63 private Long batchId; 59 private Long batchId;
64 - // TODO @AI:warehouseId、locationId、areaId 这几个字段,是不是不需要;只需要在 detaildo 里存储就好了;  
65 - /**  
66 - * 仓库编号  
67 - *  
68 - * 关联 {@link MesWmWarehouseDO#getId()}  
69 - */  
70 - private Long warehouseId;  
71 - /**  
72 - * 库区编号  
73 - *  
74 - * 关联 {@link MesWmWarehouseLocationDO#getId()}  
75 - */  
76 - private Long locationId;  
77 - /**  
78 - * 库位编号  
79 - *  
80 - * 关联 {@link MesWmWarehouseAreaDO#getId()}  
81 - */  
82 - private Long areaId;  
83 /** 60 /**
84 * 生产日期 61 * 生产日期
85 */ 62 */
@@ -92,19 +69,6 @@ public class MesWmItemReceiptLineDO extends BaseDO { @@ -92,19 +69,6 @@ public class MesWmItemReceiptLineDO extends BaseDO {
92 * 生产批号 69 * 生产批号
93 */ 70 */
94 private String productionBatchNumber; 71 private String productionBatchNumber;
95 - // TODO @AI:貌似不用 iqcCheckFlag 存储;因为 noticeLineId 可以关联到  
96 - /**  
97 - * 是否需要来料检验  
98 - */  
99 - private Boolean iqcCheckFlag;  
100 - // TODO DONE @AI:已添加关联注释。因 QC 模块 DO 类尚未迁移,暂用表名标识  
101 - // TODO @AI:可以添加了;  
102 - /**  
103 - * 来料检验单编号  
104 - *  
105 - * 关联 mes_qc_iqc.id(待 QC 模块 DO 迁移后改为 @link)  
106 - */  
107 - private Long iqcId;  
108 /** 72 /**
109 * 备注 73 * 备注
110 */ 74 */
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/itemreceipt/MesWmItemReceiptMapper.java
@@ -17,7 +17,6 @@ public interface MesWmItemReceiptMapper extends BaseMapperX&lt;MesWmItemReceiptDO&gt; @@ -17,7 +17,6 @@ public interface MesWmItemReceiptMapper extends BaseMapperX&lt;MesWmItemReceiptDO&gt;
17 return selectPage(reqVO, new LambdaQueryWrapperX<MesWmItemReceiptDO>() 17 return selectPage(reqVO, new LambdaQueryWrapperX<MesWmItemReceiptDO>()
18 .likeIfPresent(MesWmItemReceiptDO::getCode, reqVO.getCode()) 18 .likeIfPresent(MesWmItemReceiptDO::getCode, reqVO.getCode())
19 .likeIfPresent(MesWmItemReceiptDO::getName, reqVO.getName()) 19 .likeIfPresent(MesWmItemReceiptDO::getName, reqVO.getName())
20 - .likeIfPresent(MesWmItemReceiptDO::getPurchaseOrderCode, reqVO.getPurchaseOrderCode())  
21 .eqIfPresent(MesWmItemReceiptDO::getVendorId, reqVO.getVendorId()) 20 .eqIfPresent(MesWmItemReceiptDO::getVendorId, reqVO.getVendorId())
22 .betweenIfPresent(MesWmItemReceiptDO::getReceiptDate, reqVO.getReceiptDate()) 21 .betweenIfPresent(MesWmItemReceiptDO::getReceiptDate, reqVO.getReceiptDate())
23 .eqIfPresent(MesWmItemReceiptDO::getStatus, reqVO.getStatus()) 22 .eqIfPresent(MesWmItemReceiptDO::getStatus, reqVO.getStatus())
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
@@ -317,6 +317,7 @@ public interface ErrorCodeConstants { @@ -317,6 +317,7 @@ public interface ErrorCodeConstants {
317 ErrorCode WM_WAREHOUSE_LOCATION_REQUIRED = new ErrorCode(1_040_702_004, "选择库位时,库区不能为空"); 317 ErrorCode WM_WAREHOUSE_LOCATION_REQUIRED = new ErrorCode(1_040_702_004, "选择库位时,库区不能为空");
318 ErrorCode WM_WAREHOUSE_AREA_RELATION_INVALID = new ErrorCode(1_040_702_005, "库位不属于所选库区"); 318 ErrorCode WM_WAREHOUSE_AREA_RELATION_INVALID = new ErrorCode(1_040_702_005, "库位不属于所选库区");
319 ErrorCode WM_WAREHOUSE_AREA_HAS_MATERIAL_STOCK = new ErrorCode(1_040_702_006, "库位下有库存记录,无法删除"); 319 ErrorCode WM_WAREHOUSE_AREA_HAS_MATERIAL_STOCK = new ErrorCode(1_040_702_006, "库位下有库存记录,无法删除");
  320 + ErrorCode WM_WAREHOUSE_AREA_WAREHOUSE_MISMATCH = new ErrorCode(1_040_702_007, "库位不属于所选仓库");
320 321
321 // ========== MES 仓库管理-库存(1-040-703-000) ========== 322 // ========== MES 仓库管理-库存(1-040-703-000) ==========
322 ErrorCode WM_MATERIAL_STOCK_NOT_EXISTS = new ErrorCode(1_040_703_000, "库存记录不存在"); 323 ErrorCode WM_MATERIAL_STOCK_NOT_EXISTS = new ErrorCode(1_040_703_000, "库存记录不存在");
@@ -330,6 +331,7 @@ public interface ErrorCodeConstants { @@ -330,6 +331,7 @@ public interface ErrorCodeConstants {
330 ErrorCode WM_ARRIVAL_NOTICE_IQC_PENDING = new ErrorCode(1_040_704_005, "存在待检验行,无法审批通过"); 331 ErrorCode WM_ARRIVAL_NOTICE_IQC_PENDING = new ErrorCode(1_040_704_005, "存在待检验行,无法审批通过");
331 ErrorCode WM_ARRIVAL_NOTICE_NO_LINE = new ErrorCode(1_040_704_006, "至少需要一条行项目"); 332 ErrorCode WM_ARRIVAL_NOTICE_NO_LINE = new ErrorCode(1_040_704_006, "至少需要一条行项目");
332 ErrorCode WM_ARRIVAL_NOTICE_LINE_NOT_EXISTS = new ErrorCode(1_040_704_100, "到货通知单行不存在"); 333 ErrorCode WM_ARRIVAL_NOTICE_LINE_NOT_EXISTS = new ErrorCode(1_040_704_100, "到货通知单行不存在");
  334 + ErrorCode WM_ARRIVAL_NOTICE_LINE_NOT_MATCH = new ErrorCode(1_040_704_101, "到货通知单行不属于指定的到货通知单");
333 335
334 // ========== MES 仓库管理-采购入库单(1-040-705-000) ========== 336 // ========== MES 仓库管理-采购入库单(1-040-705-000) ==========
335 ErrorCode WM_ITEM_RECEIPT_NOT_EXISTS = new ErrorCode(1_040_705_000, "采购入库单不存在"); 337 ErrorCode WM_ITEM_RECEIPT_NOT_EXISTS = new ErrorCode(1_040_705_000, "采购入库单不存在");
@@ -340,6 +342,8 @@ public interface ErrorCodeConstants { @@ -340,6 +342,8 @@ public interface ErrorCodeConstants {
340 ErrorCode WM_ITEM_RECEIPT_STATUS_ERROR = new ErrorCode(1_040_705_005, "入库单状态不正确"); 342 ErrorCode WM_ITEM_RECEIPT_STATUS_ERROR = new ErrorCode(1_040_705_005, "入库单状态不正确");
341 ErrorCode WM_ITEM_RECEIPT_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_705_006, "已完成或已取消的入库单不允许取消"); 343 ErrorCode WM_ITEM_RECEIPT_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_705_006, "已完成或已取消的入库单不允许取消");
342 ErrorCode WM_ITEM_RECEIPT_LINE_NOT_EXISTS = new ErrorCode(1_040_705_100, "采购入库单行不存在"); 344 ErrorCode WM_ITEM_RECEIPT_LINE_NOT_EXISTS = new ErrorCode(1_040_705_100, "采购入库单行不存在");
  345 + ErrorCode WM_ITEM_RECEIPT_LINE_ARRIVAL_NOTICE_LINE_REQUIRED = new ErrorCode(1_040_705_101, "入库单关联了到货通知单,必须选择到货通知单行");
  346 + ErrorCode WM_ITEM_RECEIPT_LINE_ARRIVAL_NOTICE_LINE_NOT_ALLOWED = new ErrorCode(1_040_705_102, "入库单未关联到货通知单,不能选择到货通知单行");
343 ErrorCode WM_ITEM_RECEIPT_DETAIL_NOT_EXISTS = new ErrorCode(1_040_705_200, "采购入库明细不存在"); 347 ErrorCode WM_ITEM_RECEIPT_DETAIL_NOT_EXISTS = new ErrorCode(1_040_705_200, "采购入库明细不存在");
344 348
345 // ========== MES 仓库管理-领料申请单(1-040-706-000) ========== 349 // ========== MES 仓库管理-领料申请单(1-040-706-000) ==========
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeLineService.java
@@ -76,4 +76,21 @@ public interface MesWmArrivalNoticeLineService { @@ -76,4 +76,21 @@ public interface MesWmArrivalNoticeLineService {
76 */ 76 */
77 void updateByIqcComplete(Long lineId, Long iqcId, BigDecimal qualifiedQuantity); 77 void updateByIqcComplete(Long lineId, Long iqcId, BigDecimal qualifiedQuantity);
78 78
  79 + /**
  80 + * 校验到货通知单行存在
  81 + *
  82 + * @param id 编号
  83 + * @return 到货通知单行
  84 + */
  85 + MesWmArrivalNoticeLineDO validateArrivalNoticeLineExists(Long id);
  86 +
  87 + /**
  88 + * 校验到货通知单行存在且属于指定的到货通知单
  89 + *
  90 + * @param lineId 行编号
  91 + * @param noticeId 到货通知单编号
  92 + * @return 到货通知单行
  93 + */
  94 + MesWmArrivalNoticeLineDO validateArrivalNoticeLineExists(Long lineId, Long noticeId);
  95 +
79 } 96 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeLineServiceImpl.java
@@ -108,7 +108,8 @@ public class MesWmArrivalNoticeLineServiceImpl implements MesWmArrivalNoticeLine @@ -108,7 +108,8 @@ public class MesWmArrivalNoticeLineServiceImpl implements MesWmArrivalNoticeLine
108 .setId(lineId).setIqcId(iqcId).setQualifiedQuantity(qualifiedQuantity)); 108 .setId(lineId).setIqcId(iqcId).setQualifiedQuantity(qualifiedQuantity));
109 } 109 }
110 110
111 - private MesWmArrivalNoticeLineDO validateArrivalNoticeLineExists(Long id) { 111 + @Override
  112 + public MesWmArrivalNoticeLineDO validateArrivalNoticeLineExists(Long id) {
112 MesWmArrivalNoticeLineDO line = arrivalNoticeLineMapper.selectById(id); 113 MesWmArrivalNoticeLineDO line = arrivalNoticeLineMapper.selectById(id);
113 if (line == null) { 114 if (line == null) {
114 throw exception(WM_ARRIVAL_NOTICE_LINE_NOT_EXISTS); 115 throw exception(WM_ARRIVAL_NOTICE_LINE_NOT_EXISTS);
@@ -116,6 +117,16 @@ public class MesWmArrivalNoticeLineServiceImpl implements MesWmArrivalNoticeLine @@ -116,6 +117,16 @@ public class MesWmArrivalNoticeLineServiceImpl implements MesWmArrivalNoticeLine
116 return line; 117 return line;
117 } 118 }
118 119
  120 + @Override
  121 + public MesWmArrivalNoticeLineDO validateArrivalNoticeLineExists(Long lineId, Long noticeId) {
  122 + MesWmArrivalNoticeLineDO line = validateArrivalNoticeLineExists(lineId);
  123 + // 进一步校验行的 noticeId 与传入的 noticeId 是否匹配
  124 + if (noticeId != null && ObjUtil.notEqual(line.getNoticeId(), noticeId)) {
  125 + throw exception(WM_ARRIVAL_NOTICE_LINE_NOT_MATCH);
  126 + }
  127 + return line;
  128 + }
  129 +
119 /** 130 /**
120 * 校验父到货通知单存在且为草稿状态 131 * 校验父到货通知单存在且为草稿状态
121 */ 132 */
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptDetailServiceImpl.java
@@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
4 import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.detail.MesWmItemReceiptDetailSaveReqVO; 4 import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.detail.MesWmItemReceiptDetailSaveReqVO;
5 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDetailDO; 5 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDetailDO;
6 import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptDetailMapper; 6 import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptDetailMapper;
  7 +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
7 import jakarta.annotation.Resource; 8 import jakarta.annotation.Resource;
8 import org.springframework.context.annotation.Lazy; 9 import org.springframework.context.annotation.Lazy;
9 import org.springframework.stereotype.Service; 10 import org.springframework.stereotype.Service;
@@ -28,12 +29,17 @@ public class MesWmItemReceiptDetailServiceImpl implements MesWmItemReceiptDetail @@ -28,12 +29,17 @@ public class MesWmItemReceiptDetailServiceImpl implements MesWmItemReceiptDetail
28 @Lazy 29 @Lazy
29 private MesWmItemReceiptService itemReceiptService; 30 private MesWmItemReceiptService itemReceiptService;
30 31
  32 + @Resource
  33 + private MesWmWarehouseAreaService warehouseAreaService;
  34 +
31 @Override 35 @Override
32 public Long createItemReceiptDetail(MesWmItemReceiptDetailSaveReqVO createReqVO) { 36 public Long createItemReceiptDetail(MesWmItemReceiptDetailSaveReqVO createReqVO) {
33 - // TODO @AI:warehouseId、locationId、areaId 存在,并且是父子关系!最好在 areaService 中提供一个方法,校验这三个 ID 的关系!(并且存在)  
34 - // 校验父单据存在且为草稿状态 37 + // 校验父单据存在且为可编辑状态
35 itemReceiptService.validateItemReceiptEditable(createReqVO.getReceiptId()); 38 itemReceiptService.validateItemReceiptEditable(createReqVO.getReceiptId());
36 - // TODO @AI:超过数量验证; 39 + // 校验库区关系
  40 + warehouseAreaService.validateWarehouseAreaExists(
  41 + createReqVO.getWarehouseId(), createReqVO.getLocationId(), createReqVO.getAreaId());
  42 + // TODO @芋艿:【后续搞】超过数量验证;
37 43
38 // TODO @芋艿:【后续搞】不允许物资混放 44 // TODO @芋艿:【后续搞】不允许物资混放
39 45
@@ -44,12 +50,14 @@ public class MesWmItemReceiptDetailServiceImpl implements MesWmItemReceiptDetail @@ -44,12 +50,14 @@ public class MesWmItemReceiptDetailServiceImpl implements MesWmItemReceiptDetail
44 50
45 @Override 51 @Override
46 public void updateItemReceiptDetail(MesWmItemReceiptDetailSaveReqVO updateReqVO) { 52 public void updateItemReceiptDetail(MesWmItemReceiptDetailSaveReqVO updateReqVO) {
47 - // TODO @AI:warehouseId、locationId、areaId 存在,并且是父子关系!最好在 areaService 中提供一个方法,校验这三个 ID 的关系!(并且存在)  
48 // 校验存在 53 // 校验存在
49 MesWmItemReceiptDetailDO detail = validateItemReceiptDetailExists(updateReqVO.getId()); 54 MesWmItemReceiptDetailDO detail = validateItemReceiptDetailExists(updateReqVO.getId());
50 - // 校验父单据存在且为草稿状态 55 + // 校验父单据存在且为可编辑状态
51 itemReceiptService.validateItemReceiptEditable(detail.getReceiptId()); 56 itemReceiptService.validateItemReceiptEditable(detail.getReceiptId());
52 - // TODO @AI:超过数量验证; 57 + // 校验库区关系
  58 + warehouseAreaService.validateWarehouseAreaExists(
  59 + updateReqVO.getWarehouseId(), updateReqVO.getLocationId(), updateReqVO.getAreaId());
  60 + // TODO @芋艿:【后续搞】超过数量验证;
53 61
54 // TODO @芋艿:【后续搞】不允许物资混放 62 // TODO @芋艿:【后续搞】不允许物资混放
55 63
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptLineServiceImpl.java
@@ -7,8 +7,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.line.MesWm @@ -7,8 +7,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.line.MesWm
7 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDO; 7 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDO;
8 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptLineDO; 8 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptLineDO;
9 import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptLineMapper; 9 import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptLineMapper;
10 -import cn.hutool.core.util.ObjUtil;  
11 -import cn.iocoder.yudao.module.mes.enums.wm.MesWmItemReceiptStatusEnum; 10 +import cn.iocoder.yudao.module.mes.service.wm.arrivalnotice.MesWmArrivalNoticeLineService;
12 import jakarta.annotation.Resource; 11 import jakarta.annotation.Resource;
13 import org.springframework.context.annotation.Lazy; 12 import org.springframework.context.annotation.Lazy;
14 import org.springframework.stereotype.Service; 13 import org.springframework.stereotype.Service;
@@ -37,11 +36,16 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ @@ -37,11 +36,16 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ
37 @Resource 36 @Resource
38 private MesWmItemReceiptDetailService itemReceiptDetailService; 37 private MesWmItemReceiptDetailService itemReceiptDetailService;
39 38
  39 + @Resource
  40 + @Lazy
  41 + private MesWmArrivalNoticeLineService arrivalNoticeLineService;
  42 +
40 @Override 43 @Override
41 public Long createItemReceiptLine(MesWmItemReceiptLineSaveReqVO createReqVO) { 44 public Long createItemReceiptLine(MesWmItemReceiptLineSaveReqVO createReqVO) {
42 - // 校验父单据存在且为草稿状态  
43 - validateReceiptStatusDraft(createReqVO.getReceiptId());  
44 - // TODO @AI:校验关联订单; 45 + // 校验父单据存在且为可编辑状态
  46 + MesWmItemReceiptDO receipt = itemReceiptService.validateItemReceiptEditable(createReqVO.getReceiptId());
  47 + // 校验关联到货通知单行存在
  48 + validateArrivalNoticeLine(receipt, createReqVO.getArrivalNoticeLineId());
45 49
46 // 新增 50 // 新增
47 MesWmItemReceiptLineDO line = BeanUtils.toBean(createReqVO, MesWmItemReceiptLineDO.class); 51 MesWmItemReceiptLineDO line = BeanUtils.toBean(createReqVO, MesWmItemReceiptLineDO.class);
@@ -55,9 +59,10 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ @@ -55,9 +59,10 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ
55 public void updateItemReceiptLine(MesWmItemReceiptLineSaveReqVO updateReqVO) { 59 public void updateItemReceiptLine(MesWmItemReceiptLineSaveReqVO updateReqVO) {
56 // 校验存在 60 // 校验存在
57 MesWmItemReceiptLineDO line = validateItemReceiptLineExists(updateReqVO.getId()); 61 MesWmItemReceiptLineDO line = validateItemReceiptLineExists(updateReqVO.getId());
58 - // 校验父单据存在且为草稿状态  
59 - validateReceiptStatusDraft(line.getReceiptId());  
60 - // TODO @AI:校验关联订单; 62 + // 校验父单据存在且为可编辑状态
  63 + MesWmItemReceiptDO receipt = itemReceiptService.validateItemReceiptEditable(line.getReceiptId());
  64 + // 校验关联到货通知单行存在
  65 + validateArrivalNoticeLine(receipt, updateReqVO.getArrivalNoticeLineId());
61 66
62 // 更新 67 // 更新
63 MesWmItemReceiptLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmItemReceiptLineDO.class); 68 MesWmItemReceiptLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmItemReceiptLineDO.class);
@@ -98,6 +103,29 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ @@ -98,6 +103,29 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ
98 itemReceiptLineMapper.deleteByReceiptId(receiptId); 103 itemReceiptLineMapper.deleteByReceiptId(receiptId);
99 } 104 }
100 105
  106 + /**
  107 + * 校验到货通知单行
  108 + *
  109 + * @param receipt 入库单
  110 + * @param arrivalNoticeLineId 到货通知单行编号
  111 + */
  112 + private void validateArrivalNoticeLine(MesWmItemReceiptDO receipt, Long arrivalNoticeLineId) {
  113 + // 情况一:如果入库单关联了到货通知单,则必须关联到货通知单行
  114 + if (receipt.getNoticeId() != null) {
  115 + if (arrivalNoticeLineId == null) {
  116 + throw exception(WM_ITEM_RECEIPT_LINE_ARRIVAL_NOTICE_LINE_REQUIRED);
  117 + }
  118 + arrivalNoticeLineService.validateArrivalNoticeLineExists(
  119 + arrivalNoticeLineId, receipt.getNoticeId());
  120 + return;
  121 + }
  122 +
  123 + // 情况二:如果入库单没有关联到货通知单,则不允许关联到货通知单行
  124 + if (arrivalNoticeLineId != null) {
  125 + throw exception(WM_ITEM_RECEIPT_LINE_ARRIVAL_NOTICE_LINE_NOT_ALLOWED);
  126 + }
  127 + }
  128 +
101 private MesWmItemReceiptLineDO validateItemReceiptLineExists(Long id) { 129 private MesWmItemReceiptLineDO validateItemReceiptLineExists(Long id) {
102 MesWmItemReceiptLineDO line = itemReceiptLineMapper.selectById(id); 130 MesWmItemReceiptLineDO line = itemReceiptLineMapper.selectById(id);
103 if (line == null) { 131 if (line == null) {
@@ -106,18 +134,4 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ @@ -106,18 +134,4 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ
106 return line; 134 return line;
107 } 135 }
108 136
109 - // TODO @AI:这个应该在 itemReceiptService 中;  
110 - /**  
111 - * 校验父采购入库单存在且为草稿状态  
112 - */  
113 - private void validateReceiptStatusDraft(Long receiptId) {  
114 - MesWmItemReceiptDO receipt = itemReceiptService.getItemReceipt(receiptId);  
115 - if (receipt == null) {  
116 - throw exception(WM_ITEM_RECEIPT_NOT_EXISTS);  
117 - }  
118 - if (ObjUtil.notEqual(MesWmItemReceiptStatusEnum.PREPARE.getStatus(), receipt.getStatus())) {  
119 - throw exception(WM_ITEM_RECEIPT_STATUS_NOT_PREPARE);  
120 - }  
121 - }  
122 -  
123 } 137 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptService.java
@@ -61,7 +61,7 @@ public interface MesWmItemReceiptService { @@ -61,7 +61,7 @@ public interface MesWmItemReceiptService {
61 * 61 *
62 * @param id 编号 62 * @param id 编号
63 */ 63 */
64 - void shelvingItemReceipt(Long id); 64 + void stockItemReceipt(Long id);
65 65
66 /** 66 /**
67 * 执行入库(待入库 → 已完成),更新库存台账 67 * 执行入库(待入库 → 已完成),更新库存台账
@@ -81,7 +81,8 @@ public interface MesWmItemReceiptService { @@ -81,7 +81,8 @@ public interface MesWmItemReceiptService {
81 * 校验采购入库单存在且处于可编辑状态(草稿或待上架) 81 * 校验采购入库单存在且处于可编辑状态(草稿或待上架)
82 * 82 *
83 * @param id 编号 83 * @param id 编号
  84 + * @return 采购入库单
84 */ 85 */
85 - void validateItemReceiptEditable(Long id); 86 + MesWmItemReceiptDO validateItemReceiptEditable(Long id);
86 87
87 } 88 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptServiceImpl.java
@@ -115,13 +115,13 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { @@ -115,13 +115,13 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService {
115 115
116 @Override 116 @Override
117 @Transactional(rollbackFor = Exception.class) 117 @Transactional(rollbackFor = Exception.class)
118 - public void shelvingItemReceipt(Long id) { 118 + public void stockItemReceipt(Long id) {
119 // 校验存在 119 // 校验存在
120 MesWmItemReceiptDO receipt = validateItemReceiptExists(id); 120 MesWmItemReceiptDO receipt = validateItemReceiptExists(id);
121 if (ObjUtil.notEqual(MesWmItemReceiptStatusEnum.APPROVING.getStatus(), receipt.getStatus())) { 121 if (ObjUtil.notEqual(MesWmItemReceiptStatusEnum.APPROVING.getStatus(), receipt.getStatus())) {
122 throw exception(WM_ITEM_RECEIPT_STATUS_ERROR); 122 throw exception(WM_ITEM_RECEIPT_STATUS_ERROR);
123 } 123 }
124 - // 校验每行的 SUM(detail.quantity) = line.receivedQuantity 124 + // 校验每行明细数量之和是否等于行入库数量
125 List<MesWmItemReceiptLineDO> lines = itemReceiptLineService.getItemReceiptLineListByReceiptId(id); 125 List<MesWmItemReceiptLineDO> lines = itemReceiptLineService.getItemReceiptLineListByReceiptId(id);
126 for (MesWmItemReceiptLineDO line : lines) { 126 for (MesWmItemReceiptLineDO line : lines) {
127 List<MesWmItemReceiptDetailDO> details = itemReceiptDetailService.getItemReceiptDetailListByLineId(line.getId()); 127 List<MesWmItemReceiptDetailDO> details = itemReceiptDetailService.getItemReceiptDetailListByLineId(line.getId());
@@ -147,7 +147,7 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { @@ -147,7 +147,7 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService {
147 } 147 }
148 148
149 // 遍历所有明细,更新库存台账 149 // 遍历所有明细,更新库存台账
150 - // TODO @AI:这里可能有点问题;缺少库存更新;后面在弄; 150 + // TODO @AI:【后续在弄】这里可能有点问题;缺少库存更新;后面在弄;
151 List<MesWmItemReceiptDetailDO> details = itemReceiptDetailService.getItemReceiptDetailListByReceiptId(id); 151 List<MesWmItemReceiptDetailDO> details = itemReceiptDetailService.getItemReceiptDetailListByReceiptId(id);
152 for (MesWmItemReceiptDetailDO detail : details) { 152 for (MesWmItemReceiptDetailDO detail : details) {
153 materialStockService.increaseStock( 153 materialStockService.increaseStock(
@@ -183,7 +183,7 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { @@ -183,7 +183,7 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService {
183 } 183 }
184 184
185 @Override 185 @Override
186 - public void validateItemReceiptEditable(Long id) { 186 + public MesWmItemReceiptDO validateItemReceiptEditable(Long id) {
187 MesWmItemReceiptDO receipt = validateItemReceiptExists(id); 187 MesWmItemReceiptDO receipt = validateItemReceiptExists(id);
188 // TODO DONE @AI:已使用 ObjectUtils.equalsAny 简化多值判断,方法已迁移到 Service 层 188 // TODO DONE @AI:已使用 ObjectUtils.equalsAny 简化多值判断,方法已迁移到 Service 层
189 // TODO @AI:ObjectUtils 封装一个方法,避免取反;脑子理解起来麻烦 189 // TODO @AI:ObjectUtils 封装一个方法,避免取反;脑子理解起来麻烦
@@ -192,6 +192,7 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { @@ -192,6 +192,7 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService {
192 MesWmItemReceiptStatusEnum.APPROVING.getStatus())) { 192 MesWmItemReceiptStatusEnum.APPROVING.getStatus())) {
193 throw exception(WM_ITEM_RECEIPT_STATUS_NOT_PREPARE); 193 throw exception(WM_ITEM_RECEIPT_STATUS_NOT_PREPARE);
194 } 194 }
  195 + return receipt;
195 } 196 }
196 197
197 private MesWmItemReceiptDO validateItemReceiptExists(Long id) { 198 private MesWmItemReceiptDO validateItemReceiptExists(Long id) {
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/warehouse/MesWmWarehouseAreaService.java
@@ -91,4 +91,13 @@ public interface MesWmWarehouseAreaService { @@ -91,4 +91,13 @@ public interface MesWmWarehouseAreaService {
91 */ 91 */
92 Long getWarehouseAreaCountByLocationId(Long locationId); 92 Long getWarehouseAreaCountByLocationId(Long locationId);
93 93
  94 + /**
  95 + * 校验仓库、库区、库位的父子关系
  96 + *
  97 + * @param warehouseId 仓库编号
  98 + * @param locationId 库区编号
  99 + * @param areaId 库位编号
  100 + */
  101 + void validateWarehouseAreaExists(Long warehouseId, Long locationId, Long areaId);
  102 +
94 } 103 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/warehouse/MesWmWarehouseAreaServiceImpl.java
@@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 import cn.iocoder.yudao.module.mes.controller.admin.wm.warehouse.vo.area.MesWmWarehouseAreaPageReqVO; 7 import cn.iocoder.yudao.module.mes.controller.admin.wm.warehouse.vo.area.MesWmWarehouseAreaPageReqVO;
8 import cn.iocoder.yudao.module.mes.controller.admin.wm.warehouse.vo.area.MesWmWarehouseAreaSaveReqVO; 8 import cn.iocoder.yudao.module.mes.controller.admin.wm.warehouse.vo.area.MesWmWarehouseAreaSaveReqVO;
9 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO; 9 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
  10 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
10 import cn.iocoder.yudao.module.mes.dal.mysql.wm.warehouse.MesWmWarehouseAreaMapper; 11 import cn.iocoder.yudao.module.mes.dal.mysql.wm.warehouse.MesWmWarehouseAreaMapper;
11 import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService; 12 import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
12 import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; 13 import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
@@ -143,4 +144,28 @@ public class MesWmWarehouseAreaServiceImpl implements MesWmWarehouseAreaService @@ -143,4 +144,28 @@ public class MesWmWarehouseAreaServiceImpl implements MesWmWarehouseAreaService
143 return areaMapper.selectCountByLocationId(locationId); 144 return areaMapper.selectCountByLocationId(locationId);
144 } 145 }
145 146
  147 + @Override
  148 + public void validateWarehouseAreaExists(Long warehouseId, Long locationId, Long areaId) {
  149 + if (areaId == null) {
  150 + return;
  151 + }
  152 + // 1.1 校验库位存在
  153 + MesWmWarehouseAreaDO area = validateWarehouseAreaExists(areaId);
  154 + // 1.2 校验库位所属的库区是否匹配
  155 + if (locationId != null && ObjUtil.notEqual(area.getLocationId(), locationId)) {
  156 + throw exception(WM_WAREHOUSE_AREA_RELATION_INVALID);
  157 + }
  158 + // 2. 校验库区存在
  159 + if (locationId != null) {
  160 + locationService.validateWarehouseLocationExists(locationId);
  161 + }
  162 + // 3. 校验仓库存在(通过库区的 locationId 关联查询)
  163 + if (warehouseId != null) {
  164 + MesWmWarehouseLocationDO location = locationService.validateWarehouseLocationExists(area.getLocationId());
  165 + if (location != null && ObjUtil.notEqual(location.getWarehouseId(), warehouseId)) {
  166 + throw exception(WM_WAREHOUSE_AREA_WAREHOUSE_MISMATCH);
  167 + }
  168 + }
  169 + }
  170 +
146 } 171 }