|  |  |  | 
|---|
|  |  |  | package com.vincent.rsf.server.manager.service.impl; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | 
|---|
|  |  |  | import com.vincent.rsf.framework.common.R; | 
|---|
|  |  |  | import com.vincent.rsf.framework.exception.CoolException; | 
|---|
|  |  |  | import com.vincent.rsf.server.api.controller.params.TaskInParam; | 
|---|
|  |  |  | import com.vincent.rsf.server.api.controller.erp.params.TaskInParam; | 
|---|
|  |  |  | import com.vincent.rsf.server.api.entity.dto.InTaskMsgDto; | 
|---|
|  |  |  | import com.vincent.rsf.server.api.service.WcsService; | 
|---|
|  |  |  | import com.vincent.rsf.server.api.utils.LocUtils; | 
|---|
|  |  |  | import com.vincent.rsf.server.common.constant.Constants; | 
|---|
|  |  |  | import com.vincent.rsf.server.manager.controller.params.CheckLocQueryParams; | 
|---|
|  |  |  | import com.vincent.rsf.server.manager.controller.params.LocToTaskParams; | 
|---|
|  |  |  | import com.vincent.rsf.server.manager.entity.*; | 
|---|
|  |  |  | import com.vincent.rsf.server.manager.enums.*; | 
|---|
|  |  |  | 
|---|
|  |  |  | private WcsService wcsService; | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private OutStockService outStockService; | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private WaveService waveService; | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private BasStationService basStationService; | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 库存出库生成出库任务 | 
|---|
|  |  |  | * type: check 盘点, stock: 库存出库 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param resouce | 
|---|
|  |  |  | * @param map | 
|---|
|  |  |  | * @param loginUserId | 
|---|
|  |  |  | * @return | 
|---|
|  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | @Synchronized | 
|---|
|  |  |  | @Transactional(rollbackFor = Exception.class) | 
|---|
|  |  |  | public void generateTask(LocToTaskParams map, Long loginUserId) throws Exception { | 
|---|
|  |  |  | public void generateTask(Short resouce, LocToTaskParams map, Long loginUserId) throws Exception { | 
|---|
|  |  |  | if (Objects.isNull(map.getSiteNo())) { | 
|---|
|  |  |  | throw new CoolException("站点不能为空!"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (Objects.isNull(map.getItems()) || map.getItems().isEmpty()) { | 
|---|
|  |  |  | throw new CoolException("明细不能为空!"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | String siteNo = map.getSiteNo(); | 
|---|
|  |  |  | List<LocItem> items = map.getItems(); | 
|---|
|  |  |  | Map<Long, List<LocItem>> listMap = items.stream().collect(Collectors.groupingBy(LocItem::getLocId)); | 
|---|
|  |  |  | AsnOrder order; | 
|---|
|  |  |  | WkOrder order; | 
|---|
|  |  |  | Wave wave; | 
|---|
|  |  |  | if (!Objects.isNull(map.getSourceId())) { | 
|---|
|  |  |  | order = outStockService.getById(map.getSourceId()); | 
|---|
|  |  |  | if (map.getType().equals(Constants.TASK_TYPE_WAVE_OUT_STOCK)) { | 
|---|
|  |  |  | order = new WkOrder(); | 
|---|
|  |  |  | wave = waveService.getById(map.getSourceId()); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | wave = new Wave(); | 
|---|
|  |  |  | order = outStockService.getById(map.getSourceId()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | order = new AsnOrder(); | 
|---|
|  |  |  | wave = new Wave(); | 
|---|
|  |  |  | order = new WkOrder(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | listMap.keySet().forEach(key -> { | 
|---|
|  |  |  | Task task = new Task(); | 
|---|
|  |  |  | Loc loc = locService.getById(key); | 
|---|
|  |  |  | logger.info("库位:>{}<UNK>", loc.getCode()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | logger.info("库位:>{}", loc.getCode()); | 
|---|
|  |  |  | if (Objects.isNull(loc)) { | 
|---|
|  |  |  | throw new CoolException("数据错误:所选库存信息不存在!!"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (!loc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_F.type)) { | 
|---|
|  |  |  | throw new CoolException("库位:" + loc.getCode() +  ",不处于F.在库状态,不可执行R.出库预约操作!!"); | 
|---|
|  |  |  | throw new CoolException("库位:" + loc.getCode() + ",不处于F.在库状态,不可执行R.出库预约操作!!"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | loc.setUseStatus(LocStsType.LOC_STS_TYPE_R.type); | 
|---|
|  |  |  | 
|---|
|  |  |  | String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_TASK_CODE, null); | 
|---|
|  |  |  | task.setOrgLoc(loc.getCode()) | 
|---|
|  |  |  | .setTaskCode(ruleCode) | 
|---|
|  |  |  | .setResource(resouce) | 
|---|
|  |  |  | .setTargSite(siteNo) | 
|---|
|  |  |  | .setSort(Constants.TASK_SORT_DEFAULT_VALUE) | 
|---|
|  |  |  | .setUpdateBy(loginUserId) | 
|---|
|  |  |  | 
|---|
|  |  |  | .setCreateTime(new Date()) | 
|---|
|  |  |  | .setUpdateTime(new Date()) | 
|---|
|  |  |  | .setTaskStatus(TaskStsType.GENERATE_OUT.id) | 
|---|
|  |  |  | .setBarcode(loc.getBarcode()); | 
|---|
|  |  |  | .setBarcode(loc.getBarcode()) | 
|---|
|  |  |  | .setMemo(map.getMemo()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | List<LocItem> locItems = this.list(new LambdaQueryWrapper<LocItem>().eq(LocItem::getLocId, key)); | 
|---|
|  |  |  | if (locItems.isEmpty()) { | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Double orgQty = locItems.stream().mapToDouble(LocItem::getAnfme).sum(); | 
|---|
|  |  |  | Double workQty = locItems.stream().mapToDouble(LocItem::getWorkQty).sum(); | 
|---|
|  |  |  | List<LocItem> locItemList = listMap.get(key); | 
|---|
|  |  |  | Double outQty = locItemList.stream().mapToDouble(LocItem::getOutQty).sum(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //            Task serviceOne = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getBarcode, loc.getBarcode())); | 
|---|
|  |  |  | //            if (!Objects.isNull(serviceOne)) { | 
|---|
|  |  |  | //                throw new CoolException("托盘任务执行中,不能重复创建!"); | 
|---|
|  |  |  | //            } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (map.getType().equals(Constants.TASK_TYPE_OUT_STOCK) || map.getType().equals(Constants.TASK_TYPE_ORDER_OUT_STOCK)) { | 
|---|
|  |  |  | Double useQty = Math.round((outQty + workQty) * 10000) / 10000.0; | 
|---|
|  |  |  | if (orgQty.compareTo(useQty) > 0) { | 
|---|
|  |  |  | //拣料出库 | 
|---|
|  |  |  | if (map.getType().equals(Constants.TASK_TYPE_OUT_STOCK) | 
|---|
|  |  |  | || map.getType().equals(Constants.TASK_TYPE_ORDER_OUT_STOCK) | 
|---|
|  |  |  | || map.getType().equals(Constants.TASK_TYPE_WAVE_OUT_STOCK)) { | 
|---|
|  |  |  | if (orgQty.compareTo(outQty) > 0) { | 
|---|
|  |  |  | //拣料出库 -- 盘点出库 | 
|---|
|  |  |  | DeviceSite deviceSite = deviceSiteService.getOne(new LambdaQueryWrapper<DeviceSite>() | 
|---|
|  |  |  | .eq(DeviceSite::getSite, siteNo) | 
|---|
|  |  |  | .eq(DeviceSite::getChannel, loc.getChannel()) | 
|---|
|  |  |  | .eq(!Objects.isNull(loc.getChannel()),DeviceSite::getChannel, loc.getChannel()) | 
|---|
|  |  |  | .eq(DeviceSite::getType, TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)); | 
|---|
|  |  |  | if (Objects.isNull(deviceSite)) { | 
|---|
|  |  |  | throw new CoolException("站点不支持拣料出库!!"); | 
|---|
|  |  |  | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | //全板出库 | 
|---|
|  |  |  | DeviceSite deviceSite = deviceSiteService.getOne(new LambdaQueryWrapper<DeviceSite>() | 
|---|
|  |  |  | .eq(DeviceSite::getChannel, loc.getChannel()) | 
|---|
|  |  |  | .eq(!Objects.isNull(loc.getChannel()), DeviceSite::getChannel, loc.getChannel()) | 
|---|
|  |  |  | .eq(DeviceSite::getSite, siteNo).eq(DeviceSite::getType, TaskType.TASK_TYPE_OUT.type)); | 
|---|
|  |  |  | if (Objects.isNull(deviceSite)) { | 
|---|
|  |  |  | throw new CoolException("站点不支持全板出库!!"); | 
|---|
|  |  |  | 
|---|
|  |  |  | } else if (map.getType().equals(Constants.TASK_TYPE_OUT_CHECK)) { | 
|---|
|  |  |  | //盘点出库 | 
|---|
|  |  |  | DeviceSite deviceSite = deviceSiteService.getOne(new LambdaQueryWrapper<DeviceSite>() | 
|---|
|  |  |  | .eq(DeviceSite::getChannel, loc.getChannel()) | 
|---|
|  |  |  | .eq(!Objects.isNull(loc.getChannel()), DeviceSite::getChannel, loc.getChannel()) | 
|---|
|  |  |  | .eq(DeviceSite::getSite, siteNo) | 
|---|
|  |  |  | .eq(DeviceSite::getType, TaskType.TASK_TYPE_CHECK_OUT.type)); | 
|---|
|  |  |  | if (Objects.isNull(deviceSite)) { | 
|---|
|  |  |  | 
|---|
|  |  |  | throw new CoolException("任务创建失败!!"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (!LocUtils.isShallowLoc(loc.getCode())) { | 
|---|
|  |  |  | //获取深库位对应浅库位 | 
|---|
|  |  |  | String shallowLoc = LocUtils.getShallowLoc(loc.getCode()); | 
|---|
|  |  |  | Loc one = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, shallowLoc)); | 
|---|
|  |  |  | if (Objects.isNull(one)) { | 
|---|
|  |  |  | throw new CoolException("对应库位不存在!!"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | Task workTask = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getBarcode, one.getBarcode())); | 
|---|
|  |  |  | if (Objects.isNull(workTask)) { | 
|---|
|  |  |  | map.setOrgLoc(one.getCode()); | 
|---|
|  |  |  | //优先生成移库任务 | 
|---|
|  |  |  | if (one.getUseStatus().equals(LocStsType.LOC_STS_TYPE_F.type)) { | 
|---|
|  |  |  | moveTask = genMoveTask(map, loginUserId); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | workTask.setSort(task.getSort() + 1).setParentId(task.getId()); | 
|---|
|  |  |  | if (!taskService.updateById(workTask)) { | 
|---|
|  |  |  | throw new CoolException("优先级修改失败!!"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //            if (!LocUtils.isShallowLoc(loc.getCode())) { | 
|---|
|  |  |  | //                //获取深库位对应浅库位 | 
|---|
|  |  |  | //                String shallowLoc = LocUtils.getShallowLoc(loc.getCode()); | 
|---|
|  |  |  | //                Loc one = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, shallowLoc)); | 
|---|
|  |  |  | //                if (Objects.isNull(one)) { | 
|---|
|  |  |  | //                    throw new CoolException("对应库位不存在!!"); | 
|---|
|  |  |  | //                } | 
|---|
|  |  |  | //                Task workTask = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getBarcode, one.getBarcode())); | 
|---|
|  |  |  | //                if (Objects.isNull(workTask)) { | 
|---|
|  |  |  | //                    map.setOrgLoc(one.getCode()); | 
|---|
|  |  |  | //                    //优先生成移库任务 | 
|---|
|  |  |  | //                    if (one.getUseStatus().equals(LocStsType.LOC_STS_TYPE_F.type)) { | 
|---|
|  |  |  | //                        moveTask = genMoveTask(map, loginUserId); | 
|---|
|  |  |  | //                    } | 
|---|
|  |  |  | //                } else { | 
|---|
|  |  |  | //                    workTask.setSort(task.getSort() + 1).setParentId(task.getId()); | 
|---|
|  |  |  | //                    if (!taskService.updateById(workTask)) { | 
|---|
|  |  |  | //                        throw new CoolException("优先级修改失败!!"); | 
|---|
|  |  |  | //                    } | 
|---|
|  |  |  | //                } | 
|---|
|  |  |  | //            } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (!Objects.isNull(moveTask.getId())) { | 
|---|
|  |  |  | moveTask.setParentId(task.getId()).setSort(moveTask.getSort() + 1); | 
|---|
|  |  |  | 
|---|
|  |  |  | .setCreateBy(loginUserId) | 
|---|
|  |  |  | .setCreateTime(new Date()) | 
|---|
|  |  |  | .setUpdateTime(new Date()) | 
|---|
|  |  |  | .setOrderType(OrderType.ORDER_OUT.type) | 
|---|
|  |  |  | .setWkType(Short.parseShort(OrderWorkType.ORDER_WORK_TYPE_STOCK_OUT.type)); | 
|---|
|  |  |  | if (map.getType().equals(Constants.TASK_TYPE_ORDER_OUT_STOCK)) { | 
|---|
|  |  |  | .setOrderType(OrderType.ORDER_OUT.type); | 
|---|
|  |  |  | if (map.getType().equals(Constants.TASK_TYPE_ORDER_OUT_STOCK)) { | 
|---|
|  |  |  | taskItem.setWkType(Short.parseShort(order.getWkType())) | 
|---|
|  |  |  | .setSourceCode(order.getCode()) | 
|---|
|  |  |  | .setSourceId(order.getId()); | 
|---|
|  |  |  | } else if (map.getType().equals(Constants.TASK_TYPE_OUT_CHECK) || map.getType().equals(Constants.TASK_TYPE_OUT_STOCK)) { | 
|---|
|  |  |  | taskItem.setSource(item.getId()) | 
|---|
|  |  |  | .setSourceId(item.getLocId()) | 
|---|
|  |  |  | .setSourceCode(item.getLocCode()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } else if (map.getType().equals(Constants.TASK_TYPE_WAVE_OUT_STOCK)) { | 
|---|
|  |  |  | taskItem.setSourceId(wave.getId()) | 
|---|
|  |  |  | .setWkType(Short.parseShort(OrderWorkType.ORDER_WORK_TYPE_OTHER.type)) | 
|---|
|  |  |  | .setSourceCode(wave.getCode()) | 
|---|
|  |  |  | .setSource(item.getSource()); | 
|---|
|  |  |  | } else if (map.getType().equals(Constants.TASK_TYPE_OUT_CHECK) || map.getType().equals(Constants.TASK_TYPE_OUT_STOCK)) { | 
|---|
|  |  |  | taskItem.setWkType(Short.parseShort(OrderWorkType.ORDER_WORK_TYPE_STOCK_OUT.type)) | 
|---|
|  |  |  | .setSource(item.getId()) | 
|---|
|  |  |  | .setSourceId(item.getLocId()) | 
|---|
|  |  |  | .setSourceCode(item.getLocCode()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | taskItems.add(taskItem); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Double qty = Math.round((item.getWorkQty() + item.getOutQty()) * 10000) / 10000.0; | 
|---|
|  |  |  | 
|---|
|  |  |  | if (Objects.isNull(map.getTarLoc()) || StringUtils.isBlank(map.getTarLoc())) { | 
|---|
|  |  |  | //目标库位为空,自动获取新库位 | 
|---|
|  |  |  | DeviceSite deviceSite = deviceSiteService.getOne(new LambdaQueryWrapper<DeviceSite>() | 
|---|
|  |  |  | .eq(DeviceSite::getType, TaskType.TASK_TYPE_LOC_MOVE.type) | 
|---|
|  |  |  | .eq(DeviceSite::getChannel, orgLoc.getChannel()), false); | 
|---|
|  |  |  | .eq(DeviceSite::getType, TaskType.TASK_TYPE_LOC_MOVE.type) | 
|---|
|  |  |  | .eq(!Objects.isNull(orgLoc.getChannel()), DeviceSite::getChannel, orgLoc.getChannel()), false); | 
|---|
|  |  |  | if (Objects.isNull(deviceSite)) { | 
|---|
|  |  |  | throw new CoolException("站点信息不存在!!"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | TaskInParam param = new TaskInParam(); | 
|---|
|  |  |  | param.setIoType(TaskType.TASK_TYPE_OUT.type) | 
|---|
|  |  |  | .setOrgLoc(map.getOrgLoc()) | 
|---|
|  |  |  | .setSourceStaNo(Integer.parseInt(deviceSite.getSite())) | 
|---|
|  |  |  | .setSourceStaNo(deviceSite.getSite()) | 
|---|
|  |  |  | .setLocType1(Integer.parseInt(orgLoc.getType()) | 
|---|
|  |  |  | ); | 
|---|
|  |  |  | InTaskMsgDto locNo; | 
|---|
|  |  |  | 
|---|
|  |  |  | .setSort(Constants.TASK_SORT_DEFAULT_VALUE) | 
|---|
|  |  |  | .setUpdateTime(new Date()) | 
|---|
|  |  |  | .setTaskStatus(TaskStsType.GENERATE_IN.id) | 
|---|
|  |  |  | .setBarcode(orgLoc.getBarcode()); | 
|---|
|  |  |  | .setBarcode(orgLoc.getBarcode()) | 
|---|
|  |  |  | .setMemo(map.getMemo()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (!taskService.save(task)) { | 
|---|
|  |  |  | throw new CoolException("新建移库任务失败!!"); | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return task; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * @author Ryan | 
|---|
|  |  |  | * @date 2025/7/16 | 
|---|
|  |  |  | * @description: 获取当前物料所有库存信息 | 
|---|
|  |  |  | * @version 1.0 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public List<LocItem> listByMatnr(CheckLocQueryParams matnr) { | 
|---|
|  |  |  | LambdaQueryWrapper<LocItem> wrapper = new LambdaQueryWrapper<LocItem>() | 
|---|
|  |  |  | .eq(StringUtils.isNotBlank(matnr.getLocCode()), LocItem::getLocCode, matnr.getLocCode()) | 
|---|
|  |  |  | //                .eq(StringUtils.isNotBlank(matnr.getChannel()), LocItem::getChannel, matnr.getChannel()) | 
|---|
|  |  |  | .in(!matnr.getMatnrCode().isEmpty(), LocItem::getMatnrCode, matnr.getMatnrCode()); | 
|---|
|  |  |  | return  this.baseMapper.listByMatnr(LocStsType.LOC_STS_TYPE_F.type, matnr.getChannel(), wrapper); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|