package com.bailuntec.service.impl;

import com.bailuntec.domain.constant.CommonConstant;
import com.bailuntec.domain.constant.Constant;
import com.bailuntec.domain.entity.*;
import com.bailuntec.domain.enumerate.PlatformType;
import com.bailuntec.domain.example.*;
import com.bailuntec.mapper.*;
import com.bailuntec.service.AutoTurnoverService;
import com.bailuntec.utils.SessionUtil;
import org.apache.ibatis.session.SqlSession;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;

/**
 * <p>
 *
 * </p>
 *
 * @author robbendev
 * @since 2020/8/13 2:09 下午
 */
public class AutoTurnoverServiceImpl implements AutoTurnoverService {

    @Override
    public List<BigDecimal> getAutoTurnoverSaleDetails(DcAutoTurnover dcAutoTurnover, int turnoverDays, int autoForecastDay) {

        SqlSession session = SessionUtil.getFactory().openSession(true);
        try {
            Queue<BigDecimal> forecastSalesDetails = new LinkedList<>();
            //销量公式
            Queue<String> forecastSalesDetailsFormula = new LinkedList<>();


            for (int j = 0; j < new BigDecimal(autoForecastDay).divide(new BigDecimal(turnoverDays), 0, BigDecimal.ROUND_UP).intValue(); j++) {


                DcAutoSalesForecastStageConfigMapper dcAutoSalesForecastStageConfigMapper = session.getMapper(DcAutoSalesForecastStageConfigMapper.class);
                DcAutoTurnoverMapper dcAutoTurnoverMapper = session.getMapper(DcAutoTurnoverMapper.class);
                DcBaseOmsSkuMapper dcBaseOmsSkuMapper = session.getMapper(DcBaseOmsSkuMapper.class);
                //命中的预测规则
                DcAutoSalesForecastStageConfig dcAutoSalesForecastStageConfig = dcAutoSalesForecastStageConfigMapper.selectMatchStage(dcAutoTurnover.getBailunSku(), dcAutoTurnover.getWarehouseCode());

//            if (dcAutoSalesForecastStageConfig == null) {
//                return;
//            }
                //周转天数
                /*
                 * 每个时间段的销量预测是dcAutoSalesForecastStageConfig对应时间段的三个参数对应的过去时间段的销量的加权平均*/

                //今天0点
                LocalDateTime midNight = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
                String bailunSku = dcAutoTurnover.getBailunSku();
                String warehouseCode = dcAutoTurnover.getWarehouseCode();


                //获取过去7天的销量
                BigDecimal last1DaySellerNum = BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(1), midNight, bailunSku, warehouseCode)).orElse(0));
                BigDecimal last2DaySellerNum = BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(2), midNight.minusDays(1), bailunSku, warehouseCode)).orElse(0));
                BigDecimal last3DaySellerNum = BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(3), midNight.minusDays(2), bailunSku, warehouseCode)).orElse(0));
                BigDecimal last4DaySellerNum = BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(4), midNight.minusDays(3), bailunSku, warehouseCode)).orElse(0));
                BigDecimal last5DaySellerNum = BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(5), midNight.minusDays(4), bailunSku, warehouseCode)).orElse(0));
                BigDecimal last6DaySellerNum = BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(6), midNight.minusDays(5), bailunSku, warehouseCode)).orElse(0));
                BigDecimal last7DaySellerNum = BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(7), midNight.minusDays(6), bailunSku, warehouseCode)).orElse(0));


