Subversion Repositories SmartDukaan

Rev

Rev 35848 | View as "text/plain" | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.spice.profitmandi.service;

import com.google.gson.Gson;
import com.spice.profitmandi.common.enumuration.MessageType;
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.common.model.*;
import com.spice.profitmandi.dao.Interface.Campaign;
import com.spice.profitmandi.dao.entity.catalog.BrandCatalog;
import com.spice.profitmandi.dao.entity.dtr.Document;
import com.spice.profitmandi.dao.entity.dtr.NotificationCampaign;
import com.spice.profitmandi.dao.entity.fofo.PartnerDailyInvestment;
import com.spice.profitmandi.dao.entity.fofo.PartnerTargetDetails;
import com.spice.profitmandi.dao.entity.fofo.PartnerType;
import com.spice.profitmandi.dao.model.BrandWiseModel;
import com.spice.profitmandi.dao.model.SimpleCampaign;
import com.spice.profitmandi.dao.model.SimpleCampaignParams;
import com.spice.profitmandi.dao.repository.dtr.DocumentRepository;
import com.spice.profitmandi.dao.repository.dtr.Mongo;
import com.spice.profitmandi.dao.repository.fofo.*;
import com.spice.profitmandi.dao.repository.transaction.OrderRepository;
import com.spice.profitmandi.service.catalog.BrandsService;
import com.spice.profitmandi.service.inventory.InventoryService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;

@Component
public class FofoUser {

    @Autowired
    private Gson gson;

    @Autowired
    private PartnerInvestmentService partnerInvestmentService;

    @Autowired
    private PartnerDailyInvestmentRepository partnerDailyInvestmentRepository;

    @Autowired
    ChartService chartService;

    @Autowired
    FofoOrderItemRepository fofoOrderItemRepository;

    @Autowired
    FofoOrderRepository fofoOrderRepository;

    @Autowired
    PartnerTypeChangeService partnerTypeChangeService;

    @Autowired
    PartnerTargetRepository partnerTargetRepository;

    @Autowired
    InventoryService inventoryService;

    @Autowired
    private Mongo mongoClient;

    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    DocumentRepository documentRepository;

    @Autowired
    BrandsService brandsService;

    @Autowired
    CurrentInventorySnapshotRepository currentInventorySnapshotRepository;

    private static final Logger LOGGER = LogManager.getLogger(FofoUser.class);

    List<String> colorList = Arrays.asList("papayawhip", "mediumseagreen", "dodgerblue", "darkblue", "gold", "#eb0029", "coral", "steelblue", "red", "deeppink", "midnightblue", "cornsilk");

    List<String> borderList = Arrays.asList("pink", "lawngreen", "lightblue", "#0000cd", "#f7e98e", "#eb0029", "lightcoral", "#0000cd", "lightsalmon", "pink", "#0000cd", "cornsilk");

    List<String> brands = Arrays.asList("Accessories", "Oppo", "Vivo", "Samsung", "Realme", "Xiaomi", "OnePlus", "Tecno", "Itel", "Lava", "Nokia");

    public String format(long value) {

        if (value >= 1000 && value < 100000) {
            double lakhs = value / 100000.0;
            double truncated = Math.floor(lakhs * 100) / 100.0;
            return String.format("%.2f L", truncated);
        }

        if (value >= 100000 && value < 10000000) {
            double lakhs = value / 100000.0;
            double truncated = Math.floor(lakhs * 100) / 100.0;
            return String.format("%.2f L", truncated);
        }

        if (value >= 10000000) {
            double crores = value / 10000000.0;
            double truncated = Math.floor(crores * 100) / 100.0;
            return String.format("%.2f Cr", truncated);
        }

        return String.valueOf(value);
    }


    @Cacheable(value = "brandStockPrices", cacheManager = "redisVeryShortCacheManager")
    public List<BrandStockPrice> getBrandStockPrices(int fofoId, boolean allBrands) throws Exception {
        Map<String, BrandStockPrice> brandStockPricesMap = inventoryService.getBrandWiseStockValue(fofoId);
        List<BrandStockPrice> brandStockPrices = new ArrayList<>();
        List<BrandCatalog> mobileBrands = brandsService.getBrandsToDisplay(3);
        mobileBrands.stream().forEach(x -> {
            if (brandStockPricesMap.containsKey(x.getName())) {
                BrandStockPrice brandStockPrice = brandStockPricesMap.get(x.getName());
                brandStockPrice.setBrandUrl(x.getLogoUrl());
                brandStockPrice.setRank(x.getBrandCategory().getRank());
                brandStockPrices.add(brandStockPrice);
            }
        });

        if (allBrands) {
            return brandStockPrices.stream().sorted(Comparator.comparingInt(BrandStockPrice::getRank)).collect(Collectors.toList());

        }

        return brandStockPrices.stream().filter(x -> x.getTotalQty() > 0).sorted(Comparator.comparingInt(BrandStockPrice::getRank)).collect(Collectors.toList());
    }

    @Cacheable(value = "partnerInvestments", cacheManager = "redisVeryShortCacheManager")
    public Map<String, Object> getInvestments(int fofoId) throws Exception {
        Map<String, Object> investments = new LinkedHashMap<>();
        PartnerDailyInvestment investment = partnerInvestmentService.getInvestment(fofoId, 0);
        LocalDate currentMonthStart = LocalDate.now().withDayOfMonth(1);
        LocalDate yesterDate = LocalDate.now().minusDays(1);
        PartnerDailyInvestment yesterdayInvestment = partnerDailyInvestmentRepository.select(fofoId, yesterDate);
        if (yesterdayInvestment == null) {
            yesterdayInvestment = new PartnerDailyInvestment();
        }

        List<PartnerDailyInvestment> currentMonthInvestments = partnerDailyInvestmentRepository.selectAll(fofoId, currentMonthStart, currentMonthStart.withDayOfMonth(currentMonthStart.lengthOfMonth()));
        boolean isInvestmentOk = partnerInvestmentService.isInvestmentOk(fofoId, ProfitMandiConstants.MIN_INVESTMENT_PERCENTAGE, ProfitMandiConstants.CUTOFF_INVESTMENT);

        long okInvestmentDays = currentMonthInvestments.stream().filter(x -> x.getShortPercentage() <= ProfitMandiConstants.OK_INVESTMENT_SHORT_PERCENTAGE).collect(Collectors.counting());
        PartnerType partnerType = partnerTypeChangeService.getTypeOnDate(fofoId, LocalDate.now());
        investments.put("today", investment.getOwnInvestment());
        investments.put("partnerType", partnerType);
        investments.put("investment", investment);
        investments.put("minimumInvestment", investment.getMinInvestment());
        investments.put("totalInvestment", investment.getOwnInvestment());
        investments.put("isInvestmentOk", isInvestmentOk);
        investments.put("inStock", investment.getInStockAmount());
        investments.put("minimum", investment.getMinInvestmentString());
        investments.put("short", investment.getShortPercentage());
        investments.put("activated_stock", investment.getActivatedStockAmount());
        investments.put("okDays", okInvestmentDays);
        investments.put("cutOf", 100-ProfitMandiConstants.CUTOFF_INVESTMENT);
        investments.put("minInvestment", 100-ProfitMandiConstants.MIN_INVESTMENT_PERCENTAGE);
        return investments;
    }

