Commit a2b0b9567e98dfbf0eb41e5a0391e6aa762176fe
1 parent
ebe91036
feat:优化二期动态分配库位逻辑
Showing
9 changed files
with
80 additions
and
39 deletions
src/main/java/com/huaheng/api/wcs/service/overrideHandle/OverrideHandleServiceImpl.java
... | ... | @@ -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 | 151 | if (StringUtils.isEmpty(locationCode)) { |
152 | 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 | 170 | } |
171 | 171 | //分配库位 |
172 | 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 | 174 | if (StringUtils.isEmpty(destinationLocationCode)) { |
175 | 175 | return AjaxResult.error("移库没有剩余库位"); |
176 | 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 | |
10 | 10 | |
11 | 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 | 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 | 19 | import com.huaheng.pc.config.zone.domain.Zone; |
20 | 20 | import com.huaheng.pc.config.zone.service.ZoneService; |
21 | 21 | import com.huaheng.pc.task.taskHeader.service.TaskHeaderService; |
22 | +import io.undertow.util.Transfer; | |
22 | 23 | import org.springframework.stereotype.Service; |
23 | 24 | import org.springframework.transaction.annotation.Transactional; |
24 | 25 | import org.springframework.util.StopWatch; |
... | ... | @@ -55,13 +56,12 @@ public class LocationAllocationServiceImpl implements LocationAllocationService |
55 | 56 | @Override |
56 | 57 | @Transactional(rollbackFor = Exception.class) |
57 | 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 | 61 | //二期5号巷道 |
61 | 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 | 65 | return locationAllocationService.isSelfCreated(roadWay, high, frequencyLocation, isFlammable); |
66 | 66 | } else { |
67 | 67 | return locationAllocationService.doubleRk(area, roadWay, high, frequencyLocation, emptyContainerTask, isFlammable); |
... | ... | @@ -73,11 +73,14 @@ public class LocationAllocationServiceImpl implements LocationAllocationService |
73 | 73 | //分配库位排序,(层-外侧-内侧-列) |
74 | 74 | @Override |
75 | 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 | 77 | Container container = containerService.getOne(new LambdaQueryWrapper<Container>().eq(Container::getCode, containerCode)); |
78 | 78 | String containerType = container.getContainerType(); |
79 | 79 | //判断预留库位 |
80 | - int reserveNumber = getDynamicReserveNumber(); | |
80 | + int reserveNumber = 0; | |
81 | + if (!transfer) {//不是移库 | |
82 | + reserveNumber = getDynamicReserveNumber(); | |
83 | + } | |
81 | 84 | LambdaQueryWrapper<Location> wrapper = Wrappers.lambdaQuery(); |
82 | 85 | wrapper |
83 | 86 | .eq(Location::getRoadway, DYNAMIC_ROADWAY) |
... | ... | @@ -106,27 +109,57 @@ public class LocationAllocationServiceImpl implements LocationAllocationService |
106 | 109 | }); |
107 | 110 | list.sort(Comparator.comparingInt(Location::getRowFlag).reversed()); |
108 | 111 | |
109 | - //大托盘占两个库位 | |
112 | + //大托盘占两个库位,只放奇数列,且右侧有空库位,且当前库位类型不是小托盘 | |
113 | + List<Location> bigContainerLocations = new ArrayList<>(); | |
110 | 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 | 163 | } else { |
131 | 164 | //分配小托盘库位,将大托盘库位过滤掉 |
132 | 165 | //小托盘不分配25列,最好让大托盘放在25列 |
... | ... | @@ -149,10 +182,12 @@ public class LocationAllocationServiceImpl implements LocationAllocationService |
149 | 182 | if (list.isEmpty()) { |
150 | 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 | 190 | if (location.getTemporaryType().equals(UNDEFINED_CONTAINER_TYPE)) { |
155 | - //设置相邻临时库位类型 | |
156 | 191 | locationAllocationService.setTemporaryLocationType(location, false); |
157 | 192 | } |
158 | 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 | 129 | if (StringUtils.isNull(warecellDomain.getWidth())) { |
130 | 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 | 135 | return AjaxResult.error("高为空或0"); |
134 | 136 | } |
135 | - warecellDomain.setWarehouseCode("CS0001"); | |
136 | 137 | return warecellAllocationService.verticalWarehouseAllocation(warecellDomain); |
137 | 138 | } |
138 | 139 | |
... | ... | @@ -212,7 +213,7 @@ public class WarecellAllocationServiceImpl implements WarecellAllocationService |
212 | 213 | //巷道 |
213 | 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 | 218 | if (StringUtils.isEmpty(locationCode)) { |
218 | 219 | return AjaxResult.error("没有库位可分配"); |
... | ... | @@ -256,7 +257,7 @@ public class WarecellAllocationServiceImpl implements WarecellAllocationService |
256 | 257 | Location destinationLocation; |
257 | 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 | 261 | if (StringUtils.isEmpty(destinationLocationCode)) { |
261 | 262 | return AjaxResult.error("移库没有剩余库位"); |
262 | 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<LocationMapper, Location> i |
750 | 750 | return null; |
751 | 751 | } |
752 | 752 | |
753 | - //获取库位的左侧空库位,且 | |
753 | + //获取库位的左侧空库位,且相邻4个库位不能有任务 | |
754 | 754 | @Override |
755 | 755 | public Location getRightEmptyLocation(Location location) { |
756 | 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 | 643 | String workshops = configService.getKey(AUTO_SHIPMENT_WORKSHOPS); |
644 | 644 | List<ShipmentHeader> shipmentHeaderList = shipmentHeaderService.list(new LambdaQueryWrapper<ShipmentHeader>() |
645 | 645 | .eq(ShipmentHeader::getCreatedBy, "MOM") |
646 | + .eq(ShipmentHeader::getDeleted, 0) | |
646 | 647 | .eq(ShipmentHeader::getAutoShipmentStatus, 0) |
647 | 648 | .eq(ShipmentHeader::getFirstStatus, RECEIPT_HEADER_BUILD) |
648 | 649 | .eq(ShipmentHeader::getLastStatus, RECEIPT_HEADER_BUILD) |
... | ... | @@ -680,7 +681,9 @@ public class ShipmentHeaderController extends BaseController { |
680 | 681 | |
681 | 682 | //获取待自动执行的出库单 |
682 | 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<ShipmentHeaderMapper, |
480 | 480 | @Override |
481 | 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 | 488 | Map<String, List<Integer>> matchingMap = new HashMap<>(); |
486 | 489 | |
... | ... |
src/main/resources/templates/shipment/shipmentHeader/shipmentHeader.html