@ekwo-ai/core 0.4.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.
- package/README.md +76 -0
- package/dist/books/backend.d.ts +118 -0
- package/dist/books/backend.d.ts.map +1 -0
- package/dist/books/backend.js +69 -0
- package/dist/books/backend.js.map +1 -0
- package/dist/books/columns.d.ts +68 -0
- package/dist/books/columns.d.ts.map +1 -0
- package/dist/books/columns.js +466 -0
- package/dist/books/columns.js.map +1 -0
- package/dist/books/contacts.d.ts +43 -0
- package/dist/books/contacts.d.ts.map +1 -0
- package/dist/books/contacts.js +67 -0
- package/dist/books/contacts.js.map +1 -0
- package/dist/books/documents.d.ts +87 -0
- package/dist/books/documents.d.ts.map +1 -0
- package/dist/books/documents.js +413 -0
- package/dist/books/documents.js.map +1 -0
- package/dist/books/format.d.ts +21 -0
- package/dist/books/format.d.ts.map +1 -0
- package/dist/books/format.js +49 -0
- package/dist/books/format.js.map +1 -0
- package/dist/books/index.d.ts +18 -0
- package/dist/books/index.d.ts.map +1 -0
- package/dist/books/index.js +18 -0
- package/dist/books/index.js.map +1 -0
- package/dist/books/payments.d.ts +57 -0
- package/dist/books/payments.d.ts.map +1 -0
- package/dist/books/payments.js +255 -0
- package/dist/books/payments.js.map +1 -0
- package/dist/books/rounding.d.ts +25 -0
- package/dist/books/rounding.d.ts.map +1 -0
- package/dist/books/rounding.js +35 -0
- package/dist/books/rounding.js.map +1 -0
- package/dist/books/shared.d.ts +33 -0
- package/dist/books/shared.d.ts.map +1 -0
- package/dist/books/shared.js +98 -0
- package/dist/books/shared.js.map +1 -0
- package/dist/client.d.ts +73 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +138 -0
- package/dist/client.js.map +1 -0
- package/dist/fec.d.ts +14 -0
- package/dist/fec.d.ts.map +1 -0
- package/dist/fec.js +13 -0
- package/dist/fec.js.map +1 -0
- package/dist/identity.d.ts +46 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +62 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/refusal.d.ts +27 -0
- package/dist/refusal.d.ts.map +1 -0
- package/dist/refusal.js +38 -0
- package/dist/refusal.js.map +1 -0
- package/dist/schema.d.ts +23 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +42 -0
- package/dist/schema.js.map +1 -0
- package/dist/types.d.ts +466 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +170 -0
- package/dist/types.js.map +1 -0
- package/package.json +34 -0
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payments and matching.
|
|
3
|
+
*
|
|
4
|
+
* `post_payment`, `reconcile` and `unreconcile` carry the rules and this file
|
|
5
|
+
* calls them. The one thing decided here is which open items a payment is
|
|
6
|
+
* offered to, oldest first — never how much is owed, which the ledger says.
|
|
7
|
+
*/
|
|
8
|
+
import { BooksError } from './backend.js';
|
|
9
|
+
import * as columns from './columns.js';
|
|
10
|
+
import { amountIn, moneyFields } from './format.js';
|
|
11
|
+
import { companyCurrency, createdBefore, idsByCode, only } from './shared.js';
|
|
12
|
+
/** What is still open on one document, as `open_items()` reports it. */
|
|
13
|
+
async function openItemsOf(backend, company, documentId) {
|
|
14
|
+
const items = await backend.rpc('open_items', { p_company_id: company });
|
|
15
|
+
const open = items.filter((item) => item.document_id === documentId);
|
|
16
|
+
if (open.length === 0) {
|
|
17
|
+
throw new BooksError(`nothing_open: document ${documentId} has no open item. Either it is not posted yet, or it is already settled, or it is not visible to you.`);
|
|
18
|
+
}
|
|
19
|
+
return open;
|
|
20
|
+
}
|
|
21
|
+
export async function recordPayment(backend, args) {
|
|
22
|
+
const before = await createdBefore(backend, 'payments', args.company_id, args.client_ref, ['id', 'entry_id']);
|
|
23
|
+
// A payment of a document: who and which way are read off its open item,
|
|
24
|
+
// which the ledger holds, rather than deduced from the kind of document.
|
|
25
|
+
// Recorded before under this reference, the document may well have nothing
|
|
26
|
+
// open any more — that is what the first call was for — so nothing open is
|
|
27
|
+
// then not a refusal.
|
|
28
|
+
let paid;
|
|
29
|
+
if (args.document_id !== undefined) {
|
|
30
|
+
try {
|
|
31
|
+
paid = await openItemsOf(backend, args.company_id, args.document_id);
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
if (before === undefined)
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const contactId = args.contact_id ?? paid?.[0]?.contact_id ?? undefined;
|
|
39
|
+
const direction = args.direction ?? (paid === undefined ? undefined : paid[0]?.side === 'debit' ? 'inbound' : 'outbound');
|
|
40
|
+
if (direction === undefined && before === undefined) {
|
|
41
|
+
throw new BooksError('missing_direction: a payment is inbound or outbound — say which, or give document_id and the open item says it.');
|
|
42
|
+
}
|
|
43
|
+
let journalId = args.journal_id;
|
|
44
|
+
if (journalId === undefined && args.journal_code !== undefined) {
|
|
45
|
+
journalId = (await idsByCode(backend, 'journals', args.company_id, [args.journal_code])).get(args.journal_code);
|
|
46
|
+
}
|
|
47
|
+
if (journalId === undefined && args.bank_account_id !== undefined) {
|
|
48
|
+
// A bank account knows the journal it moves through; asking the caller
|
|
49
|
+
// to repeat it was the first thing the real test tripped over.
|
|
50
|
+
const account = await backend.select({
|
|
51
|
+
table: 'bank_accounts',
|
|
52
|
+
columns: ['journal_id'],
|
|
53
|
+
where: [
|
|
54
|
+
{ column: 'id', op: 'eq', value: args.bank_account_id },
|
|
55
|
+
{ column: 'company_id', op: 'eq', value: args.company_id },
|
|
56
|
+
],
|
|
57
|
+
});
|
|
58
|
+
journalId = account[0]?.journal_id ?? undefined;
|
|
59
|
+
}
|
|
60
|
+
if (journalId === undefined && before === undefined) {
|
|
61
|
+
throw new BooksError('missing_journal: a payment needs the bank or cash book it goes through — give bank_account_id (list_bank_accounts), or journal_id / journal_code (get_company lists the journals).');
|
|
62
|
+
}
|
|
63
|
+
// Recorded before under this reference: nothing is inserted, and what a
|
|
64
|
+
// dropped connection left undone — the booking, the matching — is finished.
|
|
65
|
+
const payment = before ?? only(await backend.insert('payments', [
|
|
66
|
+
{
|
|
67
|
+
company_id: args.company_id,
|
|
68
|
+
direction,
|
|
69
|
+
payment_date: args.payment_date,
|
|
70
|
+
amount: amountIn(args.amount),
|
|
71
|
+
// Never a literal, for the reason `create_document` gives: a company
|
|
72
|
+
// that keeps its books in another currency would get a euro payment
|
|
73
|
+
// out of a euro written here.
|
|
74
|
+
currency_code: args.currency_code ?? (await companyCurrency(backend, args.company_id)),
|
|
75
|
+
exchange_rate: args.exchange_rate === undefined ? 1 : String(args.exchange_rate),
|
|
76
|
+
contact_id: contactId ?? null,
|
|
77
|
+
journal_id: journalId,
|
|
78
|
+
bank_account_id: args.bank_account_id ?? null,
|
|
79
|
+
reference: args.reference ?? null,
|
|
80
|
+
memo: args.memo ?? null,
|
|
81
|
+
client_ref: args.client_ref ?? null,
|
|
82
|
+
},
|
|
83
|
+
], ['id']), 'the payment could not be created');
|
|
84
|
+
const booked = typeof payment['entry_id'] === 'string' ? payment['entry_id'] : undefined;
|
|
85
|
+
const entry = only(booked === undefined
|
|
86
|
+
? moneyFields(await backend.rpc('post_payment', { p_payment_id: payment['id'] }), [
|
|
87
|
+
'total_debit',
|
|
88
|
+
'total_credit',
|
|
89
|
+
])
|
|
90
|
+
: await backend.select({
|
|
91
|
+
table: 'entries',
|
|
92
|
+
columns: columns.ENTRY,
|
|
93
|
+
where: [{ column: 'id', op: 'eq', value: booked }],
|
|
94
|
+
}), 'the payment produced no entry');
|
|
95
|
+
const lines = await backend.select({
|
|
96
|
+
table: 'entry_lines',
|
|
97
|
+
columns: columns.ENTRY_LINE,
|
|
98
|
+
where: [{ column: 'entry_id', op: 'eq', value: entry['id'] }],
|
|
99
|
+
order: [{ column: 'sequence' }],
|
|
100
|
+
});
|
|
101
|
+
const matched = args.match_open_items === false || contactId === undefined || (args.document_id !== undefined && paid === undefined)
|
|
102
|
+
? []
|
|
103
|
+
: await matchOpenItems(backend, args.company_id, contactId, lines, paid === undefined ? undefined : new Set(paid.map((item) => item.line_id)));
|
|
104
|
+
const settled = await backend.select({
|
|
105
|
+
table: 'payments',
|
|
106
|
+
columns: columns.PAYMENT,
|
|
107
|
+
where: [{ column: 'id', op: 'eq', value: payment['id'] }],
|
|
108
|
+
});
|
|
109
|
+
return {
|
|
110
|
+
payment: settled[0] ?? null,
|
|
111
|
+
entry,
|
|
112
|
+
entry_lines: lines,
|
|
113
|
+
matched,
|
|
114
|
+
...(before === undefined ? {} : { replayed: true }),
|
|
115
|
+
note: contactId === undefined
|
|
116
|
+
? 'No contact was given, so the payment landed on the company default third-party account and nothing was matched.'
|
|
117
|
+
: 'Matching is what makes a document paid: documents.amount_paid is derived from it.',
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Matches the payment against the open items of a contact, oldest first.
|
|
122
|
+
*
|
|
123
|
+
* Only lines on the same third-party account, on the other side, still
|
|
124
|
+
* carrying a residual. Each pairing is a call to `reconcile`, which is what
|
|
125
|
+
* draws the letter and keeps the residual honest; this function decides
|
|
126
|
+
* nothing about amounts beyond "the smaller of what is left on either side".
|
|
127
|
+
*/
|
|
128
|
+
async function matchOpenItems(backend, company, contact, paymentLines, among) {
|
|
129
|
+
const accounts = await backend.select({
|
|
130
|
+
table: 'accounts',
|
|
131
|
+
columns: ['id', 'reconcilable'],
|
|
132
|
+
where: [
|
|
133
|
+
{
|
|
134
|
+
column: 'id',
|
|
135
|
+
op: 'in',
|
|
136
|
+
value: paymentLines
|
|
137
|
+
.map((line) => line['account_id'])
|
|
138
|
+
.filter((id) => typeof id === 'string'),
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
});
|
|
142
|
+
const reconcilable = new Set(accounts.filter((account) => account.reconcilable).map((a) => a.id));
|
|
143
|
+
const paymentLine = paymentLines.find((line) => typeof line['account_id'] === 'string' && reconcilable.has(line['account_id']));
|
|
144
|
+
if (paymentLine === undefined)
|
|
145
|
+
return [];
|
|
146
|
+
const accountId = paymentLine['account_id'];
|
|
147
|
+
const paymentIsDebit = Number(paymentLine['debit'] ?? 0) > 0;
|
|
148
|
+
const candidates = await backend.select({
|
|
149
|
+
table: 'entry_lines',
|
|
150
|
+
columns: [...columns.ENTRY_LINE, 'company_id'],
|
|
151
|
+
where: [
|
|
152
|
+
{ column: 'company_id', op: 'eq', value: company },
|
|
153
|
+
{ column: 'contact_id', op: 'eq', value: contact },
|
|
154
|
+
{ column: 'account_id', op: 'eq', value: accountId },
|
|
155
|
+
],
|
|
156
|
+
limit: 500,
|
|
157
|
+
});
|
|
158
|
+
const entryIds = [...new Set(candidates.map((line) => line['entry_id']))];
|
|
159
|
+
const entries = await backend.select({
|
|
160
|
+
table: 'entries',
|
|
161
|
+
columns: ['id', 'state', 'entry_date::text'],
|
|
162
|
+
where: [{ column: 'id', op: 'in', value: entryIds }],
|
|
163
|
+
});
|
|
164
|
+
const posted = new Map(entries.filter((entry) => entry.state === 'posted').map((e) => [e.id, e]));
|
|
165
|
+
// Which scale the allocation is worked out on. `reconcile` matches two
|
|
166
|
+
// lines in the same foreign currency in *that* currency, because that is
|
|
167
|
+
// where they are equal, and reads `p_amount` the same way. So when the
|
|
168
|
+
// payment is foreign the amounts below are its currency's, and a candidate
|
|
169
|
+
// in another currency is left alone rather than matched at the wrong scale.
|
|
170
|
+
const home = await companyCurrency(backend, company);
|
|
171
|
+
const currency = paymentLine['currency_code'];
|
|
172
|
+
const foreign = currency !== null && currency !== home && paymentLine['amount_currency'] !== null;
|
|
173
|
+
/** What is still open on a line, on the scale the matching uses. */
|
|
174
|
+
const openOf = (line) => {
|
|
175
|
+
const ledger = Math.abs(Number(line['balance'] ?? 0));
|
|
176
|
+
const left = ledger - Number(line['matched_amount'] ?? 0);
|
|
177
|
+
if (!foreign)
|
|
178
|
+
return left;
|
|
179
|
+
const inCurrency = Math.abs(Number(line['amount_currency'] ?? 0));
|
|
180
|
+
return ledger === 0 ? 0 : Math.round((inCurrency * left * 100) / ledger) / 100;
|
|
181
|
+
};
|
|
182
|
+
const open = candidates
|
|
183
|
+
.filter((line) => line['id'] !== paymentLine['id'])
|
|
184
|
+
.filter((line) => among === undefined || among.has(line['id']))
|
|
185
|
+
.filter((line) => posted.has(line['entry_id']))
|
|
186
|
+
.filter((line) => (Number(line['debit'] ?? 0) > 0) !== paymentIsDebit)
|
|
187
|
+
.filter((line) => !foreign || line['currency_code'] === currency)
|
|
188
|
+
.map((line) => ({
|
|
189
|
+
line,
|
|
190
|
+
residual: openOf(line),
|
|
191
|
+
due: String(line['date_maturity'] ?? posted.get(line['entry_id'])?.entry_date ?? ''),
|
|
192
|
+
}))
|
|
193
|
+
.filter((item) => item.residual > 0.005)
|
|
194
|
+
.sort((a, b) => a.due.localeCompare(b.due));
|
|
195
|
+
let remaining = openOf(paymentLine);
|
|
196
|
+
const done = [];
|
|
197
|
+
for (const item of open) {
|
|
198
|
+
if (remaining <= 0.005)
|
|
199
|
+
break;
|
|
200
|
+
const amount = Math.min(remaining, item.residual).toFixed(2);
|
|
201
|
+
const reconciliation = moneyFields(await backend.rpc('reconcile', {
|
|
202
|
+
p_line_a: paymentLine['id'],
|
|
203
|
+
p_line_b: item.line['id'],
|
|
204
|
+
p_amount: amount,
|
|
205
|
+
}), ['amount']);
|
|
206
|
+
done.push(reconciliation[0] ?? null);
|
|
207
|
+
remaining -= Number(amount);
|
|
208
|
+
}
|
|
209
|
+
return done;
|
|
210
|
+
}
|
|
211
|
+
export async function reconcile(backend, args) {
|
|
212
|
+
const rows = moneyFields(await backend.rpc('reconcile', {
|
|
213
|
+
p_line_a: args.line_a,
|
|
214
|
+
p_line_b: args.line_b,
|
|
215
|
+
p_amount: args.amount === undefined ? null : amountIn(args.amount),
|
|
216
|
+
}), ['amount']);
|
|
217
|
+
return { reconciliation: rows[0] ?? null };
|
|
218
|
+
}
|
|
219
|
+
export async function unreconcile(backend, args) {
|
|
220
|
+
await backend.rpcVoid('unreconcile', { p_reconciliation_id: args.reconciliation_id });
|
|
221
|
+
return {
|
|
222
|
+
unreconciled: args.reconciliation_id,
|
|
223
|
+
note: 'The matching is undone. The entries themselves are untouched: matching changes no account.',
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* A statement line pays a document: `settle_from_statement()` books the
|
|
228
|
+
* payment the line is and matches it against the open items named. Naming a
|
|
229
|
+
* document names what is open on it; nothing here chooses between candidates.
|
|
230
|
+
*/
|
|
231
|
+
export async function settleFromStatement(backend, args) {
|
|
232
|
+
let lineIds = args.line_ids;
|
|
233
|
+
if (lineIds === undefined || lineIds.length === 0) {
|
|
234
|
+
if (args.document_id === undefined) {
|
|
235
|
+
throw new BooksError('no_lines_named: settling needs the document this money pays, or the open items themselves.');
|
|
236
|
+
}
|
|
237
|
+
const transaction = only(await backend.select({
|
|
238
|
+
table: 'bank_transactions',
|
|
239
|
+
columns: ['company_id'],
|
|
240
|
+
where: [{ column: 'id', op: 'eq', value: args.transaction_id }],
|
|
241
|
+
}), `bank transaction ${args.transaction_id}`);
|
|
242
|
+
lineIds = (await openItemsOf(backend, transaction.company_id, args.document_id)).map((item) => item.line_id);
|
|
243
|
+
}
|
|
244
|
+
await backend.rpc('settle_from_statement', {
|
|
245
|
+
p_transaction_id: args.transaction_id,
|
|
246
|
+
p_line_ids: lineIds,
|
|
247
|
+
});
|
|
248
|
+
const settled = await backend.select({
|
|
249
|
+
table: 'bank_transactions',
|
|
250
|
+
columns: columns.BANK_TRANSACTION,
|
|
251
|
+
where: [{ column: 'id', op: 'eq', value: args.transaction_id }],
|
|
252
|
+
});
|
|
253
|
+
return { transaction: settled[0] ?? null, settled_lines: lineIds };
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=payments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payments.js","sourceRoot":"","sources":["../../src/books/payments.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one rounding rule of Ekwo: **half up, on the absolute value, at the
|
|
3
|
+
* currency's decimals**.
|
|
4
|
+
*
|
|
5
|
+
* Three packages used to answer this differently — `Math.round((v + EPSILON) *
|
|
6
|
+
* 100) / 100`, `Math.round(v * 100) / 100` and `Number.prototype.toFixed(2)` —
|
|
7
|
+
* and the three disagreed on the two cases that matter: a negative half, where
|
|
8
|
+
* `Math.round` goes towards positive infinity and turns -0.005 into -0.00, and
|
|
9
|
+
* a value a binary float cannot hold, where 2.675 becomes 2.67 because
|
|
10
|
+
* `2.675 * 100` is really 267.49999999999994. A credit note is a sale with the
|
|
11
|
+
* sign flipped; a rule that treats the two differently puts a cent between an
|
|
12
|
+
* invoice and its credit note, and the cent is found by the person filing the
|
|
13
|
+
* return.
|
|
14
|
+
*
|
|
15
|
+
* Half up on the absolute value is what an invoice, a VAT return and a set of
|
|
16
|
+
* annual accounts are written with, and it is symmetric by construction: the
|
|
17
|
+
* rounding of -x is the rounding of x with the sign put back.
|
|
18
|
+
*
|
|
19
|
+
* The file is deliberately identical in every package that holds a copy. A
|
|
20
|
+
* format brick may not import the core or another brick, so the rule is
|
|
21
|
+
* duplicated rather than shared — and `tests/rounding.test.ts` reads the
|
|
22
|
+
* copies and refuses one that has drifted. See `docs/decisions.md`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function roundCurrency(value: number, decimals?: number): number;
|
|
25
|
+
//# sourceMappingURL=rounding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rounding.d.ts","sourceRoot":"","sources":["../../src/books/rounding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,SAAI,GAAG,MAAM,CAUjE"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one rounding rule of Ekwo: **half up, on the absolute value, at the
|
|
3
|
+
* currency's decimals**.
|
|
4
|
+
*
|
|
5
|
+
* Three packages used to answer this differently — `Math.round((v + EPSILON) *
|
|
6
|
+
* 100) / 100`, `Math.round(v * 100) / 100` and `Number.prototype.toFixed(2)` —
|
|
7
|
+
* and the three disagreed on the two cases that matter: a negative half, where
|
|
8
|
+
* `Math.round` goes towards positive infinity and turns -0.005 into -0.00, and
|
|
9
|
+
* a value a binary float cannot hold, where 2.675 becomes 2.67 because
|
|
10
|
+
* `2.675 * 100` is really 267.49999999999994. A credit note is a sale with the
|
|
11
|
+
* sign flipped; a rule that treats the two differently puts a cent between an
|
|
12
|
+
* invoice and its credit note, and the cent is found by the person filing the
|
|
13
|
+
* return.
|
|
14
|
+
*
|
|
15
|
+
* Half up on the absolute value is what an invoice, a VAT return and a set of
|
|
16
|
+
* annual accounts are written with, and it is symmetric by construction: the
|
|
17
|
+
* rounding of -x is the rounding of x with the sign put back.
|
|
18
|
+
*
|
|
19
|
+
* The file is deliberately identical in every package that holds a copy. A
|
|
20
|
+
* format brick may not import the core or another brick, so the rule is
|
|
21
|
+
* duplicated rather than shared — and `tests/rounding.test.ts` reads the
|
|
22
|
+
* copies and refuses one that has drifted. See `docs/decisions.md`.
|
|
23
|
+
*/
|
|
24
|
+
export function roundCurrency(value, decimals = 2) {
|
|
25
|
+
const factor = 10 ** decimals;
|
|
26
|
+
const scaled = Math.abs(value) * factor;
|
|
27
|
+
// The nudge is proportional to the number, which is what makes it work at
|
|
28
|
+
// 1.005 and at 1000000.005 alike, and far too small to move a value that is
|
|
29
|
+
// not already within a bit of the halfway point.
|
|
30
|
+
const rounded = Math.round(scaled + Number.EPSILON * scaled);
|
|
31
|
+
// `-0` is a value of its own in JavaScript and it prints as "-0.00".
|
|
32
|
+
// Adding zero turns it back into `0`.
|
|
33
|
+
return (value < 0 ? -rounded : rounded) / factor + 0;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=rounding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rounding.js","sourceRoot":"","sources":["../../src/books/rounding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,QAAQ,GAAG,CAAC;IACvD,MAAM,MAAM,GAAG,EAAE,IAAI,QAAQ,CAAC;IAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;IACxC,0EAA0E;IAC1E,4EAA4E;IAC5E,iDAAiD;IACjD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC;IAC7D,qEAAqE;IACrE,sCAAsC;IACtC,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the bookkeeping functions share: reading one row or saying why not,
|
|
3
|
+
* turning codes into ids, and the currency a company keeps its books in.
|
|
4
|
+
*/
|
|
5
|
+
import { type Backend } from './backend.js';
|
|
6
|
+
/** The row, or a refusal naming what row level security did not return. */
|
|
7
|
+
export declare function only<T>(rows: T[], what: string): T;
|
|
8
|
+
/** The row, or a refusal that says what was not visible rather than crashing. */
|
|
9
|
+
export declare function onlyVisible<T>(rows: T[], what: string): T;
|
|
10
|
+
/** `{ id: name }` for a set of rows, to put names next to foreign keys. */
|
|
11
|
+
export declare function namesOf(backend: Backend, table: string, ids: (string | null | undefined)[]): Promise<Record<string, string>>;
|
|
12
|
+
/**
|
|
13
|
+
* The row a caller already created under this reference, if there is one.
|
|
14
|
+
*
|
|
15
|
+
* A creation that carries a `client_ref` is looked up before it is made, so a
|
|
16
|
+
* caller that repeats itself after a dropped connection gets the first row
|
|
17
|
+
* back rather than a second one. The lookup is a convenience and not the
|
|
18
|
+
* guarantee: two callers racing each other both find nothing, and the unique
|
|
19
|
+
* index on `(company_id, client_ref)` is what refuses the slower one.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createdBefore(backend: Backend, table: 'contacts' | 'documents' | 'payments', company: string, clientRef: string | undefined, columns: string[]): Promise<Record<string, unknown> | undefined>;
|
|
22
|
+
/** Resolves codes to ids in one query, and says which code was unknown. */
|
|
23
|
+
/**
|
|
24
|
+
* The currency an amount is in when the caller names none: the company's own.
|
|
25
|
+
*
|
|
26
|
+
* Never a literal. A company that keeps its books in Canadian dollars would
|
|
27
|
+
* get a euro invoice out of a euro written here, and a wrong answer is worse
|
|
28
|
+
* than a refusal. `companies.currency_code` is never null, so there is always
|
|
29
|
+
* one to find.
|
|
30
|
+
*/
|
|
31
|
+
export declare function companyCurrency(backend: Backend, company: string): Promise<string>;
|
|
32
|
+
export declare function idsByCode(backend: Backend, table: 'accounts' | 'taxes' | 'journals', company: string, codes: string[]): Promise<Map<string, string>>;
|
|
33
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/books/shared.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAExD,2EAA2E;AAC3E,wBAAgB,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,CAQlD;AAGD,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,CAQzD;AAGD,2EAA2E;AAC3E,wBAAsB,OAAO,CAC3B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,GACjC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CASjC;AAGD;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,UAAU,GAAG,WAAW,GAAG,UAAU,EAC5C,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAW9C;AAED,2EAA2E;AAC3E;;;;;;;GAOG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAaxF;AAED,wBAAsB,SAAS,CAC7B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,UAAU,GAAG,OAAO,GAAG,UAAU,EACxC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAqB9B"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the bookkeeping functions share: reading one row or saying why not,
|
|
3
|
+
* turning codes into ids, and the currency a company keeps its books in.
|
|
4
|
+
*/
|
|
5
|
+
import { BooksError } from './backend.js';
|
|
6
|
+
/** The row, or a refusal naming what row level security did not return. */
|
|
7
|
+
export function only(rows, what) {
|
|
8
|
+
const row = rows[0];
|
|
9
|
+
if (row === undefined) {
|
|
10
|
+
throw new BooksError(`not_found: ${what}. Either it does not exist, or your role on that company does not allow this.`);
|
|
11
|
+
}
|
|
12
|
+
return row;
|
|
13
|
+
}
|
|
14
|
+
/** The row, or a refusal that says what was not visible rather than crashing. */
|
|
15
|
+
export function onlyVisible(rows, what) {
|
|
16
|
+
const row = rows[0];
|
|
17
|
+
if (row === undefined) {
|
|
18
|
+
throw new BooksError(`not_found: ${what}. Either it does not exist or you are not a member of the company that holds it.`);
|
|
19
|
+
}
|
|
20
|
+
return row;
|
|
21
|
+
}
|
|
22
|
+
/** `{ id: name }` for a set of rows, to put names next to foreign keys. */
|
|
23
|
+
export async function namesOf(backend, table, ids) {
|
|
24
|
+
const wanted = [...new Set(ids.filter((id) => typeof id === 'string'))];
|
|
25
|
+
if (wanted.length === 0)
|
|
26
|
+
return {};
|
|
27
|
+
const rows = await backend.select({
|
|
28
|
+
table,
|
|
29
|
+
columns: ['id', 'name'],
|
|
30
|
+
where: [{ column: 'id', op: 'in', value: wanted }],
|
|
31
|
+
});
|
|
32
|
+
return Object.fromEntries(rows.map((row) => [row.id, row.name]));
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The row a caller already created under this reference, if there is one.
|
|
36
|
+
*
|
|
37
|
+
* A creation that carries a `client_ref` is looked up before it is made, so a
|
|
38
|
+
* caller that repeats itself after a dropped connection gets the first row
|
|
39
|
+
* back rather than a second one. The lookup is a convenience and not the
|
|
40
|
+
* guarantee: two callers racing each other both find nothing, and the unique
|
|
41
|
+
* index on `(company_id, client_ref)` is what refuses the slower one.
|
|
42
|
+
*/
|
|
43
|
+
export async function createdBefore(backend, table, company, clientRef, columns) {
|
|
44
|
+
if (clientRef === undefined)
|
|
45
|
+
return undefined;
|
|
46
|
+
const rows = await backend.select({
|
|
47
|
+
table,
|
|
48
|
+
columns,
|
|
49
|
+
where: [
|
|
50
|
+
{ column: 'company_id', op: 'eq', value: company },
|
|
51
|
+
{ column: 'client_ref', op: 'eq', value: clientRef },
|
|
52
|
+
],
|
|
53
|
+
});
|
|
54
|
+
return rows[0];
|
|
55
|
+
}
|
|
56
|
+
/** Resolves codes to ids in one query, and says which code was unknown. */
|
|
57
|
+
/**
|
|
58
|
+
* The currency an amount is in when the caller names none: the company's own.
|
|
59
|
+
*
|
|
60
|
+
* Never a literal. A company that keeps its books in Canadian dollars would
|
|
61
|
+
* get a euro invoice out of a euro written here, and a wrong answer is worse
|
|
62
|
+
* than a refusal. `companies.currency_code` is never null, so there is always
|
|
63
|
+
* one to find.
|
|
64
|
+
*/
|
|
65
|
+
export async function companyCurrency(backend, company) {
|
|
66
|
+
const rows = await backend.select({
|
|
67
|
+
table: 'companies',
|
|
68
|
+
columns: ['currency_code'],
|
|
69
|
+
where: [{ column: 'id', op: 'eq', value: company }],
|
|
70
|
+
});
|
|
71
|
+
const currency = rows[0]?.currency_code;
|
|
72
|
+
if (currency === undefined) {
|
|
73
|
+
throw new BooksError(`not_found: company ${company}. Either it does not exist or you are not a member of it.`);
|
|
74
|
+
}
|
|
75
|
+
return currency;
|
|
76
|
+
}
|
|
77
|
+
export async function idsByCode(backend, table, company, codes) {
|
|
78
|
+
const singular = { accounts: 'account', taxes: 'tax', journals: 'journal' }[table];
|
|
79
|
+
const wanted = [...new Set(codes)];
|
|
80
|
+
if (wanted.length === 0)
|
|
81
|
+
return new Map();
|
|
82
|
+
const rows = await backend.select({
|
|
83
|
+
table,
|
|
84
|
+
columns: ['id', 'code'],
|
|
85
|
+
where: [
|
|
86
|
+
{ column: 'company_id', op: 'eq', value: company },
|
|
87
|
+
{ column: 'code', op: 'in', value: wanted },
|
|
88
|
+
],
|
|
89
|
+
});
|
|
90
|
+
const found = new Map(rows.map((row) => [row.code, row.id]));
|
|
91
|
+
for (const code of wanted) {
|
|
92
|
+
if (!found.has(code)) {
|
|
93
|
+
throw new BooksError(`unknown_${singular}_code: no ${singular} "${code}" in this company. list_accounts, get_company and the ekwo://companies/{id}/taxes resource say what exists.`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return found;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/books/shared.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A thin client over the Ekwo schema.
|
|
3
|
+
*
|
|
4
|
+
* It is deliberately small: Supabase already exposes every table as REST with
|
|
5
|
+
* an OpenAPI description, so there is nothing to wrap there. What is worth
|
|
6
|
+
* wrapping is the handful of functions that carry the accounting rules, and
|
|
7
|
+
* the FEC export.
|
|
8
|
+
*
|
|
9
|
+
* `@supabase/supabase-js` is an optional peer dependency; only the two
|
|
10
|
+
* methods used here are required, so any structurally compatible client
|
|
11
|
+
* works and this package keeps zero runtime dependencies.
|
|
12
|
+
*/
|
|
13
|
+
import { type FecOptions } from '@ekwo-ai/fec';
|
|
14
|
+
import type { AgedBalanceRow, Entry, Instance, InstanceEdition, InstanceAdmin, IsoDate, TrialBalanceRow, Uuid, VatReturnRow } from './types.js';
|
|
15
|
+
export interface RpcResult<T> {
|
|
16
|
+
data: T | null;
|
|
17
|
+
error: {
|
|
18
|
+
message: string;
|
|
19
|
+
code?: string;
|
|
20
|
+
details?: string;
|
|
21
|
+
} | null;
|
|
22
|
+
}
|
|
23
|
+
/** The slice of `@supabase/supabase-js` this client needs. */
|
|
24
|
+
export interface SupabaseLike {
|
|
25
|
+
rpc<T = unknown>(fn: string, args?: Record<string, unknown>): PromiseLike<RpcResult<T>>;
|
|
26
|
+
}
|
|
27
|
+
export declare class EkwoError extends Error {
|
|
28
|
+
name: string;
|
|
29
|
+
readonly code: string | undefined;
|
|
30
|
+
constructor(message: string, code?: string);
|
|
31
|
+
}
|
|
32
|
+
export interface PeriodRange {
|
|
33
|
+
companyId: Uuid;
|
|
34
|
+
from: IsoDate;
|
|
35
|
+
to: IsoDate;
|
|
36
|
+
}
|
|
37
|
+
export declare class EkwoClient {
|
|
38
|
+
private readonly db;
|
|
39
|
+
constructor(db: SupabaseLike);
|
|
40
|
+
/** Books a document and returns the entry it produced. */
|
|
41
|
+
postDocument(documentId: Uuid): Promise<Entry>;
|
|
42
|
+
/** Numbers and posts an entry that was built by hand. */
|
|
43
|
+
postEntry(entryId: Uuid): Promise<Entry>;
|
|
44
|
+
/**
|
|
45
|
+
* Matches a debit line against a credit line. With no amount, the smaller
|
|
46
|
+
* of the two open amounts is used.
|
|
47
|
+
*/
|
|
48
|
+
reconcile(debitLineId: Uuid, creditLineId: Uuid, amount?: number): Promise<unknown>;
|
|
49
|
+
trialBalance(range: PeriodRange): Promise<TrialBalanceRow[]>;
|
|
50
|
+
vatReturn(range: PeriodRange): Promise<VatReturnRow[]>;
|
|
51
|
+
agedBalance(companyId: Uuid, at: IsoDate, group?: 'receivable' | 'payable'): Promise<AgedBalanceRow[]>;
|
|
52
|
+
/** The French FEC for a period, ready to be written to disk. */
|
|
53
|
+
generateFec(range: PeriodRange, options?: FecOptions): Promise<string>;
|
|
54
|
+
/**
|
|
55
|
+
* Records the installation. Called once, by the installer; raises if this
|
|
56
|
+
* database has already been set up.
|
|
57
|
+
*/
|
|
58
|
+
initInstance(organizationName: string, country: string, edition?: InstanceEdition): Promise<Instance>;
|
|
59
|
+
/**
|
|
60
|
+
* Makes a user an instance administrator. The first claim is open; after
|
|
61
|
+
* that only an administrator may appoint another.
|
|
62
|
+
*/
|
|
63
|
+
claimInstanceAdmin(userId?: Uuid): Promise<InstanceAdmin>;
|
|
64
|
+
/**
|
|
65
|
+
* Opt-in: records an address so Ekwo can reach the operator. Never
|
|
66
|
+
* required, and `unregisterInstance()` undoes it.
|
|
67
|
+
*/
|
|
68
|
+
registerInstance(contactEmail: string): Promise<Instance>;
|
|
69
|
+
unregisterInstance(): Promise<Instance>;
|
|
70
|
+
/** Installs a country chart of accounts, journals and taxes into a company. */
|
|
71
|
+
installCountryTemplate(companyId: Uuid, country: string): Promise<void>;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAA6B,KAAK,UAAU,EAAoB,MAAM,cAAc,CAAC;AAC5F,OAAO,KAAK,EACV,cAAc,EACd,KAAK,EACL,QAAQ,EACR,eAAe,EACf,aAAa,EACb,OAAO,EACP,eAAe,EACf,IAAI,EACJ,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACf,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACpE;AAED,8DAA8D;AAC9D,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;CACzF;AAED,qBAAa,SAAU,SAAQ,KAAK;IACzB,IAAI,SAAe;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;gBAEtB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;CAI3C;AAYD,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,IAAI,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,EAAE,OAAO,CAAC;CACb;AAED,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,YAAY;IAE7C,0DAA0D;IACpD,YAAY,CAAC,UAAU,EAAE,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC;IAKpD,yDAAyD;IACnD,SAAS,CAAC,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC;IAK9C;;;OAGG;IACG,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IASnF,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAS5D,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAStD,WAAW,CACf,SAAS,EAAE,IAAI,EACf,EAAE,EAAE,OAAO,EACX,KAAK,GAAE,YAAY,GAAG,SAAwB,GAC7C,OAAO,CAAC,cAAc,EAAE,CAAC;IAS5B,gEAAgE;IAC1D,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAS5E;;;OAGG;IACG,YAAY,CAChB,gBAAgB,EAAE,MAAM,EACxB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,eAA6B,GACrC,OAAO,CAAC,QAAQ,CAAC;IASpB;;;OAGG;IACG,kBAAkB,CAAC,MAAM,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC;IAO/D;;;OAGG;IACG,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAOzD,kBAAkB,IAAI,OAAO,CAAC,QAAQ,CAAC;IAK7C,+EAA+E;IACzE,sBAAsB,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAS9E"}
|