ReceiptDetailServiceImpl.java 18.5 KB
package com.huaheng.pc.receipt.receiptDetail.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.huaheng.common.constant.QuantityConstant;
import com.huaheng.common.exception.service.ServiceException;
import com.huaheng.common.support.Convert;
import com.huaheng.common.utils.StringUtils;
import com.huaheng.common.utils.security.ShiroUtils;
import com.huaheng.framework.web.domain.AjaxResult;
import com.huaheng.pc.check.checkHeader.domain.CheckHeader;
import com.huaheng.pc.check.checkHeader.service.CheckHeaderService;
import com.huaheng.pc.config.configValue.domain.ConfigValue;
import com.huaheng.pc.config.configValue.service.ConfigValueService;
import com.huaheng.pc.config.material.domain.Material;
import com.huaheng.pc.config.material.service.MaterialService;
import com.huaheng.pc.config.materialType.domain.MaterialType;
import com.huaheng.pc.config.materialType.service.MaterialTypeService;
import com.huaheng.pc.config.receiptPreference.domain.ReceiptPreference;
import com.huaheng.pc.config.receiptPreference.service.ReceiptPreferenceService;
import com.huaheng.pc.config.receiptType.domain.ReceiptType;
import com.huaheng.pc.config.receiptType.service.ReceiptTypeService;
import com.huaheng.pc.config.statusFlow.domain.StatusFlowDetail;
import com.huaheng.pc.config.statusFlow.service.StatusFlowDetailService;
import com.huaheng.pc.receipt.receiptHeader.domain.ReceiptHeader;
import com.huaheng.pc.receipt.receiptHeader.service.ReceiptHeaderService;
import com.huaheng.pc.system.config.domain.Config;
import com.huaheng.pc.system.dict.domain.DictData;
import com.huaheng.pc.system.dict.service.IDictDataService;
import io.swagger.models.auth.In;
import org.aspectj.weaver.loadtime.Aj;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaheng.pc.receipt.receiptDetail.domain.ReceiptDetail;
import com.huaheng.pc.receipt.receiptDetail.mapper.ReceiptDetailMapper;
import com.huaheng.pc.receipt.receiptDetail.service.ReceiptDetailService;
import org.springframework.transaction.annotation.Transactional;

@Service
public class ReceiptDetailServiceImpl extends ServiceImpl<ReceiptDetailMapper, ReceiptDetail> implements ReceiptDetailService{

    @Resource
    private MaterialService materialService;
    @Resource
    private ReceiptHeaderService receiptHeaderService;
    @Resource
    private ReceiptTypeService receiptTypeService;
    @Resource
    private StatusFlowDetailService statusFlowDetailService;
    @Resource
    private MaterialTypeService materialTypeService;
    @Resource
    private ReceiptPreferenceService receiptPreferenceService;
    @Resource
    private IDictDataService dictDataService;
    @Resource
    private CheckHeaderService checkHeaderService;
    @Resource
    private ConfigValueService configValueService;

    /**
     * 新增入库明细
     * @param receiptDetail
     * @return
     */
    @Transactional
    public AjaxResult saveReceiptDetaial(ReceiptDetail receiptDetail){
        /* 判断入库头表状态*/
        LambdaQueryWrapper<ReceiptHeader> lambdaReceiptHeader = Wrappers.lambdaQuery();
        lambdaReceiptHeader.eq(ReceiptHeader::getId, receiptDetail.getReceiptId());
        ReceiptHeader receiptHeader = receiptHeaderService.getOne(lambdaReceiptHeader);

        //判断入库头表状态
        if (receiptHeader == null ){
            throw new ServiceException("找不到主单据");
        } else if (receiptHeader.getFirstStatus() > QuantityConstant.RECEIPT_HEADER_POOL){
            throw new ServiceException("单据进入订单池后,不允许新增明细");
        } else if (receiptHeader.getFirstStatus() == 20) {
            throw new ServiceException("单据已作废");
        }
        receiptDetail.setReceiptCode(receiptHeader.getCode());

        /* 判断物料编码*/
        LambdaQueryWrapper<Material> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(Material::getCode, receiptDetail.getMaterialCode());
        Material material = materialService.getOne(lambdaQueryWrapper);
        if (material == null) {
            throw new ServiceException("物料不存在");
        }
        receiptDetail.setCompanyCode(material.getCompanyCode());
        receiptDetail.setMaterialCode(material.getCode());
        receiptDetail.setMaterialName(material.getName());
        receiptDetail.setMaterialSpec(material.getSpec());
        receiptDetail.setMaterialUnit(material.getUnit());

        receiptDetail.setCreatedBy(ShiroUtils.getLoginName());
        receiptDetail.setLastUpdatedBy(ShiroUtils.getLoginName());
        receiptDetail.setWarehouseCode(ShiroUtils.getWarehouseCode());

        //根据流程配置更新入库明细下一流程
        ReceiptDetail receiptDetail1 = queryflow(receiptDetail);

        if (this.save(receiptDetail1)) {
            receiptHeader.setTotalQty(receiptHeader.getTotalQty().add(receiptDetail1.getTotalQty()));
            receiptHeader.setTotalLines(receiptHeader.getTotalLines()+1);
            receiptHeaderService.updateById(receiptHeader);
            return AjaxResult.success("新增单据明细成功");
        } else {
            return AjaxResult.error("新增单据明细失败!");
        }

    }

