Commit a2b0b9567e98dfbf0eb41e5a0391e6aa762176fe

Authored by 易文鹏
1 parent ebe91036

feat:优化二期动态分配库位逻辑

src/main/java/com/huaheng/api/wcs/service/overrideHandle/OverrideHandleServiceImpl.java
@@ -147,7 +147,7 @@ public class OverrideHandleServiceImpl implements OverrideHandleService { @@ -147,7 +147,7 @@ public class OverrideHandleServiceImpl implements OverrideHandleService {
147 } 147 }
148 } 148 }
149 149
150 - String locationCode = locationAllocationService.allocation(high, area, roadWay, containerCode, frequencyLocation, onlyEmptyContainer, isSelfCreated, isFlammable); 150 + String locationCode = locationAllocationService.allocation(high, area, roadWay, containerCode, frequencyLocation, onlyEmptyContainer, isSelfCreated, isFlammable, false);
151 if (StringUtils.isEmpty(locationCode)) { 151 if (StringUtils.isEmpty(locationCode)) {
152 return AjaxResult.error("没有库位可分配"); 152 return AjaxResult.error("没有库位可分配");
153 } 153 }
src/main/java/com/huaheng/api/wcs/service/taskAssignService/TaskAssignServiceImpl.java
@@ -170,7 +170,7 @@ public class TaskAssignServiceImpl implements TaskAssignService { @@ -170,7 +170,7 @@ public class TaskAssignServiceImpl implements TaskAssignService {
170 } 170 }
171 //分配库位 171 //分配库位
172 String destinationLocationCode = locationAllocationService.allocation(insideLocation.getHigh(), insideLocation.getArea(), "5", 172 String destinationLocationCode = locationAllocationService.allocation(insideLocation.getHigh(), insideLocation.getArea(), "5",
173 - containerCode, insideLocation.getFrequencyLocation(), insideLocation.getOnlyEmptyContainer(), isSelfCreated, isFlammable); 173 + containerCode, insideLocation.getFrequencyLocation(), insideLocation.getOnlyEmptyContainer(), isSelfCreated, isFlammable, true);
174 if (StringUtils.isEmpty(destinationLocationCode)) { 174 if (StringUtils.isEmpty(destinationLocationCode)) {
175 return AjaxResult.error("移库没有剩余库位"); 175 return AjaxResult.error("移库没有剩余库位");
176 } else if (destinationLocationCode.length() > 10) { 176 } else if (destinationLocationCode.length() > 10) {
src/main/java/com/huaheng/api/wcs/service/warecellAllocation/LocationAllocationService.java
@@ -9,9 +9,9 @@ public interface LocationAllocationService { @@ -9,9 +9,9 @@ public interface LocationAllocationService {
9 9
10 10
11 String allocation(int high, String area, String roadWay, String containerCode, Integer frequencyLocation, 11 String allocation(int high, String area, String roadWay, String containerCode, Integer frequencyLocation,
12 - Integer emptyContainerTask, Integer isSelfCreated, boolean isFlammable); 12 + Integer emptyContainerTask, Integer isSelfCreated, boolean isFlammable, boolean transfer);
13 13
14 - String fiveStacker(int high, String containerCode, boolean isFlammable); 14 + String fiveStacker(int high, String containerCode, boolean isFlammable, boolean transfer);
15 15
16 void setTemporaryLocationType(Location location, boolean isBigContainer); 16 void setTemporaryLocationType(Location location, boolean isBigContainer);
17 17
src/main/java/com/huaheng/api/wcs/service/warecellAllocation/LocationAllocationServiceImpl.java
@@ -19,6 +19,7 @@ import com.huaheng.pc.config.locationType.service.LocationTypeService; @@ -19,6 +19,7 @@ import com.huaheng.pc.config.locationType.service.LocationTypeService;
19 import com.huaheng.pc.config.zone.domain.Zone; 19 import com.huaheng.pc.config.zone.domain.Zone;
20 import com.huaheng.pc.config.zone.service.ZoneService; 20 import com.huaheng.pc.config.zone.service.ZoneService;
21 import com.huaheng.pc.task.taskHeader.service.TaskHeaderService; 21 import com.huaheng.pc.task.taskHeader.service.TaskHeaderService;
  22 +import io.undertow.util.Transfer;
22 import org.springframework.stereotype.Service; 23 import org.springframework.stereotype.Service;
23 import org.springframework.transaction.annotation.Transactional; 24 import org.springframework.transaction.annotation.Transactional;
24 import org.springframework.util.StopWatch; 25 import org.springframework.util.StopWatch;
@@ -55,13 +56,12 @@ public class LocationAllocationServiceImpl implements LocationAllocationService @@ -55,13 +56,12 @@ public class LocationAllocationServiceImpl implements LocationAllocationService
55 @Override 56 @Override
56 @Transactional(rollbackFor = Exception.class) 57 @Transactional(rollbackFor = Exception.class)
57 public String allocation(int high, String area, String roadWay, String containerCode, Integer frequencyLocation, 58 public String allocation(int high, String area, String roadWay, String containerCode, Integer frequencyLocation,
58 - Integer emptyContainerTask, Integer isSelfCreated, boolean isFlammable) { 59 + Integer emptyContainerTask, Integer isSelfCreated, boolean isFlammable, boolean transfer) {
59 60
60 //二期5号巷道 61 //二期5号巷道
61 if (roadWay.equals(DYNAMIC_ROADWAY)) { 62 if (roadWay.equals(DYNAMIC_ROADWAY)) {
62 - return locationAllocationService.fiveStacker(high, containerCode, isFlammable);  
63 - //自建单据  
64 - } else if (isSelfCreated == 1) { 63 + return locationAllocationService.fiveStacker(high, containerCode, isFlammable, transfer);
  64 + } else if (isSelfCreated == 1) { //自建单据
65 return locationAllocationService.isSelfCreated(roadWay, high, frequencyLocation, isFlammable); 65 return locationAllocationService.isSelfCreated(roadWay, high, frequencyLocation, isFlammable);
66 } else { 66 } else {
67 return locationAllocationService.doubleRk(area, roadWay, high, frequencyLocation, emptyContainerTask, isFlammable); 67 return locationAllocationService.doubleRk(area, roadWay, high, frequencyLocation, emptyContainerTask, isFlammable);
@@ -73,11 +73,14 @@ public class LocationAllocationServiceImpl implements LocationAllocationService @@ -73,11 +73,14 @@ public class LocationAllocationServiceImpl implements LocationAllocationService
73 //分配库位排序,(层-外侧-内侧-列) 73 //分配库位排序,(层-外侧-内侧-列)
74 @Override 74 @Override
75 @Transactional(rollbackFor = Exception.class) 75 @Transactional(rollbackFor = Exception.class)
76 - public String fiveStacker(int high, String containerCode, boolean isFlammable) { 76 + public String fiveStacker(int high, String containerCode, boolean isFlammable, boolean transfer) {
77 Container container = containerService.getOne(new LambdaQueryWrapper<Container>().eq(Container::getCode, containerCode)); 77 Container container = containerService.getOne(new LambdaQueryWrapper<Container>().eq(Container::getCode, containerCode));
78 String containerType = container.getContainerType(); 78 String containerType = container.getContainerType();
79 //判断预留库位 79 //判断预留库位
80 - int reserveNumber = getDynamicReserveNumber(); 80 + int reserveNumber = 0;
  81 + if (!transfer) {//不是移库
  82 + reserveNumber = getDynamicReserveNumber();
  83 + }
81 LambdaQueryWrapper<Location> wrapper = Wrappers.lambdaQuery(); 84 LambdaQueryWrapper<Location> wrapper = Wrappers.lambdaQuery();
82 wrapper 85 wrapper
83 .eq(Location::getRoadway, DYNAMIC_ROADWAY) 86 .eq(Location::getRoadway, DYNAMIC_ROADWAY)
@@ -106,27 +109,57 @@ public class LocationAllocationServiceImpl implements LocationAllocationService @@ -106,27 +109,57 @@ public class LocationAllocationServiceImpl implements LocationAllocationService
106 }); 109 });
107 list.sort(Comparator.comparingInt(Location::getRowFlag).reversed()); 110 list.sort(Comparator.comparingInt(Location::getRowFlag).reversed());
108 111
109 - //大托盘占两个库位 112 + //大托盘占两个库位,只放奇数列,且右侧有空库位,且当前库位类型不是小托盘
  113 + List<Location> bigContainerLocations = new ArrayList<>();
110 if (containerType.equals(CONTAINER_TYPE_X) || containerType.equals(CONTAINER_TYPE_W)) { 114 if (containerType.equals(CONTAINER_TYPE_X) || containerType.equals(CONTAINER_TYPE_W)) {
111 - for (Location location : list) {  
112 - //大托盘只放奇数列,且右侧有空库位,且当前库位类型不是小托盘  
113 - if (location.getIColumn() % 2 != 0 && !location.getTemporaryType().startsWith(SMALL_CONTAINER_TYPE)) {  
114 - Location rightLocation = locationService.getRightEmptyLocation(location);  
115 - if (rightLocation != null) {  
116 - //禁用库位  
117 - int updateCount = locationService.updateStatusNew(rightLocation.getCode(), DEFAULT_WAREHOUSE, STATUS_LOCATION_DISABLE, STATUS_LOCATION_EMPTY);  
118 - if (updateCount != 1) {  
119 - throw new ServiceException("分配库位时,禁用库位失败");  
120 - }  
121 - if (location.getTemporaryType().equals(UNDEFINED_CONTAINER_TYPE)) {  
122 - //设置相邻临时库位类型  
123 - locationAllocationService.setTemporaryLocationType(location, true);  
124 - }  
125 - return location.getCode();  
126 - } 115 + List<Location> filteredLocations = list.stream()
  116 + .filter(location -> location.getIColumn() % 2 != 0 && !location.getTemporaryType().startsWith(SMALL_CONTAINER_TYPE)).collect(Collectors.toList());
  117 +
  118 + for (Location filteredLocation : filteredLocations) {
  119 + Location rightLocation = locationService.getRightEmptyLocation(filteredLocation);
  120 + if (rightLocation != null) {
  121 + bigContainerLocations.add(filteredLocation);
127 } 122 }
128 } 123 }
129 - return null; 124 + if (bigContainerLocations.isEmpty()) {
  125 + return null;
  126 + }
  127 + if (!transfer && bigContainerLocations.size() <= 4) {//留4个大托盘库位移库用
  128 + return "可能是大托盘库位不够用了";
  129 + }
  130 + //todo 也可以在这里排序
  131 + Location location = bigContainerLocations.get(0);
  132 + Location rightLocation = locationService.getRightEmptyLocation(location);
  133 + //禁用库位
  134 + int updateCount = locationService.updateStatusNew(rightLocation.getCode(), DEFAULT_WAREHOUSE, STATUS_LOCATION_DISABLE, STATUS_LOCATION_EMPTY);
  135 + if (updateCount != 1) {
  136 + throw new ServiceException("分配库位时,禁用库位失败");
  137 + }
  138 + //设置相邻临时库位类型
  139 + if (location.getTemporaryType().equals(UNDEFINED_CONTAINER_TYPE)) {
  140 + locationAllocationService.setTemporaryLocationType(location, true);
  141 + }
  142 + return location.getCode();
  143 +
  144 + //for (Location location : list) {
  145 + // //大托盘只放奇数列,且右侧有空库位,且当前库位类型不是小托盘
  146 + // if (location.getIColumn() % 2 != 0 && !location.getTemporaryType().startsWith(SMALL_CONTAINER_TYPE)) {
  147 + // Location rightLocation = locationService.getRightEmptyLocation(location);
  148 + // if (rightLocation != null) {
  149 + // //禁用库位
  150 + // int updateCount = locationService.updateStatusNew(rightLocation.getCode(), DEFAULT_WAREHOUSE, STATUS_LOCATION_DISABLE, STATUS_LOCATION_EMPTY);
  151 + // if (updateCount != 1) {
  152 + // throw new ServiceException("分配库位时,禁用库位失败");
  153 + // }
  154 + // if (location.getTemporaryType().equals(UNDEFINED_CONTAINER_TYPE)) {
  155 + // //设置相邻临时库位类型
  156 + // locationAllocationService.setTemporaryLocationType(location, true);
  157 + // }
  158 + // return location.getCode();
  159 + // }
  160 + // }
  161 + //}
  162 + //return null;
130 } else { 163 } else {
131 //分配小托盘库位,将大托盘库位过滤掉 164 //分配小托盘库位,将大托盘库位过滤掉
132 //小托盘不分配25列,最好让大托盘放在25列 165 //小托盘不分配25列,最好让大托盘放在25列
@@ -149,10 +182,12 @@ public class LocationAllocationServiceImpl implements LocationAllocationService @@ -149,10 +182,12 @@ public class LocationAllocationServiceImpl implements LocationAllocationService
149 if (list.isEmpty()) { 182 if (list.isEmpty()) {
150 return null; 183 return null;
151 } 184 }
152 -  
153 - Location location = list.stream().findFirst().orElse(null); 185 + if (list.size() <= reserveNumber) {
  186 + return "可能是小托盘库位不够用了";
  187 + }
  188 + Location location = list.get(0);
  189 + //设置相邻临时库位类型
154 if (location.getTemporaryType().equals(UNDEFINED_CONTAINER_TYPE)) { 190 if (location.getTemporaryType().equals(UNDEFINED_CONTAINER_TYPE)) {
155 - //设置相邻临时库位类型  
156 locationAllocationService.setTemporaryLocationType(location, false); 191 locationAllocationService.setTemporaryLocationType(location, false);
157 } 192 }
158 return location.getCode(); 193 return location.getCode();
src/main/java/com/huaheng/api/wcs/service/warecellAllocation/WarecellAllocationServiceImpl.java
@@ -129,10 +129,11 @@ public class WarecellAllocationServiceImpl implements WarecellAllocationService @@ -129,10 +129,11 @@ public class WarecellAllocationServiceImpl implements WarecellAllocationService
129 if (StringUtils.isNull(warecellDomain.getWidth())) { 129 if (StringUtils.isNull(warecellDomain.getWidth())) {
130 return AjaxResult.error("宽为空"); 130 return AjaxResult.error("宽为空");
131 } 131 }
132 - if (StringUtils.isNull(warecellDomain.getHeight()) || "0".equals(warecellDomain.getHeight())) { 132 + warecellDomain.setWarehouseCode("CS0001");
  133 + String height = warecellDomain.getHeight();
  134 + if (StringUtils.isNull(height) || "0".equals(height)) {
133 return AjaxResult.error("高为空或0"); 135 return AjaxResult.error("高为空或0");
134 } 136 }
135 - warecellDomain.setWarehouseCode("CS0001");  
136 return warecellAllocationService.verticalWarehouseAllocation(warecellDomain); 137 return warecellAllocationService.verticalWarehouseAllocation(warecellDomain);
137 } 138 }
138 139
@@ -212,7 +213,7 @@ public class WarecellAllocationServiceImpl implements WarecellAllocationService @@ -212,7 +213,7 @@ public class WarecellAllocationServiceImpl implements WarecellAllocationService
212 //巷道 213 //巷道
213 String roadWay = roadWays.get(0); 214 String roadWay = roadWays.get(0);
214 //分配库位 215 //分配库位
215 - locationCode = locationAllocationService.allocation(high, area, roadWay, containerCode, frequencyLocation, emptyContainerTask, isSelfCreated, isFlammable); 216 + locationCode = locationAllocationService.allocation(high, area, roadWay, containerCode, frequencyLocation, emptyContainerTask, isSelfCreated, isFlammable, false);
216 217
217 if (StringUtils.isEmpty(locationCode)) { 218 if (StringUtils.isEmpty(locationCode)) {
218 return AjaxResult.error("没有库位可分配"); 219 return AjaxResult.error("没有库位可分配");
@@ -256,7 +257,7 @@ public class WarecellAllocationServiceImpl implements WarecellAllocationService @@ -256,7 +257,7 @@ public class WarecellAllocationServiceImpl implements WarecellAllocationService
256 Location destinationLocation; 257 Location destinationLocation;
257 if (roadWay.equals("5")) { 258 if (roadWay.equals("5")) {
258 //分配库位 259 //分配库位
259 - String destinationLocationCode = locationAllocationService.allocation(high, area, roadWay, containerCode, frequencyLocation, emptyContainerTask, isSelfCreated, isFlammable); 260 + String destinationLocationCode = locationAllocationService.allocation(high, area, roadWay, containerCode, frequencyLocation, emptyContainerTask, isSelfCreated, isFlammable, true);
260 if (StringUtils.isEmpty(destinationLocationCode)) { 261 if (StringUtils.isEmpty(destinationLocationCode)) {
261 return AjaxResult.error("移库没有剩余库位"); 262 return AjaxResult.error("移库没有剩余库位");
262 } else if (destinationLocationCode.length() > 10) { 263 } else if (destinationLocationCode.length() > 10) {
src/main/java/com/huaheng/pc/config/location/service/LocationServiceImpl.java
@@ -750,7 +750,7 @@ public class LocationServiceImpl extends ServiceImpl&lt;LocationMapper, Location&gt; i @@ -750,7 +750,7 @@ public class LocationServiceImpl extends ServiceImpl&lt;LocationMapper, Location&gt; i
750 return null; 750 return null;
751 } 751 }
752 752
753 - //获取库位的左侧空库位,且 753 + //获取库位的左侧空库位,且相邻4个库位不能有任务
754 @Override 754 @Override
755 public Location getRightEmptyLocation(Location location) { 755 public Location getRightEmptyLocation(Location location) {
756 Location rightEmptyLocation = locationService.getOne(new LambdaQueryWrapper<Location>() 756 Location rightEmptyLocation = locationService.getOne(new LambdaQueryWrapper<Location>()
src/main/java/com/huaheng/pc/shipment/shipmentHeader/controller/ShipmentHeaderController.java
@@ -643,6 +643,7 @@ public class ShipmentHeaderController extends BaseController { @@ -643,6 +643,7 @@ public class ShipmentHeaderController extends BaseController {
643 String workshops = configService.getKey(AUTO_SHIPMENT_WORKSHOPS); 643 String workshops = configService.getKey(AUTO_SHIPMENT_WORKSHOPS);
644 List<ShipmentHeader> shipmentHeaderList = shipmentHeaderService.list(new LambdaQueryWrapper<ShipmentHeader>() 644 List<ShipmentHeader> shipmentHeaderList = shipmentHeaderService.list(new LambdaQueryWrapper<ShipmentHeader>()
645 .eq(ShipmentHeader::getCreatedBy, "MOM") 645 .eq(ShipmentHeader::getCreatedBy, "MOM")
  646 + .eq(ShipmentHeader::getDeleted, 0)
646 .eq(ShipmentHeader::getAutoShipmentStatus, 0) 647 .eq(ShipmentHeader::getAutoShipmentStatus, 0)
647 .eq(ShipmentHeader::getFirstStatus, RECEIPT_HEADER_BUILD) 648 .eq(ShipmentHeader::getFirstStatus, RECEIPT_HEADER_BUILD)
648 .eq(ShipmentHeader::getLastStatus, RECEIPT_HEADER_BUILD) 649 .eq(ShipmentHeader::getLastStatus, RECEIPT_HEADER_BUILD)
@@ -680,7 +681,9 @@ public class ShipmentHeaderController extends BaseController { @@ -680,7 +681,9 @@ public class ShipmentHeaderController extends BaseController {
680 681
681 //获取待自动执行的出库单 682 //获取待自动执行的出库单
682 public List<ShipmentHeader> getPrepareShipmentHeaderList() { 683 public List<ShipmentHeader> getPrepareShipmentHeaderList() {
683 - return shipmentHeaderService.list(new LambdaQueryWrapper<ShipmentHeader>().eq(ShipmentHeader::getAutoShipmentStatus, 1)); 684 + return shipmentHeaderService.list(new LambdaQueryWrapper<ShipmentHeader>()
  685 + .eq(ShipmentHeader::getDeleted, 0)
  686 + .eq(ShipmentHeader::getAutoShipmentStatus, 1));
684 } 687 }
685 688
686 //批量修改出库单状态 689 //批量修改出库单状态
src/main/java/com/huaheng/pc/shipment/shipmentHeader/service/ShipmentHeaderServiceImpl.java
@@ -480,7 +480,10 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl&lt;ShipmentHeaderMapper, @@ -480,7 +480,10 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl&lt;ShipmentHeaderMapper,
480 @Override 480 @Override
481 public AjaxResult autoBillMerge() { 481 public AjaxResult autoBillMerge() {
482 //出库单状态是新建的单据,根据通知单号、原仓库、车间都相同都的出库单进行合并。(只合并一次) 482 //出库单状态是新建的单据,根据通知单号、原仓库、车间都相同都的出库单进行合并。(只合并一次)
483 - List<ShipmentHeader> list = shipmentHeaderService.list(new LambdaQueryWrapper<ShipmentHeader>().eq(ShipmentHeader::getFirstStatus, QuantityConstant.SHIPMENT_HEADER_BUILD)); 483 + List<ShipmentHeader> list = shipmentHeaderService.list(new LambdaQueryWrapper<ShipmentHeader>()
  484 + .eq(ShipmentHeader::getDeleted, 0)
  485 + .eq(ShipmentHeader::getLastStatus, QuantityConstant.SHIPMENT_HEADER_BUILD)
  486 + .eq(ShipmentHeader::getFirstStatus, QuantityConstant.SHIPMENT_HEADER_BUILD));
484 // 用于存储相同出库单的映射 487 // 用于存储相同出库单的映射
485 Map<String, List<Integer>> matchingMap = new HashMap<>(); 488 Map<String, List<Integer>> matchingMap = new HashMap<>();
486 489
src/main/resources/templates/shipment/shipmentHeader/shipmentHeader.html
@@ -940,7 +940,6 @@ @@ -940,7 +940,6 @@
940 } else { 940 } else {
941 $('#shipmentDeleted').val('是') 941 $('#shipmentDeleted').val('是')
942 } 942 }
943 - ;  
944 $('#shipmentUserDef1').val(value.data.userDef1); 943 $('#shipmentUserDef1').val(value.data.userDef1);
945 $('#shipmentUserDef2').val(value.data.userDef2); 944 $('#shipmentUserDef2').val(value.data.userDef2);
946 $('#shipmentUserDef3').val(value.data.userDef3); 945 $('#shipmentUserDef3').val(value.data.userDef3);