diff --git a/klp-admin/src/main/resources/application.yml b/klp-admin/src/main/resources/application.yml index 767f6efc..76265db7 100644 --- a/klp-admin/src/main/resources/application.yml +++ b/klp-admin/src/main/resources/application.yml @@ -158,6 +158,7 @@ security: # 测试接口 - /test/** - /klp/generateRecord + - /klp/generateRecord/** # MyBatisPlus配置 diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsStockIoServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsStockIoServiceImpl.java index 683b1e6b..77c2c360 100644 --- a/klp-wms/src/main/java/com/klp/service/impl/WmsStockIoServiceImpl.java +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsStockIoServiceImpl.java @@ -163,7 +163,7 @@ public class WmsStockIoServiceImpl implements IWmsStockIoService { throw new RuntimeException("未能获取到单位"); } // 入库操作 - changeStock(bo.getWarehouseId(), bo.getItemType(), bo.getItemId(), bo.getQuantity(), true, unit); + changeStock(bo.getWarehouseId(), bo.getItemType(), bo.getItemId(), bo.getBatchNo(), bo.getQuantity(), true, unit); return true; } @Override @@ -184,7 +184,7 @@ public class WmsStockIoServiceImpl implements IWmsStockIoService { throw new RuntimeException("未能获取到单位"); } // 出库操作 - changeStock(bo.getWarehouseId(), bo.getItemType(), bo.getItemId(), bo.getQuantity(), false, unit); + changeStock(bo.getWarehouseId(), bo.getItemType(), bo.getItemId(), bo.getBatchNo(), bo.getQuantity(), false, unit); return true; } @@ -272,7 +272,7 @@ public class WmsStockIoServiceImpl implements IWmsStockIoService { // 执行入库操作(退库就是入库) changeStock(returnDetail.getWarehouseId(), returnDetail.getItemType(), - returnDetail.getItemId(), returnDetail.getQuantity(), true, unit); + returnDetail.getItemId(), returnDetail.getBatchNo(), returnDetail.getQuantity(), true, unit); } // 更新单据状态为已审核(2) returnStockIo.setStatus(2); @@ -297,23 +297,24 @@ public class WmsStockIoServiceImpl implements IWmsStockIoService { if (details == null || details.isEmpty()) { throw new RuntimeException("单据明细不能为空"); } + //如果details.batchNo不相等则需要去stock表新建一条批次号不同的记录 for (WmsStockIoDetail detail : details) { String ioType = stockIo.getIoType(); if ("in".equals(ioType)) { // 入库:目标库位库存增加 - changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getQuantity(), true, detail.getUnit()); + changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), true, detail.getUnit()); } else if ("out".equals(ioType)) { // 出库:目标库位库存减少 - changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getQuantity(), false, detail.getUnit()); + changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), false, detail.getUnit()); } else if ("transfer".equals(ioType)) { // 移库:fromWarehouseId减少,warehouseId增加 if (detail.getFromWarehouseId() == null) { throw new RuntimeException("移库明细缺少源库位ID"); } // 先减少源库位 - changeStock(detail.getFromWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getQuantity(), false, detail.getUnit()); + changeStock(detail.getFromWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), false, detail.getUnit()); // 再增加目标库位 - changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getQuantity(), true, detail.getUnit()); + changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), true, detail.getUnit()); } else { throw new RuntimeException("未知的出入库类型"); } @@ -343,19 +344,18 @@ public class WmsStockIoServiceImpl implements IWmsStockIoService { String ioType = stockIo.getIoType(); if ("in".equals(ioType)) { // 入库撤销:目标库位库存减少 -// changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), false, detail.getUnit()); - changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getQuantity(), false, detail.getUnit()); + changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), false, detail.getUnit()); } else if ("out".equals(ioType)) { // 出库撤销:目标库位库存增加 - changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getQuantity(), true, detail.getUnit()); + changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), true, detail.getUnit()); } else if ("transfer".equals(ioType)) { if (detail.getFromWarehouseId() == null) { throw new ServiceException("移库明细缺少源库位ID"); } // 源库位库存增加 - changeStock(detail.getFromWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getQuantity(), true, detail.getUnit()); + changeStock(detail.getFromWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), true, detail.getUnit()); // 目标库位库存减少 - changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getQuantity(), false, detail.getUnit()); + changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), false, detail.getUnit()); } else { throw new ServiceException("未知的出入库类型"); } @@ -427,12 +427,32 @@ public class WmsStockIoServiceImpl implements IWmsStockIoService { * 库存增减,isAdd=true为增加,false为减少,减少时校验库存是否足够 */ private void changeStock(Long warehouseId, String itemType, Long itemId, BigDecimal quantity, boolean isAdd, String unit) { - WmsStock stock = stockMapper.selectOne(Wrappers.lambdaQuery() - .eq(WmsStock::getWarehouseId, warehouseId) - .eq(WmsStock::getItemType, itemType) - .eq(WmsStock::getItemId, itemId) -// .eq(WmsStock::getBatchNo, batchNo) - .last("limit 1")); + changeStock(warehouseId, itemType, itemId, null, quantity, isAdd, unit); + } + + /** + * 库存增减(支持批次号),isAdd=true为增加,false为减少,减少时校验库存是否足够 + */ + private void changeStock(Long warehouseId, String itemType, Long itemId, String batchNo, BigDecimal quantity, boolean isAdd, String unit) { + WmsStock stock = null; + + if (StringUtils.isNotBlank(batchNo)) { + // 如果指定了批次号,按批次号查找 + stock = stockMapper.selectOne(Wrappers.lambdaQuery() + .eq(WmsStock::getWarehouseId, warehouseId) + .eq(WmsStock::getItemType, itemType) + .eq(WmsStock::getItemId, itemId) + .eq(WmsStock::getBatchNo, batchNo) + .last("limit 1")); + } else { + // 如果没有指定批次号,查找任意一个批次 + stock = stockMapper.selectOne(Wrappers.lambdaQuery() + .eq(WmsStock::getWarehouseId, warehouseId) + .eq(WmsStock::getItemType, itemType) + .eq(WmsStock::getItemId, itemId) + .last("limit 1")); + } + if (stock == null) { if (!isAdd) { throw new RuntimeException("库存不足,无法出库/移库"); @@ -442,18 +462,37 @@ public class WmsStockIoServiceImpl implements IWmsStockIoService { stock.setWarehouseId(warehouseId); stock.setItemType(itemType); stock.setItemId(itemId); - stock.setBatchNo("B-100"); + stock.setBatchNo(StringUtils.isNotBlank(batchNo) ? batchNo : "B-100"); stock.setQuantity(quantity); stock.setUnit(unit); stockMapper.insert(stock); } else { - BigDecimal newQty = isAdd ? stock.getQuantity().add(quantity) : stock.getQuantity().subtract(quantity); - if (newQty.compareTo(BigDecimal.ZERO) < 0) { - throw new RuntimeException("库存不足,无法出库/移库"); + // 如果指定了批次号且与现有库存批次号不同,需要新建记录 + if (StringUtils.isNotBlank(batchNo) && !batchNo.equals(stock.getBatchNo())) { + if (!isAdd) { + throw new RuntimeException("指定批次号库存不足,无法出库/移库"); + } + // 新建不同批次号的库存记录 + WmsStock newStock = new WmsStock(); + newStock.setWarehouseId(warehouseId); + newStock.setItemType(itemType); + newStock.setItemId(itemId); + newStock.setBatchNo(batchNo); + newStock.setQuantity(quantity); + newStock.setUnit(unit); + stockMapper.insert(newStock); + stock = newStock; // 更新stock引用用于日志记录 + } else { + // 更新现有库存 + BigDecimal newQty = isAdd ? stock.getQuantity().add(quantity) : stock.getQuantity().subtract(quantity); + if (newQty.compareTo(BigDecimal.ZERO) < 0) { + throw new RuntimeException("库存不足,无法出库/移库"); + } + stock.setQuantity(newQty); + stockMapper.updateById(stock); } - stock.setQuantity(newQty); - stockMapper.updateById(stock); } + // 记录库存变更日志 WmsStockLog log = new WmsStockLog(); log.setWarehouseId(warehouseId);