Commit 6a9c2c25e51d5a4ccd19c47d4e8f4aac5bb515a8

Authored by YunaiV
1 parent 6358bff9

✨ feat(transaction): 添加库存事务创建逻辑,支持入库和出库操作

yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/MesBizTypeConstants.java
... ... @@ -36,14 +36,15 @@ public final class MesBizTypeConstants {
36 36 public static final int WM_MISC_ISSUE = 113; // 其他出库:MesWmMiscIssueDO
37 37 public static final int WM_MISC_RECPT = 114; // 其他入库:MesWmMiscReceiptDO
38 38 public static final int WM_ISSUE = 115; // 生产领料:MesWmProductionIssueDO
39   - public static final int WM_RT_ISSUE = 116; // 生产退料:MesWmReturnIssueDO
  39 + public static final int WM_RETURN_ISSUE = 116; // 生产退料:MesWmReturnIssueDO
40 40 public static final int WM_PRODUCT_RECPT = 117; // 生产入库:MesWmProductReceiptDO
41 41 public static final int WM_PRODUCT_SALES = 118; // 销售出库:MesWmProductSalesDO
42   - public static final int WM_RT_SALES = 119; // 销售退货入库:MesWmReturnSalesDO
  42 + public static final int WM_RETURN_SALES = 119; // 销售退货入库:MesWmReturnSalesDO
43 43 public static final int WM_OUTSOURCE_ISSUE = 120; // 外协发料:MesWmOutsourceIssueDO
44 44 public static final int WM_OUTSOURCE_RECPT = 121; // 外协入库:MesWmOutsourceReceiptDO
45 45 public static final int WM_ITEM_CONSUME = 122; // 生产消耗:MesWmItemConsumeDO
46 46 public static final int WM_PRODUCT_PRODUCE = 123; // 产品产出:MesWmProductProduceDO
  47 + public static final int WM_RETURN_VENDOR = 124; // 供应商退货出库:MesWmReturnVendorDO
47 48  
48 49 // ========== CAL 排班模块 [200, 300) ==========
49 50  
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeLineService.java
... ... @@ -28,4 +28,12 @@ public interface MesWmItemConsumeLineService {
28 28 */
29 29 PageResult<MesWmItemConsumeLineDO> getItemConsumeLinePage(MesWmItemConsumeLinePageReqVO pageReqVO);
30 30  
  31 + /**
  32 + * 查询指定消耗记录的所有行
  33 + *
  34 + * @param consumeId 消耗记录编号
  35 + * @return 消耗行列表
  36 + */
  37 + List<MesWmItemConsumeLineDO> getItemConsumeLineListByConsumeId(Long consumeId);
  38 +
31 39 }
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeLineServiceImpl.java
... ... @@ -44,4 +44,9 @@ public class MesWmItemConsumeLineServiceImpl implements MesWmItemConsumeLineServ
44 44 return itemConsumeLineMapper.selectPage(pageReqVO, consume.getId());
45 45 }
46 46  
  47 + @Override
  48 + public List<MesWmItemConsumeLineDO> getItemConsumeLineListByConsumeId(Long consumeId) {
  49 + return itemConsumeLineMapper.selectListByConsumeId(consumeId);
  50 + }
  51 +
47 52 }
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptServiceImpl.java
... ... @@ -12,9 +12,12 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceip
12 12 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDetailDO;
13 13 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptLineDO;
14 14 import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptMapper;
  15 +import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
15 16 import cn.iocoder.yudao.module.mes.enums.wm.MesWmItemReceiptStatusEnum;
  17 +import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
16 18 import cn.iocoder.yudao.module.mes.service.wm.arrivalnotice.MesWmArrivalNoticeService;
17   -import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
  19 +import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
  20 +import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
