package com.sw.mes.itemclean.clean.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.sw.mes.core.annotation.Jinko;
import com.sw.mes.core.api.system.StoreFeignClients;
import com.sw.mes.core.api.system.YbFeignClients;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.dto.*;
import com.sw.mes.core.dto.sap.ReportSapChargItemDto;
import com.sw.mes.core.dto.sap.ReportSapGoodsmvtDto;
import com.sw.mes.core.dto.store.*;
import com.sw.mes.core.enums.EnumValuesFactory;
import com.sw.mes.core.enums.ItemCleanEnums;
import com.sw.mes.core.enums.MesToSapTypeEnum;
import com.sw.mes.core.enums.RecycleCleanSAPEnum;
import com.sw.mes.core.exception.BusinessException;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultCode;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.itemclean.clean.domain.*;
import com.sw.mes.itemclean.clean.dto.*;
import com.sw.mes.itemclean.clean.dto.boxNoOperate.BoxNoOperate;
import com.sw.mes.itemclean.clean.dto.boxNoOperate.MaterialNo;
import com.sw.mes.itemclean.clean.mapper.*;
import com.sw.mes.itemclean.clean.mapping.ScanBoxNoMapping;
import com.sw.mes.itemclean.clean.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sw.mes.itemclean.clean.vo.MaterialUnpackingVo;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 分选拆箱 服务实现类
 * </p>
 *
 * @author liuzemin
 * @since 2022-11-10
 */
@Service
public class MaterialUnpackingServiceImpl extends ServiceImpl<MaterialUnpackingMapper, MaterialUnpacking> implements MaterialUnpackingService, ScanBoxNoService {

    @Autowired
    GenerateBusinessNoService generateBusinessNoService;

    @Autowired
    MaterialApplyOrderService materialApplyOrderService;

    @Autowired
    ModelMapper modelMapper;

    @Autowired
    MaterialUnpackingMapper materialUnpackingMapper;

    @Autowired
    MaterialUnpackingDetailMapper materialUnpackingDetailMapper;

    @Autowired
    MaterialUnpackingDetailService materialUnpackingDetailService;

    @Autowired
    MaterialApplyOrderMapper materialApplyOrderMapper;

    @Autowired
    MaterialApplyOrderRelationMapper materialApplyOrderRelationMapper;

    @Autowired
    MaterialStoreSignBoxMapper materialStoreSignBoxMapper;

    @Autowired
    private MaterialStoreSignBoxService materialStoreSignBoxService;

    @Autowired
    private CleaningProcessFlowService cleaningProcessFlowService;

    @Autowired
    YbFeignClients ybFeignClients;

    @Autowired
    StoreFeignClients storeFeignClients;

    private final static String FX_MARK = "PP";

    @Override
    public BoxPropertyDto scanBoxNo(GeneralScanBoxNoParam param) {

        LambdaQueryWrapper<MaterialStoreSignBox> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialStoreSignBox::getMaterialBoxNo, param.getBoxNo());
        queryWrapper.eq(MaterialStoreSignBox::getPickingStatus, 1);
        queryWrapper.ne(MaterialStoreSignBox::getIsEmptyBox, 1);

//        queryWrapper.eq(MaterialStoreSignBox::getIsPack, 1);
//        queryWrapper.eq(MaterialStoreSignBox::getDelFlag, 0);
//        queryWrapper.in(MaterialStoreSignBox::getMaterialType, Arrays.asList(ItemCleanEnums.MaterialType.原生多晶.getKey()
//                ,ItemCleanEnums.MaterialType.回收料.getKey()
//                ,ItemCleanEnums.MaterialType.返工料.getKey()));
        queryWrapper.last("limit 1");
        MaterialStoreSignBox box = materialStoreSignBoxService.getOne(queryWrapper);
        if (box == null) {
            throw new RuntimeException(param.getBoxNo() + "该箱号不存在！");
        }
        if (box.getIsEmptyBox() == 1) {
            throw new RuntimeException(param.getBoxNo() + "该箱号为空箱！");
        }
        if (box.getMaterialType() == ItemCleanEnums.MaterialType.原生多晶.getKey()
                || box.getMaterialType() == ItemCleanEnums.MaterialType.回收料.getKey()
                || box.getMaterialType() == ItemCleanEnums.MaterialType.返工料.getKey()
        ){
            return ScanBoxNoMapping.toDto(box);
        }else {
            throw new RuntimeException(param.getScanName()+":当前箱号"+param.getBoxNo()+"属于"+ItemCleanEnums.MaterialType.getText(box.getMaterialType()));
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int createStorageSign(MaterialUnpackingVo materialUnpackingVo) {
        MaterialUnpacking materialUnpacking=fromVo(materialUnpackingVo);

        //新增
        if(materialUnpackingVo.getMaterialBoxNo()==null){
            //主表信息
            String materialBoxNo= generateBusinessNoService.generateBoxNo(new BoxNoOperate(ItemCleanEnums.BoxNoType.分选成箱,new MaterialNo(materialUnpackingVo.getMaterialCode())));
            materialUnpacking.setMaterialBoxNo(materialBoxNo);
            materialUnpacking.setCreateUser(BaseContextHandler.getUsername());
            materialUnpacking.setCreateTime(LocalDateTime.now());
            materialUnpacking.setStagingFlag(1);
            materialUnpacking.setDelFlag(0);
            this.saveOrUpdate(materialUnpacking);

            //附表信息
            List<MaterialUnpackingDetail> materialUnpackingDetails = materialUnpackingVo.getMaterialUnpackingDetails();
            for(MaterialUnpackingDetail materialUnpackingDetail:materialUnpackingDetails){
                materialUnpackingDetail.setMaterialBoxNo(materialBoxNo);
                materialUnpackingDetail.setCreateUser(BaseContextHandler.getUsername());
                materialUnpackingDetail.setCreateTime(LocalDateTime.now());
                materialUnpackingDetail.setDelFlag(0);
                materialUnpackingDetail.setMaterialType(materialUnpackingDetail.getMaterialType());
                // 更新原箱子的“是否空箱”字段
                MaterialStoreSignBox box = materialStoreSignBoxService.getByBoxNo(materialUnpackingDetail.getUnpackingBoxNo());
                if (box!=null && !box.getIsEmptyBox().equals(materialUnpackingDetail.getIsEmptyBox())){
                    box.setIsEmptyBox(materialUnpackingDetail.getIsEmptyBox());
                    materialStoreSignBoxService.saveOrUpdate(box);
                }
            }
            //批量插入附表信息
            materialUnpackingDetailService.insertUnpackingDetails(materialUnpackingDetails);
        }else{
            //修改
            materialUnpacking.setUpdateUser(BaseContextHandler.getUsername());
            materialUnpacking.setUpdateTime(LocalDateTime.now());
            materialUnpacking.setStagingFlag(1);
            materialUnpacking.setDelFlag(0);
            LambdaQueryWrapper<MaterialUnpacking> updateWrapper = new LambdaQueryWrapper<>();
            updateWrapper.eq(MaterialUnpacking::getMaterialBoxNo, materialUnpacking.getMaterialBoxNo());
            materialUnpackingMapper.update(materialUnpacking,updateWrapper);

            //删除附表相关子数据
            LambdaQueryWrapper<MaterialUnpackingDetail> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(MaterialUnpackingDetail::getMaterialBoxNo, materialUnpacking.getMaterialBoxNo());
            materialUnpackingDetailMapper.delete(queryWrapper);

            //插入新的附表数据
            List<MaterialUnpackingDetail> materialUnpackingDetails = materialUnpackingVo.getMaterialUnpackingDetails();

            for(MaterialUnpackingDetail materialUnpackingDetail:materialUnpackingDetails){
                materialUnpackingDetail.setCreateUser(BaseContextHandler.getUsername());
                materialUnpackingDetail.setCreateTime(LocalDateTime.now());
                materialUnpackingDetail.setUpdateUser(BaseContextHandler.getUsername());
                materialUnpackingDetail.setUpdateTime(LocalDateTime.now());
                materialUnpackingDetail.setDelFlag(0);
                materialUnpackingDetail.setMaterialBoxNo(materialUnpacking.getMaterialBoxNo());
                materialUnpackingDetail.setMaterialType(materialUnpackingDetail.getMaterialType());
                // 更新原箱子的“是否空箱”字段
                MaterialStoreSignBox box = materialStoreSignBoxService.getByBoxNo(materialUnpackingDetail.getUnpackingBoxNo());
                if (box!=null && !box.getIsEmptyBox().equals(materialUnpackingDetail.getIsEmptyBox())){
                    box.setIsEmptyBox(materialUnpackingDetail.getIsEmptyBox());
                    materialStoreSignBoxService.saveOrUpdate(box);
                }
            }
            //批量插入附表信息
            materialUnpackingDetailService.insertUnpackingDetails(materialUnpackingDetails);

        }
        return 1;
    }

    @Override
    public MaterialUnpackingVo selectStorageSign(String materialBoxNo) {

        LambdaQueryWrapper<MaterialUnpacking> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialUnpacking::getMaterialBoxNo, materialBoxNo);
        MaterialUnpacking MaterialUnpacking=materialUnpackingMapper.selectOne(queryWrapper);
        if(MaterialUnpacking==null) {
            return null;
        }
        MaterialUnpackingVo materialUnpackingVo=toLazyDto(MaterialUnpacking);

        LambdaQueryWrapper<MaterialUnpackingDetail> queryDetailWrapper = new LambdaQueryWrapper<>();
        queryDetailWrapper.eq(MaterialUnpackingDetail::getMaterialBoxNo, materialBoxNo);
        List<MaterialUnpackingDetail> materialUnpackingDetails=materialUnpackingDetailMapper.selectList(queryDetailWrapper);
        materialUnpackingVo.setMaterialUnpackingDetails(materialUnpackingDetails);

        return materialUnpackingVo;
    }