    /**
     * 修改入库明细
     * @param receiptDetail
     * @return
     */
    @Override
    @Transactional
    public AjaxResult updateReceiptDetaial(ReceiptDetail receiptDetail) {
        /* 先修改入库头表中的总数量和总行数,再更新记录,完成后更新入库头表中总数量和总行数*/

        //查询原记录
        ReceiptDetail originalReceiptDetail= this.getById(receiptDetail.getId());
        ReceiptHeader receiptHeader = receiptHeaderService.getById(receiptDetail.getReceiptId());
        //判断物料编码是否被修改
        if (!originalReceiptDetail.getMaterialCode().equals(receiptDetail.getMaterialCode())){
            LambdaQueryWrapper<Material> lambdaMaterial = Wrappers.lambdaQuery();
            lambdaMaterial.eq(Material::getCode,receiptDetail.getMaterialCode());
            Material material = materialService.getOne(lambdaMaterial);
            if (material == null) {
                throw new ServiceException("该物料编码不存在");

            }else {
                receiptDetail.setMaterialName(material.getName());
                receiptDetail.setMaterialSpec(material.getSpec());
                receiptDetail.setMaterialUnit(material.getUnit());
                receiptDetail.setProcessStamp("0");
                receiptHeader.setTotalQty(receiptHeader.getTotalQty().subtract(originalReceiptDetail.getTotalQty()));
                receiptHeader.setTotalLines(receiptHeader.getTotalLines()-1);
                if ( !receiptHeaderService.updateById(receiptHeader)){
                    return AjaxResult.error("入库头表更新失败");
                }
            }
        }

        //如果单据状态为驳回则设置状态为提交审核
        if ("10".equals(receiptDetail.getProcessStamp())){
            receiptDetail.setProcessStamp("5");
        }
        receiptDetail.setLastUpdatedBy(ShiroUtils.getLoginName());
        if ( !this.updateById(receiptDetail) ){
            return AjaxResult.error("入库明细更新失败");
        } else {

            receiptHeader.setTotalQty(receiptHeader.getTotalQty().add(receiptDetail.getTotalQty()));
            receiptHeader.setTotalLines(receiptHeader.getTotalLines()+1);
            receiptHeaderService.updateById(receiptHeader);
            return AjaxResult.success("修改单据明细成功");
        }
    }

