ReceiptTaskService.java 22.5 KB
package com.huaheng.pc.task.taskHeader.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.huaheng.common.constant.QuantityConstant;
import com.huaheng.common.exception.service.ServiceException;
import com.huaheng.common.utils.StringUtils;
import com.huaheng.common.utils.security.ShiroUtils;
import com.huaheng.framework.web.domain.AjaxResult;
import com.huaheng.pc.config.container.domain.Container;
import com.huaheng.pc.config.container.service.ContainerService;
import com.huaheng.pc.config.location.domain.Location;
import com.huaheng.pc.config.location.service.LocationService;
import com.huaheng.pc.config.material.domain.Material;
import com.huaheng.pc.config.material.service.MaterialService;
import com.huaheng.pc.config.materialMultiple.domain.MaterialMultiple;
import com.huaheng.pc.config.materialMultiple.service.MaterialMultipleServiceImpl;
import com.huaheng.pc.config.materialUnit.domain.MaterialUnit;
import com.huaheng.pc.config.materialWarnning.domain.MaterialWarning;
import com.huaheng.pc.config.materialWarnning.service.IMaterialWarningService;
import com.huaheng.pc.config.materialWarnning.service.impl.MaterialWarningServiceImpl;
import com.huaheng.pc.inventory.inventoryDetail.domain.InventoryDetail;
import com.huaheng.pc.inventory.inventoryDetail.service.InventoryDetailService;
import com.huaheng.pc.inventory.inventoryHeader.domain.InventoryHeader;
import com.huaheng.pc.inventory.inventoryHeader.service.InventoryHeaderService;
import com.huaheng.pc.inventory.inventoryTransaction.domain.InventoryTransaction;
import com.huaheng.pc.inventory.inventoryTransaction.service.InventoryTransactionService;
import com.huaheng.pc.receipt.receiptContainerDetail.domain.ReceiptContainerDetail;
import com.huaheng.pc.receipt.receiptContainerDetail.service.ReceiptContainerDetailService;
import com.huaheng.pc.receipt.receiptContainerHeader.domain.ReceiptContainerHeader;
import com.huaheng.pc.receipt.receiptContainerHeader.service.ReceiptContainerHeaderService;
import com.huaheng.pc.receipt.receiptDetail.domain.ReceiptDetail;
import com.huaheng.pc.receipt.receiptDetail.service.ReceiptDetailService;
import com.huaheng.pc.receipt.receiptHeader.domain.ReceiptHeader;
import com.huaheng.pc.receipt.receiptHeader.service.ReceiptHeaderService;
import com.huaheng.pc.task.taskDetail.domain.TaskDetail;
import com.huaheng.pc.task.taskDetail.service.TaskDetailService;
import com.huaheng.pc.task.taskHeader.domain.TaskHeader;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

/**
 * 入库任务创建和完成
 * @author mahua
 * @date 2020/7/6
 */
@Service
public class ReceiptTaskService {

    @Resource
    private TaskHeaderService taskHeaderService;
    @Resource
    private TaskDetailService taskDetailService;
    @Resource
    private InventoryHeaderService inventoryHeaderService;
    @Resource
    private InventoryDetailService inventoryDetailService;
    @Resource
    private InventoryTransactionService inventoryTransactionService;
    @Resource
    private ReceiptHeaderService receiptHeaderService;
    @Resource
    private ReceiptDetailService receiptDetailService;
    @Resource
    private ReceiptContainerDetailService receiptContainerDetailService;
    @Resource
    private ReceiptContainerHeaderService receiptContainerHeaderService;
    @Resource
    private ContainerService containerService;
    @Resource
    private LocationService locationService;
    @Resource
    private MaterialService materialService;
    @Resource
    private MaterialMultipleServiceImpl materialMultipleService;
    @Resource
    private IMaterialWarningService materialWarningService;

