package com.jwipc.finance.logic.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Maps;
import com.jwipc.constant.DictCode;
import com.jwipc.dto.ExportDataDTO;
import com.jwipc.exception.DaoException;
import com.jwipc.finance.convert.PaymentPlanDetailConvert;
import com.jwipc.finance.dto.PaymentPlanItemDTO;
import com.jwipc.finance.entity.PaymentPlan;
import com.jwipc.finance.entity.PaymentPlanDetail;
import com.jwipc.finance.logic.PaymentPlanDetailLogic;
import com.jwipc.finance.model.po.AccountStatementPO;
import com.jwipc.finance.model.po.CreatePcaDetailPO;
import com.jwipc.finance.model.po.PaymentPlanDetailPO;
import com.jwipc.finance.model.query.AccountStatementQuery;
import com.jwipc.finance.model.query.PaymentPlanQuery;
import com.jwipc.finance.service.*;
import com.jwipc.page.PageUtil;
import com.jwipc.page.PageView;
import com.jwipc.security.LoginUtil;
import com.jwipc.supplier.clent.dto.SupplierDTO;
import com.jwipc.supplier.client.SupplierClient;
import com.jwipc.supplier.entity.Supplier;
import com.jwipc.sys.client.DictClient;
import com.jwipc.sys.client.SequenceClient;
import com.jwipc.sys.client.dto.DictDTO;
import com.jwipc.sys.model.po.CompanyPO;
import com.jwipc.sys.model.po.PurchaseGroupPO;
import com.jwipc.sys.model.query.CompanyQuery;
import com.jwipc.sys.model.query.PurchaseGroupQuery;
import com.jwipc.sys.service.ICompanyService;
import com.jwipc.sys.service.IPurchaseGroupService;
import com.jwipc.util.DateUtils;
import com.jwipc.util.EasyExcelUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.temporal.WeekFields;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author 邓京术
 * @date 2025/9/4 14:00
 * @desc
 */
@Service
@RequiredArgsConstructor
public class PaymentPlanDetailLogicImpl implements PaymentPlanDetailLogic {
    private final PaymentPlanDetailConvert paymentPlanDetailConvert;
    private final IPaymentPlanDetailService paymentPlanDetailService;
    private final IAccountStatementService accountStatementService;
    private final IPaymentPlanService paymentPlanService;
    private final StringRedisTemplate stringRedisTemplate;
    private final DictClient dictClient;
    private final SequenceClient sequenceClient;
    private final IInvoicedApplyDetailService invoicedApplyDetailService;
    private final SupplierClient supplierClient;
    private final ICompanyService companyService;
    private final IPurchaseGroupService purchaseGroupService;

    @Override
    public PageView findByPaymentPlanIdPage(PaymentPlanQuery paymentPlanQuery) {
//    public PageView findByPaymentPlanIdPage(Long ppId,String supCodeOrName,String companyCode,String paymentTermCode,String paymentWay,String currencyCode,String purchaseGroup,String paymentExpireDateStart,String paymentExpireDateEnd) {
        if (paymentPlanQuery.getPpId() != null) {
            List<PaymentPlanDetailPO> statementItemPOS = paymentPlanDetailService.findByPaymentPlanId(paymentPlanQuery);
            List<PaymentPlanItemDTO> list = paymentPlanDetailConvert.po2DtoList(statementItemPOS);
            list.stream().forEach(itemDTO ->{
                WeekFields weekFields = WeekFields.of(Locale.getDefault());
                // 获取当前日期的周数（周一作为一周的开始）
                int weekOfMonth = itemDTO.getPaymentExpireDate().get(weekFields.weekOfMonth());
                itemDTO.setPaymentPlanWeek(weekOfMonth + "");
            });
            PageView pageView = PageUtil.getPV(list, list.size());
            return pageView;
        }else {
            return null;
        }
    }

