Subversion Repositories SmartDukaan

Rev

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