Subversion Repositories SmartDukaan

Rev

Rev 37047 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
25979 tejbeer 1
package com.spice.profitmandi.web.controller;
2
 
29266 manish 3
import com.google.gson.Gson;
31370 tejbeer 4
import com.mongodb.DBObject;
25988 tejbeer 5
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
33843 ranu 6
import com.spice.profitmandi.common.model.*;
29426 manish 7
import com.spice.profitmandi.common.util.FileUtil;
34627 aman.kumar 8
import com.spice.profitmandi.common.util.FormattingUtils;
31370 tejbeer 9
import com.spice.profitmandi.common.web.util.ResponseSender;
25979 tejbeer 10
import com.spice.profitmandi.dao.entity.auth.AuthUser;
32464 tejbeer 11
import com.spice.profitmandi.dao.entity.catalog.BrandCatalog;
30416 tejbeer 12
import com.spice.profitmandi.dao.entity.fofo.PartnerDailyInvestment;
33843 ranu 13
import com.spice.profitmandi.dao.entity.user.*;
30773 amit.gupta 14
import com.spice.profitmandi.dao.enumuration.cs.EscalationType;
31249 tejbeer 15
import com.spice.profitmandi.dao.enumuration.dtr.CommunicationType;
29598 tejbeer 16
import com.spice.profitmandi.dao.enumuration.dtr.LeadSource;
25979 tejbeer 17
import com.spice.profitmandi.dao.enumuration.dtr.LeadStatus;
33843 ranu 18
import com.spice.profitmandi.dao.model.*;
25979 tejbeer 19
import com.spice.profitmandi.dao.repository.auth.AuthRepository;
30185 tejbeer 20
import com.spice.profitmandi.dao.repository.auth.PartnerCollectionPlanRepository;
30434 tejbeer 21
import com.spice.profitmandi.dao.repository.auth.PartnerCollectionRemarkRepository;
30416 tejbeer 22
import com.spice.profitmandi.dao.repository.cs.CsService;
29266 manish 23
import com.spice.profitmandi.dao.repository.cs.PositionRepository;
33843 ranu 24
import com.spice.profitmandi.dao.repository.dtr.*;
30416 tejbeer 25
import com.spice.profitmandi.dao.repository.fofo.PartnerDailyInvestmentRepository;
35223 ranu 26
import com.spice.profitmandi.dao.repository.fofo.RbmRatingRepository;
25979 tejbeer 27
import com.spice.profitmandi.dao.repository.inventory.StateRepository;
30445 tejbeer 28
import com.spice.profitmandi.dao.repository.transaction.UserWalletRepository;
29266 manish 29
import com.spice.profitmandi.service.AuthService;
30416 tejbeer 30
import com.spice.profitmandi.service.PartnerCollectionService;
33917 ranu 31
import com.spice.profitmandi.service.RbmTargetService;
32464 tejbeer 32
import com.spice.profitmandi.service.catalog.BrandsService;
34650 aman.kumar 33
import com.spice.profitmandi.service.order.OrderService;
30416 tejbeer 34
import com.spice.profitmandi.service.user.RetailerService;
25979 tejbeer 35
import com.spice.profitmandi.web.model.LoginDetails;
36
import com.spice.profitmandi.web.util.CookiesProcessor;
37
import com.spice.profitmandi.web.util.MVCResponseSender;
35548 aman 38
import org.apache.commons.csv.CSVFormat;
39
import org.apache.commons.csv.CSVParser;
33843 ranu 40
import org.apache.commons.csv.CSVRecord;
34707 aman.kumar 41
import org.apache.commons.io.output.ByteArrayOutputStream;
33843 ranu 42
import org.apache.logging.log4j.LogManager;
43
import org.apache.logging.log4j.Logger;
44
import org.springframework.beans.factory.annotation.Autowired;
37035 aman 45
import org.springframework.beans.factory.annotation.Value;
33843 ranu 46
import org.springframework.core.io.InputStreamResource;
47
import org.springframework.http.HttpHeaders;
48
import org.springframework.http.HttpStatus;
49
import org.springframework.http.MediaType;
50
import org.springframework.http.ResponseEntity;
51
import org.springframework.stereotype.Controller;
35507 ranu 52
import org.springframework.transaction.annotation.Transactional;
33843 ranu 53
import org.springframework.ui.Model;
54
import org.springframework.util.StringUtils;
55
import org.springframework.web.bind.annotation.*;
56
import org.springframework.web.multipart.MultipartFile;
25979 tejbeer 57
 
33843 ranu 58
import javax.servlet.http.HttpServletRequest;
59
import javax.servlet.http.HttpServletResponse;
60
import java.io.ByteArrayInputStream;
61
import java.io.InputStream;
35548 aman 62
import java.io.InputStreamReader;
63
import java.io.Reader;
35223 ranu 64
import java.text.DecimalFormat;
36101 ranu 65
import java.time.DayOfWeek;
33843 ranu 66
import java.time.LocalDate;
67
import java.time.LocalDateTime;
36101 ranu 68
import java.time.LocalTime;
33843 ranu 69
import java.time.format.DateTimeFormatter;
36101 ranu 70
import java.time.temporal.TemporalAdjusters;
33843 ranu 71
import java.util.*;
72
import java.util.Map.Entry;
73
import java.util.stream.Collectors;
74
 
