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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.superdesk.uniorder.common.enums.common.*;
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.enums.accounting.AccountingOrderTypeDimEnum;
import cn.superdesk.uniorder.common.exception.utils.ExceptionUtils;
import cn.superdesk.uniorder.common.json.AnJsonUtils;
import cn.superdesk.uniorder.common.lamda.AnLamdaUtils;
import cn.superdesk.uniorder.common.numerical.AnCollectionUtils;
import cn.superdesk.uniorder.dao.entity.base.*;
import cn.superdesk.uniorder.dao.mapper.base.*;
import cn.superdesk.uniorder.dto.param.operation.UnifiedOrderIssuesFlowingParam;
import cn.superdesk.uniorder.dto.param.setting.UnifiedServicePartGoodsTransportParam;
import cn.superdesk.uniorder.dto.receive.consumer.superdeskappservices.flashdeliver.FlashDeliverRefundOrderGoodsReceiveParam;
import cn.superdesk.uniorder.dto.receive.consumer.superdeskappservices.flashdeliver.FlashDeliverRefundOrderOrderReceiveParam;
import cn.superdesk.uniorder.dto.receive.consumer.superdeskappservices.flashdeliver.FlashDeliverRefundOrderReceiveParam;
import cn.superdesk.uniorder.service.order.receive.ReceiveFlashDeliverRefundOrderService;
import cn.superdesk.uniorder.service.order.base.*;
import cn.superdesk.uniorder.service.setting.UnifiedServiceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

