/*
|
* 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.production.service.impl;
|
|
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.util.StrUtil;
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
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.chinaztt.mes.basic.entity.Location;
|
import com.chinaztt.mes.basic.entity.Part;
|
import com.chinaztt.mes.basic.entity.WorkstationLocation;
|
import com.chinaztt.mes.basic.mapper.LocationMapper;
|
import com.chinaztt.mes.basic.mapper.PartMapper;
|
import com.chinaztt.mes.basic.mapper.WorkstationLocationMapper;
|
import com.chinaztt.mes.common.numgen.NumberGenerator;
|
import com.chinaztt.mes.common.wrapper.QueryWrapperUtil;
|
import com.chinaztt.mes.production.dto.ProductOutputDTO;
|
import com.chinaztt.mes.production.dto.SegmentationTaskRecordDTO;
|
import com.chinaztt.mes.production.entity.*;
|
import com.chinaztt.mes.production.mapper.*;
|
import com.chinaztt.mes.production.service.SegmentationTaskRecordService;
|
import com.chinaztt.mes.warehouse.dto.IfsMoveLibraryInfoDTO;
|
import com.chinaztt.mes.warehouse.dto.StockAddDTO;
|
import com.chinaztt.mes.warehouse.dto.StockDTO;
|
import com.chinaztt.mes.warehouse.entity.Stock;
|
import com.chinaztt.mes.warehouse.mapper.StockMapper;
|
import com.chinaztt.mes.warehouse.service.StockService;
|
import com.chinaztt.mes.warehouse.util.StockUtils;
|
import com.chinaztt.mes.warehouse.util.TransactionType;
|
import com.chinaztt.ztt.common.core.util.R;
|
import com.chinaztt.ztt.common.sequence.sequence.Sequence;
|
import lombok.AllArgsConstructor;
|
import org.apache.commons.lang3.math.NumberUtils;
|
import org.springframework.beans.BeanUtils;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.time.LocalDateTime;
|
import java.time.format.DateTimeFormatter;
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.List;
|
import java.util.stream.Collectors;
|
|
/**
|
* 分割任务明细
|
*
|
* @author shz
|
* @date 2023-02-14 09:04:11
|
*/
|
@Service
|
@AllArgsConstructor
|
@Transactional(rollbackFor = Exception.class)
|
public class SegmentationTaskRecordServiceImpl extends ServiceImpl<SegmentationTaskRecordMapper, SegmentationTaskRecord> implements SegmentationTaskRecordService {
|
|
private NumberGenerator<SegmentationTask> segmentationTaskNumberGenerator;
|
private SegmentationTaskMapper segmentationTaskMapper;
|
private StockMapper stockMapper;
|
private SegmentationTaskInputMapper segmentationTaskInputMapper;
|
private StockUtils stockUtils;
|
private PartMapper partMapper;
|
private StockService stockService;
|
private LocationMapper locationMapper;
|
private ExaminerMapper examinerMapper;
|
private WorkstationLocationMapper workstationLocationMapper;
|
private Sequence segmentationSequence;
|
|
@Override
|
public IPage<SegmentationTaskRecordDTO> getPage(Page page, QueryWrapper<SegmentationTaskRecordDTO> gen,SegmentationTaskRecordDTO segmentationTaskRecordDTO) {
|
SegmentationTaskRecordDTO searchSegmentationTaskRecordDTO = new SegmentationTaskRecordDTO();
|
BeanUtils.copyProperties(segmentationTaskRecordDTO,searchSegmentationTaskRecordDTO);
|
segmentationTaskRecordDTO.setStartTime(null);
|
segmentationTaskRecordDTO.setEndTime(null);
|
return this.baseMapper.getPage(page,QueryWrapperUtil.gen(segmentationTaskRecordDTO),searchSegmentationTaskRecordDTO);
|
}
|
|
@Override
|
public boolean fullSave(SegmentationTaskRecordDTO segmentationTaskRecord) {
|
|
String taskNo = segmentationTaskNumberGenerator.generateNumberWithPrefix(SegmentationTask.DIGIT, SegmentationTask.PREFIX, SegmentationTask::getNo);
|
|
// 投入总调整数量
|
BigDecimal totalInputNum = segmentationTaskRecord.getInputs().stream().map(SegmentationTaskInput::getAdjustQty).reduce(BigDecimal.ZERO, BigDecimal::add);
|
// 生产总数量不能大于输入数量
|
BigDecimal totalProduceNum = segmentationTaskRecord.getProductQty().multiply(new BigDecimal(segmentationTaskRecord.getDiskNum()));
|
|
// 占用库存 = 生产数量 + 报废数量
|
for (SegmentationTaskInput input : segmentationTaskRecord.getInputs()) {
|
// 判断是否为工序库存
|
Stock stock = stockMapper.selectById(input.getStockId());
|
if (stock.getOperationStockStatus()) {
|
throw new RuntimeException("工序库存不能作为分割投入");
|
}
|
|
// 如果存在多余的库存,需要将多余的库存释放
|
if (segmentationTaskRecord.getReturnInputStockId() != null && input.getStockId().equals(segmentationTaskRecord.getReturnInputStockId())) {
|
BigDecimal returnNum = totalInputNum.subtract(totalProduceNum);
|
if (input.getAdjustQty().compareTo(returnNum) < 0) {
|
throw new RuntimeException("需退回数量大于原输入数量");
|
} else {
|
input.setAdjustQty(input.getAdjustQty().subtract(returnNum));
|
}
|
}
|
stockUtils.updateById(input.getStockId(), input.getAdjustQty().add(input.getScrapQty()).negate(), BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, taskNo, TransactionType.SEGMENTATION_IN.getValue());
|
}
|
|
// 生成分割主表数据
|
SegmentationTask segmentationTask = SegmentationTask.builder()
|
.no(taskNo)
|
.taskType(segmentationTaskRecord.getTaskType())
|
.diskNum(segmentationTaskRecord.getDiskNum())
|
.partId(segmentationTaskRecord.getPartId())
|
.unit(segmentationTaskRecord.getUnit())
|
.productionUser(segmentationTaskRecord.getProductionUser())
|
.dutyRecordId(segmentationTaskRecord.getDutyRecordId())
|
.workstationId(segmentationTaskRecord.getWorkstationId())
|
.build();
|
segmentationTaskMapper.insert(segmentationTask);
|
|
DateTimeFormatter snFormat = DateTimeFormatter.ofPattern("yyMMdd");
|
String snDate = snFormat.format(LocalDateTime.now());
|
/* SegmentationTaskRecord maxRecord = this.baseMapper.selectOne(Wrappers.<SegmentationTaskRecord>lambdaQuery()
|
.like(SegmentationTaskRecord::getPartBatchNo, "Q" + snDate)
|
.orderByDesc(SegmentationTaskRecord::getPartBatchNo)
|
.last("LIMIT 1"));
|
int num = 1;
|
if (maxRecord != null) {
|
String partBatchNo = maxRecord.getPartBatchNo();
|
num = Integer.parseInt(partBatchNo.substring(partBatchNo.length() - 6)) + 1;
|
}*/
|
|
Part part = this.partMapper.selectById(segmentationTaskRecord.getPartId());
|
WorkstationLocation workstationLocation = workstationLocationMapper.selectOne(Wrappers.<WorkstationLocation>lambdaQuery().eq(WorkstationLocation::getWorkstationId, segmentationTask.getWorkstationId())
|
.eq(WorkstationLocation::getLocationType, WorkstationLocation.QUALIFIED_LOCATION).last("limit 1"));
|
Location qualifiedLocation = locationMapper.selectById(workstationLocation.getLocationId());
|
|
// 生成分割明细数据
|
for (int i = 0; i < segmentationTaskRecord.getDiskNum(); i++) {
|
SegmentationTaskRecord record = new SegmentationTaskRecord();
|
BeanUtil.copyProperties(segmentationTaskRecord, record);
|
record.setTaskId(segmentationTask.getId());
|
int num = Integer.parseInt(segmentationSequence.nextNo().substring(8));
|
record.setPartBatchNo("Q" + snDate + String.format("%06d", num));
|
record.setLocationId(qualifiedLocation.getId());
|
// 分盘IFS批次号不变,检号分盘和拼盘根据是否启用批次号来判断
|
if (SegmentationTask.TASK_TYPE_CENT_LINE.equals(segmentationTaskRecord.getTaskType())) {
|
record.setIfsBatchNo(segmentationTaskRecord.getInputs().get(0).getIfsBatchNo());
|
} else {
|
if (part.getLotTrackingIfs()) {
|
record.setIfsBatchNo(record.getPartBatchNo());
|
} else {
|
record.setIfsBatchNo("*");
|
}
|
}
|
record.setStatus(SegmentationTaskRecord.STATUS_DRAFT);
|
this.baseMapper.insert(record);
|
//num++;
|
}
|
|
BigDecimal totalNum = segmentationTaskRecord.getInputs().stream().map(SegmentationTaskInput::getAdjustQty).reduce(BigDecimal.ZERO, BigDecimal::add);
|
// 生成分割输入数据
|
for (SegmentationTaskInput input : segmentationTaskRecord.getInputs()) {
|
input.setTaskId(segmentationTask.getId());
|
input.setProportion(input.getAdjustQty().divide(totalNum, 2, RoundingMode.HALF_UP));
|
input.setUnit(segmentationTaskRecord.getUnit());
|
segmentationTaskInputMapper.insert(input);
|
}
|
|
return true;
|
}
|
|
@Override
|
public synchronized boolean fullUpdate(List<SegmentationTaskRecordDTO> segmentationTaskRecords) {
|
if (CollectionUtil.isNotEmpty(segmentationTaskRecords)) {
|
for (SegmentationTaskRecordDTO segmentationTaskRecord : segmentationTaskRecords) {
|
SegmentationTaskRecord record = this.baseMapper.selectById(segmentationTaskRecord.getId());
|
if (record == null) {
|
throw new RuntimeException("分割任务不存在");
|
}
|
|
if (SegmentationTaskRecord.STATUS_DRAFT.equals(record.getStatus())) {
|
if (segmentationTaskRecord.getProductQty().compareTo(record.getProductQty()) != 0) {
|
// 找出所有投入数据
|
List<SegmentationTaskInput> inputs = segmentationTaskInputMapper.selectList(Wrappers.<SegmentationTaskInput>lambdaQuery()
|
.eq(SegmentationTaskInput::getTaskId, record.getTaskId()));
|
BigDecimal totalInputNum = BigDecimal.ZERO;
|
for (SegmentationTaskInput input : inputs) {
|
totalInputNum = totalInputNum.add(input.getAdjustQty()).add(input.getScrapQty());
|
}
|
|
BigDecimal totalProductQty = record.getProductQty();
|
// 找出所有明细数据
|
List<SegmentationTaskRecord> records = this.baseMapper.selectList(Wrappers.<SegmentationTaskRecord>lambdaQuery()
|
.eq(SegmentationTaskRecord::getTaskId, record.getTaskId()).ne(SegmentationTaskRecord::getId, record.getId()));
|
if (records.size() > 0) {
|
totalProductQty = totalProductQty.add(records.stream().map(SegmentationTaskRecord::getProductQty).reduce(BigDecimal.ZERO, BigDecimal::add));
|
}
|
|
if (totalProductQty.compareTo(totalInputNum) > 0) {
|
throw new RuntimeException("分割数量大于投入数量");
|
}
|
}
|
|
// 校验分段描述
|
if (StrUtil.isNotBlank(segmentationTaskRecord.getSegmentDesc())) {
|
checkSegmentDesc(segmentationTaskRecord.getProductQty(), segmentationTaskRecord.getSegmentDesc());
|
}
|
|
// 如果生产数量减少,需要将多余数量退回
|
if (segmentationTaskRecord.getProductQty().compareTo(record.getProductQty()) != 0) {
|
BigDecimal returnNum = record.getProductQty().subtract(segmentationTaskRecord.getProductQty());
|
SegmentationTask segmentationTask = this.segmentationTaskMapper.selectById(record.getTaskId());
|
if (segmentationTask.getTaskType().equals(SegmentationTask.TASK_TYPE_MERGE_DISH)) {
|
SegmentationTaskInput input = this.segmentationTaskInputMapper.selectOne(Wrappers.<SegmentationTaskInput>lambdaQuery()
|
.eq(SegmentationTaskInput::getTaskId, record.getTaskId())
|
.eq(SegmentationTaskInput::getStockId, segmentationTaskRecord.getReturnInputStockId()));
|
if (returnNum.compareTo(BigDecimal.ZERO) > 0) {
|
if (input.getAdjustQty().compareTo(returnNum) < 0) {
|
throw new RuntimeException("退回数量无法大于该批次投入数量");
|
}
|
}
|
|
stockUtils.updateById(segmentationTaskRecord.getReturnInputStockId(), returnNum, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, segmentationTask.getNo(), TransactionType.SEGMENTATION_OUT.getValue());
|
// 更新投入数量
|
input.setAdjustQty(input.getAdjustQty().subtract(returnNum));
|
segmentationTaskInputMapper.updateById(input);
|
} else {
|
SegmentationTaskInput input = this.segmentationTaskInputMapper.selectOne(Wrappers.<SegmentationTaskInput>lambdaQuery().eq(SegmentationTaskInput::getTaskId, record.getTaskId()));
|
if (returnNum.compareTo(BigDecimal.ZERO) > 0) {
|
if (input.getAdjustQty().compareTo(returnNum) < 0) {
|
throw new RuntimeException("退回数量无法大于该批次投入数量");
|
}
|
}
|
|
stockUtils.updateById(input.getStockId(), returnNum, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, segmentationTask.getNo(), TransactionType.SEGMENTATION_OUT.getValue());
|
// 更新投入数量
|
input.setAdjustQty(input.getAdjustQty().subtract(returnNum));
|
segmentationTaskInputMapper.updateById(input);
|
}
|
}
|
record.setProductQty(segmentationTaskRecord.getProductQty());
|
record.setSegmentDesc(segmentationTaskRecord.getSegmentDesc());
|
}
|
record.setReelNumber(segmentationTaskRecord.getReelNumber());
|
record.setRemark(segmentationTaskRecord.getRemark());
|
this.updateById(record);
|
}
|
}
|
return true;
|
}
|
|
@Override
|
public boolean delByIds(List<Long> ids) {
|
synchronized (ids.toString().intern()) {
|
for (Long id : ids) {
|
SegmentationTaskRecord record = this.baseMapper.selectById(id);
|
if (record == null) {
|
throw new RuntimeException("分割任务不存在");
|
}
|
if (!SegmentationTaskRecord.STATUS_DRAFT.equals(record.getStatus())) {
|
throw new RuntimeException("分割任务状态不是草稿");
|
}
|
SegmentationTask task = segmentationTaskMapper.selectById(record.getTaskId());
|
Integer count = this.baseMapper.selectCount(Wrappers.<SegmentationTaskRecord>lambdaQuery()
|
.eq(SegmentationTaskRecord::getTaskId, record.getTaskId()).ne(SegmentationTaskRecord::getId, record.getId()));
|
|
// 查找所有投入数据
|
List<SegmentationTaskInput> inputs = segmentationTaskInputMapper.selectList(Wrappers.<SegmentationTaskInput>lambdaQuery()
|
.eq(SegmentationTaskInput::getTaskId, record.getTaskId()));
|
for (SegmentationTaskInput input : inputs) {
|
// 计算该投入所需退回数量
|
BigDecimal summary = record.getProductQty().multiply(input.getProportion());
|
// 如果为最后一条明细,退回所有投入数量
|
if (count == 0) {
|
// 退回库存
|
stockUtils.updateById(input.getStockId(), input.getAdjustQty().add(input.getScrapQty()), BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, task.getNo(), TransactionType.SEGMENTATION_OUT.getValue());
|
// 删除投入数据
|
segmentationTaskInputMapper.deleteById(input.getId());
|
// 删除主表数据
|
segmentationTaskMapper.deleteById(task.getId());
|
|
// 投入数量小于退回数量
|
} else if (summary.compareTo(input.getAdjustQty()) < 0) {
|
// 更新投入数量
|
input.setAdjustQty(input.getAdjustQty().subtract(summary));
|
segmentationTaskInputMapper.updateById(input);
|
|
// 退回库存
|
stockUtils.updateById(input.getStockId(), summary, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, task.getNo(), TransactionType.SEGMENTATION_OUT.getValue());
|
}
|
}
|
// 删除分割明细数据
|
this.baseMapper.deleteById(id);
|
}
|
}
|
return true;
|
}
|
|
@Override
|
public boolean submit(List<Long> ids) {
|
synchronized (ids.toString().intern()) {
|
List<SegmentationTaskRecord> records = this.baseMapper.selectBatchIds(ids);
|
if (CollectionUtil.isEmpty(records)) {
|
throw new RuntimeException("分割任务不存在");
|
}
|
|
Long count = records.stream().map(SegmentationTaskRecord::getTaskId).distinct().count();
|
if (count.intValue() != 1) {
|
throw new RuntimeException("只能提交同一个任务的明细");
|
}
|
|
records.stream().filter(record -> !SegmentationTaskRecord.STATUS_DRAFT.equals(record.getStatus())).forEach(record -> {
|
throw new RuntimeException("只能提交草稿状态的明细");
|
});
|
|
Integer checkCount = this.baseMapper.selectCount(Wrappers.<SegmentationTaskRecord>lambdaQuery()
|
.eq(SegmentationTaskRecord::getTaskId, records.get(0).getTaskId())
|
.notIn(SegmentationTaskRecord::getId, ids));
|
if (checkCount > 0) {
|
throw new RuntimeException("该任务存在明细未提交");
|
}
|
|
SegmentationTask task = segmentationTaskMapper.selectById(records.get(0).getTaskId());
|
|
// 查找所有投入数据
|
List<SegmentationTaskInput> segmentationTaskInputs = this.segmentationTaskInputMapper.selectList(Wrappers.<SegmentationTaskInput>lambdaQuery()
|
.eq(SegmentationTaskInput::getTaskId, task.getId()));
|
BigDecimal totalScrapQty = segmentationTaskInputs.stream().map(SegmentationTaskInput::getScrapQty).reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
// 如果类型为分盘
|
if (SegmentationTask.TASK_TYPE_CENT_LINE.equals(task.getTaskType())) {
|
Stock inputStock = stockMapper.selectById(segmentationTaskInputs.get(0).getStockId());
|
Location inputLocation = locationMapper.selectById(inputStock.getLocationId());
|
Location nowLocation = locationMapper.selectById(records.get(0).getLocationId());
|
// 存在废料需要发放
|
if (totalScrapQty.compareTo(BigDecimal.ZERO) > 0) {
|
List<StockDTO> stocks = new ArrayList<>();
|
StockDTO stockDTO = new StockDTO();
|
stockDTO.setPartId(task.getPartId());
|
stockDTO.setLocationId(inputLocation.getId());
|
stockDTO.setLocationNo(inputLocation.getIfsLocation());
|
stockDTO.setPartBatchNo(segmentationTaskInputs.get(0).getPartBatchNo());
|
stockDTO.setIfsBatchNo(segmentationTaskInputs.get(0).getIfsBatchNo());
|
stockDTO.setManualInput(true);
|
stockDTO.setAvailableStockQuantityMove(totalScrapQty);
|
stockDTO.setAdjustType("Issue");
|
stockDTO.setAdjustMemo("库存发放");
|
stocks.add(stockDTO);
|
stockService.inventAdjustForRfcable(stocks, "Issue", null);
|
}
|
|
// 判断投入库位和分割库位是否一致,不一致进行库存件移库
|
if (!records.get(0).getLocationId().equals(inputLocation.getId())) {
|
Part part = partMapper.selectById(inputStock.getPartId());
|
List<IfsMoveLibraryInfoDTO> ifsMoveLibraryInfoDTOList = new ArrayList<>();
|
IfsMoveLibraryInfoDTO param = new IfsMoveLibraryInfoDTO();
|
param.setStartLocationNo(inputLocation.getIfsLocation());
|
param.setArriveLocationNo(nowLocation.getIfsLocation());
|
param.setMoveQty(segmentationTaskInputs.get(0).getAdjustQty());
|
param.setPartNo(segmentationTaskInputs.get(0).getPartNo());
|
param.setBatchNo(segmentationTaskInputs.get(0).getIfsBatchNo());
|
param.setSerialNo("*");
|
param.setEngChgLevel(part.getEngChgLevel());
|
if(part.getLotTrackingIfs() != null && part.getLotTrackingIfs()){
|
param.setWaivDevRejNo(segmentationTaskInputs.get(0).getPartBatchNo());//wdr号(把mes的sn号放里面)
|
}else{
|
param.setWaivDevRejNo("*");//wdr号
|
}
|
ifsMoveLibraryInfoDTOList.add(param);
|
|
stockService.ifsMoveLibrary(ifsMoveLibraryInfoDTOList);
|
}
|
|
// 新增MES库存,调用更改wdr号接口
|
List<StockDTO> stocks = new ArrayList<>();
|
for (SegmentationTaskRecord record : records) {
|
StockAddDTO stockAddDTO = new StockAddDTO();
|
stockAddDTO.setPartsId(record.getPartId());
|
stockAddDTO.setNewLocationId(record.getLocationId());
|
stockAddDTO.setNewPartBatchNo(record.getPartBatchNo());
|
stockAddDTO.setReelNumber(record.getReelNumber());
|
stockAddDTO.setOperationStockStatus(false);
|
stockAddDTO.setIfsBatchNo(record.getIfsBatchNo());
|
stockAddDTO.setManualInput(true);
|
StockDTO stockDTO = BeanUtil.copyProperties(stockUtils.query(stockAddDTO), StockDTO.class);
|
stockUtils.updateById(stockDTO.getId(), record.getProductQty(), BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, task.getNo(), TransactionType.SEGMENTATION_SUBMIT.getValue());
|
stockDTO.setAvailableStockQuantityMove(record.getProductQty());
|
stockDTO.setLocationNo(nowLocation.getIfsLocation());
|
stocks.add(stockDTO);
|
}
|
stockService.ifsImportChangeWdrStd(stocks, segmentationTaskInputs.get(0).getPartBatchNo());
|
|
// 检号分盘和拼盘
|
} else {
|
// 投入发放
|
List<StockDTO> inStocks = new ArrayList<>();
|
for (SegmentationTaskInput input : segmentationTaskInputs) {
|
Stock inputStock = stockMapper.selectById(input.getStockId());
|
Location inputLocation = locationMapper.selectById(inputStock.getLocationId());
|
|
// 通过零件号、库位号、IFS批次号查询IFS库存数量查询接口,获取WDR号
|
JSONObject ifsStockQuery = new JSONObject();
|
ifsStockQuery.put("PART_NO", input.getPartNo());
|
ifsStockQuery.put("LOCATION_NO", inputLocation.getIfsLocation());
|
ifsStockQuery.put("LOT_BATCH_NO", input.getIfsBatchNo());
|
ifsStockQuery.put("QUANTITY_FLAG", ">0");
|
R ifsStock = stockService.getIfsStock(null, ifsStockQuery);
|
String wdrNo;
|
if (ifsStock.getCode() == 0) {
|
JSONArray jsonArray = (JSONArray) ifsStock.getData();
|
if (jsonArray.size() == 0) {
|
throw new RuntimeException("IFS库存未找到该投入,IFS批次号为:" + input.getIfsBatchNo());
|
} else {
|
wdrNo = jsonArray.getJSONObject(0).getString("WAIV_DEV_REJ_NO");
|
}
|
} else {
|
throw new RuntimeException("IFS库存查询接口调用失败,原因:" + ifsStock.getMsg());
|
}
|
|
StockDTO stockDTO = new StockDTO();
|
stockDTO.setPartId(inputStock.getPartId());
|
stockDTO.setPartNo(input.getPartNo());
|
stockDTO.setLocationNo(inputLocation.getIfsLocation());
|
stockDTO.setPartBatchNo(wdrNo);
|
stockDTO.setIfsBatchNo(input.getIfsBatchNo());
|
stockDTO.setManualInput(true);
|
stockDTO.setAvailableStockQuantityMove(input.getAdjustQty().add(input.getScrapQty()));
|
stockDTO.setAdjustType("Issue");
|
stockDTO.setAdjustMemo("库存发放");
|
inStocks.add(stockDTO);
|
}
|
// stockService.inventAdjustForRfcable(inStocks, "Issue", "T03");
|
|
// 库存调整
|
List<StockDTO> stocks = new ArrayList<>();
|
// 组装库存数据
|
for (SegmentationTaskRecord record : records) {
|
Location location = locationMapper.selectById(record.getLocationId());
|
StockAddDTO stockAddDTO = new StockAddDTO();
|
stockAddDTO.setPartsId(record.getPartId());
|
stockAddDTO.setNewLocationId(record.getLocationId());
|
stockAddDTO.setNewPartBatchNo(record.getPartBatchNo());
|
stockAddDTO.setReelNumber(record.getReelNumber());
|
stockAddDTO.setOperationStockStatus(false);
|
stockAddDTO.setIfsBatchNo(record.getIfsBatchNo());
|
stockAddDTO.setManualInput(true);
|
StockDTO stockDTO = BeanUtil.copyProperties(stockUtils.query(stockAddDTO), StockDTO.class);
|
stockUtils.updateById(stockDTO.getId(), record.getProductQty(), BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, task.getNo(), TransactionType.SEGMENTATION_SUBMIT.getValue());
|
stockDTO.setAvailableStockQuantityMove(record.getProductQty());
|
stockDTO.setLocationNo(location.getIfsLocation());
|
stockDTO.setAdjustType("Receive");
|
stockDTO.setAdjustMemo("库存接收");
|
inStocks.add(stockDTO);
|
}
|
stockService.inventAdjustForRfcable(inStocks, "", "T03");
|
}
|
|
this.update(Wrappers.<SegmentationTaskRecord>lambdaUpdate()
|
.eq(SegmentationTaskRecord::getTaskId, task.getId())
|
.set(SegmentationTaskRecord::getStatus, SegmentationTaskRecord.STATUS_SUBMIT));
|
}
|
return true;
|
}
|
|
@Override
|
public List<SegmentationTaskRecordDTO> batchLabelPrint(List<Long> ids) {
|
return this.baseMapper.batchLabelPrint(ids);
|
}
|
|
@Override
|
public boolean check(SegmentationTaskRecordDTO segmentationTaskRecord) {
|
// 分盘和检号分盘
|
if (segmentationTaskRecord.getDiskNum() == null || segmentationTaskRecord.getDiskNum() <= 0
|
|| segmentationTaskRecord.getProductQty() == null || segmentationTaskRecord.getProductQty().compareTo(BigDecimal.ZERO) <= 0) {
|
throw new RuntimeException("盘数和生产数量未填或填写错误");
|
}
|
if (SegmentationTask.TASK_TYPE_CENT_LINE.equals(segmentationTaskRecord.getTaskType()) || SegmentationTask.TASK_TYPE_CHECK_CENT_LINE.equals(segmentationTaskRecord.getTaskType())) {
|
if (segmentationTaskRecord.getInputs().size() > 1) {
|
throw new RuntimeException("分盘任务只能有一个输入");
|
}
|
}
|
|
BigDecimal totalInputNum = BigDecimal.ZERO;
|
// 检测输入数量是否正确
|
for (SegmentationTaskInput input : segmentationTaskRecord.getInputs()) {
|
Stock stock = stockMapper.selectById(input.getStockId());
|
BigDecimal inputNum = input.getAdjustQty().add(input.getScrapQty());
|
if (stock.getAvailableStockQuantity().compareTo(inputNum) != 0) {
|
throw new RuntimeException("库存可用数量与输入可用数量和报废数量之和不一致");
|
}
|
totalInputNum = totalInputNum.add(input.getAdjustQty());
|
}
|
|
// 校验分段描述
|
if (StrUtil.isNotBlank(segmentationTaskRecord.getSegmentDesc())) {
|
checkSegmentDesc(segmentationTaskRecord.getProductQty(), segmentationTaskRecord.getSegmentDesc());
|
}
|
|
// 生产总数量不能大于输入数量
|
BigDecimal totalProduceNum = segmentationTaskRecord.getProductQty().multiply(new BigDecimal(segmentationTaskRecord.getDiskNum()));
|
if (totalProduceNum.compareTo(totalInputNum) > 0) {
|
throw new RuntimeException("生产总数量不能大于输入数量");
|
} else if (totalProduceNum.compareTo(totalInputNum) < 0) {
|
return false;
|
}
|
return true;
|
}
|
|
@Override
|
public List<SegmentationTaskInput> checkEdit(List<SegmentationTaskRecordDTO> segmentationTaskRecords) {
|
List<SegmentationTaskRecordDTO> listByIds = this.baseMapper.getListByIds(segmentationTaskRecords.stream().map(SegmentationTaskRecordDTO::getId).collect(Collectors.toList()));
|
for (SegmentationTaskRecordDTO record : listByIds) {
|
if (record.getStatus().equals(SegmentationTaskRecord.STATUS_SUBMIT)) {
|
throw new RuntimeException("已提交的分盘任务不能修改");
|
}
|
for (SegmentationTaskRecordDTO newRecord : segmentationTaskRecords) {
|
// 拼盘需要判断是否需要选择退库
|
if (record.getId().equals(newRecord.getId()) && record.getTaskType().equals(SegmentationTask.TASK_TYPE_MERGE_DISH)) {
|
if (record.getProductQty().compareTo(newRecord.getProductQty()) != 0) {
|
return this.segmentationTaskInputMapper.selectList(Wrappers.<SegmentationTaskInput>lambdaQuery()
|
.eq(SegmentationTaskInput::getTaskId, record.getTaskId()));
|
}
|
}
|
}
|
}
|
return new ArrayList<>();
|
}
|
|
private void checkSegmentDesc(BigDecimal productQty, String segmentDesc) {
|
String[] split = segmentDesc.split("\\+");
|
if (split.length > 1) {
|
for (String desc : split) {
|
if (!NumberUtils.isCreatable(desc)) {
|
throw new RuntimeException("分段描述只能用数字分段");
|
}
|
}
|
} else {
|
throw new RuntimeException("分段描述格式不正确");
|
}
|
List<String> segmentList = Arrays.asList(split);
|
BigDecimal totalSegment = segmentList.stream().reduce(BigDecimal.ZERO, (a, b) -> a.add(new BigDecimal(b)), BigDecimal::add);
|
if (productQty.compareTo(totalSegment.divide(BigDecimal.valueOf(1000))) != 0) {
|
throw new RuntimeException("分段描述与生产数量不一致");
|
}
|
}
|
}
|