25979 tejbeer 75
@Controller
35458 amit 76
@Transactional(rollbackFor = Throwable.class)
25979 tejbeer 77
public class LeadController {
32464 tejbeer 78
    private static final Logger LOGGER = LogManager.getLogger(LeadController.class);
25979 tejbeer 79
 
37035 aman 80
    /** Source / createdBy label for leads captured by the AI assistant (chat + voice). */
81
    private static final String AI_LEAD_SOURCE = "AI Assistant";
82
 
37036 aman 83
    // AI leads are auto-assigned round-robin (one by one) between these two auth users (was hardcoded 53 / Shankar Mushran).
84
    private static final int AI_ASSIGN_KHUSHBU = 134;  // Khushbu Saxena (khushbu@smartdukaan.com)
85
    private static final int AI_ASSIGN_ARCHANA = 126;  // Archana Ramola (archana@smartdukaan.com)
86
    private final java.util.concurrent.atomic.AtomicInteger aiAssignToggle = new java.util.concurrent.atomic.AtomicInteger(0);
87
 
37035 aman 88
    @Value("${ai.lead.intake.token:}")
89
    private String aiLeadIntakeToken;
90
 
91
    /**
92
     * AI-assistant lead intake, hosted in the fofo app so it deploys via {@code fofo_deploy}. Mirrors the
93
     * profitmandi-web /add/lead contract: shared-secret {@code Auth-Token}, source stamped server-side,
94
     * idempotent by mobile+source, NOT NULL columns coalesced (so a minimal name+number lead never
95
     * crashes), stores {@code state} + {@code recordingUrl}, status = pending (Open/New). This path is
96
     * excluded from fofo's authentication/role/post interceptors in WebConfig.
97
     */
98
    @RequestMapping(value = ProfitMandiConstants.URL_AI_LEAD_INTAKE, method = RequestMethod.POST)
99
    @ResponseBody
100
    public ResponseEntity<?> aiLead(HttpServletRequest request,
101
                                    @RequestHeader(name = "Auth-Token", required = false) String authToken,
102
                                    @RequestBody AiLeadRequest aiLeadRequest) {
103
        LOGGER.info("AI lead intake request: {}", aiLeadRequest);
104
 
105
        if (aiLeadIntakeToken == null || aiLeadIntakeToken.trim().isEmpty()
106
                || authToken == null || !aiLeadIntakeToken.equals(authToken)) {
107
            LOGGER.warn("AI lead intake rejected: invalid or missing Auth-Token");
108
            return aiLeadResponse(HttpStatus.UNAUTHORIZED, "401", "UNAUTHORIZED", "FAILURE", null);
109
        }
110
 
111
        String rawMobile = aiLeadRequest.getMobile();
112
        String mobile = rawMobile == null ? "" : rawMobile.replaceAll("\\D", "");
113
        if (mobile.length() > 10) {
114
            mobile = mobile.substring(mobile.length() - 10);
115
        }
116
        if (mobile.length() != 10) {
117
            return aiLeadResponse(HttpStatus.BAD_REQUEST, "400", "Mobile number must contain 10 digits", "FAILURE", null);
118
        }
119
 
120
        String firstName = aiLeadRequest.getFirstName();
121
        if (firstName == null || firstName.trim().isEmpty()) {
122
            return aiLeadResponse(HttpStatus.BAD_REQUEST, "400", "First name is required", "FAILURE", null);
123
        }
124
 
125
        // Idempotency scoped to AI leads only (the AI side retries fire-and-forget posts).
126
        Lead existing = leadRepository.selectByMobileNumberAndSource(mobile, AI_LEAD_SOURCE);
127
        if (existing != null) {
128
            LOGGER.info("AI lead intake: AI lead already exists for mobile {} (id={}), skipping create", mobile, existing.getId());
129
            return aiLeadResponse(HttpStatus.OK, "200", "OK", "SUCCESS", existing.getId());
130
        }
131
 
132
        Lead lead = new Lead();
133
        lead.setLeadMobile(mobile);
134
        lead.setFirstName(firstName.trim());
135
        // last_name / city / address / state are NOT NULL in user.lead; coalesce nulls to "" so a minimal lead never crashes.
136
        lead.setLastName(aiLeadRequest.getLastName() == null ? "" : aiLeadRequest.getLastName().trim());
137
        String city = aiLeadRequest.getCity() == null ? "" : aiLeadRequest.getCity().trim();
138
        lead.setCity(city);
139
        lead.setOutLetName(aiLeadRequest.getOutletName());
140
        // AI does not collect a separate address; mirror web capture and fall back to city.
141
        lead.setAddress(city);
142
        String state = aiLeadRequest.getState();
143
        lead.setState(state == null ? "" : state.trim());
144
 
145
        // Source stamped server-side; caller cannot override it.
146
        lead.setSource(AI_LEAD_SOURCE);
147
        lead.setCreatedBy(AI_LEAD_SOURCE);
148
        lead.setStatus(LeadStatus.pending);
149
        lead.setColor("yellow");
150
 
151
        // Optional call-recording URL (voice leads only); store null when absent.
152
        String recordingUrl = aiLeadRequest.getRecordingUrl();
153
        if (recordingUrl != null && !recordingUrl.trim().isEmpty()) {
154
            lead.setRecordingUrl(recordingUrl.trim());
155
        }
156
 
37036 aman 157
        // Round-robin between Khushbu and Archana, one lead at a time (toggle only advances on a real create, not dedup hits).
158
        int assignTo = (aiAssignToggle.getAndIncrement() % 2 == 0) ? AI_ASSIGN_KHUSHBU : AI_ASSIGN_ARCHANA;
159
        lead.setAssignTo(assignTo);
37035 aman 160
        lead.setAuthId(lead.getAssignTo());
161
        lead.setCreatedTimestamp(LocalDateTime.now());
162
        lead.setUpdatedTimestamp(LocalDateTime.now());
163
        leadRepository.persist(lead);
164
 
37036 aman 165
        LOGGER.info("AI lead intake: created lead id={} for mobile {}, assigned to authId={}", lead.getId(), mobile, assignTo);
37035 aman 166
        return aiLeadResponse(HttpStatus.OK, "200", "OK", "SUCCESS", lead.getId());
167
    }
168
 
169
    private ResponseEntity<Map<String, Object>> aiLeadResponse(HttpStatus status, String statusCode,
170
                                                               String statusMessage, String responseStatus, Object response) {
171
        Map<String, Object> body = new HashMap<>();
172
        body.put("statusCode", statusCode);
173
        body.put("statusMessage", statusMessage);
174
        body.put("response", response);
175
        body.put("responseStatus", responseStatus);
176
        return ResponseEntity.status(status).body(body);
177
    }
178
 
32464 tejbeer 179
    @Autowired
180
    private LeadRepository leadRepository;
25979 tejbeer 181
 
32464 tejbeer 182
    @Autowired
183
    private LeadActivityRepository leadActivityRepository;
25979 tejbeer 184
 
32464 tejbeer 185
    @Autowired
36787 ranu 186
    private com.spice.profitmandi.dao.repository.dtr.LeadVisitRequestRepository leadVisitRequestRepository;
187
 
188
    @Autowired
32464 tejbeer 189
    private StateRepository stateRepository;
25979 tejbeer 190
 
32464 tejbeer 191
    @Autowired
192
    private AuthService authService;
29266 manish 193
 
32464 tejbeer 194
    @Autowired
195
    private AuthRepository authRepository;
25979 tejbeer 196
 
32464 tejbeer 197
    @Autowired
198
    private Gson gson;
29266 manish 199
 
32464 tejbeer 200
    @Autowired
201
    private CookiesProcessor cookiesProcessor;
29426 manish 202
 
32464 tejbeer 203
    @Autowired
204
    PositionRepository positionRepository;
25979 tejbeer 205
 
32464 tejbeer 206
    @Autowired
207
    private MVCResponseSender mvcResponseSender;
25979 tejbeer 208
 
32464 tejbeer 209
    @Autowired
210
    private PartnerCollectionPlanRepository partnerCollectionPlanRepository;
30185 tejbeer 211
 
32464 tejbeer 212
    @Autowired
213
    private CsService csService;
30416 tejbeer 214
 
32464 tejbeer 215
    @Autowired
216
    private FofoStoreRepository fofoStoreRepository;
30416 tejbeer 217
 
32464 tejbeer 218
    @Autowired
219
    private PartnerCollectionService partnerCollectionService;
30416 tejbeer 220
 
32464 tejbeer 221
    @Autowired
222
    private RetailerService retailerService;
30416 tejbeer 223
 
32464 tejbeer 224
    @Autowired
225
    private PartnerCollectionRemarkRepository partnerCollectionRemarkRepository;
30434 tejbeer 226
 
32464 tejbeer 227
    @Autowired
228
    private PartnerDailyInvestmentRepository partnerDailyInvestmentRepository;
30445 tejbeer 229
 
32464 tejbeer 230
    @Autowired
231
    private UserWalletRepository userWalletRepository;
30445 tejbeer 232
 
32464 tejbeer 233
    @Autowired
234
    private FranchiseeVisitRepository franchiseeVisitRepository;
30522 tejbeer 235
 
32464 tejbeer 236
    @Autowired
237
    private FranchiseeActivityRepository franchiseeActivityRepository;
30522 tejbeer 238
 
32464 tejbeer 239
    @Autowired
240
    private VisitRequestRepository visitRequestRepository;
31249 tejbeer 241
 
32464 tejbeer 242
    @Autowired
243
    private LeadBrandRepository leadBrandRepository;
31370 tejbeer 244
 
32464 tejbeer 245
    @Autowired
246
    private LeadDetailRepository leadDetailRepository;
31370 tejbeer 247
 
32464 tejbeer 248
    @Autowired
36642 ranu 249
    private LeadLiveLocationRepository leadLiveLocationRepository;
250
 
251
    @Autowired
36644 ranu 252
    private BeatRouteRepository beatRouteRepository;
36642 ranu 253
 
254
    @Autowired
36644 ranu 255
    private LeadRouteRepository leadRouteRepository;
256
 
257
    @Autowired
258
    private BeatRepository beatRepository;
259
 
260
    @Autowired
36818 ranu 261
    private org.springframework.mail.javamail.JavaMailSender gmailRelaySender;
262
 
263
    @Autowired
32464 tejbeer 264
    private Mongo mongoClient;
31370 tejbeer 265
 
32464 tejbeer 266
    @Autowired
267
    private ResponseSender<?> responseSender;
31370 tejbeer 268
 
32464 tejbeer 269
    @Autowired
270
    private BrandsService brandsService;
34650 aman.kumar 271
    @Autowired
272
    OrderService orderService;
25988 tejbeer 273
 
35223 ranu 274
 
275
    @Autowired
276
    private RbmRatingRepository rbmRatingRepository;
277
 
32464 tejbeer 278
    List<LeadStatus> status = Arrays.asList(LeadStatus.notInterested, LeadStatus.finalized);
27609 tejbeer 279
 
32464 tejbeer 280
    @RequestMapping(value = "/getOpenLead", method = RequestMethod.GET)
35769 amit 281
    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 = "startDate", required = false) LocalDate startDate, @RequestParam(name = "endDate", required = false) LocalDate endDate, Model model) throws Exception {
29445 manish 282
 
29426 manish 283
 
35769 amit 284
        LocalDateTime startDateTime = startDate != null ? startDate.atStartOfDay() : null;
285
        LocalDateTime endDateTime = endDate != null ? endDate.atTime(23, 59, 59) : null;
286
        LOGGER.info("startDateTime: " + startDateTime + ", endDateTime: " + endDateTime);
287
 
32464 tejbeer 288
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
289
        String emailId = loginDetails.getEmailId();
290
        AuthUser authUser = authRepository.selectByEmailOrMobile(emailId);
29426 manish 291
 
34890 aman 292
        boolean isPositionSales = positionRepository.hasCategory(authUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_SALES);
27610 tejbeer 293
 
32464 tejbeer 294
        if (leadStatus.contains(LeadStatus.All)) {
27615 tejbeer 295
 
32464 tejbeer 296
            leadStatus.add(LeadStatus.pending);
297
            leadStatus.add(LeadStatus.notInterested);
298
            leadStatus.add(LeadStatus.finalized);
299
        }
29744 tejbeer 300
 
32464 tejbeer 301
        if (color.contains("All")) {
302
            color.add("yellow");
303
            color.add("green");
304
        }
29445 manish 305
 
32464 tejbeer 306
        List<Lead> leads = new ArrayList<>();
29445 manish 307
 
32464 tejbeer 308
        model.addAttribute("colors", color);
29744 tejbeer 309
 
32464 tejbeer 310
        Map<Integer, List<LeadActivity>> leadActivityMap = new HashMap<>();
29445 manish 311
 
32464 tejbeer 312
        List<Integer> authUserIds = null;
29445 manish 313
 
32464 tejbeer 314
        LOGGER.info("color111" + color);
315
        List<Lead> leadFollowUp = new ArrayList<>();
34890 aman 316
        if (isPositionSales) {
32464 tejbeer 317
            authUserIds = authService.getAllReportees(authUser.getId());
318
            authUserIds.add(authUser.getId());
319
            LOGGER.info("authIds" + authUserIds);
29753 tejbeer 320
 
32464 tejbeer 321
            LOGGER.info("leadStatus" + leadStatus);
29445 manish 322
 
35769 amit 323
            if (startDateTime == null) {
29445 manish 324
 
32464 tejbeer 325
                if (!leadStatus.contains(LeadStatus.followUp)) {
29852 tejbeer 326
 
32464 tejbeer 327
                    leads = leadRepository.selectAllByColorStatusAndUpdatedTimestampAndAuthIds(leadStatus, authUserIds, color, LocalDateTime.now().minusMonths(1));
328
                }
29852 tejbeer 329
 
32464 tejbeer 330
                if (leadStatus.contains(LeadStatus.followUp) || leadStatus.contains(LeadStatus.All)) {
331
                    leadFollowUp = leadRepository.selectByAssignAuthIdsAndStatus(authUserIds, LeadStatus.followUp);
332
                    leads.addAll(leadFollowUp);
333
                }
29445 manish 334
 
32464 tejbeer 335
            } else {
29852 tejbeer 336
 
32464 tejbeer 337
                if (!leadStatus.contains(LeadStatus.followUp)) {
35769 amit 338
                    leads = leadRepository.selectAllByColorStatusAndBetweenCreatedDateAndAuthIds(leadStatus, authUserIds, color, startDateTime, endDateTime);
32464 tejbeer 339
                }
29852 tejbeer 340
 
32464 tejbeer 341
                if (leadStatus.contains(LeadStatus.followUp) || leadStatus.contains(LeadStatus.All)) {
30290 tejbeer 342
 
32464 tejbeer 343
                    leadFollowUp = leadRepository.selectByAssignAuthIdsAndStatus(authUserIds, LeadStatus.followUp);
29852 tejbeer 344
 
32464 tejbeer 345
                    leads.addAll(leadFollowUp);
29852 tejbeer 346
 
32464 tejbeer 347
                }
29445 manish 348
 
32464 tejbeer 349
            }
29445 manish 350
 
32464 tejbeer 351
        } else {
29445 manish 352
 
35769 amit 353
            if (startDateTime == null) {
32464 tejbeer 354
                if (!leadStatus.contains(LeadStatus.followUp)) {
29852 tejbeer 355
 
32464 tejbeer 356
                    leads = leadRepository.selectAllByColorStatusAndUpdatedTimestamp(leadStatus, color, LocalDateTime.now().minusMonths(1));
357
                }
358
                if (leadStatus.contains(LeadStatus.followUp) || leadStatus.contains(LeadStatus.All)) {
30290 tejbeer 359
 
32464 tejbeer 360
                    leadFollowUp = leadRepository.selectAllByStatus(LeadStatus.followUp);
29445 manish 361
 
32464 tejbeer 362
                    leads.addAll(leadFollowUp);
363
                }
364
                LOGGER.info("leadlocalDateTime1" + leads);
29445 manish 365
 
32464 tejbeer 366
            } else {
367
                if (!leadStatus.contains(LeadStatus.followUp)) {
35769 amit 368
                    leads = leadRepository.selectAllByColorStatusAndBetweenCreatedDate(leadStatus, color, startDateTime, endDateTime);
32464 tejbeer 369
                }
29852 tejbeer 370
 
34890 aman 371
                if (leadStatus.contains(LeadStatus.followUp)) {
30290 tejbeer 372
 
32464 tejbeer 373
                    leadFollowUp = leadRepository.selectAllByStatus(LeadStatus.followUp);
29445 manish 374
 
32464 tejbeer 375
                    leads.addAll(leadFollowUp);
376
                }
377
                LOGGER.info("leadlocalDateTime2" + leads);
29426 manish 378
 
32464 tejbeer 379
            }
29445 manish 380
 
32464 tejbeer 381
        }
27642 tejbeer 382
 
34890 aman 383
        if (isPositionSales && authUserIds.size() > 0) {
32464 tejbeer 384
            List<String> leadCreators = new ArrayList<>();
385
            leadCreators.add("daily-sync");
34032 amit.gupta 386
            leadCreators.addAll(csService.getAuthUserIds(ProfitMandiConstants.TICKET_CATEGORY_SALES, Arrays.asList(EscalationType.L1, EscalationType.L2)).stream().map(x -> x.getFullName()).collect(Collectors.toList()));
387
            leadCreators.addAll(csService.getAuthUserIds(ProfitMandiConstants.TICKET_CATEGORY_BGC, Arrays.asList(EscalationType.L1, EscalationType.L2, EscalationType.L3)).stream().map(x -> x.getFullName()).collect(Collectors.toList()));
32464 tejbeer 388
            model.addAttribute("leadCreators", leadCreators);
389
        }
390
        List<Lead> weekLast = new ArrayList<>();
391
        List<Lead> weekThird = new ArrayList<>();
392
        List<Lead> weekSecond = new ArrayList<>();
393
        List<Lead> weekFirst = new ArrayList<>();
394
        LocalDateTime curDate = LocalDate.now().atStartOfDay();
395
        List<LeadWeakWiseModel> lwDays = new ArrayList<>();
29266 manish 396
 
32464 tejbeer 397
        for (int i = 7; i >= 1; i--) {
398
            LocalDateTime startOfDay = curDate.minusDays(i);
29266 manish 399
 
32464 tejbeer 400
            LeadWeakWiseModel lm = new LeadWeakWiseModel();
401
            lm.setMonth(startOfDay.toLocalDate());
402
            lwDays.add(lm);
403
        }
404
        if (!leads.isEmpty()) {
29266 manish 405
 
32464 tejbeer 406
            weekLast.addAll(
407
                    leads.stream().filter(x -> x.getCreatedTimestamp().isAfter(curDate.minusDays(28)) && x.getCreatedTimestamp().isBefore(curDate.minusDays(21))).collect(Collectors.toList()));
29266 manish 408
 
32464 tejbeer 409
            weekThird.addAll(leads.stream().filter(x -> x.getCreatedTimestamp().isAfter(curDate.minusDays(21)) && x.getCreatedTimestamp().isBefore(curDate.minusDays(14))).collect(Collectors.toList()));
29426 manish 410
 
32464 tejbeer 411
            weekSecond.addAll(leads.stream().filter(x -> x.getCreatedTimestamp().isAfter(curDate.minusDays(14)) && x.getCreatedTimestamp().isBefore(curDate.minusDays(7))).collect(Collectors.toList()));
29744 tejbeer 412
 
32464 tejbeer 413
            weekFirst.addAll(leads.stream().filter(x -> x.getCreatedTimestamp().isAfter(curDate.minusDays(7))).collect(Collectors.toList()));
29266 manish 414
 
32464 tejbeer 415
        }
416
        LOGGER.info("weekLast" + weekLast);
417
        LOGGER.info("weekThird" + weekThird);
418
        LOGGER.info("weekSecond" + weekSecond);
419
        Map<String, Long> leadLasts = weekLast.stream().collect(Collectors.groupingBy(x -> x.getCreatedBy(), Collectors.counting()));
420
        Map<String, Long> leadThirds = weekThird.stream().collect(Collectors.groupingBy(x -> x.getCreatedBy(), Collectors.counting()));
421
        Map<String, Long> leadSeconds = weekSecond.stream().collect(Collectors.groupingBy(x -> x.getCreatedBy(), Collectors.mapping(Lead::getCreatedBy, Collectors.counting())));
29266 manish 422
 
32464 tejbeer 423
        Map<String, Map<LocalDate, Long>> leadFirsts = weekFirst.stream().collect(Collectors.groupingBy(x -> x.getCreatedBy(), Collectors.groupingBy(x -> x.getCreatedTimestamp().toLocalDate(), Collectors.counting())));
29266 manish 424
 
32464 tejbeer 425
        LOGGER.info("leadFirsts" + leadFirsts);
25979 tejbeer 426
 
32464 tejbeer 427
        List<Integer> authIds = new ArrayList<>();
428
        if (!leads.isEmpty()) {
27610 tejbeer 429
 
32464 tejbeer 430
            authIds.addAll(leads.stream().map(x -> x.getAssignTo()).collect(Collectors.toList()));
29744 tejbeer 431
 
32464 tejbeer 432
            leadActivityMap = leadActivityRepository.selectAllByleadIds(leads.stream().map(x -> x.getId()).collect(Collectors.toList())).stream().collect(Collectors.groupingBy(LeadActivity::getLeadId, Collectors.toList()));
27723 tejbeer 433
 
35395 amit 434
            Map<Integer, AuthUser> authIdAndAuthUserMap = authRepository.selectByIds(authIds).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
32464 tejbeer 435
            model.addAttribute("leadActivityMap", leadActivityMap);
436
            model.addAttribute("authIdAndAuthUserMap", authIdAndAuthUserMap);
36787 ranu 437
 
438
            // Pending visit requests per lead — drives the "Visit request pending"
439
            // badge on the row template. Best-effort: never blocks the list render.
440
            try {
441
                List<Integer> leadIds = leads.stream().map(Lead::getId).collect(Collectors.toList());
442
                List<com.spice.profitmandi.dao.entity.user.LeadVisitRequest> pending =
443
                        leadVisitRequestRepository.selectByLeadIdsAndStatus(leadIds, "PENDING");
444
                Set<Integer> pendingSet = pending.stream()
445
                        .map(com.spice.profitmandi.dao.entity.user.LeadVisitRequest::getLeadId)
446
                        .collect(Collectors.toSet());
447
                model.addAttribute("pendingVisitRequestLeadIds", pendingSet);
448
            } catch (Exception e) {
449
                LOGGER.warn("pending visit-request lookup failed: {}", e.getMessage());
450
                model.addAttribute("pendingVisitRequestLeadIds", new HashSet<Integer>());
451
            }
32464 tejbeer 452
        }
29266 manish 453
 
32464 tejbeer 454
        ChartLeadModel cm = this.getLeadChart(leads);
455
        model.addAttribute("chartLead", gson.toJson(cm));
29266 manish 456
 
32464 tejbeer 457
        LOGGER.info("ChartLeadModel" + gson.toJson(cm));
458
        LOGGER.info("lwDays" + lwDays);
29426 manish 459
 
32464 tejbeer 460
        LOGGER.info("leads" + leads);
461
        List<String> stateNames = stateRepository.selectAll().stream().map(x -> x.getName()).collect(Collectors.toList());
34127 tejus.loha 462
//        List<AuthUser> authUsers = authRepository.selectAllActiveUser();
35098 ranu 463
        List<AuthUser> authUsers = new ArrayList<>();
464
        List<AuthUser> salesUsers = csService.getAuthUserIds(ProfitMandiConstants.TICKET_CATEGORY_SALES, Arrays.asList(EscalationType.L1, EscalationType.L2, EscalationType.L3));
465
        List<AuthUser> abmUsers = csService.getAuthUserIds(ProfitMandiConstants.TICKET_CATEGORY_ABM, Arrays.asList(EscalationType.L1, EscalationType.L2, EscalationType.L3));
35252 aman 466
        List<AuthUser> bgcUsers = csService.getAuthUserIds(ProfitMandiConstants.TICKET_CATEGORY_BGC, Arrays.asList(EscalationType.L1, EscalationType.L2, EscalationType.L3));
35098 ranu 467
        authUsers.addAll(salesUsers);
468
        authUsers.addAll(abmUsers);
35252 aman 469
        authUsers.addAll(bgcUsers);
32464 tejbeer 470
        LocalDate lastDate = curDate.minusDays(1).toLocalDate();
29426 manish 471
 
32464 tejbeer 472
        List<LocalDate> weekDates = new ArrayList<>();
29426 manish 473
 
32464 tejbeer 474
        weekDates.add(curDate.minusDays(28).toLocalDate());
475
        weekDates.add(curDate.minusDays(22).toLocalDate());
476
        weekDates.add(curDate.minusDays(21).toLocalDate());
477
        weekDates.add(curDate.minusDays(15).toLocalDate());
478
        weekDates.add(curDate.minusDays(14).toLocalDate());
479
        weekDates.add(curDate.minusDays(8).toLocalDate());
480
        weekDates.add(curDate.minusDays(7).toLocalDate());
481
        LOGGER.info("lastDate" + lastDate);
29426 manish 482
 
32464 tejbeer 483
        model.addAttribute("weekDates", weekDates);
31249 tejbeer 484
 
35769 amit 485
        model.addAttribute("startDate", startDate);
486
        model.addAttribute("endDate", endDate);
32464 tejbeer 487
        model.addAttribute("lastDate", lastDate);
488
        model.addAttribute("stateNames", stateNames);
31249 tejbeer 489
 
32464 tejbeer 490
        model.addAttribute("communicationTypes", CommunicationType.values());
25979 tejbeer 491
 
32464 tejbeer 492
        model.addAttribute("authUsers", authUsers);
33223 amit.gupta 493
        model.addAttribute("leads", leads);
32464 tejbeer 494
        model.addAttribute("leadStatus", LeadStatus.values());
495
        model.addAttribute("leadLasts", leadLasts);
496
        model.addAttribute("leadThirds", leadThirds);
497
        model.addAttribute("leadSeconds", leadSeconds);
498
        model.addAttribute("leadFirsts", leadFirsts);
499
        model.addAttribute("lwDays", lwDays);
31370 tejbeer 500
 
32464 tejbeer 501
        model.addAttribute("selectedLeadStatus", leadStatus.get(0));
31370 tejbeer 502
 
35548 aman 503
        boolean showBulkUploader =
504
                "sm@smartdukaan.com".equalsIgnoreCase(emailId);
31370 tejbeer 505
 
35548 aman 506
        model.addAttribute("showBulkUploader", showBulkUploader);
507
 
32464 tejbeer 508
        List<BrandCatalog> brandsDisplays = brandsService.getBrandsToDisplay(3);
509
        brandsDisplays.addAll(brandsService.getBrandsToDisplay(6));
510
        model.addAttribute("brandsDisplays", brandsDisplays.stream().distinct().collect(Collectors.toList()));
31370 tejbeer 511
 
32464 tejbeer 512
        LOGGER.info("brandsDisplays" + brandsDisplays);
27642 tejbeer 513
 
36642 ranu 514
        // Geo location status map for all leads
515
        if (!leads.isEmpty()) {
516
            List<Integer> allLeadIds = leads.stream().map(Lead::getId).collect(Collectors.toList());
517
            Map<Integer, LeadLiveLocation> geoLocationMap = leadLiveLocationRepository.selectByLeadIds(allLeadIds).stream()
518
                    .collect(Collectors.toMap(LeadLiveLocation::getLeadId, x -> x, (a, b) -> a));
519
            model.addAttribute("geoLocationMap", geoLocationMap);
520
        } else {
521
            model.addAttribute("geoLocationMap", new HashMap<>());
522
        }
523
        model.addAttribute("salesUsers", salesUsers);
524
        model.addAttribute("bgcUsers", bgcUsers);
25979 tejbeer 525
 
32464 tejbeer 526
        return "lead";
29266 manish 527
 
32464 tejbeer 528
    }
29266 manish 529
 
