| | |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductSalesStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmSalesNoticeStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockReserveBizTypeEnum; |
| | | 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.wm.materialstock.MesWmMaterialStockService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.salesnotice.MesWmSalesNoticeService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.stockreserve.MesWmStockReserveService; |
| | | 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.erp.api.sale.ErpSaleOrderApi; |
| | |
| | | private MesWmTransactionService wmTransactionService; |
| | | @Resource |
| | | private MesWmMaterialStockService materialStockService; |
| | | @Resource |
| | | private MesWmStockReserveService stockReserveService; |
| | | |
| | | @Resource |
| | | private ErpSaleOrderApi saleOrderApi; |
| | |
| | | if (CollUtil.isEmpty(details)) { |
| | | throw exception(WM_PRODUCT_SALES_DETAILS_EMPTY); |
| | | } |
| | | // 校验库存充足 |
| | | // 校验库存充足并创建占用 |
| | | for (MesWmProductSalesDetailDO detail : details) { |
| | | materialStockService.validateSelectedStock( |
| | | detail.getMaterialStockId(), |
| | |
| | | detail.getWarehouseId(), |
| | | detail.getLocationId(), |
| | | detail.getAreaId(), |
| | | detail.getQuantity() |
| | | ); |
| | | // 创建库存占用 |
| | | stockReserveService.createReserve( |
| | | detail.getMaterialStockId(), |
| | | MesWmStockReserveBizTypeEnum.PRODUCT_SALES.getType(), |
| | | id, |
| | | sales.getCode(), |
| | | detail.getId(), |
| | | detail.getItemId(), |
| | | detail.getQuantity() |
| | | ); |
| | | } |
| | |
| | | throw exception(WM_PRODUCT_SALES_CANNOT_FINISH); |
| | | } |
| | | |
| | | // 2. 遍历所有明细,创建库存事务(扣减库存 + 记录流水) |
| | | // 2. 确认占用转出库(释放占用量) |
| | | stockReserveService.confirmReserveToOutbound(MesWmStockReserveBizTypeEnum.PRODUCT_SALES.getType(), id); |
| | | |
| | | // 3. 遍历所有明细,创建库存事务(扣减库存 + 记录流水) |
| | | createTransactionList(sales); |
| | | |
| | | // 3. 更新出库单状态 |
| | | // 4. 更新出库单状态 |
| | | productSalesMapper.updateById(new MesWmProductSalesDO() |
| | | .setId(id).setStatus(MesWmProductSalesStatusEnum.FINISHED.getStatus())); |
| | | |
| | | // 4. 更新关联的发货通知单状态 |
| | | // 5. 更新关联的发货通知单出库数量和状态 |
| | | if (sales.getNoticeId() != null) { |
| | | salesNoticeService.finishSalesNotice(sales.getNoticeId()); |
| | | updateSalesNoticeOutCount(sales); |
| | | } |
| | | |
| | | // 5. 回写 ERP 销售订单的出库数量和状态 |
| | | // 6. 回写 ERP 销售订单的出库数量和状态 |
| | | updateErpSaleOrderOutCount(sales); |
| | | } |
| | | |
| | | /** |
| | | * 更新发货通知单的出库数量和状态 |
| | | */ |
| | | 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()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | MesWmProductSalesStatusEnum.CANCELED.getStatus())) { |
| | | throw exception(WM_PRODUCT_SALES_CANNOT_CANCEL); |
| | | } |
| | | // 释放库存占用 |
| | | stockReserveService.releaseReserve(MesWmStockReserveBizTypeEnum.PRODUCT_SALES.getType(), id); |
| | | // 取消 |
| | | productSalesMapper.updateById(new MesWmProductSalesDO() |
| | | .setId(id).setStatus(MesWmProductSalesStatusEnum.CANCELED.getStatus())); |