ErpManagerImpl.java

package com.mycim.server.erp.manager.impl;

import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.exception.SystemIllegalArgumentException;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.jdbc.Page;
import com.mycim.framework.logging.Logger;
import com.mycim.framework.logging.LoggerFactory;
import com.mycim.framework.utils.beans.BeanUtils;
import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.framework.utils.lang.collections.CollectionUtils;
import com.mycim.framework.utils.lang.collections.MapUtils;
import com.mycim.framework.utils.lang.math.NumberUtils;
import com.mycim.framework.utils.lang.time.DateUtils;
import com.mycim.server.asm.manager.LotInventoryManager;
import com.mycim.server.asm.manager.MaterialManager;
import com.mycim.server.asm.manager.WarehouseManager;
import com.mycim.server.base.manager.NamedObjectManager;
import com.mycim.server.base.manager.TransactionLogManager;
import com.mycim.server.erp.dao.ErpDao;
import com.mycim.server.erp.dto.*;
import com.mycim.server.erp.manager.ErpManager;
import com.mycim.server.prp.manager.OperationManager;
import com.mycim.server.prp.manager.ProductManager;
import com.mycim.server.prp.manager.ProductVersionManager;
import com.mycim.server.system.manager.FacilityManager;
import com.mycim.server.system.manager.ReferenceFileManager;
import com.mycim.server.wip.manager.LotManager;
import com.mycim.server.wip.manager.LotQueryManager;
import com.mycim.server.wip.manager.UnitQueryManager;
import com.mycim.server.workorder.manager.WorkOrderManager;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.SystemConstant;
import com.mycim.valueobject.bas.TransactionLog;
import com.mycim.valueobject.consts.*;
import com.mycim.valueobject.erp.ErpMesProductBindBean;
import com.mycim.valueobject.inv.LotInventoryDO;
import com.mycim.valueobject.inv.MaterialDO;
import com.mycim.valueobject.inv.WarehouseTransBO;
import com.mycim.valueobject.inv.value.WarehouseNames;
import com.mycim.valueobject.prp.Item;
import com.mycim.valueobject.prp.Operation;
import com.mycim.valueobject.prp.WorkOrder;
import com.mycim.valueobject.prp.WorkOrderLine;
import com.mycim.valueobject.sys.ReferenceFileDetail;
import com.mycim.valueobject.wip.Lot;
import com.mycim.valueobject.wip.LotStatus;
import com.mycim.valueobject.wip.TransReason;
import com.mycim.valueobject.wip.Unit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Luopeng.Wang
 * @version 6.0.0
 * @date 2021/5/21
 **/
@Service
@Transactional
public class ErpManagerImpl implements ErpManager {

    private final static Logger logger = LoggerFactory.getLogger(ErpManagerImpl.class);

    @Autowired
    private MaterialManager materialManager;

    @Autowired
    private NamedObjectManager namedObjectManager;

    @Autowired
    private ErpDao erpDao;

    @Autowired
    private ProductManager productManager;

    @Autowired
    private ProductVersionManager productVersionManager;

    @Autowired
    private WorkOrderManager workOrderManager;

    @Autowired
    private WarehouseManager warehouseManager;

    @Autowired
    private ReferenceFileManager referenceFileManager;

    @Autowired
    private LotInventoryManager lotInventoryManager;

    @Autowired
    private OperationManager operationManager;

    @Autowired
    private LotManager lotManager;

    @Autowired
    private LotQueryManager lotQueryManager;

    @Autowired
    private UnitQueryManager unitQueryManager;

    @Autowired
    private FacilityManager facilityManager;

    @Autowired
    private TransactionLogManager transactionLogManager;

    @Override
    public void receiveErpMaterial(ErpMaterialDto erpMaterialDto) {

        String materialId = erpMaterialDto.getMatnr();
        String storeUom = erpMaterialDto.getMeins();
        String type = erpMaterialDto.getMtart();
        String semi = StringUtils.equalsIgnoreCase(erpMaterialDto.getSemiFinish(), ErpConstants.SEMI_FINISH_FLAG)?ErpConstants.SEMI_FINISH_FLAG:null;

        Assert.isFalse(StringUtils.isEmpty(materialId),
                       Errors.create().key(MessageIdList.MATERIAL_ID_NOT_EMPTY).content("Material Id can not be empty!").build());

        //原材料数据进行新增修改,暂不支持删除
        //只有Z001类型的物料,才接收
        //通过类表查询对应的ObjectType和ObjectSubType,若没有则报错。
        ReferenceFileDetail referenceFileDetail = new ReferenceFileDetail(ReferenceDetailNames.ERP_TYPE_DEFINITION, namedObjectManager
                .getNamedSpace(LocalContext.getFacilityRrn(), ObjectList.REFERENCE_FILE_KEY), ObjectList.REFERENCE_FILE_KEY);
        referenceFileDetail.setKey1Value(type);
        referenceFileDetail.setKey2Value(" ");
        ReferenceFileDetail detail = referenceFileManager.getReferenceFileDetail(referenceFileDetail);
        String objectType = detail.getData1Value();
        String objectSubType = detail.getData2Value();
        if (StringUtils.isNotBlank(objectType)) {
            MaterialDO material = new MaterialDO(materialId, namedObjectManager.getNamedSpace(LocalContext.getFacilityRrn(), ObjectList.ITEM_KEY), ObjectList.ITEM_KEY);
            material = materialManager.getMaterial(material);

            if (material == null || material.getInstanceRrn() <= 0) {
                material = new MaterialDO(materialId, namedObjectManager.getNamedSpace(LocalContext.getFacilityRrn(), ObjectList.ITEM_KEY), ObjectList.ITEM_KEY);
                material.setObjectType(objectType);
                material.setInstanceId(materialId);
                material.setStoreUom(storeUom);
                material.setObjectSubtype(objectSubType);
                material.setItemClass(SystemConstant.Str.WAFER);
                material.setTransId(TransactionNames.CREATE_KEY);
                material.setSubproductFlag(semi);//半成品标记
                materialManager.insertMaterial(material);
            } else {
                material.setObjectSubtype(objectSubType);
                material.setStoreUom(storeUom);
                material.setSubproductFlag(semi);//半成品标记
                materialManager.updateMaterial(material);
            }
        } else {
            throw new SystemIllegalArgumentException(
                    Errors.create().content("MES cannot match MTART {} ").args(type).build());
        }

        this.changeErpMaterialStatus(erpMaterialDto, ErpConstants.STATUS_SUCCESS);
    }