  /*  @Override
    @Transactional(rollbackFor = Exception.class)
    public String createFinishStorageSign(MaterialUnpackingVo materialUnpackingVo) {
        MaterialUnpacking materialUnpacking=fromVo(materialUnpackingVo);

//        List<MaterialApplyOrder> materialApplyOrderOrds=new ArrayList<>();

        List<MaterialApplyOrder> materialApplyOrderCxs=new ArrayList<>();
        List<MaterialApplyOrder> materialApplyOrderBcxs=new ArrayList<>();
        MaterialApplyOrder materialApplyOrderFxcx=new MaterialApplyOrder();

        //新增
        if(materialUnpackingVo.getMaterialBoxNo()==null){
            //新增主表信息
            String materialBoxNo= generateBusinessNoService.generateBoxNo(new BoxNoOperate(ItemCleanEnums.BoxNoType.分选成箱,new MaterialNo(materialUnpackingVo.getMaterialCode())));
            materialUnpacking.setMaterialBoxNo(materialBoxNo);
            materialUnpacking.setCreateUser(BaseContextHandler.getUsername());
            materialUnpacking.setCreateTime(LocalDateTime.now());
            materialUnpacking.setStagingFlag(0);
            materialUnpacking.setDelFlag(0);
            this.saveOrUpdate(materialUnpacking);

            //附表信息
            List<MaterialUnpackingDetail> materialUnpackingDetails = materialUnpackingVo.getMaterialUnpackingDetails();
            for(MaterialUnpackingDetail materialUnpackingDetail:materialUnpackingDetails){
                //１封装附表的数据行对象
                materialUnpackingDetail.setMaterialBoxNo(materialBoxNo);
                materialUnpackingDetail.setCreateUser(BaseContextHandler.getUsername());
                materialUnpackingDetail.setCreateTime(LocalDateTime.now());
                materialUnpackingDetail.setDelFlag(0);
                materialUnpackingDetail.setMaterialType(materialUnpackingDetail.getMaterialType());

                //２封装领料单新增拆箱记录的对象
                MaterialApplyOrder materialApplyOrder = materialApplyOrderService.selectMaterialOrder(materialUnpackingDetail);
                //新增拆箱记录的对象
                MaterialApplyOrder materialApplyOrderCx=new MaterialApplyOrder();
                BeanUtil.copyProperties(materialApplyOrder,materialApplyOrderCx,"id");
                materialApplyOrderCx.setMaterialProp(ItemCleanEnums.MaterialProp.分选拆箱.getKey());
                materialApplyOrderCx.setDelFlag(0);
                materialApplyOrderCx.setCreateUser(BaseContextHandler.getUsername());
                materialApplyOrderCx.setCreateTime(LocalDateTime.now());
                materialApplyOrderCxs.add(materialApplyOrderCx);


                //3封装领料单修改被拆箱记录　逻辑删除的　对象
                MaterialApplyOrder materialApplyOrdeBcx=new MaterialApplyOrder();
                BeanUtil.copyProperties(materialApplyOrdeBcx,materialApplyOrder);
                materialApplyOrdeBcx.setDelFlag(1);
                materialApplyOrdeBcx.setUpdateUser(BaseContextHandler.getUsername());
                materialApplyOrdeBcx.setUpdateTime(LocalDateTime.now());
                materialApplyOrderBcxs.add(materialApplyOrdeBcx);

                //4封装领料单分选成箱的记录对象
                BeanUtil.copyProperties(materialApplyOrder,materialApplyOrderFxcx,"id");
                materialApplyOrderFxcx.setMaterialProp(ItemCleanEnums.MaterialProp.分选成箱.getKey());
                materialApplyOrderFxcx.setMaterialBoxNo(materialUnpackingDetail.getMaterialBoxNo());
                materialApplyOrderFxcx.setDelFlag(0);
                materialApplyOrderFxcx.setWeight(materialUnpacking.getWeight());
                materialApplyOrderFxcx.setCreateUser(BaseContextHandler.getUsername());
                materialApplyOrderFxcx.setCreateTime(LocalDateTime.now());
                materialApplyOrderFxcx.setApplyTime(LocalDateTime.now());
                materialApplyOrderFxcx.setApplyName(BaseContextHandler.getUsername());

            }
            //批量插入附表信息
            materialUnpackingDetailService.insertUnpackingDetails(materialUnpackingDetails);
        }else{
            //修改主表信息
            materialUnpacking.setUpdateUser(BaseContextHandler.getUsername());
            materialUnpacking.setUpdateTime(LocalDateTime.now());
            materialUnpacking.setStagingFlag(0);

            LambdaQueryWrapper<MaterialUnpacking> updateWrapper = new LambdaQueryWrapper<>();
            updateWrapper.eq(MaterialUnpacking::getMaterialBoxNo, materialUnpacking.getMaterialBoxNo());
            materialUnpackingMapper.update(materialUnpacking,updateWrapper);

            //删除附表相关子数据
            LambdaQueryWrapper<MaterialUnpackingDetail> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(MaterialUnpackingDetail::getMaterialBoxNo, materialUnpacking.getMaterialBoxNo());
            materialUnpackingDetailMapper.delete(queryWrapper);

            //插入新的附表数据
            List<MaterialUnpackingDetail> materialUnpackingDetails = materialUnpackingVo.getMaterialUnpackingDetails();
            for(MaterialUnpackingDetail materialUnpackingDetail:materialUnpackingDetails){
                materialUnpackingDetail.setCreateUser(BaseContextHandler.getUsername());
                materialUnpackingDetail.setCreateTime(LocalDateTime.now());
                materialUnpackingDetail.setUpdateUser(BaseContextHandler.getUsername());
                materialUnpackingDetail.setUpdateTime(LocalDateTime.now());
                materialUnpackingDetail.setDelFlag(0);
                materialUnpackingDetail.setMaterialType(materialUnpackingDetail.getMaterialType());

                //２封装领料单新增拆箱记录的对象
                MaterialApplyOrder materialApplyOrder = materialApplyOrderService.selectMaterialOrder(materialUnpackingDetail);

                //新增拆箱记录的对象
                MaterialApplyOrder materialApplyOrderCx=new MaterialApplyOrder();
                BeanUtil.copyProperties(materialApplyOrder,materialApplyOrderCx,"id");
                materialApplyOrderCx.setMaterialProp(ItemCleanEnums.MaterialProp.分选拆箱.getKey());
                materialApplyOrderCx.setDelFlag(0);
                materialApplyOrderCx.setCreateUser(BaseContextHandler.getUsername());
                materialApplyOrderCx.setCreateTime(LocalDateTime.now());
                materialApplyOrderCxs.add(materialApplyOrderCx);


                //3封装领料单修改被拆箱记录　逻辑删除的　对象
                MaterialApplyOrder materialApplyOrdeBcx=new MaterialApplyOrder();
                BeanUtil.copyProperties(materialApplyOrdeBcx,materialApplyOrder);
                materialApplyOrdeBcx.setDelFlag(1);
                materialApplyOrdeBcx.setUpdateUser(BaseContextHandler.getUsername());
                materialApplyOrdeBcx.setUpdateTime(LocalDateTime.now());
                materialApplyOrderBcxs.add(materialApplyOrdeBcx);

                //4封装领料单分选成箱的记录对象
                BeanUtil.copyProperties(materialApplyOrder,materialApplyOrderFxcx,"id");
                materialApplyOrderFxcx.setMaterialProp(ItemCleanEnums.MaterialProp.分选成箱.getKey());
                materialApplyOrderFxcx.setMaterialBoxNo(materialUnpackingDetail.getMaterialBoxNo());
                materialApplyOrderFxcx.setDelFlag(0);
                materialApplyOrderFxcx.setWeight(materialUnpacking.getWeight());
                materialApplyOrderFxcx.setCreateUser(BaseContextHandler.getUsername());
                materialApplyOrderFxcx.setCreateTime(LocalDateTime.now());
                materialApplyOrderFxcx.setApplyTime(LocalDateTime.now());
                materialApplyOrderFxcx.setApplyName(BaseContextHandler.getUsername());
            }
            //批量插入附表信息
            materialUnpackingDetailService.insertUnpackingDetails(materialUnpackingDetails);
        }

        //一、处理领料单
        //1插入成箱数据行---增加一条6分选成箱的数据
        materialApplyOrderMapper.insert(materialApplyOrderFxcx);

        //2修改被拆箱的逻辑删除标志；把delFlag　从0修改为1
        for(MaterialApplyOrder materialApplyOrderBcx:materialApplyOrderBcxs){
            materialApplyOrderMapper.updateById(materialApplyOrderBcx);
        }

        //3插入被拆箱的数据行，其中　delFlag为0,materialProp　物料类型修改为　5分选拆箱
        for(MaterialApplyOrder materialApplyOrderCx:materialApplyOrderCxs){
            materialApplyOrderMapper.insert(materialApplyOrderCx);
        }
        //4生成拆箱和成箱之间的关联关系表
        for(MaterialApplyOrder materialApplyOrderCx:materialApplyOrderCxs){
            MaterialApplyOrderRelation materialApplyOrderRelation=new MaterialApplyOrderRelation();
            materialApplyOrderRelation.setMaterialBoxNoParent(materialApplyOrderCx.getMaterialBoxNo());
            materialApplyOrderRelation.setParentId(materialApplyOrderCx.getId());
            materialApplyOrderRelation.setSonId(materialApplyOrderFxcx.getId());
            materialApplyOrderRelation.setMaterialBoxNoSon(materialApplyOrderFxcx.getMaterialBoxNo());
            materialApplyOrderRelationMapper.insert(materialApplyOrderRelation);
        }

        // 二、打签箱暂存表：删除原拆箱箱号删除，新的箱号进行插入
        MaterialStoreSignBox materialStoreSignBox=new MaterialStoreSignBox();
        BeanUtil.copyProperties(materialUnpacking,materialStoreSignBox,"id");
        materialStoreSignBox.setPickingStatus(1);
        materialStoreSignBox.setDelFlag(0);
        materialStoreSignBox.setIsPack(1);
        materialStoreSignBox.setIsEmptyBox(0);

        materialStoreSignBoxMapper.insert(materialStoreSignBox);

        for(MaterialUnpackingDetail materialUnpackingDetail : materialUnpackingVo.getMaterialUnpackingDetails()){
            LambdaQueryWrapper<MaterialStoreSignBox> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(MaterialStoreSignBox::getMaterialBoxNo,materialUnpackingDetail.getUnpackingBoxNo());
            MaterialStoreSignBox ordMaterialStoreSignBox= materialStoreSignBoxMapper.selectOne(queryWrapper);
            ordMaterialStoreSignBox.setDelFlag(1);
            materialStoreSignBoxMapper.updateById(ordMaterialStoreSignBox);
        }

      return materialUnpacking.getMaterialBoxNo();
    }
*/