    /**
     * 明细查看页面，数据导出按钮
     * @param paymentPlanQuery
     * @return
     */
    @Override
    public void exportPaymentPlanDetailData(HttpServletResponse response, String exportFiled, PaymentPlanQuery paymentPlanQuery) {
        //需要查询一下总数
        paymentPlanQuery.setRows(1);
        paymentPlanQuery.setPage(1);
        String go_published = stringRedisTemplate.opsForValue().get("exportPaymentPlanDetailData_" + LoginUtil.getUserId());
        if (null != go_published && go_published.equals("Y")) {
            throw new DaoException("数据正在导出中，请勿重复操作！");
        }
//        final Page<ShortagePlanReleasePO> page = PageUtil.toPage(basicPlanQuery);
//        shortagePlanService.findWaitReleaseData(page, basicPlanQuery);
//        final long total = page.getTotal();
////        if (total > sysProp.getExportMaxCount()) {
//////            throw new DaoException(StrUtil.format("导出数据超过{}条", sysProp.getExportMaxCount()));
////        }
        Set<String> colorList = Set.of("actualPayAmount","remark","paymentExpireDate");
        // 查询数据列表，直接调用列表的查询，无需特殊改动
        exportFiled = exportFiled.replace("deleteFlag","deleteDes");

        final List<DictDTO> paymentTermList = dictClient.getDicByType(DictCode.PAYMENT_TERMS.getCode());
        List<String> paymentTerms = new ArrayList<>();
        paymentTerms.addAll(paymentTermList.stream()
                .map(DictDTO::getName)
                .collect(Collectors.toList()));

        final List<DictDTO> paymentWayList = dictClient.getDicByType(DictCode.PAYMENT_WAY.getCode());
        List<String> paymentWays = new ArrayList<>();
        paymentWays.addAll(paymentWayList.stream()
                .map(DictDTO::getName)
                .collect(Collectors.toList()));


        final List<DictDTO> currencyList = dictClient.getDicByType(DictCode.CURRENCY.getCode());
        List<String> currencies = new ArrayList<>();
        currencies.addAll(currencyList.stream()
                .map(DictDTO::getName)
                .collect(Collectors.toList()));

        List<ExportDataDTO> exportDataDTOS = JSON.parseArray(exportFiled, ExportDataDTO.class);
        final ExportDataDTO exportDataDTO = ExportDataDTO.builder().field("id").title("").build();
        exportDataDTOS.add(0, exportDataDTO);
        for (ExportDataDTO dataDTO : exportDataDTOS) {
            if (colorList.contains(dataDTO.getField())) {
                dataDTO.setColor(IndexedColors.YELLOW.getIndex());
            }
            if ("paymentTermCode".equals(dataDTO.getField())){
                dataDTO.setSelectList(paymentTerms);
            }
            if ("paymentWay".equals(dataDTO.getField())){
                dataDTO.setSelectList(paymentWays);
            }
            if ("currencyCode".equals(dataDTO.getField())){
                dataDTO.setSelectList(currencies);
            }
//            if ("paymentType".equals(exportDataDTO.getField())){
//                exportDataDTO.setSelectList(mslList);
//            }
        }
        stringRedisTemplate.opsForValue().set("exportPaymentPlanDetailData_" + LoginUtil.getUserId(), "Y", 30, TimeUnit.SECONDS);
        List<PaymentPlanDetailPO> statementItemPOS = paymentPlanDetailService.findByPaymentPlanId(paymentPlanQuery);
        List<PaymentPlanItemDTO> list = paymentPlanDetailConvert.po2DtoList(statementItemPOS);
        list.stream().forEach(itemDTO ->{
            WeekFields weekFields = WeekFields.of(Locale.getDefault());
            // 获取当前日期的周数（周一作为一周的开始）
            int weekOfMonth = itemDTO.getPaymentExpireDate().get(weekFields.weekOfMonth());
            itemDTO.setPaymentPlanWeek(weekOfMonth + "");

            if (itemDTO.getDeleteFlag() == 0) {
                itemDTO.setDeleteDes("未删除");
            } else {
                itemDTO.setDeleteDes("已删除");
            }

            itemDTO.setPaymentType((itemDTO.getPaymentType() == null || itemDTO.getPaymentType().equals("D"))?"对账款":"预付款");

            currencyList.stream().forEach(oo->{
                if (oo.getCode().equals(itemDTO.getCurrencyCode())) {
                    itemDTO.setCurrencyCode(oo.getName());
                }
            });

            paymentTermList.stream().forEach(oo->{
                if (oo.getCode().equals(itemDTO.getPaymentTermCode())) {
                    itemDTO.setPaymentTermCode(oo.getName());
                }
            });

            paymentWayList.stream().forEach(oo->{
                if (oo.getCode().equals(itemDTO.getPaymentWay())) {
                    itemDTO.setPaymentWay(oo.getName());
                }
            });
        });
        //同步执行
        try {
            EasyExcelUtils.trendsModelWriteTow(response,
                    "付款计划明细数据-" + DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN), "sheet", list,
                    exportDataDTOS);
        } catch (IOException e) {
            throw new RuntimeException("导出excel文档失败.");
        }
        stringRedisTemplate.opsForValue().set("exportPaymentPlanDetailData_" + LoginUtil.getUserId(), "N", 30, TimeUnit.SECONDS);
    }

    @Override
    public void importPaymentPlanDetailData(List<Map<String, String>> dataList) {
        int i = 2;
        StringBuilder sb = new StringBuilder();
        //如果付款计划单号不一致，则报错，如果付款计划单号数据库不存在，则报错。
        String paymentPlanNo = "";
        //用来检查对账单号不能重复导入。
        Map<String,String> accountStatementNoMap = Maps.newHashMap();
        List<PaymentPlanDetail> updatePayDetailList = new ArrayList<>();
        PaymentPlan paymentPlanTemp = null;



        for (Map<String, String> stringMap : dataList) {
            i ++ ;
            String actualPayAmount = stringMap.get("actualPayAmount");//应付金额
            String appliedUnpaidAmount = stringMap.get("appliedUnpaidAmount");//已请款未付金额(历史)
            String paymentExpireDate = stringMap.get("paymentExpireDate");//付款到期日
            String supplierCode = stringMap.get("supplierCode");
            String supplierName = stringMap.get("supplierName");
            String companyCode = stringMap.get("companyCode");
            String currencyCode = stringMap.get("currencyCode");
            String paymentType = stringMap.get("paymentType");//类型
            String paymentWay = stringMap.get("paymentWay");//付款方式
            String paymentTermCode = stringMap.get("paymentTermCode");//付款条件
            String purchaseGroup = stringMap.get("purchaseGroup");//采购组
            String accountStatementYear = stringMap.get("accountStatementYear");//采购组
            String accountStatementMonth = stringMap.get("accountStatementMonth");//采购组
            String remark = stringMap.get("remark");//备注
            String status = stringMap.get("status");//备注
            if (null != status && "删除".equals(status)) {
                continue;
            }

            //校验对账单号是否存在
            String id = stringMap.get("id");
            Boolean isAdd = StringUtils.isEmpty(id);
            String accNo = stringMap.get("accountStatementNo");
            String paymentPlanNoTemp = stringMap.get("paymentPlanNo");
            final List<DictDTO> currencyList = dictClient.getDicByType(DictCode.CURRENCY.getCode());
            final List<DictDTO> paymentTermList = dictClient.getDicByType(DictCode.PAYMENT_TERMS.getCode());
            final List<DictDTO> paymentWayList = dictClient.getDicByType(DictCode.PAYMENT_WAY.getCode());
            CompanyQuery query =  new CompanyQuery();
            List<CompanyPO> companyList = companyService.findPageByQuery(null, query);
            PurchaseGroupQuery groupQuery = new PurchaseGroupQuery();
            List<PurchaseGroupPO> purchaseGroupPOS = purchaseGroupService.findPageByQuery(null, groupQuery);

            if (!StringUtils.isNotEmpty(paymentPlanNoTemp)) {
                throw new DaoException("付款计划单号不能为空，请检查!");
            }

            //付款到期日格式校验  2025-03-12
            if (StringUtils.isNotEmpty(stringMap.get("paymentExpireDate"))) {
                try {
                    String launchDateStr = stringMap.get("paymentExpireDate").replaceAll("/","-");
                    LocalDateTime launchDate = DateUtils.formatYYYYMMDDDash(launchDateStr);
                    stringMap.put("paymentExpireDate",launchDateStr);
                } catch (Exception e) {
                    sb.append("第" + i + "行付款到期日格式错误，请检查\n\r");
                }
            } else {
                sb.append("第" + i + "行付款到期日不能为空，请检查\n\r");
            }
            if (StringUtils.isNotEmpty(actualPayAmount)) {
                try {
                    BigDecimal temp = new BigDecimal(actualPayAmount);
                } catch (Exception e) {
                    sb.append("第" + i + "行应付金额:"+actualPayAmount+"格式错误，请检查\n\r");
                }
            }
            if (StringUtils.isNotEmpty(appliedUnpaidAmount)) {
                try {
                    BigDecimal temp = new BigDecimal(appliedUnpaidAmount);
                } catch (Exception e) {
                    sb.append("第" + i + "行已请款未付金额(历史):"+appliedUnpaidAmount+"格式错误，请检查\n\r");
                }
            }

            //检查供应商是否存在
            SupplierDTO supplier = null;
            if (StringUtils.isNotEmpty(supplierCode)) {
                if (isAdd) {
                    supplier = supplierClient.getSupplierByCode(supplierCode);
                    if (!Objects.nonNull(supplier)) {
                        sb.append("第" + i + "行供应商编码"+supplierCode + "不存在，请检查\n\r");
                    }
                }
            } else {
                sb.append("第" + i + "行供应商编码不能为空，请检查\n\r");
            }
            if (StringUtils.isNotEmpty(supplierName)) {
                if (isAdd) {
                    if (!supplier.getSupplierName().equals(supplierName)) {
                        sb.append("第" + i + "行供应商名称："+supplierName + "不匹配，请检查\n\r");
                    }
                }
            } else {
                sb.append("第" + i + "行供应商名称不能为空，请检查\n\r");
            }

            if (StringUtils.isNotEmpty(companyCode)) {

            } else {
                sb.append("第" + i + "行公司不能为空，请检查\n\r");
            }

            if (StringUtils.isNotEmpty(paymentWay)) {

            } else {
                sb.append("第" + i + "行付款方式不能为空，请检查\n\r");
            }

            if (StringUtils.isNotEmpty(currencyCode)) {

            } else {
                sb.append("第" + i + "行币种不能为空，请检查\n\r");
            }

            if (StringUtils.isNotEmpty(paymentTermCode)) {

            } else {
                sb.append("第" + i + "行付款条件不能为空，请检查\n\r");
            }

            if (StringUtils.isNotEmpty(purchaseGroup)) {

            } else {
                sb.append("第" + i + "行采购组不能为空，请检查\n\r");
            }
            boolean flag = false;
            for (DictDTO oo : currencyList) {
                if (oo.getName().equals(currencyCode)) {
                    currencyCode = oo.getCode();
                    flag = true;
                    break;
                }
            }
            if (!flag) {
                sb.append("第" + i + "行币种:"+currencyCode+"不存在，请检查\n\r");
            }
            flag = false;
            for (DictDTO oo : paymentTermList) {
                if (oo.getName().equals(paymentTermCode)) {
                    paymentTermCode = oo.getCode();
                    flag = true;
                    break;
                }
            }
            if (!flag) {
                sb.append("第" + i + "行付款条件:"+paymentTermCode+"不存在，请检查\n\r");
            }
            flag = false;
            for (DictDTO oo : paymentWayList) {
                if (oo.getName().equals(paymentWay)) {
                    paymentWay = oo.getCode();
                    flag = true;
                    break;
                }
            }
            if (!flag) {
                sb.append("第" + i + "行付款方式:"+paymentWay+"不存在，请检查\n\r");
            }
            flag = false;
            for (CompanyPO oo : companyList) {
                companyCode = companyCode.replace("(","").replace(")","");
                if ((oo.getCompanyCode()+oo.getCompanyName()).equals(companyCode)) {
                    companyCode = oo.getCompanyCode();
                    flag = true;
                    break;
                }
            }
            if (!flag) {
                sb.append("第" + i + "行公司:"+companyCode+"不存在，请检查\n\r");
            }
            flag = false;
            for (PurchaseGroupPO oo : purchaseGroupPOS) {
                purchaseGroup = purchaseGroup.replace("(","").replace(")","");
                if ((oo.getPurchaseGroupCode()+oo.getPurchaseGroupName()).equals(purchaseGroup) || oo.getPurchaseGroupName().equals(purchaseGroup)) {
                    purchaseGroup = oo.getPurchaseGroupCode();
                    flag = true;
                    break;
                }
            }
            if (!flag) {
                sb.append("第" + i + "行采购组:"+purchaseGroup+"不存在，请检查\n\r");
            }

            if (StringUtils.isNotEmpty(sb.toString())) {
                throw new DaoException(sb.toString());
            }


            if (StringUtils.isEmpty(paymentPlanNo)) {
                paymentPlanNo = paymentPlanNoTemp;
                //查询数据库付款计划单号是否存在
                //检查数据库是否已经存在当月付款计划单
                LambdaQueryWrapper<PaymentPlan> paymentPlanLambdaQueryWrapper = new LambdaQueryWrapper<>();
                paymentPlanLambdaQueryWrapper.eq(PaymentPlan::getPaymentPlanNo, paymentPlanNo);
                paymentPlanTemp = paymentPlanService.getOne(paymentPlanLambdaQueryWrapper);
                if (!Objects.nonNull(paymentPlanTemp)) {
                    throw new DaoException("付款计划单号:" + paymentPlanNo + "不存在，请检查!");
                }
            } else if (!paymentPlanNo.equals(paymentPlanNoTemp)) {
                throw new DaoException("付款计划单号:" +paymentPlanNo+"及" + paymentPlanNoTemp + "不一致");
            }
            final PaymentPlanItemDTO paymentPlanItemDTO = BeanUtil.mapToBean(stringMap,
                    PaymentPlanItemDTO.class, true);
            paymentPlanItemDTO.setCurrencyCode(currencyCode);
            paymentPlanItemDTO.setPurchaseGroup(purchaseGroup);
            paymentPlanItemDTO.setCompanyCode(companyCode);
            paymentPlanItemDTO.setPaymentWay(paymentWay);
            paymentPlanItemDTO.setPaymentTermCode(paymentTermCode);

            //校验对账单行号不能重复
            if (StringUtils.isNotEmpty(accNo)) {
                if (StringUtils.isEmpty(accountStatementYear) || StringUtils.isEmpty(accountStatementMonth)) {
                    sb.append("第" + i + "行请填写对账单年月\n\r");
                }
                //如果付款类型为对账款则提示报错， 2025-12-03
                if (null == paymentType || "预付款".equals(paymentType)) {
                    sb.append("第" + i + "行付款类型["+paymentType+"]有误,请检查\n\r");
                }
                if (accountStatementNoMap.keySet().contains(accNo)) {
                    throw new DaoException("第" +i + "行对账单号:" + accNo + "已存在，请检查!");
                } else {
                    accountStatementNoMap.put(accNo, accNo);
                }

                //检查对账单数据库是否存在。。
                AccountStatementQuery accountStatementQuery = new AccountStatementQuery();
                accountStatementQuery.setStatementNo(accNo);
                List<AccountStatementPO> paymentPlanDetailPOS = accountStatementService.accountOrApplyListByNo(accountStatementQuery);
                if (null == paymentPlanDetailPOS || paymentPlanDetailPOS.size() <= 0) {
                    throw new DaoException("第" +i + "行对账单号:" + accNo + "不存在");
                }

                PaymentPlanQuery paymentPlanQuery = new PaymentPlanQuery();
                paymentPlanQuery.setPpId(String.valueOf(paymentPlanTemp.getId()));
                paymentPlanQuery.setAccountStatementNo(accNo);
                List<PaymentPlanDetailPO> paymentPlanDetailList = paymentPlanDetailService.findByPaymentPlanId(paymentPlanQuery);
                //新增的情况
                if (isAdd) {
                    if(null != paymentPlanDetailList && paymentPlanDetailList.size() >= 1) {
                        throw new DaoException("对账单号：" + accNo + "不能重复");
                    }
                    AccountStatementPO temp = paymentPlanDetailPOS.get(0);
                    if (!temp.getSupplierCode().equals(supplierCode)) {
                        throw new DaoException("供应商编码：" + supplierCode + "与原对账单号的供应商编码: "+temp.getSupplierCode()+"不一致。");
                    }
                    if (!temp.getCompanyCode().equals(companyCode)) {
                        throw new DaoException("公司：" + companyCode + "与原对账单号的公司: "+temp.getCompanyCode()+"不一致。");
                    }
                    if (!temp.getCurrencyCode().equals(currencyCode)) {
                        throw new DaoException("货币：" + currencyCode + "与原对账单号的货币: "+temp.getCurrencyCode()+"不一致。");
                    }
                    if (!temp.getPaymentWay().equals(paymentWay)) {
//                        throw new DaoException("付款方式：" + paymentWay + "与原对账单号的付款方式: "+temp.getPaymentWay()+"不一致。");
                    }
                    if (!temp.getPaymentTermCode().equals(paymentTermCode)) {
                        throw new DaoException("付款条件：" + paymentTermCode + "与原对账单号的付款条件: "+temp.getPaymentTermCode()+"不一致。");
                    }
                    if (!temp.getPurchaseGroup().equals(purchaseGroup)) {
                        throw new DaoException("采购组：" + purchaseGroup + "与原对账单号的采购组: "+temp.getPurchaseGroup()+"不一致。");
                    }
                    //计算
                    PaymentPlanDetail paymentPlanDetail = paymentPlanItemDTO.toAsd();
                    paymentPlanDetail.setPaymentPlanId(paymentPlanTemp.getId());
                    paymentPlanDetail.setPaymentPlanNo(paymentPlanNo);
                    final String itemNo = sequenceClient.getCodeSequenceNo(paymentPlanNo , "payment_plan_code",1);
                    paymentPlanDetail.setPaymentPlanDetailNo(Integer.parseInt(itemNo));
                    paymentPlanDetail.setCreateUserId(LoginUtil.getUserId());
                    paymentPlanDetail.setCreateUserCode(LoginUtil.getAccount());
                    paymentPlanDetail.setCreateUserName(LoginUtil.getName());
                    paymentPlanDetail.setCreateTime(LocalDateTime.now());
                    paymentPlanDetail.setNewSign("X");
                    paymentPlanDetail.setPaymentType("D");
                    // 获取当前日期的周数（周一作为一周的开始）
                    WeekFields weekFields = WeekFields.of(Locale.getDefault());
                    int weekOfMonth = paymentPlanDetail.getPaymentExpireDate().get(weekFields.weekOfMonth());
                    paymentPlanDetail.setPaymentPlanWeek(weekOfMonth + "");
//                            asd.setAccountStatementYear(temp.getAccountStatementYear());
//                            asd.setAccountStatementMonth(temp.getAccountStatementMonth());
                    //计算上月已申请，未付款的金额放到未付金额（历史）
                    List<CreatePcaDetailPO>  createPcaDetailPOS = invoicedApplyDetailService.queryCodApplyInvoiceListByAccountStatementNo(accNo, paymentPlanTemp.getPaymentPlanYear() + paymentPlanTemp.getPaymentPlanMonth());
                    BigDecimal appliedUnpaidAmountHis = BigDecimal.ZERO;
                    //统计未付金额及应付金额
                    for (CreatePcaDetailPO createPcaDetailPO : createPcaDetailPOS) {
                        //排除已经付款完成的  fin_payment_cod_apply 付款申请主表 status == 5 或者是(承兑汇票类型 且在oa审批中 也算付款完成)
                        if (createPcaDetailPO.getStatus() != null && (createPcaDetailPO.getStatus() == 5 || (createPcaDetailPO.getStatus() == 3 && createPcaDetailPO.getPaymentWayDesc().equals("承兑汇票")))) {
                            //付款完成的累加
                        } else {
                            appliedUnpaidAmountHis = appliedUnpaidAmountHis.add(createPcaDetailPO.getBudOutMoney());
                        }
                    }
                    paymentPlanDetail.setAppliedUnpaidAmount(appliedUnpaidAmountHis);
                    updatePayDetailList.add(paymentPlanDetail);
                    //修改的情况
                } else {
                    //只能修改应付金额和付款日期，备注
                    PaymentPlanDetail paymentPlanDetail = paymentPlanDetailService.getById(id);
                    if (Objects.isNull(paymentPlanDetail)) {
                        throw new DaoException("付款计划明细id:" + id + "不存在，请检查");
                    }
                    if(null != paymentPlanDetailList && paymentPlanDetailList.size() >= 1 && !String.valueOf(paymentPlanDetailList.get(0).getId()).equals(id)) {
                        throw new DaoException("对账单号：" + accNo + "不能重复");
                    }
                    paymentPlanDetail.setActualPayAmount(paymentPlanItemDTO.getActualPayAmount());
                    paymentPlanDetail.setRemark(paymentPlanItemDTO.getRemark()==null?"":paymentPlanItemDTO.getRemark());
                    paymentPlanDetail.setAppliedUnpaidAmount(new BigDecimal(appliedUnpaidAmount));
                    paymentPlanDetail.setPaymentExpireDate(paymentPlanItemDTO.getPaymentExpireDate());
                    WeekFields weekFields = WeekFields.of(Locale.getDefault());
                    // 获取当前日期的周数（周一作为一周的开始）
                    int weekOfMonth = paymentPlanDetail.getPaymentExpireDate().get(weekFields.weekOfMonth());
                    paymentPlanDetail.setPaymentPlanWeek(weekOfMonth + "");
                    paymentPlanDetail.setRemark(remark);
                    paymentPlanDetail.setUpdateUserId(LoginUtil.getUserId());
                    paymentPlanDetail.setUpdateUserCode(LoginUtil.getAccount());
                    paymentPlanDetail.setUpdateUserName(LoginUtil.getName());
                    paymentPlanDetail.setUpdateTime(LocalDateTime.now());
                    paymentPlanDetail.setPaymentWay(paymentPlanItemDTO.getPaymentWay());
                    updatePayDetailList.add(paymentPlanDetail);
                }
                //如果对账单号为空，则
            } else {
                if (StringUtils.isNotEmpty(accountStatementYear) || StringUtils.isNotEmpty(accountStatementMonth)) {
                    sb.append("第" + i + "行请不要填写对账单年月\n\r");
                }
                //如果付款类型为对账款则提示报错， 2025-12-03
                if (null == paymentType || "对账款".equals(paymentType)) {
                    sb.append("第" + i + "行付款类型["+paymentType+"]有误,请检查\n\r");
                }
                //新增的情况
                if (isAdd) {
                    PaymentPlanDetail paymentPlanDetail = paymentPlanItemDTO.toAsd();
                    paymentPlanDetail.setPaymentPlanId(paymentPlanTemp.getId());
                    paymentPlanDetail.setPaymentPlanNo(paymentPlanNo);
                    //计算上月已申请，未付款的金额放到未付金额（历史）
                    AccountStatementQuery accountStatementQuery = new AccountStatementQuery();
                    accountStatementQuery.setSupplierCode(paymentPlanDetail.getSupplierCode());
                    accountStatementQuery.setCompanyCode(paymentPlanDetail.getCompanyCode());
                    accountStatementQuery.setAccountStatementYear(paymentPlanTemp.getPaymentPlanYear() + paymentPlanTemp.getPaymentPlanMonth());
                    List<AccountStatementPO> accountStatementPOS = accountStatementService.findAccountStatementBySupplierCodeS2(accountStatementQuery);
                    //计算总额
                    final BigDecimal[] budOutMoney = {BigDecimal.ZERO};
                    accountStatementPOS.stream().forEach(oo -> {
                        //排除已经付款完成的  fin_payment_advance_apply 付款申请主表 status == 5
                        if (oo.getStatus() != null && oo.getStatus() == 5) {
                            //付款完成的累加
                        } else if (null != oo.getActualUnpaidAmount()) {
                            budOutMoney[0] = budOutMoney[0].add(oo.getActualUnpaidAmount());
                        }
                    });
                    paymentPlanDetail.setAppliedUnpaidAmount(budOutMoney[0]);
                    final String itemNo = sequenceClient.getCodeSequenceNo(paymentPlanNo , "payment_plan_code",1);
                    paymentPlanDetail.setPaymentPlanDetailNo(Integer.parseInt(itemNo));
                    paymentPlanDetail.setCreateUserId(LoginUtil.getUserId());
                    paymentPlanDetail.setCreateUserCode(LoginUtil.getAccount());
                    paymentPlanDetail.setCreateUserName(LoginUtil.getName());
                    paymentPlanDetail.setCreateTime(LocalDateTime.now());
                    paymentPlanDetail.setNewSign("X");
                    paymentPlanDetail.setPaymentType("S");
                    updatePayDetailList.add(paymentPlanDetail);
                    //修改的情况
                } else {
                    //只能修改应付金额和付款日期，备注
                    PaymentPlanDetail paymentPlanDetail = paymentPlanDetailService.getById(id);
                    if (Objects.isNull(paymentPlanDetail)) {
                        throw new DaoException("付款计划明细id:" + id + "不存在，请检查");
                    }
                    paymentPlanDetail.setActualPayAmount(paymentPlanItemDTO.getActualPayAmount());
                    paymentPlanDetail.setRemark(paymentPlanItemDTO.getRemark()==null?"":paymentPlanItemDTO.getRemark());
                    paymentPlanDetail.setAppliedUnpaidAmount(new BigDecimal(appliedUnpaidAmount));
                    paymentPlanDetail.setPaymentExpireDate(paymentPlanItemDTO.getPaymentExpireDate());
                    WeekFields weekFields = WeekFields.of(Locale.getDefault());
                    // 获取当前日期的周数（周一作为一周的开始）
                    int weekOfMonth = paymentPlanDetail.getPaymentExpireDate().get(weekFields.weekOfMonth());
                    paymentPlanDetail.setPaymentPlanWeek(weekOfMonth + "");
                    paymentPlanDetail.setRemark(remark);
                    paymentPlanDetail.setUpdateUserId(LoginUtil.getUserId());
                    paymentPlanDetail.setUpdateUserCode(LoginUtil.getAccount());
                    paymentPlanDetail.setUpdateUserName(LoginUtil.getName());
                    paymentPlanDetail.setUpdateTime(LocalDateTime.now());
                    paymentPlanDetail.setPaymentWay(paymentPlanItemDTO.getPaymentWay());
                    updatePayDetailList.add(paymentPlanDetail);
                }
            }
            //如果错误达到5000长度，就抛出异常 2025-05-21 邓京术
            if (StringUtils.isNotEmpty(sb.toString()) && sb.toString().length() > 5000) {
                throw new DaoException(sb.toString());
            }
        }
        if (StringUtils.isNotEmpty(sb.toString())) {
            throw new DaoException(sb.toString());
        }
        if (!updatePayDetailList.isEmpty()) {
            if(!paymentPlanDetailService.saveOrUpdateBatch(updatePayDetailList)){
                throw new DaoException("导入付款单明细数据失败, 请联系管理员");
            }
        }
    }

}