    @Override
    public void receiveErpWorkOrder(ErpWorkOrderDto workOrderDto) {
        String workOrderId = workOrderDto.getAufnr();//工单ID
        String productId = workOrderDto.getPlnbez();//产品ID
        Integer plannedYield = workOrderDto.getGamng();
        String startDay = workOrderDto.getGstrp();
        String requiredDay = workOrderDto.getGltrp();
        String dueDay = workOrderDto.getEtdat();
        String customerOrder = workOrderDto.getKdauf();//销售订单号
        String customerOrderNo = workOrderDto.getKdpos();

        String erpClient = workOrderDto.getMandt();
        String erpFactory = workOrderDto.getWerks();
        String workOrderType = workOrderDto.getAuart();

        //MES与ERP的产品和工单需要对应,因此废弃此段代码。
        //plnbez字段为 产品ID,mes中未创建,则创建默认 。
        // Item item = new Item(productId, namedObjectManager.getNamedSpace(LocalContext.getFacilityRrn(), ObjectList.PRODUCT_KEY), ObjectList.PRODUCT_KEY);
        // item = productManager.getItem(item);
        // if (item == null || item.getInstanceRrn() <= 0) {
        //     item = new Item(productId,
        //                     namedObjectManager.getNamedSpace(LocalContext.getFacilityRrn(), ObjectList.PRODUCT_KEY),
        //                     ObjectList.PRODUCT_KEY);
        //     item.setSumLoopCount(0);
        //     long productRrn = productManager.insertItem(item);
        //
        //     productVersionManager.addProductVersion(productRrn, 0);
        // }

        WorkOrder workOrder = new WorkOrder(workOrderId, namedObjectManager
                .getNamedSpace(LocalContext.getFacilityRrn(), ObjectList.WORKORDER), ObjectList.WORKORDER);

        WorkOrder queryWorkOrder = workOrderManager.getWorkOrderById(workOrderId);
        if (queryWorkOrder == null || queryWorkOrder.getInstanceRrn() <= 0) {
            workOrder.setWorkorderId(workOrderId);
            workOrder.setProductId(productId);
            workOrder.setPlannedYield(plannedYield);
            workOrder.setStartDay(
                    new Timestamp(DateUtils.parse(startDay, ErpConstants.DATE_FORMAT4DAY_NOSPLICING).getTime()));
            workOrder.setRequireDay(
                    new Timestamp(DateUtils.parse(requiredDay, ErpConstants.DATE_FORMAT4DAY_NOSPLICING).getTime()));
            Timestamp dueDate;
            if (StringUtils.isBlank(dueDay)){
                if (ErpConstants.ZP03.equalsIgnoreCase(workOrderType) || ErpConstants.ZP04.equalsIgnoreCase(workOrderType)){
                    //当订单类型(字段:AUART)为:ZP03 OR ZP04 时,离厂日期(字段:ETDAT)可以为空
                    dueDate = null;
                }else {
                    dueDate = new Timestamp(DateUtils.parse(dueDay, ErpConstants.DATE_FORMAT4DAY_NOSPLICING).getTime());
                }
            } else {
                dueDate= new Timestamp(DateUtils.parse(dueDay, ErpConstants.DATE_FORMAT4DAY_NOSPLICING).getTime());
            }
            workOrder.setDueDate(dueDate);
            workOrder.setCustomerOrder(customerOrder);
            workOrder.setCustomerOrderNo(customerOrderNo);

            workOrder.setErpClient(erpClient);
            workOrder.setErpFactory(erpFactory);
            workOrder.setWorkorderType(workOrderType);


            List<ErpWorkOrderLineDto> lines = workOrderDto.getLines();
            List<WorkOrderLine> workOrderLines = lines.stream().map(erpWorkOrderLineDto -> {
                WorkOrderLine workOrderLine = new WorkOrderLine();
                workOrderLine.setMaterialId(erpWorkOrderLineDto.getMatnr());
                workOrderLine.setMaterialType(erpWorkOrderLineDto.getMtart());
                workOrderLine.setRequireQty(erpWorkOrderLineDto.getBdmng());

                return workOrderLine;
            }).collect(Collectors.toList());

            workOrder.setWorkOrderLines(workOrderLines);

            workOrderManager.insertWorkOrder(workOrder);
        }

        this.changeErpWorkOrderStatus(workOrderDto, ErpConstants.STATUS_SUCCESS);
        this.changeErpWorkOrderLineStatus(workOrderDto.getLines(), ErpConstants.STATUS_SUCCESS);

    }

    @Override
    public List<ErpMaterialDto> getAvaliableErpMaterial() {
        List<ErpMaterialDto> erpMaterialDtos = erpDao.getAvaliableErpMaterial();
        return erpMaterialDtos;
    }

    @Override
    public List<Map<String, String>> getCanReceiveMaterialList() {
        return erpDao.getCanReceiveMaterialList();
    }

    @Override
    public List<ErpWorkOrderDto> getAvaliableErpWorkOrder() {
        return erpDao.getAvaliableErpWorkOrder();
    }

    @Override
    public List<ErpWorkOrderLineDto> getAvaliableErpWorkOrderLine() {
        return erpDao.getAvaliableErpWorkOrderLine();
    }

    @Override
    public void changeErpMaterialStatus(ErpMaterialDto erpMaterialDto, String status) {
        erpDao.changeErpMaterialStatus(erpMaterialDto, status);
    }

    @Override
    public void changeErpWorkOrderStatus(ErpWorkOrderDto erpWorkOrderDto, String status) {
        erpDao.changeErpWorkOrderStatus(erpWorkOrderDto, status);
    }

    @Override
    public void changeErpWorkOrderLineStatus(List<ErpWorkOrderLineDto> erpWorkOrderLineDtos, String status) {
        erpDao.changeErpWorkOrderLineStatus(erpWorkOrderLineDtos, status);
    }

