package cn.superdesk.uniorder.controller.marketing.department;

import cn.hutool.core.date.DateUtil;
import cn.superdesk.uniorder.common.excel.ExcelResponse;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.controller.base.BaseController;
import cn.superdesk.uniorder.dao.entity.organisation.SysEnterprise;
import cn.superdesk.uniorder.dao.entity.marketing.department.UnifiedAreaCity;
import cn.superdesk.uniorder.dao.entity.marketing.UnifiedStatisticsVirt;
import cn.superdesk.uniorder.dto.vo._function.select.SelectOptionAreaItem;
import cn.superdesk.uniorder.dto.vo._function.select.SelectOptionVirt;
import cn.superdesk.uniorder.dto.vo.marketing.department.*;
import cn.superdesk.uniorder.dto.vo.unified.*;
import cn.superdesk.uniorder.dubbo.consumer.organisation.SysEnterpriseDubboConsumerService;
import cn.superdesk.uniorder.dubbo.consumer.sys.SysUserDubboConsumerService;
import cn.superdesk.uniorder.dubbo.consumer.unified.UnifiedAreaDubboConsumerService;
import cn.superdesk.uniorder.dubbo.consumer.marketing.UnifiedStatisticsVirtCommonDubboConsumerService;
import cn.superdesk.uniorder.dto.utils.ConvertTreeUtils;
import cn.superdesk.uniorder.common.exception.utils.ExceptionUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


@Api(value = "市场管理-区域管理", tags = {"市场管理-区域管理"})
@Slf4j
@RestController
@RequestMapping("/uarea")
public class UnifiedAreaController extends BaseController {


    @Autowired
    private UnifiedAreaDubboConsumerService                 unifiedAreaDubboConsumerService;
    @Autowired
    private UnifiedStatisticsVirtCommonDubboConsumerService unifiedStatisticsVirtDubboConsumerService;
    @Autowired
    private SysUserDubboConsumerService                     sysUserDubboConsumerService;
    @Autowired
    private SysEnterpriseDubboConsumerService               sysEnterpriseDubboConsumerService;

