Commit 21367548214073fe1fb5743d5948d635a9fd3d4f
1 parent
2c47bb70
feat: 库存详情,特殊出库
Showing
6 changed files
with
634 additions
and
11 deletions
src/main/java/com/huaheng/common/constant/QuantityConstant.java
... | ... | @@ -738,6 +738,11 @@ public class QuantityConstant { |
738 | 738 | public static final String SHIPMENT_BILL_TYPE_SCRAP = "DOW"; |
739 | 739 | |
740 | 740 | /** |
741 | + * 出库单类型:报废出库单 | |
742 | + */ | |
743 | + public static final String SHIPMENT_BILL_TYPE_SPECIAL = "TS"; | |
744 | + | |
745 | + /** | |
741 | 746 | * 出库单类型:工单领料单 |
742 | 747 | */ |
743 | 748 | public static final String SHIPMENT_BILL_TYPE_OTF = "OTF"; |
... | ... |
src/main/java/com/huaheng/pc/inventory/inventoryDetail/controller/InventoryDetailController.java
... | ... | @@ -24,11 +24,13 @@ import org.apache.shiro.authz.annotation.RequiresPermissions; |
24 | 24 | import org.springframework.stereotype.Controller; |
25 | 25 | import org.springframework.ui.ModelMap; |
26 | 26 | import org.springframework.web.bind.annotation.*; |
27 | +import org.thymeleaf.expression.Ids; | |
27 | 28 | |
28 | 29 | import javax.annotation.Resource; |
29 | 30 | import java.lang.reflect.InvocationTargetException; |
30 | 31 | import java.time.LocalDate; |
31 | 32 | import java.util.ArrayList; |
33 | +import java.util.Arrays; | |
32 | 34 | import java.util.List; |
33 | 35 | |
34 | 36 | /** |
... | ... | @@ -227,10 +229,61 @@ public class InventoryDetailController extends BaseController { |
227 | 229 | @PostMapping("/inventoryLevelWarning/list") |
228 | 230 | @ResponseBody |
229 | 231 | public TableDataInfo getInventoryLevelWarning(InventoryDetail detail, |
230 | - @RequestParam(name = "pageNum", defaultValue = "1") Integer pageNo, | |
231 | - @RequestParam(name = "pageSize", defaultValue = "50") Integer pageSize) { | |
232 | + @RequestParam(name = "pageNum", defaultValue = "1") Integer pageNo, | |
233 | + @RequestParam(name = "pageSize", defaultValue = "50") Integer pageSize) { | |
232 | 234 | Page<InventoryLevelWarning> page = new Page<>(pageNo, pageSize); |
233 | 235 | Page<InventoryLevelWarning> list = inventoryDetailService.getInventoryLevelWarning(page, detail.getMaterialCode()); |
234 | 236 | return getMpDataTable(list.getRecords(), list.getTotal()); |
235 | 237 | } |
238 | + | |
239 | + @GetMapping("/inventoryList") | |
240 | + public String inventoryList() { | |
241 | + return prefix + "/inventoryList"; | |
242 | + } | |
243 | + | |
244 | + @Log(title = "库存-库存详情", operating = "查看库存明细详情", action = BusinessType.GRANT) | |
245 | + @PostMapping("/getInventoryList") | |
246 | + @ResponseBody | |
247 | + public TableDataInfo inventoryList(InventoryDetail inventoryDetail, String createdBegin, String createdEnd) { | |
248 | + if (StringUtils.isNotEmpty(createdEnd)) { | |
249 | + createdEnd = LocalDate.parse(createdEnd).plusDays(1).toString(); | |
250 | + } | |
251 | + LambdaQueryWrapper<InventoryDetail> lambdaQueryWrapper = Wrappers.lambdaQuery(); | |
252 | + lambdaQueryWrapper | |
253 | + .ge(StringUtils.isNotEmpty(createdBegin), InventoryDetail::getCreated, createdBegin) | |
254 | + .lt(StringUtils.isNotEmpty(createdEnd), InventoryDetail::getCreated, createdEnd) | |
255 | + .eq(StringUtils.isNotEmpty(inventoryDetail.getZoneCode()), InventoryDetail::getZoneCode, inventoryDetail.getZoneCode()) | |
256 | + .eq(StringUtils.isNotEmpty(inventoryDetail.getLocationCode()), InventoryDetail::getLocationCode, inventoryDetail.getLocationCode()) | |
257 | + .eq(StringUtils.isNotEmpty(inventoryDetail.getContainerCode()), InventoryDetail::getContainerCode, inventoryDetail.getContainerCode()) | |
258 | + .eq(StringUtils.isNotEmpty(inventoryDetail.getVehicleCode()), InventoryDetail::getVehicleCode, inventoryDetail.getVehicleCode()) | |
259 | + .like(StringUtils.isNotEmpty(inventoryDetail.getSupplierCode()), InventoryDetail::getSupplierCode, inventoryDetail.getSupplierCode()) | |
260 | + .like(StringUtils.isNotEmpty(inventoryDetail.getMaterialCode()), InventoryDetail::getMaterialCode, inventoryDetail.getMaterialCode()) | |
261 | + .like(StringUtils.isNotEmpty(inventoryDetail.getMaterialName()), InventoryDetail::getMaterialName, inventoryDetail.getMaterialName()) | |
262 | + .like(StringUtils.isNotEmpty(inventoryDetail.getMaterialSpec()), InventoryDetail::getMaterialSpec, inventoryDetail.getMaterialSpec()) | |
263 | + .like(StringUtils.isNotEmpty(inventoryDetail.getBatch()), InventoryDetail::getBatch, inventoryDetail.getBatch()) | |
264 | + .like(StringUtils.isNotEmpty(inventoryDetail.getOrderCode()), InventoryDetail::getOrderCode, inventoryDetail.getOrderCode()) | |
265 | + .like(StringUtils.isNotEmpty(inventoryDetail.getShipmentReferCode()), InventoryDetail::getShipmentReferCode, inventoryDetail.getShipmentReferCode()) | |
266 | + .like(StringUtils.isNotEmpty(inventoryDetail.getCreatedBy()), InventoryDetail::getCreatedBy, inventoryDetail.getCreatedBy()) | |
267 | + .orderByDesc(InventoryDetail::getId); | |
268 | + List<InventoryDetail> list = inventoryDetailService.list(lambdaQueryWrapper); | |
269 | + return getDataTable(list); | |
270 | + } | |
271 | + | |
272 | + @GetMapping("/specialShipping/{ids}") | |
273 | + public String specialShipping(@PathVariable("ids") String ids, ModelMap modelMap) { | |
274 | + modelMap.put("ids", ids); | |
275 | + return prefix + "/specialShipping"; | |
276 | + } | |
277 | + | |
278 | + @Log(title = "库存-库存详情", operating = "特殊出库", action = BusinessType.GRANT) | |
279 | + @PostMapping("/specialShipping") | |
280 | + @ResponseBody | |
281 | + public AjaxResult specialShipping(@RequestParam("ids") String inventoryDetailIds, String port) { | |
282 | + if (StringUtils.isEmpty(inventoryDetailIds)) { | |
283 | + return AjaxResult.error("出库失败,库存明细为空"); | |
284 | + } | |
285 | + List<String> inventoryDetailIdList = Arrays.asList(inventoryDetailIds.split(",")); | |
286 | + inventoryDetailService.shipping(inventoryDetailIdList, port); | |
287 | + return AjaxResult.success("出库成功"); | |
288 | + } | |
236 | 289 | } |
... | ... |
src/main/java/com/huaheng/pc/inventory/inventoryDetail/service/InventoryDetailService.java
... | ... | @@ -100,6 +100,13 @@ public interface InventoryDetailService extends IService<InventoryDetail> { |
100 | 100 | * @return 库存明细 |
101 | 101 | */ |
102 | 102 | List<InventoryDetail> getByHeaderIds(List<Integer> headerIds); |
103 | + | |
104 | + /** | |
105 | + * 快速出库 | |
106 | + * @param inventoryDetailIdList 库存明细id | |
107 | + * @param port 出库口 | |
108 | + */ | |
109 | + void shipping(List<String> inventoryDetailIdList, String port); | |
103 | 110 | } |
104 | 111 | |
105 | 112 | |
... | ... |
src/main/java/com/huaheng/pc/inventory/inventoryDetail/service/InventoryDetailServiceImpl.java
1 | 1 | package com.huaheng.pc.inventory.inventoryDetail.service; |
2 | 2 | |
3 | 3 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
4 | +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | |
4 | 5 | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
5 | 6 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
6 | 7 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
... | ... | @@ -14,16 +15,29 @@ import com.huaheng.pc.check.checkDetail.domain.CheckDetail; |
14 | 15 | import com.huaheng.pc.check.checkDetail.service.CheckDetailService; |
15 | 16 | import com.huaheng.pc.check.checkHeader.domain.CheckHeader; |
16 | 17 | import com.huaheng.pc.check.checkHeader.service.CheckHeaderService; |
18 | +import com.huaheng.pc.config.container.domain.Container; | |
19 | +import com.huaheng.pc.config.container.service.ContainerService; | |
17 | 20 | import com.huaheng.pc.config.location.domain.Location; |
18 | 21 | import com.huaheng.pc.config.location.service.LocationService; |
19 | 22 | import com.huaheng.pc.config.shipmentPreference.domain.ShipmentPreference; |
23 | +import com.huaheng.pc.config.vehicle.domain.Vehicle; | |
24 | +import com.huaheng.pc.config.vehicle.service.VehicleService; | |
20 | 25 | import com.huaheng.pc.inventory.inventoryDetail.domain.InventoryDetail; |
21 | 26 | import com.huaheng.pc.inventory.inventoryDetail.domain.InventoryExpireWarning; |
22 | 27 | import com.huaheng.pc.inventory.inventoryDetail.domain.InventoryLevelWarning; |
23 | 28 | import com.huaheng.pc.inventory.inventoryDetail.mapper.InventoryDetailMapper; |
29 | +import com.huaheng.pc.inventory.inventoryHeader.domain.InventoryHeader; | |
24 | 30 | import com.huaheng.pc.inventory.inventoryHeader.service.InventoryHeaderService; |
25 | -import com.huaheng.pc.receipt.receiptDetail.service.ReceiptDetailService; | |
31 | +import com.huaheng.pc.inventory.inventoryTransaction.domain.InventoryTransaction; | |
32 | +import com.huaheng.pc.inventory.inventoryTransaction.service.InventoryTransactionService; | |
33 | +import com.huaheng.pc.shipment.shipmentContainerDetail.domain.ShipmentContainerDetail; | |
34 | +import com.huaheng.pc.shipment.shipmentContainerDetail.service.ShipmentContainerDetailService; | |
35 | +import com.huaheng.pc.shipment.shipmentContainerHeader.domain.ShipmentContainerHeader; | |
36 | +import com.huaheng.pc.shipment.shipmentContainerHeader.service.ShipmentContainerHeaderService; | |
26 | 37 | import com.huaheng.pc.shipment.shipmentDetail.domain.ShipmentDetail; |
38 | +import com.huaheng.pc.shipment.shipmentDetail.service.ShipmentDetailService; | |
39 | +import com.huaheng.pc.shipment.shipmentHeader.domain.ShipmentHeader; | |
40 | +import com.huaheng.pc.shipment.shipmentHeader.service.ShipmentHeaderService; | |
27 | 41 | import com.huaheng.pc.system.dict.domain.DictData; |
28 | 42 | import com.huaheng.pc.system.dict.service.IDictDataService; |
29 | 43 | import com.huaheng.pc.task.taskDetail.domain.TaskDetail; |
... | ... | @@ -31,7 +45,6 @@ import com.huaheng.pc.task.taskDetail.service.TaskDetailService; |
31 | 45 | import com.huaheng.pc.task.taskHeader.domain.TaskHeader; |
32 | 46 | import com.huaheng.pc.task.taskHeader.service.TaskHeaderService; |
33 | 47 | import org.apache.commons.beanutils.BeanUtils; |
34 | -import org.springframework.beans.factory.annotation.Autowired; | |
35 | 48 | import org.springframework.stereotype.Service; |
36 | 49 | import org.springframework.transaction.annotation.Transactional; |
37 | 50 | |
... | ... | @@ -44,7 +57,8 @@ import java.util.stream.Collectors; |
44 | 57 | @Service |
45 | 58 | public class InventoryDetailServiceImpl extends ServiceImpl<InventoryDetailMapper, InventoryDetail> implements InventoryDetailService { |
46 | 59 | |
47 | - | |
60 | + @Resource | |
61 | + private InventoryDetailService inventoryDetailService; | |
48 | 62 | @Resource |
49 | 63 | private TaskHeaderService taskHeaderService; |
50 | 64 | @Resource |
... | ... | @@ -53,16 +67,28 @@ public class InventoryDetailServiceImpl extends ServiceImpl<InventoryDetailMappe |
53 | 67 | private InventoryDetailMapper inventoryDetailMapper; |
54 | 68 | @Resource |
55 | 69 | private LocationService locationService; |
56 | - @Autowired | |
70 | + @Resource | |
57 | 71 | private InventoryHeaderService inventoryHeaderService; |
58 | - @Autowired | |
59 | - private ReceiptDetailService receiptDetailService; | |
60 | - @Autowired | |
72 | + @Resource | |
73 | + private ShipmentHeaderService shipmentHeaderService; | |
74 | + @Resource | |
75 | + private ShipmentDetailService shipmentDetailService; | |
76 | + @Resource | |
61 | 77 | private CheckHeaderService checkHeaderService; |
62 | - @Autowired | |
78 | + @Resource | |
63 | 79 | private CheckDetailService checkDetailService; |
64 | - @Autowired | |
80 | + @Resource | |
65 | 81 | private IDictDataService dictDataService; |
82 | + @Resource | |
83 | + private ContainerService containerService; | |
84 | + @Resource | |
85 | + private VehicleService vehicleService; | |
86 | + @Resource | |
87 | + private ShipmentContainerHeaderService shipmentContainerHeaderService; | |
88 | + @Resource | |
89 | + private ShipmentContainerDetailService shipmentContainerDetailService; | |
90 | + @Resource | |
91 | + private InventoryTransactionService inventoryTransactionService; | |
66 | 92 | |
67 | 93 | |
68 | 94 | /** |
... | ... | @@ -381,6 +407,218 @@ public class InventoryDetailServiceImpl extends ServiceImpl<InventoryDetailMappe |
381 | 407 | queryWrapper.in(InventoryDetail::getInventoryHeaderId, headerIds); |
382 | 408 | return super.list(queryWrapper); |
383 | 409 | } |
410 | + | |
411 | + @Override | |
412 | + @Transactional(rollbackFor = Exception.class) | |
413 | + public void shipping(List<String> inventoryDetailIdList, String port) { | |
414 | + if (StringUtils.isEmpty(inventoryDetailIdList)) { | |
415 | + throw new ServiceException("快速出库失败,库存明细id为空"); | |
416 | + } | |
417 | + LambdaQueryWrapper<InventoryDetail> queryWrapper = Wrappers.lambdaQuery(); | |
418 | + queryWrapper.in(InventoryDetail::getId, inventoryDetailIdList); | |
419 | + List<InventoryDetail> allInventoryDetailList = super.list(queryWrapper); | |
420 | + // 获取库存头id并去重 | |
421 | + List<Integer> inventoryHeaderIdList = allInventoryDetailList.stream() | |
422 | + .map(InventoryDetail::getInventoryHeaderId) | |
423 | + .distinct().collect(Collectors.toList()); | |
424 | + List<InventoryHeader> inventoryHeaderList = inventoryHeaderService.getByIds(inventoryHeaderIdList); | |
425 | + | |
426 | + // 生成特殊出库单据头 | |
427 | + InventoryHeader inventoryHeaderAny = inventoryHeaderList.stream().findAny().orElse(new InventoryHeader()); | |
428 | + ShipmentHeader shipmentHeader = new ShipmentHeader(); | |
429 | + shipmentHeader.setWarehouseCode(inventoryHeaderAny.getWarehouseCode()); | |
430 | + shipmentHeader.setCompanyCode(inventoryHeaderAny.getCompanyCode()); | |
431 | + shipmentHeader.setCode(shipmentHeaderService.createCode(QuantityConstant.SHIPMENT_BILL_TYPE_SPECIAL)); | |
432 | + shipmentHeader.setShipmentType(QuantityConstant.SHIPMENT_BILL_TYPE_SPECIAL); | |
433 | + shipmentHeader.setLastStatus(QuantityConstant.SHIPMENT_HEADER_GROUPDISK); | |
434 | + shipmentHeader.setFirstStatus(QuantityConstant.SHIPMENT_HEADER_GROUPDISK); | |
435 | + shipmentHeader.setReferCode("快速出库"); | |
436 | + boolean save = shipmentHeaderService.save(shipmentHeader); | |
437 | + if (!save) { | |
438 | + throw new ServiceException("特殊出库失败,保存出库单头表失败"); | |
439 | + } | |
440 | + List<ShipmentDetail> shipmentDetailList = new ArrayList<>(); | |
441 | + inventoryHeaderList.forEach(inventoryHeader -> { | |
442 | + String locationCode = inventoryHeader.getLocationCode(); | |
443 | + String containerCode = inventoryHeader.getContainerCode(); | |
444 | + Location location = locationService.getLocationByCode(locationCode); | |
445 | + Container container = containerService.getContainerByCode(containerCode); | |
446 | + // 校验 | |
447 | + if (QuantityConstant.STATUS_LOCATION_LOCK.equals(location.getStatus())) { | |
448 | + throw new ServiceException(StringUtils.format("特殊出库失败,库位 {} 已锁定", locationCode)); | |
449 | + } | |
450 | + if (QuantityConstant.STATUS_CONTAINER_LOCK.equals(container.getStatus())) { | |
451 | + throw new ServiceException(StringUtils.format("特殊出库失败,库位 {} 已锁定", containerCode)); | |
452 | + } | |
453 | + boolean success; | |
454 | + success = locationService.updateStatus(locationCode, QuantityConstant.STATUS_LOCATION_LOCK); | |
455 | + if (!success) { | |
456 | + throw new ServiceException("特殊出库失败,锁定库位失败"); | |
457 | + } | |
458 | + success = containerService.updateStatus(containerCode, QuantityConstant.STATUS_CONTAINER_LOCK); | |
459 | + if (!success) { | |
460 | + throw new ServiceException("特殊出库失败,锁定容器失败"); | |
461 | + } | |
462 | + | |
463 | + LambdaUpdateWrapper<InventoryHeader> updateWrapper = Wrappers.lambdaUpdate(); | |
464 | + updateWrapper.eq(InventoryHeader::getId, inventoryHeader.getId()) | |
465 | + .set(InventoryHeader::getContainerStatus, QuantityConstant.STATUS_CONTAINER_LOCK); | |
466 | + success = inventoryHeaderService.update(updateWrapper); | |
467 | + if (!success) { | |
468 | + throw new ServiceException("特殊出库失败,锁定库存载具状态失败"); | |
469 | + } | |
470 | + | |
471 | + List<TaskHeader> unCompleteTaskList = taskHeaderService.getUnCompleteTaskList(); | |
472 | + for (TaskHeader taskHeader : unCompleteTaskList) { | |
473 | + if (inventoryHeader.getLocationCode().equals(taskHeader.getFromLocation()) || inventoryHeader.getLocationCode().equals(taskHeader.getToLocation())) { | |
474 | + throw new ServiceException(StringUtils.format("特殊出库失败,库位 {} 存在未完成的任务", inventoryHeader.getLocationCode())); | |
475 | + } | |
476 | + } | |
477 | + | |
478 | + List<InventoryDetail> inventoryDetailList = inventoryDetailService.getByHeaderId(inventoryHeader.getId()); | |
479 | + inventoryDetailList.forEach(inventoryDetail -> { | |
480 | + InventoryDetail temp = new InventoryDetail(); | |
481 | + temp.setId(inventoryDetail.getId()); | |
482 | + temp.setTaskQty(inventoryDetail.getQty()); | |
483 | + if (!inventoryDetailService.updateById(temp)) { | |
484 | + throw new ServiceException("特殊出库失败,更新库存明细失败"); | |
485 | + } | |
486 | + }); | |
487 | + | |
488 | + // 配盘头 | |
489 | + ShipmentContainerHeader shipmentContainerHeader = new ShipmentContainerHeader(); | |
490 | + shipmentContainerHeader.setShipmentCode(shipmentHeader.getCode()); | |
491 | + shipmentContainerHeader.setStatus(QuantityConstant.SHIPMENT_CONTAINER_TASK); | |
492 | + shipmentContainerHeader.setContainerCode(inventoryHeader.getContainerCode()); | |
493 | + shipmentContainerHeader.setContainerType(container.getContainerType()); | |
494 | + shipmentContainerHeader.setLocationCode(inventoryHeader.getLocationCode()); | |
495 | + shipmentContainerHeader.setTaskType(QuantityConstant.TASK_TYPE_WHOLESHIPMENT); | |
496 | + shipmentContainerHeader.setPort(port); | |
497 | + shipmentContainerHeader.setCompanyCode(inventoryHeader.getCompanyCode()); | |
498 | + shipmentContainerHeader.setWarehouseCode(inventoryHeader.getWarehouseCode()); | |
499 | + shipmentContainerHeader.setContainerCode(inventoryHeader.getContainerCode()); | |
500 | + // 盛具类型 | |
501 | + shipmentContainerHeader.setVehicleCode(inventoryHeader.getVehicleCode()); | |
502 | + Vehicle vehicle = vehicleService.getVehicleByCode(inventoryHeader.getVehicleCode()); | |
503 | + shipmentContainerHeader.setVehicleTypeCode(vehicle.getVehicleType()); | |
504 | + success = shipmentContainerHeaderService.save(shipmentContainerHeader); | |
505 | + if (!success) { | |
506 | + throw new ServiceException("保存出库配盘头表失败"); | |
507 | + } | |
508 | + // 任务头 | |
509 | + TaskHeader taskHeader = new TaskHeader(); | |
510 | + com.huaheng.common.utils.bean.BeanUtils.copyBeanProp(taskHeader, inventoryHeader); | |
511 | + taskHeader.setCreated(null); | |
512 | + taskHeader.setCreatedBy(null); | |
513 | + taskHeader.setLastUpdated(null); | |
514 | + taskHeader.setLastUpdatedBy(null); | |
515 | + taskHeader.setId(null); | |
516 | + taskHeader.setTaskType(QuantityConstant.TASK_TYPE_WHOLESHIPMENT); | |
517 | + // 设置200:前端出库任务也页面查询时,条件为此字段=200 | |
518 | + taskHeader.setInternalTaskType(QuantityConstant.TASK_TYPE_SUPPLEMENTRECEIPT); | |
519 | + taskHeader.setStatus(QuantityConstant.TASK_STATUS_BUILD); | |
520 | + taskHeader.setPort(port); | |
521 | + taskHeader.setFromLocation(inventoryHeader.getLocationCode()); | |
522 | + taskHeader.setAllocationHeadId(shipmentContainerHeader.getId()); | |
523 | + if (!taskHeaderService.save(taskHeader)) { | |
524 | + throw new ServiceException("创建出库任务失败,保存任务头表失败"); | |
525 | + } | |
526 | + | |
527 | + List<ShipmentContainerDetail> shipmentContainerDetailList = new ArrayList<>(); | |
528 | + List<TaskDetail> taskDetailList = new ArrayList<>(); | |
529 | + List<InventoryTransaction> inventoryTransactionList = new ArrayList<>(); | |
530 | + // 遍历库存明细,生成单据明细、配盘明细、任务明细 | |
531 | + inventoryDetailList.forEach(inventoryDetail -> { | |
532 | + boolean success2; | |
533 | + // 出库单明细 | |
534 | + ShipmentDetail shipmentDetail = new ShipmentDetail(); | |
535 | + com.huaheng.common.utils.bean.BeanUtils.copyBeanProp(shipmentDetail, inventoryDetail); | |
536 | + shipmentDetail.setId(null); | |
537 | + shipmentDetail.setCreated(null); | |
538 | + shipmentDetail.setCreatedBy(Objects.requireNonNull(ShiroUtils.getUser()).getUserName()); | |
539 | + shipmentDetail.setLastUpdated(null); | |
540 | + shipmentDetail.setLastUpdatedBy(Objects.requireNonNull(ShiroUtils.getUser()).getUserName()); | |
541 | + shipmentDetail.setShipmentId(shipmentHeader.getId()); | |
542 | + shipmentDetail.setShipmentCode(shipmentHeader.getCode()); | |
543 | + shipmentDetail.setStatus(QuantityConstant.SHIPMENT_HEADER_GROUPDISK); | |
544 | + shipmentDetail.setTaskQty(shipmentDetail.getQty()); | |
545 | + shipmentDetailList.add(shipmentDetail); | |
546 | + // 创建出库单明细 | |
547 | + success2 = shipmentDetailService.save(shipmentDetail); | |
548 | + if (!success2) { | |
549 | + throw new ServiceException("特殊出库失败,保存出库单明细失败"); | |
550 | + } | |
551 | + // 配盘明细 | |
552 | + ShipmentContainerDetail shipmentContainerDetail = new ShipmentContainerDetail(); | |
553 | + com.huaheng.common.utils.bean.BeanUtils.copyBeanProp(shipmentContainerDetail, inventoryDetail); | |
554 | + shipmentContainerDetail.setId(null); | |
555 | + shipmentContainerDetail.setCreated(null); | |
556 | + shipmentContainerDetail.setCreatedBy(Objects.requireNonNull(ShiroUtils.getUser()).getUserName()); | |
557 | + shipmentContainerDetail.setLastUpdated(null); | |
558 | + shipmentContainerDetail.setLastUpdatedBy(Objects.requireNonNull(ShiroUtils.getUser()).getUserName()); | |
559 | + shipmentContainerDetail.setShippingContainerId(shipmentContainerHeader.getId()); | |
560 | + shipmentContainerDetail.setShipmentCode(shipmentContainerHeader.getShipmentCode()); | |
561 | + shipmentContainerDetail.setContainerCode(shipmentContainerHeader.getContainerCode()); | |
562 | + shipmentContainerDetail.setLocationCode(shipmentContainerHeader.getLocationCode()); | |
563 | + shipmentContainerDetail.setInventoryId(inventoryDetail.getId()); | |
564 | + shipmentContainerDetail.setShipmentId(shipmentHeader.getId()); | |
565 | + shipmentContainerDetail.setShipmentDetailId(shipmentDetail.getId()); | |
566 | + shipmentContainerDetail.setStatus(QuantityConstant.SHIPMENT_CONTAINER_TASK); | |
567 | + shipmentContainerDetailList.add(shipmentContainerDetail); | |
568 | + | |
569 | + // 任务明细 | |
570 | + TaskDetail taskDetail = new TaskDetail(); | |
571 | + com.huaheng.common.utils.bean.BeanUtils.copyBeanProp(taskDetail, inventoryDetail); | |
572 | + taskDetail.setId(null); | |
573 | + taskDetail.setCreated(null); | |
574 | + taskDetail.setCreatedBy(Objects.requireNonNull(ShiroUtils.getUser()).getUserName()); | |
575 | + taskDetail.setLastUpdated(null); | |
576 | + taskDetail.setLastUpdatedBy(Objects.requireNonNull(ShiroUtils.getUser()).getUserName()); | |
577 | + taskDetail.setTaskId(taskHeader.getId()); | |
578 | + taskDetail.setTaskType(taskHeader.getTaskType()); | |
579 | + taskDetail.setInternalTaskType(taskHeader.getInternalTaskType()); | |
580 | + taskDetail.setFromLocation(taskHeader.getFromLocation()); | |
581 | + taskDetail.setBillDetailId(shipmentDetail.getId()); | |
582 | + taskDetail.setBillCode(shipmentHeader.getCode()); | |
583 | + taskDetail.setAllocationId(shipmentContainerHeader.getId()); | |
584 | + taskDetail.setToInventoryId(inventoryDetail.getId()); | |
585 | + taskDetail.setFromInventoryId(inventoryDetail.getId()); | |
586 | + taskDetailList.add(taskDetail); | |
587 | + | |
588 | + // 创建交易记录 | |
589 | + InventoryTransaction inventoryTransaction = new InventoryTransaction(); | |
590 | + com.huaheng.common.utils.bean.BeanUtils.copyBeanProp(inventoryTransaction, inventoryDetail); | |
591 | + inventoryTransaction.setCreated(null); | |
592 | + inventoryTransaction.setCreatedBy(null); | |
593 | + inventoryTransaction.setId(null); | |
594 | + inventoryTransaction.setTransactionType(QuantityConstant.INVENTORY_TRANSACTION_SHIPMENT); | |
595 | + inventoryTransactionList.add(inventoryTransaction); | |
596 | + }); | |
597 | + | |
598 | + // 创建配盘明细 | |
599 | + success = shipmentContainerDetailService.saveBatch(shipmentContainerDetailList); | |
600 | + if (!success) { | |
601 | + throw new ServiceException("特殊出库失败,保存出库配盘失败"); | |
602 | + } | |
603 | + // 创建出库任务明细 | |
604 | + success = taskDetailService.saveBatch(taskDetailList); | |
605 | + if (!success) { | |
606 | + throw new ServiceException("特殊出库失败,创建出库任务失败"); | |
607 | + } | |
608 | + // 创建库存交易记录 | |
609 | + success = inventoryTransactionService.saveBatch(inventoryTransactionList); | |
610 | + if (!success) { | |
611 | + throw new ServiceException("特殊出库失败,创建交易记录失败"); | |
612 | + } | |
613 | + }); | |
614 | + ShipmentHeader updateShipmentHeader = new ShipmentHeader(); | |
615 | + updateShipmentHeader.setId(shipmentHeader.getId()); | |
616 | + updateShipmentHeader.setTotalQty(shipmentDetailList.stream().map(ShipmentDetail::getQty).reduce(BigDecimal.ZERO, BigDecimal::add)); | |
617 | + updateShipmentHeader.setTotalLines(shipmentDetailList.size()); | |
618 | + if (!shipmentHeaderService.updateById(updateShipmentHeader)) { | |
619 | + throw new ServiceException("特殊出库失败,更新出库单头失败"); | |
620 | + } | |
621 | + } | |
384 | 622 | } |
385 | 623 | |
386 | 624 | |
... | ... |
src/main/resources/templates/inventory/inventoryDetail/inventoryList.html
0 → 100644
1 | +<!DOCTYPE HTML> | |
2 | +<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"> | |
3 | +<meta charset="utf-8"> | |
4 | +<head th:include="include :: header"></head> | |
5 | +<body class="white-bg"> | |
6 | +<div class="container-div"> | |
7 | + <div class="row"> | |
8 | + <div class="col-sm-12 select-info"> | |
9 | + <form autocomplete="off" id="inventory-form"> | |
10 | + <div class="select-list"> | |
11 | + <ul> | |
12 | + <li> | |
13 | + <label>库位编码:</label> | |
14 | + <input id="locationCode" name="locationCode" placeholder="请输入库位编码" type="text"/> | |
15 | + </li> | |
16 | + <li> | |
17 | + <label>载具编码:</label> | |
18 | + <input id="containerCode" name="containerCode" placeholder="请输入载具编码" type="text"/> | |
19 | + </li> | |
20 | + <li> | |
21 | + <label>盛具编码:</label> | |
22 | + <input id="vehicleCode" name="vehicleCode" placeholder="请输入盛具编码" type="text"/> | |
23 | + </li> | |
24 | + <li> | |
25 | + <label>物料编码:</label> | |
26 | + <input name="materialCode" placeholder="请输入物料编码" type="text"/> | |
27 | + </li> | |
28 | + <li> | |
29 | + <label>物料名称:</label> | |
30 | + <input name="materialName" placeholder="请输入物料名称" type="text"/> | |
31 | + </li> | |
32 | + <li> | |
33 | + <label>物料单位:</label> | |
34 | + <input name="materialUnit" placeholder="请输入物料单位" type="text"/> | |
35 | + </li> | |
36 | + <li> | |
37 | + <label>物料规格:</label> | |
38 | + <input name="materialSpec" placeholder="请输入物料规格" type="text"/> | |
39 | + </li> | |
40 | + <li> | |
41 | + <label>批次:</label> | |
42 | + <input name="batch" placeholder="请输入批次" type="text"/> | |
43 | + </li> | |
44 | + <li> | |
45 | + <label>锁定工单号:</label> | |
46 | + <input name="orderCode" placeholder="请输入工单号" type="text"/> | |
47 | + </li> | |
48 | + <li> | |
49 | + <label>锁定领料单号:</label> | |
50 | + <input name="shipmentReferCode" placeholder="请输入领料单号" type="text"/> | |
51 | + </li> | |
52 | + <li> | |
53 | + <label>供应商:</label> | |
54 | + <select id="supplierCode" name="supplierCode" | |
55 | + th:with="type=${@SupplierService.getCode()}"> | |
56 | + <option value="">所有</option> | |
57 | + <option th:each="e : ${type}" th:text="${e['name']}" | |
58 | + th:value="${e['code']}"> | |
59 | + </option> | |
60 | + </select> | |
61 | + </li> | |
62 | + <li class="select-time" style="height:30px"> | |
63 | + <label>创建时间: </label> | |
64 | + <input class="time-input" id="startTime" name="createdBegin" placeholder="开始时间" | |
65 | + type="text"/> | |
66 | + <span>-</span> | |
67 | + <input class="time-input" id="endTime" name="createdEnd" placeholder="结束时间" | |
68 | + type="text"/> | |
69 | + </li> | |
70 | + <li style="float: right; margin-right: 45px"> | |
71 | + <a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"> | |
72 | + <i class="fa fa-search"></i> 搜索 | |
73 | + </a> | |
74 | + <a class="btn btn-warning btn-rounded btn-sm" | |
75 | + onclick="$.form.reset('inventory-form')"> | |
76 | + <i class="fa fa-refresh"></i> 重置 | |
77 | + </a> | |
78 | + </li> | |
79 | + </ul> | |
80 | + </div> | |
81 | + </form> | |
82 | + </div> | |
83 | + <div class="btn-group hidden-xs" id="toolbar" role="group"> | |
84 | + <a class="btn btn-outline btn-primary btn-rounded" onclick="specialShipping()" | |
85 | + shiro:hasPermission="inventory:inventoryList:shipping"> | |
86 | + <i class="fa fa-eye"></i> 出库 | |
87 | + </a> | |
88 | + <a class="btn btn-outline btn-danger btn-rounded" onclick="report()"> | |
89 | + <i class="fa fa-eye"></i> 打印 | |
90 | + </a> | |
91 | + </div> | |
92 | + <div class="col-sm-12 select-table"> | |
93 | + <table class="table table-bordered table-hover text-nowrap" data-mobile-responsive="true" | |
94 | + id="bootstrap-table"> | |
95 | + </table> | |
96 | + </div> | |
97 | + </div> | |
98 | +</div> | |
99 | +<div th:include="include :: footer"></div> | |
100 | +<script th:inline="javascript"> | |
101 | + let prefix = ctx + "inventory/inventoryDetail"; | |
102 | + let inventoryStatus = [[${@dict.getType('inventorySts')}]]; | |
103 | + let supplier = [[${@SupplierService.getCode()}]]; | |
104 | + $(function () { | |
105 | + $.table.init({ | |
106 | + url: prefix + "/getInventoryList", | |
107 | + modalName: "库存详情", | |
108 | + sortable: true, // 是否启用排序 | |
109 | + sortStable: true, // 设置为 true 将获得稳定的排序 | |
110 | + sortName: "id", | |
111 | + sortOrder: "desc", | |
112 | + search: false, | |
113 | + pagination: false, | |
114 | + columns: [ | |
115 | + { | |
116 | + checkbox: true | |
117 | + }, | |
118 | + { | |
119 | + field: 'locationCode', | |
120 | + title: '库位编码' | |
121 | + }, | |
122 | + { | |
123 | + field: 'containerCode', | |
124 | + title: '载具编码' | |
125 | + }, | |
126 | + { | |
127 | + field: 'vehicleCode', | |
128 | + title: '盛具编码', | |
129 | + align: 'center', | |
130 | + }, | |
131 | + { | |
132 | + field: 'materialCode', | |
133 | + title: '物料编码' | |
134 | + }, | |
135 | + { | |
136 | + field: 'materialName', | |
137 | + title: '物料名称' | |
138 | + }, | |
139 | + { | |
140 | + field: 'materialSpec', | |
141 | + title: '物料规格' | |
142 | + }, | |
143 | + { | |
144 | + field: 'materialUnit', | |
145 | + title: '物料单位' | |
146 | + }, | |
147 | + { | |
148 | + field: 'weight', | |
149 | + title: '重量(克)', | |
150 | + align: 'center', | |
151 | + }, | |
152 | + { | |
153 | + field: 'inventorySts', | |
154 | + title: '物料状态', | |
155 | + align: 'center', | |
156 | + formatter: function (value, row, index) { | |
157 | + return $.table.selectDictLabel(inventoryStatus, value); | |
158 | + } | |
159 | + }, | |
160 | + { | |
161 | + field: 'locationNoX', | |
162 | + title: 'x' | |
163 | + }, | |
164 | + { | |
165 | + field: 'locationNoY', | |
166 | + title: 'y' | |
167 | + }, | |
168 | + { | |
169 | + field: 'batch', | |
170 | + title: '批次' | |
171 | + }, | |
172 | + { | |
173 | + field: 'tracingNo', | |
174 | + title: '追溯码' | |
175 | + }, | |
176 | + { | |
177 | + field: 'qty', | |
178 | + title: '库存数量' | |
179 | + }, | |
180 | + { | |
181 | + field: 'taskQty', | |
182 | + title: '预定执行数量' | |
183 | + }, | |
184 | + { | |
185 | + field: 'orderCode', | |
186 | + title: '锁定工单号', | |
187 | + }, | |
188 | + { | |
189 | + field: 'shipmentReferCode', | |
190 | + title: '锁定领料单号', | |
191 | + }, | |
192 | + { | |
193 | + field: 'supplierCode', | |
194 | + title: '供应商', | |
195 | + visible: true, | |
196 | + formatter: function (value, row, index) { | |
197 | + let actions = []; | |
198 | + $.each(supplier, function (index, item) { | |
199 | + if (item.code === value) { | |
200 | + actions.push("<span class='badge badge-info'>" + item.name + "</span>"); | |
201 | + return false; | |
202 | + } | |
203 | + }); | |
204 | + return actions.join(''); | |
205 | + }, | |
206 | + }, | |
207 | + { | |
208 | + field: 'created', | |
209 | + title: '入库日期', | |
210 | + sortable: true | |
211 | + }, | |
212 | + { | |
213 | + field: 'createdBy', | |
214 | + title: '创建用户', | |
215 | + visible: true | |
216 | + }, | |
217 | + { | |
218 | + field: 'lastUpdated', | |
219 | + title: '最后修改时间', | |
220 | + sortable: true | |
221 | + }, | |
222 | + { | |
223 | + field: 'lastUpdatedBy', | |
224 | + title: '更新用户' | |
225 | + }, | |
226 | + ] | |
227 | + }); | |
228 | + }) | |
229 | + | |
230 | + function specialShipping() { | |
231 | + let rows = $("#bootstrap-table").bootstrapTable('getSelections'); | |
232 | + let ids = rows.map(x => x.id).join(","); | |
233 | + if (rows.length === 0) { | |
234 | + $.modal.alertWarning("请至少选择一条记录"); | |
235 | + return; | |
236 | + } | |
237 | + $.modal.open("特殊出库", prefix + "/specialShipping/" + ids) | |
238 | + } | |
239 | + | |
240 | + function report() { | |
241 | + let rows = $("#bootstrap-table").bootstrapTable('getSelections'); | |
242 | + if (rows.length === 0) { | |
243 | + $.modal.alertWarning("请至少选择一条记录"); | |
244 | + return; | |
245 | + } | |
246 | + let ids = rows.map(x => x.id); | |
247 | + let url = prefix + '/report/' + ids; | |
248 | + $.modal.open("库存打印", url); | |
249 | + } | |
250 | +</script> | |
251 | +</body> | |
252 | +</html> | |
0 | 253 | \ No newline at end of file |
... | ... |
src/main/resources/templates/inventory/inventoryDetail/specialShipping.html
0 → 100644
1 | +<!DOCTYPE HTML> | |
2 | +<html lang="zh" xmlns:th="http://www.thymeleaf.org"> | |
3 | +<meta charset="utf-8"> | |
4 | +<head> | |
5 | + <th:block th:include="include :: header"/> | |
6 | + <th:block th:include="include :: select2-css"/> | |
7 | + <script src="/wms/js/jquery.min.js"></script> | |
8 | +</head> | |
9 | +<body class="white-bg"> | |
10 | +<div class="wrapper wrapper-content animated fadeInRight ibox-content"> | |
11 | + <form class="form-horizontal m" id="form-inventory-specialShipping"> | |
12 | + <label> | |
13 | + <input id="ids" name="ids" hidden="hidden" th:value="${ids}"/> | |
14 | + </label> | |
15 | + <div class="form-group"> | |
16 | + <label class="col-sm-3 control-label">出库口:</label> | |
17 | + <div class="col-sm-8"> | |
18 | + <select id="port" name="port" class="form-control"></select> | |
19 | + </div> | |
20 | + </div> | |
21 | + <div class="form-group"> | |
22 | + <div class="form-control-static col-sm-offset-9"> | |
23 | + <button type="submit" class="btn btn-primary">出库</button> | |
24 | + <button onclick="$.modal.close()" class="btn btn-danger" type="button">关闭</button> | |
25 | + </div> | |
26 | + </div> | |
27 | + </form> | |
28 | +</div> | |
29 | +<div th:include="include::footer"></div> | |
30 | +<th:block th:include="include :: select2-js"/> | |
31 | +<script type="text/javascript"> | |
32 | + var prefix = ctx + "inventory/inventoryDetail" | |
33 | + $("#form-inventory-specialShipping").validate({ | |
34 | + rules: { | |
35 | + ids: { | |
36 | + required: true, | |
37 | + }, | |
38 | + port: { | |
39 | + required: true, | |
40 | + }, | |
41 | + }, | |
42 | + submitHandler: function (form) { | |
43 | + $.operate.save(prefix + "/specialShipping", $('#form-inventory-specialShipping').serialize()); | |
44 | + } | |
45 | + }); | |
46 | + | |
47 | + $(function () { | |
48 | + $('#port').select2({ | |
49 | + ajax: { | |
50 | + url: ctx + 'config/station/getDataByType', | |
51 | + dataType: 'json', | |
52 | + type: 'post', | |
53 | + data: function (params) { | |
54 | + return { | |
55 | + types: "2,3", | |
56 | + port: params.term | |
57 | + } | |
58 | + }, | |
59 | + }, | |
60 | + placeholder: "请选择出库口", | |
61 | + templateResult: function (data) { | |
62 | + return data.id + " " + data.text; | |
63 | + } | |
64 | + }); | |
65 | + }) | |
66 | +</script> | |
67 | +</body> | |
68 | +</html> | |
0 | 69 | \ No newline at end of file |
... | ... |