    @Override
    public void batchReceiveMaterial(List<String> receiveList, Operation warehouse) {
        long facilityRrn = LocalContext.getFacilityRrn();
        String userId = LocalContext.getUserId();
        for (String str : receiveList){
            //1.查询出对应的物料接收数据,并判断是否能用
            String[] strArr = str.split(StringUtils.COMMA_SIGN);
            String mcy = strArr[0];
            String mci = strArr[1];
            String mcp = strArr[2];
            Map<String,String> receiveData = erpDao.getCanReceiveMaterial(mcy, mci, mcp);
            Assert.isFalse(receiveData == null, Errors.create().key(MessageIdList.FLIP_DATA_ERROR).content("Data error").build());
            Assert.isFalse(ErpConstants.STATUS_SUCCESS.equalsIgnoreCase(receiveData.get("status")),
                           Errors.create().key(MessageIdList.DATA_HAVE_MODIFY).content("Data has been modified!").build());
            Assert.isTrue(ErpConstants.ORDER_ISSUE.equalsIgnoreCase(receiveData.get("moveType")),
                          Errors.create().key(MessageIdList.DATA_HAVE_MODIFY).content("Data has been modified!").build());

            //2.检查物料是否在BOM中
            String pOrderId = receiveData.get("productOrderId");
            String materialId = receiveData.get("materialId");
            Assert.isFalse(erpDao.checkMaterialInBom(pOrderId, materialId)<=0,
                           Errors.create().key(MessageIdList.MATERIAL_NOT_MATCH)
                           .content("MaterialId {} cannot match WorkOrder!").args(materialId).build());

            //3、组装成mes的物料接收数据
            MaterialDO material = new MaterialDO(materialId, namedObjectManager.getNamedSpace(facilityRrn, ObjectList.ITEM_KEY), ObjectList.ITEM_KEY);
            material = materialManager.getMaterial(material);
            Assert.isFalse(material == null, Errors.create().key(MessageIdList.MATERIAL_NOT_EXIST)
                                                   .content("Material Id {} does not exist!").args(material).build());
            WarehouseTransBO warehouseTrans = new WarehouseTransBO();
            String materialLotId = MapUtils.getString(receiveData, AsmConst.LOT_NUMBER);
            //半成品的物料批(物料ID以9开头),每一批的接收不能超过25片。
            if (StringUtils.startsWith(StringUtils.stripStart(materialId, "0"), "9")){
                double receiveQty = NumberUtils.toDouble(MapUtils.getString(receiveData, AsmConst.QTY));
                boolean warnFlag = receiveQty > 25;
                //先查询这个物料批有没有被接收过
                List<LotInventoryDO> list = lotInventoryManager.getLotInventoryListByLotNumberLike(material.getInstanceRrn(), warehouse.getInstanceRrn(), materialLotId + "_");
                if (CollectionUtils.isNotEmpty(list)){
                    double hisCount = 0.0;
                    for (LotInventoryDO lid:list){
                        hisCount += lid.getReceiptQty();
                    }
                    warnFlag = hisCount + receiveQty > 25;
                }
                Assert.isFalse(warnFlag, Errors.create().key(MessageIdList.QTY_EXCEEDS_25).
                        content("The received quantity of semi-finished material lot {} exceeds 25 !").args(materialLotId).build());
            }
            //SAP系统存在将物料批拆分成多个生产订单下发物料的情况,故以物料批ID+工单ID作为物料批的ID
            materialLotId = materialLotId + "_" + pOrderId;
            receiveData.put(AsmConst.LOT_NUMBER, materialLotId);
            buildWarehouseTrans(warehouseTrans, warehouse, material, receiveData);
            List<WarehouseTransBO> receiveTrans = new ArrayList<>();
            receiveTrans.add(warehouseTrans);
            warehouseManager.saveReceivedMaterialToWarehouse(facilityRrn, userId, receiveTrans);
            //MES产品与SAP产品的绑定关系(Auto)
            bindMesAndSapProductId(pOrderId, materialId);

            //4、修改中间表的读取状态
            erpDao.updateMaterialReceiveStatus(mcy, mci, mcp);
        }


    }

    private void bindMesAndSapProductId(String pOrderId, String materialId) {
        //先根据order对象找到环境值
        //在通过orderID和环境值去找ZMES_MATERIAL中的MES_MATNR字段
        //如果MES产品已存在,并且未绑定,则通过ORDER ID、SAP产品去绑定MES产品
        //如果不存在,则跳过,并打印一下log
        WorkOrder workOrder = workOrderManager.getWorkOrderById(pOrderId);
        Assert.isFalse(workOrder == null || workOrder.getWorkorderRrn() <= 0,
                       Errors.create().key(MessageIdList.WORKORDER_NOT_FOUND).content("WorkOrder {} not found").args(pOrderId).build());
        String mandt = workOrder.getErpClient();
        String plant = workOrder.getErpFactory();
        String erpProduct = workOrder.getProductId();

        ErpMaterialDto erpMaterialDto = erpDao.getMesProductId(materialId, mandt, plant);
        if (erpMaterialDto == null || StringUtils.isBlank(erpMaterialDto.getMesMatnr())){
            logger.info("The MES_MATNR corresponding to the SAP material {} is empty!", materialId);
            return;
        }
        Item item = new Item(erpMaterialDto.getMesMatnr(), namedObjectManager.getNamedSpace(LocalContext.getFacilityRrn(), ObjectList.PRODUCT_KEY), ObjectList.PRODUCT_KEY);
        item = productManager.getItem(item);
        if (item == null || item.getInstanceRrn() <= 0) {
            logger.info("MES_MATNR {} does not exist in the MES system!", erpMaterialDto.getMesMatnr());
        } else {
            ErpMesProductBindBean epbb = new ErpMesProductBindBean();
            epbb.setErpOrderId(pOrderId);
            epbb.setErpProductId(erpProduct);
            epbb.setMesProductId(erpMaterialDto.getMesMatnr());
            epbb = erpDao.getBindMesProduct(epbb);
            if (epbb != null){
                logger.info("SAP Product {} has been binded to {}!", erpProduct, epbb.getMesProductId());
            } else {
                insertBindMesProduct(new ErpMesProductBindBean(item.getInstanceId(), item.getInstanceRrn(), erpProduct, pOrderId, mandt, plant));
            }
        }
    }

