Commit e9aaf4bebb9dba795b735e953f2c63a076427fdc
1 parent
05b47ece
feat: 自建单据-单据给一个分配库位逻辑
Showing
7 changed files
with
143 additions
and
46 deletions
src/main/java/com/huaheng/api/mes/service/MesServiceImpl.java
... | ... | @@ -371,9 +371,6 @@ public class MesServiceImpl implements IMesService { |
371 | 371 | newMaterial.setCompanyCode("BHF"); |
372 | 372 | materialService.save(newMaterial); |
373 | 373 | } else { |
374 | - if (!material.getCode().equals(shipmentDetail.getMaterialCode())) { | |
375 | - throw new ServiceException("物料编码对不上,出库单:" + shipmentDetail.getMaterialCode() + "物料表:" + material.getCode()); | |
376 | - } | |
377 | 374 | shipmentDetail.setMaterialSpec(material.getSpec()); |
378 | 375 | shipmentDetail.setMaterialUnit(material.getUnit()); |
379 | 376 | } |
... | ... |
src/main/java/com/huaheng/api/tv/controller/TvController.java
... | ... | @@ -108,7 +108,7 @@ public class TvController extends BaseController { |
108 | 108 | } |
109 | 109 | |
110 | 110 | |
111 | - //二期新入库看板,显示入库次数和入库数量 | |
111 | + //二期新入库看板,显示出入库次数和出入库数量 | |
112 | 112 | @PostMapping("/getTvReceiptFrequencyAndQty") |
113 | 113 | @ResponseBody |
114 | 114 | public TVResult getTvReceiptFrequencyAndQty() { |
... | ... | @@ -120,9 +120,19 @@ public class TvController extends BaseController { |
120 | 120 | String sql2 = "SELECT a.click_date AS DATE,ifnull( b.taskCount, 0 ) AS count FROM(SELECT curdate() AS click_date UNION ALL SELECT date_sub( curdate(), INTERVAL 1 DAY ) AS click_date UNION ALL SELECT date_sub( curdate(), INTERVAL 2 DAY ) AS click_date UNION ALL SELECT date_sub( curdate(), INTERVAL 3 DAY ) AS click_date UNION ALL SELECT date_sub( curdate(), INTERVAL 4 DAY ) AS click_date UNION ALL SELECT date_sub( curdate(), INTERVAL 5 DAY ) AS click_date UNION ALL SELECT date_sub( curdate(), INTERVAL 6 DAY ) AS click_date ) a LEFT JOIN (SELECT DATE ( h.completeTime ) AS completeTime,COUNT( DISTINCT h.id ) AS taskCount FROM task_detail d JOIN task_header h ON d.taskId = h.id WHERE h.completeTime >= DATE_SUB( CURDATE(), INTERVAL 7 DAY ) AND h.STATUS = 100 AND h.internalTaskType=100 GROUP BY DATE ( h.completeTime )) b ON a.click_date = b.completeTime ORDER BY a.click_date;"; |
121 | 121 | List<LinkedHashMap<String, Object>> list2 = mapper.selectCommon(sql2); |
122 | 122 | |
123 | + | |
124 | + //数量 | |
125 | + String sql3 = "SELECT a.click_date AS DATE,ifnull( b.taskQty, 0 ) AS qty FROM(SELECT curdate() AS click_date UNION ALL SELECT date_sub( curdate(), INTERVAL 1 DAY ) AS click_date UNION ALL SELECT date_sub( curdate(), INTERVAL 2 DAY ) AS click_date UNION ALL SELECT date_sub( curdate(), INTERVAL 3 DAY ) AS click_date UNION ALL SELECT date_sub( curdate(), INTERVAL 4 DAY ) AS click_date UNION ALL SELECT date_sub( curdate(), INTERVAL 5 DAY ) AS click_date UNION ALL SELECT date_sub( curdate(), INTERVAL 6 DAY ) AS click_date ) a LEFT JOIN (SELECT DATE ( h.completeTime ) AS completeTime,SUM( d.qty ) AS taskQty FROM task_detail d JOIN task_header h ON d.taskId = h.id WHERE h.completeTime >= DATE_SUB( CURDATE(), INTERVAL 7 DAY ) AND h.STATUS = 100 AND h.internalTaskType=200 GROUP BY DATE ( h.completeTime )) b ON a.click_date = b.completeTime ORDER BY a.click_date;"; | |
126 | + List<LinkedHashMap<String, Object>> list3 = mapper.selectCommon(sql3); | |
127 | + //次数 | |
128 | + String sql4 = "SELECT a.click_date AS DATE,ifnull( b.taskCount, 0 ) AS count FROM(SELECT curdate() AS click_date UNION ALL SELECT date_sub( curdate(), INTERVAL 1 DAY ) AS click_date UNION ALL SELECT date_sub( curdate(), INTERVAL 2 DAY ) AS click_date UNION ALL SELECT date_sub( curdate(), INTERVAL 3 DAY ) AS click_date UNION ALL SELECT date_sub( curdate(), INTERVAL 4 DAY ) AS click_date UNION ALL SELECT date_sub( curdate(), INTERVAL 5 DAY ) AS click_date UNION ALL SELECT date_sub( curdate(), INTERVAL 6 DAY ) AS click_date ) a LEFT JOIN (SELECT DATE ( h.completeTime ) AS completeTime,COUNT( DISTINCT h.id ) AS taskCount FROM task_detail d JOIN task_header h ON d.taskId = h.id WHERE h.completeTime >= DATE_SUB( CURDATE(), INTERVAL 7 DAY ) AND h.STATUS = 100 AND h.internalTaskType=200 GROUP BY DATE ( h.completeTime )) b ON a.click_date = b.completeTime ORDER BY a.click_date;"; | |
129 | + List<LinkedHashMap<String, Object>> list4 = mapper.selectCommon(sql4); | |
130 | + | |
123 | 131 | ReceiptFrequencyAndQty resultData = new ReceiptFrequencyAndQty(); |
124 | 132 | resultData.setReceiptQty(list); |
125 | 133 | resultData.setReceiptFrequency(list2); |
134 | + resultData.setShipmentQty(list3); | |
135 | + resultData.setShipmentFrequency(list4); | |
126 | 136 | return TVResult.success(resultData); |
127 | 137 | } |
128 | 138 | |
... | ... |
src/main/java/com/huaheng/api/tv/domain/ReceiptFrequencyAndQty.java
... | ... | @@ -9,4 +9,7 @@ import java.util.List; |
9 | 9 | public class ReceiptFrequencyAndQty { |
10 | 10 | private List<LinkedHashMap<String, Object>> ReceiptFrequency; |
11 | 11 | private List<LinkedHashMap<String, Object>> ReceiptQty; |
12 | + | |
13 | + private List<LinkedHashMap<String, Object>> ShipmentFrequency; | |
14 | + private List<LinkedHashMap<String, Object>> ShipmentQty; | |
12 | 15 | } |
... | ... |
src/main/java/com/huaheng/api/wcs/service/warecellAllocation/LocationAllocationService.java
... | ... | @@ -15,5 +15,7 @@ public interface LocationAllocationService { |
15 | 15 | |
16 | 16 | void setTemporaryLocationType(Location location, boolean isBigContainer); |
17 | 17 | |
18 | - String doubleRk(String area, String roadWay, int high, Integer frequencyLocation, Integer emptyContainerTask, Integer isSelfCreated, boolean isFlammable); | |
18 | + String doubleRk(String area, String roadWay, int high, Integer frequencyLocation, Integer emptyContainerTask, boolean isFlammable); | |
19 | + | |
20 | + String isSelfCreated(String roadWay, int high, Integer frequencyLocation, boolean isFlammable); | |
19 | 21 | } |
... | ... |
src/main/java/com/huaheng/api/wcs/service/warecellAllocation/LocationAllocationServiceImpl.java
... | ... | @@ -60,8 +60,11 @@ public class LocationAllocationServiceImpl implements LocationAllocationService |
60 | 60 | //二期5号巷道 |
61 | 61 | if (roadWay.equals(DYNAMIC_ROADWAY)) { |
62 | 62 | return locationAllocationService.fiveStacker(high, containerCode, isFlammable); |
63 | + //自建单据 | |
64 | + } else if (isSelfCreated == 1) { | |
65 | + return locationAllocationService.isSelfCreated(roadWay, high, frequencyLocation, isFlammable); | |
63 | 66 | } else { |
64 | - return locationAllocationService.doubleRk(area, roadWay, high, frequencyLocation, emptyContainerTask, isSelfCreated, isFlammable); | |
67 | + return locationAllocationService.doubleRk(area, roadWay, high, frequencyLocation, emptyContainerTask, isFlammable); | |
65 | 68 | } |
66 | 69 | } |
67 | 70 | |
... | ... | @@ -74,7 +77,7 @@ public class LocationAllocationServiceImpl implements LocationAllocationService |
74 | 77 | Container container = containerService.getOne(new LambdaQueryWrapper<Container>().eq(Container::getCode, containerCode)); |
75 | 78 | String containerType = container.getContainerType(); |
76 | 79 | //判断预留库位 |
77 | - int reserveNumber = getReserveNumber(); | |
80 | + int reserveNumber = getDynamicReserveNumber(); | |
78 | 81 | LambdaQueryWrapper<Location> wrapper = Wrappers.lambdaQuery(); |
79 | 82 | wrapper |
80 | 83 | .eq(Location::getRoadway, DYNAMIC_ROADWAY) |
... | ... | @@ -146,7 +149,7 @@ public class LocationAllocationServiceImpl implements LocationAllocationService |
146 | 149 | if (list.isEmpty()) { |
147 | 150 | return null; |
148 | 151 | } |
149 | - | |
152 | + | |
150 | 153 | Location location = list.stream().findFirst().orElse(null); |
151 | 154 | if (location.getTemporaryType().equals(UNDEFINED_CONTAINER_TYPE)) { |
152 | 155 | //设置相邻临时库位类型 |
... | ... | @@ -203,7 +206,7 @@ public class LocationAllocationServiceImpl implements LocationAllocationService |
203 | 206 | */ |
204 | 207 | @Override |
205 | 208 | @Transactional(rollbackFor = Exception.class) |
206 | - public String doubleRk(String area, String roadWay, int high, Integer frequencyLocation, Integer emptyContainerTask, Integer isSelfCreated, boolean isFlammable) { | |
209 | + public String doubleRk(String area, String roadWay, int high, Integer frequencyLocation, Integer emptyContainerTask, boolean isFlammable) { | |
207 | 210 | // 获取双伸位预留库位数 |
208 | 211 | int reserveNumber = getReserveNumber(); |
209 | 212 | // 移除掉可用库位数小于预留库位数的巷道 |
... | ... | @@ -214,6 +217,7 @@ public class LocationAllocationServiceImpl implements LocationAllocationService |
214 | 217 | .eq(Location::getHigh, high) |
215 | 218 | .eq(Location::getContainerCode, "") |
216 | 219 | .orderByAsc(Location::getILayer) |
220 | + .eq(Location::getSelfCreated, NOTSELFCREATED) | |
217 | 221 | .last(" limit 20"); |
218 | 222 | |
219 | 223 | // emptyContainerTask=1表示是空托盘任务 |
... | ... | @@ -224,14 +228,6 @@ public class LocationAllocationServiceImpl implements LocationAllocationService |
224 | 228 | } else { |
225 | 229 | wrapper.eq(Location::getOnlyEmptyContainer, 0); |
226 | 230 | } |
227 | - | |
228 | - //自建单据 | |
229 | - if (isSelfCreated == 1) { | |
230 | - wrapper.eq(Location::getSelfCreated, 1); | |
231 | - } else { | |
232 | - wrapper.eq(Location::getSelfCreated, 0); | |
233 | - } | |
234 | - | |
235 | 231 | List<Location> totalLocationList = locationService.list(wrapper); |
236 | 232 | //双伸位预留库位数不够了就排除掉该巷道 |
237 | 233 | if (totalLocationList.size() <= reserveNumber) { |
... | ... | @@ -246,6 +242,7 @@ public class LocationAllocationServiceImpl implements LocationAllocationService |
246 | 242 | .eq(Location::getHigh, high) |
247 | 243 | .eq(Location::getRowFlag, ROW_OUT)//外侧 |
248 | 244 | .eq(Location::getContainerCode, "") |
245 | + .eq(Location::getSelfCreated, NOTSELFCREATED) | |
249 | 246 | .last(" limit 20"); |
250 | 247 | |
251 | 248 | //空托盘 |
... | ... | @@ -255,14 +252,6 @@ public class LocationAllocationServiceImpl implements LocationAllocationService |
255 | 252 | } else { |
256 | 253 | locationLambda.eq(Location::getOnlyEmptyContainer, 0); |
257 | 254 | } |
258 | - | |
259 | - //自建单据 | |
260 | - if (isSelfCreated == 1) { | |
261 | - locationLambda.eq(Location::getSelfCreated, 1); | |
262 | - } else { | |
263 | - locationLambda.eq(Location::getSelfCreated, 0); | |
264 | - } | |
265 | - | |
266 | 255 | //频繁库位 |
267 | 256 | String str; |
268 | 257 | if (frequencyLocation == 1) { |
... | ... | @@ -284,7 +273,7 @@ public class LocationAllocationServiceImpl implements LocationAllocationService |
284 | 273 | if (isFlammable) { |
285 | 274 | locationLambda.orderByAsc(Location::getILayer); |
286 | 275 | } else { |
287 | - locationLambda.last("ORDER BY " + str + ", (CASE WHEN iLayer > 2 THEN iLayer ELSE iLayer + 10 END) ASC"); | |
276 | + locationLambda.last("ORDER BY " + str + ", (CASE WHEN iLayer > 2 THEN iLayer ELSE iLayer + 20 END) ASC"); | |
288 | 277 | } |
289 | 278 | } |
290 | 279 | |
... | ... | @@ -312,6 +301,7 @@ public class LocationAllocationServiceImpl implements LocationAllocationService |
312 | 301 | .eq(Location::getHigh, high) |
313 | 302 | .eq(Location::getRowFlag, ROW_IN) |
314 | 303 | .eq(Location::getContainerCode, "") |
304 | + .eq(Location::getSelfCreated, NOTSELFCREATED) | |
315 | 305 | .last(" limit 20"); |
316 | 306 | |
317 | 307 | if (emptyContainerTask == 1) { |
... | ... | @@ -321,12 +311,6 @@ public class LocationAllocationServiceImpl implements LocationAllocationService |
321 | 311 | locationLambda.eq(Location::getOnlyEmptyContainer, 0); |
322 | 312 | } |
323 | 313 | |
324 | - if (isSelfCreated == 1) { | |
325 | - locationLambda.eq(Location::getSelfCreated, 1); | |
326 | - } else { | |
327 | - locationLambda.eq(Location::getSelfCreated, 0); | |
328 | - } | |
329 | - | |
330 | 314 | //频繁库位 |
331 | 315 | //if (frequencyLocation == 1) { |
332 | 316 | // locationLambda.orderByAsc(Location::getFrequencyLocation); //升序 |
... | ... | @@ -343,7 +327,7 @@ public class LocationAllocationServiceImpl implements LocationAllocationService |
343 | 327 | if (isFlammable) { |
344 | 328 | locationLambda.orderByAsc(Location::getILayer); |
345 | 329 | } else { |
346 | - locationLambda.last("ORDER BY " + str + ", (CASE WHEN iLayer > 2 THEN iLayer ELSE iLayer + 10 END) ASC"); | |
330 | + locationLambda.last("ORDER BY " + str + ", (CASE WHEN iLayer > 2 THEN iLayer ELSE iLayer + 20 END) ASC"); | |
347 | 331 | } |
348 | 332 | } |
349 | 333 | locationList = locationService.list(locationLambda); |
... | ... | @@ -368,6 +352,113 @@ public class LocationAllocationServiceImpl implements LocationAllocationService |
368 | 352 | return location.getCode(); |
369 | 353 | } |
370 | 354 | |
355 | + //自建单据 | |
356 | + @Override | |
357 | + public String isSelfCreated(String roadWay, int high, Integer frequencyLocation, boolean isFlammable) { | |
358 | + // 获取双伸位预留库位数 | |
359 | + int reserveNumber = getReserveNumber(); | |
360 | + // 移除掉可用库位数小于预留库位数的巷道 | |
361 | + LambdaQueryWrapper<Location> wrapper = Wrappers.lambdaQuery(); | |
362 | + wrapper.eq(Location::getArea, AREA) | |
363 | + .eq(Location::getRoadway, roadWay) | |
364 | + .eq(Location::getStatus, STATUS_LOCATION_EMPTY) | |
365 | + .eq(Location::getHigh, high) | |
366 | + .eq(Location::getSelfCreated, SELFCREATED) | |
367 | + .eq(Location::getContainerCode, "") | |
368 | + .orderByAsc(Location::getILayer) | |
369 | + .last(" limit 20"); | |
370 | + | |
371 | + List<Location> totalLocationList = locationService.list(wrapper); | |
372 | + //双伸位预留库位数不够了就排除掉该巷道 | |
373 | + if (totalLocationList.size() <= reserveNumber) { | |
374 | + return "可能是自建单据库位不够用了,请检查预留库位数"; | |
375 | + } | |
376 | + | |
377 | + // 查找外侧的库位 | |
378 | + LambdaQueryWrapper<Location> locationLambda = Wrappers.lambdaQuery(); | |
379 | + locationLambda.eq(Location::getArea, AREA) | |
380 | + .eq(Location::getRoadway, roadWay) | |
381 | + .eq(Location::getStatus, STATUS_LOCATION_EMPTY) | |
382 | + .eq(Location::getHigh, high) | |
383 | + .eq(Location::getSelfCreated, SELFCREATED) | |
384 | + .eq(Location::getRowFlag, ROW_OUT)//外侧 | |
385 | + .eq(Location::getContainerCode, "") | |
386 | + .last(" limit 20"); | |
387 | + | |
388 | + //频繁库位 | |
389 | + String str; | |
390 | + if (frequencyLocation == 1) { | |
391 | + str = "frequencyLocation asc"; | |
392 | + } else if (frequencyLocation == 2) { | |
393 | + //常用 | |
394 | + locationLambda.ge(Location::getFrequencyLocation, 2);//大于等于2 | |
395 | + str = "frequencyLocation asc"; | |
396 | + } else { | |
397 | + //不常用 | |
398 | + str = "frequencyLocation desc"; | |
399 | + } | |
400 | + | |
401 | + //可燃物料 | |
402 | + if (isFlammable) { | |
403 | + locationLambda.orderByAsc(Location::getILayer); | |
404 | + } else { | |
405 | + locationLambda.last("ORDER BY " + str + ", (CASE WHEN iLayer > 2 THEN iLayer ELSE iLayer + 20 END) ASC"); | |
406 | + } | |
407 | + | |
408 | + | |
409 | + List<Location> locationList = locationService.list(locationLambda); | |
410 | + List<Location> removeLocaationList = new ArrayList<>(); | |
411 | + if (locationList != null && !locationList.isEmpty()) { | |
412 | + for (Location location1 : locationList) { | |
413 | + //库位内侧,有未完成的任务就去掉这个库位 | |
414 | + if (taskHeaderService.getUncompleteTaskInNear(location1) > 0) { | |
415 | + removeLocaationList.add(location1); | |
416 | + } | |
417 | + } | |
418 | + } | |
419 | + if (locationList != null) { | |
420 | + locationList.removeAll(removeLocaationList); | |
421 | + } | |
422 | + | |
423 | + // 如果没有外侧库位可分配了,再查内侧的库位 | |
424 | + if (locationList == null || locationList.isEmpty()) { | |
425 | + locationLambda = Wrappers.lambdaQuery(); | |
426 | + locationLambda.eq(Location::getArea, AREA) | |
427 | + .eq(StringUtils.isNotEmpty(roadWay), Location::getRoadway, roadWay) | |
428 | + .eq(Location::getStatus, STATUS_LOCATION_EMPTY) | |
429 | + .eq(Location::getHigh, high) | |
430 | + .eq(Location::getSelfCreated, SELFCREATED) | |
431 | + .eq(Location::getRowFlag, ROW_IN) | |
432 | + .eq(Location::getContainerCode, "") | |
433 | + .last(" limit 20"); | |
434 | + | |
435 | + //可燃物料(空托盘不用进来判断) | |
436 | + if (isFlammable) { | |
437 | + locationLambda.orderByAsc(Location::getILayer); | |
438 | + } else { | |
439 | + locationLambda.last("ORDER BY " + str + ", (CASE WHEN iLayer > 2 THEN iLayer ELSE iLayer + 20 END) ASC"); | |
440 | + } | |
441 | + locationList = locationService.list(locationLambda); | |
442 | + | |
443 | + removeLocaationList = new ArrayList<>(); | |
444 | + if (locationList != null && !locationList.isEmpty()) { | |
445 | + for (Location location1 : locationList) { | |
446 | + if (taskHeaderService.getUncompleteTaskInNear(location1) > 0) { | |
447 | + removeLocaationList.add(location1); | |
448 | + } | |
449 | + } | |
450 | + } | |
451 | + if (locationList != null) { | |
452 | + locationList.removeAll(removeLocaationList); | |
453 | + } | |
454 | + } | |
455 | + if (locationList == null || locationList.isEmpty()) { | |
456 | + return null; | |
457 | + } | |
458 | + Location location = locationList.stream().findFirst().orElse(null); | |
459 | + return location.getCode(); | |
460 | + } | |
461 | + | |
371 | 462 | |
372 | 463 | //获取双伸位预留库位数 |
373 | 464 | private int getReserveNumber() { |
... | ... | @@ -375,6 +466,13 @@ public class LocationAllocationServiceImpl implements LocationAllocationService |
375 | 466 | return StringUtils.isNotEmpty(value) ? Integer.parseInt(value) : 0; |
376 | 467 | } |
377 | 468 | |
469 | + | |
470 | + //获取5号堆垛机动态分配大小托盘双伸位预留库位数(12个) | |
471 | + private int getDynamicReserveNumber() { | |
472 | + String value = configService.getKey(DYNAMIC_DOUBLE_FORK_RESERVE_LOCATION); | |
473 | + return StringUtils.isNotEmpty(value) ? Integer.parseInt(value) : 0; | |
474 | + } | |
475 | + | |
378 | 476 | /** |
379 | 477 | * 单伸位库位入库分配库位 |
380 | 478 | */ |
... | ... |
src/main/java/com/huaheng/pc/receipt/receiptHeaderHistory/service/ReceiptHeaderHistoryService.java
... | ... | @@ -129,12 +129,6 @@ public class ReceiptHeaderHistoryService extends ServiceImpl<ReceiptHeaderHistor |
129 | 129 | String createdBy = receiptHeader.getCreatedBy(); |
130 | 130 | String lastUpdatedBy = receiptHeader.getLastUpdatedBy(); |
131 | 131 | Date lastUpdated = receiptHeader.getLastUpdated(); |
132 | - | |
133 | - String code = receiptHeader.getCode(); | |
134 | - List<ReceiptHeaderHistory> list = list(new LambdaQueryWrapper<ReceiptHeaderHistory>().eq(ReceiptHeaderHistory::getCode, code)); | |
135 | - if (!list.isEmpty()) { | |
136 | - return; | |
137 | - } | |
138 | 132 | ReceiptHeaderHistory receiptHeaderHistory = new ReceiptHeaderHistory(); |
139 | 133 | BeanUtils.copyProperties(receiptHeader, receiptHeaderHistory); |
140 | 134 | if (StringUtils.isNotEmpty(name) && "回传".equals(name)) { |
... | ... |
src/main/java/com/huaheng/pc/shipment/shipmentHeaderHistory/service/ShipmentHeaderHistoryServiceImpl.java
... | ... | @@ -53,13 +53,6 @@ public class ShipmentHeaderHistoryServiceImpl extends ServiceImpl<ShipmentHeader |
53 | 53 | String createdBy = shipmentHeader.getCreatedBy(); |
54 | 54 | String lastUpdatedBy = shipmentHeader.getLastUpdatedBy(); |
55 | 55 | Date lastUpdated = shipmentHeader.getLastUpdated(); |
56 | - | |
57 | - String code = shipmentHeader.getCode(); | |
58 | - List<ShipmentHeaderHistory> list = list(new LambdaQueryWrapper<ShipmentHeaderHistory>().eq(ShipmentHeaderHistory::getCode, code)); | |
59 | - if (!list.isEmpty()) { | |
60 | - return; | |
61 | - } | |
62 | - | |
63 | 56 | ShipmentHeaderHistory shipmentHeaderHistory = new ShipmentHeaderHistory(); |
64 | 57 | |
65 | 58 | BeanUtils.copyProperties(shipmentHeader, shipmentHeaderHistory); |
... | ... |