18 21 import jakarta.annotation.Resource;
19 22 import org.springframework.context.annotation.Lazy;
20 23 import org.springframework.stereotype.Service;
... ... @@ -25,6 +28,7 @@ import java.math.BigDecimal;
25 28 import java.util.List;
26 29  
27 30 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  31 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
28 32 import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
29 33  
30 34 /**
... ... @@ -39,16 +43,14 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService {
39 43  
40 44 @Resource
41 45 private MesWmItemReceiptLineService itemReceiptLineService;
42   -
43 46 @Resource
44 47 private MesWmItemReceiptDetailService itemReceiptDetailService;
45   -
46 48 @Resource
47 49 @Lazy
48 50 private MesWmArrivalNoticeService arrivalNoticeService;
49 51  
50 52 @Resource
51   - private MesWmMaterialStockService materialStockService;
  53 + private MesWmTransactionService wmTransactionService;
52 54  
53 55 @Override
54 56 public Long createItemReceipt(MesWmItemReceiptSaveReqVO createReqVO) {
... ... @@ -140,31 +142,37 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService {
140 142 @Override
141 143 @Transactional(rollbackFor = Exception.class)
142 144 public void finishItemReceipt(Long id) {
143   - // 校验存在
  145 + // 1. 校验存在
144 146 MesWmItemReceiptDO receipt = validateItemReceiptExists(id);
145 147 if (ObjUtil.notEqual(MesWmItemReceiptStatusEnum.APPROVED.getStatus(), receipt.getStatus())) {
146 148 throw exception(WM_ITEM_RECEIPT_STATUS_ERROR);
147 149 }
148 150  
149   - // 遍历所有明细,更新库存台账
150   - // TODO @AI:【后续在弄】这里可能有点问题;缺少库存更新;后面在弄;
151   - List<MesWmItemReceiptDetailDO> details = itemReceiptDetailService.getItemReceiptDetailListByReceiptId(id);
152   - for (MesWmItemReceiptDetailDO detail : details) {
153   - materialStockService.increaseStock(
154   - detail.getItemId(), detail.getWarehouseId(), detail.getLocationId(), detail.getAreaId(),
155   - detail.getBatchId(), detail.getQuantity(), receipt.getVendorId(), null, null);
156   - }
  151 + // 2. 遍历所有明细,创建库存事务(增加库存 + 记录流水)
  152 + createTransactionList(receipt);
157 153  
158   - // 更新入库单状态
  154 + // 3. 更新入库单状态
159 155 itemReceiptMapper.updateById(new MesWmItemReceiptDO()
160 156 .setId(id).setStatus(MesWmItemReceiptStatusEnum.FINISHED.getStatus()));
161 157  
162   - // 更新关联的到货通知单状态
  158 + // 4. 更新关联的到货通知单状态
163 159 if (receipt.getNoticeId() != null) {
164 160 arrivalNoticeService.finishArrivalNotice(receipt.getNoticeId());
165 161 }
166 162 }
167 163  
  164 + private void createTransactionList(MesWmItemReceiptDO receipt) {
  165 + List<MesWmItemReceiptDetailDO> details = itemReceiptDetailService.getItemReceiptDetailListByReceiptId(receipt.getId());
  166 + wmTransactionService.createTransactionList(convertList(details, detail -> new MesWmTransactionSaveReqDTO()
  167 + .setType(MesWmTransactionTypeEnum.IN.getType()).setItemId(detail.getItemId())
  168 + .setQuantity(detail.getQuantity()) // 入库数量为正数
  169 + .setBatchId(detail.getBatchId())
  170 + .setWarehouseId(detail.getWarehouseId()).setLocationId(detail.getLocationId()).setAreaId(detail.getAreaId())
  171 + .setVendorId(receipt.getVendorId()).setReceiptTime(receipt.getReceiptDate())
  172 + .setBizType(MesBizTypeConstants.WM_ITEM_RECEIPT_IN).setBizId(receipt.getId())
  173 + .setBizCode(receipt.getCode()).setBizLineId(detail.getLineId())));
  174 + }
  175 +
168 176 @Override
169 177 @Transactional(rollbackFor = Exception.class)
170 178 public void cancelItemReceipt(Long id) {
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/outsourceissue/MesWmOutsourceIssueServiceImpl.java
... ... @@ -12,9 +12,12 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.wm.outsourceissue.MesWmOutsour
12 12 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.outsourceissue.MesWmOutsourceIssueDO;
13 13 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.outsourceissue.MesWmOutsourceIssueLineDO;
14 14 import cn.iocoder.yudao.module.mes.dal.mysql.wm.outsourceissue.MesWmOutsourceIssueMapper;
  15 +import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
15 16 import cn.iocoder.yudao.module.mes.enums.wm.MesWmOutsourceIssueStatusEnum;
  17 +import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
  18 +import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
  19 +import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
16 20 import jakarta.annotation.Resource;
17   -import lombok.extern.slf4j.Slf4j;
18 21 import org.springframework.stereotype.Service;
19 22 import org.springframework.transaction.annotation.Transactional;
20 23 import org.springframework.validation.annotation.Validated;
... ... @@ -24,6 +27,7 @@ import java.util.List;
24 27 import java.util.Map;
25 28  
26 29 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  30 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
27 31 import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
28 32  
29 33 /**
... ... @@ -33,7 +37,6 @@ import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
33 37 */
34 38 @Service
35 39 @Validated
36   -@Slf4j
37 40 public class MesWmOutsourceIssueServiceImpl implements MesWmOutsourceIssueService {
38 41  
39 42 @Resource
... ... @@ -41,9 +44,10 @@ public class MesWmOutsourceIssueServiceImpl implements MesWmOutsourceIssueServic
41 44  
42 45 @Resource
43 46 private MesWmOutsourceIssueLineService outsourceIssueLineService;
44   -
45 47 @Resource
46 48 private MesWmOutsourceIssueDetailService outsourceIssueDetailService;
  49 + @Resource
  50 + private MesWmTransactionService wmTransactionService;
47 51  
48 52 @Override
49 53 public Long createOutsourceIssue(MesWmOutsourceIssueSaveReqVO createReqVO) {
... ... @@ -153,20 +157,26 @@ public class MesWmOutsourceIssueServiceImpl implements MesWmOutsourceIssueServic
153 157 throw exception(WM_OUTSOURCE_ISSUE_STATUS_NOT_APPROVED);
154 158 }
155 159  
156   - // 2. 扣减库存(遍历明细表,逐条扣减)
157   - List<MesWmOutsourceIssueDetailDO> details = outsourceIssueDetailService.getOutsourceIssueDetailListByIssueId(id);
158   - for (MesWmOutsourceIssueDetailDO detail : details) {
159   - // TODO: 调用库存服务扣减库存
160   - // materialStockService.decreaseStock(detail.getMaterialStockId(), detail.getQuantity());
161   - log.info("[finishOutsourceIssue][发料单({}) 扣减库存 - 库存ID: {}, 数量: {}]",
162   - id, detail.getMaterialStockId(), detail.getQuantity());
163   - }
  160 + // 2. 遍历所有明细,创建库存事务(扣减库存 + 记录流水)
  161 + createTransactionList(issue);
164 162  
165 163 // 3. 更新单据状态为已完成
166 164 outsourceIssueMapper.updateById(new MesWmOutsourceIssueDO()
167 165 .setId(id).setStatus(MesWmOutsourceIssueStatusEnum.FINISHED.getStatus()));
168 166 }
169 167  
  168 + private void createTransactionList(MesWmOutsourceIssueDO issue) {
  169 + List<MesWmOutsourceIssueDetailDO> details = outsourceIssueDetailService.getOutsourceIssueDetailListByIssueId(issue.getId());
  170 + wmTransactionService.createTransactionList(convertList(details, detail -> new MesWmTransactionSaveReqDTO()
  171 + .setType(MesWmTransactionTypeEnum.OUT.getType()).setItemId(detail.getItemId())
  172 + .setQuantity(detail.getQuantity().negate()) // 出库数量为负数
  173 + .setBatchId(detail.getBatchId())
  174 + .setWarehouseId(detail.getWarehouseId()).setLocationId(detail.getLocationId()).setAreaId(detail.getAreaId())
  175 + .setVendorId(issue.getVendorId())
  176 + .setBizType(MesBizTypeConstants.WM_OUTSOURCE_ISSUE).setBizId(issue.getId())
  177 + .setBizCode(issue.getCode()).setBizLineId(detail.getLineId())));
  178 + }
  179 +