//                forecastSalesDetails.offer(last1DaySellerNum);
//                forecastSalesDetailsFormula.offer(StringUtils.SPACE);
//                forecastSalesDetails.offer(last2DaySellerNum);
//                forecastSalesDetailsFormula.offer(StringUtils.SPACE);
//                forecastSalesDetails.offer(last3DaySellerNum);
//                forecastSalesDetailsFormula.offer(StringUtils.SPACE);
//                forecastSalesDetails.offer(last4DaySellerNum);
//                forecastSalesDetailsFormula.offer(StringUtils.SPACE);
//                forecastSalesDetails.offer(last5DaySellerNum);
//                forecastSalesDetailsFormula.offer(StringUtils.SPACE);
//                forecastSalesDetails.offer(last6DaySellerNum);
//                forecastSalesDetailsFormula.offer(StringUtils.SPACE);
//                forecastSalesDetails.offer(last7DaySellerNum);
//                forecastSalesDetailsFormula.offer(StringUtils.SPACE);


                if (dcAutoSalesForecastStageConfig != null) {
                    int duration1 = BigDecimal.valueOf(turnoverDays).multiply(dcAutoSalesForecastStageConfig.getOneRatio()).intValue();
                    int duration2 = BigDecimal.valueOf(turnoverDays).multiply(dcAutoSalesForecastStageConfig.getTwoRatio()).intValue();
                    int duration3 = turnoverDays - duration1 - duration2;


                    /*第一部分预测*/
                    BigDecimal duration1ForecastSellerNum = BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getOneN1().intValue()), midNight, bailunSku, warehouseCode)).orElse(0))
                            .multiply(dcAutoSalesForecastStageConfig.getOneN2())
                            .add(BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getOneN3().intValue()), midNight, bailunSku, warehouseCode)).orElse(0))
                                    .multiply(dcAutoSalesForecastStageConfig.getOneN4()))
                            .add(BigDecimal.valueOf(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getOneN5().intValue()), midNight, bailunSku, warehouseCode))
                                    .multiply(dcAutoSalesForecastStageConfig.getOneN6()));

                    for (int i = 0; i < duration1; i++) {
                        if (autoForecastDay >= forecastSalesDetails.size()) {
                            forecastSalesDetails.offer(duration1ForecastSellerNum);
                            forecastSalesDetailsFormula.offer("(" + dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getOneN1().intValue()), midNight, bailunSku, warehouseCode) + "*" + dcAutoSalesForecastStageConfig.getOneN2() + ")"
                                    + "+"
                                    + "（" + BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getOneN3().intValue()), midNight, bailunSku, warehouseCode)).orElse(0)) + "*" + dcAutoSalesForecastStageConfig.getOneN4() + "）"
                                    + "+"
                                    + "（" + BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getOneN5().intValue()), midNight, bailunSku, warehouseCode)).orElse(0)) + "*" + dcAutoSalesForecastStageConfig.getOneN6() + "）");


                        }
                    }

                    /*第二部分预测*/
                    BigDecimal duration2ForecastSellerNum = BigDecimal.valueOf(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getTwoN1().intValue()), midNight, bailunSku, warehouseCode))
                            .multiply(dcAutoSalesForecastStageConfig.getTwoN2())
                            .add(BigDecimal.valueOf(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getTwoN3().intValue()), midNight, bailunSku, warehouseCode))
                                    .multiply(dcAutoSalesForecastStageConfig.getTwoN4()))
                            .add(BigDecimal.valueOf(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getTwoN5().intValue()), midNight, bailunSku, warehouseCode))
                                    .multiply(dcAutoSalesForecastStageConfig.getTwoN6()));

                    for (int i = 0; i < duration2; i++) {
                        if (autoForecastDay >= forecastSalesDetails.size()) {

                            forecastSalesDetails.offer(duration2ForecastSellerNum);

                            forecastSalesDetailsFormula.offer("(" + dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getTwoN1().intValue()), midNight, bailunSku, warehouseCode) + "*" + dcAutoSalesForecastStageConfig.getTwoN2() + ")"
                                    + "+"
                                    + "（" + BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getTwoN3().intValue()), midNight, bailunSku, warehouseCode)).orElse(0)) + "*" + dcAutoSalesForecastStageConfig.getTwoN4() + "）"
                                    + "+"
                                    + "（" + BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getTwoN5().intValue()), midNight, bailunSku, warehouseCode)).orElse(0)) + "*" + dcAutoSalesForecastStageConfig.getTwoN6() + "）");
                        }
                    }


                    /*第三部分预测*/
                    BigDecimal duration3ForecastSellerNum = BigDecimal.valueOf(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getThreeN1().intValue()), midNight, bailunSku, warehouseCode))
                            .multiply(dcAutoSalesForecastStageConfig.getThreeN2())
                            .add(BigDecimal.valueOf(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getThreeN3().intValue()), midNight, bailunSku, warehouseCode))
                                    .multiply(dcAutoSalesForecastStageConfig.getThreeN4()))
                            .add(BigDecimal.valueOf(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getThreeN5().intValue()), midNight, bailunSku, warehouseCode))
                                    .multiply(dcAutoSalesForecastStageConfig.getThreeN6()));

                    for (int i = 0; i < duration3; i++) {
                        if (autoForecastDay >= forecastSalesDetails.size()) {

                            forecastSalesDetails.offer(duration3ForecastSellerNum);

                            forecastSalesDetailsFormula.offer("(" + dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getThreeN1().intValue()), midNight, bailunSku, warehouseCode) + "*" + dcAutoSalesForecastStageConfig.getThreeN2() + ")"
                                    + "+"
                                    + "（" + BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getThreeN3().intValue()), midNight, bailunSku, warehouseCode)).orElse(0)) + "*" + dcAutoSalesForecastStageConfig.getThreeN4() + "）"
                                    + "+"
                                    + "（" + BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getThreeN5().intValue()), midNight, bailunSku, warehouseCode)).orElse(0)) + "*" + dcAutoSalesForecastStageConfig.getThreeN6() + "）");
                        }
                    }

