| Line 53... |
Line 53... |
| 53 |
import java.io.*;
|
53 |
import java.io.*;
|
| 54 |
import java.math.BigDecimal;
|
54 |
import java.math.BigDecimal;
|
| 55 |
import java.time.*;
|
55 |
import java.time.*;
|
| 56 |
import java.time.format.DateTimeFormatter;
|
56 |
import java.time.format.DateTimeFormatter;
|
| 57 |
import java.time.temporal.ChronoUnit;
|
57 |
import java.time.temporal.ChronoUnit;
|
| - |
|
58 |
import java.time.temporal.TemporalAdjusters;
|
| - |
|
59 |
import java.time.DayOfWeek;
|
| 58 |
import java.util.*;
|
60 |
import java.util.*;
|
| 59 |
import java.util.stream.Collectors;
|
61 |
import java.util.stream.Collectors;
|
| 60 |
|
62 |
|
| 61 |
import static java.util.stream.Collectors.toList;
|
63 |
import static java.util.stream.Collectors.toList;
|
| 62 |
|
64 |
|
| Line 265... |
Line 267... |
| 265 |
}
|
267 |
}
|
| 266 |
|
268 |
|
| 267 |
|
269 |
|
| 268 |
|
270 |
|
| 269 |
public void sendRbmFeedbackSummaryEmail() throws MessagingException, ProfitMandiBusinessException, IOException {
|
271 |
public void sendRbmFeedbackSummaryEmail() throws MessagingException, ProfitMandiBusinessException, IOException {
|
| - |
|
272 |
// Weekly date range: Previous Monday to Sunday
|
| - |
|
273 |
LocalDate today = LocalDate.now();
|
| - |
|
274 |
LocalDate previousMonday = today.with(TemporalAdjusters.previous(DayOfWeek.MONDAY));
|
| - |
|
275 |
LocalDate previousSunday = previousMonday.plusDays(6);
|
| 270 |
LocalDateTime startOfMonth = LocalDate.now().withDayOfMonth(1).atStartOfDay();
|
276 |
LocalDateTime startOfWeek = previousMonday.atStartOfDay();
|
| 271 |
LocalDateTime endOfMonth = LocalDateTime.now();
|
277 |
LocalDateTime endOfWeek = previousSunday.atTime(23, 59, 59);
|
| - |
|
278 |
|
| 272 |
String[] bcc = {"tarun.verma@smartdukaan.com"};
|
279 |
String[] bcc = {"tarun.verma@smartdukaan.com"};
|
| - |
|
280 |
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd-MMM-yyyy");
|
| 273 |
|
281 |
|
| 274 |
// Get all RBM users
|
282 |
// Get all RBM users
|
| 275 |
List<AuthUser> authUsers = csService.getAuthUserIds(
|
283 |
List<AuthUser> authUsers = csService.getAuthUserIds(
|
| 276 |
ProfitMandiConstants.TICKET_CATEGORY_RBM,
|
284 |
ProfitMandiConstants.TICKET_CATEGORY_RBM,
|
| 277 |
Arrays.asList(EscalationType.L1)
|
285 |
Arrays.asList(EscalationType.L1)
|
| Line 282... |
Line 290... |
| 282 |
return;
|
290 |
return;
|
| 283 |
}
|
291 |
}
|
| 284 |
|
292 |
|
| 285 |
List<Integer> rbmIds = authUsers.stream().map(AuthUser::getId).collect(Collectors.toList());
|
293 |
List<Integer> rbmIds = authUsers.stream().map(AuthUser::getId).collect(Collectors.toList());
|
| 286 |
|
294 |
|
| 287 |
// Fetch ratings for all RBMs for current month
|
295 |
// Fetch ratings for all RBMs for the week
|
| 288 |
List<RbmRating> feedbackList = rbmRatingRepository.selectByRbmIdsAndDateRange(rbmIds, startOfMonth, endOfMonth);
|
296 |
List<RbmRating> feedbackList = rbmRatingRepository.selectByRbmIdsAndDateRange(rbmIds, startOfWeek, endOfWeek);
|
| 289 |
|
297 |
|
| 290 |
if (feedbackList.isEmpty()) {
|
298 |
if (feedbackList.isEmpty()) {
|
| 291 |
LOGGER.info("No feedback entries found for RBMs.");
|
299 |
LOGGER.info("No feedback entries found for RBMs for the week.");
|
| 292 |
return;
|
300 |
return;
|
| 293 |
}
|
301 |
}
|
| 294 |
|
302 |
|
| 295 |
// Sort feedback by createTimeStamp DESC
|
303 |
// Sort feedback by createTimeStamp DESC
|
| 296 |
feedbackList.sort((a, b) -> b.getCreateTimeStamp().compareTo(a.getCreateTimeStamp()));
|
304 |
feedbackList.sort((a, b) -> b.getCreateTimeStamp().compareTo(a.getCreateTimeStamp()));
|
| Line 313... |
Line 321... |
| 313 |
|
321 |
|
| 314 |
// Map RBM ID to name for quick lookup
|
322 |
// Map RBM ID to name for quick lookup
|
| 315 |
Map<Integer, String> rbmNameMap = authUsers.stream()
|
323 |
Map<Integer, String> rbmNameMap = authUsers.stream()
|
| 316 |
.collect(Collectors.toMap(AuthUser::getId, AuthUser::getFullName));
|
324 |
.collect(Collectors.toMap(AuthUser::getId, AuthUser::getFullName));
|
| 317 |
|
325 |
|
| - |
|
326 |
// Calculate RBM statistics: average rating and unique partner count
|
| - |
|
327 |
Map<Integer, List<RbmRating>> feedbackByRbm = feedbackList.stream()
|
| - |
|
328 |
.collect(Collectors.groupingBy(RbmRating::getRbmId));
|
| - |
|
329 |
|
| - |
|
330 |
List<RbmWeeklyStats> rbmStatsList = new ArrayList<>();
|
| - |
|
331 |
for (Map.Entry<Integer, List<RbmRating>> entry : feedbackByRbm.entrySet()) {
|
| - |
|
332 |
int rbmId = entry.getKey();
|
| - |
|
333 |
List<RbmRating> ratings = entry.getValue();
|
| - |
|
334 |
|
| - |
|
335 |
double avgRating = ratings.stream()
|
| - |
|
336 |
.mapToInt(RbmRating::getRating)
|
| - |
|
337 |
.average()
|
| - |
|
338 |
.orElse(0.0);
|
| - |
|
339 |
|
| - |
|
340 |
long uniquePartnerCount = ratings.stream()
|
| - |
|
341 |
.map(RbmRating::getFofoId)
|
| - |
|
342 |
.distinct()
|
| - |
|
343 |
.count();
|
| - |
|
344 |
|
| - |
|
345 |
String rbmName = rbmNameMap.getOrDefault(rbmId, "Unknown RBM");
|
| - |
|
346 |
rbmStatsList.add(new RbmWeeklyStats(rbmId, rbmName, avgRating, (int) uniquePartnerCount));
|
| - |
|
347 |
}
|
| - |
|
348 |
|
| - |
|
349 |
// Find max partner count for normalization
|
| - |
|
350 |
int maxPartnerCount = rbmStatsList.stream()
|
| - |
|
351 |
.mapToInt(RbmWeeklyStats::getPartnerCount)
|
| - |
|
352 |
.max()
|
| - |
|
353 |
.orElse(1);
|
| - |
|
354 |
|
| - |
|
355 |
// Calculate combined score: 65% partner count + 35% rating
|
| - |
|
356 |
// Score = (0.65 × partnerCount/maxPartnerCount) + (0.35 × avgRating/5)
|
| - |
|
357 |
for (RbmWeeklyStats stats : rbmStatsList) {
|
| - |
|
358 |
double partnerScore = (double) stats.getPartnerCount() / maxPartnerCount;
|
| - |
|
359 |
double ratingScore = stats.getAvgRating() / 5.0;
|
| - |
|
360 |
double combinedScore = (0.65 * partnerScore) + (0.35 * ratingScore);
|
| - |
|
361 |
stats.setCombinedScore(combinedScore);
|
| - |
|
362 |
}
|
| - |
|
363 |
|
| - |
|
364 |
// Sort by combined score DESC and assign rank
|
| - |
|
365 |
rbmStatsList.sort((a, b) -> Double.compare(b.getCombinedScore(), a.getCombinedScore()));
|
| - |
|
366 |
for (int i = 0; i < rbmStatsList.size(); i++) {
|
| - |
|
367 |
rbmStatsList.get(i).setRank(i + 1);
|
| - |
|
368 |
}
|
| - |
|
369 |
|
| - |
|
370 |
// Create map for quick lookup of stats by RBM ID
|
| - |
|
371 |
Map<Integer, RbmWeeklyStats> rbmStatsMap = rbmStatsList.stream()
|
| - |
|
372 |
.collect(Collectors.toMap(RbmWeeklyStats::getRbmId, s -> s));
|
| - |
|
373 |
|
| 318 |
// Generate HTML content
|
374 |
// Generate HTML content
|
| 319 |
StringBuilder emailContent = new StringBuilder();
|
375 |
StringBuilder emailContent = new StringBuilder();
|
| 320 |
emailContent.append("<html><body>");
|
376 |
emailContent.append("<html><body>");
|
| 321 |
emailContent.append("<p>Dear Team,</p>");
|
377 |
emailContent.append("<p>Dear Team,</p>");
|
| 322 |
emailContent.append("<p>Here is the <b>latest RBM Rating and Feedback Summary</b> for ")
|
378 |
emailContent.append("<p>Here is the <b>Weekly RBM Rating and Feedback Summary</b> for the week: <b>")
|
| - |
|
379 |
.append(previousMonday.format(dateFormatter))
|
| - |
|
380 |
.append(" to ")
|
| - |
|
381 |
.append(previousSunday.format(dateFormatter))
|
| - |
|
382 |
.append("</b></p>");
|
| - |
|
383 |
|
| - |
|
384 |
// RBM Ranking Summary Table
|
| - |
|
385 |
emailContent.append("<h3>RBM Weekly Rankings</h3>");
|
| - |
|
386 |
emailContent.append("<p style='font-size: 12px; color: #666;'>Rank = 65% Partner Count + 35% Avg Rating</p>");
|
| - |
|
387 |
emailContent.append("<table border='1' cellspacing='0' cellpadding='5' style='border-collapse: collapse;'>");
|
| - |
|
388 |
emailContent.append("<tr style='background-color: #4CAF50; color: white;'>")
|
| - |
|
389 |
.append("<th>Rank</th>")
|
| - |
|
390 |
.append("<th>RBM Name</th>")
|
| - |
|
391 |
.append("<th>Partner Count</th>")
|
| - |
|
392 |
.append("<th>Avg Rating</th>")
|
| - |
|
393 |
.append("<th>Score</th>")
|
| - |
|
394 |
.append("</tr>");
|
| - |
|
395 |
|
| - |
|
396 |
// Already sorted by rank (combined score DESC)
|
| - |
|
397 |
for (RbmWeeklyStats stats : rbmStatsList) {
|
| - |
|
398 |
emailContent.append("<tr>")
|
| - |
|
399 |
.append("<td style='text-align: center; font-weight: bold;'>").append(stats.getRank()).append("</td>")
|
| 323 |
.append(LocalDate.now().getMonth()).append(":</p>");
|
400 |
.append("<td>").append(stats.getRbmName()).append("</td>")
|
| - |
|
401 |
.append("<td style='text-align: center;'>").append(stats.getPartnerCount()).append("</td>")
|
| - |
|
402 |
.append("<td style='text-align: center;'>").append(String.format("%.2f", stats.getAvgRating())).append("</td>")
|
| - |
|
403 |
.append("<td style='text-align: center;'>").append(String.format("%.2f", stats.getCombinedScore())).append("</td>")
|
| - |
|
404 |
.append("</tr>");
|
| - |
|
405 |
}
|
| - |
|
406 |
emailContent.append("</table>");
|
| 324 |
|
407 |
|
| - |
|
408 |
// Detailed Feedback Table
|
| - |
|
409 |
emailContent.append("<br><h3>Detailed Feedback</h3>");
|
| 325 |
emailContent.append("<table border='1' cellspacing='0' cellpadding='5'>");
|
410 |
emailContent.append("<table border='1' cellspacing='0' cellpadding='5' style='border-collapse: collapse;'>");
|
| 326 |
emailContent.append("<tr>")
|
411 |
emailContent.append("<tr style='background-color: #2196F3; color: white;'>")
|
| 327 |
.append("<th>RBM Name</th>")
|
412 |
.append("<th>RBM Name</th>")
|
| - |
|
413 |
.append("<th>Rank</th>")
|
| 328 |
.append("<th>Partner Name</th>")
|
414 |
.append("<th>Partner Name</th>")
|
| 329 |
.append("<th>Rating</th>")
|
415 |
.append("<th>Rating</th>")
|
| 330 |
.append("<th>Comment</th>")
|
416 |
.append("<th>Comment</th>")
|
| 331 |
.append("<th>Date</th>")
|
417 |
.append("<th>Date</th>")
|
| 332 |
.append("</tr>");
|
418 |
.append("</tr>");
|
| 333 |
|
419 |
|
| 334 |
for (RbmRating rating : feedbackList) {
|
420 |
for (RbmRating rating : feedbackList) {
|
| - |
|
421 |
int rbmId = rating.getRbmId();
|
| 335 |
String rbmName = rbmNameMap.getOrDefault(rating.getRbmId(), "Unknown RBM");
|
422 |
String rbmName = rbmNameMap.getOrDefault(rbmId, "Unknown RBM");
|
| 336 |
String partnerName = fofoNameMap.getOrDefault(rating.getFofoId(), "Unknown Partner");
|
423 |
String partnerName = fofoNameMap.getOrDefault(rating.getFofoId(), "Unknown Partner");
|
| - |
|
424 |
RbmWeeklyStats stats = rbmStatsMap.get(rbmId);
|
| - |
|
425 |
|
| 337 |
emailContent.append("<tr>")
|
426 |
emailContent.append("<tr>")
|
| 338 |
.append("<td>").append(rbmName).append("</td>")
|
427 |
.append("<td>").append(rbmName).append("</td>")
|
| - |
|
428 |
.append("<td style='text-align: center; font-weight: bold;'>").append(stats != null ? stats.getRank() : "-").append("</td>")
|
| 339 |
.append("<td>").append(partnerName).append("</td>")
|
429 |
.append("<td>").append(partnerName).append("</td>")
|
| 340 |
.append("<td>").append(rating.getRating()).append("</td>")
|
430 |
.append("<td style='text-align: center;'>").append(rating.getRating()).append("</td>")
|
| 341 |
.append("<td>").append(rating.getComment() != null ? rating.getComment() : "-").append("</td>")
|
431 |
.append("<td>").append(rating.getComment() != null ? rating.getComment() : "-").append("</td>")
|
| 342 |
.append("<td>").append(rating.getCreateTimeStamp().toLocalDate()).append("</td>")
|
432 |
.append("<td>").append(rating.getCreateTimeStamp().toLocalDate()).append("</td>")
|
| 343 |
.append("</tr>");
|
433 |
.append("</tr>");
|
| 344 |
}
|
434 |
}
|
| 345 |
|
435 |
|
| 346 |
emailContent.append("</table>");
|
436 |
emailContent.append("</table>");
|
| 347 |
emailContent.append("<br><p>Regards,<br>Smart Dukaan Team</p>");
|
437 |
emailContent.append("<br><p>Regards,<br>Smart Dukaan Team</p>");
|
| 348 |
emailContent.append("</body></html>");
|
438 |
emailContent.append("</body></html>");
|
| 349 |
|
439 |
|
| 350 |
String subject = "Monthly RBM Feedback Summary - " + LocalDate.now().getMonth();
|
440 |
String subject = "Weekly RBM Feedback Summary - " + previousMonday.format(dateFormatter) + " to " + previousSunday.format(dateFormatter);
|
| 351 |
|
441 |
|
| 352 |
List<String> sendTo = new ArrayList<>();
|
442 |
List<String> sendTo = new ArrayList<>();
|
| 353 |
sendTo.add("sm@smartdukaan.com"); //
|
443 |
sendTo.add("sm@smartdukaan.com");
|
| 354 |
sendTo.add("chiranjib.sarkar@smartdukaan.com"); //
|
444 |
sendTo.add("chiranjib.sarkar@smartdukaan.com");
|
| 355 |
sendTo.add("kamini.sharma@smartdukaan.com"); //
|
445 |
sendTo.add("kamini.sharma@smartdukaan.com");
|
| 356 |
|
446 |
|
| 357 |
String[] emailRecipients = sendTo.toArray(new String[0]);
|
447 |
String[] emailRecipients = sendTo.toArray(new String[0]);
|
| 358 |
|
448 |
|
| 359 |
|
- |
|
| 360 |
this.sendMailHtmlFormat(emailRecipients, emailContent.toString(), null, bcc, subject);
|
449 |
this.sendMailHtmlFormat(emailRecipients, emailContent.toString(), null, bcc, subject);
|
| 361 |
|
450 |
|
| 362 |
LOGGER.info("Consolidated RBM feedback summary email sent.");
|
451 |
LOGGER.info("Weekly RBM feedback summary email sent for week: {} to {}", previousMonday, previousSunday);
|
| - |
|
452 |
}
|
| - |
|
453 |
|
| - |
|
454 |
// Inner class to hold RBM weekly statistics
|
| - |
|
455 |
private static class RbmWeeklyStats {
|
| - |
|
456 |
private final int rbmId;
|
| - |
|
457 |
private final String rbmName;
|
| - |
|
458 |
private final double avgRating;
|
| - |
|
459 |
private final int partnerCount;
|
| - |
|
460 |
private double combinedScore;
|
| - |
|
461 |
private int rank;
|
| - |
|
462 |
|
| - |
|
463 |
public RbmWeeklyStats(int rbmId, String rbmName, double avgRating, int partnerCount) {
|
| - |
|
464 |
this.rbmId = rbmId;
|
| - |
|
465 |
this.rbmName = rbmName;
|
| - |
|
466 |
this.avgRating = avgRating;
|
| - |
|
467 |
this.partnerCount = partnerCount;
|
| - |
|
468 |
}
|
| - |
|
469 |
|
| - |
|
470 |
public int getRbmId() { return rbmId; }
|
| - |
|
471 |
public String getRbmName() { return rbmName; }
|
| - |
|
472 |
public double getAvgRating() { return avgRating; }
|
| - |
|
473 |
public int getPartnerCount() { return partnerCount; }
|
| - |
|
474 |
public double getCombinedScore() { return combinedScore; }
|
| - |
|
475 |
public void setCombinedScore(double combinedScore) { this.combinedScore = combinedScore; }
|
| - |
|
476 |
public int getRank() { return rank; }
|
| - |
|
477 |
public void setRank(int rank) { this.rank = rank; }
|
| 363 |
}
|
478 |
}
|
| 364 |
|
479 |
|
| 365 |
|
480 |
|
| 366 |
public void sendSalesFeedbackSummaryEmail() throws MessagingException, ProfitMandiBusinessException, IOException {
|
481 |
public void sendSalesFeedbackSummaryEmail() throws MessagingException, ProfitMandiBusinessException, IOException {
|
| - |
|
482 |
// Weekly date range: Previous Monday to Sunday
|
| - |
|
483 |
LocalDate today = LocalDate.now();
|
| - |
|
484 |
LocalDate previousMonday = today.with(TemporalAdjusters.previous(DayOfWeek.MONDAY));
|
| - |
|
485 |
LocalDate previousSunday = previousMonday.plusDays(6);
|
| 367 |
LocalDateTime startOfMonth = LocalDate.now().withDayOfMonth(1).atStartOfDay();
|
486 |
LocalDateTime startOfWeek = previousMonday.atStartOfDay();
|
| 368 |
LocalDateTime endOfMonth = LocalDateTime.now();
|
487 |
LocalDateTime endOfWeek = previousSunday.atTime(23, 59, 59);
|
| - |
|
488 |
|
| 369 |
String[] bcc = {"tarun.verma@smartdukaan.com"};
|
489 |
String[] bcc = {"tarun.verma@smartdukaan.com"};
|
| 370 |
// String[] bcc = {"tejus.lohani@smartdukaan.com"};
|
490 |
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd-MMM-yyyy");
|
| 371 |
|
491 |
|
| 372 |
// Get all Sales users
|
492 |
// Get all Sales users
|
| 373 |
List<AuthUser> authUsers = csService.getAuthUserIds(
|
493 |
List<AuthUser> authUsers = csService.getAuthUserIds(
|
| 374 |
ProfitMandiConstants.TICKET_CATEGORY_SALES,
|
494 |
ProfitMandiConstants.TICKET_CATEGORY_SALES,
|
| 375 |
Arrays.asList(EscalationType.L1)
|
495 |
Arrays.asList(EscalationType.L1)
|
| Line 380... |
Line 500... |
| 380 |
return;
|
500 |
return;
|
| 381 |
}
|
501 |
}
|
| 382 |
|
502 |
|
| 383 |
List<Integer> salesL1Ids = authUsers.stream().map(AuthUser::getId).collect(Collectors.toList());
|
503 |
List<Integer> salesL1Ids = authUsers.stream().map(AuthUser::getId).collect(Collectors.toList());
|
| 384 |
|
504 |
|
| 385 |
// Fetch ratings for all RBMs for current month
|
505 |
// Fetch ratings for all Sales L1 for the week
|
| 386 |
List<SalesRating> feedbackList = salesRatingRepository.selectBySalesL1IdsAndDateRange(salesL1Ids, startOfMonth, endOfMonth);
|
506 |
List<SalesRating> feedbackList = salesRatingRepository.selectBySalesL1IdsAndDateRange(salesL1Ids, startOfWeek, endOfWeek);
|
| 387 |
|
507 |
|
| 388 |
if (feedbackList.isEmpty()) {
|
508 |
if (feedbackList.isEmpty()) {
|
| 389 |
LOGGER.info("No feedback entries found for Sales.");
|
509 |
LOGGER.info("No feedback entries found for Sales for the week.");
|
| 390 |
return;
|
510 |
return;
|
| 391 |
}
|
511 |
}
|
| 392 |
|
512 |
|
| 393 |
// Sort feedback by createTimeStamp DESC
|
513 |
// Sort feedback by createTimeStamp DESC
|
| 394 |
feedbackList.sort((a, b) -> b.getCreateTimeStamp().compareTo(a.getCreateTimeStamp()));
|
514 |
feedbackList.sort((a, b) -> b.getCreateTimeStamp().compareTo(a.getCreateTimeStamp()));
|
| Line 407... |
Line 527... |
| 407 |
String displayName = partnerName + " (" + storeCode + ")";
|
527 |
String displayName = partnerName + " (" + storeCode + ")";
|
| 408 |
fofoNameMap.put(fofoId, displayName);
|
528 |
fofoNameMap.put(fofoId, displayName);
|
| 409 |
}
|
529 |
}
|
| 410 |
}
|
530 |
}
|
| 411 |
|
531 |
|
| 412 |
// Map RBM ID to name for quick lookup
|
532 |
// Map Sales L1 ID to name for quick lookup
|
| 413 |
Map<Integer, String> salesL1NameMap = authUsers.stream()
|
533 |
Map<Integer, String> salesL1NameMap = authUsers.stream()
|
| 414 |
.collect(Collectors.toMap(AuthUser::getId, AuthUser::getFullName));
|
534 |
.collect(Collectors.toMap(AuthUser::getId, AuthUser::getFullName));
|
| 415 |
|
535 |
|
| - |
|
536 |
// Calculate Sales L1 statistics: average rating and unique partner count
|
| - |
|
537 |
Map<Integer, List<SalesRating>> feedbackBySales = feedbackList.stream()
|
| - |
|
538 |
.collect(Collectors.groupingBy(SalesRating::getSalesL1Id));
|
| - |
|
539 |
|
| - |
|
540 |
List<SalesWeeklyStats> salesStatsList = new ArrayList<>();
|
| - |
|
541 |
for (Map.Entry<Integer, List<SalesRating>> entry : feedbackBySales.entrySet()) {
|
| - |
|
542 |
int salesL1Id = entry.getKey();
|
| - |
|
543 |
List<SalesRating> ratings = entry.getValue();
|
| - |
|
544 |
|
| - |
|
545 |
double avgRating = ratings.stream()
|
| - |
|
546 |
.mapToInt(SalesRating::getRating)
|
| - |
|
547 |
.average()
|
| - |
|
548 |
.orElse(0.0);
|
| - |
|
549 |
|
| - |
|
550 |
long uniquePartnerCount = ratings.stream()
|
| - |
|
551 |
.map(SalesRating::getFofoId)
|
| - |
|
552 |
.distinct()
|
| - |
|
553 |
.count();
|
| - |
|
554 |
|
| - |
|
555 |
String salesL1Name = salesL1NameMap.getOrDefault(salesL1Id, "Unknown Sales Person");
|
| - |
|
556 |
salesStatsList.add(new SalesWeeklyStats(salesL1Id, salesL1Name, avgRating, (int) uniquePartnerCount));
|
| - |
|
557 |
}
|
| - |
|
558 |
|
| - |
|
559 |
// Find max partner count for normalization
|
| - |
|
560 |
int maxPartnerCount = salesStatsList.stream()
|
| - |
|
561 |
.mapToInt(SalesWeeklyStats::getPartnerCount)
|
| - |
|
562 |
.max()
|
| - |
|
563 |
.orElse(1);
|
| - |
|
564 |
|
| - |
|
565 |
// Calculate combined score: 65% partner count + 35% rating
|
| - |
|
566 |
// Score = (0.65 × partnerCount/maxPartnerCount) + (0.35 × avgRating/5)
|
| - |
|
567 |
for (SalesWeeklyStats stats : salesStatsList) {
|
| - |
|
568 |
double partnerScore = (double) stats.getPartnerCount() / maxPartnerCount;
|
| - |
|
569 |
double ratingScore = stats.getAvgRating() / 5.0;
|
| - |
|
570 |
double combinedScore = (0.65 * partnerScore) + (0.35 * ratingScore);
|
| - |
|
571 |
stats.setCombinedScore(combinedScore);
|
| - |
|
572 |
}
|
| - |
|
573 |
|
| - |
|
574 |
// Sort by combined score DESC and assign rank
|
| - |
|
575 |
salesStatsList.sort((a, b) -> Double.compare(b.getCombinedScore(), a.getCombinedScore()));
|
| - |
|
576 |
for (int i = 0; i < salesStatsList.size(); i++) {
|
| - |
|
577 |
salesStatsList.get(i).setRank(i + 1);
|
| - |
|
578 |
}
|
| - |
|
579 |
|
| - |
|
580 |
// Create map for quick lookup of stats by Sales L1 ID
|
| - |
|
581 |
Map<Integer, SalesWeeklyStats> salesStatsMap = salesStatsList.stream()
|
| - |
|
582 |
.collect(Collectors.toMap(SalesWeeklyStats::getSalesL1Id, s -> s));
|
| - |
|
583 |
|
| 416 |
// Generate HTML content
|
584 |
// Generate HTML content
|
| 417 |
StringBuilder emailContent = new StringBuilder();
|
585 |
StringBuilder emailContent = new StringBuilder();
|
| 418 |
emailContent.append("<html><body>");
|
586 |
emailContent.append("<html><body>");
|
| 419 |
emailContent.append("<p>Dear Team,</p>");
|
587 |
emailContent.append("<p>Dear Team,</p>");
|
| 420 |
emailContent.append("<p>Here is the <b>latest Sales L1 Rating and Feedback Summary</b> for ")
|
588 |
emailContent.append("<p>Here is the <b>Weekly Sales L1 Rating and Feedback Summary</b> for the week: <b>")
|
| - |
|
589 |
.append(previousMonday.format(dateFormatter))
|
| - |
|
590 |
.append(" to ")
|
| - |
|
591 |
.append(previousSunday.format(dateFormatter))
|
| - |
|
592 |
.append("</b></p>");
|
| - |
|
593 |
|
| - |
|
594 |
// Sales L1 Ranking Summary Table
|
| - |
|
595 |
emailContent.append("<h3>Sales L1 Weekly Rankings</h3>");
|
| - |
|
596 |
emailContent.append("<p style='font-size: 12px; color: #666;'>Rank = 65% Partner Count + 35% Avg Rating</p>");
|
| - |
|
597 |
emailContent.append("<table border='1' cellspacing='0' cellpadding='5' style='border-collapse: collapse;'>");
|
| - |
|
598 |
emailContent.append("<tr style='background-color: #4CAF50; color: white;'>")
|
| - |
|
599 |
.append("<th>Rank</th>")
|
| - |
|
600 |
.append("<th>Sales L1 Name</th>")
|
| - |
|
601 |
.append("<th>Partner Count</th>")
|
| - |
|
602 |
.append("<th>Avg Rating</th>")
|
| - |
|
603 |
.append("<th>Score</th>")
|
| - |
|
604 |
.append("</tr>");
|
| - |
|
605 |
|
| - |
|
606 |
// Already sorted by rank (combined score DESC)
|
| - |
|
607 |
for (SalesWeeklyStats stats : salesStatsList) {
|
| - |
|
608 |
emailContent.append("<tr>")
|
| - |
|
609 |
.append("<td style='text-align: center; font-weight: bold;'>").append(stats.getRank()).append("</td>")
|
| 421 |
.append(LocalDate.now().getMonth()).append(":</p>");
|
610 |
.append("<td>").append(stats.getSalesL1Name()).append("</td>")
|
| - |
|
611 |
.append("<td style='text-align: center;'>").append(stats.getPartnerCount()).append("</td>")
|
| - |
|
612 |
.append("<td style='text-align: center;'>").append(String.format("%.2f", stats.getAvgRating())).append("</td>")
|
| - |
|
613 |
.append("<td style='text-align: center;'>").append(String.format("%.2f", stats.getCombinedScore())).append("</td>")
|
| - |
|
614 |
.append("</tr>");
|
| - |
|
615 |
}
|
| - |
|
616 |
emailContent.append("</table>");
|
| 422 |
|
617 |
|
| - |
|
618 |
// Detailed Feedback Table
|
| - |
|
619 |
emailContent.append("<br><h3>Detailed Feedback</h3>");
|
| 423 |
emailContent.append("<table border='1' cellspacing='0' cellpadding='5'>");
|
620 |
emailContent.append("<table border='1' cellspacing='0' cellpadding='5' style='border-collapse: collapse;'>");
|
| 424 |
emailContent.append("<tr>")
|
621 |
emailContent.append("<tr style='background-color: #2196F3; color: white;'>")
|
| 425 |
.append("<th>Sales L1 Name</th>")
|
622 |
.append("<th>Sales L1 Name</th>")
|
| - |
|
623 |
.append("<th>Rank</th>")
|
| 426 |
.append("<th>Partner Name</th>")
|
624 |
.append("<th>Partner Name</th>")
|
| 427 |
.append("<th>Partner Category</th>")
|
625 |
.append("<th>Partner Category</th>")
|
| 428 |
.append("<th>Rating</th>")
|
626 |
.append("<th>Rating</th>")
|
| 429 |
.append("<th>Comment</th>")
|
627 |
.append("<th>Comment</th>")
|
| 430 |
.append("<th>Date</th>")
|
628 |
.append("<th>Date</th>")
|
| 431 |
.append("</tr>");
|
629 |
.append("</tr>");
|
| 432 |
|
630 |
|
| 433 |
for (SalesRating rating : feedbackList) {
|
631 |
for (SalesRating rating : feedbackList) {
|
| - |
|
632 |
int salesL1Id = rating.getSalesL1Id();
|
| 434 |
String salesL1 = salesL1NameMap.getOrDefault(rating.getSalesL1Id(), "Unknown Sales Person");
|
633 |
String salesL1Name = salesL1NameMap.getOrDefault(salesL1Id, "Unknown Sales Person");
|
| 435 |
String partnerName = fofoNameMap.getOrDefault(rating.getFofoId(), "Unknown Partner");
|
634 |
String partnerName = fofoNameMap.getOrDefault(rating.getFofoId(), "Unknown Partner");
|
| 436 |
LOGGER.info("partnerName11- {}",partnerName);
|
635 |
SalesWeeklyStats stats = salesStatsMap.get(salesL1Id);
|
| 437 |
PartnerType partnerType = partnerTypeChangeService.getTypeOnDate(rating.getFofoId(), LocalDate.now());
|
636 |
PartnerType partnerType = partnerTypeChangeService.getTypeOnDate(rating.getFofoId(), LocalDate.now());
|
| - |
|
637 |
|
| 438 |
emailContent.append("<tr>")
|
638 |
emailContent.append("<tr>")
|
| 439 |
.append("<td>").append(salesL1).append("</td>")
|
639 |
.append("<td>").append(salesL1Name).append("</td>")
|
| - |
|
640 |
.append("<td style='text-align: center; font-weight: bold;'>").append(stats != null ? stats.getRank() : "-").append("</td>")
|
| 440 |
.append("<td>").append(partnerName).append("</td>")
|
641 |
.append("<td>").append(partnerName).append("</td>")
|
| 441 |
.append("<td>").append(partnerType).append("</td>")
|
642 |
.append("<td>").append(partnerType).append("</td>")
|
| 442 |
.append("<td>").append(rating.getRating()).append("</td>")
|
643 |
.append("<td style='text-align: center;'>").append(rating.getRating()).append("</td>")
|
| 443 |
.append("<td>").append(rating.getComment() != null ? rating.getComment() : "-").append("</td>")
|
644 |
.append("<td>").append(rating.getComment() != null ? rating.getComment() : "-").append("</td>")
|
| 444 |
.append("<td>").append(rating.getCreateTimeStamp().toLocalDate()).append("</td>")
|
645 |
.append("<td>").append(rating.getCreateTimeStamp().toLocalDate()).append("</td>")
|
| 445 |
.append("</tr>");
|
646 |
.append("</tr>");
|
| 446 |
}
|
647 |
}
|
| 447 |
|
648 |
|
| 448 |
emailContent.append("</table>");
|
649 |
emailContent.append("</table>");
|
| 449 |
emailContent.append("<br><p>Regards,<br>Smartdukaan Team</p>");
|
650 |
emailContent.append("<br><p>Regards,<br>Smart Dukaan Team</p>");
|
| 450 |
emailContent.append("</body></html>");
|
651 |
emailContent.append("</body></html>");
|
| 451 |
|
652 |
|
| 452 |
String subject = "Monthly Sales L1 Feedback Summary Test test - " + LocalDate.now().getMonth();
|
653 |
String subject = "Weekly Sales L1 Feedback Summary - " + previousMonday.format(dateFormatter) + " to " + previousSunday.format(dateFormatter);
|
| 453 |
|
654 |
|
| 454 |
List<String> sendTo = new ArrayList<>();
|
655 |
List<String> sendTo = new ArrayList<>();
|
| 455 |
sendTo.add("sm@smartdukaan.com"); //
|
656 |
sendTo.add("sm@smartdukaan.com");
|
| 456 |
sendTo.add("chiranjib.sarkar@smartdukaan.com"); //
|
657 |
sendTo.add("chiranjib.sarkar@smartdukaan.com");
|
| 457 |
sendTo.add("kamini.sharma@smartdukaan.com"); //
|
658 |
sendTo.add("kamini.sharma@smartdukaan.com");
|
| 458 |
|
659 |
|
| 459 |
String[] emailRecipients = sendTo.toArray(new String[0]);
|
660 |
String[] emailRecipients = sendTo.toArray(new String[0]);
|
| 460 |
|
661 |
|
| 461 |
|
- |
|
| 462 |
this.sendMailHtmlFormat(emailRecipients, emailContent.toString(), null, bcc, subject);
|
662 |
this.sendMailHtmlFormat(emailRecipients, emailContent.toString(), null, bcc, subject);
|
| 463 |
|
663 |
|
| 464 |
LOGGER.info("Consolidated Sales L1 feedback summary email sent.");
|
664 |
LOGGER.info("Weekly Sales L1 feedback summary email sent for week: {} to {}", previousMonday, previousSunday);
|
| - |
|
665 |
}
|
| - |
|
666 |
|
| - |
|
667 |
// Inner class to hold Sales L1 weekly statistics
|
| - |
|
668 |
private static class SalesWeeklyStats {
|
| - |
|
669 |
private final int salesL1Id;
|
| - |
|
670 |
private final String salesL1Name;
|
| - |
|
671 |
private final double avgRating;
|
| - |
|
672 |
private final int partnerCount;
|
| - |
|
673 |
private double combinedScore;
|
| - |
|
674 |
private int rank;
|
| - |
|
675 |
|
| - |
|
676 |
public SalesWeeklyStats(int salesL1Id, String salesL1Name, double avgRating, int partnerCount) {
|
| - |
|
677 |
this.salesL1Id = salesL1Id;
|
| - |
|
678 |
this.salesL1Name = salesL1Name;
|
| - |
|
679 |
this.avgRating = avgRating;
|
| - |
|
680 |
this.partnerCount = partnerCount;
|
| - |
|
681 |
}
|
| - |
|
682 |
|
| - |
|
683 |
public int getSalesL1Id() { return salesL1Id; }
|
| - |
|
684 |
public String getSalesL1Name() { return salesL1Name; }
|
| - |
|
685 |
public double getAvgRating() { return avgRating; }
|
| - |
|
686 |
public int getPartnerCount() { return partnerCount; }
|
| - |
|
687 |
public double getCombinedScore() { return combinedScore; }
|
| - |
|
688 |
public void setCombinedScore(double combinedScore) { this.combinedScore = combinedScore; }
|
| - |
|
689 |
public int getRank() { return rank; }
|
| - |
|
690 |
public void setRank(int rank) { this.rank = rank; }
|
| 465 |
}
|
691 |
}
|
| 466 |
|
692 |
|
| 467 |
public Map<String, Set<Integer>> generateBiReportHierarchyWise() throws Exception{
|
693 |
public Map<String, Set<Integer>> generateBiReportHierarchyWise() throws Exception{
|
| 468 |
List<Integer> categoryIds = Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_RBM, ProfitMandiConstants.TICKET_CATEGORY_SALES,ProfitMandiConstants.TICKET_CATEGORY_ABM,ProfitMandiConstants.TICKET_CATEGORY_BUSINESSINTELLIGENT);
|
694 |
List<Integer> categoryIds = Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_RBM, ProfitMandiConstants.TICKET_CATEGORY_SALES,ProfitMandiConstants.TICKET_CATEGORY_ABM,ProfitMandiConstants.TICKET_CATEGORY_BUSINESSINTELLIGENT);
|
| 469 |
Map<String, Set<Integer>> storeGuyEntry = csService.getAuthUserPartnerIdMappingByCategoryIds(categoryIds, false);
|
695 |
Map<String, Set<Integer>> storeGuyEntry = csService.getAuthUserPartnerIdMappingByCategoryIds(categoryIds, false);
|