32464 tejbeer 530
    public ChartLeadModel getLeadChart(List<Lead> leads) throws ProfitMandiBusinessException {
29426 manish 531
 
32464 tejbeer 532
        Map<LeadStatus, Long> leadStatusMap = leads.stream().collect(
533
                Collectors.groupingBy(x -> x.getStatus(), Collectors.mapping(Lead::getStatus, Collectors.counting())));
29266 manish 534
 
32464 tejbeer 535
        Map<String, Long> hotLeadsMap = leads.stream().collect(
536
                Collectors.groupingBy(x -> x.getColor(), Collectors.mapping(Lead::getColor, Collectors.counting())));
29445 manish 537
 
32464 tejbeer 538
        LOGGER.info("hotLeadsMap" + hotLeadsMap);
539
        ChartLeadModel cm = new ChartLeadModel();
29445 manish 540
 
32464 tejbeer 541
        HashSet<LeadStatus> labels = new HashSet<LeadStatus>();
542
        labels.addAll(leadStatusMap.keySet());
29445 manish 543
 
32464 tejbeer 544
        List<String> hotLeads = new ArrayList<>();
545
        hotLeads.addAll(leadStatusMap.keySet().stream().map(x -> x.toString()).collect(Collectors.toSet()));
546
        hotLeads.add("HotLead");
29598 tejbeer 547
 
32464 tejbeer 548
        List<String> hotLeadKeys = new ArrayList<>();
29445 manish 549
 
32464 tejbeer 550
        hotLeadKeys.add("HotLead");
551
        List<String> hotLeadGreen = new ArrayList<>(hotLeadKeys);
29266 manish 552
 
32464 tejbeer 553
        LOGGER.info("hotLeads" + hotLeads);
29266 manish 554
 
32464 tejbeer 555
        List<LeadStatus> labelList = new ArrayList<>(labels);
556
        List<String> backgroundColor = new ArrayList<>();
557
        LOGGER.info("hotLeadKeys" + hotLeadKeys);
558
        List<Long> values = new ArrayList<>();
29598 tejbeer 559
 
32464 tejbeer 560
        for (String hotLead : hotLeads) {
29445 manish 561
 
32464 tejbeer 562
            if (hotLead.equals("pending")) {
563
                backgroundColor.add("pink");
564
                values.add(leadStatusMap.get(LeadStatus.pending));
565
            }
566
            if (hotLead.equals("notInterested")) {
567
                backgroundColor.add("red");
568
                values.add(leadStatusMap.get(LeadStatus.notInterested));
569
            }
570
            if (hotLead.equals("followUp")) {
571
                backgroundColor.add("#9ACD32");
572
                values.add(leadStatusMap.get(LeadStatus.followUp));
573
            }
574
            if (hotLead.equals("finalized")) {
575
                backgroundColor.add("blue");
576
                values.add(leadStatusMap.get(LeadStatus.finalized));
577
            }
29445 manish 578
 
32464 tejbeer 579
            if (hotLead.equals("HotLead")) {
580
                backgroundColor.add("green");
581
                values.add(hotLeadsMap.get("Green"));
29266 manish 582
 
32464 tejbeer 583
            }
29266 manish 584
 
32464 tejbeer 585
        }
586
        LOGGER.info("labelList" + labelList);
29266 manish 587
 
32464 tejbeer 588
        LOGGER.info("backgroundColor" + backgroundColor);
589
        LOGGER.info("labelsChartLead" + labels);
590
        LeadStatusData data = new LeadStatusData();
591
        data.setData(values);
592
        data.setBackgroundColor(backgroundColor);
593
        data.setLabel("DataSet 1");
29266 manish 594
 
32464 tejbeer 595
        PieLables label = new PieLables();
596
        label.setFontColor("black");
597
        label.setFontSize(15);
29266 manish 598
 
32464 tejbeer 599
        Legend legend = new Legend();
600
        legend.setLabels(label);
601
        legend.setPosition("left");
29266 manish 602
 
32464 tejbeer 603
        List<LeadStatusData> dataList = new ArrayList<>();
604
        dataList.add(data);
29266 manish 605
 
32464 tejbeer 606
        DataLeadModel datasets = new DataLeadModel();
607
        datasets.setDatasets(dataList);
608
        datasets.setLabels(hotLeads);
29266 manish 609
 
32464 tejbeer 610
        OptionModel om = new OptionModel();
611
        om.setLegend(legend);
29266 manish 612
 
32464 tejbeer 613
        cm.setType("pie");
614
        cm.setData(datasets);
615
        cm.setOptions(om);
25988 tejbeer 616
 
32464 tejbeer 617
        return cm;
618
    }
25988 tejbeer 619
 
34650 aman.kumar 620
    @RequestMapping(value = "/downloadDateWiseLead", method = RequestMethod.GET)
34707 aman.kumar 621
    public ResponseEntity<?> getdownloadLeadDataByDate(HttpServletRequest request,
622
                                                       @RequestParam(name = "leadStatus", required = false, defaultValue = "All") List<LeadStatus> leadStatus,
623
                                                       @RequestParam(name = "color", required = false, defaultValue = "All") List<String> color,
35769 amit 624
                                                       @RequestParam(name = "startDate", required = false) LocalDate startDate,
625
                                                       @RequestParam(name = "endDate", required = false) LocalDate endDate) throws Exception {
25988 tejbeer 626
 
34650 aman.kumar 627
        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);
628
        String emailId = fofoDetails.getEmailId();
35769 amit 629
        LocalDateTime startDateTime = startDate != null ? startDate.atStartOfDay() : null;
630
        LocalDateTime endDateTime = endDate != null ? endDate.atTime(23, 59, 59) : null;
34650 aman.kumar 631
        List<Lead> leads = new ArrayList<>();
632
        AuthUser authUser = authRepository.selectByEmailOrMobile(emailId);
633
 
34707 aman.kumar 634
        if (leadStatus.contains(LeadStatus.All)) {
635
            leadStatus.add(LeadStatus.pending);
636
            leadStatus.add(LeadStatus.notInterested);
637
            leadStatus.add(LeadStatus.finalized);
36984 aman 638
            // NOTE: do NOT add followUp here. Follow-ups are pulled separately (undated) below,
639
            // mirroring the on-screen view. Adding it here made the date query get skipped so the
640
            // download collapsed to follow-ups only (original bug).
34707 aman.kumar 641
        }
642
        if (color.contains("All")) {
643
            color.add("yellow");
644
            color.add("green");
645
        }
34650 aman.kumar 646
 
647
        Map<Integer, List<LeadActivity>> leadActivityMap = new HashMap<>();
648
        boolean authPositon = positionRepository.hasCategory(authUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_SALES);
649
        List<Integer> authUserIds = null;
650
        List<Lead> leadFollowUp = new ArrayList<>();
651
 
652
        if (authPositon) {
653
            authUserIds = authService.getAllReportees(authUser.getId());
654
            authUserIds.add(authUser.getId());
35769 amit 655
            if (startDateTime == null) {
34650 aman.kumar 656
                if (!leadStatus.contains(LeadStatus.followUp)) {
657
                    leads = leadRepository.selectAllByColorStatusAndUpdatedTimestampAndAuthIds(leadStatus, authUserIds, color, LocalDateTime.now().minusMonths(1));
658
                }
659
                if (leadStatus.contains(LeadStatus.followUp) || leadStatus.contains(LeadStatus.All)) {
660
                    leadFollowUp = leadRepository.selectByAssignAuthIdsAndStatus(authUserIds, LeadStatus.followUp);
661
                    leads.addAll(leadFollowUp);
662
                }
663
            } else {
36984 aman 664
                // Date range: non-follow-up statuses created within [start, end], PLUS all follow-ups
665
                // (undated) — mirrors the on-screen view so the CSV matches what the user sees.
666
                if (!leadStatus.contains(LeadStatus.followUp)) {
667
                    leads = leadRepository.selectAllByColorStatusAndBetweenCreatedDateAndAuthIds(leadStatus, authUserIds, color, startDateTime, endDateTime);
668
                }
669
                if (leadStatus.contains(LeadStatus.followUp) || leadStatus.contains(LeadStatus.All)) {
670
                    leadFollowUp = leadRepository.selectByAssignAuthIdsAndStatus(authUserIds, LeadStatus.followUp);
671
                    leads.addAll(leadFollowUp);
672
                }
34650 aman.kumar 673
            }
674
        } else {
35769 amit 675
            if (startDateTime == null) {
34650 aman.kumar 676
                if (!leadStatus.contains(LeadStatus.followUp)) {
677
                    leads = leadRepository.selectAllByColorStatusAndUpdatedTimestamp(leadStatus, color, LocalDateTime.now().minusMonths(1));
678
                }
679
                if (leadStatus.contains(LeadStatus.followUp) || leadStatus.contains(LeadStatus.All)) {
680
                    leadFollowUp = leadRepository.selectAllByStatus(LeadStatus.followUp);
681
                    leads.addAll(leadFollowUp);
682
                }
683
            } else {
36984 aman 684
                // Date range: non-follow-up statuses created within [start, end], PLUS all follow-ups
685
                // (undated) — mirrors the on-screen view.
686
                if (!leadStatus.contains(LeadStatus.followUp)) {
687
                    leads = leadRepository.selectAllByColorStatusAndBetweenCreatedDate(leadStatus, color, startDateTime, endDateTime);
688
                }
689
                if (leadStatus.contains(LeadStatus.followUp) || leadStatus.contains(LeadStatus.All)) {
690
                    leadFollowUp = leadRepository.selectAllByStatus(LeadStatus.followUp);
691
                    leads.addAll(leadFollowUp);
692
                }
34650 aman.kumar 693
            }
34707 aman.kumar 694
        }
34650 aman.kumar 695
 
34707 aman.kumar 696
        // Build activity map and auth map (SAME AS VIEW ENDPOINT)
36984 aman 697
        // Guard both lookups on a non-empty result: an empty list would generate an invalid
698
        // "IN ()" and 500 (e.g. a date range with no leads), so an empty range yields an empty CSV.
699
        Map<Integer, AuthUser> authIdAndAuthUserMap = new HashMap<>();
34650 aman.kumar 700
        if (!leads.isEmpty()) {
34707 aman.kumar 701
            List<Integer> leadIds = leads.stream().map(Lead::getId).collect(Collectors.toList());
702
            leadActivityMap = leadActivityRepository.selectAllByleadIds(leadIds).stream()
703
                    .collect(Collectors.groupingBy(LeadActivity::getLeadId));
36984 aman 704
            List<Integer> authIds = leads.stream().map(Lead::getAssignTo).collect(Collectors.toList());
705
            authIdAndAuthUserMap = authRepository.selectByIds(authIds).stream()
706
                    .collect(Collectors.toMap(AuthUser::getId, x -> x));
34650 aman.kumar 707
        }
34707 aman.kumar 708
 
709
        // Build CSV rows (USE DIRECT LEAD PROPERTIES - NO ACTIVITY FALLBACK)
34650 aman.kumar 710
        List<List<?>> rows = new ArrayList<>();
711
        for (Lead lead : leads) {
712
            List<LeadActivity> activities = leadActivityMap.get(lead.getId());
34707 aman.kumar 713
 
714
            // Use FIRST activity's schedule timestamp if exists
34650 aman.kumar 715
            String scheduleTimestamp = (activities != null && !activities.isEmpty())
716
                    ? FormattingUtils.format(activities.get(0).getSchelduleTimestamp())
34707 aman.kumar 717
                    : "";
34650 aman.kumar 718
 
34707 aman.kumar 719
            // DIRECTLY use Lead properties (NO fallback to activity)
720
            Double potential = lead.getPotential();
721
            String outLetName = lead.getOutLetName() != null ? lead.getOutLetName() : "";
34650 aman.kumar 722
 
34707 aman.kumar 723
            // Assignee name (blank if missing)
724
            String assignTo = "";
725
            if (authIdAndAuthUserMap.containsKey(lead.getAssignTo())) {
726
                AuthUser user = authIdAndAuthUserMap.get(lead.getAssignTo());
727
                assignTo = (user.getFirstName() + " " + user.getLastName()).trim();
728
            }
34650 aman.kumar 729
 
34707 aman.kumar 730
            rows.add(Arrays.asList(
35579 aman 731
                    lead.getId(),
34707 aman.kumar 732
                    lead.getSource(),
733
                    lead.getFullName(),
734
                    outLetName,
735
                    potential,
736
                    lead.getLeadMobile(),
737
                    lead.getAddress() != null ? lead.getAddress() : "",
738
                    lead.getCity() != null ? lead.getCity() : "",
739
                    lead.getState() != null ? lead.getState() : "",
740
                    lead.getCreatedBy() != null ? lead.getCreatedBy() : "",
741
                    lead.getStatus().toString(),
742
                    FormattingUtils.format(lead.getCreatedTimestamp()),
743
                    FormattingUtils.format(lead.getUpdatedTimestamp()),
744
                    scheduleTimestamp,
745
                    lead.getClosureTimestamp() != null
746
                            ? FormattingUtils.format(lead.getClosureTimestamp())
747
                            : "",  // Handle null closure
748
                    assignTo,
749
                    lead.getColor() != null ? lead.getColor() : ""
750
            ));
751
        }
34650 aman.kumar 752
 
34707 aman.kumar 753
        // Generate CSV response
754
        ByteArrayOutputStream baos = FileUtil.getCSVByteStream(
35579 aman 755
                Arrays.asList("Id", "Source", "Partner Name", "Outlet Name", "Potential", "Mobile", "Address", "City", "State",
34707 aman.kumar 756
                        "Created By", "Status", "Created On", "Updated On", "Scheduled Timestamp",
757
                        "Closure Timestamp", "Assign To", "Color"),
758
                rows
759
        );
760
        return orderService.downloadReportInCsv(baos, rows, "LeadDetails_");
34650 aman.kumar 761
    }
762
 
32464 tejbeer 763
    @RequestMapping(value = "/getClosedLead", method = RequestMethod.GET)
764
    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 {
765
        List<AuthUser> authUsers = authRepository.selectAllActiveUser();
766
        List<Lead> leads = null;
767
        long size = 0;
768
        leads = leadRepository.selectAllByStatus(status, offset, limit);
769
        size = leadRepository.selectCountByStatus(status);
25988 tejbeer 770
 
32464 tejbeer 771
        if (!leads.isEmpty()) {
772
            List<Integer> authIds = new ArrayList<>();
773
            for (Lead lead : leads) {
774
                authIds.add(lead.getAssignTo());
775
            }
35395 amit 776
            Map<Integer, AuthUser> authIdAndAuthUserMap = authRepository.selectByIds(authIds).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
25988 tejbeer 777
 
32464 tejbeer 778
            model.addAttribute("leads", leads);
779
            model.addAttribute("start", offset + 1);
780
            model.addAttribute("size", size);
781
            model.addAttribute("searchTerm", searchTerm);
782
            model.addAttribute("authIdAndAuthUserMap", authIdAndAuthUserMap);
783
            model.addAttribute("url", "/getPaginatedClosedLeads");
25988 tejbeer 784
 
32464 tejbeer 785
            if (leads.size() < limit) {
786
                model.addAttribute("end", offset + leads.size());
787
            } else {
788
                model.addAttribute("end", offset + limit);
789
            }
25988 tejbeer 790
 
32464 tejbeer 791
        } else {
792
            model.addAttribute("lead", leads);
25988 tejbeer 793
 
32464 tejbeer 794
            model.addAttribute("size", size);
795
        }
25988 tejbeer 796
 
32464 tejbeer 797
        model.addAttribute("authUsers", authUsers);
798
        return "lead-close";
799
    }
25988 tejbeer 800
 
32464 tejbeer 801
    @RequestMapping(value = "/getPaginatedClosedLeads", method = RequestMethod.GET)
802
    public String getPaginatedClosedLeads(HttpServletRequest request, @RequestParam(name = "offset", defaultValue = "0") int offset, @RequestParam(name = "limit", defaultValue = "10") int limit, Model model) throws ProfitMandiBusinessException {
803
        List<Lead> leads = null;
804
        leads = leadRepository.selectAllByStatus(status, offset, limit);
25988 tejbeer 805
 
32464 tejbeer 806
        if (!leads.isEmpty()) {
807
            List<Integer> authIds = new ArrayList<>();
808
            for (Lead lead : leads) {
809
                authIds.add(lead.getAssignTo());
810
            }
35395 amit 811
            Map<Integer, AuthUser> authIdAndAuthUserMap = authRepository.selectByIds(authIds).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
32464 tejbeer 812
            model.addAttribute("authIdAndAuthUserMap", authIdAndAuthUserMap);
813
            model.addAttribute("leads", leads);
814
            model.addAttribute("url", "/getPaginatedClosedLeads");
25988 tejbeer 815
 
37047 ranu 816
            List<Integer> allLeadIds = leads.stream().map(Lead::getId).collect(Collectors.toList());
817
            Map<Integer, LeadLiveLocation> geoLocationMap = leadLiveLocationRepository.selectByLeadIds(allLeadIds).stream()
818
                    .collect(Collectors.toMap(LeadLiveLocation::getLeadId, x -> x, (a, b) -> a));
819
            model.addAttribute("geoLocationMap", geoLocationMap);
32464 tejbeer 820
        } else {
821
            model.addAttribute("leads", leads);
37047 ranu 822
            model.addAttribute("geoLocationMap", new HashMap<>());
32464 tejbeer 823
        }
824
        return "lead-close-paginated";
825
    }
25988 tejbeer 826
 
32464 tejbeer 827
    @RequestMapping(value = "/searchLeads")
828
    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 {
829
        List<AuthUser> authUsers = authRepository.selectAllActiveUser();
830
        List<Lead> leads = null;
831
        long size = 0;
832
        if (!(searchTerm.equals(""))) {
833
            leads = leadRepository.selectBySearchTerm(status, searchTerm, offset, limit);
34155 tejus.loha 834
            size = leadRepository.selectCountByStatus(status);
835
            Map<Integer, AuthUser> authIdAndAuthUserMap = new HashMap<>();
836
            List<Integer> authIds = new ArrayList<>();
32464 tejbeer 837
            if (!(leads.size() == 0)) {
838
                for (Lead lead : leads) {
839
                    authIds.add(lead.getAssignTo());
840
                }
35395 amit 841
                authIdAndAuthUserMap = authRepository.selectByIds(authIds).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
32464 tejbeer 842
                if (leads.size() < limit) {
843
                    model.addAttribute("end", offset + leads.size());
844
                } else {
845
                    model.addAttribute("end", offset + limit);
846
                }
847
            } else {
34155 tejus.loha 848
                model.addAttribute("end", offset + limit);
32464 tejbeer 849
            }
34155 tejus.loha 850
            model.addAttribute("leads", leads);
851
            model.addAttribute("authIdAndAuthUserMap", authIdAndAuthUserMap);
852
            model.addAttribute("start", offset + 1);
853
            model.addAttribute("size", size);
854
            model.addAttribute("searchTerm", searchTerm);
32464 tejbeer 855
        } else {
856
            leads = leadRepository.selectAllByStatus(status, offset, limit);
857
            size = leadRepository.selectCountByStatus(status);
25988 tejbeer 858
 
32464 tejbeer 859
            if (!leads.isEmpty()) {
860
                List<Integer> authIds = new ArrayList<>();
861
                for (Lead lead : leads) {
862
                    authIds.add(lead.getAssignTo());
863
                }
35395 amit 864
                Map<Integer, AuthUser> authIdAndAuthUserMap = authRepository.selectByIds(authIds).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
25988 tejbeer 865
 
32464 tejbeer 866
                model.addAttribute("leads", leads);
867
                model.addAttribute("start", offset + 1);
868
                model.addAttribute("size", size);
869
                model.addAttribute("searchTerm", searchTerm);
870
                model.addAttribute("authIdAndAuthUserMap", authIdAndAuthUserMap);
25988 tejbeer 871
 
32464 tejbeer 872
                if (leads.size() < limit) {
873
                    model.addAttribute("end", offset + leads.size());
874
                } else {
875
                    model.addAttribute("end", offset + limit);
876
                }
25988 tejbeer 877
 
32464 tejbeer 878
            }
879
        }
25988 tejbeer 880
 
32464 tejbeer 881
        model.addAttribute("authUsers", authUsers);
882
        return "lead-close";
883
    }