//                    dcAutoTurnover.setSalesDetails(new Gson().toJson(forecastSalesDetails));
//                    dcAutoTurnover.setSalesDetailsFormula(new Gson().toJson(forecastSalesDetailsFormula));
                    //            dcAutoTurnoverMapper.updateByPrimaryKey(dcAutoTurnover);

                } else {
                    for (int i = 0; i < turnoverDays; i++) {
                        if (autoForecastDay >= forecastSalesDetails.size()) {

                            forecastSalesDetails.offer(dcAutoTurnover.getDailyWeightedSales());
                        }
                    }
                }
            }
            return new ArrayList<>(forecastSalesDetails);

        } finally {
            session.close();
        }
    }


    @Override
    public List<String> getAutoTurnoverSaleDetailsFormula(DcAutoTurnover dcAutoTurnover, int turnoverDays, int autoForecastDay) {

        SqlSession session = SessionUtil.getFactory().openSession(true);
        try {
            Queue<BigDecimal> forecastSalesDetails = new LinkedList<>();
            //销量公式
            Queue<String> forecastSalesDetailsFormula = new LinkedList<>();


            for (int j = 0; j < new BigDecimal(autoForecastDay).divide(new BigDecimal(turnoverDays), 0, BigDecimal.ROUND_UP).intValue(); j++) {

                DcAutoSalesForecastStageConfigMapper dcAutoSalesForecastStageConfigMapper = session.getMapper(DcAutoSalesForecastStageConfigMapper.class);
                DcAutoTurnoverMapper dcAutoTurnoverMapper = session.getMapper(DcAutoTurnoverMapper.class);
                DcBaseOmsSkuMapper dcBaseOmsSkuMapper = session.getMapper(DcBaseOmsSkuMapper.class);
                //命中的预测规则
                DcAutoSalesForecastStageConfig dcAutoSalesForecastStageConfig = dcAutoSalesForecastStageConfigMapper.selectMatchStage(dcAutoTurnover.getBailunSku(), dcAutoTurnover.getWarehouseCode());

//            if (dcAutoSalesForecastStageConfig == null) {
//                return;
//            }
                //周转天数
                /*
                 * 每个时间段的销量预测是dcAutoSalesForecastStageConfig对应时间段的三个参数对应的过去时间段的销量的加权平均*/

                //今天0点
                LocalDateTime midNight = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
                String bailunSku = dcAutoTurnover.getBailunSku();
                String warehouseCode = dcAutoTurnover.getWarehouseCode();


                //获取过去7天的销量
                BigDecimal last1DaySellerNum = BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(1), midNight, bailunSku, warehouseCode)).orElse(0));
                BigDecimal last2DaySellerNum = BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(2), midNight.minusDays(1), bailunSku, warehouseCode)).orElse(0));
                BigDecimal last3DaySellerNum = BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(3), midNight.minusDays(2), bailunSku, warehouseCode)).orElse(0));
                BigDecimal last4DaySellerNum = BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(4), midNight.minusDays(3), bailunSku, warehouseCode)).orElse(0));
                BigDecimal last5DaySellerNum = BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(5), midNight.minusDays(4), bailunSku, warehouseCode)).orElse(0));
                BigDecimal last6DaySellerNum = BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(6), midNight.minusDays(5), bailunSku, warehouseCode)).orElse(0));
                BigDecimal last7DaySellerNum = BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(7), midNight.minusDays(6), bailunSku, warehouseCode)).orElse(0));