    public Map<String, Object> getInvestmentsMonths(int fofoId, int month) throws Exception {
        Map<String, Object> investments = new LinkedHashMap<>();
        PartnerDailyInvestment investment = partnerInvestmentService.getInvestment(fofoId, 0);
        LocalDate currentMonthStart = LocalDate.now().withDayOfMonth(1).minusMonths(month);

        LocalDate yesterDate = LocalDate.now().minusDays(1);
        PartnerDailyInvestment yesterdayInvestment = partnerDailyInvestmentRepository.select(fofoId, yesterDate);
        if (yesterdayInvestment == null) {
            yesterdayInvestment = new PartnerDailyInvestment();
        }

        List<PartnerDailyInvestment> currentMonthInvestments = partnerDailyInvestmentRepository.selectAll(fofoId, currentMonthStart, currentMonthStart.withDayOfMonth(currentMonthStart.lengthOfMonth()));

        long okInvestmentDays = currentMonthInvestments.stream().filter(x -> x.getShortPercentage() <= ProfitMandiConstants.OK_INVESTMENT_SHORT_PERCENTAGE).collect(Collectors.counting());
        investments.put("today", investment.getOwnInvestment());
        investments.put("investment", investment);
        investments.put("inStock", investment.getInStockAmount());
        investments.put("minimum", investment.getMinInvestmentString());
        investments.put("short", investment.getShortPercentage());
        investments.put("activated_stock", investment.getActivatedStockAmount());
        investments.put("okDays", okInvestmentDays);
        return investments;
    }

    public ChartModel getLmsLineChart(int fofoId) throws ProfitMandiBusinessException {

        LocalDateTime curDate = LocalDate.now().atStartOfDay();
        Map<String, Map<YearMonth, Double>> brandMonthValue = new HashMap<>();
        Map<YearMonth, Map<String, Double>> monthValueMap = new HashMap<>();

        Map<String, Double> lmsBrandWiseSale = null;

        for (int i = 0; i <= 6; i++) {

            LocalDateTime startOfMonth = curDate.withDayOfMonth(1).minusMonths(i);

            LOGGER.info("startOfMonth" + startOfMonth);

            lmsBrandWiseSale = fofoOrderItemRepository.selectSumAmountGroupByBrand(
                    curDate.withDayOfMonth(1).minusMonths(i), curDate.withDayOfMonth(1).minusMonths(i - 1), fofoId);

            Map<Integer, Double> accesorieslmsSale = fofoOrderRepository.selectSumSaleGroupByFofoIdsForMobileOrAccessories(fofoId, curDate.withDayOfMonth(1).minusMonths(i), curDate.withDayOfMonth(1).minusMonths(i - 1), Optional.of(false));
            LOGGER.info("lmsBrandWiseSale" + lmsBrandWiseSale);

            lmsBrandWiseSale.put("Accessories", accesorieslmsSale.get(fofoId));

            monthValueMap.put(YearMonth.from(startOfMonth), lmsBrandWiseSale);
            for (Entry<String, Double> lbw : lmsBrandWiseSale.entrySet()) {
                Map<YearMonth, Double> yearMonthValue = new HashMap<>();
                if (brandMonthValue.containsKey(lbw.getKey())) {
                    yearMonthValue = brandMonthValue.get(lbw.getKey());
                    yearMonthValue.put(YearMonth.from(startOfMonth), lbw.getValue());
                } else {

                    yearMonthValue.put(YearMonth.from(startOfMonth), lbw.getValue());

                }
                brandMonthValue.put(lbw.getKey(), yearMonthValue);

            }

        }

        LOGGER.info("brandMonthValue" + brandMonthValue);

        Map<String, List<Double>> sortedBrandValue = new LinkedHashMap<>();

        for (String brand : brands) {
            Map<YearMonth, Double> yearMonthValue = brandMonthValue.get(brand);
            for (int i = 6; i >= 0; i--) {

                LocalDateTime startMonth = curDate.withDayOfMonth(1).minusMonths(i);
                LOGGER.debug("startMonth {}", startMonth);

                if (yearMonthValue != null) {
                    if (yearMonthValue.get(YearMonth.from(startMonth)) == null) {
                        yearMonthValue.put(YearMonth.from(startMonth), 0.0);
                    }

                } else {
                    yearMonthValue = new HashMap<>();
                    yearMonthValue.put(YearMonth.from(startMonth), 0.0);
                }
            }

            Map<YearMonth, Double> sortedMonthBrandValue = new TreeMap<>(yearMonthValue);

            brandMonthValue.put(brand, sortedMonthBrandValue);

            sortedBrandValue.put(brand, sortedMonthBrandValue.values().stream().collect(Collectors.toList()));

        }

        LOGGER.info("brandMonthValue" + brandMonthValue);

        LOGGER.info("sortedBrandValue" + sortedBrandValue);

        ChartModel cm = chartService.createChart(6, sortedBrandValue, colorList, borderList, "Brand Wise LMS");

        return cm;

    }

