| Line 46... |
Line 46... |
| 46 |
Map<String, Double> salesParams,
|
46 |
Map<String, Double> salesParams,
|
| 47 |
Map<String, Double> purchaseParams,
|
47 |
Map<String, Double> purchaseParams,
|
| 48 |
Map<String, Double> creditParams) {
|
48 |
Map<String, Double> creditParams) {
|
| 49 |
Map<AgendaType, Decision> out = new LinkedHashMap<>();
|
49 |
Map<AgendaType, Decision> out = new LinkedHashMap<>();
|
| 50 |
|
50 |
|
| - |
|
51 |
// REVIVAL store: the Revival agenda owns the visit — every data-driven
|
| - |
|
52 |
// agenda EXCEPT loan overdue (CREDIT_DUES) is suppressed (AUTO instances
|
| - |
|
53 |
// close; MANUAL ones are never touched by the cron).
|
| - |
|
54 |
Decision revivalSuppressed = new Decision(Action.CLOSE, "{\"reason\":\"REVIVAL\"}");
|
| - |
|
55 |
|
| 51 |
// LOW_INVESTMENT — existing platform metric, PJP trigger at shortPct.
|
56 |
// LOW_INVESTMENT — existing platform metric, PJP trigger at shortPct.
|
| - |
|
57 |
if (in.revival) {
|
| - |
|
58 |
out.put(AgendaType.LOW_INVESTMENT, revivalSuppressed);
|
| 52 |
if (in.shortPercentage == null || in.minInvestment <= 0) {
|
59 |
} else if (in.shortPercentage == null || in.minInvestment <= 0) {
|
| 53 |
out.put(AgendaType.LOW_INVESTMENT, new Decision(Action.LEAVE, null));
|
60 |
out.put(AgendaType.LOW_INVESTMENT, new Decision(Action.LEAVE, null));
|
| 54 |
} else {
|
61 |
} else {
|
| 55 |
double shortPct = param(investParams, "shortPct", 50);
|
62 |
double shortPct = param(investParams, "shortPct", 50);
|
| 56 |
String metric = "{\"shortPct\":" + Math.round(in.shortPercentage) + "}";
|
63 |
String metric = "{\"shortPct\":" + Math.round(in.shortPercentage) + "}";
|
| 57 |
out.put(AgendaType.LOW_INVESTMENT, new Decision(
|
64 |
out.put(AgendaType.LOW_INVESTMENT, new Decision(
|
| 58 |
in.shortPercentage > shortPct ? Action.OPEN : Action.CLOSE, metric));
|
65 |
in.shortPercentage > shortPct ? Action.OPEN : Action.CLOSE, metric));
|
| 59 |
}
|
66 |
}
|
| 60 |
|
67 |
|
| 61 |
// LOW_SALES — hysteresis vs trailing baseline.
|
68 |
// LOW_SALES — hysteresis vs trailing baseline.
|
| 62 |
double monthlyBaseline = in.baselineAmt / (param(salesParams, "baselineDays", 90) / 30d);
|
69 |
double monthlyBaseline = in.baselineAmt / (param(salesParams, "baselineDays", 90) / 30d);
|
| - |
|
70 |
if (in.revival) {
|
| - |
|
71 |
out.put(AgendaType.LOW_SALES, revivalSuppressed);
|
| 63 |
if (in.storeActivatedRecently || monthlyBaseline <= 0) {
|
72 |
} else if (in.storeActivatedRecently || monthlyBaseline <= 0) {
|
| 64 |
out.put(AgendaType.LOW_SALES, new Decision(Action.LEAVE, null));
|
73 |
out.put(AgendaType.LOW_SALES, new Decision(Action.LEAVE, null));
|
| 65 |
} else {
|
74 |
} else {
|
| 66 |
double flagPct = param(salesParams, "flagPct", 40);
|
75 |
double flagPct = param(salesParams, "flagPct", 40);
|
| 67 |
double clearPct = param(salesParams, "clearPct", 75);
|
76 |
double clearPct = param(salesParams, "clearPct", 75);
|
| 68 |
String metric = "{\"current\":" + Math.round(in.currentAmt)
|
77 |
String metric = "{\"current\":" + Math.round(in.currentAmt)
|
| Line 74... |
Line 83... |
| 74 |
} else {
|
83 |
} else {
|
| 75 |
out.put(AgendaType.LOW_SALES, new Decision(Action.LEAVE, metric));
|
84 |
out.put(AgendaType.LOW_SALES, new Decision(Action.LEAVE, metric));
|
| 76 |
}
|
85 |
}
|
| 77 |
}
|
86 |
}
|
| 78 |
|
87 |
|
| 79 |
// LOW_PURCHASE — days since last billed purchase; REVIVAL stores are
|
88 |
// LOW_PURCHASE — days since last billed purchase.
|
| 80 |
// the Revival agenda's problem, not this one's.
|
- |
|
| 81 |
if (in.revival) {
|
89 |
if (in.revival) {
|
| 82 |
out.put(AgendaType.LOW_PURCHASE, new Decision(Action.CLOSE, "{\"reason\":\"REVIVAL\"}"));
|
90 |
out.put(AgendaType.LOW_PURCHASE, revivalSuppressed);
|
| 83 |
} else {
|
91 |
} else {
|
| 84 |
double gapDays = param(purchaseParams, "gapDays", 15);
|
92 |
double gapDays = param(purchaseParams, "gapDays", 15);
|
| 85 |
boolean flag = in.lastBillDaysAgo == null || in.lastBillDaysAgo >= gapDays;
|
93 |
boolean flag = in.lastBillDaysAgo == null || in.lastBillDaysAgo >= gapDays;
|
| 86 |
String metric = "{\"gapDays\":" + (in.lastBillDaysAgo == null ? -1 : in.lastBillDaysAgo) + "}";
|
94 |
String metric = "{\"gapDays\":" + (in.lastBillDaysAgo == null ? -1 : in.lastBillDaysAgo) + "}";
|
| 87 |
out.put(AgendaType.LOW_PURCHASE, new Decision(flag ? Action.OPEN : Action.CLOSE, metric));
|
95 |
out.put(AgendaType.LOW_PURCHASE, new Decision(flag ? Action.OPEN : Action.CLOSE, metric));
|