Subversion Repositories SmartDukaan

Rev

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