package cn.superdesk.uniorder.service.accounting.unified.supplier.Impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.superdesk.uniorder.common.enums.common.CommonAccountingStateEnum;
import cn.superdesk.uniorder.common.enums.common.CommonNeedReviseMarkEnum;
import cn.superdesk.uniorder.common.enums.common.CommonOrderCompletStateEnum;
import cn.superdesk.uniorder.common.enums.common.CommonServiceNoEnum;
import cn.superdesk.uniorder.common.enums.invoice.supplier.InvoiceApplySupplierInvoiceProgressingStatusEnum;
import cn.superdesk.uniorder.common.enums.accounting.AccountingOrderBackAccountStatusEnum;
import cn.superdesk.uniorder.common.enums.accounting.AccountingOrderDimCreateByEnum;
import cn.superdesk.uniorder.common.enums.accounting.AccountingOrderInvoiceApplyStatusEnum;
import cn.superdesk.uniorder.common.enums.accounting.AccountingOrderIsSendEmailEnum;
import cn.superdesk.uniorder.common.enums.accounting.supplier.AccountingOrderSupplierAccountingStatusEnum;
import cn.superdesk.uniorder.common.json.AnJsonUtils;
import cn.superdesk.uniorder.common.lamda.AnLamdaUtils;
import cn.superdesk.uniorder.common.numerical.AnDateUtils;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.common.rest.response.ResponseResultInnerUtils;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.dao.entity.accounting.unified.supplier.AccountingUnifiedSupplier;
import cn.superdesk.uniorder.dao.entity.accounting.unified.supplier.AccountingUnifiedSupplierXGoods;
import cn.superdesk.uniorder.dao.entity.base.UnifiedOrder;
import cn.superdesk.uniorder.dao.entity.base.UnifiedOrderGoods;
import cn.superdesk.uniorder.dao.mapper.accounting.unified.supplier.*;
import cn.superdesk.uniorder.dao.mapper.base.*;
import cn.superdesk.uniorder.dto.param.accounting.unified.supplier.AccountingUnifiedSupplierOpCreateParamDimGoods;
import cn.superdesk.uniorder.dto.param.accounting.unified.supplier.AccountingUnifiedSupplierCreateParamDimGoodsSelected;
import cn.superdesk.uniorder.service.accounting.unified.supplier.AccountingUnifiedSupplierServiceOpCreateDimGoods;
import cn.superdesk.uniorder.service.accounting.unified.supplier.AccountingUnifiedSupplierServiceOpStatistics;
import cn.superdesk.uniorder.service.accounting.unified.supplier.AccountingUnifiedSupplierXGoodsService;
import cn.superdesk.uniorder.service.order.base.UnifiedOrderCreditService;
import cn.superdesk.uniorder.service.order.base.UnifiedOrderGoodsService;
import cn.superdesk.uniorder.service.order.base.UnifiedOrderService;
import cn.superdesk.uniorder.service.setting.UnifiedSnConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
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
 * @CreateDate: 2021/10/25 下午7:54
 * @UpdateUser: linjinyu
 * @UpdateDate: 2021/10/25 下午7:54
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class AccountingUnifiedSupplierServiceOpCreateDimGoodsImpl implements AccountingUnifiedSupplierServiceOpCreateDimGoods {

    @Autowired
    private UnifiedOrderMapper                   unifiedOrderMapper;
    @Autowired
    private UnifiedOrderMapperEx                 unifiedOrderMapperEx;
    @Autowired
    private UnifiedOrderMapperExSupplierDimOrder unifiedOrderMapperExSupplierDimOrder;
    @Autowired
    private UnifiedOrderService                  unifiedOrderService;

    @Autowired
    private UnifiedOrderGoodsMapper   unifiedOrderGoodsMapper;
    @Autowired
    private UnifiedOrderGoodsMapperEx unifiedOrderGoodsMapperEx;
    @Autowired
    private UnifiedOrderGoodsService  unifiedOrderGoodsService;

    @Autowired
    private UnifiedOrderCreditMapper  unifiedOrderCreditMapper;
    @Autowired
    private UnifiedOrderCreditService unifiedOrderCreditService;

    @Autowired
    private AccountingUnifiedSupplierMapper   accountingUnifiedSupplierMapper;
    @Autowired
    private AccountingUnifiedSupplierMapperEx accountingUnifiedSupplierMapperEx;

    @Autowired
    private AccountingUnifiedSupplierOrderMapper    accountingUnifiedSupplierOrderMapper;
    @Autowired
    private AccountingUnifiedSupplierXOrderMapperEx accountingUnifiedSupplierXOrderMapperEx;

    @Autowired
    private AccountingUnifiedSupplierXGoodsMapper   accountingUnifiedSupplierXGoodsMapper;
    @Autowired
    private AccountingUnifiedSupplierXGoodsMapperEx accountingUnifiedSupplierXGoodsMapperEx;
    @Autowired
    private AccountingUnifiedSupplierXGoodsService  accountingUnifiedSupplierXGoodsService;

    @Autowired
    private AccountingUnifiedSupplierServiceOpStatistics accountingUnifiedSupplierServiceOpStatistics;

    @Autowired
    private UnifiedSnConfigService unifiedSnConfigService;

    private String fetchGroupKeyByServiceNoDimOrder(UnifiedOrder unifiedOrder) {
        return unifiedOrder.getServiceNo();
    }

    private Long fetchGroupKeyBySaleIdDimOrder(UnifiedOrder unifiedOrder) {
        return unifiedOrder.getSaleId();
    }


    @Override
    public R<AccountingUnifiedSupplier> opCreateAccountingDimGoodsPreProcess(AccountingUnifiedSupplierOpCreateParamDimGoods accountingUnifiedSupplierCreateParamDimGoods, LoginSysUser loginSysUser) {

//		List<AccountingUnifiedSupplierCreateParamDimGoodsSelected> requestParams = AnJsonUtils.toList(accountingUnifiedSupplierCreateParamDimGoods.getJsonStr(), AccountingUnifiedSupplierCreateParamDimGoodsSelected.class);


        List<AccountingUnifiedSupplierCreateParamDimGoodsSelected> requestParams = accountingUnifiedSupplierCreateParamDimGoods.getGoodsSelected();
        log.info("供应商 创建对账单 包体 {}", AnJsonUtils.toJson(requestParams));


//		/****************************************** 添加逻辑- start ******************************************/
//		List<Long> processSysUnifiedOrderGoodsIds = requestParams.stream()
//				.filter(o -> null != o.getUnifiedOrderId())
//				.filter(AnLamdaUtils.distinctByKey(o -> o.getUnifiedOrderGoodsId()))
//				.map(UnifiedSupplierCreateDimGoodsParamJsonStruct::getUnifiedOrderGoodsId)
//				.collect(Collectors.toList());
//
//		AccountingSupplierNotYetDimGoodsCriteria                criteria = new AccountingSupplierNotYetDimGoodsCriteria();
//		criteria.setUnifiedOrderGoodsIds(processSysUnifiedOrderGoodsIds);
//		List<UnifiedOrderJoinGoodsOfSupplierStatementOfAccount> exportData = unifiedOrderService.getSupplierUnAccountingDimGoodsList(criteria);


        /****************************************** 添加逻辑-订单状态较验 mark by linjinyu at 20210302 start ******************************************/

        List<Long> processUnifiedOrderIds = requestParams.stream()
                .filter(o -> null != o.getUnifiedOrderId())
                .filter(AnLamdaUtils.distinctByKey(o -> o.getUnifiedOrderId()))
                .map(AccountingUnifiedSupplierCreateParamDimGoodsSelected::getUnifiedOrderId)
                .collect(Collectors.toList());

        List<UnifiedOrder> toBeOrderList = unifiedOrderService.findBySysUnifiedOrderIds(processUnifiedOrderIds);

        if (CollUtil.isEmpty(toBeOrderList)) {
            log.error("没有找到要创建对账单的订单 {}", AnJsonUtils.toJson(toBeOrderList));
            return new ResponseResultInnerUtils<AccountingUnifiedSupplier>().setErrorMsg(500, "创建对账单操作-失败-没有找到要创建对账单的订单");
        }

        /****************************************** 添加逻辑-供应商较验 mark by linjinyu at 20210805 start ******************************************/

        Map<Long, List<UnifiedOrder>> transferMapGroupBySaleId = toBeOrderList.parallelStream()
                .collect(Collectors.groupingBy(e -> fetchGroupKeyBySaleIdDimOrder(e), Collectors.toList()));

        if (transferMapGroupBySaleId.keySet().size() > 1) {
            log.error("存在多个 供应商(来源) {}", AnJsonUtils.toJson(toBeOrderList));
            return new ResponseResultInnerUtils<AccountingUnifiedSupplier>().setErrorMsg(500, "创建对账单操作-失败-存在多个 供应商(来源)-供应商名称一样不代表是同一个供应商");
        }

        /****************************************** 添加逻辑-订单类型较验 mark by linjinyu at 20210302 start ******************************************/

        Map<String, List<UnifiedOrder>> transferMapGroupByServiceNo = toBeOrderList.parallelStream()
                .collect(Collectors.groupingBy(e -> fetchGroupKeyByServiceNoDimOrder(e), Collectors.toList()));

        if (transferMapGroupByServiceNo.keySet().size() > 1) {
            log.error("存在多种 订单类型(来源) {}", AnJsonUtils.toJson(toBeOrderList));
            return new ResponseResultInnerUtils<AccountingUnifiedSupplier>().setErrorMsg(500, "创建对账单操作-失败-存在多种 订单类型(来源)");
        }


        /****************************************** 添加逻辑-订单状态 非已完成 不能创建对账单-目前 不是侨城汇的 不作 已完成 要求 start ******************************************/

        for (String serviceNo : transferMapGroupByServiceNo.keySet()) {
            log.info("Map key {} value {}", serviceNo, transferMapGroupByServiceNo.get(serviceNo));

            switch (CommonServiceNoEnum.getByServiceNo(serviceNo)) {
                case 服务之窗:
                    break;
                case 企业采购:
                    break;
                case 代客下单:
                    break;
                case 企业福利:
                    break;
                case 企业福利_侨城汇:

                    /****************************************** 添加订单状态较验-订单状态-已完成逻辑 mark by linjinyu at 20210302 start ******************************************/
                    // pay_time send_time finish_time 都是空的？侨城汇 mark by linjinyu at 20210302

                    // 侨城汇 企业福利 order_state order_state_name
                    //		-1 已关闭
                    //		1 待发货
                    //		2 待收货
                    //		3 已完成
                    List<Predicate<UnifiedOrder>> predicatesUnifiedOrderByOrderStateNoEq3 = new ArrayList<>();
//					predicatesUnifiedOrderByOrderStateNoEq3.add(r -> r.getOrderState() != null && r.getOrderState() != 3);
                    predicatesUnifiedOrderByOrderStateNoEq3.add(r -> r.getCompletState() != null && r.getCompletState().compareTo(CommonOrderCompletStateEnum.已完成.getKey()) != 0);
                    List<UnifiedOrder> warningOrderList = AnLamdaUtils.filters(toBeOrderList, predicatesUnifiedOrderByOrderStateNoEq3);

                    // 存在未完成订单 返回
                    if (CollUtil.isNotEmpty(warningOrderList)) {

                        log.error("存在 订单状态 非 [已完成] 返回 {}", AnJsonUtils.toJson(warningOrderList));
                        return new ResponseResultInnerUtils<AccountingUnifiedSupplier>().setErrorMsg(500, "创建对账单操作-失败-存在 订单状态 非 [已完成] 返回");
                    }
                    /****************************************** 添加订单状态较验-订单状态-已完成逻辑 mark by linjinyu at 20210302   end ******************************************/

                    break;
                case 楼闪送:
                    break;
                case UNKNOW:
                    break;
                default:
                    break;
            }

        }

        /****************************************** 添加逻辑-订单状态较验 mark by linjinyu at 20210302   end ******************************************/

        /****************************************** 添加逻辑-锁定状态校验 mark by linjinyu at 20210702 start ******************************************/

        List<Long> processUnifiedOrderGoodsIds = requestParams.stream()
                .filter(o -> null != o.getUnifiedOrderGoodsId())
                .filter(AnLamdaUtils.distinctByKey(o -> o.getUnifiedOrderGoodsId()))
                .map(AccountingUnifiedSupplierCreateParamDimGoodsSelected::getUnifiedOrderGoodsId)
                .collect(Collectors.toList());

        List<UnifiedOrderGoods> processUnifiedOrderGoodsList = unifiedOrderGoodsService.findBySysUnifiedOrderGoodsIds(processUnifiedOrderGoodsIds);

        /****************************************** // TODO 过虑已对账商品 start ******************************************/

        List<Predicate<UnifiedOrderGoods>> predicatesUnifiedOrderGoodsByAccountingStateSupplierEq1 = new ArrayList<>();
        predicatesUnifiedOrderGoodsByAccountingStateSupplierEq1.add(r -> r.getAccountingStateSupplier() != null && r.getAccountingStateSupplier() == 1);
        List<UnifiedOrderGoods> predicatesUnifiedOrderGoodsByAccountingStateSupplierEq1Filter = AnLamdaUtils.filters(processUnifiedOrderGoodsList, predicatesUnifiedOrderGoodsByAccountingStateSupplierEq1);

        if (CollUtil.isNotEmpty(predicatesUnifiedOrderGoodsByAccountingStateSupplierEq1Filter)) {
            // TODO 记录错误-传过来的数据-包含已对账商品
            return null;
        }

        /****************************************** // TODO 过虑已对账商品   end ******************************************/


        /****************************************** 添加逻辑-锁定状态校验 mark by linjinyu at 20210702 start ******************************************/

        AccountingUnifiedSupplier accountingUnifiedSupplier = new AccountingUnifiedSupplier();


        /****************************************** 为了填充 供应商对账单信息 start ******************************************/

//	1. "账单周期"开始日期&结束日期均不为空: 服务端将该前端传的账单周期开始日期&结束日期,记录到该对账单的账单周期;
//	2. "账单周期"开始日期&结束日期均为空: 服务端计算该对账单的账单周期开始日期&结束日期;
//	2.1 对账单内数据排序: 按数据的下单时间"升序"依次排列显示;
//      开始日期: 取该对账单第一条数据的下单时间的日期作为账单周期的开始日期;
//      结束日期: 取该对账单最后一条数据的下单时间的日期作为账单周期的结束日期;

        // 供应商对账单 参数 存储前判定
        if (StringUtils.isNotEmpty(accountingUnifiedSupplierCreateParamDimGoods.getStartTime())
                && StringUtils.isNotEmpty(accountingUnifiedSupplierCreateParamDimGoods.getEndTime())) {

//			accountingUnifiedSupplier.setStartTime(AnDateUtils.parseDate(accountingUnifiedSupplierCreateParamDimGoods.getStartTime(), AnDateUtils.TIMESTAMP_PATTERN));
//			accountingUnifiedSupplier.setEndTime(AnDateUtils.parseDate(accountingUnifiedSupplierCreateParamDimGoods.getEndTime(), AnDateUtils.TIMESTAMP_PATTERN));

            accountingUnifiedSupplier.setStartTime(AnDateUtils.parseDate(accountingUnifiedSupplierCreateParamDimGoods.getStartTime(), AnDateUtils.DATE_PATTERN));
            accountingUnifiedSupplier.setEndTime(AnDateUtils.parseDate(accountingUnifiedSupplierCreateParamDimGoods.getEndTime(), AnDateUtils.DATE_PATTERN));

        } else {

            UnifiedOrder _startOrder = toBeOrderList.get(0);

            UnifiedOrder _endOrder = null;
            if (toBeOrderList.size() > 1) {
                _endOrder = toBeOrderList.get(toBeOrderList.size() - 1);
            } else {
                _endOrder = _startOrder;
            }
            accountingUnifiedSupplier.setStartTime(_startOrder.getCreateTime());
            accountingUnifiedSupplier.setEndTime(_endOrder.getCreateTime());

        }


        /****************************************** 前端没有传 start ******************************************/

        // 供应商对账单 参数 存储前判定
        accountingUnifiedSupplier.setAddress(accountingUnifiedSupplierCreateParamDimGoods.getAddress());

        // 供应商对账单 参数 存储前判定
        if (StringUtils.isNotEmpty(accountingUnifiedSupplierCreateParamDimGoods.getIsEmail())) {
            accountingUnifiedSupplier.setIsSendEmail(Integer.valueOf(accountingUnifiedSupplierCreateParamDimGoods.getIsEmail()));
        } else {
            accountingUnifiedSupplier.setIsSendEmail(AccountingOrderIsSendEmailEnum.未发送.getKey());
        }

        // 供应商对账单 参数 存储前判定
        accountingUnifiedSupplier.setInvoiceTitle(accountingUnifiedSupplierCreateParamDimGoods.getInvoiceTitle());

        if (StringUtils.isNotEmpty(accountingUnifiedSupplierCreateParamDimGoods.getInvoiceType())) {
            accountingUnifiedSupplier.setInvoiceType(Integer.valueOf(accountingUnifiedSupplierCreateParamDimGoods.getInvoiceType()));
        } else {
            // TODO 写死 1
            accountingUnifiedSupplier.setInvoiceType(1);
        }

        accountingUnifiedSupplier.setTaxCode(accountingUnifiedSupplierCreateParamDimGoods.getTaxCode());

        /****************************************** 前端没有传   end ******************************************/

        /****************************************** 京东对账差异点 start ******************************************/

        // mark by linjinyu at 20211026 简单做吧
//		【后端开发中(进度50%)-20211022-更新进度-京东线上对账需求讲解-需求跟进-侨城汇8月京东对账异常】 https://www.tapd.cn/33003868/prong/stories/view/1133003868001003091
//		需求6:对账单列表(按供应商结算2.0 版流程和功能交互是同一套功能,不同点是部分状态系统控制)
//		①京东的账单,在京东对账模块,点击确认账单时,根据商品维度产生账单,对账单状态系统默认为:已确认、申请开票状态为:全部申请

        if (ObjectUtil.isNotNull(accountingUnifiedSupplierCreateParamDimGoods.getSpecialHandle()) && accountingUnifiedSupplierCreateParamDimGoods.getSpecialHandle().equals(886)) {
            accountingUnifiedSupplier.setAccountingStatus(AccountingOrderSupplierAccountingStatusEnum.已确认.getKey());
            accountingUnifiedSupplier.setInvoiceApplyStatus(AccountingOrderInvoiceApplyStatusEnum.全部申请.getKey());
        } else {
            accountingUnifiedSupplier.setAccountingStatus(AccountingOrderSupplierAccountingStatusEnum.待提交.getKey());
            accountingUnifiedSupplier.setInvoiceApplyStatus(AccountingOrderInvoiceApplyStatusEnum.未申请.getKey());
        }


        /****************************************** 京东对账差异点   end ******************************************/

        /****************************************** 开票申请部分 start ******************************************/

        // 0-未申请;1-全部申请;2-部分申请;
        accountingUnifiedSupplier.setInvoiceApplyModeRecord(0);
        accountingUnifiedSupplier.setInvoiceApplyTime(DateUtil.date());
        accountingUnifiedSupplier.setInvoiceApplyUserId(loginSysUser.getSysUserId());

        // 修正为 开票进展 流程类
        accountingUnifiedSupplier.setInvoiceStatus(InvoiceApplySupplierInvoiceProgressingStatusEnum.未申请.getKey());

        accountingUnifiedSupplier.setBackAccountStatus(AccountingOrderBackAccountStatusEnum.未回款.getKey());

        /**
         * 20220426 保留集采账单对账时间
         */
        if (ObjectUtil.isNotNull(accountingUnifiedSupplierCreateParamDimGoods.getJcStatementCreateTime())) {
            accountingUnifiedSupplier.setCreateTime(accountingUnifiedSupplierCreateParamDimGoods.getJcStatementCreateTime());
        }else {
            accountingUnifiedSupplier.setCreateTime(DateUtil.date());
        }
        accountingUnifiedSupplier.setCreateUserId(loginSysUser.getSysUserId());

        accountingUnifiedSupplier.setNeedReviseMark(CommonNeedReviseMarkEnum.正常.getKey());


        /****************************************** 差异部分 Dim Goods start ******************************************/
        // 对账单 关联的 订单


        UnifiedOrder order = unifiedOrderService.findById(requestParams.get(0).getUnifiedOrderId());

        // 取 供应商 商户 信息
        if (StringUtils.isNotEmpty(accountingUnifiedSupplierCreateParamDimGoods.getSaleId())) {
            accountingUnifiedSupplier.setSaleId(Long.parseLong(accountingUnifiedSupplierCreateParamDimGoods.getSaleId()));
            accountingUnifiedSupplier.setSaleName(accountingUnifiedSupplierCreateParamDimGoods.getSaleName());
        } else {
            accountingUnifiedSupplier.setSaleId(order.getSaleId());
            accountingUnifiedSupplier.setSaleName(order.getSaleName());
        }

        /**
         * 20220426 保留集采原始sn
         */
        String accountingOrderSn;
        if (StringUtils.isNotBlank(accountingUnifiedSupplierCreateParamDimGoods.getJcAccountingOrderSn())) {
            accountingOrderSn = accountingUnifiedSupplierCreateParamDimGoods.getJcAccountingOrderSn();
        }else {
            accountingOrderSn = unifiedSnConfigService.getSupplierStatementOfAccountSnBySnowflake(order.getServiceNo());
        }

        if (StringUtils.isEmpty(accountingOrderSn)) {
            return new ResponseResultInnerUtils<AccountingUnifiedSupplier>().setErrorMsg(500, "创建对账单操作-失败-生成对账单编号失败-有可能是服务号未配置-请联系管理员");
        }
        /****************************************** 差异部分 Dim Goods  end ******************************************/


        accountingUnifiedSupplier.setAccountingOrderSn(accountingOrderSn);

        /****************************************** 为了填充 供应商对账单信息   end *****************************—*************/

        /**
         * 20220516 订单来源处理
         */
        if (StringUtils.isNotBlank(accountingUnifiedSupplierCreateParamDimGoods.getSourceFrom())) {
            accountingUnifiedSupplier.setSourceFrom(accountingUnifiedSupplierCreateParamDimGoods.getSourceFrom());
        }
        if (StringUtils.isNotBlank(accountingUnifiedSupplierCreateParamDimGoods.getServiceNo())) {
            accountingUnifiedSupplier.setServiceNo(accountingUnifiedSupplierCreateParamDimGoods.getServiceNo());
        }

        return opCreateAccountingDimGoods(accountingUnifiedSupplier, requestParams);
    }

    /**
     * 供应商结算 供应商对账 创建对账单
     *
     * @param statementOfAccount 实体类
     * @param requestParams      关系 对账单 X 商品 行数 accountingOrderId accountingOrderSn unifiedOrderId unifiedOrderGoodsId unifiedOrderCreditId
     * @return
     */
    @Override
    @Transactional
    public R<AccountingUnifiedSupplier> opCreateAccountingDimGoods(AccountingUnifiedSupplier statementOfAccount, List<AccountingUnifiedSupplierCreateParamDimGoodsSelected> requestParams) {

        statementOfAccount.setDimCreateBy(AccountingOrderDimCreateByEnum.商品.getKey());

        // 对账单 信息在上一步已经好了
        accountingUnifiedSupplierMapper.insert(statementOfAccount);

        /****************************************** 差异部分 Dim Goods start ******************************************/

        // TODO 待重构 此可以在上一步处理 , 不行 XX用到了
        List<Long> processSysUnifiedOrderIds      = requestParams.stream().filter(o -> null != o.getUnifiedOrderId()).filter(AnLamdaUtils.distinctByKey(o -> o.getUnifiedOrderId())).map(AccountingUnifiedSupplierCreateParamDimGoodsSelected::getUnifiedOrderId).collect(Collectors.toList());
        List<Long> processSysUnifiedOrderGoodsIds = requestParams.stream().filter(o -> null != o.getUnifiedOrderGoodsId()).filter(AnLamdaUtils.distinctByKey(o -> o.getUnifiedOrderGoodsId())).map(AccountingUnifiedSupplierCreateParamDimGoodsSelected::getUnifiedOrderGoodsId).collect(Collectors.toList());
        List<Long> processOutGoodsIds             = requestParams.stream().filter(o -> null != o.getGoodsId()).filter(AnLamdaUtils.distinctByKey(o -> o.getGoodsId())).map(AccountingUnifiedSupplierCreateParamDimGoodsSelected::getGoodsId).collect(Collectors.toList());

        List<String> processOrderSn = unifiedOrderService.convertSysUnifiedOrderIds2OrderSn(processSysUnifiedOrderIds);

        Map<Long, String>            mapSysUnifiedOrderId2OrderSn     = unifiedOrderService.convertSysUnifiedOrderIds2MapSysUnifiedOrderId2OrderSn(processSysUnifiedOrderIds);
        Map<Long, UnifiedOrderGoods> mapSysUnifiedOrderGoodsId2Entity = unifiedOrderGoodsService.convertSysUnifiedOrderGoodsIds2MapSysUnifiedOrderGoodsId2Entity(processSysUnifiedOrderGoodsIds);

        Map<String, Object> params = new HashMap<>();
        params.put("dimCreateBy", AccountingOrderDimCreateByEnum.商品.getKey());
        params.put("accountingOrderSn", statementOfAccount.getAccountingOrderSn());
        params.put("ids", processSysUnifiedOrderIds); // 这个是 uo.id


        // 对账单 X 订单 兼容 老做法 订单维度 TODO 如果开放了 商品维度对账,这个大概是错的 但这样插入是对的 程序是对的 , 但再回到订单维度,逻辑可能是错的
        accountingUnifiedSupplierXOrderMapperEx.createRelation(params);

        // 批量插入
        List<AccountingUnifiedSupplierXGoods> processAccountingUnifiedSupplierXGoodsList = new ArrayList<>();

        // 对账单 X [订单] X 商品 TODO mark by linjinyu 20201029 由于时间赶 先这样弄 一条条没效率 | 已优化 mark by linjinyu at 20211203
        for (AccountingUnifiedSupplierCreateParamDimGoodsSelected structItem : requestParams) {

            AccountingUnifiedSupplierXGoods xGoods = new AccountingUnifiedSupplierXGoods();

            xGoods.setDimCreateBy(AccountingOrderDimCreateByEnum.商品.getKey());

            xGoods.setAccountingOrderId(statementOfAccount.getId());
            xGoods.setAccountingOrderSn(statementOfAccount.getAccountingOrderSn());

            xGoods.setUnifiedOrderId(structItem.getUnifiedOrderId());
            xGoods.setOrderSn(mapSysUnifiedOrderId2OrderSn.get(structItem.getUnifiedOrderId()));

            xGoods.setUnifiedOrderGoodsId(structItem.getUnifiedOrderGoodsId());
            xGoods.setGoodsId(mapSysUnifiedOrderGoodsId2Entity.get(structItem.getUnifiedOrderGoodsId()).getGoodsId());
            xGoods.setOutSnapshotOrderGoodsId(mapSysUnifiedOrderGoodsId2Entity.get(structItem.getUnifiedOrderGoodsId()).getOutSnapshotOrderGoodsId());

            xGoods.setCreateUserId(1L);
            xGoods.setCreateTime(DateUtil.date());
            xGoods.setUpdateUserId(1L);
            xGoods.setCreateTime(DateUtil.date());

            processAccountingUnifiedSupplierXGoodsList.add(xGoods);

        }

        int ret = accountingUnifiedSupplierXGoodsService.insertBatch(processAccountingUnifiedSupplierXGoodsList);


        // TODO 更新 订单 供应商对账状态 -> 已对账 这个是错的,商品维度可能有部分对账的情况
        unifiedOrderService.updateAccountingStateSupplierByOrderSns(processOrderSn, CommonAccountingStateEnum.已对账);

        // 更新 商品 供应商对账状态 -> 已对账
        unifiedOrderGoodsService.updateAccountingStateSupplierByOrderSnAndSysUnifiedOrderGoodsIds(processOrderSn, processSysUnifiedOrderGoodsIds, CommonAccountingStateEnum.已对账);

        // 更新 流水 供应商对账状态  -> 已对账 20200925 供应商结算 创建对账单 如果 积分 流水 有的话 关联 更新状态 为 已对账状态
        unifiedOrderCreditService.updateFieldAccountingStateSupplierByOrderSnAndOutGoodsIds(processOrderSn, processOutGoodsIds, CommonAccountingStateEnum.已对账);

        /****************************************** 差异部分 Dim Goods   end ******************************************/

        // 统计
		accountingUnifiedSupplierServiceOpStatistics.statistics(statementOfAccount);

        return new ResponseResultInnerUtils<AccountingUnifiedSupplier>().setData(statementOfAccount, "创建对账单操作-成功");
    }


}
