Subversion Repositories SmartDukaan

Rev

Rev 31454 | Rev 31478 | Go to most recent revision | View as "text/plain" | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.spice.profitmandi.web.controller;

import com.google.gson.Gson;
import com.mongodb.DBObject;
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.common.model.*;
import com.spice.profitmandi.common.util.FileUtil;
import com.spice.profitmandi.common.web.util.ResponseSender;
import com.spice.profitmandi.dao.entity.auth.AuthUser;
import com.spice.profitmandi.dao.entity.fofo.PartnerDailyInvestment;
import com.spice.profitmandi.dao.entity.user.*;
import com.spice.profitmandi.dao.enumuration.cs.EscalationType;
import com.spice.profitmandi.dao.enumuration.dtr.CommunicationType;
import com.spice.profitmandi.dao.enumuration.dtr.LeadSource;
import com.spice.profitmandi.dao.enumuration.dtr.LeadStatus;
import com.spice.profitmandi.dao.model.*;
import com.spice.profitmandi.dao.repository.auth.AuthRepository;
import com.spice.profitmandi.dao.repository.auth.PartnerCollectionPlanRepository;
import com.spice.profitmandi.dao.repository.auth.PartnerCollectionRemarkRepository;
import com.spice.profitmandi.dao.repository.cs.CsService;
import com.spice.profitmandi.dao.repository.cs.PositionRepository;
import com.spice.profitmandi.dao.repository.dtr.*;
import com.spice.profitmandi.dao.repository.fofo.PartnerDailyInvestmentRepository;
import com.spice.profitmandi.dao.repository.inventory.StateRepository;
import com.spice.profitmandi.dao.repository.transaction.UserWalletRepository;
import com.spice.profitmandi.service.AuthService;
import com.spice.profitmandi.service.PartnerCollectionService;
import com.spice.profitmandi.service.user.RetailerService;
import com.spice.profitmandi.web.model.LoginDetails;
import com.spice.profitmandi.web.util.CookiesProcessor;
import com.spice.profitmandi.web.util.MVCResponseSender;
import org.apache.commons.csv.CSVRecord;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;

@Controller
@Transactional(rollbackOn = Throwable.class)
public class LeadController {
        private static final Logger LOGGER = LogManager.getLogger(LeadController.class);

        @Autowired
        private LeadRepository leadRepository;

        @Autowired
        private LeadActivityRepository leadActivityRepository;

        @Autowired
        private StateRepository stateRepository;

        @Autowired
        private AuthService authService;

        @Autowired
        private AuthRepository authRepository;

        @Autowired
        private Gson gson;

        @Autowired
        private CookiesProcessor cookiesProcessor;

        @Autowired
        PositionRepository positionRepository;

        @Autowired
        private MVCResponseSender mvcResponseSender;

        @Autowired
        private PartnerCollectionPlanRepository partnerCollectionPlanRepository;

        @Autowired
        private CsService csService;

        @Autowired
        private FofoStoreRepository fofoStoreRepository;

        @Autowired
        private PartnerCollectionService partnerCollectionService;

        @Autowired
        private RetailerService retailerService;

        @Autowired
        private PartnerCollectionRemarkRepository partnerCollectionRemarkRepository;

        @Autowired
        private PartnerDailyInvestmentRepository partnerDailyInvestmentRepository;

        @Autowired
        private UserWalletRepository userWalletRepository;

        @Autowired
        private FranchiseeVisitRepository franchiseeVisitRepository;

        @Autowired
        private FranchiseeActivityRepository franchiseeActivityRepository;

        @Autowired
        private VisitRequestRepository visitRequestRepository;

        @Autowired
        private LeadBrandRepository leadBrandRepository;

        @Autowired
        private LeadDetailRepository leadDetailRepository;

        @Autowired
        private Mongo mongoClient;

        @Autowired
        private ResponseSender<?> responseSender;

        List<LeadStatus> status = Arrays.asList(LeadStatus.notInterested, LeadStatus.finalized);