25988 tejbeer 884
 
32464 tejbeer 885
    @RequestMapping(value = "/searchLeadPaginated")
886
    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 {
887
        LOGGER.info("In search Item....");
888
        List<Lead> leads = null;
889
        if (!searchTerm.equals("")) {
890
            leads = leadRepository.selectBySearchTerm(status, searchTerm, offset, limit);
891
            if (!(leads.size() == 0)) {
25988 tejbeer 892
 
32464 tejbeer 893
                List<Integer> authIds = new ArrayList<>();
894
                for (Lead lead : leads) {
895
                    authIds.add(lead.getAssignTo());
896
                }
35395 amit 897
                Map<Integer, AuthUser> authIdAndAuthUserMap = authRepository.selectByIds(authIds).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
32464 tejbeer 898
                model.addAttribute("authIdAndAuthUserMap", authIdAndAuthUserMap);
899
                model.addAttribute("leads", leads);
37047 ranu 900
 
901
                List<Integer> allLeadIds = leads.stream().map(Lead::getId).collect(Collectors.toList());
902
                Map<Integer, LeadLiveLocation> geoLocationMap = leadLiveLocationRepository.selectByLeadIds(allLeadIds).stream()
903
                        .collect(Collectors.toMap(LeadLiveLocation::getLeadId, x -> x, (a, b) -> a));
904
                model.addAttribute("geoLocationMap", geoLocationMap);
32464 tejbeer 905
            }
906
        }
37047 ranu 907
        if (!model.containsAttribute("geoLocationMap")) {
908
            model.addAttribute("geoLocationMap", new HashMap<>());
909
        }
31249 tejbeer 910
 
32464 tejbeer 911
        return "lead-close-paginated";
31249 tejbeer 912
 
32464 tejbeer 913
    }
31249 tejbeer 914
 
36984 aman 915
    // Global lead search box: find ANY lead by name / mobile / outlet / city, no date filter needed.
916
    @RequestMapping(value = "/globalLeadSearch")
917
    public String globalLeadSearch(HttpServletRequest request,
918
                                   @RequestParam(name = "searchTerm", required = false, defaultValue = "") String searchTerm,
919
                                   Model model) {
920
        List<Lead> leads = new ArrayList<>();
921
        if (!searchTerm.trim().isEmpty()) {
922
            leads = leadRepository.selectByGlobalSearch(searchTerm.trim(), 200);
923
            if (!leads.isEmpty()) {
37048 ranu 924
                List<Integer> allLeadIds = leads.stream().map(Lead::getId).collect(Collectors.toList());
36984 aman 925
                List<Integer> authIds = leads.stream().map(Lead::getAssignTo).collect(Collectors.toList());
926
                Map<Integer, AuthUser> authIdAndAuthUserMap = authRepository.selectByIds(authIds).stream()
927
                        .collect(Collectors.toMap(AuthUser::getId, x -> x));
928
                model.addAttribute("authIdAndAuthUserMap", authIdAndAuthUserMap);
37047 ranu 929
 
930
                Map<Integer, LeadLiveLocation> geoLocationMap = leadLiveLocationRepository.selectByLeadIds(allLeadIds).stream()
931
                        .collect(Collectors.toMap(LeadLiveLocation::getLeadId, x -> x, (a, b) -> a));
932
                model.addAttribute("geoLocationMap", geoLocationMap);
37048 ranu 933
 
934
                Map<Integer, List<LeadActivity>> leadActivityMap = leadActivityRepository.selectAllByleadIds(allLeadIds).stream()
935
                        .collect(Collectors.groupingBy(LeadActivity::getLeadId, Collectors.toList()));
936
                model.addAttribute("leadActivityMap", leadActivityMap);
937
 
938
                try {
939
                    Set<Integer> pendingSet = leadVisitRequestRepository.selectByLeadIdsAndStatus(allLeadIds, "PENDING").stream()
940
                            .map(com.spice.profitmandi.dao.entity.user.LeadVisitRequest::getLeadId)
941
                            .collect(Collectors.toSet());
942
                    model.addAttribute("pendingVisitRequestLeadIds", pendingSet);
943
                } catch (Exception e) {
944
                    model.addAttribute("pendingVisitRequestLeadIds", new HashSet<Integer>());
945
                }
36984 aman 946
            }
947
        }
37047 ranu 948
        if (!model.containsAttribute("geoLocationMap")) {
949
            model.addAttribute("geoLocationMap", new HashMap<>());
950
        }
37048 ranu 951
        if (!model.containsAttribute("leadActivityMap")) {
952
            model.addAttribute("leadActivityMap", new HashMap<>());
953
        }
954
        if (!model.containsAttribute("pendingVisitRequestLeadIds")) {
955
            model.addAttribute("pendingVisitRequestLeadIds", new HashSet<Integer>());
956
        }
36984 aman 957
        model.addAttribute("leads", leads);
958
        model.addAttribute("searchTerm", searchTerm);
37048 ranu 959
        return "lead-global-search";
36984 aman 960
    }
961
 
32464 tejbeer 962
    @RequestMapping(value = "/getLeadActivity", method = RequestMethod.GET)
963
    public String getLeadActivity(HttpServletRequest request, @RequestParam int leadId, Model model) throws Exception {
964
        List<LeadActivity> leadActivity = leadActivityRepository.selectBYLeadId(leadId);
25979 tejbeer 965
 
32464 tejbeer 966
        LOGGER.info("leadActivity" + leadActivity);
31370 tejbeer 967
 
32464 tejbeer 968
        model.addAttribute("leadActivity", leadActivity);
969
        model.addAttribute("authUserMap", authRepository.selectAllActiveUser().stream().collect(Collectors.toMap(x -> x.getId(), x -> x)));
31370 tejbeer 970
 
32464 tejbeer 971
        return "lead_activity_modal";
972
    }
31370 tejbeer 973
 
32464 tejbeer 974
    @RequestMapping(value = "/getLead", method = RequestMethod.GET)
975
    public ResponseEntity<?> getLead(HttpServletRequest request, @RequestParam int leadId) throws Exception {
976
        Lead lead = leadRepository.selectById(leadId);
31370 tejbeer 977
 
32464 tejbeer 978
        LeadDetail leadDetail = leadDetailRepository.selectByLeadId(lead.getId());
979
        if (leadDetail != null) {
980
            lead.setOutLetName(leadDetail.getOutletName());
981
        }
31249 tejbeer 982
 
32464 tejbeer 983
        return responseSender.ok(lead);
25979 tejbeer 984
 
32464 tejbeer 985
    }
31249 tejbeer 986
 
32464 tejbeer 987
    @RequestMapping(value = "/createLead", method = RequestMethod.POST)
988
    public String CreateLead(HttpServletRequest request, @RequestBody CreateRefferalRequest createRefferalRequest, Model model) throws Exception {
989
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
35083 vikas 990
        Lead leadDetails = leadRepository.selectByMobileNumber(createRefferalRequest.getMobile());
991
        LOGGER.info("Lead Details {}", leadDetails);
31249 tejbeer 992
 
35083 vikas 993
        if (leadDetails != null && leadDetails.getStatus() != LeadStatus.notInterested) {
994
            AuthUser authUser1 = authRepository.selectById(leadDetails.getAssignTo());
995
            model.addAttribute("response1", "Lead already exists, created by " + leadDetails.getCreatedBy() +
996
                    " on " + FormattingUtils.format(leadDetails.getCreatedTimestamp()) +
34671 aman.kumar 997
                    ", assigned to " + authUser1.getFullName());
998
            return "response";
34627 aman.kumar 999
 
34671 aman.kumar 1000
 
34627 aman.kumar 1001
        }
1002
 
32464 tejbeer 1003
        LOGGER.info("createRefferalRequest" + createRefferalRequest.getSchelduleTimestamp());
1004
        Lead lead = new Lead();
1005
        lead.setFirstName(createRefferalRequest.getFirstName());
1006
        lead.setLastName(createRefferalRequest.getLastName());
1007
        lead.setLeadMobile(createRefferalRequest.getMobile());
1008
        lead.setState(createRefferalRequest.getState());
1009
        lead.setCity(createRefferalRequest.getCity());
1010
        lead.setAddress(createRefferalRequest.getAddress());
1011
        lead.setCreatedTimestamp(LocalDateTime.now());
1012
        lead.setUpdatedTimestamp(LocalDateTime.now());
1013
        lead.setStatus(createRefferalRequest.getStatus());
1014
        lead.setAssignTo(createRefferalRequest.getAssignTo());
1015
        lead.setSource(createRefferalRequest.getSource());
36741 ranu 1016
        if (Boolean.TRUE.equals(createRefferalRequest.getColorCheck())) {
32471 tejbeer 1017
            lead.setColor("Green");
1018
        } else {
1019
            lead.setColor("Yellow");
1020
        }
32464 tejbeer 1021
        // change
1022
        AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
1023
        String authUserName = authUser.getFirstName() + " " + authUser.getLastName();
1024
        lead.setCreatedBy(authUserName);
1025
        lead.setAuthId(authUser.getId());
1026
        LOGGER.info("lead --- {}", lead);
1027
        leadRepository.persist(lead);
1028
        LeadActivity leadActivity = new LeadActivity();
1029
        leadActivity.setLeadId(lead.getId());
1030
        leadActivity.setRemark(createRefferalRequest.getRemark());
1031
        leadActivity.setAuthId(authUser.getId());
32471 tejbeer 1032
 
32464 tejbeer 1033
        LOGGER.info("createRefferalRequest" + createRefferalRequest.getCommunicationType());
25979 tejbeer 1034
 
32464 tejbeer 1035
        if (createRefferalRequest.getStatus() == LeadStatus.followUp) {
1036
            leadActivity.setSchelduleTimestamp(createRefferalRequest.getSchelduleTimestamp());
1037
            leadActivity.setCommunicationType(createRefferalRequest.getCommunicationType());
25979 tejbeer 1038
 
32464 tejbeer 1039
            if (leadActivity.getCommunicationType().equals(CommunicationType.VISIT)) {
1040
                visitRequestRepository.createVisitRequest(lead.getId(), "lead", lead.getAssignTo(), createRefferalRequest.getSchelduleTimestamp());
1041
            }
1042
        } else {
1043
            leadActivity.setSchelduleTimestamp(null);
1044
        }
1045
        leadActivity.setCreatedTimestamp(LocalDateTime.now());
1046
        leadActivityRepository.persist(leadActivity);
34127 tejus.loha 1047
        if (!lead.getStatus().equals(LeadStatus.notInterested)) {
1048
            LeadDetailModel leadDetail = new LeadDetailModel();
1049
            leadDetail.setLeadId(lead.getId());
1050
            leadDetail.setOutletName(createRefferalRequest.getOutletName());
1051
            leadDetail.setCounterSize(createRefferalRequest.getCounterSize());
25979 tejbeer 1052
 
31249 tejbeer 1053
 
34127 tejus.loha 1054
            leadDetail.setFrontp(createRefferalRequest.getFrontp());
1055
            leadDetail.setFrontWithMarket(createRefferalRequest.getFrontWithMarket());
31370 tejbeer 1056
 
1057
 
34127 tejus.loha 1058
            leadDetail.setInternalLongShot(createRefferalRequest.getInternalLongShot());
31370 tejbeer 1059
 
34127 tejus.loha 1060
            leadDetail.setInternalLeftWall(createRefferalRequest.getInternalLeftWall());
29598 tejbeer 1061
 
34127 tejus.loha 1062
            leadDetail.setInternalRightWall(createRefferalRequest.getInternalRightWall());
1063
            List<LeadBrandModel> brandModels = new ArrayList<LeadBrandModel>();
27605 tejbeer 1064
 
34127 tejus.loha 1065
            for (LeadBrandModel leadBrandModel : createRefferalRequest.getLeadBrands()) {
25979 tejbeer 1066
 
34127 tejus.loha 1067
                LeadBrandModel leadBrand = new LeadBrandModel();
1068
                leadBrand.setBrand(leadBrandModel.getBrand());
1069
                leadBrand.setValue(leadBrandModel.getValue());
29598 tejbeer 1070
 
34127 tejus.loha 1071
                brandModels.add(leadBrand);
25979 tejbeer 1072
 
34127 tejus.loha 1073
            }
29598 tejbeer 1074
 
34127 tejus.loha 1075
            leadDetail.setLeadBrands(brandModels);
29598 tejbeer 1076
 
32471 tejbeer 1077
            leadRepository.persistLeadDetail(leadDetail, authUser);
1078
        }
32464 tejbeer 1079
        model.addAttribute("response1", mvcResponseSender.createResponseString(true));
29598 tejbeer 1080
 
32464 tejbeer 1081
        return "response";
29598 tejbeer 1082
 
32464 tejbeer 1083
    }
29476 manish 1084
 
29473 manish 1085
 
32464 tejbeer 1086
    @RequestMapping(value = "/editLead", method = RequestMethod.POST)
