package cn.superdesk.uniorder.service.invoice.customer.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import cn.superdesk.uniorder.common.enums.accounting.AccountingOrderDimCreateByEnum;
import cn.superdesk.uniorder.common.enums.common.CommonDirectionEnum;
import cn.superdesk.uniorder.common.enums.common.CommonOrderGoodsUnitEnum;
import cn.superdesk.uniorder.common.enums.common.CommonServiceNoEnum;
import cn.superdesk.uniorder.common.enums.thirdpart.jd.SysQuartzScheduleTaskStatementOfAccountRunStateEnum;
import cn.superdesk.uniorder.common.excel.utils.ExcelExportModeEasyExcelUtils;
import cn.superdesk.uniorder.common.excel.ExcelResponse;
import cn.superdesk.uniorder.common.excel.biz.SugarUpBigDecimalCellWriteHandler;
import cn.superdesk.uniorder.common.exception.utils.ExceptionUtils;
import cn.superdesk.uniorder.common.json.AnJsonUtils;
import cn.superdesk.uniorder.common.numerical.AnBeanUtils;
import cn.superdesk.uniorder.common.numerical.AnStringUtils;
import cn.superdesk.uniorder.dao.entity.accounting.score.customer.AccountingScoreCustomer;
import cn.superdesk.uniorder.dao.entity.invoice.common.InvoiceBankInfo;
import cn.superdesk.uniorder.dao.entity.sys.notify.SysNotify;
import cn.superdesk.uniorder.dao.mapper.invoice.customer.InvoiceApplyMapperExScore;
import cn.superdesk.uniorder.dao.mapper.invoice.customer.InvoiceApplyMapperExUnified;
import cn.superdesk.uniorder.dto._constant.ResourceConstant;
import cn.superdesk.uniorder.dto.vo.invoice.common.InvoiceBankInfoVo;
import cn.superdesk.uniorder.dto.vo.invoice.customer.*;
import cn.superdesk.uniorder.notify.NotifyUtils;
import cn.superdesk.uniorder.openapicall.thirdpart.szhtxx.electronicInvoice.dto.request.SingleBillingRequestBodyKpContent;
import cn.superdesk.uniorder.service.accounting.score.customer.AccountingScoreCustomerService;
import cn.superdesk.uniorder.service.invoice.common.InvoiceBankInfoService;
import cn.superdesk.uniorder.service.invoice.common.InvoiceTypeService;
import cn.superdesk.uniorder.service.invoice.customer.InvoiceApplyCustomerExportExcelService;
import cn.superdesk.uniorder.service.organisation.SysEnterpriseExtInvoiceService;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: Java类作用描述
 * @Author: linjinyu
 * @CreateDate: 2021/2/23 下午3:55
 * @UpdateUser: linjinyu
 * @UpdateDate: 2021/2/23 下午3:55
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class InvoiceApplyCustomerExportExcelServiceImpl implements InvoiceApplyCustomerExportExcelService {


    @Autowired
    private InvoiceApplyMapperExScore   invoiceApplyCustomerMapperExScore;
    @Autowired
    private InvoiceApplyMapperExUnified invoiceApplyCustomerMapperExUnified;


    @Autowired
    private InvoiceTypeService invoiceTypeService;

    @Autowired
    private SysEnterpriseExtInvoiceService sysEnterpriseExtInvoiceService;
    @Autowired
    private InvoiceBankInfoService         invoiceBankInfoService;
    @Autowired
    private AccountingScoreCustomerService accountingScoreCustomerService;


    @Autowired
    private ResourceConstant resourceConstant;


    /****************************************** 客户结算 发票申请管理 op导出列表 start ******************************************/

    /**
     * TODO 未实现
     *
     * @param resultList
     * @return
     */
    public SysNotify exportExcelInvoiceApplyFocusUnifiedDimGoods(List<ExportExcelInvoiceApplyForceUnifiedDimGoodsVo> resultList) {
        SysNotify sysNotify = new SysNotify();
        return sysNotify;
    }

    /****************************************** 客户结算 发票申请管理 op导出列表   end ******************************************/


    /**************************************** 积分结算 发票申请管理 op导出列表 start ****************************************/

    private static final String TEMPLATE_EXCEL_EXPORT_INVOICE_APPLY_FOCUS_SCORE_LIST_EXCEL_V_2_1 = "exportInvoiceApplyListExcelV2_1.xlsx";

    /**
     * 积分结算 发票申请管理 op导出列表 v2.1
     *
     * @param resultList
     * @return
     */
    public SysNotify exportInvoiceApplyListExcelV2_1(List<InvoiceApplyCustomerPageVo> resultList) {

        String excelExportPathRoot             = resourceConstant.getPathRoot();
        String excelExportRelativePathTemplate = resourceConstant.getPathTemplate();
        String excelExportRelativePathStorage  = resourceConstant.getPathStorage();

        String relativePath = File.separator + "excel" + File.separator + "invoice" + File.separator + "customer" + File.separator;

        String templateRelativePath = excelExportPathRoot + excelExportRelativePathTemplate + relativePath;
        String templateFullPath;

        String targetFullPath          = excelExportPathRoot + excelExportRelativePathStorage;
        String targetFileName          = "积分结算v2.1" + "_" + "发票申请管理_" + "op导出列表" + ExcelResponse.addTail() + ".xlsx";
        String targetWriteFileFullPath = targetFullPath + relativePath + targetFileName;

//		if (!FileUtil.exist(targetWriteFileFullPath)) {
//			FileUtil.mkdir(targetWriteFileFullPath);
//		}
        FileUtil.touch(targetWriteFileFullPath);

        /******************************************  start ******************************************/

        ExcelWriterBuilder excelWriterBuilder = EasyExcel
                .write(targetWriteFileFullPath);
        ExcelWriter excelWriter = null;

        WriteSheet writeSheet0 = EasyExcel
                .writerSheet(0, "列表")
                .build();
        FillConfig fillConfig = FillConfig
                .builder()
                .forceNewRow(Boolean.FALSE)
                .build();


        // 文件
        templateFullPath = templateRelativePath + TEMPLATE_EXCEL_EXPORT_INVOICE_APPLY_FOCUS_SCORE_LIST_EXCEL_V_2_1;

        excelWriter = excelWriterBuilder
                .withTemplate(templateFullPath)
                .build();
        excelWriter
                .fill(new FillWrapper("detail", resultList), fillConfig, writeSheet0);
        // 别忘记关闭流
        excelWriter.finish();


        /******************************************  start ******************************************/

        return NotifyUtils.createSysNotify(
                targetFileName,
                relativePath + targetFileName,
                SysQuartzScheduleTaskStatementOfAccountRunStateEnum.成功
        );
    }

    /**************************************** 积分结算 发票申请管理 op导出列表   end ****************************************/


    private static final String TEMPLATE_EXCEL_EXPORT_INVOICE_APPLY_FOCUS_SCORE_DIM_CREDIT_MODE_1 = "exportExcelInvoiceApplyFocusScoreDimCreditMode1.xlsx";
    private static final String TEMPLATE_EXCEL_EXPORT_INVOICE_APPLY_FOCUS_SCORE_DIM_CREDIT_MODE_2 = "exportExcelInvoiceApplyFocusScoreDimCreditMode2.xlsx";
    private static final String TEMPLATE_EXCEL_EXPORT_INVOICE_APPLY_FOCUS_SCORE_DIM_CREDIT_MODE_3 = "exportExcelInvoiceApplyFocusScoreDimCreditMode3.xlsx";// 导出开票数据

    // 首先这东西分三种情况

//		1. 搜索框 条件 结算集
//		2. 搜索框 条件 结算集 后 界面上 勾选 要以 开票申请编号 分 sheet 分合并前 合并后
//		3. 搜索框 条件 结算集 后 界面上 勾选 要以 开票申请编号 分 sheet 财务专用

    public SysNotify exportExcelInvoiceApplyFocusScoreDimCreditMode1(List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo> resultList) {


        String excelExportPathRoot             = resourceConstant.getPathRoot();
        String excelExportRelativePathTemplate = resourceConstant.getPathTemplate();
        String excelExportRelativePathStorage  = resourceConstant.getPathStorage();

        String relativePath = File.separator + "excel" +
                File.separator + "invoice" +
                File.separator + "customer" +
                File.separator;

        String templateRelativePath = excelExportPathRoot + excelExportRelativePathTemplate + relativePath;
        String templateFullPath;

        String targetFullPath          = excelExportPathRoot + excelExportRelativePathStorage;
        String targetFileName          = "客户结算" + "_" + "发票(开票申请)_" + "导出报表" + ExcelResponse.addTail() + ".xlsx";
        String targetWriteFileFullPath = targetFullPath + relativePath + targetFileName;

//		if (!FileUtil.exist(targetWriteFileFullPath)) {
//			FileUtil.mkdir(targetWriteFileFullPath);
//		}
        FileUtil.touch(targetWriteFileFullPath);

        /******************************************  start ******************************************/

        ExcelWriterBuilder excelWriterBuilder = EasyExcel
                .write(targetWriteFileFullPath);
        ExcelWriter excelWriter = null;

        WriteSheet writeSheet0 = EasyExcel
                .writerSheet(0, "发票申请-结果模式")
                .build();
        FillConfig fillConfig = FillConfig
                .builder()
                .forceNewRow(Boolean.FALSE)
                .build();


        // 文件
        templateFullPath = templateRelativePath + TEMPLATE_EXCEL_EXPORT_INVOICE_APPLY_FOCUS_SCORE_DIM_CREDIT_MODE_1;

        excelWriter = excelWriterBuilder
                .withTemplate(templateFullPath)
                .build();
        excelWriter
                .fill(new FillWrapper("detail", resultList), fillConfig, writeSheet0);

        // 别忘记关闭流
        excelWriter.finish();


        /******************************************  start ******************************************/

        return NotifyUtils.createSysNotify(
                targetFileName,
                relativePath + targetFileName,
                SysQuartzScheduleTaskStatementOfAccountRunStateEnum.成功
        );
    }

    public SysNotify exportExcelInvoiceApplyFocusScoreDimCreditMode2(List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo> resultList) {

        String excelExportPathRoot             = resourceConstant.getPathRoot();
        String excelExportRelativePathTemplate = resourceConstant.getPathTemplate();
        String excelExportRelativePathStorage  = resourceConstant.getPathStorage();

        String relativePath = File.separator + "excel" + File.separator + "invoice" + File.separator + "customer" + File.separator;

        String templateRelativePath = excelExportPathRoot + excelExportRelativePathTemplate + relativePath;
        String templateFullPath;

        String targetFullPath = excelExportPathRoot + excelExportRelativePathStorage;
//		String targetFileName          = "客户结算" + "_" + "发票(开票申请)" + "_" + "勾选导出开票数据" + ExcelResponse.addTail() + ".xlsx";
        // ZIP 积分结算_开票明细_操作导出按钮_202105081028
        String targetZipFileName          = "积分结算" + "_" + "发票(开票申请)" + "_" + "勾选导出报表" + ExcelResponse.addTail() + ".zip";
        String targetZipWriteFileFullPath = targetFullPath + relativePath + targetZipFileName;

//		if (!FileUtil.exist(targetWriteFileFullPath)) {
//			FileUtil.mkdir(targetWriteFileFullPath);
//		}
        FileUtil.touch(targetZipWriteFileFullPath);

        /******************************************  start ******************************************/

//		ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(targetWriteFileFullPath)
////				.inMemory(Boolean.TRUE)
//				;
//		ExcelWriter excelWriter = null;

        templateFullPath = templateRelativePath + TEMPLATE_EXCEL_EXPORT_INVOICE_APPLY_FOCUS_SCORE_DIM_CREDIT_MODE_2;
//		excelWriter = excelWriterBuilder
////				.withTemplate(templateFullPath)
//				.build();

        /****************************************** 侨城汇需求 20210922 start ******************************************/

        qchNeed20210922(resultList);

        /****************************************** 侨城汇需求 20210922   end ******************************************/


        // 得到处理后的数据 - add by linjinyu at 20220418 特殊处理 - 过滤微信
        // 追溯【【结算中心-正式环境】积分结算-发票申请管理-CIA2022041508129024-导出报表和导出开票数据-合并数据里面不需要有微信支付的流水数据】https://www.tapd.cn/33003868/bugtrace/bugs/view?bug_id=1133003868001004988
        Map<String, InvoiceApplyCustomerExportExcelFocusScoreDimCreditStruct> resultMap = mergeResultByExcelDebugAndCreateWorkbook(2, resultList);

        // 初始化Excel文件列表
        List<File> excelFileList = new ArrayList<>();

        try {
            int sheetNo = 0;
            for (Map.Entry<String, InvoiceApplyCustomerExportExcelFocusScoreDimCreditStruct> _entry : resultMap.entrySet()) {

                String outVirtName = AnStringUtils.stringListConvertToString(_entry
                        .getValue()
                        .getTransferListBySheet()
                        .stream()
                        .map(ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo::getEnterpriseName)
                        .distinct()
                        .collect(Collectors.toList())
                );
                String invoiceApplySn = _entry.getKey();
                String accountingOrderSn = AnStringUtils.stringListConvertToString(_entry.getValue()
                        .getTransferListBySheet()
                        .stream()
                        .map(ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo::getAccountingOrderSn)
                        .distinct()
                        .collect(Collectors.toList())
                );


                // Excel 企业名称+开票申请单号+结算单编号
//				String targetXlsxFileName          = outVirtName + "_" + invoiceApplySn + "_" + accountingOrderSn + ExcelResponse.addTail() + ".xlsx";
                String targetXlsxFileName          = outVirtName + "_" + accountingOrderSn + "_" + invoiceApplySn + ".xlsx";
                String targetXlsxWriteFileFullPath = targetFullPath + relativePath + targetXlsxFileName;


                ExcelWriter excelWriter = EasyExcel
                        .write(targetXlsxWriteFileFullPath)
                        .inMemory(Boolean.TRUE)
                        .registerWriteHandler(SugarUpBigDecimalCellWriteHandler
                                .builder()
                                .startRow(1)
                                .matchCell(Arrays.asList(13, 15))
                                .build()
                        )
//				        .withTemplate(templateFullPath)
                        .build();


                /****************************************** 侨城汇需求 20210922 start ******************************************/
//				qchNeed20210922(_entry.getValue().getTransferListBySheet());
                /****************************************** 侨城汇需求 20210922   end ******************************************/


                // stream 排序
                List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo> transferListBySheetSortByOrderCreateTime = _entry.getValue().getTransferListBySheet()
                        .stream()
                        .sorted(
                                Comparator
                                        .comparing(ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo::getOrderCreateTime)
                                        .thenComparing(ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo::getOrderSn)
                        )
                        .collect(Collectors.toList());

                sheetNo = sheetNo + 1;
                ExcelExportModeEasyExcelUtils.createSheetByWorkbook(
                        transferListBySheetSortByOrderCreateTime, // _entry.getValue().getTransferListBySheet(),
                        mapperHead.get(2),
                        mapperValue.get(2),
                        excelWriter,
                        sheetNo,
                        _entry.getKey()
                );
                sheetNo = sheetNo + 1;

                /****************************************** 侨城汇需求 20210922 start ******************************************/
//				qchNeed20210922(_entry.getValue().getTransferListBySheetMerge());
                /****************************************** 侨城汇需求 20210922   end ******************************************/

                List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo> transferListBySheetMergeSortByOrderCreateTime = _entry.getValue().getTransferListBySheetMerge()
                        .stream()
                        .sorted(
                                Comparator
                                        .comparing(ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo::getOrderCreateTime)
                                        .thenComparing(ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo::getOrderSn)
                        )
                        .collect(Collectors.toList());

                ExcelExportModeEasyExcelUtils.createSheetByWorkbook(
                        transferListBySheetMergeSortByOrderCreateTime, // _entry.getValue().getTransferListBySheetMerge(),
                        mapperHeadMerge.get(2),
                        mapperValueMerge.get(2),
                        excelWriter,
                        sheetNo,
                        _entry.getKey() + "_合并"
                );

                // 别忘记关闭流
                excelWriter.finish();

                excelFileList.add(FileUtil.file(targetXlsxWriteFileFullPath));
            }

            // 生成zip
            ZipUtil.zip(FileUtil.file(targetZipWriteFileFullPath), false, excelFileList.toArray(new File[excelFileList.size()]));

        } catch (Exception e) {

            log.error("exportExcelInvoiceApplyFocusScoreDimCreditMode2 \n{}", ExceptionUtils.getMessage(e));
            return NotifyUtils.createSysNotify(targetZipFileName, relativePath + targetZipFileName, SysQuartzScheduleTaskStatementOfAccountRunStateEnum.失败);
        }


        /******************************************  start ******************************************/

        return NotifyUtils.createSysNotify(targetZipFileName, relativePath + targetZipFileName, SysQuartzScheduleTaskStatementOfAccountRunStateEnum.成功);
    }

    public SysNotify exportExcelInvoiceApplyFocusScoreDimCreditMode3(List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo> resultList) {


        String excelExportPathRoot             = resourceConstant.getPathRoot();
        String excelExportRelativePathTemplate = resourceConstant.getPathTemplate();
        String excelExportRelativePathStorage  = resourceConstant.getPathStorage();

        String relativePath = File.separator + "excel" + File.separator + "invoice" + File.separator + "customer" + File.separator;

        String templateRelativePath = excelExportPathRoot + excelExportRelativePathTemplate + relativePath;
        String templateFullPath;


        String targetFullPath = excelExportPathRoot + excelExportRelativePathStorage;
//		String targetFileName          = "客户结算" + "_" + "发票(开票申请)" + "_" + "勾选导出开票数据" + ExcelResponse.addTail() + ".xlsx";
        // ZIP 积分结算_开票明细_操作导出按钮_202105081028
        String targetZipFileName          = "积分结算" + "_" + "发票(开票申请)" + "_" + "勾选导出开票数据" + ExcelResponse.addTail() + ".zip";
        String targetZipWriteFileFullPath = targetFullPath + relativePath + targetZipFileName;

//		if (!FileUtil.exist(targetWriteFileFullPath)) {
//			FileUtil.mkdir(targetWriteFileFullPath);
//		}
        FileUtil.touch(targetZipWriteFileFullPath);

        /******************************************  start ******************************************/

//		ExcelWriterBuilder excelWriterBuilder = ;

        // 模板文件没在用
        templateFullPath = templateRelativePath + TEMPLATE_EXCEL_EXPORT_INVOICE_APPLY_FOCUS_SCORE_DIM_CREDIT_MODE_3;

        /****************************************** 侨城汇需求 20210922 start ******************************************/

        qchNeed20210922(resultList);

        /****************************************** 侨城汇需求 20210922   end ******************************************/

        // 得到处理后的数据
        Map<String, InvoiceApplyCustomerExportExcelFocusScoreDimCreditStruct> resultMap = mergeResultByExcelDebugAndCreateWorkbook(3, resultList);

        // 初始化Excel文件列表
        List<File> excelFileList = new ArrayList<>();

        try {

            // 生成 excel
            int sheetNo = 0;
            for (Map.Entry<String, InvoiceApplyCustomerExportExcelFocusScoreDimCreditStruct> _entry : resultMap.entrySet()) {

                String outVirtName = AnStringUtils.stringListConvertToString(_entry.getValue()
                        .getTransferListBySheet()
                        .stream()
                        .map(ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo::getEnterpriseName)
                        .distinct()
                        .collect(Collectors.toList())
                );
                String invoiceApplySn = _entry.getKey();
                String accountingOrderSn = AnStringUtils.stringListConvertToString(_entry.getValue()
                        .getTransferListBySheet()
                        .stream()
                        .map(ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo::getAccountingOrderSn)
                        .distinct()
                        .collect(Collectors.toList())
                );


                // Excel 企业名称+开票申请单号+结算单编号
//				String targetXlsxFileName          = outVirtName + "_" + invoiceApplySn + "_" + accountingOrderSn + ExcelResponse.addTail() + ".xlsx";
                String targetXlsxFileName          = outVirtName + "_" + accountingOrderSn + "_" + invoiceApplySn + ".xlsx";
                String targetXlsxWriteFileFullPath = targetFullPath + relativePath + targetXlsxFileName;


                ExcelWriter excelWriter = EasyExcel
                        .write(targetXlsxWriteFileFullPath)
                        .inMemory(Boolean.TRUE)
                        .registerWriteHandler(SugarUpBigDecimalCellWriteHandler.builder().startRow(1).matchCell(Arrays.asList(11)).build())
//				        .withTemplate(templateFullPath)
                        .build();

                /****************************************** 侨城汇需求 20210922 start ******************************************/

//				qchNeed20210922(_entry.getValue().getTransferListBySheetMerge());

                /****************************************** 侨城汇需求 20210922   end ******************************************/

                List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo> transferListBySheetMergeSortByOrderCreateTime = _entry.getValue().getTransferListBySheetMerge()
                        .stream()
                        .sorted(
                                Comparator
                                        .comparing(ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo::getOrderCreateTime)
                                        .thenComparing(ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo::getOrderSn)
                        )
                        .collect(Collectors.toList());

                ExcelExportModeEasyExcelUtils.createSheetByWorkbook(
                        transferListBySheetMergeSortByOrderCreateTime, // _entry.getValue().getTransferListBySheetMerge(),
                        mapperHeadMerge.get(3),
                        mapperValueMerge.get(3),
                        excelWriter,
                        sheetNo,
                        _entry.getKey() + "_合并"
                );

                // 别忘记关闭流
                excelWriter.finish();

                excelFileList.add(FileUtil.file(targetXlsxWriteFileFullPath));

            }

            // 生成zip
            ZipUtil.zip(FileUtil.file(targetZipWriteFileFullPath), false, excelFileList.toArray(new File[excelFileList.size()]));

        } catch (Exception e) {

            log.error("exportExcelInvoiceApplyFocusScoreDimCreditMode2 \n{}", ExceptionUtils.getMessage(e));

            return NotifyUtils.createSysNotify(targetZipFileName, relativePath + targetZipFileName, SysQuartzScheduleTaskStatementOfAccountRunStateEnum.失败);
        }


        /******************************************  start ******************************************/

        return NotifyUtils.createSysNotify(targetZipFileName, relativePath + targetZipFileName, SysQuartzScheduleTaskStatementOfAccountRunStateEnum.成功);
    }

    // 积分结算 findInvoiceApplyFocusScoreDimCredit 的补充
    public void qchNeed20210922(List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo> resultTmp) {


        // 得出当前数据 发票申请的 id -> sn
//		Long   invoiceApplyId;
//		String invoiceApplySn;
//		Map<Long, String> invoiceApplyMap = resultTmp.stream().collect(Collectors.toMap(
//				/* key      */ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo::getInvoiceApplyId,
//				/* value    */ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo::getInvoiceApplySn,
//				/* key重复时 */(key1, key2) -> key2,
//				LinkedHashMap::new
//		));

        /****************************************** 对账单 start ******************************************/

//		Long    accountingOrderId;
//		String  accountingOrderSn;
        Map<Long, String> accountingOrderMap = resultTmp.stream().collect(
                Collectors.toMap(
                        /* key      */ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo::getAccountingOrderId,
                        /* value    */ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo::getAccountingOrderSn,
                        /* key重复时 */(key1, key2) -> key2,
                        LinkedHashMap::new
                ));

        List<Long> accountingOrderIds = CollUtil.newArrayList(accountingOrderMap.keySet());

        Map<Long, AccountingScoreCustomer> accountingScoreCustomerMap                  = accountingScoreCustomerService.convertAccountingScoreCustomerList2MapAccountingOrderIdEntity(accountingOrderIds);
        Map<Long, InvoiceBankInfoVo>       accountingScoreCustomerInvoiceBankInfoVoMap = new HashMap<>();


        for (Map.Entry<Long, AccountingScoreCustomer> _entry : accountingScoreCustomerMap.entrySet()) {

            AccountingScoreCustomer accountingScoreCustomer = _entry.getValue();

            InvoiceBankInfoVo invoiceBankInfoVo;
            if (StrUtil.isNotBlank(accountingScoreCustomer.getInvoiceBankInfoSnapshot())) {
                invoiceBankInfoVo = AnJsonUtils.toObject(accountingScoreCustomer.getInvoiceBankInfoSnapshot(), InvoiceBankInfoVo.class);
            } else {
                InvoiceBankInfo invoiceBankInfo = invoiceBankInfoService.getInvoiceBankInfoByIdOrNullByDefault(accountingScoreCustomer.getBankInfoId());
                invoiceBankInfoVo = AnBeanUtils.copy(invoiceBankInfo, InvoiceBankInfoVo.class);
            }

            accountingScoreCustomerInvoiceBankInfoVoMap.put(_entry.getKey(), invoiceBankInfoVo);
        }

        /****************************************** 对账单   end ******************************************/

        resultTmp.forEach(vo -> {

            /****************************************** 税率 start ******************************************/

            // 税率要求是 取值 0-1 0.00 形态
            if (null != vo.getOperationTaxRate()) {
                vo.setOperationTaxRate(vo.getOperationTaxRate().divide(new BigDecimal(100L), 2, BigDecimal.ROUND_HALF_UP));
            }

            /****************************************** 税率   end ******************************************/

            /****************************************** 默认 start ******************************************/

            vo.setEncryptedVersionNumber("33.0");
            vo.setFlagTaxIncentives("0"); // 享受优惠政策;默认为0
            vo.setFlagTaxIncluded("含税");

            /****************************************** 默认   end ******************************************/

            /****************************************** 填充 销方信息 -> 收款方信息 start ******************************************/

            if (ObjectUtil.isNotNull(accountingScoreCustomerInvoiceBankInfoVoMap)
                    && ObjectUtil.isNotNull(accountingScoreCustomerInvoiceBankInfoVoMap.get(vo.getAccountingOrderId()))) {

                InvoiceBankInfoVo invoiceBankInfoVo = accountingScoreCustomerInvoiceBankInfoVoMap.get(vo.getAccountingOrderId());

                vo.setPersonNameCashier(invoiceBankInfoVo.getPersonNameCashier());
                vo.setPersonNameReview(invoiceBankInfoVo.getPersonNameReview());
                vo.setPersonNameInvoice(invoiceBankInfoVo.getPersonNameInvoice());

            } else {
                vo.setPersonNameCashier("卢嘉文");// 曾鹏 【【结算中心-积分结算】导出开票数据,默认的收款人内容调整为"卢嘉文"。】 https://www.tapd.cn/33003868/prong/stories/view/1133003868001003933
                vo.setPersonNameReview("翁浩锐");
                vo.setPersonNameInvoice("");
            }

            /****************************************** 填充 销方信息 -> 收款方信息   end ******************************************/

//			// 购方信息 -> 企业扩展信息-发票抬中 findInvoiceApplyFocusScoreDimCredit
//			vo.setPurchaserCompanyType("01");

        });
    }


    /****************************************** 甲方要求减几个字段 mark by linjinyu at 20210317   end ******************************************/

//	private static Map<Integer, Function<String[], List<List<String>>>> modeOfExportExcelInvoiceApplyFocusScoreDimCredit = new HashMap<>();

    private static Map<Integer, String[]> mapperHead  = new HashMap<>();
    private static Map<Integer, String[]> mapperValue = new HashMap<>();

    private static Map<Integer, String[]> mapperHeadMerge  = new HashMap<>();
    private static Map<Integer, String[]> mapperValueMerge = new HashMap<>();

    static {

        // 初始化
//		modeOfExportExcelInvoiceApplyFocusScoreDimCredit.put(1, (mode) -> getHead(fieldHeadMode1Static));
//		modeOfExportExcelInvoiceApplyFocusScoreDimCredit.put(2, (mode) -> getHead(fieldHeadMode2Static));
//		modeOfExportExcelInvoiceApplyFocusScoreDimCredit.put(3, (mode) -> getHead(fieldHeadMode3Static));

        mapperHead.put(1, InvoiceApplyCustomerExportExcelFocusScoreDimCreditStatic.fieldHeadMode1Static);
        mapperValue.put(1, InvoiceApplyCustomerExportExcelFocusScoreDimCreditStatic.fieldValueMode1Static);

        mapperHead.put(2, InvoiceApplyCustomerExportExcelFocusScoreDimCreditStatic.fieldHeadMode2Static);
        mapperValue.put(2, InvoiceApplyCustomerExportExcelFocusScoreDimCreditStatic.fieldValueMode2Static);

        mapperHead.put(3, InvoiceApplyCustomerExportExcelFocusScoreDimCreditStatic.fieldHeadMode3Static);
        mapperValue.put(3, InvoiceApplyCustomerExportExcelFocusScoreDimCreditStatic.fieldValueMode3Static);

        mapperHeadMerge.put(2, InvoiceApplyCustomerExportExcelFocusScoreDimCreditStatic.fieldHeadMode2StaticMerge);
        mapperValueMerge.put(2, InvoiceApplyCustomerExportExcelFocusScoreDimCreditStatic.fieldValueMode2StaticMerge);

        mapperHeadMerge.put(3, InvoiceApplyCustomerExportExcelFocusScoreDimCreditStatic.fieldHeadMode3StaticMerge);
        mapperValueMerge.put(3, InvoiceApplyCustomerExportExcelFocusScoreDimCreditStatic.fieldValueMode3StaticMerge);
    }


    /**
     * 可行 再合并 TODO 现在已经改成只处理数据 markby linjinyu at 202106031203
     *
     * @param resultList
     * @return
     */
    public Map<String, InvoiceApplyCustomerExportExcelFocusScoreDimCreditStruct> mergeResultByExcelDebugAndCreateWorkbook(Integer mode, List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo> resultList) {


        // 变换
        List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo> transformList = resultList.parallelStream()
                .filter(o -> CommonOrderGoodsUnitEnum.项.getDesc().equals(o.getUnit()) && null != o.getGoodsId() && o.getGoodsId().equals(-1L))
                .collect(Collectors.toList());

        if (CollUtil.isNotEmpty(transformList)) {
            transformList.forEach(o -> {
                o.setGoodsId(0L);
            });
        }


//        log.info("\n\n\nexportExcelInvoiceApplyFocusScoreDimCredit 数据准备 : {}\n\n\n", AnJsonUtils.toJson(resultList));

//		HSSFWorkbook workbook = new HSSFWorkbook();
        FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.FALSE).build();

        Map<String, InvoiceApplyCustomerExportExcelFocusScoreDimCreditStruct> resultMap = new HashMap<>();

        if (CollUtil.isEmpty(resultList)) {
            return resultMap;
        }

//		// 得出当前数据 发票申请的 id -> sn
//		Map<Long, String> invoiceApplyMap = resultList.stream().collect(Collectors.toMap(
//				/* key      */ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo::getInvoiceApplyId,
//				/* value    */ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo::getInvoiceApplySn,
//				/* key重复时 */(key1, key2) -> key2,
//				LinkedHashMap::new
//		));

        // 因为是可以多选的 所以先按 发票申请Id 分组
        Map<String, List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo>> transferMapGrouopByInvoiceApplyId = resultList
                .parallelStream()
                .collect(Collectors.groupingBy(ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo::getInvoiceApplySn, Collectors.toList()));
//				.collect(Collectors.groupingBy(e -> fetchGroupKey(e), Collectors.toList()));

//		List<ExportExcelInvoiceApplyForceScoreDimCreditVo> transferListBySheet      = null;
//		List<ExportExcelInvoiceApplyForceScoreDimCreditVo> transferListBySheetMerge = null;


        int sheetNo = 0;
        // 因为是可以多选的 所以先按 发票申请Id 分组 每个 entry 是 一份
        for (Map.Entry<String, List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo>> entry : transferMapGrouopByInvoiceApplyId.entrySet()) {

//			transferListBySheet = new ArrayList<>();
//			transferListBySheetMerge = new ArrayList<>();

            InvoiceApplyCustomerExportExcelFocusScoreDimCreditStruct struct = new InvoiceApplyCustomerExportExcelFocusScoreDimCreditStruct();
            struct.setTransferListBySheet(new ArrayList<>());
            struct.setTransferListBySheetMerge(new ArrayList<>());

            // 转换 正负单
            entry.getValue().forEach(item -> {
                // keyword convertInvoiceApplyCustomerSelectScoreVo2ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo
                item.setOrderSn(item.getDirection().compareTo(CommonDirectionEnum.正向.getKey()) == 0 ? item.getOrderSn() : item.getRefundOrderSn());
            });


//            /**************************************** 特殊处理 - 过滤微信 start add by linjinyu at 20220418 ****************************************/
//
//            //【【结算中心-正式环境】积分结算-发票申请管理-CIA2022041508129024-导出报表和导出开票数据-合并数据里面不需要有微信支付的流水数据】https://www.tapd.cn/33003868/bugtrace/bugs/view?bug_id=1133003868001004988
//            /**
//             * InvoiceApplyCustomerQueryCriteria 本身这个类上有这个开关
//             *  @ApiModelProperty("对账单内的流水对账状态;是否对账的问题:-1-不对账;1-已对账;默认为0,不区分;订单|商品|流水,共用的对账状态:-1-不对账;1-已对账;2-未对账;3-已作废; 引用 enum CommonAccountingStateEnum")
//             *  private Integer creditAccountingState = 0;
//             */
//
//            List<Predicate<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo>> filterAccountingStateEq1 = new ArrayList<>();
//            filterAccountingStateEq1.add(r -> !r.getBatchs().equals("wechat"));
//
//            // 过滤出客户对账状态位 为 已对账 1
//            List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo> resultListFilterAccountingStateEq1 = AnLamdaUtils.filters(entry.getValue(), filterAccountingStateEq1);
//
//            /**************************************** 特殊处理 - 过滤微信   end add by linjinyu at 20220418 ****************************************/


            /**************************************** 合并操作 start ****************************************/

            Map<String, List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo>> transferMapGrouopByInvoiceApplyIdGroupBy = entry.getValue()
                    .parallelStream()
                    .collect(Collectors.groupingBy(e -> InvoiceApplyCustomerExportExcelFocusScoreDimCreditStatic.fetchGroupKeyByName(e), Collectors.toList()));

            /**************************************** 合并操作   end ****************************************/

            /**************************************** 合并操作后处理 start ****************************************/

            for (Map.Entry<String, List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo>> _entry : transferMapGrouopByInvoiceApplyIdGroupBy.entrySet()) {


//                CIA2022033160239104_CAA2022033137117184_ME20211007222908382628_JF20210929110466041_福利积分_资生堂沐浴露_91828_13.00_1070223010000000000_129.0000 _size : 2
                log.info("_groupKey : {} _size : {}", _entry.getKey(), _entry.getValue().size());

                // 为什么是大于1? 答:订单里某个商品是用多种积分支付的情况
                if (_entry.getValue().size() > 1) {
//					log.info("\n{}", JsonUtils.toJson(_entry.getValue()));

                    // TODO 处理 合并
                    ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo _merge = new ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo();

                    BeanUtil.copyProperties(_entry.getValue().get(0), _merge);

//                    log.info("难道批次为空？\n{}", JSONUtil.toJsonPrettyStr(_entry.getValue()));

//					【【结算中心-测试环境】【后端处理】积分结算-发票申请管理-发起开票(深圳航信电子发票)，开票申请合并同订单同商品时，数量也叠加合并，商品数量无需合并。】https://www.tapd.cn/33003868/bugtrace/bugs/view?bug_id=1133003868001004804

//					这个问题大概是同一个订单里某个商品是用多种积分支付的情况
                    // 这个问题对最终的数是没差的，差的地方就是缺陷所说的，数量不对且产生了扣减项，最终的结算金额是没有问题 mark by linjinyu at 20220328

                    // 商品数量
                    _merge.setQuantity(_entry.getValue().stream()
//                            .filter(o -> o.getOutSnapshotOrderGoodsId() != null)
//                            .filter(AnLamdaUtils.distinctByKey(o -> o.getOutSnapshotOrderGoodsId()))
                            .map(item -> item.getQuantity() == null ? 0 : item.getQuantity())
                            .reduce(0, Integer::sum));


                    /**************************************** 商品数量 分开两种情况处理 mark by linjinyu at 20220328 start ****************************************/

                    /** 妈的，改需求后这个又不合用了
                     //                    正负 向 plus-minus

                     //                    BigDecimal plusQuantity = _entry.getValue().stream()
                     //                            .filter(AnLamdaUtils.distinctByKey(o -> o.getOrderSn() + o.getGoodsId()))
                     //                            .map(item -> item.getQuantity() == null ? 0 : item.getQuantity())
                     //                            .reduce(0, Integer::sum);

                     // 妈的，改需求后这个又不合用了
                     Map<String, Integer> orderSnGoodsIdMap = _entry.getValue().parallelStream()
                     .collect(
                     //                                    Collectors.groupingBy(e -> InvoiceApplyCustomerExportExcelFocusScoreDimCreditStatic.fetchGroupKeyByOrderSnGoodsIdForSub(e),
                     Collectors.toMap(
                     /-* key      *-/key -> key.getOrderSn() + "_" + key.getGoodsId().toString(),
                     /-* value    *-/value -> value.getQuantity(),
                     /-* key重复时 *-/(key1, key2) -> key2,
                     LinkedHashMap::new
                     )
                     );

                     log.info("\n查证\n{}", JSONUtil.toJsonPrettyStr(orderSnGoodsIdMap));

                     Integer countQuantity = 0;
                     for (Map.Entry<String, Integer> __entry : orderSnGoodsIdMap.entrySet()) {

                     countQuantity = countQuantity + __entry.getValue();

                     log.info("合并数量 {} {} ", __entry.getKey(), countQuantity);

                     }

                     _merge.setQuantity(countQuantity);
                     **/

                    /**************************************** 商品数量 分开两种情况处理 mark by linjinyu at 20220328   end ****************************************/


//					// 销售单价
//					_merge.setPrice(_entry.getValue().stream()
//							.map(item -> item.getPrice() == null ? BigDecimal.ZERO : item.getPrice())
//							.reduce(BigDecimal.ZERO, BigDecimal::add));
                    // 结算金额(积分)
                    _merge.setBalance(_entry.getValue().stream()
                            .map(item -> item.getBalance() == null ? BigDecimal.ZERO : item.getBalance())
                            .reduce(BigDecimal.ZERO, BigDecimal::add));

//					累加
//					BigDecimal::add

                    /****************************************** 侨城汇 合并后数据为0不要了 start ******************************************/

                    // 此 不能用 || 或 因为还真有 数据为 1 金额为 0
                    // 改 &&
                    if (_merge.getQuantity().compareTo(0) != 0
                            && _merge.getBalance().compareTo(BigDecimal.ZERO) != 0
                            && !_merge.getBatchs().equals("wechat")
                    ) {
//						transferListBySheetMerge.add(_merge);
                        struct.getTransferListBySheetMerge().add(_merge);
                    }


                } else {

                    if (!_entry.getValue().get(0).getBatchs().equals("wechat")) {
                        struct.getTransferListBySheetMerge().addAll(_entry.getValue());
                    }

                }

//				transferListBySheet.addAll(_entry.getValue());
                struct.getTransferListBySheet().addAll(_entry.getValue());
            }

            resultMap.put(/* InvoiceNo */entry.getKey(), struct);


            /****************************************** 不在这处理了 start ******************************************/
//			try {
////				ExcelExportModePoiHssfUtils.createSheetByWorkbook(transferListBySheet, fieldHeadMode2Static, fieldValueMode2Static, workbook, invoiceApplyMap.get(entry.getKey()).toString() + "");
////				ExcelExportModePoiHssfUtils.createSheetByWorkbook(transferListBySheetMerge, fieldHeadMode2StaticMerge, fieldValueMode2StaticMerge, workbook, invoiceApplyMap.get(entry.getKey()).toString() + "_合并");
//
//				if (mode.compareTo(2) == 0) {
//
//					log.info("\n\n\n创建 sheet : {} \ntransferListBySheet 数据准备 : {}\n\n\n", invoiceApplyMap.get(entry.getKey()), JsonUtils.toJson(transferListBySheet));
////					WriteSheet writeSheet0 = EasyExcel
////							.writerSheet(sheetNo)
////							.sheetName(invoiceApplyMap.get(entry.getKey()))
////							.head(getHead(mapperHead.get(mode)))
////							.build();
//////					excelWriter.fill(new FillWrapper("detail", transferListBySheet), fillConfig, writeSheet0);
////					excelWriter.write(transferListBySheet, writeSheet0);
//					sheetNo = sheetNo + 1;
//					ExcelExportModeEasyExcelUtils.createSheetByWorkbook(transferListBySheet, mapperHead.get(mode), mapperValue.get(mode), excelWriter, sheetNo, invoiceApplyMap.get(entry.getKey()));
//				}
//
//				log.info("\n\n\n创建 sheet : {} \ntransferListBySheetMerge 数据准备 : {}\n\n\n", invoiceApplyMap.get(entry.getKey()) + "_合并", JsonUtils.toJson(transferListBySheetMerge));
////				WriteSheet writeSheet1 = EasyExcel
////						.writerSheet(sheetNo + 1)
////						.sheetName(invoiceApplyMap.get(entry.getKey()) + "_合并")
////						.head(getHead(mapperHead.get(mode)))
////						.build();
//////				excelWriter.fill(new FillWrapper("detail", transferListBySheetMerge), fillConfig, writeSheet1);
////				excelWriter.write(transferListBySheetMerge, writeSheet1);
//				sheetNo = sheetNo + 1;
//				ExcelExportModeEasyExcelUtils.createSheetByWorkbook(transferListBySheetMerge, mapperHeadMerge.get(mode), mapperValueMerge.get(mode), excelWriter, sheetNo, invoiceApplyMap.get(entry.getKey()) + "_合并");
//
//			} catch (Exception e) {
//
//				e.printStackTrace();
//			}
            /****************************************** 不在这处理了 start ******************************************/

//			sheetNo = sheetNo + 2;
        }

        return resultMap;


    }

    /**
     * @param result
     * @return
     */
    @Deprecated
    private List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo> mergeResultByExcelDebug(List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo> result) {

        // 因为是可以多选的 所以先按 发票申请Id 分组
        Map<Long, List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo>> transferMapGrouopByInvoiceApplyId = result.parallelStream()
                .collect(Collectors.groupingBy(ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo::getInvoiceApplyId, Collectors.toList()));
//				.collect(Collectors.groupingBy(e -> fetchGroupKey(e), Collectors.toList()));

        List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo> transferList = new ArrayList<>();

        // 因为是可以多选的 所以先按 发票申请Id 分组 每个 entry 是 一份
        for (Map.Entry<Long, List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo>> entry : transferMapGrouopByInvoiceApplyId.entrySet()) {

            Map<String, List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo>> transferMapGrouopByInvoiceApplyIdGroupBy = entry.getValue().parallelStream()
                    .collect(Collectors.groupingBy(e -> InvoiceApplyCustomerExportExcelFocusScoreDimCreditStatic.fetchGroupKeyById(e), Collectors.toList()));

            for (Map.Entry<String, List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo>> _entry : transferMapGrouopByInvoiceApplyIdGroupBy.entrySet()) {

//                log.info("_groupKey : {} _size : {}", _entry.getKey(), _entry.getValue().size());

                if (_entry.getValue().size() > 1) {
//                    log.info("\n{}", AnJsonUtils.toJson(_entry.getValue()));
                }

                transferList.addAll(_entry.getValue());
            }
        }

        return transferList;

    }

    // TODO
    @Deprecated
    private void mergeResultByExcel(List<ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo> result) {

        result.parallelStream()
//				.collect(Collectors.groupingBy(InvoiceApplyExportExcelForceScore::getUnifiedOrderGoodsId, Collectors.toList()))
                .collect(Collectors.groupingBy(e -> InvoiceApplyCustomerExportExcelFocusScoreDimCreditStatic.fetchGroupKeyById(e), Collectors.toList()))
                .forEach((groupKey, transferList) -> {


                    ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo mergeRow = new ExportExcelInvoiceApplyCustomerForceScoreDimCreditVo();

                    log.info("\ngroupKey : {}\ntransferList : {}", groupKey, AnJsonUtils.toJson(transferList));

//					authorizedStationInfo.setStationId(k);
//					List<AuthorizedPileInfo> authorizedPileInfos = new ArrayList<>();
//					v.parallelStream().collect(Collectors.groupingBy(CrmAuthorizedInfo::getPileId, Collectors.toList())).forEach((k1, v1) -> {
//						AuthorizedPileInfo authorizedPileInfo = new AuthorizedPileInfo();
//						authorizedPileInfo.setPileId(k1);
//						authorizedPileInfo.setGunIds(v1.stream().map(CrmAuthorizedInfo::getGunId).collect(Collectors.toList()));
//						authorizedPileInfos.add(authorizedPileInfo);
//					});
//					authorizedStationInfo.setPileIds(authorizedPileInfos);

//					authorizedStationInfos.add(authorizedStationInfo);
                });

    }

    /****************************************** 客户结算 开票申请 列表导出 Excel数据   end ******************************************/


    // 区分 订单类型 为了不改代码