        @RequestMapping(value = "/getOpenLead", method = RequestMethod.GET)
        public String getOpenLead(HttpServletRequest request,
                        @RequestParam(name = "leadStatus", required = false, defaultValue = "All") List<LeadStatus> leadStatus,
                        @RequestParam(name = "color", required = false, defaultValue = "All") List<String> color,
                        @RequestParam(name = "leadDate", required = false, defaultValue = "") LocalDate leadDate, Model model)
                        throws Exception {

                LocalDateTime localDateTime = null;
                if (leadDate != null) {
                        localDateTime = leadDate.atStartOfDay();
                }
                LOGGER.info("localDateTime" + localDateTime);

                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                String emailId = loginDetails.getEmailId();
                AuthUser authUser = authRepository.selectByEmailOrMobile(emailId);

                boolean authPositon = positionRepository.hasCategory(authUser.getId(),
                                ProfitMandiConstants.TICKET_CATEGORY_SALES);

                if (leadStatus.contains(LeadStatus.All)) {

                        leadStatus.add(LeadStatus.pending);
                        leadStatus.add(LeadStatus.notInterested);
                        leadStatus.add(LeadStatus.finalized);
                }

                if (color.contains("All")) {
                        color.add("yellow");
                        color.add("green");
                }

                List<Lead> leads = new ArrayList<>();

                model.addAttribute("colors", color);

                Map<Integer, List<LeadActivity>> leadActivityMap = new HashMap<>();

                List<Integer> authUserIds = null;

                LOGGER.info("color111" + color);

                List<Lead> leadFollowUp = new ArrayList<>();

                if (authPositon) {
                        authUserIds = authService.getAllReportees(authUser.getId());
                        authUserIds.add(authUser.getId());
                        LOGGER.info("authIds" + authUserIds);

                        LOGGER.info("leadStatus" + leadStatus);

                        if (localDateTime == null) {

                                if (!leadStatus.contains(LeadStatus.followUp)) {

                                        leads = leadRepository.selectAllByColorStatusAndUpdatedTimestampAndAuthIds(leadStatus, authUserIds,
                                                        color, LocalDateTime.now().minusMonths(1));
                                }

                                if (leadStatus.contains(LeadStatus.followUp) || leadStatus.contains(LeadStatus.All)) {
                                        leadFollowUp = leadRepository.selectByAssignAuthIdsAndStatus(authUserIds, LeadStatus.followUp);
                                        leads.addAll(leadFollowUp);
                                }

                        } else {

                                if (!leadStatus.contains(LeadStatus.followUp)) {

                                        leads = leadRepository.selectAllByColorStatusAndUpdatedTimestampAndAuthIds(leadStatus, authUserIds,
                                                        color, localDateTime);
                                }

                                if (leadStatus.contains(LeadStatus.followUp) || leadStatus.contains(LeadStatus.All)) {

                                        leadFollowUp = leadRepository.selectByAssignAuthIdsAndStatus(authUserIds, LeadStatus.followUp);

                                        leads.addAll(leadFollowUp);

                                }

                        }

                } else {

                        if (localDateTime == null) {
                                if (!leadStatus.contains(LeadStatus.followUp)) {

                                        leads = leadRepository.selectAllByColorStatusAndUpdatedTimestamp(leadStatus, color,
                                                        LocalDateTime.now().minusMonths(1));
                                }
                                if (leadStatus.contains(LeadStatus.followUp) || leadStatus.contains(LeadStatus.All)) {

                                        leadFollowUp = leadRepository.selectAllByStatus(LeadStatus.followUp);

                                        leads.addAll(leadFollowUp);
                                }
                                LOGGER.info("leadlocalDateTime1" + leads);

                        } else {
                                if (!leadStatus.contains(LeadStatus.followUp)) {

                                        leads = leadRepository.selectAllByColorStatusAndUpdatedTimestamp(leadStatus, color, localDateTime);
                                }

                                if (leadStatus.contains(LeadStatus.followUp) || leadStatus.contains(LeadStatus.All)) {

                                        leadFollowUp = leadRepository.selectAllByStatus(LeadStatus.followUp);

                                        leads.addAll(leadFollowUp);
                                }
                                LOGGER.info("leadlocalDateTime2" + leads);

                        }

                }

                if (authPositon && authUserIds.size() > 0) {
                        List<String> leadCreators = new ArrayList<>();
                        leadCreators.add("daily-sync");
                        leadCreators.addAll(authRepository.selectAllAuthUserByIds(authUserIds).stream().map(x -> x.getFullName())
                                        .collect(Collectors.toList()));
                        model.addAttribute("leadCreators", leadCreators);
                }
                List<Lead> weekLast = new ArrayList<>();
                List<Lead> weekThird = new ArrayList<>();
                List<Lead> weekSecond = new ArrayList<>();
                List<Lead> weekFirst = new ArrayList<>();
                LocalDateTime curDate = LocalDate.now().atStartOfDay();
                List<LeadWeakWiseModel> lwDays = new ArrayList<>();

                for (int i = 7; i >= 1; i--) {
                        LocalDateTime startOfDay = curDate.minusDays(i);

                        LeadWeakWiseModel lm = new LeadWeakWiseModel();
                        lm.setMonth(startOfDay.toLocalDate());
                        lwDays.add(lm);
                }
                if (!leads.isEmpty()) {

                        weekLast.addAll(
                                        leads.stream()
                                                        .filter(x -> x.getCreatedTimestamp().isAfter(curDate.minusDays(28))
                                                                        && x.getCreatedTimestamp().isBefore(curDate.minusDays(21)))
                                                        .collect(Collectors.toList()));

                        weekThird
                                        .addAll(leads.stream()
                                                        .filter(x -> x.getCreatedTimestamp().isAfter(curDate.minusDays(21))
                                                                        && x.getCreatedTimestamp().isBefore(curDate.minusDays(14)))
                                                        .collect(Collectors.toList()));

                        weekSecond
                                        .addAll(leads.stream()
                                                        .filter(x -> x.getCreatedTimestamp().isAfter(curDate.minusDays(14))
                                                                        && x.getCreatedTimestamp().isBefore(curDate.minusDays(7)))
                                                        .collect(Collectors.toList()));

                        weekFirst.addAll(leads.stream().filter(x -> x.getCreatedTimestamp().isAfter(curDate.minusDays(7)))
                                        .collect(Collectors.toList()));

                }
                LOGGER.info("weekLast" + weekLast);
                LOGGER.info("weekThird" + weekThird);
                LOGGER.info("weekSecond" + weekSecond);
                Map<String, Long> leadLasts = weekLast.stream()
                                .collect(Collectors.groupingBy(x -> x.getCreatedBy(), Collectors.counting()));
                Map<String, Long> leadThirds = weekThird.stream()
                                .collect(Collectors.groupingBy(x -> x.getCreatedBy(), Collectors.counting()));
                Map<String, Long> leadSeconds = weekSecond.stream().collect(Collectors.groupingBy(x -> x.getCreatedBy(),
                                Collectors.mapping(Lead::getCreatedBy, Collectors.counting())));

                Map<String, Map<LocalDate, Long>> leadFirsts = weekFirst.stream()
                                .collect(Collectors.groupingBy(x -> x.getCreatedBy(),
                                                Collectors.groupingBy(x -> x.getCreatedTimestamp().toLocalDate(), Collectors.counting())));

                LOGGER.info("leadFirsts" + leadFirsts);

                List<Integer> authIds = new ArrayList<>();
                if (!leads.isEmpty()) {

                        authIds.addAll(leads.stream().map(x -> x.getAssignTo()).collect(Collectors.toList()));

                        leadActivityMap = leadActivityRepository
                                        .selectAllByleadIds(leads.stream().map(x -> x.getId()).collect(Collectors.toList())).stream()
                                        .collect(Collectors.groupingBy(LeadActivity::getLeadId, Collectors.toList()));

                        Map<Integer, AuthUser> authIdAndAuthUserMap = authRepository.selectAllAuthUserByIds(authIds).stream()
                                        .collect(Collectors.toMap(x -> x.getId(), x -> x));
                        model.addAttribute("leadActivityMap", leadActivityMap);
                        model.addAttribute("authIdAndAuthUserMap", authIdAndAuthUserMap);
                }

                ChartLeadModel cm = this.getLeadChart(leads);
                model.addAttribute("chartLead", gson.toJson(cm));

                LOGGER.info("ChartLeadModel" + gson.toJson(cm));
                LOGGER.info("lwDays" + lwDays);

                LOGGER.info("leads" + leads);
                List<String> stateNames = stateRepository.selectAll().stream().map(x -> x.getName())
                                .collect(Collectors.toList());
                List<AuthUser> authUsers = authRepository.selectAllActiveUser();
                LocalDate lastDate = curDate.minusDays(1).toLocalDate();

                List<LocalDate> weekDates = new ArrayList<>();

                weekDates.add(curDate.minusDays(28).toLocalDate());
                weekDates.add(curDate.minusDays(22).toLocalDate());
                weekDates.add(curDate.minusDays(21).toLocalDate());
                weekDates.add(curDate.minusDays(15).toLocalDate());
                weekDates.add(curDate.minusDays(14).toLocalDate());
                weekDates.add(curDate.minusDays(8).toLocalDate());
                weekDates.add(curDate.minusDays(7).toLocalDate());
                LOGGER.info("lastDate" + lastDate);

                model.addAttribute("weekDates", weekDates);

                model.addAttribute("leadDate", leadDate);
                model.addAttribute("lastDate", lastDate);
                model.addAttribute("stateNames", stateNames);

                model.addAttribute("communicationTypes", CommunicationType.values());

                model.addAttribute("authUsers", authUsers);
                model.addAttribute("lead", leads);
                model.addAttribute("leadStatus", LeadStatus.values());
                model.addAttribute("leadLasts", leadLasts);
                model.addAttribute("leadThirds", leadThirds);
                model.addAttribute("leadSeconds", leadSeconds);
                model.addAttribute("leadFirsts", leadFirsts);
                model.addAttribute("lwDays", lwDays);

                model.addAttribute("selectedLeadStatus", leadStatus.get(0));

                List<DBObject> mobileBrands = mongoClient.getAllBrandsToDisplay(3);

                List<String> brands = mobileBrands.stream().map(x -> (String) x.get("name")).collect(Collectors.toList());

                model.addAttribute("brands", brands);

                return "lead";

        }

