package com.chinaztt.mes.plan.service.impl;
|
|
import cn.hutool.core.collection.CollectionUtil;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
|
import com.chinaztt.mes.common.handler.StateMachineHandler;
|
import com.chinaztt.mes.common.numgen.NumberGenerator;
|
import com.chinaztt.mes.common.util.StateResult;
|
import com.chinaztt.mes.common.util.WxCpUtils;
|
import com.chinaztt.mes.plan.dto.MpsRequirementsDTO;
|
import com.chinaztt.mes.plan.entity.*;
|
import com.chinaztt.mes.plan.mapper.*;
|
import com.chinaztt.mes.plan.service.MpsRequirementsService;
|
import com.chinaztt.mes.plan.state.requirement.MpsRequirementsStateMachineConfig;
|
import com.chinaztt.mes.plan.state.requirement.constant.MpsRequirementsEvents;
|
import com.chinaztt.mes.plan.state.requirement.constant.MpsRequirementsStates;
|
import com.chinaztt.ztt.admin.api.feign.RemoteParamService;
|
import com.chinaztt.ztt.common.core.constant.SecurityConstants;
|
import lombok.AllArgsConstructor;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.messaging.Message;
|
import org.springframework.messaging.support.MessageBuilder;
|
import org.springframework.statemachine.config.StateMachineFactory;
|
import org.springframework.statemachine.persist.StateMachinePersister;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.math.BigDecimal;
|
import java.time.LocalDateTime;
|
import java.time.format.DateTimeFormatter;
|
import java.util.ArrayList;
|
import java.util.List;
|
import java.util.stream.Collectors;
|
|
/**
|
* @ClassName MpsRequirementsServiceImpl
|
* @Description TODO
|
* @Author luh
|
* @Date 2020/8/27 16:51
|
* @Version 1.0
|
**/
|
@Service
|
@Transactional(rollbackFor = Exception.class)
|
@AllArgsConstructor
|
public class MpsRequirementsServiceImpl extends ServiceImpl<MpsRequirementsMapper, MpsRequirements> implements MpsRequirementsService {
|
private static Logger logger = LoggerFactory.getLogger(MpsRequirementsServiceImpl.class);
|
private PlanJoinOrderRequirementsMapper planJoinOrderRequirementsMapper;
|
private MpsSourceMapper planMpsSourceMapper;
|
private MasterProductionScheduleMapper masterProductionScheduleMapper;
|
private NumberGenerator<MpsRequirements> requirementsNumberGenerator;
|
private NumberGenerator<MasterProductionSchedule> scheduleNumberGenerator;
|
private StateMachineFactory<MpsRequirementsStates, MpsRequirementsEvents> mpsRequirementsStateMachineFactory;
|
private StateMachinePersister<MpsRequirementsStates, MpsRequirementsEvents, MpsRequirements> persister;
|
private CustomerOrderMapper customerOrderMapper;
|
private RemoteParamService remoteParamService;
|
|
@Override
|
public IPage<List<MpsRequirements>> getMpsRequirementsPage(Page page, QueryWrapper<MpsRequirementsDTO> mpsRequirements, String type) {
|
return baseMapper.getMpsRequirementsPage(page, mpsRequirements, type);
|
}
|
|
@Override
|
public boolean deleteById(Long id) {
|
// 判断一下是否已生成主计划,若生成无法删除
|
List<String> mpsNos = baseMapper.selectScheduleByRequirementsId(id);
|
if (CollectionUtil.isNotEmpty(mpsNos)) {
|
throw new RuntimeException("已生成对应主计划无法删除:" + mpsNos.stream().collect(Collectors.joining(",")));
|
}
|
// 1.删除主生产计划需求
|
boolean result = SqlHelper.retBool(baseMapper.deleteById(id));
|
// 2.删除主生产计划需求和客户订单关联表
|
planJoinOrderRequirementsMapper.delete(Wrappers.<PlanJoinOrderRequirements>query().lambda()
|
.eq(PlanJoinOrderRequirements::getMpsRequirementsId, id));
|
return result;
|
}
|
|
@Override
|
public boolean updateById(MpsRequirements mpsRequirements) {
|
boolean result = SqlHelper.retBool(baseMapper.updateById(mpsRequirements));
|
// 更新来源对应的主生产计划的最新时间
|
masterProductionScheduleMapper.updateRequiredDateBySource(mpsRequirements);
|
try {
|
String staffStr = remoteParamService.getByKey("MPS_REQUIMENT_UPDATE_STAFF", SecurityConstants.FROM_IN).getData();
|
if (StringUtils.isNotBlank(staffStr)) {
|
WxCpUtils.inform(staffStr, mpsRequirements.getUpdateUser() + "编辑了主需求:" + mpsRequirements.getIndeRequNo(), null);
|
}
|
} catch (Exception e) {
|
logger.error(e.getMessage());
|
throw new RuntimeException("编辑主需求消息推送失败");
|
}
|
return result;
|
}
|
|
@Override
|
public boolean save(MpsRequirements mpsRequirements) {
|
mpsRequirements.setSourceType("01");
|
mpsRequirements.setIndeRequNo(requirementsNumberGenerator.generateNumberWithPrefix(MpsRequirements.DIGIT, MpsRequirements.PREFIX, MpsRequirements::getIndeRequNo));
|
boolean result = SqlHelper.retBool(baseMapper.insert(mpsRequirements));
|
try {
|
String staffStr = remoteParamService.getByKey("MPS_REQUIMENT_INSERT_STAFF", SecurityConstants.FROM_IN).getData();
|
if (StringUtils.isNotBlank(staffStr)) {
|
WxCpUtils.inform(staffStr, mpsRequirements.getUpdateUser() + "创建了主需求:" + mpsRequirements.getIndeRequNo(), null);
|
}
|
} catch (Exception e) {
|
logger.error(e.getMessage());
|
throw new RuntimeException("新增主需求消息推送失败");
|
}
|
return result;
|
}
|
|
@Override
|
public MpsRequirementsDTO selectById(Long id) {
|
return baseMapper.selectDtoById(id);
|
}
|
|
@Override
|
public void checkOverageOrder(MpsRequirements mpsRequirements) {
|
BigDecimal qtyRequiredSum = baseMapper.getQtyRequiredSumById(mpsRequirements.getId());
|
if (BigDecimal.ZERO.compareTo(qtyRequiredSum) == 0) {
|
// 1.不存在客户订单
|
return;
|
} else {
|
// 2.查询对应客户订单的数量
|
BigDecimal orderQuantity = baseMapper.getOrderQuantityById(mpsRequirements.getId());
|
qtyRequiredSum = qtyRequiredSum.add(mpsRequirements.getQtyRequired());
|
if (qtyRequiredSum.compareTo(orderQuantity) == 1) {
|
// 超出数量
|
throw new RuntimeException("修改后的总计划需求数量超出订单数量:" + qtyRequiredSum.subtract(orderQuantity).stripTrailingZeros().toPlainString());
|
}
|
}
|
}
|
|
@Override
|
public boolean changeState(List<Long> ids, String event) {
|
if (CollectionUtil.isEmpty(ids)) {
|
throw new RuntimeException("请选择主生产计划需求");
|
}
|
for (Long id : ids) {
|
MpsRequirements mpsRequirements = baseMapper.selectById(id);
|
Message<MpsRequirementsEvents> message = MessageBuilder.withPayload(MpsRequirementsEvents.valueOf(event)).setHeader("mpsRequirements", mpsRequirements).build();
|
StateMachineHandler handler = new StateMachineHandler(mpsRequirementsStateMachineFactory, persister, MpsRequirementsStateMachineConfig.MACHINE_ID, mpsRequirements);
|
StateResult res = handler.sendEvent(message, mpsRequirements.getId());
|
if (!res.isSuccess()) {
|
throw new RuntimeException(res.getMsg());
|
}
|
}
|
return true;
|
}
|
|
@Override
|
public boolean createMasterProductionSchedule(List<MpsRequirementsDTO> mpsRequirementsDTOList) {
|
if (CollectionUtil.isEmpty(mpsRequirementsDTOList)) {
|
throw new RuntimeException("请选择主生产计划需求");
|
}
|
List<List<MpsRequirementsDTO>> partList = new ArrayList<>();
|
// 1.先按零件分组
|
List<List<MpsRequirementsDTO>> groupList = new ArrayList<>();
|
mpsRequirementsDTOList.stream().collect(Collectors.groupingBy(MpsRequirementsDTO::getPartId, Collectors.toList()))
|
.forEach((part, listByPart) -> {
|
groupList.add(listByPart);
|
});
|
try {
|
for (List<MpsRequirementsDTO> listByPart : groupList) {
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
Long id = listByPart.get(0).getPartId();
|
LocalDateTime requiredDate = listByPart.get(0).getRequiredDate();
|
String date = formatter.format(listByPart.get(0).getCreateTime());
|
MasterProductionSchedule newMasterProductionSchedule = masterProductionScheduleMapper.getPlanProduction(id, date);
|
if (newMasterProductionSchedule != null) {
|
if (newMasterProductionSchedule.getRequiredDate().isBefore(listByPart.get(0).getRequiredDate())) {
|
requiredDate = newMasterProductionSchedule.getRequiredDate();
|
}
|
newMasterProductionSchedule.setQtyRequired(newMasterProductionSchedule.getQtyRequired().add(listByPart.get(0).getQtyPlaned()));
|
newMasterProductionSchedule.setRequiredDate(requiredDate);
|
newMasterProductionSchedule.setSource("主需求");
|
masterProductionScheduleMapper.updateById(newMasterProductionSchedule);
|
// 2.3.保存主生产计划来源
|
for (MpsRequirementsDTO mpsRequirementsDTO : listByPart) {
|
save(mpsRequirementsDTO, newMasterProductionSchedule.getId());
|
}
|
} else {
|
partList.add(listByPart);
|
}
|
}
|
|
} catch (Exception e) {
|
log.error("创建主生产计划失败", e);
|
throw new RuntimeException("创建主生产计划失败");
|
}
|
// 2.再合并生成主计划
|
try {
|
for (List<MpsRequirementsDTO> listByPart : partList) {
|
// 2.1合并计划数量,取最早的需求日期
|
BigDecimal totalQuantity = BigDecimal.ZERO;
|
LocalDateTime requiredDate = listByPart.get(0).getRequiredDate();
|
for (MpsRequirementsDTO mpsRequirementsDTO : listByPart) {
|
totalQuantity = totalQuantity.add(mpsRequirementsDTO.getQtyPlaned());
|
if (mpsRequirementsDTO.getRequiredDate().isBefore(requiredDate)) {
|
requiredDate = mpsRequirementsDTO.getRequiredDate();
|
}
|
}
|
// 2.2.保存主生产计划
|
MasterProductionSchedule masterProductionSchedule = new MasterProductionSchedule();
|
masterProductionSchedule.setMpsNo(scheduleNumberGenerator.generateNumberWithPrefix(MasterProductionSchedule.DIGIT, MasterProductionSchedule.PREFIX, MasterProductionSchedule::getMpsNo));
|
masterProductionSchedule.setPartId(listByPart.get(0).getPartId());
|
masterProductionSchedule.setQtyRequired(totalQuantity);
|
masterProductionSchedule.setRequiredDate(requiredDate);
|
masterProductionSchedule.setSource("主需求");
|
masterProductionScheduleMapper.insert(masterProductionSchedule);
|
// 2.3.保存主生产计划来源
|
for (MpsRequirementsDTO mpsRequirementsDTO : listByPart) {
|
save(mpsRequirementsDTO, masterProductionSchedule.getId());
|
}
|
}
|
|
} catch (Exception e) {
|
log.error("创建主生产计划失败", e);
|
throw new RuntimeException("创建主生产计划失败");
|
}
|
return true;
|
}
|
|
@Override
|
public List<CustomerOrder> getCustomer(Long id) {
|
return customerOrderMapper.getCustomer(id);
|
}
|
|
private void save(MpsRequirementsDTO mpsRequirementsDTO, Long id) {
|
try {
|
MpsSource planMpsSource = new MpsSource();
|
planMpsSource.setMpsId(id);
|
planMpsSource.setMpsRequId(mpsRequirementsDTO.getId());
|
planMpsSource.setQtyPlaned(mpsRequirementsDTO.getQtyPlaned());
|
planMpsSource.setRemark(mpsRequirementsDTO.getRemark());
|
planMpsSourceMapper.insert(planMpsSource);
|
// 2.4.更新对应的主生产计划需求-已计划数量
|
baseMapper.updatePlanRequiredById(mpsRequirementsDTO);
|
} catch (Exception e) {
|
log.error("保存主生产计划来源失败", e);
|
throw new RuntimeException("保存主生产计划来源失败");
|
}
|
}
|
}
|