package com.hzs.sale.deliver.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.hzs.common.core.constant.MemberFieldConstants;
import com.hzs.common.core.constant.SystemFieldConstants;
import com.hzs.common.core.constant.msg.CommonMsgConstants;
import com.hzs.common.core.constant.msg.ConfigMsgConstants;
import com.hzs.common.core.constant.msg.DocumentMsgConstants;
import com.hzs.common.core.constant.msg.SaOrderMsgConstants;
import com.hzs.common.core.domain.R;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.exception.ServiceException;
import com.hzs.common.core.utils.CommonUtil;
import com.hzs.common.core.utils.reflect.ReflectUtils;
import com.hzs.common.domain.member.account.CuMemberAccount;
import com.hzs.common.domain.member.ext.CuMemberAccountExt;
import com.hzs.common.domain.sale.deliver.SaDeliver;
import com.hzs.common.domain.sale.deliver.SaDeliverBarCode;
import com.hzs.common.domain.sale.deliver.SaDeliverItems;
import com.hzs.common.domain.sale.ext.SaOrderExt;
import com.hzs.common.domain.sale.ext.SaOrderItemsExt;
import com.hzs.common.domain.sale.order.SaOrder;
import com.hzs.common.domain.sale.order.SaOrderBonus;
import com.hzs.common.domain.sale.order.SaOrderChargeLog;
import com.hzs.common.domain.sale.order.SaOrderItems;
import com.hzs.common.domain.system.base.BdStorehouse;
import com.hzs.common.domain.system.config.BdAccount;
import com.hzs.common.core.utils.TransactionUtils;
import com.hzs.member.account.IMemberAccountServiceApi;
import com.hzs.sale.deliver.dto.OrderSelfBarCodeDTO;
import com.hzs.sale.deliver.dto.OrderSelfDTO;
import com.hzs.sale.deliver.param.DeliverSecondDataParam;
import com.hzs.sale.deliver.param.DeliverSecondSubmitParam;
import com.hzs.sale.deliver.param.SelfDeliverBarCodeParam;
import com.hzs.sale.deliver.param.SelfDeliverParam;
import com.hzs.sale.deliver.service.ISaDeliverBarCodeService;
import com.hzs.sale.deliver.service.ISaDeliverBusinessService;
import com.hzs.sale.deliver.service.ISaDeliverItemsService;
import com.hzs.sale.deliver.service.ISaDeliverService;
import com.hzs.sale.order.dto.OrderUseBarCodeDTO;
import com.hzs.sale.order.param.SelfPickUpParam;
import com.hzs.sale.order.service.*;
import com.hzs.sale.pub.dto.SecondAccountDTO;
import com.hzs.sale.pub.dto.SecondDTO;
import com.hzs.sale.pub.dto.SecondProductDTO;
import com.hzs.system.base.IBarCodeServiceApi;
import com.hzs.system.base.ICurrencyServiceApi;
import com.hzs.system.base.dto.BarCodeUseDTO;
import com.hzs.system.base.dto.CurrencyDTO;
import com.hzs.system.config.IAccountServiceApi;
import com.hzs.system.sys.IApprovalServiceApi;
import com.hzs.system.sys.dto.ApprovalBusinessResultDTO;
import com.hzs.system.sys.dto.ApprovalSubmitDTO;
import com.hzs.system.sys.dto.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 发货单业务服务
 */
@Slf4j
@Service
public class SaDeliverBusinessServiceImpl implements ISaDeliverBusinessService {

    @Autowired
    private ISaOrderService iSaOrderService;
    @Autowired
    private ISaOrderItemsService iSaOrderItemsService;
    @Autowired
    private ISaOrderBonusService iSaOrderBonusService;
    @Autowired
    private ISaOrderChargeLogService iSaOrderChargeLogService;
    @Autowired
    private IOrderBusinessService iOrderBusinessService;
    @Autowired
    private ISaDeliverService iSaDeliverService;
    @Autowired
    private ISaDeliverItemsService iSaDeliverItemsService;
    @Autowired
    private ISaDeliverBarCodeService iSaDeliverBarCodeService;
    @Autowired
    private ISaOrderSelfLogService saOrderSelfLogService;

