@robosystems/client 0.3.9 → 0.3.11

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.
@@ -76,36 +76,6 @@ class LedgerClient {
76
76
  async getTransaction(graphId, transactionId) {
77
77
  return this.gqlQuery(graphId, graphql_1.GetLedgerTransactionDocument, { transactionId }, 'Get transaction', (data) => data.transaction);
78
78
  }
79
- /**
80
- * Create a standalone business-event Transaction without entries.
81
- *
82
- * Returns a `transaction_id` that can be passed to `createJournalEntry`
83
- * to attach entries to this event. Use when a single event (invoice,
84
- * payment, deposit) produces multiple entries over its lifecycle.
85
- *
86
- * `amount` is in minor currency units (cents).
87
- * `type` is free-form: invoice, payment, bill, expense, deposit, etc.
88
- */
89
- async createTransaction(graphId, options) {
90
- const body = {
91
- type: options.type,
92
- date: options.date,
93
- amount: options.amount,
94
- currency: options.currency ?? 'USD',
95
- status: options.status ?? 'pending',
96
- description: options.description ?? null,
97
- merchant_name: options.merchantName ?? null,
98
- reference_number: options.referenceNumber ?? null,
99
- number: options.number ?? null,
100
- category: options.category ?? null,
101
- due_date: options.dueDate ?? null,
102
- };
103
- const headers = options.idempotencyKey
104
- ? { 'Idempotency-Key': options.idempotencyKey }
105
- : undefined;
106
- const envelope = await this.callOperation('Create transaction', (0, sdk_gen_1.opCreateTransaction)({ path: { graph_id: graphId }, body, headers }));
107
- return (envelope.result ?? {});
108
- }
109
79
  // ── Trial Balance ──────────────────────────────────────────────────
110
80
  /** Trial balance by raw CoA account. */
111
81
  async getTrialBalance(graphId, options) {
@@ -132,22 +102,6 @@ class LedgerClient {
132
102
  const list = await this.gqlQuery(graphId, graphql_1.ListLedgerTaxonomiesDocument, { taxonomyType: options?.taxonomyType ?? null }, 'List taxonomies', (data) => data.taxonomies);
133
103
  return list?.taxonomies ?? [];
134
104
  }
135
- /** Create a new taxonomy (used for CoA + mapping taxonomies). */
136
- async createTaxonomy(graphId, body) {
137
- const envelope = await this.callOperation('Create taxonomy', (0, sdk_gen_1.opCreateTaxonomy)({ path: { graph_id: graphId }, body }));
138
- return (envelope.result ?? {});
139
- }
140
- /** Update mutable fields on a taxonomy. `taxonomy_type` is immutable. */
141
- async updateTaxonomy(graphId, body) {
142
- const envelope = await this.callOperation('Update taxonomy', (0, sdk_gen_1.opUpdateTaxonomy)({ path: { graph_id: graphId }, body }));
143
- return (envelope.result ?? {});
144
- }
145
- /** Soft-delete a taxonomy (`is_active=false`). */
146
- async deleteTaxonomy(graphId, taxonomyId) {
147
- const body = { taxonomy_id: taxonomyId };
148
- const envelope = await this.callOperation('Delete taxonomy', (0, sdk_gen_1.opDeleteTaxonomy)({ path: { graph_id: graphId }, body }));
149
- return (envelope.result ?? {});
150
- }
151
105
  /**
152
106
  * Link the graph's entity to a taxonomy (ENTITY_HAS_TAXONOMY edge).
153
107
  * Idempotent — returns existing linkage if already present.
@@ -156,6 +110,25 @@ class LedgerClient {
156
110
  const envelope = await this.callOperation('Link entity taxonomy', (0, sdk_gen_1.opLinkEntityTaxonomy)({ path: { graph_id: graphId }, body }));
157
111
  return (envelope.result ?? {});
158
112
  }
113
+ /**
114
+ * Create a taxonomy block atomically (taxonomy + structures + elements +
115
+ * associations + rules in one envelope).
116
+ */
117
+ async createTaxonomyBlock(graphId, body, idempotencyKey) {
118
+ const headers = idempotencyKey ? { 'Idempotency-Key': idempotencyKey } : undefined;
119
+ const envelope = await this.callOperation('Create taxonomy block', (0, sdk_gen_1.opCreateTaxonomyBlock)({ path: { graph_id: graphId }, body, headers }));
120
+ return (envelope.result ?? {});
121
+ }
122
+ /** Update a taxonomy block — add/update/remove elements, structures, associations, or rules. */
123
+ async updateTaxonomyBlock(graphId, body) {
124
+ const envelope = await this.callOperation('Update taxonomy block', (0, sdk_gen_1.opUpdateTaxonomyBlock)({ path: { graph_id: graphId }, body }));
125
+ return (envelope.result ?? {});
126
+ }
127
+ /** Delete a taxonomy block. Cascades through elements, structures, and associations. */
128
+ async deleteTaxonomyBlock(graphId, body) {
129
+ const envelope = await this.callOperation('Delete taxonomy block', (0, sdk_gen_1.opDeleteTaxonomyBlock)({ path: { graph_id: graphId }, body }));
130
+ return (envelope.result ?? { deleted: true });
131
+ }
159
132
  /** List elements (CoA accounts, GAAP concepts, etc.) with filters. */
160
133
  async listElements(graphId, options) {
161
134
  return this.gqlQuery(graphId, graphql_1.ListLedgerElementsDocument, {
@@ -171,22 +144,6 @@ class LedgerClient {
171
144
  async listUnmappedElements(graphId, options) {
172
145
  return this.gqlQuery(graphId, graphql_1.ListLedgerUnmappedElementsDocument, { mappingId: options?.mappingId ?? null }, 'List unmapped elements', (data) => data.unmappedElements);
173
146
  }
174
- /** Create a new element within a taxonomy (native CoA account, etc.). */
175
- async createElement(graphId, body) {
176
- const envelope = await this.callOperation('Create element', (0, sdk_gen_1.opCreateElement)({ path: { graph_id: graphId }, body }));
177
- return (envelope.result ?? {});
178
- }
179
- /** Update mutable fields on an element. `taxonomy_id` and `source` are immutable. */
180
- async updateElement(graphId, body) {
181
- const envelope = await this.callOperation('Update element', (0, sdk_gen_1.opUpdateElement)({ path: { graph_id: graphId }, body }));
182
- return (envelope.result ?? {});
183
- }
184
- /** Soft-delete an element (`is_active=false`). */
185
- async deleteElement(graphId, elementId) {
186
- const body = { element_id: elementId };
187
- const envelope = await this.callOperation('Delete element', (0, sdk_gen_1.opDeleteElement)({ path: { graph_id: graphId }, body }));
188
- return (envelope.result ?? {});
189
- }
190
147
  // ── Structures ──────────────────────────────────────────────────────
191
148
  /** List reporting structures (IS, BS, CF, schedules) with optional filters. */
192
149
  async listStructures(graphId, options) {
@@ -196,36 +153,6 @@ class LedgerClient {
196
153
  }, 'List structures', (data) => data.structures);
197
154
  return list?.structures ?? [];
198
155
  }
199
- /**
200
- * Create a new structure. Most common use is a CoA→reporting mapping
201
- * structure; also used for custom statement + schedule structures.
202
- */
203
- async createStructure(graphId, body) {
204
- const envelope = await this.callOperation('Create structure', (0, sdk_gen_1.opCreateStructure)({ path: { graph_id: graphId }, body }));
205
- return envelope.result;
206
- }
207
- /** Convenience wrapper — create a CoA→GAAP mapping structure. */
208
- async createMappingStructure(graphId, options) {
209
- const body = {
210
- name: options?.name ?? 'CoA to Reporting',
211
- structure_type: 'coa_mapping',
212
- taxonomy_id: options?.taxonomyId ?? 'tax_usgaap_reporting',
213
- description: options?.description ?? 'Map Chart of Accounts to US GAAP reporting concepts',
214
- };
215
- const envelope = await this.callOperation('Create mapping structure', (0, sdk_gen_1.opCreateStructure)({ path: { graph_id: graphId }, body }));
216
- return envelope.result;
217
- }
218
- /** Update mutable fields on a structure. `structure_type` is immutable. */
219
- async updateStructure(graphId, body) {
220
- const envelope = await this.callOperation('Update structure', (0, sdk_gen_1.opUpdateStructure)({ path: { graph_id: graphId }, body }));
221
- return (envelope.result ?? {});
222
- }
223
- /** Soft-delete a structure (`is_active=false`). */
224
- async deleteStructure(graphId, structureId) {
225
- const body = { structure_id: structureId };
226
- const envelope = await this.callOperation('Delete structure', (0, sdk_gen_1.opDeleteStructure)({ path: { graph_id: graphId }, body }));
227
- return (envelope.result ?? {});
228
- }
229
156
  // ── Mappings ────────────────────────────────────────────────────────
230
157
  /** List active CoA→reporting mapping structures. */
231
158
  async listMappings(graphId) {
@@ -259,23 +186,6 @@ class LedgerClient {
259
186
  const envelope = await this.callOperation('Auto-map elements', (0, sdk_gen_1.opAutoMapElements)({ path: { graph_id: graphId }, body }));
260
187
  return { operationId: envelope.operationId, status: envelope.status };
261
188
  }
262
- /** Bulk create associations within a single structure, atomically. */
263
- async createAssociations(graphId, structureId, associations) {
264
- const body = { structure_id: structureId, associations };
265
- const envelope = await this.callOperation('Create associations', (0, sdk_gen_1.opCreateAssociations)({ path: { graph_id: graphId }, body }));
266
- return (envelope.result ?? {});
267
- }
268
- /** Update mutable fields on an association (order, weight, confidence). */
269
- async updateAssociation(graphId, body) {
270
- const envelope = await this.callOperation('Update association', (0, sdk_gen_1.opUpdateAssociation)({ path: { graph_id: graphId }, body }));
271
- return (envelope.result ?? {});
272
- }
273
- /** Hard-delete an association (any type: presentation, calculation, mapping). */
274
- async deleteAssociation(graphId, associationId) {
275
- const body = { association_id: associationId };
276
- const envelope = await this.callOperation('Delete association', (0, sdk_gen_1.opDeleteAssociation)({ path: { graph_id: graphId }, body }));
277
- return (envelope.result ?? { deleted: true });
278
- }
279
189
  // ── Information Blocks ─────────────────────────────────────────────
280
190
  /**
281
191
  * Fetch an Information Block envelope by id — the generic
@@ -357,21 +267,36 @@ class LedgerClient {
357
267
  const envelope = await this.callOperation('Delete schedule', (0, sdk_gen_1.opDeleteInformationBlock)({ path: { graph_id: graphId }, body }));
358
268
  return (envelope.result ?? { deleted: true });
359
269
  }
360
- /** Truncate a schedule — end it early at `newEndDate`. */
361
- async truncateSchedule(graphId, structureId, options) {
270
+ /**
271
+ * Dispose of a schedule asset — atomically truncates forward facts,
272
+ * deletes the SumEquals rule, and posts a balanced disposal entry.
273
+ *
274
+ * Routes through `create-event-block` with `event_type='asset_disposed'`.
275
+ * `occurred_at` is required and represents the disposal date.
276
+ */
277
+ async disposeSchedule(graphId, options) {
362
278
  const body = {
363
- structure_id: structureId,
364
- new_end_date: options.newEndDate,
365
- reason: options.reason,
366
- };
367
- const envelope = await this.callOperation('Truncate schedule', (0, sdk_gen_1.opTruncateSchedule)({ path: { graph_id: graphId }, body }));
368
- const raw = envelope.result;
369
- return {
370
- structureId: raw.structure_id,
371
- newEndDate: raw.new_end_date,
372
- factsDeleted: raw.facts_deleted,
373
- reason: raw.reason,
279
+ event_type: 'asset_disposed',
280
+ event_category: 'adjustment',
281
+ source: 'native',
282
+ occurred_at: options.occurredAt,
283
+ apply_handlers: true,
284
+ metadata: {
285
+ schedule_id: options.scheduleId,
286
+ proceeds: options.proceeds ?? 0,
287
+ proceeds_element_id: options.proceedsElementId ?? null,
288
+ gain_loss_element_id: options.gainLossElementId ?? null,
289
+ memo: options.memo ?? null,
290
+ reason: options.reason ?? 'asset_disposed_event',
291
+ },
374
292
  };
293
+ const envelope = await this.callOperation('Dispose schedule', (0, sdk_gen_1.opCreateEventBlock)({ path: { graph_id: graphId }, body }));
294
+ return (envelope.result ?? {});
295
+ }
296
+ /** Evaluate taxonomy rules against facts in a structure. */
297
+ async evaluateRules(graphId, body) {
298
+ const envelope = await this.callOperation('Evaluate rules', (0, sdk_gen_1.opEvaluateRules)({ path: { graph_id: graphId }, body }));
299
+ return (envelope.result ?? {});
375
300
  }
376
301
  // ── Period close ────────────────────────────────────────────────────
377
302
  /** Close status for all schedules in a fiscal period. */
@@ -384,37 +309,30 @@ class LedgerClient {
384
309
  }
385
310
  /**
386
311
  * Idempotently create (or refresh) a draft closing entry from a
387
- * schedule for a period. See `ClosingEntryOutcome` for semantics.
312
+ * schedule for a period.
313
+ *
314
+ * Routes through `create-event-block` with
315
+ * `event_type='schedule_entry_due'`. Returns the EventBlockEnvelope —
316
+ * the underlying handler is idempotent and dispatches to one of
317
+ * created / unchanged / regenerated / removed / skipped internally.
388
318
  */
389
319
  async createClosingEntry(graphId, structureId, postingDate, periodStart, periodEnd, memo) {
390
320
  const body = {
391
- structure_id: structureId,
392
- posting_date: postingDate,
393
- period_start: periodStart,
394
- period_end: periodEnd,
395
- memo: memo ?? undefined,
396
- };
397
- const envelope = await this.callOperation('Create closing entry', (0, sdk_gen_1.opCreateClosingEntry)({ path: { graph_id: graphId }, body }));
398
- return rawToClosingEntry(envelope.result);
399
- }
400
- /**
401
- * Create a manual balanced closing entry (not tied to a schedule).
402
- * Used for disposals, adjustments, and one-off closing events.
403
- */
404
- async createManualClosingEntry(graphId, options) {
405
- const body = {
406
- posting_date: options.postingDate,
407
- memo: options.memo,
408
- entry_type: options.entryType,
409
- line_items: options.lineItems.map((li) => ({
410
- element_id: li.elementId,
411
- debit_amount: li.debitAmount ?? 0,
412
- credit_amount: li.creditAmount ?? 0,
413
- description: li.description ?? null,
414
- })),
321
+ event_type: 'schedule_entry_due',
322
+ event_category: 'recognition',
323
+ source: 'scheduled',
324
+ occurred_at: `${postingDate}T00:00:00Z`,
325
+ apply_handlers: true,
326
+ metadata: {
327
+ schedule_id: structureId,
328
+ posting_date: postingDate,
329
+ period_start: periodStart,
330
+ period_end: periodEnd,
331
+ memo: memo ?? null,
332
+ },
415
333
  };
416
- const envelope = await this.callOperation('Create manual closing entry', (0, sdk_gen_1.opCreateManualClosingEntry)({ path: { graph_id: graphId }, body }));
417
- return rawToClosingEntry(envelope.result);
334
+ const envelope = await this.callOperation('Create closing entry', (0, sdk_gen_1.opCreateEventBlock)({ path: { graph_id: graphId }, body }));
335
+ return (envelope.result ?? {});
418
336
  }
419
337
  // ── Closing book ───────────────────────────────────────────────────
420
338
  /** Grouped closing book structures for the close-screen sidebar. */
@@ -479,28 +397,43 @@ class LedgerClient {
479
397
  /**
480
398
  * Create a journal entry with balanced line items (DR=CR enforced).
481
399
  *
482
- * Defaults to `status='draft'`. Pass `status='posted'` for historical
483
- * data import where entries represent already-happened business events.
400
+ * Routes through `create-event-block` with
401
+ * `event_type='journal_entry_recorded'` the Python handler forwards
402
+ * to the internal journal-entry command. Defaults to `status='draft'`;
403
+ * pass `status='posted'` for historical data imports.
484
404
  *
485
405
  * Supply `idempotencyKey` to make the call safe to retry — replays
486
406
  * within 24 hours return the same envelope. Reusing the key with a
487
407
  * different body returns HTTP 409.
408
+ *
409
+ * Returns the EventBlockEnvelope (event row fields); query the ledger
410
+ * separately if you need the resulting entry_id.
488
411
  */
489
412
  async createJournalEntry(graphId, options) {
490
413
  const body = {
491
- posting_date: options.postingDate,
492
- memo: options.memo,
493
- line_items: options.lineItems.map((li) => ({
494
- element_id: li.elementId,
495
- debit_amount: li.debitAmount,
496
- credit_amount: li.creditAmount,
497
- description: li.description ?? null,
498
- })),
499
- type: options.type,
500
- status: options.status,
501
- transaction_id: options.transactionId ?? null,
414
+ event_type: 'journal_entry_recorded',
415
+ event_category: 'adjustment',
416
+ source: 'native',
417
+ occurred_at: `${options.postingDate}T00:00:00Z`,
418
+ apply_handlers: true,
419
+ metadata: {
420
+ posting_date: options.postingDate,
421
+ memo: options.memo,
422
+ line_items: options.lineItems.map((li) => ({
423
+ element_id: li.elementId,
424
+ debit_amount: li.debitAmount,
425
+ credit_amount: li.creditAmount,
426
+ description: li.description ?? null,
427
+ })),
428
+ type: options.type ?? 'standard',
429
+ status: options.status ?? 'draft',
430
+ transaction_id: options.transactionId ?? null,
431
+ },
502
432
  };
503
- const envelope = await this.callOperation('Create journal entry', (0, sdk_gen_1.opCreateJournalEntry)({ path: { graph_id: graphId }, body }));
433
+ const headers = options.idempotencyKey
434
+ ? { 'Idempotency-Key': options.idempotencyKey }
435
+ : undefined;
436
+ const envelope = await this.callOperation('Create journal entry', (0, sdk_gen_1.opCreateEventBlock)({ path: { graph_id: graphId }, body, headers }));
504
437
  return (envelope.result ?? {});
505
438
  }
506
439
  /** Update a draft journal entry. Posted entries are immutable. */
@@ -517,14 +450,109 @@ class LedgerClient {
517
450
  /**
518
451
  * Reverse a posted journal entry — creates an offsetting entry and marks
519
452
  * the original as reversed.
453
+ *
454
+ * Routes through `create-event-block` with
455
+ * `event_type='journal_entry_reversed'`.
520
456
  */
521
457
  async reverseJournalEntry(graphId, entryId, options) {
458
+ const occurredDate = options?.postingDate ?? new Date().toISOString().slice(0, 10);
522
459
  const body = {
523
- entry_id: entryId,
524
- posting_date: options?.postingDate ?? null,
525
- memo: options?.memo ?? null,
460
+ event_type: 'journal_entry_reversed',
461
+ event_category: 'adjustment',
462
+ source: 'native',
463
+ occurred_at: `${occurredDate}T00:00:00Z`,
464
+ apply_handlers: true,
465
+ metadata: {
466
+ entry_id: entryId,
467
+ posting_date: options?.postingDate ?? null,
468
+ memo: options?.memo ?? null,
469
+ reason: options?.reason ?? null,
470
+ },
526
471
  };
527
- const envelope = await this.callOperation('Reverse journal entry', (0, sdk_gen_1.opReverseJournalEntry)({ path: { graph_id: graphId }, body }));
472
+ const envelope = await this.callOperation('Reverse journal entry', (0, sdk_gen_1.opCreateEventBlock)({ path: { graph_id: graphId }, body }));
473
+ return (envelope.result ?? {});
474
+ }
475
+ // ── Event blocks (generic preview + status transitions) ──────────────
476
+ /**
477
+ * Dry-run an event block — resolve the handler, evaluate metadata, and
478
+ * return the planned GL rows without writing anything. Companion to
479
+ * `createJournalEntry` / `reverseJournalEntry` / `createClosingEntry` /
480
+ * `disposeSchedule`: pass the same body you'd send to those methods
481
+ * (the underlying `CreateEventBlockRequest`) and inspect what the
482
+ * handler would do.
483
+ */
484
+ async previewEventBlock(graphId, body) {
485
+ const envelope = await this.callOperation('Preview event block', (0, sdk_gen_1.opPreviewEventBlock)({ path: { graph_id: graphId }, body }));
486
+ return (envelope.result ?? {});
487
+ }
488
+ /**
489
+ * Apply a status transition and/or field corrections to an existing
490
+ * event block. Use for posting drafts (`classified` → `committed` →
491
+ * `fulfilled`), voiding, superseding (correction chains), or patching
492
+ * `description` / `effective_at` / `metadata`.
493
+ */
494
+ async updateEventBlock(graphId, body) {
495
+ const envelope = await this.callOperation('Update event block', (0, sdk_gen_1.opUpdateEventBlock)({ path: { graph_id: graphId }, body }));
496
+ return (envelope.result ?? {});
497
+ }
498
+ // ── Agents (REA counterparties) ───────────────────────────────────────
499
+ /**
500
+ * Create an agent — REA counterparty (customer, vendor, employee, etc.)
501
+ * referenced by event blocks via `agent_id`. `(source, external_id)` is
502
+ * unique when `external_id` is provided, so external-source ingestion is
503
+ * idempotent at the DB level.
504
+ */
505
+ async createAgent(graphId, body, idempotencyKey) {
506
+ const headers = idempotencyKey ? { 'Idempotency-Key': idempotencyKey } : undefined;
507
+ const envelope = await this.callOperation('Create agent', (0, sdk_gen_1.opCreateAgent)({ path: { graph_id: graphId }, body, headers }));
508
+ return (envelope.result ?? {});
509
+ }
510
+ /**
511
+ * Update an agent. `metadata_patch` is a partial merge into the existing
512
+ * metadata object; all other fields replace.
513
+ */
514
+ async updateAgent(graphId, body) {
515
+ const envelope = await this.callOperation('Update agent', (0, sdk_gen_1.opUpdateAgent)({ path: { graph_id: graphId }, body }));
516
+ return (envelope.result ?? {});
517
+ }
518
+ // ── Event handlers (DSL handler registry) ────────────────────────────
519
+ /**
520
+ * Register a tenant-configurable event handler — DSL row in the
521
+ * `event_handlers` table that drives `create-event-block` for event
522
+ * types not covered by a Python handler. Match selectors plus a
523
+ * `transaction_template` describing the GL rows to produce.
524
+ */
525
+ async createEventHandler(graphId, body) {
526
+ const envelope = await this.callOperation('Create event handler', (0, sdk_gen_1.opCreateEventHandler)({ path: { graph_id: graphId }, body }));
527
+ return (envelope.result ?? {});
528
+ }
529
+ /**
530
+ * Update a registered event handler. Pass `approve: true` to flip an
531
+ * AI-suggested handler from unapproved to active.
532
+ */
533
+ async updateEventHandler(graphId, body) {
534
+ const envelope = await this.callOperation('Update event handler', (0, sdk_gen_1.opUpdateEventHandler)({ path: { graph_id: graphId }, body }));
535
+ return (envelope.result ?? {});
536
+ }
537
+ // ── Financial statements (graph-backed) ──────────────────────────────
538
+ /**
539
+ * Live financial statement — pulls facts directly from the graph for
540
+ * an explicit period window (or fiscal year) and returns the statement
541
+ * shape without a persisted Report row. Useful for ad-hoc previews and
542
+ * dashboards.
543
+ */
544
+ async liveFinancialStatement(graphId, body) {
545
+ const envelope = await this.callOperation('Live financial statement', (0, sdk_gen_1.opLiveFinancialStatement)({ path: { graph_id: graphId }, body }));
546
+ return (envelope.result ?? {});
547
+ }
548
+ /**
549
+ * Run a financial statement analysis against an existing report.
550
+ * On shared-repo graphs (e.g. SEC), `ticker` is required; on tenant
551
+ * graphs it's ignored. Either pass an explicit `report_id` or let the
552
+ * server auto-resolve via `fiscal_year` + `period_type`.
553
+ */
554
+ async financialStatementAnalysis(graphId, body) {
555
+ const envelope = await this.callOperation('Financial statement analysis', (0, sdk_gen_1.opFinancialStatementAnalysis)({ path: { graph_id: graphId }, body }));
528
556
  return (envelope.result ?? {});
529
557
  }
530
558
  // ── Fact grid (graph-backed analytical query) ─────────────────────
@@ -730,19 +758,6 @@ class LedgerClient {
730
758
  }
731
759
  exports.LedgerClient = LedgerClient;
732
760
  // ── Module-private conversion helpers ─────────────────────────────────
733
- function rawToClosingEntry(data) {
734
- return {
735
- outcome: data.outcome,
736
- entryId: data.entry_id ?? null,
737
- status: data.status ?? null,
738
- postingDate: data.posting_date ?? null,
739
- memo: data.memo ?? null,
740
- debitElementId: data.debit_element_id ?? null,
741
- creditElementId: data.credit_element_id ?? null,
742
- amount: data.amount ?? null,
743
- reason: data.reason ?? null,
744
- };
745
- }
746
761
  function rawFiscalCalendarToCamel(raw) {
747
762
  return {
748
763
  graphId: raw.graph_id,