package cn.superdesk.uniorder.service.order.base.impl;

import cn.hutool.core.collection.CollUtil;
import cn.superdesk.uniorder.common.enums.accounting.customer.AccountingOrderCustomerAccountingStatusEnum;
import cn.superdesk.uniorder.common.enums.common.CommonAccountingStateEnum;
import cn.superdesk.uniorder.common.enums.order.UnifiedOrderCreditBackAccountStatusEnum;
import cn.superdesk.uniorder.common.enums.order.UnifiedOrderCreditInvoiceApplyStatusEnum;
import cn.superdesk.uniorder.common.enums.order.UnifiedOrderCreditInvoiceMakeStatusEnum;
import cn.superdesk.uniorder.common.exception.utils.AssertUtils;
import cn.superdesk.uniorder.common.json.AnJsonUtils;
import cn.superdesk.uniorder.common.lamda.AnLamdaUtils;
import cn.superdesk.uniorder.common.numerical.AnBeanUtils;
import cn.superdesk.uniorder.common.numerical.AnStringUtils;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.dao.entity.accounting.score.customer.AccountingScoreCustomer;
import cn.superdesk.uniorder.dao.entity.accounting.score.customer.AccountingScoreCustomerXCredit;
import cn.superdesk.uniorder.dao.entity.accounting.score.customer.AccountingScoreCustomerXCreditExample;
import cn.superdesk.uniorder.dao.entity.base.UnifiedOrderCredit;
import cn.superdesk.uniorder.dao.entity.base.UnifiedOrderCreditExample;
import cn.superdesk.uniorder.dao.entity.invoice.customer.InvoiceApplyXGoods;
import cn.superdesk.uniorder.dao.mapper.accounting.score.customer.AccountingScoreCustomerMapper;
import cn.superdesk.uniorder.dao.mapper.accounting.score.customer.AccountingScoreCustomerMapperEx;
import cn.superdesk.uniorder.dao.mapper.accounting.score.customer.AccountingScoreCustomerXCreditMapper;
import cn.superdesk.uniorder.dao.mapper.base.UnifiedOrderCreditMapper;
import cn.superdesk.uniorder.service.accounting.score.customer.AccountingScoreCustomerService;
import cn.superdesk.uniorder.service.order.base.UnifiedOrderCreditService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @Description:
 * @Author: linjinyu
 * @Email linjinyu@avic-s.com
 * @CreateDate: 2020-09-23 15:16:04
 * @UpdateUser: linjinyu
 * @UpdateDate: 2020-09-23 15:16:04
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class UnifiedOrderCreditServiceImpl implements UnifiedOrderCreditService {

    @Autowired
    private UnifiedOrderCreditMapper unifiedOrderCreditMapper;

    @Autowired
    private AccountingScoreCustomerMapper        accountingScoreCustomerMapper;
    @Autowired
    private AccountingScoreCustomerMapperEx      accountingScoreCustomerMapperEx;
    @Autowired
    private AccountingScoreCustomerXCreditMapper accountingScoreCustomerXCreditMapper;

    @Autowired
    private AccountingScoreCustomerService accountingScoreCustomerService;


    /****************************************** extends BaseService 部分 start ******************************************/


    @Override
    public int insertSelective(UnifiedOrderCredit entity) {
        return unifiedOrderCreditMapper.insertSelective(entity);
    }

    @Override
    public int updateByPrimaryKeySelective(UnifiedOrderCredit entity) {
        return unifiedOrderCreditMapper.updateByPrimaryKeySelective(entity);
    }

    @Override
    public void deleteObj(Long id) {
    }

    @Override
    public UnifiedOrderCredit findById(Long id) {
        return unifiedOrderCreditMapper.selectByPrimaryKey(id);
    }

    @Override
    public PageInfo<UnifiedOrderCredit> findByPaging(Map<String, Object> conditions, Integer pageNun, Integer pageSize) {
        return null;
    }

    @Override
    public List<UnifiedOrderCredit> findAll(Map<String, Object> queryMap) {
        return null;
    }

    /****************************************** extends BaseService 部分   end ******************************************/


    @Override
    public void addUnifiedOrderCredit(UnifiedOrderCredit entity) {
        unifiedOrderCreditMapper.insertSelective(entity);
    }

    @Override
    public void updateUnifiedOrderCredit(UnifiedOrderCredit entity) {
        UnifiedOrderCredit originEntity = unifiedOrderCreditMapper.selectByPrimaryKey(entity.getId());
        AssertUtils.notNull(originEntity);
        AnBeanUtils.copy(entity, originEntity);
        unifiedOrderCreditMapper.updateByPrimaryKey(originEntity);
    }

    @Override
    public void deleteUnifiedOrderCredit(Long id) {
        unifiedOrderCreditMapper.deleteByPrimaryKey(id);
    }

    @Override
    public UnifiedOrderCredit findUnifiedOrderCreditById(Long id) {
        UnifiedOrderCredit entity = unifiedOrderCreditMapper.selectByPrimaryKey(id);
        AssertUtils.notNull(entity);
        return entity;
    }

    @Override
    public R<List<UnifiedOrderCredit>> pageQuery(Map<String, Object> conditions, int pageNun, int pageSize) {

        // 样例 保留
//		UnifiedOrderCredit unifiedOrderCreditConditions = BeanUtils.mapToBean(conditions,UnifiedOrderCredit.class);

        UnifiedOrderCreditExample          example  = new UnifiedOrderCreditExample();
        UnifiedOrderCreditExample.Criteria criteria = example.createCriteria();

        PageHelper.startPage(pageNun, pageSize);
        List<UnifiedOrderCredit>     resultList = unifiedOrderCreditMapper.selectByExample(example);
        PageInfo<UnifiedOrderCredit> page       = new PageInfo<UnifiedOrderCredit>(resultList);
        PageHelper.clearPage();

        return new R<List<UnifiedOrderCredit>>(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), resultList);

    }

    /**
     * 给 商城 侨城汇 用的
     * 商城 总端 积分发放查询
     *
     * @param conditions
     * @return
     */
    @Override
    public Map<String, Integer> checkStatement(Map<String, Object> conditions) {

        Map<String, Integer> result = new HashMap<>();

        if (null == conditions.get("batchs")) {
            return result;
        }

        UnifiedOrderCreditExample example = new UnifiedOrderCreditExample();
//		UnifiedOrderCreditExample.Criteria criteria =


        List<String> batchsList = AnStringUtils.stringArrayConvertToStringList((String) conditions.get("batchs"), ",");

        log.info("checkStatement \n\n\n\n{}", AnJsonUtils.toJson(batchsList));

        for (String batchs : batchsList) {

            log.info("{}", batchs);

            example.clear();
            List<UnifiedOrderCredit> resultList = new ArrayList<>();

            example.createCriteria()
//					.andAccountingStateSupplierEqualTo(UnifiedOrderAccountingStateEnum.已对账.getKey())
                    .andAccountingStateCustomerEqualTo(CommonAccountingStateEnum.已对账.getKey())
                    .andBatchsEqualTo(batchs);
            resultList = unifiedOrderCreditMapper.selectByExample(example);

            if (CollUtil.isNotEmpty(resultList)) {
                result.put(batchs, resultList.size());
            } else {
                result.put(batchs, 0);
            }

            resultList.clear();

        }

        return result;

    }


    /****************************************** 关于 供应商结算 对账单 设置 对账状态 或 恢复 对账状态 start ******************************************/
    /**
     * 触发 基于 创建 订单维度创建 供应商对账单
     * 积分流水 基于 订单Sn 来更新 供应商对账 状态
     *
     * @param processOrderSn
     * @param state
     * @return
     */
    @Override
    public int updateFieldAccountingStateSupplierByOrderSn(List<String> processOrderSn, CommonAccountingStateEnum state) {

        if (CollUtil.isEmpty(processOrderSn)) {
            log.error("updateAccountingStateSupplierByOrderSn processOrderSn isEmpty = true && CommonAccountingStateEnum = {}", state.getDesc());
            return 0;
        }

        UnifiedOrderCreditExample forUpdateExample = new UnifiedOrderCreditExample();
        forUpdateExample.createCriteria()
                .andOrderSnIn(processOrderSn)
                .andAccountingStateSupplierNotEqualTo(state.getKey());

        UnifiedOrderCredit forUpdateEntity = new UnifiedOrderCredit();
        forUpdateEntity.setAccountingStateSupplier(state.getKey());

        return unifiedOrderCreditMapper.updateByExampleSelective(forUpdateEntity, forUpdateExample);
    }

    /**
     * 触发 基于 创建 商品维度创建 供应商对账单
     * 积分流水 基于 订单Sn OutGoodsIds 来更新 供应商对账 状态
     *
     * @param processOrderSn
     * @param processOutGoodsIds
     * @param state
     * @return
     */
    @Override
    public int updateFieldAccountingStateSupplierByOrderSnAndOutGoodsIds(List<String> processOrderSn, List<Long> processOutGoodsIds, CommonAccountingStateEnum state) {

        if (CollUtil.isEmpty(processOrderSn)) {
            log.error("updateAccountingStateSupplierByOrderSnAndOutGoodsIds processOrderSn isEmpty = true && CommonAccountingStateEnum = {}", state.getDesc());
            return 0;
        }

        if (CollUtil.isEmpty(processOutGoodsIds)) {
            log.error("updateAccountingStateSupplierByOrderSnAndOutGoodsIds processOutGoodsIds isEmpty = true && CommonAccountingStateEnum = {}", state.getDesc());
            return 0;
        }

        UnifiedOrderCreditExample forUpdateExample = new UnifiedOrderCreditExample();
        forUpdateExample.createCriteria()
                .andOrderSnIn(processOrderSn)
                .andGoodsIdIn(processOutGoodsIds)
                .andAccountingStateSupplierNotEqualTo(state.getKey());

        UnifiedOrderCredit forUpdateEntity = new UnifiedOrderCredit();
        forUpdateEntity.setAccountingStateSupplier(state.getKey());

        return unifiedOrderCreditMapper.updateByExampleSelective(forUpdateEntity, forUpdateExample);
    }
    /****************************************** 关于 供应商结算 对账单 设置 对账状态 或 恢复 对账状态   end ******************************************/


    /****************************************** 关于 客户结算 对账单 设置 对账状态 或 恢复 对账状态 start ******************************************/

    /**
     * 垂直思维-看业务复合用-通过 订单编号 来更新 流水 客户对账状态
     * <p>
     * 触发 基于 创建 订单维度创建 客户|企业|积分对账单
     *
     * @param processOrderSn
     * @param state
     * @return
     */
    @Override
    public int updateFieldAccountingStateCustomerByOrderSn(List<String> processOrderSn, CommonAccountingStateEnum state) {

        if (CollUtil.isEmpty(processOrderSn)) {
            log.error("updateAccountingStateCustomerByOrderSn processOrderSn isEmpty = true && CommonAccountingStateEnum = {}", state.getDesc());
            return 0;
        }

        UnifiedOrderCreditExample forUpdateExample = new UnifiedOrderCreditExample();
        forUpdateExample.createCriteria()
                .andOrderSnIn(processOrderSn)
                .andAccountingStateCustomerNotEqualTo(state.getKey());

        UnifiedOrderCredit forUpdateEntity = new UnifiedOrderCredit();
        forUpdateEntity.setAccountingStateCustomer(state.getKey());

        return unifiedOrderCreditMapper.updateByExampleSelective(forUpdateEntity, forUpdateExample);
    }

    /**
     * 垂直思维-通过 订单编号 商品GoodsId 来更新 流水 客户对账状态
     * <p>
     * 触发 基于 创建 商品维度创建 客户|企业|积分对账单
     *
     * @param processOrderSn
     * @param processOutGoodsIds
     * @param state
     * @return
     */
    public int updateFieldAccountingStateCustomerByOrderSnAndOutGoodsIds(List<String> processOrderSn, List<Long> processOutGoodsIds, CommonAccountingStateEnum state) {

        if (CollUtil.isEmpty(processOrderSn)) {
            log.error("updateAccountingStateCustomerByOrderSnAndOutGoodsIds processOrderSn isEmpty = true && CommonAccountingStateEnum = {}", state.getDesc());
            return 0;
        }

        if (CollUtil.isEmpty(processOutGoodsIds)) {
            log.error("updateAccountingStateCustomerByOrderSnAndOutGoodsIds processOutGoodsIds isEmpty = true && CommonAccountingStateEnum = {}", state.getDesc());
            return 0;
        }

        UnifiedOrderCreditExample forUpdateExample = new UnifiedOrderCreditExample();
        forUpdateExample.createCriteria()
                .andOrderSnIn(processOrderSn)
                .andGoodsIdIn(processOutGoodsIds)
                .andAccountingStateCustomerNotEqualTo(state.getKey());

        UnifiedOrderCredit forUpdateEntity = new UnifiedOrderCredit();
        forUpdateEntity.setAccountingStateCustomer(state.getKey());

        return unifiedOrderCreditMapper.updateByExampleSelective(forUpdateEntity, forUpdateExample);
    }

    /**
     * 更新 流水's 客户对账状态
     * 垂直思维-通过 流水Id UnifiedOrderCreditId (统一订单的Id-入库后) 来更新 流水 客户对账状态
     * 业务引用记录
     * 1. 侨城汇 积分结算 未对账流水 创建对账单
     *
     * @param processUnifiedOrderCreditIds
     * @param state
     * @return
     */
    public int updateFieldAccountingStateCustomerByUnifiedOrderCreditIds(List<Long> processUnifiedOrderCreditIds, CommonAccountingStateEnum state) {

        if (CollUtil.isEmpty(processUnifiedOrderCreditIds)) {
            log.error("updateFieldAccountingStateCustomerByUnifiedOrderCreditIds processUnifiedOrderCreditIds isEmpty = true && CommonAccountingStateEnum = {}", state.getDesc());
            return 0;
        }

        UnifiedOrderCreditExample forUpdateExample = new UnifiedOrderCreditExample();
        forUpdateExample.createCriteria()
                .andIdIn(processUnifiedOrderCreditIds)
                .andAccountingStateCustomerNotEqualTo(state.getKey());

        UnifiedOrderCredit forUpdateEntity = new UnifiedOrderCredit();
        forUpdateEntity.setAccountingStateCustomer(state.getKey());

        return unifiedOrderCreditMapper.updateByExampleSelective(forUpdateEntity, forUpdateExample);

    }

    /**
     * 更新 流水's 发票申请状态
     *
     * @param processUnifiedOrderCreditIds
     * @param state
     * @return
     */
    @Override
    public int updateFieldInvoiceApplyStatusByUnifiedOrderCreditIds(List<Long> processUnifiedOrderCreditIds, UnifiedOrderCreditInvoiceApplyStatusEnum state) {

        if (CollUtil.isEmpty(processUnifiedOrderCreditIds)) {
            log.error("updateFieldInvoiceApplyStatusByUnifiedOrderCreditIds processUnifiedOrderCreditIds isEmpty = true && UnifiedOrderCreditInvoiceApplyStatusEnum = {}", state.getDesc());
            return 0;
        }

        UnifiedOrderCreditExample forUpdateExample = new UnifiedOrderCreditExample();
        forUpdateExample.createCriteria()
                .andIdIn(processUnifiedOrderCreditIds)
                .andInvoiceApplyStatusNotEqualTo(state.getKey());

        UnifiedOrderCredit forUpdateEntity = new UnifiedOrderCredit();
        forUpdateEntity.setInvoiceApplyStatus(state.getKey());

        return unifiedOrderCreditMapper.updateByExampleSelective(forUpdateEntity, forUpdateExample);

    }

    /**
     * 开票状态 是否已登记开票 0-未登记;1-已登记;uoc.invoice_make_status,
     *
     * @param processUnifiedOrderCreditIds
     * @param state
     * @return
     */
    @Override
    public int updateFieldInvoiceMakeStatusByUnifiedOrderCreditIds(List<Long> processUnifiedOrderCreditIds, UnifiedOrderCreditInvoiceMakeStatusEnum state) {

        if (CollUtil.isEmpty(processUnifiedOrderCreditIds)) {
            log.error("updateFieldInvoiceMakeStatusByUnifiedOrderCreditIds processUnifiedOrderCreditIds isEmpty = true && UnifiedOrderCreditInvoiceMakeStatusEnum = {}", state.getDesc());
            return 0;
        }

        UnifiedOrderCreditExample forUpdateExample = new UnifiedOrderCreditExample();
        forUpdateExample.createCriteria()
                .andIdIn(processUnifiedOrderCreditIds)
                .andInvoiceMakeStatusNotEqualTo(state.getKey());

        UnifiedOrderCredit forUpdateEntity = new UnifiedOrderCredit();
        forUpdateEntity.setInvoiceMakeStatus(state.getKey());

        return unifiedOrderCreditMapper.updateByExampleSelective(forUpdateEntity, forUpdateExample);

    }


    /**
     * 回款状态 是否回款 0-未回款;1-已回款;uoc.back_status
     *
     * @param processUnifiedOrderCreditIds
     * @param state
     * @return
     */
    @Override
    public int updateFieldBackAccountStatusByUnifiedOrderCreditIds(List<Long> processUnifiedOrderCreditIds, UnifiedOrderCreditBackAccountStatusEnum state) {

        if (CollUtil.isEmpty(processUnifiedOrderCreditIds)) {
            log.error("updateFieldBackAccountStatusByUnifiedOrderCreditIds processUnifiedOrderCreditIds isEmpty = true && UnifiedOrderCreditBackAccountStatusEnum = {}", state.getDesc());
            return 0;
        }

        UnifiedOrderCreditExample forUpdateExample = new UnifiedOrderCreditExample();
        forUpdateExample.createCriteria()
                .andIdIn(processUnifiedOrderCreditIds)
                .andBackStatusNotEqualTo(state.getKey());


        UnifiedOrderCredit forUpdateEntity = new UnifiedOrderCredit();
        forUpdateEntity.setBackStatus(state.getKey());

        return unifiedOrderCreditMapper.updateByExampleSelective(forUpdateEntity, forUpdateExample);

    }

    /****************************************** 关于 客户结算 对账单 设置 对账状态 或 恢复 对账状态   end ******************************************/

    /****************************************** 流水 状态 回款状态 start ******************************************/

    /**
     * @param invoiceX
     * @param state
     * @return
     */
    public int updateFieldBackAccountStatusByInvoiceX(List<InvoiceApplyXGoods> invoiceX, UnifiedOrderCreditBackAccountStatusEnum state) {

        if (CollUtil.isEmpty(invoiceX)) {
            return 0;
        }

        List<Long> processUnifiedOrderCreditIds = invoiceX.stream().map(e -> e.getUnifiedOrderCreditId()).collect(Collectors.toList());

        return updateFieldBackAccountStatusByUnifiedOrderCreditIds(processUnifiedOrderCreditIds, state);
    }

    /****************************************** 流水 状态 回款状态   end ******************************************/


    /****************************************** 补丁程序 start ******************************************/

    @Override
    public String checkAndFixAccountingStateCustomer(/*积分批次号*/String batchs) {

        StringBuffer report = new StringBuffer();

        report.append("批次Sn  : ").append(batchs).append("\n");


        // TODO
        //  step 1 先以这个 批次号 客户对账状态已对账 查出流水
        //  step 2 再用这个流水集合去查 关联关系 得出 对账单
        //  |---- 如果没有对账单
        //  |---- 如果 流水 再想想

        UnifiedOrderCreditExample selectByBatchsCreditExample = new UnifiedOrderCreditExample();
        selectByBatchsCreditExample.createCriteria()
                .andBatchsEqualTo(batchs);

        List<UnifiedOrderCredit> unifiedOrderCreditListByBatchs = unifiedOrderCreditMapper.selectByExample(selectByBatchsCreditExample);

        if (CollUtil.isEmpty(unifiedOrderCreditListByBatchs)) {
            // 已验证
            return "此批次号没找到相关积分流水";
        } else {

            // 已对账
            List<Predicate<UnifiedOrderCredit>> filterAccountingStateEq1 = new ArrayList<>();
            filterAccountingStateEq1.add(r -> r.getAccountingStateCustomer().equals(1));

            // 未对账
            List<Predicate<UnifiedOrderCredit>> filterAccountingStateEq2 = new ArrayList<>();
            filterAccountingStateEq2.add(r -> r.getAccountingStateCustomer().equals(2));

            // 过滤出客户对账状态位 为 已对账 1
            List<UnifiedOrderCredit> unifiedOrderCreditListByBatchsFilterAccountingStateEq1 = AnLamdaUtils.filters(unifiedOrderCreditListByBatchs, filterAccountingStateEq1);

            // 过滤出客户对账状态位 为 未对账 2
            List<UnifiedOrderCredit> unifiedOrderCreditListByBatchsFilterAccountingStateEq2 = AnLamdaUtils.filters(unifiedOrderCreditListByBatchs, filterAccountingStateEq2);


            if (CollUtil.isEmpty(unifiedOrderCreditListByBatchsFilterAccountingStateEq1)) {
                // 已验证
                return "此批次号 没有 已对账 记录,不需修正";
            } else {

                // 客户结算 对账状态 已对账 积分流水Ids 上一步已经排除 所以 此处必定大于等于1
                List<Long> creditIdsAccountingStateEq1 = unifiedOrderCreditListByBatchsFilterAccountingStateEq1.stream().map(o -> o.getId()).collect(Collectors.toList());

                AccountingScoreCustomerXCreditExample xCreditExample = new AccountingScoreCustomerXCreditExample();
                xCreditExample.createCriteria()
                        .andUnifiedOrderCreditIdIn(creditIdsAccountingStateEq1);
                List<AccountingScoreCustomerXCredit> xCreditAccountingStateEq1List = accountingScoreCustomerXCreditMapper.selectByExample(xCreditExample);


                // 如果为空 证明 关联关系不存在 需要修正
                if (CollUtil.isEmpty(xCreditAccountingStateEq1List)) {

                    UnifiedOrderCreditExample updateAccountingStateEq2Example = new UnifiedOrderCreditExample();
                    updateAccountingStateEq2Example.createCriteria()
                            .andIdIn(creditIdsAccountingStateEq1);

                    UnifiedOrderCredit updateAccountingStateEq2Entity = new UnifiedOrderCredit();
                    updateAccountingStateEq2Entity.setAccountingStateCustomer(CommonAccountingStateEnum.未对账.getKey());

                    unifiedOrderCreditMapper.updateByExampleSelective(updateAccountingStateEq2Entity, updateAccountingStateEq2Example);

                    // 已验证
                    report
                            .append("批次Sn  : ").append(batchs).append("\n")
                            .append("流水Ids : ").append(AnJsonUtils.toJson(creditIdsAccountingStateEq1))
                            .append("结果    : 状态修正成功");

                    return report.toString();

                }


                Integer countCreditIds = creditIdsAccountingStateEq1.size();
                Integer countCreditX   = xCreditAccountingStateEq1List.size();

                log.info("查询 \n" +
                                "根据批次得到的积分流水|对账状态|已对账|{}\n" +
                                "根据上边的结果去查关系|{}",
                        countCreditIds, countCreditX);


                // 只能查出 某批次 积分流水 条数 与 关联关系 条数 是否相等
                // 就是说 如果一个对账单包含多个批次,是检查不出来的 对账单号 DZ2020112600003 就是这样的例子
//				SELECT
//						ascuxc.accounting_order_sn,
//						uoc.batchs
//				FROM
//				accounting_score_customer_x_credit ascuxc
//				LEFT JOIN unified_order_credit uoc ON
//				ascuxc.unified_order_credit_id = uoc.id
//				WHERE
//						accounting_order_sn = 'DZ2020112600003'
//				GROUP BY
//				uoc.batchs
                if (countCreditIds.equals(countCreditX)) {

                    Map<String, List<AccountingScoreCustomerXCredit>> groupByAccountingOrderSnMap = groupByAccountingOrderSn(xCreditAccountingStateEq1List);

                    if (groupByAccountingOrderSnMap.size() == 1) {

                        report
                                .append("结果      : 关联关系 正常 无需修正 一个对账单包含多个批次|同样的企业 是正常的 \n")
                                .append("对账单号为 : ").append(AnJsonUtils.toJson(groupByAccountingOrderSnMap.keySet()));
                    } else {

                        report
                                .append("结果      : 关联关系 异常 存在于多个对账单 不作修正\n")
                                .append("对账单号为 : ").append(AnJsonUtils.toJson(groupByAccountingOrderSnMap.keySet()));
                    }

                } else if (countCreditX.intValue() < countCreditIds.intValue()) {
                    report
                            .append("结果    : 关联关系 < 已对账流水 异常 此批次Sn可能存部分未对账 不作修正")
                            .append("流水Ids : ").append(AnJsonUtils.toJson(creditIdsAccountingStateEq1)).append("\n");

                } else if (countCreditX.intValue() > countCreditIds.intValue()) {

//					report
//							.append("批次Sn  : ").append(batchs).append("\n")
//							.append("结果    : 关联关系 > 已对账流水 异常 不作修正");
//							.append("积分流水Ids : ").append(JsonUtils.toJson(creditIdsAccountingStateEq1)).append("\n");


                    Map<String, List<AccountingScoreCustomerXCredit>> groupByAccountingOrderSnMap = groupByAccountingOrderSn(xCreditAccountingStateEq1List);

                    for (Map.Entry<String, List<AccountingScoreCustomerXCredit>> entry : groupByAccountingOrderSnMap.entrySet()) {

                        AccountingScoreCustomer accountingScoreCustomer = accountingScoreCustomerService.findByAccountingOrderSn(entry.getKey());

                        if (null == accountingScoreCustomer) {
                            report.append("对账单号为 : ").append(entry.getKey()).append(" 不存在\n");
                            continue;
                        } else if (accountingScoreCustomer.getAccountingStatus().equals(AccountingOrderCustomerAccountingStatusEnum.已取消.getKey())) {
                            report.append("对账单号为 : ").append(entry.getKey()).append(" 已取消\n");
                            continue;
                        } else {

                            if (countCreditIds.equals(entry.getValue().size())) {
                                report.append("对账单号为 : ").append(entry.getKey()).append(" 关联关系 正常\n");
                            } else {
                                report.append("对账单号为 : ").append(entry.getKey()).append(" 关联关系 异常\n");
                            }
                        }


                    }

                } else {
                    report
                            .append("结果    : 关联关系 异常 不作修正 要进一步排查!")
                            .append("流水Ids : ").append(AnJsonUtils.toJson(creditIdsAccountingStateEq1)).append("\n");
                }

            }

        }

        return report.toString();
    }

    private static String fetchGroupKeyByAccountingOrderSn(AccountingScoreCustomerXCredit accountingScoreCustomerXCredit) {
        return accountingScoreCustomerXCredit.getAccountingOrderSn();
    }

    public Map<String, List<AccountingScoreCustomerXCredit>> groupByAccountingOrderSn(List<AccountingScoreCustomerXCredit> xCreditList) {


        Map<String, List<AccountingScoreCustomerXCredit>> transferMapGrouopByAccountingOrderSn = xCreditList.parallelStream()
                .collect(Collectors.groupingBy(e -> fetchGroupKeyByAccountingOrderSn(e), Collectors.toList()));

        return transferMapGrouopByAccountingOrderSn;

    }
    /****************************************** 补丁程序 start ******************************************/

    /****************************************** 工具类方法 start ******************************************/

    @Override
    public List<String> queryOrderSnsBySelectCreditIds(List<Long> selectCreditIds) {

        List<String> orderSns = new ArrayList<>();

        if (CollUtil.isEmpty(selectCreditIds)) {
            log.error("queryOrderSnsBySelectCreditIds selectCreditIds isEmpty = true");
            return orderSns;
        }


        UnifiedOrderCreditExample selectCreditIdsExample = new UnifiedOrderCreditExample();
        selectCreditIdsExample.createCriteria()
                .andIdIn(selectCreditIds);

        List<UnifiedOrderCredit> resultList = unifiedOrderCreditMapper.selectByExample(selectCreditIdsExample);

        if (CollUtil.isNotEmpty(resultList)) {
            orderSns = resultList.stream().filter(AnLamdaUtils.distinctByKey(o -> o.getOrderSn())).map(o -> o.getOrderSn()).collect(Collectors.toList());
        }

        return orderSns;
    }

    /****************************************** 工具类方法   end ******************************************/

}