170 180 @Override
171 181 @Transactional(rollbackFor = Exception.class)
172 182 public void cancelOutsourceIssue(Long id) {
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/outsourcereceipt/MesWmOutsourceReceiptServiceImpl.java
... ... @@ -15,11 +15,14 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.wm.outsourcereceipt.MesWmOutso
15 15 import cn.iocoder.yudao.module.mes.dal.mysql.wm.outsourcereceipt.MesWmOutsourceReceiptDetailMapper;
16 16 import cn.iocoder.yudao.module.mes.dal.mysql.wm.outsourcereceipt.MesWmOutsourceReceiptLineMapper;
17 17 import cn.iocoder.yudao.module.mes.dal.mysql.wm.outsourcereceipt.MesWmOutsourceReceiptMapper;
  18 +import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
18 19 import cn.iocoder.yudao.module.mes.enums.wm.MesWmOutsourceReceiptStatusEnum;
19 20 import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
  21 +import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
20 22 import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
21 23 import cn.iocoder.yudao.module.mes.service.md.vendor.MesMdVendorService;
22   -import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
  24 +import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
  25 +import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
23 26 import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
24 27 import jakarta.annotation.Resource;
25 28 import org.springframework.stereotype.Service;
... ... @@ -31,6 +34,7 @@ import java.util.List;
31 34 import java.util.Map;
32 35  
33 36 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  37 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
34 38 import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
35 39  
36 40 /**
... ... @@ -50,7 +54,7 @@ public class MesWmOutsourceReceiptServiceImpl implements MesWmOutsourceReceiptSe
50 54 private MesWmOutsourceReceiptDetailMapper outsourceReceiptDetailMapper;
51 55  
52 56 @Resource
53   - private MesWmMaterialStockService materialStockService;
  57 + private MesWmTransactionService wmTransactionService;
54 58  
55 59 @Resource
56 60 private MesMdVendorService vendorService;
... ... @@ -170,26 +174,32 @@ public class MesWmOutsourceReceiptServiceImpl implements MesWmOutsourceReceiptSe
170 174 @Override
171 175 @Transactional(rollbackFor = Exception.class)
172 176 public void finishOutsourceReceipt(Long id) {
173   - // 校验存在
  177 + // 1. 校验存在
174 178 MesWmOutsourceReceiptDO receipt = validateOutsourceReceiptExists(id);
175 179 if (ObjUtil.notEqual(MesWmOutsourceReceiptStatusEnum.APPROVED.getStatus(), receipt.getStatus())) {
176 180 throw exception(WM_OUTSOURCE_RECEIPT_STATUS_ERROR);
177 181 }
178 182  
179   - // 遍历所有明细,校验并更新库存台账
180   - // DONE @AI:芋艿【暂时不处理】;后续在观察;(AI 未修复原因:标注为后续处理,需人工介入)
181   - List<MesWmOutsourceReceiptDetailDO> details = outsourceReceiptDetailMapper.selectListByReceiptId(id);
182   - for (MesWmOutsourceReceiptDetailDO detail : details) {
183   - materialStockService.increaseStock(
184   - detail.getItemId(), detail.getWarehouseId(), detail.getLocationId(), detail.getAreaId(),
185   - detail.getBatchId(), detail.getQuantity(), receipt.getVendorId(), null, null);
186   - }
  183 + // 2. 遍历所有明细,创建库存事务(增加库存 + 记录流水)
  184 + createTransactionList(receipt);
187 185  
188   - // 更新入库单状态
  186 + // 3. 更新入库单状态
189 187 outsourceReceiptMapper.updateById(new MesWmOutsourceReceiptDO()
190 188 .setId(id).setStatus(MesWmOutsourceReceiptStatusEnum.FINISHED.getStatus()));
191 189 }
192 190  
  191 + private void createTransactionList(MesWmOutsourceReceiptDO receipt) {
  192 + List<MesWmOutsourceReceiptDetailDO> details = outsourceReceiptDetailMapper.selectListByReceiptId(receipt.getId());
  193 + wmTransactionService.createTransactionList(convertList(details, detail -> new MesWmTransactionSaveReqDTO()
  194 + .setType(MesWmTransactionTypeEnum.IN.getType()).setItemId(detail.getItemId())
  195 + .setQuantity(detail.getQuantity()) // 入库数量为正数
  196 + .setBatchId(detail.getBatchId())
  197 + .setWarehouseId(detail.getWarehouseId()).setLocationId(detail.getLocationId()).setAreaId(detail.getAreaId())
  198 + .setVendorId(receipt.getVendorId()).setReceiptTime(receipt.getReceiptDate())
  199 + .setBizType(MesBizTypeConstants.WM_OUTSOURCE_RECPT).setBizId(receipt.getId())
  200 + .setBizCode(receipt.getCode()).setBizLineId(detail.getLineId())));
  201 + }
  202 +
193 203 @Override
194 204 @Transactional(rollbackFor = Exception.class)
195 205 public void cancelOutsourceReceipt(Long id) {
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java
... ... @@ -13,9 +13,12 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSa
13 13 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDetailDO;
14 14 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO;
15 15 import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesMapper;
  16 +import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
16 17 import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductSalesStatusEnum;
  18 +import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
17 19 import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService;
18   -import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
  20 +import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
  21 +import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
19 22 import jakarta.annotation.Resource;
20 23 import org.springframework.stereotype.Service;
21 24 import org.springframework.transaction.annotation.Transactional;
... ... @@ -25,6 +28,7 @@ import java.math.BigDecimal;
25 28 import java.util.List;
26 29  
27 30 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  31 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
28 32 import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
29 33  
30 34 /**
... ... @@ -49,7 +53,7 @@ public class MesWmProductSalesServiceImpl implements MesWmProductSalesService {
49 53 private MesMdClientService clientService;
50 54  
51 55 @Resource
52   - private MesWmMaterialStockService materialStockService;
  56 + private MesWmTransactionService wmTransactionService;
53 57  
54 58 @Override
55 59 public Long createProductSales(MesWmProductSalesSaveReqVO createReqVO) {
... ... @@ -170,26 +174,31 @@ public class MesWmProductSalesServiceImpl implements MesWmProductSalesService {
170 174 @Override
171 175 @Transactional(rollbackFor = Exception.class)
172 176 public void finishProductSales(Long id) {
173   - // 校验存在
  177 + // 1. 校验存在
174 178 MesWmProductSalesDO sales = validateProductSalesExists(id);
175 179 if (ObjUtil.notEqual(MesWmProductSalesStatusEnum.APPROVED.getStatus(), sales.getStatus())) {
176 180 throw exception(WM_PRODUCT_SALES_CANNOT_FINISH);
177 181 }
178 182  
179   - // 遍历所有明细,扣减库存
180   - // DONE @AI:需要实现 decreaseStock 方法(AI 未修复原因:需要 materialStockService 提供 decreaseStock 方法实现)
181   - List<MesWmProductSalesDetailDO> details = productSalesDetailService.getProductSalesDetailListBySalesId(id);
182   - for (MesWmProductSalesDetailDO detail : details) {
183   - // materialStockService.decreaseStock(
184   - // detail.getItemId(), detail.getWarehouseId(), detail.getLocationId(), detail.getAreaId(),
185   - // detail.getBatchId(), detail.getQuantity(), sales.getClientId(), null, null);
186   - }
  183 + // 2. 遍历所有明细,创建库存事务(扣减库存 + 记录流水)
  184 + createTransactionList(sales);
187 185  
188   - // 更新出库单状态
  186 + // 3. 更新出库单状态
189 187 productSalesMapper.updateById(new MesWmProductSalesDO()
190 188 .setId(id).setStatus(MesWmProductSalesStatusEnum.FINISHED.getStatus()));
191 189 }
192 190  
  191 + private void createTransactionList(MesWmProductSalesDO sales) {
  192 + List<MesWmProductSalesDetailDO> details = productSalesDetailService.getProductSalesDetailListBySalesId(sales.getId());
  193 + wmTransactionService.createTransactionList(convertList(details, detail -> new MesWmTransactionSaveReqDTO()
  194 + .setType(MesWmTransactionTypeEnum.OUT.getType()).setItemId(detail.getItemId())
  195 + .setQuantity(detail.getQuantity().negate()) // 出库数量为负数
  196 + .setBatchId(detail.getBatchId())
  197 + .setWarehouseId(detail.getWarehouseId()).setLocationId(detail.getLocationId()).setAreaId(detail.getAreaId())
  198 + .setBizType(MesBizTypeConstants.WM_PRODUCT_SALES).setBizId(sales.getId())
  199 + .setBizCode(sales.getCode()).setBizLineId(detail.getLineId())));
  200 + }
  201 +
193 202 @Override
194 203 @Transactional(rollbackFor = Exception.class)
195 204 public void cancelProductSales(Long id) {
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesServiceImpl.java
... ... @@ -13,10 +13,14 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSale
13 13 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesDetailDO;
14 14 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesLineDO;
15 15 import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnsales.MesWmReturnSalesMapper;
  16 +import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
16 17 import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
17 18 import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnSalesStatusEnum;
  19 +import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
18 20 import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService;
19 21 import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
  22 +import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
  23 +import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
20 24 import jakarta.annotation.Resource;
21 25 import org.springframework.stereotype.Service;
22 26 import org.springframework.transaction.annotation.Transactional;
... ... @@ -27,6 +31,7 @@ import java.util.List;
27 31 import java.util.Map;
28 32  
29 33 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  34 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
30 35 import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
31 36  
32 37 /**
... ... @@ -49,6 +54,8 @@ public class MesWmReturnSalesServiceImpl implements MesWmReturnSalesService {
49 54 private MesMdClientService clientService;
50 55 @Resource
51 56 private MesMdItemService itemService;
  57 + @Resource
  58 + private MesWmTransactionService wmTransactionService;
52 59  
53 60 @Override
54 61 @Transactional(rollbackFor = Exception.class)
... ... @@ -162,20 +169,25 @@ public class MesWmReturnSalesServiceImpl implements MesWmReturnSalesService {
162 169 }
163 170 }
164 171  
165   - // 2. 遍历所有明细,更新库存台账(增加库存)
166   - // DONE @芋艿:【后续在弄】这里需要库存更新;后面在弄(AI 未修复原因:标注为后续处理,需人工介入)
167   - List<MesWmReturnSalesDetailDO> details = returnSalesDetailService.getReturnSalesDetailListByReturnId(id);
168   - for (MesWmReturnSalesDetailDO detail : details) {
169   - // materialStockService.increaseStock(
170   - // detail.getItemId(), detail.getWarehouseId(), detail.getLocationId(), detail.getAreaId(),
171   - // detail.getBatchId(), detail.getQuantity(), null, null, null);
172   - }
  172 + // 2. 遍历所有明细,创建库存事务(增加库存 + 记录流水)
  173 + createTransactionList(returnSales);
173 174  
174 175 // 3. 更新退货单状态
175 176 returnSalesMapper.updateById(new MesWmReturnSalesDO()
176 177 .setId(id).setStatus(MesWmReturnSalesStatusEnum.FINISHED.getStatus()));
177 178 }
178 179  
  180 + private void createTransactionList(MesWmReturnSalesDO returnSales) {
  181 + List<MesWmReturnSalesDetailDO> details = returnSalesDetailService.getReturnSalesDetailListByReturnId(returnSales.getId());
  182 + wmTransactionService.createTransactionList(convertList(details, detail -> new MesWmTransactionSaveReqDTO()
  183 + .setType(MesWmTransactionTypeEnum.IN.getType()).setItemId(detail.getItemId())
  184 + .setQuantity(detail.getQuantity()) // 入库数量为正数
  185 + .setBatchId(detail.getBatchId())
  186 + .setWarehouseId(detail.getWarehouseId()).setLocationId(detail.getLocationId()).setAreaId(detail.getAreaId())
  187 + .setBizType(MesBizTypeConstants.WM_RETURN_SALES).setBizId(returnSales.getId())
  188 + .setBizCode(returnSales.getCode()).setBizLineId(detail.getLineId())));
  189 + }
  190 +
179 191 @Override
180 192 @Transactional(rollbackFor = Exception.class)
181 193 public void cancelReturnSales(Long id) {
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorServiceImpl.java
... ... @@ -12,8 +12,12 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVen
12 12 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorDetailDO;
13 13 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorLineDO;
14 14 import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnvendor.MesWmReturnVendorMapper;
  15 +import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
15 16 import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnVendorStatusEnum;
  17 +import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
16 18 import cn.iocoder.yudao.module.mes.service.md.vendor.MesMdVendorService;
  19 +import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
  20 +import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
17 21 import jakarta.annotation.Resource;
18 22 import org.springframework.stereotype.Service;
19 23 import org.springframework.transaction.annotation.Transactional;
... ... @@ -23,6 +27,7 @@ import java.math.BigDecimal;
23 27 import java.util.List;
24 28  
25 29 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  30 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
26 31 import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
27 32  
28 33 /**
... ... @@ -41,6 +46,8 @@ public class MesWmReturnVendorServiceImpl implements MesWmReturnVendorService {
41 46 private MesWmReturnVendorDetailService returnVendorDetailService;
42 47 @Resource
43 48 private MesMdVendorService vendorService;
  49 + @Resource
  50 + private MesWmTransactionService wmTransactionService;
44 51  
45 52 @Override
46 53 @Transactional(rollbackFor = Exception.class)
... ... @@ -124,26 +131,32 @@ public class MesWmReturnVendorServiceImpl implements MesWmReturnVendorService {
124 131 @Override
125 132 @Transactional(rollbackFor = Exception.class)
126 133 public void finishReturnVendor(Long id) {
127   - // 校验存在
  134 + // 1. 校验存在
128 135 MesWmReturnVendorDO returnVendor = validateReturnVendorExists(id);
129 136 if (ObjUtil.notEqual(MesWmReturnVendorStatusEnum.APPROVED.getStatus(), returnVendor.getStatus())) {
130 137 throw exception(WM_RETURN_VENDOR_STATUS_INVALID);
131 138 }
132 139  
133   - // 遍历所有明细,更新库存台账(扣减库存)
134   - // DONE @芋艿:【后续在弄】这里可能有点问题;缺少库存更新;后面在弄;(AI 未修复原因:标注为后续处理,需人工介入)
135   - List<MesWmReturnVendorDetailDO> details = returnVendorDetailService.getReturnVendorDetailListByReturnId(id);
136   - for (MesWmReturnVendorDetailDO detail : details) {
137   - // materialStockService.decreaseStock(
138   - // detail.getItemId(), detail.getWarehouseId(), detail.getLocationId(), detail.getAreaId(),
139   - // detail.getBatchId(), detail.getQuantity(), null, null, null);
140   - }
  140 + // 2. 遍历所有明细,创建库存事务(扣减库存 + 记录流水)
  141 + createTransactionList(returnVendor);
141 142  
142   - // 更新退货单状态
  143 + // 3. 更新退货单状态
143 144 returnVendorMapper.updateById(new MesWmReturnVendorDO()
144 145 .setId(id).setStatus(MesWmReturnVendorStatusEnum.FINISHED.getStatus()));
145 146 }
146 147  
  148 + private void createTransactionList(MesWmReturnVendorDO returnVendor) {
  149 + List<MesWmReturnVendorDetailDO> details = returnVendorDetailService.getReturnVendorDetailListByReturnId(returnVendor.getId());
  150 + wmTransactionService.createTransactionList(convertList(details, detail -> new MesWmTransactionSaveReqDTO()
  151 + .setType(MesWmTransactionTypeEnum.OUT.getType()).setItemId(detail.getItemId())
  152 + .setQuantity(detail.getQuantity().negate()) // 出库数量为负数
  153 + .setBatchId(detail.getBatchId()).setBatchCode(detail.getBatchCode())
  154 + .setWarehouseId(detail.getWarehouseId()).setLocationId(detail.getLocationId()).setAreaId(detail.getAreaId())
  155 + .setVendorId(returnVendor.getVendorId())
  156 + .setBizType(MesBizTypeConstants.WM_RETURN_VENDOR).setBizId(returnVendor.getId())
  157 + .setBizCode(returnVendor.getCode()).setBizLineId(detail.getLineId())));
  158 + }
  159 +
147 160 @Override
148 161 @Transactional(rollbackFor = Exception.class)
149 162 public void cancelReturnVendor(Long id) {
... ...