ohadakit 1.0.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/LICENSE +21 -0
- package/README.md +385 -0
- package/dist/browser/ohadakit.iife.js +3 -0
- package/dist/browser/ohadakit.umd.js +3 -0
- package/dist/cjs/index.js +6456 -0
- package/dist/esm/index.js +6456 -0
- package/dist/types/AccountBook.d.ts +58 -0
- package/dist/types/LedgerEngine.d.ts +45 -0
- package/dist/types/core/Account.d.ts +49 -0
- package/dist/types/core/AccountIndex.d.ts +31 -0
- package/dist/types/core/AccountRegistry.d.ts +39 -0
- package/dist/types/core/types.d.ts +127 -0
- package/dist/types/custom/CustomAccountIndex.d.ts +28 -0
- package/dist/types/custom/CustomAccountManager.d.ts +44 -0
- package/dist/types/custom/CustomAccountValidator.d.ts +23 -0
- package/dist/types/custom/errors.d.ts +37 -0
- package/dist/types/custom/index.d.ts +8 -0
- package/dist/types/custom/types.d.ts +52 -0
- package/dist/types/data/ohada/accounts-flat.d.ts +27 -0
- package/dist/types/data/ohada/class-1-ressources.d.ts +3 -0
- package/dist/types/data/ohada/class-2-immobilisations.d.ts +3 -0
- package/dist/types/data/ohada/class-3-stocks.d.ts +3 -0
- package/dist/types/data/ohada/class-4-tiers.d.ts +3 -0
- package/dist/types/data/ohada/class-5-tresorerie.d.ts +3 -0
- package/dist/types/data/ohada/class-6-charges.d.ts +3 -0
- package/dist/types/data/ohada/class-7-produits.d.ts +3 -0
- package/dist/types/data/ohada/class-8-hao.d.ts +3 -0
- package/dist/types/data/ohada/class-9-engagements.d.ts +3 -0
- package/dist/types/data/ohada/classes.d.ts +3 -0
- package/dist/types/data/ohada/index.d.ts +26 -0
- package/dist/types/data/ohada/types.d.ts +39 -0
- package/dist/types/data/ohada-accounts.d.ts +6 -0
- package/dist/types/export/Exporter.d.ts +11 -0
- package/dist/types/i18n/TranslationService.d.ts +15 -0
- package/dist/types/i18n/account-names.d.ts +3 -0
- package/dist/types/i18n/index.d.ts +4 -0
- package/dist/types/i18n/types.d.ts +13 -0
- package/dist/types/index.d.ts +25 -0
- package/dist/types/query/QueryEngine.d.ts +30 -0
- package/dist/types/storage/LocalStorage.d.ts +14 -0
- package/dist/types/storage/MemoryStorage.d.ts +11 -0
- package/dist/types/validation/errors.d.ts +43 -0
- package/dist/types/validation/validators.d.ts +14 -0
- package/package.json +75 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-Present Justin Dah-kenangnon <dah.kenangnon@gmail.com>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# OhadaKit
|
|
4
|
+
|
|
5
|
+
**Production-ready TypeScript SDK for the OHADA/SYSCOHADA accounting chart of accounts**
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/ohadakit)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
[](https://www.typescriptlang.org/)
|
|
10
|
+
|
|
11
|
+
[Installation](#installation) · [Quick Start](#quick-start) · [API](#core-api) · [GitHub](https://github.com/Dahkenangnon/OhadaKit)
|
|
12
|
+
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Features
|
|
18
|
+
|
|
19
|
+
- **Complete OHADA Chart** — All 1000+ accounts across 9 classes
|
|
20
|
+
- **O(1) Lookups** — Map-based indexes and Trie prefix search for instant retrieval
|
|
21
|
+
- **Type-Safe** — Full TypeScript support with branded types and `Result<T, E>` pattern
|
|
22
|
+
- **Query Builder** — Fluent API with filters, fuzzy search, and sorting
|
|
23
|
+
- **i18n** — Localized account names in French, English, Portuguese, and Spanish
|
|
24
|
+
- **Custom Accounts** — Overlay pattern for creating custom sub-accounts and overriding labels
|
|
25
|
+
- **Pluggable Storage** — Attach notes with any storage backend (memory, localStorage, custom)
|
|
26
|
+
- **Export** — JSON (flat/hierarchical) and CSV output formats
|
|
27
|
+
- **Zero Dependencies** — Core SDK has no external dependencies
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install ohadakit
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { LedgerEngine } from 'ohadakit';
|
|
39
|
+
|
|
40
|
+
const ledger = new LedgerEngine();
|
|
41
|
+
|
|
42
|
+
// Get an account (Result type — explicit error handling)
|
|
43
|
+
const result = ledger.get('4111');
|
|
44
|
+
if (result.ok) {
|
|
45
|
+
console.log(result.data.name); // "Clients"
|
|
46
|
+
console.log(result.data.pathString); // "41 > 411 > 4111"
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Or use convenience accessors
|
|
50
|
+
const account = ledger.getOrNull('4111'); // Account | null
|
|
51
|
+
const account2 = ledger.getOrThrow('411'); // Account (throws on error)
|
|
52
|
+
|
|
53
|
+
// Query builder
|
|
54
|
+
const expenses = ledger.query()
|
|
55
|
+
.inClass('6')
|
|
56
|
+
.atLevel(3)
|
|
57
|
+
.nameContains('personnel')
|
|
58
|
+
.sortBy('code', 'asc')
|
|
59
|
+
.execute();
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Core API
|
|
63
|
+
|
|
64
|
+
### Account Access
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
ledger.get('4111') // Result<Account> with validation
|
|
68
|
+
ledger.getOrNull('4111') // Account | null
|
|
69
|
+
ledger.getOrThrow('4111') // Account (throws on error)
|
|
70
|
+
|
|
71
|
+
// Direct registry access
|
|
72
|
+
ledger.registry.has('4111') // boolean
|
|
73
|
+
ledger.registry.getByClass('4') // Account[]
|
|
74
|
+
ledger.registry.getByLevel(3) // Account[]
|
|
75
|
+
ledger.registry.searchByPrefix('41') // Account[] (Trie-based)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Query Builder
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
ledger.query()
|
|
82
|
+
.inClass(['4', '5']) // Filter by class(es)
|
|
83
|
+
.atLevel([3, 4]) // Filter by level(s)
|
|
84
|
+
.withParent('41') // Filter by parent
|
|
85
|
+
.nameContains('client') // Search in name
|
|
86
|
+
.codeMatches(/^6[0-3]/) // Regex pattern
|
|
87
|
+
.where(acc => acc.isLeaf) // Custom predicate
|
|
88
|
+
.sortBy('code', 'asc') // Sort results
|
|
89
|
+
.offset(10).limit(20) // Pagination
|
|
90
|
+
.execute(); // Get Account[]
|
|
91
|
+
|
|
92
|
+
// Convenience methods
|
|
93
|
+
ledger.query().inClass('4').count(); // number
|
|
94
|
+
ledger.query().inClass('4').first(); // Account | null
|
|
95
|
+
ledger.query().inClass('4').exists(); // boolean
|
|
96
|
+
|
|
97
|
+
// Fuzzy search
|
|
98
|
+
ledger.query()
|
|
99
|
+
.search('cliens', { fuzzy: true, threshold: 0.6 })
|
|
100
|
+
.execute();
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Account Relationships
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
const account = ledger.getOrThrow('4111');
|
|
107
|
+
|
|
108
|
+
account.parent // Account | null
|
|
109
|
+
account.children // Account[]
|
|
110
|
+
account.ancestors // Account[] (nearest parent first)
|
|
111
|
+
account.siblings // Account[]
|
|
112
|
+
account.path // Account[] (root to self)
|
|
113
|
+
account.pathString // "41 > 411 > 4111"
|
|
114
|
+
account.isLeaf // boolean
|
|
115
|
+
account.isRoot // boolean
|
|
116
|
+
account.depth // number
|
|
117
|
+
|
|
118
|
+
account.isDescendantOf('4') // true
|
|
119
|
+
account.isAncestorOf('41111') // true (if exists)
|
|
120
|
+
account.getDescendants() // Account[]
|
|
121
|
+
account.getDescendantsAtLevel(2) // grandchildren only
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Internationalization (i18n)
|
|
125
|
+
|
|
126
|
+
Supports 4 OHADA locales: French (fr), English (en), Portuguese (pt), Spanish (es).
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
// Set locale at creation
|
|
130
|
+
const ledger = new LedgerEngine({ locale: 'en' });
|
|
131
|
+
|
|
132
|
+
// Or change later
|
|
133
|
+
ledger.setLocale('en');
|
|
134
|
+
ledger.getLocale(); // 'en'
|
|
135
|
+
ledger.getAvailableLocales(); // ['fr', 'en', 'pt', 'es']
|
|
136
|
+
|
|
137
|
+
// Get localized account name (falls back to French if translation missing)
|
|
138
|
+
ledger.getLocalizedName('4111'); // English name or French fallback
|
|
139
|
+
|
|
140
|
+
// Direct TranslationService access
|
|
141
|
+
ledger.i18n.getAccountName('10', 'Capital');
|
|
142
|
+
ledger.i18n.hasTranslation('10');
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Custom Accounts
|
|
146
|
+
|
|
147
|
+
Extend the immutable OHADA chart with custom sub-accounts and label overrides.
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
import { CustomAccountManager, MemoryStorage } from 'ohadakit';
|
|
151
|
+
|
|
152
|
+
const manager = new CustomAccountManager({
|
|
153
|
+
storage: new MemoryStorage()
|
|
154
|
+
});
|
|
155
|
+
await manager.initialize();
|
|
156
|
+
|
|
157
|
+
// Create a custom sub-account (3+ characters, must start with parent code)
|
|
158
|
+
const result = await manager.createAccount({
|
|
159
|
+
code: '411-VIP',
|
|
160
|
+
name: 'Clients VIP',
|
|
161
|
+
parentCode: '411'
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// Override label of an existing account
|
|
165
|
+
await manager.updateLabel('4111', 'Clients - Particuliers');
|
|
166
|
+
|
|
167
|
+
// Query custom + official accounts together
|
|
168
|
+
manager.getByCode('411-VIP'); // Account
|
|
169
|
+
manager.getAll(); // All official + custom accounts
|
|
170
|
+
manager.getCustomAccounts(); // Only custom accounts
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### AccountBook (Unified Facade)
|
|
174
|
+
|
|
175
|
+
`AccountBook` wraps all OhadaKit features into a single entry point: official accounts, custom accounts, label overrides, notes, i18n, and export — with snapshot/restore for state management.
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
import { AccountBook, MemoryStorage } from 'ohadakit';
|
|
179
|
+
|
|
180
|
+
const book = new AccountBook({ storage: new MemoryStorage() });
|
|
181
|
+
await book.initialize();
|
|
182
|
+
|
|
183
|
+
// Access any account (official + custom, with label overrides applied)
|
|
184
|
+
const account = book.getAccountOrNull('411');
|
|
185
|
+
|
|
186
|
+
// Create custom sub-accounts
|
|
187
|
+
await book.createAccount({ code: '411-VIP', name: 'Clients VIP', parentCode: '411' });
|
|
188
|
+
|
|
189
|
+
// Override labels
|
|
190
|
+
await book.updateLabel('4111', 'Clients - Particuliers');
|
|
191
|
+
|
|
192
|
+
// Notes work on both official and custom accounts
|
|
193
|
+
await book.setNote('411-VIP', 'High-value clients');
|
|
194
|
+
|
|
195
|
+
// Export merged data (official + custom + overrides)
|
|
196
|
+
const json = book.exportToJSON({ pretty: true });
|
|
197
|
+
const csv = book.exportToCSV();
|
|
198
|
+
|
|
199
|
+
// i18n
|
|
200
|
+
book.setLocale('en');
|
|
201
|
+
book.getLocalizedName('10'); // English name
|
|
202
|
+
|
|
203
|
+
// Stats
|
|
204
|
+
const stats = await book.getStats();
|
|
205
|
+
// { total, byClass, byLevel, customAccountCount, labelOverrideCount, noteCount }
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
#### Snapshot / Restore
|
|
209
|
+
|
|
210
|
+
Capture and restore the entire book state (custom accounts, label overrides, notes) as a plain JSON object:
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
// Take a snapshot
|
|
214
|
+
const snapshot = await book.snapshot();
|
|
215
|
+
// { version, timestamp, locale, customAccounts, labelOverrides, notes }
|
|
216
|
+
|
|
217
|
+
// Store it anywhere (database, file, API)
|
|
218
|
+
const json = JSON.stringify(snapshot);
|
|
219
|
+
|
|
220
|
+
// Restore into a fresh or existing book
|
|
221
|
+
const result = await book.restore(JSON.parse(json));
|
|
222
|
+
if (!result.ok) {
|
|
223
|
+
console.error('Restore failed:', result.error.message);
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
#### When to use AccountBook vs LedgerEngine
|
|
228
|
+
|
|
229
|
+
| Use case | Recommendation |
|
|
230
|
+
|----------|---------------|
|
|
231
|
+
| Quick lookups on official accounts only | `LedgerEngine` |
|
|
232
|
+
| Custom accounts + label overrides + notes | `AccountBook` |
|
|
233
|
+
| App needs snapshot/restore of chart state | `AccountBook` |
|
|
234
|
+
| Prototype without persistence wiring | `LedgerEngine` |
|
|
235
|
+
|
|
236
|
+
### Notes Storage
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
import { LedgerEngine, LocalStorageAdapter } from 'ohadakit';
|
|
240
|
+
|
|
241
|
+
// In-memory (default)
|
|
242
|
+
const ledger = new LedgerEngine();
|
|
243
|
+
|
|
244
|
+
// Browser localStorage
|
|
245
|
+
const ledger = new LedgerEngine({
|
|
246
|
+
storage: new LocalStorageAdapter('myapp:')
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
await ledger.setNote('5121', 'Mobile Money Orange');
|
|
250
|
+
await ledger.getNote('5121'); // 'Mobile Money Orange'
|
|
251
|
+
await ledger.deleteNote('5121');
|
|
252
|
+
await ledger.hasNote('5121'); // false
|
|
253
|
+
await ledger.getAllNotes(); // Map<string, string>
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Export
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
// JSON (flat or hierarchical)
|
|
260
|
+
ledger.exportToJSON({ structure: 'flat', pretty: true });
|
|
261
|
+
ledger.exportToJSON({ structure: 'hierarchical' });
|
|
262
|
+
|
|
263
|
+
// CSV
|
|
264
|
+
ledger.exportToCSV({ columns: ['code', 'name', 'level'] });
|
|
265
|
+
ledger.exportToCSV({ delimiter: ';', includeHeader: true });
|
|
266
|
+
|
|
267
|
+
// Export specific class
|
|
268
|
+
ledger.exportClass('4', 'json', { structure: 'flat' });
|
|
269
|
+
ledger.exportClass('4', 'csv', { columns: ['code', 'name'] });
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Validation
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
import { validateAccountCodeFormat, AccountNotFoundError } from 'ohadakit';
|
|
276
|
+
|
|
277
|
+
// Format validation (no registry lookup)
|
|
278
|
+
const formatResult = validateAccountCodeFormat('4111'); // Result<string>
|
|
279
|
+
|
|
280
|
+
// Full validation with Result type
|
|
281
|
+
const result = ledger.get('9999');
|
|
282
|
+
if (!result.ok && result.error instanceof AccountNotFoundError) {
|
|
283
|
+
console.error(result.error.message);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Batch validation
|
|
287
|
+
const { valid, invalid } = ledger.validateBatch(['4111', '5121', '9999']);
|
|
288
|
+
// valid: [{ code: '4111', account }, { code: '5121', account }]
|
|
289
|
+
// invalid: [{ code: '9999', error }]
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## Using OhadaKit in an Accounting App
|
|
293
|
+
|
|
294
|
+
OhadaKit manages the **chart of accounts** — it does not own journal entries, balances, or transactions. Your app links to OhadaKit via account codes used as foreign keys.
|
|
295
|
+
|
|
296
|
+
```
|
|
297
|
+
┌──────────────────────────┐ ┌──────────────────────────┐
|
|
298
|
+
│ Your App │ │ OhadaKit │
|
|
299
|
+
│ │ │ │
|
|
300
|
+
│ Journal Entries ────────┼─FK──▶ AccountBook │
|
|
301
|
+
│ Balances ───────────────┼─FK──▶ ├─ Official Accounts │
|
|
302
|
+
│ Trial Balance ──────────┼─FK──▶ ├─ Custom Accounts │
|
|
303
|
+
│ Financial Statements │ │ ├─ Label Overrides │
|
|
304
|
+
│ │ │ ├─ Notes │
|
|
305
|
+
│ Your DB / API │ │ └─ i18n + Export │
|
|
306
|
+
└──────────────────────────┘ └──────────────────────────┘
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Step-by-step Integration
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
import { AccountBook, MemoryStorage } from 'ohadakit';
|
|
313
|
+
|
|
314
|
+
// 1. Initialize the book
|
|
315
|
+
const book = new AccountBook({ storage: new MemoryStorage() });
|
|
316
|
+
await book.initialize();
|
|
317
|
+
|
|
318
|
+
// 2. Validate account codes when creating journal entries
|
|
319
|
+
function addJournalEntry(debitCode: string, creditCode: string, amount: number) {
|
|
320
|
+
if (!book.has(debitCode)) throw new Error(`Unknown account: ${debitCode}`);
|
|
321
|
+
if (!book.has(creditCode)) throw new Error(`Unknown account: ${creditCode}`);
|
|
322
|
+
|
|
323
|
+
// Store in your database with account codes as FKs
|
|
324
|
+
return { debitCode, creditCode, amount, date: new Date() };
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// 3. Resolve names for display
|
|
328
|
+
function getAccountName(code: string): string {
|
|
329
|
+
return book.getAccountOrNull(code)?.name ?? `Unknown (${code})`;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// 4. Save/restore chart state alongside your app data
|
|
333
|
+
async function saveAppState(db: any) {
|
|
334
|
+
const snapshot = await book.snapshot();
|
|
335
|
+
await db.put('chart-state', JSON.stringify(snapshot));
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### What OhadaKit Owns vs What Your App Owns
|
|
340
|
+
|
|
341
|
+
| Concern | Owner |
|
|
342
|
+
|---------|-------|
|
|
343
|
+
| Chart of accounts (official 1000+ accounts) | OhadaKit |
|
|
344
|
+
| Custom sub-accounts & label overrides | OhadaKit (via AccountBook) |
|
|
345
|
+
| Notes attached to accounts | OhadaKit (via AccountBook) |
|
|
346
|
+
| Account name translations (fr/en/pt/es) | OhadaKit |
|
|
347
|
+
| Journal entries, postings | Your app |
|
|
348
|
+
| Account balances, trial balance | Your app |
|
|
349
|
+
| Financial statements | Your app |
|
|
350
|
+
| User authentication, permissions | Your app |
|
|
351
|
+
|
|
352
|
+
## OHADA Structure
|
|
353
|
+
|
|
354
|
+
```
|
|
355
|
+
Level 1: Class (1-9)
|
|
356
|
+
└─ Level 2: Main account (10, 11...)
|
|
357
|
+
└─ Level 3: Sub-account (101, 102...)
|
|
358
|
+
└─ Level 4: Detail account (1011, 1012...)
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
| Class | Description |
|
|
362
|
+
|-------|-------------|
|
|
363
|
+
| 1 | Comptes de ressources durables |
|
|
364
|
+
| 2 | Comptes d'actif immobilise |
|
|
365
|
+
| 3 | Comptes de stocks |
|
|
366
|
+
| 4 | Comptes de tiers |
|
|
367
|
+
| 5 | Comptes de tresorerie |
|
|
368
|
+
| 6 | Comptes de charges des activites ordinaires |
|
|
369
|
+
| 7 | Comptes de produits des activites ordinaires |
|
|
370
|
+
| 8 | Comptes des autres charges et autres produits |
|
|
371
|
+
| 9 | Comptes des engagements hors bilan |
|
|
372
|
+
|
|
373
|
+
## License
|
|
374
|
+
|
|
375
|
+
MIT © [@Dahkenangnon](https://github.com/Dahkenangnon)
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
<div align="center">
|
|
380
|
+
|
|
381
|
+
**[GitHub](https://github.com/Dahkenangnon/OhadaKit)** · **[Issues](https://github.com/Dahkenangnon/OhadaKit/issues)** · **[npm](https://www.npmjs.com/package/ohadakit)**
|
|
382
|
+
|
|
383
|
+
Questions or feedback? Reach out at **dah.kenangnon@gmail.com**
|
|
384
|
+
|
|
385
|
+
</div>
|