    public ChartModel getPurchaseOrderChart(int fofoId) throws ProfitMandiBusinessException {

        LocalDateTime curDate = LocalDate.now().atStartOfDay();

        LOGGER.info("startMonth" + curDate.withDayOfMonth(1).minusMonths(6));

        LocalDateTime startOfMonth = curDate.withDayOfMonth(1).minusMonths(1);
        List<BrandWiseModel> soblms = orderRepository.selectAllBilledOrderGroupByBrandFofoId(fofoId, curDate.withDayOfMonth(1).minusMonths(6));
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM-yyyy");
        Map<String, Map<YearMonth, Double>> brandMonthValue = new HashMap<>();
        for (BrandWiseModel bwl : soblms) {
            Map<YearMonth, Double> yearMonthValue = new HashMap<>();
            if (brandMonthValue.containsKey(bwl.getBrand())) {
                yearMonthValue = brandMonthValue.get(bwl.getBrand());
                yearMonthValue.put(YearMonth.parse(bwl.getYearMonth(), dateTimeFormatter), (double) bwl.getAmount());
            } else {

                yearMonthValue.put(YearMonth.parse(bwl.getYearMonth(), dateTimeFormatter), (double) bwl.getAmount());

            }
            brandMonthValue.put(bwl.getBrand(), yearMonthValue);

        }
        LOGGER.info("soblms" + brandMonthValue);

        Map<String, List<Double>> sortedBrandValue = new LinkedHashMap<>();

        for (String brand : brands) {
            Map<YearMonth, Double> yearMonthValue = brandMonthValue.get(brand);
            for (int i = 6; i >= 0; i--) {

                LocalDateTime startMonth = curDate.withDayOfMonth(1).minusMonths(i);

                if (yearMonthValue != null) {
                    if (yearMonthValue.get(YearMonth.from(startMonth)) == null) {
                        yearMonthValue.put(YearMonth.from(startMonth), 0.0);
                    }

                } else {
                    yearMonthValue = new HashMap<>();
                    yearMonthValue.put(YearMonth.from(startMonth), 0.0);
                }
            }

            Map<YearMonth, Double> sortedMonthBrandValue = new TreeMap<>(yearMonthValue);

            brandMonthValue.put(brand, sortedMonthBrandValue);

            sortedBrandValue.put(brand, sortedMonthBrandValue.values().stream().collect(Collectors.toList()));

        }

        LOGGER.info("brandMonthValue" + brandMonthValue);

        ChartModel cm = chartService.createChart(6, sortedBrandValue, colorList, borderList, "Brand Wise Monthly Purchase");

        return cm;

    }

    @Cacheable(value = "partnerSales", cacheManager = "redisVeryShortCacheManager")
    public Map<String, Object> getSales(int fofoId) throws ProfitMandiBusinessException {

        Map<String, Object> salesMap = new LinkedHashMap<>();
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime startOfToday = LocalDate.now().atStartOfDay();
        int monthLength = LocalDate.now().lengthOfMonth();
        int daysGone = now.getDayOfMonth() - 1;
        int daysRemaining = monthLength - daysGone;
        Double todaySale = fofoOrderItemRepository.selectSumMopGroupByRetailer(startOfToday, now, fofoId, false).get(fofoId);
        Double mtdSaleTillYesterDay = fofoOrderItemRepository.selectSumMopGroupByRetailer(startOfToday.withDayOfMonth(1), startOfToday, fofoId, false).get(fofoId);
        Double mtdSale = mtdSaleTillYesterDay + todaySale;
        // This matches exactly what getMonthsale() does
        LocalDateTime startOfLastMonth = startOfToday.withDayOfMonth(1).minusMonths(1);
        int currentDayOfMonth = startOfToday.getDayOfMonth();
        int lastMonthLength = YearMonth.from(startOfLastMonth).lengthOfMonth();
        LocalDateTime lmtdEndDate = startOfLastMonth.plusDays(Math.min(currentDayOfMonth, lastMonthLength));

        Double lmtdSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
                startOfLastMonth, lmtdEndDate, fofoId, false).get(fofoId);

        List<PartnerTargetDetails> partnerTargetDetails = partnerTargetRepository.selectAllGeEqAndLeEqStartDateAndEndDate(LocalDateTime.now());
        if (partnerTargetDetails.isEmpty()) {
            partnerTargetDetails = partnerTargetRepository.selectAllGeEqAndLeEqStartDateAndEndDate(LocalDateTime.now().minusMonths(3));
        }

        PartnerType partnerType = partnerTypeChangeService.getTypeOnDate(fofoId, LocalDate.now());

        int currentRate = 0;
        if (mtdSaleTillYesterDay > 0) {
            currentRate = (int) (mtdSaleTillYesterDay / daysGone);
        }

        salesMap.put("requiredType", partnerType.next());
        float reqdAmount = partnerTypeChangeService.getMinimumAmount(partnerType.next());
        int requiredRate = (int) ((reqdAmount - mtdSaleTillYesterDay) / daysRemaining);
        if (partnerType.equals(PartnerType.PLATINUM) && requiredRate < currentRate) {
            requiredRate = currentRate;
        }
        salesMap.put("requiredRate", requiredRate);
        salesMap.put("requiredTypeImage", PartnerType.imageMap.get(partnerType.next()));

        salesMap.put("todaySale", todaySale == null ? 0 : todaySale);
        salesMap.put("mtdSale", mtdSale == null ? 0 : mtdSale);
        salesMap.put("lmtdSale", lmtdSale == null ? 0 : lmtdSale);

