/*
|
* Copyright (c) 2018-2025, ztt All rights reserved.
|
*
|
* Redistribution and use in source and binary forms, with or without
|
* modification, are permitted provided that the following conditions are met:
|
*
|
* Redistributions of source code must retain the above copyright notice,
|
* this list of conditions and the following disclaimer.
|
* Redistributions in binary form must reproduce the above copyright
|
* notice, this list of conditions and the following disclaimer in the
|
* documentation and/or other materials provided with the distribution.
|
* Neither the name of the pig4cloud.com developer nor the names of its
|
* contributors may be used to endorse or promote products derived from
|
* this software without specific prior written permission.
|
* Author: ztt
|
*/
|
package com.chinaztt.mes.plan.service.impl;
|
|
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.util.StrUtil;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
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.plan.dto.*;
|
import com.chinaztt.mes.plan.entity.*;
|
import com.chinaztt.mes.plan.mapper.*;
|
import com.chinaztt.mes.plan.service.CustomerOrderProduceTaskService;
|
import com.chinaztt.mes.plan.service.CustomerOrderService;
|
import com.chinaztt.mes.plan.service.ManufacturingOrderService;
|
import com.chinaztt.mes.plan.state.masterproductionschedule.constant.MasterProductionScheduleStateStringValues;
|
import com.chinaztt.mes.technology.entity.JoinDocumentBomRouting;
|
import com.chinaztt.mes.technology.entity.Operation;
|
import com.chinaztt.mes.technology.mapper.JoinDocumentBomRoutingMapper;
|
import com.chinaztt.mes.technology.mapper.OperationMapper;
|
import com.chinaztt.mes.technology.entity.RoutingOperation;
|
import groovy.util.MapEntry;
|
import lombok.AllArgsConstructor;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.math.BigDecimal;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* 段长任务单
|
*
|
* @author shz
|
* @date 2023-03-07 09:28:25
|
*/
|
@AllArgsConstructor
|
@Transactional(rollbackFor = Exception.class)
|
@Service
|
public class CustomerOrderProduceTaskServiceImpl extends ServiceImpl<CustomerOrderProduceTaskMapper, CustomerOrderProduceTask> implements CustomerOrderProduceTaskService {
|
|
private OperationTaskProduceMapper operationTaskProduceMapper;
|
private CustomerOrderService customerOrderService;
|
private MasterProductionScheduleTheoryQuantityMapper masterProductionScheduleTheoryQuantityMapper;
|
private ManufacturingOrderService manufacturingOrderService;
|
private MasterProductionScheduleMapper masterProductionScheduleMapper;
|
private OperationMapper operationMapper;
|
private ManufacturingOrderSnGenerateMapper manufacturingOrderSnGenerateMapper;
|
private JoinDocumentBomRoutingMapper joinDocumentBomRoutingMapper;
|
|
@Override
|
public List<CustomerOrderProduceTaskDTO> getPage(QueryWrapper<CustomerOrderProduceTaskDTO> gen) {
|
return this.baseMapper.getPage(gen);
|
}
|
|
@Override
|
public synchronized boolean submit(List<CustomerOrderProduceTaskDTO> customerOrderProduceTasks) {
|
if (CollectionUtil.isNotEmpty(customerOrderProduceTasks)) {
|
List<Long> ids = customerOrderProduceTasks.stream().map(CustomerOrderProduceTask::getId).collect(Collectors.toList());
|
List<CustomerOrderProduceTask> taskList = this.baseMapper.selectBatchIds(ids);
|
long count = taskList.stream().filter(task -> CustomerOrderProduceTask.STATUS_SUBMIT.equals(task.getStatus())).count();
|
if (count > 0) {
|
throw new RuntimeException("存在任务单已提交,请刷新后重试");
|
}
|
|
for (CustomerOrderProduceTaskDTO customerOrderProduceTask : customerOrderProduceTasks) {
|
if (CollectionUtil.isEmpty(customerOrderProduceTask.getRoutingOperations())) {
|
throw new RuntimeException("合并缆号->" + customerOrderProduceTask.getMergeSnNo() + ",未设置起始工序!");
|
}
|
}
|
|
// 查询合并缆号为相同的任务单一起提交
|
List<CustomerOrderProduceTask> leftoverTasks = this.baseMapper.selectList(Wrappers.<CustomerOrderProduceTask>lambdaQuery()
|
.in(CustomerOrderProduceTask::getMergeSnNo, taskList.stream().map(CustomerOrderProduceTask::getMergeSnNo).distinct().collect(Collectors.toList()))
|
.notIn(CustomerOrderProduceTask::getId, ids));
|
taskList.addAll(leftoverTasks);
|
|
// 根据零件id进行分组
|
Map<Long, List<CustomerOrderProduceTask>> taskMapByPart = taskList.stream().collect(Collectors.groupingBy(CustomerOrderProduceTask::getPartId));
|
for (Map.Entry<Long, List<CustomerOrderProduceTask>> taskMapByPartEntry : taskMapByPart.entrySet()) {
|
long checkDocumentCount = taskMapByPartEntry.getValue().stream().map(CustomerOrderProduceTask::getTechnologyDocumentId).distinct().count();
|
if (checkDocumentCount > 1) {
|
throw new RuntimeException("相同零件的工艺文件不一致,无法一起提交");
|
}
|
|
// 生成主生产计划号
|
// 这里根据销售订单id再分组
|
List<CustomerOrderDTO> customerOrderDTOList = new ArrayList<>();
|
Map<Long, List<CustomerOrderProduceTask>> taskMapByOrder = taskMapByPartEntry.getValue().stream().collect(Collectors.groupingBy(CustomerOrderProduceTask::getCustomerOrderId));
|
for (Map.Entry<Long, List<CustomerOrderProduceTask>> taskMapByOrderEntry : taskMapByOrder.entrySet()) {
|
// 组装生成主生产计划所需数据
|
CustomerOrderDTO customerOrderDTO = BeanUtil.copyProperties(customerOrderService.getById(taskMapByOrderEntry.getKey()), CustomerOrderDTO.class);
|
List<OperationTaskProduce> operationTaskProduces = this.operationTaskProduceMapper.selectBatchIds(taskMapByOrderEntry.getValue().stream().map(CustomerOrderProduceTask::getOperationTaskProduceId).collect(Collectors.toList()));
|
customerOrderDTO.setOutPutBatchList(operationTaskProduces);
|
customerOrderDTO.setQtyPlaned(operationTaskProduces.stream().map(OperationTaskProduce::getQty).reduce(BigDecimal.ZERO, BigDecimal::add));
|
customerOrderDTO.setPartId(taskMapByPartEntry.getKey());
|
customerOrderDTOList.add(customerOrderDTO);
|
}
|
// 创建主生产计划,更新任务单状态为已处理
|
MasterProductionSchedule productionSchedule = customerOrderService.createOneMasterProductionScheduleByCustomerOrders(customerOrderDTOList);
|
masterProductionScheduleMapper.update(null, Wrappers.<MasterProductionSchedule>lambdaUpdate()
|
.set(MasterProductionSchedule::getState, MasterProductionScheduleStateStringValues.PROCESSED)
|
.eq(MasterProductionSchedule::getId, productionSchedule.getId()));
|
|
// 更新任务单主计划id
|
this.baseMapper.update(null, Wrappers.<CustomerOrderProduceTask>lambdaUpdate()
|
.set(CustomerOrderProduceTask::getMpsId, productionSchedule.getId())
|
.in(CustomerOrderProduceTask::getId, taskMapByPartEntry.getValue().stream().map(CustomerOrderProduceTask::getId).collect(Collectors.toList())));
|
|
Optional<CustomerOrderProduceTaskDTO> first = customerOrderProduceTasks.stream()
|
.filter(task -> task.getPartId().equals(taskMapByPartEntry.getValue().get(0).getPartId())).findFirst();
|
if (first.isPresent()) {
|
if (CollectionUtil.isEmpty(first.get().getRoutingOperations())) {
|
throw new RuntimeException("未选择开始工序");
|
}
|
|
// 根据主生产计划号创建车间订单
|
// 1.查询半成品理论用量
|
List<MasterProductionScheduleTheoryQuantityDTO> theoryQuantityList = masterProductionScheduleTheoryQuantityMapper.getTheoryQuantity(productionSchedule.getId());
|
// 2.创建车间订单
|
List<ManufacturingOrderDTO> manufacturingOrderList = new ArrayList<>();
|
|
// 找出所有开始的节点
|
List<JoinDocumentBomRouting> startRoutings = joinDocumentBomRoutingMapper.selectList(Wrappers.<JoinDocumentBomRouting>lambdaQuery()
|
.eq(JoinDocumentBomRouting::getDocumentId, productionSchedule.getTechnologyDocumentId())
|
.in(JoinDocumentBomRouting::getRoutingId, first.get().getRoutingOperations().stream().map(RoutingOperation::getRoutingId).collect(Collectors.toList())));
|
|
Set<JoinDocumentBomRouting> totalRoutings = new HashSet<>();
|
// 递归找出所有的节点
|
for (JoinDocumentBomRouting startRouting : startRoutings) {
|
totalRoutings.addAll(joinDocumentBomRoutingMapper.findAllParentBomRoutingsById(startRouting.getId()));
|
}
|
// 去重
|
List<JoinDocumentBomRouting> collect = totalRoutings.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(JoinDocumentBomRouting::getId))), ArrayList::new));
|
|
Map<Long, ManufacturingOrderDTO> manufacturingOrderMap = new HashMap<>();
|
for (MasterProductionScheduleTheoryQuantityDTO theoryQuantityDTO : theoryQuantityList) {
|
boolean flag = false;
|
for (JoinDocumentBomRouting joinDocumentBomRouting : collect) {
|
if (joinDocumentBomRouting.getBomId().equals(theoryQuantityDTO.getBomId()) && joinDocumentBomRouting.getRoutingId().equals(theoryQuantityDTO.getRoutingId())) {
|
flag = true;
|
break;
|
}
|
}
|
|
if (flag) {
|
if (manufacturingOrderMap.containsKey(theoryQuantityDTO.getPartId())) {
|
ManufacturingOrderDTO manufacturingOrderDTO = manufacturingOrderMap.get(theoryQuantityDTO.getPartId());
|
manufacturingOrderDTO.setQtyRequired(manufacturingOrderDTO.getQtyRequired().add(theoryQuantityDTO.getOrderQuantity()));
|
manufacturingOrderMap.put(theoryQuantityDTO.getPartId(), manufacturingOrderDTO);
|
} else {
|
ManufacturingOrderDTO manufacturingOrderDTO = new ManufacturingOrderDTO();
|
manufacturingOrderDTO.setMpsId(productionSchedule.getId());
|
manufacturingOrderDTO.setPartId(theoryQuantityDTO.getPartId());
|
manufacturingOrderDTO.setPartNo(theoryQuantityDTO.getPartNo());
|
manufacturingOrderDTO.setPartName(theoryQuantityDTO.getPartName());
|
manufacturingOrderDTO.setTechnologyRoutingId(theoryQuantityDTO.getRoutingId());
|
manufacturingOrderDTO.setBomId(theoryQuantityDTO.getBomId());
|
manufacturingOrderDTO.setQtyRequired(theoryQuantityDTO.getOrderQuantity());
|
manufacturingOrderDTO.setRequiredDate(productionSchedule.getRequiredDate());
|
manufacturingOrderDTO.setWorkShop(customerOrderProduceTasks.get(0).getWorkshop());
|
manufacturingOrderDTO.setWorkshopTypeCode("M");
|
manufacturingOrderDTO.setScheduleTheoryQuantityId(theoryQuantityDTO.getId());
|
manufacturingOrderDTO.setManufactureAttr(productionSchedule.getManufactureAttr());
|
manufacturingOrderDTO.setIsReportOperation(true);
|
manufacturingOrderMap.put(theoryQuantityDTO.getPartId(), manufacturingOrderDTO);
|
}
|
}
|
}
|
manufacturingOrderMap.forEach((k, v) -> {
|
manufacturingOrderList.add(v);
|
});
|
|
manufacturingOrderService.addBatchForMerge(manufacturingOrderList, first.get().getRoutingOperations(), first.get().getIsGenerateSn());
|
|
List<Long> operationIds = first.get().getRoutingOperations().stream().map(RoutingOperation::getOperationId).distinct().collect(Collectors.toList());
|
List<Operation> operation = operationMapper.selectBatchIds(operationIds);
|
this.baseMapper.update(null, Wrappers.<CustomerOrderProduceTask>lambdaUpdate()
|
.set(CustomerOrderProduceTask::getOperationId, StrUtil.join(",", operationIds))
|
.set(CustomerOrderProduceTask::getOperationName, StrUtil.join(",", operation.stream().map(Operation::getName).collect(Collectors.toList())))
|
.set(CustomerOrderProduceTask::getWorkshop, first.get().getWorkshop())
|
.set(CustomerOrderProduceTask::getStatus, CustomerOrderProduceTask.STATUS_SUBMIT)
|
.in(CustomerOrderProduceTask::getId, taskMapByPartEntry.getValue().stream().map(CustomerOrderProduceTask::getId).collect(Collectors.toList())));
|
}
|
}
|
}
|
return true;
|
}
|
|
@Override
|
public boolean back(List<Long> ids) {
|
if (CollectionUtil.isNotEmpty(ids)) {
|
List<CustomerOrderProduceTask> customerOrderProduceTasks = this.baseMapper.selectBatchIds(ids);
|
long count = customerOrderProduceTasks.stream().filter(task -> CustomerOrderProduceTask.STATUS_SUBMIT.equals(task.getStatus())).count();
|
if (count > 0) {
|
throw new RuntimeException("存在任务单已提交,无法退回");
|
}
|
|
// 查询合并缆号为相同的任务单
|
List<CustomerOrderProduceTask> leftoverTasks = this.baseMapper.selectList(Wrappers.<CustomerOrderProduceTask>lambdaQuery()
|
.in(CustomerOrderProduceTask::getMergeSnNo, customerOrderProduceTasks.stream().map(CustomerOrderProduceTask::getMergeSnNo).distinct().collect(Collectors.toList()))
|
.notIn(CustomerOrderProduceTask::getId, ids));
|
if (CollectionUtil.isNotEmpty(leftoverTasks)) {
|
customerOrderProduceTasks.addAll(leftoverTasks);
|
}
|
|
// 删除任务单数据
|
this.baseMapper.deleteBatchIds(customerOrderProduceTasks.stream().map(CustomerOrderProduceTask::getId).collect(Collectors.toList()));
|
|
// 更新批次表状态为未生成任务单
|
return SqlHelper.retBool(this.operationTaskProduceMapper.update(null, Wrappers.<OperationTaskProduce>lambdaUpdate()
|
.set(OperationTaskProduce::getIsGenerateTask, false)
|
.in(OperationTaskProduce::getId, customerOrderProduceTasks.stream().map(CustomerOrderProduceTask::getOperationTaskProduceId).collect(Collectors.toList()))));
|
}
|
return false;
|
}
|
|
@Override
|
public boolean fullUpdate(CustomerOrderProduceTask customerOrderProduceTask) {
|
CustomerOrderProduceTask task = this.getById(customerOrderProduceTask.getId());
|
if (task == null) {
|
throw new RuntimeException("任务单不存在");
|
}
|
|
if (task.getStatus().equals(CustomerOrderProduceTask.STATUS_SUBMIT)) {
|
throw new RuntimeException("任务单已提交,无法修改");
|
}
|
|
List<CustomerOrderProduceTask> leftoverTasks = this.baseMapper.selectList(Wrappers.<CustomerOrderProduceTask>lambdaQuery()
|
.eq(CustomerOrderProduceTask::getMergeSnNo, task.getMergeSnNo())
|
.ne(CustomerOrderProduceTask::getId, customerOrderProduceTask.getId()));
|
List<Long> ids = new ArrayList<>();
|
ids.add(customerOrderProduceTask.getId());
|
if (CollectionUtil.isNotEmpty(leftoverTasks)) {
|
ids.addAll(leftoverTasks.stream().map(CustomerOrderProduceTask::getId).collect(Collectors.toList()));
|
}
|
return this.update(Wrappers.<CustomerOrderProduceTask>lambdaUpdate()
|
.set(CustomerOrderProduceTask::getOperationProduceQty, customerOrderProduceTask.getOperationProduceQty())
|
.in(CustomerOrderProduceTask::getId, ids));
|
}
|
|
@Override
|
public List<CustomerOrderProduceTaskDTO> getPartsByOrderNo(String otcCustomerOrderNo) {
|
return this.baseMapper.getPartsByOrderNo(otcCustomerOrderNo);
|
}
|
|
@Override
|
public List<Operation> getOperationsByTaskIds(List<Long> ids) {
|
if (CollectionUtil.isEmpty(ids)) {
|
throw new RuntimeException("未选择数据!");
|
}
|
List<Operation> result = new ArrayList<>();
|
List<CustomerOrderProduceTask> customerOrderProduceTasks = this.baseMapper.selectBatchIds(ids);
|
if (CollectionUtil.isNotEmpty(customerOrderProduceTasks)) {
|
if (customerOrderProduceTasks.stream().map(CustomerOrderProduceTask::getTechnologyDocumentId).distinct().count() > 1) {
|
throw new RuntimeException("选择的任务单的工艺文件不一致!无法设置相同工序!");
|
}
|
result = this.baseMapper.getOperationsByTaskIds(ids);
|
}
|
return result;
|
}
|
}
|