    /**
     * 根据流程配置更新入库明细下一流程
     * @param receiptDetail
     * @return
     */
    @Transactional
    public ReceiptDetail queryflow(ReceiptDetail receiptDetail){
        //当单据状态为驳回或作废时不更新状态
        if ("10".equals(receiptDetail.getProcessStamp()) || "20".equals(receiptDetail.getProcessStamp())){
            return receiptDetail;
        }

        //如果入库明细绑定了入库流程则从入库明细中选择流程
        if ( StringUtils.isNotEmpty(receiptDetail.getStatusFlowCode())){
            List<StatusFlowDetail> statusFlowDetails = statusFlowDetailService.queryStatusFlowDetail(receiptDetail.getStatusFlowCode());
            String status = nextStatusFlow(statusFlowDetails, receiptDetail.getProcessStamp());
            //在状态到达时候是判断是否要质检
            if (QuantityConstant.RECEIPT_HEADER_RECEIVING.toString().equals(status) && inspection(receiptDetail)){
                receiptDetail.setProcessStamp(QuantityConstant.RECEIPT_HEADER_CHECK.toString());
            } else {
                receiptDetail.setProcessStamp(status);
            }
            return receiptDetail;
        }
        //查询头表信息
        LambdaQueryWrapper<ReceiptHeader> lambdaReceiptHeader = Wrappers.lambdaQuery();
        lambdaReceiptHeader.eq(ReceiptHeader::getCode, receiptDetail.getReceiptCode());
        ReceiptHeader receiptHeader = receiptHeaderService.getOne(lambdaReceiptHeader);

        //查询明细表中入库物料信息
        LambdaQueryWrapper<Material> lambdaMaterial = Wrappers.lambdaQuery();
        lambdaMaterial.eq(Material::getCode, receiptDetail.getMaterialCode());
        Material material = materialService.getOne(lambdaMaterial);

        //查询头表中绑定的入库类型中的入库流程
        LambdaQueryWrapper<ReceiptType> lambdaReceiptType = Wrappers.lambdaQuery();
        lambdaReceiptType.eq(ReceiptType::getCode,  receiptHeader.getReceiptType())
                .eq(ReceiptType::getWarehouseCode,ShiroUtils.getWarehouseCode());
        ReceiptType receiptType = receiptTypeService.getOne(lambdaReceiptType);


        if (receiptType.getReceiptFlow() != null){
            //物料是否有入库流程
            List<StatusFlowDetail> statusFlowDetails = statusFlowDetailService.queryStatusFlowDetail(receiptType.getReceiptFlow());
            String status = nextStatusFlow(statusFlowDetails, receiptDetail.getProcessStamp());
            //在状态到达时候是判断是否要质检
            if (QuantityConstant.RECEIPT_HEADER_RECEIVING.toString().equals(status) && inspection(receiptDetail)){
                receiptDetail.setProcessStamp(QuantityConstant.RECEIPT_HEADER_CHECK.toString());
            } else {
                receiptDetail.setProcessStamp(status);
            }
            return receiptDetail;
        } else if (material.getReceivingFlow() != null){
            //物料是否有入库流程
            List<StatusFlowDetail> statusFlowDetails = statusFlowDetailService.queryStatusFlowDetail(material.getReceivingFlow());
            String status = nextStatusFlow(statusFlowDetails, receiptDetail.getProcessStamp());
            //在状态到达时候是判断是否要质检
            if (QuantityConstant.RECEIPT_HEADER_RECEIVING.toString().equals(status) && inspection(receiptDetail)){
                receiptDetail.setProcessStamp(QuantityConstant.RECEIPT_HEADER_CHECK.toString());
            } else {
                receiptDetail.setProcessStamp(status);
            }
            return receiptDetail;
        } else {
            //该物料类别是否有入库流程
            LambdaQueryWrapper<MaterialType> lambdaMaterialType = Wrappers.lambdaQuery();
            lambdaMaterialType.eq(MaterialType::getCode, material.getType());
            MaterialType materialType = materialTypeService.getOne(lambdaMaterialType);
            if (materialType.getReceivingFlow() != null) {
                List<StatusFlowDetail> statusFlowDetails = statusFlowDetailService.queryStatusFlowDetail(materialType.getReceivingFlow());
                String status = nextStatusFlow(statusFlowDetails, receiptDetail.getProcessStamp());
                //在状态到达时候是判断是否要质检
                if (QuantityConstant.RECEIPT_HEADER_RECEIVING.toString().equals(status) && inspection(receiptDetail)){
                    receiptDetail.setProcessStamp(QuantityConstant.RECEIPT_HEADER_CHECK.toString());
                } else {
                    receiptDetail.setProcessStamp(status);
                }
                return receiptDetail;
            } else {
                //查询系统参数配置中绑定的入库首选项A
                LambdaQueryWrapper<ConfigValue> lambdaQueryWrapper = Wrappers.lambdaQuery();
                lambdaQueryWrapper.eq(ConfigValue::getModuleType, "receipt");
                ConfigValue configValue = configValueService.getOne(lambdaQueryWrapper);

                //以上都没有的情况下查询入库首选项中的入库流程
                LambdaQueryWrapper<ReceiptPreference> lambda = Wrappers.lambdaQuery();
                lambda.eq(ReceiptPreference::getCode, configValue.getValue());
                ReceiptPreference receiptPreference = receiptPreferenceService.getOne(lambda);
                List<StatusFlowDetail> statusFlowDetails = statusFlowDetailService.queryStatusFlowDetail(receiptPreference.getReceivingFlow());
                String status = nextStatusFlow(statusFlowDetails, receiptDetail.getProcessStamp());
                //在状态到达时候是判断是否要质检
                if (QuantityConstant.RECEIPT_HEADER_RECEIVING.toString().equals(status) && inspection(receiptDetail)){
                    receiptDetail.setProcessStamp(QuantityConstant.RECEIPT_HEADER_CHECK.toString());
                } else {
                    receiptDetail.setProcessStamp(status);
                }
                return receiptDetail;
            }
        }
    }

