@harbortouch/skytab-analytics-report-utils 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +64 -69
- package/dist/index.d.cts +7 -4
- package/dist/index.d.ts +7 -4
- package/dist/index.js +63 -69
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -51,6 +51,7 @@ __export(index_exports, {
|
|
|
51
51
|
TICKET_LIVE_DEFAULT_VISIBLE_COLUMNS: () => TICKET_LIVE_DEFAULT_VISIBLE_COLUMNS,
|
|
52
52
|
TICKET_SUMMARY_AVAILABLE_COLUMNS: () => TICKET_SUMMARY_AVAILABLE_COLUMNS,
|
|
53
53
|
TICKET_SUMMARY_DEFAULT_VISIBLE_COLUMNS: () => TICKET_SUMMARY_DEFAULT_VISIBLE_COLUMNS,
|
|
54
|
+
calculateFieldTotal: () => calculateFieldTotal,
|
|
54
55
|
calculateReportTotals: () => calculateReportTotals,
|
|
55
56
|
dailySalesConfig: () => dailySalesConfig,
|
|
56
57
|
dailySalesDiscountsConfig: () => dailySalesDiscountsConfig,
|
|
@@ -98,18 +99,18 @@ var FIELDS = {
|
|
|
98
99
|
type: "percent",
|
|
99
100
|
columnKey: "salesVarLwPct",
|
|
100
101
|
footerCalculation: {
|
|
101
|
-
type: "
|
|
102
|
-
numeratorField: "
|
|
103
|
-
denominatorField: "
|
|
102
|
+
type: "variancePercent",
|
|
103
|
+
numeratorField: "salesVarLW",
|
|
104
|
+
denominatorField: "salesAmountNet"
|
|
104
105
|
}
|
|
105
106
|
},
|
|
106
107
|
salesVarLYPct: {
|
|
107
108
|
type: "percent",
|
|
108
109
|
columnKey: "salesVarLyPct",
|
|
109
110
|
footerCalculation: {
|
|
110
|
-
type: "
|
|
111
|
-
numeratorField: "
|
|
112
|
-
denominatorField: "
|
|
111
|
+
type: "variancePercent",
|
|
112
|
+
numeratorField: "salesVarLY",
|
|
113
|
+
denominatorField: "salesAmountNet"
|
|
113
114
|
}
|
|
114
115
|
},
|
|
115
116
|
salesAmountNetLastWeek: { type: "money" },
|
|
@@ -127,18 +128,18 @@ var FIELDS = {
|
|
|
127
128
|
type: "percent",
|
|
128
129
|
columnKey: "guestsVarLwPct",
|
|
129
130
|
footerCalculation: {
|
|
130
|
-
type: "
|
|
131
|
-
numeratorField: "
|
|
132
|
-
denominatorField: "
|
|
131
|
+
type: "variancePercent",
|
|
132
|
+
numeratorField: "guestsVarLW",
|
|
133
|
+
denominatorField: "guestsCount"
|
|
133
134
|
}
|
|
134
135
|
},
|
|
135
136
|
guestsVarLYPct: {
|
|
136
137
|
type: "percent",
|
|
137
138
|
columnKey: "guestsVarLyPct",
|
|
138
139
|
footerCalculation: {
|
|
139
|
-
type: "
|
|
140
|
-
numeratorField: "
|
|
141
|
-
denominatorField: "
|
|
140
|
+
type: "variancePercent",
|
|
141
|
+
numeratorField: "guestsVarLY",
|
|
142
|
+
denominatorField: "guestsCount"
|
|
142
143
|
}
|
|
143
144
|
},
|
|
144
145
|
guestsCountLastWeek: { type: "number" },
|
|
@@ -156,18 +157,22 @@ var FIELDS = {
|
|
|
156
157
|
type: "money",
|
|
157
158
|
columnKey: "salesPerGuestLw",
|
|
158
159
|
footerCalculation: {
|
|
159
|
-
type: "
|
|
160
|
-
numeratorField: "
|
|
161
|
-
|
|
160
|
+
type: "quotientOfDifferences",
|
|
161
|
+
numeratorField: "salesAmountNet",
|
|
162
|
+
numeratorAdjustField: "salesVarLW",
|
|
163
|
+
denominatorField: "guestsCount",
|
|
164
|
+
denominatorAdjustField: "guestsVarLW"
|
|
162
165
|
}
|
|
163
166
|
},
|
|
164
167
|
salesPerGuestLY: {
|
|
165
168
|
type: "money",
|
|
166
169
|
columnKey: "salesPerGuestLy",
|
|
167
170
|
footerCalculation: {
|
|
168
|
-
type: "
|
|
169
|
-
numeratorField: "
|
|
170
|
-
|
|
171
|
+
type: "quotientOfDifferences",
|
|
172
|
+
numeratorField: "salesAmountNet",
|
|
173
|
+
numeratorAdjustField: "salesVarLY",
|
|
174
|
+
denominatorField: "guestsCount",
|
|
175
|
+
denominatorAdjustField: "guestsVarLY"
|
|
171
176
|
}
|
|
172
177
|
}
|
|
173
178
|
};
|
|
@@ -1524,65 +1529,54 @@ function isNumericType(type) {
|
|
|
1524
1529
|
}
|
|
1525
1530
|
|
|
1526
1531
|
// src/totals.ts
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
const {
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
for (const [field, config] of Object.entries(fieldConfig)) {
|
|
1533
|
-
const { type, columnKey, footerCalculation: calc } = config;
|
|
1534
|
-
if (!type || type === "string" || type === "date" || type === "time" || type === "boolean") {
|
|
1535
|
-
continue;
|
|
1536
|
-
}
|
|
1537
|
-
if (calc?.type === "none") {
|
|
1538
|
-
} else if (!calc || calc.type === "sum") {
|
|
1539
|
-
if (columnKey || calc?.type === "sum") {
|
|
1540
|
-
fieldsToSum.add(field);
|
|
1541
|
-
}
|
|
1542
|
-
} else {
|
|
1543
|
-
derivedFields.push({ field, calc });
|
|
1544
|
-
if (calc.numeratorField) {
|
|
1545
|
-
fieldsToSum.add(calc.numeratorField);
|
|
1546
|
-
}
|
|
1547
|
-
if (calc.denominatorField) {
|
|
1548
|
-
fieldsToSum.add(calc.denominatorField);
|
|
1549
|
-
}
|
|
1550
|
-
}
|
|
1532
|
+
var sumField = (rows, field) => rows.reduce((acc, row) => acc + (row[field] ?? 0), 0);
|
|
1533
|
+
var calculateFieldTotal = (rows, field, config) => {
|
|
1534
|
+
const { type } = config;
|
|
1535
|
+
if (!type || type === "string" || type === "date" || type === "time" || type === "boolean" || type === "conditional") {
|
|
1536
|
+
return null;
|
|
1551
1537
|
}
|
|
1552
|
-
const
|
|
1553
|
-
|
|
1554
|
-
|
|
1538
|
+
const calc = config.footerCalculation;
|
|
1539
|
+
if (calc?.type === "none") {
|
|
1540
|
+
return 0;
|
|
1555
1541
|
}
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1542
|
+
if (!calc || calc.type === "sum") {
|
|
1543
|
+
return config.columnKey || calc?.type === "sum" ? sumField(rows, field) : 0;
|
|
1544
|
+
}
|
|
1545
|
+
const { numeratorField, denominatorField } = calc;
|
|
1546
|
+
if (!numeratorField || !denominatorField) {
|
|
1547
|
+
return 0;
|
|
1548
|
+
}
|
|
1549
|
+
const num = sumField(rows, numeratorField);
|
|
1550
|
+
const den = sumField(rows, denominatorField);
|
|
1551
|
+
if (calc.type === "percentChange") {
|
|
1552
|
+
return den ? (num - den) / den : 0;
|
|
1553
|
+
}
|
|
1554
|
+
if (calc.type === "variancePercent") {
|
|
1555
|
+
const prior = den - num;
|
|
1556
|
+
return prior ? num / prior : 0;
|
|
1557
|
+
}
|
|
1558
|
+
if (calc.type === "average") {
|
|
1559
|
+
return den > 0 ? num / den : 0;
|
|
1560
|
+
}
|
|
1561
|
+
if (calc.type === "quotientOfDifferences") {
|
|
1562
|
+
const { numeratorAdjustField, denominatorAdjustField } = calc;
|
|
1563
|
+
const numAdj = numeratorAdjustField ? sumField(rows, numeratorAdjustField) : 0;
|
|
1564
|
+
const denAdj = denominatorAdjustField ? sumField(rows, denominatorAdjustField) : 0;
|
|
1565
|
+
const effectiveDen = den - denAdj;
|
|
1566
|
+
return effectiveDen !== 0 ? (num - numAdj) / effectiveDen : 0;
|
|
1565
1567
|
}
|
|
1568
|
+
return 0;
|
|
1569
|
+
};
|
|
1570
|
+
var calculateReportTotals = (data, fieldConfig, opts) => {
|
|
1571
|
+
const { labelField, label } = opts;
|
|
1566
1572
|
const result = {};
|
|
1567
1573
|
for (const [field, config] of Object.entries(fieldConfig)) {
|
|
1568
|
-
const
|
|
1569
|
-
|
|
1570
|
-
result[field] = "";
|
|
1571
|
-
} else if (type === "boolean") {
|
|
1572
|
-
result[field] = false;
|
|
1573
|
-
} else {
|
|
1574
|
-
result[field] = 0;
|
|
1575
|
-
}
|
|
1574
|
+
const total = calculateFieldTotal(data, field, config);
|
|
1575
|
+
result[field] = total ?? "";
|
|
1576
1576
|
}
|
|
1577
1577
|
result[labelField] = label;
|
|
1578
|
-
for (const [field, value] of Object.entries(sums)) {
|
|
1579
|
-
result[field] = value;
|
|
1580
|
-
}
|
|
1581
|
-
for (const [field, value] of Object.entries(derived)) {
|
|
1582
|
-
result[field] = value;
|
|
1583
|
-
}
|
|
1584
1578
|
return result;
|
|
1585
|
-
}
|
|
1579
|
+
};
|
|
1586
1580
|
|
|
1587
1581
|
// src/reports/dailySalesRefundsVoids.ts
|
|
1588
1582
|
var FIRST_COLUMN_WIDTH8 = 240;
|
|
@@ -1795,6 +1789,7 @@ var formatFieldValue = (value, type, localeOptions, fullRecord, fieldConfig = DE
|
|
|
1795
1789
|
TICKET_LIVE_DEFAULT_VISIBLE_COLUMNS,
|
|
1796
1790
|
TICKET_SUMMARY_AVAILABLE_COLUMNS,
|
|
1797
1791
|
TICKET_SUMMARY_DEFAULT_VISIBLE_COLUMNS,
|
|
1792
|
+
calculateFieldTotal,
|
|
1798
1793
|
calculateReportTotals,
|
|
1799
1794
|
dailySalesConfig,
|
|
1800
1795
|
dailySalesDiscountsConfig,
|
package/dist/index.d.cts
CHANGED
|
@@ -1181,11 +1181,13 @@ declare function getColumnExportHeaderLabel(colTitle: string, groupTitle: string
|
|
|
1181
1181
|
|
|
1182
1182
|
type FieldType = 'string' | 'money' | 'percent' | 'number' | 'fixedNumber' | 'date' | 'time' | 'boolean' | 'conditional';
|
|
1183
1183
|
type ColumnAlignment = 'left' | 'right';
|
|
1184
|
-
type FooterCalculationType = 'sum' | 'percentChange' | 'average' | 'none';
|
|
1184
|
+
type FooterCalculationType = 'sum' | 'percentChange' | 'variancePercent' | 'average' | 'quotientOfDifferences' | 'none';
|
|
1185
1185
|
interface FooterCalculation<TField = string> {
|
|
1186
1186
|
type: FooterCalculationType;
|
|
1187
1187
|
numeratorField?: TField;
|
|
1188
|
+
numeratorAdjustField?: string;
|
|
1188
1189
|
denominatorField?: TField;
|
|
1190
|
+
denominatorAdjustField?: string;
|
|
1189
1191
|
}
|
|
1190
1192
|
interface ConditionalConfiguration<TField = string> {
|
|
1191
1193
|
conditionalField: TField;
|
|
@@ -1242,7 +1244,8 @@ interface CalculateReportTotalsOptions {
|
|
|
1242
1244
|
labelField: string;
|
|
1243
1245
|
label: string;
|
|
1244
1246
|
}
|
|
1245
|
-
declare
|
|
1247
|
+
declare const calculateFieldTotal: <T>(rows: T[], field: keyof T, config: ColumnPresentationConfig) => number | null;
|
|
1248
|
+
declare const calculateReportTotals: <T>(data: T[], fieldConfig: Record<string, ColumnPresentationConfig>, opts: CalculateReportTotalsOptions) => T;
|
|
1246
1249
|
|
|
1247
1250
|
type SalesSummaryField = 'groupById' | 'groupByName' | 'salesAmountNet' | 'salesVarLW' | 'salesVarLY' | 'salesVarLWPct' | 'salesVarLYPct' | 'salesAmountNetLastWeek' | 'salesAmountNetLastYear' | 'salesAmountGross' | 'salesAmountGrossLastWeek' | 'salesAmountGrossLastYear' | 'ticketsCount' | 'ticketsCountLastWeek' | 'ticketsCountLastYear' | 'guestsCount' | 'guestsVarLW' | 'guestsVarLY' | 'guestsVarLWPct' | 'guestsVarLYPct' | 'guestsCountLastWeek' | 'guestsCountLastYear' | 'salesPerGuestTY' | 'salesPerGuestLW' | 'salesPerGuestLY';
|
|
1248
1251
|
declare const SALES_SUMMARY_AVAILABLE_COLUMNS: SalesSummaryField[];
|
|
@@ -1352,6 +1355,6 @@ declare const getReportFormattingLocaleOptions: (locations: {
|
|
|
1352
1355
|
countryCode: string;
|
|
1353
1356
|
language: string;
|
|
1354
1357
|
}[]) => LocaleOption[];
|
|
1355
|
-
declare const formatFieldValue: (value: unknown, type: FieldType, localeOptions: LocaleOption, fullRecord: Record<string, unknown> | null, fieldConfig?: ColumnPresentationConfig) => string;
|
|
1358
|
+
declare const formatFieldValue: (value: unknown, type: FieldType, localeOptions: LocaleOption, fullRecord: Record<string, unknown> | null | undefined, fieldConfig?: ColumnPresentationConfig) => string;
|
|
1356
1359
|
|
|
1357
|
-
export { COLUMN_REGISTRY, type CalculateReportTotalsOptions, type ColumnAlignment, type ColumnGroupConfig, type ColumnMetadata, type ColumnPresentationConfig, DAILY_SALES_AVAILABLE_COLUMNS, DAILY_SALES_BY_GROUP_AVAILABLE_COLUMNS, DAILY_SALES_DEFAULT_VISIBLE_COLUMNS, DAILY_SALES_DISCOUNTS_AVAILABLE_COLUMNS, DAILY_SALES_DISCOUNTS_DEFAULT_VISIBLE_COLUMNS, DAILY_SALES_PAYMENTS_AVAILABLE_COLUMNS, DAILY_SALES_PAYMENTS_DEFAULT_VISIBLE_COLUMNS, DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUMNS, DAILY_SALES_REFUNDS_VOIDS_DEFAULT_VISIBLE_COLUMNS, DAILY_SALES_TAXES_AVAILABLE_COLUMNS, DAILY_SALES_TAXES_DEFAULT_VISIBLE_COLUMNS, DAILY_SALES_TRENDS_AVAILABLE_COLUMNS, EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS, EMPLOYEE_TIMECARD_DEFAULT_VISIBLE_COLUMNS, type FieldType, type FooterCalculation, type FooterCalculationType, type FormatDateOptions, type FormatMoneyOptions, type FormatNumberOptions, type FormatTimeOptions, ITEM_TAX_AVAILABLE_COLUMNS, ITEM_TAX_DEFAULT_VISIBLE_COLUMNS, type LocaleOption, MODIFIER_MIX_AVAILABLE_COLUMNS, MODIFIER_MIX_DEFAULT_VISIBLE_COLUMNS, PRODUCT_MIX_AVAILABLE_COLUMNS, PRODUCT_MIX_CHART_FIELDS, PRODUCT_MIX_DEFAULT_VISIBLE_COLUMNS, Report, type ReportColumnKey, type ReportConfig, type ReportType, SALES_BY_ITEM_DETAIL_AVAILABLE_COLUMNS, SALES_BY_ITEM_DETAIL_DEFAULT_VISIBLE_COLUMNS, SALES_SUMMARY_AVAILABLE_COLUMNS, SALES_SUMMARY_DEFAULT_VISIBLE_COLUMNS, TICKET_LIVE_AVAILABLE_COLUMNS, TICKET_LIVE_DEFAULT_VISIBLE_COLUMNS, TICKET_SUMMARY_AVAILABLE_COLUMNS, TICKET_SUMMARY_DEFAULT_VISIBLE_COLUMNS, type TimeFormat, calculateReportTotals, dailySalesConfig, dailySalesDiscountsConfig, dailySalesPaymentsConfig, dailySalesRefundsVoidsConfig, dailySalesTaxesConfig, dailySalesTrendsConfig, employeeTimecardConfig, formatDate, formatFieldValue, formatFixedNumber, formatInteger, formatMoney, formatMoneyWithoutSymbol, formatPercent, formatString, formatTime, getColumnAlignment, getColumnExportHeaderLabel, getColumnMetadata, getDateToFormat, getNumberToFormat, getReportConfig, getReportFormattingLocaleOptions, isNumericType, itemTaxConfig, modifierMixConfig, productMixConfig, salesByItemDetailConfig, salesSummaryConfig, ticketLiveConfig, ticketSummaryConfig };
|
|
1360
|
+
export { COLUMN_REGISTRY, type CalculateReportTotalsOptions, type ColumnAlignment, type ColumnGroupConfig, type ColumnMetadata, type ColumnPresentationConfig, DAILY_SALES_AVAILABLE_COLUMNS, DAILY_SALES_BY_GROUP_AVAILABLE_COLUMNS, DAILY_SALES_DEFAULT_VISIBLE_COLUMNS, DAILY_SALES_DISCOUNTS_AVAILABLE_COLUMNS, DAILY_SALES_DISCOUNTS_DEFAULT_VISIBLE_COLUMNS, DAILY_SALES_PAYMENTS_AVAILABLE_COLUMNS, DAILY_SALES_PAYMENTS_DEFAULT_VISIBLE_COLUMNS, DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUMNS, DAILY_SALES_REFUNDS_VOIDS_DEFAULT_VISIBLE_COLUMNS, DAILY_SALES_TAXES_AVAILABLE_COLUMNS, DAILY_SALES_TAXES_DEFAULT_VISIBLE_COLUMNS, DAILY_SALES_TRENDS_AVAILABLE_COLUMNS, EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS, EMPLOYEE_TIMECARD_DEFAULT_VISIBLE_COLUMNS, type FieldType, type FooterCalculation, type FooterCalculationType, type FormatDateOptions, type FormatMoneyOptions, type FormatNumberOptions, type FormatTimeOptions, ITEM_TAX_AVAILABLE_COLUMNS, ITEM_TAX_DEFAULT_VISIBLE_COLUMNS, type LocaleOption, MODIFIER_MIX_AVAILABLE_COLUMNS, MODIFIER_MIX_DEFAULT_VISIBLE_COLUMNS, PRODUCT_MIX_AVAILABLE_COLUMNS, PRODUCT_MIX_CHART_FIELDS, PRODUCT_MIX_DEFAULT_VISIBLE_COLUMNS, Report, type ReportColumnKey, type ReportConfig, type ReportType, SALES_BY_ITEM_DETAIL_AVAILABLE_COLUMNS, SALES_BY_ITEM_DETAIL_DEFAULT_VISIBLE_COLUMNS, SALES_SUMMARY_AVAILABLE_COLUMNS, SALES_SUMMARY_DEFAULT_VISIBLE_COLUMNS, TICKET_LIVE_AVAILABLE_COLUMNS, TICKET_LIVE_DEFAULT_VISIBLE_COLUMNS, TICKET_SUMMARY_AVAILABLE_COLUMNS, TICKET_SUMMARY_DEFAULT_VISIBLE_COLUMNS, type TimeFormat, calculateFieldTotal, calculateReportTotals, dailySalesConfig, dailySalesDiscountsConfig, dailySalesPaymentsConfig, dailySalesRefundsVoidsConfig, dailySalesTaxesConfig, dailySalesTrendsConfig, employeeTimecardConfig, formatDate, formatFieldValue, formatFixedNumber, formatInteger, formatMoney, formatMoneyWithoutSymbol, formatPercent, formatString, formatTime, getColumnAlignment, getColumnExportHeaderLabel, getColumnMetadata, getDateToFormat, getNumberToFormat, getReportConfig, getReportFormattingLocaleOptions, isNumericType, itemTaxConfig, modifierMixConfig, productMixConfig, salesByItemDetailConfig, salesSummaryConfig, ticketLiveConfig, ticketSummaryConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -1181,11 +1181,13 @@ declare function getColumnExportHeaderLabel(colTitle: string, groupTitle: string
|
|
|
1181
1181
|
|
|
1182
1182
|
type FieldType = 'string' | 'money' | 'percent' | 'number' | 'fixedNumber' | 'date' | 'time' | 'boolean' | 'conditional';
|
|
1183
1183
|
type ColumnAlignment = 'left' | 'right';
|
|
1184
|
-
type FooterCalculationType = 'sum' | 'percentChange' | 'average' | 'none';
|
|
1184
|
+
type FooterCalculationType = 'sum' | 'percentChange' | 'variancePercent' | 'average' | 'quotientOfDifferences' | 'none';
|
|
1185
1185
|
interface FooterCalculation<TField = string> {
|
|
1186
1186
|
type: FooterCalculationType;
|
|
1187
1187
|
numeratorField?: TField;
|
|
1188
|
+
numeratorAdjustField?: string;
|
|
1188
1189
|
denominatorField?: TField;
|
|
1190
|
+
denominatorAdjustField?: string;
|
|
1189
1191
|
}
|
|
1190
1192
|
interface ConditionalConfiguration<TField = string> {
|
|
1191
1193
|
conditionalField: TField;
|
|
@@ -1242,7 +1244,8 @@ interface CalculateReportTotalsOptions {
|
|
|
1242
1244
|
labelField: string;
|
|
1243
1245
|
label: string;
|
|
1244
1246
|
}
|
|
1245
|
-
declare
|
|
1247
|
+
declare const calculateFieldTotal: <T>(rows: T[], field: keyof T, config: ColumnPresentationConfig) => number | null;
|
|
1248
|
+
declare const calculateReportTotals: <T>(data: T[], fieldConfig: Record<string, ColumnPresentationConfig>, opts: CalculateReportTotalsOptions) => T;
|
|
1246
1249
|
|
|
1247
1250
|
type SalesSummaryField = 'groupById' | 'groupByName' | 'salesAmountNet' | 'salesVarLW' | 'salesVarLY' | 'salesVarLWPct' | 'salesVarLYPct' | 'salesAmountNetLastWeek' | 'salesAmountNetLastYear' | 'salesAmountGross' | 'salesAmountGrossLastWeek' | 'salesAmountGrossLastYear' | 'ticketsCount' | 'ticketsCountLastWeek' | 'ticketsCountLastYear' | 'guestsCount' | 'guestsVarLW' | 'guestsVarLY' | 'guestsVarLWPct' | 'guestsVarLYPct' | 'guestsCountLastWeek' | 'guestsCountLastYear' | 'salesPerGuestTY' | 'salesPerGuestLW' | 'salesPerGuestLY';
|
|
1248
1251
|
declare const SALES_SUMMARY_AVAILABLE_COLUMNS: SalesSummaryField[];
|
|
@@ -1352,6 +1355,6 @@ declare const getReportFormattingLocaleOptions: (locations: {
|
|
|
1352
1355
|
countryCode: string;
|
|
1353
1356
|
language: string;
|
|
1354
1357
|
}[]) => LocaleOption[];
|
|
1355
|
-
declare const formatFieldValue: (value: unknown, type: FieldType, localeOptions: LocaleOption, fullRecord: Record<string, unknown> | null, fieldConfig?: ColumnPresentationConfig) => string;
|
|
1358
|
+
declare const formatFieldValue: (value: unknown, type: FieldType, localeOptions: LocaleOption, fullRecord: Record<string, unknown> | null | undefined, fieldConfig?: ColumnPresentationConfig) => string;
|
|
1356
1359
|
|
|
1357
|
-
export { COLUMN_REGISTRY, type CalculateReportTotalsOptions, type ColumnAlignment, type ColumnGroupConfig, type ColumnMetadata, type ColumnPresentationConfig, DAILY_SALES_AVAILABLE_COLUMNS, DAILY_SALES_BY_GROUP_AVAILABLE_COLUMNS, DAILY_SALES_DEFAULT_VISIBLE_COLUMNS, DAILY_SALES_DISCOUNTS_AVAILABLE_COLUMNS, DAILY_SALES_DISCOUNTS_DEFAULT_VISIBLE_COLUMNS, DAILY_SALES_PAYMENTS_AVAILABLE_COLUMNS, DAILY_SALES_PAYMENTS_DEFAULT_VISIBLE_COLUMNS, DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUMNS, DAILY_SALES_REFUNDS_VOIDS_DEFAULT_VISIBLE_COLUMNS, DAILY_SALES_TAXES_AVAILABLE_COLUMNS, DAILY_SALES_TAXES_DEFAULT_VISIBLE_COLUMNS, DAILY_SALES_TRENDS_AVAILABLE_COLUMNS, EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS, EMPLOYEE_TIMECARD_DEFAULT_VISIBLE_COLUMNS, type FieldType, type FooterCalculation, type FooterCalculationType, type FormatDateOptions, type FormatMoneyOptions, type FormatNumberOptions, type FormatTimeOptions, ITEM_TAX_AVAILABLE_COLUMNS, ITEM_TAX_DEFAULT_VISIBLE_COLUMNS, type LocaleOption, MODIFIER_MIX_AVAILABLE_COLUMNS, MODIFIER_MIX_DEFAULT_VISIBLE_COLUMNS, PRODUCT_MIX_AVAILABLE_COLUMNS, PRODUCT_MIX_CHART_FIELDS, PRODUCT_MIX_DEFAULT_VISIBLE_COLUMNS, Report, type ReportColumnKey, type ReportConfig, type ReportType, SALES_BY_ITEM_DETAIL_AVAILABLE_COLUMNS, SALES_BY_ITEM_DETAIL_DEFAULT_VISIBLE_COLUMNS, SALES_SUMMARY_AVAILABLE_COLUMNS, SALES_SUMMARY_DEFAULT_VISIBLE_COLUMNS, TICKET_LIVE_AVAILABLE_COLUMNS, TICKET_LIVE_DEFAULT_VISIBLE_COLUMNS, TICKET_SUMMARY_AVAILABLE_COLUMNS, TICKET_SUMMARY_DEFAULT_VISIBLE_COLUMNS, type TimeFormat, calculateReportTotals, dailySalesConfig, dailySalesDiscountsConfig, dailySalesPaymentsConfig, dailySalesRefundsVoidsConfig, dailySalesTaxesConfig, dailySalesTrendsConfig, employeeTimecardConfig, formatDate, formatFieldValue, formatFixedNumber, formatInteger, formatMoney, formatMoneyWithoutSymbol, formatPercent, formatString, formatTime, getColumnAlignment, getColumnExportHeaderLabel, getColumnMetadata, getDateToFormat, getNumberToFormat, getReportConfig, getReportFormattingLocaleOptions, isNumericType, itemTaxConfig, modifierMixConfig, productMixConfig, salesByItemDetailConfig, salesSummaryConfig, ticketLiveConfig, ticketSummaryConfig };
|
|
1360
|
+
export { COLUMN_REGISTRY, type CalculateReportTotalsOptions, type ColumnAlignment, type ColumnGroupConfig, type ColumnMetadata, type ColumnPresentationConfig, DAILY_SALES_AVAILABLE_COLUMNS, DAILY_SALES_BY_GROUP_AVAILABLE_COLUMNS, DAILY_SALES_DEFAULT_VISIBLE_COLUMNS, DAILY_SALES_DISCOUNTS_AVAILABLE_COLUMNS, DAILY_SALES_DISCOUNTS_DEFAULT_VISIBLE_COLUMNS, DAILY_SALES_PAYMENTS_AVAILABLE_COLUMNS, DAILY_SALES_PAYMENTS_DEFAULT_VISIBLE_COLUMNS, DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUMNS, DAILY_SALES_REFUNDS_VOIDS_DEFAULT_VISIBLE_COLUMNS, DAILY_SALES_TAXES_AVAILABLE_COLUMNS, DAILY_SALES_TAXES_DEFAULT_VISIBLE_COLUMNS, DAILY_SALES_TRENDS_AVAILABLE_COLUMNS, EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS, EMPLOYEE_TIMECARD_DEFAULT_VISIBLE_COLUMNS, type FieldType, type FooterCalculation, type FooterCalculationType, type FormatDateOptions, type FormatMoneyOptions, type FormatNumberOptions, type FormatTimeOptions, ITEM_TAX_AVAILABLE_COLUMNS, ITEM_TAX_DEFAULT_VISIBLE_COLUMNS, type LocaleOption, MODIFIER_MIX_AVAILABLE_COLUMNS, MODIFIER_MIX_DEFAULT_VISIBLE_COLUMNS, PRODUCT_MIX_AVAILABLE_COLUMNS, PRODUCT_MIX_CHART_FIELDS, PRODUCT_MIX_DEFAULT_VISIBLE_COLUMNS, Report, type ReportColumnKey, type ReportConfig, type ReportType, SALES_BY_ITEM_DETAIL_AVAILABLE_COLUMNS, SALES_BY_ITEM_DETAIL_DEFAULT_VISIBLE_COLUMNS, SALES_SUMMARY_AVAILABLE_COLUMNS, SALES_SUMMARY_DEFAULT_VISIBLE_COLUMNS, TICKET_LIVE_AVAILABLE_COLUMNS, TICKET_LIVE_DEFAULT_VISIBLE_COLUMNS, TICKET_SUMMARY_AVAILABLE_COLUMNS, TICKET_SUMMARY_DEFAULT_VISIBLE_COLUMNS, type TimeFormat, calculateFieldTotal, calculateReportTotals, dailySalesConfig, dailySalesDiscountsConfig, dailySalesPaymentsConfig, dailySalesRefundsVoidsConfig, dailySalesTaxesConfig, dailySalesTrendsConfig, employeeTimecardConfig, formatDate, formatFieldValue, formatFixedNumber, formatInteger, formatMoney, formatMoneyWithoutSymbol, formatPercent, formatString, formatTime, getColumnAlignment, getColumnExportHeaderLabel, getColumnMetadata, getDateToFormat, getNumberToFormat, getReportConfig, getReportFormattingLocaleOptions, isNumericType, itemTaxConfig, modifierMixConfig, productMixConfig, salesByItemDetailConfig, salesSummaryConfig, ticketLiveConfig, ticketSummaryConfig };
|
package/dist/index.js
CHANGED
|
@@ -10,18 +10,18 @@ var FIELDS = {
|
|
|
10
10
|
type: "percent",
|
|
11
11
|
columnKey: "salesVarLwPct",
|
|
12
12
|
footerCalculation: {
|
|
13
|
-
type: "
|
|
14
|
-
numeratorField: "
|
|
15
|
-
denominatorField: "
|
|
13
|
+
type: "variancePercent",
|
|
14
|
+
numeratorField: "salesVarLW",
|
|
15
|
+
denominatorField: "salesAmountNet"
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
18
|
salesVarLYPct: {
|
|
19
19
|
type: "percent",
|
|
20
20
|
columnKey: "salesVarLyPct",
|
|
21
21
|
footerCalculation: {
|
|
22
|
-
type: "
|
|
23
|
-
numeratorField: "
|
|
24
|
-
denominatorField: "
|
|
22
|
+
type: "variancePercent",
|
|
23
|
+
numeratorField: "salesVarLY",
|
|
24
|
+
denominatorField: "salesAmountNet"
|
|
25
25
|
}
|
|
26
26
|
},
|
|
27
27
|
salesAmountNetLastWeek: { type: "money" },
|
|
@@ -39,18 +39,18 @@ var FIELDS = {
|
|
|
39
39
|
type: "percent",
|
|
40
40
|
columnKey: "guestsVarLwPct",
|
|
41
41
|
footerCalculation: {
|
|
42
|
-
type: "
|
|
43
|
-
numeratorField: "
|
|
44
|
-
denominatorField: "
|
|
42
|
+
type: "variancePercent",
|
|
43
|
+
numeratorField: "guestsVarLW",
|
|
44
|
+
denominatorField: "guestsCount"
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
guestsVarLYPct: {
|
|
48
48
|
type: "percent",
|
|
49
49
|
columnKey: "guestsVarLyPct",
|
|
50
50
|
footerCalculation: {
|
|
51
|
-
type: "
|
|
52
|
-
numeratorField: "
|
|
53
|
-
denominatorField: "
|
|
51
|
+
type: "variancePercent",
|
|
52
|
+
numeratorField: "guestsVarLY",
|
|
53
|
+
denominatorField: "guestsCount"
|
|
54
54
|
}
|
|
55
55
|
},
|
|
56
56
|
guestsCountLastWeek: { type: "number" },
|
|
@@ -68,18 +68,22 @@ var FIELDS = {
|
|
|
68
68
|
type: "money",
|
|
69
69
|
columnKey: "salesPerGuestLw",
|
|
70
70
|
footerCalculation: {
|
|
71
|
-
type: "
|
|
72
|
-
numeratorField: "
|
|
73
|
-
|
|
71
|
+
type: "quotientOfDifferences",
|
|
72
|
+
numeratorField: "salesAmountNet",
|
|
73
|
+
numeratorAdjustField: "salesVarLW",
|
|
74
|
+
denominatorField: "guestsCount",
|
|
75
|
+
denominatorAdjustField: "guestsVarLW"
|
|
74
76
|
}
|
|
75
77
|
},
|
|
76
78
|
salesPerGuestLY: {
|
|
77
79
|
type: "money",
|
|
78
80
|
columnKey: "salesPerGuestLy",
|
|
79
81
|
footerCalculation: {
|
|
80
|
-
type: "
|
|
81
|
-
numeratorField: "
|
|
82
|
-
|
|
82
|
+
type: "quotientOfDifferences",
|
|
83
|
+
numeratorField: "salesAmountNet",
|
|
84
|
+
numeratorAdjustField: "salesVarLY",
|
|
85
|
+
denominatorField: "guestsCount",
|
|
86
|
+
denominatorAdjustField: "guestsVarLY"
|
|
83
87
|
}
|
|
84
88
|
}
|
|
85
89
|
};
|
|
@@ -1436,65 +1440,54 @@ function isNumericType(type) {
|
|
|
1436
1440
|
}
|
|
1437
1441
|
|
|
1438
1442
|
// src/totals.ts
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
const {
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
for (const [field, config] of Object.entries(fieldConfig)) {
|
|
1445
|
-
const { type, columnKey, footerCalculation: calc } = config;
|
|
1446
|
-
if (!type || type === "string" || type === "date" || type === "time" || type === "boolean") {
|
|
1447
|
-
continue;
|
|
1448
|
-
}
|
|
1449
|
-
if (calc?.type === "none") {
|
|
1450
|
-
} else if (!calc || calc.type === "sum") {
|
|
1451
|
-
if (columnKey || calc?.type === "sum") {
|
|
1452
|
-
fieldsToSum.add(field);
|
|
1453
|
-
}
|
|
1454
|
-
} else {
|
|
1455
|
-
derivedFields.push({ field, calc });
|
|
1456
|
-
if (calc.numeratorField) {
|
|
1457
|
-
fieldsToSum.add(calc.numeratorField);
|
|
1458
|
-
}
|
|
1459
|
-
if (calc.denominatorField) {
|
|
1460
|
-
fieldsToSum.add(calc.denominatorField);
|
|
1461
|
-
}
|
|
1462
|
-
}
|
|
1443
|
+
var sumField = (rows, field) => rows.reduce((acc, row) => acc + (row[field] ?? 0), 0);
|
|
1444
|
+
var calculateFieldTotal = (rows, field, config) => {
|
|
1445
|
+
const { type } = config;
|
|
1446
|
+
if (!type || type === "string" || type === "date" || type === "time" || type === "boolean" || type === "conditional") {
|
|
1447
|
+
return null;
|
|
1463
1448
|
}
|
|
1464
|
-
const
|
|
1465
|
-
|
|
1466
|
-
|
|
1449
|
+
const calc = config.footerCalculation;
|
|
1450
|
+
if (calc?.type === "none") {
|
|
1451
|
+
return 0;
|
|
1467
1452
|
}
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1453
|
+
if (!calc || calc.type === "sum") {
|
|
1454
|
+
return config.columnKey || calc?.type === "sum" ? sumField(rows, field) : 0;
|
|
1455
|
+
}
|
|
1456
|
+
const { numeratorField, denominatorField } = calc;
|
|
1457
|
+
if (!numeratorField || !denominatorField) {
|
|
1458
|
+
return 0;
|
|
1459
|
+
}
|
|
1460
|
+
const num = sumField(rows, numeratorField);
|
|
1461
|
+
const den = sumField(rows, denominatorField);
|
|
1462
|
+
if (calc.type === "percentChange") {
|
|
1463
|
+
return den ? (num - den) / den : 0;
|
|
1464
|
+
}
|
|
1465
|
+
if (calc.type === "variancePercent") {
|
|
1466
|
+
const prior = den - num;
|
|
1467
|
+
return prior ? num / prior : 0;
|
|
1468
|
+
}
|
|
1469
|
+
if (calc.type === "average") {
|
|
1470
|
+
return den > 0 ? num / den : 0;
|
|
1471
|
+
}
|
|
1472
|
+
if (calc.type === "quotientOfDifferences") {
|
|
1473
|
+
const { numeratorAdjustField, denominatorAdjustField } = calc;
|
|
1474
|
+
const numAdj = numeratorAdjustField ? sumField(rows, numeratorAdjustField) : 0;
|
|
1475
|
+
const denAdj = denominatorAdjustField ? sumField(rows, denominatorAdjustField) : 0;
|
|
1476
|
+
const effectiveDen = den - denAdj;
|
|
1477
|
+
return effectiveDen !== 0 ? (num - numAdj) / effectiveDen : 0;
|
|
1477
1478
|
}
|
|
1479
|
+
return 0;
|
|
1480
|
+
};
|
|
1481
|
+
var calculateReportTotals = (data, fieldConfig, opts) => {
|
|
1482
|
+
const { labelField, label } = opts;
|
|
1478
1483
|
const result = {};
|
|
1479
1484
|
for (const [field, config] of Object.entries(fieldConfig)) {
|
|
1480
|
-
const
|
|
1481
|
-
|
|
1482
|
-
result[field] = "";
|
|
1483
|
-
} else if (type === "boolean") {
|
|
1484
|
-
result[field] = false;
|
|
1485
|
-
} else {
|
|
1486
|
-
result[field] = 0;
|
|
1487
|
-
}
|
|
1485
|
+
const total = calculateFieldTotal(data, field, config);
|
|
1486
|
+
result[field] = total ?? "";
|
|
1488
1487
|
}
|
|
1489
1488
|
result[labelField] = label;
|
|
1490
|
-
for (const [field, value] of Object.entries(sums)) {
|
|
1491
|
-
result[field] = value;
|
|
1492
|
-
}
|
|
1493
|
-
for (const [field, value] of Object.entries(derived)) {
|
|
1494
|
-
result[field] = value;
|
|
1495
|
-
}
|
|
1496
1489
|
return result;
|
|
1497
|
-
}
|
|
1490
|
+
};
|
|
1498
1491
|
|
|
1499
1492
|
// src/reports/dailySalesRefundsVoids.ts
|
|
1500
1493
|
var FIRST_COLUMN_WIDTH8 = 240;
|
|
@@ -1706,6 +1699,7 @@ export {
|
|
|
1706
1699
|
TICKET_LIVE_DEFAULT_VISIBLE_COLUMNS,
|
|
1707
1700
|
TICKET_SUMMARY_AVAILABLE_COLUMNS,
|
|
1708
1701
|
TICKET_SUMMARY_DEFAULT_VISIBLE_COLUMNS,
|
|
1702
|
+
calculateFieldTotal,
|
|
1709
1703
|
calculateReportTotals,
|
|
1710
1704
|
dailySalesConfig,
|
|
1711
1705
|
dailySalesDiscountsConfig,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@harbortouch/skytab-analytics-report-utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Centralized report column presentation configuration for SkyTab Analytics",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22.6.0",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"type": "module",
|
|
23
23
|
"scripts": {
|
|
24
24
|
"build": "tsup",
|
|
25
|
-
"dev": "tsup --watch",
|
|
25
|
+
"dev": "tsup --watch --no-clean",
|
|
26
26
|
"lint:js": "eslint src",
|
|
27
27
|
"lint:js:fix": "eslint src --fix",
|
|
28
28
|
"lint:types": "tsc --noEmit",
|