package com.ruoyi.production.service.impl;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
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.ruoyi.basic.mapper.ProductMapper;
|
import com.ruoyi.basic.mapper.ProductModelMapper;
|
import com.ruoyi.basic.pojo.Product;
|
import com.ruoyi.basic.pojo.ProductModel;
|
import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
|
import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
|
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
|
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.utils.SecurityUtils;
|
import com.ruoyi.common.utils.bean.BeanUtils;
|
import com.ruoyi.procurementrecord.utils.StockUtils;
|
import com.ruoyi.production.dto.ProductStructureDto;
|
import com.ruoyi.production.dto.ProductionProductMainDto;
|
import com.ruoyi.production.mapper.*;
|
import com.ruoyi.production.pojo.*;
|
import com.ruoyi.production.service.ProductionProductMainService;
|
import com.ruoyi.project.system.domain.SysUser;
|
import com.ruoyi.project.system.mapper.SysUserMapper;
|
import com.ruoyi.project.system.service.ISysNoticeService;
|
import com.ruoyi.quality.mapper.*;
|
import com.ruoyi.quality.pojo.*;
|
import com.ruoyi.quality.service.IQualityInspectService;
|
import com.ruoyi.stock.support.FinishedProductStockDimensionResolver;
|
import lombok.AllArgsConstructor;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.time.LocalDate;
|
import java.time.LocalDateTime;
|
import java.time.format.DateTimeFormatter;
|
import java.util.*;
|
import java.util.function.Function;
|
import java.util.stream.Collectors;
|
|
@Service
|
@AllArgsConstructor
|
@Transactional(rollbackFor = Exception.class)
|
public class ProductionProductMainServiceImpl extends ServiceImpl<ProductionProductMainMapper, ProductionProductMain> implements ProductionProductMainService {
|
|
private static final String PROCESS_VOLTAGE_SORT = "电压分选";
|
private static final String PROCESS_OPTICAL_INSPECTION = "光检外观";
|
private static final String PROCESS_PACKAGING = "包装";
|
|
private IQualityInspectService qualityInspectService;
|
private ProductionProductMainMapper productionProductMainMapper;
|
|
|
private ProductWorkOrderMapper productWorkOrderMapper;
|
|
private ProductProcessRouteItemMapper productProcessRouteItemMapper;
|
private SysUserMapper userMapper;
|
|
private ProductionProductOutputMapper productionProductOutputMapper;
|
|
|
private ProductModelMapper productModelMapper;
|
|
private QualityInspectMapper qualityInspectMapper;
|
private QualityUnqualifiedMapper qualityUnqualifiedMapper;
|
|
private ProductProcessMapper productProcessMapper;
|
private ProductProcessRouteMapper productProcessRouteMapper;
|
|
private ProductMapper productMapper;
|
|
|
private QualityTestStandardParamMapper qualityTestStandardParamMapper;
|
private QualityTestStandardMapper qualityTestStandardMapper;
|
|
private QualityInspectParamMapper qualityInspectParamMapper;
|
|
private ProductStructureMapper productStructureMapper;
|
|
private ProductionProductInputMapper productionProductInputMapper;
|
|
private ProductOrderMapper productOrderMapper;
|
|
private SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper;
|
|
private StockUtils stockUtils;
|
|
/**
|
* 解析生产报工对应的成品入库维度。
|
*/
|
private FinishedProductStockDimensionResolver finishedProductStockDimensionResolver;
|
|
private ISysNoticeService sysNoticeService;
|
|
@Override
|
public IPage<ProductionProductMainDto> listPageProductionProductMainDto(Page page, ProductionProductMainDto productionProductMainDto) {
|
return productionProductMainMapper.listPageProductionProductMainDto(page, productionProductMainDto);
|
}
|
|
/**
|
* 新增报工,并根据当前工序处理质检和入库逻辑。
|
*/
|
@Override
|
public Boolean addProductMain(ProductionProductMainDto dto) {
|
SysUser user = userMapper.selectUserById(dto.getUserId());
|
ProductionProductMain productionProductMain = new ProductionProductMain();
|
//当前工艺路线对应的工序详情
|
ProductProcessRouteItem productProcessRouteItem = productProcessRouteItemMapper.selectById(dto.getProductProcessRouteItemId());
|
if (productProcessRouteItem == null) {
|
throw new RuntimeException("工艺路线工序项不存在");
|
}
|
//检查上一个工序是否已报工
|
Integer currentDragSort = productProcessRouteItem.getDragSort();
|
if (currentDragSort != null && currentDragSort > 1) {
|
boolean isPreviousReported = productionProductMainMapper.checkPreviousProcessReported(
|
productProcessRouteItem.getProductRouteId(),
|
currentDragSort
|
);
|
if (!isPreviousReported) {
|
throw new RuntimeException("上一道工序尚未报工,当前工序不能报工");
|
}
|
|
// 查询所有之前的工序(排序号小于当前工序)
|
List<ProductProcessRouteItem> previousItems = productProcessRouteItemMapper.selectList(
|
Wrappers.<ProductProcessRouteItem>lambdaQuery()
|
.eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId())
|
.lt(ProductProcessRouteItem::getDragSort, currentDragSort)
|
);
|
if (CollectionUtils.isNotEmpty(previousItems)) {
|
// 提取之前工序的名称列表
|
List<String> previousProcessNames = new ArrayList<>();
|
for (ProductProcessRouteItem item : previousItems) {
|
ProductProcess process = productProcessMapper.selectById(item.getProcessId());
|
if (process != null) {
|
previousProcessNames.add(process.getName());
|
}
|
}
|
|
// 检查之前的工序是否有被隔离的不合格记录
|
List<QualityUnqualified> unqualifiedList = qualityUnqualifiedMapper.selectUnqualifiedByProcessNames(previousProcessNames);
|
if (CollectionUtils.isNotEmpty(unqualifiedList)) {
|
throw new RuntimeException("前序工序存在隔离记录,当前工序不能报工");
|
}
|
}
|
}
|
//当前具体工序
|
ProductProcess productProcess = productProcessMapper.selectById(productProcessRouteItem.getProcessId());
|
//工艺路线中当前工序对应的产出规格型号
|
ProductModel productModel = productModelMapper.selectById(productProcessRouteItem.getProductModelId());
|
//查询该生产订单对应的bom
|
ProductProcessRoute productProcessRoute = productProcessRouteMapper.selectById(productProcessRouteItem.getProductRouteId());
|
/*新增报工主表*/
|
//查询最大报工编号
|
String datePrefix = "BG" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd"));
|
QueryWrapper<ProductionProductMain> queryWrapper = new QueryWrapper<>();
|
queryWrapper.select("MAX(product_no) as maxNo")
|
.likeRight("product_no", datePrefix);
|
List<Map<String, Object>> resultList = productionProductMainMapper.selectMaps(queryWrapper);
|
int sequenceNumber = 1;
|
if (resultList != null && !resultList.isEmpty()) {
|
Map<String, Object> result = resultList.get(0);
|
if (result != null) {
|
Object maxNoObj = result.get("maxNo");
|
if (maxNoObj != null) {
|
String lastNo = maxNoObj.toString();
|
if (lastNo.startsWith(datePrefix)) {
|
try {
|
String seqStr = lastNo.substring(datePrefix.length());
|
sequenceNumber = Integer.parseInt(seqStr) + 1;
|
} catch (NumberFormatException e) {
|
sequenceNumber = 1;
|
}
|
}
|
}
|
}
|
}
|
String productNo = String.format("%s%03d", datePrefix, sequenceNumber);
|
productionProductMain.setProductNo(productNo);
|
Long userId = dto.getUserId();
|
String userName = dto.getUserName();
|
if (userId == null) {
|
userId = SecurityUtils.getLoginUser().getUserId();
|
userName = SecurityUtils.getLoginUser().getNickName();
|
}
|
productionProductMain.setUserId(userId);
|
productionProductMain.setUserName(userName);
|
productionProductMain.setProductProcessRouteItemId(dto.getProductProcessRouteItemId());
|
productionProductMain.setWorkOrderId(dto.getWorkOrderId());
|
productionProductMain.setStatus(0);
|
productionProductMainMapper.insert(productionProductMain);
|
/*新增报工投入表*/
|
List<ProductStructureDto> productStructureDtos = productStructureMapper.listBybomAndProcess(productProcessRoute.getBomId(), productProcess.getId());
|
if (productStructureDtos.isEmpty()) {
|
//如果该工序没有产品结构的投入品,那这个投入品和产出品是同一个
|
ProductStructureDto productStructureDto = new ProductStructureDto();
|
productStructureDto.setProductModelId(productProcessRouteItem.getProductModelId());
|
productStructureDto.setUnitQuantity(BigDecimal.ONE);
|
productStructureDtos.add(productStructureDto);
|
}
|
Set<Long> parentIds = productStructureDtos.stream()
|
.map(ProductStructureDto::getParentId)
|
.filter(Objects::nonNull)
|
.collect(Collectors.toSet());
|
Map<Long, ProductStructureDto> parentMap = new HashMap<>();
|
if (!parentIds.isEmpty()) {
|
parentMap = productStructureMapper.selectByIds(parentIds)
|
.stream()
|
.collect(Collectors.toMap(
|
ProductStructureDto::getId,
|
Function.identity()
|
));
|
}
|
for (ProductStructureDto productStructureDto : productStructureDtos) {
|
ProductionProductInput productionProductInput = new ProductionProductInput();
|
productionProductInput.setProductModelId(productStructureDto.getProductModelId());
|
// productionProductInput.setQuantity(productStructureDto.getUnitQuantity().multiply(dto.getQuantity()));
|
BigDecimal childQty = productStructureDto.getUnitQuantity();
|
BigDecimal parentQty = BigDecimal.ONE;
|
if (productStructureDto.getParentId() != null) {
|
ProductStructureDto parent = parentMap.get(productStructureDto.getParentId());
|
if (parent != null) {
|
parentQty = parent.getUnitQuantity();
|
}
|
}
|
|
// 核心计算
|
BigDecimal needQty = childQty.divide(parentQty, 6, RoundingMode.HALF_UP).multiply(dto.getQuantity());
|
productionProductInput.setQuantity(needQty);
|
productionProductInput.setProductMainId(productionProductMain.getId());
|
productionProductInputMapper.insert(productionProductInput);
|
stockUtils.substractStock(productStructureDto.getProductModelId(), productionProductInput.getQuantity(),
|
StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode(), productionProductMain.getId(), null);
|
}
|
/*新增报工产出表*/
|
ProductionProductOutput productionProductOutput = new ProductionProductOutput();
|
productionProductOutput.setProductMainId(productionProductMain.getId());
|
productionProductOutput.setProductModelId(productProcessRouteItem.getProductModelId());
|
productionProductOutput.setQuantity(dto.getQuantity() != null ? dto.getQuantity() : BigDecimal.ZERO);
|
productionProductOutput.setScrapQty(dto.getScrapQty() != null ? dto.getScrapQty() : BigDecimal.ZERO);
|
productionProductOutput.setOtherData(dto.getOtherData() != null ? dto.getOtherData() : "");
|
productionProductOutputMapper.insert(productionProductOutput);
|
|
ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(dto.getWorkOrderId());
|
ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId());
|
|
//合格数量=报工数量-报废数量
|
BigDecimal productQty = productionProductOutput.getQuantity().subtract(productionProductOutput.getScrapQty());
|
List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(
|
Wrappers.<ProductProcessRouteItem>lambdaQuery()
|
.eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId())
|
);
|
boolean isRouteLastProcess = productProcessRouteItem.getDragSort() == productProcessRouteItems.size();
|
ReportStockRule reportStockRule = resolveReportStockRule(productProcessRouteItem, productProcess, productProcessRouteItems);
|
|
String processCategory = null;
|
String voltage = null;
|
if (productQty.compareTo(BigDecimal.ZERO) > 0 && reportStockRule.isFinishedGoodsStockIn()) {
|
processCategory = finishedProductStockDimensionResolver.resolveProcessCategory(productionProductMain.getId());
|
voltage = finishedProductStockDimensionResolver.resolveVoltage(productionProductMain.getId());
|
}
|
|
if (productQty.compareTo(BigDecimal.ZERO) > 0) {
|
/*新增质检*/
|
if (productProcessRouteItem.getIsQuality()) {
|
//对应的过程检或者出厂检
|
int inspectType = 1;
|
String process = productProcess.getName();
|
if (reportStockRule.isFinishedGoodsStockIn()) {
|
inspectType = 2;
|
process = null;
|
}
|
Product product = productMapper.selectById(productModel.getProductId());
|
QualityInspect qualityInspect = new QualityInspect();
|
qualityInspect.setProductId(product.getId());
|
qualityInspect.setProductName(product.getProductName());
|
qualityInspect.setModel(productModel.getModel());
|
qualityInspect.setUnit(productModel.getUnit());
|
qualityInspect.setQuantity(productionProductOutput.getQuantity());
|
qualityInspect.setProcess(process);
|
qualityInspect.setInspectState(0);
|
qualityInspect.setInspectType(inspectType);
|
qualityInspect.setDefectiveQuantity(productionProductOutput.getScrapQty());
|
qualityInspect.setProductMainId(productionProductMain.getId());
|
qualityInspect.setProductModelId(productModel.getId());
|
qualityInspectMapper.insert(qualityInspect);
|
List<QualityTestStandard> qualityTestStandard = qualityTestStandardMapper.getQualityTestStandardByProductId(product.getId(), inspectType, process);
|
if (qualityTestStandard.size() > 0) {
|
qualityInspect.setTestStandardId(qualityTestStandard.get(0).getId());
|
qualityInspectMapper.updateById(qualityInspect);
|
qualityTestStandardParamMapper.selectList(
|
Wrappers.<QualityTestStandardParam>lambdaQuery()
|
.eq(QualityTestStandardParam::getTestStandardId, qualityTestStandard.get(0).getId())
|
)
|
.forEach(qualityTestStandardParam -> {
|
QualityInspectParam param = new QualityInspectParam();
|
BeanUtils.copyProperties(qualityTestStandardParam, param);
|
param.setId(null);
|
param.setInspectId(qualityInspect.getId());
|
qualityInspectParamMapper.insert(param);
|
});
|
}
|
} else {
|
if (reportStockRule.shouldCreateStockIn()) {
|
if (reportStockRule.isFinishedGoodsStockIn()) {
|
stockUtils.addStock(productProcessRouteItem.getProductModelId(), productQty,
|
StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode(), productionProductMain.getId(),
|
processCategory, voltage);
|
} else {
|
stockUtils.addStockNoReview(productProcessRouteItem.getProductModelId(), productQty,
|
StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode(), productionProductMain.getId());
|
}
|
}
|
if (productionProductOutput.getScrapQty().compareTo(BigDecimal.ZERO) > 0) {
|
stockUtils.addUnStockNoReview(productProcessRouteItem.getProductModelId(), productionProductOutput.getScrapQty(),
|
StockInUnQualifiedRecordTypeEnum.QUALITYINSPECT_UNSTOCK_IN.getCode(), productionProductMain.getId());
|
}
|
}
|
|
productWorkOrder.setCompleteQuantity(productWorkOrder.getCompleteQuantity().add(productQty));
|
if (ObjectUtils.isNull(productWorkOrder.getActualStartTime())) {
|
productWorkOrder.setActualStartTime(LocalDate.now());
|
}
|
if (productWorkOrder.getCompleteQuantity().compareTo(productWorkOrder.getPlanQuantity()) == 0) {
|
productWorkOrder.setActualEndTime(LocalDate.now());
|
}
|
productWorkOrderMapper.updateById(productWorkOrder);
|
|
if (ObjectUtils.isNull(productOrder.getStartTime())) {
|
productOrder.setStartTime(LocalDateTime.now());
|
}
|
if (isRouteLastProcess) {
|
productOrder.setCompleteQuantity(productOrder.getCompleteQuantity().add(productQty));
|
if (productOrder.getCompleteQuantity().compareTo(productOrder.getQuantity()) == 0) {
|
productOrder.setEndTime(LocalDateTime.now());
|
}
|
}
|
productOrderMapper.updateById(productOrder);
|
|
SalesLedgerProductionAccounting salesLedgerProductionAccounting = SalesLedgerProductionAccounting.builder()
|
.productMainId(productionProductMain.getId())
|
.schedulingUserId(userId)
|
.schedulingUserName(userName)
|
.finishedNum(productQty)
|
.workHours(productProcess.getSalaryQuota())
|
.process(productProcess.getName())
|
.schedulingDate(LocalDate.now())
|
.tenantId(dto.getTenantId())
|
.build();
|
salesLedgerProductionAccountingMapper.insert(salesLedgerProductionAccounting);
|
}
|
return true;
|
}
|
|
/**
|
* 判断当前报工是否需要入库,以及是否按成品入库处理。
|
*/
|
private ReportStockRule resolveReportStockRule(ProductProcessRouteItem currentRouteItem,
|
ProductProcess currentProcess,
|
List<ProductProcessRouteItem> routeItems) {
|
boolean isRouteLastProcess = currentRouteItem.getDragSort() != null
|
&& CollectionUtils.isNotEmpty(routeItems)
|
&& currentRouteItem.getDragSort().equals(routeItems.size());
|
String currentProcessName = normalizeProcessName(currentProcess == null ? null : currentProcess.getName());
|
if (PROCESS_VOLTAGE_SORT.equals(currentProcessName)) {
|
return new ReportStockRule(false, false);
|
}
|
|
Map<Long, String> processNameMap = loadRouteProcessNameMap(routeItems);
|
boolean hasVoltageSort = containsProcess(routeItems, processNameMap, PROCESS_VOLTAGE_SORT);
|
boolean hasOpticalInspection = containsProcess(routeItems, processNameMap, PROCESS_OPTICAL_INSPECTION);
|
boolean hasPackaging = containsProcess(routeItems, processNameMap, PROCESS_PACKAGING);
|
|
if (hasPackaging && PROCESS_PACKAGING.equals(currentProcessName)) {
|
return new ReportStockRule(true, true);
|
}
|
if (hasPackaging && PROCESS_OPTICAL_INSPECTION.equals(currentProcessName)) {
|
return new ReportStockRule(false, false);
|
}
|
if (!hasPackaging && hasVoltageSort && hasOpticalInspection && PROCESS_OPTICAL_INSPECTION.equals(currentProcessName)) {
|
return new ReportStockRule(true, true);
|
}
|
return new ReportStockRule(true, isRouteLastProcess);
|
}
|
|
/**
|
* 批量加载工艺路线中的工序名称。
|
*/
|
private Map<Long, String> loadRouteProcessNameMap(List<ProductProcessRouteItem> routeItems) {
|
if (CollectionUtils.isEmpty(routeItems)) {
|
return Collections.emptyMap();
|
}
|
Set<Long> processIds = routeItems.stream()
|
.map(ProductProcessRouteItem::getProcessId)
|
.filter(Objects::nonNull)
|
.collect(Collectors.toSet());
|
if (processIds.isEmpty()) {
|
return Collections.emptyMap();
|
}
|
return productProcessMapper.selectBatchIds(processIds).stream()
|
.collect(Collectors.toMap(ProductProcess::getId, process -> normalizeProcessName(process.getName())));
|
}
|
|
/**
|
* 判断工艺路线中是否包含指定工序。
|
*/
|
private boolean containsProcess(List<ProductProcessRouteItem> routeItems, Map<Long, String> processNameMap, String processName) {
|
return routeItems.stream()
|
.map(ProductProcessRouteItem::getProcessId)
|
.map(processNameMap::get)
|
.anyMatch(processName::equals);
|
}
|
|
/**
|
* 统一工序名称格式,避免规则匹配时受空白字符影响。
|
*/
|
private String normalizeProcessName(String processName) {
|
return processName == null ? "" : processName.trim();
|
}
|
|
/**
|
* 单次报工对应的入库规则。
|
*/
|
private static final class ReportStockRule {
|
private final boolean createStockIn;
|
private final boolean finishedGoodsStockIn;
|
|
private ReportStockRule(boolean createStockIn, boolean finishedGoodsStockIn) {
|
this.createStockIn = createStockIn;
|
this.finishedGoodsStockIn = finishedGoodsStockIn;
|
}
|
|
private boolean shouldCreateStockIn() {
|
return createStockIn;
|
}
|
|
private boolean isFinishedGoodsStockIn() {
|
return finishedGoodsStockIn;
|
}
|
}
|
|
@Override
|
public Boolean removeProductMain(Long id) {
|
List<QualityInspect> qualityInspects = qualityInspectMapper.selectList(
|
Wrappers.<QualityInspect>lambdaQuery().eq(QualityInspect::getProductMainId, id)
|
);
|
if (qualityInspects.size() > 0) {
|
List<QualityUnqualified> qualityUnqualifieds = qualityUnqualifiedMapper.selectList(
|
Wrappers.<QualityUnqualified>lambdaQuery()
|
.in(QualityUnqualified::getInspectId, qualityInspects.stream().map(QualityInspect::getId).collect(Collectors.toList()))
|
);
|
if (qualityUnqualifieds.size() > 0 && qualityUnqualifieds.get(0).getInspectState() == 1) {
|
throw new ServiceException("该报工已完成不合格处理,不能删除");
|
}
|
}
|
|
ProductionProductMain productionProductMain = productionProductMainMapper.selectById(id);
|
ProductProcessRouteItem productProcessRouteItem = productProcessRouteItemMapper.selectById(productionProductMain.getProductProcessRouteItemId());
|
ProductionProductOutput productionProductOutput = productionProductOutputMapper.selectList(
|
Wrappers.<ProductionProductOutput>lambdaQuery().eq(ProductionProductOutput::getProductMainId, productionProductMain.getId())
|
).get(0);
|
|
salesLedgerProductionAccountingMapper.delete(
|
new LambdaQueryWrapper<SalesLedgerProductionAccounting>()
|
.eq(SalesLedgerProductionAccounting::getProductMainId, productionProductMain.getId())
|
);
|
|
ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(productionProductMain.getWorkOrderId());
|
if (productWorkOrder != null && productionProductOutput != null) {
|
BigDecimal outputQty = productionProductOutput.getQuantity() == null ? BigDecimal.ZERO : productionProductOutput.getQuantity();
|
BigDecimal scrapQty = productionProductOutput.getScrapQty() == null ? BigDecimal.ZERO : productionProductOutput.getScrapQty();
|
BigDecimal completeQty = productWorkOrder.getCompleteQuantity() == null ? BigDecimal.ZERO : productWorkOrder.getCompleteQuantity();
|
|
BigDecimal validQuantity = outputQty.subtract(scrapQty);
|
productWorkOrder.setCompleteQuantity(completeQty.subtract(validQuantity));
|
productWorkOrder.setActualEndTime(null);
|
productWorkOrderMapper.updateById(productWorkOrder);
|
} else {
|
throw new ServiceException("操作失败:工单信息或产出记录不存在");
|
}
|
|
List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(
|
Wrappers.<ProductProcessRouteItem>lambdaQuery().eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId())
|
);
|
if (productProcessRouteItem.getDragSort() != null
|
&& productProcessRouteItems != null
|
&& productProcessRouteItem.getDragSort() == productProcessRouteItems.size()) {
|
ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId());
|
if (productOrder != null) {
|
BigDecimal orderCompleteQty = productOrder.getCompleteQuantity() == null ? BigDecimal.ZERO : productOrder.getCompleteQuantity();
|
BigDecimal totalQty = productionProductOutput.getQuantity() != null ? productionProductOutput.getQuantity() : BigDecimal.ZERO;
|
BigDecimal scrapQty = productionProductOutput.getScrapQty() != null ? productionProductOutput.getScrapQty() : BigDecimal.ZERO;
|
BigDecimal actualQualifiedQty = totalQty.subtract(scrapQty);
|
BigDecimal newCompleteQty = orderCompleteQty.subtract(actualQualifiedQty);
|
productOrder.setCompleteQuantity(newCompleteQty.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : newCompleteQty);
|
productOrder.setEndTime(null);
|
productOrderMapper.updateById(productOrder);
|
} else {
|
throw new ServiceException("关联的生产订单不存在");
|
}
|
}
|
|
qualityInspectMapper.selectList(
|
new LambdaQueryWrapper<QualityInspect>()
|
.eq(QualityInspect::getProductMainId, productionProductMain.getId())
|
).forEach(q -> {
|
qualityInspectParamMapper.delete(
|
new LambdaQueryWrapper<QualityInspectParam>()
|
.eq(QualityInspectParam::getInspectId, q.getId())
|
);
|
qualityInspectMapper.deleteById(q.getId());
|
stockUtils.deleteStockInRecord(q.getId(), StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode());
|
});
|
|
productionProductOutputMapper.delete(
|
new LambdaQueryWrapper<ProductionProductOutput>()
|
.eq(ProductionProductOutput::getProductMainId, productionProductMain.getId())
|
);
|
productionProductInputMapper.delete(
|
new LambdaQueryWrapper<ProductionProductInput>()
|
.eq(ProductionProductInput::getProductMainId, productionProductMain.getId())
|
);
|
stockUtils.deleteStockInRecord(productionProductMain.getId(), StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode());
|
stockUtils.deleteStockInRecord(productionProductMain.getId(), StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode());
|
stockUtils.deleteStockOutRecord(productionProductMain.getId(), StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode());
|
productionProductMainMapper.deleteById(productionProductMain.getId());
|
return true;
|
}
|
|
@Override
|
public ArrayList<Long> listMain(List<Long> idList) {
|
return productionProductMainMapper.listMain(idList);
|
}
|
|
@Override
|
public List<ProductionProductMainDto> getByProductWorkOrderId(Long productWorkOrderId) {
|
List<ProductionProductMainDto> productionProductMainDtos = productionProductMainMapper.getByProductWorkOrderId(productWorkOrderId);
|
if (productionProductMainDtos == null || productionProductMainDtos.isEmpty()) {
|
return productionProductMainDtos;
|
}
|
|
List<Long> productMainIds = productionProductMainDtos.stream()
|
.map(ProductionProductMainDto::getId)
|
.collect(Collectors.toList());
|
|
List<QualityInspect> qualityInspects = qualityInspectMapper.selectList(
|
Wrappers.<QualityInspect>lambdaQuery()
|
.in(QualityInspect::getProductMainId, productMainIds)
|
);
|
|
if (!qualityInspects.isEmpty()) {
|
List<Long> inspectIds = qualityInspects.stream()
|
.map(QualityInspect::getId)
|
.collect(Collectors.toList());
|
|
List<QualityUnqualified> qualityUnqualifieds = qualityUnqualifiedMapper.selectList(
|
Wrappers.<QualityUnqualified>lambdaQuery()
|
.in(QualityUnqualified::getInspectId, inspectIds)
|
);
|
|
Map<Long, QualityUnqualified> inspectIdToUnqualifiedMap = qualityUnqualifieds.stream()
|
.collect(Collectors.toMap(QualityUnqualified::getInspectId, q -> q, (q1, q2) -> q1));
|
|
Map<Long, QualityInspect> productMainIdToInspectMap = qualityInspects.stream()
|
.collect(Collectors.toMap(QualityInspect::getProductMainId, q -> q, (q1, q2) -> q1));
|
|
productionProductMainDtos.forEach(p -> {
|
QualityInspect qualityInspect = productMainIdToInspectMap.get(p.getId());
|
if (qualityInspect != null) {
|
p.setDefectiveQuantity(qualityInspect.getDefectiveQuantity());
|
p.setQualifiedQty(p.getQuantity().subtract(p.getScrapQty()).subtract(p.getDefectiveQuantity()));
|
QualityUnqualified qualityUnqualified = inspectIdToUnqualifiedMap.get(qualityInspect.getId());
|
if (qualityUnqualified != null) {
|
p.setDealResult(qualityUnqualified.getDealResult() == null ? "" : qualityUnqualified.getDealResult());
|
}
|
}
|
});
|
}
|
|
return productionProductMainDtos;
|
}
|
}
|