You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
udi-wms-java/src/main/java/com/glxp/api/service/inout/IoSplitQxService.java

484 lines
26 KiB
Java

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.glxp.api.service.inout;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.glxp.api.dao.inout.IoSplitCodeMapper;
import com.glxp.api.entity.basic.SysWorkplacePutRel;
import com.glxp.api.entity.basic.UdiRelevanceEntity;
import com.glxp.api.entity.collect.*;
import com.glxp.api.entity.inout.IoSplitCodeEntity;
import com.glxp.api.entity.inout.IoSplitFifoCodeEntity;
import com.glxp.api.entity.inout.IoSplitFifoInv;
import com.glxp.api.exception.JsonException;
import com.glxp.api.req.basic.FilterUdiRelRequest;
import com.glxp.api.res.basic.UdiRelevanceResponse;
import com.glxp.api.service.basic.UdiRelevanceService;
import com.glxp.api.service.collect.*;
import com.glxp.api.service.thrsys.SysWorkplacePutRelService;
import com.glxp.api.util.IntUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/**
* @author AnthonyYwj
* @date 2024/12/24
*/
@Service
public class IoSplitQxService {
@Resource
IoSplitCodeMapper splitCodeMapper;
@Resource
IoSplitFifoCodeService splitFifoCodeService;
@Resource
IoCollectOrderBizService collectOrderBizService;
@Resource
IoCollectOrderCodeAutoService collectOrderCodeAutoService;
@Resource
UdiRelevanceService udiRelevanceService;
@Resource
IoCollectOrderCodeManService collectOrderCodeManService;
@Resource
IoSplitCodeService splitCodeService;
@Resource
IoCollectOrderBizBackupService ioCollectOrderBizBackupService;
@Resource
SysWorkplacePutRelService workplacePutRelService;
@Resource
IoSplitFifoInvService splitFifoInvService;
@Transactional(rollbackFor = Exception.class)
public void finishQxAutoTagCode(IoCollectOrder collectOrder, Boolean isAuto, String queueCode) {
SysWorkplacePutRel sysWorkplacePutRel = workplacePutRelService.findPutWorkPlace(collectOrder.getWorkPlaceCode(), collectOrder.getBusType());
Long putWorkPlaceCode = null;
if (sysWorkplacePutRel != null)
putWorkPlaceCode = sysWorkplacePutRel.getWorkPlaceCode();
List<IoCollectOrderBiz> collectOrderBizs = collectOrderBizService.listByBillNo(collectOrder.getBillNo());
//如果手动扫码判断该码是否在队列里,如果已在队列,则队列里剔除
List<IoCollectOrderCodeMan> collectOrderCodeMEN = collectOrderCodeManService.listByBillNo(collectOrder.getBillNo());
if (CollUtil.isNotEmpty(collectOrderCodeMEN)) {
for (IoCollectOrderCodeMan collectOrderCodeMan : collectOrderCodeMEN) {
IoSplitFifoCodeEntity splitFifoCodeEntity = splitFifoCodeService.findByCode(collectOrderCodeMan.getUdiCode(), putWorkPlaceCode);
if (splitFifoCodeEntity != null) {
collectOrderCodeMan.setRemoveFlag(true);
if (IntUtil.value(splitFifoCodeEntity.getScanCount()) - IntUtil.value(collectOrderCodeMan.getScanCount()) <= 0) {
splitFifoCodeService.removeById(splitFifoCodeEntity.getId());
IoSplitFifoInv splitFifoInv = splitFifoInvService.findByFifoCode(splitFifoCodeEntity);
if (splitFifoInv != null) {
splitFifoInv.setOutCount(IntUtil.value(splitFifoInv.getOutCount()) + IntUtil.value(splitFifoCodeEntity.getTotalCount()));
int lockCount = IntUtil.value(splitFifoInv.getLockCount()) - IntUtil.value(splitFifoCodeEntity.getTotalCount());
splitFifoInv.setLockCount(lockCount > 0 ? lockCount : 0);
splitFifoInv.setReCount(IntUtil.value(splitFifoInv.getInCount()) - IntUtil.value(splitFifoInv.getOutCount()));
splitFifoInv.setAvailableCount(IntUtil.value(splitFifoInv.getInCount()) - IntUtil.value(splitFifoInv.getLockCount()) - IntUtil.value(splitFifoInv.getOutCount()));
splitFifoInvService.updateById(splitFifoInv);
}
} else {
//队列码数量大于扫码数量更新数量(一般指无序列号)
// UdiRelevanceEntity udiRelevanceEntity = udiRelevanceService.selectById(collectOrderCodeMan.getRelId());
FilterUdiRelRequest filterUdiRelRequest = new FilterUdiRelRequest();
filterUdiRelRequest.setId(collectOrderCodeMan.getRelId());
filterUdiRelRequest.setPackLevel("1");
UdiRelevanceResponse udiRelevanceResponse = udiRelevanceService.selectOneUdi(filterUdiRelRequest);
int removeCount = IntUtil.value(collectOrderCodeMan.getScanCount()) * udiRelevanceResponse.getBhxjsl();
splitFifoCodeService.updateById(IoSplitFifoCodeEntity.builder()
.id(splitFifoCodeEntity.getId())
.scanCount(IntUtil.value(splitFifoCodeEntity.getScanCount()) - IntUtil.value(collectOrderCodeMan.getScanCount()))
.totalCount(IntUtil.value(splitFifoCodeEntity.getTotalCount()) - removeCount)
.build());
IoSplitFifoInv splitFifoInv = splitFifoInvService.findByFifoCode(splitFifoCodeEntity);
if (splitFifoInv != null) {
splitFifoInv.setOutCount(IntUtil.value(splitFifoInv.getOutCount()) + removeCount);
int lockCount = IntUtil.value(splitFifoInv.getLockCount()) - removeCount;
splitFifoInv.setLockCount(lockCount > 0 ? lockCount : 0);
splitFifoInv.setReCount(IntUtil.value(splitFifoInv.getInCount()) - IntUtil.value(splitFifoInv.getOutCount()));
splitFifoInv.setAvailableCount(IntUtil.value(splitFifoInv.getInCount()) - IntUtil.value(splitFifoInv.getLockCount()) - IntUtil.value(splitFifoInv.getOutCount()));
splitFifoInvService.updateById(splitFifoInv);
}
}
}
//判断拆零表里是否存在,如果存在则剔除
IoSplitCodeEntity splitCodeEntity = splitCodeService.findByCode(collectOrderCodeMan.getUdiCode(), putWorkPlaceCode);
if (splitCodeEntity != null && IntUtil.value(splitCodeEntity.getRemainCount()) > 0) {
if (IntUtil.value(splitCodeEntity.getRemainCount()) > IntUtil.value(collectOrderCodeMan.getScanActCount())) {
splitCodeEntity.setRemainCount(IntUtil.value(splitCodeEntity.getRemainCount()) - IntUtil.value(collectOrderCodeMan.getScanActCount()));
} else {
splitCodeEntity.setRemainCount(0);
}
collectOrderCodeMan.setSplitFlag(true);
splitCodeService.updateById(splitCodeEntity);
}
}
}
for (IoCollectOrderBiz collectOrderBiz : collectOrderBizs) {
UdiRelevanceResponse udiRelevanceResponse = null;
if (StrUtil.isNotEmpty(collectOrderBiz.getCheckCode())) {
List<Long> relIds = udiRelevanceService.selectByCheckCode(collectOrderBiz.getCheckCode());
if (CollUtil.isNotEmpty(relIds)) {
udiRelevanceResponse = udiRelevanceService.selectByLevelRelId(relIds.get(0) + "");
}
} else {
udiRelevanceResponse = udiRelevanceService.selectByLevelRelId(collectOrderBiz.getRelId() + "");
}
//去除掉已经手动扫码的数据,找出需要自动扫码的明细,执行上述的拆零或整取
int unTagCount = collectOrderBiz.getCount() - IntUtil.value(collectOrderBiz.getScanActCount());
if (unTagCount > 0) {
collectOrderBiz.setUnTagCount(unTagCount);
} else {
collectOrderBiz.setTagStatus(3);
//手动扫码时涉及到拆零时,把拆零剩余数量插入至拆零表里
if (unTagCount < 0) {
List<IoCollectOrderCodeMan> newList = filterCode(collectOrderCodeMEN, collectOrderBiz, udiRelevanceResponse);
if (CollUtil.isNotEmpty(newList)) {
for (IoCollectOrderCodeMan item : newList) {
if (IntUtil.value(item.getSplitFlag())) {
IoSplitCodeEntity splitCodeEntity = splitCodeService.findByCode(item.getUdiCode(), putWorkPlaceCode);
splitCodeEntity.setRemainCount(-unTagCount);
splitCodeService.updateById(splitCodeEntity);
} else {
IoSplitCodeEntity ioSplitCodeEntity = IoSplitCodeEntity.builder().code(item.getUdiCode())
.errUdiCode(item.getUdiCode())
.orderId(item.getOrderIdFk())
.action(collectOrder.getBusType())
.relId(item.getRelId())
.nameCode(item.getNameCode())
.batchNo(item.getBatchNo())
.produceDate(item.getProductDate())
.expireDate(item.getExpireDate())
.serialNo(item.getSerialNo())
.scanCount(item.getScanCount())
.totalCount(item.getScanCount())
.workPlaceCode(putWorkPlaceCode)
.status(2)
.fifoSplit(1)
.createTime(new Date()).updateTime(new Date())
.remainCount(item.getRemainCount()).build();
this.decorateUnpackExpireTime(ioSplitCodeEntity);
splitCodeService.save(ioSplitCodeEntity);
}
}
}
}
continue;
}
//
splitRemove(collectOrderBiz, collectOrder, putWorkPlaceCode, isAuto);
}
ArrayList<IoCollectOrderBizBackup> ioCollectOrderBizBackups = new ArrayList<>();
for (IoCollectOrderBiz ioCollectOrderBiz : collectOrderBizs) {
IoCollectOrderBizBackup ioCollectOrderBizBackup = new IoCollectOrderBizBackup();
BeanUtils.copyProperties(ioCollectOrderBiz, ioCollectOrderBizBackup);
ioCollectOrderBizBackups.add(ioCollectOrderBizBackup);
}
ioCollectOrderBizBackupService.saveBatch(ioCollectOrderBizBackups);
}
public void splitRemove(IoCollectOrderBiz collectOrderBiz, IoCollectOrder collectOrder, Long
putWorkPlaceCode, Boolean isAuto) {
List<IoSplitCodeEntity> ioSplitCodeEntities = null;
List<Long> relIds = new ArrayList<>();
//1.按照先进先出原则查询拆零表获取拆零表ID
if (StrUtil.isNotEmpty(collectOrderBiz.getCheckCode())) {
relIds = udiRelevanceService.selectByCheckCode(collectOrderBiz.getCheckCode());
if (CollUtil.isNotEmpty(relIds)) {
ioSplitCodeEntities = findSplitCodes(relIds, collectOrderBiz.getBatchNo(), putWorkPlaceCode);
}
} else {
ioSplitCodeEntities = findSplitCodes(collectOrderBiz.getRelId(), collectOrderBiz.getBatchNo(), putWorkPlaceCode);
relIds.add(collectOrderBiz.getRelId());
}
//2.如果拆零表为空,则自动从预出库队列中获拉取数据
if (CollUtil.isEmpty(ioSplitCodeEntities)) {
addFifoCode(relIds, collectOrderBiz.getBatchNo(), IntUtil.value(collectOrderBiz.getUnTagCount()), putWorkPlaceCode);
if (StrUtil.isNotEmpty(collectOrderBiz.getCheckCode())) {
relIds = udiRelevanceService.selectByCheckCode(collectOrderBiz.getCheckCode());
if (CollUtil.isNotEmpty(relIds)) {
ioSplitCodeEntities = findSplitCodes(relIds, collectOrderBiz.getBatchNo(), putWorkPlaceCode);
}
} else {
ioSplitCodeEntities = findSplitCodes(relIds, collectOrderBiz.getBatchNo(), putWorkPlaceCode);
}
}
//3.如果拆零表不为空,则开始扣除数量
int count = 0;
int unCount = 0; //剩余未扣减数量
unCount = IntUtil.value(collectOrderBiz.getUnTagCount());
for (IoSplitCodeEntity ioSplitCodeEntity : ioSplitCodeEntities) {
count = IntUtil.value(ioSplitCodeEntity.getRemainCount()) - unCount;
collectOrderCodeAutoService.save(IoCollectOrderCodeAuto.builder()
.codeIdFk(ioSplitCodeEntity.getId())
.udiCode(ioSplitCodeEntity.getCode())
.orderIdFk(collectOrder.getBillNo())
.batchNo(ioSplitCodeEntity.getBatchNo())
.productDate(ioSplitCodeEntity.getProduceDate())
.expireDate(ioSplitCodeEntity.getExpireDate())
.serialNo(ioSplitCodeEntity.getSerialNo())
.relId(ioSplitCodeEntity.getRelId())
.bizIdFk(collectOrderBiz.getId())
.fifoSplit(ioSplitCodeEntity.getFifoSplit())
.createTime(new Date())
.updateTime(new Date())
.build());
if (count > 0) {
ioSplitCodeEntity.setRemainCount(count);
unCount = 0;
splitCodeMapper.updateById(ioSplitCodeEntity);
break;
} else if (count == 0) {
ioSplitCodeEntity.setRemainCount(0);
unCount = 0;
} else {
ioSplitCodeEntity.setRemainCount(0);
unCount = -count;
}
splitCodeMapper.updateById(ioSplitCodeEntity);
}
if (unCount > 0) {
//4.拆零表数量不足,则从预出库队列中获取数据
Integer fifoCount = addFifoCode(relIds, collectOrderBiz.getBatchNo(), unCount, putWorkPlaceCode);
if (fifoCount == 0) {
//预出库队列数量不足
collectOrderBiz.setTagStatus(2);
collectOrderBiz.setTagMsg("预出库队列码数量不足,赋码失败!");
if (isAuto)
throw new JsonException(500, "提交失败,工位库存数量不足!");
else return;
} else {
//再次执行赋码
ioSplitCodeEntities = findSplitCodes(relIds, collectOrderBiz.getBatchNo(), putWorkPlaceCode);
for (IoSplitCodeEntity ioSplitCodeEntity : ioSplitCodeEntities) {
if (IntUtil.value(ioSplitCodeEntity.getRemainCount()) > 0) {
count = IntUtil.value(ioSplitCodeEntity.getRemainCount()) - unCount;
collectOrderCodeAutoService.save(IoCollectOrderCodeAuto.builder()
.codeIdFk(ioSplitCodeEntity.getId())
.udiCode(ioSplitCodeEntity.getCode())
.orderIdFk(collectOrder.getBillNo())
.batchNo(ioSplitCodeEntity.getBatchNo())
.productDate(ioSplitCodeEntity.getProduceDate())
.expireDate(ioSplitCodeEntity.getExpireDate())
.serialNo(ioSplitCodeEntity.getSerialNo())
.relId(ioSplitCodeEntity.getRelId())
.bizIdFk(collectOrderBiz.getId())
.fifoSplit(ioSplitCodeEntity.getFifoSplit())
.createTime(new Date())
.updateTime(new Date())
.build());
if (count > 0) {
ioSplitCodeEntity.setRemainCount(count);
splitCodeMapper.updateById(ioSplitCodeEntity);
break;
} else if (count == 0) {
ioSplitCodeEntity.setRemainCount(0);
splitCodeMapper.updateById(ioSplitCodeEntity);
} else {
ioSplitCodeEntity.setRemainCount(0);
splitCodeMapper.updateById(ioSplitCodeEntity);
unCount = -count;
}
}
}
if (unCount > 0) {
collectOrderBiz.setTagStatus(2);
collectOrderBiz.setTagMsg("预出库队列码数量不足,赋码失败!");
if (isAuto)
throw new JsonException(500, "提交失败,工位库存数量不足!");
else return;
} else {
collectOrderBiz.setTagStatus(3);
collectOrderBiz.setTagMsg("赋码完成!");
}
}
} else {
collectOrderBiz.setTagStatus(3);
collectOrderBiz.setTagMsg("赋码完成!");
}
collectOrderBiz.setUnTagCount(unCount);
collectOrderBizService.updateById(collectOrderBiz);
}
/**
* 从预出库队列里面取出数据,添加至拆零表
*/
public Integer addFifoCode(List<Long> relIds, String batchNo, Integer requiredCount, Long workplaceCode) {
// Query FIFO codes based on criteria
List<IoSplitFifoCodeEntity> fifoCodeList = splitFifoCodeService
.list(new LambdaQueryWrapper<IoSplitFifoCodeEntity>()
.in(IoSplitFifoCodeEntity::getRelId, relIds)
.eq(StrUtil.isNotEmpty(batchNo), IoSplitFifoCodeEntity::getBatchNo, batchNo)
.eq(workplaceCode != null, IoSplitFifoCodeEntity::getWorkPlaceCode, workplaceCode)
.orderByAsc(IoSplitFifoCodeEntity::getInBactchNo)
);
int totalProcessedCount = 0;
List<IoSplitCodeEntity> splitCodesToAdd = new ArrayList<>();
List<Long> idsToRemove = new ArrayList<>();
for (IoSplitFifoCodeEntity fifoCode : fifoCodeList) {
boolean isTargetReached = false;
int processedScans = 0;
for (int i = 0; i < fifoCode.getScanCount(); i++) {
// Create new FIFO code entity
IoSplitFifoCodeEntity newFifoCode = new IoSplitFifoCodeEntity();
BeanUtils.copyProperties(fifoCode, newFifoCode);
newFifoCode.setScanCount(1);
int codesPerScan = fifoCode.getTotalCount() / fifoCode.getScanCount();
newFifoCode.setTotalCount(codesPerScan);
// Create and populate split code entity
IoSplitCodeEntity splitCode = new IoSplitCodeEntity();
BeanUtils.copyProperties(newFifoCode, splitCode);
totalProcessedCount += IntUtil.value(newFifoCode.getTotalCount());
splitCode.setRemainCount(splitCode.getTotalCount());
splitCode.setStatus(1);
splitCode.setFifoSplit(newFifoCode.getFifoSplit());
splitCode.setId(null);
this.decorateUnpackExpireTime(splitCode);
splitCodesToAdd.add(splitCode);
// Update inventory
IoSplitFifoInv inventory = splitFifoInvService.findByFifoCode(newFifoCode);
if (inventory != null) {
updateInventory(inventory, newFifoCode.getTotalCount());
splitFifoInvService.updateById(inventory);
}
// Update original FIFO code
splitFifoCodeService.updateById(IoSplitFifoCodeEntity.builder()
.id(fifoCode.getId())
.scanCount(IntUtil.value(fifoCode.getScanCount()) - 1)
.totalCount(IntUtil.value(fifoCode.getTotalCount()) - codesPerScan)
.build());
processedScans++;
if (totalProcessedCount >= requiredCount) {
isTargetReached = true;
break;
}
}
if (isTargetReached) {
if (processedScans == fifoCode.getScanCount()) {
idsToRemove.add(fifoCode.getId());
}
break;
}
}
// Batch operations
if (!idsToRemove.isEmpty()) {
splitFifoCodeService.removeByIds(idsToRemove);
}
if (!splitCodesToAdd.isEmpty()) {
splitCodeMapper.insertBatch(splitCodesToAdd);
}
return totalProcessedCount;
}
private void updateInventory(IoSplitFifoInv inventory, Integer processedCount) {
inventory.setOutCount(IntUtil.value(inventory.getOutCount()) + IntUtil.value(processedCount));
int lockCount = IntUtil.value(inventory.getLockCount()) - IntUtil.value(processedCount);
inventory.setLockCount(lockCount > 0 ? lockCount : 0);
inventory.setReCount(IntUtil.value(inventory.getInCount()) - IntUtil.value(inventory.getOutCount()));
inventory.setAvailableCount(IntUtil.value(inventory.getInCount()) - IntUtil.value(inventory.getLockCount()) - IntUtil.value(inventory.getOutCount()));
}
//包装拆包失效时间
void decorateUnpackExpireTime(IoSplitCodeEntity ioSplitCodeEntity) {
Long relId = ioSplitCodeEntity.getRelId();
UdiRelevanceEntity relevanceEntity = udiRelevanceService.getById(relId);
int n = IntUtil.value(relevanceEntity.getUnpackUseTime());
// 获取当前时间
Calendar calendar = Calendar.getInstance();
Date unpackTime = calendar.getTime();
// 加上n小时
calendar.add(Calendar.HOUR_OF_DAY, n);
// 转换为Date对象
Date unpackExpireTime = calendar.getTime();
ioSplitCodeEntity.setUnpackTime(unpackTime);
ioSplitCodeEntity.setUnpackExpireTime(unpackExpireTime);
}
public List<IoSplitCodeEntity> findSplitCodes(Long relId, String batchNo, Long workPlaceCode) {
List<IoSplitCodeEntity> ioSplitCodeEntities = splitCodeMapper.selectList(new LambdaQueryWrapper<IoSplitCodeEntity>()
.eq(IoSplitCodeEntity::getRelId, relId)
.eq(StrUtil.isNotEmpty(batchNo), IoSplitCodeEntity::getBatchNo, batchNo)
.eq(workPlaceCode != null, IoSplitCodeEntity::getWorkPlaceCode, workPlaceCode)
.gt(IoSplitCodeEntity::getRemainCount, 0)
.in(IoSplitCodeEntity::getStatus, 1, 2).orderByAsc(IoSplitCodeEntity::getInBactchNo));
return ioSplitCodeEntities;
}
public List<IoSplitCodeEntity> findSplitCodes(List<Long> relIds, String batchNo, Long workPlaceCode) {
List<IoSplitCodeEntity> ioSplitCodeEntities = splitCodeMapper.selectList(new LambdaQueryWrapper<IoSplitCodeEntity>()
.in(IoSplitCodeEntity::getRelId, relIds)
.eq(StrUtil.isNotEmpty(batchNo), IoSplitCodeEntity::getBatchNo, batchNo)
.eq(workPlaceCode != null, IoSplitCodeEntity::getWorkPlaceCode, workPlaceCode)
.gt(IoSplitCodeEntity::getRemainCount, 0)
.in(IoSplitCodeEntity::getStatus, 1, 2).orderByAsc(IoSplitCodeEntity::getInBactchNo));
return ioSplitCodeEntities;
}
public List<IoCollectOrderCodeMan> filterCode
(List<IoCollectOrderCodeMan> collectOrderCodes, IoCollectOrderBiz collectOrderBiz, UdiRelevanceResponse
udiRelevanceResponse) {
int unTagCount = IntUtil.value(collectOrderBiz.getScanActCount()) - collectOrderBiz.getCount();
List<IoCollectOrderCodeMan> newList = new ArrayList<IoCollectOrderCodeMan>();
int count = 0;
boolean first = true;
for (IoCollectOrderCodeMan collectOrderCode : collectOrderCodes) {
if (collectOrderCode.getBizIdFk().equals(collectOrderBiz.getId())) {
if (IntUtil.value(collectOrderCode.getIsSplitCode())) {
if (first) {
int remainder = unTagCount % IntUtil.value(udiRelevanceResponse.getBhsycjsl());
collectOrderCode.setRemainCount(remainder);
first = false;
} else {
collectOrderCode.setRemainCount(collectOrderCode.getScanActCount());
}
newList.add(collectOrderCode);
} else {
count = count + collectOrderCode.getScanActCount();
if (!IntUtil.value(collectOrderCode.getRemoveFlag())) {
if (count > collectOrderBiz.getCount()) {
if (first) {
int remainder = unTagCount % IntUtil.value(udiRelevanceResponse.getBhsycjsl());
collectOrderCode.setRemainCount(remainder);
first = false;
} else {
collectOrderCode.setRemainCount(collectOrderCode.getScanActCount());
}
newList.add(collectOrderCode);
}
}
}
}
}
return newList;
}
}