Commit e9aaf4bebb9dba795b735e953f2c63a076427fdc

Authored by 易文鹏
1 parent 05b47ece

feat: 自建单据-单据给一个分配库位逻辑

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&lt;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&lt;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);
... ...