CBR冲销

tags/yfai-mes-ext-v1.0
jun 11 months ago
parent 14ae5dcdf4
commit 6bd043ff5d

@ -24,6 +24,10 @@
<groupId>i3plus.ext.mes</groupId> <groupId>i3plus.ext.mes</groupId>
<artifactId>i3plus-ext-mes-pojo</artifactId> <artifactId>i3plus-ext-mes-pojo</artifactId>
</dependency> </dependency>
<dependency>
<groupId>i3plus.pojo</groupId>
<artifactId>i3plus-pojo-model</artifactId>
</dependency>
</dependencies> </dependencies>
<parent> <parent>

@ -1,6 +1,7 @@
package cn.estsh.i3plus.ext.mes.api.base; package cn.estsh.i3plus.ext.mes.api.base;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder; import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder;
import cn.estsh.i3plus.pojo.model.wms.WmsProductModel;
import java.util.List; import java.util.List;
@ -20,4 +21,6 @@ public interface IMesWorkOrderService extends IBaseMesService<MesWorkOrder> {
List<MesWorkOrder> sumMesWorkOrderQtyToSap(String organizeCode); List<MesWorkOrder> sumMesWorkOrderQtyToSap(String organizeCode);
List<MesWorkOrder> queryMesWorkOrderProcessToSap(String organizeCode); List<MesWorkOrder> queryMesWorkOrderProcessToSap(String organizeCode);
void doReportWorkReversal(WmsProductModel model);
} }

@ -9,6 +9,7 @@ import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.pojo.base.enumutil.ResourceEnumUtil; import cn.estsh.i3plus.pojo.base.enumutil.ResourceEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder; import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import cn.estsh.i3plus.pojo.model.wms.WmsProductModel;
import cn.estsh.impp.framework.boot.auth.AuthUtil; import cn.estsh.impp.framework.boot.auth.AuthUtil;
import cn.estsh.impp.framework.boot.exception.ImppBusiException; import cn.estsh.impp.framework.boot.exception.ImppBusiException;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder; import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
@ -124,6 +125,24 @@ public class MesWorkOrderController extends BaseMesController<MesWorkOrder> {
} }
} }
@PostMapping(value = "/report-work-reversal")
@ApiOperation(value = "反向冲销")
public ResultBean doReportWorkReversal(@RequestBody WmsProductModel model) {
try {
ValidatorBean.checkNotNull(model.getOrganizeCode(),"工厂代码不能为空");
ValidatorBean.checkNotNull(model.getQty(),"数量不能为空");
ValidatorBean.checkNotNull(model.getSn(),"条码不能为空");
ValidatorBean.checkNotNull(model.getPartNo(),"零件号不能为空");
ValidatorBean.checkNotNull(model.getPartNo(),"零件号不能为空");
mesWorkOrderService.doReportWorkReversal(model);
return ResultBean.success("反向冲销成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
} catch (ImppBusiException busExcep) {
return ResultBean.fail(busExcep);
} catch (Exception e) {
return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
}
}
} }

