Subversion Repositories SmartDukaan

Rev

Rev 36227 | 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.ReporticoProject;
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.common.model.*;
import com.spice.profitmandi.dao.entity.auth.AuthUser;
import com.spice.profitmandi.dao.entity.auth.Menu;
import com.spice.profitmandi.dao.entity.cs.Bulletin;
import com.spice.profitmandi.dao.entity.cs.Position;
import com.spice.profitmandi.dao.entity.fofo.FofoStore;
import com.spice.profitmandi.dao.entity.fofo.PartnerType;
import com.spice.profitmandi.dao.entity.inventory.ReporticoCacheTable;
import com.spice.profitmandi.dao.entity.transaction.LoanSummary;
import com.spice.profitmandi.dao.entity.transaction.StateWiseLoanSummary;
import com.spice.profitmandi.dao.enumuration.cs.EscalationType;
import com.spice.profitmandi.dao.model.BrandWiseModel;
import com.spice.profitmandi.dao.model.BulletinOfferModal;
import com.spice.profitmandi.dao.model.PartnerDetailModel;
import com.spice.profitmandi.dao.model.WarehouseWiseStockModel;
import com.spice.profitmandi.dao.repository.auth.AuthRepository;
import com.spice.profitmandi.dao.repository.auth.MenuCategoryRepository;
import com.spice.profitmandi.dao.repository.auth.MenuRepository;
import com.spice.profitmandi.dao.repository.cs.*;
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
import com.spice.profitmandi.dao.repository.fofo.ActivatedImeiRepository;
import com.spice.profitmandi.dao.repository.inventory.ReporticoCacheTableRepository;
import com.spice.profitmandi.dao.repository.inventory.SaholicInventoryCISRepository;
import com.spice.profitmandi.dao.repository.transaction.OrderRepository;
import com.spice.profitmandi.service.offers.TodayOfferService;
import com.spice.profitmandi.service.transaction.SDCreditService;
import com.spice.profitmandi.service.user.RetailerService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import java.util.stream.LongStream;

@Component
public class AdminUser {
    @Autowired
    private Gson gson;

    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    TicketRepository ticketRepository;

    @Autowired
    private ChartService chartService;

    @Autowired
    RetailerService retailerService;

    @Autowired
    AuthRepository authRepository;

    @Autowired
    FofoStoreRepository fofoStoreRepository;

    @Autowired
    CsService1 csService1;

    @Autowired
    CsService csService;

    @Autowired
    private MenuRepository menuRepository;

    @Autowired
    private PositionRepository positionRepository;

    @Autowired
    private MenuCategoryRepository menuCategoryRepository;

    @Autowired
    private SaholicInventoryCISRepository saholicInventoryCISRepository;

    @Autowired
    private ReporticoCacheTableRepository reporticoCacheTableRepository;

    @Autowired
    private ActivatedImeiRepository activatedImeiRepository;

    @Autowired
    private PartnerStatsService partnerStatsService;
    @Autowired
    private SDCreditService sdCreditService;

    @Autowired
    BulletinRepository bulletinRepository;

    @Autowired
    TodayOfferService todayOfferService;

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

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

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

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

