|
|
|
@ -39,6 +39,7 @@ import com.alibaba.fastjson.JSONObject;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
import org.apache.commons.collections.map.CaseInsensitiveMap;
|
|
|
|
|
import org.apache.commons.collections.map.HashedMap;
|
|
|
|
|
import org.python.antlr.ast.While;
|
|
|
|
|
import org.springframework.beans.BeanUtils;
|
|
|
|
|
import org.springframework.beans.BeansException;
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
@ -186,6 +187,21 @@ public class MesWorkOrderService extends BaseMesService<MesWorkOrder> implements
|
|
|
|
|
@Autowired
|
|
|
|
|
private MesPartProdGroupRepository mesPartProdGroupRao;
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private MesPullingOrderInfoRepository mesPullingOrderInfoRao;
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private MesPartPullRepository partPullRao;
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private MesWorkCenterRepository workCenterRao;
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private MesPartPullDetailRepository partPullDetailRao;
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private MesBomRepository bomRao;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public MesWorkOrder insert(MesWorkOrder bean) {
|
|
|
|
|
// 数据校验
|
|
|
|
@ -715,6 +731,220 @@ public class MesWorkOrderService extends BaseMesService<MesWorkOrder> implements
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void doCreateKitting(List<MesWorkOrder> mesWorkOrderList,String organizeCode) {
|
|
|
|
|
//todo 在工单点击发布时,也需要重新触发拉动单,工单关闭时,也需要关闭拉动单
|
|
|
|
|
//1.拉动组获取 -- 根据拉动组类型获取kitting,需要判断是否生成是否生成拉动单开关
|
|
|
|
|
DdlPackBean partPullPackBean = DdlPackBean.getDdlPackBean(organizeCode);
|
|
|
|
|
DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.PART_PULL_ORDER_TYPE.KITTING_PULL.getValue(),"pullOrderType", partPullPackBean);
|
|
|
|
|
DdlPreparedPack.getNumEqualPack(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue(),"isAutoCreatePullOrder", partPullPackBean);
|
|
|
|
|
List<MesPartPull> mesPartPullList = partPullRao.findByHqlWhere(partPullPackBean);
|
|
|
|
|
//2.工单 过滤出未生成拉动单的工单pullingStatus,按照拉动组产线分组,每组按照工单序号排序
|
|
|
|
|
Map<String, List<MesWorkOrder>> workOrderMap = mesWorkOrderList.stream().filter(item -> item.getPullingStatus() == MesExtEnumUtil.WORK_ORDER_PULLING_STATUS.NOTCREATE.getValue()).collect(Collectors.groupingBy(MesWorkOrder::getWorkCenterCode));
|
|
|
|
|
|
|
|
|
|
//3.查询2中所有的产线信息 ,判断生成拉动单的工单状态 generateStatus 与工单状态对比 是否生成拉动单 MesExtEnumUtil.GENERATE_STATUS需要和工单类型一致才生成拉动单
|
|
|
|
|
List<String> workOrderCenterList = new ArrayList<>(workOrderMap.keySet());
|
|
|
|
|
DdlPackBean workCenterPackBean = DdlPackBean.getDdlPackBean(organizeCode);
|
|
|
|
|
DdlPreparedPack.getInPackList(workOrderCenterList,"workCenterCode", workCenterPackBean);
|
|
|
|
|
List<MesWorkCenter> workCenterList = workCenterRao.findByHqlWhere(workCenterPackBean);
|
|
|
|
|
Map<String, List<MesWorkCenter>> workCenterMap = workCenterList.stream().collect(Collectors.groupingBy(MesWorkCenter::getWorkCenterCode));
|
|
|
|
|
//4.遍历拉动组
|
|
|
|
|
for (MesPartPull mesPartPull : mesPartPullList) {
|
|
|
|
|
String workCenterCode = mesPartPull.getWorkCenterCode();
|
|
|
|
|
//按数量圆整
|
|
|
|
|
if(mesPartPull.getRoundMethod() == MesExtEnumUtil.PART_PULL_ROUND_METHOD.ROUND_BY_QUANTITY.getValue()){
|
|
|
|
|
List<MesWorkOrder> workOrderList = workOrderMap.get(workCenterCode);
|
|
|
|
|
//遍历工单,打散成bom 生成拉动单
|
|
|
|
|
List<MesWorkCenter> mesWorkCenters = workCenterMap.get(workCenterCode);
|
|
|
|
|
if (CollectionUtils.isEmpty(workOrderList) || CollectionUtils.isEmpty(mesWorkCenters)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
Map<String, List<MesWorkOrder>> orderMap = workOrderList.stream().collect(Collectors.groupingBy(MesWorkOrder::getPartNo));
|
|
|
|
|
for (String producePartNoAndTime : orderMap.keySet()) {
|
|
|
|
|
List<MesWorkOrder> workOrderListNew = orderMap.get(producePartNoAndTime);
|
|
|
|
|
doCreateKittingOrder(workOrderListNew,mesPartPull,mesWorkCenters.get(0));
|
|
|
|
|
}
|
|
|
|
|
//按成套圆整
|
|
|
|
|
} else if (mesPartPull.getRoundMethod() == MesExtEnumUtil.PART_PULL_ROUND_METHOD.ROUND_DOOR_PANELS_NUMBER.getValue()) {
|
|
|
|
|
//按成套圆整 会是同一个拉动组 生成拉动单
|
|
|
|
|
Map<Long, List<MesWorkOrder>> groupCodeMap = workOrderMap.get(workCenterCode).stream().collect(Collectors.groupingBy(MesWorkOrder::getGroupCode));
|
|
|
|
|
for (Long l : groupCodeMap.keySet()) {
|
|
|
|
|
List<MesWorkOrder> workOrderList = groupCodeMap.get(l);
|
|
|
|
|
List<MesWorkCenter> mesWorkCenters = workCenterMap.get(workCenterCode);
|
|
|
|
|
if (CollectionUtils.isEmpty(workOrderList) || CollectionUtils.isEmpty(mesWorkCenters)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
doCreateGroupKittingOrder(workOrderList,mesPartPull,mesWorkCenters.get(0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//按成套圆整
|
|
|
|
|
private void doCreateGroupKittingOrder(List<MesWorkOrder> workOrderListNew,MesPartPull mesPartPull,MesWorkCenter mesWorkCenter){
|
|
|
|
|
String organizeCode = mesPartPull.getOrganizeCode();
|
|
|
|
|
List<MesBom> list = new ArrayList<>();
|
|
|
|
|
//1.查询拉动组详情
|
|
|
|
|
DdlPackBean pullPartDetailPackBean = DdlPackBean.getDdlPackBean(organizeCode);
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(mesPartPull.getPullCode(),"pullCode", pullPartDetailPackBean);
|
|
|
|
|
List<MesPartPullDetail> mesPartPullDetailList = partPullDetailRao.findByHqlWhere(pullPartDetailPackBean);
|
|
|
|
|
if (CollectionUtils.isEmpty(mesPartPullDetailList)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 打散所有的工单的bom
|
|
|
|
|
List<String> pullPartNoList = mesPartPullDetailList.stream().map(MesPartPullDetail::getPullPartNo).collect(Collectors.toList());
|
|
|
|
|
Map<String, MesPartPullDetail> pullDetailMap = mesPartPullDetailList.stream().collect(Collectors.toMap(MesPartPullDetail::getPullPartNo, Function.identity()));
|
|
|
|
|
for (MesWorkOrder mesWorkOrder : workOrderListNew) {
|
|
|
|
|
List<MesBom> bomList = getPlatBom(null, mesWorkOrder.getPartNo(), TimeTool.getNowTime(true), organizeCode);
|
|
|
|
|
List<MesBom> collect = bomList.stream().filter(item -> pullPartNoList.contains(item.getItemPartNo())).collect(Collectors.toList());
|
|
|
|
|
collect.forEach(item -> item.setItemQty(item.getItemQty() * mesWorkOrder.getQty()));
|
|
|
|
|
list.addAll(collect);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算所有拉动单的数量,生成拉动单
|
|
|
|
|
|
|
|
|
|
String workOrderStr = workOrderListNew.stream().map(MesWorkOrder::getWorkOrderNo).collect(Collectors.joining("/r/n"));
|
|
|
|
|
String workOrderPartNoStr = workOrderListNew.stream().map(MesWorkOrder::getPartNo).collect(Collectors.joining("/r/n"));
|
|
|
|
|
String workOrderPartNameStr = workOrderListNew.stream().map(MesWorkOrder::getPartName).collect(Collectors.joining("/r/n"));
|
|
|
|
|
String custPartNo = workOrderListNew.stream().map(MesWorkOrder::getCustPartNo).collect(Collectors.joining("/r/n"));
|
|
|
|
|
MesPullingOrderInfo pullingOrder = new MesPullingOrderInfo();
|
|
|
|
|
pullingOrder.setOrganizeCode(organizeCode);
|
|
|
|
|
pullingOrder.setPullingOrderNo("xxx"); //拉动单号 + 8位年月日 + 5位流水号
|
|
|
|
|
pullingOrder.setPullOrderType(mesPartPull.getPullOrderType());
|
|
|
|
|
pullingOrder.setPullGroupFid(mesPartPull.getId());
|
|
|
|
|
pullingOrder.setWorkOrderNo(workOrderStr);
|
|
|
|
|
pullingOrder.setIsPrint(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue());
|
|
|
|
|
pullingOrder.setPrintStatus(MesExtEnumUtil.PRINT_STATUS.UNPRINT.getValue());
|
|
|
|
|
pullingOrder.setPullOrderStatus(MesExtEnumUtil.PULL_ORDER_STATUS.PULL_ORDER_STATUS_10.getValue());
|
|
|
|
|
pullingOrder.setWorkCenterCode(mesPartPull.getWorkCenterCode());
|
|
|
|
|
pullingOrder.setPullCode(mesPartPull.getPullCode());
|
|
|
|
|
pullingOrder.setPartNo(workOrderPartNoStr);
|
|
|
|
|
pullingOrder.setPartName(workOrderPartNameStr);
|
|
|
|
|
pullingOrder.setCustPartNo(custPartNo);
|
|
|
|
|
pullingOrder.setCarModelCode(workOrderListNew.get(0).getCarModelCode());
|
|
|
|
|
pullingOrder.setOrderFlag(workOrderListNew.get(0).getOrderFlag());
|
|
|
|
|
ConvertBean.serviceModelInitialize(pullingOrder, AuthUtil.getSessionUser().getUserName());
|
|
|
|
|
|
|
|
|
|
// 需要合并同类项
|
|
|
|
|
Map<String, List<MesBom>> itemBomMap = list.stream().collect(Collectors.groupingBy(MesBom::getItemPartNo));
|
|
|
|
|
for (String itemPartNo : itemBomMap.keySet()) {
|
|
|
|
|
List<MesBom> mesBoms = itemBomMap.get(itemPartNo);
|
|
|
|
|
double sum = mesBoms.stream().collect(Collectors.summarizingDouble(MesBom::getItemQty)).getSum();
|
|
|
|
|
MesPullingOrderPartInfo detail = new MesPullingOrderPartInfo();
|
|
|
|
|
detail.setOrganizeCode(organizeCode);
|
|
|
|
|
detail.setPullCode(pullingOrder.getPullCode());
|
|
|
|
|
detail.setPullingOrderNo(pullingOrder.getPullingOrderNo());
|
|
|
|
|
detail.setWorkOrderNo(pullingOrder.getWorkOrderNo());
|
|
|
|
|
detail.setWorkOrderSeq(pullingOrder.getWorkOrderSeq());
|
|
|
|
|
detail.setCustOrderNo(pullingOrder.getCustOrderNo());
|
|
|
|
|
MesBom mesBom = mesBoms.get(0);
|
|
|
|
|
detail.setPartNo(mesBom.getItemPartNo());
|
|
|
|
|
detail.setPartName(mesBom.getItemPartName());
|
|
|
|
|
detail.setPullQty(sum);
|
|
|
|
|
detail.setCustOrderNo(pullingOrder.getCustOrderNo());
|
|
|
|
|
detail.setWorkOrderSeq(pullingOrder.getWorkOrderSeq());
|
|
|
|
|
detail.setWaterSeq(pullingOrder.getProductSeq());
|
|
|
|
|
detail.setWorkCellCode(mesWorkCenter.getWorkCenterCode());
|
|
|
|
|
detail.setStatus(MesExtEnumUtil.PULL_ORDER_PART_STATUS.UN_SENTED.getValue());///明细已送料为1,未送料为0
|
|
|
|
|
detail.setCustPartNo(pullingOrder.getCustPartNo());
|
|
|
|
|
detail.setCarSeries(pullDetailMap.get(itemPartNo) == null ? "" : pullDetailMap.get(itemPartNo).getCarSeries());
|
|
|
|
|
detail.setOrderFlag(pullingOrder.getOrderFlag());
|
|
|
|
|
ConvertBean.serviceModelInitialize(detail, AuthUtil.getSessionUser().getUserName());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
private void doCreateKittingOrder(List<MesWorkOrder> workOrderListNew,MesPartPull mesPartPull,MesWorkCenter mesWorkCenter) {
|
|
|
|
|
String organizeCode = mesWorkCenter.getOrganizeCode();
|
|
|
|
|
//1.查询拉动组详情
|
|
|
|
|
DdlPackBean pullPartDetailPackBean = DdlPackBean.getDdlPackBean(organizeCode);
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(mesPartPull.getPullCode(),"pullCode", pullPartDetailPackBean);
|
|
|
|
|
List<MesPartPullDetail> mesPartPullDetailList = partPullDetailRao.findByHqlWhere(pullPartDetailPackBean);
|
|
|
|
|
if (CollectionUtils.isEmpty(mesPartPullDetailList)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
//bom中对应的partNo列表
|
|
|
|
|
List<String> partNoList = mesPartPullDetailList.stream().map(MesPartPullDetail::getPartNo).collect(Collectors.toList());
|
|
|
|
|
//深汕按照包装圆整
|
|
|
|
|
if (mesPartPull.getRoundMethod() == MesExtEnumUtil.PART_PULL_ROUND_METHOD.ROUND_BY_QUANTITY.getValue()){
|
|
|
|
|
int packRoundQty = Integer.parseInt(mesPartPull.getPackRoundQty());
|
|
|
|
|
String partNo = workOrderListNew.get(0).getPartNo();
|
|
|
|
|
//打散bom
|
|
|
|
|
List<MesBom> bomList = getPlatBom(null, partNo, TimeTool.getNowTime(true), organizeCode);
|
|
|
|
|
//需要生成拉动单的零件
|
|
|
|
|
List<MesBom> bomPullList = bomList.stream().filter(item -> partNoList.contains(item.getItemPartNo())).collect(Collectors.toList());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 满足一个拉动组就生成一个拉动单
|
|
|
|
|
* 分类
|
|
|
|
|
* 1.当前bom 子零件数量 * 工单需求数量 > packRoundQty multiple是多少,是否有余数 取模
|
|
|
|
|
* 2.当前bom 子零件数量 * 工单需求数量 = packRoundQty 直接整除,看看是否大于1 ,大于1需要拆分多个拉动单
|
|
|
|
|
* 3.当前bom 子零件数量 * 工单需求数量 < packRoundQty 需要增加一个工单来补充当前的数量,补不齐继续补充
|
|
|
|
|
*/
|
|
|
|
|
Map<String,Double> partNoRemainder = new HashMap<>();
|
|
|
|
|
for (int i = 0; i < workOrderListNew.size(); i++) {
|
|
|
|
|
MesWorkOrder mesWorkOrder = workOrderListNew.get(0);
|
|
|
|
|
Double qty = mesWorkOrder.getQty();
|
|
|
|
|
bomPullList.forEach(item -> item.setItemQty(item.getItemQty() * qty));
|
|
|
|
|
for (int j = 0; j < bomPullList.size(); j++) {
|
|
|
|
|
double m = bomPullList.get(j).getItemQty() % packRoundQty;
|
|
|
|
|
double n = bomPullList.get(j).getItemQty() / packRoundQty;
|
|
|
|
|
if (m == 0 && n != 0){
|
|
|
|
|
//子零件数量 * 工单需求数量 = packRoundQty
|
|
|
|
|
//证明当前零件需要拉动的数量是圆整数量的倍数,需要拆分多个拉动单,或者一个拉动单就满足了
|
|
|
|
|
|
|
|
|
|
}else if (m != 0 && n == 0) {
|
|
|
|
|
//子零件数量 * 工单需求数量 < packRoundQty
|
|
|
|
|
//证明需要凑下一个工单的当前零件
|
|
|
|
|
} else if (m !=0 && n > 0) {
|
|
|
|
|
//子零件数量 * 工单需求数量 > packRoundQty
|
|
|
|
|
//够一个拉动单以上的数据,还有余数给
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<MesBom> getPlatBom(MesBom mesBom,String partNo, String effectiveTime,String organizeCode) {
|
|
|
|
|
//MES汇报查询BOM是否携带结束查询条件
|
|
|
|
|
MesConfig config = mesConfigService.getCfgValueByCode(organizeCode, MesExtConstWords.MES_REPORT_FIND_BOM_WITH_EFFENDTIME);
|
|
|
|
|
Boolean isWithEffEndTime = (null != config && !org.springframework.util.StringUtils.isEmpty(config.getCfgValue()) && config.getCfgValue().equals(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr())) ? true : false;
|
|
|
|
|
|
|
|
|
|
if (mesBom == null) {
|
|
|
|
|
//首先根据虚结构的零件号查询出最新的一条bom信息作为bomCode
|
|
|
|
|
DdlPackBean bomCodePackBean = DdlPackBean.getDdlPackBean(organizeCode);
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(partNo, MesExtConstWords.PART_NO, bomCodePackBean);
|
|
|
|
|
DdlPreparedPack.getStringSmallerPack(effectiveTime, MesExtConstWords.EFF_START_TIME, bomCodePackBean);
|
|
|
|
|
if (isWithEffEndTime) DdlPreparedPack.getStringBiggerPack(effectiveTime, MesExtConstWords.EFF_END_TIME, bomCodePackBean);
|
|
|
|
|
DdlPreparedPack.getOrderBy(MesExtConstWords.EFF_START_TIME, CommonEnumUtil.ASC_OR_DESC.DESC.getValue(), bomCodePackBean);
|
|
|
|
|
List<MesBom> bomList = bomRao.findByHqlTopWhere(bomCodePackBean, 1);
|
|
|
|
|
if (bomList == null || bomList.isEmpty()) {
|
|
|
|
|
return new ArrayList<>();
|
|
|
|
|
}
|
|
|
|
|
mesBom = bomList.get(0);
|
|
|
|
|
}
|
|
|
|
|
List<MesBom> bomResultList = new ArrayList<>();
|
|
|
|
|
DdlPackBean bomPackBean = DdlPackBean.getDdlPackBean(organizeCode);
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(mesBom.getBomCode(), "bomCode", bomPackBean);
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(partNo, MesExtConstWords.PART_NO, bomPackBean);
|
|
|
|
|
DdlPreparedPack.getStringEqualPack(mesBom.getEffStartTime(), MesExtConstWords.EFF_START_TIME, bomPackBean);
|
|
|
|
|
List<MesBom> bomList = bomRao.findByHqlWhere(bomPackBean);
|
|
|
|
|
|
|
|
|
|
for (MesBom bom : bomList) {
|
|
|
|
|
if (bom.getPartType() != null && bom.getPartType().equalsIgnoreCase("X")) {
|
|
|
|
|
getPlatBom(null,bom.getItemPartNo(), effectiveTime, organizeCode);
|
|
|
|
|
} else {
|
|
|
|
|
bom.setBomCode(bom.getBomCode().toLowerCase());
|
|
|
|
|
bomResultList.add(bom);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bomResultList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void checkData(List<MesWorkOrder> mesWorkOrderList, String organizeCode) {
|
|
|
|
|
MesWorkOrder next = mesWorkOrderList.iterator().next();
|
|
|
|
|
String nowDate = TimeTool.getNowTime(true);
|
|
|
|
|