//                forecastSalesDetails.offer(last1DaySellerNum);
//                forecastSalesDetailsFormula.offer(StringUtils.SPACE);
//                forecastSalesDetails.offer(last2DaySellerNum);
//                forecastSalesDetailsFormula.offer(StringUtils.SPACE);
//                forecastSalesDetails.offer(last3DaySellerNum);
//                forecastSalesDetailsFormula.offer(StringUtils.SPACE);
//                forecastSalesDetails.offer(last4DaySellerNum);
//                forecastSalesDetailsFormula.offer(StringUtils.SPACE);
//                forecastSalesDetails.offer(last5DaySellerNum);
//                forecastSalesDetailsFormula.offer(StringUtils.SPACE);
//                forecastSalesDetails.offer(last6DaySellerNum);
//                forecastSalesDetailsFormula.offer(StringUtils.SPACE);
//                forecastSalesDetails.offer(last7DaySellerNum);
//                forecastSalesDetailsFormula.offer(StringUtils.SPACE);


                if (dcAutoSalesForecastStageConfig != null) {
                    int duration1 = BigDecimal.valueOf(turnoverDays).multiply(dcAutoSalesForecastStageConfig.getOneRatio()).intValue();
                    int duration2 = BigDecimal.valueOf(turnoverDays).multiply(dcAutoSalesForecastStageConfig.getTwoRatio()).intValue();
                    int duration3 = turnoverDays - duration1 - duration2;


                    /*第一部分预测*/
                    BigDecimal duration1ForecastSellerNum = BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getOneN1().intValue()), midNight, bailunSku, warehouseCode)).orElse(0))
                            .multiply(dcAutoSalesForecastStageConfig.getOneN2())
                            .add(BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getOneN3().intValue()), midNight, bailunSku, warehouseCode)).orElse(0))
                                    .multiply(dcAutoSalesForecastStageConfig.getOneN4()))
                            .add(BigDecimal.valueOf(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getOneN5().intValue()), midNight, bailunSku, warehouseCode))
                                    .multiply(dcAutoSalesForecastStageConfig.getOneN6()));

                    for (int i = 0; i < duration1; i++) {
                        if (autoForecastDay >= forecastSalesDetails.size()) {
                            forecastSalesDetails.offer(duration1ForecastSellerNum);
                            forecastSalesDetailsFormula.offer("(" + dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getOneN1().intValue()), midNight, bailunSku, warehouseCode) + "*" + dcAutoSalesForecastStageConfig.getOneN2() + ")"
                                    + "+"
                                    + "（" + BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getOneN3().intValue()), midNight, bailunSku, warehouseCode)).orElse(0)) + "*" + dcAutoSalesForecastStageConfig.getOneN4() + "）"
                                    + "+"
                                    + "（" + BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getOneN5().intValue()), midNight, bailunSku, warehouseCode)).orElse(0)) + "*" + dcAutoSalesForecastStageConfig.getOneN6() + "）");


                        }
                    }

                    /*第二部分预测*/
                    BigDecimal duration2ForecastSellerNum = BigDecimal.valueOf(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getTwoN1().intValue()), midNight, bailunSku, warehouseCode))
                            .multiply(dcAutoSalesForecastStageConfig.getTwoN2())
                            .add(BigDecimal.valueOf(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getTwoN3().intValue()), midNight, bailunSku, warehouseCode))
                                    .multiply(dcAutoSalesForecastStageConfig.getTwoN4()))
                            .add(BigDecimal.valueOf(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getTwoN5().intValue()), midNight, bailunSku, warehouseCode))
                                    .multiply(dcAutoSalesForecastStageConfig.getTwoN6()));

                    for (int i = 0; i < duration2; i++) {
                        if (autoForecastDay >= forecastSalesDetails.size()) {

                            forecastSalesDetails.offer(duration2ForecastSellerNum);

                            forecastSalesDetailsFormula.offer("(" + dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getTwoN1().intValue()), midNight, bailunSku, warehouseCode) + "*" + dcAutoSalesForecastStageConfig.getTwoN2() + ")"
                                    + "+"
                                    + "（" + BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getTwoN3().intValue()), midNight, bailunSku, warehouseCode)).orElse(0)) + "*" + dcAutoSalesForecastStageConfig.getTwoN4() + "）"
                                    + "+"
                                    + "（" + BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getTwoN5().intValue()), midNight, bailunSku, warehouseCode)).orElse(0)) + "*" + dcAutoSalesForecastStageConfig.getTwoN6() + "）");
                        }
                    }


                    /*第三部分预测*/
                    BigDecimal duration3ForecastSellerNum = BigDecimal.valueOf(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getThreeN1().intValue()), midNight, bailunSku, warehouseCode))
                            .multiply(dcAutoSalesForecastStageConfig.getThreeN2())
                            .add(BigDecimal.valueOf(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getThreeN3().intValue()), midNight, bailunSku, warehouseCode))
                                    .multiply(dcAutoSalesForecastStageConfig.getThreeN4()))
                            .add(BigDecimal.valueOf(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getThreeN5().intValue()), midNight, bailunSku, warehouseCode))
                                    .multiply(dcAutoSalesForecastStageConfig.getThreeN6()));

                    for (int i = 0; i < duration3; i++) {
                        if (autoForecastDay >= forecastSalesDetails.size()) {

                            forecastSalesDetails.offer(duration3ForecastSellerNum);

                            forecastSalesDetailsFormula.offer("(" + dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getThreeN1().intValue()), midNight, bailunSku, warehouseCode) + "*" + dcAutoSalesForecastStageConfig.getThreeN2() + ")"
                                    + "+"
                                    + "（" + BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getThreeN3().intValue()), midNight, bailunSku, warehouseCode)).orElse(0)) + "*" + dcAutoSalesForecastStageConfig.getThreeN4() + "）"
                                    + "+"
                                    + "（" + BigDecimal.valueOf(Optional.ofNullable(dcBaseOmsSkuMapper.omsSkuSellerCount(midNight.minusDays(dcAutoSalesForecastStageConfig.getThreeN5().intValue()), midNight, bailunSku, warehouseCode)).orElse(0)) + "*" + dcAutoSalesForecastStageConfig.getThreeN6() + "）");
                        }
                    }

