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.StockOutQualifiedRecordTypeEnum;
|
import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
|
import com.ruoyi.common.exception.ServiceException;
|
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.quality.mapper.*;
|
import com.ruoyi.quality.pojo.*;
|
import com.ruoyi.quality.service.IQualityInspectService;
|
import lombok.AllArgsConstructor;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import com.ruoyi.production.mapper.ProductionProductMainMapper;
|
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.time.LocalDate;
|
import java.time.LocalDateTime;
|
import java.time.format.DateTimeFormatter;
|
import java.util.ArrayList;
|
import java.util.List;
|
import java.util.Map;
|
|
@Service
|
@AllArgsConstructor
|
@Transactional(rollbackFor = Exception.class)
|
public class ProductionProductMainServiceImpl extends ServiceImpl<ProductionProductMainMapper, ProductionProductMain> implements ProductionProductMainService {
|
|
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 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;
|
|
|
@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("工艺路线项不存在");
|
}
|
// 获取订单的工单
|
List<ProductWorkOrder> productWorkOrderList = productWorkOrderMapper.selectList(Wrappers.<ProductWorkOrder>lambdaQuery()
|
.eq(ProductWorkOrder::getProductOrderId, productProcessRouteItem.getProductOrderId()));
|
// 获取完成数量
|
BigDecimal completeQuantity = productWorkOrderList
|
.stream()
|
.filter(item -> item.getStatus() == 3)
|
.map(ProductWorkOrder::getCompleteQuantity)
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
// 获取所有数量
|
BigDecimal totalQuantity = productWorkOrderList
|
.stream()
|
.map(ProductWorkOrder::getPlanQuantity)
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
// 获取未完成数量
|
BigDecimal unCompleteQuantity = totalQuantity.subtract(completeQuantity);
|
if (unCompleteQuantity.compareTo(BigDecimal.ZERO) <= 0) {
|
throw new ServiceException("该工单已全部完成");
|
}
|
// 计算比例
|
BigDecimal ratio = unCompleteQuantity.divide(totalQuantity, 2, RoundingMode.HALF_UP);
|
if(CollectionUtils.isEmpty(productWorkOrderList)){
|
productWorkOrderList = new ArrayList<>();
|
}
|
//当前具体工序
|
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();
|
System.out.println("lastNo: " + lastNo);
|
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);
|
productionProductMain.setUserId(dto.getUserId());
|
productionProductMain.setUserName(dto.getUserName());
|
productionProductMain.setProductProcessRouteItemId(dto.getProductProcessRouteItemId());
|
productionProductMain.setWorkOrderId(dto.getWorkOrderId());
|
productionProductMain.setStatus(0);
|
productionProductMainMapper.insert(productionProductMain);
|
/*新增报工投入表(逻辑改为手动领料)*/
|
// List<ProductStructureDto> productStructureDtos = productStructureMapper.listBybomAndProcess(productProcess.getId());
|
// if (productStructureDtos.size() == 0) {
|
// //如果该工序没有产品结构的投入品,那这个投入品和产出品是同一个
|
// ProductStructureDto productStructureDto = new ProductStructureDto();
|
// productStructureDto.setProductModelId(productProcessRouteItem.getProductModelId());
|
// productStructureDto.setUnitQuantity(BigDecimal.ONE);
|
// productStructureDtos.add(productStructureDto);
|
// }
|
// for (ProductStructureDto productStructureDto : productStructureDtos) {
|
//
|
// ProductionProductInput productionProductInput = new ProductionProductInput();
|
// productionProductInput.setProductModelId(productStructureDto.getProductModelId());
|
// productionProductInput.setQuantity(dto.getQuantity());
|
// productionProductInput.setProductMainId(productionProductMain.getId());
|
// productionProductInputMapper.insert(productionProductInput);
|
// stockUtils.substractStock(productStructureDto.getProductModelId(), productionProductInput.getQuantity(), StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode(), productionProductMain.getId());
|
//
|
// }
|
/*新增报工产出表*/
|
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);
|
productionProductOutputMapper.insert(productionProductOutput);
|
//合格数量=报工数量-报废数量
|
BigDecimal productQty = productionProductOutput.getQuantity().subtract(productionProductOutput.getScrapQty());
|
//只有合格数量>0才能增加相应数据
|
if (productQty.compareTo(BigDecimal.ZERO) > 0) {
|
/*新增质检*/
|
List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.<ProductProcessRouteItem>lambdaQuery().eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId()));
|
if (productProcessRouteItem.getIsQuality()) {
|
//对应的过程检或者出厂检
|
int inspectType = 1;
|
String process = productProcess.getName();//工序
|
if (productWorkOrderList.size() == productProcessRouteItems.size() - 1) {
|
//最后一道工序生成出厂检
|
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(productQty);
|
qualityInspect.setProcess(process);
|
qualityInspect.setInspectState(0);
|
qualityInspect.setInspectType(inspectType);
|
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 {
|
//直接入库
|
// stockUtils.addStock(productProcessRouteItem.getProductModelId(), productQty, StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode(), productionProductMain.getId());
|
}
|
/*更新工单和生产订单*/
|
ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(dto.getWorkOrderId());
|
productWorkOrder.setCompleteQuantity(productWorkOrder.getCompleteQuantity().add(productQty));
|
if (ObjectUtils.isNull(productWorkOrder.getActualStartTime())) {
|
productWorkOrder.setActualStartTime(LocalDate.now());//实际开始时间
|
productWorkOrder.setStatus(2);
|
}
|
if (productWorkOrder.getCompleteQuantity().compareTo(productWorkOrder.getPlanQuantity()) == 0) {
|
productWorkOrder.setActualEndTime(LocalDate.now());//实际结束时间
|
productWorkOrder.setStatus(3);
|
}
|
productWorkOrderMapper.updateById(productWorkOrder);
|
//生产订单
|
ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId());
|
if (ObjectUtils.isNull(productOrder.getStartTime())) {
|
productOrder.setStartTime(LocalDateTime.now());//开始时间
|
productOrder.setStatus("生产中");
|
}
|
// 通过比例计算完成数量
|
productOrder.setCompleteQuantity(productOrder.getQuantity().multiply(ratio));
|
if (productWorkOrderList.size() == productProcessRouteItems.size() - 1) {
|
//如果是最后一道工序报工之后生产订单完成数量+
|
productOrder.setCompleteQuantity(productOrder.getQuantity());
|
if (productOrder.getCompleteQuantity().compareTo(productOrder.getQuantity()) == 0) {
|
productOrder.setEndTime(LocalDateTime.now());//结束时间
|
productOrder.setStatus("已完成");
|
// 生产完成入库
|
stockUtils.addStock(productProcessRouteItem.getProductModelId(), productOrder.getCompleteQuantity(), StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode(), productionProductMain.getId());
|
}
|
}
|
productOrderMapper.updateById(productOrder);
|
/*添加生产核算*/
|
SalesLedgerProductionAccounting salesLedgerProductionAccounting = SalesLedgerProductionAccounting.builder()
|
.productMainId(productionProductMain.getId())
|
.schedulingUserId(user.getUserId())
|
.schedulingUserName(user.getNickName())
|
.finishedNum(productQty)
|
.workHours(productProcess.getSalaryQuota())
|
.process(productProcess.getName())
|
.schedulingDate(LocalDate.now())
|
.tenantId(dto.getTenantId())
|
.build();
|
salesLedgerProductionAccountingMapper.insert(salesLedgerProductionAccounting);
|
}
|
//如果报废数量>0,需要进入报废的库存
|
// if (ObjectUtils.isNotEmpty(dto.getScrapQty())) {
|
// if (dto.getScrapQty().compareTo(BigDecimal.ZERO) > 0) {
|
// stockUtils.addUnStock(productModel.getId(), dto.getScrapQty(), StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode(), productionProductMain.getId());
|
// }
|
// }
|
return true;
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Boolean removeProductMain(Long id) {
|
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);
|
}
|
}
|