| Line 702... |
Line 702... |
| 702 |
*
|
702 |
*
|
| 703 |
* <p>Returns the page plus the true total, so the table can report "50 of 229" rather than
|
703 |
* <p>Returns the page plus the true total, so the table can report "50 of 229" rather than
|
| 704 |
* implying the twelve rows it drew are all there are. A non-empty {@code q} searches across all
|
704 |
* implying the twelve rows it drew are all there are. A non-empty {@code q} searches across all
|
| 705 |
* leads and ignores the date window — see {@code LeadRepository.selectPipeline}.
|
705 |
* leads and ignores the date window — see {@code LeadRepository.selectPipeline}.
|
| 706 |
*/
|
706 |
*/
|
| 707 |
public Map<String, Object> pipeline(String q, Integer regionId, LocalDateTime from, LocalDateTime to,
|
707 |
public Map<String, Object> pipeline(String q, Integer regionId, Integer agentId, LocalDateTime from, LocalDateTime to,
|
| 708 |
String sort, String dir, int page, int pageSize) {
|
708 |
String sort, String dir, int page, int pageSize) {
|
| 709 |
int size = Math.min(Math.max(pageSize, 1), MAX_PAGE_SIZE);
|
709 |
int size = Math.min(Math.max(pageSize, 1), MAX_PAGE_SIZE);
|
| 710 |
int p = Math.max(page, 1);
|
710 |
int p = Math.max(page, 1);
|
| 711 |
boolean searching = q != null && !q.trim().isEmpty();
|
711 |
boolean searching = q != null && !q.trim().isEmpty();
|
| 712 |
|
712 |
|
| 713 |
long total = leadRepository.countPipeline(q, regionId, from, to);
|
713 |
long total = leadRepository.countPipeline(q, regionId, agentId, from, to);
|
| 714 |
List<Lead> leads = leadRepository.selectPipeline(q, regionId, from, to, sort, dir, (p - 1) * size, size);
|
714 |
List<Lead> leads = leadRepository.selectPipeline(q, regionId, agentId, from, to, sort, dir, (p - 1) * size, size);
|
| 715 |
|
715 |
|
| 716 |
Map<String, Object> out = new LinkedHashMap<>();
|
716 |
Map<String, Object> out = new LinkedHashMap<>();
|
| 717 |
out.put("rows", toRows(leads));
|
717 |
out.put("rows", toRows(leads));
|
| 718 |
out.put("total", total);
|
718 |
out.put("total", total);
|
| 719 |
out.put("page", p);
|
719 |
out.put("page", p);
|
| Line 870... |
Line 870... |
| 870 |
m.put("stage", eff != null ? eff.name() : null);
|
870 |
m.put("stage", eff != null ? eff.name() : null);
|
| 871 |
m.put("stageLabel", pretty(eff));
|
871 |
m.put("stageLabel", pretty(eff));
|
| 872 |
m.put("stageIndex", stageIndex);
|
872 |
m.put("stageIndex", stageIndex);
|
| 873 |
m.put("terminal", terminal);
|
873 |
m.put("terminal", terminal);
|
| 874 |
m.put("created", l.getCreatedTimestamp() == null ? null : l.getCreatedTimestamp().toString());
|
874 |
m.put("created", l.getCreatedTimestamp() == null ? null : l.getCreatedTimestamp().toString());
|
| - |
|
875 |
// The creator, not the assignee: user.lead.created_by is stamped at creation (the pipeline
|
| - |
|
876 |
// table shows the same column). Rows written before that stamp fall back to the creating
|
| - |
|
877 |
// account; the owner was never a correct stand-in and read as a different person.
|
| - |
|
878 |
String createdBy = l.getCreatedBy() == null ? "" : l.getCreatedBy().trim();
|
| - |
|
879 |
if (createdBy.isEmpty() && l.getAuthId() > 0) {
|
| - |
|
880 |
AuthUser creator = l.getAuthId() == l.getAssignTo() ? owner : authRepository.selectById(l.getAuthId());
|
| 875 |
m.put("createdBy", owner != null ? owner.getFullName() : null); // best-effort
|
881 |
createdBy = creator != null ? creator.getFullName() : "";
|
| - |
|
882 |
}
|
| - |
|
883 |
m.put("createdBy", createdBy.isEmpty() ? null : createdBy);
|
| 876 |
m.put("path", l.getCreationPath());
|
884 |
m.put("path", l.getCreationPath());
|
| 877 |
m.put("contact", l.getLeadMobile());
|
885 |
m.put("contact", l.getLeadMobile());
|
| 878 |
m.put("location", joinLoc(l.getAddress(), l.getCity(), l.getState()));
|
886 |
m.put("location", joinLoc(l.getAddress(), l.getCity(), l.getState()));
|
| 879 |
m.put("regionCode", l.getRegionCode());
|
887 |
m.put("regionCode", l.getRegionCode());
|
| 880 |
m.put("value", l.getPotential());
|
888 |
m.put("value", l.getPotential());
|