@mj-biz-apps/orders-core-entities-server 0.0.1 → 5.2.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 (267) hide show
  1. package/LICENSE +183 -0
  2. package/README.md +141 -2
  3. package/dist/AccountingBridge.d.ts +65 -0
  4. package/dist/AccountingBridge.d.ts.map +1 -0
  5. package/dist/AccountingBridge.js +102 -0
  6. package/dist/AccountingBridge.js.map +1 -0
  7. package/dist/AdvanceOrderStateOperation.d.ts +80 -0
  8. package/dist/AdvanceOrderStateOperation.d.ts.map +1 -0
  9. package/dist/AdvanceOrderStateOperation.js +267 -0
  10. package/dist/AdvanceOrderStateOperation.js.map +1 -0
  11. package/dist/ApplyAccountCreditOperation.d.ts +97 -0
  12. package/dist/ApplyAccountCreditOperation.d.ts.map +1 -0
  13. package/dist/ApplyAccountCreditOperation.js +275 -0
  14. package/dist/ApplyAccountCreditOperation.js.map +1 -0
  15. package/dist/BaseDeliveryChannel.d.ts +106 -0
  16. package/dist/BaseDeliveryChannel.d.ts.map +1 -0
  17. package/dist/BaseDeliveryChannel.js +36 -0
  18. package/dist/BaseDeliveryChannel.js.map +1 -0
  19. package/dist/BasePaymentProvider.d.ts +239 -0
  20. package/dist/BasePaymentProvider.d.ts.map +1 -0
  21. package/dist/BasePaymentProvider.js +91 -0
  22. package/dist/BasePaymentProvider.js.map +1 -0
  23. package/dist/BundleBehavior.d.ts +139 -0
  24. package/dist/BundleBehavior.d.ts.map +1 -0
  25. package/dist/BundleBehavior.js +173 -0
  26. package/dist/BundleBehavior.js.map +1 -0
  27. package/dist/BundleEngine.d.ts +60 -0
  28. package/dist/BundleEngine.d.ts.map +1 -0
  29. package/dist/BundleEngine.js +197 -0
  30. package/dist/BundleEngine.js.map +1 -0
  31. package/dist/CancelSubscriptionOperation.d.ts +98 -0
  32. package/dist/CancelSubscriptionOperation.d.ts.map +1 -0
  33. package/dist/CancelSubscriptionOperation.js +317 -0
  34. package/dist/CancelSubscriptionOperation.js.map +1 -0
  35. package/dist/CapturePaymentOperation.d.ts +62 -0
  36. package/dist/CapturePaymentOperation.d.ts.map +1 -0
  37. package/dist/CapturePaymentOperation.js +463 -0
  38. package/dist/CapturePaymentOperation.js.map +1 -0
  39. package/dist/CheckEntitlementOperation.d.ts +27 -0
  40. package/dist/CheckEntitlementOperation.d.ts.map +1 -0
  41. package/dist/CheckEntitlementOperation.js +45 -0
  42. package/dist/CheckEntitlementOperation.js.map +1 -0
  43. package/dist/CheckoutSessionService.d.ts +258 -0
  44. package/dist/CheckoutSessionService.d.ts.map +1 -0
  45. package/dist/CheckoutSessionService.js +1557 -0
  46. package/dist/CheckoutSessionService.js.map +1 -0
  47. package/dist/DeliveryBehavior.d.ts +121 -0
  48. package/dist/DeliveryBehavior.d.ts.map +1 -0
  49. package/dist/DeliveryBehavior.js +145 -0
  50. package/dist/DeliveryBehavior.js.map +1 -0
  51. package/dist/DeliveryRecipientResolver.d.ts +38 -0
  52. package/dist/DeliveryRecipientResolver.d.ts.map +1 -0
  53. package/dist/DeliveryRecipientResolver.js +93 -0
  54. package/dist/DeliveryRecipientResolver.js.map +1 -0
  55. package/dist/DeliveryResolver.d.ts +14 -0
  56. package/dist/DeliveryResolver.d.ts.map +1 -0
  57. package/dist/DeliveryResolver.js +45 -0
  58. package/dist/DeliveryResolver.js.map +1 -0
  59. package/dist/EmailDeliveryChannel.d.ts +31 -0
  60. package/dist/EmailDeliveryChannel.d.ts.map +1 -0
  61. package/dist/EmailDeliveryChannel.js +158 -0
  62. package/dist/EmailDeliveryChannel.js.map +1 -0
  63. package/dist/EntitlementBehavior.d.ts +235 -0
  64. package/dist/EntitlementBehavior.d.ts.map +1 -0
  65. package/dist/EntitlementBehavior.js +330 -0
  66. package/dist/EntitlementBehavior.js.map +1 -0
  67. package/dist/EntitlementEngine.d.ts +97 -0
  68. package/dist/EntitlementEngine.d.ts.map +1 -0
  69. package/dist/EntitlementEngine.js +338 -0
  70. package/dist/EntitlementEngine.js.map +1 -0
  71. package/dist/EntitlementGrantClaimDriver.d.ts +42 -0
  72. package/dist/EntitlementGrantClaimDriver.d.ts.map +1 -0
  73. package/dist/EntitlementGrantClaimDriver.js +158 -0
  74. package/dist/EntitlementGrantClaimDriver.js.map +1 -0
  75. package/dist/EntitlementRead.d.ts +82 -0
  76. package/dist/EntitlementRead.d.ts.map +1 -0
  77. package/dist/EntitlementRead.js +368 -0
  78. package/dist/EntitlementRead.js.map +1 -0
  79. package/dist/FulfillOrderLinesOperation.d.ts +34 -0
  80. package/dist/FulfillOrderLinesOperation.d.ts.map +1 -0
  81. package/dist/FulfillOrderLinesOperation.js +208 -0
  82. package/dist/FulfillOrderLinesOperation.js.map +1 -0
  83. package/dist/FulfillmentBehavior.d.ts +101 -0
  84. package/dist/FulfillmentBehavior.d.ts.map +1 -0
  85. package/dist/FulfillmentBehavior.js +145 -0
  86. package/dist/FulfillmentBehavior.js.map +1 -0
  87. package/dist/GLAccountResolver.d.ts +123 -0
  88. package/dist/GLAccountResolver.d.ts.map +1 -0
  89. package/dist/GLAccountResolver.js +175 -0
  90. package/dist/GLAccountResolver.js.map +1 -0
  91. package/dist/GetFulfillmentQueueOperation.d.ts +35 -0
  92. package/dist/GetFulfillmentQueueOperation.d.ts.map +1 -0
  93. package/dist/GetFulfillmentQueueOperation.js +221 -0
  94. package/dist/GetFulfillmentQueueOperation.js.map +1 -0
  95. package/dist/GetOverdueWorklistOperation.d.ts +41 -0
  96. package/dist/GetOverdueWorklistOperation.d.ts.map +1 -0
  97. package/dist/GetOverdueWorklistOperation.js +210 -0
  98. package/dist/GetOverdueWorklistOperation.js.map +1 -0
  99. package/dist/GiftCardBehavior.d.ts +97 -0
  100. package/dist/GiftCardBehavior.d.ts.map +1 -0
  101. package/dist/GiftCardBehavior.js +121 -0
  102. package/dist/GiftCardBehavior.js.map +1 -0
  103. package/dist/GiftCardEngine.d.ts +59 -0
  104. package/dist/GiftCardEngine.d.ts.map +1 -0
  105. package/dist/GiftCardEngine.js +197 -0
  106. package/dist/GiftCardEngine.js.map +1 -0
  107. package/dist/GuestOrderClaimDriver.d.ts +36 -0
  108. package/dist/GuestOrderClaimDriver.d.ts.map +1 -0
  109. package/dist/GuestOrderClaimDriver.js +161 -0
  110. package/dist/GuestOrderClaimDriver.js.map +1 -0
  111. package/dist/InvoiceBehavior.d.ts +394 -0
  112. package/dist/InvoiceBehavior.d.ts.map +1 -0
  113. package/dist/InvoiceBehavior.js +496 -0
  114. package/dist/InvoiceBehavior.js.map +1 -0
  115. package/dist/InvoiceBuilder.d.ts +48 -0
  116. package/dist/InvoiceBuilder.d.ts.map +1 -0
  117. package/dist/InvoiceBuilder.js +352 -0
  118. package/dist/InvoiceBuilder.js.map +1 -0
  119. package/dist/InvoiceDisplay.d.ts +96 -0
  120. package/dist/InvoiceDisplay.d.ts.map +1 -0
  121. package/dist/InvoiceDisplay.js +121 -0
  122. package/dist/InvoiceDisplay.js.map +1 -0
  123. package/dist/ListEntitlementsOperation.d.ts +21 -0
  124. package/dist/ListEntitlementsOperation.d.ts.map +1 -0
  125. package/dist/ListEntitlementsOperation.js +39 -0
  126. package/dist/ListEntitlementsOperation.js.map +1 -0
  127. package/dist/ManualPaymentProvider.d.ts +19 -0
  128. package/dist/ManualPaymentProvider.d.ts.map +1 -0
  129. package/dist/ManualPaymentProvider.js +92 -0
  130. package/dist/ManualPaymentProvider.js.map +1 -0
  131. package/dist/OrderEntityServer.d.ts +542 -0
  132. package/dist/OrderEntityServer.d.ts.map +1 -0
  133. package/dist/OrderEntityServer.js +2100 -0
  134. package/dist/OrderEntityServer.js.map +1 -0
  135. package/dist/OrderJournalEntryFactory.d.ts +140 -0
  136. package/dist/OrderJournalEntryFactory.d.ts.map +1 -0
  137. package/dist/OrderJournalEntryFactory.js +466 -0
  138. package/dist/OrderJournalEntryFactory.js.map +1 -0
  139. package/dist/OrderLineEntityServer.d.ts +90 -0
  140. package/dist/OrderLineEntityServer.d.ts.map +1 -0
  141. package/dist/OrderLineEntityServer.js +260 -0
  142. package/dist/OrderLineEntityServer.js.map +1 -0
  143. package/dist/OrdersSettings.d.ts +36 -0
  144. package/dist/OrdersSettings.d.ts.map +1 -0
  145. package/dist/OrdersSettings.js +147 -0
  146. package/dist/OrdersSettings.js.map +1 -0
  147. package/dist/PaymentAllocationFactory.d.ts +128 -0
  148. package/dist/PaymentAllocationFactory.d.ts.map +1 -0
  149. package/dist/PaymentAllocationFactory.js +235 -0
  150. package/dist/PaymentAllocationFactory.js.map +1 -0
  151. package/dist/PaymentHeaderEntityServer.d.ts +180 -0
  152. package/dist/PaymentHeaderEntityServer.d.ts.map +1 -0
  153. package/dist/PaymentHeaderEntityServer.js +656 -0
  154. package/dist/PaymentHeaderEntityServer.js.map +1 -0
  155. package/dist/PaymentIntentService.d.ts +101 -0
  156. package/dist/PaymentIntentService.d.ts.map +1 -0
  157. package/dist/PaymentIntentService.js +150 -0
  158. package/dist/PaymentIntentService.js.map +1 -0
  159. package/dist/PaymentJournalEntryFactory.d.ts +99 -0
  160. package/dist/PaymentJournalEntryFactory.d.ts.map +1 -0
  161. package/dist/PaymentJournalEntryFactory.js +127 -0
  162. package/dist/PaymentJournalEntryFactory.js.map +1 -0
  163. package/dist/PaymentLineEntityServer.d.ts +73 -0
  164. package/dist/PaymentLineEntityServer.d.ts.map +1 -0
  165. package/dist/PaymentLineEntityServer.js +303 -0
  166. package/dist/PaymentLineEntityServer.js.map +1 -0
  167. package/dist/PaymentProviderBehavior.d.ts +222 -0
  168. package/dist/PaymentProviderBehavior.d.ts.map +1 -0
  169. package/dist/PaymentProviderBehavior.js +368 -0
  170. package/dist/PaymentProviderBehavior.js.map +1 -0
  171. package/dist/PaymentProviderResolver.d.ts +84 -0
  172. package/dist/PaymentProviderResolver.d.ts.map +1 -0
  173. package/dist/PaymentProviderResolver.js +220 -0
  174. package/dist/PaymentProviderResolver.js.map +1 -0
  175. package/dist/PaymentReversalFactory.d.ts +107 -0
  176. package/dist/PaymentReversalFactory.d.ts.map +1 -0
  177. package/dist/PaymentReversalFactory.js +174 -0
  178. package/dist/PaymentReversalFactory.js.map +1 -0
  179. package/dist/PaymentSettlement.d.ts +56 -0
  180. package/dist/PaymentSettlement.d.ts.map +1 -0
  181. package/dist/PaymentSettlement.js +243 -0
  182. package/dist/PaymentSettlement.js.map +1 -0
  183. package/dist/PaymentTermsBehavior.d.ts +109 -0
  184. package/dist/PaymentTermsBehavior.d.ts.map +1 -0
  185. package/dist/PaymentTermsBehavior.js +172 -0
  186. package/dist/PaymentTermsBehavior.js.map +1 -0
  187. package/dist/PaymentWebhookHandler.d.ts +103 -0
  188. package/dist/PaymentWebhookHandler.d.ts.map +1 -0
  189. package/dist/PaymentWebhookHandler.js +246 -0
  190. package/dist/PaymentWebhookHandler.js.map +1 -0
  191. package/dist/PreviewPriceOperation.d.ts +62 -0
  192. package/dist/PreviewPriceOperation.d.ts.map +1 -0
  193. package/dist/PreviewPriceOperation.js +161 -0
  194. package/dist/PreviewPriceOperation.js.map +1 -0
  195. package/dist/PriceOrderOperation.d.ts +93 -0
  196. package/dist/PriceOrderOperation.d.ts.map +1 -0
  197. package/dist/PriceOrderOperation.js +146 -0
  198. package/dist/PriceOrderOperation.js.map +1 -0
  199. package/dist/ProductPriceEntityServer.d.ts +34 -0
  200. package/dist/ProductPriceEntityServer.d.ts.map +1 -0
  201. package/dist/ProductPriceEntityServer.js +97 -0
  202. package/dist/ProductPriceEntityServer.js.map +1 -0
  203. package/dist/RefundPaymentOperation.d.ts +61 -0
  204. package/dist/RefundPaymentOperation.d.ts.map +1 -0
  205. package/dist/RefundPaymentOperation.js +177 -0
  206. package/dist/RefundPaymentOperation.js.map +1 -0
  207. package/dist/RevenueRecognition.d.ts +76 -0
  208. package/dist/RevenueRecognition.d.ts.map +1 -0
  209. package/dist/RevenueRecognition.js +133 -0
  210. package/dist/RevenueRecognition.js.map +1 -0
  211. package/dist/ReversalBehavior.d.ts +82 -0
  212. package/dist/ReversalBehavior.d.ts.map +1 -0
  213. package/dist/ReversalBehavior.js +100 -0
  214. package/dist/ReversalBehavior.js.map +1 -0
  215. package/dist/ReversalResolver.d.ts +37 -0
  216. package/dist/ReversalResolver.d.ts.map +1 -0
  217. package/dist/ReversalResolver.js +96 -0
  218. package/dist/ReversalResolver.js.map +1 -0
  219. package/dist/SpawnRenewalsOperation.d.ts +109 -0
  220. package/dist/SpawnRenewalsOperation.d.ts.map +1 -0
  221. package/dist/SpawnRenewalsOperation.js +295 -0
  222. package/dist/SpawnRenewalsOperation.js.map +1 -0
  223. package/dist/StoredValuePaymentProvider.d.ts +52 -0
  224. package/dist/StoredValuePaymentProvider.d.ts.map +1 -0
  225. package/dist/StoredValuePaymentProvider.js +205 -0
  226. package/dist/StoredValuePaymentProvider.js.map +1 -0
  227. package/dist/StripeACHPaymentProvider.d.ts +50 -0
  228. package/dist/StripeACHPaymentProvider.d.ts.map +1 -0
  229. package/dist/StripeACHPaymentProvider.js +211 -0
  230. package/dist/StripeACHPaymentProvider.js.map +1 -0
  231. package/dist/StripePaymentProvider.d.ts +83 -0
  232. package/dist/StripePaymentProvider.d.ts.map +1 -0
  233. package/dist/StripePaymentProvider.js +442 -0
  234. package/dist/StripePaymentProvider.js.map +1 -0
  235. package/dist/SubscriptionBehavior.d.ts +197 -0
  236. package/dist/SubscriptionBehavior.d.ts.map +1 -0
  237. package/dist/SubscriptionBehavior.js +415 -0
  238. package/dist/SubscriptionBehavior.js.map +1 -0
  239. package/dist/checkoutCaptureAlert.d.ts +16 -0
  240. package/dist/checkoutCaptureAlert.d.ts.map +1 -0
  241. package/dist/checkoutCaptureAlert.js +55 -0
  242. package/dist/checkoutCaptureAlert.js.map +1 -0
  243. package/dist/checkoutCaptureRetry.d.ts +27 -0
  244. package/dist/checkoutCaptureRetry.d.ts.map +1 -0
  245. package/dist/checkoutCaptureRetry.js +50 -0
  246. package/dist/checkoutCaptureRetry.js.map +1 -0
  247. package/dist/claimDriverHelpers.d.ts +15 -0
  248. package/dist/claimDriverHelpers.d.ts.map +1 -0
  249. package/dist/claimDriverHelpers.js +34 -0
  250. package/dist/claimDriverHelpers.js.map +1 -0
  251. package/dist/entity-names.d.ts +15 -0
  252. package/dist/entity-names.d.ts.map +1 -0
  253. package/dist/entity-names.js +15 -0
  254. package/dist/entity-names.js.map +1 -0
  255. package/dist/identityClaimContracts.d.ts +118 -0
  256. package/dist/identityClaimContracts.d.ts.map +1 -0
  257. package/dist/identityClaimContracts.js +58 -0
  258. package/dist/identityClaimContracts.js.map +1 -0
  259. package/dist/index.d.ts +126 -0
  260. package/dist/index.d.ts.map +1 -0
  261. package/dist/index.js +115 -0
  262. package/dist/index.js.map +1 -0
  263. package/dist/sql-guards.d.ts +78 -0
  264. package/dist/sql-guards.d.ts.map +1 -0
  265. package/dist/sql-guards.js +115 -0
  266. package/dist/sql-guards.js.map +1 -0
  267. package/package.json +50 -5