    public ChartModel getBrandWiseLmp(List<Integer> warehouseIds, List<Integer> fofoIds, LocalDate startDate,
                                      LocalDate endDate, String filterType) {
        //LOGGER.info("params" + warehouseIds + fofoIds + startDate);

        List<BrandWiseModel> brandWiseLms = orderRepository.selectGroupByBrandLmp(fofoIds, warehouseIds, startDate,
                endDate, filterType);
        LOGGER.info("brandWiseLms" + brandWiseLms);
        ChartModel cm = null;

        if (filterType.equals("dateWise")) {
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM-dd-yyyy");

            Map<String, Map<LocalDate, Double>> brandDateValue = new HashMap<>();
            for (BrandWiseModel bwl : brandWiseLms) {
                if (!brandDateValue.containsKey(bwl.getBrand())) {
                    brandDateValue.put(bwl.getBrand(), new HashMap<>());
                }
                Map<LocalDate, Double> dateWiseSalesMap = brandDateValue.get(bwl.getBrand());
                dateWiseSalesMap.put(LocalDate.parse(bwl.getYearMonth(), dateTimeFormatter), (double) bwl.getAmount());
            }

            long days = startDate.until(endDate, ChronoUnit.DAYS);
            List<LocalDate> allDatesBetween = LongStream.range(0, days).mapToObj(x -> startDate.plusDays(x))
                    .collect(Collectors.toList());
            LOGGER.info("All dates between {}", allDatesBetween);

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

            for (String brand : brands) {
                if (!brandDateValue.containsKey(brand)) {
                    brandDateValue.put(brand, new HashMap<>());
                }
                Map<LocalDate, Double> dateWiseBrand = brandDateValue.get(brand);
                for (LocalDate date : allDatesBetween) {
                    if (dateWiseBrand.get(date) == null) {
                        dateWiseBrand.put(date, 0.0);
                    }
                }

                Map<LocalDate, Double> sortedMonthBrandValue = new TreeMap<>(dateWiseBrand);
                sortedBrandValue.put(brand, new ArrayList<>(sortedMonthBrandValue.values()));
                LOGGER.info("Sorted Brandwise values count {}", sortedMonthBrandValue.size());
            }

            LOGGER.info("brandMonthValueCount {}", brandDateValue.size());

            LOGGER.info("sortedBrandValueCount {}", sortedBrandValue.size());
            cm = chartService.createChartWithLabels(
                    allDatesBetween.stream().map(x -> x.format((DateTimeFormatter.ofPattern("dd MMM''uu"))))
                            .collect(Collectors.toCollection(LinkedHashSet::new)),
                    sortedBrandValue, colorList, borderList, "Brand Wise Date Wise Purchase");

        } else {

            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM-yyyy");

            Map<String, Map<YearMonth, Double>> brandMonthValue = new HashMap<>();
            for (BrandWiseModel bwl : brandWiseLms) {
                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);

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

            Period age = Period.between(startDate, endDate);
            int months = age.getMonths();
            LOGGER.info("months" + months);
            LOGGER.info("brandWiseLms" + brandWiseLms);
            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 = months; 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()));

            }

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

        }

        return cm;
    }

    public ChartInvestmentModel getAllStatePartnerType(Map<Integer, PartnerDetailModel> fofoIdAndallValues)
            throws ProfitMandiBusinessException {

        Map<String, Float> partnerTypeCount = new HashMap<>();

        List<PartnerType> partnerTypes = Arrays.asList(PartnerType.values());

        for (PartnerType partnerType : partnerTypes) {

            float count = fofoIdAndallValues.entrySet().stream()
                    .filter(x -> x.getValue() != null && x.getValue().getPartnerType().equals(partnerType)).count();

            partnerTypeCount.put(partnerType.toString(), count);

        }

        ChartInvestmentModel cm = new ChartInvestmentModel();

        HashSet<String> labels = new HashSet<String>();
        labels.addAll(partnerTypes.stream().skip(1).map(x -> x.toString()).collect(Collectors.toList()));
        List<String> labelList = new ArrayList<>(labels);

        List<String> backgroundColor = new ArrayList<>();

        List<Float> values = new ArrayList<>();

        for (String label : labelList) {
            values.add(partnerTypeCount.get(label));
            if (label.equals("BRONZE")) {
                backgroundColor.add("#CD7F32");
            }
            if (label.equals("SILVER")) {
                backgroundColor.add("silver");
            }
            if (label.equals("GOLD")) {
                backgroundColor.add("#FFD700");
            }
            if (label.equals("DIAMOND")) {
                backgroundColor.add("#B9F2FF");
            }

            if (label.equals("PLATINUM")) {
                backgroundColor.add("#800080");
            }
            if (label.equals("NEW")) {
                backgroundColor.add("green");
            }

        }

        LOGGER.info("valuesPartnerType" + values);
        LOGGER.info("partnerTypeCount" + partnerTypeCount);

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

        PieLables label = new PieLables();
        label.setFontColor("black");
        label.setFontSize(22);

        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 Map<String, Object> getFilter(int warehouseId, String email, LocalDateTime date, LocalDateTime endDate)
            throws ProfitMandiBusinessException {
        Map<String, Object> map = new HashMap<>();
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();
        Map<Integer, CustomRetailer> crm = null;
        Map<Integer, String> warehouseMap = ProfitMandiConstants.WAREHOUSE_MAP;

        Set<Integer> fofoIds = csService1.getAuthFofoIds(email, true);

        if (warehouseId != 0) {

            fofoIds = fofoStoreRepository.selectPartnerByfofoIdAndWarehouse(new ArrayList<>(fofoIds), warehouseId)
                    .stream().map(x -> x).collect(Collectors.toSet());

        }

        if (fofoIds != null) {

            crm = fofoIds.stream().map(x -> customRetailerMap.get(x)).filter(x -> x != null)
                    .collect(Collectors.toList()).stream().collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));

        }

        map.put("date", date);
        map.put("endDate", endDate);
        map.put("customRetailersMap", crm);
        map.put("fofoIds", fofoIds);
        map.put("warehouseMap", warehouseMap);

        return map;

    }

    public ChartModel getBrandWiseLms(List<Integer> warehouseIds, List<Integer> fofoIds, LocalDate startDate,
                                      LocalDate endDate, String filterType) {
        //LOGGER.info("params" + warehouseIds + fofoIds + startDate);

        List<BrandWiseModel> brandWiseLms = fofoStoreRepository.selectGroupByBrandLms(fofoIds, warehouseIds, startDate,
                endDate, filterType);
        //LOGGER.info("brandWiseLms" + brandWiseLms);

        ChartModel cm = null;

        if (filterType.equals("dateWise")) {
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM-dd-yyyy");

            Map<String, Map<LocalDate, Double>> brandDateValue = new HashMap<>();
            for (BrandWiseModel bwl : brandWiseLms) {
                if (!brandDateValue.containsKey(bwl.getBrand())) {
                    brandDateValue.put(bwl.getBrand(), new HashMap<>());
                }
                Map<LocalDate, Double> dateWiseSalesMap = brandDateValue.get(bwl.getBrand());
                dateWiseSalesMap.put(LocalDate.parse(bwl.getYearMonth(), dateTimeFormatter), (double) bwl.getAmount());
            }

            long days = startDate.until(endDate, ChronoUnit.DAYS);
            List<LocalDate> allDatesBetween = LongStream.range(0, days).mapToObj(x -> startDate.plusDays(x))
                    .collect(Collectors.toList());
            //LOGGER.info("All dates between {}", allDatesBetween);

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

            for (String brand : brands) {
                if (!brandDateValue.containsKey(brand)) {
                    brandDateValue.put(brand, new HashMap<>());
                }
                Map<LocalDate, Double> dateWiseBrand = brandDateValue.get(brand);
                for (LocalDate date : allDatesBetween) {
                    if (dateWiseBrand.get(date) == null) {
                        dateWiseBrand.put(date, 0.0);
                    }
                }

                Map<LocalDate, Double> sortedMonthBrandValue = new TreeMap<>(dateWiseBrand);
                sortedBrandValue.put(brand, new ArrayList<>(sortedMonthBrandValue.values()));
                LOGGER.info("Sorted Brandwise values count {}", sortedMonthBrandValue.size());
            }

            LOGGER.info("brandMonthValueCount {}", brandDateValue.size());

            LOGGER.info("sortedBrandValueCount {}", sortedBrandValue.size());
            cm = chartService.createChartWithLabels(
                    allDatesBetween.stream().map(x -> x.format((DateTimeFormatter.ofPattern("dd MMM''uu"))))
                            .collect(Collectors.toCollection(LinkedHashSet::new)),
                    sortedBrandValue, colorList, borderList, "Brand Wise Date Wise Sale");

        } else {

            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM-yyyy");

            Map<String, Map<YearMonth, Double>> brandMonthValue = new HashMap<>();
            for (BrandWiseModel bwl : brandWiseLms) {
                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);

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

            Period age = Period.between(startDate, endDate);
            int months = age.getMonths();
            //LOGGER.info("months" + months);
            //LOGGER.info("brandWiseLms" + brandWiseLms);
            //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 = months; 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()));

            }

            cm = chartService.createChart(months, sortedBrandValue, colorList, borderList, "Brand Wise Monthly Sale");
        }

        return cm;
    }

    public String adminPanel(int fofoId, String email, Model model) throws Exception {
        List<Menu> menus = null;
        boolean isAboveL1 = false;
        try {
            AuthUser authUser = authRepository.selectByEmailOrMobile(email);
            List<Position> positions = positionRepository.selectAllByAuthUserId(authUser.getId());
            LOGGER.info("positionslist - {}", positions);
            Map<Integer, PartnerDetailModel> warehousePartnerDetailMap = null;

            Map<Integer, WarehouseWiseStockModel> warehouseStockMap;
            LinkedHashMap<Integer, WarehouseWiseStockModel> warehouseStockSortedMap = new LinkedHashMap<>();

            Map<Integer, String> warehouseMap = ProfitMandiConstants.WAREHOUSE_MAP;
            Map<Integer, String> wm = new LinkedHashMap<>();

            Map<AuthUser, Long> authUserTicketCount = null;
            LoanSummary loanSummary = sdCreditService.getLoanSummary();

            Map<String, StateWiseLoanSummary> stateWiseLoanSummaryMap = sdCreditService.getLoanSummaryStateWise();
            model.addAttribute("loanSummary", loanSummary);
            model.addAttribute("stateWiseLoanSummaryMap", stateWiseLoanSummaryMap);


            for (Map.Entry<Integer, String> entry : warehouseMap.entrySet()) {
                wm.put(entry.getKey(), entry.getValue());
            }

            wm.put(0, "Total Values");
            long stockValue = 0;
            long stockQty = 0;
            long pendingIndent = 0;
            long tertiary = 0;

            isAboveL1 = positions.stream().anyMatch(pos -> pos.getEscalationType() != EscalationType.L1);
            boolean isRBM = positions.stream().anyMatch(pos -> pos.getCategoryId() == ProfitMandiConstants.TICKET_CATEGORY_RBM);
            // RBM category: only L3 and above can see all stores
            boolean isRbmL3OrAbove = positions.stream().anyMatch(pos ->
                    pos.getCategoryId() == ProfitMandiConstants.TICKET_CATEGORY_RBM
                            && pos.getEscalationType() != null
                            && pos.getEscalationType() != EscalationType.L1
                            && pos.getEscalationType() != EscalationType.L2);
            model.addAttribute("isRBM", isRBM);
            model.addAttribute("authEmail", email);
            Set<Integer> fofoIds = new HashSet<>();
            if (isRbmL3OrAbove) {
                fofoIds = fofoStoreRepository.selectActiveStores().stream().map(x -> x.getId()).collect(Collectors.toSet());
            } else {
                fofoIds = csService1.getAuthFofoIds(email, true);
            }


            if (fofoIds != null && fofoIds.size() > 0) {
                Map<Integer, List<Integer>> warehouseIdFofoIdMap = getWarehouseIdFofoIdMap(fofoIds);
                List<WarehouseWiseStockModel> warehouseStocks = saholicInventoryCISRepository
                        .selectGroupByWarehouse(new ArrayList<>(warehouseIdFofoIdMap.keySet()));

                warehouseStockMap = warehouseStocks.stream().collect(Collectors.toMap(x -> x.getWarehouseId(), x -> x));

                if (!warehouseStockMap.isEmpty()) {
                    for (Entry<Integer, WarehouseWiseStockModel> warehouseStock : warehouseStockMap.entrySet()) {
                        stockValue += warehouseStock.getValue().getStockValue();
                        stockQty += warehouseStock.getValue().getStockQty();
                        pendingIndent += warehouseStock.getValue().getPendingIndent();
                        tertiary += warehouseStock.getValue().getTertiary();
                    }
                    WarehouseWiseStockModel ws = new WarehouseWiseStockModel();
                    ws.setStockQty(stockQty);
                    ws.setStockValue(stockValue);
                    ws.setPendingIndent(pendingIndent);
                    ws.setTertiary(tertiary);
                    ws.setWarehouseId(0);
                    warehouseStockMap.put(0, ws);

                }

                warehouseStockMap.entrySet().stream().sorted(Map.Entry.comparingByKey(Comparator.reverseOrder()))
                        .forEachOrdered(x -> warehouseStockSortedMap.put(x.getKey(), x.getValue()));

                ReporticoCacheTable rctSaholic = reporticoCacheTableRepository.selectByTableName("SaholicInventoryCIS");
                model.addAttribute("reporticoDate", rctSaholic);

                // warehouseStock
                warehousePartnerDetailMap = this.getWarehousePartnerDetail(warehouseIdFofoIdMap);

                ReporticoCacheTable rctPartneStat = reporticoCacheTableRepository.selectByTableName("partnerStat");

                Set<CustomRetailer> positionRetailers = fofoIds.stream()
                        .map(x -> {
                            try {
                                return retailerService.getAllFofoRetailers().get(x);
                            } catch (ProfitMandiBusinessException e) {
                                throw new RuntimeException(e);
                            }
                        }).filter(x -> x != null)
                        .collect(Collectors.toSet());
                model.addAttribute("retailers", gson.toJson(positionRetailers));
                model.addAttribute("reporticoProjectMap", ReporticoProject.salesReporticoProjectMap);
                model.addAttribute("warehouses", getWarehouses(positionRetailers));
                model.addAttribute("rctPartneStat", rctPartneStat);
            } else {
                List<Position> warehousePositions = positions.stream()
                        .filter(x -> x.getCategoryId() == ProfitMandiConstants.TICKET_CATEGORY_WAREHOUSE)
                        .collect(Collectors.toList());
                if (warehousePositions.size() > 0) {
                    Set<CustomRetailer> positionRetailers = new HashSet<>();
                    csService.getPositionCustomRetailerMap(warehousePositions).values().forEach(customRetailers -> {
                        positionRetailers.addAll(customRetailers);
                    });
                    model.addAttribute("reporticoProjectMap", ReporticoProject.warehouseReporticoMap);
                    model.addAttribute("retailers", gson.toJson(positionRetailers));
                    model.addAttribute("warehouses", getWarehouses(positionRetailers));
                }
                List<Position> categoryPositions = positions.stream()
                        .filter(x -> x.getCategoryId() == ProfitMandiConstants.TICKET_CATEGORY_CATEGORY)
                        .collect(Collectors.toList());
                if (categoryPositions.size() > 0) {
                    Set<CustomRetailer> positionRetailers = new HashSet<>();
                    csService.getPositionCustomRetailerMap(warehousePositions).values().forEach(customRetailers -> {
                        positionRetailers.addAll(customRetailers);
                    });
                    model.addAttribute("reporticoProjectMap", ReporticoProject.warehouseReporticoMap);
                    model.addAttribute("retailers", gson.toJson(positionRetailers));
                    model.addAttribute("warehouses", getWarehouses(positionRetailers));
                }
            }

            if (positions.size() > 0) {
                if (positions.stream()
                        .filter(x -> x.getEscalationType().equals(EscalationType.L3)
                                || x.getEscalationType().equals(EscalationType.L4)
                                || x.getEscalationType().equals(EscalationType.L5))
                        .count() > 0) {
                    authUserTicketCount = ticketRepository.selectAllAuthUserTicketCount(Optional.of(false));
                }
            }

            if (Arrays.asList("amit.gupta@smartdukaan.com", "ranu.rajput@smartdukaan.com", "vikas.jangra@smartdukaan.com", "aman.gupta@smartdukaan.com").contains(email)) {
                menus = menuRepository.selectAllBySequence();
            } else if (positions.size() > 0) {
                if (positions.stream().filter(x -> x.getEscalationType().equals(EscalationType.L5)).count() > 0) {
                    menus = menuRepository.selectAllBySequence();
                } else {
                    List<Integer> menuIds = menuCategoryRepository.selectAllByPositions(positions).stream()
                            .map(x -> x.getMenuId()).collect(Collectors.toList());
                    if (menuIds.size() > 0) {
                        menus = menuRepository.selectAllByIds(menuIds);
                    }
                }
            }

            model.addAttribute("authId", authUser.getId());

            model.addAttribute("warehousePartnerDetailMap", warehousePartnerDetailMap);
            model.addAttribute("warehouseMap", wm);
            model.addAttribute("authUserTicketCount", authUserTicketCount);
            model.addAttribute("warehouseStockMap", warehouseStockSortedMap);
            LocalDateTime curDate = LocalDate.now().atStartOfDay();

            model.addAttribute("date", curDate.withDayOfMonth(1).minusMonths(6).toLocalDate());

        } catch (ProfitMandiBusinessException e) {
        }
        // Filter out "Manager Ticket" menu item for L1-only users (must be at least L2 in any position)
        if (menus != null && !isAboveL1) {
            menus = menus.stream()
                    .filter(m -> !"manager-ticket".equals(m.getActionClass()))
                    .collect(Collectors.toList());
        }
        List<Menu> menuList = (menus != null) ? this.prepareMenu(menus) : new ArrayList<>();
        //LOGGER.info("menu" + menuList);
        model.addAttribute("menu", menuList);
        return "admin";
    }


    public Map<ProfitMandiConstants.BULLETIN_TYPE_ENUM, List<BulletinOfferModal>> getTodayBulletin(List<Position> positions, LocalDateTime date) throws Exception {
        List<Long> regionIds = positions.stream().map(x -> Long.valueOf(x.getRegionId())).collect(Collectors.toList());

        regionIds.add(5L);


        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("h:mm a");

        LocalDateTime startDate = date.toLocalDate().minusDays(1).atTime(LocalTime.MAX);
        LocalDateTime endDate = date.toLocalDate().plusDays(1).atTime(LocalTime.MAX);
        List<BulletinOfferModal> bulletinOfferModals = new ArrayList<>();

        List<Bulletin> bulletins = bulletinRepository.selectALlTodayBulletinByRegionIds(regionIds, startDate, endDate);
        for (Bulletin b : bulletins) {

            BulletinOfferModal modal = new BulletinOfferModal();
            modal.setOfferId(b.getId());
            modal.setDescription(b.getDescription());
            modal.setCreatedTime(formatter.format(b.getCreatedAt()));
            modal.setCatalogOffer(false);
            modal.setCreatedAt(b.getCreatedAt());
            modal.setCreatedBy(b.getCreatedBy());
            modal.setBulletinType(ProfitMandiConstants.BULLETIN_TYPE_ENUM.BULLETIN);

            // ADD THIS BLOCK
            if (b.getDocumentIds() != null && !b.getDocumentIds().isEmpty()) {
                List<Integer> docIds = Arrays.stream(b.getDocumentIds().split(","))
                        .map(String::trim)
                        .map(Integer::parseInt)
                        .collect(Collectors.toList());

                modal.setDocumentIds(docIds);
            }

            bulletinOfferModals.add(modal);
        }

        // 0️⃣ Thought of the Day (virtual bulletin)
        BulletinOfferModal thoughtModal = new BulletinOfferModal();
        thoughtModal.setOfferId(0L); // dummy
        thoughtModal.setDescription(SalesThoughtConstants.getTodayThought());
        thoughtModal.setCreatedAt(LocalDateTime.MAX); // IMPORTANT → always first
        thoughtModal.setCreatedTime("");
        thoughtModal.setCatalogOffer(false);
        thoughtModal.setCreatedBy("SYSTEM");
        thoughtModal.setBulletinType(ProfitMandiConstants.BULLETIN_TYPE_ENUM.BULLETIN);

        bulletinOfferModals.add(thoughtModal);


        List<BulletinOfferModal> getTodayCreatedCatalogOffer = todayOfferService.findAllTodayCatalogOfferBulletin(regionIds.stream().map(x -> x.intValue()).collect(Collectors.toList()), startDate, endDate);
        bulletinOfferModals.addAll(getTodayCreatedCatalogOffer);

        List<BulletinOfferModal> getTodaySchemes = todayOfferService.findAllTodaySchemeBulletin(regionIds.stream().map(x -> x.intValue()).collect(Collectors.toList()), startDate, endDate);
        bulletinOfferModals.addAll(getTodaySchemes);

        List<BulletinOfferModal> getTodayCardCashback = todayOfferService.findAllTodayWebOfferBulletin(startDate, endDate);
        bulletinOfferModals.addAll(getTodayCardCashback);

        List<BulletinOfferModal> getTodayPrebookingList = todayOfferService.getAllTodayCreatedPreBookingList(startDate, endDate);
        bulletinOfferModals.addAll(getTodayPrebookingList);

        bulletinOfferModals.sort(
                Comparator.comparing(BulletinOfferModal::getCreatedAt).reversed()
        );

        Map<ProfitMandiConstants.BULLETIN_TYPE_ENUM, List<BulletinOfferModal>> bulletinOffermap =
                bulletinOfferModals.stream()
                        .collect(Collectors.groupingBy(
                                BulletinOfferModal::getBulletinType,
                                () -> new EnumMap<>(ProfitMandiConstants.BULLETIN_TYPE_ENUM.class),
                                Collectors.toList()
                        ));

        bulletinOfferModals.sort(
                Comparator.comparing(BulletinOfferModal::getCreatedAt).reversed()
        );



        return bulletinOffermap;
    }

    private Map<Integer, List<Integer>> getWarehouseIdFofoIdMap(Set<Integer> fofoIds) throws ProfitMandiBusinessException {
        Map<Integer, List<Integer>> warehouseIdFofoIdMap = fofoStoreRepository
                .selectActivePartnersByRetailerIds(new ArrayList<>(fofoIds)).stream()
                .collect(Collectors.groupingBy(FofoStore::getWarehouseId,
                        Collectors.mapping(FofoStore::getId, Collectors.toList())));
        // warehouseStock
        if (!warehouseIdFofoIdMap.containsKey(7573)) {
            warehouseIdFofoIdMap.put(7573, new ArrayList<>());
        }
        return warehouseIdFofoIdMap;
    }

    private List<Menu> prepareMenu(List<Menu> menus) {
        List<Menu> returnMenu = new ArrayList<>();
        Map<Menu, List<Menu>> subMenuMap = new HashMap<>();
        for (Menu menu : menus) {
            if (menu.get_parent() == null) {
                if (!subMenuMap.containsKey(menu)) {
                    subMenuMap.put(menu, new ArrayList<>());
                }
            } else {
                Menu parentMenu = menu.get_parent();
                if (!subMenuMap.containsKey(parentMenu)) {
                    subMenuMap.put(parentMenu, new ArrayList<>());
                }
                subMenuMap.get(parentMenu).add(menu);
            }
        }
        subMenuMap.entrySet().stream().forEach(entry -> {
            entry.getKey().setSubMenus(entry.getValue());
            returnMenu.add(entry.getKey());
        });
        return returnMenu;
    }

    public Map<Integer, PartnerDetailModel> getWarehousePartnerDetail(Map<Integer, List<Integer>> warehousePartnerMap)
            throws Exception {

        Map<Integer, PartnerDetailModel> warehouseIdAndallValues = new LinkedHashMap<>();
        // Map<Integer, List<FofoStore>> warehousePartnerMap =
        // fofoStoreRepository.getWarehousePartnerMap();
        Map<Integer, PartnerDetailModel> partnerStats = this.getPartnersStatDataFromFile();
        List<Integer> allfofoIds = new ArrayList<>();
        if (partnerStats != null) {
            for (Entry<Integer, List<Integer>> warehouse : warehousePartnerMap.entrySet()) {
                List<Integer> fofoIds = warehouse.getValue().stream().collect(Collectors.toList());
                allfofoIds.addAll(fofoIds);
                List<PartnerDetailModel> partnerDetails = fofoIds.stream().map(x -> partnerStats.get(x))
                        .collect(Collectors.toList());
                if (partnerDetails != null && !partnerDetails.isEmpty()) {
                    PartnerDetailModel partnerDetailModel = partnerStatsService.getAggregateStats(partnerDetails);
                    warehouseIdAndallValues.put(warehouse.getKey(), partnerDetailModel);
                }

            }
            List<PartnerDetailModel> allPartnerDetails = allfofoIds.stream().map(x -> partnerStats.get(x))
                    .collect(Collectors.toList());
            //LOGGER.info("allPartnerDetails" + allPartnerDetails);
            PartnerDetailModel partnerDetailModel = partnerStatsService
                    .getAggregateStats(new ArrayList<>(allPartnerDetails));
            warehouseIdAndallValues.put(0, partnerDetailModel);
        }
        return warehouseIdAndallValues;
    }

    public Map<Integer, PartnerDetailModel> getPartnersStatDataFromFile() throws Exception {
        ObjectInputStream objectinputstream = null;
        Map<Integer, PartnerDetailModel> partnerStat = null;
        try {
//            FileInputStream streamIn = new FileInputStream("/tmp/partnerStat.tmp");
            FileInputStream streamIn = new FileInputStream("/var/www/partner_stats/partnerStat.tmp");
            objectinputstream = new ObjectInputStream(streamIn);
            partnerStat = (Map<Integer, PartnerDetailModel>) objectinputstream.readObject();

            objectinputstream.close();

        } catch (Exception e) {
            LOGGER.info("exceptionddd" + e);

            e.printStackTrace();

        } finally {
            if (objectinputstream != null) {
                objectinputstream.close();
            }
        }
        return partnerStat;

    }

    private String getWarehouses(Set<CustomRetailer> positionRetailers) {
        Map<Integer, String> warehouses = new HashMap<>();
        positionRetailers.stream().forEach(x -> {
            if (x.getWarehouseId() != 0) {
                warehouses.put(x.getWarehouseId(), ProfitMandiConstants.WAREHOUSE_MAP.get(x.getWarehouseId()));
            }
        });
        return gson.toJson(warehouses);

    }


}