    /**
     * 升级后分选成箱-成箱打签功能
     *
     * @param materialUnpackingVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FxToBoxInfoPrintDto createFinishStorageSign(MaterialUnpackingVo materialUnpackingVo) {
        MaterialUnpacking materialUnpacking = fromVo(materialUnpackingVo);
        MaterialStoreSignBox materialStoreSignBox = materialStoreSignBoxService.useInfoByMaterialProductBatchNo(materialUnpackingVo.getProductBatchNo());

        //1 新增主表信息
        String ppProductBatch = generateBusinessNoService.generateBoxNoForUnpack(FX_MARK);
        if (StringUtils.isBlank(materialUnpacking.getMaterialCode())) {
            throw new BusinessException("物料编码为空:" + materialUnpacking.getMaterialCode());
        }
        materialUnpacking.setMaterialBoxNo(ppProductBatch);
        materialUnpacking.setFxProductBatchNo(ppProductBatch);
        materialUnpacking.setUnpackingBoxNo(materialStoreSignBox.getBoxNo());
        materialUnpacking.setCreateUser(BaseContextHandler.getUsername());
        materialUnpacking.setCreateTime(LocalDateTime.now());
        materialUnpacking.setStagingFlag(1);
        materialUnpacking.setOtherWeight(materialUnpackingVo.getOtherWeight());
        materialUnpacking.setDelFlag(ItemCleanEnums.MaterialDelFlag.未删除.getKey());
        materialUnpacking.setHasGone(materialUnpackingVo.getHasGone());
        materialUnpacking.setUseStatus(ItemCleanEnums.MaterialFxUseStatus.未使用.getKey());
        materialUnpacking.setActualWeight(materialUnpacking.getWeight());
        materialUnpacking.setDateProduceBatchNo(materialStoreSignBox.getDateProduceBatchNo());
        //2 附表信息
        List<MaterialUnpackingDetail> materialUnpackingDetails = materialUnpackingVo.getMaterialUnpackingDetails();
        if (CollectionUtils.isNotEmpty(materialUnpackingDetails)) {
            for (MaterialUnpackingDetail materialUnpackingDetail : materialUnpackingDetails) {
                //１封装附表的数据行对象
                materialUnpackingDetail.setMaterialBoxNo(ppProductBatch);
                materialUnpackingDetail.setCreateUser(BaseContextHandler.getUsername());
                materialUnpackingDetail.setCreateTime(LocalDateTime.now());
                materialUnpackingDetail.setDelFlag(0);
                materialUnpackingDetail.setMaterialType(materialUnpackingDetail.getMaterialType());
            }
        }

        //3、处理领料单
        BigDecimal usedWeightTotal = materialStoreSignBox.getUsedWeight().add(materialUnpackingVo.getWeight());
        BigDecimal unusedWeightTotal = materialStoreSignBox.getWeight().subtract(usedWeightTotal);
        if (unusedWeightTotal.compareTo(BigDecimal.ZERO) < 0) {
            throw new BusinessException("该箱:" + materialStoreSignBox.getBoxNo() + "物料重量不足!");
        }

        materialStoreSignBox.setUpdateUser(BaseContextHandler.getUsername());
        materialStoreSignBox.setUpdateTime(LocalDateTime.now());
        materialStoreSignBox.setUsedWeight(usedWeightTotal);
        materialStoreSignBox.setUnusedWeight(unusedWeightTotal);
        materialStoreSignBox.setHasGone(materialUnpackingVo.getHasGone());

        //4 分选完成,硅料原材料仓出库(要求: 维护的一定和余料工单的下个工序的副产品材料仓一致)+向sap报工原料消耗

            String warehouseCode = getWareHouseCodeByWorkOrderNo(materialUnpacking.getAufnr());
            String recycledMaterialCode = materialStoreSignBox.getMaterialCode();
            String recycledProductBatchNo = materialStoreSignBox.getProductBatchNo();
            Integer id = materialStoreSignBox.getId();
            //第一次分选的时候,关联被合批的批次全部出库
            if (ItemCleanEnums.MaterialUseStatus.已分选.getKey() != materialStoreSignBox.getUseStatus()
                    && ItemCleanEnums.MaterialUseStatus.已清空.getKey() != materialStoreSignBox.getUseStatus()) {
                String dateProduceBatchNo = materialStoreSignBox.getDateProduceBatchNo();
                WarehouseOutputBillBo warehouseOutputBillBo = newOutputBill(dateProduceBatchNo, recycledMaterialCode, materialStoreSignBox.getActualWeight(), recycledProductBatchNo, id, warehouseCode);
                Result<String> resultStore = storeFeignClients.outputApply(warehouseOutputBillBo);
                if (ResultCode.SUCCESS.getCode() != resultStore.getCode()) {
                    log.error("线边仓出库失败:" + resultStore.getMessage());
                    throw new BusinessException("线边仓出库失败:" + resultStore.getMessage());
                } else {
                    //第一次分选的时候,关联被合批的批次的重量全部消耗
                    try {
                        this.handleReportSapGoodsmvtDto(materialUnpacking.getAufnr(), recycledMaterialCode, dateProduceBatchNo, materialStoreSignBox.getWeight(), "KG", warehouseCode);
                    } catch (Exception e) {
                        log.error("硅料清洗分选异常:" + e.getMessage());
                    }
                }
            }
            //保存分选信息
            this.saveOrUpdate(materialUnpacking);
            //批量插入附表信息
            materialUnpackingDetailService.insertUnpackingDetails(materialUnpackingDetails);
            //处理领料单
            materialStoreSignBox.setUseStatus(ItemCleanEnums.MaterialUseStatus.已分选.getKey());
            if (unusedWeightTotal.compareTo(BigDecimal.ZERO) == 0) {
                materialStoreSignBox.setUseStatus(ItemCleanEnums.MaterialUseStatus.已清空.getKey());
            }
            materialStoreSignBox.setFxAufnr(materialUnpacking.getAufnr());
            materialStoreSignBoxService.updateById(materialStoreSignBox);
            //3 过站,分选出站,清洗待进站(老批次,箱号出站;新批次,箱号进入下一站点)
            cleaningProcessFlowService.outStation(materialStoreSignBox.getProductBatchNo(), materialStoreSignBox.getProductBatchNo(), materialUnpacking.getWeight(), materialUnpacking.getUnusedWeight(), materialUnpacking.getUsedWeight(), "", EnumValuesFactory.CleaningWipStorageCode.分选.getValue(), "", materialUnpackingVo.getUnpackingBoxNo(), EnumValuesFactory.CleaningWipStorageCode.领料.getValue(), EnumValuesFactory.CleaningWipStorageStatus.工序出站.getKey());

            cleaningProcessFlowService.inStation(materialUnpacking.getFxProductBatchNo(), materialUnpackingVo.getProductBatchNo(), materialUnpacking.getWeight(), materialUnpacking.getUnusedWeight(), materialUnpacking.getUsedWeight(), "", EnumValuesFactory.CleaningWipStorageCode.清洗.getValue(), "", materialUnpacking.getBoxNo(), EnumValuesFactory.CleaningWipStorageCode.分选.getValue(), EnumValuesFactory.CleaningWipStorageStatus.工序待进站.getKey());

        //5 返回打印对象
        FxToBoxInfoPrintDto fxToBoxInfoPrintDto = buildFxToBoxInfoPrintDto(materialUnpacking);
        return fxToBoxInfoPrintDto;
    }

    /**
     * 通过工单号获取 材料仓库位
     *
     * @param workOrderNo 计划工单
     * @return
     */
    @Jinko(author = "yyl", value = "通过工单号获取材料仓库位")
    private String getWareHouseCodeByWorkOrderNo(String workOrderNo) {
        //通过计划工单中的片区field4找到字典中的材料仓
        Result<ProductionOrderDto> productionOrder = ybFeignClients.getListByAufnr(workOrderNo);
        String field4 = "";
        String warehouseCode = "";
        if (productionOrder.getCode() != ResultCode.SUCCESS.getCode() || null == productionOrder.getData()) {
            throw new RuntimeException("工单查询异常：" + productionOrder.getMessage());
        }
        ProductionOrderDto orderData = productionOrder.getData();
        if (null != orderData) {
            field4 = orderData.getField4();
        }
        if (null != field4) {
            Result<DictionaryItemDto> dictionaryItemDtoResult = ybFeignClients.findNameByThemeValueAndItemValue("ByProductWarehouseLocation", field4);
            if (null != dictionaryItemDtoResult && null != dictionaryItemDtoResult.getData() && ResultCode.SUCCESS.getCode() == dictionaryItemDtoResult.getCode()) {
                warehouseCode = dictionaryItemDtoResult.getData().getExtendValue();
            } else {
                throw new BusinessException(dictionaryItemDtoResult.getMessage() + "详情: 关键字[ByProductWarehouseLocation]中的[工作中心编码]: " + field4 + " 未配置");
            }
        }
        return warehouseCode;
    }