    @Override
    public void recordMaterialReturnLog(String warehouseId, String materialId, String sourceType,
                                        List<Map<String, Object>> conversionList) {
        long facilityRrn = LocalContext.getFacilityRrn();
        Operation warehouse = operationManager.getOperation(warehouseId, facilityRrn);
        MaterialDO material = new MaterialDO(materialId, namedObjectManager.getNamedSpace(facilityRrn, ObjectList.ITEM_KEY), ObjectList.ITEM_KEY);
        material = materialManager.getMaterial(material);
        for (Map<String, Object> map: conversionList){
            String lotNumber = MapUtils.getString(map, "lotNumber");
            String qty = MapUtils.getString(map, "qty");
            String key1 = MapUtils.getString(map, "key1");
            String key2 = MapUtils.getString(map, "conversionType");
            // String comments = MapUtils.getString(map, "comments");
            ReferenceFileDetail rereferenceFileDetail = new ReferenceFileDetail(ReferenceDetailNames.TRANS_MATERIAL_TYPE, namedObjectManager
                    .getNamedSpace(facilityRrn, ObjectList.REFERENCE_FILE_KEY), ObjectList.REFERENCE_FILE_KEY);
            rereferenceFileDetail.setKey1Value(key1);
            rereferenceFileDetail.setKey2Value(key2);
            ReferenceFileDetail detail = referenceFileManager.getReferenceFileDetail(rereferenceFileDetail);
            String rtnFlag = detail.getData1Value();

            LotInventoryDO lid = lotInventoryManager
                    .getLotInventory(lotNumber, material.getInstanceRrn(), warehouse.getInstanceRrn());
            String porderId = lid.getAttributeData3();
            String sapMaterialId = lid.getAttributeData4();
            WorkOrder workOrder = workOrderManager.getWorkOrderById(porderId);
            Assert.isFalse(workOrder == null || workOrder.getWorkorderRrn() <= 0,
                           Errors.create().key(MessageIdList.WORKORDER_NOT_FOUND).content("WorkOrder {} not found").args(porderId).build());
            Map<String,String> paramMap = new HashMap<>();
            paramMap.put("mandt", workOrder.getErpClient());
            paramMap.put("plant", workOrder.getErpFactory());
            paramMap.put("orderId", porderId);
            paramMap.put("moveType", ErpConstants.MOVE_TYPE_262);
            paramMap.put("materialId", sapMaterialId);
            String returnLotNumber = StringUtils.beforeFirst(lotNumber,'_');
            paramMap.put("lotNumber", returnLotNumber);
            paramMap.put("qty", qty);
            paramMap.put("uom", material.getStoreUom());
            paramMap.put("flag", rtnFlag);
            erpDao.recordMaterialReturnLog(paramMap);
            //标记物料批次待确认
            erpDao.markMaterialLotReturn(material.getItemRrn(), warehouse.getInstanceRrn(), lotNumber, key2);
        }
    }

    @Override
    public Map createLot(Map transInfo) {
        Map resultsInfo = lotManager.createLotAndMoveNext(transInfo);

        Long lotRrn = MapUtils.getLong(resultsInfo, "lotRrn");
        Lot lot = lotQueryManager.getLot(lotRrn);

        WorkOrder workOrder = workOrderManager.getWorkOrderById(lot.getInnerOrderNO());
        Assert.isFalse(workOrder == null || workOrder.getWorkorderRrn() <= 0,
                       Errors.create().key(MessageIdList.WORKORDER_NOT_FOUND).content("WorkOrder {} not found").args(lot.getInnerOrderNO()).build());

        if (StringUtils.isNotBlank(workOrder.getCustomerOrder())){
            //SAP那边,当销售订单为空的时候,即为研发订单,不需要写入WAFER Start的数据
            ErpWaferStartDto waferStartDto = new ErpWaferStartDto();
            waferStartDto.setMandt(workOrder.getErpClient());
            waferStartDto.setVbeln(workOrder.getCustomerOrder());
            waferStartDto.setPosnr(workOrder.getCustomerOrderNo());
            waferStartDto.setMatnr(workOrder.getProductId());
            waferStartDto.setAufnr(workOrder.getWorkorderId());
            waferStartDto.setErdat(DateUtils.getNowTime(ErpConstants.DATE_FORMAT4DAY_NOSPLICING));
            waferStartDto.setErzet(DateUtils.getNowTime(ErpConstants.DATE_FORMAT4TIME_NOSPLICING));
            erpDao.insertOrUpdateErpWaferStart(waferStartDto);
        }

        workOrderManager.addStartQty4WorkOrder(workOrder, lot.getInt_qty1());

        return resultsInfo;
    }

    @Override
    public List<Map<String, String>> getConfirmedReturnRequest() {
        return erpDao.getConfirmedReturnRequest();
    }


    @Override
    public void actuallyReturnBom(String warehouseId, List<Map<String, String>> materialList) {
        long facilityRrn = LocalContext.getFacilityRrn();
        Operation warehouse = operationManager.getOperation(warehouseId, facilityRrn);

        for (Map<String,String> map: materialList) {
            //先查出已经被确认的退料申请的具体物料信息
            String materialId  = MapUtils.getString(map,"materialId");
            MaterialDO materialDO = new MaterialDO(materialId,
                                                   namedObjectManager.getNamedSpace(facilityRrn, ObjectList.ITEM_KEY),
                                                   ObjectList.ITEM_KEY);
            MaterialDO material = materialManager.getMaterial(materialDO);
            //实际退料
            String lotNumber = MapUtils.getString(map, AsmConst.LOT_NUMBER);
            convertBomFromWarehouse(ErpConstants.SOURCE_TYPE, warehouse, material,
                                                                          map, facilityRrn, LocalContext.getUserId() );
            //修改中间表的状态,需要物料批的主批ID
            map.put(AsmConst.LOT_NUMBER, lotNumber);
            erpDao.updateReturnRequestStatusForBom(map);
        }
    }

    @Override
    public List<Map<String, String>> getReceiveOrReturnBomList(String moveType) {
        return erpDao.getReceiveOrReturnBomList(moveType);
    }