//                    dcAutoTurnover.setSalesDetails(new Gson().toJson(forecastSalesDetails));
//                    dcAutoTurnover.setSalesDetailsFormula(new Gson().toJson(forecastSalesDetailsFormula));
                    //            dcAutoTurnoverMapper.updateByPrimaryKey(dcAutoTurnover);

                } else {
                    for (int i = 0; i < turnoverDays; i++) {
                        if (autoForecastDay >= forecastSalesDetails.size()) {

                            forecastSalesDetails.offer(dcAutoTurnover.getDailyWeightedSales());
                        }
                    }
                }
            }
            return new ArrayList<>(forecastSalesDetailsFormula);

        } finally {
            session.close();
        }
    }


    public void autoTurnoverFromStock(DcBaseStock dcBaseStock) {
        SqlSession session = SessionUtil.getFactory().openSession(true);

        try {
            /*mapper*/

            //仓库mapper
            DcBaseWarehouseMapper baseWarehouseMapper = session.getMapper(DcBaseWarehouseMapper.class);
            //周转mapper
            DcAutoTurnoverMapper dcAutoTurnoverMapper = session.getMapper(DcAutoTurnoverMapper.class);
            //sku mapper
            DcBaseSkuMapper baseSkuMapper = session.getMapper(DcBaseSkuMapper.class);
            //平均采购指标mapper
            DcAveragePurchaseMapper dcAveragePurchaseMapper = session.getMapper(DcAveragePurchaseMapper.class);
            //仓库平均指标mapper
            DcAverageWarehouseMapper dcAverageWarehouseMapper = session.getMapper(DcAverageWarehouseMapper.class);
            //采购在途mapper
            DcMidTransitMapper dcMidTransitMapper = session.getMapper(DcMidTransitMapper.class);
            //海外仓FBA仓入库天数设定 mapper
            DcAutoConfigDeliveryMapper dcAutoConfigDeliveryMapper = session.getMapper(DcAutoConfigDeliveryMapper.class);

            //库存对应的周转记录
            DcAutoTurnover dcAutoTurnover = dcAutoTurnoverMapper.selectOneByExample(DcAutoTurnoverExample.newAndCreateCriteria()
                    .andBailunSkuEqualTo(dcBaseStock.getBailunSku())
                    .andWarehouseCodeEqualTo(dcBaseStock.getWarehouseCode())
                    .example());

            if (dcAutoTurnover == null) {
                dcAutoTurnover = new DcAutoTurnover();
                //设置百伦sku
                dcAutoTurnover.setBailunSku(dcBaseStock.getBailunSku());
                dcAutoTurnover.setWarehouseCode(dcBaseStock.getWarehouseCode());
            }

            //周转记录对应的仓库编码
            DcBaseWarehouse dcBaseWarehouse = baseWarehouseMapper.selectOneByExample(DcBaseWarehouseExample
                    .newAndCreateCriteria()
                    .andWarehouseCodeEqualTo(dcAutoTurnover.getWarehouseCode())
                    .example());

            if (dcBaseWarehouse != null) {
                //设置仓库名称
                dcAutoTurnover.setWarehouseName(dcBaseWarehouse.getWarehouseName());
                if (dcBaseWarehouse.getSystemFlag().toUpperCase().equals(PlatformType.FBA.value())) {
                    dcAutoTurnover.setWarehouseName(dcBaseWarehouse.getBailunAccount());
                }
            }

            //周转记录对应的基础sku
            DcBaseSku dcBaseSku = baseSkuMapper.selectOneByExample(DcBaseSkuExample
                    .newAndCreateCriteria()
                    .andBailunSkuEqualTo(dcAutoTurnover.getBailunSku())
                    .example());


            //sku对应的采购平均指标
            DcAveragePurchase dcAveragePurchase = dcAveragePurchaseMapper.selectOneByExample(DcAveragePurchaseExample
                    .newAndCreateCriteria()
                    .andBailunSkuEqualTo(dcAutoTurnover.getBailunSku())
                    .andWarehouseCodeEqualTo(dcAutoTurnover.getWarehouseCode())
                    .andSupplierIdEqualTo(dcBaseSku.getSuppliersId())
                    .example());

            //sku对应的仓库平均指标
            DcAverageWarehouse dcAverageWarehouse = dcAverageWarehouseMapper.selectOneByExample(DcAverageWarehouseExample
                    .newAndCreateCriteria()
                    .andBailunSkuEqualTo(dcAutoTurnover.getBailunSku())
                    .andWarehouseCodeEqualTo(dcAutoTurnover.getWarehouseCode())
                    .example());

            //是否先款后货? 先款后货供应链长度加一天 或者 没有采购平均指标这数据也要加一天 paymentBeforeDelivery = 1
            Integer paymentBeforeDelivery = null;
            if (dcAveragePurchase == null || (dcAveragePurchase.getPaymentType() != null && dcAveragePurchase.getPaymentType().equals(1))) {
                paymentBeforeDelivery = 1;
            }

            //百伦sku一级分类
            Integer bailunFirstLevelCategoryId = null;

            //海外仓FBA仓入库天数设定 (调拨头程 + 调拨打包 + 海外仓入库天数)
            DcAutoConfigDelivery dcAutoConfigDelivery;

            //如果不是国内仓 就读配置表
            if (dcBaseWarehouse != null && !dcBaseWarehouse.getHqType().equals(CommonConstant.DOMESTIC_WAREHOUSE)) {

                dcAutoConfigDelivery = dcAutoConfigDeliveryMapper.selectOneByExample(DcAutoConfigDeliveryExample
                        .newAndCreateCriteria()
                        .andVariableCodeEqualTo(dcAutoTurnover.getWarehouseCode())
                        .andBailunSkuEqualTo(dcAutoTurnover.getBailunSku())
                        .andStatusEqualTo(1)
                        .andTypeEqualTo(1)
                        .example());

                if (dcAutoConfigDelivery == null) {
                    dcAutoConfigDelivery = dcAutoConfigDeliveryMapper.selectOneByExample(DcAutoConfigDeliveryExample
                            .newAndCreateCriteria()
                            .andVariableCodeEqualTo(dcBaseWarehouse.getHqType())
                            .andBailunSkuEqualTo(dcAutoTurnover.getBailunSku())
                            .andStatusEqualTo(1)
                            .andTypeEqualTo(2)
                            .example());
                }
                if (dcAutoConfigDelivery == null) {
                    dcAutoConfigDelivery = dcAutoConfigDeliveryMapper.selectOneByExample(DcAutoConfigDeliveryExample
                            .newAndCreateCriteria()
                            .andVariableCodeEqualTo(dcAutoTurnover.getWarehouseCode())
                            .andStatusEqualTo(1)
                            .andTypeEqualTo(3)
                            .example());
                }
                if (dcAutoConfigDelivery == null) {
                    dcAutoConfigDelivery = dcAutoConfigDeliveryMapper.selectOneByExample(DcAutoConfigDeliveryExample
                            .newAndCreateCriteria()
                            .andVariableCodeEqualTo(dcBaseWarehouse.getHqType())
                            .andStatusEqualTo(1)
                            .andTypeEqualTo(4)
                            .example());
                }
                if (dcAutoConfigDelivery == null) {
                    dcAutoConfigDelivery = new DcAutoConfigDelivery(0, 0, 0);
                }

                /*
                 * 供应商交期
                 * 先取dc_average_purchase,如果平均交期没有
                 * 再去SKUMS取, 取SKUMS数据的时候如果是国内仓，就还取dc_base_sku原来那个字段，否则就要取dc_base_sku原新字段（调拨交期)
                 */
                Integer turnoverSupplierDelivery = dcAveragePurchase != null && dcAveragePurchase.getDeliveryDays() >= 0 ? dcAveragePurchase.getDeliveryDays() : -1;

                if (turnoverSupplierDelivery.equals(-1) || turnoverSupplierDelivery > 100) {
                    turnoverSupplierDelivery = dcBaseSku.getSupplierDelivery();
                    //如果非国内仓且是JIT，就取调拨交期
                    if (!dcBaseWarehouse.getHqType().equals(CommonConstant.DOMESTIC_WAREHOUSE) && (Constant.BUYER_JIT_1.equals(dcBaseSku.getBuyerName()) || Constant.BUYER_JIT_2.equals(dcBaseSku.getBuyerName()))) {
                        turnoverSupplierDelivery = dcBaseSku.getTransferDelivery();
                    }
                }

                //入库天数
                Integer turnoverInboundDelivery = Constant.INSPECTION_DELIVE;
                //设置质检入库天数-配置值(实际还没用上)
                dcAutoTurnover.setInspectionConfigDelivery(turnoverInboundDelivery);
                //设置调拨头程
                Integer turnoverTransferHeadDelivery = dcAutoConfigDelivery.getTranferHead();
                dcAutoTurnover.setTransferConfigDelivery(turnoverTransferHeadDelivery);
                //设置调拨打包
                Integer turnoverTransferBaleDelivery = dcAutoConfigDelivery.getTranferBale();
                dcAutoTurnover.setTransferBaleConfigDelivery(turnoverTransferBaleDelivery);
                //设置海外仓入库
                Integer turnoverAbroadInboundDelivery = dcAutoConfigDelivery.getAbroadInbound();
                dcAutoTurnover.setAbroadInboundConfigDelivery(turnoverAbroadInboundDelivery);


                if (dcAverageWarehouse != null) {
                    if (dcAverageWarehouse.getInboundDays() != null && dcAverageWarehouse.getInboundDays() > 0) {
                        turnoverInboundDelivery = dcAverageWarehouse.getInboundDays();
                    }
                    if (dcAverageWarehouse.getTransferDelivery() != null && dcAverageWarehouse.getTransferDelivery().compareTo(BigDecimal.ZERO) > 0) {
                        turnoverTransferHeadDelivery = dcAverageWarehouse.getTransferDelivery().intValue();
                    }
                    if (dcAverageWarehouse.getTransferBaleDelivery() != null && dcAverageWarehouse.getTransferBaleDelivery().compareTo(BigDecimal.ZERO) > 0) {
                        turnoverTransferBaleDelivery = dcAverageWarehouse.getTransferBaleDelivery().intValue();
                    }
                    if (dcAverageWarehouse.getAbroadInboundDelivery() != null && dcAverageWarehouse.getAbroadInboundDelivery().compareTo(BigDecimal.ZERO) > 0) {
                        turnoverAbroadInboundDelivery = dcAverageWarehouse.getAbroadInboundDelivery().intValue();
                    }
                }

                //设置供应商交期天数
                dcAutoTurnover.setSupplierDelivery(turnoverSupplierDelivery);
                //设置质检入库天数 最终取值
                dcAutoTurnover.setInspectionDelivery(turnoverInboundDelivery);
                //设置调拨头程天数 最终取值
                dcAutoTurnover.setTransferDelivery(turnoverTransferHeadDelivery);
                //设置调拨打包天数 平均取值
                dcAutoTurnover.setTransferBaleDelivery(turnoverTransferBaleDelivery);
                //设置海外仓哭茹天数 最终取值
                dcAutoTurnover.setAbroadInboundDelivery(turnoverAbroadInboundDelivery);

                //周转期
                Integer turnoverDays = turnoverSupplierDelivery + turnoverInboundDelivery + turnoverTransferHeadDelivery + turnoverTransferBaleDelivery + turnoverAbroadInboundDelivery;

                if (paymentBeforeDelivery != null) {

                }
            }


        } finally {
            SessionUtil.closeSession();
        }
    }
}
