package com.jwipc.contract.logic.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
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.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jwipc.api.dto.ErpApiResult;
import com.jwipc.constant.DictCode;
import com.jwipc.contract.convert.ContractPaymentApplyConvert;
import com.jwipc.contract.convert.ContractPaymentInvoicedReceiptConvert;
import com.jwipc.contract.dto.*;
import com.jwipc.contract.entity.*;
import com.jwipc.contract.logic.ContractPaymentApplyLogic;
import com.jwipc.contract.model.po.AttachmentManualCheckPO;
import com.jwipc.contract.model.po.ContractPaymentApplyPO;
import com.jwipc.contract.model.po.CreateContractPayDetailPO;
import com.jwipc.contract.model.query.ContractPaymentApplyHeadQuery;
import com.jwipc.contract.service.*;
import com.jwipc.exception.DaoException;
//import com.jwipc.finance.PaymentPlanClient;
import com.jwipc.page.PageUtil;
import com.jwipc.page.PageView;
import com.jwipc.prop.FinancialShareProp;
import com.jwipc.prop.PriceHandle;
import com.jwipc.security.LoginUtil;
import com.jwipc.sys.client.*;
import com.jwipc.sys.client.dto.*;
import com.jwipc.sys.constant.FinancialShareClient;
import com.jwipc.sys.constant.SysKingdeeInvoiceCloudClient;
import com.jwipc.sys.dto.FinancialShareApiResultDTO;
import com.jwipc.sys.entity.Attachment;
import com.jwipc.sys.entity.BusinessAttachment;
import com.jwipc.sys.model.po.BusinessAttachmentPO;
import com.jwipc.sys.model.query.BusinessAttachmentQuery;
import com.jwipc.sys.service.IAttachmentService;
import com.jwipc.sys.service.IBusinessAttachmentService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author 邓京术
 * @date 2025/01/10 13:12
 * @desc
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class ContractPaymentApplyLogicImpl implements ContractPaymentApplyLogic {
    private final IContractPaymentApplyService contractPaymentApplyService;
    private final IContractPaymentApplyDetailService contractPaymentApplyDetailService;
    private final IContractPaymentInvoicedReceiptService contractPaymentInvoicedReceiptService;
    private final ContractPaymentInvoicedReceiptConvert contractPaymentInvoicedReceiptConvert;
    private final IBusinessAttachmentService businessAttachmentService;
    private final SequenceClient sequenceClient;
    private final IContractPaymentInvoicedReceiptService invoicedReceiptService;
    private final KingdeeImageClient kingdeeImageClient;
    private final FinancialShareClient financialShareClient;
//    private final PaymentPlanClient paymentPlanClient;
    private final IContractDeliveryDetailService contractDeliveryDetailService;
    private final ContractPaymentApplyConvert contractPaymentApplyConvert;
    private final PriceHandle priceHandle;
    private final IContractService contractService;
    private final DictClient dictClient;
    private final TaxClient taxClient;
    private final PurchaseGroupClient purchaseGroupClient;
    private final IAttachmentService attachmentService;
    private final FinancialShareProp financialShareProp;
    private final SysKingdeeInvoiceCloudClient sysKingdeeInvoiceCloudClient;
    private final static String PaymentCodLock = "PaymentCodLock_";
    private final StringRedisTemplate redisTemplate;
    private final static String Business_Type_Code = "contract_payment_apply";

    @Override
    public PageView selectDataByQuery(ContractPaymentApplyHeadQuery query) {
        final Page<ContractPaymentApply> dbPage = PageUtil.toPage(query);
        List<ContractPaymentApplyPO> poList = contractPaymentApplyService.selectListByPage(dbPage, query);
        List<ContractPaymentApplyDTO> dtoList = contractPaymentApplyConvert.POToDTOList(poList);
        return PageUtil.getPV(dtoList, dbPage.getTotal());
    }

    @Override
    public ContractPaymentApplyDTO getById(Long id) {
        ContractPaymentApply contractPaymentApply = contractPaymentApplyService.getById(id);
        return contractPaymentApplyConvert.entity2DTO(contractPaymentApply);
    }

//    /**
//     * 获取货到付款相关信息
//     *
//     * @param query 查询条件
//     * @return
//     */
//    @Override
//    public List<CreatePcaDetailDto> readCodPaymentInvoiceData(PaymentApplyItemQuery query) {
//        //已过账没有付款或没有付款完全的数据
//        List<CreatePcaDetailPO> paymentData = invoicedApplyLogic.readCodPaymentInvoiceData(query);
//        //已经预付数据
//        List<CreatePcaDetailPO> applyData = paymentAdvanceApplyLogic.findByQuery(query);
//        if (CollectionUtils.isNotEmpty(paymentData)) {
//            //根据已获取的过账数据筛选已经货到付款的数据
//            List<CreatePcaDetailPO> alreadyData = paymentCodApplyDetailService.findByApplyCodeAndItem(paymentData, null);
//            //处理数据开票数据
//            for (CreatePcaDetailPO detailDto : paymentData) {
//                for (CreatePcaDetailPO dto : alreadyData) {
//                    if (detailDto.getDataKey().equals(dto.getDataKey())) {
//                        //已申请金额
//                        detailDto.setAlreadyApplyAmount(detailDto.getAlreadyApplyAmount().add(dto.getBudInnerMoney()).add(dto.getBudOutMoney()));
//                        //已付款金额
//                        if (dto.getStatus() == 5) {
//                            detailDto.setAlreadyPaymentAmount(detailDto.getAlreadyPaymentAmount().add(dto.getBudInnerMoney()).add(dto.getBudOutMoney()));
//                        }
//                        break;
//                    }
//                }
//                detailDto.setApplyAmount(detailDto.getItAmount().subtract(detailDto.getAlreadyApplyAmount() == null ? BigDecimal.ZERO : detailDto.getAlreadyApplyAmount()));
//            }
//        }
//
//        List<CreatePcaDetailPO> paymentAdvanceApplyList = Lists.newArrayList();
//
//        if (CollectionUtils.isNotEmpty(applyData)) {
//            //货到付款中已经消费的预付数据
//            List<CreatePcaDetailPO> alreadyApply = paymentCodApplyDetailService.findByAlreadyData(applyData);
//            //处理预付数据
//            aa:
//            for (CreatePcaDetailPO detailDto : applyData) {
//
//                for (CreatePcaDetailPO dto : alreadyApply) {
//                    if (detailDto.getDataKey().equals(dto.getDataKey()) && detailDto.getDetailId().equals(dto.getDetailId())) {
//                        //可申请金额
//                        detailDto.setApplyAmount(detailDto.getApplyAmount().subtract(dto.getBudInnerMoney().add(dto.getBudOutMoney())));
//                        //预算内申请金额
//                        detailDto.setBudInnerMoney(detailDto.getBudInnerMoney().subtract(dto.getBudInnerMoney()));
//                        //预算外申请金额
//                        detailDto.setBudOutMoney(detailDto.getBudOutMoney().subtract(dto.getBudOutMoney()));
//                        //剩余可消费金额大于等于0表示消费完全，不用记录
//                        if (detailDto.getApplyAmount().compareTo(BigDecimal.ZERO) < 0) {
//                            paymentAdvanceApplyList.add(detailDto);
//                        }
//                        continue aa;
//                    }
//                }
//                paymentAdvanceApplyList.add(detailDto);
//            }
//        }
//
//        //预付款订单+行号分组集合
//        Map<String, List<CreatePcaDetailPO>> listMap2 = paymentAdvanceApplyList.stream().collect(Collectors.groupingBy(e -> e.getPoCode() + "_" + e.getPoItemNo()));
//
//        //根据订单号匹配预付款数据
//        aa:
//        for (CreatePcaDetailPO paymentDatum : paymentData) {
//            String poCode = paymentDatum.getPoCode();
//            String poItemNo = paymentDatum.getPoItemNo();
//            for (String s : listMap2.keySet()) {
//                //根据订单号+行号匹配相应的预付款
//                if (s.equals(poCode + "_" + poItemNo)) {
//                    paymentDatum.setCreatePcaDetailDtos(listMap2.get(s));
//                    continue aa;
//                }
//            }
//        }
//
//        return paymentCodApplyConvert.createPcaDetailPO2DTOList(paymentData);
//    }

    @Override
    @Transactional
    public void saveOrUpdate(ContractPaymentApplySaveDTO data) {
        if (ObjectUtil.isNull(data)) {
            throw new DaoException("参数异常, 请重新操作");
        }
        List<ContractPaymentApplyDetail> pcaDetailList = Lists.newArrayList();

        ContractPaymentApply byId = contractPaymentApplyService.getById(data.getId());
        ContractPaymentApply headData = data.toPca();
        //防重

        //新增
        if (data.getId() == null) {
            String orderCode = sequenceClient.getCodeSequenceNo("Contract_payment_apply", 6);
            //防止单号重复
            Boolean flag = true;
            while (flag) {
                ContractPaymentApply contractPaymentApplyTemp = contractPaymentApplyService.getOne(new LambdaQueryWrapper<ContractPaymentApply>()
                        .eq(ContractPaymentApply::getApApplyNo, orderCode)
                        .eq(ContractPaymentApply::getDeleteFlag,0));
                if (Objects.nonNull(contractPaymentApplyTemp)) {
                    orderCode = sequenceClient.getCodeSequenceNo("Contract_payment_apply", 6);
                    flag = true;
                } else {
                    flag = false;
                }
            }
            data.setApApplyNo(orderCode);
            headData.setApApplyNo(orderCode);
            headData.setDeleteFlag(0);
            headData.setCreateTime(LocalDateTime.now());
            headData.setCreateUserId(LoginUtil.getUserId());
            headData.setCreateUserCode(LoginUtil.getAccount());
            headData.setCreateUserName(LoginUtil.getName());
            headData.setFreezeStatus(0);//默认为未冻结
            //计算预算外超额
            if (headData.getOaBudOutMoney() != null && headData.getBudOutMoney() != null) {
                headData.setOaOutExcess(headData.getOaBudOutMoney().add(headData.getBudOutMoney()));
                //计算预算外超出比
                if (headData.getOaQuaeterBud() != null && headData.getOaQuaeterBud().compareTo(BigDecimal.ZERO) > 0) {
                    headData.setOaExcessScale(headData.getOaOutExcess().divide(headData.getOaQuaeterBud(), priceHandle.getPrecision(), priceHandle.getCutType() == 0 ? RoundingMode.HALF_UP : RoundingMode.HALF_DOWN));
                }
            }
            // 1.付款申请累计请款金额等于0时，允许保存请款单,2.保存时，请款单状态自动更新为“付款完成”
            if (headData.getActualityPayMoney() == null || (headData.getActualityPayMoney() != null && headData.getActualityPayMoney().compareTo(new BigDecimal(BigInteger.ZERO)) == 0)) {
                headData.setOaAleradyPayMoney(headData.getOaBorrowMoney());
                headData.setStatus(5);
            }

            //查询影响编码 质保款从验收款带入影像代码
            if (data.getPaymentType().equals("04")) {
                if (CollectionUtils.isNotEmpty(data.getItemList())) {
                    for (ContractPaymentApplySaveDTO.ApplyDetail paymentCodApplyDetail : data.getItemList()) {
                        String contractNo = paymentCodApplyDetail.getContractNo();
//                        ContractPaymentApply tempContractPaymentApply = contractPaymentApplyService.getOne(new LambdaQueryWrapper<ContractPaymentApply>()
//                                .eq(ContractPaymentApply::getContractNo,contractNo)
//                                .eq(ContractPaymentApply::getPaymentType,data.getPaymentType()));
                        List<ContractPaymentApply> tempContractPaymentApply = contractPaymentApplyService.findDataStatusByContractList(contractNo,"03");
                        if (CollectionUtils.isNotEmpty(tempContractPaymentApply) && tempContractPaymentApply.size() > 0) {
                            headData.setImgCode(tempContractPaymentApply.get(0).getImgCode());
                            headData.setImgTime(tempContractPaymentApply.get(0).getImgTime());
                            headData.setImgUserId(tempContractPaymentApply.get(0).getImgUserId());
                            headData.setPoImgCode(tempContractPaymentApply.get(0).getPoImgCode());
                            headData.setPoImgTime(tempContractPaymentApply.get(0).getPoImgTime());
                            headData.setPoImgUserId(tempContractPaymentApply.get(0).getPoImgUserId());
                            break;
                        }
                    }
                }
            }

            contractPaymentApplyService.save(headData);

            //开票申请明细
//            List<InvoicedApplyDetail> invoicedApplyDetails = Lists.newArrayList();
            //预付款明细
//            List<ContractPaymentApplyDetail> advanceApplyDetails = Lists.newArrayList();
            for (ContractPaymentApplySaveDTO.ApplyDetail ad : data.getItemList()) {
                ContractPaymentApplyDetail codApplyDetail = ad.toPcaDetail();
                codApplyDetail.setCppId(headData.getId());
                codApplyDetail.setCppNo(headData.getApApplyNo());
                pcaDetailList.add(codApplyDetail);
                //判断是否已经全部被消费
                if (ad.getIsUsed() == 1) {
                    //预付款
//                    if ("Z001".equals(ad.getAmountType())) {
//                        PaymentAdvanceApplyDetail paymentAdvanceApplyDetail = new PaymentAdvanceApplyDetail();
//                        paymentAdvanceApplyDetail.setId(ad.getSourceId());
//                    codApplyDetail.setCodFlag(1);
//                        advanceApplyDetails.add(paymentAdvanceApplyDetail);
//                    } else {
//                        InvoicedApplyDetail applyDetail = new InvoicedApplyDetail();
//                        applyDetail.setId(ad.getSourceId());
//                        applyDetail.setCodFlag(1);
//                        invoicedApplyDetails.add(applyDetail);
//                    }
                }
            }

            if (CollectionUtils.isNotEmpty(pcaDetailList)) {
                contractPaymentApplyDetailService.saveBatch(pcaDetailList);
            }

            List<ContractPaymentInvoicedReceiptDTO> invoicedReceiptDataList = data.getInvoicedReceiptData();
            if (CollUtil.isNotEmpty(invoicedReceiptDataList)) {
                //过滤出invoicedReceiptDataList中notDeleteFlag为0的数据
                invoicedReceiptDataList = invoicedReceiptDataList.stream().filter(invoicedReceiptDTO -> invoicedReceiptDTO.getNotDeleteFlag() == 0).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(invoicedReceiptDataList)) {
//                    InvoicedApplyDTO headDto = params.getHeadData();
//                    InvoicedApply old = invoicedApplyService.getById(headDto.getId());
//                    if (old.getRedReversalStatus() != 1 && old.getRedReversalStatus() != 4) {
//                        throw new DaoException("该开票申请单不支持补票操作, 请检查");
//                    }
//                    InvoicedApply head = invoicedApplyConvert.dto2Entity(headDto);
//                    head.setUpdateTime(LocalDateTime.now());
//                    head.setUpdateUserId(LoginUtil.getUserId());
//                    head.setUpdateUserCode(LoginUtil.getAccount());
//                    head.setUpdateUserName(LoginUtil.getName());
//                    head.setRedReversalStatus(2);
//                    if (!invoicedApplyService.updateById(head)) {
//                        throw new DaoException("保存开票申请表头数据失败, 前联系管理员");
//                    }

                    invoicedReceiptDataList.forEach(e -> e.setIaId(headData.getId()));

                    //判断本次发票号码是否重复
                    List<ContractPaymentInvoicedReceiptDTO> nonNullNameList = invoicedReceiptDataList.stream()
                            .filter(p -> StringUtils.isNotEmpty(p.getInvoiceNumber()))
                            .toList();
                    if (CollectionUtils.isNotEmpty(nonNullNameList)) {
                        Map<String, List<ContractPaymentInvoicedReceiptDTO>> ext = nonNullNameList.stream()
                                .collect(Collectors.groupingBy(ContractPaymentInvoicedReceiptDTO::getInvoiceNumber))
                                .entrySet().stream()
                                .filter(entry -> entry.getValue().size() > 1)
                                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                        if (ObjectUtil.isNotNull(ext)) {
                            ext.forEach((key, value) -> {
                                throw new DaoException("发票号码：" + key + "重复" + value.size() + "条，请删除其中" + (value.size() - 1) + "条");
                            });
                        }
                    }
                    //判断本次数电发票号码是否重复
                    List<ContractPaymentInvoicedReceiptDTO> nonNullElectronNameList = data.getInvoicedReceiptData().stream()
                            .filter(p -> StringUtils.isNotEmpty(p.getElectronInvoiceNumber()))
                            .toList();
                    if (CollectionUtils.isNotEmpty(nonNullElectronNameList)) {
                        Map<String, List<ContractPaymentInvoicedReceiptDTO>> electronExt = nonNullElectronNameList.stream()
                                .collect(Collectors.groupingBy(ContractPaymentInvoicedReceiptDTO::getElectronInvoiceNumber))
                                .entrySet().stream()
                                .filter(entry -> entry.getValue().size() > 1)
                                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                        if (ObjectUtil.isNotNull(electronExt)) {
                            electronExt.forEach((key, value) -> {
                                throw new DaoException("数电发票号码：" + key + "重复" + value.size() + "条，请删除其中" + (value.size() - 1) + "条");
                            });
                        }
                    }
                    //判断发票号码是否重复
                    for (ContractPaymentInvoicedReceiptDTO invoicedReceipt : invoicedReceiptDataList) {
                        //状态 正常
                        invoicedReceipt.setDeductionStatus("0");
                        if (StrUtil.isNotEmpty(invoicedReceipt.getInvoiceNumber())) {
                            ContractPaymentInvoicedReceipt invoicedReceipt1 = contractPaymentInvoicedReceiptService.getExitDataByIaIdAndInvoiceNumber(headData.getId(), invoicedReceipt.getInvoiceNumber());
                            if (ObjectUtil.isNotNull(invoicedReceipt1)) {
                                throw new DaoException("发票号码：" + invoicedReceipt.getInvoiceNumber() + "在系统中已存在，不可录入");
                            }
                        }

                    }
                    //判断数电发票号码是否重复
                    for (ContractPaymentInvoicedReceiptDTO invoicedReceipt : invoicedReceiptDataList) {
                        invoicedReceipt.setDeleteFlag(0);
                        if (StrUtil.isNotEmpty(invoicedReceipt.getElectronInvoiceNumber())) {
                            invoicedReceipt.setElectronInvoiceNumber(invoicedReceipt.getElectronInvoiceNumber().trim());//去除空格
                            ContractPaymentInvoicedReceipt invoicedReceipt1 = contractPaymentInvoicedReceiptService.getExitDataByIaIdAndElectronInvoiceNumber(headData.getId(), invoicedReceipt.getElectronInvoiceNumber());
                            if (ObjectUtil.isNotNull(invoicedReceipt1)) {
                                throw new DaoException("数电发票号码：" + invoicedReceipt.getElectronInvoiceNumber() + "在系统中已存在，不可录入");
                            }
                        }
                    }
                    // 新增或编辑
                    contractPaymentInvoicedReceiptService.saveOrUpdateBatch(contractPaymentInvoicedReceiptConvert.dto2EntityList(invoicedReceiptDataList));
                }
            }

            if (CollectionUtils.isNotEmpty(data.getFileList())) {
                List<BusinessAttachment> fileList = Lists.newArrayList();
                for (ContractBusinessAttachmentDTO entity : data.getFileList()) {
                    BusinessAttachment attachment = businessAttachmentService.getById(entity.getId());
                    attachment.setBusinessId(headData.getId());
                    attachment.setBusinessCode(headData.getApApplyNo());
                    attachment.setBusinessTypeCode("contract_payment_apply");
                    fileList.add(attachment);
                }
                businessAttachmentService.saveOrUpdateBatch(fileList);
            }
            //附件检查项
            if (CollUtil.isNotEmpty(data.getManualCheckList())){
                data.getManualCheckList().forEach(manualCheck -> {
                    manualCheck.setBusinessId(headData.getId());
                    manualCheck.setBusinessCode(headData.getApApplyNo());
                    manualCheck.setBusinessType(4);
                    if (manualCheck.getId() == null){
                        manualCheck.setId(IdWorker.getId());
                        manualCheck.setCreateUser(LoginUtil.getUserId());
                        manualCheck.setCreateTime(LocalDateTime.now());
                    }else {
                        manualCheck.setUpdateUser(LoginUtil.getUserId());
                        manualCheck.setUpdateTime(LocalDateTime.now());
                        manualCheck.setCreateUser(null);
                        manualCheck.setCreateTime(null);
                    }
                });
                List<AttachmentManualCheckPO> manualCheckList = data.getManualCheckList();
                contractPaymentApplyDetailService.saveManualCheckList(manualCheckList);
            }


            // 更新明细行号
            contractPaymentApplyDetailService.updateDetailItemNo(headData.getId());
//            //更新预付款
//            if (CollectionUtils.isNotEmpty(advanceApplyDetails)) {
//                paymentAdvanceApplyDetailService.updateBatchById(advanceApplyDetails);
//            }
//            //开票申请状态
//            if (CollectionUtils.isNotEmpty(invoicedApplyDetails)) {
//                invoicedApplyDetailService.updateBatchById(invoicedApplyDetails);
//            }
//            String backStr = initPaymentPlanSummary(headData, true);
//            if (StringUtils.isNotEmpty(backStr) && backStr.equals("F")) {
////                暂时去掉付款计划的约束，方便测试，上生产时，需要恢复，邓京术 2025-09-25
////                throw new DaoException("本月付款计划没有发布，请先发布付款计划！");
//            }
        } else {

            // 1.付款申请累计请款金额等于0时，允许保存请款单,2.保存时，请款单状态自动更新为“付款完成”
            if (headData.getActualityPayMoney() == null || (headData.getActualityPayMoney() != null && headData.getActualityPayMoney().compareTo(new BigDecimal(BigInteger.ZERO)) == 0)) {
                headData.setOaAleradyPayMoney(headData.getOaBorrowMoney());
                headData.setStatus(5);
            }
            headData.setUpdateTime(LocalDateTime.now());
            headData.setUpdateUserId(LoginUtil.getUserId());
            headData.setUpdateUserCode(LoginUtil.getAccount());
            headData.setUpdateUserName(LoginUtil.getName());
            //查询影响编码 质保款从验收款带入影像代码
            if (data.getPaymentType().equals("04")) {
                if (CollectionUtils.isNotEmpty(data.getItemList())) {
                    for (ContractPaymentApplySaveDTO.ApplyDetail paymentCodApplyDetail : data.getItemList()) {
                        String contractNo = paymentCodApplyDetail.getContractNo();
//                        ContractPaymentApply tempContractPaymentApply = contractPaymentApplyService.getOne(new LambdaQueryWrapper<ContractPaymentApply>()
//                                .eq(ContractPaymentApply::getContractNo,contractNo)
//                                .eq(ContractPaymentApply::getPaymentType,"03"));
                        List<ContractPaymentApply> tempContractPaymentApply = contractPaymentApplyService.findDataStatusByContractList(contractNo,"03");
                        if (CollectionUtils.isNotEmpty(tempContractPaymentApply) && tempContractPaymentApply.size() > 0) {
                            headData.setImgCode(tempContractPaymentApply.get(0).getImgCode());
                            headData.setImgTime(tempContractPaymentApply.get(0).getImgTime());
                            headData.setImgUserId(tempContractPaymentApply.get(0).getImgUserId());
                            headData.setPoImgCode(tempContractPaymentApply.get(0).getPoImgCode());
                            headData.setPoImgTime(tempContractPaymentApply.get(0).getPoImgTime());
                            headData.setPoImgUserId(tempContractPaymentApply.get(0).getPoImgUserId());
                            break;
                        }
                    }
                }
            }

            contractPaymentApplyService.updateById(headData);
            //开票申请明细
//            List<InvoicedApplyDetail> invoicedApplyDetails = Lists.newArrayList();
            //预付款明细
            List<ContractPaymentApplyDetail> advanceApplyDetails = Lists.newArrayList();

            if (CollectionUtils.isNotEmpty(data.getItemList())) {
                for (ContractPaymentApplySaveDTO.ApplyDetail paymentCodApplyDetail : data.getItemList()) {
                    ContractPaymentApplyDetail detail = paymentCodApplyDetail.toPcaDetail();
                    detail.setCppNo(StringUtils.isEmpty(paymentCodApplyDetail.getCppNo()) ? byId.getApApplyNo() : paymentCodApplyDetail.getCppNo());
                    detail.setCppId(Objects.isNull(paymentCodApplyDetail.getCppId()) ? byId.getId() : paymentCodApplyDetail.getCppId());
                    pcaDetailList.add(detail);
                    //货到付款
//                    if ("Z003".equals(paymentCodApplyDetail.getAmountType())) {
//                        InvoicedApplyDetail invoicedApplyDetail = new InvoicedApplyDetail();
//                        invoicedApplyDetail.setId(paymentCodApplyDetail.getSourceId());
//                        if (paymentCodApplyDetail.getIsUsed() == 1) {
//                            invoicedApplyDetail.setCodFlag(1);
//                        } else {
//                            invoicedApplyDetail.setCodFlag(0);
//                        }
//                        invoicedApplyDetails.add(invoicedApplyDetail);
//                    }

                    //请款明细有金额有更新时，需要更新付款计划汇总，减少付款计划汇总的本月已请款金额， fin_payment_plan_summary applied_payment_amount 2025-07-30 邓京术
//                    PaymentCodApplyDetail detailDel = paymentCodApplyDetailService.getById(detail.getId());
//                    initPaymentPlan(detail, detailDel, headData,1);

                }
                contractPaymentApplyDetailService.saveOrUpdateBatch(pcaDetailList);
            }
            //删除的行根据类型释放 预付款和开票申请
            if (CollectionUtils.isNotEmpty(data.getDelItemIdList())) {
                List<ContractPaymentApplyDetail> detailList = Lists.newArrayList();
                for (ContractPaymentApplySaveDTO.DelDetail delDetail : data.getDelItemIdList()) {
                    ContractPaymentApplyDetail ad = new ContractPaymentApplyDetail();
                    ad.setId(delDetail.getId());
                    ad.setDeleteFlag(1);
                    detailList.add(ad);
                    //可能传空过来
                    if (delDetail.getId() == null) continue;

//                    if ("Z003".equals(delDetail.getAmountType())) {
//                        InvoicedApplyDetail invoicedApplyDetail = new InvoicedApplyDetail();
//                        invoicedApplyDetail.setId(delDetail.getSourceId());
//                        invoicedApplyDetail.setCodFlag(0);
//                        invoicedApplyDetails.add(invoicedApplyDetail);
//                    } else {
//                        PaymentAdvanceApplyDetail advanceApplyDetail = new PaymentAdvanceApplyDetail();
//                        advanceApplyDetail.setId(delDetail.getSourceId());
//                        advanceApplyDetail.setCodFlag(0);
//                        advanceApplyDetails.add(advanceApplyDetail);
//                    }
                    //请款明细有删除时，需要更新付款计划汇总，减少付款计划汇总的本月已请款金额， fin_payment_plan_summary applied_payment_amount 2025-07-30 邓京术
//                    PaymentCodApplyDetail adtDel = paymentCodApplyDetailService.getById(delDetail.getSourceId());
//                    initPaymentPlan(null, adtDel, headData, 3);
                }
                contractPaymentApplyDetailService.updateBatchById(detailList);
            }

            List<ContractPaymentInvoicedReceiptDTO> invoicedReceiptDataList = data.getInvoicedReceiptData();
            if (CollUtil.isNotEmpty(invoicedReceiptDataList)) {
                //过滤出invoicedReceiptDataList中notDeleteFlag为0的数据
                invoicedReceiptDataList = invoicedReceiptDataList.stream().filter(invoicedReceiptDTO -> invoicedReceiptDTO.getNotDeleteFlag() == 0).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(invoicedReceiptDataList)) {
//                    InvoicedApplyDTO headDto = params.getHeadData();
//                    InvoicedApply old = invoicedApplyService.getById(headDto.getId());
//                    if (old.getRedReversalStatus() != 1 && old.getRedReversalStatus() != 4) {
//                        throw new DaoException("该开票申请单不支持补票操作, 请检查");
//                    }
//                    InvoicedApply head = invoicedApplyConvert.dto2Entity(headDto);
//                    head.setUpdateTime(LocalDateTime.now());
//                    head.setUpdateUserId(LoginUtil.getUserId());
//                    head.setUpdateUserCode(LoginUtil.getAccount());
//                    head.setUpdateUserName(LoginUtil.getName());
//                    head.setRedReversalStatus(2);
//                    if (!invoicedApplyService.updateById(head)) {
//                        throw new DaoException("保存开票申请表头数据失败, 前联系管理员");
//                    }

                    invoicedReceiptDataList.forEach(e -> e.setIaId(byId.getId()));

                    //判断本次发票号码是否重复
                    List<ContractPaymentInvoicedReceiptDTO> nonNullNameList = invoicedReceiptDataList.stream()
                            .filter(p -> StringUtils.isNotEmpty(p.getInvoiceNumber()))
                            .toList();
                    if (CollectionUtils.isNotEmpty(nonNullNameList)) {
                        Map<String, List<ContractPaymentInvoicedReceiptDTO>> ext = nonNullNameList.stream()
                                .collect(Collectors.groupingBy(ContractPaymentInvoicedReceiptDTO::getInvoiceNumber))
                                .entrySet().stream()
                                .filter(entry -> entry.getValue().size() > 1)
                                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                        if (ObjectUtil.isNotNull(ext)) {
                            ext.forEach((key, value) -> {
                                throw new DaoException("发票号码：" + key + "重复" + value.size() + "条，请删除其中" + (value.size() - 1) + "条");
                            });
                        }
                    }
                    //判断本次数电发票号码是否重复
                    List<ContractPaymentInvoicedReceiptDTO> nonNullElectronNameList = data.getInvoicedReceiptData().stream()
                            .filter(p -> StringUtils.isNotEmpty(p.getElectronInvoiceNumber()))
                            .toList();
                    if (CollectionUtils.isNotEmpty(nonNullElectronNameList)) {
                        Map<String, List<ContractPaymentInvoicedReceiptDTO>> electronExt = nonNullElectronNameList.stream()
                                .collect(Collectors.groupingBy(ContractPaymentInvoicedReceiptDTO::getElectronInvoiceNumber))
                                .entrySet().stream()
                                .filter(entry -> entry.getValue().size() > 1)
                                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                        if (ObjectUtil.isNotNull(electronExt)) {
                            electronExt.forEach((key, value) -> {
                                throw new DaoException("数电发票号码：" + key + "重复" + value.size() + "条，请删除其中" + (value.size() - 1) + "条");
                            });
                        }
                    }
                    //判断发票号码是否重复
                    for (ContractPaymentInvoicedReceiptDTO invoicedReceipt : invoicedReceiptDataList) {
                        if (StrUtil.isNotEmpty(invoicedReceipt.getInvoiceNumber())) {
                            ContractPaymentInvoicedReceipt invoicedReceipt1 = contractPaymentInvoicedReceiptService.getExitDataByIaIdAndInvoiceNumber(byId.getId(), invoicedReceipt.getInvoiceNumber());
                            if (ObjectUtil.isNotNull(invoicedReceipt1)) {
                                throw new DaoException("发票号码：" + invoicedReceipt.getInvoiceNumber() + "在系统中已存在，不可录入");
                            }
                        }

                    }
                    //判断数电发票号码是否重复
                    for (ContractPaymentInvoicedReceiptDTO invoicedReceipt : invoicedReceiptDataList) {
                        invoicedReceipt.setDeleteFlag(0);
                        if (StrUtil.isNotEmpty(invoicedReceipt.getElectronInvoiceNumber())) {
                            invoicedReceipt.setElectronInvoiceNumber(invoicedReceipt.getElectronInvoiceNumber().trim());//去除空格
                            ContractPaymentInvoicedReceipt invoicedReceipt1 = contractPaymentInvoicedReceiptService.getExitDataByIaIdAndElectronInvoiceNumber(byId.getId(), invoicedReceipt.getElectronInvoiceNumber());
                            if (ObjectUtil.isNotNull(invoicedReceipt1)) {
                                throw new DaoException("数电发票号码：" + invoicedReceipt.getElectronInvoiceNumber() + "在系统中已存在，不可录入");
                            }
                        }
                    }
                    // 新增或编辑
                    contractPaymentInvoicedReceiptService.saveOrUpdateBatch(contractPaymentInvoicedReceiptConvert.dto2EntityList(invoicedReceiptDataList));
//                    this.toImg(headDto.getId());
                }
            }


            if (CollectionUtils.isNotEmpty(data.getFileList())) {
                List<BusinessAttachment> fileList = Lists.newArrayList();
                for (ContractBusinessAttachmentDTO entity : data.getFileList()) {
                    BusinessAttachment attachment = businessAttachmentService.getById(entity.getId());
                    attachment.setBusinessId(byId.getId());
                    attachment.setBusinessCode(byId.getApApplyNo());
                    attachment.setBusinessTypeCode("contract_payment_apply");
                    fileList.add(attachment);
                }
                businessAttachmentService.saveOrUpdateBatch(fileList);
            }

            if (CollUtil.isNotEmpty(data.getManualCheckList())) {
                data.getManualCheckList().forEach(manualCheck -> {
                    manualCheck.setBusinessId(byId.getId());
                    manualCheck.setBusinessCode(byId.getApApplyNo());
                    manualCheck.setBusinessType(4);
                    if (manualCheck.getId() == null){
                        manualCheck.setId(IdWorker.getId());
                        manualCheck.setCreateUser(LoginUtil.getUserId());
                        manualCheck.setCreateTime(LocalDateTime.now());
                    }else {
                        manualCheck.setUpdateUser(LoginUtil.getUserId());
                        manualCheck.setUpdateTime(LocalDateTime.now());
                        manualCheck.setCreateUser(null);
                        manualCheck.setCreateTime(null);
                    }
                });
                List<AttachmentManualCheckPO> manualCheckList = data.getManualCheckList();
                contractPaymentApplyDetailService.saveManualCheckList(manualCheckList);
            }

            if (CollectionUtils.isNotEmpty(advanceApplyDetails)) {
                contractPaymentApplyDetailService.updateBatchById(advanceApplyDetails);
            }

            // 更新明细行号
            contractPaymentApplyDetailService.updateDetailItemNo(Objects.isNull(headData.getId()) ? byId.getId() : headData.getId());
//            initPaymentPlanSummary(byId, false);
        }

        //如果是非质保款状态 ，则重新推送影像
        if (data.getId() == null && !data.getPaymentType().equals("04")) {
            this.pushImage(String.valueOf(headData.getId()));
            this.toPoImg(String.valueOf(headData.getId()));
        } else if (!data.getPaymentType().equals("04")) {
            this.deleteImage(String.valueOf(headData.getId()));
            this.deletePoImg(String.valueOf(headData.getId()));
            this.pushImage(String.valueOf(headData.getId()));
            this.toPoImg(String.valueOf(headData.getId()));
        }
    }


    @Override
    @Transactional
    public String importAttachement(List<Map<String,String>> data) {
        Map<String,String> contractNoMap = new HashMap();
        List<BusinessAttachment> fileList = Lists.newArrayList();
        List<BusinessAttachment> deleteList = Lists.newArrayList();

        for (Map<String,String> map : data) {
            if (contractNoMap.containsKey(map.get("contractNo"))) {

            } else {
                String contractNo = map.get("contractNo");
                String id = map.get("id");
                //0 新增 1 修改
                String optType = map.get("optType");
                //合同类型 03模具 其他非模具
                String contractType = map.get("contractType");
                //付款阶段 01 预付款
                String paymentAround = map.get("paymentAround");

                List<Contract> contracts = contractService.list(Wrappers.lambdaQuery(Contract.class).eq(Contract::getContractCode, contractNo));
                if (CollectionUtils.isNotEmpty(contracts)) {
                    String fileIds = contracts.get(0).getContractSignFiels();
                    if(StringUtils.isNotEmpty(fileIds)) {
                        String[] fileIdsArr = fileIds.split(",");
                        for (String fileId : fileIdsArr) {
                            boolean isFlag = false;
                            //判断是否已经导入,如果已经导入的要删除，重新建
                            List<BusinessAttachment> tempList = businessAttachmentService.list(Wrappers.lambdaQuery(BusinessAttachment.class)
                                    .eq(BusinessAttachment::getFileId, fileId)
                                    .eq(BusinessAttachment::getBusinessId, id)
                                    .eq(BusinessAttachment::getBusinessTypeCode, "contract_payment_apply")
                                    .eq(BusinessAttachment::getDeleteFlag,0));

                            if (CollectionUtils.isNotEmpty(tempList)) {
                                //新增直接删除
                                if (optType.equals("0")) {
                                    isFlag = false;
                                    deleteList.addAll(tempList);
                                }
                            }
                            if (!optType.equals("0")) {
                                //修改  判断合同号是否一致，一致则跳过，否则删除
                                List<CreateContractPayDetailPO> createPcaDetailPOS = contractPaymentApplyDetailService.queryCodApplyInvoiceById(Long.parseLong(id));
                                if (CollectionUtils.isNotEmpty(createPcaDetailPOS) && createPcaDetailPOS.get(0).getContractNo().equals(contractNo)) {
                                    isFlag = true;
                                } else if (CollectionUtils.isNotEmpty(tempList)) {
                                    deleteList.addAll(tempList);
                                }
                            }
                            if (!isFlag) {
                                Attachment attachment = attachmentService.getById(fileId);
                                BusinessAttachment businessAttachment = new BusinessAttachment();
                                businessAttachment.setFileId(Long.parseLong(fileId));
                                businessAttachment.setFileName(attachment.getFileName());
                                //合同类型
                                businessAttachment.setType("contractType");

                                businessAttachment.setBusinessId(Long.parseLong(id));
                                businessAttachment.setBusinessCode("contract_payment_apply");
                                businessAttachment.setBusinessTypeCode("contract_payment_apply");
                                businessAttachment.setDeleteFlag(0);
                                businessAttachment.setSourceType(0);
//                            businessAttachment.setCreateUserId(LoginUtil.getUserId());
//                            businessAttachment.setCreateUserCode(LoginUtil.getAccount());
//                            businessAttachment.setCreateUserName(LoginUtil.getName());
                                businessAttachment.setCreateTime(LocalDateTime.now());
                                businessAttachment.setUpdateTime(LocalDateTime.now());
                                businessAttachment.setUpdateUser(LoginUtil.getUserId());
                                businessAttachment.setCreateUser(LoginUtil.getUserId());
//                            businessAttachment.setCreateTime(new Date());
                                fileList.add(businessAttachment);
                            }
                        }
                    }
                }

                //查询送货单文件，
                List<ContractDeliveryDetail> contractDeliveryDetailList = contractDeliveryDetailService.list(Wrappers.lambdaQuery(ContractDeliveryDetail.class).eq(ContractDeliveryDetail::getContractNo, contractNo).eq(ContractDeliveryDetail::getDeleteFlag,0));
                if (CollectionUtils.isNotEmpty(contractDeliveryDetailList)) {

                    Set<Long> uniqueIds = contractDeliveryDetailList.stream()
                            .map(ContractDeliveryDetail::getDeliveryId) // 抽取id
                            .collect(Collectors.toSet()); // 收集到Set中自动去重
                    List<Long> deliveryIds = new ArrayList<>(uniqueIds);
                    for (Long deliveryId: deliveryIds) {
                        //判断是否已经导入
                        List<BusinessAttachment> businessAttachmentList = businessAttachmentService.list(Wrappers.lambdaQuery(BusinessAttachment.class).eq(BusinessAttachment::getBusinessId, deliveryId)
                                .eq(BusinessAttachment::getBusinessTypeCode, "contract_delivery").eq(BusinessAttachment::getDeleteFlag, 0));
                        if (CollectionUtils.isNotEmpty(businessAttachmentList)) {
                            for (BusinessAttachment businessAttachment : businessAttachmentList) {
                                boolean isFlag = false;
                                List<BusinessAttachment> tempList = businessAttachmentService.list(Wrappers.lambdaQuery(BusinessAttachment.class)
                                        .eq(BusinessAttachment::getFileId, businessAttachment.getFileId())
                                        .eq(BusinessAttachment::getBusinessId, id)
                                        .eq(BusinessAttachment::getBusinessTypeCode, "contract_payment_apply")
                                        .eq(BusinessAttachment::getDeleteFlag, 0));
                                if (CollectionUtils.isNotEmpty(tempList)) {
                                    //新增直接删除
                                    if (optType.equals("0")) {
                                        isFlag = false;
                                        deleteList.addAll(tempList);
                                    }
                                }
                                //修改  判断合同号是否一致，一致则跳过，否则删除
                                List<CreateContractPayDetailPO> createPcaDetailPOS = contractPaymentApplyDetailService.queryCodApplyInvoiceById(Long.parseLong(id));
                                if (!optType.equals("0")) {
                                    if (createPcaDetailPOS.get(0).getContractNo().equals(contractNo)) {
                                        isFlag = true;
                                    } else {
                                        deleteList.addAll(tempList);
                                    }
                                }
                                if (!isFlag) {
                                    Attachment attachment = attachmentService.getById(businessAttachment.getFileId());
                                    BusinessAttachment businessAttachment01 = new BusinessAttachment();
                                    businessAttachment01.setFileId(businessAttachment.getFileId());
                                    businessAttachment01.setFileName(attachment.getFileName());
                                    businessAttachment01.setType("contract_delivery");
                                    businessAttachment01.setBusinessId(Long.parseLong(id));
                                    businessAttachment01.setBusinessCode("contract_payment_apply");
                                    businessAttachment01.setBusinessTypeCode("contract_payment_apply");
                                    businessAttachment01.setDeleteFlag(0);
                                    businessAttachment01.setSourceType(0);
                                    businessAttachment01.setCreateTime(LocalDateTime.now());
                                    businessAttachment01.setUpdateTime(LocalDateTime.now());
                                    businessAttachment01.setUpdateUser(LoginUtil.getUserId());
                                    businessAttachment01.setCreateUser(LoginUtil.getUserId());
                                    fileList.add(businessAttachment01);
                                }
                            }
                        }
                    }
                }
                contractNoMap.put("contractNo", contractNo);
            }
        }
        if (CollectionUtils.isNotEmpty(fileList)) {
            businessAttachmentService.saveOrUpdateBatch(fileList);
        }
        if (CollectionUtils.isNotEmpty(deleteList)) {
            for (BusinessAttachment businessAttachment: deleteList) {
                businessAttachment.setDeleteFlag(1);
            }
            businessAttachmentService.saveOrUpdateBatch(deleteList);
        }
        return null;
    }

    @Override
    @Transactional
    public void updateContractPaymentStatus(Long id, String status) {
        ContractPaymentApply byId = contractPaymentApplyService.getById(id);
        byId.setChangeStatus(Integer.parseInt(status));
        contractPaymentApplyService.updateById(byId);
    }

    @Override
    @Transactional
    public void updateContractPaymentApply(Map updateMap) {
        String appNo = (String)updateMap.get("appNo");
        ContractPaymentApply contractPaymentApply = contractPaymentApplyService.getOne(new LambdaQueryWrapper<ContractPaymentApply>().eq(ContractPaymentApply::getApApplyNo, appNo));
        int changeStatus = (Integer) updateMap.get("changeStatus");
        contractPaymentApply.setChangeStatus(changeStatus);
        if (changeStatus == 1) {
            contractPaymentApply.setStatus(7);
            contractPaymentApply.setPaymentCompanyName((String)updateMap.get("paymentCompanyName"));
            contractPaymentApply.setSupBankName((String)updateMap.get("supBankName"));
            contractPaymentApply.setSupBankAccount((String)updateMap.get("supBankAccount"));
            contractPaymentApply.setSupBankCode((String)updateMap.get("supBankCode"));
            contractPaymentApply.setBankCode((String)updateMap.get("supBankCode"));
            contractPaymentApply.setBankInterCode((String)updateMap.get("bankInterCode"));
            contractPaymentApply.setBankAddress((String)updateMap.get("bankAddress"));
//            updateMap.put("paymentCompanyName", paymentChange.getPaymentCompanyName());
//            updateMap.put("supBankName", (paymentChange.getSupBankName()));
//            updateMap.put("supBankAccount", (paymentChange.getSupBankAccount()));
//            updateMap.put("supBankCode", (paymentChange.getSupBankCode()));
//            updateMap.put("bankCode", (paymentChange.getSupBankCode()));
//            updateMap.put("bankInterCode", (paymentChange.getBankInterCode()));
//            updateMap.put("bankAddress", (paymentChange.getBankAddress()));
        }
        contractPaymentApplyService.updateById(contractPaymentApply);
    }

    @Override
    public String saveOrUpdateCheck(ContractPaymentApplySaveDTO data) {
        //提醒：三个月内相同供应商、相同金额提醒；

        //查询三个月内相同供应商、相同金额
//        List<PaymentCodApply> list = paymentCodApplyService.findDataBySupplierAndAmount(data.getSupplierCode(), data.getOaBorrowMoney(), 3);
//        if (CollectionUtils.isNotEmpty(list)){
//            return StrUtil.format("供应商：{}、申请金额：{}在三个月内存在重复申请的数据，单号：{}", data.getSupplierName(), data.getOaBorrowMoney(), list.get(0).getApApplyNo());
//        }
        LambdaQueryWrapper<ContractPaymentApply> query = new LambdaQueryWrapper<ContractPaymentApply>()
                .eq(ContractPaymentApply::getPaymentCompanyName, data.getPaymentCompanyName())
                .eq(ContractPaymentApply::getSupBankName, data.getSupBankName())
                .eq(ContractPaymentApply::getSupBankAccount, data.getSupBankAccount())
                .eq(ContractPaymentApply::getSupBankCode, data.getSupBankCode())
                .eq(ContractPaymentApply::getBankInterCode, data.getBankInterCode())
                .eq(ContractPaymentApply::getBankAddress, data.getBankAddress());
        if (ObjectUtil.isNotNull(data.getId())){
            query.ne(ContractPaymentApply::getId, data.getId());
        }
        query.last(" limit 1");
        ContractPaymentApply bank = contractPaymentApplyService.getOne(query);
        if (ObjectUtil.isNull( bank)){
            return StrUtil.format("供应商：{}、银行名称：{}、银行账号：{}、银行代码：{}、银行国际代码：{}、银行地址：{}为第一次付款，请核对银行信息", data.getSupplierName(), data.getPaymentCompanyName(), data.getSupBankName(), data.getSupBankAccount(), data.getSupBankCode(), data.getBankInterCode(), data.getBankAddress());
        }
        for (ContractPaymentApplySaveDTO.ApplyDetail ad : data.getItemList()) {
            //对账请款，相同供应商、相同合同、相同请款金额，弹窗提醒请款人
            List<ContractPaymentApplyDetail> list2 = contractPaymentApplyService.findDataBySupplierAndAccountAndAmount(data.getSupplierCode(), ad.getContractNo(), ad.getBudOutMoney(),data.getId());
            if (CollectionUtils.isNotEmpty(list2)){
                return StrUtil.format("供应商：{}、合同编号：{}、本次申请金额：{}存在重复申请的数据，单号：{}", data.getSupplierName(), ad.getContractNo(), ad.getBudOutMoney(),list2.get(0).getCppNo());
            }
        }
        //拿到交易公司编码
        String companyCode = data.getCompanyCode();
        String contractNo = "";
        //拿到合同编号
        if(CollectionUtils.isNotEmpty(data.getItemList())){
            ContractPaymentApplySaveDTO.ApplyDetail applyDetail = data.getItemList().get(0);
            contractNo = applyDetail.getContractNo();
        }
        LambdaQueryWrapper<Contract> wrapper = new LambdaQueryWrapper<>();
        //根据合同编号找到对应交易公司编码
        wrapper.eq(Contract::getContractCode, contractNo);
        // 执行查询
        Contract contract = contractService.getOne(wrapper);
        String companyCodeByContractNo = contract.getContractCompanyCode();
        if (ObjectUtil.isNotEmpty(companyCodeByContractNo)){
            //比对两个编码是否一致性交易主体与合同甲方不一致，则报错”请款交易主体XXX与合同XXX的甲方XXX不一致，请确认！“
            if (!companyCode.equals(companyCodeByContractNo)){
                throw new DaoException(StrUtil.format("请款交易主体{}与合同{}的甲方{}不一致，请确认！", data.getCompanyCode(), contractNo,contract.getContractCompanyCode()));
            }
        }else {
            //抛出异常交易公司编码为空
            throw new DaoException("交易主体编码为空");
        }
        return null;
    }

    @Override
    @Transactional
    public void deleteCodApply(String applyIds) {
        final List<Long> appIdList = JSONArray.parseArray(applyIds, Long.class);
        // 校验对账付款申请单状态
        final List<ContractPaymentApply> list = contractPaymentApplyService.findDataStatusByIdList(appIdList);
        // 不允许删除的对账付款申请单号
        String pcaCode = "";
        for (ContractPaymentApply pca : list) {
            if (5 == pca.getStatus()||3 == pca.getStatus()||4 == pca.getStatus()||7 == pca.getStatus()||8 == pca.getStatus()||9 == pca.getStatus()) {
                pcaCode = pca.getApApplyNo();
                break;
            }
        }
        if (StringUtils.isNotEmpty(pcaCode)) {
            throw new DaoException("MRO付款申请单: " + pcaCode + ", 当前状态不可删除, 请检查");
        }

        //根据oaProcessCode查询相同审批单号的申请单，进行删除动作 2024-08-20 邓京术
        for (ContractPaymentApply paymentCodApply : list) {
            if (StringUtils.isNotEmpty(paymentCodApply.getOaProcessCode())) {
                //根据oa流程号查询相同流程号的申请单
                List<ContractPaymentApply> oaSamePaymentCodApplyList = contractPaymentApplyService.list(
                        new LambdaQueryWrapper<ContractPaymentApply>().eq(ContractPaymentApply::getOaProcessCode, paymentCodApply.getOaProcessCode()));
                //如果id相同，则filter
                for (ContractPaymentApply tempPaymentCodApply : oaSamePaymentCodApplyList) {
                    boolean flag = false;
                    for (Long ll : appIdList) {
                        if (ll.equals(tempPaymentCodApply.getId())) {
                            flag = true;
                            break;
                        }
                    }
                    if (!flag) {
                        appIdList.add(tempPaymentCodApply.getId());
                    }
                }
            }
        }

        List<ContractPaymentApply> applyList = Lists.newArrayList();
        for (Long applyId : appIdList) {
            ContractPaymentApply apply = new ContractPaymentApply();
            apply.setId(applyId);
            apply.setDeleteFlag(1);
            apply.setUpdateTime(LocalDateTime.now());
            apply.setUpdateUserId(LoginUtil.getUserId());
            apply.setUpdateUserCode(LoginUtil.getAccount());
            apply.setUpdateUserName(LoginUtil.getName());
            applyList.add(apply);
        }

        if (!contractPaymentApplyService.updateBatchById(applyList)) {
            throw new DaoException("删除MRO付款申请单失败");
        }

        // 删除MRO付款申请明细数据
        contractPaymentApplyDetailService.delDetailByApplyId(appIdList);
        //去除绑定的预付款和开票申请
//        List<PaymentCodApplyDetail> details = contractPaymentApplyDetailService.findByPaymentDetail(appIdList);
        //开票申请明细
//        List<InvoicedApplyDetail> invoicedApplyDetails = Lists.newArrayList();
        //预付款明细
//        List<PaymentAdvanceApplyDetail> advanceApplyDetails = Lists.newArrayList();
//        for (PaymentCodApplyDetail detail : details) {
//            if ("Z001".equals(detail.getAmountType())) {
//                PaymentAdvanceApplyDetail detail1 = new PaymentAdvanceApplyDetail();
//                detail1.setId(detail.getSourceId());
//                detail1.setCodFlag(0);
//                advanceApplyDetails.add(detail1);
//            } else {
//                InvoicedApplyDetail invoicedApplyDetail = new InvoicedApplyDetail();
//                invoicedApplyDetail.setId(detail.getSourceId());
//                invoicedApplyDetail.setCodFlag(0);
//                invoicedApplyDetails.add(invoicedApplyDetail);
//            }
//
//        }


//        if (CollectionUtils.isNotEmpty(invoicedApplyDetails)) {
//            invoicedApplyDetailService.updateBatchById(invoicedApplyDetails);
//        }
//        if (CollectionUtils.isNotEmpty(advanceApplyDetails)) {
//            paymentAdvanceApplyDetailService.updateBatchById(advanceApplyDetails);
//        }
        //重新计算汇总
        //付款申请删除时，需要同时更新付款计划汇总数据 邓京术 2025-07-31
//        for (PaymentCodApply paymentCodApply : list) {
//            PaymentCodApply byId = paymentCodApplyService.getById(paymentCodApply.getId());
//            initPaymentPlanSummary(byId, false);
//        }
    }

    @Override
    public List<CreateCpaDetailDto> queryCodApplyInvoiceById(Long id, Integer totalFlag, String businessType) {
        List<CreateContractPayDetailPO> createPcaDetailPOS = contractPaymentApplyDetailService.queryCodApplyInvoiceById(id);
        List<CreateCpaDetailDto> createPcaDetailDtos = contractPaymentApplyConvert.createPcaDetailPO2DTOList(createPcaDetailPOS);
        if (CollectionUtils.isNotEmpty(createPcaDetailDtos)) {
            //根据已获取的过账数据筛选已经货到付款的数据
            List<CreateContractPayDetailPO> alreadyData = contractPaymentApplyDetailService.findByAccountCodeAndItem1(createPcaDetailPOS, id , createPcaDetailDtos.get(0).getContractNo());
            //处理数据开票数据
            for (CreateCpaDetailDto detailDto : createPcaDetailDtos) {
                BigDecimal alreadyApplyAmount = BigDecimal.ZERO;
                BigDecimal alreadyPaymentAmount = BigDecimal.ZERO;
                if (CollectionUtils.isNotEmpty(alreadyData)) {
                    for (CreateContractPayDetailPO dto : alreadyData) {
                        if (detailDto.getPoItemNo().equals(dto.getDataKey())) {
                            alreadyApplyAmount = alreadyApplyAmount.add(dto.getBudOutMoney());
                            //已付款完成的总金额
                            if (dto.getStatus() == 5) {
                                alreadyPaymentAmount = alreadyPaymentAmount.add(dto.getBudOutMoney());
                            }
                        }
                    }
                }
                //已申请金额
                detailDto.setAlreadyApplyAmount(alreadyApplyAmount);
                //已付款金额
                detailDto.setAlreadyPaymentAmount(alreadyPaymentAmount);
                //可申请金额 = 实际应该金额 - 已申请金额
                detailDto.setApplyAmount(detailDto.getActualUnpaidAmount().subtract(detailDto.getAlreadyApplyAmount() == null ? BigDecimal.ZERO : detailDto.getAlreadyApplyAmount()));
            }
        }
        return createPcaDetailDtos;
    }

    /**
     * 发票，附件类型影像
     * @param pushIds
     */
    @Override
    public void toPoImg(String pushIds) {
        List<Long> idList = Arrays.stream(StringUtils.split(pushIds, ",")).map(Long::valueOf).toList();
        for (Long id : idList) {
            List<BusinessAttachmentClientDTO> attachmentClientDTOList = new ArrayList<>();
            // MRO付款申请 附件
            ContractPaymentApply contractPaymentApply = contractPaymentApplyService.getById(id);
            if (contractPaymentApply == null) {
                throw new DaoException("MRO付款申请单不存在或已被删除，无法推送影像档案");
            }
//            String files = contractPaymentApply.getFiles();
//            if (StringUtils.isNotEmpty(files)) {
//                List<String> fileIds = Arrays.asList(StringUtils.split(files, ","));
//                for (String fileId : fileIds) {
//                    BusinessAttachmentClientDTO businessAttachmentClientDTO = new BusinessAttachmentClientDTO();
//                    businessAttachmentClientDTO.setFileId(Long.valueOf(fileId));
//                    attachmentClientDTOList.add(businessAttachmentClientDTO);
//                }
//            }
            // 关联发票
            invoicedReceiptService.getInvoiceReceiptListByIaId(id).forEach(invoice -> {
                BusinessAttachmentClientDTO businessAttachmentClientDTO = new BusinessAttachmentClientDTO();
                if (invoice.getFileId() != null) {
                    businessAttachmentClientDTO.setFileId(invoice.getFileId());
                    attachmentClientDTOList.add(businessAttachmentClientDTO);
                }
            });
            // 附件清单
            businessAttachmentService.list(new LambdaQueryWrapper<BusinessAttachment>().eq(BusinessAttachment::getBusinessId, id)
                    .eq(BusinessAttachment::getBusinessTypeCode, Business_Type_Code)
                    .eq(BusinessAttachment::getDeleteFlag, "0"))
                    .forEach(attachment -> {
                        BusinessAttachmentClientDTO businessAttachmentClientDTO = new BusinessAttachmentClientDTO();
                        if (attachment.getFileId() != null) {
                            businessAttachmentClientDTO.setFileId(attachment.getFileId());
                            businessAttachmentClientDTO.setId(attachment.getId());
                            attachmentClientDTOList.add(businessAttachmentClientDTO);
                        }
                    });
            // 推送影像
            if (CollectionUtils.isNotEmpty(attachmentClientDTOList)) {
                KingdeeImageClientDTO kingdeeImageClientDTO = new KingdeeImageClientDTO();
                kingdeeImageClientDTO.setBusinessAttachmentList(attachmentClientDTOList);
                KingdeeImageClientDTO result = kingdeeImageClient.pushImage(kingdeeImageClientDTO);
                contractPaymentApply.setPoImgCode(result.getImageCode());
                contractPaymentApply.setPoImgTime(LocalDateTime.now());
                contractPaymentApply.setPoImgUserId(LoginUtil.getUserId());
                contractPaymentApplyService.saveOrUpdate(contractPaymentApply);
            }
        }
    }

    /**
     * 主表附件影像
     * @param pushIds
     */
    @Override
    public void pushImage(String pushIds) {
        List<Long> idList = Arrays.stream(StringUtils.split(pushIds, ",")).map(Long::valueOf).toList();
        for (Long id : idList) {
            List<BusinessAttachmentClientDTO> attachmentClientDTOList = new ArrayList<>();
            // MRO付款申请 附件
            ContractPaymentApply contractPaymentApply = contractPaymentApplyService.getById(id);
            if (contractPaymentApply == null) {
                throw new DaoException("MRO付款申请单不存在或已被删除，无法推送影像档案");
            }
            String files = contractPaymentApply.getFiles();
            if (StringUtils.isNotEmpty(files)) {
                List<String> fileIds = Arrays.asList(StringUtils.split(files, ","));
                for (String fileId : fileIds) {
                    BusinessAttachmentClientDTO businessAttachmentClientDTO = new BusinessAttachmentClientDTO();
                    businessAttachmentClientDTO.setFileId(Long.valueOf(fileId));
                    attachmentClientDTOList.add(businessAttachmentClientDTO);
                }
            }

            String paymentFiles = contractPaymentApply.getPaymentFiles();
            if (StringUtils.isNotEmpty(paymentFiles)) {
                List<String> fileIds = Arrays.asList(StringUtils.split(paymentFiles, ","));
                for (String fileId : fileIds) {
                    BusinessAttachmentClientDTO businessAttachmentClientDTO = new BusinessAttachmentClientDTO();
                    businessAttachmentClientDTO.setFileId(Long.valueOf(fileId));
                    attachmentClientDTOList.add(businessAttachmentClientDTO);
                }
            }
            // 关联发票
//            invoicedReceiptService.getInvoiceReceiptListByIaId(id).forEach(invoice -> {
//                BusinessAttachmentClientDTO businessAttachmentClientDTO = new BusinessAttachmentClientDTO();
//                if (invoice.getFileId() != null) {
//                    businessAttachmentClientDTO.setFileId(invoice.getFileId());
//                    attachmentClientDTOList.add(businessAttachmentClientDTO);
//                }
//            });
            // 附件清单
//            businessAttachmentService.list(new LambdaQueryWrapper<BusinessAttachment>().eq(BusinessAttachment::getBusinessId, id)
//                            .eq(BusinessAttachment::getBusinessTypeCode, Business_Type_Code)
//                            .eq(BusinessAttachment::getDeleteFlag, "0"))
//                    .forEach(attachment -> {
//                        BusinessAttachmentClientDTO businessAttachmentClientDTO = new BusinessAttachmentClientDTO();
//                        if (attachment.getFileId() != null) {
//                            businessAttachmentClientDTO.setFileId(attachment.getFileId());
//                            businessAttachmentClientDTO.setId(attachment.getId());
//                            attachmentClientDTOList.add(businessAttachmentClientDTO);
//                        }
//                    });
            // 推送影像
            if (CollectionUtils.isNotEmpty(attachmentClientDTOList)) {
                KingdeeImageClientDTO kingdeeImageClientDTO = new KingdeeImageClientDTO();
                kingdeeImageClientDTO.setBusinessAttachmentList(attachmentClientDTOList);
                KingdeeImageClientDTO result = kingdeeImageClient.pushImage(kingdeeImageClientDTO);
                contractPaymentApply.setImgCode(result.getImageCode());
                contractPaymentApply.setImgTime(LocalDateTime.now());
                contractPaymentApply.setImgUserId(LoginUtil.getUserId());
                contractPaymentApplyService.saveOrUpdate(contractPaymentApply);
            }
        }
    }

    @Override
    public void deleteImage(String deleteIds) {
        List<Long> idList = Arrays.stream(StringUtils.split(deleteIds, ",")).map(Long::valueOf).toList();
        for (Long id : idList) {
            ContractPaymentApply contractPaymentApply = contractPaymentApplyService.getById(id);
            if (contractPaymentApply == null) {
                throw new DaoException("MRO付款申请单不存在或已被删除，无法删除影像档案");
            }
            BusinessAttachmentQuery query = new BusinessAttachmentQuery();
            query.setBusinessId(id);
            query.setBusinessTypeCodes(Business_Type_Code);
            List<BusinessAttachmentPO> businessAttachmentPOList = businessAttachmentService.queryByPageByCodes(null, query);
            // 删除影像
            KingdeeImageClientDTO kingdeeImageClientDTO = new KingdeeImageClientDTO();
            List<BusinessAttachmentClientDTO> businessAttachmentList = businessAttachmentPOList.stream()
                    .map(po -> {
                        BusinessAttachmentClientDTO dto = new BusinessAttachmentClientDTO();
                        dto.setFileId(po.getFileId());
                        dto.setId(po.getId());
                        return dto;
                    })
                    .toList();
            kingdeeImageClientDTO.setBusinessAttachmentList(businessAttachmentList);
            if (StringUtils.isNotEmpty(contractPaymentApply.getImgCode())&&contractPaymentApply.getImgTime()!=null) {
                kingdeeImageClientDTO.setImageCode(contractPaymentApply.getImgCode());
                kingdeeImageClient.deleteAllImage(kingdeeImageClientDTO);
                contractPaymentApplyService.update(new LambdaUpdateWrapper<ContractPaymentApply>()
                        .set(ContractPaymentApply::getImgCode,null)
                        .set(ContractPaymentApply::getImgTime,null)
                        .set(ContractPaymentApply::getImgUserId,null)
                        .eq(ContractPaymentApply::getId,id));
            }
//            // 清空影像信息
//            contractPaymentApply.setImgCode(null);
//            contractPaymentApply.setImgTime(null);
//            contractPaymentApply.setImgUserId(null);
//            contractPaymentApplyService.saveOrUpdate(contractPaymentApply);
        }
    }

    @Override
    public void deletePoImg(String deleteIds) {
        List<Long> idList = Arrays.stream(StringUtils.split(deleteIds, ",")).map(Long::valueOf).toList();
        for (Long id : idList) {
            ContractPaymentApply contractPaymentApply = contractPaymentApplyService.getById(id);
            if (contractPaymentApply == null) {
                throw new DaoException("MRO付款申请单不存在或已被删除，无法删除影像档案");
            }

            // 删除影像
//            KingdeeImageClientDTO kingdeeImageClientDTO = new KingdeeImageClientDTO();
//            List<BusinessAttachmentClientDTO> businessAttachmentList = businessAttachmentPOList.stream()
//                    .map(po -> {
//                        BusinessAttachmentClientDTO dto = new BusinessAttachmentClientDTO();
//                        dto.setFileId(po.getFileId());
//                        dto.setId(po.getId());
//                        return dto;
//                    })
//                    .toList();
//            kingdeeImageClientDTO.setBusinessAttachmentList(businessAttachmentList);
//            if (StringUtils.isNotEmpty(contractPaymentApply.getImgCode())&&contractPaymentApply.getImgTime()!=null) {
//                kingdeeImageClientDTO.setImageCode(contractPaymentApply.getImgCode());
//                kingdeeImageClient.deleteAllImage(kingdeeImageClientDTO);
                contractPaymentApplyService.update(new LambdaUpdateWrapper<ContractPaymentApply>()
                        .set(ContractPaymentApply::getPoImgCode,null)
                        .set(ContractPaymentApply::getPoImgTime,null)
                        .set(ContractPaymentApply::getPoImgUserId,null)
                        .eq(ContractPaymentApply::getId,id));
//            }
        }
    }

    @Override
    public List<CreateCpaDetailDto> queryInvoiceByContractDetailId(Long poItemNo) {
        List<CreateContractPayDetailPO> alreadyData = contractPaymentApplyDetailService.queryInvoiceByContractDetailId(poItemNo);
        List<CreateCpaDetailDto> createPcaDetailDtos = contractPaymentApplyConvert.createPcaDetailPO2DTOList(alreadyData);
        return createPcaDetailDtos;
    }

    @Override
    public void pushOpen(String ids) {
        final String lockKey1 = PaymentCodLock + LoginUtil.getUserId();
        if (!redisTemplate.opsForValue().setIfAbsent(lockKey1, "Y", 30, TimeUnit.SECONDS)) {
            log.info("正在处理中，请稍后提交!");
            throw new DaoException("单据正在处理中，请稍后提交!");
        }
        List<String> idList = Arrays.asList(StringUtils.split(ids, ","));
        List<ContractPaymentApply> paymentCodApplyList = contractPaymentApplyService.listByIds(idList);
        if (CollectionUtils.isNotEmpty(paymentCodApplyList)) {
            JSONObject reqBody = new JSONObject();
            reqBody.put("appId", financialShareProp.getFinancialShare().getAppId());
            reqBody.put("appSecret", financialShareProp.getFinancialShare().getAppSecret());
            reqBody.put("accountId", financialShareProp.getFinancialShare().getAccountId());

            FinancialShareApiResultDTO invoiceCloudResult = sysKingdeeInvoiceCloudClient.getAppToken(reqBody);
            if (!invoiceCloudResult.getStatus()) {
                redisTemplate.delete(lockKey1);
                throw new DaoException(StrUtil.format("金蝶获取appToken接口报错：{}", invoiceCloudResult.getMessage()));
            }
            JSONObject appObject = invoiceCloudResult.getData();
            String appToken = appObject.getString("app_token");

            JSONObject reqBody2 = new JSONObject();
            reqBody2.put("user", financialShareProp.getFinancialShare().getUser());
            reqBody2.put("usertype", "UserName");
            reqBody2.put("apptoken", appToken);
            reqBody2.put("accountId", financialShareProp.getFinancialShare().getAccountId());
            FinancialShareApiResultDTO accessTokenResult = sysKingdeeInvoiceCloudClient.getAccessToken(reqBody2);
            JSONObject accessObject = accessTokenResult.getData();
            String accessToken = accessObject.getString("access_token");
            for (ContractPaymentApply paymentCodApply : paymentCodApplyList) {
                if (StringUtils.isEmpty(paymentCodApply.getPoImgCode())){
                    redisTemplate.delete(lockKey1);
                    throw new DaoException("此单据没有付款影像，请先影像化");
                }
                 //增加redis锁如果这个单据的数据正在处理就直接返回
                final String lockKey = PaymentCodLock + paymentCodApply.getApApplyNo();
                if (!redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 30, TimeUnit.SECONDS)) {
                    log.info("此单据："+paymentCodApply.getApApplyNo()+"正在处理，请稍后提交!");
                    throw new DaoException("此单据："+paymentCodApply.getApApplyNo()+"正在处理，请稍后提交!");
                }
                if (paymentCodApply.getStatus() != 1&&paymentCodApply.getStatus() != 2&&paymentCodApply.getStatus() != 4){
                    redisTemplate.delete(lockKey1);
                    redisTemplate.delete(lockKey);
                    throw new DaoException("此单据："+paymentCodApply.getApApplyNo()+"状态不可推送!");
                }

                PaymentImportToOpenDTO payImportToOpenDTO = new PaymentImportToOpenDTO();
                PaymentImportToOpenDTO.DataHead dataHead = new PaymentImportToOpenDTO.DataHead();
                // 结算组织.编码
                dataHead.setSettleorg_number(paymentCodApply.getCompanyCode());
                // 单据编号
                dataHead.setBillno(paymentCodApply.getApApplyNo());
                // 单据类型.编码
                dataHead.setBilltype_number("ap_payapply_oth_BT_S");
                // 申请日期
                dataHead.setApplydate(LocalDateTimeUtil.format(paymentCodApply.getCreateTime(), "yyyy-MM-dd"));
                // 申请组织.编码
                dataHead.setApplyorg_number(paymentCodApply.getCompanyCode());
                // 采购组织.编码
                dataHead.setPurorg_number(paymentCodApply.getCompanyCode());
                // 付款组织.编码
                dataHead.setPayorg_number(paymentCodApply.getPaymentCompanyCode());
                // 收款供应商.编码
                dataHead.setM4p4_supplier_number(paymentCodApply.getSupplierCode());
                // 供应商开户行
                dataHead.setM4p4_assacct(paymentCodApply.getSupBankName());
                // 开户行账号
                dataHead.setM4p4_deposit_bank(paymentCodApply.getSupBankAccount());
                // 银行代码
                dataHead.setM4p4_bank_code(StringUtils.isNotEmpty(paymentCodApply.getSupBankCode()) ? paymentCodApply.getSupBankCode() : "");
                //收款地址
                dataHead.setM4p4_pay_address(StringUtils.isNotEmpty(paymentCodApply.getBankAddress()) ? paymentCodApply.getBankAddress() : "");
                //收款单位
                dataHead.setM4p4_payee(StringUtils.isNotEmpty(paymentCodApply.getPaymentCompanyName()) ? paymentCodApply.getPaymentCompanyName() : "");
                // 业务类型
                dataHead.setM4p4_business_type(paymentCodApply.getBusinessType());
                // 提前支付  合同付款不传
//                dataHead.setM4p4_advancepayment(String.valueOf(paymentCodApply.getAdvancePaymentFlag()));

                BigDecimal exceedPlanPayMonthAmount = BigDecimal.ZERO;//paymentPlanClient.findSupplierPaymentPlanSummary(paymentCodApply.getSupplierCode(), paymentCodApply.getCompanyCode(), 2,"C");
                if (exceedPlanPayMonthAmount.floatValue() > 0f) {
                    //打上超计划标识，及金额
                    dataHead.setM4p4_ex_pay_plan("1");
                    dataHead.setM4p4_ex_pay_planamt(exceedPlanPayMonthAmount.stripTrailingZeros().toPlainString());
                }else {
                    dataHead.setM4p4_ex_pay_plan("0");
                    dataHead.setM4p4_ex_pay_planamt("0");
                }
//                if (paymentCodApply.getPayPlanMoney() != null && paymentCodApply.getPayPlanMoney().compareTo(BigDecimal.ZERO) > 0) {
//                    if (paymentCodApply.getPayPlanMoney() != null && paymentCodApply.getOaBorrowMoney().compareTo(paymentCodApply.getPayPlanMoney()) > 0) {
//                        dataHead.setM4p4_ex_pay_plan("1");
//                        dataHead.setM4p4_ex_pay_planamt(paymentCodApply.getOaBorrowMoney().subtract(paymentCodApply.getPayPlanMoney()).stripTrailingZeros().toPlainString());
//                    } else {
//                        dataHead.setM4p4_ex_pay_plan("0");
//                        dataHead.setM4p4_ex_pay_planamt("0");
//                    }
//                } else {
//                    dataHead.setM4p4_ex_pay_plan("0");
//                    dataHead.setM4p4_ex_pay_planamt("0");
//                }

                // 付款用途
                dataHead.setM4p4_pay_purpose(paymentCodApply.getPaymentPurposeDesc());
                // 影像文件
                dataHead.setImageno(paymentCodApply.getImgCode());
                dataHead.setM4p4_image_file(paymentCodApply.getPoImgCode());
                // 承兑期限
                if (StrUtil.isNotEmpty(paymentCodApply.getAcceptanceMethod())) {
                    DictDTO dict = dictClient.getDictByTypeAndCode(DictCode.SUPPLIER_ACCETP_DEADLINE.getCode(), paymentCodApply.getAcceptanceMethod());
                    dataHead.setM4p4_accep_period(ObjectUtil.isNotNull(dict) ? dict.getName() : "");
                } else {
                    dataHead.setM4p4_accep_period("");
                }

                // 报关公司
                dataHead.setM4p4_customs_broker(paymentCodApply.getFaSupplier());
                // 供应商退款
//                dataHead.setM4p4_supplier_refund(paymentCodApply.getSupplierReturn());
                if (paymentCodApply.getCompanyCode().equals(paymentCodApply.getPaymentCompanyCode()) && paymentCodApply.getPaymentWayCode().equals("B")) {
                    // 付款方式.编码
                    dataHead.setM4p4_pay_type_number("101");
                } else if (!paymentCodApply.getCompanyCode().equals(paymentCodApply.getPaymentCompanyCode()) && paymentCodApply.getPaymentWayCode().equals("B")) {
                    // 付款方式.编码
                    dataHead.setM4p4_pay_type_number("105");
                } else if (paymentCodApply.getPaymentWayCode().equals("C")) {
                    // 付款方式.编码
                    dataHead.setM4p4_pay_type_number("201");
                } else if (paymentCodApply.getPaymentWayCode().equals("D")) {
                    // 付款方式.编码
                    dataHead.setM4p4_pay_type_number("701");
                }
                // 备注
                dataHead.setM4p4_remarks(paymentCodApply.getApplyRemark());
                // 经办人.工号
                dataHead.setM4p4_handler_number("admin".equals(paymentCodApply.getOaHandlerCode()) ? "ID-000005" : paymentCodApply.getOaHandlerCode());
                dataHead.setCreator_number("admin".equals(LoginUtil.getAccount()) ? "ID-000005" : LoginUtil.getAccount());
                // 付款币种.货币代码
                dataHead.setPaycurrency_number(paymentCodApply.getCurrencyCode());
                // 结算币.货币代码
                dataHead.setSettlecurrency_number(paymentCodApply.getCurrencyCode());
                // 汇率表.编码
//                dataHead.setExratetable_number("");
                // 汇率日期
//                dataHead.setExratedate("");
                // 换算方式
//                dataHead.setQuotation("");

                // 已付款金额
                BigDecimal actualPayAmount = BigDecimal.ZERO;//paymentPlanClient.findSupplierPaymentPlanSummary(paymentCodApply.getSupplierCode(), paymentCodApply.getCompanyCode(), 1,"C");
                //已付款金额
                dataHead.setM4p4_amt_paid(actualPayAmount == null ? "0" : actualPayAmount.stripTrailingZeros().toPlainString());
                // 申请金额
                dataHead.setApplyamount(paymentCodApply.getOaBorrowMoney() == null ? "0" : paymentCodApply.getOaBorrowMoney().stripTrailingZeros().toPlainString());

                // 折扣总金额
                dataHead.setM4p4_discount_amt_sum((paymentCodApply.getOaBorrowMoney() == null ? BigDecimal.ZERO : paymentCodApply.getOaBorrowMoney()).subtract(paymentCodApply.getActualityPayMoney() == null ? BigDecimal.ZERO : paymentCodApply.getActualityPayMoney()).stripTrailingZeros().toPlainString());
                // 应付总金额
                dataHead.setM4p4_pay_amt_amt(paymentCodApply.getActualityPayMoney() == null ? "0" : paymentCodApply.getActualityPayMoney().stripTrailingZeros().toPlainString());
                dataHead.setM4p4_ex_planamt(paymentCodApply.getPayPlanMoney() == null ? "0" : paymentCodApply.getPayPlanMoney().stripTrailingZeros().toPlainString());
                dataHead.setM4p4_intelbank_code(StringUtils.isNotEmpty(paymentCodApply.getBankInterCode()) ? paymentCodApply.getBankInterCode() : "");
                // 申请金额折结算币
//                dataHead.setAppseleamount("");
//                // 交易类型.编码
//                dataHead.setM4p4_crosstrantype_number("");
//                // 核准金额
                dataHead.setApprovalamount(paymentCodApply.getActualityPayMoney()==null?"0":paymentCodApply.getActualityPayMoney().stripTrailingZeros().toPlainString());
                //逾期款项
                dataHead.setM4p4_overdue_payamt(paymentCodApply.getOverdueAmount() == null ? "0" : paymentCodApply.getOverdueAmount().stripTrailingZeros().toPlainString());
                //到期款项
                dataHead.setM4p4_due_payamt(paymentCodApply.getDueAmount() == null ? "0" : paymentCodApply.getDueAmount().stripTrailingZeros().toPlainString());
                //应付账款余额
                dataHead.setM4p4_ac_paybalance(paymentCodApply.getAccountsPayableBalance() == null ? "0" : paymentCodApply.getAccountsPayableBalance().stripTrailingZeros().toPlainString());
                //暂估余额
                dataHead.setM4p4_estimate_balance(paymentCodApply.getProvisionalBalance() == null ? "0" : paymentCodApply.getProvisionalBalance().stripTrailingZeros().toPlainString());
                //代收
                dataHead.setM4p4_collection(String.valueOf(paymentCodApply.getCollectionFlag()));
                //手续费承担方01 ：付款方02 ：收款方03 ：共同承担
                dataHead.setFeepayer(paymentCodApply.getFeePayer());
//                dataHead.setM4p4_pay_behalf(paymentCodApply.getCompanyCode().equals(paymentCodApply.getPaymentCompanyCode())?"0":"1");
//                dataHead.setM4p4_emergency_degree(String.valueOf(paymentCodApply.getUrgentFlag()));
//                // 核准金额折结算币
//                dataHead.setAprseleamount("");

                //代收供应商
                dataHead.setM4p4_agency_supplier_number(paymentCodApply.getPaymentSupplierCode());

                dataHead.setM4p4_emergency_degree(String.valueOf(paymentCodApply.getUrgentFlag()));

                List<PaymentImportToOpenDTO.Entry> entryList = new ArrayList<>();

                List<PaymentImportToOpenDTO.Entry4> entryList4 = new ArrayList<>();
                dataHead.setM4p4_srm_entry(entryList4);

                Map<String,String> expireDateMap = Maps.newHashMap();
                Map<String,String> costCenterCodeMap = Maps.newHashMap();

                //成本中心list抓取
                List<PaymentImportToOpenDTO.Entry6> entry6List = new ArrayList<>();
                List<CreateCpaDetailDto> pcaDetailList = this.queryCodApplyInvoiceById(paymentCodApply.getId(), null, paymentCodApply.getBusinessType());
                int i = 0;
                for (CreateCpaDetailDto pcaDetail : pcaDetailList) {
                    PaymentImportToOpenDTO.Entry entry = new PaymentImportToOpenDTO.Entry();
                    // 明细.id
                    entry.setId("207-" + String.valueOf(pcaDetail.getId()));
                    // 明细.摘要
                    entry.setM4p4_summary(pcaDetail.getItemRemark());
                    // 明细.付款条件
                    entry.setM4p4_pay_term(pcaDetail.getIpwCode());
                    // 明细.报关公司
                    entry.setM4p4_custom_broker(pcaDetail.getSupplierCode2());

                    // 明细.已申请金额
                    entry.setM4p4_applied_amt(pcaDetail.getAlreadyApplyAmount() == null ? "0" : pcaDetail.getAlreadyApplyAmount().stripTrailingZeros().toPlainString());
                    // 明细.折扣金额
                    entry.setM4p4_discount_amt(pcaDetail.getDiscountMoney() == null ? "0" : pcaDetail.getDiscountMoney().stripTrailingZeros().toPlainString());
                    // 明细.本次申请金额
                    entry.setM4p4_applied_amt_e(pcaDetail.getBudOutMoney() == null ? "0" : pcaDetail.getBudOutMoney().stripTrailingZeros().toPlainString());
                    // 明细.可申请金额
                    entry.setM4p4_applied_amt_a(pcaDetail.getApplyAmount() == null ? "0" : pcaDetail.getApplyAmount().stripTrailingZeros().toPlainString());

                    // 明细.冲账金额
                    entry.setM4p4_offset_amt(pcaDetail.getStrikePriceAmount() == null ? "0" : pcaDetail.getStrikePriceAmount().stripTrailingZeros().toPlainString());
                    // 明细.付款到期日
                    entry.setM4p4_pay_due_date(pcaDetail.getPaymentExpireDate() == null ? null : LocalDateTimeUtil.format(pcaDetail.getPaymentExpireDate(), "yyyy-MM-dd"));
                    // 明细.期望付款日
                    entry.setE_expaydate(pcaDetail.getExpectationPaymentDate() == null ? "" : LocalDateTimeUtil.format(pcaDetail.getExpectationPaymentDate(), "yyyy-MM-dd"));
                    // 明细.采购组
                    if (StrUtil.isNotEmpty(pcaDetail.getPurchaseGroup())) {
                        PurchaseGroupDTO purchaseGroupDTO = purchaseGroupClient.getByCode(pcaDetail.getPurchaseGroup());
                        entry.setM4p4_procure_group(ObjectUtil.isNotNull(purchaseGroupDTO) ? StrUtil.format("({}){}", purchaseGroupDTO.getPurchaseGroupCode(), purchaseGroupDTO.getPurchaseGroupName()) : "");
                    } else {
                        entry.setM4p4_procure_group("");
                    }
                    // 明细.开票申请单号
//                    entry.setM4p4_inv_apply(pcaDetail.getInvoiceNo());
                    // 明细.对账单号
//                    entry.setM4p4_statementnumber(pcaDetail.getAccountStatementNo());
                    // 明细.申请金额
                    entry.setE_applyamount(pcaDetail.getBudOutMoney() == null ? "0" : pcaDetail.getBudOutMoney().stripTrailingZeros().toPlainString());
                    //含税金额
                    entry.setM4p4_taxandamt(pcaDetail.getItAmount() == null ? "0" : pcaDetail.getItAmount().stripTrailingZeros().toPlainString());
                    // 明细.税率
                    TaxDTO taxDTO = taxClient.getByCode(pcaDetail.getTaxCode());
                    if (ObjectUtil.isNotNull(taxDTO)) {
                        //获取taxName中的数字，前面加上V
                        String taxCode = "V" + taxDTO.getTaxName().chars()
                                .filter(Character::isDigit)
                                .mapToObj(c -> String.valueOf((char) c))
                                .collect(Collectors.joining());

                        entry.setM4p4_taxrate_number(taxCode);
                    }
                    // 明细.申请金额折结算币
//                    entry.setE_appseleamount("");
                    //TODO 付款类型.编码
                    entry.setE_paymenttype_number("207");
                    // 明细.往来类型
                    entry.setE_asstacttype("bd_supplier");
                    // 往来户.编码
                    entry.setE_asstact_number(paymentCodApply.getSupplierCode());
                    entry.setM4p4_supplier_number(paymentCodApply.getSupplierCode());
                    // 结算方式.编码
                    entry.setE_settlementtype_number(dataHead.getM4p4_pay_type_number());
                    // 明细.实际应付金额
                    entry.setE_payamount(pcaDetail.getItAmount() == null ? "0" : pcaDetail.getItAmount().subtract(pcaDetail.getDiscountMoney() == null ? BigDecimal.ZERO : pcaDetail.getDiscountMoney()).stripTrailingZeros().toPlainString());
                    // 明细.核准金额

                    // 执行减法操作
                    BigDecimal result = pcaDetail.getBudOutMoney().subtract(pcaDetail.getDiscountMoney());
                    // 设置结果保留两位小数，使用RoundingMode.HALF_UP作为舍入模式
                    BigDecimal resultWithScale = result.setScale(2, RoundingMode.HALF_UP);
                    entry.setE_approvedamt(resultWithScale + "");
                    //明细.对账影像
                    entry.setM4p4_reconcilia_image(pcaDetail.getAccountImageCode());
                    //明细.开票影像
                    entry.setM4p4_invoice_image(pcaDetail.getInvoicedImageCode());
                    i++;
                    //明细.分录行号
                    entry.setSeq(i);
                    //明细.合同序号
                    entry.setM4p4_contract_number(pcaDetail.getPoItemNo());
                    //明细.合同类型
                    entry.setM4p4_contract_type(pcaDetail.getContractType());
                    //明细.合同编号
                    entry.setM4p4_contract_no(pcaDetail.getContractNo());
                    //查询成本中心

                    List<String> costCenterCodeList = contractPaymentApplyDetailService.getCostCenterCodeByContractNo(pcaDetail.getContractNo());
                    for (String code : costCenterCodeList) {
                        if (costCenterCodeMap.keySet().contains(code)) {

                        } else {
                            PaymentImportToOpenDTO.Entry6 entry6 = new PaymentImportToOpenDTO.Entry6();
                            entry6.setNumber(code);
                            entry6List.add(entry6);
                            costCenterCodeMap.put(code,code);
                        }
                    }
                    //行号
                    entry.setM4p4_purchase_row(pcaDetail.getItemNo());
                    //付款申请明细.项目编号
                    entry.setM4p4_projectno("");
                    //付款申请明细.项目名称
                    entry.setM4p4_projectname("");
                    //	付款申请明细.付款阶段 [01:预付款, 02:进度款, 03:验收款, 04:质保款]
                    entry.setM4p4_pay_phase(pcaDetail.getPaymentAround());
                    //	付款申请明细.阶段付款金额
                    entry.setM4p4_stage_pay_amt(pcaDetail.getAroundAmount());

                    // 明细.核准金额折结算币
//                    entry.setE_approvedseleamt("");



                    entryList.add(entry);


                    //根据到期日来汇总核准金额
                    // 明细.付款到期日
                    String key  = LocalDateTimeUtil.format(pcaDetail.getExpectationPaymentDate(), "yyyy-MM-dd");
                    if (expireDateMap.keySet().contains(key)) {
                        for (PaymentImportToOpenDTO.Entry4 entry4 : entryList4) {
                            //如果期望付款日相同，则stop
                            if (entry4.getM4p4_ex_payment_date().equals(key)) {
                                String contractNo = entry4.getM4p4_account_number();
                                if (contractNo.indexOf(key) <= 0) {
                                    entry4.setM4p4_account_number(contractNo + "/" + key);
                                }
                                entry4.setM4p4_approved_amount(entry4.getM4p4_approved_amount().add(resultWithScale));
                                entry4.setE_applyamount(entry4.getM4p4_approved_amount());
                                break;
                            }
                        }
                    } else {
                        PaymentImportToOpenDTO.Entry4 entry4 = new PaymentImportToOpenDTO.Entry4();
                        entry4.setM4p4_ex_payment_date(key);
                        entry4.setM4p4_srm_entry_id("207-" + String.valueOf(pcaDetail.getId()));
                        entry4.setM4p4_account_number(pcaDetail.getContractNo());
                        entry4.setM4p4_approved_amount(resultWithScale);
                        entry4.setE_applyamount(resultWithScale);
                        entry4.setM4p4_settlement_modes_number(dataHead.getM4p4_pay_type_number());
                        entry4.setE_asstact_number(paymentCodApply.getSupplierCode());
                        entry4.setE_paymenttype_number("207");
                        entryList4.add(entry4);
                        expireDateMap.put(key,key);
                    }
                }
                //成本中心 根据合同编号去合同采购明细取成本中心列表
                if (null != entry6List && entry6List.size() > 0) {
                    dataHead.setM4p4_costcenter(entry6List);
                }

                dataHead.setEntry(entryList);

                List<AttachmentManualCheckPO> attachmentManualCheckPOList = contractPaymentApplyService.getByBusinessIdAndTypeList(paymentCodApply.getId());
                //3单匹配是否齐全
                List<PaymentImportToOpenDTO.Entry2> entryList2 = new ArrayList<>();
                for (AttachmentManualCheckPO attachmentManualCheckPO : attachmentManualCheckPOList) {
                    PaymentImportToOpenDTO.Entry2 entry2 = new PaymentImportToOpenDTO.Entry2();
                    entry2.setM4p4_complete(String.valueOf(attachmentManualCheckPO.getManualCheck()));
                    DictDTO dictDTO = dictClient.getDictByTypeAndCode("businessFileType", attachmentManualCheckPO.getType());
                    entry2.setM4p4_attachment_type(ObjectUtil.isNotNull(dictDTO)?dictDTO.getName():"");
                    entryList2.add(entry2);
                }
                dataHead.setM4p4_3ord_matc_entry(entryList2);

                List<PaymentImportToOpenDTO.Entry3> entryList3 = new ArrayList<>();
                dataHead.setM4p4_inventry(entryList3);

                AtomicInteger j = new AtomicInteger();
                //查询发票信息
                invoicedReceiptService.getInvoiceReceiptListByIaId(paymentCodApply.getId()).forEach(invoice -> {
//                    BusinessAttachmentClientDTO businessAttachmentClientDTO = new BusinessAttachmentClientDTO();
//                    if (invoice.getFileId() != null) {
//                        businessAttachmentClientDTO.setFileId(invoice.getFileId());
//                        attachmentClientDTOList.add(businessAttachmentClientDTO);
//                    }
                    PaymentImportToOpenDTO.Entry3 m4p4_inventry = new PaymentImportToOpenDTO.Entry3();
                    //发票类型.编码 1
                    m4p4_inventry.setM4p4_i_invoicetypef7_number(invoice.getType()+"");
//                    m4p4_inventry.setM4p4_i_invoicetypef7_number(invoice.getInvoiceNumber());
                    //发票状态
                    m4p4_inventry.setM4p4_i_invoicestatus(invoice.getDeductionStatus());
                    //发票明细.可抵扣编号
                    m4p4_inventry.setM4p4_deductible_number(invoice.getDeductionCodeType() + "");
                    //发票明细.发票代码
                    m4p4_inventry.setM4p4_i_invoicecode(invoice.getInvoiceCode());
                    //发票明细.发票号码
                    m4p4_inventry.setM4p4_i_invoiceno(invoice.getInvoiceNumber());
                    //发票明细.数电号码
                    m4p4_inventry.setM4p4_phone_number(invoice.getElectronInvoiceNumber());
                    // 明细.税率
                    TaxDTO taxDTO = taxClient.getByCode(invoice.getTaxRate());
                    if (ObjectUtil.isNotNull(taxDTO)) {
                        //获取taxName中的数字，前面加上V
//                        String taxCode = "V" + taxDTO.getTaxName().chars()
//                                .filter(Character::isDigit)
//                                .mapToObj(c -> String.valueOf((char) c))
//                                .collect(Collectors.joining());

                        m4p4_inventry.setM4p4_i_taxrate(taxDTO.getTaxValue());
                    }

                    m4p4_inventry.setM4p4_i_currency_number(invoice.getCurrencyCode());
                    //发票明细.含税金额
                    m4p4_inventry.setM4p4_tax_amount(invoice.getTaxAmount());
                    //发票明细.未税金额
                    m4p4_inventry.setM4p4_no_tax_amount(invoice.getNoTaxAmount());
                    //发票明细.税额
                    m4p4_inventry.setM4p4_i_tax(invoice.getDiffTaxMoney());
//                    m4p4_inventry.setM4p4_invoice_image(pcaDetail.getInvoicedImageCode());
                    j.getAndIncrement();
                    m4p4_inventry.setSeq(j.intValue());
                    entryList3.add(m4p4_inventry);
                });


                payImportToOpenDTO.setData(dataHead);
                ErpApiResult<com.jwipc.sys.dto.PaymentImportToOpenResultDTO> result = financialShareClient.contractPayImportToOpen(accessToken, payImportToOpenDTO);
                if (!result.getStatus()) {
                    redisTemplate.delete(lockKey);
                    redisTemplate.delete(lockKey1);
                    throw new DaoException("金蝶系统接口报错：" + result.getMessage());
                }
                String id = result.getData().getResult().get(0).getId();
                String code = result.getData().getResult().get(0).getNumber();
                paymentCodApply.setOaProcessId(id);
                paymentCodApply.setOaProcessCode(code);
                paymentCodApply.setStatus(3);
                contractPaymentApplyService.updateById(paymentCodApply);
                redisTemplate.delete(lockKey);
                redisTemplate.delete(lockKey1);
            }
        }
    }

}