    @Override
    public void batchReturnMaterialBom(List<String> returnList, Operation warehouse, String conversionType) {
        List<Map<String, String>> returnMapList = new ArrayList<>();
        for (String str : returnList) {
            //1.查询出对应的物料退回数据,并判断是否能用
            String[] strArr = str.split(StringUtils.COMMA_SIGN);
            String sapClintId = strArr[0];
            String materialCertificateId = strArr[1];
            String sapMaterialId = strArr[2];
            String lotNumber = strArr[3];
            String zeile = strArr[4];
            Map<String,String> returnData = erpDao.getCanReceiveBom(sapClintId, materialCertificateId, sapMaterialId, lotNumber, zeile);
            Assert.isFalse(returnData == null, Errors.create().key(MessageIdList.FLIP_DATA_ERROR).content("Data error").build());
            Assert.isFalse(ErpConstants.STATUS_SUCCESS.equalsIgnoreCase(returnData.get("status")),
                           Errors.create().key(MessageIdList.DATA_HAVE_MODIFY).content("Data has been modified!").build());

            String materialId = returnData.get("materialId");

            MaterialDO material = new MaterialDO(materialId, namedObjectManager.getNamedSpace(LocalContext.getFacilityRrn(), ObjectList.ITEM_KEY), ObjectList.ITEM_KEY);
            material = materialManager.getMaterial(material);
            // check materialId 是否存在
            Assert.isFalse(material == null, Errors.create().key(MessageIdList.MATERIAL_NOT_EXIST)
                                                   .content("Material Id {} does not exist!").args(material).build());

            String returnMaterialLotNumber = lotInventoryManager.getReturnMaterialLotNumberForBom(material.getItemRrn(), warehouse.getInstanceRrn(), lotNumber);
            Assert.isFalse(StringUtils.isEmpty(returnMaterialLotNumber), Errors.create().key(MessageIdList.ERP_NO_SUB_LOT_NUMBER).content("No sub-materialLotNumber of {} was found!").args(lotNumber).build());
            returnData.put("conversionType", conversionType);
            returnMapList.add(returnData);
        }
        actuallyReturnBom(warehouse.getInstanceId(), returnMapList);
    }

    @Override
    public List<String> queryMaterialIdByWorkOrderId(String workOrderId) {
        return erpDao.queryMaterialIdByWorkOrderId(workOrderId);
    }

    @Override
    public void actuallyReturnMaterial(String warehouseId, List<Map<String, String>> materialList) {
        long facilityRrn = LocalContext.getFacilityRrn();
        Operation warehouse = operationManager.getOperation(warehouseId, facilityRrn);

        for (Map<String,String> map: materialList){
            //先查出已经被确认的退料申请的具体物料信息
            String materialId  = MapUtils.getString(map,"materialId");
            MaterialDO materialDO = new MaterialDO(materialId,
                                                   namedObjectManager.getNamedSpace(facilityRrn, ObjectList.ITEM_KEY),
                                                   ObjectList.ITEM_KEY);
            MaterialDO material = materialManager.getMaterial(materialDO);
            //实际退料
            String lotNumber = MapUtils.getString(map, AsmConst.LOT_NUMBER);
            String returnMaterialLotNumber = convertMaterialFromWarehouse(ErpConstants.SOURCE_TYPE, warehouse, material,
                                                                          map, facilityRrn, ErpConstants.ERP_USER );
            //修改中间表的状态,需要物料批的主批ID
            map.put(AsmConst.LOT_NUMBER, lotNumber);
            erpDao.updateReturnRequestStatus(map);
            erpDao.markMaterialLotReturn(material.getItemRrn(), warehouse.getInstanceRrn(), returnMaterialLotNumber, StringUtils.EMPTY);
        }
    }

    @Override
    public void changeErpShipLotStatus(ErpShipLotDto erpShipLotDto, String status) {
        erpDao.changeErpShipLotStatus(erpShipLotDto, status);
    }

    @Override
    public List<ErpShipLotDto> getAvaliableErpShipLot() {
        return erpDao.getAvaliableErpShipLot();
    }

    @Override
    public void shipLot4Erp(ErpShipLotDto erpShipLotDto) {
        String lotId = erpShipLotDto.getBatch();

        List<Map> allFacility = facilityManager.getAllFacility();

        Lot lot = null;
        for (Map map : allFacility) {
            Lot tempLot = lotQueryManager.getLot(lotId, MapUtils.getLong(map, "FACILITY_RRN", 0L));
            if (tempLot != null && tempLot.getLotRrn() > 0) {
                lot = tempLot;
                break;
            }
        }

        Assert.isFalse(lot == null || lot.getLotRrn() <= 0,
                       Errors.create().content(" Incorrect lot information!").build());

        Assert.isFalse(!StringUtils.equals(LotStatus.FINISH, lot.getLotStatus()),
                       Errors.create().content("Lot status {} cannot ship!").args(lot.getLotStatus()).build());

        Assert.isFalse(StringUtils.isEmpty(lot.getInnerOrderNO()),
                       Errors.create().content("Lot workorder not found!").build());

        WorkOrder workOrder = workOrderManager.getWorkOrderById(lot.getInnerOrderNO());

        //1.shiplot
        Map<String, Object> lotMap = BeanUtils.copyBeanToMap(lot);
        Map transMap = new HashMap();
        lotMap.put("storage", "");
        lotMap.put("completedssLevel", erpShipLotDto.getYeild());
        lotMap.put("completedssType", CompletedssConstants.COMPLETEDSS_TYPE_WAFER);
        transMap.put("dataArray", Arrays.asList(lotMap));

        TransReason transReason = new TransReason();
        transReason.setReason("ERP SHIP LOT!");
        transMap.put("transReason", transReason);

        lotManager.shipLot(transMap);
        //修改批次的标记
        lotManager.updateLotExtAttribute(lot.getLotRrn(), null, null ,"");
        this.changeErpShipLotStatus(erpShipLotDto, ErpConstants.STATUS_SUCCESS);

        //2.close workorder
        workOrderManager.addShipQty4WorkOrder(workOrder, lot.getInt_qty1());

        int workorderAvalibleQty = workOrderManager.getWorkorderAvalibleShipQty(lot.getInnerOrderNO());
        if (workorderAvalibleQty <= 0) {
            closeWorkorder4Erp(workOrder);
        }

    }

