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 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&lt;LocationMapper, Location&gt; 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&lt;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
... ... @@ -940,7 +940,6 @@
940 940 } else {
941 941 $('#shipmentDeleted').val('是')
942 942 }
943   - ;
944 943 $('#shipmentUserDef1').val(value.data.userDef1);
945 944 $('#shipmentUserDef2').val(value.data.userDef2);
946 945 $('#shipmentUserDef3').val(value.data.userDef3);
... ...