package com.bailuntec.job;

import com.alibaba.fastjson.JSON;
import com.bailuntec.domain.constant.CommonConstant;
import com.bailuntec.domain.constant.Constant;
import com.bailuntec.domain.entity.*;
import com.bailuntec.domain.enumerate.OrderExceptionStatus;
import com.bailuntec.domain.enumerate.OrderExceptionType;
import com.bailuntec.domain.enumerate.PlatformType;
import com.bailuntec.domain.example.*;
import com.bailuntec.domain.pojo.*;
import com.bailuntec.mapper.*;
import com.bailuntec.support.CallBailunSystem;
import com.bailuntec.support.PointJob;
import com.bailuntec.utils.ExceptionUtil;
import com.bailuntec.utils.OkHttpUtil;
import com.bailuntec.utils.PropertiesUtil;
import com.bailuntec.utils.SessionUtil;
import com.dangdang.ddframe.job.api.ShardingContext;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Slf4j
public class OrderSyncJob extends PointJob {
    private OkHttpClient okHttpClient = OkHttpUtil.getInstance();
    private PropertiesUtil propertiesUtil = PropertiesUtil.getInstance("const");

    @Override
    public void executeJob(ShardingContext shardingContext, JobPointLog jobPointLog) {
        LinkedHashMap<String, String> map = new LinkedHashMap<>(4);
        //临时处理速卖通数据
        map.put("pageCount", jobPointLog.getPageSize().toString());
        //时间回退一点, 避免服务器时间不一致而漏单
        map.put("BailunLastUpdateTimeFrom", DateTimeFormatter.ofPattern(CommonConstant.TIME_FORMAT).format(jobPointLog.getStartTime().minusMinutes(3)));
        map.put("BailunLastUpdateTimeTo", DateTimeFormatter.ofPattern(CommonConstant.TIME_FORMAT).format(jobPointLog.getEndTime()));
        do {
            map.put("pageIndex", jobPointLog.getPageIndex().equals(0) ? "1" : jobPointLog.getPageIndex().toString());
            Response response = null;
            String omsResultStr = null;
            try {
                Request request = new Request.Builder()
                        .get()
                        .url(OkHttpUtil.attachHttpGetParams(propertiesUtil.getPropertyAsString("BAILUNORDER_URL"), map))
                        .addHeader("Content-Type", "application/json")
                        .build();
                response = okHttpClient.newCall(request).execute();
                omsResultStr = response.body().string();
            } catch (IOException e) {
                throw new RuntimeException(ExceptionUtil.transform(e),e);
            } finally {
                if (response != null) {
                    response.close();
                }
            }
            if (StringUtils.isNoneBlank(omsResultStr)) {
                OmsResultRoot omsResultRoot = JSON.parseObject(omsResultStr, OmsResultRoot.class);
                if (omsResultRoot != null && omsResultRoot.getSuccess().booleanValue()) {
                    OmsResultInfo omsResultInfo = omsResultRoot.getResult();
                    if (jobPointLog.getPageIndex().equals(0)) {
                        jobPointLog.setPageIndex(omsResultInfo.getTotalPages() + 1);
                    }
                    if (omsResultInfo.getResult() != null && omsResultInfo.getResult().size() > 0) {
                        analyseOmsOrder(omsResultInfo.getResult());
                    }
                } else {
                    throw new RuntimeException("调用OMS接口同步百伦订单失败, 响应200, 请求参数" + map.toString());
                }
            } else {
                throw new RuntimeException("调用OMS接口同步百伦订单失败, 响应为null, 请求参数" + map.toString());
            }
            if (jobPointLog.getPageIndex() % 10 == 0) {
                try {
                    JobPointLogMapper mapper = SessionUtil.getSession().getMapper(JobPointLogMapper.class);
                    mapper.upsertSelective(jobPointLog);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new RuntimeException(ExceptionUtil.transform(e), e);
                } finally {
                    SessionUtil.closeSession();
                }
            }
            jobPointLog.setPageIndex(jobPointLog.getPageIndex() - 1);
        } while (0 < jobPointLog.getPageIndex());
        jobPointLog.setPageIndex(0);
        jobPointLog.setStartTime(jobPointLog.getEndTime());
        jobPointLog.setEndTime(jobPointLog.getEndTime().plusDays(jobPointLog.getIntervalTime()).isAfter(LocalDateTime.now()) ? LocalDateTime.now() : jobPointLog.getEndTime().plusDays(jobPointLog.getIntervalTime()));
    }

