Subversion Repositories SmartDukaan

Rev

Rev 37630 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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