package com.gs.xky.service; import cn.hutool.core.collection.CollUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.gs.xky.config.ApiResponse; import com.gs.xky.config.DataAcquisitionConfiguration; import com.gs.xky.config.PurchaseParam; import com.gs.xky.config.XkyCommonParam; import com.gs.xky.entity.MesRohInData; import com.gs.xky.entity.PurchaseOrderCompare; import com.gs.xky.entity.PurchaseOrderDetail; import com.gs.xky.mapper.PurchaseOrderCompareMapper; import lombok.RequiredArgsConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.IOException; import java.util.Date; import java.util.List; @Service @Transactional(rollbackFor = Exception.class) @RequiredArgsConstructor public class PurchaseService { private static final Logger log = LoggerFactory.getLogger(PurchaseService.class); private final ApiService apiService; private final MesRohInDataService mesRohInDataService; private final PurchaseOrderDetailService purchaseOrderDetailService; private final PurchaseOrderCompareMapper purchaseOrderCompareMapper; /** * 同步采购订单明细数据 * 从第三方接口获取采购订单明细数据并保存到本地数据库 * 注意:该接口有以下限制: * 1. 访问频率不能低于2小时 * 2. 一次请求中时间范围不能大于24小时 * * @throws IOException 接口调用异常 */ public void syncPurchaseOrderDetails() throws IOException { long currentTimeMillis = System.currentTimeMillis(); // 限制请求时间范围为24小时 long startDate = currentTimeMillis - (24 * 60 * 60 * 1000L); XkyCommonParam param = XkyCommonParam.GetInit(); PurchaseParam bodyParam = new PurchaseParam(); bodyParam.setStartTime(startDate); bodyParam.setEndTime(currentTimeMillis); bodyParam.setErpCode(DataAcquisitionConfiguration.TEST_ERP_CODE); // 查询所有状态的订单 // bodyParam.setOrderStatusList(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}); bodyParam.setPurchaseTypeList(new int[]{1}); param.setBody(bodyParam); log.info("【syncPurchaseOrderDetails】开始同步采购订单数据,时间范围:{} 至 {}", startDate, currentTimeMillis); // 调用采购订单明细接口 ApiResponse response = apiService.sendListRequest( param, PurchaseOrderDetail.class, "https://openapi.xiekeyun.com/purchase/report/list.json" ); List orderDetails = response.getDataList(); if (CollUtil.isEmpty(orderDetails)) { log.info("【syncPurchaseOrderDetails】返回列表为空,跳过处理"); return; } log.info("【syncPurchaseOrderDetails】获取到{}条采购订单数据", orderDetails.size()); // 处理采购订单明细数据 orderDetails.forEach(detail -> { try { // 根据有效标志和订单状态处理不同的业务逻辑 if (detail.getValidFlag() != null && detail.getValidFlag() == 0) { log.info("【syncPurchaseOrderDetails】无效订单,跳过处理: {}", detail.getPoErpNo()); return; } // 获取项次前面的编号部分 String linePrefix = extractLinePrefix(detail.getLineNo()); log.info("【syncPurchaseOrderDetails】项次前缀: {}", linePrefix); // 查询ERP系统中对应的采购订单数据 LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(MesRohInData::getBillNo, detail.getPoErpNo()) .eq(MesRohInData::getOrderLineId, linePrefix); // 获取ERP数据 MesRohInData erpData = mesRohInDataService.getOne(wrapper, false); if (erpData == null) { log.info("【syncPurchaseOrderDetails】未找到对应的ERP数据,订单号: {}, 项次: {}", detail.getPoErpNo(), linePrefix); // 创建一个包含"暂无数据"值的比对记录 savePurchaseOrderCompare(detail, null); } else { // 记录比对结果 savePurchaseOrderCompare(detail, erpData); } // 保存SRM采购订单明细 savePurchaseOrderDetail(detail); } catch (Exception e) { log.error("【syncPurchaseOrderDetails 处理异常】订单号: {}, 项次: {}, 异常: {}", detail.getPoErpNo(), detail.getLineNo(), e.getMessage(), e); throw new RuntimeException(e); } }); } /** * 从lineNo中提取前缀部分 * 例如:从"10-1"中提取出"10" * * @param lineNo 项次编号,格式如"10-1" * @return 项次前缀,如"10" */ private String extractLinePrefix(String lineNo) { if (lineNo == null || lineNo.isEmpty()) { return ""; } // 使用"-"分割字符串 String[] parts = lineNo.split("-"); if (parts.length > 0) { return parts[0]; // 返回第一部分 } // 如果没有"-",则返回原字符串 return lineNo; } /** * 保存ERP与SRM采购订单数据比对结果 * * @param detail SRM采购订单明细 * @param erpData ERP采购订单数据(可能为null) */ private void savePurchaseOrderCompare(PurchaseOrderDetail detail, MesRohInData erpData) { String linePrefix = extractLinePrefix(detail.getLineNo()); // 查询是否已存在比对记录 LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(PurchaseOrderCompare::getBillNo, detail.getPoErpNo()) .eq(PurchaseOrderCompare::getLineNo, detail.getLineNo()); PurchaseOrderCompare compareData = purchaseOrderCompareMapper.selectOne(wrapper); if (compareData == null) { // 创建新的比对记录 compareData = new PurchaseOrderCompare(); compareData.setBillNo(detail.getPoErpNo()); compareData.setOrderLineId(linePrefix); compareData.setLineNo(detail.getLineNo()); compareData.setProductCode(detail.getProductCode()); compareData.setProductName(detail.getProductName()); compareData.setCreateTime(new Date()); } // 计算SRM待收数量 Integer srmPurchaseQty = detail.getTotalAnswerQty(); Integer srmReceivedQty = detail.getTotalReceiveQty(); Integer srmWaitReceiveQty = srmPurchaseQty - srmReceivedQty; // 设置SRM数据 compareData.setSrmPurchaseQty(srmPurchaseQty); compareData.setSrmReceivedQty(srmReceivedQty); compareData.setSrmWaitReceiveQty(srmWaitReceiveQty); // 设置ERP数据和差异 if (erpData == null) { // ERP系统中没有数据,设置为0 compareData.setErpPurchaseQty(0); compareData.setErpReceivedQty(0); compareData.setErpWaitReceiveQty(0); compareData.setDiffFlag(1); // 有差异 compareData.setDiffQty(srmWaitReceiveQty); // 差异数量为SRM待收数量 } else { // 计算ERP待收数量 Long erpPurchaseQty = erpData.getPurchaseQty(); Long erpReceivedQty = erpData.getTotalReceivedQty(); Long erpWaitReceiveQty = erpPurchaseQty - erpReceivedQty; // 计算差异 Long diffQty = srmWaitReceiveQty.longValue() - erpWaitReceiveQty; // Integer diffFlag = (diffQty > 0) ? 1 : 0; Integer diffFlag = srmWaitReceiveQty.longValue() != erpWaitReceiveQty ? 1 : 0; // 设置ERP数据 compareData.setErpPurchaseQty(erpPurchaseQty.intValue()); compareData.setErpReceivedQty(erpReceivedQty.intValue()); compareData.setErpWaitReceiveQty(erpWaitReceiveQty.intValue()); compareData.setDiffFlag(diffFlag); compareData.setDiffQty(diffQty.intValue()); } compareData.setUpdateTime(new Date()); // 保存或更新比对记录 boolean result; if (compareData.getId() == null) { result = purchaseOrderCompareMapper.insert(compareData) > 0; if (result) { log.info("【savePurchaseOrderCompare】新增数据比对记录: 订单号:{}, 项次:{}, 差异标识:{}, 差异数量:{}", detail.getPoErpNo(), detail.getLineNo(), compareData.getDiffFlag(), compareData.getDiffQty()); } else { log.error("【savePurchaseOrderCompare】新增数据比对记录失败: 订单号:{}, 项次:{}", detail.getPoErpNo(), detail.getLineNo()); } } else { result = purchaseOrderCompareMapper.updateById(compareData) > 0; if (result) { log.info("【savePurchaseOrderCompare】更新数据比对记录: 订单号:{}, 项次:{}, 差异标识:{}, 差异数量:{}", detail.getPoErpNo(), detail.getLineNo(), compareData.getDiffFlag(), compareData.getDiffQty()); } else { log.error("【savePurchaseOrderCompare】更新数据比对记录失败: 订单号:{}, 项次:{}", detail.getPoErpNo(), detail.getLineNo()); } } } /** * 保存或更新采购订单明细 * * @param detail 采购订单明细数据 */ private void savePurchaseOrderDetail(PurchaseOrderDetail detail) { log.info("【savePurchaseOrderDetail】保存采购订单明细: {}, 项次: {}", detail.getPoErpNo(), detail.getLineNo()); // 保存采购订单明细 boolean result = purchaseOrderDetailService.save(detail); if (result) { log.info("【savePurchaseOrderDetail】保存采购订单明细成功: {}, 项次: {}", detail.getPoErpNo(), detail.getLineNo()); } else { log.error("【savePurchaseOrderDetail】保存采购订单明细失败: {}, 项次: {}", detail.getPoErpNo(), detail.getLineNo()); } } }