| Line 141... |
Line 141... |
| 141 |
LocalDateTime base = lead.getCreatedTimestamp() != null ? lead.getCreatedTimestamp() : LocalDateTime.now();
|
141 |
LocalDateTime base = lead.getCreatedTimestamp() != null ? lead.getCreatedTimestamp() : LocalDateTime.now();
|
| 142 |
lead.setFirstContactDue(base.plusHours(SLA_HOURS));
|
142 |
lead.setFirstContactDue(base.plusHours(SLA_HOURS));
|
| 143 |
return a;
|
143 |
return a;
|
| 144 |
}
|
144 |
}
|
| 145 |
|
145 |
|
| - |
|
146 |
/**
|
| - |
|
147 |
* Stamp the LMS fields onto a lead created by a path that predates the LMS form.
|
| - |
|
148 |
*
|
| - |
|
149 |
* <p>Deliberately narrower than {@link #assign}: it never writes {@code status}. The legacy
|
| - |
|
150 |
* Leads screen owns that column and sets it per submission (pending / followUp / notInterested);
|
| - |
|
151 |
* {@code assign()} would flatten every one of those to pending and change what those screens
|
| - |
|
152 |
* show. Stage is likewise only set when the caller left it null.
|
| - |
|
153 |
*
|
| - |
|
154 |
* <p>What it always does is start the SLA clock, which is the point: 0 of 37,756 production
|
| - |
|
155 |
* leads had {@code first_contact_due}, so the SLA heat-map and the funnel's SLA% column had
|
| - |
|
156 |
* nothing to measure however correct their queries were.
|
| - |
|
157 |
*
|
| - |
|
158 |
* <p>Region comes from {@code lead.regionId} when the caller knows it, otherwise from the state
|
| - |
|
159 |
* name. An unmappable state (Bihar, Maharashtra) or an ambiguous one (Uttar Pradesh, which spans
|
| - |
|
160 |
* UP West / UP East / Remaining UP West) leaves the lead in HOLD with no owner — still clocked,
|
| - |
|
161 |
* still visible in the HOLD queue, which is the honest outcome rather than a guessed owner.
|
| - |
|
162 |
*/
|
| - |
|
163 |
public Assignment stamp(Lead lead, String creationPath) {
|
| - |
|
164 |
if (lead.getCreationPath() == null || lead.getCreationPath().trim().isEmpty()) {
|
| - |
|
165 |
lead.setCreationPath((creationPath != null && creationPath.trim().equalsIgnoreCase("B")) ? "B" : "A");
|
| - |
|
166 |
}
|
| - |
|
167 |
|
| - |
|
168 |
Integer regionId = lead.getRegionId();
|
| - |
|
169 |
if (regionId == null || regionId <= 0) {
|
| - |
|
170 |
regionId = resolveRegionIdByState(lead.getState());
|
| - |
|
171 |
}
|
| - |
|
172 |
Assignment a = resolve(regionId);
|
| - |
|
173 |
lead.setRegionId(a.regionId);
|
| - |
|
174 |
lead.setRegionCode(a.regionCode);
|
| - |
|
175 |
lead.setAssignmentStatus(a.assignmentStatus);
|
| - |
|
176 |
if (a.bm != null) {
|
| - |
|
177 |
lead.setOwnerBmId(a.bm.getId());
|
| - |
|
178 |
}
|
| - |
|
179 |
|
| - |
|
180 |
// Stage only when absent — a caller that already knows better keeps its value.
|
| - |
|
181 |
if (lead.getStage() == null) {
|
| - |
|
182 |
lead.setStage(LeadStage.ASSIGNED);
|
| - |
|
183 |
}
|
| - |
|
184 |
if (lead.getUnreachableCount() == null) {
|
| - |
|
185 |
lead.setUnreachableCount(0);
|
| - |
|
186 |
}
|
| - |
|
187 |
// Stamped once. Re-stamping a lead on edit would move the deadline and quietly clear a breach.
|
| - |
|
188 |
if (lead.getFirstContactDue() == null) {
|
| - |
|
189 |
LocalDateTime base = lead.getCreatedTimestamp() != null ? lead.getCreatedTimestamp() : LocalDateTime.now();
|
| - |
|
190 |
lead.setFirstContactDue(base.plusHours(SLA_HOURS));
|
| - |
|
191 |
}
|
| - |
|
192 |
return a;
|
| - |
|
193 |
}
|
| - |
|
194 |
|
| - |
|
195 |
/**
|
| - |
|
196 |
* cs.region id for a free-text state, matched case-insensitively on the region name.
|
| - |
|
197 |
*
|
| - |
|
198 |
* <p>Six of the seven SOP regions are named exactly as the states the legacy form captures
|
| - |
|
199 |
* (Haryana, Delhi, Punjab, Rajasthan, Uttarakhand, Madhya Pradesh). "Uttar Pradesh" is
|
| - |
|
200 |
* deliberately NOT mapped: it covers three regions and the state alone cannot say which, so
|
| - |
|
201 |
* guessing would hand 15,881 leads to the wrong BM. Those go to HOLD for a human to place.
|
| - |
|
202 |
*/
|
| - |
|
203 |
public Integer resolveRegionIdByState(String state) {
|
| - |
|
204 |
if (state == null || state.trim().isEmpty()) {
|
| - |
|
205 |
return null;
|
| - |
|
206 |
}
|
| - |
|
207 |
String wanted = state.trim();
|
| - |
|
208 |
List<Region> all = regionRepository.selectAll();
|
| - |
|
209 |
if (all == null) {
|
| - |
|
210 |
return null;
|
| - |
|
211 |
}
|
| - |
|
212 |
for (Region r : all) {
|
| - |
|
213 |
if (r.getName() != null && r.getName().trim().equalsIgnoreCase(wanted)) {
|
| - |
|
214 |
return r.getId();
|
| - |
|
215 |
}
|
| - |
|
216 |
}
|
| - |
|
217 |
for (Region r : all) {
|
| - |
|
218 |
if (r.getRegionCode() != null && r.getRegionCode().trim().equalsIgnoreCase(wanted)) {
|
| - |
|
219 |
return r.getId();
|
| - |
|
220 |
}
|
| - |
|
221 |
}
|
| - |
|
222 |
return null;
|
| - |
|
223 |
}
|
| - |
|
224 |
|
| 146 |
// ---- LMS id ---------------------------------------------------------------------------
|
225 |
// ---- LMS id ---------------------------------------------------------------------------
|
| 147 |
|
226 |
|
| 148 |
/** LMS-<REGION>-<YY>-<6-digit id>, e.g. LMS-UPW-26-000123. Call after the lead has an id. */
|
227 |
/** LMS-<REGION>-<YY>-<6-digit id>, e.g. LMS-UPW-26-000123. Call after the lead has an id. */
|
| 149 |
public String generateLmsCode(Lead lead) {
|
228 |
public String generateLmsCode(Lead lead) {
|
| 150 |
String region = (lead.getRegionCode() != null && !lead.getRegionCode().isEmpty())
|
229 |
String region = (lead.getRegionCode() != null && !lead.getRegionCode().isEmpty())
|