    /**
     * 区域管理首页列表(新)
     *
     * @return
     */
    @ApiOperation(value = "区域管理首页列表(新)")
    @RequestMapping(value = "/getweb", method = RequestMethod.POST)
    @ResponseBody
    public R<List<UnifiedAreaWeb>> getweb() {

        R<List<UnifiedAreaWeb>> result = new R<>();

        try {
            Map<String, Object> params = new HashMap<>();
            Date                beginD = DateUtil.date();


            List<UnifiedAreaWeb> ls = unifiedAreaDubboConsumerService.getweb(getToken(), params);

            // 树形转化
            List<UnifiedAreaWeb> nodeList = new ArrayList<>();
            for (UnifiedAreaWeb node : ls) {

                if (node.getParentId() == null) {
                    node = ConvertTreeUtils.buildTreeArea(ls, node);
                    nodeList.add(node);
                }
            }

            Date endD = DateUtil.date();


            result.setData(nodeList);
            result.setSuccess(true);

            log.info("开始时间:{}\n结束时间:{}\n耗时:{}\n", beginD.getTime(), endD.getTime(), (beginD.getTime() - endD.getTime()));

        } catch (Exception e) {

            result.setCode(String.valueOf(e.hashCode()));
            result.setSuccess(false);
            result.setMessage(e.getMessage());

            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 新增区域
     *
     * @return
     */
    @ApiOperation(value = "新增区域")
    @RequestMapping(value = "/addnew", method = RequestMethod.POST)
    @ResponseBody
    public R<Object> addnew(UnifiedAreaParam param) {

        R<Object> result = new R<>();

        try {

            if (!StringUtils.isNotEmpty(param.getAreaName())) {
                result.setCode(400);
                result.setSuccess(false);
                result.setMessage("区域名称不能为空！");
                return result;
            }

            Map<String, Object> resMap = unifiedAreaDubboConsumerService.addNew(getToken(), param);

            if (resMap.get("code").toString().equals("1")) {
                result.setSuccess(true);
                result.setData(resMap.get("data"));
            } else {
                result.setSuccess(false);
                result.setMessage(resMap.get("msg").toString());
            }

        } catch (Exception e) {

            result.setCode(String.valueOf(e.hashCode()));
            result.setSuccess(false);
            result.setMessage(e.getMessage());

            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
        }

        return result;
    }


    /**
     * 修改区域
     *
     * @return
     */
    @ApiOperation(value = "修改区域")
    @RequestMapping(value = "/updatenew", method = RequestMethod.POST)
    @ResponseBody
    public R<Object> updatenew(UnifiedAreaParam param) {

        R<Object> result = new R<>();

        try {

            Map<String, Object> resMap = unifiedAreaDubboConsumerService.updateNew(getToken(), param);

            if (resMap.get("code").toString().equals("1")) {
                result.setSuccess(true);
                result.setData(resMap.get("data"));
            } else {
                result.setSuccess(false);
                result.setMessage(resMap.get("msg").toString());
            }

        } catch (Exception e) {

            result.setCode(String.valueOf(e.hashCode()));
            result.setSuccess(false);
            result.setMessage(e.getMessage());

            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 历史指标(新)
     *
     * @return
     */
    @ApiOperation(value = "历史指标(新)")
    @RequestMapping(value = "/gethistarget", method = RequestMethod.POST)
    @ResponseBody
    public R<List<UnifiedAreaCityTargetVo>> getHistoryTarget() {

        R<List<UnifiedAreaCityTargetVo>> result = new R<>();

        try {
            Map<String, Object> params = new HashMap<>();

            params.put("areaItemId", getLong("areaItemId"));

            List<UnifiedAreaCityTargetVo> resultList = unifiedAreaDubboConsumerService.getTargetAll(getToken(), params);

            if (resultList != null && resultList.size() > 0) {

                for (UnifiedAreaCityTargetVo vo : resultList) {

                    // 很多单个计算的 , 就目前 意义不大了
//					Map<String, Object> queryParams = new HashMap<>();
//					queryParams.put("areaItemId", vo.getAreaCityId());
//					queryParams.put("syear", vo.getYearly());
//					queryParams.put("smonth", vo.getMonthly());
//
//					BigDecimal orderAmount = unifiedStatisticsVirtDubboConsumerService.getOrderAmountByAreaItem(queryParams);
//
//					vo.setOrderAmount(orderAmount);

                    Map<String, Object> queryParams = new HashMap<>();
                    queryParams.put("areaId", vo.getAreaCityId());
                    queryParams.put("syear", vo.getYearly());
                    queryParams.put("smonth", vo.getMonthly());

                    UnifiedStatisticsVirtSum statisticsVirtSum = unifiedStatisticsVirtDubboConsumerService.getStatisticsSum(queryParams);

                    vo.setOrderAmount(statisticsVirtSum.getOrderAmount());
                    vo.setOrderCostAmount(statisticsVirtSum.getOrderCostAmount());
                    vo.setOrderProfitAmount(vo.getOrderAmount().subtract(vo.getOrderCostAmount()));

                }
            }

            result.setData(resultList);
            result.setSuccess(true);

        } catch (Exception e) {

            result.setCode(String.valueOf(e.hashCode()));
            result.setSuccess(false);
            result.setMessage(e.getMessage());

            log.error(ExceptionUtils.getMessage(e));

            e.printStackTrace();
        }
        return result;
    }


    /**
     * 获取未配置区域企业(新)
     *
     * @return
     */
    @ApiOperation(value = "获取未配置区域企业(新)")
    @RequestMapping(value = "/getvirtnotinarea", method = RequestMethod.POST)
    @ResponseBody
    public R<List<SelectOptionVirt>> getVirtNotInArea() {

        R<List<SelectOptionVirt>> result = new R<>();

        try {

            Map<String, Object> params = new HashMap<>();
            params.put("notinarea", 1);

            List<SelectOptionVirt> ls = unifiedAreaDubboConsumerService.getVirtNotInArea(params);

            result.setData(ls);
            result.setSuccess(true);

        } catch (Exception e) {

            result.setCode(String.valueOf(e.hashCode()));
            result.setSuccess(false);
            result.setMessage(e.getMessage());

            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
        }
        return result;
    }


    /**
     * 绑定解绑企业(新)
     *
     * @return
     */
    @ApiOperation(value = "绑定解绑企业(新)")
    @RequestMapping(value = "/joinvirt", method = RequestMethod.POST)
    @ResponseBody
    public R<Object> joinvirt() {

        R<Object> result = new R<>();

        try {

            Long     areaItemId = getLong("areaItemId");
            String   virtIdsStr = getString("virtIds");
            String   type       = getString("type");
            String[] virtIds    = virtIdsStr.split(",");

            for (int i = 0; i < virtIds.length; i++) {
                Long virtId = Long.parseLong(virtIds[i]);
                unifiedAreaDubboConsumerService.updateAreaVirt(areaItemId, virtId, type);
            }

            result.setSuccess(true);

        } catch (Exception e) {

            result.setCode(String.valueOf(e.hashCode()));
            result.setSuccess(false);
            result.setMessage(e.getMessage());

            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 删除区域(新)
     *
     * @return
     */
    @ApiOperation(value = "删除区域(新)")
    @RequestMapping(value = "/del", method = RequestMethod.POST)
    @ResponseBody
    public R<Object> delete() {
        R<Object> result = new R<>();
        try {

            // 父级ID
            Long id = getLong("id");

            Map<String, Object> queryMap = new HashMap<>();
            queryMap.put("parentId", id);
            List<UnifiedAreaCity> areaCities = unifiedAreaDubboConsumerService.findAll(queryMap);

            if (areaCities != null && areaCities.size() > 0) {
                result.setCode(400);
                result.setSuccess(false);
                result.setMessage("请先删除子级区域！");
                return result;

            }
            unifiedAreaDubboConsumerService.delItemTran(id);
            result.setSuccess(true);

        } catch (Exception e) {
            result.setCode(String.valueOf(e.hashCode()));
            result.setSuccess(false);
            result.setMessage(e.getMessage());
            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
        }
        return result;
    }


    /**
     * 获取子区域下企业(新)
     *
     * @return
     */
    @ApiOperation(value = "获取子区域下企业(新)")
    @RequestMapping(value = "/getvirtinarea", method = RequestMethod.POST)
    @ResponseBody
    public R<List<SelectOptionVirt>> getVirtInArea() {
        R<List<SelectOptionVirt>> result = new R<>();
        try {
            Map<String, Object> params = new HashMap<>();

            params.put("inarea", 1);
            params.put("areaItemId", getLong("areaItemId"));

            List<SelectOptionVirt> ls = unifiedAreaDubboConsumerService.getVirtNotInArea(params);

            result.setData(ls);
            result.setSuccess(true);

        } catch (Exception e) {
            result.setCode(String.valueOf(e.hashCode()));
            result.setSuccess(false);
            result.setMessage(e.getMessage());
            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 子级区域下拉框
     *
     * @return
     */
    @ApiOperation(value = "子级区域下拉框")
    @RequestMapping(value = "/getareaitemselect", method = RequestMethod.POST)
    @ResponseBody
    public R<List<SelectOptionAreaItem>> getAreaItemSelect() {

        R<List<SelectOptionAreaItem>> result = new R<>();

        try {

            Map<String, Object> params = new HashMap<>();
            params.put("areaId", getString("areaId"));

            List<SelectOptionAreaItem> ls = unifiedAreaDubboConsumerService.findAreaItemSelect(params);

            result.setSuccess(true);
            result.setData(ls);

        } catch (Exception e) {

            result.setCode(String.valueOf(e.hashCode()));
            result.setSuccess(false);
            result.setMessage(e.getMessage());

            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
        }

        return result;
    }

    /**
     * 报表管理-区域统计
     *
     * @return
     */
    @ApiOperation(value = "报表管理-区域统计")
    @RequestMapping(value = "/getareatj", method = RequestMethod.POST)
    @ResponseBody
    public R<List<UnifiedAreaTJ>> getAreaTj() {

        R<List<UnifiedAreaTJ>> result = new R<>();

        try {
            Map<String, Object> headMap = new HashMap<>();

            // 销售价
            BigDecimal headSalesKpiTarget      = BigDecimal.ZERO;
            BigDecimal headOrderAmount         = BigDecimal.ZERO;
            BigDecimal headOrderRefundAmount   = BigDecimal.ZERO;
            BigDecimal headSalesCompletionRate = BigDecimal.ZERO;

            // 成本价
            BigDecimal headProfitKpiTarget       = BigDecimal.ZERO;
            BigDecimal headOrderCostAmount       = BigDecimal.ZERO;
            BigDecimal headOrderRefundCostAmount = BigDecimal.ZERO;
            BigDecimal headProfitCompletionRate  = BigDecimal.ZERO;

            BigDecimal headOrderProfitAmount = BigDecimal.ZERO;

            /****************************************** 搜索框 start ******************************************/
            Map<String, Object> params = new HashMap<>();
            // 区域选择
            params.put("areaId", getString("areaId"));
            // 月份
            String dtstr = getString("month");//yyyy-MM
            int    year  = Integer.parseInt(dtstr.substring(0, 4));
            int    month = Integer.parseInt(dtstr.substring(5));
            params.put("yearly", year);
            params.put("monthly", month);
            // 客户经理
            params.put("customerId", getLong("customerId"));
            // 采购专家
            params.put("purchaseId", getLong("purchaseId"));
            /****************************************** 搜索框 start ******************************************/

            List<UnifiedAreaTJ> ls = unifiedAreaDubboConsumerService.getareatj(params);

            List<UnifiedAreaTJ> templs = ls;

            for (UnifiedAreaTJ item : ls) {

                Map<String, Object> queryTJ = new HashMap<>();
                queryTJ.put("areaId", item.getId());
                queryTJ.put("syear", year);
                queryTJ.put("smonth", month);
                UnifiedStatisticsVirtSum statisticsVirtSum = unifiedStatisticsVirtDubboConsumerService.getStatisticsSum(queryTJ);

                // add
                if (statisticsVirtSum == null) {

                    statisticsVirtSum = new UnifiedStatisticsVirtSum();

                    statisticsVirtSum.setQuantity(0);

                    /****************************************** mark by linjinyu at 20201125 重构 start ******************************************/
                    statisticsVirtSum.setOrderAmount(new BigDecimal("0"));
                    statisticsVirtSum.setOrderCostAmount(new BigDecimal("0"));
                    statisticsVirtSum.setOrderRefundAmount(new BigDecimal("0"));
                    statisticsVirtSum.setOrderRefundCostAmount(new BigDecimal("0"));
                    statisticsVirtSum.setOrderTransportAmount(new BigDecimal("0"));

                    statisticsVirtSum.setGoodsAmount(new BigDecimal("0"));
                    statisticsVirtSum.setGoodsCostAmount(new BigDecimal("0"));
                    statisticsVirtSum.setGoodsRefundAmount(new BigDecimal("0"));
                    statisticsVirtSum.setGoodsRefundCostAmount(new BigDecimal("0"));
                    statisticsVirtSum.setGoodsTransportAmount(new BigDecimal("0"));

                    /****************************************** mark by linjinyu at 20201125 重构   end ******************************************/

                    statisticsVirtSum.setPayableAmount(new BigDecimal(0));
                }

                item.setOrderCostAmount(statisticsVirtSum.getOrderCostAmount());

                //item.setOrderCostAmountReturn(null);

                //add 20200219 新增成本金额 退货成本金额
                Map<String, Object> costQuery = new HashMap<>();
                costQuery.put("sYear", year);
                costQuery.put("sMonth", month);
                costQuery.put("areaId", item.getId());
                costQuery.put("cost", 2);
                BigDecimal costAmountReturn = unifiedStatisticsVirtDubboConsumerService.getOrderCostAmount(costQuery);

                if (costAmountReturn == null) {
                    costAmountReturn = new BigDecimal("0");
                }

                item.setOrderRefundCostAmount(costAmountReturn);

//				BigDecimal orderamount = unifiedStatisticsVirtDubboConsumerService.getOrderAmountByAreaItem(queryTJ);
//				BigDecimal returnamount = unifiedStatisticsVirtDubboConsumerService.getreturnAmountByAreaItem(queryTJ);
//				if (orderamount == null) {
//					orderamount = new BigDecimal("0");
//				}
//				if (returnamount == null) {
//					returnamount = new BigDecimal("0");
//				}

                item.setOrderAmount(statisticsVirtSum.getOrderAmount());
                item.setOrderRefundAmount(statisticsVirtSum.getOrderRefundAmount());

                // 完成率 =(完成金额-退货金额)÷ KPI指标
                if (item.getKpiTarget() != null
                        && item.getKpiTarget().compareTo(new BigDecimal(0)) > 0) {

//					item.setOverRate(new BigDecimal((item.getOrderAmount().doubleValue()-item.getOrderRefundAmount().doubleValue()) / item.getKpiTarget().doubleValue()));

                    item.setOverRate(item.getOrderAmount().subtract(item.getOrderRefundAmount()).divide(item.getKpiTarget(), 4, BigDecimal.ROUND_HALF_DOWN));

                }
                int iy = year;
                int im = month;
                if (im == 1) {
                    im = 12;
                    iy--;
                } else {
                    im--;
                }

                Map<String, Object> lastTJ = new HashMap<>();
                lastTJ.put("syear", iy);
                lastTJ.put("smonth", im);
                lastTJ.put("areaId", item.getId());

                //BigDecimal lastamount = unifiedStatisticsVirtDubboConsumerService.getOrderAmountByAreaItem(lastTJ);
                UnifiedStatisticsVirtSum statisticsVirtSumLast = unifiedStatisticsVirtDubboConsumerService.getStatisticsSum(lastTJ);
//				if (lastamount == null) {
//					lastamount = new BigDecimal("0");
//				}


                if (statisticsVirtSumLast == null) {

                    statisticsVirtSumLast = new UnifiedStatisticsVirtSum();

                    statisticsVirtSumLast.setQuantity(0);

                    /****************************************** mark by linjinyu at 20201125 重构 start ******************************************/

                    statisticsVirtSumLast.setOrderAmount(new BigDecimal("0"));
                    statisticsVirtSumLast.setOrderCostAmount(new BigDecimal("0"));
                    statisticsVirtSumLast.setOrderRefundAmount(new BigDecimal("0"));
                    statisticsVirtSumLast.setOrderRefundCostAmount(new BigDecimal("0"));
                    statisticsVirtSumLast.setOrderTransportAmount(new BigDecimal("0"));

                    statisticsVirtSumLast.setGoodsAmount(new BigDecimal("0"));
                    statisticsVirtSumLast.setGoodsCostAmount(new BigDecimal("0"));
                    statisticsVirtSumLast.setGoodsRefundAmount(new BigDecimal("0"));
                    statisticsVirtSumLast.setGoodsRefundCostAmount(new BigDecimal("0"));
                    statisticsVirtSumLast.setGoodsTransportAmount(new BigDecimal("0"));

                    /****************************************** mark by linjinyu at 20201125 重构 start ******************************************/

                    statisticsVirtSumLast.setPayableAmount(new BigDecimal(0));
                }

                item.setLastMonthAmount(statisticsVirtSumLast.getOrderAmount());

                // 上月环比 =(本月销售(完成)金额-上月销售(完成)金额)/ 上月销售(完成)金额 × 100%
                if (statisticsVirtSumLast.getOrderAmount() != null && statisticsVirtSumLast.getOrderAmount().doubleValue() != 0) {
//					item.setLastMonthRate(new BigDecimal((item.getOrderAmount().doubleValue()-item.getLastMonthAmount().doubleValue()) / item.getLastMonthAmount().doubleValue()));
                    item.setLastMonthRate(item.getOrderAmount().subtract(item.getLastMonthAmount()).divide(item.getLastMonthAmount(), 4, BigDecimal.ROUND_HALF_DOWN));
                }


//				本月毛利完成率 -修前:error 计算(mark by linjinyu at 20201126)


                // 本月累计毛利润 =(本月订单销额总额-本月订单成本总额-本月订单退货-本月退货成本)
//				item.setProfit(new BigDecimal(item.getOrderAmount().doubleValue()-item.getOrderCostAmount().doubleValue()-item.getOrderRefundAmount().doubleValue()-item.getOrderRefundCostAmount().doubleValue()));
                item.setProfit(item.getOrderAmount().subtract(item.getOrderCostAmount()).subtract(item.getOrderRefundAmount()).subtract(item.getOrderRefundCostAmount()));

                if (item.getProfit() != null
                        && item.getOrderRefundAmount() != null
                        && item.getOrderAmount() != null
                        && (item.getOrderAmount().doubleValue() - item.getOrderRefundAmount().doubleValue()) > 0) {

                    // 本月毛利率 = 利润 / (销售(完成)总额-销售(完成)退货总额)
//					item.setProfitRate(new BigDecimal(item.getProfit().doubleValue() / (item.getOrderAmount().doubleValue()-item.getOrderRefundAmount().doubleValue())));
                    item.setProfitRate(item.getProfit().divide(item.getOrderAmount().subtract(item.getOrderRefundAmount()), 4, BigDecimal.ROUND_HALF_DOWN));

                }


                log.info("本月毛利完成率 = 利润(本月订单销额总额-本月订单成本总额-本月订单退货-本月退货成本) / 毛利KPI指标: \n{} , {}\n{} , {}",
                        item.getProfit(),
                        item.getProfit().compareTo(new BigDecimal(0)),
                        item.getProfitKpiTarget(),
                        item.getProfitKpiTarget().compareTo(new BigDecimal(0)));

                if (item.getProfit() != null && item.getProfit().compareTo(new BigDecimal(0)) > 0
                        && item.getProfitKpiTarget() != null && item.getProfitKpiTarget().compareTo(new BigDecimal(0)) > 0) {

                    // 本月毛利完成率 = 利润 / 毛利KPI指标
//					item.setProfitCompletionRate(new BigDecimal(item.getProfit().doubleValue() / (item.getProfitKpiTarget().doubleValue())));
                    item.setProfitCompletionRate(item.getProfit().divide(item.getProfitKpiTarget(), 4, BigDecimal.ROUND_HALF_DOWN));
                }

                // 计算头部数据
//				if (item.getKpiTarget() != null) {
//					headkpi = headkpi.add(item.getKpiTarget());
//				}
//				headAmount = headAmount.add(item.getOrderAmount());
//				headreturn = headreturn.add(item.getOrderRefundAmount());

                // 统计
                int virtCount = item.getVirtCount() == null ? 0 : item.getVirtCount();

                for (int i = 0; i < templs.size(); i++) {
                    if (templs.get(i).getId().equals(item.getId())) {
                        continue;
                    }
                    if (Arrays.asList(templs.get(i).getAreaFullIds().split(",")).contains(item.getId().toString())) {
                        virtCount += (templs.get(i).getVirtCount() == null ? 0 : templs.get(i).getVirtCount());
                    }
                }

                item.setVirtCount(virtCount);
            }


            // 统计
            int toplev = 3;
            for (UnifiedAreaTJ item :
                    ls) {
                if (item.getLev() < toplev) {
                    toplev = item.getLev();
                }
            }

            // 树形转化
            List<UnifiedAreaTJ> nodeList = new ArrayList<>();


            for (UnifiedAreaTJ node : ls) {

                if (node.getLev() == toplev) {

                    if (null != node.getOrderAmount()) {
                        headOrderAmount = headOrderAmount.add(node.getOrderAmount());
                    }

                    if (null != node.getOrderCostAmount()) {
                        headOrderCostAmount = headOrderCostAmount.add(node.getOrderCostAmount());
                    }

                    if (null != node.getOrderRefundAmount()) {
                        headOrderRefundAmount = headOrderRefundAmount.add(node.getOrderRefundAmount());
                    }

                    if (null != node.getOrderRefundCostAmount()) {
                        headOrderRefundCostAmount = headOrderRefundCostAmount.add(node.getOrderRefundCostAmount());
                    }

                    if (node.getKpiTarget() != null) {
                        headSalesKpiTarget = headSalesKpiTarget.add(node.getKpiTarget());
                    }

                    if (node.getProfitKpiTarget() != null) {
                        headProfitKpiTarget = headProfitKpiTarget.add(node.getProfitKpiTarget());
                    }
                }

                if (node.getLev() == toplev) {
                    node = ConvertTreeUtils.buildTree(ls, node);
                    nodeList.add(node);
                }
            }


            if (headSalesKpiTarget.compareTo(BigDecimal.ZERO) != 0) {
                // 销售完成率 =(完成金额-退货金额)÷ KPI指标
                headSalesCompletionRate = headOrderAmount.subtract(headOrderRefundAmount).divide(headSalesKpiTarget, 4, BigDecimal.ROUND_HALF_DOWN);
            }

            // 利润(本月订单销额总额-本月订单成本总额-本月订单退货-本月退货成本)
            headOrderProfitAmount = headOrderAmount.subtract(headOrderCostAmount).subtract(headOrderRefundAmount).subtract(headOrderRefundCostAmount);

            if (headProfitKpiTarget.compareTo(BigDecimal.ZERO) != 0) {
                // 本月毛利完成率 = 利润 / 毛利KPI指标
                headProfitCompletionRate = headOrderProfitAmount.divide(headProfitKpiTarget, 4, BigDecimal.ROUND_HALF_DOWN);
            }

            // 销售KPI指标-本月销售KPI指标
            headMap.put("headSalesKpiTarget", headSalesKpiTarget);
            // 销售总额
            headMap.put("headOrderAmount", headOrderAmount);
            // 退款总额
            headMap.put("headOrderRefundAmount", headOrderRefundAmount);
            // 销售指标完成率
            headMap.put("headSalesCompletionRate", headSalesCompletionRate);

            // 毛利KPI指标-毛利KPI指标
            headMap.put("headProfitKpiTarget", headProfitKpiTarget);
            // 订单成本总额
            headMap.put("headOrderCostAmount", headOrderCostAmount);
            // 退款成本总额
            headMap.put("headOrderRefundCostAmount", headOrderRefundCostAmount);
            // 毛利金额 headOrderAmount-headOrderCostAmount
            headMap.put("headOrderProfitAmount", headOrderProfitAmount);
            // 毛利完成率
            headMap.put("headProfitCompletionRate", headProfitCompletionRate);

            result.setSuccess(true);
            result.setData(nodeList);
            result.setHeadData(headMap);

        } catch (Exception e) {

            result.setCode(String.valueOf(e.hashCode()));
            result.setSuccess(false);
            result.setMessage(e.getMessage());

            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
        }

        return result;
    }

    /**
     * 导出区域统计
     *
     * @param response
     * @throws IOException
     */
    @ApiOperation(value = "区域统计-Excel 导出")
    @RequestMapping(value = "/getareatjexcel", method = RequestMethod.GET)
    public void getNotDzOrderExcel(HttpServletResponse response) throws IOException {

        try {

            Map<String, Object> params = new HashMap<>();

            params.put("areaId", getString("areaId"));

            String dtstr = getString("month");// yyyy-MM
            int    year  = Integer.parseInt(dtstr.substring(0, 4));
            int    month = Integer.parseInt(dtstr.substring(5));
            params.put("yearly", year);
            params.put("monthly", month);

            params.put("customerId", getLong("customerId"));
            params.put("purchaseId", getLong("purchaseId"));

            // 区域数据
            List<UnifiedAreaTJ> dataList = unifiedAreaDubboConsumerService.getareatj(params);

            for (UnifiedAreaTJ item : dataList) {

                Map<String, Object> queryTJ = new HashMap<>();
                queryTJ.put("syear", year);
                queryTJ.put("smonth", month);
                queryTJ.put("areaId", item.getId());

                UnifiedStatisticsVirtSum statisticsVirtSum = unifiedStatisticsVirtDubboConsumerService.getStatisticsSum(queryTJ);

                // add
                if (statisticsVirtSum == null) {

                    statisticsVirtSum = new UnifiedStatisticsVirtSum();

                    statisticsVirtSum.setQuantity(0);

                    /****************************************** mark by linjinyu at 20201125 重构 start ******************************************/

                    statisticsVirtSum.setOrderAmount(new BigDecimal("0"));
                    statisticsVirtSum.setOrderCostAmount(new BigDecimal("0"));
                    statisticsVirtSum.setOrderRefundAmount(new BigDecimal("0"));
                    statisticsVirtSum.setOrderRefundCostAmount(new BigDecimal("0"));
                    statisticsVirtSum.setOrderTransportAmount(new BigDecimal("0"));

                    statisticsVirtSum.setGoodsAmount(new BigDecimal("0"));
                    statisticsVirtSum.setGoodsCostAmount(new BigDecimal("0"));
                    statisticsVirtSum.setGoodsRefundAmount(new BigDecimal("0"));
                    statisticsVirtSum.setGoodsRefundCostAmount(new BigDecimal("0"));
                    statisticsVirtSum.setGoodsTransportAmount(new BigDecimal("0"));

                    /****************************************** mark by linjinyu at 20201125 重构   end ******************************************/

                    statisticsVirtSum.setPayableAmount(new BigDecimal(0));
                }

                item.setOrderCostAmount(statisticsVirtSum.getOrderCostAmount());
                //item.setOrderCostAmountReturn(null);


                /****************************************** 退货成本 start ******************************************/
                // add 20200219 新增成本金额 退货成本金额
                Map<String, Object> costQuery = new HashMap<>();
                costQuery.put("sYear", year);
                costQuery.put("sMonth", month);
                costQuery.put("areaId", item.getId());
                costQuery.put("cost", 2);

                BigDecimal orderRefundCostAmount = unifiedStatisticsVirtDubboConsumerService.getOrderCostAmount(costQuery);
                if (orderRefundCostAmount == null) {
                    orderRefundCostAmount = new BigDecimal("0");
                }
                item.setOrderRefundCostAmount(orderRefundCostAmount);
                /****************************************** 退货成本 start ******************************************/

//				BigDecimal orderamount = unifiedStatisticsVirtDubboConsumerService.getOrderAmountByAreaItem(queryTJ);
//				BigDecimal returnamount = unifiedStatisticsVirtDubboConsumerService.getreturnAmountByAreaItem(queryTJ);
//				if (orderamount == null) {
//					orderamount = new BigDecimal("0");
//				}
//				if (returnamount == null) {
//					returnamount = new BigDecimal("0");
//				}

                item.setOrderAmount(statisticsVirtSum.getOrderAmount());
                item.setOrderRefundAmount(statisticsVirtSum.getOrderRefundAmount());

                // 本月销售额完成率 =(本月销售(完成)金额-本月退货金额)÷ KPI指标
                if (item.getKpiTarget() != null && item.getKpiTarget().doubleValue() != 0) {
                    item.setOverRate(new BigDecimal((item.getOrderAmount().doubleValue() - item.getOrderRefundAmount().doubleValue())
                            / item.getKpiTarget().doubleValue()
                    ));
                }


                /****************************************** 上月统计数据 start ******************************************/
                int iy = year;
                int im = month;
                if (im == 1) {
                    im = 12;
                    iy--;
                } else {
                    im--;
                }

                Map<String, Object> lastMountTJParams = new HashMap<>();
                lastMountTJParams.put("syear", iy);
                lastMountTJParams.put("smonth", im);
                lastMountTJParams.put("areaId", item.getId());

                //BigDecimal lastamount = unifiedStatisticsVirtDubboConsumerService.getOrderAmountByAreaItem(lastTJ);
                UnifiedStatisticsVirtSum statisticsVirtSumLast = unifiedStatisticsVirtDubboConsumerService.getStatisticsSum(lastMountTJParams);
//				if (lastamount == null) {
//					lastamount = new BigDecimal("0");
//				}

                if (statisticsVirtSumLast == null) {

                    statisticsVirtSumLast = new UnifiedStatisticsVirtSum();

                    statisticsVirtSumLast.setQuantity(0);

                    /****************************************** mark by linjinyu at 20201125 重构 start ******************************************/
                    statisticsVirtSumLast.setOrderAmount(new BigDecimal("0"));
                    statisticsVirtSumLast.setOrderCostAmount(new BigDecimal("0"));
                    statisticsVirtSumLast.setOrderRefundAmount(new BigDecimal("0"));
                    statisticsVirtSumLast.setOrderRefundCostAmount(new BigDecimal("0"));
                    statisticsVirtSumLast.setOrderTransportAmount(new BigDecimal("0"));

                    statisticsVirtSumLast.setGoodsAmount(new BigDecimal("0"));
                    statisticsVirtSumLast.setGoodsCostAmount(new BigDecimal("0"));
                    statisticsVirtSumLast.setGoodsRefundAmount(new BigDecimal("0"));
                    statisticsVirtSumLast.setGoodsRefundCostAmount(new BigDecimal("0"));
                    statisticsVirtSumLast.setGoodsTransportAmount(new BigDecimal("0"));

                    /****************************************** mark by linjinyu at 20201125 重构   end ******************************************/
                    statisticsVirtSumLast.setPayableAmount(new BigDecimal(0));

                }

                item.setLastMonthAmount(statisticsVirtSumLast.getOrderAmount());

                // 上月环比=(本月销售(完成)金额-上月完成金额)÷ 上月完成金额 × 100%
                if (statisticsVirtSumLast.getOrderAmount() != null && statisticsVirtSumLast.getOrderAmount().doubleValue() != 0) {
                    item.setLastMonthRate(new BigDecimal((item.getOrderAmount().doubleValue() - item.getLastMonthAmount().doubleValue())
                            / item.getLastMonthAmount().doubleValue()));
                }
                /****************************************** 上月统计数据   end ******************************************/

                // 本月累计毛利润计算 (本月营业总额-本月成本 -本月退货-本月退货成本)
                item.setProfit(new BigDecimal(item.getOrderAmount().doubleValue() - item.getOrderCostAmount().doubleValue()
                        - (item.getOrderRefundAmount().doubleValue() - item.getOrderRefundCostAmount().doubleValue())));
                // 本月毛利率 利润/ (总额-退货)
                if (item.getProfit() != null && item.getOrderRefundAmount() != null && item.getOrderAmount() != null && (item.getOrderAmount().doubleValue()
                        - item.getOrderRefundAmount().doubleValue()) > 0) {
                    item.setProfitRate(new BigDecimal(item.getProfit().doubleValue() / (item.getOrderAmount().doubleValue() - item.getOrderRefundAmount().doubleValue())));
                }

            }

            // TODO 待重构 mark by linjinyu at 20201125
            String[] field = {"areaName", "virtCount", "customerUsernames", "purchaseUsernames",
                    "kpiTarget", "orderAmount", "costPrice", "returnAmount", "costPriceReturn", "profit",
                    "profitrate", "lastAmount", "lastRate"};

            String[] fieldZhCn = {"区域", "企业数量", "客户经理", "采购专家",
                    "本月KPI指标", "本月营业总额", "本月成本总额", "本月退货营业额", "本月退货成本总额", "本月累计毛利",
                    "本月累计毛利率", "上月毛利", "上月环比"};

//			HSSFWorkbook workbook = ExcelExportModePoiHssfUtils.createWorkbook(dataList, fieldZhCn, field, "区域统计");
//			// 准备将Excel的输出流通过response输出到页面下载
//			response.reset();
//			// 二进制输出流
//			response.setContentType("application/octet-stream");
//			response.setCharacterEncoding("UTF-8");
//			// 这后面可以设置导出Excel的名称,此例中名为student.xls
//			response.setHeader("Content-disposition",
//					"attachment;filename=" + URLEncoder.encode("区域统计", "UTF-8") + ".xls");
//			// 刷新缓冲
//			response.flushBuffer();
//
//			// workbook将Excel写入到response的输出流中,供页面下载
//			workbook.write(response.getOutputStream());

            ExcelResponse.out(dataList, fieldZhCn, field, "区域统计", "区域统计", response);

        } catch (Exception e) {

            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
        }
    }

    /**
     * 企业统计
     *
     * @return
     */
    @ApiOperation(value = "企业统计")
    @RequestMapping(value = "/getvirttj", method = RequestMethod.POST)
    @ResponseBody
    public R<List<UnifiedCustomerTJ>> getVirtTj() {

        R<List<UnifiedCustomerTJ>> result = new R<>();

        try {

            Map<String, Object> params = new HashMap<>();

            params.put("areaId", getLong("areaId"));
            params.put("virtId", getString("virtId"));


            // yyyy-MM
            String dtstr = getString("month");

            int year  = Integer.parseInt(dtstr.substring(0, 4));
            int month = Integer.parseInt(dtstr.substring(5));

            params.put("yearly", year);
            params.put("monthly", month);
            params.put("customerId", getLong("customerId"));
            params.put("purchaseId", getLong("purchaseId"));

            result = unifiedStatisticsVirtDubboConsumerService.getDataByPage(getToken(), params, getPageNum(), getPageSize());

            List<Long> outVirtIds = result.getData()
                    .stream()
                    .filter(o -> null != o.getVirtId())
                    .map(UnifiedCustomerTJ::getVirtId)
                    .distinct()
                    .collect(Collectors.toList());

            Map<Long, SysEnterprise> optionSysEnterprise = sysEnterpriseDubboConsumerService.findByOutVirtIdsConvertKV(outVirtIds);

            for (UnifiedCustomerTJ item : result.getData()) {


                // TODO 就目前数据 这个地方有可能为空 mark by linjinyu 20200706
//				SysEnterprise sysEnterprise = sysEnterpriseDubboConsumerService.findByVirtId(item.getVirtId());

                if (null != optionSysEnterprise.get(item.getVirtId()) && null != optionSysEnterprise.get(item.getVirtId())) {
                    item.setVirtName(optionSysEnterprise.get(item.getVirtId()).getEnterpriseName());
                } else {
                    item.setVirtName("企业信息异常-不存在");
                }


                // add 20200219 新增成本金额 退货成本金额
                Map<String, Object> costQuery = new HashMap<>();

                costQuery.clear();
                costQuery.put("sYear", year);
                costQuery.put("sMonth", month);
                costQuery.put("virtId", item.getVirtId());
                // 负方向
                costQuery.put("cost", 2);

                BigDecimal orderRefundCostAmount = unifiedStatisticsVirtDubboConsumerService.getOrderCostAmount(costQuery);

                if (orderRefundCostAmount == null) {
                    orderRefundCostAmount = new BigDecimal("0");
                }

                item.setOrderRefundCostAmount(orderRefundCostAmount);
                if (null == item.getOrderCostAmount()) {
                    item.setOrderCostAmount(new BigDecimal(0));
                }

                int iy = year;
                int im = month;
                if (im == 1) {
                    im = 12;
                    iy--;
                } else {
                    im--;
                }

                Map<String, Object> lastTJ = new HashMap<>();
                lastTJ.put("sYear", iy);
                lastTJ.put("sMonth", im);
                lastTJ.put("virtId", item.getVirtId());

                List<UnifiedStatisticsVirt> statisticsVirts = unifiedStatisticsVirtDubboConsumerService.findAll(lastTJ);

                if (statisticsVirts != null && statisticsVirts.size() > 0) {
                    item.setLastOrderAmount(statisticsVirts.get(0).getOrderAmount());
                } else {
                    item.setLastOrderAmount(new BigDecimal(0));
                }

                // 上月环比=(本月完成金额-上月完成金额)÷上月完成金额×100%
                if (item.getLastOrderAmount() != null && item.getLastOrderAmount().doubleValue() != 0) {
                    item.setLastRate(new BigDecimal((item.getOrderAmount().doubleValue() - item.getLastOrderAmount().doubleValue())
                            / item.getLastOrderAmount().doubleValue()));
                }

                UnifiedAreaCityWithVirt areaCityWithVirt = unifiedAreaDubboConsumerService.getAreaDetailByVirtId(item.getVirtId());

                if (areaCityWithVirt == null) {
                    continue;
                }

                item.setAreaId(areaCityWithVirt.getId());

                item.setAreaName(areaCityWithVirt.getAreaFullNames());
                item.setCustomerUsernames(areaCityWithVirt.getCustomerUsersName());
                item.setPurchaseUsernames(areaCityWithVirt.getPurchaseUsersName());

                // 订单退货金额
                if (item.getOrderRefundAmount() == null) {
                    item.setOrderRefundAmount(new BigDecimal(0));
                }


                // 本月累计毛利润计算 (本月营业总额-本月成本 -本月退货-本月退货成本)
                item.setProfit(new BigDecimal(item.getOrderAmount().doubleValue() - item.getOrderCostAmount().doubleValue()
                        - (item.getOrderRefundAmount().doubleValue() - item.getOrderRefundCostAmount().doubleValue())));

                // 本月毛利率 利润 / (总额-退货)
                if (item.getProfit() != null && item.getOrderRefundAmount() != null && item.getOrderAmount() != null && (item.getOrderAmount().doubleValue()
                        - item.getOrderRefundAmount().doubleValue()) > 0) {
                    item.setProfitRate(new BigDecimal(item.getProfit().doubleValue() / (item.getOrderAmount().doubleValue() - item.getOrderRefundAmount().doubleValue())));
                }

            }
        } catch (Exception e) {

            result.setCode(String.valueOf(e.hashCode()));
            result.setSuccess(false);
            result.setMessage(e.getMessage());

            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
        }

        return result;
    }


    /**
     * 企业统计-Excel 导出
     *
     * @return
     */
    @ApiOperation(value = "企业统计-Excel 导出")
    @RequestMapping(value = "/getvirttjexcel", method = RequestMethod.GET)
    public void getVirtTjExcel(HttpServletResponse response) throws IOException {

        try {

            Map<String, Object> params = new HashMap<>();

            params.put("areaId", getLong("areaId"));
            params.put("virtId", getString("virtId"));

            String dtstr = getString("month");//yyyy-MM
            int    year  = Integer.parseInt(dtstr.substring(0, 4));
            int    month = Integer.parseInt(dtstr.substring(5));
            params.put("yearly", year);
            params.put("monthly", month);

            params.put("customerId", getLong("customerId"));
            params.put("purchaseId", getLong("purchaseId"));

            List<UnifiedCustomerTJ> dataList = unifiedStatisticsVirtDubboConsumerService.getStatisticsVirtData(getToken(), params);
            for (UnifiedCustomerTJ item : dataList) {

                item.setSYear(year);
                item.setSMonth(month);

                SysEnterprise sysEnterprise = sysEnterpriseDubboConsumerService.findByVirtId(item.getVirtId());
                item.setVirtName(sysEnterprise.getEnterpriseName());
                // add 20200219 新增成本金额 退货成本金额
                Map<String, Object> costQuery = new HashMap<>();

                costQuery.clear();
                costQuery.put("sYear", year);
                costQuery.put("sMonth", month);
                costQuery.put("virtId", item.getVirtId());
                // 负方向
                costQuery.put("cost", 2);

                BigDecimal orderRefundCostAmount = unifiedStatisticsVirtDubboConsumerService.getOrderCostAmount(costQuery);
                if (orderRefundCostAmount == null) {
                    orderRefundCostAmount = new BigDecimal("0");
                }

                item.setOrderRefundCostAmount(orderRefundCostAmount);

                if (item.getOrderCostAmount() == null) {
                    item.setOrderCostAmount(new BigDecimal(0));
                }

                int iy = year;
                int im = month;
                if (im == 1) {
                    im = 12;
                    iy--;
                } else {
                    im--;
                }

                Map<String, Object> lastTJ = new HashMap<>();
                lastTJ.put("sYear", iy);
                lastTJ.put("sMonth", im);
                lastTJ.put("virtId", item.getVirtId());

                List<UnifiedStatisticsVirt> statisticsVirts = unifiedStatisticsVirtDubboConsumerService.findAll(lastTJ);

                if (statisticsVirts != null && statisticsVirts.size() > 0) {
                    item.setLastOrderAmount(statisticsVirts.get(0).getOrderAmount());
                } else {
                    item.setLastOrderAmount(new BigDecimal(0));
                }

                // 上月环比=(本月完成金额-上月完成金额)÷上月完成金额×100%
                if (item.getLastOrderAmount() != null && item.getLastOrderAmount().doubleValue() != 0) {
                    item.setLastRate(new BigDecimal((item.getOrderAmount().doubleValue() - item.getLastOrderAmount().doubleValue())
                            / item.getLastOrderAmount().doubleValue()));
                }

                UnifiedAreaCityWithVirt areaCityWithVirt = unifiedAreaDubboConsumerService.getAreaDetailByVirtId(item.getVirtId());

                if (areaCityWithVirt == null) {
                    continue;
                }

                item.setAreaId(areaCityWithVirt.getId());
                item.setAreaName(areaCityWithVirt.getAreaName());
                item.setCustomerUsernames(areaCityWithVirt.getCustomerUsersName());
                item.setPurchaseUsernames(areaCityWithVirt.getPurchaseUsersName());


                // 本月累计毛利润计算 (本月营业总额-本月成本-本月退货-本月退货成本)
                item.setProfit(new BigDecimal(item.getOrderAmount().doubleValue() - item.getOrderCostAmount().doubleValue()
                        - (item.getOrderRefundAmount().doubleValue() - item.getOrderRefundCostAmount().doubleValue())));
            }

            String[] field = {"SYear", "SMonth", "areaName", "areaItemName", "customerUsernames", "purchaseUsernames",
                    "virtName", "orderAmount", "costPrice", "returnAmount", "costPriceReturn", "profit", "lastOrderAmount", "lastRate"};

            String[] fieldZhCn = {"年份", "月份", "一级区域", "二级区域", "客户经理", "采购专家",
                    "企业名称", "本月营业总额", "本月成本总额", "本月退货营业额", "本月退货成本总额", "本月累计毛利润", "上月完成金额",
                    "上月环比"};

//			HSSFWorkbook workbook = ExcelExportModePoiHssfUtils.createWorkbook(dataList, fieldZhCn, field, "企业统计");
//			// 准备将Excel的输出流通过response输出到页面下载
//			response.reset();
//			// 二进制输出流
//			response.setContentType("application/octet-stream");
//			response.setCharacterEncoding("UTF-8");
//			// 这后面可以设置导出Excel的名称,此例中名为student.xls
//			response.setHeader("Content-disposition",
//					"attachment;filename=" + URLEncoder.encode("企业统计", "UTF-8") + ".xls");
//			// 刷新缓冲
//			response.flushBuffer();
//
//			// workbook将Excel写入到response的输出流中,供页面下载
//			workbook.write(response.getOutputStream());

            ExcelResponse.out(dataList, fieldZhCn, field, "企业统计", "企业统计", response);

        } catch (Exception e) {
            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
        }

    }
}