        public ChartLeadModel getLeadChart(List<Lead> leads) throws ProfitMandiBusinessException {

                Map<LeadStatus, Long> leadStatusMap = leads.stream().collect(
                                Collectors.groupingBy(x -> x.getStatus(), Collectors.mapping(Lead::getStatus, Collectors.counting())));

                Map<String, Long> hotLeadsMap = leads.stream().collect(
                                Collectors.groupingBy(x -> x.getColor(), Collectors.mapping(Lead::getColor, Collectors.counting())));

                LOGGER.info("hotLeadsMap" + hotLeadsMap);
                ChartLeadModel cm = new ChartLeadModel();

                HashSet<LeadStatus> labels = new HashSet<LeadStatus>();
                labels.addAll(leadStatusMap.keySet());

                List<String> hotLeads = new ArrayList<>();
                hotLeads.addAll(leadStatusMap.keySet().stream().map(x -> x.toString()).collect(Collectors.toSet()));
                hotLeads.add("HotLead");

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

                hotLeadKeys.add("HotLead");
                List<String> hotLeadGreen = new ArrayList<>(hotLeadKeys);

                LOGGER.info("hotLeads" + hotLeads);

                List<LeadStatus> labelList = new ArrayList<>(labels);
                List<String> backgroundColor = new ArrayList<>();
                LOGGER.info("hotLeadKeys" + hotLeadKeys);
                List<Long> values = new ArrayList<>();

                for (String hotLead : hotLeads) {

                        if (hotLead.equals("pending")) {
                                backgroundColor.add("pink");
                                values.add(leadStatusMap.get(LeadStatus.pending));
                        }
                        if (hotLead.equals("notInterested")) {
                                backgroundColor.add("red");
                                values.add(leadStatusMap.get(LeadStatus.notInterested));
                        }
                        if (hotLead.equals("followUp")) {
                                backgroundColor.add("#9ACD32");
                                values.add(leadStatusMap.get(LeadStatus.followUp));
                        }
                        if (hotLead.equals("finalized")) {
                                backgroundColor.add("blue");
                                values.add(leadStatusMap.get(LeadStatus.finalized));
                        }

                        if (hotLead.equals("HotLead")) {
                                backgroundColor.add("green");
                                values.add(hotLeadsMap.get("Green"));

                        }

                }
                LOGGER.info("labelList" + labelList);

                LOGGER.info("backgroundColor" + backgroundColor);
                LOGGER.info("labelsChartLead" + labels);
                LeadStatusData data = new LeadStatusData();
                data.setData(values);
                data.setBackgroundColor(backgroundColor);
                data.setLabel("DataSet 1");

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

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

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

                DataLeadModel datasets = new DataLeadModel();
                datasets.setDatasets(dataList);
                datasets.setLabels(hotLeads);

                OptionModel om = new OptionModel();
                om.setLegend(legend);

                cm.setType("pie");
                cm.setData(datasets);
                cm.setOptions(om);

                return cm;
        }

        @RequestMapping(value = "/getClosedLead", method = RequestMethod.GET)
        public String getClosedLead(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit,
                        @RequestParam(name = "searchTerm", required = false, defaultValue = "") String searchTerm, Model model)
                        throws Exception {
                List<AuthUser> authUsers = authRepository.selectAllActiveUser();
                List<Lead> leads = null;
                long size = 0;
                leads = leadRepository.selectAllByStatus(status, offset, limit);
                size = leadRepository.selectCountByStatus(status);

                if (!leads.isEmpty()) {
                        List<Integer> authIds = new ArrayList<>();
                        for (Lead lead : leads) {
                                authIds.add(lead.getAssignTo());
                        }
                        Map<Integer, AuthUser> authIdAndAuthUserMap = authRepository.selectAllAuthUserByIds(authIds).stream()
                                        .collect(Collectors.toMap(x -> x.getId(), x -> x));

                        model.addAttribute("leads", leads);
                        model.addAttribute("start", offset + 1);
                        model.addAttribute("size", size);
                        model.addAttribute("searchTerm", searchTerm);
                        model.addAttribute("authIdAndAuthUserMap", authIdAndAuthUserMap);
                        model.addAttribute("url", "/getPaginatedClosedLeads");

                        if (leads.size() < limit) {
                                model.addAttribute("end", offset + leads.size());
                        } else {
                                model.addAttribute("end", offset + limit);
                        }

                } else {
                        model.addAttribute("lead", leads);

                        model.addAttribute("size", size);
                }

                model.addAttribute("authUsers", authUsers);
                return "lead-close";
        }

        @RequestMapping(value = "/getPaginatedClosedLeads", method = RequestMethod.GET)
        public String getPaginatedClosedLeads(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                List<Lead> leads = null;
                leads = leadRepository.selectAllByStatus(status, offset, limit);

                if (!leads.isEmpty()) {
                        List<Integer> authIds = new ArrayList<>();
                        for (Lead lead : leads) {
                                authIds.add(lead.getAssignTo());
                        }
                        Map<Integer, AuthUser> authIdAndAuthUserMap = authRepository.selectAllAuthUserByIds(authIds).stream()
                                        .collect(Collectors.toMap(x -> x.getId(), x -> x));
                        model.addAttribute("authIdAndAuthUserMap", authIdAndAuthUserMap);
                        model.addAttribute("leads", leads);
                        model.addAttribute("url", "/getPaginatedClosedLeads");

                } else {
                        model.addAttribute("leads", leads);

                }
                return "lead-close-paginated";
        }

        @RequestMapping(value = "/searchLeads")
        public String getClosedLeads(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit,
                        @RequestParam(name = "searchTerm", required = false, defaultValue = "") String searchTerm, Model model)
                        throws ProfitMandiBusinessException {
                List<AuthUser> authUsers = authRepository.selectAllActiveUser();
                List<Lead> leads = null;
                long size = 0;
                if (!(searchTerm.equals(""))) {
                        leads = leadRepository.selectBySearchTerm(status, searchTerm, offset, limit);
                        if (!(leads.size() == 0)) {
                                size = leadRepository.selectCountByStatus(status);
                                List<Integer> authIds = new ArrayList<>();
                                for (Lead lead : leads) {
                                        authIds.add(lead.getAssignTo());
                                }
                                Map<Integer, AuthUser> authIdAndAuthUserMap = authRepository.selectAllAuthUserByIds(authIds).stream()
                                                .collect(Collectors.toMap(x -> x.getId(), x -> x));
                                model.addAttribute("authIdAndAuthUserMap", authIdAndAuthUserMap);
                                model.addAttribute("leads", leads);
                                model.addAttribute("start", offset + 1);
                                model.addAttribute("size", size);
                                model.addAttribute("searchTerm", searchTerm);

                                if (leads.size() < limit) {
                                        model.addAttribute("end", offset + leads.size());
                                } else {
                                        model.addAttribute("end", offset + limit);
                                }
                        } else {
                                throw new ProfitMandiBusinessException("lead", searchTerm, "leads Not Found");
                        }
                } else {
                        leads = leadRepository.selectAllByStatus(status, offset, limit);
                        size = leadRepository.selectCountByStatus(status);

                        if (!leads.isEmpty()) {
                                List<Integer> authIds = new ArrayList<>();
                                for (Lead lead : leads) {
                                        authIds.add(lead.getAssignTo());
                                }
                                Map<Integer, AuthUser> authIdAndAuthUserMap = authRepository.selectAllAuthUserByIds(authIds).stream()
                                                .collect(Collectors.toMap(x -> x.getId(), x -> x));

                                model.addAttribute("leads", leads);
                                model.addAttribute("start", offset + 1);
                                model.addAttribute("size", size);
                                model.addAttribute("searchTerm", searchTerm);
                                model.addAttribute("authIdAndAuthUserMap", authIdAndAuthUserMap);

                                if (leads.size() < limit) {
                                        model.addAttribute("end", offset + leads.size());
                                } else {
                                        model.addAttribute("end", offset + limit);
                                }

                        }
                }

                model.addAttribute("authUsers", authUsers);
                return "lead-close";
        }

        @RequestMapping(value = "/searchLeadPaginated")
        public String searchLeadPaginated(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit,
                        @RequestParam(name = "searchTerm", required = false, defaultValue = "") String searchTerm, Model model)
                        throws ProfitMandiBusinessException {
                LOGGER.info("In search Item....");
                List<Lead> leads = null;
                if (!searchTerm.equals("")) {
                        leads = leadRepository.selectBySearchTerm(status, searchTerm, offset, limit);
                        if (!(leads.size() == 0)) {

                                List<Integer> authIds = new ArrayList<>();
                                for (Lead lead : leads) {
                                        authIds.add(lead.getAssignTo());
                                }
                                Map<Integer, AuthUser> authIdAndAuthUserMap = authRepository.selectAllAuthUserByIds(authIds).stream()
                                                .collect(Collectors.toMap(x -> x.getId(), x -> x));
                                model.addAttribute("authIdAndAuthUserMap", authIdAndAuthUserMap);
                                model.addAttribute("leads", leads);
                        }
                }

                return "lead-close-paginated";

        }