    @Override
    public void shipLotRequest(List<Map<String, String>> paramMap) {
        long facilityRrn = LocalContext.getFacilityRrn();
        Operation warehouse = operationManager.getOperation(MapUtils.getString(ErpConstants.getFirst(paramMap),
                                                                               "warehouseId", "WAFER_BANK"), facilityRrn);
        for (Map map : paramMap){
            String lotId = MapUtils.getString(map, "lotId");
            Lot lot = lotQueryManager.getLot(lotId, facilityRrn);
            List<Unit> units = unitQueryManager.getAllUnits(lot.getLotRrn());
            Unit unit = ErpConstants.getFirst(units);
            String materialId = unit.getItemId();
            String lotNumber = unit.getUnitAlias2();
            MaterialDO materialDO = new MaterialDO(materialId,
                                                   namedObjectManager.getNamedSpace(facilityRrn, ObjectList.ITEM_KEY),
                                                   ObjectList.ITEM_KEY);
            MaterialDO material = materialManager.getMaterial(materialDO);
            Assert.isFalse(material == null || material.getInstanceRrn() <= 0,
                           Errors.create().content("Material {} not found").args(materialId).build());
            // LotInventoryDO lid =  lotInventoryManager.getLotInventory(lotNumber, material.getInstanceRrn(), warehouse.getInstanceRrn());
            final String sapLotNumber = StringUtils.beforeFirst(lotNumber,'_');
            WorkOrder workOrder = workOrderManager.getWorkOrderById(lot.getInnerOrderNO());
            Assert.isFalse(workOrder == null || workOrder.getWorkorderRrn() <= 0,
                           Errors.create().key(MessageIdList.WORKORDER_NOT_FOUND).content("WorkOrder {} not found").args(lot.getInnerOrderNO()).build());

            //上传批次信息
            ErpShipLotDto esld = new ErpShipLotDto();
            esld.setMandt(workOrder.getErpClient());
            esld.setPlant(workOrder.getErpFactory());
            esld.setOrderId(lot.getInnerOrderNO());
            esld.setMaterial(workOrder.getProductId());//SAP需要成品ID,即产品的ID
            esld.setBatch(lot.getLotId());
            esld.setMoveType(ErpConstants.ZP04.equalsIgnoreCase(workOrder.getWorkorderType())?
                                     ErpConstants.MOVE_TYPE_531:ErpConstants.MOVE_TYPE_101);
            esld.setEntryQnt(lot.getInt_qty1());
            esld.setEntryUom(material.getStoreUom());
            esld.setLpcUom(lot.getInt_qty1());
            // esld.setVfdat(DateUtils.formatDate(lot.getDueDate(), ErpConstants.DATE_FORMAT4DAY_NOSPLICING));
            esld.setHsdat(DateUtils.getNowTime(ErpConstants.DATE_FORMAT4DAY_NOSPLICING));
            esld.setLwedt(DateUtils.getNowTime(ErpConstants.DATE_FORMAT4DAY_NOSPLICING));
            esld.setErdat(DateUtils.getNowTime(ErpConstants.DATE_FORMAT4DAY_NOSPLICING));
            esld.setErzet(DateUtils.getNowTime(ErpConstants.DATE_FORMAT4TIME_NOSPLICING));
            erpDao.insertOrUpdateErpShipLot(esld);

            //上传wafer信息
            List<ErpWaferRptDto> erpWaferRptDtos = units.stream().map(tempUnit -> {
                ErpWaferRptDto erpWaferRptDto = new ErpWaferRptDto();
                erpWaferRptDto.setMandt(workOrder.getErpClient());
                erpWaferRptDto.setMatnr(workOrder.getProductId());
                erpWaferRptDto.setCharg(lot.getLotId());
                erpWaferRptDto.setZwfid(tempUnit.getUnitId());
                erpWaferRptDto.setErdat(DateUtils.getNowTime(ErpConstants.DATE_FORMAT4DAY_NOSPLICING));
                erpWaferRptDto.setErzet(DateUtils.getNowTime(ErpConstants.DATE_FORMAT4TIME_NOSPLICING));
                erpWaferRptDto.setCtmltid(sapLotNumber);
                erpWaferRptDto.setCtmwfid(tempUnit.getCustomerT7Code());
                return erpWaferRptDto;
            }).collect(Collectors.toList());
            erpDao.insertOrUpdateErpWafer(erpWaferRptDtos);

            //修改批次的标记
            lotManager.updateLotExtAttribute(lot.getLotRrn(), null, null , ErpConstants.SHIP_REQUEST);
        }
    }

    @Override
    public Page queryBindMesProduct(Page page, ErpMesProductBindBean empbb) {
        return erpDao.queryBindMesProduct(page, empbb);
    }

    @Override
    public void insertBindMesProduct(ErpMesProductBindBean empbb) {
        TransactionLog transactionLog = buildTransactionLog(empbb);
        erpDao.insertBindMesProduct(empbb);
        erpDao.insertBindMesProductHistory(empbb, transactionLog);
        transactionLogManager.markTransactionLog(transactionLog);
    }

    @Override
    public void updateBindMesProduct(ErpMesProductBindBean empbb) {
        TransactionLog transactionLog = buildTransactionLog(empbb);
        erpDao.updateBindMesProduct(empbb);
        erpDao.insertBindMesProductHistory(empbb, transactionLog);
        transactionLogManager.markTransactionLog(transactionLog);
    }

    @Override
    public void deleteBindMesProduct(ErpMesProductBindBean empbb) {
        TransactionLog transactionLog = buildTransactionLog(empbb);
        erpDao.insertBindMesProductHistory(empbb, transactionLog);
        erpDao.deleteBindMesProduct(empbb);
        transactionLogManager.markTransactionLog(transactionLog);
    }

    @Override
    public List<ErpMesProductBindBean> queryNotBindMesProduct() {
        return erpDao.queryNotBindMesProduct();
    }

