diff --git a/win-module-wms/win-module-wms-biz/src/main/java/com/win/module/wms/dal/mysql/balance/BalanceMapper.java b/win-module-wms/win-module-wms-biz/src/main/java/com/win/module/wms/dal/mysql/balance/BalanceMapper.java index d29bdc3e..161d17f6 100644 --- a/win-module-wms/win-module-wms-biz/src/main/java/com/win/module/wms/dal/mysql/balance/BalanceMapper.java +++ b/win-module-wms/win-module-wms-biz/src/main/java/com/win/module/wms/dal/mysql/balance/BalanceMapper.java @@ -95,7 +95,13 @@ public interface BalanceMapper extends BaseMapperX { } /** - * 更新库存余额数量,出库qty是负数 + * 更查找库存余额 + * @param packingNumber 包装号 + * @param itemCode 物品编号 + * @param batch 批次 + * @param inventoryStatus 库存状态 + * @param locationCode 库位编号 + * @return 符合条件的库存余额 */ default List getBalanceList(String packingNumber, String itemCode, String batch, String inventoryStatus, String locationCode) { QueryWrapper queryWrapper = new QueryWrapper<>(); @@ -117,6 +123,17 @@ public interface BalanceMapper extends BaseMapperX { return selectList(queryWrapper); } + /** + * 根据库位编号查找库存余额数量 + * @param locationCode 库位编号 + * @return 库存余额数量 + */ + default long getBalanceCount(String locationCode) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("location_code", locationCode); + return selectCount(queryWrapper); + } + default PageResult selectPage(BalancePageReqVO reqVO) { return selectPage(reqVO, new LambdaQueryWrapperX() .eqIfPresent(BalanceDO::getPackingNumber, reqVO.getPackingNumber()) diff --git a/win-module-wms/win-module-wms-biz/src/main/java/com/win/module/wms/service/location/LocationService.java b/win-module-wms/win-module-wms-biz/src/main/java/com/win/module/wms/service/location/LocationService.java index 9b9976a8..e9869d55 100644 --- a/win-module-wms/win-module-wms-biz/src/main/java/com/win/module/wms/service/location/LocationService.java +++ b/win-module-wms/win-module-wms-biz/src/main/java/com/win/module/wms/service/location/LocationService.java @@ -4,7 +4,6 @@ import com.win.framework.common.pojo.CustomConditions; import com.win.framework.common.pojo.PageResult; import com.win.module.wms.controller.location.vo.*; import com.win.module.wms.controller.rule.vo.RuleRespVO; -import com.win.module.wms.dal.dataobject.itembasic.ItembasicDO; import com.win.module.wms.dal.dataobject.location.LocationDO; import javax.validation.Valid; @@ -93,8 +92,10 @@ public interface LocationService { /** * 上架推荐策略 * @param ruleRespVO 上架策略 - * @param itembasicDO 物品 + * @param itemCode 物料编码 + * @param batch 批次 + * @param inventoryStatus 状态 * @return */ - LocationDO inspectLocation(RuleRespVO ruleRespVO, ItembasicDO itembasicDO); + LocationDO inspectLocation(RuleRespVO ruleRespVO, String itemCode, String batch, String inventoryStatus); } diff --git a/win-module-wms/win-module-wms-biz/src/main/java/com/win/module/wms/service/location/LocationServiceImpl.java b/win-module-wms/win-module-wms-biz/src/main/java/com/win/module/wms/service/location/LocationServiceImpl.java index 385fa2df..5710ddfb 100644 --- a/win-module-wms/win-module-wms-biz/src/main/java/com/win/module/wms/service/location/LocationServiceImpl.java +++ b/win-module-wms/win-module-wms-biz/src/main/java/com/win/module/wms/service/location/LocationServiceImpl.java @@ -13,7 +13,7 @@ import com.win.framework.datapermission.core.util.DataPermissionUtils; import com.win.module.wms.controller.location.vo.*; import com.win.module.wms.controller.rule.vo.RuleRespVO; import com.win.module.wms.convert.location.LocationConvert; -import com.win.module.wms.dal.dataobject.itembasic.ItembasicDO; +import com.win.module.wms.dal.dataobject.balance.BalanceDO; import com.win.module.wms.dal.dataobject.location.LocationDO; import com.win.module.wms.dal.mysql.balance.BalanceMapper; import com.win.module.wms.dal.mysql.expectout.ExpectoutMapper; @@ -45,16 +45,16 @@ public class LocationServiceImpl implements LocationService { private BalanceMapper balanceMapper; @Resource - private ExpectoutMapper expectoutMapper ; + private ExpectoutMapper expectoutMapper; @Resource private RuleService ruleService; @Override public Long createLocation(LocationCreateReqVO createReqVO) { - validateLocationForCreateOrUpdate(createReqVO.getId(),createReqVO.getCode(),createReqVO.getAreaCode(),createReqVO.getWarehouseCode() - ,createReqVO.getLocationGroupCode(),createReqVO.getErpLocationCode(),createReqVO.getType(),createReqVO.getPickPriority() - ,createReqVO.getUserGroupCode(),createReqVO.getAvailable()); + validateLocationForCreateOrUpdate(createReqVO.getId(), createReqVO.getCode(), createReqVO.getAreaCode(), createReqVO.getWarehouseCode() + , createReqVO.getLocationGroupCode(), createReqVO.getErpLocationCode(), createReqVO.getType(), createReqVO.getPickPriority() + , createReqVO.getUserGroupCode(), createReqVO.getAvailable()); // 插入 LocationDO location = LocationConvert.INSTANCE.convert(createReqVO); locationMapper.insert(location); @@ -65,9 +65,9 @@ public class LocationServiceImpl implements LocationService { @Override public void updateLocation(LocationUpdateReqVO updateReqVO) { // 校验存在 - validateLocationForCreateOrUpdate(updateReqVO.getId(),updateReqVO.getCode(),updateReqVO.getAreaCode(),updateReqVO.getWarehouseCode() - ,updateReqVO.getLocationGroupCode(),updateReqVO.getErpLocationCode(),updateReqVO.getType(),updateReqVO.getPickPriority() - ,updateReqVO.getUserGroupCode(),updateReqVO.getAvailable()); + validateLocationForCreateOrUpdate(updateReqVO.getId(), updateReqVO.getCode(), updateReqVO.getAreaCode(), updateReqVO.getWarehouseCode() + , updateReqVO.getLocationGroupCode(), updateReqVO.getErpLocationCode(), updateReqVO.getType(), updateReqVO.getPickPriority() + , updateReqVO.getUserGroupCode(), updateReqVO.getAvailable()); // 更新 LocationDO updateObj = LocationConvert.INSTANCE.convert(updateReqVO); locationMapper.updateById(updateObj); @@ -105,7 +105,8 @@ public class LocationServiceImpl implements LocationService { public PageResult getLocationSenior(CustomConditions conditions) { return locationMapper.selectSenior(conditions); } - private String validateLocationImport( LocationDO location ){ + + private String validateLocationImport(LocationDO location) { StringBuilder message = new StringBuilder(); try { validateLocationExists(null); @@ -113,7 +114,7 @@ public class LocationServiceImpl implements LocationService { message.append(ex.getMessage()).append(","); } try { - validateCodeExists(null,location.getCode()); + validateCodeExists(null, location.getCode()); } catch (ServiceException ex) { message.append(ex.getMessage()).append(","); } @@ -168,22 +169,21 @@ public class LocationServiceImpl implements LocationService { } List errorList = new ArrayList<>(); locations.forEach(location -> { - LocationDO locationDO = LocationConvert.INSTANCE.convert(location); - String message =this.validateLocationImport(locationDO); + LocationDO locationDO = LocationConvert.INSTANCE.convert(location); + String message = this.validateLocationImport(locationDO); boolean flag = true; - if(!message.isEmpty()){ + if (!message.isEmpty()) { LocationImportErrorVO importErrorVO = LocationConvert.INSTANCE.convert2(locationDO); importErrorVO.setImportStatus("失败"); importErrorVO.setImportRemark(message.substring(0, message.length() - 1)); errorList.add(importErrorVO); flag = false; } - if(flag){ + if (flag) { LocationDO existConfigurationSetting = locationMapper.selectByCode(locationDO.getCode()); - if (existConfigurationSetting == null&& mode != 3) { + if (existConfigurationSetting == null && mode != 3) { locationMapper.insert(LocationConvert.INSTANCE.convert(location)); - } - else if (existConfigurationSetting != null && mode != 2) { + } else if (existConfigurationSetting != null && mode != 2) { // 如果存在,判断是否允许更新 locationDO.setId(existConfigurationSetting.getId()); locationMapper.updateById(locationDO); @@ -192,12 +192,13 @@ public class LocationServiceImpl implements LocationService { }); return errorList; } - private void validateLocationForCreateOrUpdate(Long id, String code,String warehouseCode, String areaCode,String erpLocationCode, String locationGroupCode, - String type,Integer pickPriority,String userGroupCode,String available) { + + private void validateLocationForCreateOrUpdate(Long id, String code, String warehouseCode, String areaCode, String erpLocationCode, String locationGroupCode, + String type, Integer pickPriority, String userGroupCode, String available) { // 关闭数据权限,避免因为没有数据权限,查询不到数据,进而导致唯一校验不正确 DataPermissionUtils.executeIgnore(() -> { validateLocationExists(id); - validateCodeExists(id,code); + validateCodeExists(id, code); // 校验code唯一 validateWarehouseCodeExists(warehouseCode); validateAreaCodeExists(areaCode); @@ -209,6 +210,7 @@ public class LocationServiceImpl implements LocationService { validateAvailableExists(available); }); } + private void validateLocationExists(Long id) { if (id == null) { return; @@ -217,8 +219,9 @@ public class LocationServiceImpl implements LocationService { throw exception(LOCATION_NOT_EXISTS); } } + @VisibleForTesting - private void validateCodeExists(Long id,String code) { + private void validateCodeExists(Long id, String code) { if (code.isEmpty()) { throw exception(LOCATION_CODE_NOT_EXISTS); } @@ -237,12 +240,14 @@ public class LocationServiceImpl implements LocationService { throw exception(LOCATION_CODE_EXISTS); } } + @VisibleForTesting private void validateWarehouseCodeExists(String warehouseCode) { if (warehouseCode.isEmpty()) { throw exception(LOCATION_WARE_HOUSE_CODE_NOT_EXISTS); } } + @VisibleForTesting private void validateAreaCodeExists(String areaCode) { if (areaCode.isEmpty()) { @@ -263,52 +268,55 @@ public class LocationServiceImpl implements LocationService { throw exception(LOCATION_LOCATION_GROUP_CODE_NOT_EXISTS); } } + @VisibleForTesting private void validateTypeExists(String type) { if (type.isEmpty()) { throw exception(LOCATION_TYPE_NOT_EXISTS); } } + @VisibleForTesting private void validatePickPriorityExists(Integer pickPriority) { if (pickPriority == null) { throw exception(LOCATION_PICK_PRIORITY_NOT_EXISTS); } } + @VisibleForTesting private void validateUserGroupCodeExists(String userGroupCode) { if (userGroupCode.isEmpty()) { throw exception(LOCATION_USER_GROUP_CODE_NOT_EXISTS); } } + @VisibleForTesting private void validateAvailableExists(String available) { if (available.isEmpty()) { throw exception(LOCATION_AVAILABLE_NOT_EXISTS); } } + //调用公共方法查询库位信息 @Override public LocationDO selectLocation(String pcode) { QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("code",pcode); - queryWrapper.eq("available","TRUE"); + queryWrapper.eq("code", pcode); + queryWrapper.eq("available", "TRUE"); LocationDO locationDO = locationMapper.selectOne(queryWrapper); - if(locationDO == null){ + if (locationDO == null) { throw exception(LOCATION_NOT_EXISTS); } else { return locationDO; } } - //{"WarehouseCode":"W1","AreaCode":"A1","LocationGroupCode":"LG1","LocationCode":"H01","EmptyLocationFirst":"FALSE","NotEmptyLocationFirst":"FALSE", - // "EnableMixItem":"TRUE","EnableMixLot":"TRUE","EnableMixStatus":"TRUE"} @Override - public LocationDO inspectLocation(RuleRespVO ruleRespVO, ItembasicDO itembasicDO) { + public LocationDO inspectLocation(RuleRespVO ruleRespVO, String itemCode, String batch, String inventoryStatus) { JSONObject jsonObject = JSONUtil.parseObj(ruleRespVO.getConfiguration()); Object locationCode = jsonObject.get("LocationCode"); //设置了库位直接返回 - if(locationCode != null) { + if (locationCode != null) { return this.selectLocation(String.valueOf(locationCode)); } //增加过滤条件 @@ -319,38 +327,38 @@ public class LocationServiceImpl implements LocationService { locationTypeList.add("FG"); queryWrapper.in("`type`", locationTypeList); Object warehouseCode = jsonObject.get("WarehouseCode"); - if(!"".equals(warehouseCode)) { + if (!"".equals(warehouseCode)) { queryWrapper.eq("warehouse_code", warehouseCode); } Object areaCode = jsonObject.get("AreaCode"); - if(!"".equals(areaCode)) { + if (!"".equals(areaCode)) { queryWrapper.eq("area_code", areaCode); } Object locationGroupCode = jsonObject.get("LocationGroupCode"); - if(!"".equals(locationGroupCode)) { + if (!"".equals(locationGroupCode)) { queryWrapper.eq("location_group_code", locationGroupCode); } //排序 Object aisleOrder = jsonObject.get("AisleOrder"); - if("DESC".equals(aisleOrder)) { + if ("DESC".equals(aisleOrder)) { queryWrapper.orderByDesc("aisle"); } else { queryWrapper.orderByAsc("aisle"); } Object shelfOrder = jsonObject.get("ShelfOrder"); - if("DESC".equals(shelfOrder)) { + if ("DESC".equals(shelfOrder)) { queryWrapper.orderByDesc("shelf"); } else { queryWrapper.orderByAsc("shelf"); } Object rowOrder = jsonObject.get("RowOrder"); - if("DESC".equals(rowOrder)) { + if ("DESC".equals(rowOrder)) { queryWrapper.orderByDesc("location_row"); } else { queryWrapper.orderByAsc("location_row"); } Object columOrder = jsonObject.get("ColumOrder"); - if("DESC".equals(columOrder)) { + if ("DESC".equals(columOrder)) { queryWrapper.orderByDesc("location_colum"); } else { queryWrapper.orderByAsc("location_colum"); @@ -367,35 +375,60 @@ public class LocationServiceImpl implements LocationService { Object enableMixLot = jsonObject.get("EnableMixLot"); //可以混状态 Object enableMixStatus = jsonObject.get("EnableMixStatus"); - if("TRUE".equals(emptyLocationFirst)) { - locationDOList = this.emptyLocationFirst(locationDOList, enableMixItem, enableMixLot, enableMixStatus); - } else if("TRUE".equals(notEmptyLocationFirst)) { - locationDOList = this.notEmptyLocationFirst(locationDOList, enableMixItem, enableMixLot, enableMixStatus); - } + locationDOList = this.locationFirst(locationDOList, emptyLocationFirst, notEmptyLocationFirst, itemCode, batch, inventoryStatus, enableMixItem, enableMixLot, enableMixStatus); return locationDOList.get(0); } /** - * 优先空库位过滤 - * @param locationDOList 库位list - * @param enableMixItem 可以混物品 - * @param enableMixLot 可以混批次 - * @param enableMixStatus 可以混状态 + * 判断优先空库位和非空库位 + * + * @param locationDOList 库位list + * @param emptyLocationFirst 优先空库位 + * @param notEmptyLocationFirst 优先非空库位 + * @param itemCode 物品编号 + * @param batch 批次 + * @param inventoryStatus 状态 + * @param enableMixItem 可以混物品 + * @param enableMixLot 可以混批次 + * @param enableMixStatus 可以混状态 * @return 过滤之后的库位list */ - private List emptyLocationFirst(List locationDOList, Object enableMixItem, Object enableMixLot, Object enableMixStatus) { - return locationDOList; - } - - /** - * 优先非空库位过滤 - * @param locationDOList 库位list - * @param enableMixItem 可以混物品 - * @param enableMixLot 可以混批次 - * @param enableMixStatus 可以混状态 - * @return 过滤之后的库位list - */ - private List notEmptyLocationFirst(List locationDOList, Object enableMixItem, Object enableMixLot, Object enableMixStatus) { + private List locationFirst(List locationDOList, Object emptyLocationFirst, Object notEmptyLocationFirst, String itemCode, String batch, String inventoryStatus, Object enableMixItem, Object enableMixLot, Object enableMixStatus) { + List emptyList = new ArrayList<>(); + List notEmptyList = new ArrayList<>(); + for (LocationDO locationDO : locationDOList) { + List balanceDOList = balanceMapper.getBalanceList(null, null, null, null, locationDO.getCode()); + if (balanceDOList.isEmpty()) { + emptyList.add(locationDO); + } else { + boolean flag = true; + for (BalanceDO balanceDO : balanceDOList) { + if ("TRUE".equals(enableMixItem) && !itemCode.equals(balanceDO.getItemCode())) { + flag = false; + break; + } + if ("TRUE".equals(enableMixLot) && !batch.equals(balanceDO.getBatch())) { + flag = false; + break; + } + if ("TRUE".equals(enableMixStatus) && !inventoryStatus.equals(balanceDO.getInventoryStatus())) { + flag = false; + break; + } + } + if (flag) { + notEmptyList.add(locationDO); + } + } + } + //优先空库位 + if("TRUE".equals(emptyLocationFirst) && !emptyList.isEmpty()) { + return emptyList; + } + //优先非空库位 + if("TRUE".equals(notEmptyLocationFirst) && !notEmptyList.isEmpty()) { + return notEmptyList; + } return locationDOList; } diff --git a/win-module-wms/win-module-wms-biz/src/main/java/com/win/module/wms/service/productionreturnRequest/ProductionreturnRequestMainServiceImpl.java b/win-module-wms/win-module-wms-biz/src/main/java/com/win/module/wms/service/productionreturnRequest/ProductionreturnRequestMainServiceImpl.java index 36f44411..3becd7b4 100644 --- a/win-module-wms/win-module-wms-biz/src/main/java/com/win/module/wms/service/productionreturnRequest/ProductionreturnRequestMainServiceImpl.java +++ b/win-module-wms/win-module-wms-biz/src/main/java/com/win/module/wms/service/productionreturnRequest/ProductionreturnRequestMainServiceImpl.java @@ -679,7 +679,7 @@ public class ProductionreturnRequestMainServiceImpl implements ProductionreturnR ItembasicDO itembasicDO = itembasicService.selectItembasic(productionreturnRecordDetailDO.getItemCode()); // 获取上架策略 并赋值 to库位 RuleRespVO ruleRespVO = ruleService.grounding(null,null,itembasicDO.getAbcClass(),itembasicDO.getType(),itembasicDO.getItemGroup(),itembasicDO.getProject(), itembasicDO.getCode(),null,null,null,null,null,null); - LocationDO locationDO = locationService.inspectLocation(ruleRespVO,itembasicDO); + LocationDO locationDO = locationService.inspectLocation(ruleRespVO, itembasicDO.getCode(), item.getBatch(), productionreturnRecordDetailDO.getInventoryStatus()); productionreturnRecordDetailDO.setToLocationCode(locationDO.getCode()); // 获取库位信息 并赋值 LocationDO locationDOFrom = locationService.selectLocation(item.getFromLocationCode()); @@ -797,7 +797,7 @@ public class ProductionreturnRequestMainServiceImpl implements ProductionreturnR productionreturnJobDetailDO.setNumber(number); // 获取上架策略 并赋值 to库位 RuleRespVO ruleRespVO = ruleService.grounding(null,null, itembasicDO.getAbcClass(), itembasicDO.getType(), itembasicDO.getItemGroup(), itembasicDO.getProject(), productionreturnJobDetailDO.getItemCode(),null,null,null,null,null,null); - LocationDO locationDO = locationService.inspectLocation(ruleRespVO, itembasicDO); + LocationDO locationDO = locationService.inspectLocation(ruleRespVO, itembasicDO.getCode(), productionreturnJobDetailDO.getBatch(), productionreturnJobDetailDO.getInventoryStatus()); productionreturnJobDetailDO.setToLocationCode(locationDO.getCode()); // 判断合格 不合格 if (!mainDO.getBusinessType().equals("ReturnToStore")) { diff --git a/win-module-wms/win-module-wms-biz/src/main/java/com/win/module/wms/service/putawayRequest/PutawayRequestMainServiceImpl.java b/win-module-wms/win-module-wms-biz/src/main/java/com/win/module/wms/service/putawayRequest/PutawayRequestMainServiceImpl.java index 50a389c2..ea810377 100644 --- a/win-module-wms/win-module-wms-biz/src/main/java/com/win/module/wms/service/putawayRequest/PutawayRequestMainServiceImpl.java +++ b/win-module-wms/win-module-wms-biz/src/main/java/com/win/module/wms/service/putawayRequest/PutawayRequestMainServiceImpl.java @@ -367,7 +367,7 @@ public class PutawayRequestMainServiceImpl implements PutawayRequestMainService RuleRespVO groundingRuleRespVO = ruleService.grounding(putawayJobMainDO.getSupplierCode(), null, itembasicDO.getAbcClass(), itembasicDO.getType(), itembasicDO.getItemGroup(), itembasicDO.getProject(), putawayJobDetailDO.getItemCode(), putawayJobDetailDO.getInventoryStatus(), null, null, null, null, null); - LocationDO locationDO = locationService.inspectLocation(groundingRuleRespVO, itembasicDO); + LocationDO locationDO = locationService.inspectLocation(groundingRuleRespVO, itembasicDO.getCode(), putawayJobDetailDO.getBatch(), putawayJobDetailDO.getInventoryStatus()); putawayJobDetailDO.setToLocationCode(locationDO.getCode()); putawayJobDetailDO.setNumber(number); putawayJobDetailDO.setMasterId(putawayJobDetailDO.getId());