| | |
| | | package com.vincent.rsf.server.manager.service.impl; |
| | | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | 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.entity.dto.InTaskMsgDto; |
| | | import com.vincent.rsf.server.api.service.WcsService; |
| | | import com.vincent.rsf.server.api.utils.LocUtils; |
| | | import com.vincent.rsf.server.api.utils.SlaveProperties; |
| | | import com.vincent.rsf.server.common.constant.Constants; |
| | | import com.vincent.rsf.server.manager.controller.params.LocToTaskParams; |
| | | import com.vincent.rsf.server.manager.entity.*; |
| | | import com.vincent.rsf.server.manager.enums.*; |
| | | import com.vincent.rsf.server.manager.enums.LocType; |
| | | import com.vincent.rsf.server.manager.mapper.LocItemMapper; |
| | | import com.vincent.rsf.server.manager.entity.LocItem; |
| | | import com.vincent.rsf.server.manager.service.LocItemService; |
| | | import com.vincent.rsf.server.manager.service.*; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.vincent.rsf.server.system.constant.SerialRuleCode; |
| | | import com.vincent.rsf.server.system.utils.SerialRuleUtils; |
| | | import lombok.Synchronized; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.lang.reflect.Array; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Service("locItemService") |
| | | public class LocItemServiceImpl extends ServiceImpl<LocItemMapper, LocItem> implements LocItemService { |
| | | |
| | | @Autowired |
| | | private LocService locService; |
| | | @Autowired |
| | | private TaskService taskService; |
| | | @Autowired |
| | | private TaskItemService taskItemService; |
| | | @Autowired |
| | | private LocItemService locItemService; |
| | | @Autowired |
| | | private DeviceSiteService deviceSiteService; |
| | | @Autowired |
| | | private SlaveProperties slaveProperties; |
| | | @Autowired |
| | | private WcsService wcsService; |
| | | |
| | | |
| | | /** |
| | | * 库存出库生成出库任务 |
| | | * type: check 盘点, stock: 库存出库 |
| | | * |
| | | * @param map |
| | | * @return |
| | | */ |
| | | @Override |
| | | @Synchronized |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public R generateTask(LocToTaskParams map) { |
| | | 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)); |
| | | listMap.keySet().forEach(key -> { |
| | | Task task = new Task(); |
| | | Loc loc = locService.getById(key); |
| | | if (Objects.isNull(loc)) { |
| | | throw new CoolException("数据错误:所选库存信息不存在!!"); |
| | | } |
| | | loc.setUseStatus(LocStsType.LOC_STS_TYPE_R.type); |
| | | |
| | | if (!locService.updateById(loc)) { |
| | | throw new CoolException("库位状态更新失败!!"); |
| | | } |
| | | |
| | | Task moveTask = new Task(); |
| | | if (!LocUtils.isShallowLoc(slaveProperties, loc.getCode())) { |
| | | //获取深库位对应浅库位 |
| | | String shallowLoc = LocUtils.getShallowLoc(slaveProperties, loc.getCode()); |
| | | Loc one = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, shallowLoc)); |
| | | if (Objects.isNull(one)) { |
| | | throw new CoolException("对应库位不存在!!"); |
| | | } |
| | | map.setOrgLoc(one.getCode()); |
| | | //优先生成移库任务 |
| | | if (!one.getUseStatus().equals(LocStsType.LOC_STS_TYPE_O.type)) { |
| | | moveTask = genMoveTask(map); |
| | | } |
| | | } |
| | | |
| | | String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_TASK_CODE, null); |
| | | task.setOrgLoc(loc.getCode()) |
| | | .setTaskCode(ruleCode) |
| | | .setParentId(moveTask.getId()) |
| | | .setTargSite(siteNo) |
| | | .setTaskStatus(TaskStsType.GENERATE_OUT.id) |
| | | .setBarcode(loc.getBarcode()); |
| | | |
| | | List<LocItem> locItems = this.list(new LambdaQueryWrapper<LocItem>().eq(LocItem::getLocId, key)); |
| | | if (locItems.isEmpty()) { |
| | | throw new CoolException("数据错误:所选库存明细不存在!!"); |
| | | } |
| | | |
| | | 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)) { |
| | | Double useQty = Math.round((outQty + workQty) * 10000) / 10000.0; |
| | | if (orgQty.compareTo(useQty) > 0) { |
| | | //拣料出库 |
| | | task.setTaskType(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type); |
| | | |
| | | DeviceSite deviceSite = deviceSiteService.getOne(new LambdaQueryWrapper<DeviceSite>() |
| | | .eq(DeviceSite::getSite, siteNo) |
| | | .eq(DeviceSite::getChannel, loc.getChannel()) |
| | | .eq(DeviceSite::getType, TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)); |
| | | if (Objects.isNull(deviceSite)) { |
| | | throw new CoolException("站点不支持拣料出库!!"); |
| | | } |
| | | } else { |
| | | //全板出库 |
| | | task.setTaskType(TaskType.TASK_TYPE_OUT.type); |
| | | DeviceSite deviceSite = deviceSiteService.getOne(new LambdaQueryWrapper<DeviceSite>() |
| | | .eq(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)) { |
| | | //盘点出库 |
| | | task.setTaskType(TaskType.TASK_TYPE_CHECK_OUT.type); |
| | | DeviceSite deviceSite = deviceSiteService.getOne(new LambdaQueryWrapper<DeviceSite>() |
| | | .eq(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 (!taskService.save(task)) { |
| | | throw new CoolException("任务创建失败!!"); |
| | | } |
| | | List<TaskItem> taskItems = new ArrayList<>(); |
| | | listMap.get(key).forEach(item -> { |
| | | TaskItem taskItem = new TaskItem(); |
| | | BeanUtils.copyProperties(item, taskItem); |
| | | taskItem.setTaskId(task.getId()) |
| | | .setAnfme(item.getOutQty()) |
| | | .setBatch(item.getBatch()) |
| | | .setOrderType(OrderType.ORDER_OUT.type) |
| | | .setWkType(Short.parseShort(OrderWorkType.ORDER_WORK_TYPE_STOCK_OUT.type)); |
| | | taskItems.add(taskItem); |
| | | |
| | | Double qty = Math.round((item.getWorkQty() + item.getOutQty()) * 10000) / 10000.0; |
| | | LocItem locItem = locItemService.getById(item.getId()); |
| | | if (Objects.isNull(locItem)) { |
| | | throw new CoolException("库存信息不存在!"); |
| | | } |
| | | |
| | | if (item.getOutQty().compareTo(0.0) < 0) { |
| | | throw new CoolException("出库数里不能小于0!!"); |
| | | } |
| | | |
| | | if (locItem.getAnfme().compareTo(qty) < 0) { |
| | | Double minusQty = Math.round((locItem.getAnfme() - locItem.getWorkQty()) * 10000) / 10000.0; |
| | | item.setWorkQty(minusQty); |
| | | } else { |
| | | item.setWorkQty(qty); |
| | | } |
| | | if (!locItemService.updateById(item)) { |
| | | throw new CoolException("库存信息修改失败!!"); |
| | | } |
| | | }); |
| | | |
| | | if (!taskItemService.saveBatch(taskItems)) { |
| | | throw new CoolException("任务明细生成失败!!"); |
| | | } |
| | | }); |
| | | |
| | | return R.ok("任务生成完成!!"); |
| | | } |
| | | |
| | | /** |
| | | * 生成移库任务 |
| | | * |
| | | * @param map |
| | | * @return |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Task genMoveTask(LocToTaskParams map) { |
| | | if (Objects.isNull(map.getOrgLoc()) || StringUtils.isBlank(map.getOrgLoc())) { |
| | | throw new CoolException("源库位不能为空!"); |
| | | } |
| | | |
| | | Loc orgLoc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, map.getOrgLoc())); |
| | | if (Objects.isNull(orgLoc)) { |
| | | throw new CoolException("源库位不存在!!"); |
| | | } |
| | | |
| | | if (orgLoc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_R.type) |
| | | || orgLoc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_S.type) |
| | | || orgLoc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_X.type ) ) { |
| | | throw new CoolException("源库位有任务正在执行中..."); |
| | | } |
| | | |
| | | orgLoc.setUseStatus(LocStsType.LOC_STS_TYPE_R.type); |
| | | |
| | | if (!locService.updateById(orgLoc)) { |
| | | throw new CoolException("出库预约失败!!"); |
| | | } |
| | | |
| | | Loc targetLoc = new Loc(); |
| | | 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); |
| | | if (Objects.isNull(deviceSite)) { |
| | | throw new CoolException("站点信息不存在!!"); |
| | | } |
| | | TaskInParam param = new TaskInParam(); |
| | | param.setIoType(TaskType.TASK_TYPE_OUT.type) |
| | | .setSourceStaNo(Integer.parseInt(deviceSite.getSite())) |
| | | .setLocType1(Integer.parseInt(orgLoc.getType())); |
| | | InTaskMsgDto locNo = null; |
| | | try { |
| | | locNo = wcsService.getLocNo(param); |
| | | } catch (Exception e) { |
| | | log.error("<UNK>", e); |
| | | throw new CoolException(e.getMessage()); |
| | | } |
| | | targetLoc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, locNo.getLocNo())); |
| | | } else { |
| | | targetLoc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, map.getTarLoc())); |
| | | } |
| | | |
| | | if (Objects.isNull(targetLoc)) { |
| | | throw new CoolException("目标库位不存在!!"); |
| | | } |
| | | |
| | | targetLoc.setUseStatus(LocStsType.LOC_STS_TYPE_S.type); |
| | | |
| | | if (!locService.updateById(targetLoc)) { |
| | | throw new CoolException("目标库位预约失败!!"); |
| | | } |
| | | |
| | | String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_TASK_CODE, null); |
| | | Task task = new Task(); |
| | | task.setOrgLoc(orgLoc.getCode()) |
| | | .setTaskCode(ruleCode) |
| | | .setTaskType(TaskType.TASK_TYPE_LOC_MOVE.type) |
| | | .setTargLoc(targetLoc.getCode()) |
| | | .setTaskStatus(TaskStsType.GENERATE_IN.id) |
| | | .setBarcode(orgLoc.getBarcode()); |
| | | |
| | | if (!taskService.save(task)) { |
| | | throw new CoolException("新建移库任务失败!!"); |
| | | } |
| | | |
| | | List<LocItem> locItems = locItemService.list(new LambdaQueryWrapper<LocItem>().eq(LocItem::getLocId, orgLoc.getId())); |
| | | if (!locItems.isEmpty()) { |
| | | List<TaskItem> taskItems = new ArrayList<>(); |
| | | for (LocItem item : locItems) { |
| | | TaskItem taskItem = new TaskItem(); |
| | | BeanUtils.copyProperties(item, taskItem); |
| | | taskItem.setTaskId(task.getId()) |
| | | .setAnfme(item.getAnfme()) |
| | | .setBatch(item.getBatch()) |
| | | .setOrderType(OrderType.ORDER_IN.type) |
| | | .setWkType(Short.parseShort(OrderWorkType.ORDER_WORK_TYPE_OTHER_IN.type)); |
| | | taskItems.add(taskItem); |
| | | } |
| | | if (!taskItemService.saveBatch(taskItems)) { |
| | | throw new CoolException("任务明细生成失败!!"); |
| | | } |
| | | } |
| | | return task; |
| | | } |
| | | } |