@@ -0,0 +1,496 @@
1
+ /**
2
+ * @fileoverview Turning an order into the document you send a customer — the decisions, with no
3
+ * database and no HTML anywhere near them.
4
+ *
5
+ * THERE IS NO INVOICE RECORD, AND THAT IS THE POINT. The confirmed order IS the receivable: it is
6
+ * what the ledger booked, what the aging report ages, and what the customer quotes on the phone. An
7
+ * invoice is that order RENDERED. Storing a second row called `Invoice` would create a number that
8
+ * can disagree with the order it came from, and the day it does, nothing in the system can tell you
9
+ * which one is right. So this module derives; it never writes.
10
+ *
11
+ * (Statements are the opposite case and are deliberately NOT built on this: a statement is a
12
+ * point-in-time snapshot of a customer's position, so re-deriving it later gives you a DIFFERENT
13
+ * document with the same date on it. That one needs storage. This one must not have it.)
14
+ *
15
+ * WHY THE SPLIT BY SELLING COMPANY IS THE LOAD-BEARING DECISION HERE. An order's lines can be sold
16
+ * by more than one company — 14 of the 75 orders in the review seed are — and each company carries
17
+ * its own receivable, its own tax registration and its own remit-to address. One document covering
18
+ * two companies would name one of them as the payee for money the other is owed. So an order
19
+ * produces one document PER SELLING COMPANY, and the invariant that matters is that the documents
20
+ * sum back to the order: `Σ documents.Gross === OrderHeader.TotalGross`. Everything below exists to
21
+ * keep that true, which is why unattributable amounts are pushed onto the header company rather
22
+ * than dropped. A dropped charge produces an invoice that is internally consistent, adds up
23
+ * perfectly, and undercharges the customer.
24
+ *
25
+ * THE LADDER MUST TIE. `ListSubtotal − Discounts + Charges + Tax === Gross`, always. The named
26
+ * discount rows are a BREAKDOWN of the line-level discount, not a second source of it — promotions
27
+ * are already baked into `OrderLine.LineTotalNet` by the time an order is confirmed. If the named
28
+ * rows do not account for the whole discount, {@link BuildDocument} emits the difference as an
29
+ * explicit residual row instead of letting the ladder quietly fail to add up.
30
+ *
31
+ * @module @mj-biz-apps/orders-core-entities-server
32
+ */
33
+ import { SplitExactly } from './BundleBehavior.js';
34
+ const Money = (n) => Math.round((Number(n) + Number.EPSILON) * 100) / 100;
35
+ // ── Decisions ────────────────────────────────────────────────────────────────────────────────────
36
+ /**
37
+ * Whether an order can be rendered as a customer-facing document at all, and what it is if so.
38
+ *
39
+ * A VOIDED ORDER IS REFUSED. Not because rendering it is hard, but because the resulting page is a
40
+ * bill for money nobody owes, indistinguishable from a real one once it is a PDF in an inbox. If
41
+ * somebody needs to see a voided order they can look at the order.
42
+ */
43
+ export function CanRender(status) {
44
+ if (status === 'Voided')
45
+ return {
46
+ OK: false,
47
+ Reason: 'This order is voided — there is nothing to bill, and a voided order rendered as an invoice is indistinguishable from a live one.',
48
+ };
49
+ return { OK: true };
50
+ }
51
+ /**
52
+ * What kind of document this order is.
53
+ *
54
+ * A reversal is a credit memo even if its total happens to be zero, and a negative total is a credit
55
+ * memo even when nothing was formally reversed — either way the customer is owed, and calling it an
56
+ * invoice would ask them to pay a negative number.
57
+ */
58
+ export function DeriveDocumentKind(facts) {
59
+ if (facts.ReversesOrderHeaderID || Number(facts.TotalGross) < 0)
60
+ return 'Credit Memo';
61
+ if (facts.Status === 'Draft' || facts.Status === 'Quoted')
62
+ return 'Quote';
63
+ return 'Invoice';
64
+ }
65
+ /** ISO date arithmetic that does not drift across a DST boundary. */
66
+ function dayNumber(iso) {
67
+ const [y, m, d] = String(iso).slice(0, 10).split('-').map(Number);
68
+ return Date.UTC(y, (m ?? 1) - 1, d ?? 1);
69
+ }
70
+ /** Whole days from `from` to `to`; negative when `to` is in the past. */
71
+ export function DaysBetween(from, to) {
72
+ return Math.round((dayNumber(to) - dayNumber(from)) / 86_400_000);
73
+ }
74
+ /**
75
+ * The date payment is due.
76
+ *
77
+ * The header's own `DueDate` wins whenever it is set — it is what the ledger and the aging report
78
+ * use, and a document that computes its own would eventually print a different date than the one
79
+ * the collector is chasing against.
80
+ */
81
+ export function DueDateFor(order) {
82
+ if (order.DueDate)
83
+ return String(order.DueDate).slice(0, 10);
84
+ const days = order.PaymentTermsNetDays;
85
+ if (days == null || !order.OrderDate)
86
+ return null;
87
+ return new Date(dayNumber(order.OrderDate) + days * 86_400_000).toISOString().slice(0, 10);
88
+ }
89
+ /** `Net 30`, or `Due on receipt` when there are no terms — never a blank line on a bill. */
90
+ export function TermsLabel(order) {
91
+ if (order.PaymentTermsName)
92
+ return order.PaymentTermsName;
93
+ if (order.PaymentTermsNetDays != null)
94
+ return `Net ${order.PaymentTermsNetDays}`;
95
+ return 'Due on receipt';
96
+ }
97
+ /**
98
+ * How the payment position reads at a glance.
99
+ *
100
+ * Derived from the two amounts rather than copied from `OrderHeader.PaymentStatus`, because this
101
+ * document may cover ONE company of several and the header's status describes the whole order —
102
+ * printing "Paid" on the unpaid half of a split order is exactly the kind of wrong that never gets
103
+ * reported, it just never gets paid.
104
+ */
105
+ export function PaymentStatusLabel(gross, paid) {
106
+ const due = Money(gross - paid);
107
+ if (gross < 0)
108
+ return 'Credit';
109
+ if (due <= 0 && gross > 0)
110
+ return 'Paid';
111
+ if (paid > 0)
112
+ return 'Partly paid';
113
+ return 'Unpaid';
114
+ }
115
+ /**
116
+ * The document number.
117
+ *
118
+ * A single-company order prints the ORDER number, unchanged: the customer, the ledger, the aging
119
+ * report and the person answering the phone all say the same string. Only when one order has to
120
+ * become several documents does a suffix appear, and then it is stable — companies are ordered by
121
+ * ID, so re-rendering the same order tomorrow produces the same `-A` and `-B`.
122
+ */
123
+ export function DocumentNumber(orderNumber, index, total) {
124
+ if (total <= 1)
125
+ return orderNumber;
126
+ return `${orderNumber}-${String.fromCharCode(65 + index)}`;
127
+ }
128
+ /**
129
+ * Spread an amount over companies, in proportion to what each is owed.
130
+ *
131
+ * Used for money that arrived against the ORDER rather than against a line — an order-level payment
132
+ * allocation has no company to belong to. Largest-remainder via {@link SplitExactly}, so the parts
133
+ * sum to the whole exactly: a pro-rata split that loses a cent leaves a document that can never be
134
+ * marked paid.
135
+ */
136
+ export function SpreadAcrossCompanies(amount, companyGross) {
137
+ const out = new Map();
138
+ if (!companyGross.length)
139
+ return out;
140
+ const parts = SplitExactly(amount, companyGross.map((c) => Math.max(0, c.Gross)));
141
+ companyGross.forEach((c, i) => out.set(c.CompanyID, parts[i]));
142
+ return out;
143
+ }
144
+ /**
145
+ * Attribute a header-level amount to companies via its line allocations.
146
+ *
147
+ * ANY UNALLOCATED REMAINDER GOES TO THE HEADER COMPANY, and the caller is told. The alternative —
148
+ * ignoring it — produces documents that are each internally consistent and together bill less than
149
+ * the order. That is the failure this whole module is arranged to prevent, so it cannot be silent.
150
+ *
151
+ * @param lineCompany Line ID -> selling company. Allocations to unknown lines fall through to the
152
+ * header company too, on the same reasoning.
153
+ */
154
+ export function AttributeByLine(total, allocations, lineCompany, headerCompanyID) {
155
+ const byCompany = new Map();
156
+ let attributed = 0;
157
+ for (const alloc of allocations) {
158
+ const company = (alloc.OrderLineID && lineCompany.get(alloc.OrderLineID)) || null;
159
+ if (!company)
160
+ continue;
161
+ byCompany.set(company, Money((byCompany.get(company) ?? 0) + Number(alloc.Amount)));
162
+ attributed = Money(attributed + Number(alloc.Amount));
163
+ }
164
+ const remainder = Money(Number(total) - attributed);
165
+ if (remainder !== 0) {
166
+ byCompany.set(headerCompanyID, Money((byCompany.get(headerCompanyID) ?? 0) + remainder));
167
+ }
168
+ return { ByCompany: byCompany, Unattributed: remainder };
169
+ }
170
+ /**
171
+ * Build the printed line rows for one company's document, nesting bundle components under the
172
+ * bundle they came from.
173
+ *
174
+ * A ROLLUP PARENT CARRIES NO MONEY OF ITS OWN — the pricing engine zeroes it so the order does not
175
+ * double — so its printed amount is the sum of the children present HERE, and those children print
176
+ * without amounts. A bundle whose components were sold by two companies therefore appears on both
177
+ * documents, each showing only its own share. That looks odd on the page and is the only version
178
+ * that adds up.
179
+ *
180
+ * A child whose parent is not in this document is promoted to the top level rather than dropped,
181
+ * with its own amount intact.
182
+ */
183
+ export function BuildRows(lines) {
184
+ const present = new Set(lines.map((l) => l.ID));
185
+ const childrenOf = new Map();
186
+ const tops = [];
187
+ for (const line of lines) {
188
+ const parent = line.ParentOrderLineID;
189
+ if (parent && present.has(parent)) {
190
+ const bucket = childrenOf.get(parent) ?? [];
191
+ bucket.push(line);
192
+ childrenOf.set(parent, bucket);
193
+ }
194
+ else {
195
+ tops.push(line);
196
+ }
197
+ }
198
+ const toRow = (line, includedInParent) => {
199
+ const kids = (childrenOf.get(line.ID) ?? []).sort((a, b) => a.LineNumber - b.LineNumber);
200
+ const rolled = line.IsRollupParent;
201
+ const childRows = kids.map((k) => toRow(k, rolled));
202
+ const amount = rolled
203
+ ? Money(kids.reduce((s, k) => s + Number(k.LineTotalNet ?? 0), 0))
204
+ : Money(line.LineTotalNet);
205
+ return {
206
+ LineID: line.ID,
207
+ LineNumber: line.LineNumber,
208
+ ProductName: line.ProductName,
209
+ ProductSKU: line.ProductSKU,
210
+ Description: line.Description,
211
+ Quantity: Number(line.Quantity),
212
+ UnitPrice: Money(line.UnitPrice),
213
+ DiscountAmount: LineDiscountOf(line),
214
+ Amount: amount,
215
+ IncludedInParent: includedInParent,
216
+ ServicePeriodStart: line.ServicePeriodStart,
217
+ ServicePeriodEnd: line.ServicePeriodEnd,
218
+ ReversesOrderLineID: line.ReversesOrderLineID,
219
+ Children: childRows,
220
+ };
221
+ };
222
+ return tops.sort((a, b) => a.LineNumber - b.LineNumber).map((l) => toRow(l, false));
223
+ }
224
+ /**
225
+ * What one line lists at, before discount.
226
+ *
227
+ * ROLLUP PARENTS LIST AT NOTHING. The parent of a bundle carries a unit price but is deliberately
228
+ * priced to zero — the components carry the money — so counting `Quantity × UnitPrice` on it as
229
+ * well inflates the subtotal by a whole bundle. The discount line below would then absorb the
230
+ * difference and the ladder would still reach the right total, while showing the customer a
231
+ * fictional list price and a fictional saving.
232
+ */
233
+ export function ListAmountOf(line) {
234
+ if (line.IsRollupParent)
235
+ return 0;
236
+ return Money(Number(line.Quantity) * Number(line.UnitPrice));
237
+ }
238
+ /**
239
+ * What one line was discounted by — DERIVED, not read.
240
+ *
241
+ * `OrderLine.DiscountAmount` IS NOT THE DISCOUNT. A discount can be recorded as an amount or as a
242
+ * percentage, and when it is a percentage the amount column stays zero: in the review seed, 15
243
+ * orders carry a discount and 16 lines have a `LineTotalNet` below list with `DiscountAmount = 0`.
244
+ * Trusting the column prints "Subtotal 600.00 / Total 540.00" with no discount row between them —
245
+ * a bill that is off by sixty dollars and looks completely ordinary.
246
+ *
247
+ * List minus net is the discount by definition, whichever way it was entered, and it carries the
248
+ * right sign on a return line without a special case: a credit of −300 discounted by 10.72 has a
249
+ * net of −289.28, so the derived discount is −10.72 and the ladder walks back UP to it.
250
+ */
251
+ export function LineDiscountOf(line) {
252
+ if (line.IsRollupParent)
253
+ return 0;
254
+ return Money(ListAmountOf(line) - Number(line.LineTotalNet ?? 0));
255
+ }
256
+ /** The list subtotal, before any discount. */
257
+ export function ListSubtotalOf(lines) {
258
+ return Money(lines.reduce((s, l) => s + ListAmountOf(l), 0));
259
+ }
260
+ /** The whole discount on this set of lines. */
261
+ export function DiscountTotalOf(lines) {
262
+ return Money(lines.reduce((s, l) => s + LineDiscountOf(l), 0));
263
+ }
264
+ /** Assemble the totals ladder in print order, with a residual row when the named discounts fall short. */
265
+ export function BuildLadder(input) {
266
+ const rows = [{ Label: 'Subtotal', Note: null, Amount: input.ListSubtotal, Kind: 'Subtotal' }];
267
+ let named = 0;
268
+ for (const d of input.Discounts) {
269
+ if (Money(d.Amount) === 0)
270
+ continue;
271
+ named = Money(named + d.Amount);
272
+ rows.push({ Label: d.Label, Note: d.Note, Amount: -Money(d.Amount), Kind: 'Discount' });
273
+ }
274
+ // The named promotions are a BREAKDOWN of the line-level discount, not a second source of it.
275
+ // When they do not account for all of it — a manual discount typed straight onto a line, an
276
+ // adjustment recorded before this document existed — the difference prints as its own row. The
277
+ // ladder adding up is not negotiable; where the discount came from is a nice-to-have.
278
+ const residual = Money(input.DiscountTotal - named);
279
+ if (residual !== 0) {
280
+ rows.push({ Label: residual > 0 ? 'Discount' : 'Adjustment', Note: null, Amount: -residual, Kind: 'Discount' });
281
+ }
282
+ for (const c of input.Charges) {
283
+ if (Money(c.Amount) === 0 && !c.IsTax)
284
+ continue;
285
+ rows.push({ Label: c.Label, Note: c.Note, Amount: Money(c.Amount), Kind: c.IsTax ? 'Tax' : 'Charge' });
286
+ }
287
+ rows.push({ Label: 'Total', Note: null, Amount: Money(input.Gross), Kind: 'Total' });
288
+ for (const p of input.Payments) {
289
+ if (Money(p.Amount) === 0)
290
+ continue;
291
+ rows.push({ Label: p.Label, Note: null, Amount: -Money(p.Amount), Kind: 'Payment' });
292
+ }
293
+ rows.push({ Label: input.DueLabel, Note: null, Amount: Money(input.AmountDue), Kind: 'Due' });
294
+ return rows;
295
+ }
296
+ /**
297
+ * Everything above, in the right order: an order and its satellites become one document per selling
298
+ * company.
299
+ *
300
+ * @param asOf The date the document is being produced, used only for the days-until-due countdown.
301
+ */
302
+ export function BuildDocuments(input) {
303
+ const { Order: order, Lines: lines, Charges: charges, Adjustments: adjustments, Payments: payments } = input;
304
+ const kind = DeriveDocumentKind(order);
305
+ const dueDate = DueDateFor(order);
306
+ const terms = TermsLabel(order);
307
+ const lineCompany = new Map(lines.map((l) => [l.ID, l.CompanyID]));
308
+ // Companies in ID order, so the -A/-B suffixes are stable across renders. An order with no
309
+ // lines still produces one document — for the header company, showing nothing — because an
310
+ // empty invoice is a visible problem and no invoice at all is not.
311
+ const companyIDs = [...new Set(lines.map((l) => l.CompanyID))].sort();
312
+ if (!companyIDs.length)
313
+ companyIDs.push(order.CompanyID);
314
+ const companyName = (id) => input.CompanyNames?.get(id) ?? lines.find((l) => l.CompanyID === id)?.CompanyName ?? order.CompanyName;
315
+ const grossByCompany = companyIDs.map((id) => ({
316
+ CompanyID: id,
317
+ Gross: Money(lines.filter((l) => l.CompanyID === id).reduce((s, l) => s + Number(l.LineTotalGross ?? 0), 0)),
318
+ }));
319
+ // Charges and adjustments are attributed through their line allocations; payments that landed on
320
+ // the order as a whole are spread pro rata. Both are computed ONCE here rather than per company,
321
+ // so every document sees the same split of the same money.
322
+ const notesByCompany = new Map();
323
+ const note = (companyID, text) => {
324
+ const bucket = notesByCompany.get(companyID) ?? [];
325
+ bucket.push(text);
326
+ notesByCompany.set(companyID, bucket);
327
+ };
328
+ const chargeSplit = charges.map((c) => {
329
+ const { ByCompany, Unattributed } = AttributeByLine(c.Amount, c.Allocations, lineCompany, order.CompanyID);
330
+ if (Unattributed !== 0 && companyIDs.length > 1) {
331
+ note(order.CompanyID, `${c.Name} of ${Unattributed.toFixed(2)} was not allocated to any line and is billed by ${companyName(order.CompanyID)}.`);
332
+ }
333
+ return { Charge: c, ByCompany };
334
+ });
335
+ const adjustmentSplit = adjustments.map((a) => {
336
+ const allocations = a.Allocations.length
337
+ ? a.Allocations
338
+ : a.OrderLineID
339
+ ? [{ OrderLineID: a.OrderLineID, Amount: a.Amount }]
340
+ : [];
341
+ const { ByCompany } = AttributeByLine(a.Amount, allocations, lineCompany, order.CompanyID);
342
+ return { Adjustment: a, ByCompany };
343
+ });
344
+ const paymentSplit = payments.map((p) => {
345
+ const lineLevel = p.Allocations.filter((al) => al.OrderLineID);
346
+ const orderLevel = Money(p.Amount - lineLevel.reduce((s, al) => s + Number(al.Amount), 0));
347
+ const { ByCompany } = AttributeByLine(Money(p.Amount - orderLevel), lineLevel, lineCompany, order.CompanyID);
348
+ if (orderLevel !== 0) {
349
+ for (const [id, share] of SpreadAcrossCompanies(orderLevel, grossByCompany)) {
350
+ if (share === 0)
351
+ continue;
352
+ ByCompany.set(id, Money((ByCompany.get(id) ?? 0) + share));
353
+ }
354
+ }
355
+ return { Payment: p, ByCompany };
356
+ });
357
+ const documents = [];
358
+ companyIDs.forEach((companyID, index) => {
359
+ const myLines = lines.filter((l) => l.CompanyID === companyID);
360
+ const listSubtotal = ListSubtotalOf(myLines);
361
+ const discountTotal = DiscountTotalOf(myLines);
362
+ const netTotal = Money(myLines.reduce((s, l) => s + Number(l.LineTotalNet ?? 0), 0));
363
+ // A zero FEE is noise and drops out. A zero TAX row is kept ONLY when this document has no
364
+ // tax to show otherwise: "Sales tax 0.00" tells a customer their exemption was applied, or
365
+ // that this seller has no nexus where the goods went, which is a different statement from a
366
+ // bill that never mentions tax at all.
367
+ //
368
+ // It is dropped once a real tax row exists, because on a split order every jurisdiction's
369
+ // charge appears on BOTH documents and only one of them carries the money — printing the
370
+ // zeroes gives the customer four tax lines, two of them empty, that read as a mistake.
371
+ const attributed = chargeSplit.map(({ Charge, ByCompany }) => ({
372
+ Charge,
373
+ Amount: Money(ByCompany.get(companyID) ?? 0),
374
+ }));
375
+ const hasRealTax = attributed.some((c) => c.Charge.Category === 'Tax' && c.Amount !== 0);
376
+ // And at most ONE of them: an order taxed in three jurisdictions by the other company would
377
+ // otherwise put three empty tax lines on this one.
378
+ const zeroTaxPlaceholder = hasRealTax ? null : attributed.find((c) => c.Charge.Category === 'Tax' && c.Amount === 0);
379
+ const myCharges = attributed
380
+ .filter((entry) => entry.Amount !== 0 || entry === zeroTaxPlaceholder)
381
+ .sort((a, b) => a.Charge.Sequence - b.Charge.Sequence);
382
+ const chargeTotal = Money(myCharges.filter((c) => c.Charge.Category !== 'Tax').reduce((s, c) => s + c.Amount, 0));
383
+ const taxFromCharges = Money(myCharges.filter((c) => c.Charge.Category === 'Tax').reduce((s, c) => s + c.Amount, 0));
384
+ // The lines are the authority for tax — `LineTax` is what the ledger booked. Charge rows of
385
+ // category Tax are how it is BROKEN OUT by jurisdiction; when the two disagree the lines win
386
+ // and the difference prints as an unlabelled tax row rather than silently going missing.
387
+ const taxTotal = Money(myLines.reduce((s, l) => s + Number(l.LineTax ?? 0), 0));
388
+ const gross = Money(myLines.reduce((s, l) => s + Number(l.LineTotalGross ?? 0), 0));
389
+ const myAdjustments = adjustmentSplit
390
+ .map(({ Adjustment, ByCompany }) => ({ Adjustment, Amount: Money(ByCompany.get(companyID) ?? 0) }))
391
+ .filter(({ Amount }) => Amount !== 0);
392
+ const myPayments = paymentSplit
393
+ .map(({ Payment, ByCompany }) => ({ Payment, Amount: Money(ByCompany.get(companyID) ?? 0) }))
394
+ .filter(({ Amount }) => Amount !== 0);
395
+ const amountPaid = Money(myPayments.reduce((s, p) => s + p.Amount, 0));
396
+ const amountDue = Money(gross - amountPaid);
397
+ const ladderCharges = myCharges
398
+ .filter((c) => c.Charge.Category !== 'Tax')
399
+ .map((c) => ({ Label: c.Charge.Name, Note: null, Amount: c.Amount, IsTax: false }));
400
+ const taxRows = myCharges
401
+ .filter((c) => c.Charge.Category === 'Tax')
402
+ .map((c) => ({
403
+ Label: c.Charge.Name,
404
+ Note: c.Charge.Rate != null ? `${(Number(c.Charge.Rate) * 100).toFixed(3).replace(/0+$/, '').replace(/\.$/, '')}%` : null,
405
+ Amount: c.Amount,
406
+ IsTax: true,
407
+ }));
408
+ const taxResidual = Money(taxTotal - taxFromCharges);
409
+ if (taxResidual !== 0) {
410
+ taxRows.push({ Label: 'Sales tax', Note: null, Amount: taxResidual, IsTax: true });
411
+ if (taxFromCharges !== 0) {
412
+ note(companyID, `Tax rows total ${taxFromCharges.toFixed(2)} but the lines carry ${taxTotal.toFixed(2)}; the difference is shown unattributed.`);
413
+ }
414
+ }
415
+ const ladder = BuildLadder({
416
+ ListSubtotal: listSubtotal,
417
+ Discounts: myAdjustments.map(({ Adjustment, Amount }) => {
418
+ const label = Adjustment.PromotionName ?? Adjustment.Reason ?? 'Discount';
419
+ return {
420
+ Label: label,
421
+ // The code is shown BESIDE the promotion's name, not repeated after it. Many
422
+ // promotions are named after their code, and "SPRING10 (SPRING10)" reads as a
423
+ // rendering fault rather than as the reference it is meant to be.
424
+ Note: Adjustment.PromotionCode && Adjustment.PromotionCode !== label ? Adjustment.PromotionCode : null,
425
+ Amount,
426
+ };
427
+ }),
428
+ DiscountTotal: discountTotal,
429
+ Charges: [...ladderCharges, ...taxRows],
430
+ Gross: gross,
431
+ Payments: myPayments.map(({ Payment, Amount }) => ({
432
+ Label: `Payment ${Payment.PaymentNumber}`,
433
+ Amount,
434
+ })),
435
+ AmountDue: amountDue,
436
+ DueLabel: kind === 'Credit Memo' ? 'Credit due you' : 'Amount due',
437
+ });
438
+ // The one invariant worth stating on the document itself: the ladder must reach the total.
439
+ const laddered = Money(listSubtotal -
440
+ discountTotal +
441
+ chargeTotal +
442
+ taxTotal);
443
+ if (laddered !== gross) {
444
+ note(companyID, `Ladder reaches ${laddered.toFixed(2)} but the lines total ${gross.toFixed(2)} — this document does not add up.`);
445
+ }
446
+ documents.push({
447
+ Kind: kind,
448
+ DocumentNumber: DocumentNumber(order.OrderNumber, index, companyIDs.length),
449
+ OrderNumber: order.OrderNumber,
450
+ OrderHeaderID: order.ID,
451
+ OrderDate: String(order.OrderDate).slice(0, 10),
452
+ DueDate: dueDate,
453
+ DaysUntilDue: dueDate && amountDue > 0 ? DaysBetween(input.AsOf, dueDate) : null,
454
+ Status: order.Status,
455
+ PaymentStatusLabel: PaymentStatusLabel(gross, amountPaid),
456
+ CompanyID: companyID,
457
+ CompanyName: companyName(companyID),
458
+ Issuer: input.Issuers?.get(companyID) ?? {
459
+ CompanyID: companyID,
460
+ Name: companyName(companyID),
461
+ AddressLines: [],
462
+ Email: null,
463
+ Phone: null,
464
+ Website: null,
465
+ TaxID: null,
466
+ CurrencyCode: null,
467
+ },
468
+ BillTo: input.BillTo,
469
+ ShipTo: input.ShipTo,
470
+ TermsLabel: terms,
471
+ ExternalDocumentNumber: order.ExternalDocumentNumber,
472
+ ReversesOrderNumber: order.ReversesOrderNumber,
473
+ ReversalReason: order.ReversalReason,
474
+ Description: order.Description,
475
+ Rows: BuildRows(myLines),
476
+ Ladder: ladder,
477
+ ListSubtotal: listSubtotal,
478
+ DiscountTotal: discountTotal,
479
+ NetTotal: netTotal,
480
+ ChargeTotal: chargeTotal,
481
+ TaxTotal: taxTotal,
482
+ Gross: gross,
483
+ AmountPaid: amountPaid,
484
+ AmountDue: amountDue,
485
+ Payments: myPayments.map(({ Payment, Amount }) => ({
486
+ PaymentNumber: Payment.PaymentNumber,
487
+ PaymentDate: String(Payment.PaymentDate).slice(0, 10),
488
+ TypeName: Payment.PaymentTypeName,
489
+ Amount,
490
+ })),
491
+ Notes: notesByCompany.get(companyID) ?? [],
492
+ });
493
+ });
494
+ return input.OnlyCompanyID ? documents.filter((d) => d.CompanyID === input.OnlyCompanyID) : documents;
495
+ }
496
+ //# sourceMappingURL=InvoiceBehavior.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InvoiceBehavior.js","sourceRoot":"","sources":["../src/InvoiceBehavior.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @fileoverview Reading an order and everything that hangs off it, so {@link BuildDocuments} can
3
+ * turn it into something you send a customer.
4
+ *
5
+ * THE SPLIT IS DELIBERATE. Every decision lives in `InvoiceBehavior` where it can be exercised with
6
+ * a literal; this file only fetches. That is why the module has no arithmetic beyond the joins it
7
+ * needs to shape the rows, and why the discount is derived over there rather than read here.
8
+ *
9
+ * IT READS AND NOTHING ELSE. There is no invoice record to write, and there must not be one — see
10
+ * the header of `InvoiceBehavior`. A caller can render the same order a hundred times and the
11
+ * hundred documents will be identical, because the order is the only state involved.
12
+ *
13
+ * THE FETCH IS FLAT, NOT PER-LINE. Charges, allocations, adjustments and payments each come back in
14
+ * ONE view call for the whole order and are indexed in memory. A twenty-line order should not cost
15
+ * eighty round trips, and the shape that produces eighty round trips is the shape that looks
16
+ * perfectly readable.
17
+ *
18
+ * @module @mj-biz-apps/orders-core-entities-server
19
+ */
20
+ import { type IMetadataProvider, type UserInfo } from '@memberjunction/core';
21
+ import { type InvoiceDocument } from './InvoiceBehavior.js';
22
+ import { ToISODate } from '@mj-biz-apps/orders-entities';
23
+ /** What a render attempt produced, or why it produced nothing. */
24
+ export interface InvoiceBuildResult {
25
+ Success: boolean;
26
+ Message?: string;
27
+ Documents: InvoiceDocument[];
28
+ }
29
+ /**
30
+ * Re-exported so this file's existing importers keep resolving it here.
31
+ *
32
+ * The implementation moved to `@mj-biz-apps/orders-entities` — it was correct in this file and
33
+ * unreachable from Angular, which is why fifteen other sites went on hand-rolling
34
+ * `String(cell).slice(0, 10)` and getting `'Thu Jul 30'`.
35
+ */
36
+ export { ToISODate };
37
+ /**
38
+ * Read one order and produce its documents — one per selling company.
39
+ *
40
+ * @param orderHeaderID The order to render.
41
+ * @param options `AsOf` drives only the days-until-due countdown; `OnlyCompanyID` narrows a split
42
+ * order to a single document without changing how the others are numbered.
43
+ */
44
+ export declare function BuildInvoiceDocuments(orderHeaderID: string, provider: IMetadataProvider, user: UserInfo, options?: {
45
+ AsOf?: string | null;
46
+ OnlyCompanyID?: string | null;
47
+ }): Promise<InvoiceBuildResult>;
48
+ //# sourceMappingURL=InvoiceBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InvoiceBuilder.d.ts","sourceRoot":"","sources":["../src/InvoiceBuilder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAW,KAAK,iBAAiB,EAAE,KAAK,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEtF,OAAO,EAKH,KAAK,eAAe,EAKvB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAkC,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAqBzF,kEAAkE;AAClE,MAAM,WAAW,kBAAkB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,eAAe,EAAE,CAAC;CAChC;AA2BD;;;;;;GAMG;AACH,OAAO,EAAE,SAAS,EAAE,CAAC;AAkBrB;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACvC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,QAAQ,EACd,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAClE,OAAO,CAAC,kBAAkB,CAAC,CAmS7B"}