Commit e5229a67805aaf01af7d70042c4b2fe2dfd8d2da
1 parent
4806bbb2
feat:优化自动出库
Showing
14 changed files
with
253 additions
and
179 deletions
src/main/java/com/huaheng/api/wcs/controller/ArrivedNoticeController.java
... | ... | @@ -42,10 +42,10 @@ public class ArrivedNoticeController extends BaseController { |
42 | 42 | |
43 | 43 | @PostMapping("/arrivedNotice") |
44 | 44 | @ApiOperation("到达拣选台") |
45 | - @ApiLogger(apiName = "wcs到达拣选台", from="ROBOT") | |
45 | + @ApiLogger(apiName = "wcs到达拣选台", from = "ROBOT") | |
46 | 46 | @Transactional(rollbackFor = Exception.class) |
47 | 47 | @ResponseBody |
48 | - public AjaxResult arrivedNotice(@RequestBody Map<String,String> map) { | |
48 | + public AjaxResult arrivedNotice(@RequestBody Map<String, String> map) { | |
49 | 49 | //String warehouseCode = "CS0001"; |
50 | 50 | String taskNo = map.get("taskNo"); |
51 | 51 | //String port = map.get("port"); |
... | ... | @@ -54,18 +54,17 @@ public class ArrivedNoticeController extends BaseController { |
54 | 54 | LambdaQueryWrapper<TaskHeader> taskHeaderLambdaQueryWrapper = Wrappers.lambdaQuery(); |
55 | 55 | taskHeaderLambdaQueryWrapper.eq(TaskHeader::getId, taskNo); |
56 | 56 | TaskHeader taskHeader = taskHeaderService.getOne(taskHeaderLambdaQueryWrapper); |
57 | - if(taskHeader != null) { | |
57 | + if (taskHeader != null) { | |
58 | + int status = taskHeader.getStatus(); | |
59 | + if (status == QuantityConstant.TASK_STATUS_COMPLETED) { | |
60 | + return AjaxResult.success("更新到达站台成功, 任务已经完成,不要重复更新"); | |
61 | + } | |
58 | 62 | taskHeader.setStatus(QuantityConstant.TASK_STATUS_ARRIVED_STATION); |
59 | 63 | } else { |
60 | 64 | return AjaxResult.error("没有找到任务taskNo:" + taskNo); |
61 | 65 | } |
62 | - //int taskType = taskHeader.getTaskType(); | |
63 | - int status = taskHeader.getStatus(); | |
64 | - if(status == QuantityConstant.TASK_STATUS_COMPLETED) { | |
65 | - return AjaxResult.success("更新到达站台成功, 任务已经完成"); | |
66 | - } | |
67 | 66 | boolean result = taskHeaderService.updateById(taskHeader); |
68 | - if(!result) { | |
67 | + if (!result) { | |
69 | 68 | return AjaxResult.error("更新到达站台失败"); |
70 | 69 | } |
71 | 70 | return AjaxResult.success("更新到达站台成功"); |
... | ... |
src/main/java/com/huaheng/pc/inventory/inventoryDetail/service/InventoryDetailService.java
... | ... | @@ -48,6 +48,8 @@ public interface InventoryDetailService extends IService<InventoryDetail> { |
48 | 48 | * @return |
49 | 49 | */ |
50 | 50 | List<InventoryDetail> queryReceiptDetailById(Integer inventoryHeaderId); |
51 | + | |
52 | + InventoryDetail getByIdForUpdate(Integer toInventoryId); | |
51 | 53 | } |
52 | 54 | |
53 | 55 | |
... | ... |
src/main/java/com/huaheng/pc/inventory/inventoryDetail/service/InventoryDetailServiceImpl.java
... | ... | @@ -286,6 +286,14 @@ public class InventoryDetailServiceImpl extends ServiceImpl<InventoryDetailMappe |
286 | 286 | return this.list(lam); |
287 | 287 | } |
288 | 288 | |
289 | + @Override | |
290 | + public InventoryDetail getByIdForUpdate(Integer toInventoryId) { | |
291 | + LambdaQueryWrapper<InventoryDetail> queryWrapper = new LambdaQueryWrapper<>(); | |
292 | + return inventoryDetailMapper.selectOne(queryWrapper | |
293 | + .eq(InventoryDetail::getId, toInventoryId) | |
294 | + .last("FOR UPDATE")); | |
295 | + } | |
296 | + | |
289 | 297 | } |
290 | 298 | |
291 | 299 | |
... | ... |
src/main/java/com/huaheng/pc/inventory/inventoryHeader/service/InventoryHeaderService.java
... | ... | @@ -63,7 +63,7 @@ public interface InventoryHeaderService extends IService<InventoryHeader> { |
63 | 63 | */ |
64 | 64 | AjaxResult getLocationForecast(String code, int type); |
65 | 65 | |
66 | - AjaxResult organizationalTransfers(String materialCode, BigDecimal qty, String beforeCompanyCode, String endCompanyCode); | |
66 | + //AjaxResult organizationalTransfers(String materialCode, BigDecimal qty, String beforeCompanyCode, String endCompanyCode); | |
67 | 67 | |
68 | 68 | //判断任务 |
69 | 69 | boolean getUncompleteReceiptTask(String locationCode); |
... | ... | @@ -87,6 +87,8 @@ public interface InventoryHeaderService extends IService<InventoryHeader> { |
87 | 87 | List<Integer> findInventoryHeaderIdsByMaterialCode(String materialCode); |
88 | 88 | |
89 | 89 | List<InventoryHeaderVO> inventoryToDto(List<InventoryHeader> originList); |
90 | + | |
91 | + InventoryHeader getByIdForUpdate(Integer inventoryHeaderId); | |
90 | 92 | } |
91 | 93 | |
92 | 94 | |
... | ... |
src/main/java/com/huaheng/pc/inventory/inventoryHeader/service/InventoryHeaderServiceImpl.java
... | ... | @@ -35,6 +35,7 @@ import com.huaheng.pc.config.warehouse.domain.Warehouse; |
35 | 35 | import com.huaheng.pc.config.zone.domain.Zone; |
36 | 36 | import com.huaheng.pc.config.zone.service.ZoneService; |
37 | 37 | import com.huaheng.pc.inventory.inventoryDetail.domain.InventoryDetail; |
38 | +import com.huaheng.pc.inventory.inventoryDetail.mapper.InventoryDetailMapper; | |
38 | 39 | import com.huaheng.pc.inventory.inventoryDetail.service.InventoryDetailService; |
39 | 40 | import com.huaheng.pc.inventory.inventoryHeader.domain.InventoryHeader; |
40 | 41 | import com.huaheng.pc.inventory.inventoryHeader.domain.dto.InventoryHeaderVO; |
... | ... | @@ -57,6 +58,7 @@ import lombok.extern.slf4j.Slf4j; |
57 | 58 | import org.apache.commons.collections.CollectionUtils; |
58 | 59 | import org.apache.commons.collections.Transformer; |
59 | 60 | import org.springframework.beans.BeanUtils; |
61 | +import org.springframework.beans.factory.annotation.Autowired; | |
60 | 62 | import org.springframework.stereotype.Service; |
61 | 63 | import org.springframework.transaction.annotation.Transactional; |
62 | 64 | |
... | ... | @@ -113,10 +115,12 @@ public class InventoryHeaderServiceImpl extends ServiceImpl<InventoryHeaderMappe |
113 | 115 | private ShipmentTaskService shipmentTaskService; |
114 | 116 | @Resource |
115 | 117 | private ShipmentHeaderService shipmentHeaderService; |
116 | - | |
118 | + @Autowired | |
119 | + private InventoryDetailMapper inventoryDetailMapper; | |
117 | 120 | @Resource |
118 | 121 | private InventoryHeaderService inventoryHeaderService; |
119 | 122 | |
123 | + | |
120 | 124 | /** |
121 | 125 | * 生成移库任务 |
122 | 126 | */ |
... | ... | @@ -432,60 +436,60 @@ public class InventoryHeaderServiceImpl extends ServiceImpl<InventoryHeaderMappe |
432 | 436 | return AjaxResult.success(inventoryDetailList); |
433 | 437 | } |
434 | 438 | |
435 | - @Override | |
436 | - @Transactional(rollbackFor = Exception.class) | |
437 | - public AjaxResult organizationalTransfers(String materialCode, BigDecimal qty, String beforeCompanyCode, String endCompanyCode) { | |
438 | - /* 查询库存*/ | |
439 | - LambdaQueryWrapper<InventoryDetail> detailLambdaQueryWrapper = Wrappers.lambdaQuery(); | |
440 | - detailLambdaQueryWrapper.eq(InventoryDetail::getMaterialCode, materialCode) | |
441 | - .eq(InventoryDetail::getCompanyCode, beforeCompanyCode); | |
442 | - List<InventoryDetail> detailList = inventoryDetailService.list(detailLambdaQueryWrapper); | |
443 | - | |
444 | - /* 计算该物料总数量*/ | |
445 | - BigDecimal totalQty = new BigDecimal(0); | |
446 | - for (InventoryDetail inventoryDetail : detailList) { | |
447 | - totalQty = totalQty.add(inventoryDetail.getQty()); | |
448 | - } | |
449 | - | |
450 | - if (totalQty.compareTo(qty) < 1) { | |
451 | - return AjaxResult.error("库存数量不足"); | |
452 | - } else { | |
453 | - /** | |
454 | - * 遍历库存,当数量大于0时,执行调拨 | |
455 | - * 库存单条记录数量小于调拨数量时,copy实体修改新实体货主编码 添加新库存记录删除原库存、调拨数量减去记录数量 | |
456 | - * 库存单条记录数量等于调拨数量时,copy实体修改新实体货主编码 添加新库存记录删除原库存、调拨数量减去记录数量 | |
457 | - * 库存单条记录数量大于调拨数量时,copy实体修改新实体货主编码 库存数量,原实体数量更新,更新两个实体 | |
458 | - */ | |
459 | - for (InventoryDetail inventoryDetail : detailList) { | |
460 | - if (qty.compareTo(new BigDecimal(0)) == 1) { | |
461 | - if (inventoryDetail.getQty().compareTo(qty) == 1) { | |
462 | - InventoryDetail inventoryDetail1 = inventoryDetail; | |
463 | - inventoryDetail1.setId(null); | |
464 | - inventoryDetail1.setCompanyCode(endCompanyCode); | |
465 | - qty = qty.subtract(inventoryDetail.getQty()); | |
466 | - inventoryDetailService.removeById(inventoryDetail.getId()); | |
467 | - inventoryDetailService.save(inventoryDetail1); | |
468 | - } else if (inventoryDetail.getQty().compareTo(qty) == 0) { | |
469 | - InventoryDetail inventoryDetail1 = inventoryDetail; | |
470 | - inventoryDetail1.setId(null); | |
471 | - inventoryDetail1.setCompanyCode(endCompanyCode); | |
472 | - qty = qty.subtract(inventoryDetail.getQty()); | |
473 | - inventoryDetailService.removeById(inventoryDetail.getId()); | |
474 | - inventoryDetailService.save(inventoryDetail1); | |
475 | - } else if (inventoryDetail.getQty().compareTo(qty) == -1) { | |
476 | - InventoryDetail inventoryDetail1 = inventoryDetail; | |
477 | - inventoryDetail1.setQty(qty); | |
478 | - inventoryDetail1.setCompanyCode(endCompanyCode); | |
479 | - inventoryDetail1.setId(null); | |
480 | - inventoryDetail.setQty(inventoryDetail.getQty().subtract(qty)); | |
481 | - inventoryDetailService.updateById(inventoryDetail); | |
482 | - inventoryDetailService.save(inventoryDetail1); | |
483 | - } | |
484 | - } | |
485 | - } | |
486 | - } | |
487 | - return AjaxResult.success(""); | |
488 | - } | |
439 | + //@Override | |
440 | + //@Transactional(rollbackFor = Exception.class) | |
441 | + //public AjaxResult organizationalTransfers(String materialCode, BigDecimal qty, String beforeCompanyCode, String endCompanyCode) { | |
442 | + // /* 查询库存*/ | |
443 | + // LambdaQueryWrapper<InventoryDetail> detailLambdaQueryWrapper = Wrappers.lambdaQuery(); | |
444 | + // detailLambdaQueryWrapper.eq(InventoryDetail::getMaterialCode, materialCode) | |
445 | + // .eq(InventoryDetail::getCompanyCode, beforeCompanyCode); | |
446 | + // List<InventoryDetail> detailList = inventoryDetailService.list(detailLambdaQueryWrapper); | |
447 | + // | |
448 | + // /* 计算该物料总数量*/ | |
449 | + // BigDecimal totalQty = new BigDecimal(0); | |
450 | + // for (InventoryDetail inventoryDetail : detailList) { | |
451 | + // totalQty = totalQty.add(inventoryDetail.getQty()); | |
452 | + // } | |
453 | + // | |
454 | + // if (totalQty.compareTo(qty) < 1) { | |
455 | + // return AjaxResult.error("库存数量不足"); | |
456 | + // } else { | |
457 | + // /** | |
458 | + // * 遍历库存,当数量大于0时,执行调拨 | |
459 | + // * 库存单条记录数量小于调拨数量时,copy实体修改新实体货主编码 添加新库存记录删除原库存、调拨数量减去记录数量 | |
460 | + // * 库存单条记录数量等于调拨数量时,copy实体修改新实体货主编码 添加新库存记录删除原库存、调拨数量减去记录数量 | |
461 | + // * 库存单条记录数量大于调拨数量时,copy实体修改新实体货主编码 库存数量,原实体数量更新,更新两个实体 | |
462 | + // */ | |
463 | + // for (InventoryDetail inventoryDetail : detailList) { | |
464 | + // if (qty.compareTo(new BigDecimal(0)) == 1) { | |
465 | + // if (inventoryDetail.getQty().compareTo(qty) == 1) { | |
466 | + // InventoryDetail inventoryDetail1 = inventoryDetail; | |
467 | + // inventoryDetail1.setId(null); | |
468 | + // inventoryDetail1.setCompanyCode(endCompanyCode); | |
469 | + // qty = qty.subtract(inventoryDetail.getQty()); | |
470 | + // inventoryDetailService.removeById(inventoryDetail.getId()); | |
471 | + // inventoryDetailService.save(inventoryDetail1); | |
472 | + // } else if (inventoryDetail.getQty().compareTo(qty) == 0) { | |
473 | + // InventoryDetail inventoryDetail1 = inventoryDetail; | |
474 | + // inventoryDetail1.setId(null); | |
475 | + // inventoryDetail1.setCompanyCode(endCompanyCode); | |
476 | + // qty = qty.subtract(inventoryDetail.getQty()); | |
477 | + // inventoryDetailService.removeById(inventoryDetail.getId()); | |
478 | + // inventoryDetailService.save(inventoryDetail1); | |
479 | + // } else if (inventoryDetail.getQty().compareTo(qty) == -1) { | |
480 | + // InventoryDetail inventoryDetail1 = inventoryDetail; | |
481 | + // inventoryDetail1.setQty(qty); | |
482 | + // inventoryDetail1.setCompanyCode(endCompanyCode); | |
483 | + // inventoryDetail1.setId(null); | |
484 | + // inventoryDetail.setQty(inventoryDetail.getQty().subtract(qty)); | |
485 | + // inventoryDetailService.updateById(inventoryDetail); | |
486 | + // inventoryDetailService.save(inventoryDetail1); | |
487 | + // } | |
488 | + // } | |
489 | + // } | |
490 | + // } | |
491 | + // return AjaxResult.success(""); | |
492 | + //} | |
489 | 493 | |
490 | 494 | @Override |
491 | 495 | public boolean getUncompleteReceiptTask(String locationCode) { |
... | ... | @@ -826,6 +830,15 @@ public class InventoryHeaderServiceImpl extends ServiceImpl<InventoryHeaderMappe |
826 | 830 | .collect(Collectors.toList()); |
827 | 831 | } |
828 | 832 | |
833 | + @Override | |
834 | + public InventoryHeader getByIdForUpdate(Integer inventoryHeaderId) { | |
835 | + LambdaQueryWrapper<InventoryHeader> queryWrapper = new LambdaQueryWrapper<>(); | |
836 | + return inventoryHeaderMapper.selectOne(queryWrapper | |
837 | + .eq(InventoryHeader::getId, inventoryHeaderId) | |
838 | + .last("FOR UPDATE")); | |
839 | + | |
840 | + } | |
841 | + | |
829 | 842 | /** |
830 | 843 | * 找到库存对应所有的入库单 |
831 | 844 | * |
... | ... |
src/main/java/com/huaheng/pc/monitor/job/task/RyTask.java
... | ... | @@ -183,7 +183,7 @@ public class RyTask extends BaseController { |
183 | 183 | //如果上一条出库单未完成,就不执行下一条 |
184 | 184 | ShipmentHeader header = shipmentHeaderService.getOne(new LambdaQueryWrapper<ShipmentHeader>() |
185 | 185 | .eq(ShipmentHeader::getDeleted, 0) |
186 | - .in(ShipmentHeader::getAutoShipmentStatus, 2)//已自动出库 | |
186 | + .in(ShipmentHeader::getAutoShipmentStatus, 2, 3) | |
187 | 187 | .last("ORDER BY requestedStartDate asc,id asc limit 1")); |
188 | 188 | if (header != null) { |
189 | 189 | if (header.getLastStatus() < QuantityConstant.SHIPMENT_HEADER_COMPLETED) {//尾状态小于拣货完成(出库单未完成),就不继续走了 |
... | ... | @@ -781,8 +781,9 @@ public class RyTask extends BaseController { |
781 | 781 | } |
782 | 782 | |
783 | 783 | |
784 | - //每天计算呆滞库存 | |
784 | + @Transactional(rollbackFor = Exception.class) | |
785 | 785 | public void expiringInventoryHandle() { |
786 | + // 获取库存信息 | |
786 | 787 | List<InventoryDetail> inventoryDetails = inventoryDetailService.list(); |
787 | 788 | if (CollectionUtils.isEmpty(inventoryDetails)) { |
788 | 789 | return; |
... | ... | @@ -796,49 +797,49 @@ public class RyTask extends BaseController { |
796 | 797 | // 获取所有物料编码 |
797 | 798 | Set<String> materialCodes = inventoryDetails.stream() |
798 | 799 | .map(InventoryDetail::getMaterialCode).collect(Collectors.toSet()); |
799 | - | |
800 | 800 | List<Material> materials = materialService.list(new LambdaQueryWrapper<Material>().in(Material::getCode, materialCodes)); |
801 | 801 | |
802 | 802 | // 创建物料编码和物料对象的映射关系 |
803 | - Map<String, Material> materialMap = new HashMap<>(); | |
804 | - for (Material material : materials) { | |
805 | - materialMap.put(material.getCode(), material); | |
806 | - } | |
803 | + Map<String, Material> materialMap = materials.stream() | |
804 | + .collect(Collectors.toMap(Material::getCode, material -> material)); | |
807 | 805 | |
808 | - List<InventoryDetail> updatedInventoryDetails = inventoryDetails.stream() | |
809 | - .map(inventoryDetail -> { | |
810 | - // 计算库存的更新时间和当前时间之间的差距 | |
811 | - long difference = DateUtils.difference(DateUtils.getNowDate(), inventoryDetail.getRealUpdated()); | |
806 | + for (InventoryDetail inventoryDetail : inventoryDetails) { | |
807 | + // 计算库存的更新时间和当前时间之间的差距 | |
808 | + long difference = DateUtils.difference(DateUtils.getNowDate(), inventoryDetail.getRealUpdated()); | |
812 | 809 | |
813 | - // 从 Map 中获取物料信息 | |
814 | - Material material = materialMap.get(inventoryDetail.getMaterialCode()); | |
815 | - if (material == null) { | |
816 | - return inventoryDetail; | |
817 | - } | |
810 | + // 从 Map 中获取物料信息 | |
811 | + Material material = materialMap.get(inventoryDetail.getMaterialCode()); | |
812 | + if (material == null) { | |
813 | + continue; | |
814 | + } | |
818 | 815 | |
819 | - int materialDays = days; | |
820 | - if (Objects.equals(material.getIsFlammable(), "是")) { | |
821 | - materialDays = Math.min(materialDays, daysFlammable); | |
822 | - } else if (Objects.equals(material.getIsBatch(), "是")) { | |
823 | - materialDays = Math.min(materialDays, daysBatch); | |
824 | - } | |
816 | + int materialDays = days; | |
817 | + if (Objects.equals(material.getIsFlammable(), "是")) { | |
818 | + materialDays = Math.min(materialDays, daysFlammable); | |
819 | + } else if (Objects.equals(material.getIsBatch(), "是")) { | |
820 | + materialDays = Math.min(materialDays, daysBatch); | |
821 | + } | |
825 | 822 | |
826 | - // 计算呆滞时长 | |
827 | - int differenceDay = DateUtils.secondToDays(difference); | |
828 | - int deadTime = Math.max(differenceDay - materialDays, 0); | |
829 | - if (deadTime == 0) { | |
830 | - inventoryDetail.setDeadTime(""); | |
831 | - } else { | |
832 | - inventoryDetail.setDeadTime(deadTime + "天"); | |
833 | - } | |
823 | + // 计算呆滞时长 | |
824 | + int differenceDay = DateUtils.secondToDays(difference); | |
825 | + int deadTime = Math.max(differenceDay - materialDays, 0); | |
834 | 826 | |
835 | - return inventoryDetail; | |
836 | - }) | |
837 | - .collect(Collectors.toList()); | |
827 | + if (deadTime == 0 && !inventoryDetail.getDeadTime().isEmpty()) { | |
828 | + LambdaUpdateWrapper<InventoryDetail> updateWrapper = Wrappers.lambdaUpdate(); | |
829 | + updateWrapper | |
830 | + .eq(InventoryDetail::getId, inventoryDetail.getId()) | |
831 | + .set(InventoryDetail::getDeadTime, ""); | |
832 | + inventoryDetailService.update(updateWrapper); | |
833 | + } | |
838 | 834 | |
839 | - // 保存更新后的库存信息 | |
840 | - inventoryDetailService.updateBatchById(updatedInventoryDetails); | |
835 | + if (deadTime > 0) { | |
836 | + LambdaUpdateWrapper<InventoryDetail> updateWrapper = Wrappers.lambdaUpdate(); | |
837 | + updateWrapper | |
838 | + .eq(InventoryDetail::getId, inventoryDetail.getId()) | |
839 | + .set(InventoryDetail::getDeadTime, deadTime + "天"); | |
840 | + inventoryDetailService.update(updateWrapper); | |
841 | + } | |
842 | + } | |
841 | 843 | } |
842 | 844 | |
843 | - | |
844 | 845 | } |
... | ... |
src/main/java/com/huaheng/pc/shipment/shipmentContainerHeader/service/ShipmentContainerHeaderServiceImpl.java
... | ... | @@ -55,6 +55,8 @@ import com.huaheng.pc.shipment.shipmentContainerHeader.domain.ShipmentContainerH |
55 | 55 | import com.huaheng.pc.shipment.shipmentContainerHeader.mapper.ShipmentContainerHeaderMapper; |
56 | 56 | import org.springframework.transaction.annotation.Transactional; |
57 | 57 | |
58 | +import static com.huaheng.common.constant.QuantityConstant.*; | |
59 | + | |
58 | 60 | @Service |
59 | 61 | public class ShipmentContainerHeaderServiceImpl extends ServiceImpl<ShipmentContainerHeaderMapper, ShipmentContainerHeader> implements ShipmentContainerHeaderService { |
60 | 62 | |
... | ... | @@ -193,12 +195,15 @@ public class ShipmentContainerHeaderServiceImpl extends ServiceImpl<ShipmentCont |
193 | 195 | } else if (i < 0) { |
194 | 196 | throw new ServiceException("出库数量不能大于单据数量!"); |
195 | 197 | } |
196 | - | |
197 | - //限制组盘数量 | |
198 | - AjaxResult ajaxResult = limitCombinationCount(inventoryDetail); | |
199 | - if (ajaxResult.hasErr()) { | |
200 | - throw new ServiceException(ajaxResult.getMsg()); | |
198 | + //限制立库组盘数量 | |
199 | + if (container.getFlat() == null || container.getFlat() != 1) { | |
200 | + AjaxResult ajaxResult = limitCombinationCount(inventoryDetail); | |
201 | + if (ajaxResult.hasErr()) { | |
202 | + throw new ServiceException(ajaxResult.getMsg()); | |
203 | + } | |
201 | 204 | } |
205 | + | |
206 | + | |
202 | 207 | shipmentDetailService.saveOrUpdate(shipmentDetail); |
203 | 208 | |
204 | 209 | //自动判定出库任务状态,根据库存数量减去预定库存相等就是整盘出--预计任务状态 |
... | ... | @@ -609,17 +614,17 @@ public class ShipmentContainerHeaderServiceImpl extends ServiceImpl<ShipmentCont |
609 | 614 | } |
610 | 615 | inventoryList.removeAll(removeInventoryList); |
611 | 616 | if (inventoryList.isEmpty() && lock) { |
612 | - return AjaxResult.error("'物料名称:" + item.getMaterialName() + ",物料编码:" + item.getMaterialCode() + "' 所在托盘全部处于锁定状态,请完成或取消任务后再进行组盘"); | |
617 | + return AjaxResult.error("'物料名称:" + item.getMaterialName() + ",物料编码:" + item.getMaterialCode() + "' 所在托盘全部处于锁定状态,请完成或取消任务或入库组盘后再进行组盘"); | |
613 | 618 | } |
614 | 619 | |
615 | - if (inventoryList.isEmpty() && item.getWaveId() != 0) { | |
616 | - Wave wave = waveService.getById(item.getWaveId()); | |
617 | - wave.setStatus(QuantityConstant.WAVE_STATUS_ERROR); | |
618 | - wave.setCurrentWaveStep(QuantityConstant.WAVE_STEP_ERROR); | |
619 | - wave.setLastWaveStep(QuantityConstant.WAVE_STEP_BUILD); | |
620 | - waveService.updateById(wave); | |
621 | - throw new ServiceException("主单为" + item.getShipmentCode() + "子单id为" + item.getId() + "的单据没有库存,波次失败"); | |
622 | - } | |
620 | + //if (inventoryList.isEmpty() && item.getWaveId() != 0) { | |
621 | + // Wave wave = waveService.getById(item.getWaveId()); | |
622 | + // wave.setStatus(QuantityConstant.WAVE_STATUS_ERROR); | |
623 | + // wave.setCurrentWaveStep(QuantityConstant.WAVE_STEP_ERROR); | |
624 | + // wave.setLastWaveStep(QuantityConstant.WAVE_STEP_BUILD); | |
625 | + // waveService.updateById(wave); | |
626 | + // throw new ServiceException("主单为" + item.getShipmentCode() + "子单id为" + item.getId() + "的单据没有库存,波次失败"); | |
627 | + //} | |
623 | 628 | if (inventoryList.isEmpty()) { |
624 | 629 | num = num + 1; |
625 | 630 | } else { |
... | ... | @@ -629,12 +634,13 @@ public class ShipmentContainerHeaderServiceImpl extends ServiceImpl<ShipmentCont |
629 | 634 | break; |
630 | 635 | } |
631 | 636 | |
632 | - //限制组盘数量 | |
633 | - AjaxResult ajaxResult = limitCombinationCount(inventory); | |
634 | - if (ajaxResult.hasErr()) { | |
635 | - throw new ServiceException(ajaxResult.getMsg()); | |
637 | + //限制立库组盘数量 | |
638 | + if (inventory.getIsFlatWarehouse() == 0) { | |
639 | + AjaxResult ajaxResult = limitCombinationCount(inventory); | |
640 | + if (ajaxResult.hasErr()) { | |
641 | + throw new ServiceException(ajaxResult.getMsg()); | |
642 | + } | |
636 | 643 | } |
637 | - | |
638 | 644 | BigDecimal inventoryQty = inventory.getQty().subtract(inventory.getTaskQty()); |
639 | 645 | ShipmentCombinationModel shipmentCombination = new ShipmentCombinationModel(); |
640 | 646 | shipmentCombination.setInventoryDetailId(inventory.getId()); |
... | ... | @@ -668,25 +674,52 @@ public class ShipmentContainerHeaderServiceImpl extends ServiceImpl<ShipmentCont |
668 | 674 | // 获取巷道信息 |
669 | 675 | String roadway = location.getRoadway(); |
670 | 676 | |
671 | - // 使用三元运算符根据巷道信息确定限制数量 | |
672 | - int limit = roadway.equals(QuantityConstant.DYNAMIC_ROADWAY) ? | |
673 | - Integer.parseInt(configService.getKey("shipmentTaskBy5RoadLimit")) : | |
674 | - Integer.parseInt(configService.getKey("shipmentContainerTaskLimit")); | |
675 | - | |
676 | - // 使用三元运算符根据巷道信息确定任务数量 | |
677 | - int shipmentTaskCount = roadway.equals(QuantityConstant.DYNAMIC_ROADWAY) ? | |
678 | - taskHeaderService.getShipmentTaskBy5Road() : | |
679 | - taskHeaderService.getShipmentContainerTask(roadway); | |
677 | + LambdaQueryWrapper<Location> wrapper = Wrappers.lambdaQuery(); | |
678 | + wrapper.eq(Location::getRoadway, roadway) | |
679 | + .eq(Location::getStatus, STATUS_LOCATION_EMPTY) | |
680 | + .eq(Location::getHigh, location.getHigh()) | |
681 | + .eq(Location::getContainerCode, "") | |
682 | + .eq(Location::getSelfCreated, NO_TSELFCREATED) | |
683 | + .eq(Location::getOnlyEmptyContainer, NO_EMPTY_CONTAINER_LOCATION); | |
684 | + List<Location> locationList = locationService.list(wrapper); | |
685 | + | |
686 | + if (locationList.size() < 3) { | |
687 | + return AjaxResult.error("该库存出库可能无法回库了"); | |
688 | + } | |
680 | 689 | |
681 | - // 检查任务数量是否超过限制 | |
682 | - if (shipmentTaskCount >= limit) { | |
683 | - // 根据巷道信息拼接错误信息 | |
684 | - String errorMessage = roadway.equals(QuantityConstant.DYNAMIC_ROADWAY) ? | |
685 | - "5号巷道不能存在超过" + limit + "个组盘和任务" : | |
686 | - "不能存在超过" + limit + "个组盘和任务"; | |
687 | - return AjaxResult.error(errorMessage); | |
690 | + List<Location> availableLocations = new ArrayList<>(); | |
691 | + for (Location location1 : locationList) { | |
692 | + // 如果库位内侧没有未完成的任务,则将其添加到可用库位列表中 | |
693 | + if (taskHeaderService.getUncompleteTaskInNear(location1) == 0) { | |
694 | + availableLocations.add(location1); | |
695 | + } | |
696 | + // 如果已经找到了 3 个可用库位,则直接返回成功 | |
697 | + if (availableLocations.size() >= 3) { | |
698 | + return AjaxResult.success(); | |
699 | + } | |
688 | 700 | } |
689 | - return AjaxResult.success(); | |
701 | + | |
702 | + return AjaxResult.error("该库存出库可能无法回库了,可能是空闲库位内/外测有任务了"); | |
703 | + | |
704 | + | |
705 | + //// 使用三元运算符根据巷道信息确定限制数量 | |
706 | + //int limit = roadway.equals(QuantityConstant.DYNAMIC_ROADWAY) ? | |
707 | + // Integer.parseInt(configService.getKey("shipmentTaskBy5RoadLimit")) : | |
708 | + // Integer.parseInt(configService.getKey("shipmentContainerTaskLimit")); | |
709 | + // | |
710 | + //// 使用三元运算符根据巷道信息确定任务数量 | |
711 | + //int shipmentTaskCount = roadway.equals(QuantityConstant.DYNAMIC_ROADWAY) ? | |
712 | + // taskHeaderService.getShipmentTaskBy5Road() : | |
713 | + // taskHeaderService.getShipmentContainerTask(roadway); | |
714 | + // | |
715 | + //// 检查任务数量是否超过限制 | |
716 | + //if (shipmentTaskCount >= limit) { | |
717 | + // // 根据巷道信息拼接错误信息 | |
718 | + // String errorMessage = roadway.equals(QuantityConstant.DYNAMIC_ROADWAY) ? | |
719 | + // "5号巷道不能存在超过" + limit + "个组盘和任务" : | |
720 | + // "不能存在超过" + limit + "个组盘和任务"; | |
721 | + // return AjaxResult.error(errorMessage); | |
722 | + //} | |
690 | 723 | } |
691 | 724 | |
692 | 725 | /** |
... | ... |
src/main/java/com/huaheng/pc/shipment/shipmentHeader/controller/ShipmentHeaderController.java
... | ... | @@ -562,19 +562,19 @@ public class ShipmentHeaderController extends BaseController { |
562 | 562 | return prefix + "/addWave"; |
563 | 563 | } |
564 | 564 | |
565 | - /** | |
566 | - * 查询波次列表 | |
567 | - */ | |
568 | - @RequiresPermissions("shipment:bill:wave") | |
569 | - //@Log(title = "出库-出库单", operating = "查询库区列表", action = BusinessType.GRANT) | |
570 | - @PostMapping("/waveList") | |
571 | - @ResponseBody | |
572 | - public TableDataInfo waveList() { | |
573 | - LambdaQueryWrapper<WaveMaster> lam = Wrappers.lambdaQuery(); | |
574 | - lam.eq(WaveMaster::getWarehouseCode, ShiroUtils.getWarehouseCode()); | |
575 | - List<WaveMaster> waveMasters = waveMasterService.list(lam); | |
576 | - return getDataTable(waveMasters); | |
577 | - } | |
565 | + ///** | |
566 | + // * 查询波次列表 | |
567 | + // */ | |
568 | + //@RequiresPermissions("shipment:bill:wave") | |
569 | + ////@Log(title = "出库-出库单", operating = "查询库区列表", action = BusinessType.GRANT) | |
570 | + //@PostMapping("/waveList") | |
571 | + //@ResponseBody | |
572 | + //public TableDataInfo waveList() { | |
573 | + // LambdaQueryWrapper<WaveMaster> lam = Wrappers.lambdaQuery(); | |
574 | + // lam.eq(WaveMaster::getWarehouseCode, ShiroUtils.getWarehouseCode()); | |
575 | + // List<WaveMaster> waveMasters = waveMasterService.list(lam); | |
576 | + // return getDataTable(waveMasters); | |
577 | + //} | |
578 | 578 | |
579 | 579 | |
580 | 580 | /** |
... | ... |
src/main/java/com/huaheng/pc/shipment/shipmentHeader/service/ShipmentHeaderServiceImpl.java
... | ... | @@ -16,6 +16,8 @@ import com.huaheng.framework.web.domain.AjaxResult; |
16 | 16 | import com.huaheng.framework.web.service.ConfigService; |
17 | 17 | import com.huaheng.pc.config.address.service.AddressService; |
18 | 18 | import com.huaheng.pc.config.company.service.CompanyService; |
19 | +import com.huaheng.pc.config.container.domain.Container; | |
20 | +import com.huaheng.pc.config.container.service.ContainerService; | |
19 | 21 | import com.huaheng.pc.config.customer.domain.Customer; |
20 | 22 | import com.huaheng.pc.config.customer.service.CustomerServiceImpl; |
21 | 23 | import com.huaheng.pc.config.location.domain.Location; |
... | ... | @@ -25,6 +27,8 @@ import com.huaheng.pc.config.shipmentType.service.ShipmentTypeService; |
25 | 27 | import com.huaheng.pc.inventory.inventoryDetail.domain.InventoryDetail; |
26 | 28 | import com.huaheng.pc.inventory.inventoryDetail.service.InventoryDetailService; |
27 | 29 | import com.huaheng.pc.receipt.receiptHeader.domain.ReceiptHeader; |
30 | +import com.huaheng.pc.shipment.shipmentContainerDetail.domain.ShipmentContainerDetail; | |
31 | +import com.huaheng.pc.shipment.shipmentContainerDetail.service.ShipmentContainerDetailService; | |
28 | 32 | import com.huaheng.pc.shipment.shipmentContainerHeader.domain.ShipmentContainerHeader; |
29 | 33 | import com.huaheng.pc.shipment.shipmentContainerHeader.service.ShipmentContainerHeaderService; |
30 | 34 | import com.huaheng.pc.shipment.shipmentDetail.domain.ShipmentDetail; |
... | ... | @@ -62,7 +66,10 @@ import java.util.stream.Collectors; |
62 | 66 | public class ShipmentHeaderServiceImpl extends ServiceImpl<ShipmentHeaderMapper, ShipmentHeader> implements ShipmentHeaderService { |
63 | 67 | @Resource |
64 | 68 | private ShipmentTaskService shipmentTaskService; |
65 | - | |
69 | + @Resource | |
70 | + private ShipmentContainerDetailService shipmentContainerDetailService; | |
71 | + @Resource | |
72 | + private ContainerService containerService; | |
66 | 73 | @Resource |
67 | 74 | private ConfigService configService; |
68 | 75 | @Resource |
... | ... | @@ -573,20 +580,19 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl<ShipmentHeaderMapper, |
573 | 580 | |
574 | 581 | @Override |
575 | 582 | public void autoShipmentExecute(ShipmentHeader shipmentHeader) { |
576 | - shipmentHeader.setAutoShipmentStatus(4); | |
583 | + shipmentHeader.setAutoShipmentStatus(3); | |
577 | 584 | shipmentHeader.setErrorMsg("自动组盘过程中程序错误,请手动组盘"); |
578 | 585 | updateById(shipmentHeader); |
579 | 586 | //自动组盘 |
580 | 587 | AjaxResult containerResult = shipmentContainerHeaderService.autoCombination(shipmentHeader.getCode(), true); |
581 | - //如果出库单明细全部为出库组盘,就不改状态了,找一些其他地方是不是也修改了,这个修改了应该就直接返回了呀,为什么还完成了单据呢 | |
582 | 588 | if (!updateShipmentErrorMsg(containerResult, shipmentHeader)) { |
583 | 589 | return; |
584 | 590 | } |
585 | - shipmentHeader.setAutoShipmentStatus(4); | |
591 | + | |
592 | + //生成任务 | |
593 | + shipmentHeader.setAutoShipmentStatus(3); | |
586 | 594 | shipmentHeader.setErrorMsg("自生成任务过程中程序错误,请手动生成任务"); |
587 | 595 | updateById(shipmentHeader); |
588 | - | |
589 | - | |
590 | 596 | List<ShipmentContainerHeader> shipmentContainerHeaders = shipmentContainerHeaderService.list(new LambdaQueryWrapper<ShipmentContainerHeader>() |
591 | 597 | .eq(ShipmentContainerHeader::getStatus, QuantityConstant.SHIPMENT_CONTAINER_BUILD)); |
592 | 598 | for (ShipmentContainerHeader item : shipmentContainerHeaders) { |
... | ... | @@ -598,21 +604,20 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl<ShipmentHeaderMapper, |
598 | 604 | } |
599 | 605 | } |
600 | 606 | |
601 | - //生成任务 | |
602 | 607 | //List<Integer> ids = (List<Integer>) containerResult.getData(); |
603 | 608 | //AjaxResult taskResult = shipmentContainerHeaderService.createAutoTask(ids); |
604 | 609 | //if (!updateShipmentErrorMsg(taskResult, shipmentHeader)) { |
605 | 610 | // return; |
606 | 611 | //} |
607 | - | |
612 | + | |
608 | 613 | //自动打印 |
609 | 614 | int isPrint = Integer.parseInt(configService.getKey(QuantityConstant.AUTO_SHIPMENT_PRINT)); |
610 | 615 | if (isPrint == 1) { |
611 | - shipmentHeader.setAutoShipmentStatus(4); | |
616 | + shipmentHeader.setAutoShipmentStatus(3); | |
612 | 617 | shipmentHeader.setErrorMsg("自动打印过程中程序错误,请手动打印"); |
613 | 618 | updateById(shipmentHeader); |
614 | 619 | AjaxResult reportResult = shipmentHeaderService.autoReportShipment(-1, shipmentHeader.getCode(), "1"); |
615 | - if (updateShipmentErrorMsg(reportResult, shipmentHeader)) { | |
620 | + if (!updateShipmentErrorMsg(reportResult, shipmentHeader)) { | |
616 | 621 | return; |
617 | 622 | } |
618 | 623 | } |
... | ... | @@ -620,7 +625,7 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl<ShipmentHeaderMapper, |
620 | 625 | //自动出库完成 |
621 | 626 | shipmentHeader.setAutoShipmentStatus(2); |
622 | 627 | shipmentHeader.setErrorMsg(""); |
623 | - updateById(shipmentHeader); | |
628 | + shipmentHeaderService.updateById(shipmentHeader); | |
624 | 629 | } |
625 | 630 | |
626 | 631 | |
... | ... | @@ -632,7 +637,7 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl<ShipmentHeaderMapper, |
632 | 637 | errorMsg = errorMsg.substring(0, 500); |
633 | 638 | } |
634 | 639 | shipmentHeader.setErrorMsg(errorMsg); |
635 | - updateById(shipmentHeader); | |
640 | + shipmentHeaderService.updateById(shipmentHeader); | |
636 | 641 | return false; |
637 | 642 | } |
638 | 643 | return true; |
... | ... |
src/main/java/com/huaheng/pc/task/taskHeader/service/ReceiptTaskService.java
... | ... | @@ -356,9 +356,12 @@ public class ReceiptTaskService { |
356 | 356 | List<InventoryDetail> inventoryDetails = inventoryDetailService.list(new LambdaQueryWrapper<InventoryDetail>().eq(InventoryDetail::getInventoryHeaderId, inventoryHeader.getId())); |
357 | 357 | if (inventoryDetails != null && !inventoryDetails.isEmpty()) { |
358 | 358 | for (InventoryDetail inventoryDetail : inventoryDetails) { |
359 | - inventoryDetail.setLocationCode(toLocation.getCode()); | |
360 | - inventoryDetail.setZoneCode(toLocation.getZoneCode()); | |
361 | - if (!inventoryDetailService.updateById(inventoryDetail)) { | |
359 | + LambdaUpdateWrapper<InventoryDetail> updateWrapper = Wrappers.lambdaUpdate(); | |
360 | + updateWrapper | |
361 | + .eq(InventoryDetail::getId, inventoryDetail.getId()) | |
362 | + .set(InventoryDetail::getLocationCode, toLocation.getCode()) | |
363 | + .set(InventoryDetail::getZoneCode, toLocation.getZoneCode()); | |
364 | + if (!inventoryDetailService.update(updateWrapper)) { | |
362 | 365 | throw new ServiceException("补充入库,更新库存明细失败"); |
363 | 366 | } |
364 | 367 | } |
... | ... |
src/main/java/com/huaheng/pc/task/taskHeader/service/ShipmentTaskService.java
... | ... | @@ -365,8 +365,11 @@ public class ShipmentTaskService { |
365 | 365 | List<InventoryDetail> inventoryDetails = inventoryDetailService.list(new LambdaQueryWrapper<InventoryDetail>().eq(InventoryDetail::getInventoryHeaderId, inventoryHeader.getId())); |
366 | 366 | if (inventoryDetails != null && !inventoryDetails.isEmpty()) { |
367 | 367 | for (InventoryDetail inventoryDetail : inventoryDetails) { |
368 | - inventoryDetail.setLocationCode(task.getToLocation()); | |
369 | - if (!inventoryDetailService.updateById(inventoryDetail)) { | |
368 | + | |
369 | + LambdaUpdateWrapper<InventoryDetail> updateWrapper = Wrappers.lambdaUpdate(); | |
370 | + updateWrapper.eq(InventoryDetail::getId, inventoryDetail.getId()) | |
371 | + .set(InventoryDetail::getLocationCode, task.getToLocation()); | |
372 | + if (!inventoryDetailService.update(updateWrapper)) { | |
370 | 373 | throw new ServiceException("完成出库任务,库存修改目标库位时失败" + inventoryDetail.getId()); |
371 | 374 | } |
372 | 375 | } |
... | ... | @@ -381,13 +384,14 @@ public class ShipmentTaskService { |
381 | 384 | //获取出库组盘明细 |
382 | 385 | ShipmentContainerDetail shipmentContainerDetail = shipmentContainerDetailService.getById(taskDetail.getAllocationId()); |
383 | 386 | //获取对应库存记录 |
384 | - InventoryDetail inventoryDetail = inventoryDetailService.getById(taskDetail.getToInventoryId()); | |
387 | + InventoryDetail inventoryDetail = inventoryDetailService.getByIdForUpdate(taskDetail.getToInventoryId()); | |
385 | 388 | if (inventoryDetail == null) { |
386 | 389 | throw new ServiceException("任务明细对应的库存ID【" + taskDetail.getToInventoryId().toString() + "】不存在!"); |
387 | 390 | } |
388 | 391 | inventoryDetail.setLastUpdatedBy(taskDetail.getLastUpdatedBy()); |
389 | 392 | //减扣库存单 |
390 | - inventoryHeader = inventoryHeaderService.getById(inventoryDetail.getInventoryHeaderId()); | |
393 | + // 使用悲观锁查询库存主表 | |
394 | + inventoryHeader = inventoryHeaderService.getByIdForUpdate(inventoryDetail.getInventoryHeaderId()); | |
391 | 395 | |
392 | 396 | //扣减库存明细 |
393 | 397 | inventoryDetail.setTaskQty(inventoryDetail.getTaskQty().subtract(taskDetail.getQty())); |
... | ... |
src/main/java/com/huaheng/pc/task/taskHeader/service/TransferTaskService.java
... | ... | @@ -191,7 +191,7 @@ public class TransferTaskService { |
191 | 191 | taskDetail.setFromInventoryId(inventoryDetail.getId()); |
192 | 192 | taskDetail.setToInventoryId(inventoryDetail.getId()); |
193 | 193 | taskDetail.setLastUpdatedBy(ShiroUtils.getName()); |
194 | - if (!taskDetailService.save(taskDetail) || !inventoryDetailService.updateById(inventoryDetail)) { | |
194 | + if (!taskDetailService.save(taskDetail)) { | |
195 | 195 | throw new ServiceException("创建任务失败"); |
196 | 196 | } |
197 | 197 | } |
... | ... |
src/main/java/com/huaheng/pc/task/taskHeader/service/WorkTaskService.java
... | ... | @@ -769,8 +769,7 @@ public class WorkTaskService { |
769 | 769 | taskDetail.setMaterialName(inventoryDetail.getMaterialName()); |
770 | 770 | taskDetail.setMaterialSpec(inventoryDetail.getMaterialSpec()); |
771 | 771 | taskDetail.setMaterialUnit(inventoryDetail.getMaterialUnit()); |
772 | - if (!taskDetailService.save(taskDetail) || | |
773 | - !inventoryDetailService.updateById(inventoryDetail)) { | |
772 | + if (!taskDetailService.save(taskDetail)) { | |
774 | 773 | throw new ServiceException("任务创建失败"); |
775 | 774 | } |
776 | 775 | } |
... | ... | @@ -843,7 +842,7 @@ public class WorkTaskService { |
843 | 842 | if (inventoryDetail.getId().equals(inventoryDetail2.getId())) { |
844 | 843 | taskDetail.setInventoryTransactionId(inventoryTransactionId); |
845 | 844 | } |
846 | - if (!taskDetailService.save(taskDetail) || !inventoryDetailService.updateById(inventoryDetail)) { | |
845 | + if (!taskDetailService.save(taskDetail)) { | |
847 | 846 | throw new ServiceException("任务创建失败"); |
848 | 847 | } |
849 | 848 | } |
... | ... | @@ -919,8 +918,13 @@ public class WorkTaskService { |
919 | 918 | List<InventoryDetail> inventoryDetails = inventoryDetailService.list(lambdaQueryWrapper2); |
920 | 919 | if (inventoryDetails != null && !inventoryDetails.isEmpty()) { |
921 | 920 | for (InventoryDetail inventoryDetail : inventoryDetails) { |
922 | - inventoryDetail.setLocationCode(taskHeader.getToLocation()); | |
923 | - inventoryDetailService.updateById(inventoryDetail); | |
921 | + LambdaUpdateWrapper<InventoryDetail> updateWrapper = Wrappers.lambdaUpdate(); | |
922 | + updateWrapper.eq(InventoryDetail::getId, inventoryDetail.getId()) | |
923 | + .set(InventoryDetail::getLocationCode, taskHeader.getToLocation()); | |
924 | + if (!inventoryDetailService.update(updateWrapper)) { | |
925 | + throw new ServiceException("库存修改目标库位时失败" + inventoryDetail.getId()); | |
926 | + } | |
927 | + | |
924 | 928 | } |
925 | 929 | containerService.updateStatus(containerCode, QuantityConstant.STATUS_CONTAINER_SOME, warehouseCode); |
926 | 930 | } |
... | ... |
src/main/resources/templates/shipment/shipmentHeader/shipmentHeader.html
... | ... | @@ -289,10 +289,10 @@ |
289 | 289 | <i class="fa fa-code-fork"></i> 自动组盘 |
290 | 290 | </a> |
291 | 291 | |
292 | - <a class="btn btn-outline btn-primary btn-rounded auto-shipment-task" onclick="Toshipping(2)" | |
293 | - shiro:hasPermission="shipment:shippingCombination:combination"> | |
294 | - <i class="fa fa-code-fork"></i> 自动组盘并生成任务 | |
295 | - </a> | |
292 | + <!-- <a class="btn btn-outline btn-primary btn-rounded auto-shipment-task" onclick="Toshipping(2)"--> | |
293 | + <!-- shiro:hasPermission="shipment:shippingCombination:combination">--> | |
294 | + <!-- <i class="fa fa-code-fork"></i> 自动组盘并生成任务--> | |
295 | + <!-- </a>--> | |
296 | 296 | <a class="btn btn-outline btn-primary btn-rounded auto-shipment" onclick="Toshipping(3)" |
297 | 297 | shiro:hasPermission="shipment:shippingCombination:combination"> |
298 | 298 | <i class="fa fa-code-fork"></i> 自动平库组盘 |
... | ... |