    /**
     * 解析订单, 并处理费用信息
     *
     * @param bailunOrderList
     */
    public void analyseOmsOrder(List<OmsResult> bailunOrderList) {
        for (OmsResult omsResult : bailunOrderList) {
            log.warn(omsResult.getOriginOrderId()); //打印订单号, 出了问题可以快速定位到订单, 再单独跑测试可以排查出问题
            if (omsResult != null && omsResult.getBailunPaymentStatus() != null && omsResult.getBailunPaymentStatus().equals(Constant.PAYMENT_STATUS)) {
                DcBaseOmsOrder dcBaseOmsOrder = new DcBaseOmsOrder();
                assignmentOrderInfo(omsResult, dcBaseOmsOrder);
                deleteSku(dcBaseOmsOrder);//因为OMS可能改订单, 部分SKU有可能会被删除, 所以先删除, 再插入, 并且更新退款为未予订单关联
                //判断是否FBA单号前缀为S0的单
                hasS0(omsResult, dcBaseOmsOrder);
                //判断是否内购订单
                hasInnerSale(omsResult, dcBaseOmsOrder);
                //判断是否刷单订单
                listOrderExceptions(omsResult, dcBaseOmsOrder);
                //获取汇率
                getExchangeRate(omsResult, dcBaseOmsOrder);
                //这个MAP, key放仓库. value放线物流路
                HashMap<String, Logistics> logisticsHashMap = new HashMap<>();
                //由LMS线路计算的物流费
                BigDecimal totalCostLogistics = getTotalCostLogistics(omsResult.getLogisticsItems(), logisticsHashMap);
                //如果订单中存在百伦SKU, 去拿一些放在SKU里的信息
                Map<String, BailunSkuStructure> bailunSkuInfoMap = new HashMap<>();
                //将每个SKU的头程费汇总为总头程费
                BigDecimal totalCostFirst = BigDecimal.ZERO;
                /**
                 * 遍历所有百伦SKU(omsResult.getBailunSku())
                 * 拿到SKU累计信息, 自发货运费按SKU重量比重取
                 */
                if (omsResult.getBailunSku() != null && omsResult.getBailunSku().size() > 0) {
                    /*
                     * 遍历SKU,先拿到SKU部分数据的累计值
                     * 比如累计数量,累计重量
                     */
                    BailunSkuCumulative bailunSkuCumulative = getBailunSkuCumulative(omsResult);
                    //SKU总个数
                    dcBaseOmsOrder.setQuantityBailunSku(bailunSkuCumulative.getTotalQuantity());
                    //计算每个SKU采购价占总采购价比重(用于摊分SKU售价之类) 以及 每个SKU重量价占总重量的比重
                    for (BailunSku bailunSkuObj : omsResult.getBailunSku()) {
                        BailunSkuStructure bailunSkuStructure = new BailunSkuStructure();
                        /*
                         * 拿每个SKU的发货仓库信息
                         * 如果是FBA库存, 要看是否共享库存
                         */
                        DcBaseWarehouse dcBaseWarehouse = getDcBaseWarehouse(bailunSkuObj, omsResult);
                        bailunSkuStructure.setDcBaseWarehouse(dcBaseWarehouse);
                        if (dcBaseWarehouse != null && dcBaseWarehouse.getHqType().equals(Constant.DOMESTIC_WAREHOUSE)) {
                            bailunSkuCumulative.setDomesticOrOverseas(true);
                        }
                        if (PlatformType.FBA.value().equals(omsResult.getPlatformType()) && dcBaseWarehouse != null) {
                            switch (dcBaseWarehouse.getAreaId()) {
                                case 6:
                                case 8:
                                case 10:
                                case 11:
                                case 12:
                                    DcBaseStockFbaShareMapper dcBaseStockFbaShareMapper = SessionUtil.getSession().getMapper(DcBaseStockFbaShareMapper.class);
                                    DcBaseStockConfigFbaMapper dcBaseStockConfigFbaMapper = SessionUtil.getSession().getMapper(DcBaseStockConfigFbaMapper.class);
                                    DcBaseWarehouseMapper baseWarehouseMapper = SessionUtil.getSession().getMapper(DcBaseWarehouseMapper.class);
                                    DcBaseStockFbaShare dcBaseStockFbaShare = dcBaseStockFbaShareMapper.selectOneByExample(DcBaseStockFbaShareExample.newAndCreateCriteria().andBailunSkuEqualTo(bailunSkuObj.getBailunSku()).example());
                                    if (dcBaseStockFbaShare != null) { //说明是共享库存, 读仓库配置
                                        DcBaseStockConfigFba dcBaseStockConfigFba = dcBaseStockConfigFbaMapper.selectOneByExample(DcBaseStockConfigFbaExample.newAndCreateCriteria().andBailunSkuEqualTo(dcBaseStockFbaShare.getBailunSku()).example());
                                        if (dcBaseStockConfigFba != null) {
                                            DcBaseWarehouse dcBaseWarehouseFba = baseWarehouseMapper.selectOneByExample(DcBaseWarehouseExample.newAndCreateCriteria().andWarehouseCodeEqualTo(dcBaseStockConfigFba.getWarehouseCode()).example());
                                            bailunSkuStructure.setDcBaseWarehouse(dcBaseWarehouseFba);
                                        } else {
                                            bailunSkuStructure.setDcBaseWarehouse(null);
                                        }
                                    } //其他的不是共享库存, 就不管了.
                                    break;
                            }
                        }
                        bailunSkuStructure.setBailunSku(bailunSkuObj.getBailunSku());
                        bailunSkuStructure.setBailunSkuUnitPrice((bailunSkuObj.getBailunSkuUnitPrice() != null && bailunSkuObj.getBailunSkuUnitPrice().getAmount() != null) ? bailunSkuObj.getBailunSkuUnitPrice().getAmount() : BigDecimal.ZERO);
                        bailunSkuStructure.setBailunSkuWeight(bailunSkuObj.getBailunSkuWeight() != null ? bailunSkuObj.getBailunSkuWeight() : BigDecimal.ZERO);
                        bailunSkuStructure.setSkuCostRatio(dcBaseOmsOrder.getCostProduct().compareTo(BigDecimal.ZERO) == 1 ? bailunSkuStructure.getBailunSkuUnitPrice().multiply(BigDecimal.valueOf(bailunSkuObj.getBailunSkuQuantityOrdered())).divide(dcBaseOmsOrder.getCostProduct(), 5, RoundingMode.HALF_EVEN) : BigDecimal.ONE);
                        bailunSkuStructure.setSkuWeightRatio(bailunSkuCumulative.getTotalWeight().compareTo(BigDecimal.ZERO) == 1 ? bailunSkuStructure.getBailunSkuWeight().multiply(BigDecimal.valueOf(bailunSkuObj.getBailunSkuQuantityOrdered())).divide(bailunSkuCumulative.getTotalWeight(), 5, RoundingMode.HALF_EVEN) : BigDecimal.ONE);
                        bailunSkuStructure.setSkuQuantityOrderd(bailunSkuObj.getBailunSkuQuantityOrdered() != null ? bailunSkuObj.getBailunSkuQuantityOrdered() : 0);
                        DcBaseOmsSku dcBaseOmsSku = new DcBaseOmsSku();
                        if (PlatformType.FBA.value().equals(omsResult.getPlatformType())) {
                            dcBaseOmsSku.setWarehouseCodeFba(dcBaseWarehouse.getWarehouseCode());
                        }
                        dcBaseOmsSku.setHasDelete(false);
                        dcBaseOmsSku.setHasScalp(dcBaseOmsOrder.getHasScalp());
                        /*
                         * dc_base_oms_sku字段赋值, 给初始值是为了避免nullPoint
                         */
                        assignmentSkuInfo(omsResult, dcBaseOmsOrder, dcBaseOmsSku, bailunSkuObj, dcBaseWarehouse, logisticsHashMap,bailunSkuStructure);
                        if (PlatformType.FBA.value().equals(omsResult.getPlatformType().toUpperCase())) {
                            //FBA费用
                            BigDecimal skuCostFbaFee = bailunSkuStructure.getSkuWeightRatio().multiply(dcBaseOmsOrder.getCostFbaFee()).setScale(5, RoundingMode.HALF_EVEN);
                            dcBaseOmsSku.setCostFbaFee(skuCostFbaFee);
                            //FBA的发货数不用从配货单信息拿, FBA只要下单亚马逊就发货
                            dcBaseOmsSku.setBailunSkuQuantityShipped(bailunSkuObj.getBailunSkuQuantityOrdered());
                            checkFbaFee(dcBaseOmsSku, dcBaseOmsOrder);
                        }
                        bailunSkuStructure.setDcBaseOmsSku(dcBaseOmsSku);
                        bailunSkuInfoMap.put(bailunSkuObj.getBailunSku(), bailunSkuStructure);
                    }
                    /*
                     * 按规则计算百伦处理费
                     * 处理费算到订单维度
                     */
                    caculateBailunHandleFee(dcBaseOmsOrder, bailunSkuCumulative);
                }
                /*
                 * 配货单处理,
                 */
                handPickingOrder(dcBaseOmsOrder, omsResult, bailunSkuInfoMap);
                /**
                 * Order费用处理
                 * 费用计算都从这里开始
                 */
                BigDecimal productAmount = dcBaseOmsOrder.getAmountProduct().compareTo(BigDecimal.ZERO) == 1 ? dcBaseOmsOrder.getAmountProduct() : dcBaseOmsOrder.getAmountTotal();
                dcBaseOmsOrder.setAmountProduct(productAmount);//部分订单 AmountProduct(产品金额)字段没值或等于0， 就取AmountTotal（商品总收入）
                //销售额统一改为 销售额=产品金额+运费-促销
                dcBaseOmsOrder.setAmountSales(productAmount.add(dcBaseOmsOrder.getAmountShipping()).subtract(dcBaseOmsOrder.getCostPromotion()));
               //平台渠道费人民币 - Ebay的平台费币种不一样， 要取不同的汇率计算
                BigDecimal costPlatformFeeRMB;
                if (PlatformType.Ebay.value().equals(dcBaseOmsOrder.getPlatformType().toUpperCase())) {
                    costPlatformFeeRMB = dcBaseOmsOrder.getCostPlatformFee().multiply(dcBaseOmsOrder.getSellerOtherExchangeRate()).setScale(5, RoundingMode.HALF_EVEN);
                } else {
                    costPlatformFeeRMB = dcBaseOmsOrder.getCostPlatformFee().multiply(dcBaseOmsOrder.getSellerOrderExchangeRate()).setScale(5, RoundingMode.HALF_EVEN);
                }
                // 如果是亚马逊订单, 检查平台费是否超高
                if (dcBaseOmsOrder.getPlatformType().toUpperCase().equals(PlatformType.Amazon.value())) {
                    checkPlatformFee(dcBaseOmsOrder);
                }
                //--begin 插入DB
                // 利润 = 销售额 -退款 -操作费 - 平台费 -头程-尾程(FBA费)- 处理费-采购成本
                BigDecimal totalAmountSalesRMB = dcBaseOmsOrder.getAmountSales().multiply(dcBaseOmsOrder.getSellerOrderExchangeRate()).setScale(5, RoundingMode.HALF_EVEN);
                BigDecimal totalCostFbaFeeRMB = dcBaseOmsOrder.getCostFbaFee().multiply(dcBaseOmsOrder.getSellerOrderExchangeRate()).setScale(5, RoundingMode.HALF_EVEN);
                BigDecimal totalCostPaypalFeeRMB = dcBaseOmsOrder.getCostPaypalFee().multiply(dcBaseOmsOrder.getSellerOrderExchangeRate()).setScale(5, RoundingMode.HALF_EVEN);
                BigDecimal totalAmountPrepaid = BigDecimal.ZERO;
                BigDecimal totalProfit = BigDecimal.ZERO;
                BigDecimal totalSkuCostLogistics = BigDecimal.ZERO;
                BigDecimal totalAmountGeneralCargo = BigDecimal.ZERO;//货值= 售价-物流-平台费, 只有普货才算货值, 不发货也算货值
                try {
                    DcBaseOmsSkuMapper omsSkuMapper = SessionUtil.getSession().getMapper(DcBaseOmsSkuMapper.class);
                    if (bailunSkuInfoMap.size() > 0) {
                        /*
                         * OMS过来的详细费用不用动
                         *  按比例算出SKU的售价(运费相关按重量比例， 其他费用按采购价比例)
                         *  利润 = 销售额 -退款 -操作费 - 平台费 -头程-尾程- 处理费-采购成本
                         *  FBA费用相当于FBA订单的尾程费
                         */
                        for (BailunSkuStructure bailunSkuStructure : bailunSkuInfoMap.values()) {
                            DcBaseOmsSku dcBaseOmsSku = bailunSkuStructure.getDcBaseOmsSku();
                            DcBaseWarehouse dcBaseWarehouse = bailunSkuStructure.getDcBaseWarehouse();
                            dcBaseOmsSku.setRatioPrice(bailunSkuStructure.getSkuCostRatio());
                            dcBaseOmsSku.setRatioWeight(bailunSkuStructure.getSkuWeightRatio());
                            //SKU总收入
                            BigDecimal skuAmountTotal = bailunSkuStructure.getSkuCostRatio().multiply(dcBaseOmsOrder.getAmountTotal()).setScale(5, RoundingMode.HALF_EVEN);
                            //SKU退款
                            BigDecimal skuAmountRefund = bailunSkuStructure.getSkuCostRatio().multiply(dcBaseOmsOrder.getAmountRefund()).setScale(5, RoundingMode.HALF_EVEN);
                            //SKU商品收入
                            BigDecimal skuAmountProduct = bailunSkuStructure.getSkuCostRatio().multiply(dcBaseOmsOrder.getAmountProduct()).setScale(5, RoundingMode.HALF_EVEN);
                            BigDecimal skuAmountProductRMB = bailunSkuStructure.getSkuCostRatio().multiply(dcBaseOmsOrder.getAmountProduct()).multiply(dcBaseOmsOrder.getSellerOrderExchangeRate()).setScale(5, RoundingMode.HALF_EVEN);
                            //SKU礼品包装收入
                            BigDecimal skuGiftAmountFee = bailunSkuStructure.getSkuCostRatio().multiply(dcBaseOmsOrder.getAmountGiftWrap()).setScale(5, RoundingMode.HALF_EVEN);
                            //SKU调整收入
                            BigDecimal skuAmountAdjustment = bailunSkuStructure.getSkuCostRatio().multiply(dcBaseOmsOrder.getAmountAdjustment()).setScale(5, RoundingMode.HALF_EVEN);
                            //SKU税费收入
                            BigDecimal skuAmountTax = bailunSkuStructure.getSkuCostRatio().multiply(dcBaseOmsOrder.getAmountTax()).setScale(5, RoundingMode.HALF_EVEN);
                            //SKU运费收入
                            BigDecimal skuAmountShipping = bailunSkuStructure.getSkuWeightRatio().multiply(dcBaseOmsOrder.getAmountShipping()).setScale(5, RoundingMode.HALF_EVEN);
                            //SKU销售额 = 将总销售额按比例摊分到SKU-原币种, SKU可能有多个
                            BigDecimal skuAmountSales = bailunSkuStructure.getSkuCostRatio().multiply(dcBaseOmsOrder.getAmountSales()).setScale(5, RoundingMode.HALF_EVEN);
                            //单个SKU售价-原币种
                            BigDecimal skuSalesPrice = bailunSkuStructure.getSkuQuantityOrderd() > 0 ? skuAmountSales.divide(BigDecimal.valueOf(bailunSkuStructure.getSkuQuantityOrderd()), 5, RoundingMode.HALF_EVEN) : BigDecimal.ZERO;
                            //SKU平台费-原币种
                            BigDecimal skuCostPlatformFee = bailunSkuStructure.getSkuCostRatio().multiply(dcBaseOmsOrder.getCostPlatformFee()).setScale(5, RoundingMode.HALF_EVEN);
                            BigDecimal skuCostPlatformFeeRMB = bailunSkuStructure.getSkuCostRatio().multiply(costPlatformFeeRMB).setScale(5, RoundingMode.HALF_EVEN);
                            // SKUPaypal费
                            BigDecimal skuPaypalFee = bailunSkuStructure.getSkuCostRatio().multiply(dcBaseOmsOrder.getCostPaypalFee()).setScale(5, RoundingMode.HALF_EVEN);
                            BigDecimal skuPaypalFeeRmb = bailunSkuStructure.getSkuCostRatio().multiply(totalCostPaypalFeeRMB).setScale(5, RoundingMode.HALF_EVEN);
                            //如果不是国内仓并且发货了 就需要计算头程费
                            totalCostFirst = caculateCostFirst(dcBaseWarehouse, dcBaseOmsSku,bailunSkuStructure,totalCostFirst);
                            //下单数大于发货数, 判定为预收费-人民币
                            if (dcBaseOmsSku.getBailunSkuQuantityOrdered() != null && dcBaseOmsSku.getBailunSkuQuantityOrdered() > dcBaseOmsSku.getBailunSkuQuantityShipped()) {
                                BigDecimal quantityPrepared = BigDecimal.valueOf(dcBaseOmsSku.getBailunSkuQuantityOrdered() - dcBaseOmsSku.getBailunSkuQuantityShipped());
                                //这是未发货(预收)部分占的平台费
                                BigDecimal skuCostPlatformFeePreparedRMB = skuCostPlatformFeeRMB.multiply(quantityPrepared).divide(BigDecimal.valueOf(dcBaseOmsSku.getBailunSkuQuantityOrdered()), 5, RoundingMode.HALF_EVEN);
                                BigDecimal amountPrepaid = (skuSalesPrice.multiply(quantityPrepared).multiply(dcBaseOmsOrder.getSellerOrderExchangeRate()).subtract(skuCostPlatformFeePreparedRMB)).divide(quantityPrepared, 5, RoundingMode.HALF_EVEN);
                                dcBaseOmsSku.setAmountPrepaid(amountPrepaid.compareTo(BigDecimal.ZERO) == 1 ? amountPrepaid : BigDecimal.ZERO);
                                totalAmountPrepaid = totalAmountPrepaid.add(dcBaseOmsSku.getAmountPrepaid());
                            }
                            //促销费-原币种
                            BigDecimal skuCostPromotion = bailunSkuStructure.getSkuCostRatio().multiply(dcBaseOmsOrder.getCostPromotion()).setScale(5, RoundingMode.HALF_EVEN);
                            //SKU销售额人民币
                            BigDecimal skuAmountSalesRMB = skuAmountSales.multiply(dcBaseOmsOrder.getSellerOrderExchangeRate()).setScale(5, RoundingMode.HALF_EVEN);
                            BigDecimal unitSkuAmountSalesRMB = BigDecimal.ZERO;
                            //FBA费-人民币
                            BigDecimal skuCostFbaFeeRMB = dcBaseOmsSku.getCostFbaFee().multiply(dcBaseOmsOrder.getSellerOrderExchangeRate()).setScale(5, RoundingMode.HALF_EVEN);
                            //百伦处理费
                            BigDecimal skuCostHandleBailun = bailunSkuStructure.getSkuWeightRatio().multiply(dcBaseOmsOrder.getCostHandleBailun()).setScale(5, RoundingMode.HALF_EVEN);
                            //百伦LMS物流费-在CostTail(尾程费-真实费用)拿不到之前就用它, 这是SKU总重量占比的费用
                            BigDecimal skuCostLogistics = bailunSkuStructure.getSkuWeightRatio().multiply(totalCostLogistics).setScale(5, RoundingMode.HALF_EVEN);
                            /*
                             * 将按比例摊分的费用算到单个SKU
                             * 摊分方法: 除以下单数
                             */
                            BigDecimal quantityOrderdDecimal = BigDecimal.valueOf(bailunSkuStructure.getSkuQuantityOrderd());
                            BigDecimal bailunSkuQuantityShippedDecimal = BigDecimal.valueOf(dcBaseOmsSku.getBailunSkuQuantityShipped());
                            BigDecimal rmbCost = BigDecimal.ZERO;
                            BigDecimal skuAmountGeneralCargo = BigDecimal.ZERO;
                            //货值= 售价-物流-平台费,只有普货才算货值, 不发货也算货值-- 这里放单个SKU的货值
                            if (bailunSkuStructure.getGeneralCargo() != null && bailunSkuStructure.getGeneralCargo()) {
                                skuAmountGeneralCargo = skuAmountProductRMB.subtract(skuCostLogistics).subtract(skuCostPlatformFeeRMB);
                                totalAmountGeneralCargo = totalAmountGeneralCargo.add(skuAmountGeneralCargo);
                            }
                            if (quantityOrderdDecimal.compareTo(BigDecimal.ZERO) == 1) {
                                dcBaseOmsSku.setAmountGeneralCargo(skuAmountGeneralCargo.divide(quantityOrderdDecimal, 5, RoundingMode.HALF_EVEN));
                                dcBaseOmsSku.setCostLogistics(bailunSkuQuantityShippedDecimal.compareTo(BigDecimal.ZERO) == 1? skuCostLogistics.divide(bailunSkuQuantityShippedDecimal, 5, RoundingMode.HALF_EVEN) : BigDecimal.ZERO);
                                dcBaseOmsSku.setAmountTotal(skuAmountTotal.divide(quantityOrderdDecimal, 5, RoundingMode.HALF_EVEN));
                                dcBaseOmsSku.setAmountProduct(skuAmountProduct.divide(quantityOrderdDecimal, 5, RoundingMode.HALF_EVEN));
                                dcBaseOmsSku.setAmountAdjustment(skuAmountAdjustment.divide(quantityOrderdDecimal, 5, RoundingMode.HALF_EVEN));
                                dcBaseOmsSku.setAmountTax(skuAmountTax.divide(quantityOrderdDecimal, 5, RoundingMode.HALF_EVEN));
                                dcBaseOmsSku.setAmountGiftWrap(skuGiftAmountFee.divide(quantityOrderdDecimal, 5, RoundingMode.HALF_EVEN));
                                dcBaseOmsSku.setCostPaypalFee(skuPaypalFee.divide(quantityOrderdDecimal, 5, RoundingMode.HALF_EVEN));
                                dcBaseOmsSku.setCostHandleBailun(skuCostHandleBailun.divide(quantityOrderdDecimal, 5, RoundingMode.HALF_EVEN));
                                dcBaseOmsSku.setCostPlatformFee(skuCostPlatformFee.divide(quantityOrderdDecimal, 5, RoundingMode.HALF_EVEN));
                                dcBaseOmsSku.setCostHandlePlatform(dcBaseOmsSku.getCostHandlePlatform().divide(quantityOrderdDecimal, 5, RoundingMode.HALF_EVEN));
                                dcBaseOmsSku.setCostFbaFee(dcBaseOmsSku.getCostFbaFee().divide(quantityOrderdDecimal, 5, RoundingMode.HALF_EVEN));
                                dcBaseOmsSku.setCostTail(dcBaseOmsSku.getCostTail().divide(quantityOrderdDecimal, 5, RoundingMode.HALF_EVEN));
                                dcBaseOmsSku.setCostProduct(bailunSkuStructure.getBailunSkuUnitPrice());
                                dcBaseOmsSku.setCostPromotion(skuCostPromotion.divide(quantityOrderdDecimal, 5, RoundingMode.HALF_EVEN));
                                dcBaseOmsSku.setAmountSales(skuAmountSales.subtract(skuCostPromotion).divide(quantityOrderdDecimal, 5, RoundingMode.HALF_EVEN));
                                dcBaseOmsSku.setAmountShipping(skuAmountShipping.divide(quantityOrderdDecimal, 5, RoundingMode.HALF_EVEN));
                                dcBaseOmsSku.setAmountRefund(skuAmountRefund.divide(quantityOrderdDecimal, 5, RoundingMode.HALF_EVEN));

                                //单个SKU的销售额
                                unitSkuAmountSalesRMB = skuAmountSalesRMB.divide(quantityOrderdDecimal, 5, RoundingMode.HALF_EVEN);
                                //单个SKU的支出
                                rmbCost = dcBaseOmsSku.getCostHandleBailun()//处理费
                                        .add(skuCostPlatformFeeRMB.divide(quantityOrderdDecimal, 5, RoundingMode.HALF_EVEN))//平台费
                                        .add(dcBaseOmsSku.getCostHandlePlatform())//第三方仓操作费
                                        .add(skuCostFbaFeeRMB.divide(quantityOrderdDecimal, 5, RoundingMode.HALF_EVEN))//FBA费
                                        .add(dcBaseOmsSku.getCostFirst())//头程费
                                        .add(dcBaseOmsSku.getCostLogistics())//百伦LMS物流费
                                        .add(dcBaseOmsSku.getCostProduct())//采购成本
                                        .add(skuPaypalFeeRmb.divide(quantityOrderdDecimal, 5, RoundingMode.HALF_EVEN))//Paypal费
                                        .setScale(5, RoundingMode.HALF_EVEN);

                            }
                            //单个SKU的费用支出
                            dcBaseOmsSku.setCostTotal(rmbCost);
                            //利润都转为人民币计算
                            BigDecimal unitSkuProfit = unitSkuAmountSalesRMB.subtract(dcBaseOmsSku.getCostTotal());
                            //只有发货的SKU才去算订单维度利润
                            BigDecimal skuShippedProfit = unitSkuProfit.multiply(bailunSkuQuantityShippedDecimal);
                            totalSkuCostLogistics = totalSkuCostLogistics.add(dcBaseOmsSku.getCostLogistics().multiply(bailunSkuQuantityShippedDecimal));
                            totalProfit = totalProfit.add(skuShippedProfit);
                            //SKU只放单个利润
                            dcBaseOmsSku.setProfitTotal(unitSkuProfit);
                            dcBaseOmsSku.setHasInnersale(dcBaseOmsOrder.getHasInnersale());
                            if (skuAmountSalesRMB.compareTo(BigDecimal.ZERO) == 0) {
                                dcBaseOmsSku.setProfitRate(BigDecimal.ZERO);
                            } else {
                                dcBaseOmsSku.setProfitRate(dcBaseOmsSku.getProfitTotal().divide(skuAmountSalesRMB, 5, RoundingMode.HALF_EVEN));
                            }
                            dcBaseOmsSku.setGmtModified(LocalDateTime.now());
                            int i = omsSkuMapper.updateByExampleSelective(dcBaseOmsSku, DcBaseOmsSkuExample.newAndCreateCriteria().andBailunSkuEqualTo(dcBaseOmsSku.getBailunSku()).andOriginOrderIdEqualTo(dcBaseOmsSku.getOriginOrderId()).andBailunAccountIdEqualTo(dcBaseOmsSku.getBailunAccountId()).example());
                            if (i == 0) {
                                omsSkuMapper.insertSelective(dcBaseOmsSku);
                            }
                        }
                    }
                    //预付款-预收金额-人民币
                    dcBaseOmsOrder.setAmountPrepaid(totalAmountPrepaid);
                    dcBaseOmsOrder.setCostFirst(totalCostFirst);
                    dcBaseOmsOrder.setCostLogistics(totalSkuCostLogistics);
                    dcBaseOmsOrder.setAmountGeneralCargo(totalAmountGeneralCargo);
                    /*
                     * OMS过来的详细费用不用动
                     * 这边处理新增了
                     *  利润 = 销售额 -退款 -操作费 - 平台费 -头程-尾程- 处理费-采购成本
                     */
                    //退款在匹配退款单的时候算
                    BigDecimal costTotal = dcBaseOmsOrder.getCostHandleBailun() //处理费
                            .add(costPlatformFeeRMB) //平台费
                            .add(dcBaseOmsOrder.getCostHandlePlatform())//第三方仓操作费
                            .add(totalCostFbaFeeRMB)//FBA操作费
                            .add(dcBaseOmsOrder.getCostFirst()) //头程费
                            .add(dcBaseOmsOrder.getCostLogistics())//LMS物流费用
                            .add(dcBaseOmsOrder.getCostProduct())//采购成本
                            .add(totalCostPaypalFeeRMB)//Paypal费
                            .setScale(5, RoundingMode.HALF_EVEN);
                    dcBaseOmsOrder.setCostTotal(costTotal);
                    //非OMS部分的利润直接减法运算
                    dcBaseOmsOrder.setProfitTotal(totalProfit);
                    //计算利润率
                    if (totalAmountSalesRMB.compareTo(BigDecimal.ZERO) == 0) {
                        dcBaseOmsOrder.setProfitRate(BigDecimal.ZERO);
                    } else {
                        dcBaseOmsOrder.setProfitRate(dcBaseOmsOrder.getProfitTotal().divide(totalAmountSalesRMB, 5, RoundingMode.HALF_EVEN));
                    }
                    dcBaseOmsOrder.setGmtModified(LocalDateTime.now());
                    DcBaseOmsOrderMapper omsOrderMapper = SessionUtil.getSession().getMapper(DcBaseOmsOrderMapper.class);
                    int i = omsOrderMapper.updateByExampleSelective(dcBaseOmsOrder, DcBaseOmsOrderExample.newAndCreateCriteria().andOriginOrderIdEqualTo(dcBaseOmsOrder.getOriginOrderId()).andBailunAccountIdEqualTo(dcBaseOmsOrder.getBailunAccountId()).example());
                    if (i == 0) {
                        omsOrderMapper.insertSelective(dcBaseOmsOrder);
                    }
                    /**
                     * 这里存平台维度的东西到表里
                     * 留作他用, 不参与计算
                     */
                    List<PlatformSku> platformSkuList = omsResult.getPlatformSku();
                    DcBaseOmsPlatformSku dcBaseOmsPlatformSku = new DcBaseOmsPlatformSku();
                    DcBaseOmsPlatformSkuMapper mapper = SessionUtil.getSession().getMapper(DcBaseOmsPlatformSkuMapper.class);
                    if (platformSkuList != null && platformSkuList.size() > 0) {
                        for (PlatformSku platformSkuInfo : platformSkuList) {
                            if (StringUtils.isNotBlank(platformSkuInfo.getPlatformSku())) {
                                BeanUtils.copyProperties(dcBaseOmsPlatformSku, dcBaseOmsOrder);
                                dcBaseOmsPlatformSku.setPlatformSku(platformSkuInfo.getPlatformSku());
                                dcBaseOmsPlatformSku.setItemId(platformSkuInfo.getPlatformSkuItemId());
                                dcBaseOmsPlatformSku.setPlatformSkuUnitPrice(platformSkuInfo.getPlatformSkuUnitPrice() != null ? platformSkuInfo.getPlatformSkuUnitPrice().getAmount() : BigDecimal.ZERO);
                                dcBaseOmsPlatformSku.setPlatformSkuQuantityOrdered(platformSkuInfo.getPlatformSkuQuantityOrdered());
                                dcBaseOmsPlatformSku.setPlatformSkuQuantityShipped(platformSkuInfo.getPlatformSkuQuantityShipped());
                                dcBaseOmsPlatformSku.setPlatformSkuTitleCn(platformSkuInfo.getPlatformSkuTitleCn());
                                dcBaseOmsPlatformSku.setPlatformSkuTitleEn(platformSkuInfo.getPlatformSkuTitleEn());
                                String site = StringUtils.isNotBlank(dcBaseOmsOrder.getWebsite()) ? dcBaseOmsOrder.getWebsite().toUpperCase().replaceAll(" ", "") : "";
                                dcBaseOmsPlatformSku.setCreateTimeSite(timeZoneChange(site, dcBaseOmsOrder.getCreateTime()));
                                dcBaseOmsPlatformSku.setPaidTimeSite(timeZoneChange(site, dcBaseOmsOrder.getPaidTime()));
                                dcBaseOmsPlatformSku.setPayTimeSite(timeZoneChange(site, dcBaseOmsOrder.getPayTime()));
                                dcBaseOmsPlatformSku.setCompanyId(omsResult.getCompanyId());
                                int ii = mapper.updateByExampleSelective(dcBaseOmsPlatformSku, DcBaseOmsPlatformSkuExample.newAndCreateCriteria().andPlatformSkuEqualTo(dcBaseOmsPlatformSku.getPlatformSku()).andOriginOrderIdEqualTo(dcBaseOmsPlatformSku.getOriginOrderId()).andBailunAccountIdEqualTo(dcBaseOmsPlatformSku.getBailunAccountId()).example());
                                if (ii == 0) {
                                    mapper.insertSelective(dcBaseOmsPlatformSku);
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new RuntimeException(ExceptionUtil.transform(e), e);
                } finally {
                    SessionUtil.closeSession();
                }
            }
        }
    }

    /**
     * 如果不是国内仓, 发货数>0, 就来取头程费
     *
     * @param dcBaseWarehouse
     * @param dcBaseOmsSku
     * @param bailunSkuStructure
     * @param totalCostFirst
     * @return
     */
    private BigDecimal caculateCostFirst(DcBaseWarehouse dcBaseWarehouse, DcBaseOmsSku dcBaseOmsSku,  BailunSkuStructure bailunSkuStructure, BigDecimal totalCostFirst) {
        if (dcBaseWarehouse != null && !dcBaseWarehouse.getHqType().equals(Constant.DOMESTIC_WAREHOUSE) && dcBaseOmsSku.getBailunSkuQuantityShipped() > 0) {
            DcMidCostFirstMapper mapper = SessionUtil.getSession().getMapper(DcMidCostFirstMapper.class);
            DcMidCostFirst dcMidCostFirst = mapper.selectOneByExample(DcMidCostFirstExample.newAndCreateCriteria().andBailunSkuEqualTo(dcBaseOmsSku.getBailunSku()).andWarehouseCodeEqualTo(dcBaseWarehouse.getWarehouseCode()).example());
            //如果dcMidCostFirst查不到,铭哥那边商量好了，头程0的，先跑调拨单，若是真是之前的SKU无法找到的，那就取值38元1KG来计算。
            if (dcMidCostFirst == null) {
                dcMidCostFirst = new DcMidCostFirst();
                dcMidCostFirst.setCostFirst(bailunSkuStructure.getBailunSkuWeight().multiply(Constant.COST_FIRST_PRICE).setScale(5, RoundingMode.HALF_EVEN));
            }
            dcBaseOmsSku.setCostFirst(dcMidCostFirst.getCostFirst());
            //GBBLJW这个仓库有些SKU是单独配置的单价
            if ("GBBLJW".equals(dcBaseWarehouse.getWarehouseCode())) {
                DcBaseOmsConfigCostFirstMapper costFirstMapper = SessionUtil.getSession().getMapper(DcBaseOmsConfigCostFirstMapper.class);
                DcBaseOmsConfigCostFirst omsConfigCostFirst = costFirstMapper.selectOneByExample(DcBaseOmsConfigCostFirstExample.newAndCreateCriteria().andCompanyIdEqualTo(dcBaseOmsSku.getCompanyId()).andBailunSkuEqualTo(dcBaseOmsSku.getBailunSku()).andWarehouseCodeEqualTo(dcBaseOmsSku.getWarehouseCode()).example());
                if (omsConfigCostFirst != null) {
                    dcBaseOmsSku.setCostFirst(bailunSkuStructure.getBailunSkuWeight().multiply(omsConfigCostFirst.getPrice()).setScale(5, RoundingMode.HALF_EVEN));
                }
            }
            totalCostFirst = totalCostFirst.add(dcBaseOmsSku.getCostFirst().multiply(BigDecimal.valueOf(dcBaseOmsSku.getBailunSkuQuantityShipped())));
        }
        return totalCostFirst;
    }

    private void hasS0(OmsResult omsResult, DcBaseOmsOrder dcBaseOmsOrder) {
        if (omsResult.getPlatformType().toUpperCase().equals(PlatformType.FBA.value()) && omsResult.getOriginOrderId().length() > 2) {
            String substring = omsResult.getOriginOrderId().substring(0, 2);
            dcBaseOmsOrder.setHasFbaS(false);
            if (substring.toUpperCase().equals("S0")) {
                dcBaseOmsOrder.setHasFbaS(true);
            }
        }

    }

    private void hasInnerSale(OmsResult omsResult, DcBaseOmsOrder dcBaseOmsOrder) {
        if (omsResult.getOriginOrderId().length() > 6) {
            String substring = omsResult.getOriginOrderId().substring(0, 6);
            dcBaseOmsOrder.setHasInnersale(false);
            if (substring.toLowerCase().equals("neigou")) {
                dcBaseOmsOrder.setHasInnersale(true);
            }
        }
    }

    private LocalDateTime timeZoneChange(String site, LocalDateTime localDateTime) {
        LocalDateTime timeZoneChangeTime = null;
        if (localDateTime != null) {
            switch (site) {
                case "AU"://澳大利亚
                    timeZoneChangeTime = localDateTime.atZone(ZoneId.of(ZoneId.SHORT_IDS.get("CTT")))
                            .withZoneSameInstant(ZoneId.of(ZoneId.SHORT_IDS.get("AET"))).toLocalDateTime();
                    break;
                case "DE"://德国
                case "ES"://西班牙
                case "FR"://法国
                case "IT"://意大利
                case "UK"://英国
                case "IE"://爱尔兰
                    timeZoneChangeTime = localDateTime.atZone(ZoneId.of(ZoneId.SHORT_IDS.get("CTT")))
                            .withZoneSameInstant(ZoneId.of("GMT")).toLocalDateTime();
                    break;
                case "JP"://日本
                    timeZoneChangeTime = localDateTime.atZone(ZoneId.of(ZoneId.SHORT_IDS.get("CTT")))
                            .withZoneSameInstant(ZoneId.of(ZoneId.SHORT_IDS.get("JST"))).toLocalDateTime();
                    break;
                case "IN"://印度
                    timeZoneChangeTime = localDateTime.atZone(ZoneId.of(ZoneId.SHORT_IDS.get("CTT")))
                            .withZoneSameInstant(ZoneId.of(ZoneId.SHORT_IDS.get("IST"))).toLocalDateTime();
                    break;
                case "BR"://巴西
                    timeZoneChangeTime = localDateTime.atZone(ZoneId.of(ZoneId.SHORT_IDS.get("CTT")))
                            .withZoneSameInstant(ZoneId.of(ZoneId.SHORT_IDS.get("AGT"))).toLocalDateTime();
                    break;
                case "RU"://俄罗斯
                    timeZoneChangeTime = localDateTime.atZone(ZoneId.of(ZoneId.SHORT_IDS.get("CTT")))
                            .withZoneSameInstant(ZoneId.of(ZoneId.SHORT_IDS.get("EAT"))).toLocalDateTime();
                    break;
                case "SE"://瑞典
                case "PL"://波兰
                case "CH"://瑞士
                case "NL"://荷兰
                case "BED"://比利时(荷兰)
                case "BEF"://比利时(法)
                case "AT"://奥地利
                    timeZoneChangeTime = localDateTime.atZone(ZoneId.of(ZoneId.SHORT_IDS.get("CTT")))
                            .withZoneSameInstant(ZoneId.of(ZoneId.SHORT_IDS.get("ECT"))).toLocalDateTime();
                    break;
                //东盟统一偏移UTC+8
                case "ID"://印尼
                case "TW"://台湾
                case "HK"://香港
                case "SG"://新加坡
                case "CN"://中国
                case "MY"://马来西亚
                case "PH"://菲律宾
                    timeZoneChangeTime = localDateTime;
                    break;
                case "":
                case "CA"://加拿大
                case "CAFR"://法属加拿大
                case "MX"://墨西哥
                case "US"://美国
                case "EBAYMOTORS"://美国
                case "GLOBAL"://全球的统一选美国
                default:
                    timeZoneChangeTime = localDateTime.atZone(ZoneId.of(ZoneId.SHORT_IDS.get("CTT")))
                            .withZoneSameInstant(ZoneId.of(ZoneId.SHORT_IDS.get("PST"))).toLocalDateTime();
            }

        }
        return timeZoneChangeTime;
    }

    private void listOrderExceptions(OmsResult omsResult, DcBaseOmsOrder dcBaseOmsOrder) {
        dcBaseOmsOrder.setHasScalp(false);
        List<OrderException> orderExceptions = omsResult.getOrderExceptions();
        if (orderExceptions != null && orderExceptions.size() > 0) {
            for (OrderException orderException : orderExceptions) {
                //type是Scalp 且status只有UnHandle，Handling才代表是刷单的才是刷单订单
                if (StringUtils.isNotBlank(orderException.getExceptionType()) && StringUtils.isNotBlank(orderException.getStatus()) && orderException.getExceptionType().equals(OrderExceptionType.Scalp.value())) {
                    if (orderException.getStatus().equals(OrderExceptionStatus.UnHandle.value()) || orderException.getStatus().equals(OrderExceptionStatus.Handling.value())){
                        dcBaseOmsOrder.setHasScalp(true);
                    }
                }
            }
        }
    }

    private BigDecimal getTotalCostLogistics(List<LogisticsItem> logisticsItems, HashMap<String, Logistics> logisticsHashMap) {
        BigDecimal totalCostLogistics = BigDecimal.ZERO;
        if (logisticsItems != null && logisticsItems.size() > 0) {
            for (LogisticsItem logisticsItem : logisticsItems) {
                if (logisticsItem.getLogisticsCost() != null && logisticsItem.getLogisticsCost().getAmount() != null) {
                    totalCostLogistics = totalCostLogistics.add(logisticsItem.getLogisticsCost().getAmount());
                }
                if (logisticsItem.getWarehouse() != null && StringUtils.isNotBlank(logisticsItem.getWarehouse().getWarehouseCode())) {
                    logisticsHashMap.put(logisticsItem.getWarehouse().getWarehouseCode(), logisticsItem.getLogisticsMethod());
                }
            }
        }
        return totalCostLogistics;
    }

    private void deleteSku(DcBaseOmsOrder dcBaseOmsOrder) {
        try {
            DcBaseOmsOrderMapper mapper = SessionUtil.getSession().getMapper(DcBaseOmsOrderMapper.class);
            mapper.logicDeleteOmsSku(dcBaseOmsOrder);
            mapper.logicDeleteOmsPick(dcBaseOmsOrder);
//            DcBaseCrmRefundMapper crmRefundMapper = SessionUtil.getSession().getMapper(DcBaseCrmRefundMapper.class);
//            crmRefundMapper.updateLinked(dcBaseOmsOrder.getOriginOrderId(), dcBaseOmsOrder.getBailunAccountId());
        } catch (Exception e) {
            throw new RuntimeException(ExceptionUtil.transform(e), e);
        } finally {
            SessionUtil.closeSession();
        }
    }

    /**
     * 计算百伦的处理费用
     * 阶梯计费
     *
     * @param dcBaseOmsOrder
     */
    private void caculateBailunHandleFee(DcBaseOmsOrder dcBaseOmsOrder,  BailunSkuCumulative bailunSkuCumulative) {
        BigDecimal costBailunHandle = BigDecimal.ONE;//海外仓和FBA 的，都是直接1元一个单
        if(bailunSkuCumulative.getDomesticOrOverseas()) {
            switch (bailunSkuCumulative.getTotalQuantity()) {
                case 0:
                    costBailunHandle = BigDecimal.ZERO;
                    break;
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                case 10:
                    costBailunHandle = BigDecimal.valueOf(0.3).multiply(BigDecimal.valueOf(bailunSkuCumulative.getTotalQuantity() - 1)).add(BigDecimal.ONE);
                    break;
                default:
                    costBailunHandle = BigDecimal.valueOf(3.7);//超过10个只取10个的费用
            }
        }
        dcBaseOmsOrder.setCostHandleBailun(costBailunHandle);
    }

    private BailunSkuCumulative getBailunSkuCumulative(OmsResult omsResult) {
        BailunSkuCumulative bailunSkuCumulative = new BailunSkuCumulative();
        bailunSkuCumulative.setDomesticOrOverseas(Boolean.FALSE);
        bailunSkuCumulative.setMaxSkuLong(BigDecimal.ZERO);
        bailunSkuCumulative.setMaxSkuWidth(BigDecimal.ZERO);
        bailunSkuCumulative.setMaxSkuHight(BigDecimal.ZERO);
        bailunSkuCumulative.setTotalWeight(BigDecimal.ZERO);
        bailunSkuCumulative.setTotalQuantity(0);
        for (BailunSku bailunSku : omsResult.getBailunSku()) {
            if (bailunSku.getBailunSkuWeight() == null) {
                bailunSku.setBailunSkuWeight(BigDecimal.ZERO);
            }
            bailunSkuCumulative.setTotalWeight(bailunSkuCumulative.getTotalWeight() != null ?
                    bailunSku.getBailunSkuWeight().multiply(BigDecimal.valueOf(bailunSku.getBailunSkuQuantityOrdered())).add(bailunSkuCumulative.getTotalWeight())
                    : bailunSku.getBailunSkuWeight().multiply(BigDecimal.valueOf(bailunSku.getBailunSkuQuantityOrdered())));
            bailunSkuCumulative.setTotalQuantity(bailunSkuCumulative.getTotalQuantity() != null ? bailunSku.getBailunSkuQuantityOrdered() + bailunSkuCumulative.getTotalQuantity() : bailunSku.getBailunSkuQuantityOrdered());
            if (PlatformType.FBA.value().equals(omsResult.getPlatformType().toUpperCase())) {
                if (!StringUtils.isEmpty(bailunSku.getBailunSkuSize())) {
                    // 该正则表达式可以匹配所有的数字 包括负数
                    String[] split = bailunSku.getBailunSkuSize().split(",");
                    BigDecimal skuLong = BigDecimal.ZERO;
                    BigDecimal skuWidth = BigDecimal.ZERO;
                    BigDecimal skuHeight = BigDecimal.ZERO;
                    if (split.length >= 3) {
                        if (!StringUtils.isEmpty(split[0]) && CommonConstant.NUMBER_AND_DECIMAL.matcher(split[0]).matches()) {
                            skuLong = new BigDecimal(split[0]);
                        }
                        if (!StringUtils.isEmpty(split[1]) && CommonConstant.NUMBER_AND_DECIMAL.matcher(split[1]).matches()) {
                            skuWidth = new BigDecimal(split[1]);
                        }
                        if (!StringUtils.isEmpty(split[2]) && CommonConstant.NUMBER_AND_DECIMAL.matcher(split[2]).matches()) {
                            skuHeight = new BigDecimal(split[2]);
                        }
                    }
                    if (skuLong.compareTo(bailunSkuCumulative.getMaxSkuLong()) >= 0)
                        bailunSkuCumulative.setMaxSkuLong(skuLong);
                    if (skuWidth.compareTo(bailunSkuCumulative.getMaxSkuWidth()) >= 0)
                        bailunSkuCumulative.setMaxSkuWidth(skuWidth);
                    if (skuHeight.compareTo(bailunSkuCumulative.getMaxSkuHight()) >= 0)
                        bailunSkuCumulative.setMaxSkuLong(skuHeight);
                }
            }
        }
        return bailunSkuCumulative;
    }

    /**
     * 拿订单仓库信息
     * 如果是FBA, 就根据accountId查仓库
     * 不是FBA, 先从订单SKU里取, 取不到就去物流信息里拿
     *
     * @param bailunSkuObj
     * @param omsResult
     * @return
     */
    private DcBaseWarehouse getDcBaseWarehouse(BailunSku bailunSkuObj, OmsResult omsResult) {
        DcBaseWarehouse dcBaseWarehouse = null;
        try {
            DcBaseWarehouseMapper baseWarehouseMapper = SessionUtil.getSession().getMapper(DcBaseWarehouseMapper.class);
            /*
             * 如果是FBA订单, 先要看这个SKU是不是共享库存
             * 再看SKU在配置表dc_base_stock_config_fba,是否有配置
             * 配置
             */
            if (PlatformType.FBA.value().equals(omsResult.getPlatformType())) {
                dcBaseWarehouse = baseWarehouseMapper.selectOneByExample(DcBaseWarehouseExample.newAndCreateCriteria().andBailunAccountIdEqualTo(omsResult.getSeller().getBailunAccountId()).example());
            } else {
                if (StringUtils.isNotBlank(bailunSkuObj.getWarehouseCode())) {
                    dcBaseWarehouse = baseWarehouseMapper.selectOneByExample(DcBaseWarehouseExample.newAndCreateCriteria().andWarehouseCodeEqualTo(bailunSkuObj.getWarehouseCode()).example());
                } else if (omsResult.getLogisticsItems() != null && omsResult.getLogisticsItems().size() > 0 && omsResult.getLogisticsItems().get(0).getWarehouse() != null && omsResult.getLogisticsItems().get(0).getWarehouse().getWarehouseCode() != null) {
                    dcBaseWarehouse = baseWarehouseMapper.selectOneByExample(DcBaseWarehouseExample.newAndCreateCriteria().andWarehouseCodeEqualTo(omsResult.getLogisticsItems().get(0).getWarehouse().getWarehouseCode()).example());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(ExceptionUtil.transform(e), e);
        } finally {
            SessionUtil.closeSession();
        }
        return dcBaseWarehouse;
    }


    /**
     * 处理配货单, 多个配货单的SKU可能重复
     * 每个SKU 单独存放, 方便导数据
     * 返回已发货的SKU 总成本
     */
    private void handPickingOrder(DcBaseOmsOrder dcBaseOmsOrder, OmsResult omsResult, Map<String, BailunSkuStructure> skuStructureMap) {
        List<PickingOrder> pickingOrderList = omsResult.getPickingOrder();
        BigDecimal totalCostPackaging = BigDecimal.ZERO;
        BigDecimal totalCostShipping = BigDecimal.ZERO;
        if (pickingOrderList != null && pickingOrderList.size() > 0) {
            /*
             * 遍历配货单信息
             */
            for (PickingOrder pickingOrder : pickingOrderList) {
                BigDecimal skuCostShipping = pickingOrder.getCostShipping() != null ? pickingOrder.getCostShipping() : BigDecimal.ZERO;
                BigDecimal skuCostPackaging = pickingOrder.getCostPackaging() != null ? pickingOrder.getCostPackaging() : BigDecimal.ZERO;
                BigDecimal outboundWeight = pickingOrder.getOutboundWeight() != null ? pickingOrder.getOutboundWeight() : BigDecimal.ZERO;
                totalCostPackaging = totalCostPackaging.add(skuCostPackaging);//总的第三方操作费
                totalCostShipping = totalCostShipping.add(skuCostShipping);//总的第三方发货费用
                List<PickingItem> pickingItems = pickingOrder.getPickingItems();
                if (pickingItems != null && pickingItems.size() > 0) {
                    BigDecimal pickOrderTotalWeight = BigDecimal.ZERO;
                    for (PickingItem pickingItem : pickingItems) {
                        BailunSkuStructure bailunSkuStructure = skuStructureMap.get(pickingItem.getBailunSku());
                        if (bailunSkuStructure != null) {
                            pickOrderTotalWeight = pickOrderTotalWeight.add(bailunSkuStructure.getBailunSkuWeight().multiply(BigDecimal.valueOf(pickingItem.getQuantityPicked())));
                        }
                    }
                    /*
                     * 遍历配货单的所有SKU
                     */
                    for (PickingItem pickingItem : pickingItems) {
                        BigDecimal quantityPickedBigDecimal = BigDecimal.valueOf(pickingItem.getQuantityPicked());
                        DcBaseOmsPick dcBaseOmsPick = new DcBaseOmsPick();
                        BailunSkuStructure bailunSkuStructure = skuStructureMap.get(pickingItem.getBailunSku());
                        BigDecimal weightRatio = bailunSkuStructure != null && pickOrderTotalWeight.compareTo(BigDecimal.ZERO) == 1 ? bailunSkuStructure.getBailunSkuWeight().multiply(quantityPickedBigDecimal).divide(pickOrderTotalWeight, 5, RoundingMode.HALF_EVEN) : BigDecimal.ONE;
                        dcBaseOmsPick.setHasDelete(false);
                        dcBaseOmsPick.setCostPackaging(skuCostPackaging);
                        dcBaseOmsPick.setCostShipping(skuCostShipping);
                        dcBaseOmsPick.setOutboundWeight(outboundWeight);
                        dcBaseOmsPick.setBailunSkuCostPackaging(skuCostPackaging.multiply(weightRatio).setScale(5, RoundingMode.HALF_EVEN));
                        dcBaseOmsPick.setBailunSkuCostShipping(skuCostShipping.multiply(weightRatio).setScale(5, RoundingMode.HALF_EVEN));
                        //从千克转为克, 且放单位SKU重量
                        dcBaseOmsPick.setBailunSkuOutboundWeight(pickingItem.getQuantityPicked() > 0 ? outboundWeight.multiply(weightRatio).multiply(Constant.RATE_1000).divide(quantityPickedBigDecimal, 5, RoundingMode.HALF_EVEN) : BigDecimal.ZERO);
                        dcBaseOmsPick.setBailunSku(pickingItem.getBailunSku());
                        dcBaseOmsPick.setQuantityPicked(pickingItem.getQuantityPicked());
                        dcBaseOmsPick.setQuantityShipped(pickingItem.getQuantityShipped());
                        dcBaseOmsPick.setDeclarePrice(pickingItem.getDeclarePrice());
                        dcBaseOmsPick.setOriginOrderId(omsResult.getOriginOrderId());
                        dcBaseOmsPick.setBailunAccountId(omsResult.getSeller().getBailunAccountId());
                        dcBaseOmsPick.setBailunOrderId(omsResult.getBailunOrderId());
                        if (pickingOrder.getLogistics() != null) {
                            dcBaseOmsPick.setLogisticsOrderId(pickingOrder.getLogistics().getLogisticsCode());
                            dcBaseOmsPick.setLogisticsOrderName(pickingOrder.getLogistics().getLogisticsName());
                        }
                        dcBaseOmsPick.setCreateTime(pickingOrder.getCreateTime());
                        dcBaseOmsPick.setShippingTime(pickingOrder.getShippingTime());
                        if (pickingOrder.getWarehouse() != null) {
                            dcBaseOmsPick.setWarehouseCode(pickingOrder.getWarehouse().getWarehouseCode());
                            dcBaseOmsPick.setWarehouseName(pickingOrder.getWarehouse().getWarehouseName());
                        }
                        dcBaseOmsPick.setPickOrderId(pickingOrder.getPickOrderId());
                        dcBaseOmsPick.setShippingStatus(pickingOrder.getShippingStatus());
                        dcBaseOmsPick.setTrackingOrderId(pickingOrder.getTrackingOrderId());
                        dcBaseOmsPick.setTrackingProvider(pickingOrder.getTrackingProvider());
                        dcBaseOmsPick.setCompanyId(omsResult.getCompanyId());
                        dcBaseOmsPick.setHasPushed(pickingOrder.getHasPushed() == null ? false : pickingOrder.getHasPushed());
                        if (bailunSkuStructure != null) {
                            DcBaseOmsSku dcBaseOmsSku = bailunSkuStructure.getDcBaseOmsSku();
                            dcBaseOmsSku.setBailunSkuQuantityShipped(dcBaseOmsSku.getBailunSkuQuantityShipped() != null ? dcBaseOmsSku.getBailunSkuQuantityShipped() + dcBaseOmsPick.getQuantityShipped() : dcBaseOmsPick.getQuantityShipped());
                            dcBaseOmsSku.setBailunSkuQuantityPicked(dcBaseOmsSku.getBailunSkuQuantityPicked() != null ? dcBaseOmsSku.getBailunSkuQuantityPicked() + dcBaseOmsPick.getQuantityPicked() : dcBaseOmsPick.getQuantityPicked());
                            if(dcBaseOmsPick.getHasPushed()) {
                                dcBaseOmsSku.setBailunSkuQuantityPushed(dcBaseOmsSku.getBailunSkuQuantityPushed() != null ? dcBaseOmsSku.getBailunSkuQuantityPushed() + dcBaseOmsPick.getQuantityPicked() : dcBaseOmsPick.getQuantityPicked());
                            }
                            dcBaseOmsSku.setCostHandlePlatform(dcBaseOmsSku.getCostHandlePlatform() != null ? dcBaseOmsSku.getCostHandlePlatform().add(dcBaseOmsPick.getBailunSkuCostPackaging()) : dcBaseOmsPick.getBailunSkuCostPackaging());
                            dcBaseOmsSku.setCostTail(dcBaseOmsSku.getCostTail() != null ? dcBaseOmsSku.getCostTail().add(dcBaseOmsPick.getBailunSkuCostShipping()) : dcBaseOmsPick.getBailunSkuCostShipping());
                        }
                        try {
                            DcBaseOmsPickMapper mapper = SessionUtil.getSession().getMapper(DcBaseOmsPickMapper.class);
                            int i = mapper.updateByExampleSelective(dcBaseOmsPick, DcBaseOmsPickExample.newAndCreateCriteria().andOriginOrderIdEqualTo(dcBaseOmsPick.getOriginOrderId())
                                    .andBailunAccountIdEqualTo(dcBaseOmsPick.getBailunAccountId()).andPickOrderIdEqualTo(dcBaseOmsPick.getPickOrderId()).andBailunSkuEqualTo(dcBaseOmsPick.getBailunSku()).example());
                            if (i == 0) {
                                mapper.insertSelective(dcBaseOmsPick);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            throw new RuntimeException(ExceptionUtil.transform(e), e);
                        } finally {
                            SessionUtil.closeSession();
                        }
                    }
                }
            }

        }
        dcBaseOmsOrder.setCostHandlePlatform(totalCostPackaging);
        dcBaseOmsOrder.setCostTail(totalCostShipping);
    }

    /**
     * 检查订单平台费用是否异常
     *
     * @param dcBaseOmsOrder
     */
    private void checkPlatformFee(DcBaseOmsOrder dcBaseOmsOrder) {
        DcBaseOrderCommissonMapper mapper = SessionUtil.getSession().getMapper(DcBaseOrderCommissonMapper.class);
//        mapper.selectByExample(DcBaseOrderCommissonExample.newAndCreateCriteria().andBailunCategoryIdEqualTo().example());
        //TODO 待补充
        BigDecimal value = dcBaseOmsOrder.getAmountTotal();
        BigDecimal theoryPlatformFee = value.multiply(Constant.AMAZON_PLATFORM_FEE_RATE).setScale(0, RoundingMode.UP);
        //如果 理论平台费 小于实际平台费 或者 平台费为0, 标记异常
        if (theoryPlatformFee.compareTo(dcBaseOmsOrder.getCostPlatformFee()) == -1 || dcBaseOmsOrder.getCostPlatformFee().equals(BigDecimal.ZERO)) {
            dcBaseOmsOrder.setHasPlatformException(true);
        }
    }


    /**
     * 拿SkU基础信息
     *
     * @param bailunSku
     * @param bailunSkuStructure
     * @return
     */
    private DcBaseSku getDcBaseSku(BailunSku bailunSku, BailunSkuStructure bailunSkuStructure) {
        DcBaseSku skuProductInfo = null;
        try {
            DcBaseSkuMapper dcBaseSkuMapper = SessionUtil.getSession().getMapper(DcBaseSkuMapper.class);
            bailunSkuStructure.setGeneralCargo(dcBaseSkuMapper.getIsGeneralCargo(bailunSku.getBailunSku()));
            skuProductInfo = dcBaseSkuMapper.selectOneByExample(DcBaseSkuExample.newAndCreateCriteria().andBailunSkuEqualTo(bailunSku.getBailunSku()).example());
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(ExceptionUtil.transform(e),e);
        } finally {
            SessionUtil.closeSession();
        }
        return skuProductInfo;
    }


    /**
     * 检查FBA费用是否异常
     *
     * @param dcBaseOmsSku
     */
    private void checkFbaFee(DcBaseOmsSku dcBaseOmsSku, DcBaseOmsOrder dcBaseOmsOrder) {
        if (dcBaseOmsSku.getBailunSkuQuantityOrdered() > 0 && dcBaseOmsSku.getCostFbaFee().compareTo(BigDecimal.ZERO) == 1) {
            DcMidFbaFeeAvgMapper dcMidFbaFeeAvgMapper = SessionUtil.getSession().getMapper(DcMidFbaFeeAvgMapper.class);
            DcMidFbaFeeAvg dcMidFbaFeeAvg = dcMidFbaFeeAvgMapper.selectOneByExample(DcMidFbaFeeAvgExample.newAndCreateCriteria().andWebsiteEqualTo(dcBaseOmsSku.getWebsite()).andBailunSkuEqualTo(dcBaseOmsSku.getBailunSku()).example());
            if (dcMidFbaFeeAvg != null && dcBaseOmsSku.getBailunSkuQuantityOrdered() != 0) {
                BigDecimal fbaFeeRmb = dcBaseOmsSku.getCostFbaFee().multiply(dcBaseOmsSku.getFinanceOrderExchangeRate()).divide(BigDecimal.valueOf(dcBaseOmsSku.getBailunSkuQuantityOrdered()), 5, RoundingMode.HALF_EVEN);
                if (fbaFeeRmb.compareTo(dcMidFbaFeeAvg.getMaxFbaFee()) == 1) {
                    dcBaseOmsSku.setHasFbaException(true);
                    dcBaseOmsOrder.setHasFbaException(true);
                }
            }
        }
    }


    /**
     * 把OMS订单中的一部分值赋值到百伦订单对象上
     *
     * @param dcBaseOmsOrder
     * @return
     */
    public void assignmentOrderInfo(OmsResult omsResult, DcBaseOmsOrder dcBaseOmsOrder) {
        dcBaseOmsOrder.setCompanyId(omsResult.getCompanyId());
        dcBaseOmsOrder.setAreaId(omsResult.getAreaId());
        dcBaseOmsOrder.setHasCancle(omsResult.getHasCancle());
        dcBaseOmsOrder.setProfitOms(omsResult.getOrderCharge().getProfitTotal() != null? omsResult.getOrderCharge().getProfitTotal().getAmount() : BigDecimal.ZERO);
        if (omsResult.getLogisticsItems() != null && omsResult.getLogisticsItems().size() > 0) {
            Warehouse warehouse = omsResult.getLogisticsItems().get(0).getWarehouse();
            Logistics logisticsMethod = omsResult.getLogisticsItems().get(0).getLogisticsMethod();
            if (warehouse != null) {
                dcBaseOmsOrder.setLogisticsWarehouseCode(warehouse.getWarehouseCode());
                dcBaseOmsOrder.setLogisticsWarehouseName(warehouse.getWarehouseName());
            }
            if (logisticsMethod != null) {
                dcBaseOmsOrder.setLogisticsMethodCode(logisticsMethod.getLogisticsCode());
                dcBaseOmsOrder.setLogisticsMethodName(logisticsMethod.getLogisticsName());
            }
        }
        //根据国家找物流规则
        if (omsResult.getReceiptAddress() != null) {
            dcBaseOmsOrder.setReceiptCountry(omsResult.getReceiptAddress().getReceiptCountry());
            dcBaseOmsOrder.setReceiptCity(omsResult.getReceiptAddress().getReceiptCity());
            dcBaseOmsOrder.setReceiptAddress(omsResult.getReceiptAddress().getReceiptAddress());
            dcBaseOmsOrder.setReceiptAddress2(omsResult.getReceiptAddress().getReceiptAddress2());
            dcBaseOmsOrder.setReceiptArea(omsResult.getReceiptAddress().getReceiptArea());
            dcBaseOmsOrder.setReceiptPostalCode(omsResult.getReceiptAddress().getReceiptPostalCode());
            dcBaseOmsOrder.setReceiverPhone(omsResult.getReceiptAddress().getReceiverPhone());
            dcBaseOmsOrder.setReceiver(omsResult.getReceiptAddress().getReceiver());
        }
        if (omsResult.getBuyer() != null) {
            dcBaseOmsOrder.setBuyerId(omsResult.getBuyer().getBuyerId());
            dcBaseOmsOrder.setBuyerEmail(omsResult.getBuyer().getBuyerEmail());
            dcBaseOmsOrder.setBuyerName(omsResult.getBuyer().getBuyerName());
        }
        if (omsResult.getSeller() != null) {
            dcBaseOmsOrder.setBailunAccountId(omsResult.getSeller().getBailunAccountId());
            dcBaseOmsOrder.setSellerAccount(omsResult.getSeller().getSellerAccount());
            dcBaseOmsOrder.setSellerId(omsResult.getSeller().getSellerId());
            dcBaseOmsOrder.setHqAccount(omsResult.getSeller().getHqAccount());
            dcBaseOmsOrder.setSellerOrderId(omsResult.getSeller().getSellerOrderId());
            dcBaseOmsOrder.setSellerEmail(omsResult.getSeller().getSellerEmail());
        }
        if (omsResult.getPayment() != null) {
            dcBaseOmsOrder.setPayTime(omsResult.getPayment().getPayTime());
            dcBaseOmsOrder.setPayMethod(omsResult.getPayment().getPayMethod());
            dcBaseOmsOrder.setPayAccount(omsResult.getPayment().getPayAccount());
            dcBaseOmsOrder.setPayStatus(omsResult.getPayment().getPayStatus());
            dcBaseOmsOrder.setCollectionAccount(omsResult.getPayment().getCollectionAccount());
        }

        dcBaseOmsOrder.setTransactionId(omsResult.getTransactionId());
        dcBaseOmsOrder.setOriginOrderId(omsResult.getOriginOrderId());
        dcBaseOmsOrder.setBailunOrderId(omsResult.getBailunOrderId());
        dcBaseOmsOrder.setPlatformType(omsResult.getPlatformType());
        dcBaseOmsOrder.setWebsite(omsResult.getWebsite());
        dcBaseOmsOrder.setPlatformOrderType(omsResult.getPlatformOrderType());
        dcBaseOmsOrder.setCreateTime(omsResult.getCreateTime());
        dcBaseOmsOrder.setPaidTime(omsResult.getPaidTime() != null ? omsResult.getPaidTime() : omsResult.getCreateTime());
        dcBaseOmsOrder.setPlatformOrderStatus(omsResult.getPlatformOrderStatus());
        dcBaseOmsOrder.setBailunOrderStatus(omsResult.getBailunOrderStatus());
        dcBaseOmsOrder.setBailunInterceptionStatus(omsResult.getBailunInterceptionStatus());
        dcBaseOmsOrder.setBailunMergeStatus(omsResult.getBailunMergeStatus());
        dcBaseOmsOrder.setBailunShippingStatus(omsResult.getBailunShippingStatus());
        dcBaseOmsOrder.setBailunPaymentStatus(omsResult.getBailunPaymentStatus());
        dcBaseOmsOrder.setOrderUpdateTime(omsResult.getOrderUpdateTime());
        dcBaseOmsOrder.setBailunPickingStatus(omsResult.getBailunPickingStatus());
        dcBaseOmsOrder.setBailunRequireLogistics(omsResult.getBailunRequireLogistics());
        //礼品包装收入
        dcBaseOmsOrder.setAmountGiftWrap((omsResult.getOrderCharge().getAmountGiftWrap() != null && omsResult.getOrderCharge().getAmountGiftWrap().getAmount() != null) ? omsResult.getOrderCharge().getAmountGiftWrap().getAmount() : BigDecimal.ZERO);
        //总收入
        dcBaseOmsOrder.setAmountTotal((omsResult.getOrderCharge().getAmountTotal() != null && omsResult.getOrderCharge().getAmountTotal().getAmount() != null) ? omsResult.getOrderCharge().getAmountTotal().getAmount() : BigDecimal.ZERO);
        //运费收入
        dcBaseOmsOrder.setAmountShipping((omsResult.getOrderCharge().getAmountShipping() != null && omsResult.getOrderCharge().getAmountShipping().getAmount() != null) ? omsResult.getOrderCharge().getAmountShipping().getAmount() : BigDecimal.ZERO);
        //产品收入或产品金额
        dcBaseOmsOrder.setAmountProduct((omsResult.getOrderCharge().getAmountProduct() != null && omsResult.getOrderCharge().getAmountProduct().getAmount() != null) ? omsResult.getOrderCharge().getAmountProduct().getAmount() : BigDecimal.ZERO);
        //税费
        dcBaseOmsOrder.setAmountTax((omsResult.getOrderCharge().getAmountTax() != null && omsResult.getOrderCharge().getAmountTax().getAmount() != null) ? omsResult.getOrderCharge().getAmountTax().getAmount() : BigDecimal.ZERO);
        //调整费
        dcBaseOmsOrder.setAmountAdjustment((omsResult.getOrderCharge().getAmountAdjustment() != null && omsResult.getOrderCharge().getAmountAdjustment().getAmount() != null) ? omsResult.getOrderCharge().getAmountAdjustment().getAmount() : BigDecimal.ZERO);
        //运费支出
        dcBaseOmsOrder.setCostShipping((omsResult.getOrderCharge().getCostShipping() != null && omsResult.getOrderCharge().getCostShipping().getAmount() != null) ? omsResult.getOrderCharge().getCostShipping().getAmount() : BigDecimal.ZERO);
        //FBA费
        dcBaseOmsOrder.setCostFbaFee((omsResult.getOrderCharge().getCostFbaFee() != null && omsResult.getOrderCharge().getCostFbaFee().getAmount() != null) ? omsResult.getOrderCharge().getCostFbaFee().getAmount() : BigDecimal.ZERO);
        //Paypal费
        dcBaseOmsOrder.setCostPaypalFee((omsResult.getOrderCharge().getCostPaypalFee() != null && omsResult.getOrderCharge().getCostPaypalFee().getAmount() != null) ? omsResult.getOrderCharge().getCostPaypalFee().getAmount() : BigDecimal.ZERO);
        //产品成本
        dcBaseOmsOrder.setCostProduct((omsResult.getOrderCharge().getCostProduct() != null && omsResult.getOrderCharge().getCostProduct().getAmount() != null) ? omsResult.getOrderCharge().getCostProduct().getAmount() : BigDecimal.ZERO);
        //促销费
        dcBaseOmsOrder.setCostPromotion((omsResult.getOrderCharge().getCostPromotion() != null && omsResult.getOrderCharge().getCostPromotion().getAmount() != null) ? omsResult.getOrderCharge().getCostPromotion().getAmount() : BigDecimal.ZERO);
        //平台渠道费
        dcBaseOmsOrder.setCostPlatformFee((omsResult.getOrderCharge().getCostPlatformFee() != null && omsResult.getOrderCharge().getCostPlatformFee().getAmount() != null) ? omsResult.getOrderCharge().getCostPlatformFee().getAmount() : BigDecimal.ZERO);
        //百伦处理费,自己的仓库操作费 - 需要计算的费用给个默认值
        dcBaseOmsOrder.setCostHandleBailun(BigDecimal.ZERO);
        //第三方仓库操作费 - 需要计算的费用给个默认值
        dcBaseOmsOrder.setCostHandlePlatform(BigDecimal.ZERO);
        //尾程费 - 需要计算的费用给个默认值
        dcBaseOmsOrder.setCostTail(BigDecimal.ZERO);
        //头程费 - 需要计算的费用给个默认值
        dcBaseOmsOrder.setCostFirst(BigDecimal.ZERO);
        //退款金额 - 需要计算的费用给个默认值
        dcBaseOmsOrder.setAmountRefund(BigDecimal.ZERO);
        //销售额 - 需要计算的费用给个默认值
        dcBaseOmsOrder.setAmountSales(BigDecimal.ZERO);
        if (omsResult.getRefundInfo() !=null) {
            dcBaseOmsOrder.setRefundTime(omsResult.getRefundInfo().getRefundTime());
            dcBaseOmsOrder.setBailunRefundStatus(omsResult.getRefundInfo().getRefundStatus());
            dcBaseOmsOrder.setRefundObj(omsResult.getRefundInfo().getRefundObj());
            dcBaseOmsOrder.setRefundReferenceId(omsResult.getRefundInfo().getRefundReferenceId());
            dcBaseOmsOrder.setRefundType(omsResult.getRefundInfo().getRefundType());
            if (omsResult.getRefundInfo().getRefundAmount() != null) {
                dcBaseOmsOrder.setAmountRefund(omsResult.getRefundInfo().getRefundAmount().getAmount() != null? omsResult.getRefundInfo().getRefundAmount().getAmount() : BigDecimal.ZERO);
            }
        }
    }

    /**
     * 把OMS订单中的一部分值赋值到百伦订单对象上
     *
     * @param dcBaseOmsSku
     * @param logisticsHashMap
     * @param bailunSkuStructure
     * @return
     */
    public void assignmentSkuInfo(OmsResult omsResult, DcBaseOmsOrder dcBaseOmsOrder, DcBaseOmsSku dcBaseOmsSku, BailunSku bailunSku, DcBaseWarehouse dcBaseWarehouse, HashMap<String, Logistics> logisticsHashMap, BailunSkuStructure bailunSkuStructure) {
        dcBaseOmsSku.setCompanyId(omsResult.getCompanyId());
        dcBaseOmsSku.setBailunSkuQuantityShipped(0);
        dcBaseOmsSku.setBailunSkuQuantityPicked(0);
        dcBaseOmsSku.setBailunSkuQuantityPushed(0);
        dcBaseOmsSku.setCostHandlePlatform(BigDecimal.ZERO);
        dcBaseOmsSku.setCostTail(BigDecimal.ZERO);
        dcBaseOmsSku.setBailunInterceptionStatus(dcBaseOmsOrder.getBailunInterceptionStatus());
        dcBaseOmsSku.setBailunSku(bailunSku.getBailunSku());
        if (dcBaseWarehouse != null) {
            dcBaseOmsSku.setWarehouseCode(dcBaseWarehouse.getWarehouseCode());
            dcBaseOmsSku.setWarehouseName(dcBaseWarehouse.getWarehouseName());
            Logistics logistics = logisticsHashMap.get(dcBaseWarehouse.getWarehouseCode());
            if (logistics != null) {
                dcBaseOmsSku.setLogisticsMethodCode(logistics.getLogisticsCode());
                dcBaseOmsSku.setLogisticsMethodName(logistics.getLogisticsName());
            }
        }
        dcBaseOmsSku.setAreaId(omsResult.getAreaId());
        dcBaseOmsSku.setHasCancle(omsResult.getHasCancle());

        // --begin 调用产品库信息 skuProductInfo, 获取分类信息, 判断是否普货
        DcBaseSku skuProductInfo = getDcBaseSku(bailunSku,bailunSkuStructure);
        if (skuProductInfo != null) {
            dcBaseOmsSku.setBailunCategoryId(skuProductInfo.getBailunCategoryId());
            dcBaseOmsSku.setBailunCategoryName(skuProductInfo.getBailunCategoryName());
            dcBaseOmsSku.setSellerName(skuProductInfo.getSellerName());

        }
        //根据国家找物流规则
        if (omsResult.getReceiptAddress() != null) {
            dcBaseOmsSku.setReceiptCountry(omsResult.getReceiptAddress().getReceiptCountry());
            dcBaseOmsSku.setReceiptCity(omsResult.getReceiptAddress().getReceiptCity());
            dcBaseOmsSku.setReceiptAddress(omsResult.getReceiptAddress().getReceiptAddress());
            dcBaseOmsSku.setReceiptAddress2(omsResult.getReceiptAddress().getReceiptAddress2());
            dcBaseOmsSku.setReceiptArea(omsResult.getReceiptAddress().getReceiptArea());
            dcBaseOmsSku.setReceiptPostalCode(omsResult.getReceiptAddress().getReceiptPostalCode());
            dcBaseOmsSku.setReceiverPhone(omsResult.getReceiptAddress().getReceiverPhone());
            dcBaseOmsSku.setReceiver(omsResult.getReceiptAddress().getReceiver());
        }
        if (omsResult.getBuyer() != null) {
            dcBaseOmsSku.setBuyerId(omsResult.getBuyer().getBuyerId());
            dcBaseOmsSku.setBuyerEmail(omsResult.getBuyer().getBuyerEmail());
            dcBaseOmsSku.setBuyerName(omsResult.getBuyer().getBuyerName());
        }
        if (omsResult.getSeller() != null) {
            dcBaseOmsSku.setBailunAccountId(omsResult.getSeller().getBailunAccountId());
            dcBaseOmsSku.setSellerAccount(omsResult.getSeller().getSellerAccount());
            dcBaseOmsSku.setSellerId(omsResult.getSeller().getSellerId());
            dcBaseOmsSku.setHqAccount(omsResult.getSeller().getHqAccount());
            dcBaseOmsSku.setSellerOrderId(omsResult.getSeller().getSellerOrderId());
            dcBaseOmsSku.setSellerEmail(omsResult.getSeller().getSellerEmail());
        }
        if (omsResult.getPayment() != null) {
            dcBaseOmsSku.setPayTime(omsResult.getPayment().getPayTime());
            dcBaseOmsSku.setPayMethod(omsResult.getPayment().getPayMethod());
            dcBaseOmsSku.setPayAccount(omsResult.getPayment().getPayAccount());
            dcBaseOmsSku.setPayStatus(omsResult.getPayment().getPayStatus());
            dcBaseOmsSku.setCollectionAccount(omsResult.getPayment().getCollectionAccount());
        }
        dcBaseOmsSku.setTransactionId(omsResult.getTransactionId());
        dcBaseOmsSku.setOriginOrderId(omsResult.getOriginOrderId());
        dcBaseOmsSku.setBailunOrderId(omsResult.getBailunOrderId());
        dcBaseOmsSku.setPlatformType(omsResult.getPlatformType());
        dcBaseOmsSku.setWebsite(omsResult.getWebsite());
        dcBaseOmsSku.setPlatformOrderType(omsResult.getPlatformOrderType());
        dcBaseOmsSku.setCreateTime(omsResult.getCreateTime());
        dcBaseOmsSku.setPaidTime(omsResult.getPaidTime() != null ? omsResult.getPaidTime() : omsResult.getCreateTime());
        dcBaseOmsSku.setPlatformOrderStatus(omsResult.getPlatformOrderStatus());
        dcBaseOmsSku.setBailunOrderStatus(omsResult.getBailunOrderStatus());
        dcBaseOmsSku.setShippingStatus(omsResult.getBailunShippingStatus());
        dcBaseOmsSku.setBailunPaymentStatus(omsResult.getBailunPaymentStatus());
        dcBaseOmsSku.setOrderUpdateTime(omsResult.getOrderUpdateTime());
        dcBaseOmsSku.setBailunPickingStatus(omsResult.getBailunPickingStatus());
        dcBaseOmsSku.setBailunRequireLogistics(omsResult.getBailunRequireLogistics());

        //币种和汇率
        dcBaseOmsSku.setOrderCurrency(dcBaseOmsOrder.getOrderCurrency());
        dcBaseOmsSku.setOtherCurrency(dcBaseOmsOrder.getOtherCurrency());
        dcBaseOmsSku.setFinanceOrderExchangeRate(dcBaseOmsOrder.getFinanceOrderExchangeRate() != null ? dcBaseOmsOrder.getFinanceOrderExchangeRate() : BigDecimal.ZERO);
        dcBaseOmsSku.setSellerOrderExchangeRate(dcBaseOmsOrder.getSellerOrderExchangeRate() != null ? dcBaseOmsOrder.getSellerOrderExchangeRate() : BigDecimal.ZERO);
        dcBaseOmsSku.setFinanceOtherExchangeRate(dcBaseOmsOrder.getFinanceOtherExchangeRate() != null ? dcBaseOmsOrder.getFinanceOtherExchangeRate() : BigDecimal.ZERO);
        dcBaseOmsSku.setSellerOtherExchangeRate(dcBaseOmsOrder.getSellerOtherExchangeRate() != null ? dcBaseOmsOrder.getSellerOtherExchangeRate() : BigDecimal.ZERO);
        dcBaseOmsSku.setOrderToUsdExchangeRate(dcBaseOmsOrder.getOrderToUsdExchangeRate() != null ? dcBaseOmsOrder.getOrderToUsdExchangeRate() : BigDecimal.ZERO);
        dcBaseOmsSku.setCnyToUsdExchangeRate(dcBaseOmsOrder.getCnyToUsdExchangeRate() != null ? dcBaseOmsOrder.getCnyToUsdExchangeRate() : BigDecimal.ZERO);
        dcBaseOmsSku.setOtherToUsdExchangeRate(dcBaseOmsOrder.getOtherToUsdExchangeRate() != null ? dcBaseOmsOrder.getOtherToUsdExchangeRate() : BigDecimal.ZERO);
        dcBaseOmsSku.setBailunSkuSize(bailunSku.getBailunSkuSize());
        dcBaseOmsSku.setBailunSkuWeight(bailunSku.getBailunSkuWeight());
        dcBaseOmsSku.setBailunSkuQuantityOrdered(bailunSku.getBailunSkuQuantityOrdered());
        dcBaseOmsSku.setBailunSkuUnitPrice(bailunSku.getBailunSkuUnitPrice().getAmount() != null ? bailunSku.getBailunSkuUnitPrice().getAmount() : BigDecimal.ZERO);
        dcBaseOmsSku.setBailunSkuTitleCn(bailunSku.getBailunSkuTitleCn());
        dcBaseOmsSku.setCostHandlePlatform(BigDecimal.ZERO);
        dcBaseOmsSku.setCostHandleBailun(BigDecimal.ZERO);
        dcBaseOmsSku.setCostTail(BigDecimal.ZERO);
        dcBaseOmsSku.setCostFirst(BigDecimal.ZERO);
        dcBaseOmsSku.setCostFbaFee(BigDecimal.ZERO);
        dcBaseOmsSku.setCostPaypalFee(BigDecimal.ZERO);
        dcBaseOmsSku.setAmountPrepaid(BigDecimal.ZERO);//更新旧数据中都已经发货,但是预付费>0的情况
        dcBaseOmsSku.setCostLogistics(BigDecimal.ZERO);
        //如果是 FBA订单1.检查FBA费用是否异常 2.
        dcBaseOmsSku.setBailunSkuQuantityShipped(0);

        dcBaseOmsSku.setBailunRefundStatus(dcBaseOmsOrder.getBailunRefundStatus());
        dcBaseOmsSku.setRefundTime(dcBaseOmsOrder.getRefundTime());
        dcBaseOmsSku.setRefundObj(dcBaseOmsOrder.getRefundObj());
        dcBaseOmsSku.setRefundReferenceId(dcBaseOmsOrder.getRefundReferenceId());
        dcBaseOmsSku.setAmountRefund(dcBaseOmsOrder.getAmountRefund());
        dcBaseOmsSku.setRefundType(dcBaseOmsOrder.getRefundType());
        dcBaseOmsSku.setHasFbaS(dcBaseOmsOrder.getHasFbaS());
    }

    /**
     * 获取汇率
     *
     * @param dcBaseOmsOrder
     * @throws Exception
     */
    public void getExchangeRate(OmsResult omsResult, DcBaseOmsOrder dcBaseOmsOrder) {
        OrderCharge orderCharge = omsResult.getOrderCharge();
        //财务需要月初的汇率,  销售需要订单支付时期的汇率(从OMS直接取)
        dcBaseOmsOrder.setFinanceOrderExchangeRate(BigDecimal.ZERO);
        dcBaseOmsOrder.setFinanceOtherExchangeRate(BigDecimal.ZERO);
        dcBaseOmsOrder.setSellerOrderExchangeRate(BigDecimal.ZERO);
        dcBaseOmsOrder.setSellerOtherExchangeRate(BigDecimal.ZERO);
        /*
         * OMS的汇率问题很大
         * 自己取汇率
         */
        if (orderCharge != null) {
            LocalDateTime exchangeDate = omsResult.getPaidTime() != null ? omsResult.getPaidTime() : omsResult.getCreateTime();
            if (orderCharge.getAmountTotal() != null) {
                BigDecimal sellerOrderExchangeRate = null;
                String orderCurrency = orderCharge.getAmountTotal().getCurrencyCode();
                if (StringUtils.isEmpty(orderCharge.getAmountTotal().getCurrencyCode()) || orderCurrency.equals(Constant.RMB_CURRENCY_RMB)) {
                    orderCurrency = Constant.RMB_CURRENCY;
                    sellerOrderExchangeRate = BigDecimal.ONE;
                } else {
                    sellerOrderExchangeRate = CallBailunSystem.getExchangeRate(orderCurrency, Constant.RMB_CURRENCY, exchangeDate);
                }
                dcBaseOmsOrder.setOrderCurrency(orderCurrency);
                BigDecimal orderFinanceExchangeRate = CallBailunSystem.getMonthExchangeRate(orderCurrency, Constant.RMB_CURRENCY, exchangeDate);
                //Order币种转美元汇率
                BigDecimal orderToUsdExchangeRate = CallBailunSystem.getMonthExchangeRate(orderCurrency, Constant.USD_CURRENCY, exchangeDate);
                //人民币转美元汇率
                BigDecimal cnyToUsdFinanceExchangeRate = CallBailunSystem.getMonthExchangeRate(Constant.RMB_CURRENCY, Constant.USD_CURRENCY, exchangeDate);
                dcBaseOmsOrder.setOrderToUsdExchangeRate(orderToUsdExchangeRate);
                dcBaseOmsOrder.setCnyToUsdExchangeRate(cnyToUsdFinanceExchangeRate);
                dcBaseOmsOrder.setFinanceOrderExchangeRate(orderFinanceExchangeRate);
                dcBaseOmsOrder.setSellerOrderExchangeRate(sellerOrderExchangeRate);
            }
            /**
             * EBAY的平台费币种与订单币种可能不一致
             */
            if (omsResult.getPlatformType() != null && PlatformType.Ebay.value().equals(omsResult.getPlatformType().toUpperCase()) && orderCharge.getCostPlatformFee() != null && !StringUtils.isEmpty(orderCharge.getCostPlatformFee().getCurrencyCode())) {
                String otherCurrency = orderCharge.getCostPlatformFee().getCurrencyCode();
                BigDecimal sellerOtherExchangeRate = null;
                if (StringUtils.isEmpty(orderCharge.getCostPlatformFee().getCurrencyCode()) || otherCurrency.equals(Constant.RMB_CURRENCY_RMB)) {
                    otherCurrency = Constant.RMB_CURRENCY;
                    sellerOtherExchangeRate = BigDecimal.ONE;
                } else {
                    sellerOtherExchangeRate = CallBailunSystem.getExchangeRate(otherCurrency, Constant.RMB_CURRENCY, exchangeDate);
                }
                dcBaseOmsOrder.setOtherCurrency(otherCurrency);
                BigDecimal otherFinanceExchangeRate = CallBailunSystem.getMonthExchangeRate(otherCurrency, Constant.RMB_CURRENCY, omsResult.getPaidTime() != null ? omsResult.getPaidTime() : omsResult.getCreateTime());
                //Other币种转美元汇率
                BigDecimal otherToUsdExchangeRate = CallBailunSystem.getMonthExchangeRate(otherCurrency, Constant.USD_CURRENCY, omsResult.getPaidTime() != null ? omsResult.getPaidTime() : omsResult.getCreateTime());
                dcBaseOmsOrder.setOtherToUsdExchangeRate(otherToUsdExchangeRate);
                dcBaseOmsOrder.setFinanceOtherExchangeRate(otherFinanceExchangeRate);
                dcBaseOmsOrder.setSellerOtherExchangeRate(sellerOtherExchangeRate);
            }
        }
    }
}