    @DubboReference
    IApprovalServiceApi iApprovalServiceApi;
    @DubboReference
    IBarCodeServiceApi iBarCodeServiceApi;
    @DubboReference
    IMemberAccountServiceApi iMemberAccountServiceApi;
    @DubboReference
    ICurrencyServiceApi iCurrencyServiceApi;
    @DubboReference
    IAccountServiceApi iAccountServiceApi;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public String selfDeliverSubmit(SelfDeliverParam param, List<SaOrderItemsExt> orderItemsList,
                                    List<SelfDeliverBarCodeParam> barCodeParamList, LoginUser loginUser) {
        // 当前时间
        Date nowDate = new Date();
        // 用户ID
        Long userId = loginUser.getUserId();
        // 所属国家
        Integer pkCountry = loginUser.getDataCountry();

        // 订单修改记录列表
        List<SaOrderChargeLog> saOrderChargeLogList = new ArrayList<>();
        // 涉及会员ID列表
        Set<Long> pkMemberList = new HashSet<>();

        // 本批订单修改记录编号
        String businessCode = CommonUtil.createSerialNumber(EOrderPrefix.ORDER_CODE);

        // 订单ID列表
        List<Long> orderIdList = orderItemsList.stream().map(SaOrderItemsExt::getPkOrder).distinct().collect(Collectors.toList());
        // 订单 + 明细列表
        List<SaOrderExt> saOrderExtList = iSaOrderService.queryOrderListByIdList(orderIdList, pkCountry);

        for (SaOrderExt saOrderExt : saOrderExtList) {
            // 记录涉及会员ID
            pkMemberList.add(saOrderExt.getPkCreator());

            // 订单明细ID列表
            List<Long> itemIdList = saOrderExt.getOrderItemsExtList().stream().map(SaOrderItemsExt::getPkId).collect(Collectors.toList());
            // 追溯码列表
            List<OrderSelfBarCodeDTO> barCodeList = new ArrayList<>();
            if (CollectionUtil.isNotEmpty(barCodeParamList)) {
                for (SelfDeliverBarCodeParam barCodeParam : barCodeParamList) {
                    if (itemIdList.contains(barCodeParam.getItemId())) {
                        barCodeList.add(BeanUtil.copyProperties(barCodeParam, OrderSelfBarCodeDTO.class));
                    }
                }
            }

            // 保存订单修改记录
            SaOrderChargeLog saOrderChargeLog = new SaOrderChargeLog();
            saOrderChargeLog.setPkOrder(saOrderExt.getPkId());
            saOrderChargeLog.setChargeType(EApprovalBusiness.SELF_DELIVERY_MANAGE.getValue());
            saOrderChargeLog.setBeforeData("");
            saOrderChargeLog.setAfterData(JSONUtil.toJsonStr(OrderSelfDTO.builder()
                    .postage(param.getPostage())
                    .pkStorehouse(param.getPkStorehouse())
                    .itemIdList(itemIdList)
                    .barCodeList(barCodeList)
                    .build()));
            saOrderChargeLog.setCreationTime(nowDate);
            saOrderChargeLog.setPkCreator(userId);
            saOrderChargeLog.setModifiedTime(saOrderChargeLog.getCreationTime());
            saOrderChargeLog.setPkModified(saOrderChargeLog.getPkCreator());
            saOrderChargeLog.setPkCountry(pkCountry);
            saOrderChargeLog.setApprovalStatus(EAgentApprovalStatus.UNAPPROVED.getValue());
            saOrderChargeLog.setBusinessCode(businessCode);
            saOrderChargeLogList.add(saOrderChargeLog);
        }

        // 条码列表
        List<BarCodeUseDTO> barCodeUseList = new ArrayList<>();
        for (SelfDeliverBarCodeParam bindCodeParam : barCodeParamList) {
            barCodeUseList.add(BarCodeUseDTO.builder()
                    .barCodeItemsId(bindCodeParam.getBarCodeId())
                    .build());
        }

        if (iSaOrderChargeLogService.saveBatch(saOrderChargeLogList)) {
            // 订单修改记录添加成功，提交签呈

            // 提交签呈处理
            R<String> resultR = iApprovalServiceApi.submitOrder(
                    ApprovalSubmitDTO.builder()
                            .eApprovalBusiness(EApprovalBusiness.SELF_DELIVERY_MANAGE)
                            .businessCode(businessCode)
                            .signType(ESignType.getEnumByValue(param.getSignType()))
                            .userIdList(param.getUserIdList())
                            .sendIdList(param.getSendIdList())
                            .remark(param.getRemark())
                            .fileList(param.getFileList())
                            .pkMemberList(pkMemberList)
                            .build(),
                    loginUser,
                    OrderUseBarCodeDTO.builder()
                            .barCodeUseList(barCodeUseList)
                            .pkCountry(pkCountry)
                            .userId(userId)
                            .build()
            );
            if (resultR.isSuccess()) {
                // 成功后判断id是否存在，存在的话说明是前台的自提清单，需要回写日志表
                if (param.getPkId() != null) {
                    SelfPickUpParam selfPickUpParam = SelfPickUpParam.builder().build();
                    selfPickUpParam.setPkCreator(userId);
                    selfPickUpParam.setApproveStatus(EApproveRechargeStatus.AGREE.getValue());
                    saOrderSelfLogService.updateSaOrderSelfLog(selfPickUpParam, param.getPkId());
                }
                return null;
            }
            throw new ServiceException(TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED) + "：" + resultR.getMsg());
        }
        return TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public String selfDeliverApprovalAgree(ApprovalBusinessResultDTO approvalBusinessResultDTO) {
        // 用户ID
        Long userId = approvalBusinessResultDTO.getLoginUser().getUserId();
        // 所属国家
        Integer pkCountry = approvalBusinessResultDTO.getLoginUser().getDataCountry();
        // 当前时间
        Date nowDate = new Date();

        // 查询订单修改记录
        List<SaOrderChargeLog> saOrderChargeLogList = iOrderBusinessService.getSaOrderChargeLogs(approvalBusinessResultDTO, EApprovalBusiness.SELF_DELIVERY_MANAGE);
        if (CollectionUtil.isEmpty(saOrderChargeLogList)) {
            log.error("订单自提同意处理失败: 签呈不存在!");
            return TransactionUtils.getContent(DocumentMsgConstants.SIGN_NOT_EXIST);
        }
        if (EAgentApprovalStatus.UNAPPROVED.getValue() != saOrderChargeLogList.get(0).getApprovalStatus()) {
            log.error("订单自提同意处理失败: 签呈已处理");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_HAS_HANDLE);
        }