    //获取配置流程中下一状态
    public String nextStatusFlow(List<StatusFlowDetail> statusFlowDetails, String status){
        //判断当前状态是否为最后状态,若为最后状态返回当前状态
        if (status == null){
            status = "0";
        }
        if (status.equals(statusFlowDetails.get(statusFlowDetails.size()-1).getFlowCode())){
            return status;
        } else {
            for (int i = 0; i < statusFlowDetails.size(); i++){
                if (Integer.parseInt(statusFlowDetails.get(i).getFlowCode()) > Integer.parseInt(status)){
                    return statusFlowDetails.get(i).getFlowCode();
                }
            }
            return status;
        }
    }

    /**
     * @description 更新头表尾状态
     * 每次明细表更新后调用该方法
     * 当所有明细表到达该状态时,更新头表状态
     * @param id 头表id
     */
    public void updateReceiptHeaderLastStatus(Integer id){
        LambdaQueryWrapper<ReceiptDetail> lambdaDetails = Wrappers.lambdaQuery();
        lambdaDetails.eq(ReceiptDetail::getReceiptId, id);
        List<ReceiptDetail> receiptDetails = this.list(lambdaDetails);

        // 判断入库明细是否为空
        if (receiptDetails.isEmpty()){
            throw new ServiceException("不存在入库明细");
        }
        //查询出头表信息
        ReceiptHeader receiptHeader = receiptHeaderService.getById(id);
        Integer minStatus = Integer.parseInt(receiptDetails.get(0).getProcessStamp());
        Integer maxStatus = Integer.parseInt(receiptDetails.get(0).getProcessStamp());
        //遍历明细状态得出最小状态值
        for (int i = 1; i<receiptDetails.size(); i++){
            if ( minStatus > Integer.parseInt(receiptDetails.get(i).getProcessStamp())) {
                minStatus = Integer.parseInt(receiptDetails.get(i).getProcessStamp());
            }
            if ( maxStatus < Integer.parseInt(receiptDetails.get(i).getProcessStamp())) {
                maxStatus = Integer.parseInt(receiptDetails.get(i).getProcessStamp());
            }
        }


        //从数据字典中获取单据当前状态
        List<DictData> dictData = dictDataService.selectDictDataByType("receiptHeaderStatus");
        for (int i = 0; i<dictData.size(); i++){
            if (dictData.get(i).getDictValue().equals(minStatus)){
                minStatus = Integer.valueOf(dictData.get(i-1).getDictValue());
            }
        }

        //若更新状态值小于头状态,更新尾状态否则更新头尾状态
        if (minStatus < receiptHeader.getFirstStatus()){
            receiptHeader.setLastStatus(minStatus);
        } if (maxStatus > receiptHeader.getFirstStatus()){
            receiptHeader.setFirstStatus(maxStatus);
            receiptHeader.setLastStatus(minStatus);
            receiptHeaderService.updateById(receiptHeader);
        }

    }

    /**
     * 入库单审核
     * @param ids
     * @param approval
     * @return
     */
    @Override
    public AjaxResult approval(String ids, Integer approval) {
        ReceiptHeader receiptHeader = new ReceiptHeader();
        if (StringUtils.isEmpty(ids)){
            return AjaxResult.error("id不能为空");
        }
        Integer[] idArray = Convert.toIntArray(ids);
        for (Integer id: idArray) {
            receiptHeader.setId(id);
            receiptHeader.setLastStatus(approval);
            receiptHeader.setFirstStatus(approval);
            receiptHeader.setLastUpdatedBy(ShiroUtils.getLoginName());
            if (!receiptHeaderService.updateById(receiptHeader)){
                throw new ServiceException("更新头表失败");
            } else {
                LambdaQueryWrapper<ReceiptDetail> lambda = Wrappers.lambdaQuery();
                lambda.eq(ReceiptDetail::getReceiptId, id);
                List<ReceiptDetail> receiptDetails = this.list(lambda);
                for (ReceiptDetail receiptDetail : receiptDetails){
                    receiptDetail.setProcessStamp(QuantityConstant.RECEIPT_HEADER_POOL.toString());
                    receiptDetail = this.queryflow(receiptDetail);
                    if (!this.updateById(receiptDetail)){
                        throw new ServiceException("更新入库明细表失败");
                    }
                }
            }
            this.updateReceiptHeaderLastStatus(id);
        }
        return AjaxResult.success("审核完成");
    }

    /**
     * 判断明细中是否质检
     */
    public boolean inspection(ReceiptDetail receiptDetail){
        //如果明细中需要质检,则判断是否已经生成质检单
        if ("0".equals(receiptDetail.getQcCheck())){
            LambdaQueryWrapper<CheckHeader> lambda = Wrappers.lambdaQuery();
            lambda.eq(CheckHeader::getCode, receiptDetail.getReceiptCode());
            CheckHeader checkHeader = checkHeaderService.getOne(lambda);
            if (checkHeader == null){
                return true;
            }
        }
        return false;
    }
}