@opencxh/domain 1.302.0 → 1.304.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 (67) hide show
  1. package/dist/entities/agreement/from-quote.d.ts +8 -8
  2. package/dist/entities/agreement/index.d.ts +2 -0
  3. package/dist/entities/agreement/invoice-head.d.ts +21 -0
  4. package/dist/entities/agreement/lifecycle.d.ts +10 -0
  5. package/dist/entities/agreement/period.d.ts +8 -0
  6. package/dist/entities/agreement/prices.d.ts +43 -0
  7. package/dist/entities/agreement/prices.test.d.ts +1 -0
  8. package/dist/entities/agreement/types.d.ts +55 -10
  9. package/dist/entities/bank/match.d.ts +16 -2
  10. package/dist/entities/bank/types.d.ts +12 -0
  11. package/dist/entities/bookkeeping/receipt.d.ts +45 -6
  12. package/dist/entities/bookkeeping/types.d.ts +1 -2
  13. package/dist/entities/business-entity/types.d.ts +11 -15
  14. package/dist/entities/catalog/pricing.d.ts +14 -12
  15. package/dist/entities/catalog/types.d.ts +20 -9
  16. package/dist/entities/company/role.d.ts +14 -0
  17. package/dist/entities/financing/schedule.d.ts +9 -3
  18. package/dist/entities/financing/types.d.ts +17 -6
  19. package/dist/entities/fulfilment/adopt.d.ts +149 -0
  20. package/dist/entities/fulfilment/configuration.d.ts +99 -0
  21. package/dist/entities/fulfilment/configuration.test.d.ts +1 -0
  22. package/dist/entities/fulfilment/customers.d.ts +63 -0
  23. package/dist/entities/fulfilment/execute.d.ts +67 -0
  24. package/dist/entities/fulfilment/fulfilment.test.d.ts +1 -0
  25. package/dist/entities/fulfilment/goods.d.ts +72 -0
  26. package/dist/entities/fulfilment/index.d.ts +9 -0
  27. package/dist/entities/fulfilment/path.d.ts +8 -0
  28. package/dist/entities/fulfilment/path.test.d.ts +1 -0
  29. package/dist/entities/fulfilment/rules.d.ts +124 -0
  30. package/dist/entities/fulfilment/target.d.ts +133 -0
  31. package/dist/entities/fulfilment/types.d.ts +293 -0
  32. package/dist/entities/ledger/entry.d.ts +47 -9
  33. package/dist/entities/ledger/types.d.ts +33 -35
  34. package/dist/entities/ledger/xaf.d.ts +3 -0
  35. package/dist/entities/money/tax.d.ts +6 -0
  36. package/dist/entities/money/totals.d.ts +5 -5
  37. package/dist/entities/purchase/choose.d.ts +62 -0
  38. package/dist/entities/purchase/choose.test.d.ts +1 -0
  39. package/dist/entities/purchase/contract.d.ts +44 -25
  40. package/dist/entities/purchase/demand.d.ts +24 -40
  41. package/dist/entities/purchase/feed.d.ts +53 -5
  42. package/dist/entities/purchase/index.d.ts +2 -0
  43. package/dist/entities/purchase/kinds.d.ts +2 -1
  44. package/dist/entities/purchase/logic.d.ts +32 -7
  45. package/dist/entities/purchase/match.d.ts +48 -6
  46. package/dist/entities/purchase/packing-slip.d.ts +23 -0
  47. package/dist/entities/purchase/types.d.ts +90 -42
  48. package/dist/entities/purchase/upsell.d.ts +20 -0
  49. package/dist/entities/purchase/upsell.test.d.ts +1 -0
  50. package/dist/entities/reports/vat.d.ts +20 -5
  51. package/dist/entities/transaction/booking.d.ts +4 -4
  52. package/dist/entities/transaction/convert.d.ts +10 -10
  53. package/dist/entities/transaction/document.d.ts +8 -3
  54. package/dist/entities/transaction/dunning.d.ts +12 -1
  55. package/dist/entities/transaction/facets.test.d.ts +1 -0
  56. package/dist/entities/transaction/keys.d.ts +3 -0
  57. package/dist/entities/transaction/kinds.d.ts +11 -10
  58. package/dist/entities/transaction/receivable.d.ts +5 -2
  59. package/dist/entities/transaction/settlement.d.ts +7 -7
  60. package/dist/entities/transaction/types.d.ts +128 -68
  61. package/dist/index.cjs +25 -25
  62. package/dist/index.d.ts +2 -1
  63. package/dist/index.js +5300 -4033
  64. package/dist/platform/bookkeeping.d.ts +8 -8
  65. package/dist/platform/provisioning.d.ts +292 -17
  66. package/package.json +1 -1
  67. /package/dist/entities/{purchase/demand.test.d.ts → agreement/invoice-head.test.d.ts} +0 -0