    @Override
    public MaterialUnpacking getByBoxNo(String boxNo) {
        LambdaQueryWrapper<MaterialUnpacking> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialUnpacking::getBoxNo, boxNo);
        queryWrapper.eq(MaterialUnpacking::getDelFlag, ItemCleanEnums.MaterialDelFlag.未删除.getKey());
        queryWrapper.orderByDesc(MaterialUnpacking::getCreateTime);
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }

    @Override
    public MaterialUnpacking getFxProductBatchNo(String fxProductBatchNo) {
        LambdaQueryWrapper<MaterialUnpacking> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialUnpacking::getFxProductBatchNo, fxProductBatchNo);
        queryWrapper.eq(MaterialUnpacking::getDelFlag, ItemCleanEnums.MaterialDelFlag.未删除.getKey());
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }

    /**
     * 根据余料批次号查询分选过的信息(包含已删除的)
     *
     * @param productBatchNo    余料批次号
     * @return
     */
    @Override
    public MaterialUnpacking getAufnrByProductBatchNo(String productBatchNo) {
        LambdaQueryWrapper<MaterialUnpacking> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialUnpacking::getProductBatchNo, productBatchNo);
        queryWrapper.in(MaterialUnpacking::getDelFlag, ItemCleanEnums.MaterialDelFlag.未删除.getKey(), ItemCleanEnums.MaterialDelFlag.已删除.getKey());
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }

    @Override
    public MaterialUnpacking getByPpProductBatchNo(String fxProductBatchNo) {
        LambdaQueryWrapper<MaterialUnpacking> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialUnpacking::getFxProductBatchNo, fxProductBatchNo);
        queryWrapper.eq(MaterialUnpacking::getDelFlag, ItemCleanEnums.MaterialDelFlag.未删除.getKey());
        queryWrapper.eq(MaterialUnpacking::getUseStatus,  ItemCleanEnums.MaterialFxUseStatus.未使用.getKey());
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }

    @Override
    public List<MaterialUnpacking> getMaterialUnpackingByPpProductBatchNo(List<String> ppProductBatchNo) {
        LambdaQueryWrapper<MaterialUnpacking> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(MaterialUnpacking::getFxProductBatchNo, ppProductBatchNo);
        return this.list(queryWrapper);
    }

    /**
     * 获取可以使用的分选物料
     * @param fxProductBatchNo
     * @return
     */
    @Override
    public MaterialUnpacking getCanUseByPpProductBatchNo(String fxProductBatchNo) {
        LambdaQueryWrapper<MaterialUnpacking> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialUnpacking::getFxProductBatchNo, fxProductBatchNo);
        queryWrapper.eq(MaterialUnpacking::getDelFlag, ItemCleanEnums.MaterialDelFlag.未删除.getKey());
        queryWrapper.in(MaterialUnpacking::getUseStatus, ItemCleanEnums.MaterialFxUseStatus.未使用.getKey(), ItemCleanEnums.MaterialFxUseStatus.已使用.getKey(),ItemCleanEnums.MaterialFxUseStatus.已合批.getKey());
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }

    @Override
    public void updateBoxStatus(String unpackingBoxNo, BigDecimal unusedWeightTotal, String boxNo) {
        BigDecimal allowUnusedWeight = BigDecimal.ZERO;
        Result<List<DictionaryItemDto>> result = ybFeignClients.findByThemeValue("allow_unusedWeight");
        if (result.getCode() == ResultCode.SUCCESS.getCode()) {
            List<DictionaryItemDto> dictionaryItemDtoList = result.getData();
            for (DictionaryItemDto dto : dictionaryItemDtoList) {
                allowUnusedWeight = new BigDecimal(dto.getValue());
            }
        }

        //2.1 被领料载具使用状态可能变更,通过剩余重量和字典配置比较判断是否释放箱子
        if (unusedWeightTotal.compareTo(allowUnusedWeight) <= 0) {
            CarrierConfigDto carrierConfigDto = new CarrierConfigDto();
            carrierConfigDto.setCarrierNo(unpackingBoxNo);
            carrierConfigDto.setStatus(0);
            ybFeignClients.updateCarrierConfigStatus(carrierConfigDto);
        }
        //2.2 领料载具使用状态变更为使用中
        CarrierConfigDto carrierConfigDto = new CarrierConfigDto();
        if(null != boxNo){
            carrierConfigDto.setCarrierNo(boxNo);
            carrierConfigDto.setStatus(1);
            ybFeignClients.updateCarrierConfigStatus(carrierConfigDto);
        }
    }

    /**
     * 供清洗上料使用
     * @param currentProductBatchNo
     * @return
     */
    @Override
    public MaterialUnpacking getUseInfoByPpProductBatchNo(String currentProductBatchNo) {
        LambdaQueryWrapper<MaterialUnpacking> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialUnpacking::getFxProductBatchNo, currentProductBatchNo);
        queryWrapper.eq(MaterialUnpacking::getDelFlag, ItemCleanEnums.MaterialDelFlag.未删除.getKey());
        queryWrapper.in(MaterialUnpacking::getUseStatus, ItemCleanEnums.MaterialFxUseStatus.未使用.getKey(), ItemCleanEnums.MaterialFxUseStatus.已使用.getKey());
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }

    /**
     *
     * 供破碎上料使用
     * @param boxNo
     * @return
     */
    @Override
    public MaterialUnpacking getUnUseInfoByBoxNo(String boxNo) {
        LambdaQueryWrapper<MaterialUnpacking> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialUnpacking::getBoxNo, boxNo);
        queryWrapper.eq(MaterialUnpacking::getDelFlag, ItemCleanEnums.MaterialDelFlag.未删除.getKey());
        queryWrapper.eq(MaterialUnpacking::getHasGone, ItemCleanEnums.MaterialHasGone.破碎.getValue());
        queryWrapper.eq(MaterialUnpacking::getUseStatus, ItemCleanEnums.MaterialFxUseStatus.未使用.getKey());
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }

    @Override
    public IPage<MaterialUnpackingJoinPageDto> queryList(IPage<MaterialUnpackingJoinPageDto> iPage, MaterialUnpackingParamQuery query) {
        return materialUnpackingMapper.queryList(iPage, query);
    }

    @Override
    public List<MaterialUnpackingJoinPageDto> queryListByParam(MaterialUnpackingParamQuery query) {
        return materialUnpackingMapper.queryList(query);
    }

    @Override
    public List<MaterialUnpacking> getByParentId(Integer parentId) {
        LambdaQueryWrapper<MaterialUnpacking> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialUnpacking::getParentId, parentId);
        queryWrapper.eq(MaterialUnpacking::getDelFlag, ItemCleanEnums.MaterialDelFlag.未删除.getKey());
        queryWrapper.eq(MaterialUnpacking::getUseStatus, ItemCleanEnums.MaterialUseStatus.已合批.getKey());
        return this.list(queryWrapper);
    }

    @Override
    public Result revertWeightById(Integer id) {
        //1 校验分选信息是否存在
        MaterialUnpacking materialUnpacking = materialUnpackingMapper.selectById(id);
        if (null == materialUnpacking) {
            return ResultGenerator.fail("分选信息不存在");
        }
        //分选信息状态
        Integer useStatus = materialUnpacking.getUseStatus();
        //余料批次
        String productBatchNo = materialUnpacking.getProductBatchNo();
        //分选重量
        BigDecimal unpackingWeight = materialUnpacking.getWeight();

        if (!useStatus.equals(ItemCleanEnums.MaterialFxUseStatus.未使用.getKey())) {
            return ResultGenerator.fail("分选信息已使用过,不允许删除!");
        }
        //2 查询领料信息
        MaterialStoreSignBox materialStoreSignBox = materialStoreSignBoxService.getUsedInfoByProductBatchNo(productBatchNo);
        //3 回退重量,删除分选信息
        BigDecimal unusedWeight = materialStoreSignBox.getUnusedWeight();
        BigDecimal usedWeight = materialStoreSignBox.getUsedWeight();
        BigDecimal weight = materialStoreSignBox.getWeight();
        //重置领料表未使用重量
        BigDecimal revertUnusedWeight = unusedWeight.add(unpackingWeight);
        //重置领料表已使用重量
        BigDecimal revertUsedWeight = usedWeight.subtract(unpackingWeight);
        if (revertUnusedWeight.compareTo(weight) > 0) {
            return ResultGenerator.fail("异常: 回退领料表总重量: " + revertUnusedWeight + "大于领料表总重量" + weight);
        }
        if (revertUsedWeight.compareTo(BigDecimal.ZERO) < 0) {
            return ResultGenerator.fail("异常: 回退领料表已使用重量: " + revertUsedWeight + "小于0");
        }
        materialStoreSignBox.setUnusedWeight(revertUnusedWeight);
        materialStoreSignBox.setUsedWeight(revertUsedWeight);
        //重置领料表数据 使用状态
        materialStoreSignBox.setUseStatus(ItemCleanEnums.MaterialUseStatus.已分选.getKey());
        materialStoreSignBox.setUpdateUser(BaseContextHandler.getUsername());
        materialStoreSignBox.setUpdateTime(LocalDateTime.now());
        materialStoreSignBoxService.updateById(materialStoreSignBox);
        //删除分选信息
        materialUnpackingMapper.deleteById(id);
        return ResultGenerator.success();
    }

    /**
     * 分选合批处理方法。
     * 对于给定的物料分选信息列表，进行合批处理，包括校验、合并信息更新等操作。
     *
     * @param dtos 物料信息列表，不可为null且至少包含一条记录。
     *             <p>
     *             注意：该方法不支持返回值，但会在执行过程中根据条件抛出运行时异常。
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void blending(List<MaterialUnpacking> dtos) {
        if (dtos != null && dtos.size() > 0) {
            //校验是否存在重复的pp号
            List<String> fxProductBatchNos = new ArrayList<>();
            fxProductBatchNos = dtos.stream().map(temp -> temp.getFxProductBatchNo()).collect(Collectors.toList());
            HashSet<String> hashSet = new HashSet<>(fxProductBatchNos);
            if (fxProductBatchNos.size() != hashSet.size()) {
                throw new RuntimeException("分选批次号重复!");
            }
            //物料编码
            String materialCode;
            String fxProductBatchNo = dtos.get(0).getFxProductBatchNo();
            MaterialUnpacking unpacking = this.getByPpProductBatchNo(fxProductBatchNo);
            if (null == unpacking) {
                throw new RuntimeException("不存在分选批次号为【" + fxProductBatchNo + "】的未使用数据");
            }
            for (MaterialUnpacking dto : dtos) {
                MaterialUnpacking materialUnpacking = null;
                materialUnpacking = this.getByPpProductBatchNo(dto.getFxProductBatchNo());
                if (null == materialUnpacking) {
                    throw new RuntimeException("不存在分选批次号为【" + dto.getFxProductBatchNo() + "】的未使用数据");
                }
                materialCode = unpacking.getMaterialCode();
                if (!materialUnpacking.getMaterialCode().equals(materialCode)) {
                    throw new RuntimeException("存在" + materialCode + "和 " + materialUnpacking.getMaterialCode() + " 不同物料编码的物料,无法合批");
                }
                String materialLevel = unpacking.getMaterialLevel();
                if (!materialUnpacking.getMaterialLevel().equals(materialLevel)) {
                    throw new RuntimeException("存在" + materialLevel + "和 " + materialUnpacking.getMaterialLevel() + " 不同等级的物料,无法合批");
                }
                String materialGear = unpacking.getMaterialGear();
                if (!materialUnpacking.getMaterialGear().equals(materialGear)) {
                    throw new RuntimeException("存在" + materialGear + "和 " + materialUnpacking.getMaterialGear() + " 不同档位的物料,无法合批");
                }
                String hasGone = unpacking.getHasGone();
                if (!materialUnpacking.getHasGone().equals(hasGone)) {
                    throw new RuntimeException("存在" + hasGone + "和 " + materialUnpacking.getHasGone() + " 不同工艺去向的物料,无法合批");
                }
                String aufnr = unpacking.getAufnr();
                if (!materialUnpacking.getAufnr().equals(aufnr)) {
                    throw new RuntimeException("存在" + aufnr + "和 " + materialUnpacking.getAufnr() + " 不同工单号的物料,无法合批");
                }
            }
            //总重量
            BigDecimal quantityClaimed = dtos.stream().map(dto -> dto.getWeight()).reduce(BigDecimal.ZERO, BigDecimal::add);
            //用重量最大的当做合并物料的新箱号
            MaterialUnpacking materialUnpacking = dtos.stream().max(Comparator.comparing(MaterialUnpacking::getWeight)).get();
            MaterialUnpacking blendingSignBox = this.getByPpProductBatchNo(materialUnpacking.getFxProductBatchNo());
            blendingSignBox.setWeight(quantityClaimed);
            blendingSignBox.setUnusedWeight(quantityClaimed);
            blendingSignBox.setUsedWeight(BigDecimal.ZERO);
            blendingSignBox.setUpdateTime(LocalDateTime.now());
            blendingSignBox.setUpdateUser(BaseContextHandler.getUsername());
            this.updateById(blendingSignBox);

            //其他被合批箱子要置空,变更状态为使用
            for (MaterialUnpacking signBoxDto : dtos) {
                if (!signBoxDto.getFxProductBatchNo().equals(blendingSignBox.getFxProductBatchNo())) {
                    String useProductBatchNo = signBoxDto.getFxProductBatchNo();
                    MaterialUnpacking useSignBox = this.getByPpProductBatchNo(useProductBatchNo);
                    if (null != useSignBox) {
                        //查找被合批的id是否存在关联合批数据
                        List<MaterialUnpacking> list = this.getByParentId(useSignBox.getId());
                        if (CollectionUtil.isNotEmpty(list)) {
                            for (MaterialUnpacking signBox : list) {
                                signBox.setParentId(blendingSignBox.getId());
                                signBox.setUpdateTime(LocalDateTime.now());
                                signBox.setUpdateUser(BaseContextHandler.getUsername());
                                signBox.setBlendingUser(BaseContextHandler.getUsername());
                                signBox.setBlendingTime(LocalDateTime.now());
                                signBox.setBlendingProductBatchNo(blendingSignBox.getFxProductBatchNo());
                                this.updateById(signBox);
                            }
                        }
                        useSignBox.setUsedWeight(useSignBox.getWeight());
                        useSignBox.setUnusedWeight(BigDecimal.ZERO);
                        useSignBox.setUseStatus(ItemCleanEnums.MaterialFxUseStatus.已合批.getKey());
                        useSignBox.setParentId(blendingSignBox.getId());
                        useSignBox.setUpdateTime(LocalDateTime.now());
                        useSignBox.setUpdateUser(BaseContextHandler.getUsername());
                        useSignBox.setBlendingUser(BaseContextHandler.getUsername());
                        useSignBox.setBlendingTime(LocalDateTime.now());
                        useSignBox.setBlendingProductBatchNo(blendingSignBox.getFxProductBatchNo());
                        this.updateById(useSignBox);
                    }
                }
            }
        } else {
            throw new RuntimeException("绑定数据小于2条,不允许合批操作!");
        }
    }


    public MaterialUnpackingVo toLazyDto(MaterialUnpacking entity) {
        return modelMapper.map(entity, MaterialUnpackingVo.class);
    }

    public MaterialUnpacking fromVo(MaterialUnpackingVo vo) {
        return modelMapper.map(vo, MaterialUnpacking.class);
    }

    /**
     * 构建分选成箱打签数据
     * @param materialUnpacking
     * @return
     */
    public FxToBoxInfoPrintDto buildFxToBoxInfoPrintDto(MaterialUnpacking materialUnpacking) {
        // 查询物料编码所属厂家
      /*  Result<MaterialCleanModelDto> result = ybFeignClients.findMaterialCleanByCode(materialUnpacking.getMaterialCode());
        if (!result.getCode().equals(ResultCode.SUCCESS.code)) {
            throw new RuntimeException("查询原料清洗产品模型发生错误");
        }
        MaterialCleanModelDto dto = result.getData();
        if (dto == null) {
            throw new RuntimeException("不存在" + materialUnpacking.getMaterialCode() + "原料清洗产品模型！");
        }*/
        FxToBoxInfoPrintDto fxToBoxInfoPrintDto = new FxToBoxInfoPrintDto();
        fxToBoxInfoPrintDto.setBoxNo(materialUnpacking.getBoxNo())
                .setFxProductBatchNo(materialUnpacking.getFxProductBatchNo())
                .setProductBatchNo(materialUnpacking.getProductBatchNo())
               // .setFromMark(dto.getFactoryCode())
                .setMaterialName(materialUnpacking.getMaterialName())
                .setMaterialCode(materialUnpacking.getMaterialCode())
                .setCreateTime(new Date())
                .setWeight(String.valueOf(materialUnpacking.getWeight()))
                .setMaterialModel(materialUnpacking.getMaterialModel())
                .setMaterialGear(materialUnpacking.getMaterialGear())
                .setMaterialLevel(materialUnpacking.getMaterialLevel())
                .setClassNo(BaseContextHandler.getUserClassNo())
                .setRemark("");
        return fxToBoxInfoPrintDto;
    }

