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.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 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 items = map.getItems(); Map> 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().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 locItems = this.list(new LambdaQueryWrapper().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 locItemList = listMap.get(key); Double outQty = locItemList.stream().mapToDouble(LocItem::getOutQty).sum(); Task serviceOne = taskService.getOne(new LambdaQueryWrapper().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() .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() .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() .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 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().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() .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("", e); throw new CoolException(e.getMessage()); } targetLoc = locService.getOne(new LambdaQueryWrapper().eq(Loc::getCode, locNo.getLocNo())); } else { targetLoc = locService.getOne(new LambdaQueryWrapper().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 locItems = locItemService.list(new LambdaQueryWrapper().eq(LocItem::getLocId, orgLoc.getId())); if (!locItems.isEmpty()) { List 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; } }