    /**
     * 创建入库任务(整盘入库、补充入库)
     *
     * @param ids 入库组盘头表id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult createReceiptTask(List<Integer> ids) {
        for (Integer id : ids) {
            ReceiptContainerHeader receiptContainerHeader = receiptContainerHeaderService.getById(id);
            if (receiptContainerHeader == null) {
                throw new ServiceException("id:" + id + "的入库组盘不存在!");
            }

            if (!receiptContainerHeader.getWarehouseCode().equals(ShiroUtils.getWarehouseCode())) {
                throw new ServiceException("id:" + id + "的入库组盘不能在" + ShiroUtils.getWarehouseCode() + "仓库操作");
            }

            //锁定容器
            Container container = new Container();
            container.setStatus("lock");
            LambdaUpdateWrapper<Container> containerUpdateWrapper = Wrappers.lambdaUpdate();
            containerUpdateWrapper.eq(Container::getCode, receiptContainerHeader.getContainerCode());
            containerService.update(container, containerUpdateWrapper);

            //查询入库组盘明细
            LambdaQueryWrapper<ReceiptContainerDetail> containerDetailLambda = Wrappers.lambdaQuery();
            containerDetailLambda.eq(ReceiptContainerDetail::getReceiptContainerId, id);
            List<ReceiptContainerDetail> list = receiptContainerDetailService.list(containerDetailLambda);

            if (list.isEmpty()) {
                throw new ServiceException("id:" + id + "的入库组盘,没有组盘明细,请先组盘!");
            }

            if (receiptContainerHeader.getStatus() == QuantityConstant.RECEIPT_CONTAINER_BUILD.intValue()) {
                if (receiptContainerHeader.getStatus() < QuantityConstant.RECEIPT_CONTAINER_TASK) {
                    receiptContainerHeader.setStatus(QuantityConstant.RECEIPT_CONTAINER_TASK);
                    receiptContainerHeaderService.updateById(receiptContainerHeader);
                }
                //添加任务主表
                TaskHeader task = new TaskHeader();
                task.setAllocationHeadId(receiptContainerHeader.getId());
                task.setInternalTaskType(QuantityConstant.TASK_INTENERTYPE_SHELF);
                task.setWarehouseCode(receiptContainerHeader.getWarehouseCode());
                task.setCompanyCode(receiptContainerHeader.getCompanyCode());
                task.setTaskType(receiptContainerHeader.getTaskType());
                task.setFromLocation(receiptContainerHeader.getFromLocation());
                task.setToLocation(receiptContainerHeader.getToLocation());
                task.setContainerCode(receiptContainerHeader.getContainerCode());
                task.setRecvDock(receiptContainerHeader.getRecvDock());
                if (taskHeaderService.save(task)) {
                    //添加任务明细表
                    for (ReceiptContainerDetail item : list) {
                        TaskDetail taskDetail = new TaskDetail();
                        taskDetail.setTaskId(task.getId());
                        taskDetail.setTaskType(task.getTaskType());
                        taskDetail.setInternalTaskType(QuantityConstant.TASK_INTENERTYPE_SHELF);
                        taskDetail.setWarehouseCode(task.getWarehouseCode());
                        taskDetail.setAllocationId(item.getId());
                        taskDetail.setCompanyCode(task.getCompanyCode());
                        taskDetail.setMaterialCode(item.getMaterialCode());
                        taskDetail.setMaterialName(item.getMaterialName());
                        taskDetail.setMaterialSpec(item.getMaterialSpec());
                        taskDetail.setMaterialUnit(item.getMaterialUnit());
                        taskDetail.setBillCode(item.getReceiptCode());
                        taskDetail.setBillDetailId(item.getReceiptDetailId());
                        taskDetail.setQty(item.getQty());
                        taskDetail.setContainerCode(task.getContainerCode());
                        taskDetail.setFromLocation(task.getFromLocation());
                        taskDetail.setToLocation(task.getToLocation());
                        taskDetail.setBatch(item.getBatch());
                        taskDetail.setProjectNo(item.getProjectNo());
                        if (!taskDetailService.save(taskDetail)) {
                            throw new ServiceException("生成任务明细失败");
                        }

                        //更新入库组盘明细状态
                        item.setStatus(QuantityConstant.RECEIPT_CONTAINER_TASK);
                        if (!receiptContainerDetailService.updateById(item)) {
                            throw new ServiceException("更新入库组盘明细状态出错");
                        }

                        /**
                         * 修改明细状态为上架
                         */
                        ReceiptDetail receiptDetail = receiptDetailService.getById(item.getReceiptDetailId());
                        receiptDetail.setProcessStamp(String.valueOf(QuantityConstant.RECEIPT_HEADER_SHELF));
                        if (!receiptDetailService.updateById(receiptDetail)) {
                            throw new ServiceException("更新入库单详情失败");
                        }
                        //更新头表状态
                        receiptDetailService.updateReceiptHeaderLastStatus(receiptDetail.getReceiptId());
                    }

                } else {
                    throw new ServiceException("任务生成失败");
                }
            }
        }
        return AjaxResult.success("生成上架任务成功");
    }

    /**
     * 完成入库任务
     *
     * @param task
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult completeReceiptTask(TaskHeader task) {
        /* 判断任务状态*/
        if (task.getStatus().equals(QuantityConstant.TASK_STATUS_COMPLETED)) {
            return AjaxResult.error("任务已完成");
        }
        BigDecimal totalQty = BigDecimal.ZERO;
        List<TaskDetail> taskDetailList = taskDetailService.findByTaskId(task.getId());
        if (taskDetailList.isEmpty()) {
            throw new ServiceException("任务明细为空");
        }
        /* 遍历任务明细,修改关联的入库组盘、入库单状态、添加库存*/
        for (TaskDetail taskDetail : taskDetailList) {
            if (taskDetail.getStatus() < QuantityConstant.TASK_STATUS_COMPLETED) {
                totalQty = totalQty.add(taskDetail.getQty());
                /*查询入库单明细*/
                ReceiptDetail receiptDetail = receiptDetailService.getById(taskDetail.getBillDetailId());
                if (StringUtils.isNotNull(receiptDetail)) {
                    LambdaQueryWrapper<InventoryHeader> inventoryHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
                    inventoryHeaderLambdaQueryWrapper.eq(InventoryHeader::getWarehouseCode, ShiroUtils.getWarehouseCode())
                            .eq(InventoryHeader::getLocationCode, task.getToLocation())
                            .eq(InventoryHeader::getContainerCode, task.getContainerCode());
                    InventoryHeader inventoryHeader = inventoryHeaderService.getOne(inventoryHeaderLambdaQueryWrapper);
                    /* 如果库存 头明细不存在则新增库存头表记录*/
                    if (StringUtils.isNull(inventoryHeader)) {
                        inventoryHeader = new InventoryHeader();
                        inventoryHeader.setWarehouseCode(receiptDetail.getWarehouseCode());
                        inventoryHeader.setLocationCode(task.getToLocation());
                        inventoryHeader.setContainerCode(task.getContainerCode());
                        inventoryHeader.setContainerStatus("some");
                        inventoryHeader.setCompanyCode(receiptDetail.getCompanyCode());
                        inventoryHeader.setTotalWeight(task.getWeight());
                        inventoryHeader.setTotalQty(new BigDecimal(0));
                        inventoryHeader.setTotalLines(0);
                        inventoryHeader.setLocking(1);
                        inventoryHeader.setEnable(1);
                        if (!inventoryHeaderService.save(inventoryHeader)) {
                            throw new ServiceException("添加库存单失败");
                        }
                        inventoryHeader = inventoryHeaderService.getOne(inventoryHeaderLambdaQueryWrapper);
                    }
                    totalQty = this.addInventoryDetail(taskDetail, receiptDetail, inventoryHeader);
                    //修改组盘表状态为完成
                    ReceiptContainerDetail receiptContainerDetail = new ReceiptContainerDetail();
                    receiptContainerDetail.setStatus(QuantityConstant.RECEIPT_CONTAINER_FINISHED);
                    LambdaUpdateWrapper<ReceiptContainerDetail> receiptContainerDetailLambdaUpdateWrapper = Wrappers.lambdaUpdate();
                    receiptContainerDetailLambdaUpdateWrapper.eq(ReceiptContainerDetail::getId, taskDetail.getAllocationId());
                    if (!receiptContainerDetailService.update(receiptContainerDetail, receiptContainerDetailLambdaUpdateWrapper)){
                        throw new ServiceException("更新组盘状态失败");
                    }

                } else {
                    throw new ServiceException("未找到id:" + taskDetail.getBillDetailId() + "入库单明细");
                }
                receiptDetail.setProcessStamp(String.valueOf(QuantityConstant.RECEIPT_HEADER_POSTING));
                receiptDetailService.updateById(receiptDetail);
                receiptDetailService.updateReceiptHeaderLastStatus(receiptDetail.getReceiptId());
                materialWarningService.materialWarning(taskDetail.getMaterialCode(), taskDetail.getCompanyCode());
            }
        }
        LambdaQueryWrapper<InventoryHeader> inventoryHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
        inventoryHeaderLambdaQueryWrapper.eq(InventoryHeader::getWarehouseCode, ShiroUtils.getWarehouseCode())
                .eq(InventoryHeader::getLocationCode, task.getToLocation())
                .eq(InventoryHeader::getContainerCode, task.getContainerCode());
        InventoryHeader inventoryHeader = inventoryHeaderService.getOne(inventoryHeaderLambdaQueryWrapper);
        if (StringUtils.isNull(inventoryHeader)) {
            throw new ServiceException("库存添加失败");
        } else {
            inventoryHeader.setTotalQty(inventoryHeader.getTotalQty().add(totalQty));
            inventoryHeader.setTotalLines(inventoryHeader.getTotalLines()+taskDetailList.size());
            inventoryHeaderService.updateById(inventoryHeader);
        }
        //修改任务主表状态,因为立库任务表单头只对应一个货箱,表单详情的任务会同时完成
        task.setStatus(QuantityConstant.TASK_STATUS_COMPLETED);
        LambdaUpdateWrapper<TaskHeader> taskHeaderLambdaUpdateWrapper = Wrappers.lambdaUpdate();
        taskHeaderLambdaUpdateWrapper.eq(TaskHeader::getId, task.getId());
        if (!taskHeaderService.update(task, taskHeaderLambdaUpdateWrapper)){
            throw new ServiceException("更新任务主表失败");
        }

        //修改库位状态和对应的容器
        Location location = new Location();
        location.setContainerCode(task.getContainerCode());
        location.setStatus("empty");
        LambdaUpdateWrapper<Location> locationLambdaUpdateWrapper = Wrappers.lambdaUpdate();
        locationLambdaUpdateWrapper.eq(Location::getCode, task.getToLocation());
        if (!locationService.update(location, locationLambdaUpdateWrapper)){
            throw new ServiceException("更新库位失败");
        }
        //修改容器状态和对应的库位
        Container container = new Container();
        container.setLocationCode(task.getToLocation());
        container.setStatus("some");
        LambdaUpdateWrapper<Container> containerLambdaUpdateWrapper = Wrappers.lambdaUpdate();
        containerLambdaUpdateWrapper.eq(Container::getCode, task.getContainerCode());
        if (!containerService.update(container, containerLambdaUpdateWrapper)) {
            throw new ServiceException("更新容器失败");
        }

        //修改入库组盘头表状态
        ReceiptContainerHeader receiptContainerHeader = new ReceiptContainerHeader();
        receiptContainerHeader.setId(task.getAllocationHeadId());
        receiptContainerHeader.setStatus(QuantityConstant.RECEIPT_CONTAINER_FINISHED);
        if (!receiptContainerHeaderService.updateById(receiptContainerHeader)) {
            throw new ServiceException("更新入库组盘头表状态失败");
        }
        return AjaxResult.success();
    }

    /**
     * 添加库存明细与库存交易记录
     * @param taskDetail 任务明细
     * @param receiptDetail 入库单明细
     * @param inventoryHeader 库存头表
     * @return 任务数量
     */
    private BigDecimal addInventoryDetail(TaskDetail taskDetail, ReceiptDetail receiptDetail, InventoryHeader inventoryHeader) {
        /*该入库明细是否已存在库存明细记录,已存在更新数量、不存在新增记录*/
        LambdaQueryWrapper<InventoryDetail> inventory = Wrappers.lambdaQuery();
        inventory.eq(InventoryDetail::getWarehouseCode, taskDetail.getWarehouseCode())
                .eq(InventoryDetail::getLocationCode, inventoryHeader.getLocationCode())
                .eq(InventoryDetail::getMaterialCode, taskDetail.getMaterialCode())
                .eq(InventoryDetail::getContainerCode, inventoryHeader.getContainerCode())
                .eq(InventoryDetail::getCompanyCode, taskDetail.getCompanyCode())
                .eq(InventoryDetail::getReceiptDetailId, taskDetail.getBillDetailId());
        InventoryDetail inventoryDetail = inventoryDetailService.getOne(inventory);
        Material material = materialService.findAllByCode(receiptDetail.getMaterialCode());
        /*单位换算*/
        BigDecimal receiptQty = taskDetail.getQty();
        if (StringUtils.isNotEmpty(receiptDetail.getMaterialUnit()) &&
                StringUtils.isNotEmpty(material.getUnit()) &&
                !receiptDetail.getMaterialUnit().equals(material.getUnit())) {
            LambdaQueryWrapper<MaterialMultiple> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(MaterialMultiple::getMaterialCode, receiptDetail.getMaterialCode())
                    .eq(MaterialMultiple::getUnitId1, receiptDetail.getMaterialUnit())
                    .eq(MaterialMultiple::getUnitId2, material.getUnit());
            MaterialMultiple materialMultiple = materialMultipleService.getOne(queryWrapper);
            if (StringUtils.isNull(materialMultiple)) {
                throw new ServiceException("入库单单位与物料绑定主单位不一致且单位换算不存在");
            } else {
                receiptQty = receiptQty.multiply(materialMultiple.getMultiple());
            }
        }
        if (StringUtils.isNotNull(inventoryDetail)) {
            inventoryDetail.setQty(inventoryDetail.getQty().add(taskDetail.getQty()));
        }
        else {
            ReceiptHeader receiptHeader = receiptHeaderService.getById(receiptDetail.getReceiptId());
            inventoryDetail = new InventoryDetail();
            inventoryDetail.setInventoryHeaderId(inventoryHeader.getId());
            inventoryDetail.setWarehouseCode(taskDetail.getWarehouseCode());
            inventoryDetail.setCompanyCode(taskDetail.getCompanyCode());
            inventoryDetail.setLocationCode(taskDetail.getToLocation());
            inventoryDetail.setContainerCode(taskDetail.getContainerCode());
            inventoryDetail.setMaterialCode(taskDetail.getMaterialCode());
            inventoryDetail.setMaterialName(taskDetail.getMaterialName());
            inventoryDetail.setMaterialSpec(taskDetail.getMaterialSpec());
            inventoryDetail.setMaterialUnit(material.getUnit());
            inventoryDetail.setQty(receiptQty);
            inventoryDetail.setTaskQty(new BigDecimal(0));
            inventoryDetail.setLockedQty(new BigDecimal(0));
            inventoryDetail.setInventorySts(taskDetail.getInventorySts());
            inventoryDetail.setSupplierCode(receiptDetail.getSupplierCode());
            inventoryDetail.setReferCode(receiptDetail.getReferCode());
            inventoryDetail.setReferDetailId(receiptDetail.getReferLineNum());
            inventoryDetail.setBatch(receiptDetail.getBatch());
            inventoryDetail.setLot(receiptDetail.getLot());
            inventoryDetail.setProjectNo(receiptDetail.getProjectNo());;
            inventoryDetail.setManufactureDate(receiptDetail.getManufactureDate());
            inventoryDetail.setExpirationDate(receiptDetail.getExpirationDate());
            inventoryDetail.setAgingDate(receiptDetail.getAgingDate());
            inventoryDetail.setAttribute1(receiptDetail.getAttribute1());
            inventoryDetail.setAttribute2(receiptDetail.getAttribute2());
            inventoryDetail.setAttribute3(receiptDetail.getAttribute3());
            inventoryDetail.setReceiptCode(receiptHeader.getCode());
            inventoryDetail.setReceiptDetailId(receiptDetail.getId());
            if (!inventoryDetailService.save(inventoryDetail)) {
                throw new ServiceException("保存库存明细失败");
            }
        }
        //记录库存交易记录
        InventoryTransaction inventoryTransaction = new InventoryTransaction();
        inventoryTransaction.setTransactionType(QuantityConstant.INVENTORY_TRANSACTION_RECEIPT);
        inventoryTransaction.setWarehouseCode(taskDetail.getWarehouseCode());
        inventoryTransaction.setCompanyCode(taskDetail.getCompanyCode());
        inventoryTransaction.setLocationCode(inventoryHeader.getLocationCode());
        inventoryTransaction.setContainerCode(inventoryHeader.getContainerCode());
        inventoryTransaction.setMaterialCode(taskDetail.getMaterialCode());
        inventoryTransaction.setMaterialName(taskDetail.getMaterialName());
        inventoryTransaction.setMaterialSpec(taskDetail.getMaterialSpec());
        inventoryTransaction.setMaterialUnit(material.getUnit());
        inventoryTransaction.setBillCode(taskDetail.getBillCode());
        inventoryTransaction.setBillDetailId(taskDetail.getBillDetailId());
        inventoryTransaction.setBatch(receiptDetail.getBatch());
        inventoryTransaction.setLot(receiptDetail.getLot());
        inventoryTransaction.setInventorySts(receiptDetail.getInventorySts());
        inventoryTransaction.setTaskQty(receiptQty);
        if (!inventoryTransactionService.save(inventoryTransaction)) {
            throw new ServiceException("新增库存记录失败");
        }
        return receiptQty;
    }
}