package com.zt.plat.module.contractorder.service.purchaseorder;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.zt.plat.framework.common.exception.ErrorCode;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.pojo.PageParam;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.framework.datapermission.core.annotation.CompanyDataPermissionIgnore;
import com.zt.plat.framework.datapermission.core.annotation.DeptDataPermissionIgnore;
import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
import com.zt.plat.module.base.api.materialinfomation.MaterialInfomationApi;
import com.zt.plat.module.base.api.materialinfomation.dto.MaterialInfomationPageReqDTO;
import com.zt.plat.module.base.api.materialinfomation.dto.MaterialInfomationRespDTO;
import com.zt.plat.module.base.api.materialinfomation.dto.MaterialInfomationSimplePageReqDTO;
import com.zt.plat.module.base.service.internalsupplyfactory.InternalSupplyFactoryService;
import com.zt.plat.module.bpm.api.task.BpmProcessInstanceApi;
import com.zt.plat.module.bpm.api.task.BpmTaskApi;
import com.zt.plat.module.bpm.api.task.dto.*;
import com.zt.plat.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
import com.zt.plat.module.contractorder.api.dto.order.OrderAndPlanDataReqDTO;
import com.zt.plat.module.contractorder.api.vo.contract.ContractRespVO;
import com.zt.plat.module.contractorder.controller.admin.purchaseorder.vo.*;
import com.zt.plat.module.contractorder.dal.dataobject.contract.ContractMainDO;
import com.zt.plat.module.contractorder.dal.dataobject.contract.SystemRelativityDO;
import com.zt.plat.module.contractorder.dal.dataobject.purchaseorder.PrchOrdDtlDO;
import com.zt.plat.module.contractorder.dal.dataobject.purchaseorder.PurchaseOrderDO;
import com.zt.plat.module.contractorder.dal.dataobject.salesorder.SalesOrderDO;
import com.zt.plat.module.contractorder.dal.mysql.contract.ContractMainMapper;
import com.zt.plat.module.contractorder.dal.mysql.contract.SystemRelativityMapper;
import com.zt.plat.module.contractorder.dal.mysql.purchaseorder.PrchOrdDtlMapper;
import com.zt.plat.module.contractorder.dal.mysql.purchaseorder.PurchaseOrderMapper;
import com.zt.plat.module.contractorder.enums.ErpConstants;
import com.zt.plat.module.contractorder.enums.OrderTypeEnum;
import com.zt.plat.module.contractorder.enums.contract.DictEnum;
import com.zt.plat.module.contractorder.enums.purchaseorder.OrderStatusEnum;
import com.zt.plat.module.contractorder.service.contract.ContractService;
import com.zt.plat.module.contractorder.util.constants.ProcessDefinitionKeyConstants;
import com.zt.plat.module.erp.controller.admin.erp.vo.ErpOrderSaveReqVO;
import com.zt.plat.module.erp.controller.admin.erp.vo.ErpOrderUpdateReqVO;
import com.zt.plat.module.erp.controller.admin.erp.vo.WarehouseFactoryRespVO;
import com.zt.plat.module.erp.dal.dataobject.erp.internalwarehouse.InternalWarehouseDO;
import com.zt.plat.module.erp.service.erp.ErpOrderService;
import com.zt.plat.module.erp.service.erp.WarehouseFactoryService;
import com.zt.plat.module.erp.service.erp.internalwarehouse.InternalWarehouseService;
import com.zt.plat.module.system.api.sequence.SequenceApi;
import com.zt.plat.module.system.api.user.AdminUserApi;
import com.zt.plat.module.system.api.user.dto.AdminUserRespDTO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.time.format.DateTimeFormatter;
import java.util.*;

import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.zt.plat.module.contractorder.enums.ErpConstants.*;
import static com.zt.plat.module.contractorder.enums.ErrorCodeConstants.CONTRACT_ORDER_EXISTS;
import static com.zt.plat.module.contractorder.enums.purchaseorder.ErrorCodeConstants.*;
import static com.zt.plat.module.receivedeliver.enums.ErrorCodeConstants.PURCHASE_ORDER_DETAIL_NOT_EXISTS;


/**
 * 采购订单 Service 实现类
 *
 * @author 后台管理-1
 */
@Slf4j
@Service
@Validated
public class PurchaseOrderServiceImpl implements PurchaseOrderService {
    @Resource
    private ErpOrderService erpOrderService;
    @Resource
    private MaterialInfomationApi materialInfomationApi;
    @Resource
    private PurchaseOrderMapper purchaseOrderMapper;
    @Resource
    private PrchOrdDtlService prchOrdDtlService;

    @Resource
    private BpmProcessInstanceApi bpmProcessInstanceApi;
    @Resource
    private AdminUserApi adminUserApi;

    @Resource
    private BpmTaskApi bpmTaskApi;
    @Resource
    private PrchOrdDtlMapper prchOrdDtlMapper;

    @Resource
    private SequenceApi sequenceApi;

    @Resource
    private ContractService contractService;

    @Resource
    private SystemRelativityMapper systemRelativityMapper;