    @Override
    public void batchReceiveMaterialBom(List<String> receiveList, Operation warehouse) {
        long facilityRrn = LocalContext.getFacilityRrn();
        String userId = LocalContext.getUserId();
        for (String str : receiveList){
            //1.查询出对应的物料接收数据,并判断是否能用
            String[] strArr = str.split(StringUtils.COMMA_SIGN);
            String sapClintId = strArr[0];
            String materialCertificateId = strArr[1];
            String sapMaterialId = strArr[2];
            String lotNumber = strArr[3];
            String zeile = strArr[4];
            Map<String,String> receiveData = erpDao.getCanReceiveBom(sapClintId, materialCertificateId, sapMaterialId, lotNumber, zeile);
            Assert.isFalse(receiveData == null, Errors.create().key(MessageIdList.FLIP_DATA_ERROR).content("Data error").build());
            Assert.isFalse(ErpConstants.STATUS_SUCCESS.equalsIgnoreCase(receiveData.get("status")),
                           Errors.create().key(MessageIdList.DATA_HAVE_MODIFY).content("Data has been modified!").build());

            String materialId = receiveData.get("materialId");
            //2、组装成mes的物料接收数据
            List<WarehouseTransBO> receiveTrans = new ArrayList<>();
            WarehouseTransBO warehouseTrans;

            MaterialDO material = new MaterialDO(materialId, namedObjectManager.getNamedSpace(facilityRrn, ObjectList.ITEM_KEY), ObjectList.ITEM_KEY);
            material = materialManager.getMaterial(material);
            Assert.isFalse(material == null, Errors.create().key(MessageIdList.MATERIAL_NOT_EXIST)
                                                   .content("Material Id {} does not exist!").args(material).build());
            warehouseTrans = new WarehouseTransBO();
            String materialLotId = MapUtils.getString(receiveData, AsmConst.LOT_NUMBER);

            receiveData.put(AsmConst.LOT_NUMBER, materialLotId);
            buildWarehouseTransForBom(warehouseTrans, warehouse, material, receiveData);
            receiveTrans.add(warehouseTrans);
            warehouseManager.saveReceivedMaterialToWarehouse(facilityRrn, userId, receiveTrans);

            //3、修改中间表的读取状态
            erpDao.updateBomReceiveStatus(sapClintId, materialCertificateId, sapMaterialId, lotNumber, zeile);
        }

    }

    public void closeWorkorder4Erp(WorkOrder workOrder) {
        workOrderManager.completeWorkOrder(workOrder.getWorkorderRrn());

        ErpCloseWorkOrderDto closeWorkOrderDto = new ErpCloseWorkOrderDto();
        closeWorkOrderDto.setMandt(workOrder.getErpClient());
        closeWorkOrderDto.setWerks(workOrder.getErpFactory());
        closeWorkOrderDto.setAufnr(workOrder.getWorkorderId());
        closeWorkOrderDto.setBudat(DateUtils.getNowTime(ErpConstants.DATE_FORMAT4DAY_NOSPLICING));
        closeWorkOrderDto.setErdat(DateUtils.getNowTime(ErpConstants.DATE_FORMAT4DAY_NOSPLICING));
        closeWorkOrderDto.setErzet(DateUtils.getNowTime(ErpConstants.DATE_FORMAT4TIME_NOSPLICING));
        erpDao.insertOrUpdateErpCloseWorkorder(closeWorkOrderDto);
    }

    // public void reportWafer4Erp(Lot lot, WorkOrder workOrder) {
    //
    //     List<Unit> unitList = unitQueryManager.getUnitList(lot.getLotRrn());
    //
    //     List<ErpWaferRptDto> erpWaferRptDtos = unitList.stream().map(unit -> {
    //         ErpWaferRptDto erpWaferRptDto = new ErpWaferRptDto();
    //         erpWaferRptDto.setMandt(workOrder.getErpClient());
    //         erpWaferRptDto.setMatnr(unit.getItemId());
    //         erpWaferRptDto.setCharg(lot.getLotId());
    //         erpWaferRptDto.setZwfid(unit.getUnitId());
    //         erpWaferRptDto.setErdat(DateUtils.getNowTime(ErpConstants.DATE_FORMAT4DAY_NOSPLICING));
    //         erpWaferRptDto.setErzet(DateUtils.getNowTime(ErpConstants.DATE_FORMAT4TIME_NOSPLICING));
    //         return erpWaferRptDto;
    //     }).collect(Collectors.toList());
    //
    //     erpDao.insertOrUpdateErpWafer(erpWaferRptDtos);
    // }

    private void buildWarehouseTrans(WarehouseTransBO warehouseTrans, Operation warehouse, MaterialDO material,
                                     Map<String, String> map) {
        warehouseTrans.setTransQty(NumberUtils.toDouble(MapUtils.getString(map, AsmConst.QTY)));
        warehouseTrans.setTransComments(MapUtils.getString(map, AsmConst.COMMENTS));

        LotInventoryDO lotInventory = warehouseTrans.getLotInventoryDO();

        lotInventory.setLotNumber(StringUtils.trim(MapUtils.getString(map, AsmConst.LOT_NUMBER)));
        lotInventory.setItemRrn(material.getInstanceRrn());
        lotInventory.setWarehouseRrn(warehouse.getInstanceRrn());
        lotInventory.setWarehouseId(warehouse.getInstanceId());
        lotInventory.setMaterialType(material.getObjectSubtype());
        Timestamp ts = new Timestamp(System.currentTimeMillis());
        lotInventory.setReceiptDate(ts);
        lotInventory.setExpirationDate(null);//根据物料的默认有效期去计算
        lotInventory.setProductionDate(null);
        lotInventory.setIncomingDate(DateUtils.stringToTimestamp(MapUtils.getString(map, "pickingDate")));
        lotInventory.setCheckDate(ts);
        lotInventory.setCheckUser(MapUtils.getString(map, AsmConst.CHECK_USER));
        lotInventory.setCheckResult(null);

        warehouseManager.setExpirationDateForReceive(material.getExpirationLength(), lotInventory);

        lotInventory.setAttributeData1(null);
        lotInventory.setAttributeData2(ErpConstants.ERP);
        lotInventory.setAttributeData3(MapUtils.getString(map, "productOrderId"));//工单ID
        lotInventory.setAttributeData4(MapUtils.getString(map, "sapMaterialId"));//sap的物料编码

        lotInventory.setStatus(WarehouseNames.ACTIVE_STATUS);
    }

