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


import cn.hutool.core.collection.CollUtil;
import cn.superdesk.uniorder.common.enums.common.CommonDirectionEnum;
import cn.superdesk.uniorder.common.enums.common.CommonNeedReviseMarkEnum;
import cn.superdesk.uniorder.common.enums.common.CommonOrderGoodsIdEnum;
import cn.superdesk.uniorder.common.enums.accounting.AccountingOrderDimCreateByEnum;
import cn.superdesk.uniorder.common.json.AnJsonUtils;
import cn.superdesk.uniorder.common.lamda.AnLamdaUtils;
import cn.superdesk.uniorder.dao.entity.accounting.unified.supplier.AccountingUnifiedSupplier;
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.dto.vo.accounting.unified.supplier.*;
import cn.superdesk.uniorder.service.accounting.unified.supplier.AccountingUnifiedSupplierServiceOpStatistics;
import cn.superdesk.uniorder.service.base.UnifiedOrderGoodsService;
import cn.superdesk.uniorder.service.base.UnifiedOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;

/**
 * @Description: Java类作用描述
 * @Author: linjinyu
 * @CreateDate: 2022/1/11 上午10:41
 * @UpdateUser: linjinyu
 * @UpdateDate: 2022/1/11 上午10:41
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class AccountingUnifiedSupplierServiceOpStatisticsImpl implements AccountingUnifiedSupplierServiceOpStatistics {


    @Autowired
    private UnifiedOrderService      unifiedOrderService;
    @Autowired
    private UnifiedOrderGoodsService unifiedOrderGoodsService;


    @Autowired
    private AccountingUnifiedSupplierMapper accountingUnifiedSupplierMapper;

    @Autowired
    private AccountingUnifiedSupplierOrderMapper    accountingUnifiedSupplierOrderMapper;
    @Autowired
    private AccountingUnifiedSupplierXOrderMapperEx accountingUnifiedSupplierXOrderMapperEx;
    @Autowired
    private AccountingUnifiedSupplierXGoodsMapper   accountingUnifiedSupplierXGoodsMapper;
    @Autowired
    private AccountingUnifiedSupplierXGoodsMapperEx accountingUnifiedSupplierXGoodsMapperEx;

    public void statistics(Long accountingOrderId) {

    }

    public void statistics(String accountingOrderSn) {

    }

    /**
     * 统计
     */
    public void statistics(AccountingUnifiedSupplier statementOfAccount, List<Long> processUnifiedOrderIds, List<Long> processUnifiedOrderGoodsIds) {

        List<UnifiedOrder>      processUnifiedOrderList      = unifiedOrderService.findBySysUnifiedOrderIds(processUnifiedOrderIds);
        List<UnifiedOrderGoods> processUnifiedOrderGoodsList = unifiedOrderGoodsService.findBySysUnifiedOrderGoodsIds(processUnifiedOrderGoodsIds);


        /****************************************** 核算 对账单 总金额 mark by linjinyu at 20210125 start ******************************************/

        // 对账单-金额
        BigDecimal goodsAmount = processUnifiedOrderGoodsList
                .stream()
                .map(item -> item.getPrice() == null ? BigDecimal.ZERO : item.getPrice().multiply(new BigDecimal(item.getQuantity())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        // 对账单-成本金额
        BigDecimal goodsCostAmount = processUnifiedOrderGoodsList
                .stream()
                .map(item -> item.getCostPrice() == null ? BigDecimal.ZERO : item.getCostPrice().multiply(new BigDecimal(item.getQuantity())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);


        /****************************************** 核算 对账单 订单数 mark by linjinyu at 20210125 start ******************************************/

        AccountingUnifiedSupplier forUpdate = new AccountingUnifiedSupplier();

        forUpdate.setId(statementOfAccount.getId());

        // 对账单-金额
//		accountingUnifiedSupplier.setAccountingAmount(goodsAmount);
        // 对账单-成本金额
//		accountingUnifiedSupplier.setAccountingCostAmount(goodsCostAmount);

        // 订单数量 orderAmount
        forUpdate.setOrderQuantity(processUnifiedOrderIds.size());
        // 订单金额
        forUpdate.setOrderAmount(BigDecimal.ZERO);
        forUpdate.setOrderCostAmount(BigDecimal.ZERO);

        // 订单商品item数量累加
        forUpdate.setGoodsQuantity(processUnifiedOrderGoodsIds.size());
        // 订单商品item的数量累加
        forUpdate.setGoodsItemQuantity(0);

        forUpdate.setGoodsAmount(goodsAmount);
        forUpdate.setGoodsCostAmount(goodsCostAmount);

        accountingUnifiedSupplierMapper.updateByPrimaryKeySelective(forUpdate);

//        if (AccountingOrderDimCreateByEnum.订单.getKey().compareTo(vo.getDimCreateBy()) == 0) {
//            accountingUnifiedSupplierServiceOpStatistics.fixDimOrder(vo);
////                    accountingUnifiedSupplierServiceOpStatistics.fixDimGoods(vo);
//        } else if (AccountingOrderDimCreateByEnum.商品.getKey().compareTo(vo.getDimCreateBy()) == 0) {
//            accountingUnifiedSupplierServiceOpStatistics.fixDimGoods(vo);
//        }
    }

    /**
     * TODO 待合并 修正列表数据显示
     *
     * @param unifiedSupplierStatementOfAccountVo
     */
    public void fixDimOrder(UnifiedSupplierStatementOfAccountVo unifiedSupplierStatementOfAccountVo) {

        // 得到 accountingOrderSn
        Map<String, Object> params = new HashMap<>();
        params.put("accountingOrderSn", unifiedSupplierStatementOfAccountVo.getAccountingOrderSn());

        AccountingUnifiedSupplierStatementOfAccountFixVoDimOrder fixVoDimOrder = checkAmountErrorForFixDimOrder(params);

        unifiedSupplierStatementOfAccountVo.setAccountingOrderAmount(fixVoDimOrder.getAccountingOrderAmount());
        unifiedSupplierStatementOfAccountVo.setAccountingOrderAmountWithFreight(fixVoDimOrder.getAccountingOrderAmountWithFreight());

        // 商品成本 - 商品退成本
        unifiedSupplierStatementOfAccountVo.setAccountingOrderCostAmount(fixVoDimOrder.getAccountingOrderCostAmount());
        // 商品成本 - 商品退成本 + 运费 + 退单退运费
        unifiedSupplierStatementOfAccountVo.setAccountingOrderCostAmountWithFreight(fixVoDimOrder.getAccountingOrderCostAmountWithFreight());

        /****************************************** 商品角度统计 start ******************************************/

        unifiedSupplierStatementOfAccountVo.setGoodsAmount(fixVoDimOrder.getGoodsAmount());
        unifiedSupplierStatementOfAccountVo.setGoodsCostAmount(fixVoDimOrder.getGoodsCostAmount());

        unifiedSupplierStatementOfAccountVo.setRefundGoodsAmount(fixVoDimOrder.getRefundGoodsAmount());
        unifiedSupplierStatementOfAccountVo.setRefundGoodsCostAmount(fixVoDimOrder.getRefundGoodsCostAmount());

        unifiedSupplierStatementOfAccountVo.setGoodsTransportAmount(fixVoDimOrder.getGoodsTransportAmount());
        unifiedSupplierStatementOfAccountVo.setRefundGoodsTransportAmount(fixVoDimOrder.getRefundGoodsTransportAmount());

        /****************************************** 数量 start ******************************************/

        unifiedSupplierStatementOfAccountVo.setOrderQuantity(fixVoDimOrder.getOrderQuantity());
        unifiedSupplierStatementOfAccountVo.setGoodsQuantity(fixVoDimOrder.getGoodsQuantity());
        unifiedSupplierStatementOfAccountVo.setGoodsItemQuantity(fixVoDimOrder.getGoodsItemQuantity());

        /****************************************** 订单角度 没作用 start ******************************************/

        unifiedSupplierStatementOfAccountVo.setOrderCostAmount(fixVoDimOrder.getOrderCostAmount());
        unifiedSupplierStatementOfAccountVo.setOrderTransportAmount(fixVoDimOrder.getOrderTransportAmount());


        /**************************************** 修订 start ****************************************/

        AccountingUnifiedSupplier fixEntity = new AccountingUnifiedSupplier();

        fixEntity.setId(unifiedSupplierStatementOfAccountVo.getId());

        fixEntity.setOrderQuantity(fixVoDimOrder.getOrderQuantity());
        fixEntity.setGoodsQuantity(fixVoDimOrder.getGoodsQuantity());
        fixEntity.setGoodsItemQuantity(fixVoDimOrder.getGoodsItemQuantity());

        fixEntity.setOrderAmount(fixVoDimOrder.getOrderAmount());
        fixEntity.setRefundOrderAmount(fixVoDimOrder.getRefundOrderAmount());

        fixEntity.setGoodsAmount(fixVoDimOrder.getGoodsAmount());
        fixEntity.setRefundGoodsAmount(fixVoDimOrder.getRefundGoodsAmount());

        fixEntity.setOrderCostAmount(fixVoDimOrder.getOrderCostAmount());
        fixEntity.setRefundOrderCostAmount(fixVoDimOrder.getRefundOrderCostAmount());

        fixEntity.setAccountingOrderAmount(fixVoDimOrder.getAccountingOrderAmount());
        fixEntity.setAccountingOrderAmountWithFreight(fixVoDimOrder.getAccountingOrderAmountWithFreight());

        fixEntity.setAccountingOrderCostAmount(fixVoDimOrder.getAccountingOrderCostAmount());
        fixEntity.setAccountingOrderCostAmountWithFreight(fixVoDimOrder.getAccountingOrderCostAmountWithFreight());

        fixEntity.setGoodsCostAmount(fixVoDimOrder.getGoodsCostAmount());
        fixEntity.setRefundGoodsCostAmount(fixVoDimOrder.getRefundGoodsCostAmount());

        fixEntity.setGoodsTransportAmount(fixVoDimOrder.getGoodsTransportAmount());
        fixEntity.setRefundGoodsTransportAmount(fixVoDimOrder.getRefundGoodsTransportAmount());

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

        int ret = accountingUnifiedSupplierMapper.updateByPrimaryKeySelective(fixEntity);

    }

    /**
     * TODO 待合并 修正列表数据显示
     *
     * @param unifiedSupplierStatementOfAccountVo
     */
    public void fixDimGoods(UnifiedSupplierStatementOfAccountVo unifiedSupplierStatementOfAccountVo) {

        // 得到 accountingOrderSn
        Map<String, Object> params = new HashMap<>();
        params.put("accountingOrderSn", unifiedSupplierStatementOfAccountVo.getAccountingOrderSn());
        AccountingUnifiedSupplierStatementOfAccountFixVoDimGoods fixVoDimGoods = checkAmountErrorForFixDimGoods(params);


        unifiedSupplierStatementOfAccountVo.setAccountingOrderAmount(fixVoDimGoods.getAccountingOrderAmount());
        unifiedSupplierStatementOfAccountVo.setAccountingOrderAmountWithFreight(fixVoDimGoods.getAccountingOrderAmountWithFreight());

        // 商品成本 - 商品退成本
        unifiedSupplierStatementOfAccountVo.setAccountingOrderCostAmount(fixVoDimGoods.getAccountingOrderCostAmount());
        // 商品成本 - 商品退成本 + 运费 + 退单退运费
        unifiedSupplierStatementOfAccountVo.setAccountingOrderCostAmountWithFreight(fixVoDimGoods.getAccountingOrderCostAmountWithFreight());

        /****************************************** 商品角度统计 start ******************************************/

        unifiedSupplierStatementOfAccountVo.setGoodsAmount(fixVoDimGoods.getGoodsAmount());
        unifiedSupplierStatementOfAccountVo.setGoodsCostAmount(fixVoDimGoods.getGoodsCostAmount());

        unifiedSupplierStatementOfAccountVo.setRefundGoodsAmount(fixVoDimGoods.getRefundGoodsAmount());
        unifiedSupplierStatementOfAccountVo.setRefundGoodsCostAmount(fixVoDimGoods.getRefundGoodsCostAmount());

        unifiedSupplierStatementOfAccountVo.setGoodsTransportAmount(fixVoDimGoods.getGoodsTransportAmount());
        unifiedSupplierStatementOfAccountVo.setRefundGoodsTransportAmount(fixVoDimGoods.getRefundGoodsTransportAmount());

        /****************************************** 数量 start ******************************************/

        unifiedSupplierStatementOfAccountVo.setOrderQuantity(fixVoDimGoods.getOrderQuantity());
        unifiedSupplierStatementOfAccountVo.setGoodsQuantity(fixVoDimGoods.getGoodsQuantity());
        unifiedSupplierStatementOfAccountVo.setGoodsItemQuantity(fixVoDimGoods.getGoodsItemQuantity());

        /****************************************** 订单角度 没作用 start ******************************************/

        unifiedSupplierStatementOfAccountVo.setOrderCostAmount(fixVoDimGoods.getOrderCostAmount());
        unifiedSupplierStatementOfAccountVo.setOrderTransportAmount(fixVoDimGoods.getOrderTransportAmount());


        /**************************************** 修订 start ****************************************/

        AccountingUnifiedSupplier fixEntity = new AccountingUnifiedSupplier();

        fixEntity.setId(unifiedSupplierStatementOfAccountVo.getId());

        fixEntity.setOrderQuantity(fixVoDimGoods.getOrderQuantity());
        fixEntity.setGoodsQuantity(fixVoDimGoods.getGoodsQuantity());
        fixEntity.setGoodsItemQuantity(fixVoDimGoods.getGoodsItemQuantity());

        fixEntity.setOrderAmount(fixVoDimGoods.getOrderAmount());
        fixEntity.setRefundOrderAmount(fixVoDimGoods.getRefundOrderAmount());

        fixEntity.setGoodsAmount(fixVoDimGoods.getGoodsAmount());
        fixEntity.setRefundGoodsAmount(fixVoDimGoods.getRefundGoodsAmount());

        fixEntity.setOrderCostAmount(fixVoDimGoods.getOrderCostAmount());
        fixEntity.setRefundOrderCostAmount(fixVoDimGoods.getRefundOrderCostAmount());

        fixEntity.setAccountingOrderAmount(fixVoDimGoods.getAccountingOrderAmount());
        fixEntity.setAccountingOrderAmountWithFreight(fixVoDimGoods.getAccountingOrderAmountWithFreight());

        fixEntity.setAccountingOrderCostAmount(fixVoDimGoods.getAccountingOrderCostAmount());
        fixEntity.setAccountingOrderCostAmountWithFreight(fixVoDimGoods.getAccountingOrderCostAmountWithFreight());

        fixEntity.setGoodsCostAmount(fixVoDimGoods.getGoodsCostAmount());
        fixEntity.setRefundGoodsCostAmount(fixVoDimGoods.getRefundGoodsCostAmount());

        fixEntity.setGoodsTransportAmount(fixVoDimGoods.getGoodsTransportAmount());
        fixEntity.setRefundGoodsTransportAmount(fixVoDimGoods.getRefundGoodsTransportAmount());


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

        int ret = accountingUnifiedSupplierMapper.updateByPrimaryKeySelective(fixEntity);

    }

    /**
     * 对账单 详情 订单维度
     *
     * @param params
     * @return
     */
    public AccountingUnifiedSupplierStatementOfAccountFixVoDimOrder checkAmountErrorForFixDimOrder(Map<String, Object> params) {

        log.error("checkAmountErrorForFixDimOrder\n\n\n{}\n\n\n", AnJsonUtils.toJson(params));


        // 先得出一份 对账单 X 商品 的数据
        List<AccountingUnifiedSuplierCheckAmountErrorForFixDimOrder> result = accountingUnifiedSupplierXOrderMapperEx.checkAmountErrorForFixDimOrder(params);

        /****************************************** 正单-商品 start ******************************************/

        List<Predicate<AccountingUnifiedSuplierCheckAmountErrorForFixDimOrder>> predicatesByPlusGoods = new ArrayList<>();
        predicatesByPlusGoods.add(
                r -> r.getGoodsName() != null
                        && (!r.getGoodsName().equals(CommonOrderGoodsIdEnum.运费.getDesc()) || !r.getGoodsName().equals(CommonOrderGoodsIdEnum.商户承担运费.getDesc()))
                        && null != r.getDirection()
                        && r.getDirection().equals(CommonDirectionEnum.正向.getKey())
        );

        /****************************************** 正单-商品   end ******************************************/


        /****************************************** 正单-运费 start ******************************************/

        List<Predicate<AccountingUnifiedSuplierCheckAmountErrorForFixDimOrder>> predicatesByTransportPlusGoods = new ArrayList<>();
        predicatesByTransportPlusGoods.add(
                r -> r.getGoodsName() != null
                        && (r.getGoodsName().equals(CommonOrderGoodsIdEnum.运费.getDesc()) || r.getGoodsName().equals(CommonOrderGoodsIdEnum.商户承担运费.getDesc()))
                        && null != r.getDirection()
                        && r.getDirection().equals(CommonDirectionEnum.正向.getKey()));

        /****************************************** 正单-运费   end ******************************************/


        /****************************************** 退单-商品 start ******************************************/

        List<Predicate<AccountingUnifiedSuplierCheckAmountErrorForFixDimOrder>> predicatesByMinusGoods = new ArrayList<>();
        predicatesByMinusGoods.add(
                r -> r.getGoodsName() != null
                        && (!r.getGoodsName().equals(CommonOrderGoodsIdEnum.退单退运费))
                        && null != r.getDirection()
                        && r.getDirection().equals(CommonDirectionEnum.负向.getKey())
        );

        /****************************************** 退单-商品   end ******************************************/

        /****************************************** 退单-退运费 start ******************************************/

        List<Predicate<AccountingUnifiedSuplierCheckAmountErrorForFixDimOrder>> predicatesByTransportMinusGoods = new ArrayList<>();
        predicatesByTransportMinusGoods.add(
                r -> r.getGoodsName() != null
                        && (r.getGoodsName().equals(CommonOrderGoodsIdEnum.退单退运费))
                        && null != r.getDirection()
                        && r.getDirection().equals(CommonDirectionEnum.负向.getKey())
        );

        /****************************************** 退单-退运费   end ******************************************/


        List<AccountingUnifiedSuplierCheckAmountErrorForFixDimOrder> predicatesByPlusGoodsFilter           = AnLamdaUtils.filters(result, predicatesByPlusGoods);
        List<AccountingUnifiedSuplierCheckAmountErrorForFixDimOrder> predicatesByMinusGoodsFilter          = AnLamdaUtils.filters(result, predicatesByMinusGoods);
        List<AccountingUnifiedSuplierCheckAmountErrorForFixDimOrder> predicatesByTransportPlusGoodsFilter  = AnLamdaUtils.filters(result, predicatesByTransportPlusGoods);
        List<AccountingUnifiedSuplierCheckAmountErrorForFixDimOrder> predicatesByTransportMinusGoodsFilter = AnLamdaUtils.filters(result, predicatesByTransportMinusGoods);

        BigDecimal orderAmount       = BigDecimal.ZERO;
        BigDecimal refundOrderAmount = BigDecimal.ZERO;

        BigDecimal goodsAmount       = BigDecimal.ZERO;
        BigDecimal refundGoodsAmount = BigDecimal.ZERO;

        BigDecimal orderTransportAmount = BigDecimal.ZERO;

        BigDecimal orderCostAmount       = BigDecimal.ZERO;
        BigDecimal refundOrderCostAmount = BigDecimal.ZERO;

        /**************************************** 主要是这些 start ****************************************/

        BigDecimal goodsCostAmount       = BigDecimal.ZERO;
        BigDecimal refundGoodsCostAmount = BigDecimal.ZERO;

        BigDecimal goodsTransportAmount       = BigDecimal.ZERO;
        BigDecimal refundGoodsTransportAmount = BigDecimal.ZERO;

        /**************************************** 主要是这些 start ****************************************/


        if (CollUtil.isNotEmpty(predicatesByPlusGoodsFilter)) {
            goodsAmount = predicatesByPlusGoodsFilter
                    .stream()
                    .map(item -> item.getPrice() == null ? BigDecimal.ZERO : item.getPrice().multiply(new BigDecimal(item.getQuantity())))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        }

        if (CollUtil.isNotEmpty(predicatesByMinusGoodsFilter)) {
            refundGoodsAmount = predicatesByMinusGoodsFilter
                    .stream()
                    .map(item -> item.getPrice() == null ? BigDecimal.ZERO : item.getPrice().multiply(new BigDecimal(item.getQuantity())))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        }

        if (CollUtil.isNotEmpty(predicatesByPlusGoodsFilter)) {
            goodsCostAmount = predicatesByPlusGoodsFilter
                    .stream()
                    .map(item -> item.getCostPrice() == null ? BigDecimal.ZERO : item.getCostPrice().multiply(new BigDecimal(item.getQuantity())))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        }

        if (CollUtil.isNotEmpty(predicatesByMinusGoodsFilter)) {
            refundGoodsCostAmount = predicatesByMinusGoodsFilter
                    .stream()
                    .map(item -> item.getCostPrice() == null ? BigDecimal.ZERO : item.getCostPrice().multiply(new BigDecimal(item.getQuantity())))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        }

        if (CollUtil.isNotEmpty(predicatesByTransportPlusGoodsFilter)) {
            goodsTransportAmount = predicatesByTransportPlusGoodsFilter
                    .stream()
                    .map(item -> item.getCostPrice() == null ? BigDecimal.ZERO : item.getCostPrice().multiply(new BigDecimal(item.getQuantity())))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        }

        if (CollUtil.isNotEmpty(predicatesByTransportMinusGoodsFilter)) {
            refundGoodsTransportAmount = predicatesByTransportPlusGoodsFilter
                    .stream()
                    .map(item -> item.getCostPrice() == null ? BigDecimal.ZERO : item.getCostPrice().multiply(new BigDecimal(item.getQuantity())))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        }

        BigDecimal accountingOrderAmount = goodsAmount.add(refundGoodsAmount);
        BigDecimal accountingOrderAmountWithFreight = accountingOrderAmount
                .add(goodsTransportAmount)
                .add(refundGoodsTransportAmount);


        BigDecimal accountingOrderCostAmount = goodsCostAmount.add(refundGoodsCostAmount);
        BigDecimal accountingOrderCostAmountWithFreight = accountingOrderCostAmount
                .add(goodsTransportAmount)
                .add(refundGoodsTransportAmount);

        log.info("核算 : " +
                        "\ngoodsCostAmount: {}" +
                        "\nrefundGoodsCostAmount: {}" +
                        "\ngoodsTransportAmount: {}" +
                        "\nrefundGoodsTransportAmount: {}" +
                        "\naccountingOrderAmount: {}" +
                        "\naccountingOrderAmountWithFreight: {}",

                goodsCostAmount,
                refundGoodsCostAmount,
                goodsTransportAmount,
                refundGoodsTransportAmount,
                accountingOrderAmount,
                accountingOrderAmountWithFreight
        );

        Integer orderQuantity     = 0;
        Integer goodsQuantity     = 0;
        Integer goodsItemQuantity = 0;

        goodsQuantity = result.size();


        AccountingUnifiedSupplierStatementOfAccountFixVoDimOrder unifiedSupplierStatementOfAccountVo = AccountingUnifiedSupplierStatementOfAccountFixVoDimOrder.builder()

                .accountingOrderAmount(accountingOrderAmount)
                .accountingOrderAmountWithFreight(accountingOrderAmountWithFreight)

                .accountingOrderCostAmount(accountingOrderCostAmount)
                .accountingOrderCostAmountWithFreight(accountingOrderCostAmountWithFreight)

                .orderAmount(orderAmount)
                .refundOrderAmount(refundOrderAmount)

                .orderTransportAmount(orderTransportAmount)

                .orderCostAmount(orderCostAmount)
                .refundOrderCostAmount(refundOrderCostAmount)

                .goodsAmount(goodsAmount)
                .refundGoodsAmount(refundGoodsAmount)

                .goodsCostAmount(goodsCostAmount)
                .refundGoodsCostAmount(refundGoodsCostAmount)

                .goodsTransportAmount(goodsTransportAmount)
                .refundGoodsTransportAmount(refundGoodsTransportAmount)

                .orderQuantity(orderQuantity)
                .goodsQuantity(goodsQuantity)
                .goodsItemQuantity(goodsItemQuantity)

                .build();

        return unifiedSupplierStatementOfAccountVo;
    }

    /**
     * 对账单 详情 商品维度
     *
     * @param params
     * @return
     */
    public AccountingUnifiedSupplierStatementOfAccountFixVoDimGoods checkAmountErrorForFixDimGoods(Map<String, Object> params) {

        log.info("对账单 详情 商品维度 {}", AnJsonUtils.toJson(params));

        // 先得出一份 对账单 X 商品 的数据
        List<AccountingUnifiedSuplierCheckAmountErrorForFixDimGoods> result = accountingUnifiedSupplierXGoodsMapperEx.checkAmountErrorForFixDimGoods(params);


        /****************************************** 正单-商品 start ******************************************/

        List<Predicate<AccountingUnifiedSuplierCheckAmountErrorForFixDimGoods>> predicatesByPlusGoods = new ArrayList<>();
        predicatesByPlusGoods.add(
                r -> r.getGoodsName() != null
                        && (!r.getGoodsName().equals(CommonOrderGoodsIdEnum.运费.getDesc()) || !r.getGoodsName().equals(CommonOrderGoodsIdEnum.商户承担运费.getDesc()))
                        && null != r.getDirection()
                        && r.getDirection().equals(CommonDirectionEnum.正向.getKey())
        );

        /****************************************** 正单-商品   end ******************************************/


        /****************************************** 正单-运费 start ******************************************/

        List<Predicate<AccountingUnifiedSuplierCheckAmountErrorForFixDimGoods>> predicatesByTransportPlusGoods = new ArrayList<>();
        predicatesByTransportPlusGoods.add(
                r -> r.getGoodsName() != null
                        && (r.getGoodsName().equals(CommonOrderGoodsIdEnum.运费.getDesc()) || r.getGoodsName().equals(CommonOrderGoodsIdEnum.商户承担运费.getDesc()))
                        && null != r.getDirection()
                        && r.getDirection().equals(CommonDirectionEnum.正向.getKey()));

        /****************************************** 正单-运费   end ******************************************/


        /****************************************** 退单-商品 start ******************************************/

        List<Predicate<AccountingUnifiedSuplierCheckAmountErrorForFixDimGoods>> predicatesByMinusGoods = new ArrayList<>();
        predicatesByMinusGoods.add(
                r -> r.getGoodsName() != null
                        && (!r.getGoodsName().equals(CommonOrderGoodsIdEnum.退单退运费))
                        && null != r.getDirection()
                        && r.getDirection().equals(CommonDirectionEnum.负向.getKey())
        );

        /****************************************** 退单-商品   end ******************************************/

        /****************************************** 退单-退运费 start ******************************************/

        List<Predicate<AccountingUnifiedSuplierCheckAmountErrorForFixDimGoods>> predicatesByTransportMinusGoods = new ArrayList<>();
        predicatesByTransportMinusGoods.add(
                r -> r.getGoodsName() != null
                        && (r.getGoodsName().equals(CommonOrderGoodsIdEnum.退单退运费))
                        && null != r.getDirection()
                        && r.getDirection().equals(CommonDirectionEnum.负向.getKey())
        );

        /****************************************** 退单-退运费   end ******************************************/


        List<AccountingUnifiedSuplierCheckAmountErrorForFixDimGoods> predicatesByPlusGoodsFilter           = AnLamdaUtils.filters(result, predicatesByPlusGoods);
        List<AccountingUnifiedSuplierCheckAmountErrorForFixDimGoods> predicatesByMinusGoodsFilter          = AnLamdaUtils.filters(result, predicatesByMinusGoods);
        List<AccountingUnifiedSuplierCheckAmountErrorForFixDimGoods> predicatesByTransportPlusGoodsFilter  = AnLamdaUtils.filters(result, predicatesByTransportPlusGoods);
        List<AccountingUnifiedSuplierCheckAmountErrorForFixDimGoods> predicatesByTransportMinusGoodsFilter = AnLamdaUtils.filters(result, predicatesByTransportMinusGoods);

        BigDecimal orderAmount       = BigDecimal.ZERO;
        BigDecimal refundOrderAmount = BigDecimal.ZERO;

        BigDecimal goodsAmount       = BigDecimal.ZERO;
        BigDecimal refundGoodsAmount = BigDecimal.ZERO;

        BigDecimal orderTransportAmount = BigDecimal.ZERO;

        BigDecimal orderCostAmount       = BigDecimal.ZERO;
        BigDecimal refundOrderCostAmount = BigDecimal.ZERO;

        /**************************************** 主要是这些 start ****************************************/

        BigDecimal goodsCostAmount       = BigDecimal.ZERO;
        BigDecimal refundGoodsCostAmount = BigDecimal.ZERO;

        BigDecimal goodsTransportAmount       = BigDecimal.ZERO;
        BigDecimal refundGoodsTransportAmount = BigDecimal.ZERO;

        /**************************************** 主要是这些 start ****************************************/


        if (CollUtil.isNotEmpty(predicatesByPlusGoodsFilter)) {
            goodsAmount = predicatesByPlusGoodsFilter
                    .stream()
                    .map(item -> item.getPrice() == null ? BigDecimal.ZERO : item.getPrice().multiply(new BigDecimal(item.getQuantity())))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        }

        if (CollUtil.isNotEmpty(predicatesByMinusGoodsFilter)) {
            refundGoodsAmount = predicatesByMinusGoodsFilter
                    .stream()
                    .map(item -> item.getPrice() == null ? BigDecimal.ZERO : item.getPrice().multiply(new BigDecimal(item.getQuantity())))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        }

        if (CollUtil.isNotEmpty(predicatesByPlusGoodsFilter)) {
            goodsCostAmount = predicatesByPlusGoodsFilter
                    .stream()
                    .map(item -> item.getCostPrice() == null ? BigDecimal.ZERO : item.getCostPrice().multiply(new BigDecimal(item.getQuantity())))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        }

        if (CollUtil.isNotEmpty(predicatesByMinusGoodsFilter)) {
            refundGoodsCostAmount = predicatesByMinusGoodsFilter
                    .stream()
                    .map(item -> item.getCostPrice() == null ? BigDecimal.ZERO : item.getCostPrice().multiply(new BigDecimal(item.getQuantity())))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        }

        if (CollUtil.isNotEmpty(predicatesByTransportPlusGoodsFilter)) {
            goodsTransportAmount = predicatesByTransportPlusGoodsFilter
                    .stream()
                    .map(item -> item.getCostPrice() == null ? BigDecimal.ZERO : item.getCostPrice().multiply(new BigDecimal(item.getQuantity())))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        }

        if (CollUtil.isNotEmpty(predicatesByTransportMinusGoodsFilter)) {
            refundGoodsTransportAmount = predicatesByTransportPlusGoodsFilter
                    .stream()
                    .map(item -> item.getCostPrice() == null ? BigDecimal.ZERO : item.getCostPrice().multiply(new BigDecimal(item.getQuantity())))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        }

        BigDecimal accountingOrderAmount = goodsAmount.add(refundGoodsAmount);
        BigDecimal accountingOrderAmountWithFreight = accountingOrderAmount
                .add(goodsTransportAmount)
                .add(refundGoodsTransportAmount);


        BigDecimal accountingOrderCostAmount = goodsCostAmount.add(refundGoodsCostAmount);
        BigDecimal accountingOrderCostAmountWithFreight = accountingOrderCostAmount
                .add(goodsTransportAmount)
                .add(refundGoodsTransportAmount);

        log.info("核算 : " +
                        "\ngoodsCostAmount: {}" +
                        "\nrefundGoodsCostAmount: {}" +
                        "\ngoodsTransportAmount: {}" +
                        "\nrefundGoodsTransportAmount: {}" +
                        "\naccountingOrderAmount: {}" +
                        "\naccountingOrderAmountWithFreight: {}",

                goodsCostAmount,
                refundGoodsCostAmount,
                goodsTransportAmount,
                refundGoodsTransportAmount,
                accountingOrderAmount,
                accountingOrderAmountWithFreight
        );

        Integer orderQuantity     = 0;
        Integer goodsQuantity     = 0;
        Integer goodsItemQuantity = 0;

        goodsQuantity = result.size();

        AccountingUnifiedSupplierStatementOfAccountFixVoDimGoods unifiedSupplierStatementOfAccountVo = AccountingUnifiedSupplierStatementOfAccountFixVoDimGoods.builder()

                .accountingOrderAmount(accountingOrderAmount)
                .accountingOrderAmountWithFreight(accountingOrderAmountWithFreight)

                .accountingOrderCostAmount(accountingOrderCostAmount)
                .accountingOrderCostAmountWithFreight(accountingOrderCostAmountWithFreight)

                .orderAmount(orderAmount)
                .refundOrderAmount(refundOrderAmount)

                .orderTransportAmount(orderTransportAmount)

                .orderCostAmount(orderCostAmount)
                .refundOrderCostAmount(refundOrderCostAmount)

                .goodsAmount(goodsAmount)
                .refundGoodsAmount(refundGoodsAmount)

                .goodsCostAmount(goodsCostAmount)
                .refundGoodsCostAmount(refundGoodsCostAmount)

                .goodsTransportAmount(goodsTransportAmount)
                .refundGoodsTransportAmount(refundGoodsTransportAmount)

                .orderQuantity(orderQuantity)
                .goodsQuantity(goodsQuantity)
                .goodsItemQuantity(goodsItemQuantity)

                .build();

        return unifiedSupplierStatementOfAccountVo;


    }
}