@ -10,7 +10,6 @@ import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum; import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.platform.common.tool.MathOperation; import cn.estsh.i3plus.platform.common.tool.MathOperation;
import cn.estsh.i3plus.platform.common.tool.TimeTool; import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.platform.common.util.MesConstWords;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean; import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack; import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
@ -20,6 +19,7 @@ import cn.estsh.i3plus.pojo.mes.model.GenSerialNoModel;
import cn.estsh.i3plus.pojo.mes.repository.*; import cn.estsh.i3plus.pojo.mes.repository.*;
import cn.estsh.i3plus.pojo.mes.util.DateUtilExt; import cn.estsh.i3plus.pojo.mes.util.DateUtilExt;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import cn.estsh.i3plus.pojo.model.wms.WmsProductModel;
import cn.estsh.impp.framework.boot.auth.AuthUtil; import cn.estsh.impp.framework.boot.auth.AuthUtil;
import cn.estsh.impp.framework.boot.exception.ImppBusiException; import cn.estsh.impp.framework.boot.exception.ImppBusiException;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder; import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
@ -30,10 +30,9 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.math.BigDecimal;
import java.util.List; import java.math.RoundingMode;
import java.util.Map; import java.util.*;
import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Service @Service
@ -77,6 +76,7 @@ public class MesWorkOrderService extends BaseMesService<MesWorkOrder> implements
private IMesPartSapService mesPartSapService; private IMesPartSapService mesPartSapService;
@Autowired @Autowired
private MesMoveRepository mesMoveRDao; private MesMoveRepository mesMoveRDao;
@Override @Override
public MesWorkOrder insert(MesWorkOrder bean) { public MesWorkOrder insert(MesWorkOrder bean) {
//插入前构造数据 //插入前构造数据
@ -504,7 +504,7 @@ public class MesWorkOrderService extends BaseMesService<MesWorkOrder> implements
//获取生产版本 //获取生产版本
MesProductVersion mesProductVersion = getMesProductVersion(mesWorkOrder); MesProductVersion mesProductVersion = getMesProductVersion(mesWorkOrder);
//物料+生产版本获取bom信息 //物料+生产版本获取bom信息
List<MesBom> mesBoms = getMesBoms(mesWorkOrder, mesPart, mesProductVersion); List<MesBom> mesBoms = getBomList(mesPart.getOrganizeCode(), mesPart, mesProductVersion.getAlternativePartList());
//报工类型 //报工类型
if (MesExtEnumUtil.REPORT_TYPE.REPORT.getValue() == mesWorkOrder.getReportType()) { if (MesExtEnumUtil.REPORT_TYPE.REPORT.getValue() == mesWorkOrder.getReportType()) {
mesWorkOrder.setReportedQty(MathOperation.add(mesWorkOrder.getNum(), mesWorkOrder.getReportedQty())); mesWorkOrder.setReportedQty(MathOperation.add(mesWorkOrder.getNum(), mesWorkOrder.getReportedQty()));
@ -538,8 +538,6 @@ public class MesWorkOrderService extends BaseMesService<MesWorkOrder> implements
//生成条码 //生成条码
List<String> resultList = getStringList(mesWorkOrder); List<String> resultList = getStringList(mesWorkOrder);
//bom子零件是虚零件 继续拆他下面的零件
recursionBomList(mesBoms);
//保存数据 //保存数据
List<MesProductOffLine> mesProductOffLineList = new ArrayList<>(); List<MesProductOffLine> mesProductOffLineList = new ArrayList<>();
for (String sn : resultList) { for (String sn : resultList) {
@ -549,30 +547,75 @@ public class MesWorkOrderService extends BaseMesService<MesWorkOrder> implements
} }
mesProductOffLineService.insertBatch(mesProductOffLineList); mesProductOffLineService.insertBatch(mesProductOffLineList);
} }
/**
* bom
*/ public List<MesBom> getBomList(String organizeCode, MesPart mesPart, String bomVersion) {
private List<MesBom> recursionBomList(List<MesBom> bomList) { List<MesBom> bomData = new ArrayList<>();
if (!org.springframework.util.CollectionUtils.isEmpty(bomList)) { // 递归展开 BOM
for (MesBom bom : bomList) { expendBomChild(organizeCode, mesPart.getPartNo(), bomVersion, bomData);
// if (bom.getItemPartNo().equals(bom.getPartNo())){
// continue; if (bomData.size() == 0) {
// } MesException.throwMesBusiException("零件号 %s 没找找到 ERP 同步的原始 BOM 数据,请检查接口是否正常!", mesPart.getPartNo());
if (!bom.getPartType().contains("V")){
continue;
} }
List<MesBom> resultList = mesBomRDao.findByProperty(
new String[]{MesConstWords.IS_VALID, MesConstWords.IS_DELETED, MesConstWords.ORGANIZE_CODE, "partNo"},
new Object[]{CommonEnumUtil.IS_VAILD.VAILD.getValue(), CommonEnumUtil.IS_DEAL.NO.getValue(),
bom.getOrganizeCode(), bom.getItemPartNo()});
recursionBomList(resultList); Iterator<MesBom> iterator = bomData.iterator();
// bom.setChildTreeList(resultList); while (iterator.hasNext()) {
MesBom item = iterator.next();
// 删除虚零件
if (Objects.equals("X", item.getPartType())) {
iterator.remove();
} else {
item.setPartNo(mesPart.getPartNo());
item.setPartName(mesPart.getPartName());
} }
} }
return bomList;
Map<String, MesBom> summaryBomMap = new HashMap<>();
for (MesBom item : bomData) {
String key = String.format("%s:%s", item.getPartNo().toUpperCase().trim(),
item.getItemPartNo().toUpperCase().trim());
if (!summaryBomMap.containsKey(key)) {
summaryBomMap.put(key, item);
} else {
MesBom tempItem = summaryBomMap.get(key);
// 子零件重复的累加数量
tempItem.setItemQty(MathOperation.add(tempItem.getItemQty(), item.getItemQty()));
}
} }
// 返回汇总数据
return new ArrayList<>(summaryBomMap.values());
}
/**
* BOM
*
* @param organizeCode
* @param partNo
* @param bomData BOM
*/
private void expendBomChild(String organizeCode, String partNo, String bomVersion, List<MesBom> bomData) {
List<MesBom> bomDetails = getMesBoms(partNo, organizeCode, bomVersion);
for (MesBom item : bomDetails) {
MesBom newItem = new MesBom();
BeanUtils.copyProperties(item, newItem);
// 处理父零件用量不为 1 的情况
if (newItem.getQty() != 1.0 && newItem.getQty() > 0.0) {
Double rateQty = divide(newItem.getItemQty(), newItem.getQty(), 8);
newItem.setQty(1.0);
newItem.setItemQty(rateQty);
}
// 加入到 BOM 清单中
bomData.add(newItem);
// 如果有子阶,继续递归
if (Objects.equals("X", item.getPartType())) {
expendBomChild(organizeCode, newItem.getItemPartNo(), null, bomData);
}
}
}
@Override @Override
public void doProductReportExt(MesWorkOrder mesWorkOrderNew) { public void doProductReportExt(MesWorkOrder mesWorkOrderNew) {
MesWorkOrder mesWorkOrder = baseRDao.getById(mesWorkOrderNew.getId()); MesWorkOrder mesWorkOrder = baseRDao.getById(mesWorkOrderNew.getId());
@ -612,7 +655,7 @@ public class MesWorkOrderService extends BaseMesService<MesWorkOrder> implements
//获取生产版本 //获取生产版本
MesProductVersion mesProductVersion = getMesProductVersion(mesWorkOrder); MesProductVersion mesProductVersion = getMesProductVersion(mesWorkOrder);
//物料+生产版本获取bom信息 //物料+生产版本获取bom信息
List<MesBom> mesBoms = getMesBoms(mesWorkOrder, mesPart, mesProductVersion); List<MesBom> mesBoms = getBomList(mesPart.getOrganizeCode(), mesPart, mesProductVersion.getAlternativePartList());
//生成条码 //生成条码
List<String> resultList = getStringList(mesWorkOrderNew); List<String> resultList = getStringList(mesWorkOrderNew);
//保存数据 //保存数据
@ -696,6 +739,59 @@ public class MesWorkOrderService extends BaseMesService<MesWorkOrder> implements
new Object[]{userName, TimeTool.getNowTime(true), MesExtEnumUtil.ORDER_STATUS.CLOSE.getValue()}, ddlPackBean); new Object[]{userName, TimeTool.getNowTime(true), MesExtEnumUtil.ORDER_STATUS.CLOSE.getValue()}, ddlPackBean);
} }
@Override
public void doReportWorkReversal(WmsProductModel model) {
//查询物料信息
MesPart mesPart = iMesPartService.getPartByPartNo(model.getPartNo(), model.getOrganizeCode());
//获取生产版本
MesProductVersion mesProductVersion = getMesProductVersion(model);
//获取bom
List<MesBom> mesBoms = getBomList(mesPart.getOrganizeCode(), mesPart, mesProductVersion.getAlternativePartList());
//保存数据
List<MesProductOffLine> mesProductOffLineList = new ArrayList<>();
for (MesBom mesBom : mesBoms) {
mesProductOffLineList.add(getMesProductOffLine(model, mesPart, mesProductVersion, mesBom));
}
mesProductOffLineService.insertBatch(mesProductOffLineList);
}
private MesProductOffLine getMesProductOffLine(WmsProductModel model, MesPart mesPart, MesProductVersion mesProductVersion, MesBom mesBom) {
MesProductOffLine newMesProductOffLine = new MesProductOffLine();
newMesProductOffLine.setReportPartNo(mesPart.getPartNo());
newMesProductOffLine.setReportPartNameRdd(mesPart.getPartName());
newMesProductOffLine.setReportSn(model.getSn());
newMesProductOffLine.setItemPartNo(mesBom.getItemPartNo());
newMesProductOffLine.setItemPartName(mesBom.getItemPartName());
newMesProductOffLine.setItemQty(MathOperation.mul(model.getQty(), mesBom.getItemQty()));
newMesProductOffLine.setAlort(mesProductVersion.getReceiveInventoryPoint());
newMesProductOffLine.setStgeLoc(mesProductVersion.getShipInventoryPoint());
newMesProductOffLine.setQty(model.getQty());
newMesProductOffLine.setBomVersion(mesProductVersion.getProductVersion());
newMesProductOffLine.setSerialNumber(model.getSn());
newMesProductOffLine.setUnit(mesBom.getUnit());
newMesProductOffLine.setItemUnit(mesBom.getItemUnit());
newMesProductOffLine.setReportType(MesExtEnumUtil.REPORT_TYPE.CBR.getValue());
newMesProductOffLine.setOrganizeCode(model.getOrganizeCode());
newMesProductOffLine.setOrderNo(model.getShipOrderNo());
newMesProductOffLine.setCustNo(model.getCustNo());
newMesProductOffLine.setCustOrder(model.getCustOrderNo());
ConvertBean.serviceModelInitialize(newMesProductOffLine, model.getUserName());
return newMesProductOffLine;
}
private MesProductVersion getMesProductVersion(WmsProductModel model) {
DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(model.getOrganizeCode());
DdlPreparedPack.getStringEqualPack(model.getPartNo(), "partNo", ddlPackBean);
DdlPreparedPack.getOrderBy(null, null, ddlPackBean);
MesProductVersion mesProductVersion = mesProductVersionRDao.getByProperty(ddlPackBean);
if (null == mesProductVersion) {
MesException.throwMesBusiException("物料【%s】生产版本信息不存在", model.getPartNo());
}
return mesProductVersion;
}
private void customerSupplyMove(MesWorkOrder mesWorkOrder, MesProductVersion mesProductVersion, List<MesBom> mesBoms, List<String> resultList, List<MesProductOffLine> mesProductOffLineList, List<MesMove> mesMoveList) { private void customerSupplyMove(MesWorkOrder mesWorkOrder, MesProductVersion mesProductVersion, List<MesBom> mesBoms, List<String> resultList, List<MesProductOffLine> mesProductOffLineList, List<MesMove> mesMoveList) {
boolean isItemMove; boolean isItemMove;
boolean isItemReport; boolean isItemReport;
@ -774,17 +870,15 @@ public class MesWorkOrderService extends BaseMesService<MesWorkOrder> implements
return resultList; return resultList;
} }
private List<MesBom> getMesBoms(MesWorkOrder mesWorkOrder, MesPart mesPart, MesProductVersion mesProductVersion) { private List<MesBom> getMesBoms(String partNo, String organizeCode, String bomVersion) {
DdlPackBean ddlPackBean; DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode);
ddlPackBean = DdlPackBean.getDdlPackBean(mesWorkOrder.getOrganizeCode()); DdlPreparedPack.getStringEqualPack(partNo, "partNo", ddlPackBean);
DdlPreparedPack.getStringEqualPack(mesPart.getPartNo(), "partNo", ddlPackBean); DdlPreparedPack.getStringEqualPack(bomVersion, "bomVersion", ddlPackBean);
DdlPreparedPack.getStringEqualPack(mesProductVersion.getAlternativePartList(), "bomVersion", ddlPackBean);
DdlPreparedPack.getStringSmallerPack(TimeTool.getNowTime(true), "effStartTime", ddlPackBean); DdlPreparedPack.getStringSmallerPack(TimeTool.getNowTime(true), "effStartTime", ddlPackBean);
DdlPreparedPack.getOrderBy("effStartTime", CommonEnumUtil.ASC_OR_DESC.DESC.getValue(), ddlPackBean); DdlPreparedPack.getOrderBy("effStartTime", CommonEnumUtil.ASC_OR_DESC.DESC.getValue(), ddlPackBean);
List<MesBom> mesBoms = mesBomRDao.findByHqlWhere(ddlPackBean); List<MesBom> mesBoms = mesBomRDao.findByHqlWhere(ddlPackBean);
if (CollectionUtils.isEmpty(mesBoms)) { if (CollectionUtils.isEmpty(mesBoms)) {
MesException.throwMesBusiException("物料【%s】生产版本【%s】对应bom信息不存在", MesException.throwMesBusiException("物料【%s】生产版本【%s】对应bom信息不存在", partNo, bomVersion);
mesWorkOrder.getPartNo(), mesProductVersion.getProductVersion());
} }
MesBom next = mesBoms.iterator().next(); MesBom next = mesBoms.iterator().next();
//如果存在多个bomCode取最新的一个 //如果存在多个bomCode取最新的一个
@ -843,6 +937,7 @@ public class MesWorkOrderService extends BaseMesService<MesWorkOrder> implements
//查询汇总工单数量 //查询汇总工单数量
return mesWorkOrderDao.sumMesWorkOrderQtyToSap(organizeCode, statusList); return mesWorkOrderDao.sumMesWorkOrderQtyToSap(organizeCode, statusList);
} }
@Override @Override
public List<MesWorkOrder> queryMesWorkOrderProcessToSap(String organizeCode) { public List<MesWorkOrder> queryMesWorkOrderProcessToSap(String organizeCode) {
List<Integer> statusList = new ArrayList<>(); List<Integer> statusList = new ArrayList<>();
@ -871,4 +966,21 @@ public class MesWorkOrderService extends BaseMesService<MesWorkOrder> implements
ConvertBean.serviceModelInitialize(move, AuthUtil.getSessionUser().getUserName()); ConvertBean.serviceModelInitialize(move, AuthUtil.getSessionUser().getUserName());
return move; return move;
} }
/**
* scale
*
* @param dividend
* @param divisor
* @param scale
* @return
*/
public Double divide(Double dividend, Double divisor, Integer scale) {
if (scale < 0) {
throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(Double.toString(dividend));
BigDecimal b2 = new BigDecimal(Double.toString(divisor));
return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue();
}
} }

