Commit 21367548214073fe1fb5743d5948d635a9fd3d4f

Authored by pengyongcheng
1 parent 2c47bb70

feat: 库存详情,特殊出库

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&lt;InventoryDetail&gt; {
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&lt;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&lt;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>&nbsp;搜索
  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>&nbsp;重置
  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
... ...