Subversion Repositories SmartDukaan

Rev

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