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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.superdesk.uniorder.common.enums.common.CommonAccountingStateEnum;
import cn.superdesk.uniorder.common.enums.common.CommonServiceNoEnum;
import cn.superdesk.uniorder.common.enums.invoice.customer.InvoiceApplyCustomerInvoiceProgressingStatusEnum;
import cn.superdesk.uniorder.common.enums.order.UnifiedOrderGoodsBackAccountStatusEnum;
import cn.superdesk.uniorder.common.enums.pay.UnifiedOrderPayTypeEnum;
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.rest.response.R;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.dao.entity.base.UnifiedOrderGoods;
import cn.superdesk.uniorder.dao.entity.base.UnifiedOrderGoodsExample;
import cn.superdesk.uniorder.dao.entity.invoice.customer.InvoiceApplyXGoods;
import cn.superdesk.uniorder.dao.mapper.base.UnifiedOrderGoodsMapper;
import cn.superdesk.uniorder.dao.mapper.base.UnifiedOrderGoodsMapperEx;
import cn.superdesk.uniorder.dao.mapper.invoice.customer.InvoiceApplyXGoodsMapperEx;
import cn.superdesk.uniorder.dto.param.order.base.UnifiedOrderGoodsQueryCriteria;
import cn.superdesk.uniorder.dto.vo.order.base.UnifiedOrderGoodsHeadVo;
import cn.superdesk.uniorder.dto.vo.order.base.UnifiedOrderGoodsListItemVo;
import cn.superdesk.uniorder.dto.vo.unified.UnifiedOrderJoinGoodsDetailVo;
import cn.superdesk.uniorder.service.order.base.UnifiedOrderGoodsService;
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.stream.Collectors;

/**
 * @Description: 商品
 * @Author: linjinyu
 * @CreateDate: 2020/10/28 下午7:29
 * @UpdateUser: linjinyu
 * @UpdateDate: 2020/10/28 下午7:29
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class UnifiedOrderGoodsServiceImpl implements UnifiedOrderGoodsService {

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

    @Autowired
    private InvoiceApplyXGoodsMapperEx invoiceOrderMapperEx;

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

    @Override
    public int insertSelective(UnifiedOrderGoods entity) {
        return unifiedOrderGoodsMapper.insertSelective(entity);
    }

    @Override
    public int updateByPrimaryKeySelective(UnifiedOrderGoods entity) {
        return unifiedOrderGoodsMapper.updateByPrimaryKeySelective(entity);
    }

    @Override
    public void deleteObj(Long id) {

        unifiedOrderGoodsMapper.deleteByPrimaryKey(id);
    }

    @Override
    public UnifiedOrderGoods findById(Long id) {
        return unifiedOrderGoodsMapper.selectByPrimaryKey(id);
    }

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

    @Override
    public List<UnifiedOrderGoods> findAll(Map<String, Object> queryMap) {

        return unifiedOrderGoodsMapperEx.findAll(queryMap);
    }

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

    /****************************************** new BaseService 部分 start ******************************************/

    @Override
    public int addUnifiedOrderGoods(UnifiedOrderGoods entity) {
        return unifiedOrderGoodsMapper.insertSelective(entity);
    }

    @Override
    public int updateUnifiedOrderGoods(UnifiedOrderGoods entity) {
        UnifiedOrderGoods originEntity = unifiedOrderGoodsMapper.selectByPrimaryKey(entity.getId());
        AssertUtils.notNull(originEntity);
        AnBeanUtils.copy(entity, originEntity);
        return unifiedOrderGoodsMapper.updateByPrimaryKeySelective(originEntity);
    }

    @Override
    public int deleteUnifiedOrderGoods(Long id) {
        return unifiedOrderGoodsMapper.deleteByPrimaryKey(id);
    }

    @Override
    public UnifiedOrderGoods findUnifiedOrderGoodsById(Long id) {
        UnifiedOrderGoods entity = unifiedOrderGoodsMapper.selectByPrimaryKey(id);
        AssertUtils.notNull(entity);
        return entity;
    }

    @Override
    public UnifiedOrderGoodsListItemVo findListItemVoById(Long id, LoginSysUser loginSysUser) {

        List<UnifiedOrderGoodsListItemVo> resultList = queryGenericParam(
                UnifiedOrderGoodsQueryCriteria
                        .builder()
                        .unifiedOrderGoodsId(id)
                        .build(),
                loginSysUser);

        if (CollUtil.isNotEmpty(resultList)) {
            return resultList.get(0);
        } else {
            return null;
        }
    }

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

        // 样例 保留