        @RequestMapping(value = "/getLeadActivity", method = RequestMethod.GET)
        public String getLeadActivity(HttpServletRequest request, @RequestParam int leadId, Model model) throws Exception {
                List<LeadActivity> leadActivity = leadActivityRepository.selectBYLeadId(leadId);

                LOGGER.info("leadActivity" + leadActivity);

                model.addAttribute("leadActivity", leadActivity);
                model.addAttribute("authUserMap",
                                authRepository.selectAllActiveUser().stream().collect(Collectors.toMap(x -> x.getId(), x -> x)));

                return "lead_activity_modal";
        }

        @RequestMapping(value = "/getLead", method = RequestMethod.GET)
        public ResponseEntity<?> getLead(HttpServletRequest request, @RequestParam int leadId) throws Exception {
                Lead lead = leadRepository.selectById(leadId);

                LeadDetail leadDetail = leadDetailRepository.selectByLeadId(lead.getId());
                if (leadDetail != null) {
                        lead.setOutLetName(leadDetail.getOutletName());
                }

                return responseSender.ok(lead);

        }

        @RequestMapping(value = "/createLead", method = RequestMethod.POST)
        public String CreateLead(HttpServletRequest request, @RequestBody CreateRefferalRequest createRefferalRequest,
                        Model model) throws Exception {
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);

                LOGGER.info("createRefferalRequest" + createRefferalRequest.getSchelduleTimestamp());
                Lead lead = new Lead();
                lead.setFirstName(createRefferalRequest.getFirstName());
                lead.setLastName(createRefferalRequest.getLastName());
                lead.setLeadMobile(createRefferalRequest.getMobile());
                lead.setState(createRefferalRequest.getState());
                lead.setCity(createRefferalRequest.getCity());
                lead.setAddress(createRefferalRequest.getAddress());
                lead.setCreatedTimestamp(LocalDateTime.now());
                lead.setUpdatedTimestamp(LocalDateTime.now());
                lead.setStatus(createRefferalRequest.getStatus());
                lead.setAssignTo(createRefferalRequest.getAssignTo());
                lead.setSource(createRefferalRequest.getSource());
                lead.setColor("yellow");
                // change
                AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
                String authUserName = authUser.getFirstName() + " " + authUser.getLastName();
                lead.setCreatedBy(authUserName);
                lead.setAuthId(authUser.getId());
                LOGGER.info("lead --- {}", lead);
                leadRepository.persist(lead);
                LeadActivity leadActivity = new LeadActivity();
                leadActivity.setLeadId(lead.getId());
                leadActivity.setRemark(createRefferalRequest.getRemark());
                leadActivity.setAuthId(authUser.getId());
                LOGGER.info("createRefferalRequest" + createRefferalRequest.getCommunicationType());

                if (createRefferalRequest.getStatus() == LeadStatus.followUp) {
                        leadActivity.setSchelduleTimestamp(createRefferalRequest.getSchelduleTimestamp());
                        leadActivity.setCommunicationType(createRefferalRequest.getCommunicationType());

                        if (leadActivity.getCommunicationType().equals(CommunicationType.VISIT)) {
                                visitRequestRepository.createVisitRequest(lead.getId(), "lead", lead.getAssignTo(),
                                                createRefferalRequest.getSchelduleTimestamp());
                        }
                } else {
                        leadActivity.setSchelduleTimestamp(null);
                }
                leadActivity.setCreatedTimestamp(LocalDateTime.now());
                leadActivityRepository.persist(leadActivity);
                model.addAttribute("response1", mvcResponseSender.createResponseString(true));