/**
 * @Description: Java类作用描述
 * @Author: linjinyu
 * @CreateDate: 2021/10/8 上午11:35
 * @UpdateUser: linjinyu
 * @UpdateDate: 2021/10/8 上午11:35
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class ReceiveFlashDeliverRefundOrderServiceImpl implements ReceiveFlashDeliverRefundOrderService {

	@Autowired
	private UnifiedOrderMapper                    unifiedOrderMapper;
	@Autowired
	private UnifiedOrderMapperEx                  unifiedOrderMapperEx;
	@Autowired
	private UnifiedOrderMapperExCustomerDimCredit unifiedOrderMapperExScore;
	@Autowired
	private UnifiedOrderGoodsMapper               unifiedOrderGoodsMapper;
	@Autowired
	private UnifiedOrderGoodsMapperEx             unifiedOrderGoodsMapperEx;
	@Autowired
	private UnifiedOrderCreditMapper              unifiedOrderCreditMapper;

	/****************************************** 退单部分 ******************************************/
	@Autowired
	private UnifiedOrderReturnMapper             unifiedOrderReturnMapper;
	@Autowired
	private UnifiedOrderReturnMapperEx           unifiedOrderReturnMapperEx;
	@Autowired
	private UnifiedOrderReturnGoodsMapper        unifiedOrderReturnGoodsMapper;
	@Autowired
	private UnifiedOrderReturnGoodsMapperEx      unifiedOrderReturnGoodsMapperEx;
	@Autowired
	private UnifiedOrderReturnCreditMapper       unifiedOrderReturnCreditMapper;
	/****************************************** 退单部分 ******************************************/

	@Autowired
	private CommonOrderProcessService            commonOrderProcessService;
	@Autowired
	private CommonMergeOrderGoodsProcessService  commonMergeOrderGoodsProcessService;
	@Autowired
	private CommonMergeOrderCreditProcessService commonMergeOrderCreditProcessService;

	@Autowired
	private CommonMergeRefundOrderProcessService       commonMergeOrderProcessService;
	@Autowired
	private CommonMergeRefundOrderCreditProcessService commonMergeRefundOrderCreditProcessService;

	@Autowired
	private CommonOrderTransportProcessService commonOrderTransportProcessService;

	@Autowired
	private UnifiedServiceService unifiedServiceService;

	@Override
	@Transactional
	public UnifiedOrderIssuesFlowingParam kafkaFlashdeliverOrderRefundReceive(FlashDeliverRefundOrderReceiveParam receiveParam) {


		UnifiedOrderIssuesFlowingParam callback = new UnifiedOrderIssuesFlowingParam();
		callback.setUid(receiveParam.getUid());
		callback.setProcessResult(CommonProcessResultEnum.正常.getKey());
		callback.setProcessReport("");

		UnifiedServicePartGoodsTransportParam defaultGoodsTransport = unifiedServiceService.getUnifiedServicePartGoodsTransport("LNSS");

		try {

			// 如查不按 文档 的结构 让它报错吧
			log.info(AnJsonUtils.toJson(receiveParam));

			// 判定 order 为空
			if (null == receiveParam.getOrder()) {
				// TODO 记录 Error
				callback.setProcessResult(CommonProcessResultEnum.异常_数据本身缺失.getKey());
				callback.setProcessReport("退单订单信息为空");
				return callback;
			}
			// 判定 goods 为空
			if (CollUtil.isEmpty(receiveParam.getGoodsList())) {
				// TODO 记录 Error
				callback.setProcessResult(CommonProcessResultEnum.异常_数据本身缺失.getKey());
				callback.setProcessReport("退单商品为空");
				return callback;
			}

			// 判定
			if (null == receiveParam.getOrder().getCompletState()) {
				callback.setProcessResult(CommonProcessResultEnum.异常_数据本身缺失.getKey());
				callback.setProcessReport("退单归类后的状态不能为空 订单完成状态 必须 业务方归类订单状态推送完成状态:1-已完成;2-未完成;3-已取消/已作废");
				return callback;
			}


			// 处理 退单 主体 转换 持久化 | 执行完后,这个退单是已经持久化了 是只 退单号来判定唯一的
			UnifiedOrderReturn unifiedOrderReturn = convertAndStoreRefundOrderReceiveParam2Entity(receiveParam);
			// 处理 退单 商品 转换 持久化
			List<UnifiedOrderReturnGoods> unifiedOrderReturnGoods = convertAndStoreRefundGoodsReceiveParam2Entity(receiveParam);
//			// 处理 退单 流水 转换
//			List<UnifiedOrderReturnCredit> unifiedOrderReturnCredits = convertRefundOrderIntegralCreditReceiveParam(receiveParam);
//			// 处理 退单 流水 持久化 这个地方 侨城汇逻辑
//			List<UnifiedOrderReturnCredit> finalRefundOrderCreditList = commonMergeRefundOrderCreditProcessService.processRefundUnifiedOrderCreditBykafkaPushOrderReceive(
//					unifiedOrderReturn,
//					unifiedOrderReturnGoods,
//					unifiedOrderReturnCredits
//			);
			List<UnifiedOrderReturnCredit> unifiedOrderReturnCredits  = new ArrayList<>();
			List<UnifiedOrderReturnCredit> finalRefundOrderCreditList = new ArrayList<>();

			/****************************************** TODO 20210120 处理退单退运费验证 start ******************************************/
			// 侨城汇 退单退运费 在楼闪送逻辑里有问题
			UnifiedOrderGoods refundOrderGoodsRefundTransport = commonOrderTransportProcessService.processRefundTransport(unifiedOrderReturn, finalRefundOrderCreditList);
			/****************************************** TODO 20210120 处理退单退运费验证   end ******************************************/

			// 重新核算 退单 修正 传过来时  amount 为 0 的问题 TODO 好像与退运费没什么关系
			accountingRefundOrderAmount(unifiedOrderReturn, unifiedOrderReturnGoods, unifiedOrderReturnCredits);

			// 反过来再处理 UnifiedOrderCredits 没有持久化 只是转换 TODO 目前这个为 size eq 0 List
			List<UnifiedOrderCredit> hedgeUnifiedOrderCreditList = processRefundOrderCredits(unifiedOrderReturn, finalRefundOrderCreditList);

			// 反过来再处理 UnifiedOrderGoods 没有持久化 只是转换
			List<UnifiedOrderGoods> hedgeUnifiedOrderGoodsList = processRefundOrderGoods(unifiedOrderReturn, unifiedOrderReturnGoods);

			// 处理退运费
			if (null != refundOrderGoodsRefundTransport) {
				hedgeUnifiedOrderGoodsList.add(refundOrderGoodsRefundTransport);
			}

			/****************************************** 分歧点 start ******************************************/
			// 反过来再处理 UnifiedOrder | 重新核算 订单 并 持久化 processScoreOrderRefundUnifiedOrder
//			UnifiedOrder hedgeUnifiedOrder = processRefundOrder(unifiedOrderReturn);
			// TODO 反过来再处理 UnifiedOrder 退单作为主体的新逻辑 | 不核算 订单 通过订单 产生 退单 主体
			UnifiedOrder hedgeUnifiedOrder = commonMergeOrderProcessService.processScoreOrderRefundUnifiedOrder(unifiedOrderReturn);
			/****************************************** 分歧点   end ******************************************/

			// 与现有数据合并 并 持久化 TODO 新主体逻辑 可能要改 先标记
			commonMergeOrderGoodsProcessService.processUnifiedOrderGoodsBykafkaPushOrderReceive(hedgeUnifiedOrder, hedgeUnifiedOrderGoodsList, -1);
			// 与现有数据合并 并 持久化 TODO 新主体逻辑 可能要改 先标记
			commonMergeOrderCreditProcessService.processUnifiedOrderCreditBykafkaPushOrderReceive(hedgeUnifiedOrder, hedgeUnifiedOrderCreditList, -1);


			// TODO 添加锁单逻辑 mark by linjinyu at 20210701
			switch (CommonOrderCompletStateEnum.get(receiveParam.getOrder().getCompletState())) {
				case 未完成:
					commonMergeOrderProcessService.lockByOrderSn(hedgeUnifiedOrder.getOrderSn());
					commonMergeOrderProcessService.lockByOrderSn(hedgeUnifiedOrder.getRefundOrderSn());
					break;
				case 已完成:
					commonMergeOrderProcessService.unlockByOrderSn(hedgeUnifiedOrder.getOrderSn());
					commonMergeOrderProcessService.unlockByOrderSn(hedgeUnifiedOrder.getRefundOrderSn());
					break;
				case 已作废:
					commonMergeOrderProcessService.unlockByOrderSn(hedgeUnifiedOrder.getOrderSn());
					commonMergeOrderProcessService.unlockByOrderSn(hedgeUnifiedOrder.getRefundOrderSn());
					break;
				default:
					commonMergeOrderProcessService.unlockByOrderSn(hedgeUnifiedOrder.getOrderSn());
					commonMergeOrderProcessService.unlockByOrderSn(hedgeUnifiedOrder.getRefundOrderSn());
					break;
			}


			// 分润处理 TODO 目前的没验证 先屏蔽 分润处理也不能在这里处理
//			processProfit(unifiedOrderReturn);

		} catch (Exception e) {

			log.error("商城 同步 统一订单 (侨城汇-积分订单)-kafkaScoreOrderRefundReceive 失败:{}", ExceptionUtils.getMessage(e));
			e.printStackTrace();

			callback.setProcessResult(CommonProcessResultEnum.异常_数据本身缺失.getKey());

		} finally {
			return callback;
		}


	}

	/**
	 * 重新 核算 退单 金额
	 * TODO 坑位
	 *
	 * @param unifiedOrderReturn
	 * @param unifiedOrderReturnGoods
	 * @param unifiedOrderReturnCredits
	 */
	private void accountingRefundOrderAmount(
			UnifiedOrderReturn unifiedOrderReturn,
			List<UnifiedOrderReturnGoods> unifiedOrderReturnGoods,
			List<UnifiedOrderReturnCredit> unifiedOrderReturnCredits
	) {

		log.info("accountingUnifiedOrderReturnAmount unifiedOrderReturn \n{}", AnJsonUtils.toPrettyJson(unifiedOrderReturn));
		log.info("accountingUnifiedOrderReturnAmount unifiedOrderReturnGoods \n{}", AnJsonUtils.toPrettyJson(unifiedOrderReturnGoods));
		log.info("accountingUnifiedOrderReturnAmount unifiedOrderReturnCredits \n{}", AnJsonUtils.toPrettyJson(unifiedOrderReturnCredits));

		if (null == unifiedOrderReturn.getAmount()
				|| unifiedOrderReturn.getAmount().compareTo(BigDecimal.ZERO) == 0) {

			log.info("TODO 退单 金额 为 0 先记录 数据错误 ");

			BigDecimal checkUnifiedOrderReturnCreditsAmount = unifiedOrderReturnCredits
					.stream()
					.map(item -> item.getBalance() == null ? BigDecimal.ZERO : item.getBalance())
					.reduce(BigDecimal.ZERO, BigDecimal::add);


			BigDecimal checkUnifiedOrderReturnGoodsPriceQuantity = unifiedOrderReturnGoods.stream()
					.map(item -> item.getPrice() == null ? BigDecimal.ZERO : item.getPrice().multiply(new BigDecimal(item.getQuantity())))
					.reduce(BigDecimal.ZERO, BigDecimal::add);


			if (checkUnifiedOrderReturnGoodsPriceQuantity.compareTo(checkUnifiedOrderReturnCreditsAmount) != 0) {

				log.info("TODO 退单的 商品 与 流水 金额还不对等 ? 楼闪送是没有流水的 这是正常的");

			} else {

				log.info("TODO 退单的 商品 与 流水 金额对等 更新");

				unifiedOrderReturn.setAmount(checkUnifiedOrderReturnCreditsAmount);

				unifiedOrderReturnMapper.updateByPrimaryKeySelective(unifiedOrderReturn);
			}
		}
	}


	/**
	 * 目前 不作总体的完整性问题,作 saveOrUpdate 操作
	 *
	 * @param refundReceiveParam
	 * @return
	 */
	private UnifiedOrderReturn convertAndStoreRefundOrderReceiveParam2Entity(FlashDeliverRefundOrderReceiveParam refundReceiveParam) {

		// 初始化 退单 主体
		UnifiedOrderReturn refundOrderEntity = new UnifiedOrderReturn();

		FlashDeliverRefundOrderOrderReceiveParam refundOrderReceiveParam = refundReceiveParam.getOrder();

		// 找一下这个退单 在当前数据库 有没有 也就是说是不是第一次推过来
		List<UnifiedOrderReturn> existRefundOrderList = unifiedOrderReturnMapperEx.findByRefundOrderSn(refundOrderReceiveParam.getRefundOrderSn());

		if (AnCollectionUtils.isNotEmpty(existRefundOrderList)) {
			refundOrderEntity = existRefundOrderList.get(0);
		}

		refundOrderEntity.setOrderDim(AccountingOrderTypeDimEnum.一般订单.getKey());

		refundOrderEntity.setOrderSn(refundOrderReceiveParam.getOrderSn());
		refundOrderEntity.setReturnSn(refundOrderReceiveParam.getRefundOrderSn());

		refundOrderEntity.setProjectId(refundOrderReceiveParam.getPurchaseOrgId());
		refundOrderEntity.setProjectName(refundOrderReceiveParam.getPurchaseOrgName());

		refundOrderEntity.setPurchaseVirtId(refundOrderReceiveParam.getPurchaseVirtId());
		refundOrderEntity.setPurchaseVirtName(refundOrderReceiveParam.getPurchaseVirtName());

		refundOrderEntity.setPurchaseDepartmentName(refundOrderReceiveParam.getPurchaseDepartmentName());

		refundOrderEntity.setPurchaseUserId(refundOrderReceiveParam.getPurchaseUserId());
		refundOrderEntity.setPurchaseUserName(refundOrderReceiveParam.getPurchaseUserName());
		refundOrderEntity.setPurchasePhone(refundOrderReceiveParam.getPurchasePhone());

		refundOrderEntity.setCreateTime(refundOrderReceiveParam.getCreateTime());
		refundOrderEntity.setPayTime(refundOrderReceiveParam.getPayTime());
		refundOrderEntity.setSendTime(refundOrderReceiveParam.getSendTime());
		refundOrderEntity.setFinishTime(refundOrderReceiveParam.getFinishTime());


		refundOrderEntity.setAmount(refundOrderReceiveParam.getRefundOrderAmount() == null ? BigDecimal.ZERO : refundOrderReceiveParam.getRefundOrderAmount());
		refundOrderEntity.setCostAmount(refundOrderReceiveParam.getRefundCostAmount() == null ? BigDecimal.ZERO : refundOrderReceiveParam.getRefundCostAmount());

		if (refundOrderEntity.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
		}

		// 退运费 mark by linjinyu at 20210120
		refundOrderEntity.setTransportAmount(refundOrderReceiveParam.getDispatchPrice());
		refundOrderEntity.setTransportAmountSource(-1);

		refundOrderEntity.setPayState(refundOrderReceiveParam.getPayState());
		refundOrderEntity.setPayStateName(refundOrderReceiveParam.getPayStateName());

		refundOrderEntity.setPayType(refundOrderReceiveParam.getPayType());
		refundOrderEntity.setPayTypeName(refundOrderReceiveParam.getPayTypeName());

		refundOrderEntity.setOrderState(refundOrderReceiveParam.getOrderState());
		refundOrderEntity.setOrderStateName(refundOrderReceiveParam.getOrderStateName());

		refundOrderEntity.setRemarks(refundOrderReceiveParam.getRemarks());
		refundOrderEntity.setOtherParams(refundOrderReceiveParam.getOtherParams());

		// 这个是要验证的 -- 未审核完成的退单是不会过来
		refundOrderEntity.setCompletState(refundOrderReceiveParam.getCompletState());

		// TODO 这个又是为什么呢? 什么设计思路
		refundOrderEntity.setUserType("kafka");
		refundOrderEntity.setUserName("kafka系统同步");

		if (null != refundOrderEntity.getId()) {

			refundOrderEntity.setUpdateUserId(1L);
			refundOrderEntity.setUpdateTime(DateUtil.date());

			unifiedOrderReturnMapper.updateByPrimaryKeySelective(refundOrderEntity);

		} else {

			refundOrderEntity.setAccountingStateCustomer(CommonAccountingStateEnum.未对账.getKey());
			// TODO 写死 这个是什么逻辑 还要查证一下
			refundOrderEntity.setPayState(refundOrderReceiveParam.getPayState() == null ? 2 : refundOrderReceiveParam.getPayState());

			refundOrderEntity.setCreateUserId(1L);
			refundOrderEntity.setCreateTime(refundOrderReceiveParam.getCreateTime());

			unifiedOrderReturnMapper.insertSelective(refundOrderEntity);
		}

		return refundOrderEntity;

	}

	/**
	 * 目前 不作总体的完整性问题,作 saveOrUpdate 操作
	 *
	 * @param orderRefundReceiveParam
	 * @return
	 */
	private List<UnifiedOrderReturnGoods> convertAndStoreRefundGoodsReceiveParam2Entity(FlashDeliverRefundOrderReceiveParam orderRefundReceiveParam) {


		FlashDeliverRefundOrderOrderReceiveParam       refundOrderReceiveParam          = orderRefundReceiveParam.getOrder();
		List<FlashDeliverRefundOrderGoodsReceiveParam> refundOrderGoodsReceiveParamList = orderRefundReceiveParam.getGoodsList();


		List<UnifiedOrderReturnGoods> existRefundOrderGoodsEntityList   = unifiedOrderReturnGoodsMapperEx.findByRefundOrderSn(refundOrderReceiveParam.getRefundOrderSn());
		List<UnifiedOrderReturnGoods> processRefundOrderGoodsEntityList = new ArrayList<>();


		// TODO 如果 过来的退商品与在库里的对不上呢? 也就是
		// 1. existRefundOrderGoodsEntityList.size >0 的情况 existRefundOrderGoodsEntityList.size ！= refundOrderGoodsReceiveParamList.size
		// 2. 就算1是 相等的 ,基于 refundOrderSn + goodsId 也有可能不等
		// 3. 也有可能是想多了

		refundOrderGoodsReceiveParamList.forEach(refundOrderGoodsReceiveParam -> {


			// 初始化 退单 商品 如果一条都没有记录
			UnifiedOrderReturnGoods refundOrderGoodsEntity = null;

			if (CollUtil.isNotEmpty(existRefundOrderGoodsEntityList)) {

				List<Predicate<UnifiedOrderReturnGoods>> predicatesRefundOrderGoodsByRefundOrderSnGoodsId = new ArrayList<>();
				predicatesRefundOrderGoodsByRefundOrderSnGoodsId.add(
						r -> r.getReturnSn() != null
								&& r.getReturnSn().equals(refundOrderGoodsReceiveParam.getRefundOrderSn())
								&& r.getGoodsId() != null
								&& r.getGoodsId().compareTo(refundOrderGoodsReceiveParam.getGoodsId()) == 0
				);
				List<UnifiedOrderReturnGoods> predicatesRefundOrderGoodsByRefundOrderSnGoodsIdFilter = AnLamdaUtils.filters(existRefundOrderGoodsEntityList, predicatesRefundOrderGoodsByRefundOrderSnGoodsId);

				// 是否有 长度大于1的情况呢
				if (AnCollectionUtils.isNotEmpty(predicatesRefundOrderGoodsByRefundOrderSnGoodsIdFilter)) {
					refundOrderGoodsEntity = predicatesRefundOrderGoodsByRefundOrderSnGoodsIdFilter.get(0);
				} else {
					refundOrderGoodsEntity = new UnifiedOrderReturnGoods();
				}
			} else {
				refundOrderGoodsEntity = new UnifiedOrderReturnGoods();
			}


			refundOrderGoodsEntity.setReturnSn(refundOrderGoodsReceiveParam.getRefundOrderSn());

			refundOrderGoodsEntity.setGoodsId(refundOrderGoodsReceiveParam.getGoodsId());
			refundOrderGoodsEntity.setOutSnapshotOrderGoodsId(refundOrderGoodsReceiveParam.getOutSnapshotOrderGoodsId());

			refundOrderGoodsEntity.setGoodsName(refundOrderGoodsReceiveParam.getGoodsName());
			refundOrderGoodsEntity.setGoodsAlias(refundOrderGoodsReceiveParam.getGoodsAlias());

			// refundOrderGoodsReceiveParam 中还有一个购买时的总数量,目前是没有记录到 refundOrderGoodsEntity,只能查日志看
			refundOrderGoodsEntity.setQuantity(refundOrderGoodsReceiveParam.getQuantityRefund());
			refundOrderGoodsEntity.setCostPrice(refundOrderGoodsReceiveParam.getCostPrice());
			refundOrderGoodsEntity.setPrice(refundOrderGoodsReceiveParam.getSellingPrice());

			/************************************** update by linjinjy 20200904 20200723_林志鹏_税率,退款格式.docx **************************************/

			refundOrderGoodsEntity.setFiscalCode(refundOrderGoodsReceiveParam.getTaxCode());
			refundOrderGoodsEntity.setTaxCode(refundOrderGoodsReceiveParam.getTaxCode());
			refundOrderGoodsEntity.setTaxRate(refundOrderGoodsReceiveParam.getTaxRateVirt());
			// 商户税率

			refundOrderGoodsEntity.setMerchTaxId(0L);
			refundOrderGoodsEntity.setMerchTaxCode(refundOrderGoodsReceiveParam.getTaxCode());
			refundOrderGoodsEntity.setMerchTaxRate(refundOrderGoodsReceiveParam.getTaxRateSale());

			// 平台税率
			refundOrderGoodsEntity.setOperationTaxId(0L);
			refundOrderGoodsEntity.setOperationTaxCode(refundOrderGoodsReceiveParam.getTaxCode());
			refundOrderGoodsEntity.setOperationTaxRate(refundOrderGoodsReceiveParam.getTaxRateVirt());

			/************************************** update by linjinjy 20200904 20200723_林志鹏_税率,退款格式.docx **************************************/

			/****************************************** 三级分类 20200904 by linjinyu 20200904_林志鹏_三极分类 ******************************************/
			refundOrderGoodsEntity.setCateIdLv1(refundOrderGoodsReceiveParam.getCateIdLv1());
			refundOrderGoodsEntity.setCateIdLv2(refundOrderGoodsReceiveParam.getCateIdLv2());
			refundOrderGoodsEntity.setCateIdLv3(refundOrderGoodsReceiveParam.getCateIdLv3());
			refundOrderGoodsEntity.setCateNameLv1(refundOrderGoodsReceiveParam.getCateNameLv1());
			refundOrderGoodsEntity.setCateNameLv2(refundOrderGoodsReceiveParam.getCateNameLv2());
			refundOrderGoodsEntity.setCateNameLv3(refundOrderGoodsReceiveParam.getCateNameLv3());
			/****************************************** 三级分类 20200904 by linjinyu 20200904_林志鹏_三极分类 ******************************************/

			// 保存数据 维权订单 货品
			if (null != refundOrderGoodsEntity.getId()) {

				refundOrderGoodsEntity.setUpdateUserId(2L);
				refundOrderGoodsEntity.setUpdateTime(DateUtil.date());

				unifiedOrderReturnGoodsMapper.updateByPrimaryKeySelective(refundOrderGoodsEntity);
			} else {

				refundOrderGoodsEntity.setCreateUserId(1L);
				refundOrderGoodsEntity.setCreateTime(DateUtil.date());

				unifiedOrderReturnGoodsMapper.insertSelective(refundOrderGoodsEntity);
			}

			processRefundOrderGoodsEntityList.add(refundOrderGoodsEntity);
		});

		return processRefundOrderGoodsEntityList;


	}

	/**
	 * 目前 不作总体的完整性问题,只作 insert 操作
	 * 重构 只作转换
	 *
	 * @param orderRefundReceiveParam
	 * @return
	 */
	@Deprecated
	private List<UnifiedOrderReturnCredit> convertRefundOrderIntegralCreditReceiveParam(FlashDeliverRefundOrderReceiveParam orderRefundReceiveParam) {

		// 初始化 退单 商品 流水 如果一条都没有记录
		List<UnifiedOrderReturnCredit> unifiedOrderReturnCredits = new ArrayList<>();

//		// 过来的 流水数据
//		List<FlashdeliverOrderRefundOrderIntegralCreditReceiveParam> params = orderRefundReceiveParam.getOrder().getIntegralCredit();
//
//		if (AnCollectionUtils.isEmpty(params)) {
//			// TODO throw error
//		}
//
//		// 商城过来的数据 TODO 新添加逻辑 退单成为新主体 且 未完成时 是没有流水数据的
//		if (AnCollectionUtils.isNotEmpty(params)) {
//
//			for (FlashdeliverOrderRefundOrderIntegralCreditReceiveParam param : params) {
//
//
//				// C位
//				if (param.getCreditType().equals(0) && param.getCreditName() == null) {
//					param.setCreditName("微信支付");
//				}
//
//				UnifiedOrderReturnCredit creditRefund = new UnifiedOrderReturnCredit();
//
//				creditRefund.setOrderSn(orderRefundReceiveParam.getOrder().getOrderSn());
//				creditRefund.setOrderId(param.getOrderId());
//
//				// 添加退单流水快照 ID 20201013 加字段
//				creditRefund.setOutSnapshotOrderCreditId(param.getOrderCreditId());
//
//				// TODO 添加退运费的 特殊逻辑
////			1. 首先, 这个是处理退单的流水
////			2. 已经约定退单退运费的积分流水goods_id为0
////			3. 但是在统一订单的处理中0为正单的运费
//				creditRefund.setGoodsId(param.getGoodsId().compareTo(0L) == 0 ? -1L : param.getGoodsId());
//				creditRefund.setCreditType(param.getCreditType());
//				creditRefund.setCreditName(param.getCreditName());
//
//				creditRefund.setDailyAccountType(param.getDailyAccountType());
//				creditRefund.setBatchs(param.getBatchs());
//				creditRefund.setBalance(param.getBalance());
//				creditRefund.setEnterpriseId(param.getEnterpriseId());
//				creditRefund.setMemberId(param.getMemberId());
//
//				creditRefund.setPayStatus(param.getPayStatus());
//				creditRefund.setPayType(param.getPayType());
//
//				creditRefund.setAccountingStateCustomer(CommonAccountingStateEnum.未对账.getKey());
//				creditRefund.setAccountingStateSupplier(CommonAccountingStateEnum.未对账.getKey());
//
//				creditRefund.setInvoiceApplyStatus(UnifiedOrderCreditInvoiceApplyStatusEnum.未申请.getKey());
//				creditRefund.setInvoiceMakeStatus(UnifiedOrderCreditInvoiceMakeStatusEnum.未登记.getKey());
//				creditRefund.setBackStatus(UnifiedOrderCreditBackAccountStatusEnum.未回款.getKey());
//
//				creditRefund.setCreateTime(DateUtil.date());
//				creditRefund.setCreateUserId(1L);
//
//				creditRefund.setUpdateTime(DateUtil.date());
//				creditRefund.setUpdateUserId(1L);
//
//				unifiedOrderReturnCredits.add(creditRefund);
//
//			}
//		}


		return unifiedOrderReturnCredits;
	}


	/**
	 * 处理 对冲 流水
	 *
	 * @param unifiedOrderReturn
	 * @param unifiedOrderReturnCredits
	 */
	private List<UnifiedOrderCredit> processRefundOrderCredits(UnifiedOrderReturn unifiedOrderReturn, /*信息来源 转换过的*/List<UnifiedOrderReturnCredit> unifiedOrderReturnCredits) {

		List<UnifiedOrderCredit> hedgeUnifiedOrderCreditList = new ArrayList<>();

		log.info("processScoreOrderRefundUnifiedOrderCredits :: unifiedOrderReturn \n{}", AnJsonUtils.toJson(unifiedOrderReturn));
		log.info("processScoreOrderRefundUnifiedOrderCredits :: unifiedOrderReturnCredits \n{}", AnJsonUtils.toJson(unifiedOrderReturnCredits));

		if (AnCollectionUtils.isEmpty(unifiedOrderReturnCredits)) {
			// TODO 如果没有数据,是要报错的

			return hedgeUnifiedOrderCreditList;
		}

//		UnifiedOrderCreditExample          checkExistExample  = new UnifiedOrderCreditExample();
//		UnifiedOrderCreditExample.Criteria checkExistCriteria = checkExistExample.createCriteria();

		for (UnifiedOrderReturnCredit unifiedOrderReturnCredit : unifiedOrderReturnCredits) {

//			checkExistCriteria.andOrderIdEqualTo(unifiedOrderReturnCredit.getOrderId())
//					.andOrderSnEqualTo(unifiedOrderReturn.getOrderSn())// 对
//					.andGoodsIdEqualTo(unifiedOrderReturnCredit.getGoodsId())// 对
//					.andEnterpriseIdEqualTo(unifiedOrderReturnCredit.getEnterpriseId())// 对
//					.andMemberIdEqualTo(unifiedOrderReturnCredit.getMemberId())// 对
////					.andCreditNameEqualTo(unifiedOrderReturnCredit.getCreditName())// 错 原来 退单 流水 积分名称 为 "" 先屏蔽
//					.andCreditTypeEqualTo(unifiedOrderReturnCredit.getCreditType())// 对
//					.andBatchsEqualTo(unifiedOrderReturnCredit.getBatchs())// 对
//					.andDirectionEqualTo(-1)// 对
//					.andBalanceEqualTo(unifiedOrderReturnCredit.getBalance().multiply(new BigDecimal(-1)));
//			List<UnifiedOrderCredit> checkExistRecord = unifiedOrderCreditMapper.selectByExample(checkExistExample);

//			if (AnCollectionUtils.isEmpty(checkExistRecord)) {

			UnifiedOrderCredit unifiedOrderCredit = new UnifiedOrderCredit();

//			unifiedOrderCredit.setOrderSn(unifiedOrderReturn.getOrderSn());
			unifiedOrderCredit.setOrderSn(unifiedOrderReturn.getReturnSn());

			unifiedOrderCredit.setDirection(CommonDirectionEnum.负向.getKey());


			unifiedOrderCredit.setOrderId(unifiedOrderReturnCredit.getOrderId());
			unifiedOrderCredit.setGoodsId(unifiedOrderReturnCredit.getGoodsId());

			unifiedOrderCredit.setOutSnapshotOrderCreditId(unifiedOrderReturnCredit.getOutSnapshotOrderCreditId());

			unifiedOrderCredit.setCreditType(unifiedOrderReturnCredit.getCreditType());
			unifiedOrderCredit.setCreditName(unifiedOrderReturnCredit.getCreditName());
			unifiedOrderCredit.setDailyAccountType(unifiedOrderReturnCredit.getDailyAccountType());

			unifiedOrderCredit.setBatchs(unifiedOrderReturnCredit.getBatchs());
			unifiedOrderCredit.setBalance(unifiedOrderReturnCredit.getBalance().multiply(new BigDecimal(-1)));

			unifiedOrderCredit.setEnterpriseId(unifiedOrderReturnCredit.getEnterpriseId());
			unifiedOrderCredit.setMemberId(unifiedOrderReturnCredit.getMemberId());
			unifiedOrderCredit.setPayStatus(unifiedOrderReturnCredit.getPayStatus());
			unifiedOrderCredit.setPayType(unifiedOrderReturnCredit.getPayType());

			unifiedOrderCredit.setCreditLockingCustomer(CommonAccountingLockingEnum.正常.getKey());
			unifiedOrderCredit.setCreditLockingSupplier(CommonAccountingLockingEnum.正常.getKey());

			unifiedOrderCredit.setAccountingStateCustomer(CommonAccountingStateEnum.未对账.getKey());
			unifiedOrderCredit.setAccountingStateSupplier(CommonAccountingStateEnum.未对账.getKey());

			unifiedOrderCredit.setInvoiceApplyStatus(UnifiedOrderCreditInvoiceApplyStatusEnum.待申请.getKey());
			unifiedOrderCredit.setInvoiceMakeStatus(UnifiedOrderCreditInvoiceMakeStatusEnum.待开票.getKey());
			unifiedOrderCredit.setBackStatus(UnifiedOrderCreditBackAccountStatusEnum.未回款.getKey());

			unifiedOrderCredit.setCreateTime(DateUtil.date());
			unifiedOrderCredit.setCreateUserId(1L);

			unifiedOrderCredit.setUpdateTime(DateUtil.date());
			unifiedOrderCredit.setUpdateUserId(1L);

			hedgeUnifiedOrderCreditList.add(unifiedOrderCredit);

//				unifiedOrderCreditMapper.insert(unifiedOrderCredit);


//			}

		}

		return hedgeUnifiedOrderCreditList;

	}

	/**
	 * 处理 商品 只是做转换
	 * 反过来再处理 UnifiedOrderGoods 没有持久化 只是转换
	 *
	 * @param unifiedOrderReturn
	 * @param unifiedOrderReturnGoodsList
	 * @return
	 */
	private List<UnifiedOrderGoods> processRefundOrderGoods(UnifiedOrderReturn unifiedOrderReturn, List<UnifiedOrderReturnGoods> unifiedOrderReturnGoodsList) {

		List<UnifiedOrderGoods> hedgeUnifiedOrderGoodsList = new ArrayList<>();

		log.info("processScoreOrderRefundUnifiedOrderGoods :: unifiedOrderReturn \n{}", AnJsonUtils.toJson(unifiedOrderReturn));
		log.info("processScoreOrderRefundUnifiedOrderGoods :: unifiedOrderReturnGoodsList \n{}", AnJsonUtils.toJson(unifiedOrderReturnGoodsList));

//		// TODO 查一下这个对冲商品有没有 20201017 12:00 发现有个问题,如果同一个单 多个商品退单好像有问题 排查
//		UnifiedOrderGoodsExample example = new UnifiedOrderGoodsExample();
//		example.createCriteria()
//				.andOrderSnEqualTo(unifiedOrderReturn.getOrderSn())
////				.andGoodsIdEqualTo(unifiedOrderReturnGoods.getGoodsId())// 目前 数据库有可能是没记录的 // TODO 什么时候 修下这个问题, 再回头修改这里
////                .andPriceEqualTo(unifiedOrderReturnGoods.getPrice()) // TODO 按道理 这个金额是不会变的,存于商城快照
////                .andCostPriceEqualTo(unifiedOrderReturnGoods.getCostPrice()) // TODO 按道理 这个金额是不会变的,存于商城快照
////                .andGoodsNameEqualTo(unifiedOrderReturnGoods.getGoodsName()) // TODO 按道理 这个金额是不会变的,存于商城快照
//				.andQuantityLessThan(0) // TODO 这里存在个疑点 是不是这个退单的商品数量都修正为 正的 , 通过乘法 Direction 来实现对冲呢?
//				.andDirectionEqualTo(-1);
//		List<UnifiedOrderGoods> existUnifiedOrderGoodsList = unifiedOrderGoodsMapper.selectByExample(example);


		unifiedOrderReturnGoodsList.forEach(unifiedOrderReturnGoods -> {
			UnifiedOrderGoods unifiedOrderGoods = new UnifiedOrderGoods();

			// TODO 分歧点
//		unifiedOrderGoods.setOrderSn(unifiedOrderReturn.getOrderSn());
			unifiedOrderGoods.setOrderSn(unifiedOrderReturn.getReturnSn());

			unifiedOrderGoods.setGoodsType(CommonOrderGoodsTypeEnum.商品.getKey());
			unifiedOrderGoods.setDirection(CommonDirectionEnum.负向.getKey());

			unifiedOrderGoods.setGoodsLockingCustomer(CommonAccountingLockingEnum.正常.getKey());
			unifiedOrderGoods.setGoodsLockingSupplier(CommonAccountingLockingEnum.正常.getKey());

			unifiedOrderGoods.setAccountingStateCustomer(CommonAccountingStateEnum.未对账.getKey());
			unifiedOrderGoods.setAccountingStateSupplier(CommonAccountingStateEnum.未对账.getKey());


			BigDecimal unitPrice = new BigDecimal(unifiedOrderReturnGoods.getPrice().doubleValue());


			unifiedOrderGoods.setGoodsName(unifiedOrderReturnGoods.getGoodsName());
			// 目前这个退单的商品没这个字段
//        unifiedOrderGoods.setOutSnapshotOrderGoodsId(unifiedOrderReturnGoods.getOutSnapshotOrderGoodsId());
			unifiedOrderGoods.setGoodsId(unifiedOrderReturnGoods.getGoodsId());

			// 对充一下负数的数量
			unifiedOrderGoods.setQuantity(0 - unifiedOrderReturnGoods.getQuantity());

			unifiedOrderGoods.setCostPrice(unifiedOrderReturnGoods.getCostPrice());
			unifiedOrderGoods.setPrice(unifiedOrderReturnGoods.getPrice());

			/****************************************** 退单退商品 添加 税率 mark by linjinyu at 20210323 start ******************************************/

			unifiedOrderGoods.setFiscalCode(unifiedOrderReturnGoods.getFiscalCode());
			unifiedOrderGoods.setTaxCode(unifiedOrderReturnGoods.getTaxCode());
			unifiedOrderGoods.setTaxRate(unifiedOrderReturnGoods.getTaxRate());

			// 商户税率
			unifiedOrderGoods.setMerchTaxId(unifiedOrderReturnGoods.getMerchTaxId());
			unifiedOrderGoods.setMerchTaxCode(unifiedOrderReturnGoods.getMerchTaxCode());
			unifiedOrderGoods.setMerchTaxRate(unifiedOrderReturnGoods.getMerchTaxRate());

			// 平台税率
			unifiedOrderGoods.setOperationTaxId(unifiedOrderReturnGoods.getOperationTaxId());
			unifiedOrderGoods.setOperationTaxCode(unifiedOrderReturnGoods.getOperationTaxCode());
			unifiedOrderGoods.setOperationTaxRate(unifiedOrderReturnGoods.getOperationTaxRate());

			/****************************************** 退单退商品 添加 税率 mark by linjinyu at 20210323   end ******************************************/

//		unifiedOrderGoods.setGoodsParams();

			unifiedOrderGoods.setCreateTime(DateUtil.date());
			unifiedOrderGoods.setCreateUserId(1L);

			unifiedOrderGoods.setUpdateTime(DateUtil.date());
			unifiedOrderGoods.setUpdateUserId(1L);


			hedgeUnifiedOrderGoodsList.add(unifiedOrderGoods);
		});


		return hedgeUnifiedOrderGoodsList;
	}

	/**
	 * 此为订单与退单共用时的情况 mark by linjinyu at 20210628
	 * <p>
	 * 传入退单 -> 重新核算订单
	 * 再重构吧 最终只要传入 orderSn 就好了
	 *
	 * @param unifiedOrderReturn
	 */
	@Deprecated
	private UnifiedOrder processRefundOrder(UnifiedOrderReturn unifiedOrderReturn) {

		log.info("processRefundOrder :: unifiedOrderReturn \n{}", AnJsonUtils.toJson(unifiedOrderReturn));

		UnifiedOrder checkGomputationUnifiedOrder = unifiedOrderMapperEx.findByOrderSn(unifiedOrderReturn.getOrderSn());
		if (null == checkGomputationUnifiedOrder) {
			// TODO 记录错误
			return null;
		}

		UnifiedOrderGoodsExample unifiedOrderGoodsExample = new UnifiedOrderGoodsExample();
		unifiedOrderGoodsExample.createCriteria()
				.andOrderSnEqualTo(unifiedOrderReturn.getOrderSn())
				// 排除退货
				.andDirectionEqualTo(1)
				// 排除运费
				.andGoodsIdNotEqualTo(0L);
//		unifiedOrderGoodsMapperEx.findByOrderSn(unifiedOrderReturn.getOrderSn());
		List<UnifiedOrderGoods> checkGomputationUnifiedOrderGoods = unifiedOrderGoodsMapper.selectByExample(unifiedOrderGoodsExample);
		if (AnCollectionUtils.isEmpty(checkGomputationUnifiedOrderGoods)) {
			// TODO 记录错误
			return null;
		}

		BigDecimal checkGomputationAmount     = BigDecimal.ZERO;
		BigDecimal checkGomputationCostAmount = BigDecimal.ZERO;

		checkGomputationAmount = checkGomputationUnifiedOrderGoods
				.stream()
				.map(item -> item.getPrice() == null ? BigDecimal.ZERO : item.getPrice().multiply(new BigDecimal(item.getQuantity())))
				.reduce(BigDecimal.ZERO, BigDecimal::add);
		checkGomputationCostAmount = checkGomputationUnifiedOrderGoods
				.stream()
				.map(item -> item.getCostPrice() == null ? BigDecimal.ZERO : item.getCostPrice().multiply(new BigDecimal(item.getQuantity())))
				.reduce(BigDecimal.ZERO, BigDecimal::add);

		checkGomputationUnifiedOrder.setAmount(checkGomputationAmount);
		checkGomputationUnifiedOrder.setCostAmount(checkGomputationCostAmount);

		commonOrderProcessService.attachUpdate(checkGomputationUnifiedOrder);

		return checkGomputationUnifiedOrder;

	}
}
