自动化立体仓库 - WMS系统
lty
17 小时以前 f08dd93e49e8461f362c8f45f17fe10e0fbdebec
src/main/java/com/zy/asrs/task/kingdee/handler/AutoTransferHandler.java
@@ -1,5 +1,6 @@
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.*;
@@ -44,52 +45,55 @@
    @Transactional(rollbackFor = Exception.class)
    public ReturnT<String> start(OrderPakin order) {
        JSONObject logData = new JSONObject();
        String responseMsg = "";
        boolean success = false;
        try {
            logData.put("orderNo", order.getOrderNo());
            logData.put("docType", order.getDocType());
            logData.put("settle", order.getSettle());
            logData.put("startTime", System.currentTimeMillis());
        // 获取该订单下的所有明细
        List<OrderDetlPakin> orderDetlPakins = orderDetlPakinService.selectList(
                new EntityWrapper<OrderDetlPakin>().eq("order_no", order.getOrderNo()));
        // 遍历每个订单明细进行库存转换
            if (orderDetlPakins.isEmpty()) {
                throw new IllegalArgumentException("订单 " + order.getOrderNo() + " 无任何明细,无法转换");
            }
            // 遍历每个订单明细进行库存转换(原逻辑保持不变)
        for (OrderDetlPakin orderDetlPakin : orderDetlPakins) {
            double orderQuantity = orderDetlPakin.getAnfme(); // 本明细需要转换的数量
            double remainingQuantity = orderQuantity;        // 剩余未满足的数量
            double convertedQuantity = 0.0;                  // 已成功转换的数量
                double orderQuantity = orderDetlPakin.getAnfme();
                double remainingQuantity = orderQuantity;
                double convertedQuantity = 0.0;
            log.info("开始处理订单明细: 订单号 = {}, 物料号 = {}, 需要转换数量 = {}",
                    order.getOrderNo(), orderDetlPakin.getMatnr(), orderQuantity);
            // 查询符合条件的可用库存:同一物料 + box_type3 以 HDU25 开头
            List<LocDetl> locDetls = locDetlService.selectList(
                    new EntityWrapper<LocDetl>()
                            .eq("matnr", orderDetlPakin.getMatnr())
                            .like("box_type3", "HDU25%")
                            .orderBy("anfme") // 可根据业务调整排序(如先进先出)
                                .like("box_type3", "HDU%")
                                .orderBy("anfme")
            );
            if (locDetls.isEmpty()) {
                log.error("无符合条件的库存: 订单 {} 物料 {}", order.getOrderNo(), orderDetlPakin.getMatnr());
                throw new IllegalArgumentException("无符合条件的库存满足订单 " + order.getOrderNo() +
                        " 的物料 " + orderDetlPakin.getMatnr());
                    throw new IllegalArgumentException("无符合条件的库存: 订单 " + order.getOrderNo() +
                            " 物料 " + orderDetlPakin.getMatnr());
            }
            // 逐条消耗库存
            for (LocDetl locDetl : locDetls) {
                if (remainingQuantity <= 0) {
                    break; // 已完全满足需求
                }
                    if (remainingQuantity <= 0) break;
                double stockQty = locDetl.getAnfme();
                if (stockQty <= 0) {
                    continue; // 跳过空库存
                }
                    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());
@@ -99,50 +103,76 @@
                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);
                        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()));
                    log.info("原库存部分消耗,更新剩余数量: 位置={}, 剩余={}", locDetl.getLocNo(), 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;
            }
            // 检查是否完全满足该明细的需求
            if (remainingQuantity > 0) {
                log.error("库存不足: 订单 {} 物料 {} 需求 {},仅转换 {},缺少 {}",
                        order.getOrderNo(), orderDetlPakin.getMatnr(), orderQuantity, convertedQuantity, remainingQuantity);
                throw new IllegalArgumentException("库存不足以满足订单 " + order.getOrderNo() +
                        " 的物料 " + orderDetlPakin.getMatnr() + " 需求,缺少 " + remainingQuantity);
                    throw new IllegalArgumentException("库存不足: 订单 " + order.getOrderNo() +
                            " 物料 " + orderDetlPakin.getMatnr() + " 缺少 " + remainingQuantity);
            }
            // 更新订单明细已转换数量
            orderDetlPakin.setQty(convertedQuantity);
            orderDetlPakinService.updateById(orderDetlPakin);
            log.info("订单明细转换完成: 订单号 = {}, 物料号 = {}, 转换数量 = {}",
                    order.getOrderNo(), orderDetlPakin.getMatnr(), convertedQuantity);
        }
        // 所有明细均处理完成,设置订单 settle = 67
            // 全部成功
        order.setSettle(67L);
        orderPakinServiceImpl.updateById(order);
        log.info("订单全部明细转换完成,设置 settle = 67,订单号 = {}", order.getOrderNo());
        return SUCCESS;
            success = true;
            responseMsg = "库存转换成功,订单号: " + order.getOrderNo() + ",已设置 settle=67";
            log.info(responseMsg);
        } 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);
        }
        return success ? SUCCESS : FAIL;
    }
    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);
        }
    }
}