@harbortouch/skytab-analytics-report-utils 0.9.0 → 0.11.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 CHANGED
@@ -23,34 +23,23 @@ __export(index_exports, {
23
23
  COLUMN_REGISTRY: () => COLUMN_REGISTRY,
24
24
  DAILY_SALES_AVAILABLE_COLUMNS: () => DAILY_SALES_AVAILABLE_COLUMNS,
25
25
  DAILY_SALES_BY_GROUP_AVAILABLE_COLUMNS: () => DAILY_SALES_BY_GROUP_AVAILABLE_COLUMNS,
26
- DAILY_SALES_DEFAULT_VISIBLE_COLUMNS: () => DAILY_SALES_DEFAULT_VISIBLE_COLUMNS,
27
26
  DAILY_SALES_DISCOUNTS_AVAILABLE_COLUMNS: () => DAILY_SALES_DISCOUNTS_AVAILABLE_COLUMNS,
28
- DAILY_SALES_DISCOUNTS_DEFAULT_VISIBLE_COLUMNS: () => DAILY_SALES_DISCOUNTS_DEFAULT_VISIBLE_COLUMNS,
29
27
  DAILY_SALES_PAYMENTS_AVAILABLE_COLUMNS: () => DAILY_SALES_PAYMENTS_AVAILABLE_COLUMNS,
30
- DAILY_SALES_PAYMENTS_DEFAULT_VISIBLE_COLUMNS: () => DAILY_SALES_PAYMENTS_DEFAULT_VISIBLE_COLUMNS,
31
28
  DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUMNS: () => DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUMNS,
32
- DAILY_SALES_REFUNDS_VOIDS_DEFAULT_VISIBLE_COLUMNS: () => DAILY_SALES_REFUNDS_VOIDS_DEFAULT_VISIBLE_COLUMNS,
33
29
  DAILY_SALES_TAXES_AVAILABLE_COLUMNS: () => DAILY_SALES_TAXES_AVAILABLE_COLUMNS,
34
- DAILY_SALES_TAXES_DEFAULT_VISIBLE_COLUMNS: () => DAILY_SALES_TAXES_DEFAULT_VISIBLE_COLUMNS,
35
30
  DAILY_SALES_TRENDS_AVAILABLE_COLUMNS: () => DAILY_SALES_TRENDS_AVAILABLE_COLUMNS,
36
31
  EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS: () => EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS,
37
- EMPLOYEE_TIMECARD_DEFAULT_VISIBLE_COLUMNS: () => EMPLOYEE_TIMECARD_DEFAULT_VISIBLE_COLUMNS,
38
32
  ITEM_TAX_AVAILABLE_COLUMNS: () => ITEM_TAX_AVAILABLE_COLUMNS,
39
- ITEM_TAX_DEFAULT_VISIBLE_COLUMNS: () => ITEM_TAX_DEFAULT_VISIBLE_COLUMNS,
40
33
  MODIFIER_MIX_AVAILABLE_COLUMNS: () => MODIFIER_MIX_AVAILABLE_COLUMNS,
41
- MODIFIER_MIX_DEFAULT_VISIBLE_COLUMNS: () => MODIFIER_MIX_DEFAULT_VISIBLE_COLUMNS,
42
34
  PRODUCT_MIX_AVAILABLE_COLUMNS: () => PRODUCT_MIX_AVAILABLE_COLUMNS,
43
35
  PRODUCT_MIX_CHART_FIELDS: () => PRODUCT_MIX_CHART_FIELDS,
44
36
  PRODUCT_MIX_DEFAULT_VISIBLE_COLUMNS: () => PRODUCT_MIX_DEFAULT_VISIBLE_COLUMNS,
45
37
  Report: () => Report,
46
38
  SALES_BY_ITEM_DETAIL_AVAILABLE_COLUMNS: () => SALES_BY_ITEM_DETAIL_AVAILABLE_COLUMNS,
47
- SALES_BY_ITEM_DETAIL_DEFAULT_VISIBLE_COLUMNS: () => SALES_BY_ITEM_DETAIL_DEFAULT_VISIBLE_COLUMNS,
48
39
  SALES_SUMMARY_AVAILABLE_COLUMNS: () => SALES_SUMMARY_AVAILABLE_COLUMNS,
49
- SALES_SUMMARY_DEFAULT_VISIBLE_COLUMNS: () => SALES_SUMMARY_DEFAULT_VISIBLE_COLUMNS,
50
40
  TICKET_LIVE_AVAILABLE_COLUMNS: () => TICKET_LIVE_AVAILABLE_COLUMNS,
51
- TICKET_LIVE_DEFAULT_VISIBLE_COLUMNS: () => TICKET_LIVE_DEFAULT_VISIBLE_COLUMNS,
52
41
  TICKET_SUMMARY_AVAILABLE_COLUMNS: () => TICKET_SUMMARY_AVAILABLE_COLUMNS,
53
- TICKET_SUMMARY_DEFAULT_VISIBLE_COLUMNS: () => TICKET_SUMMARY_DEFAULT_VISIBLE_COLUMNS,
42
+ calculateFieldTotal: () => calculateFieldTotal,
54
43
  calculateReportTotals: () => calculateReportTotals,
55
44
  dailySalesConfig: () => dailySalesConfig,
56
45
  dailySalesDiscountsConfig: () => dailySalesDiscountsConfig,
@@ -98,18 +87,18 @@ var FIELDS = {
98
87
  type: "percent",
99
88
  columnKey: "salesVarLwPct",
100
89
  footerCalculation: {
101
- type: "percentChange",
102
- numeratorField: "salesAmountNet",
103
- denominatorField: "salesAmountNetLastWeek"
90
+ type: "variancePercent",
91
+ numeratorField: "salesVarLW",
92
+ denominatorField: "salesAmountNet"
104
93
  }
105
94
  },
106
95
  salesVarLYPct: {
107
96
  type: "percent",
108
97
  columnKey: "salesVarLyPct",
109
98
  footerCalculation: {
110
- type: "percentChange",
111
- numeratorField: "salesAmountNet",
112
- denominatorField: "salesAmountNetLastYear"
99
+ type: "variancePercent",
100
+ numeratorField: "salesVarLY",
101
+ denominatorField: "salesAmountNet"
113
102
  }
114
103
  },
115
104
  salesAmountNetLastWeek: { type: "money" },
@@ -127,18 +116,18 @@ var FIELDS = {
127
116
  type: "percent",
128
117
  columnKey: "guestsVarLwPct",
129
118
  footerCalculation: {
130
- type: "percentChange",
131
- numeratorField: "guestsCount",
132
- denominatorField: "guestsCountLastWeek"
119
+ type: "variancePercent",
120
+ numeratorField: "guestsVarLW",
121
+ denominatorField: "guestsCount"
133
122
  }
134
123
  },
135
124
  guestsVarLYPct: {
136
125
  type: "percent",
137
126
  columnKey: "guestsVarLyPct",
138
127
  footerCalculation: {
139
- type: "percentChange",
140
- numeratorField: "guestsCount",
141
- denominatorField: "guestsCountLastYear"
128
+ type: "variancePercent",
129
+ numeratorField: "guestsVarLY",
130
+ denominatorField: "guestsCount"
142
131
  }
143
132
  },
144
133
  guestsCountLastWeek: { type: "number" },
@@ -156,18 +145,22 @@ var FIELDS = {
156
145
  type: "money",
157
146
  columnKey: "salesPerGuestLw",
158
147
  footerCalculation: {
159
- type: "average",
160
- numeratorField: "salesAmountNetLastWeek",
161
- denominatorField: "guestsCountLastWeek"
148
+ type: "quotientOfDifferences",
149
+ numeratorField: "salesAmountNet",
150
+ numeratorAdjustField: "salesVarLW",
151
+ denominatorField: "guestsCount",
152
+ denominatorAdjustField: "guestsVarLW"
162
153
  }
163
154
  },
164
155
  salesPerGuestLY: {
165
156
  type: "money",
166
157
  columnKey: "salesPerGuestLy",
167
158
  footerCalculation: {
168
- type: "average",
169
- numeratorField: "salesAmountNetLastYear",
170
- denominatorField: "guestsCountLastYear"
159
+ type: "quotientOfDifferences",
160
+ numeratorField: "salesAmountNet",
161
+ numeratorAdjustField: "salesVarLY",
162
+ denominatorField: "guestsCount",
163
+ denominatorAdjustField: "guestsVarLY"
171
164
  }
172
165
  }
173
166
  };
@@ -209,16 +202,13 @@ var SALES_SUMMARY_AVAILABLE_COLUMNS = [
209
202
  "salesPerGuestLW",
210
203
  "salesPerGuestLY"
211
204
  ];
212
- var SALES_SUMMARY_DEFAULT_VISIBLE_COLUMNS = [
213
- "salesAmountNet",
214
- "guestsCount",
215
- "salesPerGuestTY"
216
- ];
205
+ var SALES_SUMMARY_DEFAULT_VISIBLE_COLUMNS = ["salesAmountNet", "guestsCount", "salesPerGuestTY"];
217
206
  var salesSummaryConfig = {
218
207
  fields: FIELDS,
219
208
  availableColumns: SALES_SUMMARY_AVAILABLE_COLUMNS,
220
209
  defaultVisibleColumns: SALES_SUMMARY_DEFAULT_VISIBLE_COLUMNS,
221
- columnGroups: COLUMN_GROUPS
210
+ columnGroups: COLUMN_GROUPS,
211
+ hasFooter: true
222
212
  };
223
213
 
224
214
  // src/reports/ticketSummary.ts
@@ -308,11 +298,11 @@ var TICKET_SUMMARY_AVAILABLE_COLUMNS = [
308
298
  "employeeName",
309
299
  "orderTypeName"
310
300
  ];
311
- var TICKET_SUMMARY_DEFAULT_VISIBLE_COLUMNS = TICKET_SUMMARY_AVAILABLE_COLUMNS;
312
301
  var ticketSummaryConfig = {
313
302
  fields: FIELDS2,
314
303
  availableColumns: TICKET_SUMMARY_AVAILABLE_COLUMNS,
315
- defaultVisibleColumns: TICKET_SUMMARY_DEFAULT_VISIBLE_COLUMNS
304
+ defaultVisibleColumns: TICKET_SUMMARY_AVAILABLE_COLUMNS,
305
+ hasFooter: true
316
306
  };
317
307
 
318
308
  // src/reports/ticketLive.ts
@@ -366,11 +356,11 @@ var TICKET_LIVE_AVAILABLE_COLUMNS = [
366
356
  "employeeName",
367
357
  "orderType"
368
358
  ];
369
- var TICKET_LIVE_DEFAULT_VISIBLE_COLUMNS = TICKET_LIVE_AVAILABLE_COLUMNS;
370
359
  var ticketLiveConfig = {
371
360
  fields: FIELDS3,
372
361
  availableColumns: TICKET_LIVE_AVAILABLE_COLUMNS,
373
- defaultVisibleColumns: TICKET_LIVE_DEFAULT_VISIBLE_COLUMNS
362
+ defaultVisibleColumns: TICKET_LIVE_AVAILABLE_COLUMNS,
363
+ hasFooter: true
374
364
  };
375
365
 
376
366
  // src/reports/productMix.ts
@@ -416,7 +406,8 @@ var PRODUCT_MIX_CHART_FIELDS = [
416
406
  var productMixConfig = {
417
407
  fields: FIELDS4,
418
408
  availableColumns: PRODUCT_MIX_AVAILABLE_COLUMNS,
419
- defaultVisibleColumns: PRODUCT_MIX_DEFAULT_VISIBLE_COLUMNS
409
+ defaultVisibleColumns: PRODUCT_MIX_DEFAULT_VISIBLE_COLUMNS,
410
+ hasFooter: true
420
411
  };
421
412
 
422
413
  // src/reports/modifierMix.ts
@@ -487,11 +478,11 @@ var FIELDS5 = {
487
478
  }
488
479
  };
489
480
  var MODIFIER_MIX_AVAILABLE_COLUMNS = ["modifiersSales", "modifiersQuantity", "avgGross"];
490
- var MODIFIER_MIX_DEFAULT_VISIBLE_COLUMNS = MODIFIER_MIX_AVAILABLE_COLUMNS;
491
481
  var modifierMixConfig = {
492
482
  fields: FIELDS5,
493
483
  availableColumns: MODIFIER_MIX_AVAILABLE_COLUMNS,
494
- defaultVisibleColumns: MODIFIER_MIX_DEFAULT_VISIBLE_COLUMNS
484
+ defaultVisibleColumns: MODIFIER_MIX_AVAILABLE_COLUMNS,
485
+ hasFooter: true
495
486
  };
496
487
 
497
488
  // src/reports/itemTax.ts
@@ -541,11 +532,11 @@ var ITEM_TAX_AVAILABLE_COLUMNS = [
541
532
  "taxableSales",
542
533
  "taxCollected"
543
534
  ];
544
- var ITEM_TAX_DEFAULT_VISIBLE_COLUMNS = ITEM_TAX_AVAILABLE_COLUMNS;
545
535
  var itemTaxConfig = {
546
536
  fields: FIELDS6,
547
537
  availableColumns: ITEM_TAX_AVAILABLE_COLUMNS,
548
- defaultVisibleColumns: ITEM_TAX_DEFAULT_VISIBLE_COLUMNS
538
+ defaultVisibleColumns: ITEM_TAX_AVAILABLE_COLUMNS,
539
+ hasFooter: false
549
540
  };
550
541
 
551
542
  // src/reports/dailySales.ts
@@ -622,11 +613,11 @@ var DAILY_SALES_BY_GROUP_AVAILABLE_COLUMNS = [
622
613
  "guestAverage",
623
614
  "salesAmountNet"
624
615
  ];
625
- var DAILY_SALES_DEFAULT_VISIBLE_COLUMNS = DAILY_SALES_AVAILABLE_COLUMNS;
626
616
  var dailySalesConfig = {
627
617
  fields: FIELDS7,
628
618
  availableColumns: DAILY_SALES_AVAILABLE_COLUMNS,
629
- defaultVisibleColumns: DAILY_SALES_DEFAULT_VISIBLE_COLUMNS
619
+ defaultVisibleColumns: DAILY_SALES_AVAILABLE_COLUMNS,
620
+ hasFooter: true
630
621
  };
631
622
  var DAILY_SALES_TRENDS_AVAILABLE_COLUMNS = [
632
623
  "ticketsCount",
@@ -638,7 +629,8 @@ var DAILY_SALES_TRENDS_AVAILABLE_COLUMNS = [
638
629
  var dailySalesTrendsConfig = {
639
630
  fields: FIELDS7,
640
631
  availableColumns: DAILY_SALES_TRENDS_AVAILABLE_COLUMNS,
641
- defaultVisibleColumns: DAILY_SALES_TRENDS_AVAILABLE_COLUMNS
632
+ defaultVisibleColumns: DAILY_SALES_TRENDS_AVAILABLE_COLUMNS,
633
+ hasFooter: true
642
634
  };
643
635
 
644
636
  // src/reports/dailySalesPayments.ts
@@ -656,11 +648,11 @@ var DAILY_SALES_PAYMENTS_AVAILABLE_COLUMNS = [
656
648
  "tipsAmount",
657
649
  "totalSales"
658
650
  ];
659
- var DAILY_SALES_PAYMENTS_DEFAULT_VISIBLE_COLUMNS = DAILY_SALES_PAYMENTS_AVAILABLE_COLUMNS;
660
651
  var dailySalesPaymentsConfig = {
661
652
  fields: FIELDS8,
662
653
  availableColumns: DAILY_SALES_PAYMENTS_AVAILABLE_COLUMNS,
663
- defaultVisibleColumns: DAILY_SALES_PAYMENTS_DEFAULT_VISIBLE_COLUMNS
654
+ defaultVisibleColumns: DAILY_SALES_PAYMENTS_AVAILABLE_COLUMNS,
655
+ hasFooter: true
664
656
  };
665
657
 
666
658
  // src/reports/dailySalesDiscounts.ts
@@ -676,11 +668,11 @@ var DAILY_SALES_DISCOUNTS_AVAILABLE_COLUMNS = [
676
668
  "itemCount",
677
669
  "discountsAmount"
678
670
  ];
679
- var DAILY_SALES_DISCOUNTS_DEFAULT_VISIBLE_COLUMNS = DAILY_SALES_DISCOUNTS_AVAILABLE_COLUMNS;
680
671
  var dailySalesDiscountsConfig = {
681
672
  fields: FIELDS9,
682
673
  availableColumns: DAILY_SALES_DISCOUNTS_AVAILABLE_COLUMNS,
683
- defaultVisibleColumns: DAILY_SALES_DISCOUNTS_DEFAULT_VISIBLE_COLUMNS
674
+ defaultVisibleColumns: DAILY_SALES_DISCOUNTS_AVAILABLE_COLUMNS,
675
+ hasFooter: true
684
676
  };
685
677
 
686
678
  // src/reports/employeeTimecard.ts
@@ -763,13 +755,13 @@ var EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS = [
763
755
  "endTime",
764
756
  "shiftHours"
765
757
  ];
766
- var EMPLOYEE_TIMECARD_DEFAULT_VISIBLE_COLUMNS = EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS;
767
758
  var employeeTimecardConfig = {
768
759
  fields: FIELDS10,
769
760
  availableColumns: EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS,
770
- defaultVisibleColumns: EMPLOYEE_TIMECARD_DEFAULT_VISIBLE_COLUMNS,
771
- columnGroups: []
761
+ defaultVisibleColumns: EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS,
762
+ columnGroups: [],
772
763
  // No column groups for this report
764
+ hasFooter: true
773
765
  };
774
766
 
775
767
  // src/reports/salesByItemDetail.ts
@@ -813,11 +805,11 @@ var SALES_BY_ITEM_DETAIL_AVAILABLE_COLUMNS = [
813
805
  "salesType",
814
806
  "itemPrice"
815
807
  ];
816
- var SALES_BY_ITEM_DETAIL_DEFAULT_VISIBLE_COLUMNS = SALES_BY_ITEM_DETAIL_AVAILABLE_COLUMNS;
817
808
  var salesByItemDetailConfig = {
818
809
  fields: FIELDS11,
819
810
  availableColumns: SALES_BY_ITEM_DETAIL_AVAILABLE_COLUMNS,
820
- defaultVisibleColumns: SALES_BY_ITEM_DETAIL_DEFAULT_VISIBLE_COLUMNS
811
+ defaultVisibleColumns: SALES_BY_ITEM_DETAIL_AVAILABLE_COLUMNS,
812
+ hasFooter: false
821
813
  };
822
814
 
823
815
  // src/report.ts
@@ -1524,65 +1516,54 @@ function isNumericType(type) {
1524
1516
  }
1525
1517
 
1526
1518
  // src/totals.ts
1527
- function calculateReportTotals(data, fieldConfig, opts) {
1528
- const rows = data;
1529
- const { labelField, label } = opts;
1530
- const fieldsToSum = /* @__PURE__ */ new Set();
1531
- const derivedFields = [];
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
- }
1519
+ var sumField = (rows, field) => rows.reduce((acc, row) => acc + (row[field] ?? 0), 0);
1520
+ var calculateFieldTotal = (rows, field, config) => {
1521
+ const { type } = config;
1522
+ if (!type || type === "string" || type === "date" || type === "time" || type === "boolean" || type === "conditional") {
1523
+ return null;
1551
1524
  }
1552
- const sums = {};
1553
- for (const field of fieldsToSum) {
1554
- sums[field] = rows.reduce((acc, row) => acc + (row[field] ?? 0), 0);
1525
+ const calc = config.footerCalculation;
1526
+ if (calc?.type === "none") {
1527
+ return null;
1555
1528
  }
1556
- const derived = {};
1557
- for (const { field, calc } of derivedFields) {
1558
- const num = sums[calc.numeratorField ?? ""] ?? 0;
1559
- const den = sums[calc.denominatorField ?? ""] ?? 0;
1560
- if (calc.type === "percentChange") {
1561
- derived[field] = den ? (num - den) / den : 0;
1562
- } else if (calc.type === "average") {
1563
- derived[field] = den > 0 ? num / den : 0;
1564
- }
1529
+ if (!calc || calc.type === "sum") {
1530
+ return config.columnKey || calc?.type === "sum" ? sumField(rows, field) : 0;
1531
+ }
1532
+ const { numeratorField, denominatorField } = calc;
1533
+ if (!numeratorField || !denominatorField) {
1534
+ return 0;
1535
+ }
1536
+ const num = sumField(rows, numeratorField);
1537
+ const den = sumField(rows, denominatorField);
1538
+ if (calc.type === "percentChange") {
1539
+ return den ? (num - den) / den : 0;
1540
+ }
1541
+ if (calc.type === "variancePercent") {
1542
+ const prior = den - num;
1543
+ return prior ? num / prior : 0;
1544
+ }
1545
+ if (calc.type === "average") {
1546
+ return den > 0 ? num / den : 0;
1565
1547
  }
1548
+ if (calc.type === "quotientOfDifferences") {
1549
+ const { numeratorAdjustField, denominatorAdjustField } = calc;
1550
+ const numAdj = numeratorAdjustField ? sumField(rows, numeratorAdjustField) : 0;
1551
+ const denAdj = denominatorAdjustField ? sumField(rows, denominatorAdjustField) : 0;
1552
+ const effectiveDen = den - denAdj;
1553
+ return effectiveDen !== 0 ? (num - numAdj) / effectiveDen : 0;
1554
+ }
1555
+ return 0;
1556
+ };
1557
+ var calculateReportTotals = (data, fieldConfig, opts) => {
1558
+ const { labelField, label } = opts;
1566
1559
  const result = {};
1567
1560
  for (const [field, config] of Object.entries(fieldConfig)) {
1568
- const { type } = config;
1569
- if (!type || type === "string" || type === "date" || type === "time") {
1570
- result[field] = "";
1571
- } else if (type === "boolean") {
1572
- result[field] = false;
1573
- } else {
1574
- result[field] = 0;
1575
- }
1561
+ const total = calculateFieldTotal(data, field, config);
1562
+ result[field] = total ?? "";
1576
1563
  }
1577
1564
  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
1565
  return result;
1585
- }
1566
+ };
1586
1567
 
1587
1568
  // src/reports/dailySalesRefundsVoids.ts
1588
1569
  var FIRST_COLUMN_WIDTH8 = 240;
@@ -1597,11 +1578,11 @@ var DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUMNS = [
1597
1578
  "amount",
1598
1579
  "pctSales"
1599
1580
  ];
1600
- var DAILY_SALES_REFUNDS_VOIDS_DEFAULT_VISIBLE_COLUMNS = DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUMNS;
1601
1581
  var dailySalesRefundsVoidsConfig = {
1602
1582
  fields: FIELDS12,
1603
1583
  availableColumns: DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUMNS,
1604
- defaultVisibleColumns: DAILY_SALES_REFUNDS_VOIDS_DEFAULT_VISIBLE_COLUMNS
1584
+ defaultVisibleColumns: DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUMNS,
1585
+ hasFooter: true
1605
1586
  };
1606
1587
 
1607
1588
  // src/reports/dailySalesTaxes.ts
@@ -1617,11 +1598,11 @@ var DAILY_SALES_TAXES_AVAILABLE_COLUMNS = [
1617
1598
  "taxesAmount",
1618
1599
  "exemptSales"
1619
1600
  ];
1620
- var DAILY_SALES_TAXES_DEFAULT_VISIBLE_COLUMNS = DAILY_SALES_TAXES_AVAILABLE_COLUMNS;
1621
1601
  var dailySalesTaxesConfig = {
1622
1602
  fields: FIELDS13,
1623
1603
  availableColumns: DAILY_SALES_TAXES_AVAILABLE_COLUMNS,
1624
- defaultVisibleColumns: DAILY_SALES_TAXES_DEFAULT_VISIBLE_COLUMNS
1604
+ defaultVisibleColumns: DAILY_SALES_TAXES_AVAILABLE_COLUMNS,
1605
+ hasFooter: true
1625
1606
  };
1626
1607
 
1627
1608
  // src/formatting.ts
@@ -1767,34 +1748,23 @@ var formatFieldValue = (value, type, localeOptions, fullRecord, fieldConfig = DE
1767
1748
  COLUMN_REGISTRY,
1768
1749
  DAILY_SALES_AVAILABLE_COLUMNS,
1769
1750
  DAILY_SALES_BY_GROUP_AVAILABLE_COLUMNS,
1770
- DAILY_SALES_DEFAULT_VISIBLE_COLUMNS,
1771
1751
  DAILY_SALES_DISCOUNTS_AVAILABLE_COLUMNS,
1772
- DAILY_SALES_DISCOUNTS_DEFAULT_VISIBLE_COLUMNS,
1773
1752
  DAILY_SALES_PAYMENTS_AVAILABLE_COLUMNS,
1774
- DAILY_SALES_PAYMENTS_DEFAULT_VISIBLE_COLUMNS,
1775
1753
  DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUMNS,
1776
- DAILY_SALES_REFUNDS_VOIDS_DEFAULT_VISIBLE_COLUMNS,
1777
1754
  DAILY_SALES_TAXES_AVAILABLE_COLUMNS,
1778
- DAILY_SALES_TAXES_DEFAULT_VISIBLE_COLUMNS,
1779
1755
  DAILY_SALES_TRENDS_AVAILABLE_COLUMNS,
1780
1756
  EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS,
1781
- EMPLOYEE_TIMECARD_DEFAULT_VISIBLE_COLUMNS,
1782
1757
  ITEM_TAX_AVAILABLE_COLUMNS,
1783
- ITEM_TAX_DEFAULT_VISIBLE_COLUMNS,
1784
1758
  MODIFIER_MIX_AVAILABLE_COLUMNS,
1785
- MODIFIER_MIX_DEFAULT_VISIBLE_COLUMNS,
1786
1759
  PRODUCT_MIX_AVAILABLE_COLUMNS,
1787
1760
  PRODUCT_MIX_CHART_FIELDS,
1788
1761
  PRODUCT_MIX_DEFAULT_VISIBLE_COLUMNS,
1789
1762
  Report,
1790
1763
  SALES_BY_ITEM_DETAIL_AVAILABLE_COLUMNS,
1791
- SALES_BY_ITEM_DETAIL_DEFAULT_VISIBLE_COLUMNS,
1792
1764
  SALES_SUMMARY_AVAILABLE_COLUMNS,
1793
- SALES_SUMMARY_DEFAULT_VISIBLE_COLUMNS,
1794
1765
  TICKET_LIVE_AVAILABLE_COLUMNS,
1795
- TICKET_LIVE_DEFAULT_VISIBLE_COLUMNS,
1796
1766
  TICKET_SUMMARY_AVAILABLE_COLUMNS,
1797
- TICKET_SUMMARY_DEFAULT_VISIBLE_COLUMNS,
1767
+ calculateFieldTotal,
1798
1768
  calculateReportTotals,
1799
1769
  dailySalesConfig,
1800
1770
  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;
@@ -1217,6 +1219,7 @@ interface ReportConfig<TField extends string = string> {
1217
1219
  availableColumns: TField[];
1218
1220
  defaultVisibleColumns: TField[];
1219
1221
  columnGroups?: ColumnGroupConfig[];
1222
+ hasFooter: boolean;
1220
1223
  }
1221
1224
 
1222
1225
  declare const Report: {
@@ -1242,21 +1245,19 @@ interface CalculateReportTotalsOptions {
1242
1245
  labelField: string;
1243
1246
  label: string;
1244
1247
  }
1245
- declare function calculateReportTotals<T>(data: T[], fieldConfig: Record<string, ColumnPresentationConfig>, opts: CalculateReportTotalsOptions): T;
1248
+ declare const calculateFieldTotal: <T>(rows: T[], field: keyof T, config: ColumnPresentationConfig) => number | null;
1249
+ declare const calculateReportTotals: <T>(data: T[], fieldConfig: Record<string, ColumnPresentationConfig>, opts: CalculateReportTotalsOptions) => T;
1246
1250
 
1247
1251
  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
1252
  declare const SALES_SUMMARY_AVAILABLE_COLUMNS: SalesSummaryField[];
1249
- declare const SALES_SUMMARY_DEFAULT_VISIBLE_COLUMNS: SalesSummaryField[];
1250
1253
  declare const salesSummaryConfig: ReportConfig<SalesSummaryField>;
1251
1254
 
1252
1255
  type TicketSummaryField = 'ticketId' | 'locationId' | 'orderName' | 'revenueCenterName' | 'daypartName' | 'inclusiveTaxesAmount' | 'locationName' | 'orderNumber' | 'businessDate' | 'ticketOpenedAt' | 'ticketClosedAt' | 'ticketTime' | 'ticketSubtotal' | 'discountsAmount' | 'surchargesAmount' | 'taxesAmount' | 'ticketGrandTotal' | 'gratuitiesAmount' | 'tipAmount' | 'paymentsAmount' | 'paymentTypeName' | 'guestsCount' | 'employeeName' | 'orderTypeName';
1253
1256
  declare const TICKET_SUMMARY_AVAILABLE_COLUMNS: TicketSummaryField[];
1254
- declare const TICKET_SUMMARY_DEFAULT_VISIBLE_COLUMNS: TicketSummaryField[];
1255
1257
  declare const ticketSummaryConfig: ReportConfig<TicketSummaryField>;
1256
1258
 
1257
1259
  type TicketLiveField = 'locationName' | 'orderNumber' | 'dateOpen' | 'timeOpen' | 'dateClose' | 'timeClose' | 'durationMinutes' | 'subtotal' | 'discountTotal' | 'surchargeTotal' | 'taxTotal' | 'grandTotal' | 'gratuityTotal' | 'totalTips' | 'paymentsReceived' | 'paymentTypeName' | 'guestCount' | 'customerName' | 'employeeName' | 'orderType';
1258
1260
  declare const TICKET_LIVE_AVAILABLE_COLUMNS: TicketLiveField[];
1259
- declare const TICKET_LIVE_DEFAULT_VISIBLE_COLUMNS: TicketLiveField[];
1260
1261
  declare const ticketLiveConfig: ReportConfig<TicketLiveField>;
1261
1262
 
1262
1263
  type ProductMixField = 'groupById' | 'groupByName' | 'salesAmountGross' | 'discountsAmount' | 'inclusiveTaxesAmount' | 'salesAmountNet' | 'itemsQuantity' | 'avgPrice' | 'salesMixPct';
@@ -1267,50 +1268,41 @@ declare const productMixConfig: ReportConfig<ProductMixField>;
1267
1268
 
1268
1269
  type ModifierMixField = 'groupById' | 'groupByName' | 'groupById2' | 'groupByName2' | 'modifiersSales' | 'modifiersQuantity' | 'itemsQuantity' | 'avgGross' | 'attachRate' | 'modifiersSalesComp' | 'modifiersQuantityComp' | 'itemsQuantityComp' | 'attachRateComp' | 'modifiersSalesVar' | 'modifiersSalesVarPct' | 'modifiersQuantityVar' | 'modifiersQuantityVarPct' | 'attachRateVar' | 'attachRateVarPct';
1269
1270
  declare const MODIFIER_MIX_AVAILABLE_COLUMNS: ModifierMixField[];
1270
- declare const MODIFIER_MIX_DEFAULT_VISIBLE_COLUMNS: ModifierMixField[];
1271
1271
  declare const modifierMixConfig: ReportConfig<ModifierMixField>;
1272
1272
 
1273
1273
  type ItemTaxField = 'locationId' | 'taxIsFlat' | 'merchantId' | 'locationName' | 'locationCity' | 'locationState' | 'itemName' | 'itemPrice' | 'departmentName' | 'revenueClassName' | 'orderTypeName' | 'taxName' | 'taxValue' | 'taxRate' | 'recordsCount' | 'taxableSales' | 'totalCollected' | 'itemTax' | 'taxCollected';
1274
1274
  declare const ITEM_TAX_AVAILABLE_COLUMNS: ItemTaxField[];
1275
- declare const ITEM_TAX_DEFAULT_VISIBLE_COLUMNS: ItemTaxField[];
1276
1275
  declare const itemTaxConfig: ReportConfig<ItemTaxField>;
1277
1276
 
1278
1277
  type DailySalesField = 'groupById' | 'groupByName' | 'itemsQuantity' | 'salesAmountGross' | 'discountsAmount' | 'inclusiveTaxesAmount' | 'salesAmountNet' | 'salesMixPct' | 'avgPrice' | 'ticketsCount' | 'guestsCount' | 'ticketAverage' | 'guestAverage' | 'ticketAvg' | 'guestAvg';
1279
1278
  declare const DAILY_SALES_AVAILABLE_COLUMNS: DailySalesField[];
1280
1279
  declare const DAILY_SALES_BY_GROUP_AVAILABLE_COLUMNS: DailySalesField[];
1281
- declare const DAILY_SALES_DEFAULT_VISIBLE_COLUMNS: DailySalesField[];
1282
1280
  declare const dailySalesConfig: ReportConfig<DailySalesField>;
1283
1281
  declare const DAILY_SALES_TRENDS_AVAILABLE_COLUMNS: DailySalesField[];
1284
1282
  declare const dailySalesTrendsConfig: ReportConfig<DailySalesField>;
1285
1283
 
1286
1284
  type DailySalesPaymentsField = 'paymentTypeName' | 'paymentsCount' | 'paymentsAmount' | 'tipsAmount' | 'totalSales';
1287
1285
  declare const DAILY_SALES_PAYMENTS_AVAILABLE_COLUMNS: DailySalesPaymentsField[];
1288
- declare const DAILY_SALES_PAYMENTS_DEFAULT_VISIBLE_COLUMNS: DailySalesPaymentsField[];
1289
1286
  declare const dailySalesPaymentsConfig: ReportConfig<DailySalesPaymentsField>;
1290
1287
 
1291
1288
  type DailySalesDiscountsField = 'discountName' | 'ticketCount' | 'itemCount' | 'discountsAmount';
1292
1289
  declare const DAILY_SALES_DISCOUNTS_AVAILABLE_COLUMNS: DailySalesDiscountsField[];
1293
- declare const DAILY_SALES_DISCOUNTS_DEFAULT_VISIBLE_COLUMNS: DailySalesDiscountsField[];
1294
1290
  declare const dailySalesDiscountsConfig: ReportConfig<DailySalesDiscountsField>;
1295
1291
 
1296
1292
  type DailySalesRefundsVoidsField = 'description' | 'count' | 'amount' | 'pctSales';
1297
1293
  declare const DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUMNS: DailySalesRefundsVoidsField[];
1298
- declare const DAILY_SALES_REFUNDS_VOIDS_DEFAULT_VISIBLE_COLUMNS: DailySalesRefundsVoidsField[];
1299
1294
  declare const dailySalesRefundsVoidsConfig: ReportConfig<DailySalesRefundsVoidsField>;
1300
1295
 
1301
1296
  type DailySalesTaxesField = 'taxName' | 'taxableSales' | 'taxesAmount' | 'exemptSales';
1302
1297
  declare const DAILY_SALES_TAXES_AVAILABLE_COLUMNS: DailySalesTaxesField[];
1303
- declare const DAILY_SALES_TAXES_DEFAULT_VISIBLE_COLUMNS: DailySalesTaxesField[];
1304
1298
  declare const dailySalesTaxesConfig: ReportConfig<DailySalesTaxesField>;
1305
1299
 
1306
1300
  type EmployeeTimecardField = 'locationId' | 'locationName' | 'businessDate' | 'employeeName' | 'isActive' | 'lookup' | 'payrollCode' | 'jobName' | 'isBreak' | 'startTime' | 'endTime' | 'shiftHours';
1307
1301
  declare const EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS: EmployeeTimecardField[];
1308
- declare const EMPLOYEE_TIMECARD_DEFAULT_VISIBLE_COLUMNS: EmployeeTimecardField[];
1309
1302
  declare const employeeTimecardConfig: ReportConfig<EmployeeTimecardField>;
1310
1303
 
1311
1304
  type SalesByItemDetailField = 'businessDate' | 'ticketClosedAt' | 'hourId' | 'daypartName' | 'locationId' | 'locationName' | 'departmentName' | 'itemName' | 'revenueCenterName' | 'revenueClassName' | 'salesAmountGross' | 'itemsQuantity' | 'transactionId' | 'guestsCount' | 'employeeName' | 'orderTypeName' | 'salesType' | 'itemPrice';
1312
1305
  declare const SALES_BY_ITEM_DETAIL_AVAILABLE_COLUMNS: SalesByItemDetailField[];
1313
- declare const SALES_BY_ITEM_DETAIL_DEFAULT_VISIBLE_COLUMNS: SalesByItemDetailField[];
1314
1306
  declare const salesByItemDetailConfig: ReportConfig<SalesByItemDetailField>;
1315
1307
 
1316
1308
  type TimeFormat = '00:00' | '00:00:00' | '00:00-24H';
@@ -1352,6 +1344,6 @@ declare const getReportFormattingLocaleOptions: (locations: {
1352
1344
  countryCode: string;
1353
1345
  language: string;
1354
1346
  }[]) => LocaleOption[];
1355
- declare const formatFieldValue: (value: unknown, type: FieldType, localeOptions: LocaleOption, fullRecord: Record<string, unknown> | null, fieldConfig?: ColumnPresentationConfig) => string;
1347
+ declare const formatFieldValue: (value: unknown, type: FieldType, localeOptions: LocaleOption, fullRecord: Record<string, unknown> | null | undefined, fieldConfig?: ColumnPresentationConfig) => string;
1356
1348
 
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 };
1349
+ 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_DISCOUNTS_AVAILABLE_COLUMNS, DAILY_SALES_PAYMENTS_AVAILABLE_COLUMNS, DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUMNS, DAILY_SALES_TAXES_AVAILABLE_COLUMNS, DAILY_SALES_TRENDS_AVAILABLE_COLUMNS, EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS, type FieldType, type FooterCalculation, type FooterCalculationType, type FormatDateOptions, type FormatMoneyOptions, type FormatNumberOptions, type FormatTimeOptions, ITEM_TAX_AVAILABLE_COLUMNS, type LocaleOption, MODIFIER_MIX_AVAILABLE_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_SUMMARY_AVAILABLE_COLUMNS, TICKET_LIVE_AVAILABLE_COLUMNS, TICKET_SUMMARY_AVAILABLE_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;
@@ -1217,6 +1219,7 @@ interface ReportConfig<TField extends string = string> {
1217
1219
  availableColumns: TField[];
1218
1220
  defaultVisibleColumns: TField[];
1219
1221
  columnGroups?: ColumnGroupConfig[];
1222
+ hasFooter: boolean;
1220
1223
  }
1221
1224
 
1222
1225
  declare const Report: {
@@ -1242,21 +1245,19 @@ interface CalculateReportTotalsOptions {
1242
1245
  labelField: string;
1243
1246
  label: string;
1244
1247
  }
1245
- declare function calculateReportTotals<T>(data: T[], fieldConfig: Record<string, ColumnPresentationConfig>, opts: CalculateReportTotalsOptions): T;
1248
+ declare const calculateFieldTotal: <T>(rows: T[], field: keyof T, config: ColumnPresentationConfig) => number | null;
1249
+ declare const calculateReportTotals: <T>(data: T[], fieldConfig: Record<string, ColumnPresentationConfig>, opts: CalculateReportTotalsOptions) => T;
1246
1250
 
1247
1251
  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
1252
  declare const SALES_SUMMARY_AVAILABLE_COLUMNS: SalesSummaryField[];
1249
- declare const SALES_SUMMARY_DEFAULT_VISIBLE_COLUMNS: SalesSummaryField[];
1250
1253
  declare const salesSummaryConfig: ReportConfig<SalesSummaryField>;
1251
1254
 
1252
1255
  type TicketSummaryField = 'ticketId' | 'locationId' | 'orderName' | 'revenueCenterName' | 'daypartName' | 'inclusiveTaxesAmount' | 'locationName' | 'orderNumber' | 'businessDate' | 'ticketOpenedAt' | 'ticketClosedAt' | 'ticketTime' | 'ticketSubtotal' | 'discountsAmount' | 'surchargesAmount' | 'taxesAmount' | 'ticketGrandTotal' | 'gratuitiesAmount' | 'tipAmount' | 'paymentsAmount' | 'paymentTypeName' | 'guestsCount' | 'employeeName' | 'orderTypeName';
1253
1256
  declare const TICKET_SUMMARY_AVAILABLE_COLUMNS: TicketSummaryField[];
1254
- declare const TICKET_SUMMARY_DEFAULT_VISIBLE_COLUMNS: TicketSummaryField[];
1255
1257
  declare const ticketSummaryConfig: ReportConfig<TicketSummaryField>;
1256
1258
 
1257
1259
  type TicketLiveField = 'locationName' | 'orderNumber' | 'dateOpen' | 'timeOpen' | 'dateClose' | 'timeClose' | 'durationMinutes' | 'subtotal' | 'discountTotal' | 'surchargeTotal' | 'taxTotal' | 'grandTotal' | 'gratuityTotal' | 'totalTips' | 'paymentsReceived' | 'paymentTypeName' | 'guestCount' | 'customerName' | 'employeeName' | 'orderType';
1258
1260
  declare const TICKET_LIVE_AVAILABLE_COLUMNS: TicketLiveField[];
1259
- declare const TICKET_LIVE_DEFAULT_VISIBLE_COLUMNS: TicketLiveField[];
1260
1261
  declare const ticketLiveConfig: ReportConfig<TicketLiveField>;
1261
1262
 
1262
1263
  type ProductMixField = 'groupById' | 'groupByName' | 'salesAmountGross' | 'discountsAmount' | 'inclusiveTaxesAmount' | 'salesAmountNet' | 'itemsQuantity' | 'avgPrice' | 'salesMixPct';
@@ -1267,50 +1268,41 @@ declare const productMixConfig: ReportConfig<ProductMixField>;
1267
1268
 
1268
1269
  type ModifierMixField = 'groupById' | 'groupByName' | 'groupById2' | 'groupByName2' | 'modifiersSales' | 'modifiersQuantity' | 'itemsQuantity' | 'avgGross' | 'attachRate' | 'modifiersSalesComp' | 'modifiersQuantityComp' | 'itemsQuantityComp' | 'attachRateComp' | 'modifiersSalesVar' | 'modifiersSalesVarPct' | 'modifiersQuantityVar' | 'modifiersQuantityVarPct' | 'attachRateVar' | 'attachRateVarPct';
1269
1270
  declare const MODIFIER_MIX_AVAILABLE_COLUMNS: ModifierMixField[];
1270
- declare const MODIFIER_MIX_DEFAULT_VISIBLE_COLUMNS: ModifierMixField[];
1271
1271
  declare const modifierMixConfig: ReportConfig<ModifierMixField>;
1272
1272
 
1273
1273
  type ItemTaxField = 'locationId' | 'taxIsFlat' | 'merchantId' | 'locationName' | 'locationCity' | 'locationState' | 'itemName' | 'itemPrice' | 'departmentName' | 'revenueClassName' | 'orderTypeName' | 'taxName' | 'taxValue' | 'taxRate' | 'recordsCount' | 'taxableSales' | 'totalCollected' | 'itemTax' | 'taxCollected';
1274
1274
  declare const ITEM_TAX_AVAILABLE_COLUMNS: ItemTaxField[];
1275
- declare const ITEM_TAX_DEFAULT_VISIBLE_COLUMNS: ItemTaxField[];
1276
1275
  declare const itemTaxConfig: ReportConfig<ItemTaxField>;
1277
1276
 
1278
1277
  type DailySalesField = 'groupById' | 'groupByName' | 'itemsQuantity' | 'salesAmountGross' | 'discountsAmount' | 'inclusiveTaxesAmount' | 'salesAmountNet' | 'salesMixPct' | 'avgPrice' | 'ticketsCount' | 'guestsCount' | 'ticketAverage' | 'guestAverage' | 'ticketAvg' | 'guestAvg';
1279
1278
  declare const DAILY_SALES_AVAILABLE_COLUMNS: DailySalesField[];
1280
1279
  declare const DAILY_SALES_BY_GROUP_AVAILABLE_COLUMNS: DailySalesField[];
1281
- declare const DAILY_SALES_DEFAULT_VISIBLE_COLUMNS: DailySalesField[];
1282
1280
  declare const dailySalesConfig: ReportConfig<DailySalesField>;
1283
1281
  declare const DAILY_SALES_TRENDS_AVAILABLE_COLUMNS: DailySalesField[];
1284
1282
  declare const dailySalesTrendsConfig: ReportConfig<DailySalesField>;
1285
1283
 
1286
1284
  type DailySalesPaymentsField = 'paymentTypeName' | 'paymentsCount' | 'paymentsAmount' | 'tipsAmount' | 'totalSales';
1287
1285
  declare const DAILY_SALES_PAYMENTS_AVAILABLE_COLUMNS: DailySalesPaymentsField[];
1288
- declare const DAILY_SALES_PAYMENTS_DEFAULT_VISIBLE_COLUMNS: DailySalesPaymentsField[];
1289
1286
  declare const dailySalesPaymentsConfig: ReportConfig<DailySalesPaymentsField>;
1290
1287
 
1291
1288
  type DailySalesDiscountsField = 'discountName' | 'ticketCount' | 'itemCount' | 'discountsAmount';
1292
1289
  declare const DAILY_SALES_DISCOUNTS_AVAILABLE_COLUMNS: DailySalesDiscountsField[];
1293
- declare const DAILY_SALES_DISCOUNTS_DEFAULT_VISIBLE_COLUMNS: DailySalesDiscountsField[];
1294
1290
  declare const dailySalesDiscountsConfig: ReportConfig<DailySalesDiscountsField>;
1295
1291
 
1296
1292
  type DailySalesRefundsVoidsField = 'description' | 'count' | 'amount' | 'pctSales';
1297
1293
  declare const DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUMNS: DailySalesRefundsVoidsField[];
1298
- declare const DAILY_SALES_REFUNDS_VOIDS_DEFAULT_VISIBLE_COLUMNS: DailySalesRefundsVoidsField[];
1299
1294
  declare const dailySalesRefundsVoidsConfig: ReportConfig<DailySalesRefundsVoidsField>;
1300
1295
 
1301
1296
  type DailySalesTaxesField = 'taxName' | 'taxableSales' | 'taxesAmount' | 'exemptSales';
1302
1297
  declare const DAILY_SALES_TAXES_AVAILABLE_COLUMNS: DailySalesTaxesField[];
1303
- declare const DAILY_SALES_TAXES_DEFAULT_VISIBLE_COLUMNS: DailySalesTaxesField[];
1304
1298
  declare const dailySalesTaxesConfig: ReportConfig<DailySalesTaxesField>;
1305
1299
 
1306
1300
  type EmployeeTimecardField = 'locationId' | 'locationName' | 'businessDate' | 'employeeName' | 'isActive' | 'lookup' | 'payrollCode' | 'jobName' | 'isBreak' | 'startTime' | 'endTime' | 'shiftHours';
1307
1301
  declare const EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS: EmployeeTimecardField[];
1308
- declare const EMPLOYEE_TIMECARD_DEFAULT_VISIBLE_COLUMNS: EmployeeTimecardField[];
1309
1302
  declare const employeeTimecardConfig: ReportConfig<EmployeeTimecardField>;
1310
1303
 
1311
1304
  type SalesByItemDetailField = 'businessDate' | 'ticketClosedAt' | 'hourId' | 'daypartName' | 'locationId' | 'locationName' | 'departmentName' | 'itemName' | 'revenueCenterName' | 'revenueClassName' | 'salesAmountGross' | 'itemsQuantity' | 'transactionId' | 'guestsCount' | 'employeeName' | 'orderTypeName' | 'salesType' | 'itemPrice';
1312
1305
  declare const SALES_BY_ITEM_DETAIL_AVAILABLE_COLUMNS: SalesByItemDetailField[];
1313
- declare const SALES_BY_ITEM_DETAIL_DEFAULT_VISIBLE_COLUMNS: SalesByItemDetailField[];
1314
1306
  declare const salesByItemDetailConfig: ReportConfig<SalesByItemDetailField>;
1315
1307
 
1316
1308
  type TimeFormat = '00:00' | '00:00:00' | '00:00-24H';
@@ -1352,6 +1344,6 @@ declare const getReportFormattingLocaleOptions: (locations: {
1352
1344
  countryCode: string;
1353
1345
  language: string;
1354
1346
  }[]) => LocaleOption[];
1355
- declare const formatFieldValue: (value: unknown, type: FieldType, localeOptions: LocaleOption, fullRecord: Record<string, unknown> | null, fieldConfig?: ColumnPresentationConfig) => string;
1347
+ declare const formatFieldValue: (value: unknown, type: FieldType, localeOptions: LocaleOption, fullRecord: Record<string, unknown> | null | undefined, fieldConfig?: ColumnPresentationConfig) => string;
1356
1348
 
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 };
1349
+ 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_DISCOUNTS_AVAILABLE_COLUMNS, DAILY_SALES_PAYMENTS_AVAILABLE_COLUMNS, DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUMNS, DAILY_SALES_TAXES_AVAILABLE_COLUMNS, DAILY_SALES_TRENDS_AVAILABLE_COLUMNS, EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS, type FieldType, type FooterCalculation, type FooterCalculationType, type FormatDateOptions, type FormatMoneyOptions, type FormatNumberOptions, type FormatTimeOptions, ITEM_TAX_AVAILABLE_COLUMNS, type LocaleOption, MODIFIER_MIX_AVAILABLE_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_SUMMARY_AVAILABLE_COLUMNS, TICKET_LIVE_AVAILABLE_COLUMNS, TICKET_SUMMARY_AVAILABLE_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: "percentChange",
14
- numeratorField: "salesAmountNet",
15
- denominatorField: "salesAmountNetLastWeek"
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: "percentChange",
23
- numeratorField: "salesAmountNet",
24
- denominatorField: "salesAmountNetLastYear"
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: "percentChange",
43
- numeratorField: "guestsCount",
44
- denominatorField: "guestsCountLastWeek"
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: "percentChange",
52
- numeratorField: "guestsCount",
53
- denominatorField: "guestsCountLastYear"
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: "average",
72
- numeratorField: "salesAmountNetLastWeek",
73
- denominatorField: "guestsCountLastWeek"
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: "average",
81
- numeratorField: "salesAmountNetLastYear",
82
- denominatorField: "guestsCountLastYear"
82
+ type: "quotientOfDifferences",
83
+ numeratorField: "salesAmountNet",
84
+ numeratorAdjustField: "salesVarLY",
85
+ denominatorField: "guestsCount",
86
+ denominatorAdjustField: "guestsVarLY"
83
87
  }
84
88
  }
85
89
  };
@@ -121,16 +125,13 @@ var SALES_SUMMARY_AVAILABLE_COLUMNS = [
121
125
  "salesPerGuestLW",
122
126
  "salesPerGuestLY"
123
127
  ];
124
- var SALES_SUMMARY_DEFAULT_VISIBLE_COLUMNS = [
125
- "salesAmountNet",
126
- "guestsCount",
127
- "salesPerGuestTY"
128
- ];
128
+ var SALES_SUMMARY_DEFAULT_VISIBLE_COLUMNS = ["salesAmountNet", "guestsCount", "salesPerGuestTY"];
129
129
  var salesSummaryConfig = {
130
130
  fields: FIELDS,
131
131
  availableColumns: SALES_SUMMARY_AVAILABLE_COLUMNS,
132
132
  defaultVisibleColumns: SALES_SUMMARY_DEFAULT_VISIBLE_COLUMNS,
133
- columnGroups: COLUMN_GROUPS
133
+ columnGroups: COLUMN_GROUPS,
134
+ hasFooter: true
134
135
  };
135
136
 
136
137
  // src/reports/ticketSummary.ts
@@ -220,11 +221,11 @@ var TICKET_SUMMARY_AVAILABLE_COLUMNS = [
220
221
  "employeeName",
221
222
  "orderTypeName"
222
223
  ];
223
- var TICKET_SUMMARY_DEFAULT_VISIBLE_COLUMNS = TICKET_SUMMARY_AVAILABLE_COLUMNS;
224
224
  var ticketSummaryConfig = {
225
225
  fields: FIELDS2,
226
226
  availableColumns: TICKET_SUMMARY_AVAILABLE_COLUMNS,
227
- defaultVisibleColumns: TICKET_SUMMARY_DEFAULT_VISIBLE_COLUMNS
227
+ defaultVisibleColumns: TICKET_SUMMARY_AVAILABLE_COLUMNS,
228
+ hasFooter: true
228
229
  };
229
230
 
230
231
  // src/reports/ticketLive.ts
@@ -278,11 +279,11 @@ var TICKET_LIVE_AVAILABLE_COLUMNS = [
278
279
  "employeeName",
279
280
  "orderType"
280
281
  ];
281
- var TICKET_LIVE_DEFAULT_VISIBLE_COLUMNS = TICKET_LIVE_AVAILABLE_COLUMNS;
282
282
  var ticketLiveConfig = {
283
283
  fields: FIELDS3,
284
284
  availableColumns: TICKET_LIVE_AVAILABLE_COLUMNS,
285
- defaultVisibleColumns: TICKET_LIVE_DEFAULT_VISIBLE_COLUMNS
285
+ defaultVisibleColumns: TICKET_LIVE_AVAILABLE_COLUMNS,
286
+ hasFooter: true
286
287
  };
287
288
 
288
289
  // src/reports/productMix.ts
@@ -328,7 +329,8 @@ var PRODUCT_MIX_CHART_FIELDS = [
328
329
  var productMixConfig = {
329
330
  fields: FIELDS4,
330
331
  availableColumns: PRODUCT_MIX_AVAILABLE_COLUMNS,
331
- defaultVisibleColumns: PRODUCT_MIX_DEFAULT_VISIBLE_COLUMNS
332
+ defaultVisibleColumns: PRODUCT_MIX_DEFAULT_VISIBLE_COLUMNS,
333
+ hasFooter: true
332
334
  };
333
335
 
334
336
  // src/reports/modifierMix.ts
@@ -399,11 +401,11 @@ var FIELDS5 = {
399
401
  }
400
402
  };
401
403
  var MODIFIER_MIX_AVAILABLE_COLUMNS = ["modifiersSales", "modifiersQuantity", "avgGross"];
402
- var MODIFIER_MIX_DEFAULT_VISIBLE_COLUMNS = MODIFIER_MIX_AVAILABLE_COLUMNS;
403
404
  var modifierMixConfig = {
404
405
  fields: FIELDS5,
405
406
  availableColumns: MODIFIER_MIX_AVAILABLE_COLUMNS,
406
- defaultVisibleColumns: MODIFIER_MIX_DEFAULT_VISIBLE_COLUMNS
407
+ defaultVisibleColumns: MODIFIER_MIX_AVAILABLE_COLUMNS,
408
+ hasFooter: true
407
409
  };
408
410
 
409
411
  // src/reports/itemTax.ts
@@ -453,11 +455,11 @@ var ITEM_TAX_AVAILABLE_COLUMNS = [
453
455
  "taxableSales",
454
456
  "taxCollected"
455
457
  ];
456
- var ITEM_TAX_DEFAULT_VISIBLE_COLUMNS = ITEM_TAX_AVAILABLE_COLUMNS;
457
458
  var itemTaxConfig = {
458
459
  fields: FIELDS6,
459
460
  availableColumns: ITEM_TAX_AVAILABLE_COLUMNS,
460
- defaultVisibleColumns: ITEM_TAX_DEFAULT_VISIBLE_COLUMNS
461
+ defaultVisibleColumns: ITEM_TAX_AVAILABLE_COLUMNS,
462
+ hasFooter: false
461
463
  };
462
464
 
463
465
  // src/reports/dailySales.ts
@@ -534,11 +536,11 @@ var DAILY_SALES_BY_GROUP_AVAILABLE_COLUMNS = [
534
536
  "guestAverage",
535
537
  "salesAmountNet"
536
538
  ];
537
- var DAILY_SALES_DEFAULT_VISIBLE_COLUMNS = DAILY_SALES_AVAILABLE_COLUMNS;
538
539
  var dailySalesConfig = {
539
540
  fields: FIELDS7,
540
541
  availableColumns: DAILY_SALES_AVAILABLE_COLUMNS,
541
- defaultVisibleColumns: DAILY_SALES_DEFAULT_VISIBLE_COLUMNS
542
+ defaultVisibleColumns: DAILY_SALES_AVAILABLE_COLUMNS,
543
+ hasFooter: true
542
544
  };
543
545
  var DAILY_SALES_TRENDS_AVAILABLE_COLUMNS = [
544
546
  "ticketsCount",
@@ -550,7 +552,8 @@ var DAILY_SALES_TRENDS_AVAILABLE_COLUMNS = [
550
552
  var dailySalesTrendsConfig = {
551
553
  fields: FIELDS7,
552
554
  availableColumns: DAILY_SALES_TRENDS_AVAILABLE_COLUMNS,
553
- defaultVisibleColumns: DAILY_SALES_TRENDS_AVAILABLE_COLUMNS
555
+ defaultVisibleColumns: DAILY_SALES_TRENDS_AVAILABLE_COLUMNS,
556
+ hasFooter: true
554
557
  };
555
558
 
556
559
  // src/reports/dailySalesPayments.ts
@@ -568,11 +571,11 @@ var DAILY_SALES_PAYMENTS_AVAILABLE_COLUMNS = [
568
571
  "tipsAmount",
569
572
  "totalSales"
570
573
  ];
571
- var DAILY_SALES_PAYMENTS_DEFAULT_VISIBLE_COLUMNS = DAILY_SALES_PAYMENTS_AVAILABLE_COLUMNS;
572
574
  var dailySalesPaymentsConfig = {
573
575
  fields: FIELDS8,
574
576
  availableColumns: DAILY_SALES_PAYMENTS_AVAILABLE_COLUMNS,
575
- defaultVisibleColumns: DAILY_SALES_PAYMENTS_DEFAULT_VISIBLE_COLUMNS
577
+ defaultVisibleColumns: DAILY_SALES_PAYMENTS_AVAILABLE_COLUMNS,
578
+ hasFooter: true
576
579
  };
577
580
 
578
581
  // src/reports/dailySalesDiscounts.ts
@@ -588,11 +591,11 @@ var DAILY_SALES_DISCOUNTS_AVAILABLE_COLUMNS = [
588
591
  "itemCount",
589
592
  "discountsAmount"
590
593
  ];
591
- var DAILY_SALES_DISCOUNTS_DEFAULT_VISIBLE_COLUMNS = DAILY_SALES_DISCOUNTS_AVAILABLE_COLUMNS;
592
594
  var dailySalesDiscountsConfig = {
593
595
  fields: FIELDS9,
594
596
  availableColumns: DAILY_SALES_DISCOUNTS_AVAILABLE_COLUMNS,
595
- defaultVisibleColumns: DAILY_SALES_DISCOUNTS_DEFAULT_VISIBLE_COLUMNS
597
+ defaultVisibleColumns: DAILY_SALES_DISCOUNTS_AVAILABLE_COLUMNS,
598
+ hasFooter: true
596
599
  };
597
600
 
598
601
  // src/reports/employeeTimecard.ts
@@ -675,13 +678,13 @@ var EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS = [
675
678
  "endTime",
676
679
  "shiftHours"
677
680
  ];
678
- var EMPLOYEE_TIMECARD_DEFAULT_VISIBLE_COLUMNS = EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS;
679
681
  var employeeTimecardConfig = {
680
682
  fields: FIELDS10,
681
683
  availableColumns: EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS,
682
- defaultVisibleColumns: EMPLOYEE_TIMECARD_DEFAULT_VISIBLE_COLUMNS,
683
- columnGroups: []
684
+ defaultVisibleColumns: EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS,
685
+ columnGroups: [],
684
686
  // No column groups for this report
687
+ hasFooter: true
685
688
  };
686
689
 
687
690
  // src/reports/salesByItemDetail.ts
@@ -725,11 +728,11 @@ var SALES_BY_ITEM_DETAIL_AVAILABLE_COLUMNS = [
725
728
  "salesType",
726
729
  "itemPrice"
727
730
  ];
728
- var SALES_BY_ITEM_DETAIL_DEFAULT_VISIBLE_COLUMNS = SALES_BY_ITEM_DETAIL_AVAILABLE_COLUMNS;
729
731
  var salesByItemDetailConfig = {
730
732
  fields: FIELDS11,
731
733
  availableColumns: SALES_BY_ITEM_DETAIL_AVAILABLE_COLUMNS,
732
- defaultVisibleColumns: SALES_BY_ITEM_DETAIL_DEFAULT_VISIBLE_COLUMNS
734
+ defaultVisibleColumns: SALES_BY_ITEM_DETAIL_AVAILABLE_COLUMNS,
735
+ hasFooter: false
733
736
  };
734
737
 
735
738
  // src/report.ts
@@ -1436,65 +1439,54 @@ function isNumericType(type) {
1436
1439
  }
1437
1440
 
1438
1441
  // src/totals.ts
1439
- function calculateReportTotals(data, fieldConfig, opts) {
1440
- const rows = data;
1441
- const { labelField, label } = opts;
1442
- const fieldsToSum = /* @__PURE__ */ new Set();
1443
- const derivedFields = [];
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
- }
1442
+ var sumField = (rows, field) => rows.reduce((acc, row) => acc + (row[field] ?? 0), 0);
1443
+ var calculateFieldTotal = (rows, field, config) => {
1444
+ const { type } = config;
1445
+ if (!type || type === "string" || type === "date" || type === "time" || type === "boolean" || type === "conditional") {
1446
+ return null;
1463
1447
  }
1464
- const sums = {};
1465
- for (const field of fieldsToSum) {
1466
- sums[field] = rows.reduce((acc, row) => acc + (row[field] ?? 0), 0);
1448
+ const calc = config.footerCalculation;
1449
+ if (calc?.type === "none") {
1450
+ return null;
1467
1451
  }
1468
- const derived = {};
1469
- for (const { field, calc } of derivedFields) {
1470
- const num = sums[calc.numeratorField ?? ""] ?? 0;
1471
- const den = sums[calc.denominatorField ?? ""] ?? 0;
1472
- if (calc.type === "percentChange") {
1473
- derived[field] = den ? (num - den) / den : 0;
1474
- } else if (calc.type === "average") {
1475
- derived[field] = den > 0 ? num / den : 0;
1476
- }
1452
+ if (!calc || calc.type === "sum") {
1453
+ return config.columnKey || calc?.type === "sum" ? sumField(rows, field) : 0;
1454
+ }
1455
+ const { numeratorField, denominatorField } = calc;
1456
+ if (!numeratorField || !denominatorField) {
1457
+ return 0;
1458
+ }
1459
+ const num = sumField(rows, numeratorField);
1460
+ const den = sumField(rows, denominatorField);
1461
+ if (calc.type === "percentChange") {
1462
+ return den ? (num - den) / den : 0;
1463
+ }
1464
+ if (calc.type === "variancePercent") {
1465
+ const prior = den - num;
1466
+ return prior ? num / prior : 0;
1467
+ }
1468
+ if (calc.type === "average") {
1469
+ return den > 0 ? num / den : 0;
1477
1470
  }
1471
+ if (calc.type === "quotientOfDifferences") {
1472
+ const { numeratorAdjustField, denominatorAdjustField } = calc;
1473
+ const numAdj = numeratorAdjustField ? sumField(rows, numeratorAdjustField) : 0;
1474
+ const denAdj = denominatorAdjustField ? sumField(rows, denominatorAdjustField) : 0;
1475
+ const effectiveDen = den - denAdj;
1476
+ return effectiveDen !== 0 ? (num - numAdj) / effectiveDen : 0;
1477
+ }
1478
+ return 0;
1479
+ };
1480
+ var calculateReportTotals = (data, fieldConfig, opts) => {
1481
+ const { labelField, label } = opts;
1478
1482
  const result = {};
1479
1483
  for (const [field, config] of Object.entries(fieldConfig)) {
1480
- const { type } = config;
1481
- if (!type || type === "string" || type === "date" || type === "time") {
1482
- result[field] = "";
1483
- } else if (type === "boolean") {
1484
- result[field] = false;
1485
- } else {
1486
- result[field] = 0;
1487
- }
1484
+ const total = calculateFieldTotal(data, field, config);
1485
+ result[field] = total ?? "";
1488
1486
  }
1489
1487
  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
1488
  return result;
1497
- }
1489
+ };
1498
1490
 
1499
1491
  // src/reports/dailySalesRefundsVoids.ts
1500
1492
  var FIRST_COLUMN_WIDTH8 = 240;
@@ -1509,11 +1501,11 @@ var DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUMNS = [
1509
1501
  "amount",
1510
1502
  "pctSales"
1511
1503
  ];
1512
- var DAILY_SALES_REFUNDS_VOIDS_DEFAULT_VISIBLE_COLUMNS = DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUMNS;
1513
1504
  var dailySalesRefundsVoidsConfig = {
1514
1505
  fields: FIELDS12,
1515
1506
  availableColumns: DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUMNS,
1516
- defaultVisibleColumns: DAILY_SALES_REFUNDS_VOIDS_DEFAULT_VISIBLE_COLUMNS
1507
+ defaultVisibleColumns: DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUMNS,
1508
+ hasFooter: true
1517
1509
  };
1518
1510
 
1519
1511
  // src/reports/dailySalesTaxes.ts
@@ -1529,11 +1521,11 @@ var DAILY_SALES_TAXES_AVAILABLE_COLUMNS = [
1529
1521
  "taxesAmount",
1530
1522
  "exemptSales"
1531
1523
  ];
1532
- var DAILY_SALES_TAXES_DEFAULT_VISIBLE_COLUMNS = DAILY_SALES_TAXES_AVAILABLE_COLUMNS;
1533
1524
  var dailySalesTaxesConfig = {
1534
1525
  fields: FIELDS13,
1535
1526
  availableColumns: DAILY_SALES_TAXES_AVAILABLE_COLUMNS,
1536
- defaultVisibleColumns: DAILY_SALES_TAXES_DEFAULT_VISIBLE_COLUMNS
1527
+ defaultVisibleColumns: DAILY_SALES_TAXES_AVAILABLE_COLUMNS,
1528
+ hasFooter: true
1537
1529
  };
1538
1530
 
1539
1531
  // src/formatting.ts
@@ -1678,34 +1670,23 @@ export {
1678
1670
  COLUMN_REGISTRY,
1679
1671
  DAILY_SALES_AVAILABLE_COLUMNS,
1680
1672
  DAILY_SALES_BY_GROUP_AVAILABLE_COLUMNS,
1681
- DAILY_SALES_DEFAULT_VISIBLE_COLUMNS,
1682
1673
  DAILY_SALES_DISCOUNTS_AVAILABLE_COLUMNS,
1683
- DAILY_SALES_DISCOUNTS_DEFAULT_VISIBLE_COLUMNS,
1684
1674
  DAILY_SALES_PAYMENTS_AVAILABLE_COLUMNS,
1685
- DAILY_SALES_PAYMENTS_DEFAULT_VISIBLE_COLUMNS,
1686
1675
  DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUMNS,
1687
- DAILY_SALES_REFUNDS_VOIDS_DEFAULT_VISIBLE_COLUMNS,
1688
1676
  DAILY_SALES_TAXES_AVAILABLE_COLUMNS,
1689
- DAILY_SALES_TAXES_DEFAULT_VISIBLE_COLUMNS,
1690
1677
  DAILY_SALES_TRENDS_AVAILABLE_COLUMNS,
1691
1678
  EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS,
1692
- EMPLOYEE_TIMECARD_DEFAULT_VISIBLE_COLUMNS,
1693
1679
  ITEM_TAX_AVAILABLE_COLUMNS,
1694
- ITEM_TAX_DEFAULT_VISIBLE_COLUMNS,
1695
1680
  MODIFIER_MIX_AVAILABLE_COLUMNS,
1696
- MODIFIER_MIX_DEFAULT_VISIBLE_COLUMNS,
1697
1681
  PRODUCT_MIX_AVAILABLE_COLUMNS,
1698
1682
  PRODUCT_MIX_CHART_FIELDS,
1699
1683
  PRODUCT_MIX_DEFAULT_VISIBLE_COLUMNS,
1700
1684
  Report,
1701
1685
  SALES_BY_ITEM_DETAIL_AVAILABLE_COLUMNS,
1702
- SALES_BY_ITEM_DETAIL_DEFAULT_VISIBLE_COLUMNS,
1703
1686
  SALES_SUMMARY_AVAILABLE_COLUMNS,
1704
- SALES_SUMMARY_DEFAULT_VISIBLE_COLUMNS,
1705
1687
  TICKET_LIVE_AVAILABLE_COLUMNS,
1706
- TICKET_LIVE_DEFAULT_VISIBLE_COLUMNS,
1707
1688
  TICKET_SUMMARY_AVAILABLE_COLUMNS,
1708
- TICKET_SUMMARY_DEFAULT_VISIBLE_COLUMNS,
1689
+ calculateFieldTotal,
1709
1690
  calculateReportTotals,
1710
1691
  dailySalesConfig,
1711
1692
  dailySalesDiscountsConfig,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@harbortouch/skytab-analytics-report-utils",
3
- "version": "0.9.0",
3
+ "version": "0.11.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",