1087
    public String EditLead(HttpServletRequest request, @RequestBody CreateLeacdActivityRequest createLeadActivityRequest, Model model) throws Exception {
1088
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
29426 manish 1089
 
32464 tejbeer 1090
        AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
29426 manish 1091
 
34113 tejus.loha 1092
        Lead lead = leadRepository.selectById(createLeadActivityRequest.getId());
1093
        AuthUser leadAuthUser = authRepository.selectById(lead.getAuthId());
32464 tejbeer 1094
        LeadDetail leadDetail = leadDetailRepository.selectByLeadId(createLeadActivityRequest.getId());
29426 manish 1095
 
36789 ranu 1096
        // Geo gate: required for follow-up / finalized (anything that schedules
1097
        // a visit or beat slot). For notInterested (close-out) no geo / no beat
1098
        // is needed — only the activity (status + reason + remark) is saved.
36792 ranu 1099
        // Non-sales assignees (BGC / other internal hand-offs) also bypass the
1100
        // gate — those are just routing the lead to another department's queue
1101
        // and don't carry a beat-day attachment.
1102
        int assignToId = createLeadActivityRequest.getAssignTo();
1103
        boolean assigneeIsSales = assignToId > 0
1104
                && positionRepository.hasCategory(assignToId, ProfitMandiConstants.TICKET_CATEGORY_SALES);
1105
        if (createLeadActivityRequest.getStatus() != LeadStatus.notInterested && assigneeIsSales) {
36789 ranu 1106
            LeadLiveLocation approvedGeo = leadLiveLocationRepository.selectApprovedByLeadId(createLeadActivityRequest.getId());
1107
            if (approvedGeo == null) {
1108
                throw new ProfitMandiBusinessException("Lead", "", "Live geo-location for this lead has not been approved yet. Please approve the geo-location before editing.");
1109
            }
36761 ranu 1110
        }
1111
 
34113 tejus.loha 1112
        if (leadDetail == null && !createLeadActivityRequest.getStatus().equals(LeadStatus.notInterested) && leadAuthUser.isActive()) {
29426 manish 1113
 
32464 tejbeer 1114
            throw new ProfitMandiBusinessException("LeadDetail", "", "Please fill lead detail");
1115
        }
29445 manish 1116
 
32464 tejbeer 1117
        LeadActivity leadActivity = new LeadActivity();
1118
        leadActivity.setLeadId(createLeadActivityRequest.getId());
1119
        leadActivity.setRemark(createLeadActivityRequest.getRemark());
29598 tejbeer 1120
 
32464 tejbeer 1121
        LOGGER.info("createRefferalRequest" + createLeadActivityRequest);
29598 tejbeer 1122
 
32464 tejbeer 1123
        if (createLeadActivityRequest.getStatus() == LeadStatus.followUp) {
1124
            leadActivity.setSchelduleTimestamp(createLeadActivityRequest.getScheldule());
1125
            leadActivity.setCommunicationType(createLeadActivityRequest.getCommunicationType());
36741 ranu 1126
            // A beat-day pick wires the lead onto that beat's route regardless of
1127
            // communication type (TELEPHONIC = call on that beat day).
1128
            String beatSelection = createLeadActivityRequest.getBeatSelection();
1129
            if (beatSelection != null && beatSelection.contains("|")) {
36644 ranu 1130
                int beatId = 0;
1131
                LocalDate beatDate = createLeadActivityRequest.getScheldule() != null
1132
                        ? createLeadActivityRequest.getScheldule().toLocalDate() : LocalDate.now();
1133
                String beatName = "Beat";
36642 ranu 1134
 
36741 ranu 1135
                String[] parts = beatSelection.split("\\|", 3);
1136
                beatDate = LocalDate.parse(parts[0]);
1137
                beatName = parts.length > 1 ? parts[1] : "Beat";
1138
                if (parts.length > 2) {
1139
                    try {
1140
                        beatId = Integer.parseInt(parts[2]);
1141
                    } catch (NumberFormatException ignored) {
36642 ranu 1142
                    }
1143
                }
1144
 
36644 ranu 1145
                // Find optimal insert position using lead geolocation
1146
                int insertAt = 0;
1147
                LeadLiveLocation leadGeo = leadLiveLocationRepository.selectApprovedByLeadId(createLeadActivityRequest.getId());
1148
                List<BeatRoute> existingStops = beatId > 0
1149
                        ? beatRouteRepository.selectByBeatId(beatId).stream()
1150
                        .sorted(Comparator.comparingInt(BeatRoute::getSequenceOrder))
1151
                        .collect(Collectors.toList())
1152
                        : new ArrayList<>();
36642 ranu 1153
 
36644 ranu 1154
                insertAt = existingStops.size(); // default: append at end
1155
 
1156
                if (!existingStops.isEmpty() && leadGeo != null) {
1157
                    // Use nearest neighbor to find optimal position
1158
                    // (simplified — append at end for now, full geocoding done in LeadGeoLocationController)
1159
                    insertAt = existingStops.size();
1160
                }
1161
 
1162
                // Shift existing stops
1163
                for (BeatRoute stop : existingStops) {
1164
                    if (stop.getSequenceOrder() >= insertAt) {
1165
                        stop.setSequenceOrder(stop.getSequenceOrder() + 1);
1166
                    }
1167
                }
1168
 
1169
                // Create lead_route entry (directly APPROVED)
1170
                LeadRoute leadRoute = new LeadRoute();
1171
                leadRoute.setBeatId(beatId);
1172
                leadRoute.setLeadId(createLeadActivityRequest.getId());
1173
                leadRoute.setScheduleDate(beatDate);
1174
                leadRoute.setSequenceOrder(insertAt);
1175
                leadRoute.setStatus("APPROVED");
1176
                leadRoute.setRequestedBy(authUser.getId());
1177
                leadRoute.setApprovedBy(authUser.getId());
1178
                leadRoute.setApprovedTimestamp(LocalDateTime.now());
1179
                leadRoute.setCreatedTimestamp(LocalDateTime.now());
1180
                leadRoute.setUpdatedTimestamp(LocalDateTime.now());
1181
 
1182
                // Set nearest store
1183
                if (!existingStops.isEmpty()) {
1184
                    leadRoute.setNearestStoreId(existingStops.get(Math.min(insertAt, existingStops.size() - 1)).getFofoId());
1185
                }
1186
                leadRouteRepository.persist(leadRoute);
1187
 
1188
                // Create visit request
1189
                visitRequestRepository.createVisitRequest(
1190
                        createLeadActivityRequest.getId(), "lead",
1191
                        createLeadActivityRequest.getAssignTo(),
1192
                        beatDate.atTime(10, 0));
1193
 
36642 ranu 1194
                // Log activity
36644 ranu 1195
                LeadActivity visitActivity = new LeadActivity();
1196
                visitActivity.setLeadId(createLeadActivityRequest.getId());
1197
                visitActivity.setRemark("Lead scheduled for visit on beat: " + beatName
1198
                        + " (" + beatDate + ") at stop #" + (insertAt + 1));
1199
                visitActivity.setAuthId(authUser.getId());
1200
                visitActivity.setCreatedTimestamp(LocalDateTime.now());
1201
                leadActivityRepository.persist(visitActivity);
32464 tejbeer 1202
            }
1203
        } else {
1204
            leadActivity.setSchelduleTimestamp(null);
1205
        }
1206
        leadActivity.setCreatedTimestamp(LocalDateTime.now());
1207
        leadActivity.setAuthId(authUser.getId());
1208
        leadActivityRepository.persist(leadActivity);
1209
        lead.setAssignTo(createLeadActivityRequest.getAssignTo());
1210
        lead.setStatus(createLeadActivityRequest.getStatus());
35548 aman 1211
        lead.setState(createLeadActivityRequest.getState());
1212
        lead.setCity(createLeadActivityRequest.getCity());
35769 amit 1213
        if (createLeadActivityRequest.getSource() != null && !createLeadActivityRequest.getSource().isEmpty()) {
1214
            lead.setSource(createLeadActivityRequest.getSource());
1215
        }
36741 ranu 1216
        if (Boolean.TRUE.equals(createLeadActivityRequest.getColorCheck())) {
32471 tejbeer 1217
            lead.setColor("Green");
1218
        } else {
1219
            lead.setColor("Yellow");
1220
        }
32464 tejbeer 1221
        lead.setNotinterestedReason(createLeadActivityRequest.getReason());
1222
        lead.setUpdatedTimestamp(LocalDateTime.now());
37003 ranu 1223
        // Persist the mutated Lead row. Without this the audit activity is written but
1224
        // the main lead table keeps the old status/assignTo — the list view shows the
1225
        // stale row while the activity dialog shows the new state.
1226
        leadRepository.persist(lead);
29426 manish 1227
 
32464 tejbeer 1228
        int authId = 0;
34127 tejus.loha 1229
        authId = lead.getAssignTo();
1230
        Map<Integer, LeadActivity> leadActivityMap = new HashMap<>();
29426 manish 1231
 
34127 tejus.loha 1232
        List<LeadActivity> leadActivitys = leadActivityRepository.selectBYLeadId(lead.getId());
29426 manish 1233
 
34127 tejus.loha 1234
        if (!leadActivitys.isEmpty()) {
1235
            leadActivityMap.put(lead.getId(), leadActivitys.get(0));
1236
        }
29426 manish 1237
 
34127 tejus.loha 1238
        Map<Integer, AuthUser> authIdAndAuthUserMap = new HashMap<>();
1239
        AuthUser AuthUser = authRepository.selectById(authId);
29426 manish 1240
 
34127 tejus.loha 1241
        authIdAndAuthUserMap.put(AuthUser.getId(), AuthUser);
29426 manish 1242
 
34127 tejus.loha 1243
        model.addAttribute("leadActivityMap", leadActivityMap);
1244
        model.addAttribute("authIdAndAuthUserMap", authIdAndAuthUserMap);
29426 manish 1245
 
30185 tejbeer 1246
 
33223 amit.gupta 1247
        model.addAttribute("lead", lead);
30185 tejbeer 1248
 
36818 ranu 1249
        // Best-effort hierarchy email — fired after the lead+activity are persisted
1250
        // so a mail failure never blocks the assignment. Covers every editLead path
1251
        // (followUp, notInterested, etc.) so every assignment is announced upward.
1252
        try {
1253
            sendLeadAssignmentEmail(lead, AuthUser, authUser,
1254
                    createLeadActivityRequest.getStatus() != null ? createLeadActivityRequest.getStatus().toString() : null);
1255
        } catch (Exception e) {
1256
            LOGGER.warn("Lead-assignment email fan-out failed (lead id {}): {}", lead.getId(), e.getMessage());
1257
        }
1258
 
32464 tejbeer 1259
        return "edit-lead";
30185 tejbeer 1260
 
32464 tejbeer 1261
    }
31370 tejbeer 1262
 
36818 ranu 1263
    // Hierarchy-wide email when a lead is assigned. Recipients:
1264
    //   - the assignee themselves (L1)
1265
    //   - every manager above the assignee, capped at L4
1266
    // L5 / Final / super-admins are intentionally NOT copied on lead-management mails.
1267
    private void sendLeadAssignmentEmail(Lead lead, AuthUser assignee, AuthUser requestedBy, String status) {
1268
        if (gmailRelaySender == null || lead == null || assignee == null) return;
1269
 
1270
        java.util.LinkedHashSet<String> recipients = new java.util.LinkedHashSet<>();
1271
        if (assignee.getEmailId() != null && !assignee.getEmailId().isEmpty()) {
1272
            recipients.add(assignee.getEmailId());
1273
        }
1274
        try {
1275
            for (AuthUser m : authService.getAllManagers(assignee.getId())) {
1276
                if (m.getEmailId() == null || m.getEmailId().isEmpty()) continue;
1277
                // Cap chain at L4 — L5 / Final never receive lead-management mails.
1278
                com.spice.profitmandi.dao.enumuration.cs.EscalationType lvl = highestEscalation(m.getId());
1279
                if (lvl != null
1280
                        && com.spice.profitmandi.dao.enumuration.cs.EscalationType.L4.isGreaterThanEqualTo(lvl)) {
1281
                    recipients.add(m.getEmailId());
1282
                }
1283
            }
1284
        } catch (Exception ignored) {
1285
        }
1286
        if (recipients.isEmpty()) return;
1287
 
1288
        // TEST OVERRIDE — uncomment to route all lead-assignment mail to one inbox.
1289
        // recipients.clear();
1290
        // recipients.add("ranu.rajput@smartdukaan.com");
1291
 
1292
        String leadName = ((lead.getFirstName() != null ? lead.getFirstName() : "")
1293
                + " " + (lead.getLastName() != null ? lead.getLastName() : "")).trim();
1294
        if (leadName.isEmpty()) leadName = "Lead #" + lead.getId();
1295
        String assigneeName = ((assignee.getFirstName() != null ? assignee.getFirstName() : "")
1296
                + " " + (assignee.getLastName() != null ? assignee.getLastName() : "")).trim();
1297
 
1298
        String subject = "Lead assigned — " + leadName + " → " + assigneeName;
1299
        StringBuilder text = new StringBuilder();
1300
        text.append("A lead has been assigned.\n\n");
1301
        text.append("Lead:        ").append(leadName).append("\n");
1302
        if (lead.getLeadMobile() != null) text.append("Mobile:      ").append(lead.getLeadMobile()).append("\n");
1303
        if (lead.getOutLetName() != null) text.append("Outlet:      ").append(lead.getOutLetName()).append("\n");
1304
        if (lead.getCity() != null || lead.getState() != null) {
1305
            text.append("Location:    ")
1306
                    .append(lead.getCity() != null ? lead.getCity() : "")
1307
                    .append(lead.getCity() != null && lead.getState() != null ? ", " : "")
1308
                    .append(lead.getState() != null ? lead.getState() : "")
1309
                    .append("\n");
1310
        }
1311
        text.append("Assignee:    ").append(assigneeName).append("\n");
1312
        if (status != null) text.append("Status:      ").append(status).append("\n");
1313
        if (requestedBy != null) {
1314
            String rbName = ((requestedBy.getFirstName() != null ? requestedBy.getFirstName() : "")
1315
                    + " " + (requestedBy.getLastName() != null ? requestedBy.getLastName() : "")).trim();
1316
            text.append("Assigned by: ").append(rbName.isEmpty() ? ("#" + requestedBy.getId()) : rbName).append("\n");
1317
        }
1318
 
1319
        try {
1320
            javax.mail.internet.MimeMessage message = gmailRelaySender.createMimeMessage();
1321
            org.springframework.mail.javamail.MimeMessageHelper helper = new org.springframework.mail.javamail.MimeMessageHelper(message, true);
1322
            helper.setSubject(subject);
1323
            helper.setText(text.toString());
1324
            helper.setTo(recipients.toArray(new String[0]));
1325
            helper.setFrom(new javax.mail.internet.InternetAddress("sdtech@smartdukaan.com", "SD Tech"));
1326
            gmailRelaySender.send(message);
1327
        } catch (Exception e) {
1328
            LOGGER.warn("Lead-assignment mail send failed: {}", e.getMessage());
1329
        }
1330
    }
1331
 
1332
    // Returns the user's highest escalation across all positions (or null).
1333
    // Used to gate the chain-mail cap.
1334
    private com.spice.profitmandi.dao.enumuration.cs.EscalationType highestEscalation(int authUserId) {
1335
        com.spice.profitmandi.dao.enumuration.cs.EscalationType highest = null;
1336
        try {
1337
            for (com.spice.profitmandi.dao.entity.cs.Position p : positionRepository.selectPositionByAuthId(authUserId)) {
1338
                if (highest == null || p.getEscalationType().isGreaterThanEqualTo(highest)) {
1339
                    highest = p.getEscalationType();
1340
                }
1341
            }
1342
        } catch (Exception ignored) {
1343
        }
1344
        return highest;
1345
    }
1346
 
32464 tejbeer 1347
    @RequestMapping(value = "/downloadIvoryLead", method = RequestMethod.GET)
1348
    public ResponseEntity<?> downloadDelayDayTemplate(HttpServletRequest request) throws Exception {
1349
        List<String> stateNames = stateRepository.selectAll().stream().map(x -> x.getName()).collect(Collectors.toList());
31370 tejbeer 1350
 
32464 tejbeer 1351
        List<List<?>> rows = new ArrayList<>();
31496 tejbeer 1352
 
32464 tejbeer 1353
        List<LeadSource> lss = LeadSource.enumValues;
31370 tejbeer 1354
 
32464 tejbeer 1355
        for (LeadSource ls : lss) {
1356
            rows.add(Arrays.asList("-", "-", "-", "-", "-", "-", "-", ls));
31478 tejbeer 1357
 
32464 tejbeer 1358
        }
1359
        for (String stateName : stateNames) {
1360
            rows.add(Arrays.asList("-", "-", "-", "-", stateName, "-", "-", "-"));
31478 tejbeer 1361
 
32464 tejbeer 1362
        }
31478 tejbeer 1363
 
32464 tejbeer 1364
        org.apache.commons.io.output.ByteArrayOutputStream baos = FileUtil.getCSVByteStream(Arrays.asList("First Name", "Last Name", "Address", "City", "State", "Mobile", "Assign To(email)", "Source"), rows);
31478 tejbeer 1365
 
32464 tejbeer 1366
        final HttpHeaders headers = new HttpHeaders();
1367
        headers.set("Content-Type", "text/csv");
1368
        headers.set("Content-disposition", "inline; filename=leads.format.csv");
1369
        headers.setContentLength(baos.toByteArray().length);
31478 tejbeer 1370
 
32464 tejbeer 1371
        final InputStream inputStream = new ByteArrayInputStream(baos.toByteArray());
1372
        final InputStreamResource inputStreamResource = new InputStreamResource(inputStream);
1373
        return new ResponseEntity<InputStreamResource>(inputStreamResource, headers, HttpStatus.OK);
31478 tejbeer 1374
 
32464 tejbeer 1375
    }
31478 tejbeer 1376
 
32464 tejbeer 1377
    @RequestMapping(value = "/csvFileAndSetLead", method = RequestMethod.POST)
1378
    public String readCsvFileAndSetLead(HttpServletRequest request, Model model, HttpServletResponse response, @RequestPart MultipartFile file) throws Throwable {
31478 tejbeer 1379
 
32464 tejbeer 1380
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
1381
        String email = loginDetails.getEmailId();
31478 tejbeer 1382
 
32464 tejbeer 1383
        AuthUser createdBy = authRepository.selectByEmailOrMobile(email);
31478 tejbeer 1384
 
32464 tejbeer 1385
        LOGGER.info("file" + file.toString());
31478 tejbeer 1386
 
32464 tejbeer 1387
        String fileName = file.getName();
31370 tejbeer 1388
 
32464 tejbeer 1389
        String fileNames = file.getOriginalFilename();
31370 tejbeer 1390
 
32464 tejbeer 1391
        LOGGER.info("fileName" + fileName);
1392
        LOGGER.info("fileNames" + fileNames);
31370 tejbeer 1393
 
32464 tejbeer 1394
        List<CSVRecord> records = FileUtil.readFile(file);
31370 tejbeer 1395
 
32464 tejbeer 1396
        for (CSVRecord record : records) {
31370 tejbeer 1397
 
32464 tejbeer 1398
            Lead lead = new Lead();
1399
            lead.setFirstName(record.get(0));
1400
            lead.setLastName(record.get(1));
1401
            lead.setAddress(record.get(2));
1402
            lead.setCity(record.get(3));
1403
            lead.setState(record.get(4));
1404
            lead.setLeadMobile(record.get(5));
1405
            LOGGER.info("record" + record.get(6));
31370 tejbeer 1406
 
32464 tejbeer 1407
            AuthUser assignTo = authRepository.selectByEmailOrMobile(record.get(6));
31370 tejbeer 1408
 
32464 tejbeer 1409
            if (assignTo == null) {
1410
                throw new ProfitMandiBusinessException("Assign To ", record.get(6), "email id not exist");
1411
            }
31370 tejbeer 1412
 
32464 tejbeer 1413
            lead.setAssignTo(assignTo.getId());
1414
            lead.setSource(record.get(7));
31370 tejbeer 1415
 
32464 tejbeer 1416
            lead.setCreatedTimestamp(LocalDateTime.now());
31370 tejbeer 1417
 
32464 tejbeer 1418
            lead.setUpdatedTimestamp(LocalDateTime.now());
1419
            lead.setStatus(LeadStatus.pending);
1420
            lead.setColor("yellow");
1421
            // change
1422
            lead.setCreatedBy(createdBy.getFullName());
1423
            lead.setAuthId(createdBy.getId());
31370 tejbeer 1424
 
32464 tejbeer 1425
            leadRepository.persist(lead);
31370 tejbeer 1426
 
32464 tejbeer 1427
            LeadActivity leadActivity = new LeadActivity();
1428
            leadActivity.setLeadId(lead.getId());
1429
            leadActivity.setRemark("New Lead");
1430
            leadActivity.setSchelduleTimestamp(null);
31370 tejbeer 1431
 
32464 tejbeer 1432
            leadActivity.setCreatedTimestamp(LocalDateTime.now());
1433
            leadActivityRepository.persist(leadActivity);
1434
            model.addAttribute("response1", mvcResponseSender.createResponseString(true));
31370 tejbeer 1435
 
32464 tejbeer 1436
        }
31370 tejbeer 1437
 
32464 tejbeer 1438
        model.addAttribute("responseSTG", mvcResponseSender.createResponseString(true));
31370 tejbeer 1439
 
32464 tejbeer 1440
        return "response";
31370 tejbeer 1441
 
32464 tejbeer 1442
    }