    private String convertMaterialFromWarehouse(String sourceType, Operation warehouse, MaterialDO material, Map<String,String> map, long facilityRrn, String userId) {

        WarehouseTransBO warehouseTrans;
        LotInventoryDO lotInventory;
        List<WarehouseTransBO> convertTrans = new ArrayList<>();
        //实际退料的物料批次
        String lotNumber = MapUtils.getString(map, AsmConst.LOT_NUMBER);
        String orderId = MapUtils.getString(map,"orderId");
        String returnMaterialLotNumber = lotInventoryManager.getReturnMaterialLotNumber(material.getItemRrn(), warehouse.getInstanceRrn(), lotNumber, orderId);
        Assert.isFalse(StringUtils.isEmpty(returnMaterialLotNumber), Errors.create().content("No sub-materialLotNumber of {} was found!").args(lotNumber).build());
        lotInventory = lotInventoryManager.getLotInventory(returnMaterialLotNumber, material.getInstanceRrn(), warehouse.getInstanceRrn());
        warehouseTrans = new WarehouseTransBO(lotInventory);
        map.put("qty", lotInventory.getTotalQuantity() +"");
        map.put("conversionType", lotInventory.getAttributeData5());
        map.put(AsmConst.LOT_NUMBER, returnMaterialLotNumber);
        buildWarehouseTrans(warehouseTrans, warehouse, material, map);

        lotInventory.setStatus(lotInventoryManager.getLotInventoryStatus(lotInventory.getLotNumber(),
                                                                         lotInventory.getTotalQuantity(),
                                                                         warehouseTrans.getTransQty()));

        warehouseTrans.setTargetType(MapUtils.getString(map, AsmConst.CONVERSION_TYPE));
        warehouseTrans.setTransType(buildConversionTargetType(sourceType, warehouseTrans.getTargetType()));
        warehouseTrans.setTargetLotNumber(StringUtils.substringBeforeLast(lotInventory.getLotNumber(), sourceType) +
                                                  warehouseTrans.getTargetType());
        convertTrans.add(warehouseTrans);

        warehouseManager.saveConvertMaterialFromWarehouse(facilityRrn, userId, convertTrans);
        return returnMaterialLotNumber;
    }

    private String buildConversionTargetType(String sourceType, String targetType) {
        String transId = referenceFileManager
                .getReferenceDetailExchange(ReferenceDetailNames.TRANS_MATERIAL_TYPE, sourceType, targetType,
                                            ReferenceFileConst.DATA_3_VALUE);
        if (StringUtils.isNotBlank(transId)) {
            return transId;
        } else {
            return sourceType + "->" + targetType;
        }
    }

    private TransactionLog buildTransactionLog(ErpMesProductBindBean empbb) {
        TransactionLog transactionLog = transactionLogManager.startTransactionLog(LocalContext.getUserId(), empbb.getTransId());
        empbb.setCreatedTimestamp(transactionLog.getTransStartTimestamp());
        empbb.setCreatedUserRrn(LocalContext.getUserRrn());
        empbb.setCreatedUserId(LocalContext.getUserId());
        empbb.setLastUpdateTimestamp(transactionLog.getTransStartTimestamp());
        empbb.setLastUpdateUserRrn(LocalContext.getUserRrn());
        empbb.setLastUpdateUserId(LocalContext.getUserId());
        return transactionLog;
    }

    private void buildWarehouseTransForBom(WarehouseTransBO warehouseTrans, Operation warehouse, MaterialDO material,
                                     Map<String, String> map) {
        warehouseTrans.setTransQty(NumberUtils.toDouble(MapUtils.getString(map, AsmConst.QTY)));
        warehouseTrans.setTransComments(MapUtils.getString(map, AsmConst.COMMENTS));

        LotInventoryDO lotInventory = warehouseTrans.getLotInventoryDO();

        lotInventory.setLotNumber(StringUtils.trim(MapUtils.getString(map, AsmConst.LOT_NUMBER)));
        lotInventory.setItemRrn(material.getInstanceRrn());
        lotInventory.setWarehouseRrn(warehouse.getInstanceRrn());
        lotInventory.setWarehouseId(warehouse.getInstanceId());
        lotInventory.setMaterialType(material.getObjectSubtype());
        Timestamp ts = new Timestamp(System.currentTimeMillis());
        lotInventory.setReceiptDate(ts);
        lotInventory.setExpirationDate(null);//根据物料的默认有效期去计算
        lotInventory.setProductionDate(null);
        lotInventory.setIncomingDate(DateUtils.stringToTimestamp(MapUtils.getString(map, "pickingDate")));
        lotInventory.setCheckDate(ts);
        lotInventory.setCheckUser(MapUtils.getString(map, AsmConst.CHECK_USER));
        lotInventory.setCheckResult(null);

        warehouseManager.setExpirationDateForReceive(material.getExpirationLength(), lotInventory);

        lotInventory.setAttributeData1(MapUtils.getString(map, "materialCertificateId"));
        lotInventory.setAttributeData2(ErpConstants.ERP);
        lotInventory.setAttributeData3(MapUtils.getString(map, "sapClintId"));//sap client号
        lotInventory.setAttributeData4(MapUtils.getString(map, "materialType"));//工厂
        lotInventory.setAttributeData5(MapUtils.getString(map, "zile"));
        lotInventory.setStatus(WarehouseNames.ACTIVE_STATUS);
    }

    private void convertBomFromWarehouse(String sourceType, Operation warehouse, MaterialDO material, Map<String,String> map, long facilityRrn, String userId) {

        WarehouseTransBO warehouseTrans;
        LotInventoryDO lotInventory;
        List<WarehouseTransBO> convertTrans = new ArrayList<>();
        //实际退料的物料批次
        String lotNumber = MapUtils.getString(map, AsmConst.LOT_NUMBER);
        String returnMaterialLotNumber = lotInventoryManager.getReturnMaterialLotNumberForBom(material.getItemRrn(), warehouse.getInstanceRrn(), lotNumber);
        Assert.isFalse(StringUtils.isEmpty(returnMaterialLotNumber), Errors.create().content("No sub-materialLotNumber of {} was found!").args(lotNumber).build());
        lotInventory = lotInventoryManager.getLotInventory(returnMaterialLotNumber, material.getInstanceRrn(), warehouse.getInstanceRrn());
        warehouseTrans = new WarehouseTransBO(lotInventory);
        map.put(AsmConst.LOT_NUMBER, returnMaterialLotNumber);
        buildWarehouseTransForBom(warehouseTrans, warehouse, material, map);

        lotInventory.setStatus(lotInventoryManager.getLotInventoryStatus(lotInventory.getLotNumber(),
                                                                         lotInventory.getTotalQuantity(),
                                                                         warehouseTrans.getTransQty()));

        warehouseTrans.setTargetType(MapUtils.getString(map, AsmConst.CONVERSION_TYPE));
        warehouseTrans.setTransType(buildConversionTargetType(sourceType, warehouseTrans.getTargetType()));
        warehouseTrans.setTargetLotNumber(StringUtils.substringBeforeLast(lotInventory.getLotNumber(), sourceType) +
                                                  warehouseTrans.getTargetType());
        convertTrans.add(warehouseTrans);
        warehouseManager.saveConvertMaterialFromWarehouse(facilityRrn, userId, convertTrans);
    }
}