//	private static final String TEMPLATE_EXCEL_EXPORT_UNIFIED_CUSTOMER_INVOICE_2_GOODS_DETAIL_DIM_GOODS_2_FLSC = "exportUnifiedCustomerInvoice2GoodsDetailDimGoods2FLSC.xlsx";
//	private static final String TEMPLATE_EXCEL_EXPORT_UNIFIED_CUSTOMER_INVOICE_2_GOODS_DETAIL_DIM_GOODS_2_LNSS = "exportUnifiedCustomerInvoice2GoodsDetailDimGoods2LNSS.xlsx";
//	private static final String TEMPLATE_EXCEL_EXPORT_UNIFIED_CUSTOMER_INVOICE_2_GOODS_DETAIL_DIM_GOODS_2_QYNG = "exportUnifiedCustomerInvoice2GoodsDetailDimGoods2QYNG.xlsx";
//	private static final String TEMPLATE_EXCEL_EXPORT_UNIFIED_CUSTOMER_INVOICE_2_GOODS_DETAIL_DIM_ORDER_2_ALLL = "exportUnifiedCustomerInvoice2GoodsDetailDimOrder2ALLL.xlsx";

    // 不区分 订单类型 mark by linjinyu at 20210526

    private static final String TEMPLATE_EXCEL_EXPORT_UNIFIED_CUSTOMER_INVOICE_2_GOODS_DETAIL_DIM_GOODS_2_FLSC = "exportUnifiedCustomerInvoice2GoodsDetailDimGoodsALL20210526.xlsx";
    private static final String TEMPLATE_EXCEL_EXPORT_UNIFIED_CUSTOMER_INVOICE_2_GOODS_DETAIL_DIM_GOODS_2_LNSS = "exportUnifiedCustomerInvoice2GoodsDetailDimGoodsALL20210526.xlsx";
    private static final String TEMPLATE_EXCEL_EXPORT_UNIFIED_CUSTOMER_INVOICE_2_GOODS_DETAIL_DIM_GOODS_2_QYNG = "exportUnifiedCustomerInvoice2GoodsDetailDimGoodsALL20210526.xlsx";
    private static final String TEMPLATE_EXCEL_EXPORT_UNIFIED_CUSTOMER_INVOICE_2_GOODS_DETAIL_DIM_ORDER_2_ALLL = "exportUnifiedCustomerInvoice2GoodsDetailDimGoodsALL20210526.xlsx";

    public SysNotify exportExcelUnifiedCustomerInvoice2GoodsDetail(InvoiceApplyCustomerDetailDimGoodsVo invoiceApplyDetailDimGoodsVo) {


//		log.info("/Users/linjinyu/JAVA_HOME/workspace_superdesk/superdesk-uniorder/superdesk-uniorder-service/src/main/resources/template/excel/invoice/customer");

//		String ROOT_RESOURCES_PATH                  = System.getProperty("user.dir");
//		String ROOT_TEMPLATE_EXCEL_PATH             = "/src/main/resources/template/excel/invoice/customer/";

//		exportUnifiedCustomerInvoice2GoodsDetailDimGoods2FLSC.xlsx
//		exportUnifiedCustomerInvoice2GoodsDetailDimGoods2LNSS.xlsx
//		exportUnifiedCustomerInvoice2GoodsDetailDimGoods2QYNG.xlsx
//		exportUnifiedCustomerInvoice2GoodsDetailDimOrder.xlsx


//		log.info("{}{}{}", ROOT_RESOURCES_PATH, ROOT_TEMPLATE_EXCEL_PATH, TEMPLATE_EXCEL_NAME_INVOICE_CUSTOMER);

        // 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
        // {} 代表普通变量 {.} 代表是list的变量
//		String templateFileName = "/Users/linjinyu/tmp" + File.separator + "template" + File.separator + "excel" + File.separator + "invoice" + File.separator + "customer" + File.separator + "exportUnifiedCustomerInvoice2GoodsDetail.xlsx";
//		String fileName         = "/Users/linjinyu/tmp" + File.separator + "template" + File.separator + "excel" + File.separator + "invoice" + File.separator + "customer" + File.separator + System.currentTimeMillis() + ".xlsx";

//		String templateRootPath     = "/Users/linjinyu/tmp";
        String excelExportPathRoot             = resourceConstant.getPathRoot();
        String excelExportRelativePathTemplate = resourceConstant.getPathTemplate();
        String excelExportRelativePathStorage  = resourceConstant.getPathStorage();

        String relativePath = File.separator + "excel" + File.separator + "invoice" + File.separator + "customer" + File.separator;

        String templateRelativePath = excelExportPathRoot + excelExportRelativePathTemplate + relativePath;
        String templateFullPath;

        String targetFullPath = excelExportPathRoot + excelExportRelativePathStorage;

        String targetFileName          = "客户结算" + "_" + "开票申请(发票)详情_" + "电子发票" + ExcelResponse.addTail() + ".xlsx";
        String targetWriteFileFullPath = targetFullPath + relativePath + targetFileName;

//		if (!FileUtil.exist(targetWriteFileFullPath)) {
//			FileUtil.mkdir(targetWriteFileFullPath);
//		}
        FileUtil.touch(targetWriteFileFullPath);

//
//		// 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行,然后下面的数据往后移动。默认 是false,会直接使用下一行,如果没有则创建。
//		// forceNewRow 如果设置了true,有个缺点 就是他会把所有的数据都放到内存了,所以慎用
//		// 简单的说 如果你的模板有list,且list不是最后一行,下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存
//		// 如果数据量大 list不是最后一行 参照下一个
////		FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
////		excelWriter.fill(data(), fillConfig, writeSheet);
////		excelWriter.fill(data(), fillConfig, writeSheet);
////
////		Map<String, Object> map = new HashMap<String, Object>();
////		map.put("date", "2019年10月9日13:28:28");
////		map.put("total", 1000);
////
////		excelWriter.fill(map, writeSheet);
////		excelWriter.finish();
//
//
//		FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build();
//		// 如果有多个list 模板上必须有{前缀.} 这里的前缀就是 data1,然后多个list必须用 FillWrapper包裹
//		excelWriter.fill(new FillWrapper("data1", data()), fillConfig, writeSheet);
//		excelWriter.fill(new FillWrapper("data1", data()), fillConfig, writeSheet);
//		excelWriter.fill(new FillWrapper("data2", data()), writeSheet);
//		excelWriter.fill(new FillWrapper("data2", data()), writeSheet);
//		excelWriter.fill(new FillWrapper("data3", data()), writeSheet);
//		excelWriter.fill(new FillWrapper("data3", data()), writeSheet);
//
//		Map<String, Object> map = new HashMap<String, Object>();
//		map.put("date", "2019年10月9日13:28:28");
//		excelWriter.fill(map, writeSheet);


        ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(targetWriteFileFullPath);
        ExcelWriter        excelWriter        = null;

        WriteSheet writeSheet0 = EasyExcel.writerSheet(0, "面单").build();
        WriteSheet writeSheet1 = EasyExcel.writerSheet(1, "明细").build();
        FillConfig fillConfig  = FillConfig.builder().forceNewRow(Boolean.FALSE).build();

        // accounting_order_type 对账单类型 1-一般;2-积分;
        // dim_create_by 对账单 创建维度:0-订单;1-商品;2-流水;

        switch (AccountingOrderDimCreateByEnum.get(invoiceApplyDetailDimGoodsVo.getDimCreateBy())) {
            case 订单:

                List<InvoiceApplyDetailDimOrderItemVo> dzOrders = invoiceApplyDetailDimGoodsVo.getDzOrders();

                InvoiceApplyDetailDimOrderItemVo sample0 = dzOrders.get(0);

                templateFullPath = templateRelativePath + TEMPLATE_EXCEL_EXPORT_UNIFIED_CUSTOMER_INVOICE_2_GOODS_DETAIL_DIM_ORDER_2_ALLL;

                excelWriter = excelWriterBuilder.withTemplate(templateFullPath).build();
                excelWriter.fill(new FillWrapper("detail", dzOrders), fillConfig, writeSheet1);
                break;
            case 商品:


                List<InvoiceApplyDetailDimGoodsItemV3Vo> innerOrderJoinGoodsList = invoiceApplyDetailDimGoodsVo.getInnerOrderJoinGoodsList();

                InvoiceApplyDetailDimGoodsItemV3Vo sample1 = innerOrderJoinGoodsList.get(0);

                switch (CommonServiceNoEnum.getByServiceNo(sample1.getServiceNo())) {
                    case UNKNOW:
                        // TODO 异常情况
                        templateFullPath = templateRelativePath + TEMPLATE_EXCEL_EXPORT_UNIFIED_CUSTOMER_INVOICE_2_GOODS_DETAIL_DIM_ORDER_2_ALLL;
                        excelWriter = excelWriterBuilder.withTemplate(templateFullPath).build();

                        break;
                    case 服务之窗:
                        // TODO 异常情况
                        templateFullPath = templateRelativePath + TEMPLATE_EXCEL_EXPORT_UNIFIED_CUSTOMER_INVOICE_2_GOODS_DETAIL_DIM_ORDER_2_ALLL;
                        excelWriter = excelWriterBuilder.withTemplate(templateFullPath).build();
                        break;
                    case 企业采购:
                        templateFullPath = templateRelativePath + TEMPLATE_EXCEL_EXPORT_UNIFIED_CUSTOMER_INVOICE_2_GOODS_DETAIL_DIM_GOODS_2_QYNG;
                        excelWriter = excelWriterBuilder.withTemplate(templateFullPath).build();
                        break;
                    case 代客下单:
                        templateFullPath = templateRelativePath + TEMPLATE_EXCEL_EXPORT_UNIFIED_CUSTOMER_INVOICE_2_GOODS_DETAIL_DIM_GOODS_2_QYNG;
                        excelWriter = excelWriterBuilder.withTemplate(templateFullPath).build();
                        break;
                    case 企业福利:
                        templateFullPath = templateRelativePath + TEMPLATE_EXCEL_EXPORT_UNIFIED_CUSTOMER_INVOICE_2_GOODS_DETAIL_DIM_GOODS_2_FLSC;
                        excelWriter = excelWriterBuilder.withTemplate(templateFullPath).build();
                        break;
                    case 企业福利_侨城汇:
                        templateFullPath = templateRelativePath + TEMPLATE_EXCEL_EXPORT_UNIFIED_CUSTOMER_INVOICE_2_GOODS_DETAIL_DIM_GOODS_2_FLSC;
                        excelWriter = excelWriterBuilder.withTemplate(templateFullPath).build();
                        break;
                    case 楼闪送:
                        templateFullPath = templateRelativePath + TEMPLATE_EXCEL_EXPORT_UNIFIED_CUSTOMER_INVOICE_2_GOODS_DETAIL_DIM_GOODS_2_LNSS;
                        excelWriter = excelWriterBuilder.withTemplate(templateFullPath).build();
                        break;
                    default:
                        // TODO 异常情况
                        templateFullPath = templateRelativePath + TEMPLATE_EXCEL_EXPORT_UNIFIED_CUSTOMER_INVOICE_2_GOODS_DETAIL_DIM_ORDER_2_ALLL;
                        excelWriter = excelWriterBuilder.withTemplate(templateFullPath).build();
                        break;
                }


                // TODO 要再分 serviceNo 先简单写吧 mark by linjinyu at 20210302
                excelWriter.fill(new FillWrapper("detail", innerOrderJoinGoodsList), fillConfig, writeSheet1);
                break;
            case 流水:
                break;
            default:
                break;
        }


        excelWriter.fill(invoiceApplyDetailDimGoodsVo, writeSheet0);


        // 别忘记关闭流
        excelWriter.finish();

        return NotifyUtils.createSysNotify(targetFileName, relativePath + targetFileName, SysQuartzScheduleTaskStatementOfAccountRunStateEnum.成功);
    }


    @Autowired
    private TransformExportExcelDimUnifiedInvoiceRegister4E6Tools transformExportExcelDimUnifiedInvoiceRegister4E6Tools;

    private static final String TEMPLATE_EXCEL_EXPORT_INVOICE_REGISTER_DIM_ORDER_4_E6 = "exportExcelInvoiceRegisterDimOrder4E6.xlsx";
    private static final String TEMPLATE_EXCEL_EXPORT_INVOICE_REGISTER_DIM_GOODS_4_E6 = "exportExcelInvoiceRegisterDimGoods4E6.xlsx";

    private static final String TEMPLATE_EXCEL_EXPORT_INVOICE_REGISTER_4_E6 = "exportExcelInvoiceRegister4E6.xlsx";

    /**
     * 待重构
     *
     * @param invoiceApplyDetailDimGoodsVo
     * @return
     */
    public SysNotify exportExcelDimUnifiedInvoiceRegister4E6(InvoiceApplyCustomerDetailDimGoodsVo invoiceApplyDetailDimGoodsVo) {

        String excelExportPathRoot             = resourceConstant.getPathRoot();
        String excelExportRelativePathTemplate = resourceConstant.getPathTemplate();
        String excelExportRelativePathStorage  = resourceConstant.getPathStorage();

        String relativePath = File.separator + "excel" + File.separator + "invoice" + File.separator + "customer" + File.separator;

        String templateRelativePath = excelExportPathRoot + excelExportRelativePathTemplate + relativePath;
        String templateFullPath;

        String targetFullPath = excelExportPathRoot + excelExportRelativePathStorage;

        String targetFileName          = "客户结算" + "_" + "开票申请(发票)税务管理软件E6_" + "ExcelAndTxt组件接口版_开票申请编号_" + invoiceApplyDetailDimGoodsVo.getInvoiceApplySn() + ExcelResponse.addTail() + ".xlsx";
        String targetWriteFileFullPath = targetFullPath + relativePath + targetFileName;

//		if (!FileUtil.exist(targetWriteFileFullPath)) {
//			FileUtil.mkdir(targetWriteFileFullPath);
//		}
        FileUtil.touch(targetWriteFileFullPath);


        ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(targetWriteFileFullPath);
        ExcelWriter        excelWriter        = null;

        WriteSheet writeSheet1 = EasyExcel.writerSheet(0).build();
        FillConfig fillConfig  = FillConfig.builder().forceNewRow(Boolean.FALSE).build();

        // accounting_order_type 对账单类型 1-一般;2-积分;
        // dim_create_by 对账单 创建维度:0-订单;1-商品;2-流水;


        List<ExportExcelDimUnifiedInvoiceRegister4E6Vo> resultData = transformExportExcelDimUnifiedInvoiceRegister4E6Tools.transform(invoiceApplyDetailDimGoodsVo, AccountingOrderDimCreateByEnum.get(invoiceApplyDetailDimGoodsVo.getDimCreateBy()));
        templateFullPath = templateRelativePath + TEMPLATE_EXCEL_EXPORT_INVOICE_REGISTER_4_E6;
        excelWriter = excelWriterBuilder.withTemplate(templateFullPath).build();
        excelWriter.fill(new FillWrapper("detail", resultData), fillConfig, writeSheet1);


        // 别忘记关闭流
        excelWriter.finish();

        return NotifyUtils.createSysNotify("税务管理软件E6-ExcelAndTxt组件接口版-" + targetFileName, relativePath + targetFileName, SysQuartzScheduleTaskStatementOfAccountRunStateEnum.成功);

    }


    private static final String TEMPLATE_EXCEL_EXPORT_SCORE_CUSTOMER_INVOICE_2_CREDIT_DETAIL_DIM_CREDIT_2_FLSC_QCH = "exportScoreCustomerInvoice2CreditDetailDimCredit2FLSC_QCH.xlsx";

    /**
     * mark by linjinyu at 20211112
     *
     * @param invoiceApplyDetailDimCreditVo
     * @return
     */
    public SysNotify exportExcelUnifiedCustomerInvoice2CreditDetail(InvoiceApplyCustomerDetailDimCreditVo invoiceApplyDetailDimCreditVo) {

        String excelExportPathRoot             = resourceConstant.getPathRoot();
        String excelExportRelativePathTemplate = resourceConstant.getPathTemplate();
        String excelExportRelativePathStorage  = resourceConstant.getPathStorage();

        String relativePath = File.separator + "excel" + File.separator + "invoice" + File.separator + "customer" + File.separator;

        String templateRelativePath = excelExportPathRoot + excelExportRelativePathTemplate + relativePath;
        String templateFullPath;

        String targetFullPath = excelExportPathRoot + excelExportRelativePathStorage;

        String targetFileName          = "积分结算" + "_" + "开票申请(发票)详情_" + "电子发票_" + invoiceApplyDetailDimCreditVo.getInvoiceApplySn() + ExcelResponse.addTail() + ".xlsx";
        String targetWriteFileFullPath = targetFullPath + relativePath + targetFileName;

        FileUtil.touch(targetWriteFileFullPath);

        ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(targetWriteFileFullPath);
        ExcelWriter        excelWriter        = null;

        WriteSheet writeSheet0 = EasyExcel.writerSheet(0, "面单").build();
        WriteSheet writeSheet1 = EasyExcel.writerSheet(1, "明细").build();
        FillConfig fillConfig  = FillConfig.builder().forceNewRow(Boolean.FALSE).build();

        // accounting_order_type 对账单类型 1-一般;2-积分;
        // dim_create_by 对账单 创建维度:0-订单;1-商品;2-流水;

        switch (AccountingOrderDimCreateByEnum.get(invoiceApplyDetailDimCreditVo.getDimCreateBy())) {
            case 订单:
                // ...
                break;
            case 商品:
                // ...
                break;
            case 流水:

                List<InvoiceApplyDetailDimCreditItemVo> dzOrders = invoiceApplyDetailDimCreditVo.getDzOrders();

                templateFullPath = templateRelativePath + TEMPLATE_EXCEL_EXPORT_SCORE_CUSTOMER_INVOICE_2_CREDIT_DETAIL_DIM_CREDIT_2_FLSC_QCH;
                excelWriter = excelWriterBuilder.withTemplate(templateFullPath).build();

                excelWriter.fill(new FillWrapper("detail", dzOrders), fillConfig, writeSheet1);

                break;
            default:
                break;
        }

        excelWriter.fill(invoiceApplyDetailDimCreditVo, writeSheet0);

        // 别忘记关闭流
        excelWriter.finish();

        return NotifyUtils.createSysNotify(targetFileName, relativePath + targetFileName, SysQuartzScheduleTaskStatementOfAccountRunStateEnum.成功);

    }

    private static final String TEMPLATE_EXCEL_EXPORT_SZHTXX_ELECTRONIC_INVOICE_FPTXX_PRE = "exportExcelSzhtxxElectronicInvoicePre.xlsx";

    public SysNotify exportOngoingInvoiceTypeEq1InvoiceModeEqSzhtxxElectronicInvoice(SingleBillingRequestBodyKpContent singleBillingRequestBodyKpContent) {

        /****************************************** 初始 start ******************************************/

        String excelExportPathRoot             = resourceConstant.getPathRoot();
        String excelExportRelativePathTemplate = resourceConstant.getPathTemplate();
        String excelExportRelativePathStorage  = resourceConstant.getPathStorage();

//        String relativePath = File.separator + "excel" + File.separator + "golden_tax_plate" + File.separator + "score" + File.separator + "customer" + File.separator + "pre" + File.separator;

        /**
         * 1. api前
         * 2. api
         * 3. excel ---- 当前
         */
        String now     = DateUtil.now();
        String fpqqlsh = singleBillingRequestBodyKpContent.getFptxx().getFpqqlsh();

        String relativePath = File.separator + "thirdpart" +
                File.separator + "szhtxx" +
                File.separator + "electronicInvoice" +
                File.separator + "1.1.1_SingleBilling" +
                File.separator;

        String templateRelativePath = excelExportPathRoot + excelExportRelativePathTemplate + relativePath;
        String templateFullPath     = templateRelativePath + TEMPLATE_EXCEL_EXPORT_SZHTXX_ELECTRONIC_INVOICE_FPTXX_PRE;

        String targetFullPath = excelExportPathRoot + excelExportRelativePathStorage;
        String targetFileName = StrUtil.format("积分结算_" + "深圳航信电子票_" + "op导出发票数据Pre_{}" + ExcelResponse.addTail() + ".xlsx",
                singleBillingRequestBodyKpContent.getFptxx().getFpqqlsh()
        );
        String targetWriteFileFullPath = targetFullPath + relativePath + fpqqlsh + File.separator + targetFileName;
        FileUtil.touch(targetWriteFileFullPath);

        /****************************************** 初始   end ******************************************/


        ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(targetWriteFileFullPath);
        ExcelWriter        excelWriter        = null;

        WriteSheet writeSheet0 = EasyExcel.writerSheet(0, "发票信息").build();
        WriteSheet writeSheet1 = EasyExcel.writerSheet(1, "发票数据").build();
        FillConfig fillConfig  = FillConfig.builder().forceNewRow(Boolean.FALSE).build();

//		templateFullPath = templateRelativePath + TEMPLATE_EXCEL_EXPORT_STATEMENTOFACCOUNT_DETAIL_DIM_CREDIT;

        excelWriter = excelWriterBuilder
                .withTemplate(templateFullPath)
                //
//                .registerWriteHandler(SugarUpBigDecimalCellWriteHandler
//                        .builder()
//                        .startRow(1)
//                        .matchCell(Arrays.asList(6, 7, 8, 9))
//                        .build()
//                )
                .build();

        excelWriter.fill(new FillWrapper("xmxx", singleBillingRequestBodyKpContent.getXmxx()), fillConfig, writeSheet1);

        Map<String, Object> exportMapFptxx = AnBeanUtils.beanToMap(singleBillingRequestBodyKpContent.getFptxx(), "fptxx");

        excelWriter
//				.fill(exportMapAccounting, writeSheet0)
                .fill(exportMapFptxx, writeSheet0);


        // 别忘记关闭流
        excelWriter.finish();

        return NotifyUtils.createSysNotify(targetFileName, relativePath + targetFileName, SysQuartzScheduleTaskStatementOfAccountRunStateEnum.成功);
    }

}