31370 tejbeer 1443
 
32464 tejbeer 1444
    @RequestMapping(value = "/teamCommitment", method = RequestMethod.GET)
1445
    public String teamCommitments(HttpServletRequest request, Model model) throws Exception {
31370 tejbeer 1446
 
32464 tejbeer 1447
        return "team-commitment";
31370 tejbeer 1448
 
32464 tejbeer 1449
    }
31370 tejbeer 1450
 
32464 tejbeer 1451
    @RequestMapping(value = "/leadDetail", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
1452
    public String leadDetail(HttpServletRequest request, @RequestBody LeadDetailModel leadDetailModel, Model model) throws Exception {
31370 tejbeer 1453
 
32464 tejbeer 1454
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
1455
        AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
31370 tejbeer 1456
 
32471 tejbeer 1457
        leadRepository.persistLeadDetail(leadDetailModel, authUser);
32464 tejbeer 1458
        model.addAttribute("response1", mvcResponseSender.createResponseString(true));
31370 tejbeer 1459
 
32464 tejbeer 1460
        return "response";
31370 tejbeer 1461
 
32464 tejbeer 1462
    }
31370 tejbeer 1463
 
32464 tejbeer 1464
    @RequestMapping(value = "/getLeadDetail", method = RequestMethod.GET)
1465
    public String getLeadDetail(HttpServletRequest request, Model model) throws Exception {
1466
        List<Integer> followUpleadIds = leadRepository.selectAllByStatus(LeadStatus.followUp).stream().map(x -> x.getId()).collect(Collectors.toList());
1467
        List<LeadDetail> leadDetails = leadDetailRepository.selectByLeadIds(followUpleadIds);
31370 tejbeer 1468
 
32464 tejbeer 1469
        List<DBObject> mobileBrands = mongoClient.getAllBrandsToDisplay(3);
31370 tejbeer 1470
 
32464 tejbeer 1471
        List<String> brands = mobileBrands.stream().map(x -> (String) x.get("name")).collect(Collectors.toList());
31370 tejbeer 1472
 
32464 tejbeer 1473
        model.addAttribute("brands", brands);
1474
        if (!leadDetails.isEmpty()) {
31370 tejbeer 1475
 
32464 tejbeer 1476
            List<Integer> detailsIds = leadDetails.stream().map(x -> x.getId()).collect(Collectors.toList());
31370 tejbeer 1477
 
32464 tejbeer 1478
            List<Integer> leadIds = leadDetails.stream().map(x -> x.getLeadId()).collect(Collectors.toList());
31370 tejbeer 1479
 
32464 tejbeer 1480
            Map<Integer, Lead> leadMap = leadRepository.selectAllByIds(leadIds).stream().filter(x -> x.getStatus().equals(LeadStatus.followUp)).collect(Collectors.toMap(x -> x.getId(), x -> x));
31370 tejbeer 1481
 
32464 tejbeer 1482
            Map<Integer, Optional<LeadActivity>> leadActivityMap = leadActivityRepository.selectAllByleadIds(leadIds).stream().collect(Collectors.groupingBy(x -> x.getLeadId(), Collectors.maxBy(Comparator.comparing(LeadActivity::getId))));
31370 tejbeer 1483
 
32464 tejbeer 1484
            model.addAttribute("leadActivityMap", leadActivityMap);
30185 tejbeer 1485
 
32464 tejbeer 1486
            List<LeadBrand> leadBrands = leadBrandRepository.selectByLeadDetailId(detailsIds);
30185 tejbeer 1487
 
32464 tejbeer 1488
            LOGGER.info("leadBrands {}" + leadBrands);
30185 tejbeer 1489
 
32464 tejbeer 1490
            Map<Integer, Map<String, Integer>> leadDetailBrandValue = new HashMap<>();
30416 tejbeer 1491
 
32464 tejbeer 1492
            Map<Integer, List<LeadBrand>> leadDetail = leadBrands.stream().collect(Collectors.groupingBy(x -> x.getLeadDetailId(), Collectors.toList()));
30416 tejbeer 1493
 
32464 tejbeer 1494
            for (Entry<Integer, List<LeadBrand>> leadDetailEntry : leadDetail.entrySet()) {
30416 tejbeer 1495
 
32464 tejbeer 1496
                Map<String, Integer> brandValue = new HashMap<>();
30416 tejbeer 1497
 
32464 tejbeer 1498
                for (LeadBrand leadBrand : leadDetailEntry.getValue()) {
1499
                    brandValue.put(leadBrand.getBrand(), leadBrand.getValue());
30416 tejbeer 1500
 
32464 tejbeer 1501
                }
1502
                leadDetailBrandValue.put(leadDetailEntry.getKey(), brandValue);
1503
            }
30416 tejbeer 1504
 
32464 tejbeer 1505
            LOGGER.info("leadDetailBrandValue {}" + leadDetailBrandValue);
30416 tejbeer 1506
 
32464 tejbeer 1507
            model.addAttribute("leadDetailBrandValue", leadDetailBrandValue);
30416 tejbeer 1508
 
32464 tejbeer 1509
            model.addAttribute("leadMap", leadMap);
1510
        }
30434 tejbeer 1511
 
32464 tejbeer 1512
        model.addAttribute("leadDetails", leadDetails);
30434 tejbeer 1513
 
32464 tejbeer 1514
        Map<Integer, AuthUser> authIdAndAuthUserMap = authRepository.selectAllActiveUser().stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
1515
        model.addAttribute("authIdAndAuthUserMap", authIdAndAuthUserMap);
30434 tejbeer 1516
 
32464 tejbeer 1517
        return "lead-detail";
30458 tejbeer 1518
 
32464 tejbeer 1519
    }
30458 tejbeer 1520
 
32464 tejbeer 1521
    @RequestMapping(value = "/getLeadDetailByLeadId", method = RequestMethod.GET)
35548 aman 1522
    public ResponseEntity<?> getLeadDetailByLeadId(@RequestParam int leadId) {
30458 tejbeer 1523
 
35548 aman 1524
        Lead lead = leadRepository.selectById(leadId);
32464 tejbeer 1525
        LeadDetail leadDetail = leadDetailRepository.selectByLeadId(leadId);
35548 aman 1526
        Map<String, Object> response = new HashMap<>();
1527
        response.put("city", lead.getCity());
1528
        response.put("state", lead.getState());
1529
        if (leadDetail != null) {
1530
            response.put("outletName", leadDetail.getOutletName());
1531
            response.put("counterSize", leadDetail.getCounterSize());
1532
        }
1533
        return responseSender.ok(response);
1534
    }
30458 tejbeer 1535
 
35548 aman 1536
    @PostMapping("/upload-assign-id")
1537
    public ResponseEntity<?> uploadAssignIdCsv(
1538
            @RequestParam("file") MultipartFile file)
1539
            throws Exception {
1540
 
1541
        try (Reader reader = new InputStreamReader(file.getInputStream());
1542
             CSVParser parser = new CSVParser(reader, CSVFormat.DEFAULT)) {
1543
 
1544
            List<CSVRecord> records = parser.getRecords();
1545
 
1546
            if (records.size() < 2) {
1547
                throw new ProfitMandiBusinessException(
1548
                        "Uploaded File", "", "No records Found");
1549
            }
1550
 
1551
            records.remove(0);
1552
 
1553
            for (CSVRecord record : records) {
1554
 
1555
                int leadId = Integer.parseInt(record.get(0));
1556
                int assignId = Integer.parseInt(record.get(1));
1557
 
1558
                Lead lead = leadRepository.selectById(leadId);
1559
 
1560
                if (lead == null) {
1561
                    LOGGER.warn("Lead not found for id {}", leadId);
1562
                    continue;
1563
                }
1564
 
1565
                lead.setAssignTo(assignId);
1566
            }
1567
        }
1568
 
1569
        return responseSender.ok("CSV processed successfully");
32464 tejbeer 1570
    }
30434 tejbeer 1571
 
35548 aman 1572
 
1573
 
32464 tejbeer 1574
    @RequestMapping(value = "/getTeamCommitment", method = RequestMethod.GET)
1575
    public String getTeamCommitments(HttpServletRequest request, @RequestParam LocalDateTime date, Model model) throws Exception {
30781 tejbeer 1576
 
32464 tejbeer 1577
        List<TeamCommitmentModel> commitments = partnerCollectionPlanRepository.selectTeamCommitmentByDate(date.toLocalDate());
30416 tejbeer 1578
 
32464 tejbeer 1579
        model.addAttribute("commitments", commitments);
1580
        return "team-commitment-table";
30416 tejbeer 1581
 
32464 tejbeer 1582
    }
30416 tejbeer 1583
 
33917 ranu 1584
    @Autowired
1585
    RbmTargetService rbmTargetService;
1586
 
1587
    @RequestMapping(value = "/rbmTodayArr", method = RequestMethod.GET)
1588
    public String getRbmTodayArr(HttpServletRequest request, Model model, @RequestParam(value = "startDate", required = false) LocalDate startDate) throws Exception {
1589
        List<RbmArrViewModel> rbmArrViewModels;
35223 ranu 1590
        DecimalFormat decimalFormat = new DecimalFormat("#"); // No decimal places
33917 ranu 1591
        if (startDate != null) {
1592
            rbmArrViewModels = rbmTargetService.getRbmTodayArr(startDate);
1593
        } else {
1594
            rbmArrViewModels = rbmTargetService.getRbmTodayArr();
1595
        }
1596
 
35223 ranu 1597
        Set<AuthUser> authUsers = new HashSet<>();
1598
        Set<AuthUser> rbmAuthUsers = csService.getAuthUserByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_RBM, EscalationType.L1).stream().filter(x -> x.isActive()).collect(Collectors.toSet());
1599
        Set<AuthUser> salesAuthUsers = csService.getAuthUserIds(ProfitMandiConstants.TICKET_CATEGORY_RBM, Arrays.asList(EscalationType.L1, EscalationType.L2)).stream().filter(x -> x.isActive()).collect(Collectors.toSet());
33953 ranu 1600
 
35223 ranu 1601
        authUsers.addAll(rbmAuthUsers);
1602
        authUsers.addAll(salesAuthUsers);
33953 ranu 1603
 
35223 ranu 1604
        double totalAchieved = rbmArrViewModels.stream().mapToDouble(RbmArrViewModel::getTotalAchievedTarget).sum();
1605
        double totalTargetSum = rbmArrViewModels.stream().mapToLong(RbmArrViewModel::getTodayTarget).sum();
1606
 
1607
        double totalHidSum = rbmArrViewModels.stream().mapToLong(RbmArrViewModel::getTodayHidTarget).sum();
1608
        double totalHidAchievedSum = rbmArrViewModels.stream().mapToLong(RbmArrViewModel::getTodayAchievedHidTarget).sum();
1609
 
1610
        double totalFastSum = rbmArrViewModels.stream().mapToLong(RbmArrViewModel::getTodayFastMovingTarget).sum();
1611
        double totalFastAchievedSum = rbmArrViewModels.stream().mapToLong(RbmArrViewModel::getTodayAchievedFastMovingTarget).sum();
1612
 
1613
        double totalSlowSum = rbmArrViewModels.stream().mapToLong(RbmArrViewModel::getTodaySlowMovingTarget).sum();
1614
        double totalSlowAchievedSum = rbmArrViewModels.stream().mapToLong(RbmArrViewModel::getTodayAchievedSlowMovingTarget).sum();
1615
 
1616
        double totalRunningSum = rbmArrViewModels.stream().mapToLong(RbmArrViewModel::getTodayRunningTarget).sum();
1617
        double totalRunningAchievedSum = rbmArrViewModels.stream().mapToLong(RbmArrViewModel::getTodayAchievedRunningTarget).sum();
1618
 
1619
        double totalOtherSum = rbmArrViewModels.stream().mapToLong(RbmArrViewModel::getTodayOtherMovingTarget).sum();
1620
        double totalOtherAchievedSum = rbmArrViewModels.stream().mapToLong(RbmArrViewModel::getTodayAchievedOtherMovingTarget).sum();
1621
 
34055 ranu 1622
        List<Sold15daysOldAgingModel> sold15daysOldAgingModels = rbmTargetService.getAgingSale(LocalDate.now(), LocalDate.now().plusDays(1));
1623
        List<Our15DaysOldAgingStock> our15DaysOldAgingStocks = rbmTargetService.our15DaysAgingStock();
1624
 
35223 ranu 1625
        long totalSoldSlow = sold15daysOldAgingModels.stream().mapToLong(Sold15daysOldAgingModel::getSlowmovingBilled).sum();
1626
        long totalSoldRun = sold15daysOldAgingModels.stream().mapToLong(Sold15daysOldAgingModel::getRunningBilled).sum();
1627
        long totalSoldFast = sold15daysOldAgingModels.stream().mapToLong(Sold15daysOldAgingModel::getFastmovingBilled).sum();
1628
        long totalSoldHid = sold15daysOldAgingModels.stream().mapToLong(Sold15daysOldAgingModel::getHidBilled).sum();
1629
        long totalSoldOther = sold15daysOldAgingModels.stream().mapToLong(Sold15daysOldAgingModel::getOthersBilled).sum();
1630
        long totalSoldAging = sold15daysOldAgingModels.stream().mapToLong(Sold15daysOldAgingModel::getTotalBilled).sum();
34103 ranu 1631
 
35223 ranu 1632
 
34103 ranu 1633
//        first week count of rbm partner billing
1634
        LocalDate firstOfCurrentMonth = LocalDate.now().withDayOfMonth(1);
1635
        LocalDate seventhOfCurrentMonth = LocalDate.now().withDayOfMonth(7);
1636
 
1637
        List<RbmBilledFofoIdsModel> rbmBilledFofoIdsModelsFirstWeek = rbmTargetService.getDateWiseBilledFofoIdByRbm(firstOfCurrentMonth, seventhOfCurrentMonth);
1638
 
1639
        Map<String, Long> rbmBilledCountMapFirstWeek = rbmBilledFofoIdsModelsFirstWeek.stream()
1640
                .filter(x -> x.getStatus().equals("Billed"))
1641
                .collect(Collectors.groupingBy(RbmBilledFofoIdsModel::getRbmName, Collectors.counting()));
1642
 
34119 ranu 1643
        long totalFirstWeekCount = rbmBilledCountMapFirstWeek.values().stream()
1644
                .mapToLong(Long::longValue)
1645
                .sum();
1646
 
34114 ranu 1647
        Map<String, Long> rbmTargetedFofoIdCountMap = rbmBilledFofoIdsModelsFirstWeek.stream()
1648
                .collect(Collectors.groupingBy(
1649
                        RbmBilledFofoIdsModel::getRbmName, // Group by RBM Name
1650
                        Collectors.counting() // Count all fofoId entries for each RBM
1651
                ));
34103 ranu 1652
 
34119 ranu 1653
        long totalTargetedCount = rbmTargetedFofoIdCountMap.values().stream().mapToLong(x -> x.longValue()).sum();
34114 ranu 1654
 
1655
 
34103 ranu 1656
//        second week count of rbm partner billing
1657
 
1658
        LocalDate eightOfCurrentMonth = LocalDate.now().withDayOfMonth(8);
1659
        LocalDate fifteenOfCurrentMonth = LocalDate.now().withDayOfMonth(15);
1660
 
1661
        List<RbmBilledFofoIdsModel> rbmBilledFofoIdsModelsSecondWeek = rbmTargetService.getDateWiseBilledFofoIdByRbm(eightOfCurrentMonth, fifteenOfCurrentMonth);
1662
 
1663
        Map<String, Long> rbmBilledCountMapSecondWeek = rbmBilledFofoIdsModelsSecondWeek.stream()
1664
                .filter(x -> x.getStatus().equals("Billed"))
1665
                .collect(Collectors.groupingBy(RbmBilledFofoIdsModel::getRbmName, Collectors.counting()));
1666
 
34119 ranu 1667
        long totalSecondWeekCount = rbmBilledCountMapSecondWeek.values().stream().mapToLong(Long::longValue).sum();
34103 ranu 1668
 
1669
//      third week count of rbm partner billing
1670
 
1671
        LocalDate sixteenOfCurrentMonth = LocalDate.now().withDayOfMonth(16);
34144 ranu 1672
        LocalDate twentySecondOfCurrentMonth = LocalDate.now().withDayOfMonth(22);
34103 ranu 1673
 
34144 ranu 1674
        List<RbmBilledFofoIdsModel> rbmBilledFofoIdsModelsThirdWeek = rbmTargetService.getDateWiseBilledFofoIdByRbm(sixteenOfCurrentMonth, twentySecondOfCurrentMonth);
34103 ranu 1675
 
1676
        Map<String, Long> rbmBilledCountMapThirdWeek = rbmBilledFofoIdsModelsThirdWeek.stream()
1677
                .filter(x -> x.getStatus().equals("Billed"))
1678
                .collect(Collectors.groupingBy(RbmBilledFofoIdsModel::getRbmName, Collectors.counting()));
1679
 
34119 ranu 1680
        long totalThirdWeekCount = rbmBilledCountMapThirdWeek.values().stream().mapToLong(Long::longValue).sum();
34103 ranu 1681
 
34119 ranu 1682
 
34103 ranu 1683
        //      fourth week count of rbm partner billing
1684
 
34144 ranu 1685
        LocalDate twentyThirdOfCurrentMonth = LocalDate.now().withDayOfMonth(23);
34103 ranu 1686
        LocalDate lastDayOfCurrentMonth = LocalDate.now().withDayOfMonth(LocalDate.now().lengthOfMonth());
1687
 
34144 ranu 1688
        List<RbmBilledFofoIdsModel> rbmBilledFofoIdsModelsFourthWeek = rbmTargetService.getDateWiseBilledFofoIdByRbm(twentyThirdOfCurrentMonth, lastDayOfCurrentMonth);
34103 ranu 1689
 
1690
        Map<String, Long> rbmBilledCountMapFourthWeek = rbmBilledFofoIdsModelsFourthWeek.stream()
1691
                .filter(x -> x.getStatus().equals("Billed"))
1692
                .collect(Collectors.groupingBy(RbmBilledFofoIdsModel::getRbmName, Collectors.counting()));
1693
 
34119 ranu 1694
        long totalFourthWeekCount = rbmBilledCountMapFourthWeek.values().stream().mapToLong(x -> x.longValue()).sum();
34103 ranu 1695
 
34119 ranu 1696
 
34103 ranu 1697
//      mtd rbm partner billing
1698
 
1699
        List<RbmBilledFofoIdsModel> rbmBilledFofoIdsModelsMtd = rbmTargetService.getDateWiseBilledFofoIdByRbm(firstOfCurrentMonth, LocalDate.now());
1700
 
1701
        Map<String, Long> rbmBilledCountMapMtd = rbmBilledFofoIdsModelsMtd.stream()
1702
                .filter(x -> x.getStatus().equals("Billed"))
1703
                .collect(Collectors.groupingBy(RbmBilledFofoIdsModel::getRbmName, Collectors.counting()));
1704
 
34119 ranu 1705
        long totalMtdCount = rbmBilledCountMapMtd.values().stream().mapToLong(Long::longValue).sum();
1706
 
1707
        Map<String, Long> zeroBilledCountMap = rbmTargetedFofoIdCountMap.entrySet().stream()
1708
                .collect(Collectors.toMap(
1709
                        Map.Entry::getKey,
1710
                        entry -> entry.getValue() - rbmBilledCountMapMtd.getOrDefault(entry.getKey(), 0L)
1711
                ));
1712
 
1713
        long totalZeroBilledCount = zeroBilledCountMap.values().stream().mapToLong(Long::longValue).sum();
1714
 
36101 ranu 1715
        //        rbmRating by franchisee visits (weekly: Monday to Sunday)
35223 ranu 1716
 
1717
        Map<Integer, String> rbmIdToNameMap = authUsers.stream()
1718
                .collect(Collectors.toMap(AuthUser::getId, AuthUser::getFullName));
1719
 
36101 ranu 1720
        // Calculate current week: Monday (start) to Sunday (end)
1721
        LocalDate today = LocalDate.now();
1722
        LocalDate monday = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
1723
        LocalDate sunday = today.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
1724
        LocalDateTime weekStart = monday.atStartOfDay();
1725
        LocalDateTime weekEnd = sunday.atTime(LocalTime.MAX);
1726
 
35223 ranu 1727
        Map<String, RbMRatingModel> rbmNameToRatingMap = rbmRatingRepository
36101 ranu 1728
                .findAverageRatingByRbmIdAndDateRange(new ArrayList<>(rbmIdToNameMap.keySet()), weekStart, weekEnd)
1729
                .stream().collect(Collectors.toMap(
35223 ranu 1730
                        x -> rbmIdToNameMap.get(x.getRbmId()),
1731
                        x -> x
1732
                ));
1733
 
1734
 
33917 ranu 1735
        LOGGER.info("rbmArrViewModels {}", rbmArrViewModels);
1736
        model.addAttribute("rbmArrViewModels", rbmArrViewModels);
35223 ranu 1737
        model.addAttribute("rbmNameToRatingMap", rbmNameToRatingMap);
1738
 
1739
        model.addAttribute("totalTargetSum", decimalFormat.format(totalTargetSum));
1740
        model.addAttribute("totalAchieved", decimalFormat.format(totalAchieved));
1741
 
1742
        model.addAttribute("totalHidSum", decimalFormat.format(totalHidSum));
1743
        model.addAttribute("totalHidAchievedSum", decimalFormat.format(totalHidAchievedSum));
1744
 
1745
        model.addAttribute("totalFastSum", decimalFormat.format(totalFastSum));
1746
        model.addAttribute("totalFastAchievedSum", decimalFormat.format(totalFastAchievedSum));
1747
 
1748
        model.addAttribute("totalSlowSum", decimalFormat.format(totalSlowSum));
1749
        model.addAttribute("totalSlowAchievedSum", decimalFormat.format(totalSlowAchievedSum));
1750
 
1751
        model.addAttribute("totalRunningSum", decimalFormat.format(totalRunningSum));
1752
        model.addAttribute("totalRunningAchievedSum", decimalFormat.format(totalRunningAchievedSum));
1753
 
1754
        model.addAttribute("totalOtherSum", decimalFormat.format(totalOtherSum));
1755
        model.addAttribute("totalOtherAchievedSum", decimalFormat.format(totalOtherAchievedSum));
1756
 
1757
        model.addAttribute("our15DaysOldAgingStocks", our15DaysOldAgingStocks);
34055 ranu 1758
        model.addAttribute("sold15daysOldAgingModels", sold15daysOldAgingModels);
35223 ranu 1759
        model.addAttribute("totalSoldSlow", totalSoldSlow);
1760
        model.addAttribute("totalSoldRun", totalSoldRun);
1761
        model.addAttribute("totalSoldFast", totalSoldFast);
1762
        model.addAttribute("totalSoldHid", totalSoldHid);
1763
        model.addAttribute("totalSoldOther", totalSoldOther);
1764
        model.addAttribute("totalSoldAging", totalSoldAging);
33917 ranu 1765
 
34114 ranu 1766
        model.addAttribute("rbmTargetedFofoIdCountMap", rbmTargetedFofoIdCountMap);
34103 ranu 1767
        model.addAttribute("rbmBilledCountMapFirstWeek", rbmBilledCountMapFirstWeek);
1768
        model.addAttribute("rbmBilledCountMapSecondWeek", rbmBilledCountMapSecondWeek);
1769
        model.addAttribute("rbmBilledCountMapThirdWeek", rbmBilledCountMapThirdWeek);
1770
        model.addAttribute("rbmBilledCountMapFourthWeek", rbmBilledCountMapFourthWeek);
1771
        model.addAttribute("rbmBilledCountMapMtd", rbmBilledCountMapMtd);
34119 ranu 1772
        model.addAttribute("zeroBilledCountMap", zeroBilledCountMap);
1773
        model.addAttribute("totalFirstWeekCount", totalFirstWeekCount);
1774
        model.addAttribute("totalTargetedCount", totalTargetedCount);
1775
        model.addAttribute("totalSecondWeekCount", totalSecondWeekCount);
1776
        model.addAttribute("totalThirdWeekCount", totalThirdWeekCount);
1777
        model.addAttribute("totalFourthWeekCount", totalFourthWeekCount);
1778
        model.addAttribute("totalMtdCount", totalMtdCount);
1779
        model.addAttribute("totalZeroBilledCount", totalZeroBilledCount);
34103 ranu 1780
 
33917 ranu 1781
        return "rbm-today-arr";
1782
    }