        PartnerType currentType = partnerTypeChangeService.getPartnerTypeByAmount(currentRate * monthLength);
        salesMap.put("currentRate", currentRate);
        salesMap.put("currentType", currentType);
        salesMap.put("currentTypeImage", PartnerType.imageMap.get(currentType));
        return salesMap;
    }


    @Cacheable(value = "partnerBrandChart", cacheManager = "redisShortCacheManager")
    public ChartModel getBrandChart(int fofoId, LocalDate startDate, LocalDate endDate, boolean isQuantity) {

        LocalDateTime curDate = startDate == null ? LocalDate.now().atStartOfDay().withDayOfMonth(1) : startDate.atStartOfDay();
        LocalDateTime lastDate = endDate == null ? LocalDate.now().atStartOfDay().with(LocalTime.MAX) : endDate.atStartOfDay();

        Map<String, Double> brandWiseAllSale = fofoOrderItemRepository.selectSumAmountGroupByBrand(curDate, lastDate, fofoId);
        Map<String, Long> brandWiseSaleQuantity = fofoOrderItemRepository.selectSumQuantityGroupByBrand(curDate, lastDate, fofoId);

        Map<Integer, Double> accesoriesmtdsale = fofoOrderRepository.selectSumSaleGroupByFofoIdsForMobileOrAccessories(fofoId, curDate, lastDate, Optional.of(false));
        brandWiseAllSale.put("Accessories", accesoriesmtdsale.get(fofoId));
        Map<Integer, Long> accesoriesMtdSaleQuantity = fofoOrderRepository.selectSumSaleQuantityGroupByFofoIdsForMobileOrAccessories(fofoId, curDate, lastDate, Optional.of(false));
        brandWiseSaleQuantity.put("Accessories", accesoriesMtdSaleQuantity.get(fofoId));
        List<ActivatedImeisWithSellingPrice> activatedImeisWithSellingPrices = fofoOrderRepository.selectValueOfActivatedImeis(curDate, lastDate, fofoId);
        Map<String, Double> activatedImeisWithSellingPriceMTD = activatedImeisWithSellingPrices.stream().collect(Collectors.toMap(x -> x.getBrand(), x -> (double) x.getSellingPrice()));
        Map<String, Long> activatedImeisWithSellingQuantityMTD = activatedImeisWithSellingPrices.stream().collect(Collectors.toMap(x -> x.getBrand(), x -> (long) x.getQuantity()));

        activatedImeisWithSellingPriceMTD.put("Lava", brandWiseAllSale.get("Lava"));
        activatedImeisWithSellingQuantityMTD.put("Lava", brandWiseSaleQuantity.get("Lava"));

        //--------------------------

        Map<String, Double> LMTDBrandWiseSale = fofoOrderItemRepository.selectSumAmountGroupByBrand(curDate.minusMonths(1), lastDate.minusMonths(1), fofoId);
        Map<String, Long> LMTDBrandWiseSaleQuantity = fofoOrderItemRepository.selectSumQuantityGroupByBrand(curDate.minusMonths(1), lastDate.minusMonths(1), fofoId);

        List<ActivatedImeisWithSellingPrice> LMTDActivatedImeisWithSellingPrices = fofoOrderRepository.selectValueOfActivatedImeis(curDate.minusMonths(1), lastDate.minusMonths(1), fofoId);
        Map<String, Double> LMTDActivatedImeisWithSellingPrice = LMTDActivatedImeisWithSellingPrices.stream().collect(Collectors.toMap(x -> x.getBrand(), x -> (double) x.getSellingPrice()));
        Map<String, Long> LMTDActivatedImeisWithSellingQuantity = LMTDActivatedImeisWithSellingPrices.stream().collect(Collectors.toMap(x -> x.getBrand(), x -> (long) x.getQuantity()));

        LMTDActivatedImeisWithSellingPrice.put("Lava", LMTDBrandWiseSale.get("Lava"));
        LMTDActivatedImeisWithSellingQuantity.put("Lava", LMTDBrandWiseSaleQuantity.get("Lava"));

        ChartModel cm = new ChartModel();

        List<String> brandList = Arrays.asList("Vivo", "Oppo", "Samsung", "Realme", "Xiaomi", "POCO", "Apple", "Tecno", "Lava", "Itel");
        LinkedHashSet<String> brandAsLabel = new LinkedHashSet<>(brandList);

        List<Double> mtdActivatedImeisValues = new ArrayList<>();
        List<Double> mtdValues = new ArrayList<>();
        List<Double> mtdUnActivatedImeisValues = new ArrayList<>();
        List<Double> mtdActivatedImeisQuantity = new ArrayList<>();
        List<Double> mtdQuantity = new ArrayList<>();
        List<Double> mtdUnActivatedImeisQuantity = new ArrayList<>();

        List<Double> lmtdActivatedImeisValues = new ArrayList<>();
        List<Double> lmtdValues = new ArrayList<>();
        List<Double> lmtdUnActivatedImeisValues = new ArrayList<>();
        List<Double> lmtdActivatedImeisQuantity = new ArrayList<>();
        List<Double> lmtdQuantity = new ArrayList<>();
        List<Double> lmtdUnActivatedImeisQuantity = new ArrayList<>();


        for (String brand : brandList) {
            if (isQuantity) {
                mtdActivatedImeisQuantity.add(activatedImeisWithSellingQuantityMTD.get(brand) == null ? 0 : (double) activatedImeisWithSellingQuantityMTD.get(brand));
                mtdQuantity.add(brandWiseSaleQuantity.get(brand) == null ? 0 : (double) brandWiseSaleQuantity.get(brand));
                if (brandWiseSaleQuantity.get(brand) != null) {
                    mtdUnActivatedImeisQuantity.add(brandWiseSaleQuantity.get(brand) - (activatedImeisWithSellingQuantityMTD.get(brand) == null ? 0 : (double) activatedImeisWithSellingQuantityMTD.get(brand)));
                }
                lmtdQuantity.add(LMTDBrandWiseSaleQuantity.get(brand) == null ? 0 : (double) LMTDBrandWiseSaleQuantity.get(brand));
                lmtdActivatedImeisQuantity.add(LMTDActivatedImeisWithSellingQuantity.get(brand) == null ? 0 : (double) LMTDActivatedImeisWithSellingQuantity.get(brand));
                lmtdUnActivatedImeisQuantity.add(LMTDBrandWiseSaleQuantity.get(brand) == null ? 0 : LMTDBrandWiseSaleQuantity.get(brand) - (LMTDActivatedImeisWithSellingQuantity.get(brand) == null ? 0 : (double) LMTDActivatedImeisWithSellingQuantity.get(brand)));
            } else {
                mtdActivatedImeisValues.add(activatedImeisWithSellingPriceMTD.get(brand) == null ? 0 : activatedImeisWithSellingPriceMTD.get(brand));
                mtdValues.add(brandWiseAllSale.get(brand) == null ? 0 : brandWiseAllSale.get(brand));
                if (brandWiseAllSale.get(brand) != null) {
                    mtdUnActivatedImeisValues.add(brandWiseAllSale.get(brand) - (activatedImeisWithSellingPriceMTD.get(brand) == null ? 0 : activatedImeisWithSellingPriceMTD.get(brand)));
                }
                lmtdValues.add(LMTDBrandWiseSale.get(brand) == null ? 0.0 : LMTDBrandWiseSale.get(brand));
                lmtdActivatedImeisValues.add(LMTDActivatedImeisWithSellingPrice.get(brand) == null ? 0.0 : LMTDActivatedImeisWithSellingPrice.get(brand));
                if (LMTDBrandWiseSale.get(brand) != null) {
                    lmtdUnActivatedImeisValues.add(LMTDBrandWiseSale.get(brand) - (LMTDActivatedImeisWithSellingPrice.get(brand) == null ? 0.0 : LMTDActivatedImeisWithSellingPrice.get(brand)));
                }
            }
        }

        DatasetModel mtdActivatedImeis = new DatasetModel();
        mtdActivatedImeis.setLabel("Total Activation");
        mtdActivatedImeis.setBorderColor("#00008b");
        mtdActivatedImeis.setBackgroundColor("#00008b");
        mtdActivatedImeis.setStack("stack0");
        mtdActivatedImeis.setOrder(0);

        DatasetModel dsmUnactivated = new DatasetModel();
        dsmUnactivated.setLabel("Total Unactivated");
        dsmUnactivated.setBackgroundColor("red");
        dsmUnactivated.setBorderColor("red");
        dsmUnactivated.setStack("stack0");
        dsmUnactivated.setOrder(1);

        DatasetModel linemtdChart = new DatasetModel();
        linemtdChart.setLabel("Total");
        linemtdChart.setBackgroundColor("#006400");
        linemtdChart.setBorderColor("#006400");
        linemtdChart.setType("line");
        linemtdChart.setOrder(2);
        linemtdChart.setFill("false");

        DatasetModel lmtdActivatedImeis = new DatasetModel();
        lmtdActivatedImeis.setLabel("prev mth Activation");
        lmtdActivatedImeis.setBackgroundColor("#87ceeb");
        lmtdActivatedImeis.setBorderColor("#87ceeb");
        lmtdActivatedImeis.setStack("stack1");
        lmtdActivatedImeis.setOrder(3);


        DatasetModel lmtdUnActivated = new DatasetModel();
        lmtdUnActivated.setLabel("prev mth Unactivation");
        lmtdUnActivated.setBackgroundColor("red");
        lmtdUnActivated.setBorderColor("red");
        lmtdUnActivated.setStack("stack1");
        lmtdUnActivated.setOrder(4);


        DatasetModel lineLmtdChart = new DatasetModel();
        lineLmtdChart.setLabel("prev mth TOTAL");
        lineLmtdChart.setBackgroundColor("hotpink");
        lineLmtdChart.setBorderColor("hotpink");
        lineLmtdChart.setType("line");
        lineLmtdChart.setOrder(5);
        lineLmtdChart.setFill("false");

        if (isQuantity) {
            mtdActivatedImeis.setData(mtdActivatedImeisQuantity);
            dsmUnactivated.setData(mtdUnActivatedImeisQuantity);
            linemtdChart.setData(mtdQuantity);
            lmtdActivatedImeis.setData(lmtdActivatedImeisQuantity);
            lmtdUnActivated.setData(lmtdUnActivatedImeisQuantity);
            lineLmtdChart.setData(lmtdQuantity);
        } else {
            mtdActivatedImeis.setData(mtdActivatedImeisValues);
            dsmUnactivated.setData(mtdUnActivatedImeisValues);
            linemtdChart.setData(mtdValues);
            lmtdActivatedImeis.setData(lmtdActivatedImeisValues);
            lmtdUnActivated.setData(lmtdUnActivatedImeisValues);
            lineLmtdChart.setData(lmtdValues);
        }

        List<DatasetModel> datasets = new ArrayList<>();
        datasets.add(mtdActivatedImeis);
        datasets.add(dsmUnactivated);
        datasets.add(linemtdChart);
        datasets.add(lmtdActivatedImeis);
        datasets.add(lmtdUnActivated);
        datasets.add(lineLmtdChart);

        DataModel dm = new DataModel();
        dm.setDatasets(datasets);
        dm.setLabels(brandAsLabel);
        Tooltips tooltips = new Tooltips();
        tooltips.setBodyFontSize(25);
        tooltips.setTitleFontSize(25);
        tooltips.setMode("index");
        tooltips.setIntersect(false);
        tooltips.setBackgroundColor("rgba(0, 0, 0, 0.7)");
        HoverModel hover = new HoverModel();
        hover.setIntersect(false);
        hover.setMode("index");

        LegendModel lm = new LegendModel();
        lm.setPosition("top");

        TitleModel tm = new TitleModel();
        if (isQuantity) {
            tm.setText("Brand Wise Sales Quantity");
        } else {
            tm.setText("Brand Wise Sales Value");
        }
        tm.setDisplay(true);
        tm.setFontSize(20);
        tm.setFontColor("#111");

        List<Axis> xAxes = new ArrayList<>();
        Axis xAxis = new Axis();
        xAxis.setStacked(true);
        xAxes.add(xAxis);

        List<Axis> yAxes = new ArrayList<>();
        Axis yAxis = new Axis();
        yAxis.setStacked(false);
        yAxes.add(yAxis);

        ScalesModel sm = new ScalesModel();
        sm.setxAxes(xAxes);

        OptionsModel om = new OptionsModel();
        om.setLegend(lm);
        om.setTitle(tm);
        om.setScales(sm);
        om.setHover(hover);
        om.setTooltips(tooltips);

        cm.setType("bar");
        cm.setData(dm);
        cm.setOptions(om);

        LOGGER.info("cm" + cm);

        return cm;

    }

    public ChartInvestmentModel getInvestmentChart(int fofoId) throws ProfitMandiBusinessException {
        PartnerDailyInvestment investment = partnerInvestmentService.getInvestment(fofoId, 0);

        Map<String, Float> investmentWalletAmount = new HashMap<>();
        investmentWalletAmount.put("Wallet", investment.getWalletAmount());
        investmentWalletAmount.put("InStocks", investment.getInStockAmount() - investment.getActivatedStockAmount());
        investmentWalletAmount.put("Unbilled Order", investment.getUnbilledAmount());
        investmentWalletAmount.put("GrnPending", investment.getGrnPendingAmount() - investment.getActivatedGrnPendingAmount());
        investmentWalletAmount.put("ReturnInTransit", investment.getReturnInTransitAmount());

        if (investment.getUtilizedAmount() > 0) {
            investmentWalletAmount.put("Credit Utilized", -investment.getUtilizedAmount());
        }

        if (investment.getShortInvestment() > 0) {
            investmentWalletAmount.put("Short Investment", investment.getShortInvestment());
        }

        ChartInvestmentModel cm = new ChartInvestmentModel();

        HashSet<String> labels = new HashSet<String>();
        labels.addAll(investmentWalletAmount.keySet());

        List<String> labelList = new ArrayList<>(labels);
        List<String> backgroundColor = new ArrayList<>();
        List<Float> values = new ArrayList<>();
        for (String label : labelList) {
            values.add(investmentWalletAmount.get(label));
            if (label.equals("Wallet")) {
                backgroundColor.add("pink");
            }
            if (label.equals("Short Investment")) {
                backgroundColor.add("red");
            }
            if (label.equals("InStocks")) {
                backgroundColor.add("#9ACD32");
            }
            if (label.equals("Unbilled Order")) {
                backgroundColor.add("blue");
            }

            if (label.equals("ReturnInTransit")) {
                backgroundColor.add("orange");
            }
            if (label.equals("GrnPending")) {
                backgroundColor.add("yellow");
            }
            if (label.equals("Credit Utilized")) {
                backgroundColor.add("grey");
            }

        }

        Data data = new Data();
        data.setData(values);
        data.setBackgroundColor(backgroundColor);
        data.setLabel("DataSet 1");

        PieLables label = new PieLables();
        label.setFontColor("White");
        label.setFontSize(15);

        Legend legend = new Legend();
        legend.setLabels(label);
        legend.setPosition("left");

        List<Data> dataList = new ArrayList<>();
        dataList.add(data);

        DataInvestmentModel datasets = new DataInvestmentModel();
        datasets.setDatasets(dataList);
        datasets.setLabels(labels);

        OptionModel om = new OptionModel();
        om.setLegend(legend);
        cm.setType("pie");
        cm.setData(datasets);
        cm.setOptions(om);

        return cm;
    }

    public List<Notification> getNotifications(List<NotificationCampaign> nc, MessageType messageType) throws ProfitMandiBusinessException {
        List<Notification> notifications = new ArrayList<>();
        Document document = null;
        if (messageType != null) {
            for (NotificationCampaign notificationCampaign : nc) {
                if (notificationCampaign.getMessageType() == messageType) {
                    Notification ns = new Notification();
                    SimpleCampaignParams scp = gson.fromJson(notificationCampaign.getImplementationParams(), SimpleCampaignParams.class);
                    Campaign campaign = new SimpleCampaign(scp);
                    LocalDateTime expire = campaign.getExpireTimestamp();
                    ns.setCid(Integer.toString(notificationCampaign.getId()));
                    ns.setType(campaign.getType());
                    ns.setMessage(campaign.getMessage());
                    ns.setTitle(campaign.getTitle());
                    if (notificationCampaign.getDocumentId() != null) {
                        document = documentRepository.selectById(notificationCampaign.getDocumentId());
                        ns.setDocumentName(document.getDisplayName());
                    }
                    ns.setUrl(campaign.getUrl());
                    ns.setShowImage(campaign.getShowImage());
                    ns.setImageUrl(campaign.getImageUrl());
                    ns.setDocumentId(notificationCampaign.getDocumentId());
                    ns.setMessageType(notificationCampaign.getMessageType());
                    ns.setCreated(
                            notificationCampaign.getCreatedTimestamp().toEpochSecond(ZoneOffset.ofHoursMinutes(5, 30)) * 1000);
                    if (LocalDateTime.now().isAfter(expire)) {
                        ns.setExpired(true);
                    } else {
                        ns.setExpired(false);
                    }
                    notifications.add(ns);
                }
            }
        } else {
            for (NotificationCampaign notificationCampaign : nc) {

                Notification ns = new Notification();
                SimpleCampaignParams scp = gson.fromJson(notificationCampaign.getImplementationParams(), SimpleCampaignParams.class);
                Campaign campaign = new SimpleCampaign(scp);
                LocalDateTime expire = campaign.getExpireTimestamp();
                ns.setCid(Integer.toString(notificationCampaign.getId()));
                ns.setType(campaign.getType());
                ns.setMessage(campaign.getMessage());
                ns.setTitle(campaign.getTitle());
                if (notificationCampaign.getDocumentId() != null) {
                    document = documentRepository.selectById(notificationCampaign.getDocumentId());
                    ns.setDocumentName(document.getDisplayName());
                }
                ns.setUrl(campaign.getUrl());
                ns.setShowImage(campaign.getShowImage());
                ns.setImageUrl(campaign.getImageUrl());
                ns.setDocumentId(notificationCampaign.getDocumentId());
                ns.setMessageType(notificationCampaign.getMessageType());
                ns.setCreated(notificationCampaign.getCreatedTimestamp().toEpochSecond(ZoneOffset.ofHoursMinutes(5, 30)) * 1000);
                if (LocalDateTime.now().isAfter(expire)) {
                    ns.setExpired(true);
                } else {
                    ns.setExpired(false);
                }
                notifications.add(ns);
            }

        }
        return notifications;

    }

    public boolean hasGift(int fofoId) {
        try {
            return currentInventorySnapshotRepository.selectByItemIdAndFofoId(ProfitMandiConstants.GIFT_ID, fofoId).getAvailability() > 0;
        } catch (ProfitMandiBusinessException e) {
            return false;
        }
    }

    public ChartModel getModelBrandChart(int fofoId, String brand, LocalDate startDate, LocalDate endDate, boolean isQuantity) {

        LocalDateTime curDate = startDate == null ? LocalDate.now().atStartOfDay().withDayOfMonth(1) : startDate.atStartOfDay();
        LocalDateTime lastDate = endDate == null ? LocalDate.now().atStartOfDay().with(LocalTime.MAX) : endDate.atStartOfDay();

        //----------------------------MTD-------------------------
        Map<String, Double> modelWiseSale = fofoOrderItemRepository.selectSumAmountGroupByBrand(curDate, lastDate, fofoId, "modelNumber", brand);
        Map<String, Long> modelWiseSaleQuantity = fofoOrderItemRepository.selectSumQuantityGroupByBrand(curDate, lastDate, fofoId, "modelNumber", brand);

        List<ActivatedImeisWithSellingPrice> activatedImeisWithSellingPricesMTD = fofoOrderItemRepository.selectValueOfActivatedImeisModelWise(curDate, lastDate, fofoId, brand);
        Map<String, Double> activatedImeisWithSellingPriceMTD = activatedImeisWithSellingPricesMTD.stream().collect(Collectors.toMap(x -> x.getModel(), x -> (double) x.getSellingPrice()));
        Map<String, Long> activatedImeisWithSellingQuantityMTD = activatedImeisWithSellingPricesMTD.stream().collect(Collectors.toMap(x -> x.getModel(), x -> (long) x.getQuantity()));


        //---------------------------------LMTD----------------------
        Map<String, Double> lmtdModelWiseSale = fofoOrderItemRepository.selectSumAmountGroupByBrand(curDate.minusMonths(1), lastDate.minusMonths(1), fofoId, "modelNumber", brand);
        Map<String, Long> lmtdModelWiseSaleQuantity = fofoOrderItemRepository.selectSumQuantityGroupByBrand(curDate.minusMonths(1), lastDate.minusMonths(1), fofoId, "modelNumber", brand);

        List<ActivatedImeisWithSellingPrice> lmtdActivatedImeisWithSellingPrices = fofoOrderItemRepository.selectValueOfActivatedImeisModelWise(curDate.minusMonths(1), lastDate.minusMonths(1), fofoId, brand);
        Map<String, Double> lmtdActivatedImeisWithSellingPrice = lmtdActivatedImeisWithSellingPrices.stream().collect(Collectors.toMap(x -> x.getModel(), x -> (double) x.getSellingPrice()));
        Map<String, Long> lmtdActivatedImeisWithSellingQuantity = lmtdActivatedImeisWithSellingPrices.stream().collect(Collectors.groupingBy(x -> x.getModel(), Collectors.summingLong(x -> x.getQuantity())));

        ChartModel cm = new ChartModel();

        List<String> brandList1 = lmtdModelWiseSale.keySet().stream().collect(Collectors.toList());
        List<String> brandList2 = modelWiseSale.keySet().stream().collect(Collectors.toList());
        HashSet<String> brandsAsLabelList = new HashSet<>();
        brandsAsLabelList.addAll(brandList1);
        brandsAsLabelList.addAll(brandList2);
        // for MTD
        List<Double> mtdActivatedImeisValues = new ArrayList<>();
        List<Double> mtdUnActivatedImeisValues = new ArrayList<>();
        List<Double> mtdValues = new ArrayList<>();
        List<Double> mtdActivatedImeisQuantity = new ArrayList<>();
        List<Double> mtdUnActivatedImeisQuantity = new ArrayList<>();
        List<Double> mtdQuantity = new ArrayList<>();

        // for LMTD
        List<Double> lmtdActivatedImeisValues = new ArrayList<>();
        List<Double> lmtdUnActivatedImeisValues = new ArrayList<>();
        List<Double> lmtdValues = new ArrayList<>();
        List<Double> lmtdActivatedImeisQuantity = new ArrayList<>();
        List<Double> lmtdUnActivatedImeisQuantity = new ArrayList<>();
        List<Double> lmtdQuantity = new ArrayList<>();


        LOGGER.info("labelsList - " + brandsAsLabelList);
        for (String brandAsLabel : brandsAsLabelList) {
            brandAsLabel = brandAsLabel.trim();
            if (isQuantity) {
                mtdActivatedImeisQuantity.add(activatedImeisWithSellingQuantityMTD.get(brandAsLabel) == null ? 0 : (double) activatedImeisWithSellingQuantityMTD.get(brandAsLabel));
                mtdQuantity.add(modelWiseSaleQuantity.get(brandAsLabel) == null ? 0 : (double) modelWiseSaleQuantity.get(brandAsLabel));
                mtdUnActivatedImeisQuantity.add(modelWiseSaleQuantity.get(brandAsLabel) == null ? 0 : modelWiseSaleQuantity.get(brandAsLabel) - (activatedImeisWithSellingQuantityMTD.get(brandAsLabel) == null ? 0 : (double) activatedImeisWithSellingQuantityMTD.get(brandAsLabel)));

                lmtdActivatedImeisQuantity.add(lmtdActivatedImeisWithSellingQuantity.get(brandAsLabel) == null ? 0 : (double) lmtdActivatedImeisWithSellingQuantity.get(brandAsLabel));
                lmtdUnActivatedImeisQuantity.add(lmtdModelWiseSaleQuantity.get(brandAsLabel) == null ? 0 : lmtdModelWiseSaleQuantity.get(brandAsLabel) - (lmtdActivatedImeisWithSellingQuantity.get(brandAsLabel) == null ? 0 : (double) lmtdActivatedImeisWithSellingQuantity.get(brandAsLabel)));
                lmtdQuantity.add(lmtdModelWiseSaleQuantity.get(brandAsLabel) == null ? 0 : (double) lmtdModelWiseSaleQuantity.get(brandAsLabel));
            } else {
                mtdActivatedImeisValues.add(activatedImeisWithSellingPriceMTD.get(brandAsLabel) == null ? 0 : activatedImeisWithSellingPriceMTD.get(brandAsLabel));
                mtdValues.add(modelWiseSale.get(brandAsLabel) == null ? 0 : modelWiseSale.get(brandAsLabel));
                if (modelWiseSale.get(brandAsLabel) != null) {
                    mtdUnActivatedImeisValues.add(modelWiseSale.get(brandAsLabel) - (activatedImeisWithSellingPriceMTD.get(brandAsLabel) == null ? 0 : activatedImeisWithSellingPriceMTD.get(brandAsLabel)));
                } else {
                    mtdUnActivatedImeisValues.add(0.0);
                }
                lmtdValues.add(lmtdModelWiseSale.get(brandAsLabel) == null ? 0 : lmtdModelWiseSale.get(brandAsLabel));
                lmtdActivatedImeisValues.add(lmtdActivatedImeisWithSellingPrice.get(brandAsLabel) == null ? 0 : lmtdActivatedImeisWithSellingPrice.get(brandAsLabel));
                if (lmtdModelWiseSale.get(brandAsLabel.trim()) != null) {
                    lmtdUnActivatedImeisValues.add(lmtdModelWiseSale.get(brandAsLabel) - (lmtdActivatedImeisWithSellingPrice.get(brandAsLabel) == null ? 0 : lmtdActivatedImeisWithSellingPrice.get(brandAsLabel)));
                } else {
                    lmtdUnActivatedImeisValues.add(0.0);
                }
            }
        }

        DatasetModel mtdActivatedImeis = new DatasetModel();
        mtdActivatedImeis.setLabel("Total Activation");
        mtdActivatedImeis.setBorderColor("#00008b");
        mtdActivatedImeis.setBackgroundColor("#00008b");
        mtdActivatedImeis.setStack("stack0");
        mtdActivatedImeis.setOrder(0);

        DatasetModel dsmUnactivated = new DatasetModel();
        dsmUnactivated.setLabel("Total Unactivated");
        dsmUnactivated.setBackgroundColor("red");
        dsmUnactivated.setBorderColor("red");
        dsmUnactivated.setStack("stack0");
        dsmUnactivated.setOrder(1);

        DatasetModel linemtdChart = new DatasetModel();
        linemtdChart.setLabel("Total");
        linemtdChart.setBackgroundColor("#006400");
        linemtdChart.setBorderColor("#006400");
        linemtdChart.setType("line");
        linemtdChart.setOrder(2);
        linemtdChart.setFill("false");

        DatasetModel LmtdActivatedImeis = new DatasetModel();
        LmtdActivatedImeis.setLabel("prev mth Activation");
        LmtdActivatedImeis.setBackgroundColor("#87ceeb");
        LmtdActivatedImeis.setBorderColor("#87ceeb");
        LmtdActivatedImeis.setStack("stack1");
        LmtdActivatedImeis.setOrder(3);

        DatasetModel lmtdUnActivated = new DatasetModel();
        lmtdUnActivated.setLabel("prev mth Unactivation");
        lmtdUnActivated.setBackgroundColor("red");
        lmtdUnActivated.setBorderColor("red");
        lmtdUnActivated.setStack("stack1");
        lmtdUnActivated.setOrder(4);

        DatasetModel lineLmtdChart = new DatasetModel();
        lineLmtdChart.setLabel("prev mth TOTAL");
        lineLmtdChart.setBackgroundColor("hotpink");
        lineLmtdChart.setBorderColor("hotpink");
        lineLmtdChart.setType("line");
        lineLmtdChart.setOrder(5);
        lineLmtdChart.setFill("false");


        if (isQuantity) {
            mtdActivatedImeis.setData(mtdActivatedImeisQuantity);
            dsmUnactivated.setData(mtdUnActivatedImeisQuantity);
            linemtdChart.setData(mtdQuantity);
            LmtdActivatedImeis.setData(lmtdActivatedImeisQuantity);
            lmtdUnActivated.setData(lmtdUnActivatedImeisQuantity);
            lineLmtdChart.setData(lmtdQuantity);
        } else {
            mtdActivatedImeis.setData(mtdActivatedImeisValues);
            dsmUnactivated.setData(mtdUnActivatedImeisValues);
            linemtdChart.setData(mtdValues);
            LmtdActivatedImeis.setData(lmtdActivatedImeisValues);
            lmtdUnActivated.setData(lmtdUnActivatedImeisValues);
            lineLmtdChart.setData(lmtdValues);
        }

        List<DatasetModel> datasets = new ArrayList<>();
        datasets.add(mtdActivatedImeis);
        datasets.add(dsmUnactivated);
        datasets.add(linemtdChart);
        datasets.add(LmtdActivatedImeis);
        datasets.add(lmtdUnActivated);
        datasets.add(lineLmtdChart);

        DataModel dm = new DataModel();
        dm.setDatasets(datasets);
        dm.setLabels(brandsAsLabelList);

        Tooltips tooltips = new Tooltips();
        tooltips.setBodyFontSize(25);
        tooltips.setTitleFontSize(25);
        tooltips.setMode("index");
        tooltips.setIntersect(false);
        tooltips.setBackgroundColor("rgba(0, 0, 0, 0.7)");
        HoverModel hover = new HoverModel();
        hover.setIntersect(false);
        hover.setMode("index");

        LegendModel lm = new LegendModel();
        lm.setPosition("top");
        TitleModel tm = new TitleModel();
        if (isQuantity) {
            tm.setText("Model Wise Sales Quantity");
        } else {
            tm.setText("Model Wise Sales Value");
        }
        tm.setDisplay(true);
        tm.setFontSize(30);
        tm.setFontColor("#050a4d");

        List<Axis> xAxes = new ArrayList<>();
        Axis xAxis = new Axis();
        xAxis.setStacked(true);
        xAxes.add(xAxis);

        List<Axis> yAxes = new ArrayList<>();
        Axis yAxis = new Axis();
        yAxis.setStacked(false);
        yAxes.add(yAxis);

        ScalesModel sm = new ScalesModel();
        sm.setxAxes(xAxes);

        OptionsModel om = new OptionsModel();
        om.setLegend(lm);
        om.setTitle(tm);
        om.setScales(sm);
        om.setHover(hover);
        om.setTooltips(tooltips);

        cm.setType("bar");
        cm.setData(dm);
        cm.setOptions(om);

        LOGGER.info("Model_cm" + cm);
        return cm;

    }

}