    @Resource
    private WarehouseFactoryService warehouseFactoryService;
    @Resource
    private InternalWarehouseService internalWarehouseService;
    @Resource
    private ContractMainMapper contractMainMapper;
    private static final Map<String, String> VALID_RELATIONS = new HashMap<>();
    static {
        // 初始化合法的双向映射关系
        VALID_RELATIONS.put("ENT", "ENTED_PUR");
        VALID_RELATIONS.put("ENTED_PUR", "ENT");
        VALID_RELATIONS.put("PUR", "SALE");
        VALID_RELATIONS.put("SALE", "PUR");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PurchaseOrderRespVO createPurchaseOrder(PurchaseOrderSaveReqVO createReqVO) {
        // 插入
        PurchaseOrderDO purchaseOrder = BeanUtils.toBean(createReqVO, PurchaseOrderDO.class);
        purchaseOrder.setIsPush(0);
        purchaseOrder.setStatus(OrderStatusEnum.IN_PROGRESS.getCode());
        //生成订单号
        String orderNumber = generateOrderNumber(purchaseOrder.getMtrlTp());
        purchaseOrder.setSystemOrderNumber(orderNumber);
        purchaseOrderMapper.insert(purchaseOrder);

        if (createReqVO.getDetails() == null || createReqVO.getDetails().isEmpty()) {
            throw exception(ORDER_DETAIL_NOT_EXISTS);
        }
        //批量插入订单明细
        createReqVO.getDetails().forEach(details -> details.setOrdId(purchaseOrder.getId()));
        List<PrchOrdDtlRespVO> prchOrdDtlRespVOS = prchOrdDtlService.batchCreatePrchOrdDtl(createReqVO.getDetails());
        PurchaseOrderRespVO purchaseOrderRespVO = BeanUtils.toBean(purchaseOrder, PurchaseOrderRespVO.class);
        purchaseOrderRespVO.setPrchOrdDtlRespVOS(prchOrdDtlRespVOS);
        return BeanUtils.toBean(purchaseOrder, PurchaseOrderRespVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePurchaseOrder(PurchaseOrderSaveReqVO updateReqVO) {
        // 校验存在
        validatePurchaseOrderExists(updateReqVO.getId());
        // 更新
        PurchaseOrderDO updateObj = BeanUtils.toBean(updateReqVO, PurchaseOrderDO.class);
        purchaseOrderMapper.updateById(updateObj);
//        批量插入订单明细
        updateReqVO.getDetails().forEach(prchOrdDtlSaveReqVO -> {
            //表示新增
            if (prchOrdDtlSaveReqVO.getId() == null) {
                prchOrdDtlSaveReqVO.setOrdId(updateReqVO.getId());
            }
        });
        prchOrdDtlService.batchUpdatePrchOrdDtl(updateReqVO.getDetails());
        log.info("更新订单明细成功");
        PurchaseOrderDO purchaseOrderDO = purchaseOrderMapper.selectById(updateReqVO.getId());
        //如果erp订单号有值就需要调用erp接口更新
        if (!StringUtils.isBlank(purchaseOrderDO.getOrderSAPNumber())) {
            boolean b = submitErp062ByUpdate(updateReqVO.getId());
            if (!b) {
                log.error("ERP订单更新失败，订单ID：【{}】", updateReqVO.getId());
                throw exception(ERP_ORDER_UPDATE_FAILED);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deletePurchaseOrder(Long id) {
        // 校验存在
        validatePurchaseOrderExists(id);
        // 删除
        purchaseOrderMapper.deleteById(id);
        prchOrdDtlService.deletePrchOrdDtlListByOrdIds(Collections.singletonList(id));
    }

    @Override
    public void deletePurchaseOrderListByIds(List<Long> ids) {
        // 校验存在
        validatePurchaseOrderExists(ids);
        // 删除
        purchaseOrderMapper.deleteByIds(ids);
        //删除根据订单号订单明细
        prchOrdDtlService.deletePrchOrdDtlListByOrdIds(ids);

    }

    private void validatePurchaseOrderNosExists(List<String> orderNos) {
        List<PurchaseOrderDO> list = purchaseOrderMapper.selectList(new LambdaQueryWrapper<PurchaseOrderDO>().in(PurchaseOrderDO::getSystemOrderNumber, orderNos));
        if (CollUtil.isEmpty(list) || list.size() != orderNos.size()) {
            throw exception(PURCHASE_ORDER_NOT_EXISTS);
        }
    }

    private void validatePurchaseOrderExists(List<Long> ids) {
        List<PurchaseOrderDO> list = purchaseOrderMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(PURCHASE_ORDER_NOT_EXISTS);
        }
    }

    private void validatePurchaseOrderExists(Long id) {
        if (purchaseOrderMapper.selectById(id) == null) {
            throw exception(PURCHASE_ORDER_NOT_EXISTS);
        }
    }

    @Override
    public PurchaseOrderDO getPurchaseOrder(Long id, String splyBsnTp) {
        return purchaseOrderMapper.selectOne(new LambdaQueryWrapper<PurchaseOrderDO>().eq(PurchaseOrderDO::getId, id).eq(splyBsnTp != null && !splyBsnTp.isEmpty(), PurchaseOrderDO::getSplyBsnTp, splyBsnTp));
    }

    @Override
    public PageResult<PurchaseOrderDO> getPurchaseOrderPage(PurchaseOrderPageReqVO pageReqVO) {
        return purchaseOrderMapper.selectPage(pageReqVO);
    }


    @Override
    @Transactional
    public String submitOrder(Long id) {
        if (ObjectUtils.isEmpty(id)) {
            throw exception(ORDER_ID_NOT_EXISTS);
        }
        PurchaseOrderDO purchaseOrderDO = purchaseOrderMapper.selectById(id);
        if (ObjectUtils.isEmpty(purchaseOrderDO)) {
            throw exception(ORDER_ID_NOT_EXISTS);
        }
        if (purchaseOrderDO.getIsPush() == 0) {
            throw exception(ORDER_DONT_SUBMIT);
        }
        AdminUserRespDTO adminUserRespDTO = adminUserApi.getUser(SecurityFrameworkUtils.getLoginUserId()).getData();
        if (ObjectUtils.isEmpty(purchaseOrderDO.getProcessInstanceId())) {
            BpmProcessInstanceCreateReqDTO pidto = new BpmProcessInstanceCreateReqDTO();
            pidto.setProcessDefinitionKey(ProcessDefinitionKeyConstants.PURCHASE_ORDER_REVIEW_PROCESS);
            pidto.setBusinessKey(String.valueOf(id));
            String data = bpmProcessInstanceApi.createProcessInstance(adminUserRespDTO.getId(), pidto).getData();
            if (StringUtils.isNotBlank(data)) {
                // 获取流程当前审批的任务节点
                List<BpmTaskRespDTO> taskList = bpmTaskApi.getTaskListByProcessInstanceId(data).getData();
                purchaseOrderDO.setProcessInstanceId(data);
                if (CollectionUtils.isNotEmpty(taskList)) {
                    BpmTaskRespDTO undoTask = taskList.get(taskList.size() - 1);// 获取流程当前审批的任务节点
                    purchaseOrderDO.setTaskId(undoTask.getId());
                }
                purchaseOrderDO.setStatus(OrderStatusEnum.APPROVING.getCode()); //
                purchaseOrderMapper.updateById(purchaseOrderDO);
                return "提交审批成功";
            }

        } else {
            // 获取流程当前审批的任务节点
            List<BpmTaskRespDTO> taskList = bpmTaskApi.getTaskListByProcessInstanceId(purchaseOrderDO.getProcessInstanceId()).getData();
            if (CollectionUtils.isNotEmpty(taskList)) {
                BpmTaskRespDTO bpmTaskDto = taskList.get(taskList.size() - 1);
                BpmApprovalDetailReqDTO badrDto = new BpmApprovalDetailReqDTO();
                badrDto.setProcessInstanceId(purchaseOrderDO.getProcessInstanceId()); // 流程实例id
                badrDto.setTaskId(bpmTaskDto.getId()); // 当前审核任务节点id
                BpmApprovalDetailRespDTO approvalDetail = bpmProcessInstanceApi.getApprovalDetail(SecurityFrameworkUtils.getLoginUserId(), badrDto).getData();
                if (BpmProcessInstanceStatusEnum.REJECT.getStatus().equals(approvalDetail.getStatus())) {
                    // 如果状态是驳回状态,需要重新创建一个流程实例
                    BpmProcessInstanceCreateReqDTO pidtoNew = new BpmProcessInstanceCreateReqDTO();
                    pidtoNew.setProcessDefinitionKey(ProcessDefinitionKeyConstants.PURCHASE_ORDER_REVIEW_PROCESS);
                    pidtoNew.setBusinessKey(String.valueOf(id));
                    String data = bpmProcessInstanceApi.createProcessInstance(adminUserRespDTO.getId(), pidtoNew).getData();
                    if (StringUtils.isNotBlank(data)) {
                        // 获取流程当前审批的任务节点
                        List<BpmTaskRespDTO> taskListNew = bpmTaskApi.getTaskListByProcessInstanceId(data).getData();
                        purchaseOrderDO.setProcessInstanceId(data);
                        if (CollectionUtils.isNotEmpty(taskListNew)) {
                            BpmTaskRespDTO undoTask = taskListNew.get(taskListNew.size() - 1);
                            purchaseOrderDO.setTaskId(undoTask.getId());
                        }
                        purchaseOrderDO.setStatus(OrderStatusEnum.APPROVING.getCode());
                        purchaseOrderMapper.updateById(purchaseOrderDO);
                        return "提交审批成功";
                    }
                } else if (BpmProcessInstanceStatusEnum.APPROVE.getStatus().equals(approvalDetail.getStatus())) {
                    return "该授信单审批流程已经审批通过";
                }
            }
        }
        log.info("流程实例id:{}", purchaseOrderDO.getProcessInstanceId());
        return "提交审批成功";
    }

    @Override
    @Transactional
    public String submitErp061(List<Long> ids) {
        List<String> results = new ArrayList<>();
        // 通过订单号查询订单
        List<PurchaseOrderWithDetailsVO> purchaseOrderWithDetailsVOS = purchaseOrderMapper.selectOrderByIds(ids);
        if (!purchaseOrderWithDetailsVOS.isEmpty()) {
            purchaseOrderWithDetailsVOS.forEach(purchaseOrderWithDetailsVO -> {
                ErpOrderSaveReqVO erpOrderSaveReqVO = new ErpOrderSaveReqVO();
                PurchaseOrderDO order = purchaseOrderWithDetailsVO.getPurchaseOrder();
                erpOrderSaveReqVO.setOrderNo(order.getSystemOrderNumber());
                // 1. 处理抬头信息(Head)
                ErpOrderSaveReqVO.Head head = new ErpOrderSaveReqVO.Head();
                head.setComp_code(order.getCpNum()); // 公司编码 -> 公司代码
                head.setVendor(order.getSupplierNumber()); // 客商编码 -> 供应商帐号
                head.setDoc_type(order.getType()); // 订单类型 -> 采购凭证类型
                head.setDoc_date(order.getVoucherDate() != null ? order.getVoucherDate().format(DateTimeFormatter.ofPattern("yyyyMMdd")) : null); // 凭证日期 -> 采购凭证日期
                head.setPurch_org(order.getPurchaseOrganizationCustomsDeclaration()); // 采购组织编码 -> 采购组织
                head.setPur_group(order.getPurchaseGroup()); // 采购组编码 -> 采购组
                head.setCurrency(order.getCurrencyNumber()); // 货币码 -> 货币码
                head.setExch_rate(order.getExchangeRate()); // 汇率 -> 汇率
                erpOrderSaveReqVO.setHead(head);

                // 2. 处理抬头扩展信息(Exte)
                ErpOrderSaveReqVO.Exte exte = new ErpOrderSaveReqVO.Exte();
                exte.setZzhth(order.getPaperContractNumber()); // 合同纸质合同号 -> 纸质合同号
                exte.setZxxyh(order.getAgreementNumber()); // 小协议号 -> 小协议号
                exte.setZnote(order.getRemark()); // 备注 -> 备注
                exte.setZlifnr(order.getAgentNumber()); // 代理方编码 -> 代理方
                erpOrderSaveReqVO.setExte(exte);

                List<JSONObject> actsCtgrDtlList = purchaseOrderWithDetailsVO.getOrderDetails().stream()
                        .map(PrchOrdDtlDO::getActsCtgrDtl).map(JSONObject::parseObject)
                        .toList();
                JSONArray jsonArray = JSONArray.from(actsCtgrDtlList);
                erpOrderSaveReqVO.setAccts(jsonArray);
                // 3. 处理行项目信息(Item)
                List<PrchOrdDtlDO> details = prchOrdDtlMapper.selectList(PrchOrdDtlDO::getOrdId, order.getId());
                if (details != null && !details.isEmpty()) {
                    List<ErpOrderSaveReqVO.Item> items = new ArrayList<>();
                    List<ErpOrderSaveReqVO.Itex> itexes = new ArrayList<>();
                    for (PrchOrdDtlDO detail : details) {
                        ErpOrderSaveReqVO.Item item = new ErpOrderSaveReqVO.Item();
                        MaterialInfomationPageReqDTO infomationPageReqDTO = new MaterialInfomationPageReqDTO();
                        infomationPageReqDTO.setPageSize(10000);
                        infomationPageReqDTO.setCode(detail.getMtrlNum());
                        CommonResult<PageResult<MaterialInfomationRespDTO>> materialInfomationPage = materialInfomationApi.getMaterialInfomationPage(infomationPageReqDTO);
                        if (materialInfomationPage.getData() == null || materialInfomationPage.getData().getList().isEmpty()) {
                            throw exception(MTRL_CODE_NOT_EXISTS);

                        }
                        MaterialInfomationRespDTO materialInfomationRespDTO = materialInfomationPage.getData().getList().get(0);
                        Map<String, Object> flatAttributes = materialInfomationRespDTO.getFlatAttributes();
                        //获取中铜物料编码
                        String mtrlZhongtongCode = flatAttributes.getOrDefault(MTRL_ZHONGTONG_CODE, "").toString();
                        if (mtrlZhongtongCode.isEmpty()) {
                            throw exception(MTRL_CODE_NOT_EXISTS);
                        }
                        //查询库位绑定编码
                        // WarehouseFactoryRespVO factoryAndWarehouse = getBoundFactoryAndWarehouse(detail.getRcvFactNum(), detail.getRcvWrhNum());
                        // 3.1 行项目基本信息
                        item.setPo_item(detail.getLineNum() != null ? detail.getLineNum().intValue() : null); // 行项目 -> 行号
                        item.setMaterial(mtrlZhongtongCode); // 物料编码 -> 物料号
                        item.setPlant(detail.getRcvFactNum()); // 收货工厂编码 -> 工厂
                        item.setStge_loc(detail.getRcvWrhNum()); // 收货库位编码 -> 库存地点
                        item.setQuantity(detail.getQty()); // 暂估数量 -> 数量
                        item.setPo_unit(detail.getUnt()); // 计量单位 -> 计量单位
                        item.setNet_price(detail.getInTaxUprc()); // 含税单价 -> 含税单价
                        item.setPrice_unit(detail.getPrcUnt() != null ? detail.getPrcUnt().intValue() : 1); // 价格单位 -> 价格单位
                        item.setTax_code(detail.getTaxNum()); // 税码 -> 税码
                      //  item.setGr_basediv(detail.getIsGrInv()); // 是否基于GR的发票校验 -> 基于GR的发票校验
                        item.setUnlimited_dlv(detail.getIsUnlRcv()); // 是否允许无限制收货 -> 允许无限制过量交货
                        item.setBatch(detail.getBat()); // 批次 -> 批次
                        item.setAcctasscat(detail.getActsCtgr()); // 科目分配类别 -> 科目分配类别
                        item.setMatl_group(detail.getMtrlCpntNum()); // 物料组编码 -> 物料组
                        item.setShort_text(detail.getShrtTxt()); // 短文本 -> 短文本
                        item.setRet_item(detail.getIsRlbkCgo()); // 退货标识 -> 退货项目标识
                        item.setFree_item(detail.getIsFreeRcv()); // 是否免费收货标识 -> 免费项目标识
                        item.setVendrbatch(String.valueOf(detail.getOutLineNum())); // 外部行项目号 -> 外部行项目号
                        item.setNote_xq(detail.getRmkUnt()); // 备注信息-需求单位 -> 备注信息-需求单位
                        item.setNote_wl(detail.getRmkMtrl()); // 备注信息-物料详细 -> 备注信息-物料详细
                        //item.setGr_basediv("1");//TODO GR发票校验
                        // 处理交货起止日期(格式:YYYYMMDD-YYYYMMDD)
                        StringBuilder vendMat = new StringBuilder();
                        if (detail.getBgnDt() != null) {
                            vendMat.append(detail.getBgnDt().format(DateTimeFormatter.ofPattern(DATE_FORMAT_YYYYMMDD)));
                        }
                        vendMat.append(TOKEN_);
                        if (detail.getDdlDt() != null) {
                            vendMat.append(detail.getDdlDt().format(DateTimeFormatter.ofPattern(DATE_FORMAT_YYYYMMDD)));
                        }
                        item.setVend_mat(TOKEN_.contentEquals(vendMat) ? null : vendMat.toString());
                        // 3.2 行项目扩展信息(Itex)
                        ErpOrderSaveReqVO.Itex itex = new ErpOrderSaveReqVO.Itex();
                        itex.setZmatnr(detail.getSaleMtrlNum()); // 销售物料号 -> 销售物料号
                        itex.setZaufnr(detail.getInOrd()); // 统计型内部订单 -> 统计型内部订单
                        itex.setZpurty(detail.getPrchCtgr()); // 采购类别 -> 采购类别
                        itex.setZmenge(detail.getOrigWet()); // 原料湿重 -> 原料湿重
                        itexes.add(itex);

                        // 3.4 委托加工物料信息(Comp) - 简化处理，实际需解析JSON
//                        List<ErpOrderSaveReqVO.Comp> comps = new ArrayList<>();
//                        if (detail.getEnttDtl() != null && !detail.getEnttDtl().isEmpty()) {
//                            // 假设ENTT_DTL是JSON数组，实际需根据具体格式解析
//                            ErpOrderSaveReqVO.Comp comp = new ErpOrderSaveReqVO.Comp();
//                            comp.setSched_line(1); // 计划行号(示例)
//                            comp.setItem_no(1); // 项目编号(示例)
//                            // 其他字段需从JSON中解析：material、plant、entry_quantity等
//                            comps.add(comp);
//                        }
//                        item.setComps(comps);

                        items.add(item);
                    }
                    erpOrderSaveReqVO.setItems(items);
                    erpOrderSaveReqVO.setItex(itexes);
                }
                String result ="ERP提交失败";
                result= erpOrderService.submitOrderToErp061(erpOrderSaveReqVO);
                Long localOrderId = purchaseOrderWithDetailsVO.getPurchaseOrder().getId();
                log.info("订单推送ERP请求完成，本地订单ID【{}】，ERP返回原始结果【{}】", localOrderId, result);

                // 初始化更新对象，设置基础订单ID
                PurchaseOrderDO upVo = new PurchaseOrderDO();
                upVo.setId(localOrderId);
                String erpId = null; // ERP订单号(PO_NUMBER)
                try {
                    if (StringUtils.isNotBlank(result)) {
                        // 解析顶层JSON对象（原代码冗余解析问题修复）
                        JSONObject rootJson = JSONObject.parseObject(result);
                        String eResp = rootJson.getString("E_RESP");
                        if (StringUtils.isNotBlank(eResp)) {
                            // 解析E_RESP为JSON对象，获取PO_NUMBER
                            JSONObject eRespJson = JSONObject.parseObject(eResp);
                            erpId = eRespJson.getString("PO_NUMBER");
                        }
                    }

                    // 3. 根据ERP订单号是否有效，设置本地订单更新属性
                    if (StringUtils.isNotBlank(erpId)) {
                        // ERP返回有效订单号，更新为成功状态
                        upVo.setOrderSAPNumber(erpId);
                        upVo.setCause("ERP提交成功，erpID为：" + erpId);
                        upVo.setErpStatus(OrderStatusEnum.FIND.getCode()); // 推送成功状态
                        log.info("订单推送ERP成功，本地订单ID【{}】，ERP订单号【{}】，已更新本地状态", localOrderId, erpId);
                    } else {
                        upVo.setOrderSAPNumber(null);
                        upVo.setErpStatus(OrderStatusEnum.RLBK.getCode());
                        upVo.setCause(result);
                        log.warn("订单推送ERP失败，本地订单ID【{}】，失败原因【{}】", localOrderId, result);
                    }

                    purchaseOrderMapper.updateById(upVo);
                    results.add(result);
                } catch (Exception e) {
                    upVo.setOrderSAPNumber(null);
                    upVo.setErpStatus(OrderStatusEnum.RLBK.getCode()); // 异常时强制置为失败状态
                    upVo.setCause("ERP返回结果解析/处理异常：" + e.getMessage());
                    // 异常时仍需更新数据库，保证订单状态一致性
                    purchaseOrderMapper.updateById(upVo);
                    log.error("订单推送ERP发生异常，本地订单ID【{}】，异常信息如下", localOrderId, e);
                    results.add("ERP返回结果解析/处理异常：" + e.getMessage());
                }
            });
            return results.get(0);
        } else {
            return "订单不存在";
        }
    }

    @Override
    public boolean submitErp062ByUpdate(Long id) {
        List<PurchaseOrderWithDetailsVO> purchaseOrderWithDetailsVOS = purchaseOrderMapper.selectOrderByAndAllIds(List.of(id));
        if (purchaseOrderWithDetailsVOS.isEmpty()) {
            throw exception(PURCHASE_ORDER_NOT_EXISTS);
        }
        if (purchaseOrderWithDetailsVOS.get(0).getPurchaseOrder().getOrderSAPNumber().isEmpty()) {
            return true;
        }
        ErpOrderUpdateReqVO erpOrderUpdateReqVO = new ErpOrderUpdateReqVO();
        setValue(erpOrderUpdateReqVO, purchaseOrderWithDetailsVOS.get(0));
        String s = erpOrderService.submitOrderToErp062(erpOrderUpdateReqVO);
        JSONObject jsonObject = JSONObject.parseObject(s);
        if ("S".equals(jsonObject.getString("flag"))) {
            log.info("订单更新ERP成功，本地订单ID【{}】，ERP返回结果【{}】", id, s);
            return true;
        } else if ("E".equals(jsonObject.getString("flag"))) {
            log.error("订单更新ERP失败，本地订单ID【{}】，ERP返回结果【{}】", id, s);
            PurchaseOrderDO upVo = new PurchaseOrderDO();
            upVo.setId(id);
            upVo.setCause(s);
            purchaseOrderMapper.updateById(upVo);
            return false;
        }
        return false;
    }

    @Override
    public boolean updateOrderStatus(Long orderId, String status) {
        // 校验存在
        validatePurchaseOrderExists(orderId);
        OrderStatusEnum byCode = OrderStatusEnum.getByCode(status);
        if (byCode == null) {
            throw exception(PURCHASE_ORDER_STATUS_ERROR);
        }
        return purchaseOrderMapper.updateById(new PurchaseOrderDO().setId(orderId).setStatus(status)) > 0;
    }

    @Override
    public List<PurchaseOrderDetailsRespVO> getOrderByOrderNo(List<String> orderNos) {
        List<PurchaseOrderWithDetailsVO> purchaseOrderWithDetailsVOS = purchaseOrderMapper.selectOrderByOrderNos(orderNos);
        List<PurchaseOrderDetailsRespVO> purchaseOrderDetailsRespVOS = new ArrayList<>();
        purchaseOrderWithDetailsVOS.forEach(purchaseOrderWithDetailsVO -> {
            PurchaseOrderDetailsRespVO purchaseOrderDetailsRespVO = BeanUtils.toBean(purchaseOrderWithDetailsVO.getPurchaseOrder(), PurchaseOrderDetailsRespVO.class);
            purchaseOrderDetailsRespVO.setOrderDetails(BeanUtils.toBean(purchaseOrderWithDetailsVO.getOrderDetails(), PrchOrdDtlDetailsRespVO.class));
            purchaseOrderDetailsRespVOS.add(purchaseOrderDetailsRespVO);
        });
        return purchaseOrderDetailsRespVOS;
    }

    @Override
    public void setOrderDetails(PurchaseOrderRespVO purchaseOrderRespVO) {
        PurchaseOrderDO purchaseOrderDO = purchaseOrderMapper.selectById(purchaseOrderRespVO.getId());
        if (purchaseOrderDO == null) {
            return;
        }
        List<PrchOrdDtlDO> prchOrdDtlDOS = prchOrdDtlMapper.selectList(new LambdaQueryWrapper<PrchOrdDtlDO>().eq(PrchOrdDtlDO::getOrdId, purchaseOrderDO.getId()));
        purchaseOrderRespVO.setPrchOrdDtlRespVOS(BeanUtils.toBean(prchOrdDtlDOS, PrchOrdDtlRespVO.class));
    }

    @Override
    public void updateOrderStatusByIdOrOrderNo(OrderStsReqVO reqVO) {
        // 校验存在
        if (reqVO.getIds() != null) {
            validatePurchaseOrderExists(reqVO.getIds());
        }
        if (reqVO.getOrderNos() != null) {
            validatePurchaseOrderNosExists(reqVO.getOrderNos());
        }
        OrderStatusEnum byCode = OrderStatusEnum.getByCode(reqVO.getSts());
        if (byCode == null) {
            throw exception(PURCHASE_ORDER_STATUS_ERROR);
        }
        purchaseOrderMapper.update(new LambdaUpdateWrapper<PurchaseOrderDO>().in(reqVO.getOrderNos() != null, PurchaseOrderDO::getSystemOrderNumber, reqVO.getOrderNos()).in(reqVO.getIds() != null, PurchaseOrderDO::getId, reqVO.getIds()).set(PurchaseOrderDO::getStatus, reqVO.getSts()));
    }

    @Override
    public CommonResult<MaterialRespVO> getMaterial(String orderNo) {
        PurchaseOrderDO purchaseOrderDO = purchaseOrderMapper.selectOne(new LambdaQueryWrapper<PurchaseOrderDO>().eq(PurchaseOrderDO::getSystemOrderNumber, orderNo));
        if (purchaseOrderDO == null) {
            throw exception(PURCHASE_ORDER_NOT_EXISTS);
        }
        String mtrlTp = purchaseOrderDO.getMtrlTp();
        if ("RAW".equals(mtrlTp)) {
            //原料
            MaterialRespVO materialRespVO = new MaterialRespVO();
            materialRespVO.setMaterialType(mtrlTp);
            materialRespVO.setMaterialUnit(purchaseOrderDO.getUnt());
            materialRespVO.setOrderNo(purchaseOrderDO.getSystemOrderNumber());
            MaterialRespVO.MaterialDetails materialDetails = new MaterialRespVO.MaterialDetails();
            materialDetails.setMaterialCode(purchaseOrderDO.getMaterialNumber());
            materialDetails.setMaterialName(purchaseOrderDO.getMaterialName());
            materialDetails.setMaterialUnit(purchaseOrderDO.getUnt());
            materialDetails.setMaterialType(purchaseOrderDO.getMtrlTp());
            materialRespVO.setMaterialDetails(List.of(materialDetails));
            return CommonResult.success(materialRespVO);
        } else {
            List<PrchOrdDtlDO> detailsByOrderIds = prchOrdDtlService.getDetailsByOrderId(purchaseOrderDO.getId());
            MaterialRespVO materialRespVO = new MaterialRespVO();
            materialRespVO.setMaterialType(mtrlTp);
            materialRespVO.setMaterialUnit(purchaseOrderDO.getUnt());
            materialRespVO.setId(String.valueOf(purchaseOrderDO.getId()));
            materialRespVO.setOrderNo(purchaseOrderDO.getSystemOrderNumber());
            materialRespVO.setMaterialDetails(detailsByOrderIds.stream().map(prchOrdDtlDO -> {
                MaterialRespVO.MaterialDetails materialDetails = new MaterialRespVO.MaterialDetails();
                materialDetails.setMaterialCode(prchOrdDtlDO.getMtrlNum());
                materialDetails.setMaterialName(prchOrdDtlDO.getMtrlName());
                materialDetails.setMaterialUnit(prchOrdDtlDO.getUnt());
                materialDetails.setMaterialType(purchaseOrderDO.getMtrlTp());
                return materialDetails;
            }).toList());
            return CommonResult.success(materialRespVO);
        }

    }

    @Override
    public Boolean linkOrder(LinkOrderReqVO LinkOrderReqVO) {

        SystemRelativityDO saveDO = new SystemRelativityDO();
        saveDO.setStatus(DictEnum.BSE_SYS_REL_TP_ORDER.getCode());
        saveDO.setUpId(LinkOrderReqVO.getUpOrderId());
        saveDO.setDownId(LinkOrderReqVO.getDownOrderId());
        //判断订单有没有关联过
        if (systemRelativityMapper.selectCount(new LambdaQueryWrapper<SystemRelativityDO>().eq(SystemRelativityDO::getUpId, saveDO.getUpId()).eq(SystemRelativityDO::getDownId, saveDO.getDownId())) > 0) {
            throw exception(CONTRACT_ORDER_EXISTS);
        }
        return systemRelativityMapper.insert(saveDO) > 0;
    }


    private void setValue(ErpOrderUpdateReqVO erpOrderUpdateReqVO, PurchaseOrderWithDetailsVO purchaseOrderWithDetailsVO) {
        //head
        PurchaseOrderDO purchaseOrderDO = purchaseOrderMapper.findOrderById(purchaseOrderWithDetailsVO.getPurchaseOrder().getId());//需要自定义sql，防止框架拼接删除条件后查询不到
        erpOrderUpdateReqVO.setPoNumber(purchaseOrderWithDetailsVO.getPurchaseOrder().getOrderSAPNumber()).setDeleteInd(purchaseOrderDO.getDeleted() ? "1" : null).setCurrency(purchaseOrderWithDetailsVO.getPurchaseOrder().getCurrencyNumber()).setExchRate(purchaseOrderWithDetailsVO.getPurchaseOrder().getExchangeRate());
        //exte
        erpOrderUpdateReqVO.setZzhth(purchaseOrderWithDetailsVO.getPurchaseOrder().getPaperContractNumber()).setZxxyh(purchaseOrderWithDetailsVO.getPurchaseOrder().getAgreementNumber()).setZnote(purchaseOrderWithDetailsVO.getPurchaseOrder().getRemark()).setZlifnr(purchaseOrderWithDetailsVO.getPurchaseOrder().getAgreementNumber());
        //item
        setItems(erpOrderUpdateReqVO, purchaseOrderWithDetailsVO);
        //itex
        setItex(erpOrderUpdateReqVO, purchaseOrderWithDetailsVO);
        //acct
        List<JSONObject> actsCtgrDtlList = purchaseOrderWithDetailsVO.getOrderDetails().stream()
                .map(PrchOrdDtlDO::getActsCtgrDtl).map(JSONObject::parseObject)
                .toList();
        JSONArray jsonArray = JSONArray.from(actsCtgrDtlList);

        // 设置到对象中
        erpOrderUpdateReqVO.setAccts(jsonArray);
    }

    private void setItems(ErpOrderUpdateReqVO erpOrderUpdateReqVO, PurchaseOrderWithDetailsVO purchaseOrderWithDetailsVO) {
        List<ErpOrderUpdateReqVO.item> items = new ArrayList<>();
        purchaseOrderWithDetailsVO.getOrderDetails().forEach(p -> {
            PrchOrdDtlDO orderDetail = prchOrdDtlMapper.selectById(p.getId());
            MaterialInfomationPageReqDTO infomationPageReqDTO = new MaterialInfomationPageReqDTO();
            infomationPageReqDTO.setPageSize(10000);
            infomationPageReqDTO.setCode(orderDetail.getMtrlNum());
            CommonResult<PageResult<MaterialInfomationRespDTO>> materialInfomationPage = materialInfomationApi.getMaterialInfomationPage(infomationPageReqDTO);
            if (materialInfomationPage.getData() == null || materialInfomationPage.getData().getList().isEmpty()) {
                throw exception(MTRL_CODE_NOT_EXISTS);

            }
            MaterialInfomationRespDTO materialInfomationRespDTO = materialInfomationPage.getData().getList().get(0);
            Map<String, Object> flatAttributes = materialInfomationRespDTO.getFlatAttributes();
            //获取中铜物料编码
            String mtrlZhongtongCode = flatAttributes.getOrDefault(MTRL_ZHONGTONG_CODE, "").toString();
            if (mtrlZhongtongCode.isEmpty()) {
                throw exception(MTRL_CODE_NOT_EXISTS);
            }
            PrchOrdDtlDO prchOrdDtlDO = prchOrdDtlMapper.findOrdDtlById(orderDetail.getId());
            ErpOrderUpdateReqVO.item item = new ErpOrderUpdateReqVO.item(); // item
            item.setPo_item(prchOrdDtlDO.getLineNum());//行号
            item.setMaterial(mtrlZhongtongCode);//物料号
            item.setPlant(prchOrdDtlDO.getRcvFactNum());//工厂
            item.setStge_loc(prchOrdDtlDO.getRcvWrhNum());//库位
            item.setQuantity(String.valueOf(prchOrdDtlDO.getQty()));// 数量
            item.setPo_unit(prchOrdDtlDO.getUnt());// 计量单位
            item.setNet_price(prchOrdDtlDO.getInTaxUprc());// 含税单价
            item.setTax_code(prchOrdDtlDO.getTaxNum());//税码
            item.setAcctasscat(prchOrdDtlDO.getActsCtgr());//科目分配类别
            item.setMatl_group(prchOrdDtlDO.getMtrlCpntNum());//物料组
            item.setShort_text(prchOrdDtlDO.getShrtTxt());//短文本
            item.setDelete_ind(prchOrdDtlDO.getDeleted() ? "1" : null);//行项目删除标识
            items.add(item);
        });
        erpOrderUpdateReqVO.setItems(items);
    }

    private void setItex(ErpOrderUpdateReqVO erpOrderUpdateReqVO, PurchaseOrderWithDetailsVO purchaseOrderWithDetailsVO) {
        List<ErpOrderUpdateReqVO.itex> itexs = new ArrayList<>();
        purchaseOrderWithDetailsVO.getOrderDetails().forEach(orderDetail -> {
            if (orderDetail.getActsCtgrDtl() != null) {
                ErpOrderUpdateReqVO.itex itex = new ErpOrderUpdateReqVO.itex(); // itex
                itex.setPo_item(orderDetail.getLineNum()); //行号
                itex.setZpurty(orderDetail.getPrchCtgr());//采购类别
                itex.setZmatnr(orderDetail.getOrigWet()); // 原料湿重
                itexs.add(itex);
            }
        });
        erpOrderUpdateReqVO.setItexs(itexs);
    }

    private String generateOrderNumber(String materialType) {
        return sequenceApi.getNextSequence("PURCHASE_ORDER_NUMBER", null, null).getData();
    }

//    @Override
//    @Transactional(rollbackFor=Exception.class)
//    public boolean orderPassReject(PurchaseorderReqVO purchaseorderReqVO) {
//        PurchaseOrderDO purchaseOrderDO = purchaseOrderMapper.selectById(purchaseorderReqVO.getId());
//        if (ObjectUtils.isEmpty(purchaseOrderDO)) {
//            throw exception(PURCHASE_ORDER_NOT_EXISTS);
//        }
//        // 获取当前流程正在审批的任务节点
//        List<BpmTaskRespDTO> taskList = bpmTaskApi.getTaskListByProcessInstanceId(purchaseOrderDO.getProcessInstanceId()).getData();
//        BpmTaskRespDTO undoTask = taskList.get(taskList.size() - 1);
//
//        // 判断是否流程已经通过、驳回
//        BpmApprovalDetailReqDTO badrDto = new BpmApprovalDetailReqDTO();
//        badrDto.setProcessInstanceId(purchaseOrderDO.getProcessInstanceId()); // 流程实例id
//        badrDto.setTaskId(undoTask.getId()); // 当前审核任务节点id
//        BpmApprovalDetailRespDTO approvalDetail = bpmProcessInstanceApi.getApprovalDetail(SecurityFrameworkUtils.getLoginUserId(), badrDto).getData();
//        //如果审核通过
//        if ("WAIT_PUSH".equals(purchaseorderReqVO.getStatus())) {
//            purchaseOrderDO.setStatus(getStatusByBpmProcessInstanceCode(approvalDetail.getStatus()));
//        } else  {
//            //如果审核不通过
//            purchaseOrderDO.setStatus(OrderStatusEnum.DRAFT.getCode());
//        }
//        //设置审核意见
//        purchaseOrderDO.setReviewOpinion(purchaseorderReqVO.getReviewOpinion());
//        if (ObjectUtils.isNotEmpty(undoTask)) {
//            purchaseOrderDO.setTaskId(undoTask.getId());
//        }
//        purchaseOrderMapper.updateById(purchaseOrderDO); //更新状态
//        // 需要调用bpm 审核接口更新审批中的状态
//        if (DictEnum.BSE_CTRT_STS_WAIT_PUSH.getCode().equals(purchaseorderReqVO.getStatus()) && ObjectUtils.isNotEmpty(undoTask)) {
//            if (approvalDetail.getStatus().equals(BpmProcessInstanceStatusEnum.RUNNING.getStatus())) {
//                BpmTaskApproveReqDTO btarDto = new BpmTaskApproveReqDTO();
//                btarDto.setId(undoTask.getId());
//                btarDto.setReason(purchaseorderReqVO.getReviewOpinion());
//                CommonResult<Boolean> booleanCommonResult = bpmProcessInstanceApi.approveTask(btarDto);
//                if (booleanCommonResult.isError()) {
//                    throw new RuntimeException(booleanCommonResult.getMsg());
//                }
//            }
//        } else if (DictEnum.BSE_CTRT_STS_REJECTED.getCode().equals(purchaseorderReqVO.getStatus()) && ObjectUtils.isNotEmpty(undoTask)) {
//            if (approvalDetail.getStatus().equals(BpmProcessInstanceStatusEnum.RUNNING.getStatus())) {
//                BpmTaskRejectReqDTO btrrDto = new BpmTaskRejectReqDTO();
//                btrrDto.setId(undoTask.getId());
//                btrrDto.setReason(purchaseorderReqVO.getReviewOpinion());
//                CommonResult<Boolean> booleanCommonResult = bpmProcessInstanceApi.rejectTask(btrrDto);
//                if (booleanCommonResult.isError()) {
//                    throw new RuntimeException(booleanCommonResult.getMsg());
//                }
//            }
//        }
//        return true;
//    }


    @Override
    public List<DownOrUpOrderRespVO> getOrderByOrderIdAndType(DownOrUpOrderReqVO reqVO) {
        PurchaseOrderDO purchaseOrderDO = purchaseOrderMapper.selectById(reqVO.getOrderId());
        if (purchaseOrderDO == null) {
            throw exception(PURCHASE_ORDER_NOT_EXISTS);
        }
        String contractNumber = purchaseOrderDO.getContractNumber();// 合同号
        ContractRespVO contractRespVO = contractService.getBySystemContractNumber(contractNumber);

        ContractRespVO upRelation = null;
        if ("up".equals(reqVO.getOrderType())) {
            log.info("获取上游订单");
            //上游
            upRelation = contractService.getUpRelation(contractRespVO.getId());
        } else {
            //下游
            log.info("获取下游订单");
            upRelation = contractService.getDownRelation(contractRespVO.getId());
        }
        List<DownOrUpOrderRespVO> orderList = new ArrayList<>();
        if (upRelation != null) {
            String systemContractNumber = upRelation.getSystemContractNumber();

            List<PurchaseOrderDO> purchaseOrderDOS = purchaseOrderMapper.selectList(new LambdaQueryWrapper<PurchaseOrderDO>().eq(PurchaseOrderDO::getContractNumber, systemContractNumber));
            purchaseOrderDOS.forEach(p -> {
                        DownOrUpOrderRespVO downOrUpOrderRespVO = new DownOrUpOrderRespVO();
                        downOrUpOrderRespVO.setOrderId(String.valueOf(p.getId()));
                        downOrUpOrderRespVO.setOrderNo(p.getSystemOrderNumber());
                        downOrUpOrderRespVO.setOrderType(reqVO.getOrderType());
                        downOrUpOrderRespVO.setContractId(String.valueOf(p.getId()));
                        downOrUpOrderRespVO.setContractName(p.getContractName());
                        downOrUpOrderRespVO.setContractNumber(p.getContractNumber());
                        downOrUpOrderRespVO.setOrder(BeanUtils.toBean(p, PurchaseOrderRespVO.class));
                        orderList.add(downOrUpOrderRespVO);
                    }
            );

        }
        return orderList;
    }

    @Override
    public List<PurchaseOrderRespVO> getBindOrderByOrder(DownOrUpOrderReqVO reqVO) {
        List<PurchaseOrderRespVO> orderList = new ArrayList<>();
        if ("up".equals(reqVO.getOrderType())) {
            log.info("获取上游订单");
            //上游
            List<SystemRelativityDO> systemRelativityDOS = systemRelativityMapper.selectList(new LambdaQueryWrapper<SystemRelativityDO>().eq(SystemRelativityDO::getDownId, reqVO.getOrderId()));
            if (!systemRelativityDOS.isEmpty()) {
                List<PurchaseOrderDO> purchaseOrderDOS = purchaseOrderMapper.selectByIds(systemRelativityDOS.stream().map(SystemRelativityDO::getUpId).toList());
                orderList = BeanUtils.toBean(purchaseOrderDOS, PurchaseOrderRespVO.class);
            }
        } else {
            //下游
            log.info("获取下游订单");
            List<SystemRelativityDO> systemRelativityDOS = systemRelativityMapper.selectList(new LambdaQueryWrapper<SystemRelativityDO>().eq(SystemRelativityDO::getUpId, reqVO.getOrderId()));
            if (!systemRelativityDOS.isEmpty()) {
                List<PurchaseOrderDO> purchaseOrderDOS = purchaseOrderMapper.selectByIds(systemRelativityDOS.stream().map(SystemRelativityDO::getDownId).toList());
                orderList = BeanUtils.toBean(purchaseOrderDOS, PurchaseOrderRespVO.class);
            }
        }
        return orderList;
    }

    @Override
    public List<PurchaseOrderDetailsRespVO> getOrderByIds(List<Long> ids) {
        List<PurchaseOrderWithDetailsVO> purchaseOrderWithDetailsVOS = purchaseOrderMapper.selectOrderByIds(ids);
        List<PurchaseOrderDetailsRespVO> purchaseOrderDetailsRespVOS = new ArrayList<>();
        purchaseOrderWithDetailsVOS.forEach(purchaseOrderWithDetailsVO -> {
            PurchaseOrderDetailsRespVO purchaseOrderDetailsRespVO = BeanUtils.toBean(purchaseOrderWithDetailsVO.getPurchaseOrder(), PurchaseOrderDetailsRespVO.class);
            purchaseOrderDetailsRespVO.setOrderDetails(BeanUtils.toBean(purchaseOrderWithDetailsVO.getOrderDetails(), PrchOrdDtlDetailsRespVO.class));
            purchaseOrderDetailsRespVOS.add(purchaseOrderDetailsRespVO);
        });
        return purchaseOrderDetailsRespVOS;
    }

    @Override
    public List<PurchaseOrderDO> getOrderByNos(List<String> orderNos) {
        return purchaseOrderMapper.selectList(PurchaseOrderDO::getSystemOrderNumber, orderNos);
    }

    @Override
    public List<PurchaseOrderDO> getOrdersByIds(List<String> ids) {
        return purchaseOrderMapper.selectByIds(ids);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean orderPassReject(PurchaseorderReqVO purchaseorderReqVO) {
        // 查询采购单
        PurchaseOrderDO purchaseOrderDO = purchaseOrderMapper.selectById(purchaseorderReqVO.getId());
        if (ObjectUtils.isEmpty(purchaseOrderDO)) {
            throw exception(PURCHASE_ORDER_NOT_EXISTS);
        }

        // 获取当前流程的所有任务节点
        List<BpmTaskRespDTO> taskList = bpmTaskApi.getTaskListByProcessInstanceId(purchaseOrderDO.getProcessInstanceId()).getData();

        // 筛选出当前待处理的任务（未结束的任务）
        BpmTaskRespDTO undoTask = taskList.stream()
                .filter(task -> task.getEndTime() == null)
                .findFirst()
                .orElse(null);

        if (ObjectUtils.isEmpty(undoTask)) {
            throw new RuntimeException("未找到待审批的任务节点");
        }

        // 先调用BPM审批接口，再更新本地状态
        if (DictEnum.BSE_CTRT_STS_WAIT_PUSH.getCode().equals(purchaseorderReqVO.getStatus())) {
            // 审批通过
            BpmTaskApproveReqDTO btarDto = new BpmTaskApproveReqDTO();
            btarDto.setId(undoTask.getId());
            btarDto.setReason(purchaseorderReqVO.getReviewOpinion());
            CommonResult<Boolean> result = bpmProcessInstanceApi.approveTask(btarDto);
            if (result.isError()) {
                throw new RuntimeException(result.getMsg());
            }
        } else if (DictEnum.BSE_CTRT_STS_REJECTED.getCode().equals(purchaseorderReqVO.getStatus())) {
            // 审批驳回
            BpmTaskRejectReqDTO btrrDto = new BpmTaskRejectReqDTO();
            btrrDto.setId(undoTask.getId());
            btrrDto.setReason(purchaseorderReqVO.getReviewOpinion());
            CommonResult<Boolean> result = bpmProcessInstanceApi.rejectTask(btrrDto);
            if (result.isError()) {
                throw new RuntimeException(result.getMsg());
            }
        }

        // 调用BPM接口后，查询最新的审批详情
        BpmApprovalDetailReqDTO badrDto = new BpmApprovalDetailReqDTO();
        badrDto.setProcessInstanceId(purchaseOrderDO.getProcessInstanceId());
        badrDto.setTaskId(undoTask.getId());
        BpmApprovalDetailRespDTO approvalDetail = bpmProcessInstanceApi.getApprovalDetail(SecurityFrameworkUtils.getLoginUserId(), badrDto).getData();

        // 使用统一方法转换状态
        purchaseOrderDO.setStatus(getStatusByBpmProcessInstanceCode(approvalDetail.getStatus()));
        purchaseOrderDO.setReviewOpinion(purchaseorderReqVO.getReviewOpinion());
        purchaseOrderDO.setTaskId(undoTask.getId());

        purchaseOrderMapper.updateById(purchaseOrderDO);

        return true;
    }

    private String getStatusByBpmProcessInstanceCode(Integer code) {
        log.debug("转换BPM状态码 - 输入码: {}", code);
        return Optional.ofNullable(code)
                .map(c -> switch (c) {
                    case -1, 3, 4 -> {
                        log.debug("BPM状态码 {} 转换为: {}", c, OrderStatusEnum.REJECTED.getCode());
                        yield OrderStatusEnum.REJECTED.getCode();
                    }
                    case 1 -> {
                        log.debug("BPM状态码 {} 转换为: {}", c, OrderStatusEnum.APPROVING.getCode());
                        yield OrderStatusEnum.APPROVING.getCode();
                    }
                    case 2 -> {
                        log.debug("BPM状态码 {} 转换为: {}", c, OrderStatusEnum.TO_SUBMIT_ERP.getCode());
                        yield OrderStatusEnum.TO_SUBMIT_ERP.getCode();
                    }
                    default -> {
                        log.error("未定义的BPM状态码: {}", c);
                        throw new IllegalArgumentException("未定义的BPM状态码：" + c);
                    }
                })
                .orElseThrow(() -> {
                    log.error("BPM状态码为null");
                    return new IllegalArgumentException("BPM状态码不能为null");
                });
    }


    @Override
    public PageResult<PurchaseOrderDO> queryOrderAndPlanData(OrderAndPlanDataReqDTO reqDTO) {
        // 1. 查询所有符合条件的数据
        List<PurchaseOrderDO> allData = purchaseOrderMapper.queryOrderAndPlanData(reqDTO);

        // 2. 获取分页参数
        Integer pageSize = reqDTO.getPageSize();
        Integer pageNum = reqDTO.getPageNo();

        // 3. 计算分页截取的起始/结束索引
        int startIndex = (pageNum - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, allData.size());

        // 4. 截取当前页数据（索引越界时返回空列表）
        List<PurchaseOrderDO> pageData = startIndex >= allData.size()
                ? new ArrayList<>()
                : allData.subList(startIndex, endIndex);
        return new PageResult<>(pageData, (long) allData.size());
    }

    @Override
    @CompanyDataPermissionIgnore
    @DeptDataPermissionIgnore
    public PageResult<PurchaseOrderDO> pageOrderNoPermission(PurchaseOrderPageReqVO pageReqVO) {
        if (pageReqVO.getId() == null){
            throw exception(PURCHASE_ORDER_ID_IS_NULL);
        }
        PurchaseOrderDO purchaseOrderDO = purchaseOrderMapper.selectById(pageReqVO.getId());
        ContractMainDO contractMainDO = contractMainMapper.selectOne(new LambdaQueryWrapper<ContractMainDO>()
                .eq(ContractMainDO::getId, purchaseOrderDO.getContractNumber()));
        ContractMainDO relatedContract = contractMainMapper.selectById(contractMainDO.getRelatedContractId());
        String splyBsnTp = VALID_RELATIONS.getOrDefault(purchaseOrderDO.getSplyBsnTp(), null); // 获取供应商业务类型
        if (splyBsnTp == null){
            throw exception(PURCHASE_ORDER_ID_IS_EMPTY);
        }
        pageReqVO.setContractNumber(relatedContract.getSystemContractNumber());
        pageReqVO.setSplyBsnTp(splyBsnTp);
        return purchaseOrderMapper.selectLinkPage(pageReqVO);
    }

    @Override
    @CompanyDataPermissionIgnore
    @DeptDataPermissionIgnore
    @Transactional(rollbackFor = Exception.class)
    public void boundOrder(BoundOrderReqVO reqVO) {
        log.info("开始执行绑定订单操作，请求参数：{}", reqVO);
        //查询当前订单是否已经绑定订单
        PurchaseOrderDO orderDO = purchaseOrderMapper.selectById(reqVO.getId());
        PurchaseOrderDO boundOrder = purchaseOrderMapper.selectById(reqVO.getBoundId());
        if (boundOrder == null|| orderDO==null){
            throw exception(PURCHASE_ORDER_NOT_EXISTS);
        }
        //判断当前订单是否是来料加工销售订单（来料加工消费订单不允许绑定订单）
        if (OrderTypeEnum.ENTED_SALE.getCode().equals(orderDO.getSplyBsnTp())) {
            throw exception(PURCHASE_ORDER_NOT_ALLOW_BIND);
        }
        if (orderDO.getRelatedOrderId()!=null){
            //将已绑定的订单置空
            PurchaseOrderDO relatedOrder = purchaseOrderMapper.selectById(orderDO.getRelatedOrderId());
            relatedOrder.setRelatedOrderId(null);
            purchaseOrderMapper.updateById(relatedOrder);
            log.info("已绑定的订单已解绑，订单ID：{}", relatedOrder.getId());
        }
        orderDO.setRelatedOrderId(reqVO.getBoundId());
        purchaseOrderMapper.updateById(orderDO);
        log.info("订单ID：{} 已绑定订单ID：{}", reqVO.getId(), reqVO.getBoundId());
        //修改已绑定的的订单
        boundOrder.setRelatedOrderId(reqVO.getId());
        purchaseOrderMapper.updateById(boundOrder);
        log.info("绑定订单操作完成，订单ID：{}", reqVO.getId());
    }


    public WarehouseFactoryRespVO getBoundFactoryAndWarehouse(String factoryCode, String warehouseCode) {
        // 1. 查询主库信息，空值直接抛异常（精准异常信息）
        InternalWarehouseDO internalWarehouseDO = internalWarehouseService
                .getInternalWarehouseByFactoryCodeAndWarehouseCode(factoryCode, warehouseCode);
        if (internalWarehouseDO == null) {
            throw exception(WAREHOUSE_CODE_OR_FACTORY_CODE_NOT_EXISTS,
                    "工厂编码：" + factoryCode + "，仓库编码：" + warehouseCode + " 不存在关联记录");
        }

        // 2. Stream流式查询+过滤，直接获取符合条件的唯一VO，空值抛异常
        return warehouseFactoryService.getWarehouseFactoryByMainId(String.valueOf(internalWarehouseDO.getId()))
                .stream()
                // 过滤条件：MMSI类型+操作类型匹配ERP常量
                .filter(vo -> ErpConstants.WAREHOUSE_MMSITYPE_PUR.equals(vo.getMmsiType())
                        && ErpConstants.WAREHOUSE_TYPE_RECEIVING.equals(vo.getOperationType()))
                // 取第一个匹配结果（无结果则抛指定异常）
                .findFirst()
                .orElseThrow(() -> exception(WAREHOUSE_CODE_OR_FACTORY_CODE_NOT_EXISTS,
                        "工厂编码：" + factoryCode + "，仓库编码：" + warehouseCode + " 无符合操作条件的库位"));
    }

    //操作步骤 1、更新erp->更新数据库
    @Override
    public boolean submitErp062ByDelete(Long id) {
        log.info("开始执行提交ERP 062 By Delete 操作，ID：{}", id);
        //查询采购单信息
        PurchaseOrderDO purchaseOrderDO = purchaseOrderMapper.selectById(id);
        if (purchaseOrderDO == null) {
            throw exception(PURCHASE_ORDER_NOT_EXISTS);
        }
        //根据订单信息查询采购单详情信息
        List<PrchOrdDtlDO> purchaseOrderDetailsDOS = prchOrdDtlService.getDetailsByOrderId(id);
        if (purchaseOrderDetailsDOS == null || purchaseOrderDetailsDOS.isEmpty()) {
            throw exception(PURCHASE_ORDER_DETAIL_NOT_EXISTS);
        }
        ErpOrderUpdateReqVO erpOrderUpdateReqVO = new ErpOrderUpdateReqVO();
        setHeadAndExte(erpOrderUpdateReqVO, purchaseOrderDO);
        setDeleteItems(erpOrderUpdateReqVO, purchaseOrderDetailsDOS);
        String str = erpOrderService.submitOrderToErp062(erpOrderUpdateReqVO);
        log.info("提交ERP 062 By Delete 结果：{}", str);
        //如果删除erp提交成功
        this.deletePurchaseOrderListByIds(List.of(id));
        return true;
    }

    ;

    private void setHeadAndExte(ErpOrderUpdateReqVO erpOrderUpdateReqVO, PurchaseOrderDO purchaseOrderDO) {
        erpOrderUpdateReqVO.setPoNumber(purchaseOrderDO.getOrderSAPNumber()).setDeleteInd("1").setCurrency(purchaseOrderDO.getCurrencyNumber()).setExchRate(purchaseOrderDO.getExchangeRate());
        erpOrderUpdateReqVO.setZzhth(purchaseOrderDO.getPaperContractNumber()).setZxxyh(purchaseOrderDO.getAgreementNumber()).setZnote(purchaseOrderDO.getRemark()).setZlifnr(purchaseOrderDO.getAgreementNumber());
    }

    private void setDeleteItems(ErpOrderUpdateReqVO erpOrderUpdateReqVO, List<PrchOrdDtlDO> purchaseOrderDetailsDOS) {
        List<ErpOrderUpdateReqVO.item> items = new ArrayList<>();
        purchaseOrderDetailsDOS.forEach(prchOrdDtlDO -> {
            MaterialInfomationPageReqDTO infomationPageReqDTO = new MaterialInfomationPageReqDTO();
            infomationPageReqDTO.setPageSize(10000);
            infomationPageReqDTO.setCode(prchOrdDtlDO.getMtrlNum());
            CommonResult<PageResult<MaterialInfomationRespDTO>> materialInfomationPage = materialInfomationApi.getMaterialInfomationPage(infomationPageReqDTO);
            if (materialInfomationPage.getData() == null || materialInfomationPage.getData().getList().isEmpty()) {
                throw exception(MTRL_CODE_NOT_EXISTS);

            }
            MaterialInfomationRespDTO materialInfomationRespDTO = materialInfomationPage.getData().getList().get(0);
            Map<String, Object> flatAttributes = materialInfomationRespDTO.getFlatAttributes();
            //获取中铜物料编码
            String mtrlZhongtongCode = flatAttributes.getOrDefault("mtrlZhongtongCode", "").toString();
            if (mtrlZhongtongCode.isEmpty()) {
                throw exception(MTRL_CODE_NOT_EXISTS);
            }
            ErpOrderUpdateReqVO.item item = new ErpOrderUpdateReqVO.item(); // item
            item.setPo_item(prchOrdDtlDO.getLineNum());//行号
            item.setMaterial(mtrlZhongtongCode);//物料号
            item.setPlant(prchOrdDtlDO.getRcvFactNum());//工厂
            item.setStge_loc(prchOrdDtlDO.getRcvWrhNum());//库位
            item.setQuantity(String.valueOf(prchOrdDtlDO.getQty()));// 数量
            item.setPo_unit(prchOrdDtlDO.getUnt());// 计量单位
            item.setNet_price(prchOrdDtlDO.getInTaxUprc());// 含税单价
            item.setTax_code(prchOrdDtlDO.getTaxNum());//税码
            item.setAcctasscat(prchOrdDtlDO.getActsCtgr());//科目分配类别
            item.setMatl_group(prchOrdDtlDO.getMtrlCpntNum());//物料组
            item.setShort_text(prchOrdDtlDO.getShrtTxt());//短文本
            item.setDelete_ind("1");//行项目删除标识
            items.add(item);
        });
        erpOrderUpdateReqVO.setItems(items);
    }
}