        // 订单ID列表
        List<Long> orderIdList = new ArrayList<>();
        // 追溯码列表
        List<OrderSelfBarCodeDTO> barCodeList = new ArrayList<>();
        // 返还邮费
        BigDecimal postage = null;
        Integer pkStorehouse = null;

        for (SaOrderChargeLog saOrderChargeLog : saOrderChargeLogList) {
            OrderSelfDTO orderSelfDTO = JSONUtil.toBean(saOrderChargeLog.getAfterData(), OrderSelfDTO.class);
            // 订单ID列表
            orderIdList.add(saOrderChargeLog.getPkOrder());
            // 追溯码列表
            barCodeList.addAll(orderSelfDTO.getBarCodeList());

            // 邮费按整次退，每个订单的数据里面都是相同的，此处可以随便取一条使用
            postage = orderSelfDTO.getPostage();
            pkStorehouse = orderSelfDTO.getPkStorehouse();
        }

        // 订单列表
        List<SaOrderExt> orderList = iSaOrderService.queryOrderListByIdList(orderIdList, pkCountry);

        // 自提时，发货单地址等信息取第一条信息
        SaOrderExt saOrder = orderList.get(0);
        // 发货单
        SaDeliver saDeliver = new SaDeliver();
        saDeliver.setDeliverCode(CommonUtil.createSerialNumber(EOrderPrefix.DELIVERY_CODE));
        saDeliver.setRecName(saOrder.getRecName());
        saDeliver.setRecPhone(saOrder.getRecPhone());
        saDeliver.setRecProvince(saOrder.getRecProvince());
        saDeliver.setRecCity(saOrder.getRecCity());
        saDeliver.setRecCounty(saOrder.getRecCounty());
        saDeliver.setRecAddress(saOrder.getRecAddress());
        saDeliver.setDeliverStatus(EDeliveryStatus.RECEIVING.getValue());
        saDeliver.setDeliverTime(nowDate);
        saDeliver.setTranType(saDeliver.getTranType());
        saDeliver.setPkCreator(userId);
        saDeliver.setCreationTime(nowDate);
        saDeliver.setPkCountry(pkCountry);

