Staff report: fold Y1 Monthly Sales Target row into the M matrix

The Y1 Monthly Sales Target fields don't match the Y1_M<n>_<metric> regex
the monthly matrix collector uses to discover rows:

  M1 -> Y1_Monthly_Sales_Targets       (no _M1 suffix; trailing 's')
  M2 -> Y1_Monthly_Sales_Targets_M2    (plural with _M2)
  M3 -> Y1_Monthly_Sales_Target_M2     (Civi name says _M2 but the value
                                        represents M3; pre-existing
                                        schema error)
  M4..M12 -> Y1_Monthly_Sales_Target_M<n>

Hardcode a period->civi-field-name map (Y1_MONTHLY_SALES_TARGET_FIELDS)
so the monthly matrix can pick these up alongside the regex-matched
Y1_M<n>_Actual_Sales / Y1_M<n>_Transactions rows. The M3->_M2
irregularity is called out inline so a future reader doesn't "fix" it
into a regression.
This commit is contained in:
Joel Brock
2026-06-10 09:29:42 -07:00
parent 63e73e7fe6
commit 50e719e1a9
+41
View File
@@ -553,6 +553,28 @@ interface Y1MatrixData {
periodLetter: "Q" | "M"; periodLetter: "Q" | "M";
usedNames: Set<string>; usedNames: Set<string>;
} }
/**
* Y1 Monthly Sales Target Civi machine names — irregular. M1 dropped the
* trailing period from "Y1_Monthly_Sales_Targets", M3 lives in a field named
* "_M2" (Civi schema error captured in the original form mapping), and the
* rest follow "Y1_Monthly_Sales_Target_M<n>". Hardcoded here so the staff
* report can fold these into the monthly Y1 matrix.
*/
const Y1_MONTHLY_SALES_TARGET_FIELDS: Record<number, string> = {
1: "Y1_Monthly_Sales_Targets",
2: "Y1_Monthly_Sales_Targets_M2",
3: "Y1_Monthly_Sales_Target_M2", // intentional: Civi name says M2, value is M3.
4: "Y1_Monthly_Sales_Target_M4",
5: "Y1_Monthly_Sales_Target_M5",
6: "Y1_Monthly_Sales_Target_M6",
7: "Y1_Monthly_Sales_Target_M7",
8: "Y1_Monthly_Sales_Target_M8",
9: "Y1_Monthly_Sales_Target_M9",
10: "Y1_Monthly_Sales_Target_M10",
11: "Y1_Monthly_Sales_Target_M11",
12: "Y1_Monthly_Sales_Target_M12",
};
function collectY1MatrixByPeriod( function collectY1MatrixByPeriod(
filled: StaffReportField[], filled: StaffReportField[],
periodLetter: "Q" | "M", periodLetter: "Q" | "M",
@@ -563,6 +585,7 @@ function collectY1MatrixByPeriod(
const byMetric = new Map<string, Map<number, StaffReportField>>(); const byMetric = new Map<string, Map<number, StaffReportField>>();
const periodsSet = new Set<number>(); const periodsSet = new Set<number>();
const metricLabel = new Map<string, string>(); const metricLabel = new Map<string, string>();
const byName = new Map(filled.map((f) => [f.descriptor.name, f]));
for (const f of filled) { for (const f of filled) {
const m = nameRe.exec(f.descriptor.name); const m = nameRe.exec(f.descriptor.name);
@@ -583,6 +606,24 @@ function collectY1MatrixByPeriod(
} }
} }
// Y1 Monthly Sales Target — fold in the irregular fields that don't fit
// the Y1_M<n>_<metric> regex above. Only present in the monthly matrix.
if (periodLetter === "M") {
const byMonth = new Map<number, StaffReportField>();
for (const [periodStr, fieldName] of Object.entries(Y1_MONTHLY_SALES_TARGET_FIELDS)) {
const f = byName.get(fieldName);
if (!f) continue;
const period = Number(periodStr);
byMonth.set(period, f);
used.add(fieldName);
periodsSet.add(period);
}
if (byMonth.size > 0) {
byMetric.set("Sales_Target", byMonth);
metricLabel.set("Sales_Target", "Sales Target");
}
}
if (byMetric.size === 0) return null; if (byMetric.size === 0) return null;
const periods = Array.from(periodsSet).sort((a, b) => a - b); const periods = Array.from(periodsSet).sort((a, b) => a - b);
const rows: Y1MatrixRow[] = Array.from(byMetric.entries()).map(([metric, byPeriod]) => ({ const rows: Y1MatrixRow[] = Array.from(byMetric.entries()).map(([metric, byPeriod]) => ({