88 lines
3.0 KiB
TypeScript
88 lines
3.0 KiB
TypeScript
export type ResourceMonthReportExplainability = {
|
|
entity: "resource_month";
|
|
periodMonth: string | null;
|
|
locationContextColumns: string[];
|
|
holidayMetricColumns: string[];
|
|
absenceMetricColumns: string[];
|
|
capacityMetricColumns: string[];
|
|
chargeabilityMetricColumns: string[];
|
|
missingRecommendedColumns: string[];
|
|
notes: string[];
|
|
};
|
|
|
|
export type ReportExplainability = ResourceMonthReportExplainability;
|
|
|
|
const RESOURCE_MONTH_LOCATION_COLUMNS = [
|
|
"countryCode",
|
|
"countryName",
|
|
"federalState",
|
|
"metroCityName",
|
|
] as const;
|
|
|
|
const RESOURCE_MONTH_HOLIDAY_COLUMNS = [
|
|
"monthlyPublicHolidayCount",
|
|
"monthlyPublicHolidayWorkdayCount",
|
|
"monthlyPublicHolidayHoursDeduction",
|
|
] as const;
|
|
|
|
const RESOURCE_MONTH_ABSENCE_COLUMNS = [
|
|
"monthlyAbsenceDayEquivalent",
|
|
"monthlyAbsenceHoursDeduction",
|
|
] as const;
|
|
|
|
const RESOURCE_MONTH_CAPACITY_COLUMNS = [
|
|
"monthlyBaseWorkingDays",
|
|
"monthlyEffectiveWorkingDays",
|
|
"monthlyBaseAvailableHours",
|
|
"monthlySahHours",
|
|
"monthlyChargeabilityTargetPct",
|
|
"monthlyTargetHours",
|
|
] as const;
|
|
|
|
const RESOURCE_MONTH_CHARGEABILITY_COLUMNS = [
|
|
"monthlyActualBookedHours",
|
|
"monthlyExpectedBookedHours",
|
|
"monthlyActualChargeabilityPct",
|
|
"monthlyExpectedChargeabilityPct",
|
|
"monthlyUnassignedHours",
|
|
] as const;
|
|
|
|
const RESOURCE_MONTH_RECOMMENDED_COLUMNS = [
|
|
...RESOURCE_MONTH_LOCATION_COLUMNS,
|
|
...RESOURCE_MONTH_HOLIDAY_COLUMNS,
|
|
...RESOURCE_MONTH_ABSENCE_COLUMNS,
|
|
...RESOURCE_MONTH_CAPACITY_COLUMNS,
|
|
] as const;
|
|
|
|
function pickIncludedColumns(
|
|
requestedColumns: string[],
|
|
columnGroup: readonly string[],
|
|
): string[] {
|
|
return columnGroup.filter((column) => requestedColumns.includes(column));
|
|
}
|
|
|
|
export function buildResourceMonthReportExplainability(
|
|
requestedColumns: string[],
|
|
periodMonth?: string,
|
|
): ResourceMonthReportExplainability {
|
|
const missingRecommendedColumns = RESOURCE_MONTH_RECOMMENDED_COLUMNS.filter(
|
|
(column) => !requestedColumns.includes(column),
|
|
);
|
|
|
|
return {
|
|
entity: "resource_month",
|
|
periodMonth: periodMonth ?? null,
|
|
locationContextColumns: pickIncludedColumns(requestedColumns, RESOURCE_MONTH_LOCATION_COLUMNS),
|
|
holidayMetricColumns: pickIncludedColumns(requestedColumns, RESOURCE_MONTH_HOLIDAY_COLUMNS),
|
|
absenceMetricColumns: pickIncludedColumns(requestedColumns, RESOURCE_MONTH_ABSENCE_COLUMNS),
|
|
capacityMetricColumns: pickIncludedColumns(requestedColumns, RESOURCE_MONTH_CAPACITY_COLUMNS),
|
|
chargeabilityMetricColumns: pickIncludedColumns(requestedColumns, RESOURCE_MONTH_CHARGEABILITY_COLUMNS),
|
|
missingRecommendedColumns,
|
|
notes: [
|
|
"monthlySahHours already reflects region-specific public holidays from country, federal state, and city context when those attributes exist on the resource.",
|
|
"monthlyAbsence* metrics only deduct workdays that are not already counted as public holidays.",
|
|
"monthlyBaseAvailableHours shows pre-deduction capacity; compare it with holiday, absence, and SAH columns to explain the final monthly availability.",
|
|
],
|
|
};
|
|
}
|