| | |
| | | package com.zy.asrs.task.kingdee.handler; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.mapper.EntityWrapper; |
| | | import com.zy.asrs.entity.*; |
| | | import com.zy.asrs.service.*; |
| | |
| | | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public ReturnT<String> start(OrderPakin order) { |
| | | // 获取该订单下的所有明细 |
| | | List<OrderDetlPakin> orderDetlPakins = orderDetlPakinService.selectList( |
| | | new EntityWrapper<OrderDetlPakin>().eq("order_no", order.getOrderNo())); |
| | | JSONObject logData = new JSONObject(); |
| | | String responseMsg = ""; |
| | | boolean success = false; |
| | | |
| | | // 遍历每个订单明细进行库存转换 |
| | | for (OrderDetlPakin orderDetlPakin : orderDetlPakins) { |
| | | double orderQuantity = orderDetlPakin.getAnfme(); // 本明细需要转换的数量 |
| | | double remainingQuantity = orderQuantity; // 剩余未满足的数量 |
| | | double convertedQuantity = 0.0; // 已成功转换的数量 |
| | | try { |
| | | logData.put("orderNo", order.getOrderNo()); |
| | | logData.put("docType", order.getDocType()); |
| | | logData.put("settle", order.getSettle()); |
| | | logData.put("startTime", System.currentTimeMillis()); |
| | | |
| | | log.info("开始处理订单明细: 订单号 = {}, 物料号 = {}, 需要转换数量 = {}", |
| | | order.getOrderNo(), orderDetlPakin.getMatnr(), orderQuantity); |
| | | // 获取该订单下的所有明细 |
| | | List<OrderDetlPakin> orderDetlPakins = orderDetlPakinService.selectList( |
| | | new EntityWrapper<OrderDetlPakin>().eq("order_no", order.getOrderNo())); |
| | | |
| | | // 查询符合条件的可用库存:同一物料 + box_type3 以 HDU25 开头 |
| | | List<LocDetl> locDetls = locDetlService.selectList( |
| | | new EntityWrapper<LocDetl>() |
| | | .eq("matnr", orderDetlPakin.getMatnr()) |
| | | .like("box_type3", "HDU25%") |
| | | .orderBy("anfme") // 可根据业务调整排序(如先进先出) |
| | | ); |
| | | |
| | | if (locDetls.isEmpty()) { |
| | | log.error("无符合条件的库存: 订单 {} 物料 {}", order.getOrderNo(), orderDetlPakin.getMatnr()); |
| | | throw new IllegalArgumentException("无符合条件的库存满足订单 " + order.getOrderNo() + |
| | | " 的物料 " + orderDetlPakin.getMatnr()); |
| | | if (orderDetlPakins.isEmpty()) { |
| | | throw new IllegalArgumentException("订单 " + order.getOrderNo() + " 无任何明细,无法转换"); |
| | | } |
| | | |
| | | // 逐条消耗库存 |
| | | for (LocDetl locDetl : locDetls) { |
| | | if (remainingQuantity <= 0) { |
| | | break; // 已完全满足需求 |
| | | // 遍历每个订单明细进行库存转换(原逻辑保持不变) |
| | | for (OrderDetlPakin orderDetlPakin : orderDetlPakins) { |
| | | double orderQuantity = orderDetlPakin.getAnfme(); |
| | | double remainingQuantity = orderQuantity; |
| | | double convertedQuantity = 0.0; |
| | | |
| | | log.info("开始处理订单明细: 订单号={}, 物料号={}, 需要转换数量={}", |
| | | order.getOrderNo(), orderDetlPakin.getMatnr(), orderQuantity); |
| | | |
| | | List<LocDetl> locDetls = locDetlService.selectList( |
| | | new EntityWrapper<LocDetl>() |
| | | .eq("matnr", orderDetlPakin.getMatnr()) |
| | | .like("box_type3", "HDU%") |
| | | .orderBy("anfme") |
| | | ); |
| | | |
| | | if (locDetls.isEmpty()) { |
| | | throw new IllegalArgumentException("无符合条件的库存: 订单 " + order.getOrderNo() + |
| | | " 物料 " + orderDetlPakin.getMatnr()); |
| | | } |
| | | |
| | | double stockQty = locDetl.getAnfme(); |
| | | if (stockQty <= 0) { |
| | | continue; // 跳过空库存 |
| | | for (LocDetl locDetl : locDetls) { |
| | | if (remainingQuantity <= 0) break; |
| | | double stockQty = locDetl.getAnfme(); |
| | | if (stockQty <= 0) continue; |
| | | |
| | | double consumeQty = Math.min(stockQty, remainingQuantity); |
| | | |
| | | // 创建分配记录... |
| | | LocDetl allocated = new LocDetl(); |
| | | BeanUtils.copyProperties(locDetl, allocated); |
| | | allocated.setAnfme(consumeQty); |
| | | allocated.setStandby1(orderDetlPakin.getStandby1()); |
| | | allocated.setStandby2(orderDetlPakin.getStandby2()); |
| | | allocated.setStandby3(orderDetlPakin.getStandby3()); |
| | | allocated.setBoxType1(orderDetlPakin.getBoxType1()); |
| | | allocated.setBoxType2(orderDetlPakin.getBoxType2()); |
| | | allocated.setBoxType3(orderDetlPakin.getBoxType3()); |
| | | allocated.setOrderNo(orderDetlPakin.getOrderNo()); |
| | | |
| | | locDetlService.insert(allocated); |
| | | |
| | | // 扣减原库存... |
| | | double remainingStock = stockQty - consumeQty; |
| | | if (remainingStock <= 0) { |
| | | locDetlService.delete(new EntityWrapper<LocDetl>() |
| | | .eq("loc_no", locDetl.getLocNo()) |
| | | .eq("matnr", locDetl.getMatnr()) |
| | | .eq("box_type3", locDetl.getBoxType3())); |
| | | } else { |
| | | locDetl.setAnfme(remainingStock); |
| | | locDetlService.update(locDetl, new EntityWrapper<LocDetl>() |
| | | .eq("loc_no", locDetl.getLocNo()) |
| | | .eq("matnr", locDetl.getMatnr()) |
| | | .eq("box_type3", locDetl.getBoxType3())); |
| | | } |
| | | |
| | | convertedQuantity += consumeQty; |
| | | remainingQuantity -= consumeQty; |
| | | } |
| | | |
| | | // 本次实际消耗的数量 |
| | | double consumeQty = Math.min(stockQty, remainingQuantity); |
| | | |
| | | // 创建一条新的“已分配给订单”的库存记录(完整复制原记录) |
| | | LocDetl allocated = new LocDetl(); |
| | | BeanUtils.copyProperties(locDetl, allocated); |
| | | |
| | | // 设置分配数量 + 覆盖指定字段 |
| | | allocated.setAnfme(consumeQty); |
| | | allocated.setStandby1(orderDetlPakin.getStandby1()); |
| | | allocated.setStandby2(orderDetlPakin.getStandby2()); |
| | | allocated.setStandby3(orderDetlPakin.getStandby3()); |
| | | allocated.setBoxType1(orderDetlPakin.getBoxType1()); |
| | | allocated.setBoxType2(orderDetlPakin.getBoxType2()); |
| | | allocated.setBoxType3(orderDetlPakin.getBoxType3()); |
| | | allocated.setOrderNo(orderDetlPakin.getOrderNo()); |
| | | |
| | | // 插入已分配记录 |
| | | locDetlService.insert(allocated); |
| | | log.info("已分配库存记录: 位置={}, 数量={}, 剩余需求={}", |
| | | locDetl.getLocNo(), consumeQty, remainingQuantity - consumeQty); |
| | | |
| | | // 处理原库存记录:扣减后数量为0则删除,否则更新剩余数量 |
| | | double remainingStock = stockQty - consumeQty; |
| | | if (remainingStock <= 0) { |
| | | // 数量正好耗尽或已为0,直接删除原记录 |
| | | locDetlService.delete(new EntityWrapper<LocDetl>().eq("loc_no",locDetl.getLocNo()).eq("matnr",locDetl.getMatnr()).eq("box_type3",locDetl.getBoxType3())); |
| | | log.info("原库存已耗尽,删除记录: 位置={}, 原数量={}", locDetl.getLocNo(), stockQty); |
| | | } else { |
| | | // 仍有剩余,更新数量 |
| | | locDetl.setAnfme(remainingStock); |
| | | locDetlService.update(locDetl,new EntityWrapper<LocDetl>().eq("loc_no",locDetl.getLocNo()).eq("matnr",locDetl.getMatnr()).eq("box_type3",locDetl.getBoxType3())); |
| | | log.info("原库存部分消耗,更新剩余数量: 位置={}, 剩余={}", locDetl.getLocNo(), remainingStock); |
| | | if (remainingQuantity > 0) { |
| | | throw new IllegalArgumentException("库存不足: 订单 " + order.getOrderNo() + |
| | | " 物料 " + orderDetlPakin.getMatnr() + " 缺少 " + remainingQuantity); |
| | | } |
| | | |
| | | // 更新统计量 |
| | | convertedQuantity += consumeQty; |
| | | remainingQuantity -= consumeQty; |
| | | orderDetlPakin.setQty(convertedQuantity); |
| | | orderDetlPakinService.updateById(orderDetlPakin); |
| | | } |
| | | |
| | | // 检查是否完全满足该明细的需求 |
| | | if (remainingQuantity > 0) { |
| | | log.error("库存不足: 订单 {} 物料 {} 需求 {},仅转换 {},缺少 {}", |
| | | order.getOrderNo(), orderDetlPakin.getMatnr(), orderQuantity, convertedQuantity, remainingQuantity); |
| | | throw new IllegalArgumentException("库存不足以满足订单 " + order.getOrderNo() + |
| | | " 的物料 " + orderDetlPakin.getMatnr() + " 需求,缺少 " + remainingQuantity); |
| | | } |
| | | // 全部成功 |
| | | order.setSettle(67L); |
| | | orderPakinServiceImpl.updateById(order); |
| | | |
| | | // 更新订单明细已转换数量 |
| | | orderDetlPakin.setQty(convertedQuantity); |
| | | orderDetlPakinService.updateById(orderDetlPakin); |
| | | success = true; |
| | | responseMsg = "库存转换成功,订单号: " + order.getOrderNo() + ",已设置 settle=67"; |
| | | log.info(responseMsg); |
| | | |
| | | log.info("订单明细转换完成: 订单号 = {}, 物料号 = {}, 转换数量 = {}", |
| | | order.getOrderNo(), orderDetlPakin.getMatnr(), convertedQuantity); |
| | | } catch (Exception e) { |
| | | success = false; |
| | | responseMsg = "库存转换失败: " + e.getMessage(); |
| | | log.error("自动转换失败,订单号: {}, 原因: {}", order.getOrderNo(), e.getMessage(), e); |
| | | |
| | | throw e; // 让 @Transactional 回滚 |
| | | } finally { |
| | | // 无论成功失败,都记录日志 |
| | | logData.put("endTime", System.currentTimeMillis()); |
| | | logData.put("durationMs", logData.getLongValue("endTime") - logData.getLongValue("startTime")); |
| | | logData.put("success", success); |
| | | logData.put("message", responseMsg); |
| | | |
| | | saveApiLog(logData, responseMsg, success); |
| | | } |
| | | |
| | | // 所有明细均处理完成,设置订单 settle = 67 |
| | | order.setSettle(67L); |
| | | orderPakinServiceImpl.updateById(order); |
| | | log.info("订单全部明细转换完成,设置 settle = 67,订单号 = {}", order.getOrderNo()); |
| | | return success ? SUCCESS : FAIL; |
| | | } |
| | | |
| | | return SUCCESS; |
| | | private void saveApiLog(JSONObject add, String response, boolean success) { |
| | | try { |
| | | apiLogService.save( |
| | | "货主转换", |
| | | "AutoTransferHandler", |
| | | null, |
| | | "127.0.0.1", |
| | | add.toJSONString(), |
| | | response, |
| | | success |
| | | ); |
| | | } catch (Exception e) { |
| | | log.error("接口日志保存失败", e); |
| | | } |
| | | } |
| | | } |