@@ -1,6 +1,7 @@
1
1
  import { LedgerMappingRule } from '../entities/bookkeeping/types';
2
2
  import { Cents } from '../entities/money/money';
3
3
  import { TaxRateKind } from '../entities/money/tax';
4
+ import { LineDimensions } from '../entities/transaction/types';
4
5
  export declare const BOOKABLE_SOURCE_PROVIDER_GROUP = "bookable-source";
5
6
  export declare const BOOKKEEPING_PROVIDER_GROUP = "bookkeeping";
6
7
  /** Routes under `/provider`. Constants, so caller and provider cannot drift apart. */
@@ -39,6 +40,8 @@ export interface BookingDocument {
39
40
  number?: string;
40
41
  counterparty: {
41
42
  companyId?: string;
43
+ /** Its role number at this administration (debtor or creditor number), as it went out. */
44
+ number?: string;
42
45
  name: string;
43
46
  vatNumber?: string;
44
47
  kvkNumber?: string;
@@ -53,7 +56,7 @@ export interface BookingDocument {
53
56
  };
54
57
  /** `"2026-09-24"`. Dates are days, not instants. */
55
58
  issueDate: string;
56
- /** Delivery date or end of the service period: decides the VAT period. */
59
+ /** When the VAT is due, if not on `issueDate`. A sales invoice leaves it out (D2). */
57
60
  taxPointDate?: string;
58
61
  dueDate?: string;
59
62
  currency: string;
@@ -95,11 +98,8 @@ export interface BookingLine {
95
98
  */
96
99
  accountKey?: string;
97
100
  productId?: string;
98
- /**
99
- * Open map: `projectId`, `costCenterId`, `customerCompanyId` (whose cost or revenue this is),
100
- * and whatever a later country needs. All of it reaches the journal line.
101
- */
102
- dimensions?: Record<string, string>;
101
+ /** KETEN-STAND B1: each reaches the journal line as its own column. */
102
+ dimensions?: LineDimensions;
103
103
  /** The cost of what this line sold (quantity × cost price): carried for margin, not booked yet. */
104
104
  costCents?: Cents;
105
105
  /**
@@ -126,8 +126,8 @@ export interface IssuedDocumentRef {
126
126
  export interface BookingAnnouncement {
127
127
  sourceApp: string;
128
128
  documentId: string;
129
- /** Empty = the default administration; finance resolves it, a row never carries "". */
130
- businessEntityId?: string;
129
+ /** Always the document's own administration (review 5a-4); `""` is refused, not "the default". */
130
+ businessEntityId: string;
131
131
  documentKind: BookingDocument["kind"];
132
132
  documentNumber?: string;
133
133
  issuedAt: number;
@@ -1,24 +1,62 @@
1
- /**
2
- * `provisioning-source`: an app that can order at a supplier through its API (Eylo: a customer
3
- * account, numbers). Purchase submits a request per order line and follows it; the provider says
4
- * what it needs and what it made.
5
- */
1
+ import { Commitment, LineRhythm } from '../entities/agreement/types';
6
2
  export declare const PROVISIONING_SOURCE_GROUP = "provisioning-source";
7
3
  export declare const PROVISIONING_ROUTES: {
8
4
  readonly describe: "/provisioning/describe";
9
5
  readonly submit: "/provisioning/submit";
10
6
  readonly status: "/provisioning/status";
7
+ readonly subscriptions: "/provisioning/subscriptions";
8
+ /** Optional, for account offers that declare `accounts`: every customer account it knows (047 step 9). */
9
+ readonly accounts: "/provisioning/accounts";
10
+ /** Optional, for providers that declare `catalog`: the assortment as price-list rows (045 D N-1). */
11
+ readonly catalog: "/provisioning/catalog";
12
+ /**
13
+ * A dry run of `submit` (plan 053): the next questions, what is still unmet and the cost — of a
14
+ * purchase, a change or an end. Every provider answers it; without a handler of its own, its
15
+ * declared `params` do.
16
+ */
17
+ readonly prepare: "/provisioning/prepare";
18
+ };
19
+ /**
20
+ * One vocabulary for the act, on the wire and on a `ProvisioningRequest` (plan 047 v2): `convert`
21
+ * swaps the product (Microsoft Transition, Pax8 ChangeProduct), `renew` starts a next term.
22
+ */
23
+ export type ProvisioningAction = "purchase" | "change" | "convert" | "suspend" | "resume" | "cancel" | "renew";
24
+ /** What one provider hands another, normalised (047 v2 §7): a few concrete kinds, no mapping language. */
25
+ export type ProvidedResource = {
26
+ kind: "phone_number";
27
+ value: string;
28
+ } | {
29
+ kind: "device";
30
+ value: string;
31
+ } | {
32
+ kind: "tenant";
33
+ value: string;
34
+ } | {
35
+ kind: "account";
36
+ value: string;
11
37
  };
12
- export type ProvisioningAction = "purchase" | "change" | "suspend" | "resume" | "cancel";
38
+ export type ResourceKind = ProvidedResource["kind"];
39
+ /** A role an offer needs another item in, and for which acts that item must be active. */
40
+ export interface RoleNeed {
41
+ role: string;
42
+ kind: ResourceKind;
43
+ min: number;
44
+ max: number;
45
+ for: ProvisioningAction[];
46
+ }
47
+ /** How an unknown outcome is recovered, per act (047 v2 §2.3). */
48
+ export type ProvisioningRecovery = "idempotent" | "lookup_by_ref" | "lookup_by_listing";
13
49
  /**
14
- * A field the supplier needs. `ordering` is filled on the order line before it goes (the tenant's
15
- * domain, the number's region); `fulfillment` is what the supplier hands back (the account id).
50
+ * A field the supplier needs. `qualify` is asked on the quote line already (the site, for a
51
+ * delivery check); `ordering` is filled before it goes (the tenant's domain, the number's region);
52
+ * `fulfillment` is what the supplier hands back (the account id). An `address` is a crm
53
+ * `CompanyAddress.id`, never a copy: the provider reads the address itself.
16
54
  */
17
55
  export interface ProvisioningParam {
18
56
  key: string;
19
57
  label: string;
20
- phase: "ordering" | "fulfillment";
21
- type?: "text" | "email" | "select";
58
+ phase: "qualify" | "ordering" | "fulfillment";
59
+ type?: "text" | "email" | "select" | "address";
22
60
  required?: boolean;
23
61
  options?: {
24
62
  value: string;
@@ -39,17 +77,126 @@ export interface ProvisionableOffer {
39
77
  actions: ProvisioningAction[];
40
78
  /** The account it makes is a usage source: approved links it to the customer's agreement. */
41
79
  usageAccount?: boolean;
80
+ /** What a successful purchase hands back to others (047 v2 §7). */
81
+ provides?: {
82
+ kind: ResourceKind;
83
+ }[];
84
+ /** What it needs from other items, per role (047 v2 §10.1). */
85
+ needs?: RoleNeed[];
86
+ /** Per act, how an unknown outcome is recovered. Absent = ask a person. */
87
+ recovery?: Partial<Record<ProvisioningAction, ProvisioningRecovery>>;
88
+ /** The provider lists what runs under an account (`subscriptions`): polled into `reported`. */
89
+ listing?: boolean;
90
+ /**
91
+ * An account offer whose accounts the provider lists (`POST /provisioning/accounts`): where
92
+ * fulfilment looks for what already runs when an existing business moves over (047 step 9).
93
+ */
94
+ accounts?: boolean;
95
+ /** The questions it starts with (plan 053); `prepare` answers the rest. */
96
+ requirements?: RequirementSpec[];
97
+ }
98
+ /**
99
+ * What one act costs at the supplier, per part: each part is a line on the purchase order, once
100
+ * or per month. Cost, internal — never shown to a customer.
101
+ */
102
+ export interface ProviderQuote {
103
+ parts: {
104
+ label: string;
105
+ cents: number;
106
+ recurring?: "month";
107
+ }[];
108
+ warnings?: string[];
109
+ }
110
+ /** One subscription as the supplier lists it under an account (Pax8, Microsoft, 047 v2 §2.1). */
111
+ export interface ReportedSubscription {
112
+ externalRef: string;
113
+ offer: string;
114
+ quantity: number;
115
+ status: "active" | "suspended" | "ended";
116
+ /** Our `requestId`, where the supplier keeps a reference (Ion `referenceId`). */
117
+ requestRef?: string;
118
+ termEndsAt?: number;
119
+ autoRenew?: boolean;
120
+ /** Microsoft NCE: every add-on has its own window; a decrease only within these. */
121
+ refundable?: {
122
+ quantity: number;
123
+ until: number;
124
+ }[];
125
+ scheduled?: {
126
+ quantity?: number;
127
+ productId?: string;
128
+ at: number;
129
+ };
130
+ /** The account it runs under at this provider (its `externalRef`), when listed flat. */
131
+ under?: string;
132
+ /** What it uses of other items (a number routed from elsewhere): bound to `requires` on adopt. */
133
+ uses?: ProvidedResource[];
134
+ }
135
+ /** One customer account a provider knows (`accounts`): matched to a crm company on adopt. */
136
+ export interface ProviderAccount {
137
+ externalRef: string;
138
+ /** The account offer it is an instance of. */
139
+ offer: string;
140
+ name: string;
141
+ kvkNumber?: string;
142
+ domain?: string;
143
+ fulfillment?: Record<string, string>;
144
+ since?: number;
145
+ }
146
+ /** `subscriptions`: what runs under one account, optionally of one offer. */
147
+ export interface SubscriptionsQuery {
148
+ account: {
149
+ externalRef?: string;
150
+ fulfillment?: Record<string, string>;
151
+ };
152
+ offer?: string;
42
153
  }
43
154
  export interface ProvisioningDescription {
44
155
  offers: ProvisionableOffer[];
156
+ /**
157
+ * The provider lists its assortment (`POST /provisioning/catalog { account }`), per connection:
158
+ * a price list with source `api` reads it instead of a file (045 D N-1).
159
+ */
160
+ catalog?: {
161
+ accounts: {
162
+ id: string;
163
+ name: string;
164
+ }[];
165
+ };
166
+ }
167
+ /** One product of a provider's assortment, as a price-list line reads it. */
168
+ export interface ProviderCatalogRow {
169
+ vendorSku: string;
170
+ description: string;
171
+ brand?: string;
172
+ group?: string;
173
+ /** The provider's offer it is ordered through (`ProvisionableOffer.key`). */
174
+ offer: string;
175
+ /** Absent: priced per order (`pricedBy: "quote"`). */
176
+ costCents?: number;
177
+ currency?: string;
45
178
  }
46
- export interface ProvisioningRequest {
47
- /** `lineKey` of the order line: the provider's idempotency key — the same request twice is one. */
179
+ export interface ProvisioningCommand {
180
+ /** The provider's idempotency key: the same request twice is one. */
48
181
  requestId: string;
49
182
  offer: string;
50
183
  action: ProvisioningAction;
51
184
  quantity: number;
185
+ /** `convert`: the product it becomes. */
186
+ toProductId?: string;
187
+ /**
188
+ * What it is bought as at the supplier, from the PO line's offer: their product
189
+ * (`SupplierOffer.vendorSku`, a Nextpertise carrier product) and its term in months.
190
+ */
191
+ vendorSku?: string;
192
+ termMonths?: number;
52
193
  params: Record<string, string>;
194
+ /** What it uses from other items, bound by role (047 v2 §10.1): the number it routes. */
195
+ inputs?: {
196
+ role: string;
197
+ itemId: string;
198
+ resource: ProvidedResource;
199
+ }[];
53
200
  /** The subscription this changes or ends. */
54
201
  externalRef?: string;
55
202
  /** What the account level handed back (its id), for an item inside it. */
@@ -57,11 +204,6 @@ export interface ProvisioningRequest {
57
204
  externalRef?: string;
58
205
  fulfillment?: Record<string, string>;
59
206
  };
60
- /** Bought elsewhere and landing here: what the purchase handed back (the numbers). */
61
- predecessor?: {
62
- externalRef?: string;
63
- fulfillment?: Record<string, string>;
64
- };
65
207
  customer?: {
66
208
  companyId: string;
67
209
  name?: string;
@@ -70,6 +212,13 @@ export interface ProvisioningRequest {
70
212
  effectiveAt?: number;
71
213
  }
72
214
  export type ProvisioningState = "pending" | "approved" | "failed" | "inquiring";
215
+ /** What the supplier ships itself for a service (the SIM, the router), followed by its tracking. */
216
+ export interface ProviderShipment {
217
+ carrier?: string;
218
+ trackingNumber?: string;
219
+ serials?: string[];
220
+ at?: number;
221
+ }
73
222
  export interface ProvisioningResult {
74
223
  state: ProvisioningState;
75
224
  externalRef?: string;
@@ -85,4 +234,130 @@ export interface ProvisioningResult {
85
234
  app: string;
86
235
  accountRef: string;
87
236
  };
237
+ /** Partly done: how many of the target succeeded (Microsoft reports per part). */
238
+ quantity?: number;
239
+ /** What it now provides to others, normalised (047 v2 §7). */
240
+ resources?: ProvidedResource[];
241
+ /** Shipped by the supplier, for this request (plan 053 G3). */
242
+ deliveries?: ProviderShipment[];
243
+ }
244
+ /** What is bought, at whom: the provider's offer and, where one offer covers many, their product. */
245
+ export interface OfferRef {
246
+ app: string;
247
+ offer: string;
248
+ sku?: string;
249
+ }
250
+ /** `app:offer`, plus `:sku` when there is one: the one way to key an offer. */
251
+ export declare function offerKey(ref: OfferRef): string;
252
+ /** The same offer; a ref without a sku matches every product of that offer. */
253
+ export declare function sameOffer(a: OfferRef, b: OfferRef): boolean;
254
+ /** Every answer by requirement key; a quantity or a yes/no is a string too. */
255
+ export type ProvisioningAnswers = Record<string, string>;
256
+ /** By when it must be met: before the quote is accepted, or before the order goes out. */
257
+ export type RequirementGate = "quote" | "order";
258
+ export type AnswerType = "text" | "email" | "address" | "select" | "boolean" | "quantity";
259
+ /** One choice, live from the supplier. A `sku` makes it a product; its cost is internal. */
260
+ export interface RequirementOption {
261
+ key: string;
262
+ label: string;
263
+ sku?: string;
264
+ costCents?: number;
265
+ recurring?: "month";
266
+ /**
267
+ * What this choice binds us to at the supplier (NCE monthly vs yearly, plan 053 G1): the same
268
+ * `Commitment` as an agreement, as far as the supplier says it (Nextpertise names only the term).
269
+ * How often they invoice is no commitment: `billedEvery`.
270
+ */
271
+ commitment?: Partial<Commitment>;
272
+ billedEvery?: LineRhythm;
273
+ }
274
+ interface RequirementBase {
275
+ key: string;
276
+ label: string;
277
+ before: RequirementGate;
278
+ }
279
+ /**
280
+ * Something we fill in. `line` says it is sold: `main` picks the supplier's product of the line
281
+ * (the network, the bundle), `addon` becomes a sub-line of its own (an EVC, premium SLA).
282
+ * `perUnit`: every unit of an exclusive item has its own (the number to port, per SIM).
283
+ */
284
+ export interface AnswerSpec extends RequirementBase {
285
+ kind: "answer";
286
+ type: AnswerType;
287
+ required?: boolean;
288
+ options?: RequirementOption[];
289
+ line?: "main" | "addon";
290
+ /** A `boolean` or `quantity` add-on's own product and cost, per unit. */
291
+ sku?: string;
292
+ costCents?: number;
293
+ recurring?: "month";
294
+ min?: number;
295
+ max?: number;
296
+ perUnit?: boolean;
297
+ /**
298
+ * An offer may fix it (`SupplierOffer.provider.answers`): the article as a filter — "Glasvezel
299
+ * 1 Gbit" fixes technology and speed. Never asked in the flow; declared in `describe`.
300
+ */
301
+ preset?: boolean;
302
+ }
303
+ /** Something the provider judges; `who` resolves it when it is not met. */
304
+ export interface ConditionSpec extends RequirementBase {
305
+ kind: "condition";
306
+ who: "colleague" | "customer" | "provider";
88
307
  }
308
+ /** Declared in `describe`: the questions an offer starts with, so a search knows who to ask. */
309
+ export type RequirementSpec = AnswerSpec | ConditionSpec;
310
+ /** What to do to meet a condition: send the link, set the record. */
311
+ export interface RequirementInstructions {
312
+ text: string;
313
+ link?: string;
314
+ record?: {
315
+ type: string;
316
+ name: string;
317
+ value: string;
318
+ };
319
+ }
320
+ export interface RequirementState {
321
+ met: boolean;
322
+ reason?: string;
323
+ /** An answer the provider proposes (from crm, or its only option). */
324
+ value?: string;
325
+ instructions?: RequirementInstructions;
326
+ }
327
+ export type Requirement = RequirementSpec & RequirementState;
328
+ /**
329
+ * `prepare`: the same act as `submit`, not sent. `answers` are everything filled in so far, the
330
+ * offer's own fixed ones included (`SupplierOffer.provider.answers`: the article as a filter).
331
+ */
332
+ export interface PrepareCommand {
333
+ ref: OfferRef;
334
+ action?: ProvisioningAction;
335
+ quantity: number;
336
+ answers: ProvisioningAnswers;
337
+ commitment?: Partial<Commitment>;
338
+ billedEvery?: LineRhythm;
339
+ externalRef?: string;
340
+ parent?: {
341
+ externalRef?: string;
342
+ fulfillment?: Record<string, string>;
343
+ };
344
+ customer?: {
345
+ companyId: string;
346
+ name?: string;
347
+ };
348
+ effectiveAt?: number;
349
+ }
350
+ /** The provider's answer: the next state of the questions, and what it costs. Internal. */
351
+ export interface Preparation {
352
+ requirements: Requirement[];
353
+ cost?: ProviderQuote;
354
+ /** Until when it holds: a deliverability check does not last. */
355
+ expiresAt?: number;
356
+ }
357
+ /**
358
+ * The questions of an offer that computes nothing: its declared `params`, met when answered
359
+ * (`qualify` before the quote, `ordering` before the order; what the supplier hands back is no
360
+ * question). What `prepare` answers for a provider that does not implement it.
361
+ */
362
+ export declare function preparationFromParams(params: ProvisioningParam[], answers: ProvisioningAnswers): Preparation;
363
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencxh/domain",
3
- "version": "1.302.0",
3
+ "version": "1.304.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",