@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 @@
1
+ {"version":3,"file":"FulfillOrderLinesOperation.js","sourceRoot":"","sources":["../src/FulfillOrderLinesOperation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Fulfilment decisions, with no database in sight.
3
+ *
4
+ * WHAT FULFILMENT IS HERE, AND WHAT IT IS NOT (D15). It is a LOGISTICS fact: the thing left the
5
+ * building. It is emphatically not an accounting event — no journal entry fires on
6
+ * Posted → Fulfilled. Revenue was settled at booking and released on its own schedule; whether the
7
+ * box has shipped changes none of it.
8
+ *
9
+ * That disconnection is deliberate and worth restating, because "revenue on delivery" is the
10
+ * intuition everyone brings. Coupling them would make a warehouse delay silently restate a closed
11
+ * period.
12
+ *
13
+ * THE PART THAT NEEDS CARE. An order auto-advances to Fulfilled when NO line requires fulfilment —
14
+ * a subscription, a download, a donation. If even one line does, the order waits for a person. The
15
+ * hazard is the middle case: an order where some lines are fulfillable and some are not. Counting
16
+ * "all lines fulfilled" would hold such an order open forever, because the non-fulfillable lines
17
+ * never flip. Only the lines that CAN be fulfilled are allowed to hold it.
18
+ *
19
+ * CONNECTS TO:
20
+ * CODE: FulfillmentEngine · FulfillOrderLinesOperation · GetFulfillmentQueueOperation
21
+ * DOC: plans/archive/bizapps-orders-master.md D15
22
+ */
23
+ /** The per-line fulfilment states (schema: CK_OrderLine_FulfillmentStatus). */
24
+ export type FulfillmentStatus = 'Pending' | 'Fulfilled' | 'Returned';
25
+ /** What a line has to say for itself. */
26
+ export interface FulfillableLine {
27
+ ID: string;
28
+ /** From the line's product TYPE. False for a subscription, a download, a donation. */
29
+ RequiresFulfillment: boolean;
30
+ /** Null when the type does not require fulfilment — the column is only meaningful when it does. */
31
+ FulfillmentStatus: FulfillmentStatus | null;
32
+ /** A reversal line is a return, not something to ship. */
33
+ ReversesOrderLineID: string | null;
34
+ /** A rollup parent is a display row; its children are the real goods (D45). */
35
+ IsRollupParent: boolean;
36
+ }
37
+ /**
38
+ * Does this line hold the order open?
39
+ *
40
+ * Four exclusions, each for its own reason:
41
+ * · the product type does not require fulfilment — nothing to ship;
42
+ * · it is a REVERSAL — goods coming back, tracked by the origin line's status, not this one;
43
+ * · it is a ROLLUP PARENT — a bundle's display row, whose children carry the actual goods;
44
+ * · it is already Fulfilled or Returned.
45
+ */
46
+ export declare function IsAwaitingFulfillment(line: FulfillableLine): boolean;
47
+ /** Every line still holding the order open. */
48
+ export declare function AwaitingFulfillment(lines: FulfillableLine[]): FulfillableLine[];
49
+ /**
50
+ * Should the order advance to Fulfilled?
51
+ *
52
+ * TRUE when nothing is awaiting fulfilment — which covers both the auto-advance case (no line ever
53
+ * required it) and the ordinary case (the last fulfillable line was just flipped).
54
+ *
55
+ * Deliberately NOT "every line is Fulfilled". On a mixed order the subscription line never flips,
56
+ * so that test would hold it open forever while the warehouse insists it shipped everything.
57
+ */
58
+ export declare function ShouldAdvanceToFulfilled(lines: FulfillableLine[]): boolean;
59
+ /**
60
+ * Would this order auto-advance without anyone touching it (D15)?
61
+ *
62
+ * Distinct from `ShouldAdvanceToFulfilled` in INTENT rather than result: this asks whether the order
63
+ * needs a fulfiller AT ALL, which is what decides whether it appears in the queue. An order that
64
+ * auto-advances should never show up there, and an order that has simply been fully worked should.
65
+ */
66
+ export declare function AutoAdvances(lines: FulfillableLine[]): boolean;
67
+ export type FlipRefusal = 'LineNotFound' | 'DoesNotRequireFulfillment' | 'AlreadyFulfilled' | 'IsReversal' | 'IsRollupParent' | 'OrderNotPosted';
68
+ /**
69
+ * May this line be flipped to Fulfilled right now?
70
+ *
71
+ * Returns null when it may, or the reason when it may not. A refusal is a normal outcome — a
72
+ * fulfiller double-clicking a already-shipped line should be told so, not have it counted twice.
73
+ */
74
+ export declare function RefuseFlip(line: FulfillableLine | null, orderStatus: string): FlipRefusal | null;
75
+ /** Human wording for a refusal, so the caller does not have to invent one. */
76
+ export declare function ExplainRefusal(reason: FlipRefusal, lineID: string): string;
77
+ /** One order's position in the fulfilment queue. */
78
+ export interface QueueGrouping {
79
+ OrderHeaderID: string;
80
+ AwaitingLineIDs: string[];
81
+ /** Every fulfillable line, whether or not still pending — the denominator for "3 of 5". */
82
+ FulfillableCount: number;
83
+ }
84
+ /**
85
+ * Group pending lines by order, in the shape a queue screen wants.
86
+ *
87
+ * Orders with nothing awaiting are omitted rather than listed as complete: a queue is work to do,
88
+ * and a screen full of finished orders is how a real backlog gets missed.
89
+ */
90
+ export declare function GroupForQueue(lines: Array<FulfillableLine & {
91
+ OrderHeaderID: string;
92
+ }>): QueueGrouping[];
93
+ /**
94
+ * The initial `FulfillmentStatus` a line should be created with.
95
+ *
96
+ * NULL — not 'Pending' — when the type requires no fulfilment. The column's own documentation says
97
+ * null means "does not apply", and writing 'Pending' on a subscription would put it in the queue
98
+ * forever waiting for a shipment that does not exist.
99
+ */
100
+ export declare function InitialFulfillmentStatus(requiresFulfillment: boolean): FulfillmentStatus | null;
101
+ //# sourceMappingURL=FulfillmentBehavior.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FulfillmentBehavior.d.ts","sourceRoot":"","sources":["../src/FulfillmentBehavior.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,+EAA+E;AAC/E,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC;AAErE,yCAAyC;AACzC,MAAM,WAAW,eAAe;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,sFAAsF;IACtF,mBAAmB,EAAE,OAAO,CAAC;IAC7B,mGAAmG;IACnG,iBAAiB,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC5C,0DAA0D;IAC1D,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,+EAA+E;IAC/E,cAAc,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAKpE;AAED,+CAA+C;AAC/C,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,eAAe,EAAE,CAE/E;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,OAAO,CAE1E;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,OAAO,CAE9D;AAED,MAAM,MAAM,WAAW,GACjB,cAAc,GACd,2BAA2B,GAC3B,kBAAkB,GAClB,YAAY,GACZ,gBAAgB,GAChB,gBAAgB,CAAC;AAKvB;;;;;GAKG;AACH,wBAAgB,UAAU,CACtB,IAAI,EAAE,eAAe,GAAG,IAAI,EAC5B,WAAW,EAAE,MAAM,GACpB,WAAW,GAAG,IAAI,CASpB;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CA2B1E;AAED,oDAAoD;AACpD,MAAM,WAAW,aAAa;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,2FAA2F;IAC3F,gBAAgB,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CACzB,KAAK,EAAE,KAAK,CAAC,eAAe,GAAG;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,GAC1D,aAAa,EAAE,CAiBjB;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,mBAAmB,EAAE,OAAO,GAAG,iBAAiB,GAAG,IAAI,CAE/F"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Fulfilment decisions, with no database in sight.
3
+ *
4
+ * WHAT FULFILMENT IS HERE, AND WHAT IT IS NOT (D15). It is a LOGISTICS fact: the thing left the
5
+ * building. It is emphatically not an accounting event — no journal entry fires on
6
+ * Posted → Fulfilled. Revenue was settled at booking and released on its own schedule; whether the
7
+ * box has shipped changes none of it.
8
+ *
9
+ * That disconnection is deliberate and worth restating, because "revenue on delivery" is the
10
+ * intuition everyone brings. Coupling them would make a warehouse delay silently restate a closed
11
+ * period.
12
+ *
13
+ * THE PART THAT NEEDS CARE. An order auto-advances to Fulfilled when NO line requires fulfilment —
14
+ * a subscription, a download, a donation. If even one line does, the order waits for a person. The
15
+ * hazard is the middle case: an order where some lines are fulfillable and some are not. Counting
16
+ * "all lines fulfilled" would hold such an order open forever, because the non-fulfillable lines
17
+ * never flip. Only the lines that CAN be fulfilled are allowed to hold it.
18
+ *
19
+ * CONNECTS TO:
20
+ * CODE: FulfillmentEngine · FulfillOrderLinesOperation · GetFulfillmentQueueOperation
21
+ * DOC: plans/archive/bizapps-orders-master.md D15
22
+ */
23
+ /**
24
+ * Does this line hold the order open?
25
+ *
26
+ * Four exclusions, each for its own reason:
27
+ * · the product type does not require fulfilment — nothing to ship;
28
+ * · it is a REVERSAL — goods coming back, tracked by the origin line's status, not this one;
29
+ * · it is a ROLLUP PARENT — a bundle's display row, whose children carry the actual goods;
30
+ * · it is already Fulfilled or Returned.
31
+ */
32
+ export function IsAwaitingFulfillment(line) {
33
+ if (!line.RequiresFulfillment)
34
+ return false;
35
+ if (line.ReversesOrderLineID)
36
+ return false;
37
+ if (line.IsRollupParent)
38
+ return false;
39
+ return (line.FulfillmentStatus ?? 'Pending') === 'Pending';
40
+ }
41
+ /** Every line still holding the order open. */
42
+ export function AwaitingFulfillment(lines) {
43
+ return lines.filter(IsAwaitingFulfillment);
44
+ }
45
+ /**
46
+ * Should the order advance to Fulfilled?
47
+ *
48
+ * TRUE when nothing is awaiting fulfilment — which covers both the auto-advance case (no line ever
49
+ * required it) and the ordinary case (the last fulfillable line was just flipped).
50
+ *
51
+ * Deliberately NOT "every line is Fulfilled". On a mixed order the subscription line never flips,
52
+ * so that test would hold it open forever while the warehouse insists it shipped everything.
53
+ */
54
+ export function ShouldAdvanceToFulfilled(lines) {
55
+ return AwaitingFulfillment(lines).length === 0;
56
+ }
57
+ /**
58
+ * Would this order auto-advance without anyone touching it (D15)?
59
+ *
60
+ * Distinct from `ShouldAdvanceToFulfilled` in INTENT rather than result: this asks whether the order
61
+ * needs a fulfiller AT ALL, which is what decides whether it appears in the queue. An order that
62
+ * auto-advances should never show up there, and an order that has simply been fully worked should.
63
+ */
64
+ export function AutoAdvances(lines) {
65
+ return !lines.some((l) => l.RequiresFulfillment && !l.ReversesOrderLineID && !l.IsRollupParent);
66
+ }
67
+ /** The statuses from which a line may be flipped to Fulfilled. */
68
+ const ORDER_STATES_ALLOWING_FULFILLMENT = new Set(['Confirmed']);
69
+ /**
70
+ * May this line be flipped to Fulfilled right now?
71
+ *
72
+ * Returns null when it may, or the reason when it may not. A refusal is a normal outcome — a
73
+ * fulfiller double-clicking a already-shipped line should be told so, not have it counted twice.
74
+ */
75
+ export function RefuseFlip(line, orderStatus) {
76
+ if (!line)
77
+ return 'LineNotFound';
78
+ // Before Confirmed nothing is owed, so nothing can ship. Voided orders are out entirely.
79
+ if (!ORDER_STATES_ALLOWING_FULFILLMENT.has(orderStatus))
80
+ return 'OrderNotPosted';
81
+ if (line.IsRollupParent)
82
+ return 'IsRollupParent';
83
+ if (line.ReversesOrderLineID)
84
+ return 'IsReversal';
85
+ if (!line.RequiresFulfillment)
86
+ return 'DoesNotRequireFulfillment';
87
+ if ((line.FulfillmentStatus ?? 'Pending') !== 'Pending')
88
+ return 'AlreadyFulfilled';
89
+ return null;
90
+ }
91
+ /** Human wording for a refusal, so the caller does not have to invent one. */
92
+ export function ExplainRefusal(reason, lineID) {
93
+ switch (reason) {
94
+ case 'LineNotFound':
95
+ return `Order line ${lineID} does not exist.`;
96
+ case 'OrderNotPosted':
97
+ return (`Order line ${lineID} cannot be fulfilled because its order is not Confirmed. ` +
98
+ `Nothing is owed until an order is confirmed, so nothing can ship.`);
99
+ case 'DoesNotRequireFulfillment':
100
+ return (`Order line ${lineID} is for a product type that requires no fulfilment — a subscription, ` +
101
+ `a download, a donation. There is nothing to ship, so there is nothing to mark.`);
102
+ case 'IsReversal':
103
+ return (`Order line ${lineID} is a reversal. Goods coming BACK are tracked on the line they ` +
104
+ `reverse, not by fulfilling the credit.`);
105
+ case 'IsRollupParent':
106
+ return (`Order line ${lineID} is a bundle's parent row, which carries no goods of its own. ` +
107
+ `Fulfil its component lines instead.`);
108
+ case 'AlreadyFulfilled':
109
+ return `Order line ${lineID} has already been fulfilled or returned.`;
110
+ }
111
+ }
112
+ /**
113
+ * Group pending lines by order, in the shape a queue screen wants.
114
+ *
115
+ * Orders with nothing awaiting are omitted rather than listed as complete: a queue is work to do,
116
+ * and a screen full of finished orders is how a real backlog gets missed.
117
+ */
118
+ export function GroupForQueue(lines) {
119
+ const byOrder = new Map();
120
+ for (const line of lines) {
121
+ const fulfillable = line.RequiresFulfillment && !line.ReversesOrderLineID && !line.IsRollupParent;
122
+ if (!fulfillable)
123
+ continue;
124
+ let group = byOrder.get(line.OrderHeaderID);
125
+ if (!group) {
126
+ group = { OrderHeaderID: line.OrderHeaderID, AwaitingLineIDs: [], FulfillableCount: 0 };
127
+ byOrder.set(line.OrderHeaderID, group);
128
+ }
129
+ group.FulfillableCount++;
130
+ if (IsAwaitingFulfillment(line))
131
+ group.AwaitingLineIDs.push(line.ID);
132
+ }
133
+ return [...byOrder.values()].filter((g) => g.AwaitingLineIDs.length > 0);
134
+ }
135
+ /**
136
+ * The initial `FulfillmentStatus` a line should be created with.
137
+ *
138
+ * NULL — not 'Pending' — when the type requires no fulfilment. The column's own documentation says
139
+ * null means "does not apply", and writing 'Pending' on a subscription would put it in the queue
140
+ * forever waiting for a shipment that does not exist.
141
+ */
142
+ export function InitialFulfillmentStatus(requiresFulfillment) {
143
+ return requiresFulfillment ? 'Pending' : null;
144
+ }
145
+ //# sourceMappingURL=FulfillmentBehavior.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FulfillmentBehavior.js","sourceRoot":"","sources":["../src/FulfillmentBehavior.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * GLAccountResolver — turns a (product, role) pair into a concrete GL account UUID.
3
+ *
4
+ * Accounting's `CreateJournalEntries` contract takes `GLAccountID`, never a role name, so the
5
+ * role→account walk is the CALLER's job (plan D5). Accounting supplies only the per-record link
6
+ * primitive — `AccountingEngineBase.ResolveLinkedAccount(entityId, recordId, role, asOfDate)` —
7
+ * and this class implements the precedence over it:
8
+ *
9
+ * Product → its ProductCategory → that category's ancestors
10
+ * → its ProductType → the line's Company
11
+ *
12
+ * Company is the last resort (the accounting-org default). Product Type sits above
13
+ * the company default so a type can name Sales once and every product of that type
14
+ * inherits it, while a category or product can still override.
15
+ *
16
+ * Most specific wins; the first link found at any level ends the walk. Nothing resolves → we
17
+ * FAIL LOUDLY (plan D5: "fail loudly" — never silently book to a default account).
18
+ *
19
+ * COMPANY INVARIANT (plan D6): the resolved account MUST belong to the order line's company.
20
+ * Accounting derives a JE's company from `GLAccount.CompanyID` and takes no CompanyID in its
21
+ * contract (their CH-2), so a mis-resolved account would silently book revenue to the wrong
22
+ * legal entity with nothing downstream to catch it. This class is therefore the ONLY place that
23
+ * invariant can be enforced, and it hard-blocks — cross-company mapping is refused entirely.
24
+ *
25
+ * CONNECTS TO:
26
+ * PRIMITIVE: AccountingEngineBase.ResolveLinkedAccount (@mj-biz-apps/accounting-engine-base)
27
+ * CALLER: OrderJournalEntryFactory (./OrderJournalEntryFactory.ts)
28
+ */
29
+ import { IMetadataProvider, UserInfo } from '@memberjunction/core';
30
+ /** GL account roles this app books against (seeded by accounting's metadata). */
31
+ export declare const GL_ROLE: {
32
+ readonly AccountsReceivable: "Accounts Receivable";
33
+ readonly Sales: "Sales";
34
+ readonly SalesDiscounts: "Sales Discounts";
35
+ readonly DeferredRevenue: "Deferred Revenue";
36
+ readonly SalesReturnsAndAllowances: "Sales Returns and Allowances";
37
+ /** Where captured cash lands. Company-level only — a payment has no product to walk from. */
38
+ readonly Cash: "Cash";
39
+ /**
40
+ * The provider's cut on a capture (D18). NOT seeded by accounting's starter roles, so callers
41
+ * must tolerate it failing to resolve — see PaymentJournalEntryFactory, which books the gross
42
+ * to Cash and reports the shortfall rather than silently misstating the bank line.
43
+ */
44
+ readonly ProcessingFee: "Processing Fee";
45
+ /**
46
+ * What the company OWES on an unredeemed gift card (D44).
47
+ *
48
+ * Selling a gift card earns nothing — money has come in and goods are owed — so the credit leg
49
+ * is a liability, not revenue. Recognising at issue and again at redemption is the classic
50
+ * gift-card double-count, and it is invisible in the ledger because both entries balance.
51
+ *
52
+ * NOT seeded by accounting's starter roles, so callers must tolerate it failing to resolve. The
53
+ * fallback is Deferred Revenue, which is the same SHAPE of obligation and keeps the entry
54
+ * correct and balanced — just coarser than a dedicated card liability. See
55
+ * OrderJournalEntryFactory, which records that it fell back rather than doing it silently.
56
+ */
57
+ readonly GiftCardLiability: "Gift Card Liability";
58
+ };
59
+ export type GLRole = (typeof GL_ROLE)[keyof typeof GL_ROLE];
60
+ /** MJ Entity IDs for the records the account links hang off. */
61
+ export interface ResolverEntityIDs {
62
+ Product: string;
63
+ ProductCategory: string;
64
+ ProductType: string;
65
+ Company: string;
66
+ }
67
+ export declare class GLAccountResolutionError extends Error {
68
+ readonly Role: string;
69
+ readonly ProductID: string;
70
+ constructor(Role: string, ProductID: string, message: string);
71
+ }
72
+ /**
73
+ * Resolves role→account for products, caching the category tree for the life of one booking.
74
+ * Construct per unit of work; do not hold across requests (the category tree is read once).
75
+ */
76
+ export declare class GLAccountResolver {
77
+ private readonly _entityIDs;
78
+ private readonly _provider;
79
+ private readonly _contextUser;
80
+ /** Injected so this class stays testable without a live accounting engine. */
81
+ private readonly _resolveLink;
82
+ private readonly _categoryParent;
83
+ private _categoriesLoaded;
84
+ constructor(_entityIDs: ResolverEntityIDs, _provider: IMetadataProvider, _contextUser: UserInfo,
85
+ /** Injected so this class stays testable without a live accounting engine. */
86
+ _resolveLink: (entityId: string, recordId: string, role: string, asOf: Date,
87
+ /** When given, only links whose ACCOUNT belongs to this company are considered (D71). */
88
+ forCompanyID?: string) => {
89
+ GLAccountID: string;
90
+ CompanyID: string;
91
+ } | null);
92
+ /**
93
+ * Walk product → category → ancestors → product type → company for `role`.
94
+ *
95
+ * @param expectedCompanyID the order line's company; the resolved account must belong to it
96
+ * @returns the resolved GL account UUID
97
+ * @throws GLAccountResolutionError when nothing resolves, or when the account's company differs
98
+ */
99
+ Resolve(role: GLRole,
100
+ /**
101
+ * NULL for company-level roles. A payment clears a receivable for a COMPANY — there is no
102
+ * product or category to walk from, so the company default is both the start and the end of
103
+ * the resolution.
104
+ */
105
+ productID: string | null, productCategoryID: string | null, expectedCompanyID: string, asOf: Date, productTypeID?: string | null): Promise<string>;
106
+ /**
107
+ * Resolve a link for an ARBITRARY record, with no walk (D71).
108
+ *
109
+ * The product walk answers "what account does this product's revenue go to". Some things are not
110
+ * products and have no category tree — a charge type, for instance — so they are looked up
111
+ * directly. Returns null rather than throwing: the caller knows whether the absence is fatal.
112
+ *
113
+ * The company invariant still applies. An account belonging to another company is refused for
114
+ * exactly the reason D6 gives: accounting derives the entry's company FROM the account, so a
115
+ * mis-resolved one books to the wrong legal entity with nothing downstream to catch it.
116
+ */
117
+ ResolveForRecord(role: GLRole, entityID: string, recordID: string, expectedCompanyID: string, asOf: Date): Promise<string | null>;
118
+ /** Category, then each ancestor, nearest first. */
119
+ private resolveUpCategoryTree;
120
+ /** One read of the category tree per booking — the walk is pointer-chasing after this. */
121
+ private ensureCategoriesLoaded;
122
+ }
123
+ //# sourceMappingURL=GLAccountResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GLAccountResolver.d.ts","sourceRoot":"","sources":["../src/GLAccountResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,EAAE,iBAAiB,EAA6B,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAG9F,iFAAiF;AACjF,eAAO,MAAM,OAAO;;;;;;IAMhB,6FAA6F;;IAE7F;;;;OAIG;;IAEH;;;;;;;;;;;OAWG;;CAEG,CAAC;AAEX,MAAM,MAAM,MAAM,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,OAAO,OAAO,CAAC,CAAC;AAE5D,gEAAgE;AAChE,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,wBAAyB,SAAQ,KAAK;aAE3B,IAAI,EAAE,MAAM;aACZ,SAAS,EAAE,MAAM;gBADjB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjC,OAAO,EAAE,MAAM;CAKtB;AAOD;;;GAGG;AACH,qBAAa,iBAAiB;IAKtB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,8EAA8E;IAC9E,OAAO,CAAC,QAAQ,CAAC,YAAY;IARjC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAoC;IACpE,OAAO,CAAC,iBAAiB,CAAS;gBAGb,UAAU,EAAE,iBAAiB,EAC7B,SAAS,EAAE,iBAAiB,EAC5B,YAAY,EAAE,QAAQ;IACvC,8EAA8E;IAC7D,YAAY,EAAE,CAC3B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,IAAI;IACV,yFAAyF;IACzF,YAAY,CAAC,EAAE,MAAM,KACpB;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAG1D;;;;;;OAMG;IACU,OAAO,CAChB,IAAI,EAAE,MAAM;IACZ;;;;OAIG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,iBAAiB,EAAE,MAAM,GAAG,IAAI,EAChC,iBAAiB,EAAE,MAAM,EACzB,IAAI,EAAE,IAAI,EACV,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,GAC9B,OAAO,CAAC,MAAM,CAAC;IAuClB;;;;;;;;;;OAUG;IACU,gBAAgB,CACzB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,iBAAiB,EAAE,MAAM,EACzB,IAAI,EAAE,IAAI,GACX,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAczB,mDAAmD;YACrC,qBAAqB;IAqBnC,0FAA0F;YAC5E,sBAAsB;CAkBvC"}
@@ -0,0 +1,175 @@
1
+ /**
2
+ * GLAccountResolver — turns a (product, role) pair into a concrete GL account UUID.
3
+ *
4
+ * Accounting's `CreateJournalEntries` contract takes `GLAccountID`, never a role name, so the
5
+ * role→account walk is the CALLER's job (plan D5). Accounting supplies only the per-record link
6
+ * primitive — `AccountingEngineBase.ResolveLinkedAccount(entityId, recordId, role, asOfDate)` —
7
+ * and this class implements the precedence over it:
8
+ *
9
+ * Product → its ProductCategory → that category's ancestors
10
+ * → its ProductType → the line's Company
11
+ *
12
+ * Company is the last resort (the accounting-org default). Product Type sits above
13
+ * the company default so a type can name Sales once and every product of that type
14
+ * inherits it, while a category or product can still override.
15
+ *
16
+ * Most specific wins; the first link found at any level ends the walk. Nothing resolves → we
17
+ * FAIL LOUDLY (plan D5: "fail loudly" — never silently book to a default account).
18
+ *
19
+ * COMPANY INVARIANT (plan D6): the resolved account MUST belong to the order line's company.
20
+ * Accounting derives a JE's company from `GLAccount.CompanyID` and takes no CompanyID in its
21
+ * contract (their CH-2), so a mis-resolved account would silently book revenue to the wrong
22
+ * legal entity with nothing downstream to catch it. This class is therefore the ONLY place that
23
+ * invariant can be enforced, and it hard-blocks — cross-company mapping is refused entirely.
24
+ *
25
+ * CONNECTS TO:
26
+ * PRIMITIVE: AccountingEngineBase.ResolveLinkedAccount (@mj-biz-apps/accounting-engine-base)
27
+ * CALLER: OrderJournalEntryFactory (./OrderJournalEntryFactory.ts)
28
+ */
29
+ import { RunView } from '@memberjunction/core';
30
+ import { UUIDsEqual } from '@memberjunction/global';
31
+ /** GL account roles this app books against (seeded by accounting's metadata). */
32
+ export const GL_ROLE = {
33
+ AccountsReceivable: 'Accounts Receivable',
34
+ Sales: 'Sales',
35
+ SalesDiscounts: 'Sales Discounts',
36
+ DeferredRevenue: 'Deferred Revenue',
37
+ SalesReturnsAndAllowances: 'Sales Returns and Allowances',
38
+ /** Where captured cash lands. Company-level only — a payment has no product to walk from. */
39
+ Cash: 'Cash',
40
+ /**
41
+ * The provider's cut on a capture (D18). NOT seeded by accounting's starter roles, so callers
42
+ * must tolerate it failing to resolve — see PaymentJournalEntryFactory, which books the gross
43
+ * to Cash and reports the shortfall rather than silently misstating the bank line.
44
+ */
45
+ ProcessingFee: 'Processing Fee',
46
+ /**
47
+ * What the company OWES on an unredeemed gift card (D44).
48
+ *
49
+ * Selling a gift card earns nothing — money has come in and goods are owed — so the credit leg
50
+ * is a liability, not revenue. Recognising at issue and again at redemption is the classic
51
+ * gift-card double-count, and it is invisible in the ledger because both entries balance.
52
+ *
53
+ * NOT seeded by accounting's starter roles, so callers must tolerate it failing to resolve. The
54
+ * fallback is Deferred Revenue, which is the same SHAPE of obligation and keeps the entry
55
+ * correct and balanced — just coarser than a dedicated card liability. See
56
+ * OrderJournalEntryFactory, which records that it fell back rather than doing it silently.
57
+ */
58
+ GiftCardLiability: 'Gift Card Liability',
59
+ };
60
+ export class GLAccountResolutionError extends Error {
61
+ constructor(Role, ProductID, message) {
62
+ super(message);
63
+ this.Role = Role;
64
+ this.ProductID = ProductID;
65
+ this.name = 'GLAccountResolutionError';
66
+ }
67
+ }
68
+ /**
69
+ * Resolves role→account for products, caching the category tree for the life of one booking.
70
+ * Construct per unit of work; do not hold across requests (the category tree is read once).
71
+ */
72
+ export class GLAccountResolver {
73
+ constructor(_entityIDs, _provider, _contextUser,
74
+ /** Injected so this class stays testable without a live accounting engine. */
75
+ _resolveLink) {
76
+ this._entityIDs = _entityIDs;
77
+ this._provider = _provider;
78
+ this._contextUser = _contextUser;
79
+ this._resolveLink = _resolveLink;
80
+ this._categoryParent = new Map();
81
+ this._categoriesLoaded = false;
82
+ }
83
+ /**
84
+ * Walk product → category → ancestors → product type → company for `role`.
85
+ *
86
+ * @param expectedCompanyID the order line's company; the resolved account must belong to it
87
+ * @returns the resolved GL account UUID
88
+ * @throws GLAccountResolutionError when nothing resolves, or when the account's company differs
89
+ */
90
+ async Resolve(role,
91
+ /**
92
+ * NULL for company-level roles. A payment clears a receivable for a COMPANY — there is no
93
+ * product or category to walk from, so the company default is both the start and the end of
94
+ * the resolution.
95
+ */
96
+ productID, productCategoryID, expectedCompanyID, asOf, productTypeID) {
97
+ const company = expectedCompanyID;
98
+ const hit = (productID ? this._resolveLink(this._entityIDs.Product, productID, role, asOf, company) : null) ??
99
+ (await this.resolveUpCategoryTree(role, productCategoryID, asOf, company)) ??
100
+ (productTypeID
101
+ ? this._resolveLink(this._entityIDs.ProductType, productTypeID, role, asOf, company)
102
+ : null) ??
103
+ this._resolveLink(this._entityIDs.Company, expectedCompanyID, role, asOf, company);
104
+ if (!hit) {
105
+ throw new GLAccountResolutionError(role, productID, productID
106
+ ? `No GL account is linked for role '${role}'. Checked the product, its category ` +
107
+ `tree, its product type, and the company default for company ${expectedCompanyID}. ` +
108
+ `Link an account for this role (product, category, product type, or company) before booking.`
109
+ : `No GL account is linked for role '${role}' at the company level for company ` +
110
+ `${expectedCompanyID}. This role is resolved company-wide (there is no product ` +
111
+ `involved), so link an account to the company before booking.`);
112
+ }
113
+ // Plan D6 — hard block. Accounting takes no CompanyID; the account IS the company.
114
+ if (!UUIDsEqual(hit.CompanyID, expectedCompanyID)) {
115
+ throw new GLAccountResolutionError(role, productID, `GL account ${hit.GLAccountID} resolved for role '${role}' belongs to company ` +
116
+ `${hit.CompanyID}, but this books to company ${expectedCompanyID}. ` +
117
+ `Cross-company account mapping is refused — the journal entry would book revenue ` +
118
+ `to the wrong legal entity.`);
119
+ }
120
+ return hit.GLAccountID;
121
+ }
122
+ /**
123
+ * Resolve a link for an ARBITRARY record, with no walk (D71).
124
+ *
125
+ * The product walk answers "what account does this product's revenue go to". Some things are not
126
+ * products and have no category tree — a charge type, for instance — so they are looked up
127
+ * directly. Returns null rather than throwing: the caller knows whether the absence is fatal.
128
+ *
129
+ * The company invariant still applies. An account belonging to another company is refused for
130
+ * exactly the reason D6 gives: accounting derives the entry's company FROM the account, so a
131
+ * mis-resolved one books to the wrong legal entity with nothing downstream to catch it.
132
+ */
133
+ async ResolveForRecord(role, entityID, recordID, expectedCompanyID, asOf) {
134
+ const hit = this._resolveLink(entityID, recordID, role, asOf, expectedCompanyID);
135
+ if (!hit)
136
+ return null;
137
+ if (!UUIDsEqual(hit.CompanyID, expectedCompanyID)) {
138
+ throw new GLAccountResolutionError(role, recordID, `GL account ${hit.GLAccountID} resolved for role '${role}' belongs to company ${hit.CompanyID}, ` +
139
+ `but this books to company ${expectedCompanyID}. Cross-company account mapping is refused.`);
140
+ }
141
+ return hit.GLAccountID;
142
+ }
143
+ /** Category, then each ancestor, nearest first. */
144
+ async resolveUpCategoryTree(role, startCategoryID, asOf, forCompanyID) {
145
+ if (!startCategoryID)
146
+ return null;
147
+ await this.ensureCategoriesLoaded();
148
+ const seen = new Set();
149
+ let current = startCategoryID;
150
+ while (current && !seen.has(current)) {
151
+ seen.add(current); // cycle guard — the DB CHECK blocks self-parenting, not longer loops
152
+ const hit = this._resolveLink(this._entityIDs.ProductCategory, current, role, asOf, forCompanyID);
153
+ if (hit)
154
+ return hit;
155
+ current = this._categoryParent.get(current) ?? null;
156
+ }
157
+ return null;
158
+ }
159
+ /** One read of the category tree per booking — the walk is pointer-chasing after this. */
160
+ async ensureCategoriesLoaded() {
161
+ if (this._categoriesLoaded)
162
+ return;
163
+ const rv = new RunView(this._provider);
164
+ const result = await rv.RunView({
165
+ EntityName: 'MJ_BizApps_Orders: Product Categories',
166
+ Fields: ['ID', 'ParentProductCategoryID'],
167
+ ResultType: 'simple',
168
+ }, this._contextUser);
169
+ for (const row of result?.Results ?? []) {
170
+ this._categoryParent.set(row.ID, row.ParentProductCategoryID ?? null);
171
+ }
172
+ this._categoriesLoaded = true;
173
+ }
174
+ }
175
+ //# sourceMappingURL=GLAccountResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GLAccountResolver.js","sourceRoot":"","sources":["../src/GLAccountResolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @fileoverview `Orders.GetFulfillmentQueue` — what still has to leave the building.
3
+ *
4
+ * WHY THIS IS AN OPERATION AND NOT A VIEW, and not a stored flag. The queue is every line still
5
+ * awaiting shipment, which changes as lines are FLIPPED rather than as anything is written to the
6
+ * order. A column would need a job whose only purpose is keeping it honest, and the day that job
7
+ * failed the warehouse would quietly stop seeing work — the worst possible failure mode for a
8
+ * backlog, because it looks like there is nothing to do.
9
+ *
10
+ * WHAT DOES NOT APPEAR HERE, each for its own reason:
11
+ * · lines whose product TYPE requires no fulfilment — a subscription, a download, a donation;
12
+ * · REVERSAL lines — goods coming back are tracked on the line they reverse, not by shipping a
13
+ * credit;
14
+ * · a bundle's ROLLUP PARENT — a display row whose children carry the actual goods (D45).
15
+ *
16
+ * Getting any of those wrong fills the queue with work nobody can do, which is how a real queue
17
+ * stops being read.
18
+ *
19
+ * @module @mj-biz-apps/orders-core-entities-server
20
+ */
21
+ import { type IMetadataProvider, type UserInfo } from '@memberjunction/core';
22
+ import { OrdersGetFulfillmentQueueOperation as OrdersGetFulfillmentQueueOperationBase, type OrdersGetFulfillmentQueueInput, type OrdersGetFulfillmentQueueOutput } from '@mj-biz-apps/orders-entities';
23
+ /**
24
+ * Assemble the fulfilment queue.
25
+ *
26
+ * Orders come back OLDEST CONFIRMED FIRST — the order a warehouse should work them in. Not by size,
27
+ * and not by customer: the oldest promise is the one most at risk of being broken.
28
+ */
29
+ export declare class GetFulfillmentQueueOperation extends OrdersGetFulfillmentQueueOperationBase {
30
+ protected InternalExecute(input: OrdersGetFulfillmentQueueInput, provider: IMetadataProvider, user: UserInfo): Promise<OrdersGetFulfillmentQueueOutput>;
31
+ private empty;
32
+ }
33
+ /** Tree-shaking anchor — call from the server bootstrap so @RegisterClass is retained. */
34
+ export declare function LoadGetFulfillmentQueueOperation(): void;
35
+ //# sourceMappingURL=GetFulfillmentQueueOperation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GetFulfillmentQueueOperation.d.ts","sourceRoot":"","sources":["../src/GetFulfillmentQueueOperation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAGH,KAAK,iBAAiB,EAEtB,KAAK,QAAQ,EAChB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACH,kCAAkC,IAAI,sCAAsC,EAC5E,KAAK,8BAA8B,EACnC,KAAK,+BAA+B,EAGvC,MAAM,8BAA8B,CAAC;AActC;;;;;GAKG;AACH,qBACa,4BAA6B,SAAQ,sCAAsC;cACpE,eAAe,CAC3B,KAAK,EAAE,8BAA8B,EACrC,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,QAAQ,GACf,OAAO,CAAC,+BAA+B,CAAC;IA4M3C,OAAO,CAAC,KAAK;CAUhB;AAED,0FAA0F;AAC1F,wBAAgB,gCAAgC,IAAI,IAAI,CAEvD"}