//		UnifiedOrderGoods unifiedOrderGoodsConditions = BeanUtils.mapToBean(conditions,UnifiedOrderGoods.class);

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

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

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

    }

    @Override
    public R<List<UnifiedOrderGoodsListItemVo>> pageQueryGenericParam(
            UnifiedOrderGoodsQueryCriteria queryCriteria,
            LoginSysUser loginSysUser) {

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

        // TODO 添加条件... 后期添加 queryCriteria 转 UnifiedOrderGoodsExample.Criteria

        PageHelper.startPage(queryCriteria.getPageNumber(), queryCriteria.getPageSize());
        List<UnifiedOrderGoodsListItemVo>     resultList = queryGenericParam(queryCriteria, loginSysUser);
        PageInfo<UnifiedOrderGoodsListItemVo> page       = new PageInfo<UnifiedOrderGoodsListItemVo>(resultList);
        PageHelper.clearPage();

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

    }

    @Override
    public UnifiedOrderGoodsHeadVo queryHeadGenericParam(
            UnifiedOrderGoodsQueryCriteria queryCriteria,
            LoginSysUser loginSysUser) {

        return unifiedOrderGoodsMapperEx.queryHeadGenericParam(queryCriteria);
    }

    @Override
    public List<UnifiedOrderGoodsListItemVo> queryGenericParam(
            UnifiedOrderGoodsQueryCriteria queryCriteria,
            LoginSysUser loginSysUser) {

        List<UnifiedOrderGoodsListItemVo> resultList = unifiedOrderGoodsMapperEx.queryGenericParam(queryCriteria);

        additionalInfoQueryGenericParam(resultList);

        return resultList;
    }

    private void additionalInfoQueryGenericParam(List<UnifiedOrderGoodsListItemVo> resultList) {

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

        /**************************************** 操作人 start ****************************************/

//		List<Long> sysUserIds = new ArrayList<>();
//
//		List<Long> createUserIds = resultList.stream().filter(o -> o.getCreateUserId() != null).filter(AnLamdaUtils.distinctByKey(o -> o.getCreateUserId())).map(o -> o.getCreateUserId()).collect(Collectors.toList());
//		List<Long> updateUserIds = resultList.stream().filter(o -> o.getUpdateUserId() != null).filter(AnLamdaUtils.distinctByKey(o -> o.getUpdateUserId())).map(o -> o.getUpdateUserId()).collect(Collectors.toList());
//
//		sysUserIds.addAll(createUserIds);
//		sysUserIds.addAll(updateUserIds);
//		sysUserIds = sysUserIds
//				.stream()
//				.distinct()
//				.collect(Collectors.toList());
//
//		log.info("\n{}", JSONUtil.toJsonStr(sysUserIds));
//		Map<Long, SysUser> sysUserMap = sysUserService.convertSysUserIds2MapSysUserId2Entity(sysUserIds);

        /**************************************** 供应商 start ****************************************/

//		List<Long> outSaleIds = new ArrayList<>();
//
//		List<Long> outMerchantIds = resultList.stream().filter(o -> o.getOutMerchantId() != null).filter(AnLamdaUtils.distinctByKey(o -> o.getOutMerchantId())).map(o -> o.getOutMerchantId()).collect(Collectors.toList());
//
//		outSaleIds.addAll(outMerchantIds);
//		outSaleIds = outSaleIds
//				.stream()
//				.distinct()
//				.collect(Collectors.toList());
//
//		Map<Long, UnifiedSupplier> sysSupplierMap = sysSupplierService.convertOutSaleIds2MapOutSaleId2Entity(outSaleIds);

        for (UnifiedOrderGoodsListItemVo vo : resultList) {


            /**************************************** 补-时间 start ****************************************/

//            CHINESE_DATE_PATTERN = "yyyy年MM月dd日";
//            CHINESE_DATE_TIME_PATTERN = "yyyy年MM月dd日HH时mm分ss秒";
//            NORM_DATE_PATTERN = "yyyy-MM-dd";
//            NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

//			if (ObjectUtil.isNotNull(vo.getCreateTime())) {
//				vo.setCreateTimeFormat(DateUtil.date(vo.getCreateTime()).toString(DatePattern.NORM_DATETIME_PATTERN));
//			}
//			if (ObjectUtil.isNotNull(vo.getUpdateTime())) {
//				vo.setUpdateTimeFormat(DateUtil.date(vo.getUpdateTime()).toString(DatePattern.NORM_DATETIME_PATTERN));
//			}

            /**************************************** 补-来源 start ****************************************/

//			if (ObjectUtil.isNotNull(vo.getServiceNo())) {
//				vo.setServiceNoName(CommonServiceNoEnum.getByServiceNo(vo.getServiceNo()).getServiceName());
//			} else {
//				vo.setServiceNoName(CommonServiceNoEnum.UNKNOW.getServiceName());
//			}
//			if (ObjectUtil.isNotNull(vo.getSourceFrom())) {
//				vo.setSourceFromName(CommonSourceFromEnum.getBySourceFromCode(vo.getSourceFrom()).getSourceFromName());
//			} else {
//				vo.setSourceFromName(CommonSourceFromEnum.UNKNOW.getSourceFromName());
//			}

            /**************************************** 补-操作人 start ****************************************/

//			if (ObjectUtil.isNotNull(sysUserMap.get(vo.getCreateUserId()))) {
//				vo.setCreateUserName(sysUserMap.get(vo.getCreateUserId()).getFullname());
//			}
//			if (ObjectUtil.isNotNull(sysUserMap.get(vo.getUpdateUserId()))) {
//				vo.setUpdateUserName(sysUserMap.get(vo.getUpdateUserId()).getFullname());
//			}

        }

    }

    /****************************************** new BaseService 部分   end ******************************************/


    /**
     * 客户结算 -> 未对账订单-创建对账单 preview
     *
     * @param params
     * @return
     */
    @Override
    public List<UnifiedOrderJoinGoodsDetailVo> getUnifiedOrderJoinGoodsDetailVoList(Map<String, Object> params) {

        List<UnifiedOrderJoinGoodsDetailVo> resultList = unifiedOrderGoodsMapperEx.getUnifiedOrderJoinGoodsDetailVoList(params);

        additionalInfoUnifiedOrderJoinGoodsDetailVo(resultList);

        return resultList;
    }

    private void additionalInfoUnifiedOrderJoinGoodsDetailVo(List<UnifiedOrderJoinGoodsDetailVo> resultList) {

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

        for (UnifiedOrderJoinGoodsDetailVo vo : resultList) {

            // 补 订单类型-订单来源-引用enum CommonServiceNoEnum
            if (ObjectUtil.isNotNull(vo.getServiceNo())) {
                vo.setServiceNoName(CommonServiceNoEnum.getByServiceNo(vo.getServiceNo()).getServiceName());
            } else {
                vo.setServiceNoName(CommonServiceNoEnum.UNKNOW.getServiceName());
            }

            vo.setInvoiceStatusName(InvoiceApplyCustomerInvoiceProgressingStatusEnum.getDesc(vo.getInvoiceStatus()));
            vo.setPayTypeName(UnifiedOrderPayTypeEnum.getDesc(vo.getPayType()));

        }
    }


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

        if (CollUtil.isEmpty(processOrderSn)) {
            log.error("updateAccountingStateSupplierByOrderSn processOrderSn isEmpty = true");
            return 0;
        }

        UnifiedOrderGoodsExample forUpdateAccountingStateGoodsExample = new UnifiedOrderGoodsExample();
        forUpdateAccountingStateGoodsExample.createCriteria()
                .andOrderSnIn(processOrderSn);

        UnifiedOrderGoods forUpdateAccountingStateGoodsEntity = new UnifiedOrderGoods();
        // 供应商对账状态
        forUpdateAccountingStateGoodsEntity.setAccountingStateSupplier(state.getKey());

        return unifiedOrderGoodsMapper.updateByExampleSelective(
                forUpdateAccountingStateGoodsEntity,
                forUpdateAccountingStateGoodsExample
        );
    }

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

        if (CollUtil.isEmpty(processOrderSn)) {
            log.error("updateAccountingStateSupplierByOrderSnAndSysUnifiedOrderGoodsIds processOrderSn isEmpty = true");
            return 0;
        }

        if (CollUtil.isEmpty(processSysUnifiedOrderGoodsIds)) {
            log.error("updateAccountingStateSupplierByOrderSnAndSysUnifiedOrderGoodsIds processSysUnifiedOrderGoodsIds isEmpty = true");
            return 0;
        }

        UnifiedOrderGoodsExample forUpdateAccountingStateGoodsExample = new UnifiedOrderGoodsExample();
        forUpdateAccountingStateGoodsExample.createCriteria()
                .andOrderSnIn(processOrderSn)
                .andIdIn(processSysUnifiedOrderGoodsIds);

        UnifiedOrderGoods forUpdateAccountingStateGoodsEntity = new UnifiedOrderGoods();
        forUpdateAccountingStateGoodsEntity.setAccountingStateSupplier(state.getKey());

        return unifiedOrderGoodsMapper.updateByExampleSelective(
                forUpdateAccountingStateGoodsEntity,
                forUpdateAccountingStateGoodsExample
        );
    }

    /****************************************** 关于 供应商结算 对账单 设置 对账状态 或 恢复 对账状态   end ******************************************/

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

    @Override
    public int updateAccountingStateCustomerByOrderSn(List<String> processOrderSn, CommonAccountingStateEnum state) {

        if (CollUtil.isEmpty(processOrderSn)) {
            log.error("updateAccountingStateCustomerByOrderSn processOrderSn isEmpty = true");
            return 0;
        }

        UnifiedOrderGoodsExample forUpdateAccountingStateGoodsExample = new UnifiedOrderGoodsExample();
        forUpdateAccountingStateGoodsExample.createCriteria()
                .andOrderSnIn(processOrderSn);

        UnifiedOrderGoods forUpdateAccountingStateGoodsEntity = new UnifiedOrderGoods();
        forUpdateAccountingStateGoodsEntity.setAccountingStateCustomer(state.getKey());

        return unifiedOrderGoodsMapper.updateByExampleSelective(
                forUpdateAccountingStateGoodsEntity,
                forUpdateAccountingStateGoodsExample
        );
    }

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

        if (CollUtil.isEmpty(processOrderSn)) {
            log.error("updateAccountingStateCustomerByOrderSnAndSysUnifiedOrderGoodsIds processOrderSn isEmpty = true");
            return 0;
        }

        if (CollUtil.isEmpty(processOrderSn)) {
            log.error("updateAccountingStateCustomerByOrderSnAndSysUnifiedOrderGoodsIds processOutGoodsIds isEmpty = true");
            return 0;
        }

        UnifiedOrderGoodsExample forUpdateAccountingStateGoodsExample = new UnifiedOrderGoodsExample();
        forUpdateAccountingStateGoodsExample.createCriteria()
                .andOrderSnIn(processOrderSn)
                .andIdIn(sysUnifiedOrderGoodsIds);

        UnifiedOrderGoods forUpdateAccountingStateGoodsEntity = new UnifiedOrderGoods();
        forUpdateAccountingStateGoodsEntity.setAccountingStateCustomer(state.getKey());

        return unifiedOrderGoodsMapper.updateByExampleSelective(forUpdateAccountingStateGoodsEntity, forUpdateAccountingStateGoodsExample);
    }

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

    /****************************************** 商品 状态 回款状态 start ******************************************/

    private String fetchGroupKeyByAccountingOrderTypeAndDimCreateBy(InvoiceApplyXGoods invoiceApplyXGoods) {
        return invoiceApplyXGoods.getAccountingOrderType() + "_" + invoiceApplyXGoods.getDimCreateBy();
    }

    @Override
    public void updateFieldBackAccountStatusByInvoiceX(/*每份数据是一份对账单的数据*/List<InvoiceApplyXGoods> invoiceX) {


        // 先要得出到底是什么情况(上边的情况之一),如果存大多种情况,这个就不能处理了
        Map<String, List<InvoiceApplyXGoods>> transferMapGroupByAccountingOrderTypeAndDimCreateBy = invoiceX
                .parallelStream()
                .collect(Collectors.groupingBy(e -> fetchGroupKeyByAccountingOrderTypeAndDimCreateBy(e), Collectors.toList()));

        Integer typeCount = transferMapGroupByAccountingOrderTypeAndDimCreateBy.size();

        if (typeCount.compareTo(1) > 0) {
            log.error("updateFieldBackAccountStatusByInvoiceX 先要得出到底是什么情况(上边的情况之一),如果存大多种情况,这个就不能处理了");
            return;
        }

        /****************************************** 过滤出已回款 start ******************************************/

        List<InvoiceApplyXGoods> invoiceXBankInfoIsNotNull = invoiceX
                .stream()
                .filter(o -> null != o.getBankId())
                .collect(Collectors.toList());

        if (CollUtil.isEmpty(invoiceXBankInfoIsNotNull)) {
            // 没有已回款记录
            return;
        }

        /****************************************** 得出类型 start ******************************************/

        String[] c = new String[0];
        String   type;
        transferMapGroupByAccountingOrderTypeAndDimCreateBy.keySet().toArray(c);
        type = c[0];

        // TODO 这个X里边的 goodsId 很有可能是个坑位 大概是会包含最小两个表的数据 mark by linjinyu at 20210119

        // 需证明
        // accounting_order_type=1 dim_create_by=0 代表 accounting_unified_customer_order.id (accounting_unified_customer_order_goods.id|unified_order_goods.id|sys_good)
        // 不必证明
        // accounting_order_type=1 dim_create_by=1 代表 unified_order.id unified_order_goods.id
        // accounting_order_type=2 dim_create_by=2 代表 unified_order.id unified_order_goods.id

        List<Long> processUnifiedOrderGoodsIds = null;
        switch (type) {
            case "1_0":

                /****************************************** 想法还是有问题 start ******************************************/

                /**

                 //		证明 是最老的方式 X 表用的是 accounting_unified_customer_order.id accounting_unified_customer_order_goods.id
                 //		SELECT *
                 //		FROM `invoice_order` invo
                 //			LEFT JOIN accounting_unified_customer_order_goods aucuog ON invo.dz_good_id = aucuog.id AND invo.dz_order_id = aucuog.dz_order_id
                 //		WHERE aucuog.id is NOT NULL



                 List<Long> processInvoiceOrderIds = invoiceX.stream().map(o -> o.getId()).collect(Collectors.toList());
                 Integer countX = invoiceX.size();
                 Integer countT = invoiceOrderMapperEx.proveFieldGoodsIdIsAccountingUnifiedCustomerOrderGoodsId(processInvoiceOrderIds);

                 // 经测试后 如果invoiceX.size = 测试返回.count 证明为 accounting_order_type=1 dim_create_by=0 代表 accounting_unified_customer_order.id accounting_unified_customer_order_goods.id
                 if (countX.compareTo(countT) == 0) {


                 // 超级坑出现了

                 //					这情况才能证是 accounting_unified_customer_order_goods 记录的是 sys_good
                 // 正在显示第 0-24 行 (共 8854 行, 查询花费 0.0043 秒。)
                 //					SELECT *
                 //							FROM `invoice_order` invo
                 //					LEFT JOIN accounting_unified_customer_order_goods aucuog ON invo.dz_good_id = aucuog.id AND invo.dz_order_id = aucuog.dz_order_id
                 //					LEFT JOIN sys_good sysg ON aucuog.good_id = sysg.id AND aucuog.price = sysg.price AND aucuog.total = sysg.total AND aucuog.unit_price = sysg.unit_price
                 //
                 //					WHERE
                 //					aucuog.id is NOT NULL
                 //					AND sysg.id IS NOT NULL

                 //					20210119_修正数据_填坑.sql


                 }
                 // 经测试后 如果invoiceX.size = 测试返回.count 证明为 accounting_order_type=1 dim_create_by=0 代表 accounting_unified_customer_order.id unified_order_goods.id
                 // 此处不完全正确 accounting_unified_customer_order_goods 我也不清楚是什么时候弃用的 , 还有就是 算了 情况比较多
                 else {
                 //					processUnifiedOrderGoodsIds = invoiceX.stream().map(o -> o.getDzGoodId()).collect(Collectors.toList());
                 }
                 **/
                /****************************************** 想法还是有问题   end ******************************************/
                break;
            case "1_1":
                processUnifiedOrderGoodsIds = invoiceXBankInfoIsNotNull
                        .stream()
                        .map(o -> o.getUnifiedOrderGoodsId())
                        .collect(Collectors.toList());
                break;
            case "2_2":
                processUnifiedOrderGoodsIds = invoiceXBankInfoIsNotNull
                        .stream()
                        .map(o -> o.getUnifiedOrderGoodsId())
                        .collect(Collectors.toList());
                break;
            default:
                break;
        }

        updateFieldBackAccountStatusByUnifiedOrderGoodsIds(
                processUnifiedOrderGoodsIds,
                UnifiedOrderGoodsBackAccountStatusEnum.已回款
        );


    }

    public int updateFieldBackAccountStatusByUnifiedOrderGoodsIds(
            List<Long> processUnifiedOrderGoodsIds,
            UnifiedOrderGoodsBackAccountStatusEnum unifiedOrderGoodsBackAccountStatusEnum) {

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

        UnifiedOrderGoodsExample exampleForUpdate = new UnifiedOrderGoodsExample();
        exampleForUpdate.createCriteria()
                .andIdIn(processUnifiedOrderGoodsIds);

        UnifiedOrderGoods entityForUpdate = new UnifiedOrderGoods();
        entityForUpdate.setBackAccountStatus(unifiedOrderGoodsBackAccountStatusEnum.getKey());

        return unifiedOrderGoodsMapper.updateByExampleSelective(entityForUpdate, exampleForUpdate);

    }

    /****************************************** 商品 状态 回款状态   end ******************************************/

    /**
     * 基于 orderSn 来查 商品
     *
     * @param processOrderSn
     * @return
     */
    @Override
    public List<UnifiedOrderGoods> findByOrderSn(String processOrderSn) {

        UnifiedOrderGoodsExample forQueryGoodsExample = new UnifiedOrderGoodsExample();
        forQueryGoodsExample.createCriteria()
                .andOrderSnEqualTo(processOrderSn);

        return unifiedOrderGoodsMapper.selectByExample(forQueryGoodsExample);
    }

    /**
     * 基于 orderSn 来查 商品
     *
     * @param processOrderSns
     * @return
     */
    @Override
    public List<UnifiedOrderGoods> findByOrderSns(List<String> processOrderSns) {

        if (CollUtil.isEmpty(processOrderSns)) {
            return new ArrayList<>();
        }

        UnifiedOrderGoodsExample forQueryGoodsExample = new UnifiedOrderGoodsExample();
        forQueryGoodsExample.createCriteria()
                .andOrderSnIn(processOrderSns);

        return unifiedOrderGoodsMapper.selectByExample(forQueryGoodsExample);
    }

    /**
     * 统一订单's unified_order_godos.id s
     *
     * @param sysUnifiedOrderGoodsIds
     * @return
     */
    @Override
    public List<UnifiedOrderGoods> findBySysUnifiedOrderGoodsIds(List<Long> sysUnifiedOrderGoodsIds) {

        UnifiedOrderGoodsExample example = new UnifiedOrderGoodsExample();
        example.createCriteria()
                .andIdIn(sysUnifiedOrderGoodsIds);
        List<UnifiedOrderGoods> result = unifiedOrderGoodsMapper.selectByExample(example);
        return result;

    }


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

    @Override
    public Map<Long, UnifiedOrderGoods> convertSysUnifiedOrderGoodsIds2MapSysUnifiedOrderGoodsId2Entity(
            List<Long> sysUnifiedOrderGoodsIds) {

        Map<Long, UnifiedOrderGoods> result = new HashMap<>();

        List<UnifiedOrderGoods> unifiedOrderList = findBySysUnifiedOrderGoodsIds(sysUnifiedOrderGoodsIds);

        if (CollUtil.isNotEmpty(unifiedOrderList)) {
            result = unifiedOrderList
                    .stream()
                    .collect(Collectors.toMap(UnifiedOrderGoods::getId, v -> v, (k, v) -> v));
        }

        return result;
    }

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

    /****************************************** 补丁部分 mark by linjinyu at 20210323 start ******************************************/

    @Override
    public String checkAndFixFixTaxRateTaxCodeFiscalCode() {

        // 先得到 退单商品
        // 再得到 正单商品

        StringBuffer report = new StringBuffer();

        UnifiedOrderGoodsExample exampleSource = new UnifiedOrderGoodsExample();
        exampleSource.createCriteria()
                .andQuantityLessThan(0);

        List<UnifiedOrderGoods> listSource = unifiedOrderGoodsMapper.selectByExample(exampleSource);

        log.info("要处理的数据 {}", AnJsonUtils.toJson(listSource));

        List<String> orderSns = listSource.stream().filter(AnLamdaUtils.distinctByKey(o -> o.getOrderSn())).map(o -> o.getOrderSn()).collect(Collectors.toList());
        List<Long>   goodsIds = listSource.stream().filter(AnLamdaUtils.distinctByKey(o -> o.getGoodsId())).map(o -> o.getGoodsId()).collect(Collectors.toList());


        UnifiedOrderGoodsExample exampleTarget = new UnifiedOrderGoodsExample();
        exampleTarget.createCriteria()
                .andOrderSnIn(orderSns)
                .andGoodsIdIn(goodsIds)
                .andQuantityGreaterThan(0);

        List<UnifiedOrderGoods> listTarget = unifiedOrderGoodsMapper.selectByExample(exampleTarget);

        Map<String, List<UnifiedOrderGoods>> transferMapGroupByOrderSnGoodsIdSource = listSource.parallelStream()
                .collect(Collectors.groupingBy(e -> fetchGroupKeyByOrderSnGoodsId(e), Collectors.toList()));

        Map<String, List<UnifiedOrderGoods>> transferMapGroupByOrderSnGoodsIdTarget = listSource.parallelStream()
                .collect(Collectors.groupingBy(e -> fetchGroupKeyByOrderSnGoodsId(e), Collectors.toList()));

        for (Map.Entry<String, List<UnifiedOrderGoods>> _entry : transferMapGroupByOrderSnGoodsIdSource.entrySet()) {

            List<UnifiedOrderGoods> _tmpListSource = _entry.getValue();
            List<UnifiedOrderGoods> _tmpListTarget = transferMapGroupByOrderSnGoodsIdTarget.get(_entry.getKey());

            if (CollUtil.isEmpty(_tmpListSource) || CollUtil.isEmpty(_tmpListTarget)) {

                report.append(_entry.getKey()).append("->异常1").append(",");
                continue;

            } else if (_tmpListSource.size() == 1 && _tmpListTarget.size() == 1) {

                UnifiedOrderGoods _4updateSource = _tmpListSource.get(0);
                UnifiedOrderGoods _4updateTarget = _tmpListTarget.get(0);

                if (null == _4updateTarget.getTaxCode() || null == _4updateTarget.getTaxRate()) {
                    report.append(_entry.getKey()).append("->异常2").append(",");
                    continue;
                }

                UnifiedOrderGoods _4updateEntity = new UnifiedOrderGoods();
                _4updateEntity.setId(_4updateSource.getId());

                _4updateEntity.setFiscalCode(_4updateTarget.getFiscalCode());
                _4updateEntity.setTaxCode(_4updateTarget.getTaxCode());
                _4updateEntity.setTaxRate(_4updateTarget.getTaxRate());

                unifiedOrderGoodsMapper.updateByPrimaryKeySelective(_4updateEntity);

                report.append(_entry.getKey()).append("->修正1").append(",");


            } else {
                report.append(_entry.getKey()).append("->异常3").append(",");
                continue;
            }

        }


        return report.toString();

    }

    @Override
    public int deleteUnifiedOrderGoodsBatch(List<Long> processSysUnifiedOrderGoodsIds) {

        UnifiedOrderGoodsExample example = new UnifiedOrderGoodsExample();
        example.createCriteria()
                .andIdIn(processSysUnifiedOrderGoodsIds);

        return unifiedOrderGoodsMapper.deleteByExample(example);

    }

    private String fetchGroupKeyByOrderSnGoodsId(UnifiedOrderGoods unifiedOrderGoods) {
        return unifiedOrderGoods.getOrderSn() + "_" + unifiedOrderGoods.getGoodsId();
    }


}
