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.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.github.pagehelper.PageHelper; 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.inout.IoSplitCodeRequest; 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.*; import java.util.stream.Collectors; @Service public class IoSplitCodeService extends ServiceImpl { @Resource IoSplitCodeMapper splitCodeMapper; @Resource IoSplitFifoCodeService splitFifoCodeService; @Resource IoCollectOrderBizService collectOrderBizService; @Resource IoCollectOrderCodeAutoService collectOrderCodeAutoService; public List filterList(IoSplitCodeRequest splitCodeRequest) { if (splitCodeRequest == null) { return Collections.emptyList(); } if (splitCodeRequest.getPage() != null) { int offset = (splitCodeRequest.getPage() - 1) * splitCodeRequest.getLimit(); PageHelper.offsetPage(offset, splitCodeRequest.getLimit()); } return super.baseMapper.filterList(splitCodeRequest); } public List findSplitCodes(Long relId, String batchNo, Long workPlaceCode) { List ioSplitCodeEntities = splitCodeMapper.selectList(new LambdaQueryWrapper() .eq(IoSplitCodeEntity::getRelId, relId) .eq(StrUtil.isNotEmpty(batchNo), IoSplitCodeEntity::getBatchNo, batchNo) .eq(workPlaceCode != null, IoSplitCodeEntity::getWorkPlaceCode, workPlaceCode) .in(IoSplitCodeEntity::getStatus, 1, 2).orderByAsc(IoSplitCodeEntity::getInBactchNo)); return ioSplitCodeEntities; } public IoSplitCodeEntity findByCode(String code, Long workPlaceCode, String busType) { List ioSplitCodeEntities = splitCodeMapper.selectList(new LambdaQueryWrapper() .eq(IoSplitCodeEntity::getCode, code) .eq(workPlaceCode != null, IoSplitCodeEntity::getWorkPlaceCode, workPlaceCode) .in(IoSplitCodeEntity::getStatus, 1, 2).orderByAsc(IoSplitCodeEntity::getInBactchNo)); if (CollUtil.isNotEmpty(ioSplitCodeEntities)) return ioSplitCodeEntities.get(0); return null; } public void splitRemove(IoCollectOrderBiz collectOrderBiz, IoCollectOrder collectOrder) { //1.按照先进先出原则,查询拆零表,获取拆零表ID List ioSplitCodeEntities = findSplitCodes(collectOrderBiz.getRelId(), collectOrderBiz.getBatchNo(), collectOrder.getWorkPlaceCode()); //2.如果拆零表为空,则自动从预出库队列中获拉取数据 if (CollUtil.isEmpty(ioSplitCodeEntities)) { addFifoCode(collectOrderBiz.getRelId(), collectOrderBiz.getBatchNo(), IntUtil.value(collectOrderBiz.getCount())); ioSplitCodeEntities = findSplitCodes(collectOrderBiz.getRelId(), collectOrderBiz.getBatchNo(), collectOrder.getWorkPlaceCode()); } //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(collectOrderBiz.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(collectOrderBiz.getRelId(), collectOrderBiz.getBatchNo(), unCount); if (fifoCount == 0) { //预出库队列数量不足 collectOrderBiz.setTagStatus(2); collectOrderBiz.setTagMsg("预出库队列码数量不足,赋码失败!"); return; // throw new JsonException(500, "提交失败,工位库存数量不足!"); } else { //再次执行赋码 ioSplitCodeEntities = findSplitCodes(collectOrderBiz.getRelId(), collectOrderBiz.getBatchNo(), collectOrder.getWorkPlaceCode()); 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(collectOrderBiz.getRelId()) .bizIdFk(collectOrderBiz.getId()) .fifoSplit(ioSplitCodeEntity.getFifoSplit()) .createTime(new Date()) .updateTime(new Date()) .build()); if (count > 0) { ioSplitCodeEntity.setRemainCount(count); break; } else if (count == 0) { ioSplitCodeEntity.setRemainCount(0); } else { ioSplitCodeEntity.setRemainCount(0); unCount = -count; } } if (unCount > 0) { collectOrderBiz.setTagStatus(2); collectOrderBiz.setTagMsg("预出库队列码数量不足,赋码失败!"); return; // throw new JsonException(500, "提交失败,工位库存数量不足!"); } else { collectOrderBiz.setTagStatus(3); collectOrderBiz.setTagMsg("赋码完成!"); } } } else { collectOrderBiz.setTagStatus(3); collectOrderBiz.setTagMsg("赋码完成!"); } collectOrderBiz.setUnTagCount(unCount); collectOrderBizService.updateById(collectOrderBiz); } @Resource UdiRelevanceService udiRelevanceService; @Resource IoCollectOrderCodeManService collectOrderCodeManService; @Resource IoSplitCodeService splitCodeService; @Resource IoCollectOrderBizBackupService ioCollectOrderBizBackupService; @Transactional(rollbackFor = Exception.class) public void finishAutoTagCode(IoCollectOrder collectOrder) { SysWorkplacePutRel sysWorkplacePutRel = workplacePutRelService.findPutWorkPlace(collectOrder.getWorkPlaceCode(), collectOrder.getBusType()); Long putWorkPlaceCode = null; if (sysWorkplacePutRel != null) putWorkPlaceCode = sysWorkplacePutRel.getWorkPlaceCode(); List collectOrderBizs = collectOrderBizService.listByBillNo(collectOrder.getBillNo()); //如果手动扫码判断该码是否在队列里,如果已在队列,则队列里剔除 List 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()); int removeCount = IntUtil.value(collectOrderCodeMan.getScanCount()) * udiRelevanceEntity.getUseLeverCount(); 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); splitFifoInv.setLockCount(IntUtil.value(splitFifoInv.getLockCount()) - removeCount); 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); } } } } } List removeIds = new ArrayList<>(); for (IoCollectOrderBiz collectOrderBiz : collectOrderBizs) { UdiRelevanceEntity udiRelevanceEntity = udiRelevanceService.selectById(collectOrderBiz.getRelId()); //去除掉已经手动扫码的数据,找出需要自动扫码的明细,执行上述的拆零或整取 int unTagCount = collectOrderBiz.getCount() - IntUtil.value(collectOrderBiz.getScanActCount()); if (unTagCount > 0) { collectOrderBiz.setUnTagCount(unTagCount); } else { collectOrderBiz.setTagStatus(3); //手动扫码时涉及到拆零时,把拆零剩余数量插入至拆零表里 if (unTagCount < 0) { if (IntUtil.value(udiRelevanceEntity.getUseLeverCount()) > -unTagCount) { Optional firstMatch = collectOrderCodeMEN.stream() .filter(item -> IntUtil.value(item.getRemoveFlag()) && item.getBizIdFk().equals(collectOrderBiz.getId())) .findFirst(); if (firstMatch.isPresent()) { IoCollectOrderCodeMan result = firstMatch.get(); IoSplitCodeEntity ioSplitCodeEntity = IoSplitCodeEntity.builder().code(result.getUdiCode()) .errUdiCode(result.getUdiCode()) .orderId(result.getOrderIdFk()) .action(collectOrder.getBusType()) .relId(result.getRelId()) .nameCode(result.getNameCode()) .batchNo(result.getBatchNo()) .produceDate(result.getProductDate()) .expireDate(result.getExpireDate()) .serialNo(result.getSerialNo()) .scanCount(result.getScanCount()) .totalCount(result.getScanCount()) .workPlaceCode(putWorkPlaceCode) .status(2) .fifoSplit(1) .createTime(new Date()).updateTime(new Date()) .remainCount(-unTagCount).build(); splitCodeService.save(ioSplitCodeEntity); } } } continue; } int quotient = collectOrderBiz.getUnTagCount() / IntUtil.value(udiRelevanceEntity.getUseLeverCount()); int remainder = collectOrderBiz.getUnTagCount() % IntUtil.value(udiRelevanceEntity.getUseLeverCount()); //2.如果整盒,从工位队列扣除 if (quotient > 0) { List ioSplitFifoCodeEntities = splitFifoCodeService.findByRelId(putWorkPlaceCode, collectOrderBiz.getRelId(), collectOrderBiz.getBatchNo()); if (ioSplitFifoCodeEntities.size() < quotient) { return; // throw new JsonException(500, "提交失败,工位库存数量不足!"); } for (int i = 0; i < quotient; i++) { IoSplitFifoCodeEntity splitFifoCodeEntity = ioSplitFifoCodeEntities.get(i); removeIds.add(splitFifoCodeEntity.getId()); collectOrderBiz.setUnTagCount(IntUtil.value(collectOrderBiz.getUnTagCount()) - IntUtil.value(udiRelevanceEntity.getUseLeverCount())); collectOrderCodeAutoService.save(IoCollectOrderCodeAuto.builder() .codeIdFk(splitFifoCodeEntity.getId()) .udiCode(splitFifoCodeEntity.getCode()) .orderIdFk(collectOrder.getBillNo()) .batchNo(splitFifoCodeEntity.getBatchNo()) .productDate(splitFifoCodeEntity.getProduceDate()) .expireDate(splitFifoCodeEntity.getExpireDate()) .serialNo(splitFifoCodeEntity.getSerialNo()) .relId(collectOrderBiz.getRelId()) .bizIdFk(collectOrderBiz.getId()) .fifoSplit(splitFifoCodeEntity.getFifoSplit()) .createTime(new Date()) .updateTime(new Date()) .build()); } } //.如果拆零,拆零表扣除 if (remainder > 0) { splitRemove(collectOrderBiz, collectOrder); } } ArrayList ioCollectOrderBizBackups = new ArrayList<>(); for (IoCollectOrderBiz ioCollectOrderBiz : collectOrderBizs) { IoCollectOrderBizBackup ioCollectOrderBizBackup = new IoCollectOrderBizBackup(); BeanUtils.copyProperties(ioCollectOrderBiz, ioCollectOrderBizBackup); ioCollectOrderBizBackups.add(ioCollectOrderBizBackup); } ioCollectOrderBizBackupService.saveBatch(ioCollectOrderBizBackups); } @Resource IoSplitFifoInvRelService splitFifoInvRelService; public List findInvIdFk(IoCollectOrder collectOrder) { List ioSplitFifoInvRels = splitFifoInvRelService.findInvIdFk(collectOrder.getWorkPlaceCode(), collectOrder.getBusType()); if (CollUtil.isNotEmpty(ioSplitFifoInvRels)) { return ioSplitFifoInvRels.stream() .map(IoSplitFifoInvRel::getInvIdFk) .collect(Collectors.toList()); } else return null; } @Resource SysWorkplacePutRelService workplacePutRelService; /** * 单据预赋码 * * @param collectOrder */ public void preAutoTagCode(IoCollectOrder collectOrder) { Long putWorkPlaceCode = null; //获取上货工位 SysWorkplacePutRel sysWorkplacePutRel = workplacePutRelService.findPutWorkPlace(collectOrder.getWorkPlaceCode(), collectOrder.getBusType()); if (sysWorkplacePutRel == null) putWorkPlaceCode = sysWorkplacePutRel.getCollectWorkCode(); List collectOrderBizs = collectOrderBizService.listByBillNo(collectOrder.getBillNo()); for (IoCollectOrderBiz collectOrderBiz : collectOrderBizs) { List splitFifoCodeEntities = splitFifoCodeService.findByRelId(putWorkPlaceCode, collectOrderBiz.getRelId(), collectOrderBiz.getBatchNo()); int total = splitFifoCodeEntities.stream() .mapToInt(IoSplitFifoCodeEntity::getTotalCount) .sum(); collectOrderBiz.setTempWorkPlaceCount(total); List splitCodeEntities = splitCodeService.findSplitCodes(collectOrderBiz.getRelId() , collectOrderBiz.getBatchNo(), sysWorkplacePutRel.getWorkPlaceCode()); int splitTotal = splitCodeEntities.stream() .mapToInt(IoSplitCodeEntity::getRemainCount) .sum(); collectOrderBiz.setTempSplitCount(splitTotal); total = total + splitTotal; if (total >= IntUtil.value(collectOrderBiz.getCount())) { collectOrderBiz.setAutoTagStatus(2); } else if (total > 0) { collectOrderBiz.setAutoTagStatus(3); } else collectOrderBiz.setAutoTagStatus(1); } collectOrderBizService.updateBatchById(collectOrderBizs); } /** * 拆零单据撤回,则将拆零表剩余数量加回预出库队列 * * @param collectOrder */ public void backSplit(IoCollectOrder collectOrder) { List collectOrderBizs = collectOrderBizService.listByBillNo(collectOrder.getBillNo()); for (IoCollectOrderBiz collectOrderBiz : collectOrderBizs) { List ioSplitCodeEntities = findSplitCodes(collectOrderBiz.getRelId(), collectOrderBiz.getBatchNo(), collectOrder.getWorkPlaceCode()); if (CollUtil.isNotEmpty(ioSplitCodeEntities)) { IoSplitCodeEntity splitCodeEntity = ioSplitCodeEntities.get(0); splitCodeEntity.setRemainCount(IntUtil.value(splitCodeEntity.getRemainCount()) + (IntUtil.value(collectOrderBiz.getCount()) - IntUtil.value(collectOrderBiz.getUnTagCount()))); splitCodeMapper.updateById(splitCodeEntity); } } } @Resource IoSplitFifoInvService splitFifoInvService; /** * 从预出库队列里面取出数据,添加至拆零表 */ public Integer addFifoCode(Long relId, String batchNo, Integer needCount) { List splitFifoCodeEntities = splitFifoCodeService .list(new LambdaQueryWrapper() .eq(IoSplitFifoCodeEntity::getRelId, relId) .eq(StrUtil.isNotEmpty(batchNo), IoSplitFifoCodeEntity::getBatchNo, batchNo) .orderByAsc(IoSplitFifoCodeEntity::getInBactchNo) ); Integer count = 0; List addSplitCodeEntities = new ArrayList<>(); List removeIds = new ArrayList<>(); for (IoSplitFifoCodeEntity splitFifoCodeEntity : splitFifoCodeEntities) { IoSplitCodeEntity splitCodeEntity = new IoSplitCodeEntity(); BeanUtils.copyProperties(splitFifoCodeEntity, splitCodeEntity); if (IntUtil.value(splitFifoCodeEntity.getFifoSplit()) == 1) { //拆零 count = IntUtil.value(splitFifoCodeEntity.getTotalCount()) + count; splitCodeEntity.setRemainCount(splitCodeEntity.getTotalCount()); } else { //整取 count = IntUtil.value(splitFifoCodeEntity.getScanCount()) + count; splitCodeEntity.setRemainCount(splitCodeEntity.getScanCount()); } splitCodeEntity.setStatus(1); splitCodeEntity.setFifoSplit(splitFifoCodeEntity.getFifoSplit()); splitCodeEntity.setId(null); addSplitCodeEntities.add(splitCodeEntity); removeIds.add(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); } if (count >= needCount) { break; } } if (removeIds.size() > 0) { splitFifoCodeService.removeByIds(removeIds); } if (addSplitCodeEntities.size() > 0) { splitCodeMapper.insertBatch(addSplitCodeEntities); } return count; } public int checkStatus(List list) { boolean hasTwo = false; boolean hasOne = false; boolean hasNone = true; for (IoCollectOrderBiz di : list) { int tagStatus = di.getTagStatus(); if (tagStatus == 2) { hasTwo = true; } else if (tagStatus == 1) { hasOne = true; } else if (tagStatus != 3) { throw new IllegalArgumentException("Invalid tagStatus value: " + tagStatus); } } for (IoCollectOrderBiz di : list) { if (IntUtil.value(di.getCount()) != IntUtil.value(di.getUnTagCount())) { hasNone = false; break; } } if (hasNone) { return 1; } if (hasTwo) { return 2; } else if (hasOne) { return 1; } else { return 3; } } }