@bash-app/bash-common 30.236.0 → 30.237.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.
Files changed (180) hide show
  1. package/dist/__tests__/statusEnums.test.js +88 -7
  2. package/dist/__tests__/statusEnums.test.js.map +1 -1
  3. package/dist/definitions.d.ts +39 -8
  4. package/dist/definitions.d.ts.map +1 -1
  5. package/dist/definitions.js +31 -10
  6. package/dist/definitions.js.map +1 -1
  7. package/dist/extendedSchemas.d.ts +6 -0
  8. package/dist/extendedSchemas.d.ts.map +1 -1
  9. package/dist/extendedSchemas.js.map +1 -1
  10. package/dist/index.d.ts +13 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +16 -4
  13. package/dist/index.js.map +1 -1
  14. package/dist/mirroredPrismaEnums.d.ts +145 -0
  15. package/dist/mirroredPrismaEnums.d.ts.map +1 -0
  16. package/dist/mirroredPrismaEnums.js +136 -0
  17. package/dist/mirroredPrismaEnums.js.map +1 -0
  18. package/dist/utils/__tests__/nonprofitUtils.test.d.ts +2 -0
  19. package/dist/utils/__tests__/nonprofitUtils.test.d.ts.map +1 -0
  20. package/dist/utils/__tests__/nonprofitUtils.test.js +84 -0
  21. package/dist/utils/__tests__/nonprofitUtils.test.js.map +1 -0
  22. package/dist/utils/__tests__/paymentUtils.test.js +87 -0
  23. package/dist/utils/__tests__/paymentUtils.test.js.map +1 -1
  24. package/dist/utils/nonprofitUtils.d.ts +21 -0
  25. package/dist/utils/nonprofitUtils.d.ts.map +1 -0
  26. package/dist/utils/nonprofitUtils.js +29 -0
  27. package/dist/utils/nonprofitUtils.js.map +1 -0
  28. package/dist/utils/paymentUtils.d.ts +23 -0
  29. package/dist/utils/paymentUtils.d.ts.map +1 -1
  30. package/dist/utils/paymentUtils.js +24 -7
  31. package/dist/utils/paymentUtils.js.map +1 -1
  32. package/dist/utils/service/__tests__/billingCapUtils.test.d.ts +2 -0
  33. package/dist/utils/service/__tests__/billingCapUtils.test.d.ts.map +1 -0
  34. package/dist/utils/service/__tests__/billingCapUtils.test.js +120 -0
  35. package/dist/utils/service/__tests__/billingCapUtils.test.js.map +1 -0
  36. package/dist/utils/service/__tests__/cancellationPolicyRefundResolver.test.js +1 -1
  37. package/dist/utils/service/__tests__/cancellationPolicyRefundResolver.test.js.map +1 -1
  38. package/dist/utils/service/__tests__/eventPromoterPhase3.test.d.ts +2 -0
  39. package/dist/utils/service/__tests__/eventPromoterPhase3.test.d.ts.map +1 -0
  40. package/dist/utils/service/__tests__/eventPromoterPhase3.test.js +243 -0
  41. package/dist/utils/service/__tests__/eventPromoterPhase3.test.js.map +1 -0
  42. package/dist/utils/service/__tests__/eventPromoterUtils.test.d.ts +2 -0
  43. package/dist/utils/service/__tests__/eventPromoterUtils.test.d.ts.map +1 -0
  44. package/dist/utils/service/__tests__/eventPromoterUtils.test.js +333 -0
  45. package/dist/utils/service/__tests__/eventPromoterUtils.test.js.map +1 -0
  46. package/dist/utils/service/__tests__/offerAllowListUtils.test.d.ts +2 -0
  47. package/dist/utils/service/__tests__/offerAllowListUtils.test.d.ts.map +1 -0
  48. package/dist/utils/service/__tests__/offerAllowListUtils.test.js +52 -0
  49. package/dist/utils/service/__tests__/offerAllowListUtils.test.js.map +1 -0
  50. package/dist/utils/service/__tests__/offerComparisonUtils.test.d.ts +2 -0
  51. package/dist/utils/service/__tests__/offerComparisonUtils.test.d.ts.map +1 -0
  52. package/dist/utils/service/__tests__/offerComparisonUtils.test.js +111 -0
  53. package/dist/utils/service/__tests__/offerComparisonUtils.test.js.map +1 -0
  54. package/dist/utils/service/__tests__/serviceBookingExposureUtils.test.d.ts +2 -0
  55. package/dist/utils/service/__tests__/serviceBookingExposureUtils.test.d.ts.map +1 -0
  56. package/dist/utils/service/__tests__/serviceBookingExposureUtils.test.js +155 -0
  57. package/dist/utils/service/__tests__/serviceBookingExposureUtils.test.js.map +1 -0
  58. package/dist/utils/service/__tests__/unifiedPricingResolver.test.d.ts +2 -0
  59. package/dist/utils/service/__tests__/unifiedPricingResolver.test.d.ts.map +1 -0
  60. package/dist/utils/service/__tests__/unifiedPricingResolver.test.js +77 -0
  61. package/dist/utils/service/__tests__/unifiedPricingResolver.test.js.map +1 -0
  62. package/dist/utils/service/__tests__/venueFBSettlementUtils.test.d.ts +2 -0
  63. package/dist/utils/service/__tests__/venueFBSettlementUtils.test.d.ts.map +1 -0
  64. package/dist/utils/service/__tests__/venueFBSettlementUtils.test.js +157 -0
  65. package/dist/utils/service/__tests__/venueFBSettlementUtils.test.js.map +1 -0
  66. package/dist/utils/service/__tests__/venueSettlementUtils.test.d.ts +2 -0
  67. package/dist/utils/service/__tests__/venueSettlementUtils.test.d.ts.map +1 -0
  68. package/dist/utils/service/__tests__/venueSettlementUtils.test.js +175 -0
  69. package/dist/utils/service/__tests__/venueSettlementUtils.test.js.map +1 -0
  70. package/dist/utils/service/__tests__/volunteerCompensationUtils.test.d.ts +2 -0
  71. package/dist/utils/service/__tests__/volunteerCompensationUtils.test.d.ts.map +1 -0
  72. package/dist/utils/service/__tests__/volunteerCompensationUtils.test.js +118 -0
  73. package/dist/utils/service/__tests__/volunteerCompensationUtils.test.js.map +1 -0
  74. package/dist/utils/service/apiServiceBookingApiUtils.d.ts.map +1 -1
  75. package/dist/utils/service/apiServiceBookingApiUtils.js +4 -0
  76. package/dist/utils/service/apiServiceBookingApiUtils.js.map +1 -1
  77. package/dist/utils/service/billingCapUtils.d.ts +86 -0
  78. package/dist/utils/service/billingCapUtils.d.ts.map +1 -0
  79. package/dist/utils/service/billingCapUtils.js +96 -0
  80. package/dist/utils/service/billingCapUtils.js.map +1 -0
  81. package/dist/utils/service/cancellationPolicyRefundResolver.d.ts +1 -1
  82. package/dist/utils/service/cancellationPolicyRefundResolver.d.ts.map +1 -1
  83. package/dist/utils/service/cancellationPolicyRefundResolver.js +1 -1
  84. package/dist/utils/service/cancellationPolicyRefundResolver.js.map +1 -1
  85. package/dist/utils/service/eventPromoterUtils.d.ts +319 -0
  86. package/dist/utils/service/eventPromoterUtils.d.ts.map +1 -0
  87. package/dist/utils/service/eventPromoterUtils.js +372 -0
  88. package/dist/utils/service/eventPromoterUtils.js.map +1 -0
  89. package/dist/utils/service/offerAllowListUtils.d.ts +42 -0
  90. package/dist/utils/service/offerAllowListUtils.d.ts.map +1 -0
  91. package/dist/utils/service/offerAllowListUtils.js +49 -0
  92. package/dist/utils/service/offerAllowListUtils.js.map +1 -0
  93. package/dist/utils/service/offerComparisonUtils.d.ts +69 -0
  94. package/dist/utils/service/offerComparisonUtils.d.ts.map +1 -0
  95. package/dist/utils/service/offerComparisonUtils.js +110 -0
  96. package/dist/utils/service/offerComparisonUtils.js.map +1 -0
  97. package/dist/utils/service/serviceBookingExposureUtils.d.ts +111 -0
  98. package/dist/utils/service/serviceBookingExposureUtils.d.ts.map +1 -0
  99. package/dist/utils/service/serviceBookingExposureUtils.js +133 -0
  100. package/dist/utils/service/serviceBookingExposureUtils.js.map +1 -0
  101. package/dist/utils/service/serviceBookingTypes.d.ts +1 -1
  102. package/dist/utils/service/serviceBookingTypes.d.ts.map +1 -1
  103. package/dist/utils/service/serviceUtils.d.ts +2 -1
  104. package/dist/utils/service/serviceUtils.d.ts.map +1 -1
  105. package/dist/utils/service/serviceUtils.js +17 -16
  106. package/dist/utils/service/serviceUtils.js.map +1 -1
  107. package/dist/utils/service/unifiedPricingResolver.d.ts +67 -0
  108. package/dist/utils/service/unifiedPricingResolver.d.ts.map +1 -0
  109. package/dist/utils/service/unifiedPricingResolver.js +75 -0
  110. package/dist/utils/service/unifiedPricingResolver.js.map +1 -0
  111. package/dist/utils/service/venueFBSettlementUtils.d.ts +122 -0
  112. package/dist/utils/service/venueFBSettlementUtils.d.ts.map +1 -0
  113. package/dist/utils/service/venueFBSettlementUtils.js +106 -0
  114. package/dist/utils/service/venueFBSettlementUtils.js.map +1 -0
  115. package/dist/utils/service/venueSettlementUtils.d.ts +107 -0
  116. package/dist/utils/service/venueSettlementUtils.d.ts.map +1 -0
  117. package/dist/utils/service/venueSettlementUtils.js +117 -0
  118. package/dist/utils/service/venueSettlementUtils.js.map +1 -0
  119. package/dist/utils/service/volunteerCompensationUtils.d.ts +75 -0
  120. package/dist/utils/service/volunteerCompensationUtils.d.ts.map +1 -0
  121. package/dist/utils/service/volunteerCompensationUtils.js +88 -0
  122. package/dist/utils/service/volunteerCompensationUtils.js.map +1 -0
  123. package/dist/utils/venueLoyalty/__tests__/eligibilityUtils.test.d.ts +2 -0
  124. package/dist/utils/venueLoyalty/__tests__/eligibilityUtils.test.d.ts.map +1 -0
  125. package/dist/utils/venueLoyalty/__tests__/eligibilityUtils.test.js +67 -0
  126. package/dist/utils/venueLoyalty/__tests__/eligibilityUtils.test.js.map +1 -0
  127. package/dist/utils/venueLoyalty/__tests__/redemptionCodeUtils.test.d.ts +2 -0
  128. package/dist/utils/venueLoyalty/__tests__/redemptionCodeUtils.test.d.ts.map +1 -0
  129. package/dist/utils/venueLoyalty/__tests__/redemptionCodeUtils.test.js +71 -0
  130. package/dist/utils/venueLoyalty/__tests__/redemptionCodeUtils.test.js.map +1 -0
  131. package/dist/utils/venueLoyalty/eligibilityUtils.d.ts +33 -0
  132. package/dist/utils/venueLoyalty/eligibilityUtils.d.ts.map +1 -0
  133. package/dist/utils/venueLoyalty/eligibilityUtils.js +49 -0
  134. package/dist/utils/venueLoyalty/eligibilityUtils.js.map +1 -0
  135. package/dist/utils/venueLoyalty/redemptionCodeUtils.d.ts +35 -0
  136. package/dist/utils/venueLoyalty/redemptionCodeUtils.d.ts.map +1 -0
  137. package/dist/utils/venueLoyalty/redemptionCodeUtils.js +74 -0
  138. package/dist/utils/venueLoyalty/redemptionCodeUtils.js.map +1 -0
  139. package/dist/venueLoyaltyRedemption.d.ts +146 -1
  140. package/dist/venueLoyaltyRedemption.d.ts.map +1 -1
  141. package/dist/venueLoyaltyRedemption.js +18 -2
  142. package/dist/venueLoyaltyRedemption.js.map +1 -1
  143. package/package.json +1 -1
  144. package/prisma/schema.prisma +609 -214
  145. package/src/__tests__/statusEnums.test.ts +119 -11
  146. package/src/definitions.ts +57 -14
  147. package/src/extendedSchemas.ts +6 -0
  148. package/src/index.ts +16 -6
  149. package/src/mirroredPrismaEnums.ts +181 -0
  150. package/src/utils/__tests__/nonprofitUtils.test.ts +117 -0
  151. package/src/utils/__tests__/paymentUtils.test.ts +93 -0
  152. package/src/utils/nonprofitUtils.ts +44 -0
  153. package/src/utils/paymentUtils.ts +33 -7
  154. package/src/utils/service/__tests__/billingCapUtils.test.ts +175 -0
  155. package/src/utils/service/__tests__/cancellationPolicyRefundResolver.test.ts +1 -1
  156. package/src/utils/service/__tests__/eventPromoterPhase3.test.ts +296 -0
  157. package/src/utils/service/__tests__/eventPromoterUtils.test.ts +396 -0
  158. package/src/utils/service/__tests__/offerAllowListUtils.test.ts +76 -0
  159. package/src/utils/service/__tests__/offerComparisonUtils.test.ts +124 -0
  160. package/src/utils/service/__tests__/serviceBookingExposureUtils.test.ts +171 -0
  161. package/src/utils/service/__tests__/unifiedPricingResolver.test.ts +83 -0
  162. package/src/utils/service/__tests__/venueSettlementUtils.test.ts +219 -0
  163. package/src/utils/service/__tests__/volunteerCompensationUtils.test.ts +172 -0
  164. package/src/utils/service/apiServiceBookingApiUtils.ts +4 -0
  165. package/src/utils/service/billingCapUtils.ts +145 -0
  166. package/src/utils/service/cancellationPolicyRefundResolver.ts +1 -1
  167. package/src/utils/service/eventPromoterUtils.ts +644 -0
  168. package/src/utils/service/offerAllowListUtils.ts +81 -0
  169. package/src/utils/service/offerComparisonUtils.ts +197 -0
  170. package/src/utils/service/serviceBookingExposureUtils.ts +218 -0
  171. package/src/utils/service/serviceBookingTypes.ts +4 -0
  172. package/src/utils/service/serviceUtils.ts +18 -21
  173. package/src/utils/service/unifiedPricingResolver.ts +149 -0
  174. package/src/utils/service/venueSettlementUtils.ts +198 -0
  175. package/src/utils/service/volunteerCompensationUtils.ts +145 -0
  176. package/src/utils/venueLoyalty/__tests__/eligibilityUtils.test.ts +103 -0
  177. package/src/utils/venueLoyalty/__tests__/redemptionCodeUtils.test.ts +92 -0
  178. package/src/utils/venueLoyalty/eligibilityUtils.ts +84 -0
  179. package/src/utils/venueLoyalty/redemptionCodeUtils.ts +94 -0
  180. package/src/venueLoyaltyRedemption.ts +177 -2