@ -34,6 +34,10 @@
<groupId>i3plus.ext.mes</groupId> <groupId>i3plus.ext.mes</groupId>
<artifactId>i3plus-ext-mes-pojo</artifactId> <artifactId>i3plus-ext-mes-pojo</artifactId>
</dependency> </dependency>
<dependency>
<groupId>i3plus.pojo</groupId>
<artifactId>i3plus-pojo-model</artifactId>
</dependency>
</dependencies> </dependencies>

@ -0,0 +1,34 @@
package cn.estsh.i3plus.ext.mes.icloud.sdk;
import cn.estsh.i3plus.ext.mes.icloud.sdkfallback.MesForWmsFactory;
import cn.estsh.i3plus.ext.mes.pojo.constant.MesCommonConstant;
import cn.estsh.i3plus.pojo.base.bean.BaseResultBean;
import cn.estsh.i3plus.pojo.model.wms.WmsProductModel;
import io.swagger.annotations.ApiOperation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
* @Description :
* @Reference :
* @Author : junsheng.li
* @CreateDate 2024/6/13 19:23
* @Modify:
**/
@FeignClient(name = "i3mes", //对应配置文件中的spring.application.name
path = MesCommonConstant.MES_YANFEN + "/mesWorkOrder",
fallbackFactory = MesForWmsFactory.class)
public interface IMesForWmsCloud {
/**
* MEScloud
*
* @return
*/
@PostMapping(value = "/report-work-reversal")
@ApiOperation(value = "反向冲销")
BaseResultBean doReportWorkReversal(@RequestBody WmsProductModel model);
}

@ -0,0 +1,35 @@
package cn.estsh.i3plus.ext.mes.icloud.sdkfallback;
import cn.estsh.i3plus.ext.mes.icloud.sdk.IMesForWmsCloud;
import cn.estsh.i3plus.platform.common.util.CommonConstWords;
import cn.estsh.i3plus.pojo.base.bean.BaseFallBackBean;
import cn.estsh.i3plus.pojo.base.bean.BaseResultBean;
import cn.estsh.i3plus.pojo.model.wms.WmsProductModel;
import feign.hystrix.FallbackFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* @Description :
* @Reference :
* @Author : junsheng.li
* @CreateDate 2024/6/13 19:13
* @Modify:
**/
@Component
public class MesForWmsFactory extends BaseFallBackBean implements FallbackFactory<IMesForWmsCloud> {
private static final Logger LOGGER = LoggerFactory.getLogger(CommonConstWords.SYSTEM_LOG);
@Override
public IMesForWmsCloud create(Throwable cause) {
return new IMesForWmsCloud() {
@Override
public BaseResultBean doReportWorkReversal(WmsProductModel model) {
return makeBaseFallBack("微服调用出错", cause);
}
};
}
}
Loading…
Cancel
Save