| Line 97... |
Line 97... |
| 97 |
/**
|
97 |
/**
|
| 98 |
* KPIs + lifecycle funnel + attention queue for the given region / created-date window. Stages come
|
98 |
* KPIs + lifecycle funnel + attention queue for the given region / created-date window. Stages come
|
| 99 |
* from LeadRepository's evidence-aware expression: BEAT_PLANNED / VISITED / ONBOARDED are read off
|
99 |
* from LeadRepository's evidence-aware expression: BEAT_PLANNED / VISITED / ONBOARDED are read off
|
| 100 |
* lead_route, location_tracking and LOI + stock payment, never off the hand-set stage column.
|
100 |
* lead_route, location_tracking and LOI + stock payment, never off the hand-set stage column.
|
| 101 |
*/
|
101 |
*/
|
| 102 |
public Map<String, Object> summary(Integer regionId, LocalDateTime from, LocalDateTime to) {
|
102 |
public Map<String, Object> summary(Integer regionId, Integer agentId, LocalDateTime from, LocalDateTime to) {
|
| 103 |
Map<String, Long> stage = toCountMap(leadRepository.countByDerivedStage(regionId, from, to));
|
103 |
Map<String, Long> stage = toCountMap(leadRepository.countByDerivedStage(regionId, agentId, from, to));
|
| 104 |
long total = 0;
|
104 |
long total = 0;
|
| 105 |
for (Long v : stage.values()) {
|
105 |
for (Long v : stage.values()) {
|
| 106 |
total += v;
|
106 |
total += v;
|
| 107 |
}
|
107 |
}
|
| 108 |
|
108 |
|
| Line 115... |
Line 115... |
| 115 |
}
|
115 |
}
|
| 116 |
reached[i] = sum;
|
116 |
reached[i] = sum;
|
| 117 |
}
|
117 |
}
|
| 118 |
|
118 |
|
| 119 |
LocalDateTime now = LocalDateTime.now();
|
119 |
LocalDateTime now = LocalDateTime.now();
|
| 120 |
Object[] att = leadRepository.attentionCounts(regionId, now, now.plusHours(1), from, to);
|
120 |
Object[] att = leadRepository.attentionCounts(regionId, agentId, now, now.plusHours(1), from, to);
|
| 121 |
long breachedNoContact = num(att, 0);
|
121 |
long breachedNoContact = num(att, 0);
|
| 122 |
long hold = num(att, 1);
|
122 |
long hold = num(att, 1);
|
| 123 |
long slaUnder1h = num(att, 2);
|
123 |
long slaUnder1h = num(att, 2);
|
| 124 |
long missingDisp = num(att, 3);
|
124 |
long missingDisp = num(att, 3);
|
| 125 |
long qualifiedNoBeat = num(att, 4);
|
125 |
long qualifiedNoBeat = num(att, 4);
|
| 126 |
long onboardedPending = num(att, 5);
|
126 |
long onboardedPending = num(att, 5);
|
| 127 |
|
127 |
|
| 128 |
// Onboarded value (SOP §18.2) = summed potential of ONBOARDED + ACTIVE leads.
|
128 |
// Onboarded value (SOP §18.2) = summed potential of ONBOARDED + ACTIVE leads.
|
| 129 |
Map<String, Double> potByStage = toSumMap(leadRepository.sumPotentialByDerivedStage(regionId, from, to));
|
129 |
Map<String, Double> potByStage = toSumMap(leadRepository.sumPotentialByDerivedStage(regionId, agentId, from, to));
|
| 130 |
double onboardedValue = potByStage.getOrDefault("ONBOARDED", 0d) + potByStage.getOrDefault("ACTIVE", 0d);
|
130 |
double onboardedValue = potByStage.getOrDefault("ONBOARDED", 0d) + potByStage.getOrDefault("ACTIVE", 0d);
|
| 131 |
|
131 |
|
| 132 |
long onboarded = stage.getOrDefault("ONBOARDED", 0L) + stage.getOrDefault("ACTIVE", 0L);
|
132 |
long onboarded = stage.getOrDefault("ONBOARDED", 0L) + stage.getOrDefault("ACTIVE", 0L);
|
| 133 |
long assigned = stage.getOrDefault("ASSIGNED", 0L);
|
133 |
long assigned = stage.getOrDefault("ASSIGNED", 0L);
|
| 134 |
long contacted = stage.getOrDefault("CONTACTED", 0L);
|
134 |
long contacted = stage.getOrDefault("CONTACTED", 0L);
|
| Line 373... |
Line 373... |
| 373 |
LocalDateTime now = LocalDateTime.now();
|
373 |
LocalDateTime now = LocalDateTime.now();
|
| 374 |
Map<String, Object> m = new LinkedHashMap<>();
|
374 |
Map<String, Object> m = new LinkedHashMap<>();
|
| 375 |
|
375 |
|
| 376 |
// Same source and same created-date window as the Command Center's attention tiles, so the
|
376 |
// Same source and same created-date window as the Command Center's attention tiles, so the
|
| 377 |
// two cannot disagree.
|
377 |
// two cannot disagree.
|
| 378 |
Object[] att = leadRepository.attentionCounts(null, now, now.plusHours(1), from, to);
|
378 |
Object[] att = leadRepository.attentionCounts(null, null, now, now.plusHours(1), from, to);
|
| 379 |
m.put("slaBreached", num(att, 0));
|
379 |
m.put("slaBreached", num(att, 0));
|
| 380 |
m.put("hold", num(att, 1));
|
380 |
m.put("hold", num(att, 1));
|
| 381 |
m.put("missingDisposition", num(att, 3));
|
381 |
m.put("missingDisposition", num(att, 3));
|
| 382 |
|
382 |
|
| 383 |
m.put("dndRegister", leadDndRepository.count());
|
383 |
m.put("dndRegister", leadDndRepository.count());
|
| Line 625... |
Line 625... |
| 625 |
|
625 |
|
| 626 |
/**
|
626 |
/**
|
| 627 |
* One page of lead rows for a drill bucket, shaped for the drawer table, plus the true total so
|
627 |
* One page of lead rows for a drill bucket, shaped for the drawer table, plus the true total so
|
| 628 |
* the drawer can page through every lead behind a bar instead of stopping at the first 100.
|
628 |
* the drawer can page through every lead behind a bar instead of stopping at the first 100.
|
| 629 |
*/
|
629 |
*/
|
| 630 |
public Map<String, Object> drill(String bucketType, String bucketKey, Integer regionId,
|
630 |
public Map<String, Object> drill(String bucketType, String bucketKey, Integer regionId, Integer agentId,
|
| 631 |
LocalDateTime from, LocalDateTime to, int page, int pageSize) {
|
631 |
LocalDateTime from, LocalDateTime to, int page, int pageSize) {
|
| 632 |
int size = Math.min(Math.max(pageSize, 1), MAX_PAGE_SIZE);
|
632 |
int size = Math.min(Math.max(pageSize, 1), MAX_PAGE_SIZE);
|
| 633 |
int p = Math.max(page, 1);
|
633 |
int p = Math.max(page, 1);
|
| 634 |
String type = bucketType == null ? "" : bucketType.trim().toUpperCase();
|
634 |
String type = bucketType == null ? "" : bucketType.trim().toUpperCase();
|
| 635 |
String key = bucketKey;
|
635 |
String key = bucketKey;
|
| Line 639... |
Line 639... |
| 639 |
if ("STAGE_REACHED".equals(type)) {
|
639 |
if ("STAGE_REACHED".equals(type)) {
|
| 640 |
type = "STAGE_IN";
|
640 |
type = "STAGE_IN";
|
| 641 |
key = stagesFrom(bucketKey);
|
641 |
key = stagesFrom(bucketKey);
|
| 642 |
}
|
642 |
}
|
| 643 |
LocalDateTime now = LocalDateTime.now();
|
643 |
LocalDateTime now = LocalDateTime.now();
|
| 644 |
long total = leadRepository.countLeadsForBucket(type, key, regionId, now, now.plusHours(1), from, to);
|
644 |
long total = leadRepository.countLeadsForBucket(type, key, regionId, agentId, now, now.plusHours(1), from, to);
|
| 645 |
List<Integer> ids = leadRepository.selectLeadIdsForBucket(type, key, regionId,
|
645 |
List<Integer> ids = leadRepository.selectLeadIdsForBucket(type, key, regionId, agentId,
|
| 646 |
now, now.plusHours(1), from, to, (p - 1) * size, size);
|
646 |
now, now.plusHours(1), from, to, (p - 1) * size, size);
|
| 647 |
List<Map<String, Object>> rows = new ArrayList<>();
|
647 |
List<Map<String, Object>> rows = new ArrayList<>();
|
| 648 |
Map<String, Object> out = new LinkedHashMap<>();
|
648 |
Map<String, Object> out = new LinkedHashMap<>();
|
| 649 |
out.put("leads", rows);
|
649 |
out.put("leads", rows);
|
| 650 |
out.put("total", total);
|
650 |
out.put("total", total);
|