@@ -0,0 +1,155 @@
1
+ import { computeServiceBookingExposure, isVariablePricingModel, summarizeServiceBookingExposures, } from "../serviceBookingExposureUtils";
2
+ describe("isVariablePricingModel", () => {
3
+ it("returns true for attendee- and revenue-driven models", () => {
4
+ expect(isVariablePricingModel("PER_ATTENDEE")).toBe(true);
5
+ expect(isVariablePricingModel("PER_PAID_ATTENDEE")).toBe(true);
6
+ expect(isVariablePricingModel("PER_BASHPOINTS_ATTENDEE")).toBe(true);
7
+ expect(isVariablePricingModel("TICKET_REVENUE_PERCENTAGE")).toBe(true);
8
+ expect(isVariablePricingModel("PRODUCT_SALES_PERCENTAGE")).toBe(true);
9
+ expect(isVariablePricingModel("TIERED")).toBe(true);
10
+ expect(isVariablePricingModel("CUSTOM")).toBe(true);
11
+ });
12
+ it("returns false for flat models", () => {
13
+ expect(isVariablePricingModel("FLAT_FEE")).toBe(false);
14
+ expect(isVariablePricingModel("HOURLY")).toBe(false);
15
+ expect(isVariablePricingModel("PER_DAY")).toBe(false);
16
+ });
17
+ it("returns false for unknown / null inputs", () => {
18
+ expect(isVariablePricingModel(null)).toBe(false);
19
+ expect(isVariablePricingModel(undefined)).toBe(false);
20
+ expect(isVariablePricingModel("NOT_A_MODEL")).toBe(false);
21
+ });
22
+ });
23
+ describe("computeServiceBookingExposure", () => {
24
+ it("treats null pricingModel as flat — expected equals worst from totalATBCents", () => {
25
+ const out = computeServiceBookingExposure({
26
+ bookingId: "b1",
27
+ label: "Legacy booking",
28
+ pricingModel: null,
29
+ totalATBCents: 150_000,
30
+ });
31
+ expect(out.isVariable).toBe(false);
32
+ expect(out.expectedCents).toBe(150_000);
33
+ expect(out.worstCaseCents).toBe(150_000);
34
+ });
35
+ it("uses flatRateCents when totalATBCents missing", () => {
36
+ const out = computeServiceBookingExposure({
37
+ bookingId: "b1",
38
+ label: "Photo Booth",
39
+ pricingModel: "FLAT_FEE",
40
+ flatRateCents: 50_000,
41
+ });
42
+ expect(out.expectedCents).toBe(50_000);
43
+ expect(out.worstCaseCents).toBe(50_000);
44
+ });
45
+ it("computes PER_ATTENDEE expected and worst case from attendee fields", () => {
46
+ const out = computeServiceBookingExposure({
47
+ bookingId: "b1",
48
+ label: "DJ",
49
+ pricingModel: "PER_ATTENDEE",
50
+ baseRateCents: 500,
51
+ expectedAttendeesAtBooking: 200,
52
+ maxAttendeesAttributable: 250,
53
+ });
54
+ expect(out.isVariable).toBe(true);
55
+ expect(out.expectedCents).toBe(100_000); // 200 * 500
56
+ expect(out.worstCaseCents).toBe(125_000); // 250 * 500
57
+ });
58
+ it("prefers maxBillableCents over the attendee ceiling for worst case", () => {
59
+ const out = computeServiceBookingExposure({
60
+ bookingId: "b1",
61
+ label: "DJ",
62
+ pricingModel: "PER_ATTENDEE",
63
+ baseRateCents: 500,
64
+ expectedAttendeesAtBooking: 200,
65
+ maxAttendeesAttributable: 250,
66
+ maxBillableCents: 200_000,
67
+ });
68
+ expect(out.worstCaseCents).toBe(200_000);
69
+ });
70
+ it("falls back to 1.5x expected when no caps set on variable bookings", () => {
71
+ const out = computeServiceBookingExposure({
72
+ bookingId: "b1",
73
+ label: "DJ",
74
+ pricingModel: "PER_ATTENDEE",
75
+ baseRateCents: 500,
76
+ expectedAttendeesAtBooking: 200,
77
+ });
78
+ expect(out.expectedCents).toBe(100_000);
79
+ expect(out.worstCaseCents).toBe(150_000); // 100_000 * 1.5
80
+ });
81
+ it("clamps worst case never below expected", () => {
82
+ // Pathological: maxBillableCents below expected.
83
+ const out = computeServiceBookingExposure({
84
+ bookingId: "b1",
85
+ label: "DJ",
86
+ pricingModel: "PER_ATTENDEE",
87
+ baseRateCents: 500,
88
+ expectedAttendeesAtBooking: 200,
89
+ maxBillableCents: 50_000, // lower than expected 100_000
90
+ });
91
+ expect(out.expectedCents).toBe(100_000);
92
+ expect(out.worstCaseCents).toBe(100_000);
93
+ });
94
+ it("handles revenue-share by using totalATB as expected, 1.5x as worst", () => {
95
+ const out = computeServiceBookingExposure({
96
+ bookingId: "b1",
97
+ label: "Venue (rev-share)",
98
+ pricingModel: "TICKET_REVENUE_PERCENTAGE",
99
+ totalATBCents: 80_000,
100
+ });
101
+ expect(out.isVariable).toBe(true);
102
+ expect(out.expectedCents).toBe(80_000);
103
+ expect(out.worstCaseCents).toBe(120_000); // 80_000 * 1.5
104
+ });
105
+ it("returns zeros when nothing usable is provided", () => {
106
+ const out = computeServiceBookingExposure({
107
+ bookingId: "b1",
108
+ label: "Mystery",
109
+ pricingModel: "CUSTOM",
110
+ });
111
+ expect(out.expectedCents).toBe(0);
112
+ expect(out.worstCaseCents).toBe(0);
113
+ });
114
+ });
115
+ describe("summarizeServiceBookingExposures", () => {
116
+ it("sums expected + worst-case across mixed bookings", () => {
117
+ const out = summarizeServiceBookingExposures([
118
+ {
119
+ bookingId: "a",
120
+ label: "DJ",
121
+ pricingModel: "PER_ATTENDEE",
122
+ baseRateCents: 500,
123
+ expectedAttendeesAtBooking: 200,
124
+ maxAttendeesAttributable: 250,
125
+ },
126
+ {
127
+ bookingId: "b",
128
+ label: "Photo Booth",
129
+ pricingModel: "FLAT_FEE",
130
+ totalATBCents: 50_000,
131
+ },
132
+ {
133
+ bookingId: "c",
134
+ label: "Caterer (legacy)",
135
+ pricingModel: null,
136
+ totalATBCents: 200_000,
137
+ },
138
+ ]);
139
+ // Expected: 100_000 + 50_000 + 200_000 = 350_000
140
+ expect(out.projectedTotalCents).toBe(350_000);
141
+ // Worst: 125_000 + 50_000 + 200_000 = 375_000
142
+ expect(out.worstCaseTotalCents).toBe(375_000);
143
+ expect(out.byBooking).toHaveLength(3);
144
+ expect(out.byBooking[0].isVariable).toBe(true);
145
+ expect(out.byBooking[1].isVariable).toBe(false);
146
+ expect(out.byBooking[2].isVariable).toBe(false);
147
+ });
148
+ it("returns zeros for an empty list", () => {
149
+ const out = summarizeServiceBookingExposures([]);
150
+ expect(out.projectedTotalCents).toBe(0);
151
+ expect(out.worstCaseTotalCents).toBe(0);
152
+ expect(out.byBooking).toEqual([]);
153
+ });
154
+ });
155
+ //# sourceMappingURL=serviceBookingExposureUtils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serviceBookingExposureUtils.test.js","sourceRoot":"","sources":["../../../../src/utils/service/__tests__/serviceBookingExposureUtils.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=unifiedPricingResolver.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unifiedPricingResolver.test.d.ts","sourceRoot":"","sources":["../../../../src/utils/service/__tests__/unifiedPricingResolver.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,77 @@
1
+ import { describe, expect, it } from "@jest/globals";
2
+ import { resolveUnifiedPricingBlock } from "../unifiedPricingResolver.js";
3
+ describe("resolveUnifiedPricingBlock", () => {
4
+ it("returns the empty block when nothing is configured", () => {
5
+ const r = resolveUnifiedPricingBlock({});
6
+ expect(r.fromUnifiedBlock).toBe(false);
7
+ expect(r.noRateConfigured).toBe(true);
8
+ expect(r.baseRateCents).toBeNull();
9
+ });
10
+ it("prefers the unified block from the first subtype that has one", () => {
11
+ const r = resolveUnifiedPricingBlock({
12
+ vendor: {
13
+ pricingModel: "FLAT_FEE",
14
+ baseRateCents: 50_000,
15
+ rateUnit: "event",
16
+ },
17
+ legacyRate: { ratePerUnitCents: 99_999 },
18
+ });
19
+ expect(r.fromUnifiedBlock).toBe(true);
20
+ expect(r.baseRateCents).toBe(50_000);
21
+ expect(r.rateUnit).toBe("event");
22
+ });
23
+ it("walks all candidate subtypes when earlier ones are empty", () => {
24
+ const r = resolveUnifiedPricingBlock({
25
+ eventService: null,
26
+ vendor: null,
27
+ exhibitor: null,
28
+ sponsor: {
29
+ pricingModel: "TIERED",
30
+ baseRateCents: 100_000,
31
+ },
32
+ });
33
+ expect(r.fromUnifiedBlock).toBe(true);
34
+ expect(r.pricingModel).toBe("TIERED");
35
+ expect(r.baseRateCents).toBe(100_000);
36
+ });
37
+ it("recognizes a unified signal even when only baseRateBashPoints is set", () => {
38
+ const r = resolveUnifiedPricingBlock({
39
+ eventService: {
40
+ pricingModel: null,
41
+ baseRateCents: null,
42
+ baseRateBashPoints: 25,
43
+ },
44
+ });
45
+ expect(r.fromUnifiedBlock).toBe(true);
46
+ expect(r.baseRateBashPoints).toBe(25);
47
+ expect(r.noRateConfigured).toBe(false);
48
+ });
49
+ it("falls back to legacy ServiceRate when no unified block exists", () => {
50
+ const r = resolveUnifiedPricingBlock({
51
+ legacyRate: {
52
+ ratePerUnitCents: 12_345,
53
+ rateUnit: "hour",
54
+ minimumQuantity: 4,
55
+ },
56
+ });
57
+ expect(r.fromUnifiedBlock).toBe(false);
58
+ expect(r.pricingModel).toBe("FLAT_FEE");
59
+ expect(r.baseRateCents).toBe(12_345);
60
+ expect(r.minimumQuantity).toBe(4);
61
+ });
62
+ it("falls through to empty when both unified and legacy are unset", () => {
63
+ const r = resolveUnifiedPricingBlock({
64
+ vendor: { pricingModel: null, baseRateCents: null },
65
+ legacyRate: null,
66
+ });
67
+ expect(r.noRateConfigured).toBe(true);
68
+ });
69
+ it("noRateConfigured stays true when unified has minimumQuantity but no rate", () => {
70
+ const r = resolveUnifiedPricingBlock({
71
+ vendor: { minimumQuantity: 10 },
72
+ });
73
+ expect(r.fromUnifiedBlock).toBe(true);
74
+ expect(r.noRateConfigured).toBe(true);
75
+ });
76
+ });
77
+ //# sourceMappingURL=unifiedPricingResolver.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unifiedPricingResolver.test.js","sourceRoot":"","sources":["../../../../src/utils/service/__tests__/unifiedPricingResolver.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=venueFBSettlementUtils.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"venueFBSettlementUtils.test.d.ts","sourceRoot":"","sources":["../../../../src/utils/service/__tests__/venueFBSettlementUtils.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,157 @@
1
+ import { resolveFBMinimumCents, settleVenueFBMinimum, settleVenueRevenueShare, FB_MINIMUM_CANCELLATION_COPY, } from "../venueFBSettlementUtils.js";
2
+ describe("settleVenueFBMinimum", () => {
3
+ it("computes a clean shortfall when actual < minimum and basis matches", () => {
4
+ const out = settleVenueFBMinimum({
5
+ fbMinimumCents: 1_000_000, // $10k
6
+ fbMinimumIncludesServiceCharge: false,
7
+ fbMinimumIncludesTax: false,
8
+ actualFbSpendCents: 750_000, // $7,500
9
+ });
10
+ expect(out.normalizedMinimumCents).toBe(1_000_000);
11
+ expect(out.normalizedActualCents).toBe(750_000);
12
+ expect(out.rawShortfallCents).toBe(250_000);
13
+ expect(out.carryoverAppliedCents).toBe(0);
14
+ expect(out.shortfallChargedCents).toBe(250_000);
15
+ expect(out.carryoverEarnedCents).toBe(0);
16
+ });
17
+ it("normalizes a minimum that includes service charge when actual does not", () => {
18
+ // Minimum is $10k *including* 20% service charge; actual is $8k pre-svc.
19
+ // Normalized minimum becomes $10k / 1.20 = $8333.33 → 833,333 cents.
20
+ const out = settleVenueFBMinimum({
21
+ fbMinimumCents: 1_000_000,
22
+ fbMinimumIncludesServiceCharge: true,
23
+ fbMinimumIncludesTax: false,
24
+ fbServiceChargeRate: 0.2,
25
+ actualFbSpendCents: 800_000,
26
+ });
27
+ expect(out.normalizedMinimumCents).toBe(833_333);
28
+ expect(out.rawShortfallCents).toBe(33_333);
29
+ expect(out.shortfallChargedCents).toBe(33_333);
30
+ });
31
+ it("redeems carryover credits against shortfall before charging the host", () => {
32
+ const out = settleVenueFBMinimum({
33
+ fbMinimumCents: 1_000_000,
34
+ fbMinimumIncludesServiceCharge: false,
35
+ fbMinimumIncludesTax: false,
36
+ actualFbSpendCents: 800_000,
37
+ availableCarryoverCents: 150_000,
38
+ });
39
+ expect(out.rawShortfallCents).toBe(200_000);
40
+ expect(out.carryoverAppliedCents).toBe(150_000);
41
+ expect(out.shortfallChargedCents).toBe(50_000);
42
+ });
43
+ it("earns carryover when actual exceeds minimum and carryover is enabled", () => {
44
+ const out = settleVenueFBMinimum({
45
+ fbMinimumCents: 1_000_000,
46
+ fbMinimumIncludesServiceCharge: false,
47
+ fbMinimumIncludesTax: false,
48
+ actualFbSpendCents: 1_250_000,
49
+ carryoverEnabled: true,
50
+ });
51
+ expect(out.rawShortfallCents).toBe(0);
52
+ expect(out.carryoverEarnedCents).toBe(250_000);
53
+ });
54
+ it("does not earn carryover when the venue has not enabled it", () => {
55
+ const out = settleVenueFBMinimum({
56
+ fbMinimumCents: 1_000_000,
57
+ fbMinimumIncludesServiceCharge: false,
58
+ fbMinimumIncludesTax: false,
59
+ actualFbSpendCents: 1_250_000,
60
+ carryoverEnabled: false,
61
+ });
62
+ expect(out.carryoverEarnedCents).toBe(0);
63
+ });
64
+ it("marks metExactly when actual === minimum after normalization", () => {
65
+ const out = settleVenueFBMinimum({
66
+ fbMinimumCents: 1_000_000,
67
+ fbMinimumIncludesServiceCharge: false,
68
+ fbMinimumIncludesTax: false,
69
+ actualFbSpendCents: 1_000_000,
70
+ });
71
+ expect(out.metExactly).toBe(true);
72
+ expect(out.shortfallChargedCents).toBe(0);
73
+ expect(out.carryoverEarnedCents).toBe(0);
74
+ });
75
+ });
76
+ describe("settleVenueRevenueShare", () => {
77
+ it("applies % when no floor is present", () => {
78
+ const out = settleVenueRevenueShare({
79
+ heldTicketRevenueCents: 1_000_000,
80
+ revenueSharePercentage: 30,
81
+ });
82
+ expect(out.venueCutPctCents).toBe(300_000);
83
+ expect(out.venuePayoutCents).toBe(300_000);
84
+ expect(out.flooredUp).toBe(false);
85
+ });
86
+ it("floors up to revenueShareMinimumCents on slow nights", () => {
87
+ const out = settleVenueRevenueShare({
88
+ heldTicketRevenueCents: 100_000,
89
+ revenueSharePercentage: 30,
90
+ revenueShareMinimumCents: 50_000,
91
+ });
92
+ expect(out.venueCutPctCents).toBe(30_000);
93
+ expect(out.venuePayoutCents).toBe(50_000);
94
+ expect(out.flooredUp).toBe(true);
95
+ });
96
+ it("clamps percentage to 0..100", () => {
97
+ expect(settleVenueRevenueShare({
98
+ heldTicketRevenueCents: 100_000,
99
+ revenueSharePercentage: 250,
100
+ }).venuePayoutCents).toBe(100_000);
101
+ expect(settleVenueRevenueShare({
102
+ heldTicketRevenueCents: 100_000,
103
+ revenueSharePercentage: -10,
104
+ }).venuePayoutCents).toBe(0);
105
+ });
106
+ });
107
+ describe("resolveFBMinimumCents", () => {
108
+ it("picks weekday minimum for Mon-Thu", () => {
109
+ expect(resolveFBMinimumCents({
110
+ bashStartDay: 2, // Tuesday
111
+ fbMinimumWeekdayCents: 800_000,
112
+ fbMinimumWeekendCents: 4_000_000,
113
+ })).toBe(800_000);
114
+ });
115
+ it("picks weekend minimum for Fri/Sat/Sun", () => {
116
+ expect(resolveFBMinimumCents({
117
+ bashStartDay: 5,
118
+ fbMinimumWeekdayCents: 800_000,
119
+ fbMinimumWeekendCents: 4_000_000,
120
+ })).toBe(4_000_000);
121
+ expect(resolveFBMinimumCents({
122
+ bashStartDay: 0, // Sun
123
+ fbMinimumWeekdayCents: 800_000,
124
+ fbMinimumWeekendCents: 4_000_000,
125
+ })).toBe(4_000_000);
126
+ });
127
+ it("returns override when the bash date falls inside an override window", () => {
128
+ const nye = new Date("2026-12-31T20:00:00Z");
129
+ const out = resolveFBMinimumCents({
130
+ bashStartDay: 4, // Thu
131
+ bashStartDate: nye,
132
+ fbMinimumWeekdayCents: 800_000,
133
+ fbMinimumWeekendCents: 4_000_000,
134
+ overrides: [
135
+ {
136
+ startsAt: new Date("2026-12-30T00:00:00Z"),
137
+ endsAt: new Date("2027-01-01T23:59:59Z"),
138
+ minimumCents: 10_000_000,
139
+ },
140
+ ],
141
+ });
142
+ expect(out).toBe(10_000_000);
143
+ });
144
+ it("returns null if the requested side has no configured minimum", () => {
145
+ expect(resolveFBMinimumCents({
146
+ bashStartDay: 3,
147
+ fbMinimumWeekdayCents: null,
148
+ fbMinimumWeekendCents: 4_000_000,
149
+ })).toBeNull();
150
+ });
151
+ });
152
+ describe("copy snippets", () => {
153
+ it("exposes the F&B cancellation copy for offer sheets and detail pages", () => {
154
+ expect(FB_MINIMUM_CANCELLATION_COPY).toMatch(/F&B minimum/);
155
+ });
156
+ });
157
+ //# sourceMappingURL=venueFBSettlementUtils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"venueFBSettlementUtils.test.js","sourceRoot":"","sources":["../../../../src/utils/service/__tests__/venueFBSettlementUtils.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=venueSettlementUtils.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"venueSettlementUtils.test.d.ts","sourceRoot":"","sources":["../../../../src/utils/service/__tests__/venueSettlementUtils.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,175 @@
1
+ import { DEFAULT_FB_CARRYOVER_EXPIRY_DAYS, REVENUE_SHARE_CANCELLATION_COPY, FB_MINIMUM_CANCELLATION_COPY, computeFBMinimumShortfallCents, computeRevenueShareCents, defaultFBCarryoverExpiresAt, resolveFBMinimumForDate, } from "../venueSettlementUtils.js";
2
+ describe("computeFBMinimumShortfallCents", () => {
3
+ it("computes a clean shortfall when subtotal < minimum", () => {
4
+ const out = computeFBMinimumShortfallCents({
5
+ fbMinimumCents: 1_000_000, // $10k
6
+ fbActualSpendCents: 750_000, // $7,500 subtotal
7
+ serviceChargeCents: 0,
8
+ taxCents: 0,
9
+ serviceChargeCountsTowardMinimum: true,
10
+ includesTax: false,
11
+ });
12
+ expect(out.coveredSpendCents).toBe(750_000);
13
+ expect(out.shortfallCents).toBe(250_000);
14
+ expect(out.excessCents).toBe(0);
15
+ expect(out.metExactly).toBe(false);
16
+ });
17
+ it("counts service charge toward minimum when the flag is on", () => {
18
+ const out = computeFBMinimumShortfallCents({
19
+ fbMinimumCents: 1_000_000,
20
+ fbActualSpendCents: 800_000,
21
+ serviceChargeCents: 160_000, // 20% svc
22
+ taxCents: 80_000,
23
+ serviceChargeCountsTowardMinimum: true,
24
+ includesTax: false,
25
+ });
26
+ expect(out.coveredSpendCents).toBe(960_000);
27
+ expect(out.shortfallCents).toBe(40_000);
28
+ });
29
+ it("excludes service charge when the flag is off", () => {
30
+ const out = computeFBMinimumShortfallCents({
31
+ fbMinimumCents: 1_000_000,
32
+ fbActualSpendCents: 800_000,
33
+ serviceChargeCents: 160_000,
34
+ taxCents: 80_000,
35
+ serviceChargeCountsTowardMinimum: false,
36
+ includesTax: false,
37
+ });
38
+ expect(out.coveredSpendCents).toBe(800_000);
39
+ expect(out.shortfallCents).toBe(200_000);
40
+ });
41
+ it("includes tax when the includesTax flag is set", () => {
42
+ const out = computeFBMinimumShortfallCents({
43
+ fbMinimumCents: 1_000_000,
44
+ fbActualSpendCents: 800_000,
45
+ serviceChargeCents: 0,
46
+ taxCents: 120_000,
47
+ serviceChargeCountsTowardMinimum: true,
48
+ includesTax: true,
49
+ });
50
+ expect(out.coveredSpendCents).toBe(920_000);
51
+ expect(out.shortfallCents).toBe(80_000);
52
+ });
53
+ it("returns excess (carryover-eligible) when covered exceeds minimum", () => {
54
+ const out = computeFBMinimumShortfallCents({
55
+ fbMinimumCents: 1_000_000,
56
+ fbActualSpendCents: 1_250_000,
57
+ serviceChargeCents: 0,
58
+ taxCents: 0,
59
+ serviceChargeCountsTowardMinimum: true,
60
+ includesTax: false,
61
+ });
62
+ expect(out.shortfallCents).toBe(0);
63
+ expect(out.excessCents).toBe(250_000);
64
+ });
65
+ it("marks metExactly when covered === minimum", () => {
66
+ const out = computeFBMinimumShortfallCents({
67
+ fbMinimumCents: 1_000_000,
68
+ fbActualSpendCents: 1_000_000,
69
+ serviceChargeCents: 0,
70
+ taxCents: 0,
71
+ serviceChargeCountsTowardMinimum: true,
72
+ includesTax: false,
73
+ });
74
+ expect(out.metExactly).toBe(true);
75
+ expect(out.shortfallCents).toBe(0);
76
+ expect(out.excessCents).toBe(0);
77
+ });
78
+ it("treats negative inputs as zero", () => {
79
+ const out = computeFBMinimumShortfallCents({
80
+ fbMinimumCents: 1_000_000,
81
+ fbActualSpendCents: -50_000,
82
+ serviceChargeCents: -10_000,
83
+ taxCents: -10_000,
84
+ serviceChargeCountsTowardMinimum: true,
85
+ includesTax: true,
86
+ });
87
+ expect(out.coveredSpendCents).toBe(0);
88
+ expect(out.shortfallCents).toBe(1_000_000);
89
+ });
90
+ });
91
+ describe("computeRevenueShareCents", () => {
92
+ it("splits 70/30 cleanly", () => {
93
+ expect(computeRevenueShareCents({ basisCents: 1_000_000, hostPct: 70 })).toEqual({ hostCents: 700_000, venueCents: 300_000 });
94
+ });
95
+ it("clamps host pct to [0, 100]", () => {
96
+ expect(computeRevenueShareCents({ basisCents: 1_000_000, hostPct: 250 })).toEqual({ hostCents: 1_000_000, venueCents: 0 });
97
+ expect(computeRevenueShareCents({ basisCents: 1_000_000, hostPct: -50 })).toEqual({ hostCents: 0, venueCents: 1_000_000 });
98
+ });
99
+ it("returns zero for a zero basis", () => {
100
+ expect(computeRevenueShareCents({ basisCents: 0, hostPct: 70 })).toEqual({ hostCents: 0, venueCents: 0 });
101
+ });
102
+ });
103
+ describe("resolveFBMinimumForDate", () => {
104
+ const TUE = new Date("2026-05-12T20:00:00Z"); // Tuesday
105
+ const SAT = new Date("2026-05-16T22:00:00Z"); // Saturday
106
+ it("picks the day-of-week minimum from the schedule", () => {
107
+ expect(resolveFBMinimumForDate({
108
+ schedule: { Mon: 800_000, Tue: 900_000, Sat: 4_000_000 },
109
+ eventStartDateTime: TUE,
110
+ })).toBe(900_000);
111
+ expect(resolveFBMinimumForDate({
112
+ schedule: { Mon: 800_000, Tue: 900_000, Sat: 4_000_000 },
113
+ eventStartDateTime: SAT,
114
+ })).toBe(4_000_000);
115
+ });
116
+ it("returns null when the schedule has no entry for the day", () => {
117
+ expect(resolveFBMinimumForDate({
118
+ schedule: { Mon: 800_000 },
119
+ eventStartDateTime: TUE,
120
+ })).toBeNull();
121
+ });
122
+ it("returns null when the schedule is missing entirely", () => {
123
+ expect(resolveFBMinimumForDate({
124
+ schedule: null,
125
+ eventStartDateTime: TUE,
126
+ })).toBeNull();
127
+ });
128
+ it("prefers an override window over the schedule when the date matches", () => {
129
+ const out = resolveFBMinimumForDate({
130
+ schedule: { Tue: 900_000 },
131
+ eventStartDateTime: new Date("2026-12-31T20:00:00Z"),
132
+ overrides: [
133
+ {
134
+ startDate: new Date("2026-12-30T00:00:00Z"),
135
+ endDate: new Date("2027-01-01T23:59:59Z"),
136
+ minimumCents: 10_000_000,
137
+ },
138
+ ],
139
+ });
140
+ expect(out).toBe(10_000_000);
141
+ });
142
+ it("ignores overrides whose window does not contain the bash date", () => {
143
+ const out = resolveFBMinimumForDate({
144
+ schedule: { Tue: 900_000 },
145
+ eventStartDateTime: TUE,
146
+ overrides: [
147
+ {
148
+ startDate: new Date("2026-12-30T00:00:00Z"),
149
+ endDate: new Date("2027-01-01T23:59:59Z"),
150
+ minimumCents: 10_000_000,
151
+ },
152
+ ],
153
+ });
154
+ expect(out).toBe(900_000);
155
+ });
156
+ });
157
+ describe("defaultFBCarryoverExpiresAt", () => {
158
+ it("defaults to 365 days from issuance", () => {
159
+ const issued = new Date("2026-01-01T00:00:00Z");
160
+ const expires = defaultFBCarryoverExpiresAt(issued);
161
+ expect(expires.getTime() - issued.getTime()).toBe(DEFAULT_FB_CARRYOVER_EXPIRY_DAYS * 86_400_000);
162
+ });
163
+ it("respects an explicit days override", () => {
164
+ const issued = new Date("2026-01-01T00:00:00Z");
165
+ const expires = defaultFBCarryoverExpiresAt(issued, 30);
166
+ expect(expires.getTime() - issued.getTime()).toBe(30 * 86_400_000);
167
+ });
168
+ });
169
+ describe("cancellation copy", () => {
170
+ it("exposes F&B + revenue-share cancellation snippets for the UI", () => {
171
+ expect(FB_MINIMUM_CANCELLATION_COPY).toMatch(/F&B minimum/);
172
+ expect(REVENUE_SHARE_CANCELLATION_COPY).toMatch(/revenue-share/i);
173
+ });
174
+ });
175
+ //# sourceMappingURL=venueSettlementUtils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"venueSettlementUtils.test.js","sourceRoot":"","sources":["../../../../src/utils/service/__tests__/venueSettlementUtils.test.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gCAAgC,EAChC,+BAA+B,EAC/B,4BAA4B,EAC5B,8BAA8B,EAC9B,wBAAwB,EACxB,2BAA2B,EAC3B,uBAAuB,GACxB,MAAM,4BAA4B,CAAC;AAEpC,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,GAAG,GAAG,8BAA8B,CAAC;YACzC,cAAc,EAAE,SAAS,EAAE,OAAO;YAClC,kBAAkB,EAAE,OAAO,EAAE,kBAAkB;YAC/C,kBAAkB,EAAE,CAAC;YACrB,QAAQ,EAAE,CAAC;YACX,gCAAgC,EAAE,IAAI;YACtC,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,GAAG,GAAG,8BAA8B,CAAC;YACzC,cAAc,EAAE,SAAS;YACzB,kBAAkB,EAAE,OAAO;YAC3B,kBAAkB,EAAE,OAAO,EAAE,UAAU;YACvC,QAAQ,EAAE,MAAM;YAChB,gCAAgC,EAAE,IAAI;YACtC,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,GAAG,GAAG,8BAA8B,CAAC;YACzC,cAAc,EAAE,SAAS;YACzB,kBAAkB,EAAE,OAAO;YAC3B,kBAAkB,EAAE,OAAO;YAC3B,QAAQ,EAAE,MAAM;YAChB,gCAAgC,EAAE,KAAK;YACvC,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,GAAG,GAAG,8BAA8B,CAAC;YACzC,cAAc,EAAE,SAAS;YACzB,kBAAkB,EAAE,OAAO;YAC3B,kBAAkB,EAAE,CAAC;YACrB,QAAQ,EAAE,OAAO;YACjB,gCAAgC,EAAE,IAAI;YACtC,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,MAAM,GAAG,GAAG,8BAA8B,CAAC;YACzC,cAAc,EAAE,SAAS;YACzB,kBAAkB,EAAE,SAAS;YAC7B,kBAAkB,EAAE,CAAC;YACrB,QAAQ,EAAE,CAAC;YACX,gCAAgC,EAAE,IAAI;YACtC,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,GAAG,GAAG,8BAA8B,CAAC;YACzC,cAAc,EAAE,SAAS;YACzB,kBAAkB,EAAE,SAAS;YAC7B,kBAAkB,EAAE,CAAC;YACrB,QAAQ,EAAE,CAAC;YACX,gCAAgC,EAAE,IAAI;YACtC,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,GAAG,GAAG,8BAA8B,CAAC;YACzC,cAAc,EAAE,SAAS;YACzB,kBAAkB,EAAE,CAAC,MAAM;YAC3B,kBAAkB,EAAE,CAAC,MAAM;YAC3B,QAAQ,EAAE,CAAC,MAAM;YACjB,gCAAgC,EAAE,IAAI;YACtC,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,CACJ,wBAAwB,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CACjE,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,CACJ,wBAAwB,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAClE,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;QACnD,MAAM,CACJ,wBAAwB,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,CAClE,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CACJ,wBAAwB,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CACzD,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC,UAAU;IACxD,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC,WAAW;IAEzD,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,CACJ,uBAAuB,CAAC;YACtB,QAAQ,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE;YACxD,kBAAkB,EAAE,GAAG;SACxB,CAAC,CACH,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAChB,MAAM,CACJ,uBAAuB,CAAC;YACtB,QAAQ,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE;YACxD,kBAAkB,EAAE,GAAG;SACxB,CAAC,CACH,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,CACJ,uBAAuB,CAAC;YACtB,QAAQ,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE;YAC1B,kBAAkB,EAAE,GAAG;SACxB,CAAC,CACH,CAAC,QAAQ,EAAE,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CACJ,uBAAuB,CAAC;YACtB,QAAQ,EAAE,IAAI;YACd,kBAAkB,EAAE,GAAG;SACxB,CAAC,CACH,CAAC,QAAQ,EAAE,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,GAAG,GAAG,uBAAuB,CAAC;YAClC,QAAQ,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE;YAC1B,kBAAkB,EAAE,IAAI,IAAI,CAAC,sBAAsB,CAAC;YACpD,SAAS,EAAE;gBACT;oBACE,SAAS,EAAE,IAAI,IAAI,CAAC,sBAAsB,CAAC;oBAC3C,OAAO,EAAE,IAAI,IAAI,CAAC,sBAAsB,CAAC;oBACzC,YAAY,EAAE,UAAU;iBACzB;aACF;SACF,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,GAAG,GAAG,uBAAuB,CAAC;YAClC,QAAQ,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE;YAC1B,kBAAkB,EAAE,GAAG;YACvB,SAAS,EAAE;gBACT;oBACE,SAAS,EAAE,IAAI,IAAI,CAAC,sBAAsB,CAAC;oBAC3C,OAAO,EAAE,IAAI,IAAI,CAAC,sBAAsB,CAAC;oBACzC,YAAY,EAAE,UAAU;iBACzB;aACF;SACF,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,2BAA2B,CAAC,MAAM,CAAC,CAAC;QACpD,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAC/C,gCAAgC,GAAG,UAAU,CAC9C,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,2BAA2B,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACxD,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,UAAU,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,CAAC,4BAA4B,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAC5D,MAAM,CAAC,+BAA+B,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=volunteerCompensationUtils.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"volunteerCompensationUtils.test.d.ts","sourceRoot":"","sources":["../../../../src/utils/service/__tests__/volunteerCompensationUtils.test.ts"],"names":[],"mappings":""}