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);
}
}