1783
 
1784
 
32464 tejbeer 1785
    @RequestMapping(value = "/partnerHealth", method = RequestMethod.GET)
1786
    public String partnerHealth(HttpServletRequest request, @RequestParam(name = "email", required = false) String email, Model model) throws Exception {
1787
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
30416 tejbeer 1788
 
32464 tejbeer 1789
        if (StringUtils.isEmpty(email)) {
1790
            email = loginDetails.getEmailId();
1791
        } else {
1792
            AuthUser selectedUser = authRepository.selectByEmailOrMobile(email);
30416 tejbeer 1793
 
32464 tejbeer 1794
            model.addAttribute("selectedUser", selectedUser);
30445 tejbeer 1795
 
32464 tejbeer 1796
        }
30445 tejbeer 1797
 
32464 tejbeer 1798
        AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
30445 tejbeer 1799
 
32464 tejbeer 1800
        Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMapping();
1801
        List<Integer> fofoIds = new ArrayList<>(storeGuyMap.get(email));
1802
        LocalDateTime startDate = LocalDate.now().atStartOfDay();
1803
        if (fofoIds != null && fofoIds.size() > 0) {
1804
            List<Integer> fofoIdList = fofoStoreRepository.selectByRetailerIds(fofoIds).stream().filter(x -> !x.isInternal()).map(x -> x.getId()).collect(Collectors.toList());
30420 tejbeer 1805
 
32464 tejbeer 1806
            Map<Integer, PartnerCollectionPlanModel> foundCollectionMap = partnerCollectionService.getCollectionMap(fofoIdList, startDate);
30416 tejbeer 1807
 
32464 tejbeer 1808
            List<Integer> remarkIds = partnerCollectionRemarkRepository.selectMaxRemarkId(fofoIdList);
30416 tejbeer 1809
 
32464 tejbeer 1810
            LOGGER.info("remarkIds {}", remarkIds);
30416 tejbeer 1811
 
32464 tejbeer 1812
            long todayOverallCall = 0;
1813
            if (!remarkIds.isEmpty()) {
30416 tejbeer 1814
 
32464 tejbeer 1815
                if (authUser.getEmailId().equals(email)) {
30441 tejbeer 1816
 
32464 tejbeer 1817
                    todayOverallCall = partnerCollectionRemarkRepository.selectByIds(remarkIds).stream().filter(x -> x.getCreateTimestamp().toLocalDate().equals(LocalDate.now())).collect(Collectors.counting());
1818
                } else {
30441 tejbeer 1819
 
32464 tejbeer 1820
                    todayOverallCall = partnerCollectionRemarkRepository.selectByAuthIdAndIds(authRepository.selectByEmailOrMobile(email).getId(), remarkIds).stream().filter(x -> x.getCreateTimestamp().toLocalDate().equals(LocalDate.now())).collect(Collectors.counting());
30416 tejbeer 1821
 
32464 tejbeer 1822
                }
30416 tejbeer 1823
 
32464 tejbeer 1824
            }
1825
            ChartLeadModel cm = new ChartLeadModel();
30416 tejbeer 1826
 
32464 tejbeer 1827
            if (!foundCollectionMap.isEmpty()) {
1828
                cm = this.getCollectionCount(foundCollectionMap.values().stream().collect(Collectors.toList()));
30416 tejbeer 1829
 
32464 tejbeer 1830
            }
1831
            model.addAttribute("chartPartnerHealth", gson.toJson(cm));
1832
            Map<Integer, PartnerDailyInvestment> partnerDailyInvestmentMap = new HashMap<>();
30416 tejbeer 1833
 
32464 tejbeer 1834
            List<PartnerDailyInvestment> partnerDailyInvestments = partnerDailyInvestmentRepository.selectAll(fofoIdList, startDate.toLocalDate().minusDays(1));
1835
            if (!partnerDailyInvestments.isEmpty()) {
1836
                partnerDailyInvestmentMap = partnerDailyInvestments.stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
1837
            }
30416 tejbeer 1838
 
32464 tejbeer 1839
            Map<LocalDate, Map<Integer, PartnerCollectionPlanModel>> pcpmMap = new TreeMap<>();
1840
            for (int i = 0; i <= 6; i++) {
30416 tejbeer 1841
 
32464 tejbeer 1842
                Map<Integer, PartnerCollectionPlanModel> collectionMap = partnerCollectionService.getCollectionMap(fofoIdList, startDate.minusDays(i));
30416 tejbeer 1843
 
32464 tejbeer 1844
                pcpmMap.put(startDate.minusDays(i).toLocalDate(), collectionMap);
1845
            }
30416 tejbeer 1846
 
32464 tejbeer 1847
            Map<Integer, PartnerCollectionPlanModel> todayPcpmMap = pcpmMap.get(startDate.toLocalDate());
1848
            model.addAttribute("todayPcpmMap", todayPcpmMap);
30416 tejbeer 1849
 
32464 tejbeer 1850
            TotalTargetColectionModel totalTargetCollection = partnerCollectionService.getTotalTargetCollection(todayPcpmMap, startDate);
1851
            model.addAttribute("totalPartnerTargetCollection", totalTargetCollection.getTotalTarget());
30416 tejbeer 1852
 
32464 tejbeer 1853
            model.addAttribute("totalPartnerAchievement", totalTargetCollection.getTotalAchievement());
30416 tejbeer 1854
 
32464 tejbeer 1855
            Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();
1856
            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));
1857
            List<Integer> allReportees = authService.getAllReportees(authUser.getId());
30416 tejbeer 1858
 
32464 tejbeer 1859
            List<Integer> salesPositionsAuthIds = positionRepository.selectPositionByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_SALES).stream().map(x -> x.getAuthUserId()).collect(Collectors.toList());
1860
            List<Integer> rbmPositionsAuthIds = positionRepository.selectPositionByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_RBM).stream().map(x -> x.getAuthUserId()).collect(Collectors.toList());
30416 tejbeer 1861
 
32464 tejbeer 1862
            salesPositionsAuthIds.addAll(rbmPositionsAuthIds);
30416 tejbeer 1863
 
32464 tejbeer 1864
            Set<Integer> empHierarchy = allReportees.stream().filter(x -> salesPositionsAuthIds.contains(x)).collect(Collectors.toSet());
34027 ranu 1865
            List<AuthUser> authUsers = new ArrayList<>();
1866
            if (!empHierarchy.isEmpty()) {
35395 amit 1867
                authUsers = authRepository.selectByIds(new ArrayList<>(empHierarchy));
34027 ranu 1868
            }
30416 tejbeer 1869
 
1870
 
32464 tejbeer 1871
            Map<Integer, AuthUser> authUserMap = authRepository.selectAll().stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
30416 tejbeer 1872
 
32464 tejbeer 1873
            LOGGER.info("todayPcpmMap {}", todayPcpmMap);
30416 tejbeer 1874
 
32464 tejbeer 1875
            model.addAttribute("authUsers", authUsers);
1876
            model.addAttribute("authUserMap", authUserMap);
1877
            model.addAttribute("partnerCollectionPlanMap", pcpmMap);
1878
            model.addAttribute("partnerDailyInvestmentMap", partnerDailyInvestmentMap);
1879
            model.addAttribute("customRetailers", customRetailers);
1880
            model.addAttribute("rankColorMap", ProfitMandiConstants.Rank_Color_Map);
1881
            model.addAttribute("todayOverallCall", todayOverallCall);
30522 tejbeer 1882
 
32464 tejbeer 1883
        }
1884
        return "partner-health";
30522 tejbeer 1885
 
32464 tejbeer 1886
    }
30522 tejbeer 1887
 
32464 tejbeer 1888
    public ChartLeadModel getCollectionCount(List<PartnerCollectionPlanModel> pcpm) throws ProfitMandiBusinessException {
30522 tejbeer 1889
 
32464 tejbeer 1890
        Map<Integer, Long> rankCount = pcpm.stream().collect(Collectors.groupingBy(x -> x.getRank(), Collectors.mapping(PartnerCollectionPlanModel::getRank, Collectors.counting())));
30522 tejbeer 1891
 
32464 tejbeer 1892
        ChartLeadModel cm = new ChartLeadModel();
30522 tejbeer 1893
 
32464 tejbeer 1894
        List<String> labels = new ArrayList<>();
1895
        labels.add("Plan for Today");
1896
        labels.add("Carry Forward");
1897
        labels.add("Untouched");
1898
        labels.add("Plan for Future");
1899
        labels.add("Normal");
30522 tejbeer 1900
 
32464 tejbeer 1901
        List<String> backgroundColor = new ArrayList<>();
1902
        List<Long> values = new ArrayList<>();
30522 tejbeer 1903
 
32464 tejbeer 1904
        for (String label : labels) {
30522 tejbeer 1905
 
32464 tejbeer 1906
            if (label.equals("Plan for Today")) {
1907
                backgroundColor.add("#007bff");
1908
                values.add(rankCount.get(1));
1909
            }
1910
            if (label.equals("Carry Forward")) {
1911
                backgroundColor.add("#ffc107");
1912
                values.add(rankCount.get(2));
1913
            }
1914
            if (label.equals("Untouched")) {
1915
                backgroundColor.add("#dc3545");
1916
                values.add(rankCount.get(3));
1917
            }
1918
            if (label.equals("Plan for Future")) {
1919
                backgroundColor.add("#6c757d");
1920
                values.add(rankCount.get(4));
1921
            }
1922
            if (label.equals("Normal")) {
1923
                backgroundColor.add("White");
1924
                values.add(rankCount.get(5));
1925
            }
30522 tejbeer 1926
 
32464 tejbeer 1927
        }
30522 tejbeer 1928
 
32464 tejbeer 1929
        LOGGER.info("backgroundColor" + backgroundColor);
1930
        LOGGER.info("labelsChartLead" + labels);
1931
        LeadStatusData data = new LeadStatusData();
1932
        data.setData(values);
1933
        data.setBackgroundColor(backgroundColor);
1934
        data.setLabel("DataSet 1");
30522 tejbeer 1935
 
32464 tejbeer 1936
        PieLables label = new PieLables();
1937
        label.setFontColor("black");
1938
        label.setFontSize(15);
30522 tejbeer 1939
 
32464 tejbeer 1940
        Legend legend = new Legend();
1941
        legend.setLabels(label);
1942
        legend.setPosition("left");
30522 tejbeer 1943
 
32464 tejbeer 1944
        List<LeadStatusData> dataList = new ArrayList<>();
1945
        dataList.add(data);
30522 tejbeer 1946
 
32464 tejbeer 1947
        DataLeadModel datasets = new DataLeadModel();
1948
        datasets.setDatasets(dataList);
1949
        datasets.setLabels(labels);
30522 tejbeer 1950
 
32464 tejbeer 1951
        OptionModel om = new OptionModel();
1952
        om.setLegend(legend);
30522 tejbeer 1953
 
32464 tejbeer 1954
        cm.setType("pie");
1955
        cm.setData(datasets);
1956
        cm.setOptions(om);
30522 tejbeer 1957
 
32464 tejbeer 1958
        return cm;
1959
    }