//    public MaterialApplyOrder toMaterialApplyOrder(MaterialUnpacking materialUnpacking) {
//        MaterialApplyOrder materialApplyOrder = modelMapper.map(materialUnpacking, MaterialApplyOrder.class);
//        materialApplyOrder.setMaterialProp(ItemCleanEnums.MaterialProp.分选成箱.getKey());
//        return materialApplyOrder;
//    }



    public MaterialApplyOrder detailToMaterialApplyOrder(MaterialUnpackingDetail materialUnpackingDetail) {
        MaterialApplyOrder materialApplyOrder = modelMapper.map(materialUnpackingDetail, MaterialApplyOrder.class);
        materialApplyOrder.setMaterialProp(ItemCleanEnums.MaterialProp.分选成箱.getKey());
        return materialApplyOrder;
    }

    /**
     * 消耗副产品报给内部系统,供上报sap使用
     *
     * @param workOrderNo    工单
     * @param materialCode   物料编码
     * @param produceBatchNo 产品批次
     * @param weight         数量(重量)
     * @param unitName       单位(KG,PC)
     * @param warehouseCode       库存地点编码
     */
    @Jinko(author = "yyl", value = "消耗副产品报给内部系统,供上报sap使用")
    private void handleReportSapGoodsmvtDto(String workOrderNo, String materialCode, String produceBatchNo, BigDecimal weight, String unitName,String warehouseCode) {
        ReportSapGoodsmvtDto reportSapGoodsmvtDto = new ReportSapGoodsmvtDto();
        List<ReportSapChargItemDto> reportSapChargItemDtos = new ArrayList<>();
        ReportSapChargItemDto reportSapChargItemDto = new ReportSapChargItemDto();
//        reportSapChargItemDto.setAtnam("P01");
//        reportSapChargItemDto.setAtwrt("JK1");
        reportSapChargItemDtos.add(reportSapChargItemDto);
        reportSapGoodsmvtDto.setChargItems(reportSapChargItemDtos);
        reportSapGoodsmvtDto.setAufnr(workOrderNo);
        reportSapGoodsmvtDto.setCharg(produceBatchNo);
        reportSapGoodsmvtDto.setBwart("261");
        reportSapGoodsmvtDto.setWerks("5041");
        reportSapGoodsmvtDto.setMatnr(materialCode);
        reportSapGoodsmvtDto.setMenge(weight == null ? "0" : weight.toString());
        reportSapGoodsmvtDto.setMeins(unitName);
        reportSapGoodsmvtDto.setZfcpFlag("X");
        reportSapGoodsmvtDto.setLgort(warehouseCode);
        reportSapGoodsmvtDto.setProcName(RecycleCleanSAPEnum.硅料清洗分选.getDesc());
        ybFeignClients.sendSapGoodsmvt(reportSapGoodsmvtDto);
        materialStoreSignBoxService.doMesToSapRecord(reportSapGoodsmvtDto, MesToSapTypeEnum.硅料清洗分选.getCode());
    }


    /**
     * 清洗硅料副产品从材料仓出库,被消耗
     *
     * @param dateProduceBatchNo     日批次号
     * @param recycledMaterialCode   物料编码
     * @param actualWeight           合批前的实际重量
     * @param recycledProductBatchNo 内部批次号
     * @param id                     父批次id
     * @param warehouseCode          库位
     * @return
     */
    private WarehouseOutputBillBo newOutputBill(String dateProduceBatchNo, String recycledMaterialCode, BigDecimal actualWeight, String recycledProductBatchNo, Integer id, String warehouseCode) {
        WarehouseOutputBillBo outputBillBo = new WarehouseOutputBillBo();
        outputBillBo.setType("生产领用");
        outputBillBo.setAutoAudit(true);
        outputBillBo.setDestination("车间");
        List<WarehouseOutputBillDetailBo> boList = new ArrayList<>();

        Result<MaterialModelDto> result = ybFeignClients.getMaterialByCode(recycledMaterialCode);
        MaterialModelDto model = result.getData();
        if (model == null) {
            throw new BusinessException("【" + recycledMaterialCode + "】物料主数据不存在，请检查数据！");
        }
        List<MaterialStoreSignBox> list = materialStoreSignBoxService.getByParentId(id);
        if (CollectionUtil.isNotEmpty(list)) {
            //封装关联批次明细
            for (MaterialStoreSignBox signBox : list) {
                WarehouseOutputBillDetailBo bo = new WarehouseOutputBillDetailBo();
                bo.setMaterialModelId(model.getId().longValue());
                bo.setMaterialModelCode(model.getCode());
                bo.setMaterialModelName(model.getName());
                bo.setBatchNo(signBox.getProductBatchNo());
                bo.setCrystalNo(signBox.getDateProduceBatchNo());
                bo.setMaterialTypeName(model.getMaterialTypeDto().getName());
                bo.setSupplier(model.getSupplier());
                bo.setSpecification(model.getSpecification());
                bo.setMaterialTh(model.getNumberOfDrawings());
                bo.setRequireCount(signBox.getActualWeight());
                bo.setUnitName(model.getUnitDto().getName());
                bo.setWarehouseName(warehouseCode);
                bo.setWarehouseCode(warehouseCode);
                boList.add(bo);
            }
        }
        //封装自己本身
        WarehouseOutputBillDetailBo bo = new WarehouseOutputBillDetailBo();
        bo.setMaterialModelId(model.getId().longValue());
        bo.setMaterialModelCode(model.getCode());
        bo.setMaterialModelName(model.getName());
        bo.setBatchNo(recycledProductBatchNo);
        bo.setCrystalNo(dateProduceBatchNo);
        bo.setMaterialTypeName(model.getMaterialTypeDto().getName());
        bo.setSupplier(model.getSupplier());
        bo.setSpecification(model.getSpecification());
        bo.setMaterialTh(model.getNumberOfDrawings());
        bo.setRequireCount(actualWeight);
        bo.setUnitName(model.getUnitDto().getName());
        bo.setWarehouseName(warehouseCode);
        bo.setWarehouseCode(warehouseCode);
        boList.add(bo);
        outputBillBo.setOutputBillDetails(boList);
        return outputBillBo;
    }
}
