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.auth.SysWorkplaceDao; import com.glxp.api.dao.collect.IoCollectOrderBizMapper; import com.glxp.api.dao.collect.IoCollectOrderMapper; import com.glxp.api.dao.inout.IoSplitFifoCodeMapper; import com.glxp.api.dao.inout.IoSplitFifoInvMapper; import com.glxp.api.entity.auth.SysWorkplace; import com.glxp.api.entity.basic.UdiRelevanceEntity; 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.collect.CollectOrderBizRequest; import com.glxp.api.req.collect.CollectOrderRequest; import com.glxp.api.req.dev.DeviceChangeOrderParam; import com.glxp.api.req.inout.IoSplitFifoCodeRequest; import com.glxp.api.req.inout.IoSplitFifoInvRequest; import com.glxp.api.res.collect.CollectOrderBizResponse; import com.glxp.api.res.collect.IoCollectOrderResponse; import com.glxp.api.res.inout.IoSplitCodeResponse; import com.glxp.api.res.inout.IoSplitInvResponse; import com.glxp.api.service.auth.SysWorkplaceService; import io.swagger.models.auth.In; 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 IoSplitFifoCodeService extends ServiceImpl { @Resource IoSplitFifoCodeMapper splitFifoCodeMapper; @Resource IoSplitFifoInvService splitFifoInvService; @Resource SysWorkplaceService sysWorkplaceService; @Resource IoCollectOrderMapper collectOrderMapper; @Resource IoCollectOrderBizMapper collectOrderBizMapper; public List filterGroupList(IoSplitFifoCodeRequest splitFifoCodeRequest) { if (splitFifoCodeRequest == null) { return Collections.emptyList(); } if (splitFifoCodeRequest.getPage() != null) { int offset = (splitFifoCodeRequest.getPage() - 1) * splitFifoCodeRequest.getLimit(); PageHelper.offsetPage(offset, splitFifoCodeRequest.getLimit()); } return super.baseMapper.filterGroupList(splitFifoCodeRequest); } public List filterList(IoSplitFifoCodeRequest splitFifoCodeRequest) { if (splitFifoCodeRequest == null) { return Collections.emptyList(); } if (splitFifoCodeRequest.getPage() != null) { int offset = (splitFifoCodeRequest.getPage() - 1) * splitFifoCodeRequest.getLimit(); PageHelper.offsetPage(offset, splitFifoCodeRequest.getLimit()); } return super.baseMapper.filterList(splitFifoCodeRequest); } public Boolean isExitCode(String code, Long workPlaceCode) { return splitFifoCodeMapper.exists( new LambdaQueryWrapper() .eq(IoSplitFifoCodeEntity::getCode, code) .eq(workPlaceCode != null, IoSplitFifoCodeEntity::getWorkPlaceCode, workPlaceCode) ); } public IoSplitFifoCodeEntity findByCode(String code, Long workPlaceCode) { return splitFifoCodeMapper.selectOne( new LambdaQueryWrapper() .eq(IoSplitFifoCodeEntity::getCode, code) .eq(workPlaceCode != null, IoSplitFifoCodeEntity::getWorkPlaceCode, workPlaceCode) .last("limit 1") ); } /** * 库存量提醒 * * @param workPlaceCode * @return */ public String findInvRemind(Long workPlaceCode) { final String[] msg = {"当前工位存量提醒:"}; SysWorkplace workplace = sysWorkplaceService.getWorkplace(workPlaceCode); if (workplace == null) throw new JsonException("未找到匹配工位"); //获取工位下的库存 IoSplitFifoInvRequest ioSplitFifoInvRequest = new IoSplitFifoInvRequest(); ioSplitFifoInvRequest.setWorkPlaceCode(workPlaceCode); List ioSplitInvResponses = splitFifoInvService.filterList(ioSplitFifoInvRequest); if (CollUtil.isEmpty(ioSplitInvResponses)) { return "当前工位存量提醒:" + "0"; } ioSplitInvResponses.forEach(item -> { Boolean enableRemind = item.getEnableRemind(); if (enableRemind){ Integer reCount = item.getReCount(); Integer invRemindCount = item.getInvRemindCount(); if (reCount < invRemindCount) { String cpmctymc = item.getCpmctymc(); String batchNo = item.getBatchNo(); if (StrUtil.isBlank(batchNo)) { msg[0] = msg[0] + cpmctymc + "存量为:" + reCount+";"; } else { msg[0] = msg[0] + cpmctymc + "[" + batchNo + "]存量为:" + reCount+";"; } } } }); return msg[0]; } /** * 获取当前工位下的带处理单据 是否库存足够 * * @param workPaceCode * @return */ public String findInvRemindByBillNo(Long workPaceCode) { final String[] msg = {"库存预警提醒:"}; if (workPaceCode == null || workPaceCode == 0l) return msg[0]; //2.遍历当前工位待处理的单据,根据orderTime排序 CollectOrderRequest collectOrderRequest = new CollectOrderRequest(); collectOrderRequest.setWorkPlaceCode(workPaceCode); collectOrderRequest.setTagStatus(1); List orderList = collectOrderMapper.filterList(collectOrderRequest); if (CollUtil.isEmpty(orderList)) return msg[0]; orderList.forEach(item -> { Integer invAlert = item.getInvAlert(); if (invAlert == 1) { msg[0] = msg[0] + item.getBillNo() + ":正常; "; } else if (invAlert == 2) { msg[0] = msg[0] + item.getBillNo() + ":不足; "; } }); return msg[0]; } /** * 通过 单据 锁定库存 * lockType 1 上锁 2释放锁 * 1、成功 返回true * 2、失败 返回false */ @Transactional(rollbackFor = Exception.class) public boolean lockInventoryByOrder(String billNo,Integer lockType){ if (StrUtil.isEmpty(billNo)) throw new JsonException("单据号不可以为空!"); //1、获取该单据信息 CollectOrderRequest collectOrderRequest = new CollectOrderRequest(); collectOrderRequest.setBillNo(billNo); List orderList = collectOrderMapper.filterList(collectOrderRequest); if (CollUtil.isEmpty(orderList)) throw new JsonException("未找到对应的单据!"); IoCollectOrderResponse order = orderList.get(0); Integer invAlert1 = order.getInvAlert(); if (lockType == 1){ if (invAlert1 == 1) throw new JsonException("该单据已锁定库存过请勿重复锁定!"); }else if (lockType == 2){ if (invAlert1 != 1) throw new JsonException("该单据未正常锁定库存过不可进行解锁库存操作!"); } //2、获取该单据下的biz明细 CollectOrderBizRequest bizRequest = new CollectOrderBizRequest(); bizRequest.setOrderIdFk(String.valueOf(order.getBillNo())); List bizList = collectOrderBizMapper.filterList(bizRequest); if (CollUtil.isEmpty(bizList)) throw new JsonException("未找到对应的单据明细!"); //3、获取当前工位的下库存数 Long workPlaceCode = order.getWorkPlaceCode(); IoSplitFifoInvRequest ioSplitFifoInvRequest = new IoSplitFifoInvRequest(); ioSplitFifoInvRequest.setWorkPlaceCode(workPlaceCode); List ioSplitInvResponses = splitFifoInvService.filterList(ioSplitFifoInvRequest); if (CollUtil.isEmpty(ioSplitInvResponses)) return false; Map> splitInvMap = ioSplitInvResponses.stream().collect(Collectors.groupingBy(IoSplitInvResponse::getRelId)); if (CollUtil.isNotEmpty(bizList)) { if (lockType == 1){ //自动分配 工位存量、更新splitMap、更新 bizList上的 缺少存量数 Integer invAlert = autoAllocationBillNoInv(splitInvMap, bizList); collectOrderMapper.updateInvAlert(order.getId(), invAlert); if (invAlert == 2){ return false; }else { return true; } }else if (lockType == 2){ unAutoAllocationBillNoInv(splitInvMap, bizList); collectOrderMapper.updateInvAlert(order.getId(), 3); } } return true; } // /** // * 预分配库存 // */ // @Transactional(rollbackFor = Exception.class) // public void preAllotInv(Long workPaceCode) { // if (workPaceCode == null || workPaceCode == 0l) return; // // //1. 查询出当前工位的未分配的库存 // IoSplitFifoCodeRequest splitFifoCodeRequest = new IoSplitFifoCodeRequest(); // splitFifoCodeRequest.setWorkPlaceCode(workPaceCode); // List ioSplitCodeResponses = this.baseMapper.filterGroupList(splitFifoCodeRequest); // if (CollUtil.isEmpty(ioSplitCodeResponses)) return; // Map> splitMap = ioSplitCodeResponses.stream().collect(Collectors.groupingBy(IoSplitCodeResponse::getRelId)); // // //2.遍历当前工位待处理的单据,根据orderTime排序 // CollectOrderRequest collectOrderRequest = new CollectOrderRequest(); // collectOrderRequest.setWorkPlaceCode(workPaceCode); // collectOrderRequest.setTagStatus(1); // List orderList = collectOrderMapper.filterList(collectOrderRequest); // if (CollUtil.isEmpty(orderList)) return; // // //3.为每个单据底下的单据详情分配数量 // for (int i = 0; i < orderList.size(); i++) { // IoCollectOrderResponse order = orderList.get(i); // CollectOrderBizRequest bizRequest = new CollectOrderBizRequest(); // bizRequest.setOrderIdFk(String.valueOf(order.getBillNo())); // List bizList = collectOrderBizMapper.filterList(bizRequest); // if (CollUtil.isNotEmpty(bizList)) { // //自动分配 工位存量、更新splitMap、更新 bizList上的 缺少存量数 // Integer invAlert = autoAllocationWorkPace(splitMap, bizList); // collectOrderMapper.updateInvAlert(order.getId(), invAlert); // } // } // // } // /** // * 自动分配 工位存量、更新splitMap、更新 bizList上的 缺少存量数 // * // * @param splitMap // * @param bizList // */ // @Transactional(rollbackFor = Exception.class) // Integer autoAllocationWorkPace(Map> splitMap, List bizList) { // Integer invAlert = 1; // for (int i = 0; i < bizList.size(); i++) { // CollectOrderBizResponse collectOrderBizResponse = bizList.get(i); // Long relId = collectOrderBizResponse.getRelId(); // String batchNo = collectOrderBizResponse.getBatchNo(); // Integer count = collectOrderBizResponse.getCount(); //当前明细 需要的数量 // Long bizId = collectOrderBizResponse.getId(); // // List ioSplitCodeResponses = splitMap.get(relId); // List newioSplitCodeResponses = new ArrayList<>(ioSplitCodeResponses.size()); // // if (CollUtil.isNotEmpty(ioSplitCodeResponses)) { // for (int j = 0; j < ioSplitCodeResponses.size(); j++) { // IoSplitCodeResponse ioSplit = ioSplitCodeResponses.get(j); // Integer totalCount = ioSplit.getTotalCount(); // if ((StrUtil.isBlank(batchNo) || batchNo.equals(ioSplit.getBatchNo())) && count > 0 && totalCount > 0) { // Integer resCount = totalCount - count;//预分配后剩余 工位存量 // if (resCount >= 0) {//足够分配 // count = 0; // ioSplit.setTotalCount(resCount); // } else {//不够分配 // count = -resCount; // ioSplit.setTotalCount(0); // } // } // newioSplitCodeResponses.add(ioSplit); // } // // splitMap.put(relId, newioSplitCodeResponses); // } // // if (count > 0) {//不够分配 // collectOrderBizMapper.updateAutoResCount(bizId, -count); // invAlert = 2; // } else { // collectOrderBizMapper.updateAutoResCount(bizId, collectOrderBizResponse.getCount()); // } // } // // return invAlert; // } @Transactional(rollbackFor = Exception.class) Integer autoAllocationBillNoInv(Map> splitMap, List bizList) { Integer invAlert = 1; List updateIoSplitFifoInv = new ArrayList<>(); for (int i = 0; i < bizList.size(); i++) { CollectOrderBizResponse collectOrderBizResponse = bizList.get(i); Long relId = collectOrderBizResponse.getRelId(); String batchNo = collectOrderBizResponse.getBatchNo(); Integer count = collectOrderBizResponse.getCount(); //当前明细 需要的数量 Long bizId = collectOrderBizResponse.getId(); List ioSplitInvResponses = splitMap.get(relId); List newioSplitCodeResponses = new ArrayList<>(ioSplitInvResponses.size()); if (CollUtil.isNotEmpty(newioSplitCodeResponses)) { for (int j = 0; j < newioSplitCodeResponses.size(); j++) { IoSplitInvResponse ioSplit = newioSplitCodeResponses.get(j); Integer reCount = ioSplit.getReCount(); Integer lockCount = ioSplit.getLockCount(); Integer totalCount = reCount-lockCount;//剩余可分配数量 if ((StrUtil.isBlank(batchNo) || batchNo.equals(ioSplit.getBatchNo())) && count > 0 && totalCount > 0) { Integer resCount = totalCount - count;//预分配后剩余 工位存量 if (resCount >= 0) {//足够分配 count = 0; ioSplit.setLockCount( lockCount + count ); IoSplitFifoInv bean = new IoSplitFifoInv(); BeanUtils.copyProperties(ioSplit,bean); updateIoSplitFifoInv.add(bean); } else {//不够分配 count = -resCount; } } newioSplitCodeResponses.add(ioSplit); } splitMap.put(relId, newioSplitCodeResponses); } if (count > 0) {//不够分配 collectOrderBizMapper.updateAutoResCount(bizId, -count); invAlert = 2; } else { collectOrderBizMapper.updateAutoResCount(bizId, collectOrderBizResponse.getCount()); } } if (CollUtil.isNotEmpty(updateIoSplitFifoInv)){ splitFifoInvService.updateBatchById(updateIoSplitFifoInv); } return invAlert; } @Transactional(rollbackFor = Exception.class) void unAutoAllocationBillNoInv(Map> splitMap, List bizList) { List updateIoSplitFifoInv = new ArrayList<>(); for (int i = 0; i < bizList.size(); i++) { CollectOrderBizResponse collectOrderBizResponse = bizList.get(i); Long relId = collectOrderBizResponse.getRelId(); String batchNo = collectOrderBizResponse.getBatchNo(); Integer count = collectOrderBizResponse.getCount(); //当前明细 需要的数量 Long bizId = collectOrderBizResponse.getId(); List ioSplitInvResponses = splitMap.get(relId); List newioSplitCodeResponses = new ArrayList<>(ioSplitInvResponses.size()); if (CollUtil.isNotEmpty(newioSplitCodeResponses)) { for (int j = 0; j < newioSplitCodeResponses.size(); j++) { IoSplitInvResponse ioSplit = newioSplitCodeResponses.get(j); Integer lockCount = ioSplit.getLockCount(); if ((StrUtil.isBlank(batchNo) || batchNo.equals(ioSplit.getBatchNo())) && count > 0 ) { ioSplit.setLockCount( lockCount - count ); IoSplitFifoInv bean = new IoSplitFifoInv(); BeanUtils.copyProperties(ioSplit,bean); updateIoSplitFifoInv.add(bean); } newioSplitCodeResponses.add(ioSplit); } splitMap.put(relId, newioSplitCodeResponses); } collectOrderBizMapper.updateAutoResCount(bizId, 0); } if (CollUtil.isNotEmpty(updateIoSplitFifoInv)){ splitFifoInvService.updateBatchById(updateIoSplitFifoInv); } } }