package com.vincent.rsf.server.manager.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.vincent.rsf.framework.common.Cools; 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.common.constant.Constants; import com.vincent.rsf.server.manager.enums.*; import com.vincent.rsf.framework.common.R; import com.vincent.rsf.framework.exception.CoolException; import com.vincent.rsf.server.api.utils.LocUtils; import com.vincent.rsf.server.manager.controller.params.GenerateTaskParams; import com.vincent.rsf.server.manager.entity.*; import com.vincent.rsf.server.manager.enums.LocType; import com.vincent.rsf.server.manager.mapper.TaskMapper; import com.vincent.rsf.server.manager.service.*; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.vincent.rsf.server.manager.utils.LocManageUtil; import com.vincent.rsf.server.system.constant.SerialRuleCode; import com.vincent.rsf.server.manager.enums.LocStsType; 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.util.*; import java.util.stream.Collectors; @Service("taskService") public class TaskServiceImpl extends ServiceImpl implements TaskService { @Autowired private WaitPakinService waitPakinService; @Autowired private TaskItemService taskItemService; @Autowired private WaitPakinItemService waitPakinItemService; @Autowired private LocService locService; @Autowired private PurchaseService purchaseService; @Autowired private AsnOrderService asnOrderService; @Autowired private AsnOrderItemService asnOrderItemService; @Autowired private StockService stockService; @Autowired private StockItemService stockItemService; @Autowired private DeviceSiteService deviceSiteService; @Autowired private LocItemService locItemService; @Autowired private DeviceBindService deviceBindService; @Autowired private WarehouseAreasService warehouseAreasService; @Autowired private WarehouseAreasItemService warehouseAreasItemService; @Autowired private WaveItemService waveItemService; @Autowired private WaveService waveService; @Autowired private BasStationService basStationService; @Autowired private TaskService taskService; @Autowired private LocItemWorkingService locItemWorkingService; @Autowired private WcsService wcsService; @Override @Transactional(rollbackFor = Exception.class) public synchronized R generateAGVTasks(WaitPakin pakins, String locCode, String orgSta, Long loginUserId) { if (Cools.isEmpty(pakins) || Cools.isEmpty(locCode)) { throw new CoolException("参数不能为空!!"); } /**获取组拖*/ List waitPakins = waitPakinService.list(new LambdaQueryWrapper() .in(WaitPakin::getId, pakins.getId()) .eq(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_DONE.val)); if (waitPakins.isEmpty()) { throw new CoolException("请检查组托状态是否完成!!"); } waitPakins.forEach(pakin -> { /**获取库位*/ String targetLoc = locCode; if (Cools.isEmpty(targetLoc)) { throw new CoolException("该站点对应库区未找到库位"); } List taskItems = new ArrayList<>(); String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_TASK_CODE, null); if (StringUtils.isBlank(ruleCode)) { throw new CoolException("编码错误:请确认编码「SYS_TASK_CODE」是否已生成!!"); } Task task = new Task(); task.setTaskCode(ruleCode) .setTaskStatus(TaskStsType.GENERATE_IN.id) .setTaskType(TaskType.TASK_TYPE_IN.type) .setWarehType(WarehType.WAREHOUSE_TYPE_AGV.val) .setTargLoc(targetLoc) .setOrgSite(orgSta) .setBarcode(pakin.getBarcode()) .setCreateBy(loginUserId) .setUpdateBy(loginUserId); if (!this.save(task)) { throw new CoolException("任务保存失败!!"); } if (!locService.update(new LambdaUpdateWrapper().eq(Loc::getCode, task.getTargLoc()) .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type).set(Loc::getBarcode, pakin.getBarcode()))) { throw new CoolException("库位预约失败!!"); } /**获取组拖明细**/ List waitPakinItems = waitPakinItemService.list(new LambdaQueryWrapper().eq(WaitPakinItem::getPakinId, pakin.getId())); if (waitPakinItems.isEmpty()) { throw new CoolException("数据错误:组拖明细不存在"); } waitPakinItems.forEach(item -> { TaskItem taskItem = new TaskItem(); BeanUtils.copyProperties(item, taskItem); taskItem.setTaskId(task.getId()) .setOrderType(OrderType.ORDER_IN.type) .setSource(item.getId()) .setTrackCode(item.getTrackCode()) .setCreateBy(loginUserId) .setUpdateBy(loginUserId) .setExtendFields(item.getExtendFields()) .setOrderId(item.getAsnId()) .setOrderItemId(item.getAsnItemId()); taskItems.add(taskItem); }); if (!taskItemService.saveBatch(taskItems)) { throw new CoolException("任务明细保存失败!!"); } waitPakinItems.forEach(item -> { if (!waitPakinItemService.update(new LambdaUpdateWrapper() .set(WaitPakinItem::getWorkQty, item.getAnfme()) .eq(WaitPakinItem::getId, item.getId()))) { throw new CoolException("组托明细修执行数量修改失败!!"); } }); }); if (!waitPakinService.update(new LambdaUpdateWrapper() .in(WaitPakin::getId, pakins.getId()) .set(WaitPakin::getUpdateBy, loginUserId) .set(WaitPakin::getCreateBy, loginUserId) .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val))) { throw new CoolException("组托状态修改失败!!"); } return R.ok("任务生成完毕!"); } @Override @Transactional(rollbackFor = Exception.class) public synchronized R generateFlatWarehouseTasks(WaitPakin pakins, String locCode, Long loginUserId) { if (Cools.isEmpty(pakins) || Cools.isEmpty(locCode)) { throw new CoolException("参数不能为空!!"); } /**获取组拖*/ List waitPakins = waitPakinService.list(new LambdaQueryWrapper() .in(WaitPakin::getId, pakins.getId()) .eq(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_DONE.val)); if (waitPakins.isEmpty()) { throw new CoolException("请检查组托状态是否完成!!"); } waitPakins.forEach(pakin -> { /**获取库位*/ String targetLoc = locCode; if (Cools.isEmpty(targetLoc)) { throw new CoolException("该站点对应库区未找到库位"); } List taskItems = new ArrayList<>(); String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_TASK_CODE, null); if (StringUtils.isBlank(ruleCode)) { throw new CoolException("编码错误:请确认编码「SYS_TASK_CODE」是否已生成!!"); } Task task = new Task(); task.setTaskCode(ruleCode) .setTaskStatus(TaskStsType.COMPLETE_IN.id) .setTaskType(TaskType.TASK_TYPE_IN.type) .setWarehType(WarehType.WAREHOUSE_TYPE_PLAT.val) .setTargLoc(targetLoc) .setBarcode(pakin.getBarcode()) .setCreateBy(loginUserId) .setUpdateBy(loginUserId); if (!this.save(task)) { throw new CoolException("任务保存失败!!"); } if (!locService.update(new LambdaUpdateWrapper().eq(Loc::getCode, task.getTargLoc()) .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type).set(Loc::getBarcode, pakin.getBarcode()))) { throw new CoolException("库位预约失败!!"); } /**获取组拖明细**/ List waitPakinItems = waitPakinItemService.list(new LambdaQueryWrapper().eq(WaitPakinItem::getPakinId, pakin.getId())); if (waitPakinItems.isEmpty()) { throw new CoolException("数据错误:组拖明细不存在"); } waitPakinItems.forEach(item -> { TaskItem taskItem = new TaskItem(); BeanUtils.copyProperties(item, taskItem); taskItem.setTaskId(task.getId()) .setOrderType(OrderType.ORDER_IN.type) .setSource(item.getId()) .setTrackCode(item.getTrackCode()) .setCreateBy(loginUserId) .setUpdateBy(loginUserId) .setExtendFields(item.getExtendFields()) .setOrderId(item.getAsnId()) .setOrderItemId(item.getAsnItemId()); taskItems.add(taskItem); }); if (!taskItemService.saveBatch(taskItems)) { throw new CoolException("任务明细保存失败!!"); } waitPakinItems.forEach(item -> { if (!waitPakinItemService.update(new LambdaUpdateWrapper() .set(WaitPakinItem::getWorkQty, item.getAnfme()) .eq(WaitPakinItem::getId, item.getId()))) { throw new CoolException("组托明细修执行数量修改失败!!"); } }); }); if (!waitPakinService.update(new LambdaUpdateWrapper() .in(WaitPakin::getId, pakins.getId()) .set(WaitPakin::getUpdateBy, loginUserId) .set(WaitPakin::getCreateBy, loginUserId) .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val))) { throw new CoolException("组拖状态修改失败!!"); } return R.ok("任务生成完毕!"); } /** * @param * @param loginUserId * @return * @author Ryan * @description 生成任务列表 * @time 2025/3/29 15:59 */ @Override @Transactional(rollbackFor = Exception.class) public synchronized R generateTasks(GenerateTaskParams waitPakin, Long loginUserId) { if (Objects.isNull(waitPakin) || waitPakin.getWaitPakins().isEmpty()) { throw new CoolException("参数不能为空!!"); } DeviceSite deviceSite = deviceSiteService.getById(waitPakin.getSiteId()); if (Objects.isNull(deviceSite)) { throw new CoolException("站点不存在!!"); } DeviceBind deviceBind = deviceBindService.getById(LocUtils.getAreaType(Integer.valueOf(deviceSite.getSite()))); if (Cools.isEmpty(deviceBind)) { throw new CoolException("库位规则未知"); } WarehouseAreas warehouseArea = warehouseAreasService.getById(deviceBind.getTypeId()); if (Cools.isEmpty(warehouseArea)) { throw new CoolException("未找到所属库区信息"); } /**获取组拖*/ List ids = waitPakin.getWaitPakins().stream().map(WaitPakin::getId).collect(Collectors.toList()); List waitPakins = waitPakinService.list(new LambdaQueryWrapper() .in(WaitPakin::getId, ids) .eq(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_DONE.val)); if (waitPakins.isEmpty()) { throw new CoolException("请检查组拖状态是否完成!!"); } waitPakins.forEach(pakin -> { /**获取库位*/ String targetLoc = LocManageUtil.getTargetLoc(warehouseArea.getId()); if (Cools.isEmpty(targetLoc)) { throw new CoolException("该站点对应库区未找到库位"); } List taskItems = new ArrayList<>(); String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_TASK_CODE, null); if (StringUtils.isBlank(ruleCode)) { throw new CoolException("编码错误:请确认编码「SYS_TASK_CODE」是否已生成!!"); } Task task = new Task(); task.setTaskCode(ruleCode) .setTaskStatus(TaskStsType.GENERATE_IN.id) .setTaskType(TaskType.TASK_TYPE_IN.type) .setTargLoc(targetLoc) .setBarcode(pakin.getBarcode()) .setOrgSite(deviceSite.getSite()) .setTargSite(deviceSite.getDeviceSite()) .setCreateBy(loginUserId) .setUpdateBy(loginUserId); // if (!Objects.isNull(waitPakin.getSiteId()) && waitPakin.getSiteId() > 0) { // DeviceSite site = deviceSiteService.getById(waitPakin.getSiteId()); // task.setTargSite(site.getSite() + ""); // } else { // task.setTargSite(LocManageUtil.getTargetSite()); // } // if (!Objects.isNull(waitPakin.getLocCode()) && StringUtils.isNotBlank(waitPakin.getLocCode())) { // List locs = locService.list(new LambdaQueryWrapper().eq(Loc::getCode, waitPakin.getLocCode())); //// if (!locs.isEmpty()) { //// throw new CoolException("库位错误:相同库位应只一条") //// } // Loc loc = locs.stream().findFirst().get(); // task.setTargSite(loc.getCode()); // } else { // task.setTargSite(LocManageUtil.getTargetSite()); // } if (!this.save(task)) { throw new CoolException("任务保存失败!!"); } if (!locService.update(new LambdaUpdateWrapper().eq(Loc::getCode, task.getTargLoc()) .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type).set(Loc::getBarcode, pakin.getBarcode()))) { throw new CoolException("库位预约失败!!"); } /**获取组拖明细**/ List waitPakinItems = waitPakinItemService.list(new LambdaQueryWrapper().eq(WaitPakinItem::getPakinId, pakin.getId())); if (waitPakinItems.isEmpty()) { throw new CoolException("数据错误:组拖明细不存在"); } waitPakinItems.forEach(item -> { TaskItem taskItem = new TaskItem(); BeanUtils.copyProperties(item, taskItem); // AsnOrder order = asnOrderService.getOne(new LambdaQueryWrapper().eq(AsnOrder::getId, item.getAsnId())); // if (Objects.isNull(order)) { // throw new CoolException("数据错误: 单据不存在!!"); // } taskItem.setTaskId(task.getId()) .setOrderType(OrderType.ORDER_IN.type) .setSource(item.getId()) .setTrackCode(item.getTrackCode()) .setPlatItemId(item.getPlatItemId()) .setPlatOrderCode(item.getPlatOrderCode()) .setPlatWorkCode(item.getPlatWorkCode()) .setProjectCode(item.getProjectCode()) .setCreateBy(loginUserId) .setUpdateBy(loginUserId) .setExtendFields(item.getExtendFields()) .setOrderId(item.getAsnId()) .setOrderItemId(item.getAsnItemId()); taskItems.add(taskItem); }); if (!taskItemService.saveBatch(taskItems)) { throw new CoolException("任务明细保存失败!!"); } waitPakinItems.forEach(item -> { if (!waitPakinItemService.update(new LambdaUpdateWrapper() .set(WaitPakinItem::getWorkQty, item.getAnfme()) .eq(WaitPakinItem::getId, item.getId()))) { throw new CoolException("组托明细修执行数量修改失败!!"); } }); }); if (!waitPakinService.update(new LambdaUpdateWrapper() .in(WaitPakin::getId, ids) .set(WaitPakin::getUpdateBy, loginUserId) .set(WaitPakin::getCreateBy, loginUserId) .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val))) { throw new CoolException("组拖状态修改失败!!"); } return R.ok("任务生成完毕!"); } /** * 入库任务 * * @param tasks * @throws Exception */ @Synchronized @Override @Transactional(rollbackFor = Exception.class) public void complateInTask(List tasks) throws Exception { for (Task task : tasks) { if (task.getTaskType().equals(TaskType.TASK_TYPE_IN.type)) { //1.入库 complateInstock(task); } else if (task.getTaskType().equals(TaskType.TASK_TYPE_PICK_IN.type) || task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_IN.type)) { //53.拣料再入库 //57.盘点再入库 pickComplateInStock(task); } else if (task.getTaskType().equals(TaskType.TASK_TYPE_LOC_MOVE.type)) { //移库 moveInStock(task); } } } @Transactional(rollbackFor = Exception.class) public void moveInStock(Task task) { if (Objects.isNull(task)) { return; } Loc loc = locService.getOne(new LambdaQueryWrapper().eq(Loc::getCode, task.getTargLoc())); if (Objects.isNull(loc)) { throw new CoolException("目标库位不存在!"); } Loc orgLoc = locService.getOne(new LambdaQueryWrapper().eq(Loc::getCode, task.getOrgLoc())); if (Objects.isNull(orgLoc)) { throw new CoolException("源库位不存在!"); } if (!loc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_S.type)) { throw new CoolException("当前库位状态不处于S.入库预约,不可执行入库操作!"); } if (!orgLoc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_R.type)) { throw new CoolException("当前库位状态不处于R.出库预约,不可执行入库操作!"); } List taskItems = taskItemService.list(new LambdaQueryWrapper().eq(TaskItem::getTaskId, task.getId())); if (!taskItems.isEmpty()) { //移库有可能是空板 try { //更新库位明细 saveLocItem(taskItems, task.getId()); } catch (Exception e) { throw new CoolException("库位明细更新失败!!"); } if (!locItemService.remove(new LambdaQueryWrapper().eq(LocItem::getLocCode, task.getOrgLoc()))) { throw new CoolException("源库位明细删除失败!"); } } /**修改库位状态为F.在库*/ if (!locService.update(new LambdaUpdateWrapper() .set(Loc::getBarcode, task.getBarcode()) .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_F.type) .eq(Loc::getCode, task.getTargLoc()))) { throw new CoolException("库位状态修改失败!!"); } if (!locService.update(new LambdaUpdateWrapper() .set(Loc::getBarcode, null) .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type).eq(Loc::getCode, task.getOrgLoc()))) { throw new CoolException("库位状态修改失败!!"); } if (!this.update(new LambdaUpdateWrapper().eq(Task::getId, task.getId()).set(Task::getTaskStatus, TaskStsType.UPDATED_IN.id))) { throw new CoolException("任务状态修改失败!!"); } } /** * 完成任务 更新库位明细信息,将单据库存更新到单据库存表 * * @param tasks * @throws Exception */ @Synchronized @Override @Transactional(rollbackFor = Exception.class) public void completeTask(List tasks) throws Exception { for (Task task : tasks) { //出库任务 if (task.getTaskType().equals(TaskType.TASK_TYPE_OUT.type)) { //全托出库 complateOutStock(task); } else if (task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)) { //拣料出库 complateOutStock(task); } else if (task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)) { //盘点出库 complateOutStock(task); } } } /** * 拣料再入库 * * @param task */ @Transactional(rollbackFor = Exception.class) public void pickComplateInStock(Task task) throws Exception { if (Objects.isNull(task)) { return; } Loc loc = locService.getOne(new LambdaQueryWrapper().eq(Loc::getCode, task.getTargLoc())); if (Objects.isNull(loc)) { throw new CoolException("库存不存在!!"); } if (!loc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_S.type)) { throw new CoolException("当前库位状态不处于S.入库预约,不可执行入库操作!"); } loc.setUseStatus(LocStsType.LOC_STS_TYPE_F.type).setBarcode(task.getBarcode()); if (!locService.updateById(loc)) { throw new CoolException("库位信息更新失败!!"); } List taskItems = taskItemService.list(new LambdaQueryWrapper().eq(TaskItem::getTaskId, task.getId())); if (taskItems.isEmpty()) { throw new CoolException("任务明细不存在!!"); } List items = new ArrayList<>(); for (TaskItem taskItem : taskItems) { LocItem locItem = new LocItem(); LocItemWorking locWorking = locItemWorkingService.getOne(new LambdaQueryWrapper() .eq(LocItemWorking::getTaskId, taskItem.getTaskId()) .eq(StringUtils.isNotBlank(taskItem.getBatch()), LocItemWorking::getBatch, taskItem.getBatch()) .eq(StringUtils.isNotBlank(taskItem.getFieldsIndex()), LocItemWorking::getFieldsIndex, taskItem.getFieldsIndex()) .eq(LocItemWorking::getMatnrId, taskItem.getMatnrId())); if (Objects.isNull(locWorking)) { throw new CoolException("数据错误,作业中库存数据丢失!!"); } if (task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_IN.type)) { locWorking.setAnfme(taskItem.getAnfme()); } BeanUtils.copyProperties(locWorking, locItem); locItem.setWorkQty(0.0).setLocCode(loc.getCode()).setLocId(loc.getId()).setId(null); items.add(locItem); } if (!locItemService.saveBatch(items)) { throw new CoolException("作业库存回写失败!!"); } TaskItem taskItem = taskItems.stream().findFirst().get(); //保存入出库流水 saveStockItems(taskItems, task, null, null, taskItem.getWkType(), taskItem.getOrderType()); if (!locItemWorkingService.remove(new LambdaQueryWrapper().eq(LocItemWorking::getTaskId, task.getId()))) { throw new CoolException("作业中库存删除失败!!"); } task.setTaskStatus(TaskStsType.UPDATED_IN.id).setUpdateTime(null); if (!taskService.updateById(task)) { throw new CoolException("任务状态修改失败!!"); } } /** * 任务取消 * * @param ids * @return */ @Override @Transactional(rollbackFor = Exception.class) public R removeTask(Long[] ids) { List longs = Arrays.asList(TaskStsType.GENERATE_IN.id, TaskStsType.GENERATE_OUT.id); List list = Arrays.asList(TaskType.TASK_TYPE_IN.type, TaskType.TASK_TYPE_OUT.type, TaskType.TASK_TYPE_EMPITY_IN.type, TaskType.TASK_TYPE_EMPITY_OUT.type, TaskType.TASK_TYPE_MERGE_OUT.type); List tasks = this.list(new LambdaQueryWrapper() .in(Task::getTaskType, list) .in(Task::getId, ids).in(Task::getTaskStatus, longs)); if (tasks.isEmpty()) { throw new CoolException("任务已处执行状态不可取消!!"); } for (Task task : tasks) { //恢复组托状态 WaitPakin waitPakin = waitPakinService.getOne(new LambdaQueryWrapper() .eq(WaitPakin::getBarcode, task.getBarcode()) ); if (null != waitPakin) { waitPakin.setIoStatus(Short.valueOf(PakinIOStatus.PAKIN_IO_STATUS_DONE.val)); if (!waitPakinService.updateById(waitPakin)) { throw new CoolException("更新组托状态失败!!"); } } Loc loc = locService.getOne(new LambdaQueryWrapper().eq(Loc::getCode, task.getTaskType() < TaskStsType.UPDATED_IN.id ? task.getTargLoc() : task.getOrgLoc())); if (null != loc && (loc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_S.type) || loc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_R.type))) { loc.setUseStatus(LocStsType.LOC_STS_TYPE_O.type); if (!locService.updateById(loc)) { throw new CoolException("更新库位状态失败!!"); } } if (!Objects.isNull(task.getWarehType()) && task.getWarehType().equals(WarehType.WAREHOUSE_TYPE_AGV.val)) { BasStation basStation = null; if (task.getTaskType().equals(TaskType.TASK_TYPE_IN.type) || task.getTaskType().equals(TaskType.TASK_TYPE_EMPITY_IN.type)) { basStation = basStationService.getOne(new LambdaQueryWrapper() .eq(BasStation::getStationName, task.getOrgSite()) .eq(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_R.type) ); } else if (task.getTaskType().equals(TaskType.TASK_TYPE_OUT.type) || task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type) || task.getTaskType().equals(TaskType.TASK_TYPE_MERGE_OUT.type) || task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type) || task.getTaskType().equals(TaskType.TASK_TYPE_EMPITY_OUT.type) ) { basStation = basStationService.getOne(new LambdaQueryWrapper() .eq(BasStation::getStationName, task.getTargLoc()) .eq(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_R.type)); } if (null == basStation) { throw new CoolException("站点状态错误!!"); } basStation.setUseStatus(LocStsType.LOC_STS_TYPE_F.type); if (!basStationService.updateById(basStation)) { throw new CoolException("更新站点状态失败!!"); } } if (!taskItemService.remove(new LambdaQueryWrapper().eq(TaskItem::getTaskId, task.getId()))) { throw new CoolException("任务明细删除失败!!"); } } if (!this.removeByIds(Arrays.asList(ids))) { throw new CoolException("Delete Fail"); } return R.ok("取消完成"); } /** * 拣料出库 * * @param id * @return */ @Override @Transactional(rollbackFor = Exception.class) public Task pickOrCheckTask(Long id, String oType) throws Exception { Task task = this.getById(id); if (Objects.isNull(task)) { throw new CoolException("当前任务不存在!!"); } Integer type; if (oType.equals(Constants.TASK_TYPE_OUT_CHECK)) { //盘点入库 type = TaskType.TASK_TYPE_CHECK_IN.type; if (!task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)) { throw new CoolException("非盘点出库 ,不可执行此操作!!"); } } else { //拣料入库 type = TaskType.TASK_TYPE_PICK_IN.type; if (!task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)) { throw new CoolException("非拣料出库 ,不可执行此操作!!"); } } Loc loc = locService.getOne(new LambdaQueryWrapper() .eq(Loc::getCode, task.getOrgLoc())); if (Objects.isNull(loc)) { throw new CoolException("没有空库位!!"); } String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_TASK_CODE, task); //更新任务主单 task.setTaskCode(ruleCode) .setTaskType(type) .setBarcode(task.getBarcode()) .setTaskStatus(TaskStsType.GENERATE_IN.id); TaskInParam param = new TaskInParam(); param.setSourceStaNo(Integer.parseInt(task.getTargSite())) .setIoType(type) .setLocType1(Integer.parseInt(loc.getType())); //获取新库位 InTaskMsgDto locInfo = wcsService.getLocNo(param); if (Objects.isNull(locInfo)) { throw new CoolException("获取库位失败!!"); } task.setTargLoc(locInfo.getLocNo()); if (!this.updateById(task)) { throw new CoolException("任务状态更新失败!!"); } List taskItems = taskItemService.list(new LambdaQueryWrapper().eq(TaskItem::getTaskId, task.getId())); for (int i = 0; i < taskItems.size(); i++) { TaskItem taskItem = taskItems.get(i); LocItemWorking locWorking = locItemWorkingService.getOne(new LambdaQueryWrapper() .eq(LocItemWorking::getTaskId, taskItem.getTaskId()) .eq(StringUtils.isNotBlank(taskItem.getBatch()), LocItemWorking::getBatch, taskItem.getBatch()) .eq(StringUtils.isNotBlank(taskItem.getFieldsIndex()), LocItemWorking::getFieldsIndex, taskItem.getFieldsIndex()) .eq(LocItemWorking::getMatnrId, taskItem.getMatnrId())); if (Objects.isNull(locWorking)) { throw new CoolException("数据错误,作业中库存数据丢失!!"); } if (task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_IN.type)) { locWorking.setWorkQty(0.0); locWorking.setAnfme(taskItem.getAnfme()); } else { if (locWorking.getAnfme().compareTo(taskItem.getAnfme()) >= 0) { locWorking.setWorkQty(0.0); locWorking.setAnfme(Math.round((locWorking.getAnfme() - taskItem.getAnfme()) * 10000) / 10000.0); } else { continue; } } if (!locItemWorkingService.updateById(locWorking)) { throw new CoolException("临时库存更新失败!!"); } taskItems.get(i).setAnfme(locWorking.getAnfme()); } if (!taskItemService.updateBatchById(taskItems)) { throw new CoolException("任务明细更新失败!!"); } Loc one = locService.getOne(new LambdaQueryWrapper().eq(Loc::getCode, task.getTargLoc())); if (Objects.isNull(one)) { throw new CoolException("目标库位不存在!!"); } one.setUseStatus(LocStsType.LOC_STS_TYPE_S.type); if (!locService.updateById(one)) { throw new CoolException("库位预约入库失败!!"); } return task; } /** * @author Ryan * @date 2025/5/20 * @description: 完成出库任务,更新出库库存信息 * @version 1.0 */ @Synchronized @Transactional(rollbackFor = Exception.class) public void complateOutStock(Task task) throws Exception { if (Objects.isNull(task)) { throw new CoolException("参数不能为空!!"); } Loc loc = locService.getOne(new LambdaQueryWrapper().eq(Loc::getCode, task.getOrgLoc())); if (Objects.isNull(loc)) { throw new CoolException("库位不存在!!"); } if (!loc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_R.type)) { throw new CoolException("库位状态不处理于R.出库预约!!"); } List taskItems = taskItemService.list(new LambdaQueryWrapper().eq(TaskItem::getTaskId, task.getId())); if (taskItems.isEmpty()) { throw new CoolException("任务明细不存在!!"); } List locItems = locItemService.list(new LambdaQueryWrapper().eq(LocItem::getLocId, loc.getId())); if (locItems.isEmpty()) { throw new CoolException("库位明细不存在!!"); } List workings = new ArrayList<>(); for (LocItem item : locItems) { LocItemWorking working = new LocItemWorking(); BeanUtils.copyProperties(item, working); working.setId(null).setTaskId(task.getId()).setLocItemId(item.getId()); workings.add(working); } if (!locItemWorkingService.saveBatch(workings)) { throw new CoolException("临时库存保存失败!!"); } try { //更新库位明细 subtractLocItem(loc); } catch (Exception e) { log.error("", e); throw new CoolException(e.getMessage()); } //添加出入库记录信息 Map> listMap = taskItems.stream().collect(Collectors.groupingBy(TaskItem::getWkType)); /***获取库存出库值,如果为空表示正常单据出库,非空表明是库存出库 * 1. 库存出库没有单据信息,单据信息默认为空 * 2. 单据库存需通过波次查询原始单据信息,将单据信息填入stock中 * */ List list = listMap.get(Short.parseShort(OrderWorkType.ORDER_WORK_TYPE_STOCK_OUT.type)); if (Objects.isNull(list) || list.isEmpty()) { Map> maps = taskItems.stream().collect(Collectors.groupingBy(TaskItem::getSource)); maps.keySet().forEach(key -> { WaveItem waveItem = waveItemService.getById(key); if (Objects.isNull(waveItem)) { throw new CoolException("波次明细不存在!!"); } try { saveOutStockItem(maps.get(key), waveItem); } catch (Exception e) { throw new CoolException(e.getMessage()); } }); } else { try { saveOutStockItem(taskItems, null); } catch (Exception e) { throw new CoolException(e.getMessage()); } } /**修改为库位状态为O.空库*/ if (!locService.update(new LambdaUpdateWrapper() .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type) .set(Loc::getBarcode, null) .eq(Loc::getId, loc.getId()))) { throw new CoolException("库位状态修改失败!!"); } if (task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type) || task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)) { if (!this.update(new LambdaUpdateWrapper() .eq(Task::getId, task.getId()) .set(Task::getTaskStatus, TaskStsType.WAVE_SEED.id))) { throw new CoolException("库存状态更新失败!!"); } } else { if (!this.update(new LambdaUpdateWrapper() .eq(Task::getId, task.getId()) .set(Task::getTaskStatus, TaskStsType.UPDATED_OUT.id))) { throw new CoolException("库存状态更新失败!!"); } //全板出库,删除临时库存 if (!locItemWorkingService.remove(new LambdaQueryWrapper().eq(LocItemWorking::getTaskId, task.getId()))) { throw new CoolException("临时库存清除失败!!"); } } } /** * @author Ryan * @date 2025/5/20 * @description: 出库信息保存至库存明细表 * @version 1.0 */ @Transactional(rollbackFor = Exception.class) public void saveOutStockItem(List taskItems, WaveItem waveItem) throws Exception { Stock stock = new Stock(); String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_STOCK_CODE, null); if (StringUtils.isBlank(ruleCode)) { throw new CoolException("当前业务:" + SerialRuleCode.SYS_STOCK_CODE + ",编码规则不存在!!"); } Double sum = taskItems.stream().mapToDouble(TaskItem::getAnfme).sum(); stock.setCode(ruleCode) .setAnfme(sum); if (Objects.isNull(waveItem)) { stock.setWkType(Short.parseShort(OrderWorkType.ORDER_WORK_TYPE_STOCK_OUT.type)) .setMemo("出库单出库,无单据信息!!") .setType(OrderType.ORDER_OUT.type); } else { //TODO 生成波次时需要将波次号写入单据,通过物料,批次,动态字段等唯一值反查单据信息 stock.setSourceId(waveItem.getId()).setType(OrderType.ORDER_OUT.type); } if (!stockService.save(stock)) { throw new CoolException("库存保存失败!!"); } List stockItems = new ArrayList<>(); for (TaskItem item : taskItems) { /**通过任务明细中的taskId查询,获取TASK的目标库位信息*/ StockItem stockItem = new StockItem(); BeanUtils.copyProperties(item, stockItem); stockItem.setSourceItemId(item.getOrderItemId()) .setStockCode(stock.getCode()) .setId(null) .setStockId(stock.getId()); stockItems.add(stockItem); } if (!stockItemService.saveBatch(stockItems)) { throw new CoolException("库存修改架失败!!"); } } /** * @author Ryan * @date 2025/5/20 * @description: 扣减库存明细 * @version 1.0 */ @Transactional(rollbackFor = Exception.class) public void subtractLocItem(Loc loc) throws Exception { if (!locItemService.remove(new LambdaQueryWrapper().eq(LocItem::getLocId, loc.getId()))) { throw new CoolException("库存明细删除失败!!"); } } /** * @author Ryan * @date 2025/5/20 * @description: 完成入库任务 * @version 1.0 */ @Transactional(rollbackFor = Exception.class) public void complateInstock(Task task) { if (Objects.isNull(task)) { return; } Loc loc = locService.getOne(new LambdaQueryWrapper().eq(Loc::getCode, task.getTargLoc())); if (Objects.isNull(loc)) { throw new CoolException("目标库位不存在!"); } if (!loc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_S.type)) { throw new CoolException("当前库位状态不处于S.入库预约,不可执行入库操作!"); } List taskItems = taskItemService.list(new LambdaQueryWrapper().eq(TaskItem::getTaskId, task.getId())); if (taskItems.isEmpty()) { throw new CoolException("任务明细不存在!!"); } try { //更新库位明细 saveLocItem(taskItems, task.getId()); } catch (Exception e) { throw new CoolException("库位明细更新失败!!"); } /**对任务明细按组拖明细进行分组*/ Map> orderMap = taskItems.stream().collect(Collectors.groupingBy(TaskItem::getSource)); orderMap.keySet().forEach(key -> { WaitPakinItem pakinItem = waitPakinItemService.getById(key); if (Objects.isNull(pakinItem)) { throw new CoolException("数据错误:组拖数据不存在,请联系管理员!!"); } List items = orderMap.get(key); try { //保存库存明细 saveStockItems(items, task, pakinItem.getId(), pakinItem.getAsnCode(), pakinItem.getWkType(), pakinItem.getType()); //移出收货区库存, 修改组托状态 removeReceiptStock(pakinItem); } catch (Exception e) { throw new CoolException(e.getMessage()); } }); /**修改库位状态为F.在库*/ if (!locService.update(new LambdaUpdateWrapper().set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_F.type).eq(Loc::getCode, task.getTargLoc()))) { throw new CoolException("库位状态修改失败!!"); } if (!this.update(new LambdaUpdateWrapper().eq(Task::getId, task.getId()).set(Task::getTaskStatus, TaskStsType.UPDATED_IN.id))) { throw new CoolException("任务状态修改失败!!"); } } /** * @param * @return * @author Ryan * @description 移除收货区库存 * @time 2025/4/30 16:32 */ @Transactional(rollbackFor = Exception.class) public void removeReceiptStock(WaitPakinItem pakinItem) { WarehouseAreasItem itemServiceOne = warehouseAreasItemService.getOne(new LambdaQueryWrapper() .eq(WarehouseAreasItem::getId, pakinItem.getSource())); if (Objects.isNull(itemServiceOne)) { throw new CoolException("数据错误:请查看请货区库存是否存在!!"); } Double workQty = Math.round((itemServiceOne.getWorkQty() - pakinItem.getAnfme()) * 10000) / 10000.0; Double qty = Math.round((itemServiceOne.getQty() + pakinItem.getAnfme()) * 10000) / 10000.0; itemServiceOne.setWorkQty(workQty).setQty(qty); if (!waitPakinService.update(new LambdaUpdateWrapper() .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_DONE.val) .eq(WaitPakin::getId, pakinItem.getPakinId()))) { throw new CoolException("组拖状态修改失败!!"); } if (qty.compareTo(itemServiceOne.getAnfme()) == 0.00) { if (!warehouseAreasItemService.removeById(itemServiceOne.getId())) { throw new CoolException("收货区物料删除失败!!"); } } else { if (!warehouseAreasItemService.updateById(itemServiceOne)) { throw new CoolException("收货区库完成数量修改失败!!"); } } } /** * @param * @return * @author Ryan * @description 更新库位明细 * @time 2025/4/15 15:28 */ @Transactional(rollbackFor = Exception.class) public void saveLocItem(List items, Long taskId) throws Exception { Task task = this.getById(taskId); if (Objects.isNull(task)) { throw new CoolException("任务不存在!!"); } List locItems = new ArrayList<>(); items.forEach(taskItem -> { Loc loc = locService.getOne(new LambdaQueryWrapper().eq(Loc::getCode, task.getTargLoc()), false); LocItem item = new LocItem(); BeanUtils.copyProperties(taskItem, item); item.setLocCode(loc.getCode()).setId(null) .setLocId(loc.getId()) .setWkType(taskItem.getWkType()) .setType(taskItem.getOrderType()); locItems.add(item); }); if (!locItemService.saveBatch(locItems)) { throw new CoolException("库位明细更新失败!!"); } } /** * 生成入库库存明细 * * @param items * @return */ @Transactional(rollbackFor = Exception.class) public void saveStockItems(List items, Task task, Long id, String code, Short wkType, String type) throws Exception { Stock stock = new Stock(); String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_STOCK_CODE, null); if (StringUtils.isBlank(ruleCode)) { throw new CoolException("当前业务:" + SerialRuleCode.SYS_STOCK_CODE + ",编码规则不存在!!"); } double sum = items.stream().mapToDouble(TaskItem::getAnfme).sum(); stock.setSourceId(id) .setCode(ruleCode) .setSourceCode(code) .setAnfme(sum) .setWkType(wkType) .setBarcode(task.getBarcode()) .setType(type); if (task.getTaskType().equals(TaskType.TASK_TYPE_IN.type) || task.getTaskType().equals(TaskType.TASK_TYPE_MERGE_IN.type) || task.getTaskType().equals(TaskType.TASK_TYPE_LOC_MOVE.type) || task.getTaskType().equals(TaskType.TASK_TYPE_EMPITY_IN.type) || task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_IN.type)) { stock.setLocCode(task.getTargLoc()); } else { stock.setLocCode(task.getOrgLoc()); } if (!stockService.save(stock)) { throw new CoolException("库存保存失败!!"); } List stockItems = new ArrayList<>(); for (TaskItem item : items) { /**通过任务明细中的taskId查询,获取TASK的目标库位信息*/ StockItem stockItem = new StockItem(); BeanUtils.copyProperties(item, stockItem); stockItem.setSourceItemId(item.getOrderItemId()) .setStockCode(stock.getCode()) .setBarcode(task.getBarcode()) .setSourceItemId(item.getOrderItemId()) .setId(null) .setStockId(stock.getId()); stockItems.add(stockItem); } if (!stockItemService.saveBatch(stockItems)) { throw new CoolException("库存修改架失败!!"); } } }