        if (iOrderBusinessService.updateSaOrderChargeLog(EApprovalBusiness.SELF_DELIVERY_MANAGE, approvalBusinessResultDTO.getBusinessCode(), pkCountry, userId, EAgentApprovalStatus.APPROVED, approvalBusinessResultDTO.getApproveRemark())) {
            // 更新订单修改记录

            // 更新订单为 店铺自提
            UpdateWrapper<SaOrder> updateOrder = new UpdateWrapper<>();
            updateOrder.set("DELIVERY_WAY", EDelivery.COMPANY_PICKED_UP.getValue());
            // 更新仓库
            if (pkStorehouse != null) {
                updateOrder.set("PK_STOREHOUSE", pkStorehouse);
            }
            updateOrder.set(SystemFieldConstants.PK_MODIFIED, userId);
            updateOrder.set(SystemFieldConstants.MODIFIED_TIME, nowDate);
            updateOrder.in(SystemFieldConstants.PK_ID, orderIdList);
            updateOrder.eq(SystemFieldConstants.DEL_FLAG, EDelFlag.UN_DELETE.getValue());
            iSaOrderService.update(updateOrder);

            // 更新订单明细状态为 已收货
            UpdateWrapper<SaOrderItems> updateOrderItem = new UpdateWrapper<>();
            updateOrderItem.set("ORDER_STATUS", EOrderStatus.RECEIVED.getValue());
            updateOrderItem.set(SystemFieldConstants.PK_MODIFIED, userId);
            updateOrderItem.set(SystemFieldConstants.MODIFIED_TIME, nowDate);
            updateOrderItem.in("PK_ORDER", orderIdList);
            updateOrderItem.eq(SystemFieldConstants.DEL_FLAG, EDelFlag.UN_DELETE.getValue());
            iSaOrderItemsService.update(updateOrderItem);

            // 添加发货单
            iSaDeliverService.save(saDeliver);

            // 发货单明细map（key：订单明细ID，value：发货单明细）
            Map<Long, SaDeliverItems> deliverItemsMap = new HashMap<>();
            // 添加发货单明细
            List<SaDeliverItems> deliverItemsList = new ArrayList<>();
            for (SaOrderExt saOrderExt : orderList) {
                for (SaOrderItemsExt saOrderItemsExt : saOrderExt.getOrderItemsExtList()) {
                    // 根据订单生成对应发货单
                    SaDeliverItems saDeliverItems = new SaDeliverItems();
                    saDeliverItems.setPkDeliver(saDeliver.getPkId());
                    saDeliverItems.setPkOrder(saOrderExt.getPkId());
                    saDeliverItems.setPkOrderItems(saOrderItemsExt.getPkId());
                    saDeliverItems.setPkProduct(saOrderItemsExt.getPkProduct());
                    saDeliverItems.setQuantity(saOrderItemsExt.getQuantity());
                    saDeliverItems.setPkCreator(userId);
                    saDeliverItems.setCreationTime(nowDate);
                    saDeliverItems.setPkCountry(pkCountry);
                    saDeliverItems.setSpecsName(saOrderItemsExt.getSpecsName());
                    saDeliverItems.setSpecsNameId(saOrderItemsExt.getSpecsNameId());
                    deliverItemsList.add(saDeliverItems);

                    deliverItemsMap.put(saOrderItemsExt.getPkId(), saDeliverItems);
                }
            }
            iSaDeliverItemsService.saveBatch(deliverItemsList);

            // 添加发货条码
            List<SaDeliverBarCode> deliverBarCodeList = new ArrayList<>();
            for (OrderSelfBarCodeDTO orderSelfBarCodeDTO : barCodeList) {
                SaDeliverItems saDeliverItems = deliverItemsMap.get(orderSelfBarCodeDTO.getItemId());
                // 封装发货条码
                SaDeliverBarCode saDeliverBarCode = new SaDeliverBarCode();
                saDeliverBarCode.setPkDeliver(saDeliverItems.getPkDeliver());
                saDeliverBarCode.setPkDeliverItems(saDeliverItems.getPkId());
                saDeliverBarCode.setPkProduct(orderSelfBarCodeDTO.getProductId());
                saDeliverBarCode.setPkBarCodeItems(orderSelfBarCodeDTO.getBarCodeId());
                saDeliverBarCode.setBarCode(orderSelfBarCodeDTO.getBarCode());
                saDeliverBarCode.setPkCreator(saDeliverItems.getPkCreator());
                saDeliverBarCode.setCreationTime(nowDate);
                saDeliverBarCode.setPkCountry(pkCountry);
                saDeliverBarCode.setPkModified(saDeliverItems.getPkCreator());
                saDeliverBarCode.setModifiedTime(nowDate);
                deliverBarCodeList.add(saDeliverBarCode);
            }
            if (deliverBarCodeList.size() > 0) {
                iSaDeliverBarCodeService.insertBatch(deliverBarCodeList);
            }
            return null;
        }
        log.error("订单自提同意处理失败: 更新数据失败");
        return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_ERROR);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public String selfDeliverApprovalReject(ApprovalBusinessResultDTO approvalBusinessResultDTO) {
        // 用户ID
        Long userId = approvalBusinessResultDTO.getLoginUser().getUserId();
        // 所属国家
        Integer pkCountry = approvalBusinessResultDTO.getLoginUser().getDataCountry();

        // 查询订单修改记录
        List<SaOrderChargeLog> saOrderChargeLogList = iOrderBusinessService.getSaOrderChargeLogs(approvalBusinessResultDTO, EApprovalBusiness.SELF_DELIVERY_MANAGE);
        if (CollectionUtil.isEmpty(saOrderChargeLogList)) {
            log.error("订单自提驳回处理失败: 签呈不存在!");
            return TransactionUtils.getContent(DocumentMsgConstants.SIGN_NOT_EXIST);
        }
        // 只有多单一个自提，此处直接拿第一条
        if (EAgentApprovalStatus.UNAPPROVED.getValue() != saOrderChargeLogList.get(0).getApprovalStatus()) {
            log.error("订单自提驳回处理失败: 签呈已处理");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_HAS_HANDLE);
        }

        // 获取追溯码ID列表
        List<Integer> barCodeItemsIdList = new ArrayList<>();

        for (SaOrderChargeLog saOrderChargeLog : saOrderChargeLogList) {
            OrderSelfDTO orderSelfDTO = JSONUtil.toBean(saOrderChargeLog.getAfterData(), OrderSelfDTO.class);
            // 获取追溯码ID列表
            barCodeItemsIdList.addAll(orderSelfDTO.getBarCodeList().stream().map(OrderSelfBarCodeDTO::getBarCodeId).collect(Collectors.toList()));
        }

        if (iOrderBusinessService.updateSaOrderChargeLog(EApprovalBusiness.SELF_DELIVERY_MANAGE, approvalBusinessResultDTO.getBusinessCode(), pkCountry, userId, EAgentApprovalStatus.REFUSE, approvalBusinessResultDTO.getApproveRemark())) {
            if (CollectionUtil.isNotEmpty(barCodeItemsIdList)) {
                // 存在条码，则取消条码使用状态
                R<String> resultR = iBarCodeServiceApi.clearBarCode(barCodeItemsIdList, pkCountry, userId);
                if (!resultR.isSuccess()) {
                    throw new ServiceException(TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED) + "：" + resultR.getMsg());
                }
            }
            return null;
        }
        log.error("订单自提驳回处理失败: 更新数据失败");
        return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_ERROR);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String secondDeliverSubmit(DeliverSecondSubmitParam param, LoginUser loginUser) {
        // 用户ID
        Long userId = loginUser.getUserId();
        // 所属国家
        Integer pkCountry = loginUser.getDataCountry();

        // 提交数据
        DeliverSecondDataParam dataParam = param.getDataParam();

        // 原订单
        SaOrder oldSaOrder = iSaOrderService.getById(dataParam.getPkId());
        if (null == oldSaOrder) {
            // 订单已不存在
            return TransactionUtils.getContent(SaOrderMsgConstants.ORDER_NOT_EXIST);
        }

        // 修改后数据
        SecondDTO secondDTO = BeanUtil.copyProperties(dataParam, SecondDTO.class);
        secondDTO.setOrderCode(CommonUtil.createSerialNumber(EOrderPrefix.ORDER_CODE));

        // 订单金额
        BigDecimal orderAmount = null != dataParam.getPostage() ? dataParam.getPostage() : BigDecimal.ZERO;
        for (SecondProductDTO productDTO : secondDTO.getProductList()) {
            // 产品金额
            BigDecimal price = null != productDTO.getPrice() ? productDTO.getPrice() : BigDecimal.ZERO;
            // 订单金额
            orderAmount = orderAmount.add(price.multiply(new BigDecimal(productDTO.getQuantity())));
        }
        // 处理扣款金额（如果会员账户不足则会抛异常）
        this.handMemberAccount(secondDTO.getAccountList(), oldSaOrder.getPkCreator(), pkCountry, orderAmount);

        // 涉及会员ID列表
        Set<Long> pkMemberList = new HashSet<>();
        pkMemberList.add(oldSaOrder.getPkMember());

        // 修改记录单号
        String businessCode = CommonUtil.createSerialNumber(EOrderPrefix.ORDER_CODE);

        // 订单修改记录
        SaOrderChargeLog saOrderChargeLog = new SaOrderChargeLog();
        saOrderChargeLog.setPkOrder(dataParam.getPkId());
        saOrderChargeLog.setChargeType(EApprovalBusiness.SECOND_DELIVER.getValue());
        saOrderChargeLog.setAfterData(JSONUtil.toJsonStr(secondDTO));
        saOrderChargeLog.setPkCreator(userId);
        saOrderChargeLog.setPkCountry(pkCountry);
        saOrderChargeLog.setBusinessCode(businessCode);

        if (iSaOrderChargeLogService.save(saOrderChargeLog)) {
            // 订单修改记录添加成功，提交签呈
            // 提交签呈处理
            R<String> resultR = iApprovalServiceApi.submitOrder(
                    ApprovalSubmitDTO.builder()
                            .eApprovalBusiness(EApprovalBusiness.SECOND_DELIVER)
                            .businessCode(businessCode)
                            .signType(ESignType.getEnumByValue(param.getSignType()))
                            .userIdList(param.getUserIdList())
                            .sendIdList(param.getSendIdList())
                            .remark(param.getRemark())
                            .fileList(param.getFileList())
                            .pkMemberList(pkMemberList)
                            .build(),
                    loginUser,
                    null
            );
            if (resultR.isSuccess()) {
                return null;
            }
            throw new ServiceException(TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED) + "：" + resultR.getMsg());
        }
        return TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String secondDeliverApprovalAgree(ApprovalBusinessResultDTO approvalBusinessResultDTO) {
        // 用户ID
        Long userId = approvalBusinessResultDTO.getLoginUser().getUserId();
        // 所属国家
        Integer pkCountry = approvalBusinessResultDTO.getLoginUser().getDataCountry();

        // 查询订单修改记录
        List<SaOrderChargeLog> saOrderChargeLogList = iOrderBusinessService.getSaOrderChargeLogs(approvalBusinessResultDTO, EApprovalBusiness.SECOND_DELIVER);
        if (CollectionUtil.isEmpty(saOrderChargeLogList)) {
            log.error("订单二次发货通过处理失败: 签呈信息不存在!");
            return TransactionUtils.getContent(DocumentMsgConstants.SIGN_NOT_EXIST);
        }
        SaOrderChargeLog saOrderChargeLog = saOrderChargeLogList.get(0);
        // 只有多单一个自提，此处直接拿第一条
        if (EAgentApprovalStatus.UNAPPROVED.getValue() != saOrderChargeLog.getApprovalStatus()) {
            log.error("订单二次发货通过处理失败: 签呈已处理");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_HAS_HANDLE);
        }

        // 原订单
        SaOrder oldSaOrder = iSaOrderService.getById(saOrderChargeLog.getPkOrder());
        if (null == oldSaOrder) {
            log.error("订单二次发货通过处理失败: 订单已不存在");
            return TransactionUtils.getContent(SaOrderMsgConstants.ORDER_NOT_EXIST);
        }

        // 二次发货数据
        SecondDTO secondDTO = JSONUtil.toBean(saOrderChargeLog.getAfterData(), SecondDTO.class);

        // 处理订单
        SaOrderExt saOrder = this.handOrder(oldSaOrder, secondDTO, userId, pkCountry);

        // 实际扣款金额（金额 + 邮费）
        BigDecimal orderAmount = saOrder.getOrderAmount().add(saOrder.getPostage());
        // 处理扣款金额（如果会员账户不足则会抛异常）
        CuMemberAccountExt updateAccount = this.handMemberAccount(secondDTO.getAccountList(), oldSaOrder.getPkCreator(), pkCountry, orderAmount);

        if (iOrderBusinessService.updateSaOrderChargeLog(EApprovalBusiness.SECOND_DELIVER, approvalBusinessResultDTO.getBusinessCode(), pkCountry, userId, EAgentApprovalStatus.APPROVED, approvalBusinessResultDTO.getApproveRemark())) {
            // 更新订单修改记录

            // 保存订单、订单明细
            iSaOrderService.processOrder(saOrder);

            // 需要计算奖金
            if (EYesNo.YES.getIntValue() == secondDTO.getBonusFlag()) {
                // 奖金项去重
                List<Integer> bonusList = secondDTO.getBonusList().stream().distinct().collect(Collectors.toList());

                List<SaOrderBonus> orderBonusList = new ArrayList<>(bonusList.size());
                for (Integer bonusInt : bonusList) {
                    SaOrderBonus saOrderBonus = new SaOrderBonus();
                    saOrderBonus.setPkOrder(saOrder.getPkId());
                    saOrderBonus.setPkBonusItems(bonusInt);
                    orderBonusList.add(saOrderBonus);
                }
                iSaOrderBonusService.insertBatch(orderBonusList);
            }

            // 需要扣款
            if (null != updateAccount) {
                R accountR = iMemberAccountServiceApi.insertMemberTrade(saOrder, updateAccount);
                if (!accountR.isSuccess()) {
                    log.error("订单二次发货同意处理失败: 会员扣款失败");
                    throw new ServiceException("订单二次发货同意处理失败: 会员扣款失败");
                }
            }

            return null;
        }
        log.error("订单二次发货同意处理失败: 更新数据失败");
        return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_ERROR);
    }

    @Override
    public String secondDeliverApprovalReject(ApprovalBusinessResultDTO approvalBusinessResultDTO) {
        // 用户ID
        Long userId = approvalBusinessResultDTO.getLoginUser().getUserId();
        // 所属国家
        Integer pkCountry = approvalBusinessResultDTO.getLoginUser().getDataCountry();

        // 查询订单修改记录
        List<SaOrderChargeLog> saOrderChargeLogList = iOrderBusinessService.getSaOrderChargeLogs(approvalBusinessResultDTO, EApprovalBusiness.SECOND_DELIVER);
        if (CollectionUtil.isEmpty(saOrderChargeLogList)) {
            log.error("订单二次发货驳回处理失败: 签呈信息不存在!");
            return TransactionUtils.getContent(DocumentMsgConstants.SIGN_NOT_EXIST);
        }
        SaOrderChargeLog saOrderChargeLog = saOrderChargeLogList.get(0);
        // 只有多单一个自提，此处直接拿第一条
        if (EAgentApprovalStatus.UNAPPROVED.getValue() != saOrderChargeLog.getApprovalStatus()) {
            log.error("订单二次发货驳回处理失败: 签呈已处理");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_HAS_HANDLE);
        }

        if (iOrderBusinessService.updateSaOrderChargeLog(EApprovalBusiness.SECOND_DELIVER, approvalBusinessResultDTO.getBusinessCode(), pkCountry, userId, EAgentApprovalStatus.REFUSE, approvalBusinessResultDTO.getApproveRemark())) {
            return null;
        }
        log.error("订单二次发货驳回处理失败: 更新数据失败");
        return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_ERROR);
    }

    /**
     * 处理订单封装
     *
     * @param oldSaOrder 原订单
     * @param secondDTO  二次发货数据
     * @param userId     用户ID
     * @param pkCountry  所属国家
     */
    private SaOrderExt handOrder(SaOrder oldSaOrder, SecondDTO secondDTO, Long userId, Integer pkCountry) {
        // 查询汇率
        CurrencyDTO currencyDTO = iCurrencyServiceApi.getCurrency(pkCountry).getData();

        // 封装订单
        SaOrderExt saOrder = new SaOrderExt();
        // 封装订单明细
        List<SaOrderItems> saOrderItemsList = new ArrayList<>();

        // 订单金额
        BigDecimal orderAmount = BigDecimal.ZERO;
        // 订单PV
        BigDecimal orderAchievement = BigDecimal.ZERO;
        // 订单BV
        BigDecimal orderAssAchievement = BigDecimal.ZERO;

        for (SecondProductDTO productDTO : secondDTO.getProductList()) {
            // 产品数量
            BigDecimal quantity = new BigDecimal(productDTO.getQuantity());
            // 产品金额
            BigDecimal price = null != productDTO.getPrice() ? productDTO.getPrice() : BigDecimal.ZERO;
            // 产品PV
            BigDecimal achievement = null != productDTO.getAchievement() ? productDTO.getAchievement() : BigDecimal.ZERO;
            // 产品BV
            BigDecimal assAchievement = null != productDTO.getAssAchievement() ? productDTO.getAssAchievement() : BigDecimal.ZERO;

            SaOrderItems saOrderItems = new SaOrderItems();
            saOrderItems.setPkProduct(productDTO.getPkProduct());
            saOrderItems.setPkRate(currencyDTO.getPkId());
            saOrderItems.setQuantity(productDTO.getQuantity());
            saOrderItems.setPrice(price);
            saOrderItems.setAchievement(achievement);
            saOrderItems.setAssAchievement(assAchievement);
            saOrderItems.setSpecsName(productDTO.getSpecsName());
            saOrderItems.setSpecsNameId(productDTO.getSpecsNameId());
            saOrderItems.setPkCreator(userId);
            saOrderItems.setPkCountry(pkCountry);
            saOrderItems.setOrderStatus(EOrderStatus.PAY.getValue());
            saOrderItemsList.add(saOrderItems);

            // 订单金额、PV、BV计算
            orderAmount = orderAmount.add(price.multiply(quantity));
            orderAchievement = orderAchievement.add(achievement.multiply(quantity));
            orderAssAchievement = orderAssAchievement.add(assAchievement.multiply(quantity));
        }

        saOrder.setOrderCode(secondDTO.getOrderCode());
        saOrder.setOrderType(EOrderType.SECOND_ORDER.getValue());
        saOrder.setPkRate(currencyDTO.getPkId());
        saOrder.setOrderAmount(orderAmount);
        saOrder.setOrderAchieve(orderAchievement);
        saOrder.setOrderAssAchieve(orderAssAchievement);
        saOrder.setPostage(secondDTO.getPostage());
        saOrder.setRecName(secondDTO.getRecName());
        saOrder.setRecPhone(secondDTO.getRecPhone());
        saOrder.setRecProvince(secondDTO.getRecProvince());
        saOrder.setRecCity(secondDTO.getRecCity());
        saOrder.setRecCounty(secondDTO.getRecCounty());
        saOrder.setRecAddress(secondDTO.getRecAddress());
        saOrder.setDeliveryWay(oldSaOrder.getDeliveryWay());
        saOrder.setOrderStatus(EPayStatus.PAID.getValue());
        saOrder.setPkCreator(oldSaOrder.getPkCreator());
        saOrder.setPkCountry(pkCountry);
        saOrder.setPkMember(oldSaOrder.getPkMember());
        saOrder.setPkReference(oldSaOrder.getPkReference());
        saOrder.setPkPlacement(oldSaOrder.getPkPlacement());
        saOrder.setTranType(oldSaOrder.getTranType());
        saOrder.setPkVertex(oldSaOrder.getPkVertex());
        saOrder.setPayType(EOrderPayType.WALLET.getValue());
        saOrder.setPkMemberStore(oldSaOrder.getPkMemberStore());
        // 根据收货省获取仓库
        BdStorehouse storehouse = iCurrencyServiceApi.queryBdStorehouseByProvince(secondDTO.getRecProvince()).getData();
        if (null != storehouse) {
            saOrder.setPkStorehouse(storehouse.getPkId());
        } else {
            saOrder.setPkStorehouse(oldSaOrder.getPkStorehouse());
        }
        saOrder.setPkOriginalOrder(oldSaOrder.getPkId());
        saOrder.setOrderItemsList(saOrderItemsList);

        return saOrder;
    }

    /**
     * 处理扣款金额
     *
     * @param accountList 扣款账户列表
     * @param pkMember    所属会员
     * @param pkCountry   所属国家
     * @param orderAmount 金额（订单金额+邮费）
     * @return
     */
    private CuMemberAccountExt handMemberAccount(List<SecondAccountDTO> accountList, Long pkMember, Integer pkCountry,
                                                 BigDecimal orderAmount) {
        CuMemberAccountExt updateAccount = null;
        // 剩余扣款金额
        BigDecimal residueAmount = orderAmount;
        if (orderAmount.compareTo(BigDecimal.ZERO) > 0) {
            // 实际扣款金额 大于0，需要计算扣款
            updateAccount = new CuMemberAccountExt();
            updateAccount.setPkMember(pkMember);
            updateAccount.setPkCountry(pkCountry);

            // 账户ID列表
            List<Integer> pkAccountList = new ArrayList<>();
            // 校验扣除比例
            BigDecimal deductRatio = BigDecimal.ZERO;
            for (SecondAccountDTO secondAccountDTO : accountList) {
                pkAccountList.add(secondAccountDTO.getPkAccount());
                deductRatio = deductRatio.add(secondAccountDTO.getDeductRatio());
            }
            // 账户map
            Map<Integer, BdAccount> accountMap = iAccountServiceApi.getAccountMap(pkAccountList).getData();
            // 会员账户
            CuMemberAccount cuMemberAccount = iMemberAccountServiceApi.queryCuMemberAccountByPkMembers(Collections.singletonList(pkMember)).getData().get(0);
            // 分母100
            BigDecimal bigDecimal100 = new BigDecimal("100");

            // 配置比例为0的扣款账户
            List<SecondAccountDTO> zeroAccountList = new ArrayList<>();

            for (SecondAccountDTO secondAccountDTO : accountList) {
                // 按扣币账户配置百分比，计算应扣金额
                BigDecimal accountAmount = orderAmount.multiply(secondAccountDTO.getDeductRatio()).divide(bigDecimal100, 2, RoundingMode.HALF_UP);

                if (accountAmount.compareTo(BigDecimal.ZERO) > 0) {
                    // 扣币账户
                    BdAccount bdAccount = accountMap.get(secondAccountDTO.getPkAccount());
                    // 扣币账户字段
                    String accountField = MemberFieldConstants.ACCOUNT + bdAccount.getFieldValue();
                    // 会员账户扣款pay字段
                    String accountPayField = MemberFieldConstants.PAY_ACCOUNT + bdAccount.getFieldValue();
                    // 当前扣币账户余额
                    BigDecimal accountBalance = ReflectUtils.invokeGetter(cuMemberAccount, accountField);

                    // 记录扣款币种的当前值，为了后续处理流水处理
                    ReflectUtils.invokeSetter(updateAccount, accountField, ReflectUtils.invokeGetter(cuMemberAccount, accountField));

                    if (accountBalance.compareTo(accountAmount) >= 0) {
                        // 当前余额大于等于扣款金额，进行处理
                        // 原账户余额减扣款金额
                        ReflectUtils.invokeSetter(cuMemberAccount, accountField, accountBalance.subtract(accountAmount));

                        // 扣款账户是否已经存在该账户扣款
                        BigDecimal tmpAccount = ReflectUtils.invokeGetter(updateAccount, accountPayField);
                        if (null == tmpAccount) {
                            tmpAccount = BigDecimal.ZERO;
                        }
                        // 扣款账户进行扣款
                        ReflectUtils.invokeSetter(updateAccount, accountPayField, tmpAccount.add(accountAmount));

                        // 剩余扣款金额
                        residueAmount = residueAmount.subtract(accountAmount);
                    } else {
                        log.error("订单二次发货处理失败: 会员余额不足");
                        throw new ServiceException(TransactionUtils.getContent(TransactionUtils.getContent(ConfigMsgConstants.MEMBER_BALANCE_INSUFFICIENT)));
                    }
                } else {
                    // 比例为0的账户单独记录
                    zeroAccountList.add(secondAccountDTO);
                }
            }
            if (deductRatio.compareTo(bigDecimal100) != 0 && residueAmount.compareTo(BigDecimal.ZERO) > 0) {
                // 扣款比例非100%，并且剩余扣款金额大于0
                for (SecondAccountDTO secondAccountDTO : zeroAccountList) {
                    // 扣币账户
                    BdAccount bdAccount = accountMap.get(secondAccountDTO.getPkAccount());
                    // 扣币账户字段
                    String accountField = MemberFieldConstants.ACCOUNT + bdAccount.getFieldValue();
                    // 会员账户扣款pay字段
                    String accountPayField = MemberFieldConstants.PAY_ACCOUNT + bdAccount.getFieldValue();
                    // 当前扣币账户余额
                    BigDecimal accountBalance = ReflectUtils.invokeGetter(cuMemberAccount, accountField);

                    if (accountBalance.compareTo(residueAmount) >= 0) {
                        // 当前币种足够扣了
                        // 原账户余额减扣款金额
                        ReflectUtils.invokeSetter(cuMemberAccount, accountField, accountBalance.subtract(residueAmount));

                        // 扣款账户是否已经存在该账户扣款
                        BigDecimal tmpAccount = ReflectUtils.invokeGetter(updateAccount, accountPayField);
                        if (null == tmpAccount) {
                            tmpAccount = BigDecimal.ZERO;
                        }
                        // 扣款账户进行扣款
                        ReflectUtils.invokeSetter(updateAccount, accountPayField, tmpAccount.add(residueAmount));

                        // 剩余扣款金额
                        residueAmount = BigDecimal.ZERO;
                        break;
                    } else {
                        // 当前币种不足
                        // 原账户清0
                        ReflectUtils.invokeSetter(cuMemberAccount, accountField, BigDecimal.ZERO);

                        // 扣款账户是否已经存在该账户扣款
                        BigDecimal tmpAccount = ReflectUtils.invokeGetter(updateAccount, accountPayField);
                        if (null == tmpAccount) {
                            tmpAccount = BigDecimal.ZERO;
                        }
                        // 扣款账户进行扣款
                        ReflectUtils.invokeSetter(updateAccount, accountPayField, tmpAccount.add(accountBalance));

                        // 剩余扣款金额
                        residueAmount = residueAmount.subtract(accountBalance);
                    }
                }
            }
            if (residueAmount.compareTo(BigDecimal.ZERO) != 0) {
                log.error("订单二次发货处理失败: 会员余额不足");
                throw new ServiceException(TransactionUtils.getContent(TransactionUtils.getContent(ConfigMsgConstants.MEMBER_BALANCE_INSUFFICIENT)));
            }
        }
        return updateAccount;
    }

}