                return "response";

        }

        @RequestMapping(value = "/editLead", method = RequestMethod.POST)
        public String EditLead(HttpServletRequest request,
                        @RequestBody CreateLeacdActivityRequest createLeadActivityRequest, Model model) throws Exception {
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);

                AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());

                LeadDetail leadDetail = leadDetailRepository.selectByLeadId(createLeadActivityRequest.getId());

                if (leadDetail == null) {

                        throw new ProfitMandiBusinessException("LeadDetail", "", "Please fill lead detail");
                }

                LeadActivity leadActivity = new LeadActivity();
                leadActivity.setLeadId(createLeadActivityRequest.getId());
                leadActivity.setRemark(createLeadActivityRequest.getRemark());

                LOGGER.info("createRefferalRequest" + createLeadActivityRequest);

                if (createLeadActivityRequest.getStatus() == LeadStatus.followUp) {
                        leadActivity.setSchelduleTimestamp(createLeadActivityRequest.getScheldule());
                        leadActivity.setCommunicationType(createLeadActivityRequest.getCommunicationType());
                        if (leadActivity.getCommunicationType().equals(CommunicationType.VISIT)) {
                                visitRequestRepository.createVisitRequest(createLeadActivityRequest.getId(), "lead",
                                                createLeadActivityRequest.getAssignTo(), createLeadActivityRequest.getScheldule());
                        }
                } else {
                        leadActivity.setSchelduleTimestamp(null);
                }
                leadActivity.setCreatedTimestamp(LocalDateTime.now());
                leadActivity.setAuthId(authUser.getId());
                leadActivityRepository.persist(leadActivity);
                Lead lead = leadRepository.selectById(createLeadActivityRequest.getId());
                lead.setAssignTo(createLeadActivityRequest.getAssignTo());
                lead.setStatus(createLeadActivityRequest.getStatus());
                lead.setNotinterestedReason(createLeadActivityRequest.getReason());
                lead.setUpdatedTimestamp(LocalDateTime.now());

                lead = leadRepository.selectById(createLeadActivityRequest.getId());

                int authId = 0;
                if (lead != null) {

                        authId = lead.getAssignTo();
                        Map<Integer, LeadActivity> leadActivityMap = new HashMap<>();

                        List<LeadActivity> leadActivitys = leadActivityRepository.selectBYLeadId(lead.getId());

                        if (!leadActivitys.isEmpty()) {
                                leadActivityMap.put(lead.getId(), leadActivitys.get(0));
                        }

                        Map<Integer, AuthUser> authIdAndAuthUserMap = new HashMap<>();
                        AuthUser AuthUser = authRepository.selectById(authId);

                        authIdAndAuthUserMap.put(AuthUser.getId(), AuthUser);

                        model.addAttribute("leadActivityMap", leadActivityMap);
                        model.addAttribute("authIdAndAuthUserMap", authIdAndAuthUserMap);
                }

                model.addAttribute("request", lead);

                return "edit-lead";

        }

        @RequestMapping(value = "/downloadIvoryLead", method = RequestMethod.GET)
        public ResponseEntity<?> downloadDelayDayTemplate(HttpServletRequest request) throws Exception {
                List<String> stateNames = stateRepository.selectAll().stream().map(x -> x.getName())
                                .collect(Collectors.toList());

                List<List<?>> rows = new ArrayList<>();

                List<LeadSource> lss = LeadSource.enumValues;

                for (LeadSource ls : lss) {
                        rows.add(Arrays.asList("-", "-", "-", "-", "-", "-", "-", ls));

                }
                for (String stateName : stateNames) {
                        rows.add(Arrays.asList("-", "-", "-", "-", stateName, "-", "-", "-"));

                }

                org.apache.commons.io.output.ByteArrayOutputStream baos = FileUtil.getCSVByteStream(Arrays.asList("First Name",
                                "Last Name", "Address", "City", "State", "Mobile", "Assign To(email)", "Source"), rows);

                final HttpHeaders headers = new HttpHeaders();
                headers.set("Content-Type", "text/csv");
                headers.set("Content-disposition", "inline; filename=leads.format.csv");
                headers.setContentLength(baos.toByteArray().length);

                final InputStream inputStream = new ByteArrayInputStream(baos.toByteArray());
                final InputStreamResource inputStreamResource = new InputStreamResource(inputStream);
                return new ResponseEntity<InputStreamResource>(inputStreamResource, headers, HttpStatus.OK);

        }

        @RequestMapping(value = "/csvFileAndSetLead", method = RequestMethod.POST)
        public String readCsvFileAndSetLead(HttpServletRequest request, Model model, HttpServletResponse response,
                        @RequestPart MultipartFile file) throws Throwable {

                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                String email = loginDetails.getEmailId();

                AuthUser createdBy = authRepository.selectByEmailOrMobile(email);

                LOGGER.info("file" + file.toString());

                String fileName = file.getName();

                String fileNames = file.getOriginalFilename();

                LOGGER.info("fileName" + fileName);
                LOGGER.info("fileNames" + fileNames);

                List<CSVRecord> records = FileUtil.readFile(file);

                for (CSVRecord record : records) {

                        Lead lead = new Lead();
                        lead.setFirstName(record.get(0));
                        lead.setLastName(record.get(1));
                        lead.setAddress(record.get(2));
                        lead.setCity(record.get(3));
                        lead.setState(record.get(4));
                        lead.setLeadMobile(record.get(5));
                        LOGGER.info("record" + record.get(6));

                        AuthUser assignTo = authRepository.selectByEmailOrMobile(record.get(6));

                        if (assignTo == null) {
                                throw new ProfitMandiBusinessException("Assign To ", record.get(6), "email id not exist");
                        }

                        lead.setAssignTo(assignTo.getId());
                        lead.setSource(record.get(7));

                        lead.setCreatedTimestamp(LocalDateTime.now());

                        lead.setUpdatedTimestamp(LocalDateTime.now());
                        lead.setStatus(LeadStatus.pending);
                        lead.setColor("yellow");
                        // change
                        lead.setCreatedBy(createdBy.getFullName());
                        lead.setAuthId(createdBy.getId());

                        leadRepository.persist(lead);

                        LeadActivity leadActivity = new LeadActivity();
                        leadActivity.setLeadId(lead.getId());
                        leadActivity.setRemark("New Lead");
                        leadActivity.setSchelduleTimestamp(null);

                        leadActivity.setCreatedTimestamp(LocalDateTime.now());
                        leadActivityRepository.persist(leadActivity);
                        model.addAttribute("response1", mvcResponseSender.createResponseString(true));

                }

                model.addAttribute("responseSTG", mvcResponseSender.createResponseString(true));

                return "response";

        }

        @RequestMapping(value = "/teamCommitment", method = RequestMethod.GET)
        public String teamCommitments(HttpServletRequest request, Model model) throws Exception {

                return "team-commitment";

        }

        @RequestMapping(value = "/leadDetail", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
        public String leadDetail(HttpServletRequest request, @RequestBody LeadDetailModel leadDetailModel, Model model)
                        throws Exception {

                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
                LeadDetail leadDetail = leadDetailRepository.selectByLeadId(leadDetailModel.getLeadId());
                if (leadDetail == null) {
                        leadDetail = new LeadDetail();
                        leadDetail.setLeadId(leadDetailModel.getLeadId());
                        leadDetail.setOutletName(leadDetailModel.getOutletName());
                        leadDetail.setCounterSize(leadDetailModel.getCounterSize());
                        leadDetail.setCreatedBy(authUser.getId());

                        leadDetail.setFrontp(leadDetailModel.getFrontp());
                        leadDetail.setFrontWithMarket(leadDetailModel.getFrontWithMarket());
                        leadDetail.setInternalLongShot(leadDetailModel.getInternalLongShot());
                        leadDetail.setInternalLeftWall(leadDetailModel.getInternalLeftWall());
                        leadDetail.setInternalRightWall(leadDetailModel.getInternalRightWall());

                        leadDetail.setCreatedTimestamp(LocalDateTime.now());

                        leadDetailRepository.persist(leadDetail);
                        for (LeadBrandModel leadBrandModel : leadDetailModel.getLeadBrands()) {

                                LeadBrand leadBrand = new LeadBrand();
                                leadBrand.setBrand(leadBrandModel.getBrand());
                                leadBrand.setValue(leadBrandModel.getValue());
                                leadBrand.setLeadDetailId(leadDetail.getId());
                                leadBrand.setLeadId(leadDetail.getLeadId());
                                leadBrand.setCreatedTimestamp(LocalDateTime.now());
                                leadBrandRepository.persist(leadBrand);

                        }
                } else {
                        throw new ProfitMandiBusinessException("LeadDetail", "", "Lead Detail Already Created");
                }

                model.addAttribute("response1", mvcResponseSender.createResponseString(true));

                return "response";

        }

        @RequestMapping(value = "/getLeadDetail", method = RequestMethod.GET)
        public String getLeadDetail(HttpServletRequest request, Model model) throws Exception {
                List<Integer> followUpleadIds = leadRepository.selectAllByStatus(LeadStatus.followUp).stream()
                                .map(x -> x.getId()).collect(Collectors.toList());
                List<LeadDetail> leadDetails = leadDetailRepository.selectByLeadIds(followUpleadIds);

                List<DBObject> mobileBrands = mongoClient.getAllBrandsToDisplay(3);

                List<String> brands = mobileBrands.stream().map(x -> (String) x.get("name")).collect(Collectors.toList());

                model.addAttribute("brands", brands);
                if (!leadDetails.isEmpty()) {

                        List<Integer> detailsIds = leadDetails.stream().map(x -> x.getId()).collect(Collectors.toList());

                        List<Integer> leadIds = leadDetails.stream().map(x -> x.getLeadId()).collect(Collectors.toList());

                        Map<Integer, Lead> leadMap = leadRepository.selectAllByIds(leadIds).stream()
                                        .filter(x -> x.getStatus().equals(LeadStatus.followUp))
                                        .collect(Collectors.toMap(x -> x.getId(), x -> x));

                        Map<Integer, Optional<LeadActivity>> leadActivityMap = leadActivityRepository.selectAllByleadIds(leadIds)
                                        .stream().collect(Collectors.groupingBy(x -> x.getLeadId(),
                                                        Collectors.maxBy(Comparator.comparing(LeadActivity::getId))));

                        model.addAttribute("leadActivityMap", leadActivityMap);

                        List<LeadBrand> leadBrands = leadBrandRepository.selectByLeadDetailId(detailsIds);

                        LOGGER.info("leadBrands {}" + leadBrands);

                        Map<Integer, Map<String, Integer>> leadDetailBrandValue = new HashMap<>();

                        Map<Integer, List<LeadBrand>> leadDetail = leadBrands.stream()
                                        .collect(Collectors.groupingBy(x -> x.getLeadDetailId(), Collectors.toList()));

                        for (Entry<Integer, List<LeadBrand>> leadDetailEntry : leadDetail.entrySet()) {

                                Map<String, Integer> brandValue = new HashMap<>();

                                for (LeadBrand leadBrand : leadDetailEntry.getValue()) {
                                        brandValue.put(leadBrand.getBrand(), leadBrand.getValue());

                                }
                                leadDetailBrandValue.put(leadDetailEntry.getKey(), brandValue);
                        }

                        LOGGER.info("leadDetailBrandValue {}" + leadDetailBrandValue);

                        model.addAttribute("leadDetailBrandValue", leadDetailBrandValue);

                        model.addAttribute("leadMap", leadMap);
                }

                model.addAttribute("leadDetails", leadDetails);

                Map<Integer, AuthUser> authIdAndAuthUserMap = authRepository.selectAllActiveUser().stream()
                                .collect(Collectors.toMap(x -> x.getId(), x -> x));
                model.addAttribute("authIdAndAuthUserMap", authIdAndAuthUserMap);

                return "lead-detail";

        }

        @RequestMapping(value = "/getLeadDetailByLeadId", method = RequestMethod.GET)
        public ResponseEntity<?> getLeadDetailByLeadId(HttpServletRequest request, @RequestParam int leadId, Model model)
                        throws Exception {

                LeadDetail leadDetail = leadDetailRepository.selectByLeadId(leadId);
                return responseSender.ok(leadDetail);

        }

        @RequestMapping(value = "/getTeamCommitment", method = RequestMethod.GET)
        public String getTeamCommitments(HttpServletRequest request, @RequestParam LocalDateTime date, Model model)
                        throws Exception {

                List<TeamCommitmentModel> commitments = partnerCollectionPlanRepository
                                .selectTeamCommitmentByDate(date.toLocalDate());

                model.addAttribute("commitments", commitments);
                return "team-commitment-table";

        }

        @RequestMapping(value = "/partnerHealth", method = RequestMethod.GET)
        public String partnerHealth(HttpServletRequest request,
                        @RequestParam(name = "email", required = false) String email, Model model) throws Exception {
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);

                if (StringUtils.isEmpty(email)) {
                        email = loginDetails.getEmailId();
                } else {
                        AuthUser selectedUser = authRepository.selectByEmailOrMobile(email);

                        model.addAttribute("selectedUser", selectedUser);

                }

                AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());

                Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMapping();
                List<Integer> fofoIds = new ArrayList<>(storeGuyMap.get(email));
                LocalDateTime startDate = LocalDate.now().atStartOfDay();
                if (fofoIds != null && fofoIds.size() > 0) {
                        List<Integer> fofoIdList = fofoStoreRepository.selectByRetailerIds(fofoIds).stream()
                                        .filter(x -> !x.isInternal()).map(x -> x.getId()).collect(Collectors.toList());

                        Map<Integer, PartnerCollectionPlanModel> foundCollectionMap = partnerCollectionService
                                        .getCollectionMap(fofoIdList, startDate);

                        List<Integer> remarkIds = partnerCollectionRemarkRepository.selectMaxRemarkId(fofoIdList);

                        LOGGER.info("remarkIds {}", remarkIds);

                        long todayOverallCall = 0;
                        if (!remarkIds.isEmpty()) {

                                if (authUser.getEmailId().equals(email)) {

                                        todayOverallCall = partnerCollectionRemarkRepository.selectByIds(remarkIds).stream()
                                                        .filter(x -> x.getCreateTimestamp().toLocalDate().equals(LocalDate.now()))
                                                        .collect(Collectors.counting());
                                } else {

                                        todayOverallCall = partnerCollectionRemarkRepository
                                                        .selectByAuthIdAndIds(authRepository.selectByEmailOrMobile(email).getId(), remarkIds)
                                                        .stream().filter(x -> x.getCreateTimestamp().toLocalDate().equals(LocalDate.now()))
                                                        .collect(Collectors.counting());

                                }

                        }
                        ChartLeadModel cm = new ChartLeadModel();

                        if (!foundCollectionMap.isEmpty()) {
                                cm = this.getCollectionCount(foundCollectionMap.values().stream().collect(Collectors.toList()));

                        }
                        model.addAttribute("chartPartnerHealth", gson.toJson(cm));
                        Map<Integer, PartnerDailyInvestment> partnerDailyInvestmentMap = new HashMap<>();

                        List<PartnerDailyInvestment> partnerDailyInvestments = partnerDailyInvestmentRepository
                                        .selectAll(fofoIdList, startDate.toLocalDate().minusDays(1));
                        if (!partnerDailyInvestments.isEmpty()) {
                                partnerDailyInvestmentMap = partnerDailyInvestments.stream()
                                                .collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
                        }

                        Map<LocalDate, Map<Integer, PartnerCollectionPlanModel>> pcpmMap = new TreeMap<>();
                        for (int i = 0; i <= 6; i++) {

                                Map<Integer, PartnerCollectionPlanModel> collectionMap = partnerCollectionService
                                                .getCollectionMap(fofoIdList, startDate.minusDays(i));

                                pcpmMap.put(startDate.minusDays(i).toLocalDate(), collectionMap);
                        }

                        Map<Integer, PartnerCollectionPlanModel> todayPcpmMap = pcpmMap.get(startDate.toLocalDate());
                        model.addAttribute("todayPcpmMap", todayPcpmMap);

                        TotalTargetColectionModel totalTargetCollection = partnerCollectionService
                                        .getTotalTargetCollection(todayPcpmMap, startDate);
                        model.addAttribute("totalPartnerTargetCollection", totalTargetCollection.getTotalTarget());

                        model.addAttribute("totalPartnerAchievement", totalTargetCollection.getTotalAchievement());

                        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();
                        Map<Integer, CustomRetailer> customRetailers = fofoIdList.stream().distinct()
                                        .map(x -> customRetailerMap.get(x)).filter(x -> x != null).collect(Collectors.toList()).stream()
                                        .collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
                        List<Integer> allReportees = authService.getAllReportees(authUser.getId());

                        List<Integer> salesPositionsAuthIds = positionRepository
                                        .selectPositionByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_SALES).stream()
                                        .map(x -> x.getAuthUserId()).collect(Collectors.toList());
                        List<Integer> rbmPositionsAuthIds = positionRepository
                                        .selectPositionByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_RBM).stream()
                                        .map(x -> x.getAuthUserId()).collect(Collectors.toList());

                        salesPositionsAuthIds.addAll(rbmPositionsAuthIds);

                        Set<Integer> empHierarchy = allReportees.stream().filter(x -> salesPositionsAuthIds.contains(x))
                                        .collect(Collectors.toSet());

                        List<AuthUser> authUsers = authRepository.selectAllAuthUserByIds(new ArrayList<>(empHierarchy));

                        Map<Integer, AuthUser> authUserMap = authRepository.selectAll().stream()
                                        .collect(Collectors.toMap(x -> x.getId(), x -> x));

                        LOGGER.info("todayPcpmMap {}", todayPcpmMap);

                        model.addAttribute("authUsers", authUsers);
                        model.addAttribute("authUserMap", authUserMap);
                        model.addAttribute("partnerCollectionPlanMap", pcpmMap);
                        model.addAttribute("partnerDailyInvestmentMap", partnerDailyInvestmentMap);
                        model.addAttribute("customRetailers", customRetailers);
                        model.addAttribute("rankColorMap", ProfitMandiConstants.Rank_Color_Map);
                        model.addAttribute("todayOverallCall", todayOverallCall);

                }
                return "partner-health";

        }

        public ChartLeadModel getCollectionCount(List<PartnerCollectionPlanModel> pcpm)
                        throws ProfitMandiBusinessException {

                Map<Integer, Long> rankCount = pcpm.stream().collect(Collectors.groupingBy(x -> x.getRank(),
                                Collectors.mapping(PartnerCollectionPlanModel::getRank, Collectors.counting())));

                ChartLeadModel cm = new ChartLeadModel();

                List<String> labels = new ArrayList<>();
                labels.add("Plan for Today");
                labels.add("Carry Forward");
                labels.add("Untouched");
                labels.add("Plan for Future");
                labels.add("Normal");

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

                for (String label : labels) {

                        if (label.equals("Plan for Today")) {
                                backgroundColor.add("#007bff");
                                values.add(rankCount.get(1));
                        }
                        if (label.equals("Carry Forward")) {
                                backgroundColor.add("#ffc107");
                                values.add(rankCount.get(2));
                        }
                        if (label.equals("Untouched")) {
                                backgroundColor.add("#dc3545");
                                values.add(rankCount.get(3));
                        }
                        if (label.equals("Plan for Future")) {
                                backgroundColor.add("#6c757d");
                                values.add(rankCount.get(4));
                        }
                        if (label.equals("Normal")) {
                                backgroundColor.add("White");
                                values.add(rankCount.get(5));
                        }

                }

                LOGGER.info("backgroundColor" + backgroundColor);
                LOGGER.info("labelsChartLead" + labels);
                LeadStatusData data = new LeadStatusData();
                data.setData(values);
                data.setBackgroundColor(backgroundColor);
                data.setLabel("DataSet 1");

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

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

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

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

                OptionModel om = new OptionModel();
                om.setLegend(legend);

                cm.setType("pie");
                cm.setData(datasets);
                cm.setOptions(om);

                return cm;
        }

        @RequestMapping(value = "/franchiseVisit", method = RequestMethod.GET)
        public String franchiseVisit(HttpServletRequest request,
                        @RequestParam(name = "email", required = false) String email, Model model) throws Exception {
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);

                AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());

                List<Integer> salesPositionsAuthIds = positionRepository
                                .selectPositionByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_SALES).stream()
                                .map(x -> x.getAuthUserId()).collect(Collectors.toList());
                List<Integer> rbmPositionsAuthIds = positionRepository
                                .selectPositionByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_RBM).stream()
                                .map(x -> x.getAuthUserId()).collect(Collectors.toList());

                salesPositionsAuthIds.addAll(rbmPositionsAuthIds);

                List<Integer> allReportees = authService.getAllReportees(authUser.getId());

                Set<Integer> empHierarchy = allReportees.stream().filter(x -> salesPositionsAuthIds.contains(x))
                                .collect(Collectors.toSet());

                List<AuthUser> authUsers = authRepository.selectAllAuthUserByIds(new ArrayList<>(empHierarchy));

                Map<Integer, String> monthValueMap = new HashMap<>();
                for (int i = 0; i <= 5; i++) {
                        LocalDateTime startOfMonth = LocalDateTime.now().withDayOfMonth(1).minusMonths(i);
                        monthValueMap.put(i, startOfMonth.format(DateTimeFormatter.ofPattern("MMM''uu")));
                }

                model.addAttribute("authUsers", authUsers);
                model.addAttribute("monthValueMap", monthValueMap);

                return "franchise-visit";

        }

        @RequestMapping(value = "/getFranchiseVisit", method = RequestMethod.GET)
        public String getFranchiseVisit(HttpServletRequest request,
                        @RequestParam(name = "authId", required = false) int authId, int yearMonth, Model model) throws Exception {

                LocalDateTime startDate = LocalDate.now().minusMonths(8).withDayOfMonth(1).atStartOfDay();
                LocalDateTime endDate = startDate.plusMonths(1).withDayOfMonth(1).toLocalDate().atStartOfDay();

                DateRangeModel drm = DateRangeModel.of(startDate, endDate);

                List<FranchiseeVisit> visits = franchiseeVisitRepository.selectByAuthUserAndDateRange(drm, authId);

                if (!visits.isEmpty()) {

                        Map<Integer, List<FranchiseeVisit>> franchiseeVisitMap = visits.stream()
                                        .collect(Collectors.groupingBy(x -> x.getScheduleTimestamp().getDayOfMonth()));

                        model.addAttribute("franchiseeVisitMap", franchiseeVisitMap);

                }

                model.addAttribute("visits", visits);
                model.addAttribute("monthLength", startDate.toLocalDate().lengthOfMonth());

                // Calender

                int Year = startDate.getYear(); // year
                int startDayOfMonth = 5;
                int spaces = startDayOfMonth;

                int month = startDate.getMonthValue();

                int[] days = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

                LOGGER.info("visits {} ", visits);

                if ((((Year % 4 == 0) && (Year % 100 != 0)) || (Year % 400 == 0)) && month == 2) {
                        days[month] = 29;
                }

                spaces = (days[month - 1] + spaces) % 7;

                model.addAttribute("month", month);
                model.addAttribute("spaces", spaces);
                model.addAttribute("days", days);

                return "franchise-visit-container";

        }

        @RequestMapping(value = "/getFranchiseeActivity", method = RequestMethod.GET)
        public String getFranchiseeActivity(HttpServletRequest request, int visitId, Model model) throws Exception {

                List<FranchiseeActivity> franchiseeActivities = franchiseeActivityRepository.selectByFranchiseeVisitId(visitId);

                FranchiseeVisit franchiseeVisit = franchiseeVisitRepository.selectById(visitId);

                Map<Integer, AuthUser> authIdAndAuthUserMap = authRepository.selectAll().stream()
                                .collect(Collectors.toMap(x -> x.getId(), x -> x));
                model.addAttribute("authIdAndAuthUserMap", authIdAndAuthUserMap);

                model.addAttribute("franchiseeVisit", franchiseeVisit);
                model.addAttribute("franchiseeActivity", franchiseeActivities.get(0));

                return "franchie-visit-detail";

        }

        @RequestMapping(value = "/indent/today_target", method = RequestMethod.GET)
        public String todayTarget(HttpServletRequest request, Model model) throws Exception {
                List<RBMPerformanceSummaryModel> summaryModels = new ArrayList<>();
                List<Integer> rbmPositionsAuthIds = positionRepository
                                .selectPositionByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_RBM).stream()
                                .filter(x -> Arrays.asList(EscalationType.L1, EscalationType.L2).contains(x.getEscalationType()))
                                .map(x -> x.getAuthUserId()).distinct().collect(Collectors.toList());
                Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMapping();
                List<TeamCommitmentModel> teamCommitmentModels = partnerCollectionPlanRepository
                                .selectTeamCommitmentByDate(LocalDate.now());
                Map<Integer, Double> rbmSecondaryTargetMap = teamCommitmentModels.stream()
                                .filter(x -> rbmPositionsAuthIds.contains(x.getAuthId()))
                                .collect(Collectors.groupingBy(x -> x.getAuthId(),
                                                Collectors.summingDouble(x -> x.getTotalTarget() == null ? 0 : x.getTotalTarget())));
                Map<Integer, Double> rbmSecondaryMap = teamCommitmentModels.stream()
                                .filter(x -> rbmPositionsAuthIds.contains(x.getAuthId()))
                                .collect(Collectors.groupingBy(x -> x.getAuthId(),
                                                Collectors.summingDouble(x -> x.getTotalAchievement() == null ? 0 : x.getTotalAchievement())));
                LocalDateTime startDate = LocalDate.now().atStartOfDay();
                for (int rbmAuthId : rbmPositionsAuthIds) {
                        RBMPerformanceSummaryModel rbmPerformanceSummaryModel = new RBMPerformanceSummaryModel();
                        rbmPerformanceSummaryModel.setAuthId(rbmAuthId);
                        AuthUser authUser = authRepository.selectById(rbmAuthId);
                        rbmPerformanceSummaryModel.setAuthName(authUser.getFullName());
                        List<Integer> fofoIds = new ArrayList<>(storeGuyMap.get(authUser.getEmailId()));

                        if (fofoIds.size() > 0) {
                                fofoIds = fofoStoreRepository.selectByRetailerIds(fofoIds).stream().filter(x -> !x.isInternal())
                                                .map(x -> x.getId()).collect(Collectors.toList());

                                /*
                                 * Map<Integer, PartnerCollectionPlanModel> foundCollectionMap =
                                 * partnerCollectionService .getCollectionMap(fofoIds, startDate);
                                 */

                                List<Integer> remarkIds = partnerCollectionRemarkRepository.selectMaxRemarkId(fofoIds);

                                LOGGER.info("remarkIds {}", remarkIds);

                                long todayOverallCall = 0;
                                if (!remarkIds.isEmpty()) {
                                        todayOverallCall = partnerCollectionRemarkRepository.selectByIds(remarkIds).stream()
                                                        .filter(x -> x.getCreateTimestamp().toLocalDate().equals(LocalDate.now()))
                                                        .collect(Collectors.counting());

                                }

                                Map<Integer, PartnerCollectionPlanModel> collectionMap = partnerCollectionService
                                                .getCollectionMap(fofoIds, startDate);

                                ChartLeadModel cm = this
                                                .getCollectionCount(collectionMap.values().stream().collect(Collectors.toList()));

                                long collectionTarget = collectionMap.values().stream().filter(x -> x.getTargetPlan() != null)
                                                .collect(Collectors.summingLong(x -> x.getTargetPlan()));
                                long collection = collectionMap.values().stream().filter(
                                                x -> x.getTargetPlan() != null && x.getTargetPlan() != 0 && x.getAchievementPlan() != null)
                                                .collect(Collectors.summingLong(x -> x.getAchievementPlan()));
                                rbmPerformanceSummaryModel.setChartLeadModel(cm);
                                rbmPerformanceSummaryModel.setPartnersCommunicated(todayOverallCall);
                                rbmPerformanceSummaryModel.setCollectionTarget(collectionTarget);
                                rbmPerformanceSummaryModel.setCollection(collection);
                                rbmPerformanceSummaryModel.setSecondaryTarget(rbmSecondaryTargetMap.get(rbmAuthId) == null ? 0
                                                : rbmSecondaryTargetMap.get(rbmAuthId).floatValue());
                                rbmPerformanceSummaryModel.setSecondary(
                                                rbmSecondaryMap.get(rbmAuthId) == null ? 0 : rbmSecondaryMap.get(rbmAuthId).floatValue());
                                summaryModels.add(rbmPerformanceSummaryModel);
                                // cm.getData().getDatasets().get(0).getData().;
                                // cm.getData().getDatasets().get(0).getBackgroundColor();
                                // cm.getData().getLabels()

                        }
                }
                model.addAttribute("summaryModels", summaryModels);
                return "today_target";
        }

        @RequestMapping(value = "/visitPlan", method = RequestMethod.GET)
        public String visitPlan(HttpServletRequest request, Model model) throws Exception {

                return "visit-request-plan";
        }

        @RequestMapping(value = "/visit/getVisitPlan", method = RequestMethod.GET)
        public String getVisitPlan(HttpServletRequest request, @RequestParam LocalDate date, Model model) throws Exception {
                List<VisitRequest> visitRequests = visitRequestRepository.selectByAuthIdAndDate(date);

                List<Integer> leadIds = visitRequests.stream().filter(x -> x.getVisitType().equals("lead"))
                                .map(x -> x.getVisitId()).collect(Collectors.toList());
                Map<Integer, Lead> leadMap = new HashMap<>();
                if (!leadIds.isEmpty()) {
                        List<Lead> leads = leadRepository.selectAllByIds(leadIds);

                        for (Lead lead : leads) {
                                List<LeadActivity> leadActivities = leadActivityRepository.selectBYLeadId(lead.getId());
                                lead.setScheduledTimestamp(leadActivities.get(0).getSchelduleTimestamp());
                                lead.setLeadActivity(leadActivities.get(0));

                                leadMap.put(lead.getId(), lead);
                        }

                }
                List<Integer> franchiseeIds = visitRequests.stream().filter(x -> x.getVisitType().equals("franchiseeVisit"))
                                .map(x -> x.getVisitId()).collect(Collectors.toList());
                Map<Integer, FranchiseeVisit> franchiseeVisitsMap = new HashMap<>();
                if (!franchiseeIds.isEmpty()) {
                        List<FranchiseeVisit> franchiseeVisits = franchiseeVisitRepository.selectAllByIds(franchiseeIds);
                        LOGGER.info("franchiseeVisits {}", franchiseeVisits);

                        for (FranchiseeVisit franchiseeVisit : franchiseeVisits) {
                                List<FranchiseeActivity> franchiseeActivities = franchiseeActivityRepository
                                                .selectByFranchiseeVisitId(franchiseeVisit.getId());
                                LOGGER.info("franchiseeActivities {}", franchiseeActivities);

                                franchiseeVisit.setScheduleTimestamp(franchiseeActivities.get(0).getSchelduleTimestamp());
                                franchiseeVisit.setFranchiseeActivity(franchiseeActivities.get(0));

                                franchiseeVisitsMap.put(franchiseeVisit.getId(), franchiseeVisit);
                        }

                }

                Map<Integer, List<VisitRequest>> visitRequestMap = visitRequests.stream()
                                .collect(Collectors.groupingBy(x -> x.getCreatedBy()));
                List<AuthUser> authUsers = authRepository.selectAllActiveUser();
                List<UserVisitModel> userVisits = new ArrayList<>();

                for (AuthUser authUser : authUsers) {

                        List<VisitRequest> authVisitRequests = visitRequestMap.get(authUser.getId());

                        if (authVisitRequests != null) {
                                UserVisitModel userVisitModel = new UserVisitModel();
                                userVisitModel.setAuthUser(authUser.getFullName());
                                List<VisitDescriptionModel> visitDescriptions = new ArrayList<>();

                                for (VisitRequest authVisitRequest : authVisitRequests) {
                                        VisitDescriptionModel visitDescriptionModel = new VisitDescriptionModel();
                                        visitDescriptionModel.setVisitId(authVisitRequest.getVisitId());

                                        if (authVisitRequest.getVisitType().equals("lead")) {
                                                Lead lead = leadMap.get(authVisitRequest.getVisitId());

                                                visitDescriptionModel.setVisitName(lead.getFirstName());
                                                visitDescriptionModel.setCity(lead.getCity());
                                                visitDescriptionModel.setState(lead.getState());
                                                visitDescriptionModel.setScheduleTime(lead.getScheduledTimestamp());
                                                visitDescriptionModel.setRemarks(lead.getLeadActivity().getRemark());

                                        } else {
                                                FranchiseeVisit franchiseeVisit = franchiseeVisitsMap.get(authVisitRequest.getVisitId());
                                                CustomRetailer customRetailer = retailerService.getFofoRetailer(franchiseeVisit.getFofoId());

                                                visitDescriptionModel.setVisitName(franchiseeVisit.getPartnerName());
                                                visitDescriptionModel.setCity(customRetailer.getAddress().getCity());
                                                visitDescriptionModel.setState(customRetailer.getAddress().getState());
                                                visitDescriptionModel
                                                                .setScheduleTime(franchiseeVisit.getFranchiseeActivity().getSchelduleTimestamp());
                                                visitDescriptionModel.setRemarks(franchiseeVisit.getAgenda());

                                        }

                                        if (authVisitRequest.getActionedBy() != 0) {
                                                AuthUser au = authRepository.selectById(authVisitRequest.getActionedBy());

                                                visitDescriptionModel.setActionBy(au.getFullName());
                                        }
                                        visitDescriptionModel.setStatus(authVisitRequest.getStatus());
                                        visitDescriptionModel.setVisitType(authVisitRequest.getVisitType());
                                        visitDescriptions.add(visitDescriptionModel);
                                }

                                userVisitModel.setVisitDescriptions(visitDescriptions);
                                userVisits.add(userVisitModel);
                        }

                }

                model.addAttribute("userVisits", userVisits);

                return "visit-request-plan";
        }
}