| | |
| | | } |
| | | })) |
| | | setData(val) |
| | | setTimeout(() => { |
| | | val.forEach((el) => { |
| | | jsbarcode(`#barcode${el.code}`, el.code, { height: 30 }); |
| | | }); |
| | | }, 10); |
| | | |
| | | |
| | | |
| | | } else { |
| | | notify(res.data.msg); |
| | | } |
| | |
| | | if (rows?.length > 0) { |
| | | http(); |
| | | } |
| | | |
| | | }, [rows]); |
| | | |
| | | // 在数据更新后生成条码 |
| | | useEffect(() => { |
| | | if (data.length > 0) { |
| | | // 等待DOM更新后再生成条码 |
| | | setTimeout(() => { |
| | | data.forEach((item) => { |
| | | const barcodeElement = document.getElementById(`barcode${item.code}`); |
| | | if (barcodeElement) { |
| | | try { |
| | | jsbarcode(`#barcode${item.code}`, item.code, { height: 30 }); |
| | | } catch (error) { |
| | | console.error(`生成条码失败: ${item.code}`, error); |
| | | } |
| | | } |
| | | }); |
| | | }, 100); |
| | | } |
| | | }, [data]); |
| | | |
| | | |
| | | return ( |
| | |
| | | colSpan={9} |
| | | style={{ border: '1px solid black' }} |
| | | > |
| | | {/* <img id={"barcode" + item.code} style={{ width: '70%', verticalAlign: 'middle' }} /> */} |
| | | <img className="template-code" src={item.barcode} style={{ width: '90%', verticalAlign: 'middle' }} alt="Barcode" /> |
| | | <img id={`barcode${item.code}`} style={{ width: '90%', verticalAlign: 'middle' }} alt="Barcode" /> |
| | | <div style={{ letterSpacing: '2px', marginTop: '1px', textAlign: 'center' }}> |
| | | <span>{item.code}</span> |
| | | </div> |
| | |
| | | empty={<EmptyData onClick={() => { setCreateDialog(true) }} />} |
| | | filters={filters} |
| | | sort={{ field: "warehouseId", order: "desc" }} |
| | | // disableSyncWithLocation={false} |
| | | actions={( |
| | | <TopToolbar> |
| | | <FilterButton /> |
| | |
| | | */ |
| | | @Override |
| | | public CommonResponse reportTask(TaskReportParams params) { |
| | | log.info("RCS回调,请求参数: {}", JSONObject.toJSONString(params)); |
| | | log.info("任务执行通知上报,请求参数: {}", JSONObject.toJSONString(params)); |
| | | |
| | | // 参数校验 |
| | | if (Objects.isNull(params)) { |
| | |
| | | |
| | | // 将任务上报回调转发到WMS系统 |
| | | String callUrl = wmsApi.getHost() + ":" + wmsApi.getPort() + WmsConstant.callBack; |
| | | log.info("RCS回调,请求地址: {}, 转换后参数: {}", callUrl, exMsgParams.toJSONString()); |
| | | log.info("任务执行通知上报,请求地址: {}, 转换后参数: {}", callUrl, exMsgParams.toJSONString()); |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | headers.add("Content-Type", "application/json"); |
| | | headers.add("api-version", "v2.0"); |
| | | HttpEntity httpEntity = new HttpEntity(exMsgParams, headers); |
| | | ResponseEntity<String> exchange = restTemplate.exchange(callUrl, HttpMethod.POST, httpEntity, String.class); |
| | | log.info("RCS回调,响应结果: {}", exchange); |
| | | log.info("任务执行通知上报,响应结果: {}", exchange); |
| | | |
| | | if (Objects.isNull(exchange.getBody())) { |
| | | // 如果回调失败,返回成功响应(避免RCS重复回调) |
| | | CommonResponse response = new CommonResponse(); |
| | | response.setCode(200); |
| | | response.setMsg("接收成功"); |
| | | log.warn("RCS回调失败,但返回成功响应,任务编号:{},批次:{}", params.getTaskNo(), params.getBatchNo()); |
| | | log.warn("任务执行通知上报回调失败,但返回成功响应,任务编号:{},批次:{}", params.getTaskNo(), params.getBatchNo()); |
| | | return response; |
| | | } else { |
| | | ObjectMapper objectMapper = new ObjectMapper(); |
| | |
| | | try { |
| | | CommonResponse result = objectMapper.readValue(exchange.getBody(), CommonResponse.class); |
| | | if (result.getCode() == 200) { |
| | | log.info("RCS回调上报成功,任务编号:{},批次:{}", params.getTaskNo(), params.getBatchNo()); |
| | | log.info("任务执行通知上报成功,任务编号:{},批次:{}", params.getTaskNo(), params.getBatchNo()); |
| | | return result; |
| | | } else { |
| | | log.warn("RCS回调上报回调返回非200状态,任务编号:{},批次:{},响应:{}", params.getTaskNo(), params.getBatchNo(), exchange.getBody()); |
| | | log.warn("任务执行通知上报回调返回非200状态,任务编号:{},批次:{},响应:{}", params.getTaskNo(), params.getBatchNo(), exchange.getBody()); |
| | | return result; |
| | | } |
| | | } catch (JsonProcessingException e) { |
| | | log.error("RCS回调上报回调响应解析失败,任务编号:{},批次:{},错误:{}", params.getTaskNo(), params.getBatchNo(), e.getMessage()); |
| | | log.error("任务执行通知上报回调响应解析失败,任务编号:{},批次:{},错误:{}", params.getTaskNo(), params.getBatchNo(), e.getMessage()); |
| | | // 解析失败时返回成功响应,避免RCS重复回调 |
| | | CommonResponse response = new CommonResponse(); |
| | | response.setCode(200); |
| | |
| | | throw new CoolException("请至少输入一个查询条件:物料编码、ASN单号、跟踪码、批次或票号"); |
| | | } |
| | | |
| | | // 如果扫描物料编码且ASN单号为空,直接从物料信息表获取,不查询收货区 |
| | | if (!Cools.isEmpty(matnrCode) && Cools.isEmpty(asnCode) && Cools.isEmpty(code) |
| | | && Cools.isEmpty(batch) && Objects.isNull(fieldIndex)) { |
| | | logger.info("=== 从物料信息表查询物料信息(不查询收货区) ==="); |
| | | logger.info("查询参数 - matnrCode: {}", matnrCode); |
| | | |
| | | Matnr matnr = matnrMapper.selectOne(new LambdaQueryWrapper<Matnr>() |
| | | .eq(Matnr::getCode, matnrCode) |
| | | .eq(Matnr::getDeleted, 0) |
| | | .last("LIMIT 1")); |
| | | |
| | | if (matnr == null) { |
| | | logger.warn("物料信息表中未找到物料编码: {}", matnrCode); |
| | | return R.ok(new ArrayList<>()); |
| | | } |
| | | |
| | | // 构造一个虚拟的 WarehouseAreasItem 对象返回物料信息 |
| | | WarehouseAreasItem item = new WarehouseAreasItem(); |
| | | item.setMatnrId(matnr.getId()); |
| | | item.setMatnrCode(matnr.getCode()); |
| | | item.setMaktx(matnr.getName()); |
| | | item.setStockUnit(matnr.getStockUnit()); |
| | | item.setUnit(matnr.getUnit()); |
| | | item.setAnfme(0.0); // 数量设为0,因为不是从收货区查询的 |
| | | item.setWorkQty(0.0); |
| | | item.setQty(0.0); |
| | | |
| | | // 设置扩展字段 |
| | | Map<String, String> fields = FieldsUtils.getFields(matnr.getFieldsIndex()); |
| | | item.setExtendFields(fields); |
| | | |
| | | List<WarehouseAreasItem> resultList = new ArrayList<>(); |
| | | resultList.add(item); |
| | | |
| | | logger.info("从物料信息表返回 1 条物料数据"); |
| | | return R.ok(resultList); |
| | | } |
| | | |
| | | //TODO 后续需根据策略配置,获取组拖数据。如:混装,按批次混装等 |
| | | LambdaQueryWrapper<WarehouseAreasItem> queryWrapper = new LambdaQueryWrapper<>(); |
| | | |
| | |
| | | logger.warn("数据库查询结果为空,可能原因:1.物料编码不匹配 2.物料未收货至收货区 3.数据已被删除"); |
| | | } |
| | | |
| | | // 如果扫描物料编码加载物料并且ASN单号为空时,从物料信息表获取物料信息并更新 |
| | | if (!Cools.isEmpty(matnrCode) && Cools.isEmpty(asnCode) && !list.isEmpty()) { |
| | | // 收集所有唯一的物料编码 |
| | | Set<String> matnrCodes = list.stream() |
| | | .map(WarehouseAreasItem::getMatnrCode) |
| | | .filter(matCode -> !Cools.isEmpty(matCode)) |
| | | .collect(Collectors.toSet()); |
| | | |
| | | // 批量查询物料信息 |
| | | if (!matnrCodes.isEmpty()) { |
| | | Map<String, Matnr> matnrMap = new HashMap<>(); |
| | | for (String matCode : matnrCodes) { |
| | | Matnr matnr = matnrMapper.selectOne(new LambdaQueryWrapper<Matnr>() |
| | | .eq(Matnr::getCode, matCode) |
| | | .eq(Matnr::getDeleted, 0) |
| | | .last("LIMIT 1")); |
| | | if (matnr != null) { |
| | | matnrMap.put(matCode, matnr); |
| | | } |
| | | } |
| | | |
| | | // 更新列表中的物料信息 |
| | | list.forEach(item -> { |
| | | String itemMatnrCode = item.getMatnrCode(); |
| | | if (!Cools.isEmpty(itemMatnrCode) && matnrMap.containsKey(itemMatnrCode)) { |
| | | Matnr matnr = matnrMap.get(itemMatnrCode); |
| | | // 从物料信息表更新物料名称 |
| | | if (!Cools.isEmpty(matnr.getName())) { |
| | | item.setMaktx(matnr.getName()); |
| | | } |
| | | // 从物料信息表更新库存单位 |
| | | if (!Cools.isEmpty(matnr.getStockUnit())) { |
| | | item.setStockUnit(matnr.getStockUnit()); |
| | | } |
| | | // 从物料信息表更新单位 |
| | | if (!Cools.isEmpty(matnr.getUnit())) { |
| | | item.setUnit(matnr.getUnit()); |
| | | } |
| | | logger.debug("已从物料信息表更新物料信息 - matnrCode: {}, name: {}, stockUnit: {}", |
| | | itemMatnrCode, matnr.getName(), matnr.getStockUnit()); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | |
| | | list.forEach(item -> { |
| | | Map<String, String> fields = FieldsUtils.getFields(item.getFieldsIndex()); |
| | | item.setExtendFields(fields); |
| | |
| | | log.warn("未处理的事件类型 - 事件类型:{},任务编码:{},任务类型:{}", |
| | | params.getEventType(), task.getTaskCode(), task.getTaskType()); |
| | | } |
| | | log.info("========== RCS回调处理完成 =========="); |
| | | log.info("========== 任务执行通知上报处理完成 =========="); |
| | | log.info("处理结果:{}", JSONObject.toJSONString(params)); |
| | | return R.ok(JSONObject.toJSONString(params)); |
| | | } |
| | |
| | | if (task.getTaskType().equals(TaskType.TASK_TYPE_IN.type)) { |
| | | //1.入库 |
| | | complateInstock(task, loginUserId); |
| | | } else if (task.getTaskType().equals(TaskType.TASK_TYPE_EMPITY_IN.type)) { |
| | | //10.空托入库 |
| | | complateEmpityInStock(task, loginUserId); |
| | | } else if (task.getTaskType().equals(TaskType.TASK_TYPE_PICK_IN.type) || task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_IN.type)) { |
| | | //53.拣料再入库 |
| | | //57.盘点再入库 |
| | |
| | | .set(WaitPakin::getUpdateBy, loginUserId) |
| | | .in(WaitPakin::getId, pakinIds))) { |
| | | throw new CoolException("组拖状态修改失败!!"); |
| | | } |
| | | |
| | | /**修改库位状态为F.在库*/ |
| | | if (!locService.update(new LambdaUpdateWrapper<Loc>().set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_F.type).eq(Loc::getCode, task.getTargLoc()))) { |
| | | throw new CoolException("库位状态修改失败!!"); |
| | | } |
| | | if (!this.update(new LambdaUpdateWrapper<Task>().eq(Task::getId, task.getId()).set(Task::getTaskStatus, TaskStsType.UPDATED_IN.id))) { |
| | | throw new CoolException("任务状态修改失败!!"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 空托入库完成 |
| | | * |
| | | * @param task |
| | | * @param loginUserId |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public synchronized void complateEmpityInStock(Task task, Long loginUserId) { |
| | | if (Objects.isNull(task)) { |
| | | return; |
| | | } |
| | | |
| | | Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().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<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId())); |
| | | if (taskItems.isEmpty()) { |
| | | throw new CoolException("任务明细不存在!!"); |
| | | } |
| | | |
| | | //更新库位明细 |
| | | saveLocItem(taskItems, task.getId(), loginUserId); |
| | | |
| | | //空托入库不校验组托信息,直接处理任务明细 |
| | | //如果有任务明细关联了组托,也需要保存入出库明细和移出收货区库存 |
| | | Map<Long, List<TaskItem>> orderMap = taskItems.stream().collect(Collectors.groupingBy(TaskItem::getSource)); |
| | | orderMap.keySet().forEach(key -> { |
| | | // 如果source不为空,说明有关联的组托明细,需要处理 |
| | | if (key != null && key > 0) { |
| | | WaitPakinItem pakinItem = waitPakinItemService.getById(key); |
| | | if (!Objects.isNull(pakinItem)) { |
| | | List<TaskItem> items = orderMap.get(key); |
| | | //保存入出库明细 |
| | | saveStockItems(items, task, pakinItem.getId(), pakinItem.getAsnCode(), pakinItem.getWkType(), pakinItem.getType(), loginUserId); |
| | | //移出收货区库存, 修改组托状态 |
| | | removeReceiptStock(pakinItem, loginUserId); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | // 处理组托状态(如果有组托关联) |
| | | Set<Long> pkinItemIds = taskItems.stream() |
| | | .map(TaskItem::getSource) |
| | | .filter(source -> source != null && source > 0) |
| | | .collect(Collectors.toSet()); |
| | | |
| | | if (!pkinItemIds.isEmpty()) { |
| | | List<WaitPakinItem> pakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>().in(WaitPakinItem::getId, pkinItemIds)); |
| | | if (!pakinItems.isEmpty()) { |
| | | Set<Long> pakinIds = pakinItems.stream().map(WaitPakinItem::getPakinId).collect(Collectors.toSet()); |
| | | if (!waitPakinService.update(new LambdaUpdateWrapper<WaitPakin>() |
| | | .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_DONE.val) |
| | | .set(WaitPakin::getUpdateBy, loginUserId) |
| | | .in(WaitPakin::getId, pakinIds))) { |
| | | throw new CoolException("组拖状态修改失败!!"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /**修改库位状态为F.在库*/ |
| | |
| | | import com.vincent.rsf.server.manager.entity.*; |
| | | import com.vincent.rsf.server.manager.enums.PakinIOStatus; |
| | | import com.vincent.rsf.server.manager.mapper.WaitPakinMapper; |
| | | import com.vincent.rsf.server.manager.mapper.MatnrMapper; |
| | | import com.vincent.rsf.server.manager.service.*; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.vincent.rsf.server.system.constant.SerialRuleCode; |
| | |
| | | private TaskService taskService; |
| | | @Autowired |
| | | private TaskItemService taskItemService; |
| | | @Autowired |
| | | private MatnrMapper matnrMapper; |
| | | |
| | | |
| | | /** |
| | |
| | | WaitPakin pakin = waitPakinService.getOne(new LambdaQueryWrapper<WaitPakin>() |
| | | .eq(WaitPakin::getBarcode, waitPakin.getBarcode())); |
| | | |
| | | // 如果容器号已经组托过,提示已组托,请更换容器条码 |
| | | if (!Objects.isNull(pakin)) { |
| | | throw new CoolException("已组托,请更换容器条码"); |
| | | } |
| | | |
| | | List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>().eq(Task::getBarcode, waitPakin.getBarcode())); |
| | | if (!tasks.isEmpty()) { |
| | | throw new CoolException("当前托盘已有任务档在执行,不能再次组托!!"); |
| | | } |
| | | if (!Objects.isNull(pakin)) { |
| | | List<WaitPakinItem> waitPakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>().eq(!Objects.isNull(pakin.getId()) ,WaitPakinItem::getPakinId, pakin.getId())); |
| | | waitPakinItems.forEach(item -> { |
| | | for (PakinItem pakinItem : waitPakin.getItems()) { |
| | | WarehouseAreasItem warehouseAreasItems = warehouseAreasItemService.getById(pakinItem.getId()); |
| | | if (Objects.isNull(warehouseAreasItems)) { |
| | | throw new CoolException("物料未送至收货区或已组托完成移出收货区!!"); |
| | | } |
| | | // 只在票号不为空时才进行重复检查 |
| | | if (!Objects.isNull(item.getFieldsIndex()) && !Objects.isNull(warehouseAreasItems.getFieldsIndex()) |
| | | && item.getFieldsIndex().equals(warehouseAreasItems.getFieldsIndex())) { |
| | | String crushNo = item.getExtendFields() != null ? item.getExtendFields().get("crushNo") : ""; |
| | | throw new CoolException("票号:" + crushNo + "已组托,不可重复组托!!"); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | |
| | | // 检查容器号是否在库存中存在(通过库位表查询) |
| | | List<Loc> locs = locService.list(new LambdaQueryWrapper<Loc>().eq(Loc::getBarcode, waitPakin.getBarcode())); |
| | | if (!locs.isEmpty()) { |
| | | List<String> locCodes = locs.stream().map(Loc::getCode).collect(Collectors.toList()); |
| | | String join = StringUtils.join(locCodes, ","); |
| | | throw new CoolException("托盘码:" + waitPakin.getBarcode() + "已被库位:" + join + "使用!!"); |
| | | throw new CoolException("在库,请更换容器条码"); |
| | | } |
| | | |
| | | double sum = waitPakin.getItems().stream().mapToDouble(PakinItem::getReceiptQty).sum(); |
| | | |
| | | WaitPakin waitPakin1 = new WaitPakin(); |
| | |
| | | |
| | | List<WaitPakinItem> items = new ArrayList<>(); |
| | | for (PakinItem pakinItem1 : waitPakin.getItems()) { |
| | | //不良标签组托 |
| | | WaitPakinItem pakinItem = new WaitPakinItem(); |
| | | |
| | | // 如果ASN单号为空,从物料信息表获取物料信息,不查询收货区 |
| | | if (StringUtils.isBlank(pakinItem1.getAsnCode())) { |
| | | if (Objects.isNull(pakinItem1.getMatnrId())) { |
| | | throw new CoolException("物料ID不能为空!!"); |
| | | } |
| | | |
| | | // 从物料信息表获取物料信息 |
| | | Matnr matnr = matnrMapper.selectById(pakinItem1.getMatnrId()); |
| | | if (Objects.isNull(matnr)) { |
| | | throw new CoolException("物料信息不存在,物料ID:" + pakinItem1.getMatnrId()); |
| | | } |
| | | |
| | | // 设置组托明细信息(不设置source,因为不在收货区) |
| | | pakinItem.setPakinId(waitPakin1.getId()) |
| | | .setSource(null) // 不在收货区,source设为null |
| | | .setAsnId(null) |
| | | .setAsnCode(null) |
| | | .setAsnItemId(null) |
| | | .setIsptResult(null) |
| | | .setPlatItemId(null) |
| | | .setPlatOrderCode(null) |
| | | .setPlatWorkCode(null) |
| | | .setProjectCode(null) |
| | | .setBatch(null) |
| | | .setUnit(matnr.getStockUnit()) |
| | | .setFieldsIndex(matnr.getFieldsIndex()) |
| | | .setMatnrId(matnr.getId()) |
| | | .setMaktx(matnr.getName()) |
| | | .setUpdateBy(userId) |
| | | .setCreateBy(userId) |
| | | .setMatnrCode(matnr.getCode()); |
| | | |
| | | // 设置组托数量 |
| | | if (pakinItem1.getReceiptQty() == null || pakinItem1.getReceiptQty().compareTo(0.0) <= 0) { |
| | | throw new CoolException("组托数量不能小于等于零!!"); |
| | | } |
| | | pakinItem.setAnfme(pakinItem1.getReceiptQty()) |
| | | .setTrackCode(pakinItem1.getTrackCode()); |
| | | } else { |
| | | // 有ASN单号,从收货区获取物料信息 |
| | | WarehouseAreasItem warehouseAreasItems = warehouseAreasItemService.getById(pakinItem1.getId()); |
| | | if (null == warehouseAreasItems) { |
| | | throw new CoolException("物料未送至收货区!!"); |
| | | } |
| | | WaitPakinItem pakinItem = new WaitPakinItem(); |
| | | |
| | | pakinItem.setAnfme(warehouseAreasItems.getAnfme()) |
| | | .setPakinId(waitPakin1.getId()) |
| | | .setSource(warehouseAreasItems.getId()) |
| | |
| | | .setUpdateBy(userId) |
| | | .setCreateBy(userId) |
| | | .setMatnrCode(warehouseAreasItems.getMatnrCode()); |
| | | |
| | | WkOrder order = asnOrderService.getById(warehouseAreasItems.getAsnId()); |
| | | if (!Objects.isNull(order)) { |
| | | pakinItem.setType(null == order.getType() ? null : order.getType()) |
| | |
| | | .setTrackCode(waitPakinItem.getTrackCode()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | items.add(pakinItem); |
| | | } |
| | | |
| | |
| | | // Double total = Math.round((sum + waitSum) * 100) / 100.0; |
| | | |
| | | for (WaitPakinItem pakinItem : items) { |
| | | // 如果source为空(没有ASN单号,不在收货区),跳过收货区更新 |
| | | if (Objects.isNull(pakinItem.getSource())) { |
| | | continue; |
| | | } |
| | | |
| | | WarehouseAreasItem one = warehouseAreasItemService.getOne(new LambdaQueryWrapper<WarehouseAreasItem>() |
| | | .eq(WarehouseAreasItem::getId, pakinItem.getSource())); |
| | | if (Objects.isNull(one)) { |