Subversion Repositories SmartDukaan

Rev

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