| 25899 |
tejbeer |
1 |
package com.spice.profitmandi.dao.repository.dtr;
|
|
|
2 |
|
| 32471 |
tejbeer |
3 |
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
|
|
|
4 |
import com.spice.profitmandi.dao.entity.auth.AuthUser;
|
| 25899 |
tejbeer |
5 |
import com.spice.profitmandi.dao.entity.user.Lead;
|
|
|
6 |
import com.spice.profitmandi.dao.enumuration.dtr.LeadStatus;
|
| 32471 |
tejbeer |
7 |
import com.spice.profitmandi.dao.model.LeadDetailModel;
|
| 33246 |
ranu |
8 |
import org.springframework.stereotype.Repository;
|
| 25899 |
tejbeer |
9 |
|
| 33246 |
ranu |
10 |
import java.time.LocalDateTime;
|
|
|
11 |
import java.util.List;
|
|
|
12 |
|
| 25899 |
tejbeer |
13 |
@Repository
|
|
|
14 |
public interface LeadRepository {
|
| 31249 |
tejbeer |
15 |
|
| 32471 |
tejbeer |
16 |
public void persist(Lead lead);
|
| 25899 |
tejbeer |
17 |
|
| 32471 |
tejbeer |
18 |
public List<Lead> selectByAssignAuthIdAndStatus(int authId, LeadStatus status, int offset, int limit);
|
| 25899 |
tejbeer |
19 |
|
| 32471 |
tejbeer |
20 |
public Lead selectById(int id);
|
| 25915 |
amit.gupta |
21 |
|
| 35507 |
ranu |
22 |
List<Lead> selectAllByColorStatusAndBetweenDate(List<LeadStatus> status, List<String> color, LocalDateTime createdTimestamp, LocalDateTime endDateTimeStamp);
|
|
|
23 |
|
| 32471 |
tejbeer |
24 |
public List<Lead> selectAllByIds(List<Integer> ids);
|
| 31249 |
tejbeer |
25 |
|
| 37692 |
vikas |
26 |
/**
|
|
|
27 |
* Filtered, sorted, paged rows for the dashboard's Lead-pipeline table. A non-empty {@code q}
|
|
|
28 |
* searches every lead and IGNORES the date window; otherwise the window applies.
|
|
|
29 |
*/
|
| 37759 |
vikas |
30 |
public List<Lead> selectPipeline(String q, Integer regionId, Integer agentId, LocalDateTime from, LocalDateTime to,
|
| 37692 |
vikas |
31 |
String sort, String dir, int offset, int limit);
|
|
|
32 |
|
|
|
33 |
/** Total rows matching the same filters as {@link #selectPipeline}. */
|
| 37759 |
vikas |
34 |
public long countPipeline(String q, Integer regionId, Integer agentId, LocalDateTime from, LocalDateTime to);
|
| 37692 |
vikas |
35 |
|
| 32471 |
tejbeer |
36 |
public List<Lead> selectByAssignAuthIdAndStatus(int authId, LeadStatus status);
|
| 26298 |
tejbeer |
37 |
|
| 32471 |
tejbeer |
38 |
public List<Lead> selectByAssignAuthIdsAndStatus(List<Integer> authId, LeadStatus status);
|
| 26298 |
tejbeer |
39 |
|
| 32471 |
tejbeer |
40 |
public List<Lead> selectAll(int offset, int limit);
|
| 25979 |
tejbeer |
41 |
|
| 33246 |
ranu |
42 |
public List<Lead> selectAllBylistStatus(List<LeadStatus> status) throws ProfitMandiBusinessException;
|
| 27610 |
tejbeer |
43 |
|
| 32471 |
tejbeer |
44 |
public List<Lead> selectAllByStatus(LeadStatus status);
|
| 25979 |
tejbeer |
45 |
|
| 32471 |
tejbeer |
46 |
public List<Lead> selectAllByStatusAndUpdatedTimestamp(List<LeadStatus> status, LocalDateTime updatedTimestamp);
|
| 27615 |
tejbeer |
47 |
|
| 32471 |
tejbeer |
48 |
public List<Lead> selectAllByStatus(List<LeadStatus> status, int offset, int limit);
|
| 25988 |
tejbeer |
49 |
|
| 32471 |
tejbeer |
50 |
List<Lead> selectLeadsScheduledBetweenDate(List<Integer> fofoIds, LocalDateTime startDate, LocalDateTime endDate);
|
| 25988 |
tejbeer |
51 |
|
| 32471 |
tejbeer |
52 |
public long selectCountByStatus(List<LeadStatus> status);
|
| 25988 |
tejbeer |
53 |
|
| 32471 |
tejbeer |
54 |
public long getLeadCount(LeadStatus status, String searchTerm);
|
| 25988 |
tejbeer |
55 |
|
| 32471 |
tejbeer |
56 |
public List<Lead> selectBySearchTerm(List<LeadStatus> status, String searchTerm, int offset, int limit);
|
| 27642 |
tejbeer |
57 |
|
| 36984 |
aman |
58 |
// Global lead search: matches name / mobile / outlet / city across ALL leads (any status, any date).
|
|
|
59 |
public List<Lead> selectByGlobalSearch(String searchTerm, int limit);
|
|
|
60 |
|
| 32471 |
tejbeer |
61 |
public List<Lead> selectAllByColorStatusAndUpdatedTimestamp(List<LeadStatus> status, List<String> color, LocalDateTime updatedTimestamp);
|
| 29277 |
manish |
62 |
|
| 34894 |
aman |
63 |
public List<Lead> selectAllByColorStatusAndCreatedTimestamp(List<LeadStatus> status, List<String> color, LocalDateTime createdTimestamp);
|
|
|
64 |
|
| 32471 |
tejbeer |
65 |
List<Lead> selectAllByStatusAndUpdatedTimestampAndAuthId(List<LeadStatus> status, LocalDateTime updatedTimestamp, List<Integer> authIds);
|
| 29277 |
manish |
66 |
|
| 32471 |
tejbeer |
67 |
List<Lead> selectAllByColorStatusAndUpdatedTimestampAndAuthIds(List<LeadStatus> status, List<Integer> authIds, List<String> color, LocalDateTime updatedTimestamp);
|
|
|
68 |
|
| 35769 |
amit |
69 |
List<Lead> selectAllByColorStatusAndBetweenCreatedDate(List<LeadStatus> status, List<String> color, LocalDateTime startDate, LocalDateTime endDate);
|
|
|
70 |
|
|
|
71 |
List<Lead> selectAllByColorStatusAndBetweenCreatedDateAndAuthIds(List<LeadStatus> status, List<Integer> authIds, List<String> color, LocalDateTime startDate, LocalDateTime endDate);
|
|
|
72 |
|
| 32471 |
tejbeer |
73 |
public void persistLeadDetail(LeadDetailModel leadDetailModel, AuthUser authUser) throws ProfitMandiBusinessException;
|
|
|
74 |
|
| 37749 |
vikas |
75 |
/**
|
|
|
76 |
* Same as {@link #persistLeadDetail(LeadDetailModel, AuthUser)} but with {@code requirePhotos}
|
|
|
77 |
* false the five store photos are optional: whatever ids are present are stored, none are demanded.
|
|
|
78 |
* The LMS Create Lead form captures the shop on a call, before anyone has been to it.
|
|
|
79 |
*/
|
|
|
80 |
public void persistLeadDetail(LeadDetailModel leadDetailModel, AuthUser authUser, boolean requirePhotos)
|
|
|
81 |
throws ProfitMandiBusinessException;
|
|
|
82 |
|
| 35079 |
vikas |
83 |
Lead selectByMobileNumber(String mobileNumber);
|
| 36957 |
aman |
84 |
|
| 37651 |
vikas |
85 |
/**
|
| 37729 |
amit |
86 |
* Every lead on this mobile that is OPEN and actually workable, newest activity first.
|
|
|
87 |
*
|
|
|
88 |
* "Workable" is two conditions, not one. The status must be open (pending/followUp), AND the
|
|
|
89 |
* assignee must still be an active auth_user. The second half matters: 331 open leads are
|
|
|
90 |
* assigned to 11 DEACTIVATED accounts (157 of them to sm@smartdukaan.com alone). Without the
|
|
|
91 |
* owner check each of those would block a fresh enquiry forever, held by an account nobody can
|
|
|
92 |
* log in to and therefore nobody can close. Filtering them out defuses all 331 without
|
|
|
93 |
* retiring a single row, which is what the "no auto-retirement" rule requires.
|
|
|
94 |
*
|
|
|
95 |
* Returns a LIST on purpose. 5,137 mobiles already carry duplicates and 10 carry more than one
|
|
|
96 |
* OPEN lead, so any uniqueness assumption here throws -- which is exactly what
|
|
|
97 |
* selectByMobileNumber does today (GlitchTip #99, #1359).
|
|
|
98 |
*/
|
|
|
99 |
List<Lead> selectActiveByMobile(String mobileNumber);
|
|
|
100 |
|
|
|
101 |
/**
|
|
|
102 |
* Last time anything happened to this lead: the later of its own updated/created stamp and its
|
|
|
103 |
* newest lead_activity row. Drives the 6-month staleness test.
|
|
|
104 |
*/
|
|
|
105 |
LocalDateTime selectLastActivityAt(int leadId);
|
|
|
106 |
|
|
|
107 |
/**
|
| 37651 |
vikas |
108 |
* Batch mobile lookup for bulk imports — one query instead of one per row.
|
|
|
109 |
*
|
|
|
110 |
* <p>Takes normalised 10-digit numbers and also matches the prefixed forms that exist in the
|
|
|
111 |
* data ({@code 91…}, {@code 0…}): of ~37k leads, 121 are stored 11- or 12-digit, so an exact
|
|
|
112 |
* 10-digit match would miss them and a bulk import would create duplicates for real retailers.
|
|
|
113 |
*/
|
|
|
114 |
List<Lead> selectByMobileNumbers(List<String> normalisedMobiles);
|
|
|
115 |
|
|
|
116 |
/**
|
|
|
117 |
* Open-lead count per owner, for balancing a bulk assignment against what each agent is already
|
|
|
118 |
* carrying. Returns {@code [authId, count]} pairs; an agent with none is simply absent.
|
|
|
119 |
*/
|
|
|
120 |
java.util.List<Object[]> countOpenLeadsByAuthIds(List<Integer> authIds);
|
|
|
121 |
|
| 36957 |
aman |
122 |
Lead selectByMobileNumberAndSource(String mobileNumber, String source);
|
| 37120 |
vikas |
123 |
|
|
|
124 |
// ---- LMS dashboard aggregation (SOP §18) -------------------------------------------------
|
|
|
125 |
// All aggregates bucket EVERY lead: rows with a real `stage` use it; legacy rows (stage NULL)
|
|
|
126 |
// derive a stage from `status` in SQL, mirroring LeadStage.fromLegacy. Read-only, no schema change.
|
|
|
127 |
|
|
|
128 |
/** (derivedStage, count) for the optional region + created-date window. */
|
| 37784 |
vikas |
129 |
java.util.List<Object[]> countByDerivedStage(Integer regionId, Integer agentId, LocalDateTime from, LocalDateTime to);
|
| 37120 |
vikas |
130 |
|
|
|
131 |
/** (derivedStage, SUM(potential)) for the optional region + window — for the onboarded-value KPI. */
|
| 37784 |
vikas |
132 |
java.util.List<Object[]> sumPotentialByDerivedStage(Integer regionId, Integer agentId, LocalDateTime from, LocalDateTime to);
|
| 37120 |
vikas |
133 |
|
|
|
134 |
/** (regionCode, derivedStage, count) across all regions in the window — feeds the state funnel. */
|
|
|
135 |
java.util.List<Object[]> countByRegionAndDerivedStage(LocalDateTime from, LocalDateTime to);
|
|
|
136 |
|
|
|
137 |
/** (regionCode, totalWithDue, onTime) — first-contact SLA compliance per region. */
|
|
|
138 |
java.util.List<Object[]> slaComplianceByRegion(LocalDateTime from, LocalDateTime to);
|
|
|
139 |
|
|
|
140 |
/** (ownerBmId, isoYearWeek, totalWithDue, onTime) — SLA compliance per BM per week, for the heat-map. */
|
|
|
141 |
java.util.List<Object[]> slaComplianceByBmAndWeek(LocalDateTime from, LocalDateTime to);
|
|
|
142 |
|
|
|
143 |
/** (derivedStage, count) of OPEN leads not touched since {@code olderThan} — the ageing widget. */
|
|
|
144 |
java.util.List<Object[]> ageingByDerivedStage(LocalDateTime olderThan);
|
|
|
145 |
|
|
|
146 |
/** Single row of conditional-sum attention counts (see impl) for the optional region. */
|
| 37749 |
vikas |
147 |
/** Attention-queue counts for the region and created-date window (same scope as the funnel). */
|
| 37784 |
vikas |
148 |
Object[] attentionCounts(Integer regionId, Integer agentId, LocalDateTime now, LocalDateTime nowPlus1h,
|
| 37749 |
vikas |
149 |
LocalDateTime from, LocalDateTime to);
|
| 37120 |
vikas |
150 |
|
| 37737 |
vikas |
151 |
/**
|
|
|
152 |
* Per-owner lead counters for the live board: {@code [authId, assigned, slaBreached]}.
|
|
|
153 |
* Breached = open, past its first-contact deadline, never contacted.
|
|
|
154 |
*/
|
|
|
155 |
List<Object[]> selectAgentLeadCounters(LocalDateTime now);
|
|
|
156 |
|
| 37120 |
vikas |
157 |
/** Lead ids for a drill-down bucket (STAGE / ATTENTION / REGION), newest first, capped at {@code limit}. */
|
| 37784 |
vikas |
158 |
java.util.List<Integer> selectLeadIdsForBucket(String bucketType, String bucketKey, Integer regionId, Integer agentId,
|
| 37120 |
vikas |
159 |
LocalDateTime now, LocalDateTime nowPlus1h,
|
| 37749 |
vikas |
160 |
LocalDateTime from, LocalDateTime to, int offset, int limit);
|
|
|
161 |
|
|
|
162 |
/** Total leads in the same drill bucket, so the drawer can page through all of them. */
|
| 37784 |
vikas |
163 |
long countLeadsForBucket(String bucketType, String bucketKey, Integer regionId, Integer agentId,
|
| 37749 |
vikas |
164 |
LocalDateTime now, LocalDateTime nowPlus1h,
|
|
|
165 |
LocalDateTime from, LocalDateTime to);
|
|
|
166 |
|
|
|
167 |
/**
|
|
|
168 |
* Effective LMS stage per lead id, computed with the same evidence-aware expression the dashboard
|
|
|
169 |
* aggregates use (beat stops, check-ins, LOI + stock payment). Lead.getEffectiveStage() reads only
|
|
|
170 |
* the column and will disagree for the funnel's tail.
|
|
|
171 |
*/
|
|
|
172 |
java.util.Map<Integer, String> selectEffectiveStages(java.util.List<Integer> ids);
|
| 25899 |
tejbeer |
173 |
}
|