@mostajs/compta-analytique 0.1.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 +16 -0
- package/llms.txt +26 -0
- package/package.json +30 -0
- package/src/index.js +45 -0
package/README.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# @mostajs/compta-analytique
|
|
2
|
+
|
|
3
|
+
**Auteur** : Dr Hamid MADANI <drmdh@msn.com> · **Licence** : AGPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
Comptabilité **analytique** (couche logique) — ventile les écritures par **axe** (type, ligne,
|
|
6
|
+
centre de coût, projet) et calcule recettes/dépenses/net + **parts (%)**. **Compose** une source
|
|
7
|
+
d'écritures injectée (DEVRULES §10) ; DB-agnostique.
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
import { createComptaAnalytique } from '@mostajs/compta-analytique';
|
|
11
|
+
const ca = createComptaAnalytique({ source: () => compta.ledger.entries(), axisOf: (e) => e.type });
|
|
12
|
+
await ca.ventilation(); // [{ axis, recettes, depenses, net, count }]
|
|
13
|
+
await ca.share(); // [{ axis, depenses, pct }]
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Tests & exemple (§11.1 / §12) : `npm install && npm test`. Proposition & livrables : `docs/`. Fiche LLM : `llms.txt`.
|
package/llms.txt
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# @mostajs/compta-analytique — fiche LLM
|
|
2
|
+
> Comptabilité analytique : ventilation des écritures par AXE (type/ligne/centre de coût/projet) + parts.
|
|
3
|
+
|
|
4
|
+
- Version: 0.1.0 · Licence: AGPL-3.0-or-later · Auteur: Dr Hamid MADANI <drmdh@msn.com>
|
|
5
|
+
- Stack: mosta-gestion-stack · Voisins: @mostajs/compta, @mostajs/compta-budget
|
|
6
|
+
|
|
7
|
+
## RÔLE
|
|
8
|
+
Ventile une SOURCE d'écritures par un AXE analytique (fonction injectée) et calcule
|
|
9
|
+
recettes/dépenses/net + parts (%). Couche logique pure, DB-agnostique, composition (§10) :
|
|
10
|
+
la source = ex. @mostajs/compta `ledger.entries`.
|
|
11
|
+
|
|
12
|
+
## EXPORTS
|
|
13
|
+
- createComptaAnalytique({ source, axisOf? }) -> { ventilation, share, top }
|
|
14
|
+
|
|
15
|
+
## API
|
|
16
|
+
- ventilation({ sens? }) -> [{ axis, recettes, depenses, net, count }] (trié dépenses desc)
|
|
17
|
+
- share() -> [{ axis, depenses, pct }] (part % du total dépenses)
|
|
18
|
+
- top(n=5) -> ventilation tronquée
|
|
19
|
+
|
|
20
|
+
## PARAMÈTRES
|
|
21
|
+
- source: () => écritures[] ({ sens:'recette'|'depense', amount, type?, line?, … })
|
|
22
|
+
- axisOf: (e) => string dimension analytique (défaut: e.type)
|
|
23
|
+
|
|
24
|
+
## COMPOSITION (Salsabil)
|
|
25
|
+
createComptaAnalytique({ source: () => compta.ledger.entries(), axisOf: (e) => e.type }) // par type d'aide
|
|
26
|
+
createComptaAnalytique({ source: () => compta.ledger.entries(), axisOf: (e) => e.line }) // par ligne de budget
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mostajs/compta-analytique",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Comptabilité analytique — ventilation des écritures par axe (type, ligne, centre de coût, projet) + parts, par composition (DB-agnostique).",
|
|
5
|
+
"author": "Dr Hamid MADANI <drmdh@msn.com>",
|
|
6
|
+
"license": "AGPL-3.0-or-later",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "src/index.js",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": "./src/index.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"src",
|
|
14
|
+
"README.md",
|
|
15
|
+
"llms.txt"
|
|
16
|
+
],
|
|
17
|
+
"keywords": [
|
|
18
|
+
"comptabilite",
|
|
19
|
+
"analytique",
|
|
20
|
+
"cost-accounting",
|
|
21
|
+
"ventilation",
|
|
22
|
+
"mostajs"
|
|
23
|
+
],
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@mostajs/mjs-unit": "^0.3.0"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"test": "node test-scripts/unit/compta-analytique.test.mjs && node examples/run.mjs"
|
|
29
|
+
}
|
|
30
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// @mostajs/compta-analytique — comptabilité ANALYTIQUE (couche logique). MVP.
|
|
2
|
+
// Ventile les écritures par AXE analytique (type, ligne, centre de coût, projet…) et
|
|
3
|
+
// calcule recettes/dépenses/net + parts. COMPOSE par INJECTION (DEVRULES §10) : reçoit une
|
|
4
|
+
// SOURCE d'écritures (ex. @mostajs/compta ledger.entries) + une fonction d'axe. DB-agnostique.
|
|
5
|
+
// @author Dr Hamid MADANI <drmdh@msn.com> · AGPL-3.0-or-later
|
|
6
|
+
|
|
7
|
+
const num = (v) => (typeof v === 'number' && Number.isFinite(v) ? v : 0);
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {object} opts
|
|
11
|
+
* @param {() => Promise<object[]>} opts.source écritures { sens:'recette'|'depense', amount, ... }
|
|
12
|
+
* @param {(e:object) => string} [opts.axisOf] dimension analytique (défaut: e.type)
|
|
13
|
+
*/
|
|
14
|
+
export function createComptaAnalytique({ source = async () => [], axisOf = (e) => e.type || 'autre' } = {}) {
|
|
15
|
+
async function rows({ sens } = {}) {
|
|
16
|
+
return (await source()).filter((e) => !sens || e.sens === sens);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Ventilation par axe : recettes / dépenses / net / nombre, triée par dépenses décroissantes. */
|
|
20
|
+
async function ventilation({ sens } = {}) {
|
|
21
|
+
const es = await rows({ sens });
|
|
22
|
+
const map = new Map();
|
|
23
|
+
for (const e of es) {
|
|
24
|
+
const k = axisOf(e) || 'autre';
|
|
25
|
+
const cur = map.get(k) || { axis: k, recettes: 0, depenses: 0, count: 0 };
|
|
26
|
+
if (e.sens === 'recette') cur.recettes += num(e.amount); else cur.depenses += num(e.amount);
|
|
27
|
+
cur.count += 1; map.set(k, cur);
|
|
28
|
+
}
|
|
29
|
+
return [...map.values()].map((x) => ({ ...x, net: x.recettes - x.depenses })).sort((a, b) => b.depenses - a.depenses);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Part (%) de chaque axe dans le total des dépenses. */
|
|
33
|
+
async function share() {
|
|
34
|
+
const v = await ventilation();
|
|
35
|
+
const total = v.reduce((s, x) => s + x.depenses, 0);
|
|
36
|
+
return v.map((x) => ({ axis: x.axis, depenses: x.depenses, pct: total ? Math.round((x.depenses / total) * 1000) / 10 : 0 }));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Top N axes par dépenses. */
|
|
40
|
+
async function top(n = 5) { return (await ventilation()).slice(0, n); }
|
|
41
|
+
|
|
42
|
+
return { ventilation, share, top };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export default createComptaAnalytique;
|