30522 tejbeer 1960
 
32464 tejbeer 1961
    @RequestMapping(value = "/franchiseVisit", method = RequestMethod.GET)
1962
    public String franchiseVisit(HttpServletRequest request, @RequestParam(name = "email", required = false) String email, Model model) throws Exception {
1963
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
30522 tejbeer 1964
 
32464 tejbeer 1965
        AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
30522 tejbeer 1966
 
32464 tejbeer 1967
        List<Integer> salesPositionsAuthIds = positionRepository.selectPositionByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_SALES).stream().map(x -> x.getAuthUserId()).collect(Collectors.toList());
1968
        List<Integer> rbmPositionsAuthIds = positionRepository.selectPositionByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_RBM).stream().map(x -> x.getAuthUserId()).collect(Collectors.toList());
30522 tejbeer 1969
 
32464 tejbeer 1970
        salesPositionsAuthIds.addAll(rbmPositionsAuthIds);
30522 tejbeer 1971
 
32464 tejbeer 1972
        List<Integer> allReportees = authService.getAllReportees(authUser.getId());
30522 tejbeer 1973
 
32464 tejbeer 1974
        Set<Integer> empHierarchy = allReportees.stream().filter(x -> salesPositionsAuthIds.contains(x)).collect(Collectors.toSet());
30522 tejbeer 1975
 
35395 amit 1976
        List<AuthUser> authUsers = authRepository.selectByIds(new ArrayList<>(empHierarchy));
30522 tejbeer 1977
 
32464 tejbeer 1978
        Map<Integer, String> monthValueMap = new HashMap<>();
1979
        for (int i = 0; i <= 5; i++) {
1980
            LocalDateTime startOfMonth = LocalDateTime.now().withDayOfMonth(1).minusMonths(i);
1981
            monthValueMap.put(i, startOfMonth.format(DateTimeFormatter.ofPattern("MMM''uu")));
1982
        }
30522 tejbeer 1983
 
32464 tejbeer 1984
        model.addAttribute("authUsers", authUsers);
1985
        model.addAttribute("monthValueMap", monthValueMap);
30522 tejbeer 1986
 
32464 tejbeer 1987
        return "franchise-visit";
30522 tejbeer 1988
 
32464 tejbeer 1989
    }
30522 tejbeer 1990
 
32464 tejbeer 1991
    @RequestMapping(value = "/getFranchiseVisit", method = RequestMethod.GET)
1992
    public String getFranchiseVisit(HttpServletRequest request, @RequestParam(name = "authId", required = false) int authId, int yearMonth, Model model) throws Exception {
30522 tejbeer 1993
 
32464 tejbeer 1994
        LocalDateTime startDate = LocalDate.now().minusMonths(8).withDayOfMonth(1).atStartOfDay();
1995
        LocalDateTime endDate = startDate.plusMonths(1).withDayOfMonth(1).toLocalDate().atStartOfDay();
30522 tejbeer 1996
 
32464 tejbeer 1997
        DateRangeModel drm = DateRangeModel.of(startDate, endDate);
30522 tejbeer 1998
 
32464 tejbeer 1999
        List<FranchiseeVisit> visits = franchiseeVisitRepository.selectByAuthUserAndDateRange(drm, authId);
30522 tejbeer 2000
 
32464 tejbeer 2001
        if (!visits.isEmpty()) {
30522 tejbeer 2002
 
32464 tejbeer 2003
            Map<Integer, List<FranchiseeVisit>> franchiseeVisitMap = visits.stream().collect(Collectors.groupingBy(x -> x.getScheduleTimestamp().getDayOfMonth()));
30522 tejbeer 2004
 
32464 tejbeer 2005
            model.addAttribute("franchiseeVisitMap", franchiseeVisitMap);
30522 tejbeer 2006
 
32464 tejbeer 2007
        }
30771 amit.gupta 2008
 
32464 tejbeer 2009
        model.addAttribute("visits", visits);
2010
        model.addAttribute("monthLength", startDate.toLocalDate().lengthOfMonth());
30771 amit.gupta 2011
 
32464 tejbeer 2012
        // Calender
30771 amit.gupta 2013
 
32464 tejbeer 2014
        int Year = startDate.getYear(); // year
2015
        int startDayOfMonth = 5;
2016
        int spaces = startDayOfMonth;
30771 amit.gupta 2017
 
32464 tejbeer 2018
        int month = startDate.getMonthValue();
30771 amit.gupta 2019
 
32464 tejbeer 2020
        int[] days = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
30771 amit.gupta 2021
 
32464 tejbeer 2022
        LOGGER.info("visits {} ", visits);
30771 amit.gupta 2023
 
32464 tejbeer 2024
        if ((((Year % 4 == 0) && (Year % 100 != 0)) || (Year % 400 == 0)) && month == 2) {
2025
            days[month] = 29;
2026
        }
30771 amit.gupta 2027
 
32464 tejbeer 2028
        spaces = (days[month - 1] + spaces) % 7;
30771 amit.gupta 2029
 
32464 tejbeer 2030
        model.addAttribute("month", month);
2031
        model.addAttribute("spaces", spaces);
2032
        model.addAttribute("days", days);
30771 amit.gupta 2033
 
32464 tejbeer 2034
        return "franchise-visit-container";
30771 amit.gupta 2035
 
32464 tejbeer 2036
    }
31249 tejbeer 2037
 
32464 tejbeer 2038
    @RequestMapping(value = "/getFranchiseeActivity", method = RequestMethod.GET)
2039
    public String getFranchiseeActivity(HttpServletRequest request, int visitId, Model model) throws Exception {
31249 tejbeer 2040
 
32464 tejbeer 2041
        List<FranchiseeActivity> franchiseeActivities = franchiseeActivityRepository.selectByFranchiseeVisitId(visitId);
31249 tejbeer 2042
 
32464 tejbeer 2043
        FranchiseeVisit franchiseeVisit = franchiseeVisitRepository.selectById(visitId);
31249 tejbeer 2044
 
32464 tejbeer 2045
        Map<Integer, AuthUser> authIdAndAuthUserMap = authRepository.selectAll().stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
2046
        model.addAttribute("authIdAndAuthUserMap", authIdAndAuthUserMap);
31249 tejbeer 2047
 
32464 tejbeer 2048
        model.addAttribute("franchiseeVisit", franchiseeVisit);
2049
        model.addAttribute("franchiseeActivity", franchiseeActivities.get(0));
31249 tejbeer 2050
 
32464 tejbeer 2051
        return "franchie-visit-detail";
31249 tejbeer 2052
 
32464 tejbeer 2053
    }
31249 tejbeer 2054
 
32464 tejbeer 2055
    @RequestMapping(value = "/indent/today_target", method = RequestMethod.GET)
2056
    public String todayTarget(HttpServletRequest request, Model model) throws Exception {
2057
        List<RBMPerformanceSummaryModel> summaryModels = new ArrayList<>();
2058
        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());
2059
        Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMapping();
2060
        List<TeamCommitmentModel> teamCommitmentModels = partnerCollectionPlanRepository.selectTeamCommitmentByDate(LocalDate.now());
2061
        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())));
2062
        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())));
2063
        LocalDateTime startDate = LocalDate.now().atStartOfDay();
2064
        for (int rbmAuthId : rbmPositionsAuthIds) {
2065
            RBMPerformanceSummaryModel rbmPerformanceSummaryModel = new RBMPerformanceSummaryModel();
2066
            rbmPerformanceSummaryModel.setAuthId(rbmAuthId);
2067
            AuthUser authUser = authRepository.selectById(rbmAuthId);
2068
            rbmPerformanceSummaryModel.setAuthName(authUser.getFullName());
33844 ranu 2069
            List<Integer> fofoIds = new ArrayList<>(storeGuyMap.get(authUser.getEmailId()));
31249 tejbeer 2070
 
32464 tejbeer 2071
            if (fofoIds.size() > 0) {
2072
                fofoIds = fofoStoreRepository.selectByRetailerIds(fofoIds).stream().filter(x -> !x.isInternal()).map(x -> x.getId()).collect(Collectors.toList());
31249 tejbeer 2073
 
32464 tejbeer 2074
                /*
2075
                 * Map<Integer, PartnerCollectionPlanModel> foundCollectionMap =
2076
                 * partnerCollectionService .getCollectionMap(fofoIds, startDate);
2077
                 */
31249 tejbeer 2078
 
33844 ranu 2079
                List<Integer> remarkIds = partnerCollectionRemarkRepository.selectMaxRemarkId(fofoIds);
2080
 
32464 tejbeer 2081
                LOGGER.info("remarkIds {}", remarkIds);
31249 tejbeer 2082
 
32464 tejbeer 2083
                long todayOverallCall = 0;
2084
                if (!remarkIds.isEmpty()) {
2085
                    todayOverallCall = partnerCollectionRemarkRepository.selectByIds(remarkIds).stream().filter(x -> x.getCreateTimestamp().toLocalDate().equals(LocalDate.now())).collect(Collectors.counting());
31249 tejbeer 2086
 
32464 tejbeer 2087
                }
31249 tejbeer 2088
 
32464 tejbeer 2089
                Map<Integer, PartnerCollectionPlanModel> collectionMap = partnerCollectionService.getCollectionMap(fofoIds, startDate);
31249 tejbeer 2090
 
32464 tejbeer 2091
                ChartLeadModel cm = this.getCollectionCount(collectionMap.values().stream().collect(Collectors.toList()));
31249 tejbeer 2092
 
32464 tejbeer 2093
                long collectionTarget = collectionMap.values().stream().filter(x -> x.getTargetPlan() != null).collect(Collectors.summingLong(x -> x.getTargetPlan()));
2094
                long collection = collectionMap.values().stream().filter(
2095
                        x -> x.getTargetPlan() != null && x.getTargetPlan() != 0 && x.getAchievementPlan() != null).collect(Collectors.summingLong(x -> x.getAchievementPlan()));
2096
                rbmPerformanceSummaryModel.setChartLeadModel(cm);
2097
                rbmPerformanceSummaryModel.setPartnersCommunicated(todayOverallCall);
2098
                rbmPerformanceSummaryModel.setCollectionTarget(collectionTarget);
2099
                rbmPerformanceSummaryModel.setCollection(collection);
2100
                rbmPerformanceSummaryModel.setSecondaryTarget(rbmSecondaryTargetMap.get(rbmAuthId) == null ? 0 : rbmSecondaryTargetMap.get(rbmAuthId).floatValue());
2101
                rbmPerformanceSummaryModel.setSecondary(
2102
                        rbmSecondaryMap.get(rbmAuthId) == null ? 0 : rbmSecondaryMap.get(rbmAuthId).floatValue());
2103
                summaryModels.add(rbmPerformanceSummaryModel);
2104
                // cm.getData().getDatasets().get(0).getData().;
2105
                // cm.getData().getDatasets().get(0).getBackgroundColor();
2106
                // cm.getData().getLabels()
31249 tejbeer 2107
 
32464 tejbeer 2108
            }
2109
        }
2110
        model.addAttribute("summaryModels", summaryModels);
2111
        return "today_target";
2112
    }
31249 tejbeer 2113
 
32464 tejbeer 2114
    @RequestMapping(value = "/visitPlan", method = RequestMethod.GET)
2115
    public String visitPlan(HttpServletRequest request, Model model) throws Exception {
31249 tejbeer 2116
 
32464 tejbeer 2117
        return "visit-request-plan";
2118
    }
31249 tejbeer 2119
 
32464 tejbeer 2120
    @RequestMapping(value = "/visit/getVisitPlan", method = RequestMethod.GET)
2121
    public String getVisitPlan(HttpServletRequest request, @RequestParam LocalDate date, Model model) throws Exception {
2122
        List<VisitRequest> visitRequests = visitRequestRepository.selectByAuthIdAndDate(date);
31249 tejbeer 2123
 
32464 tejbeer 2124
        List<Integer> leadIds = visitRequests.stream().filter(x -> x.getVisitType().equals("lead")).map(x -> x.getVisitId()).collect(Collectors.toList());
2125
        Map<Integer, Lead> leadMap = new HashMap<>();
2126
        if (!leadIds.isEmpty()) {
2127
            List<Lead> leads = leadRepository.selectAllByIds(leadIds);
31249 tejbeer 2128
 
32464 tejbeer 2129
            for (Lead lead : leads) {
2130
                List<LeadActivity> leadActivities = leadActivityRepository.selectBYLeadId(lead.getId());
2131
                lead.setScheduledTimestamp(leadActivities.get(0).getSchelduleTimestamp());
2132
                lead.setLeadActivity(leadActivities.get(0));
31249 tejbeer 2133
 
32464 tejbeer 2134
                leadMap.put(lead.getId(), lead);
2135
            }
31249 tejbeer 2136
 
32464 tejbeer 2137
        }
2138
        List<Integer> franchiseeIds = visitRequests.stream().filter(x -> x.getVisitType().equals("franchiseeVisit")).map(x -> x.getVisitId()).collect(Collectors.toList());
2139
        Map<Integer, FranchiseeVisit> franchiseeVisitsMap = new HashMap<>();
2140
        if (!franchiseeIds.isEmpty()) {
2141
            List<FranchiseeVisit> franchiseeVisits = franchiseeVisitRepository.selectAllByIds(franchiseeIds);
2142
            LOGGER.info("franchiseeVisits {}", franchiseeVisits);
31249 tejbeer 2143
 
32464 tejbeer 2144
            for (FranchiseeVisit franchiseeVisit : franchiseeVisits) {
2145
                List<FranchiseeActivity> franchiseeActivities = franchiseeActivityRepository.selectByFranchiseeVisitId(franchiseeVisit.getId());
2146
                LOGGER.info("franchiseeActivities {}", franchiseeActivities);
2147
 
2148
                franchiseeVisit.setScheduleTimestamp(franchiseeActivities.get(0).getSchelduleTimestamp());
2149
                franchiseeVisit.setFranchiseeActivity(franchiseeActivities.get(0));
2150
 
2151
                franchiseeVisitsMap.put(franchiseeVisit.getId(), franchiseeVisit);
2152
            }
2153
 
2154
        }
2155
 
2156
        Map<Integer, List<VisitRequest>> visitRequestMap = visitRequests.stream().collect(Collectors.groupingBy(x -> x.getCreatedBy()));
2157
        List<AuthUser> authUsers = authRepository.selectAllActiveUser();
2158
        List<UserVisitModel> userVisits = new ArrayList<>();
2159
 
2160
        for (AuthUser authUser : authUsers) {
2161
 
2162
            List<VisitRequest> authVisitRequests = visitRequestMap.get(authUser.getId());
2163
 
2164
            if (authVisitRequests != null) {
2165
                UserVisitModel userVisitModel = new UserVisitModel();
2166
                userVisitModel.setAuthUser(authUser.getFullName());
2167
                List<VisitDescriptionModel> visitDescriptions = new ArrayList<>();
2168
 
2169
                for (VisitRequest authVisitRequest : authVisitRequests) {
2170
                    VisitDescriptionModel visitDescriptionModel = new VisitDescriptionModel();
2171
                    visitDescriptionModel.setVisitId(authVisitRequest.getVisitId());
2172
 
2173
                    if (authVisitRequest.getVisitType().equals("lead")) {
2174
                        Lead lead = leadMap.get(authVisitRequest.getVisitId());
2175
 
2176
                        visitDescriptionModel.setVisitName(lead.getFirstName());
2177
                        visitDescriptionModel.setCity(lead.getCity());
2178
                        visitDescriptionModel.setState(lead.getState());
2179
                        visitDescriptionModel.setScheduleTime(lead.getScheduledTimestamp());
2180
                        visitDescriptionModel.setRemarks(lead.getLeadActivity().getRemark());
2181
 
2182
                    } else {
2183
                        FranchiseeVisit franchiseeVisit = franchiseeVisitsMap.get(authVisitRequest.getVisitId());
2184
                        CustomRetailer customRetailer = retailerService.getFofoRetailer(franchiseeVisit.getFofoId());
2185
 
2186
                        visitDescriptionModel.setVisitName(franchiseeVisit.getPartnerName());
2187
                        visitDescriptionModel.setCity(customRetailer.getAddress().getCity());
2188
                        visitDescriptionModel.setState(customRetailer.getAddress().getState());
2189
                        visitDescriptionModel.setScheduleTime(franchiseeVisit.getFranchiseeActivity().getSchelduleTimestamp());
2190
                        visitDescriptionModel.setRemarks(franchiseeVisit.getAgenda());
2191
 
2192
                    }
2193
 
2194
                    if (authVisitRequest.getActionedBy() != 0) {
2195
                        AuthUser au = authRepository.selectById(authVisitRequest.getActionedBy());
2196
 
2197
                        visitDescriptionModel.setActionBy(au.getFullName());
2198
                    }
2199
                    visitDescriptionModel.setStatus(authVisitRequest.getStatus());
2200
                    visitDescriptionModel.setVisitType(authVisitRequest.getVisitType());
2201
                    visitDescriptions.add(visitDescriptionModel);
2202
                }
2203
 
2204
                userVisitModel.setVisitDescriptions(visitDescriptions);
2205
                userVisits.add(userVisitModel);
2206
            }
2207
 
2208
        }
2209
 
2210
        model.addAttribute("userVisits", userVisits);
2211
 
2212
        return "visit-request-plan";
2213
    }
25979 tejbeer 2214
}