@atmoner/logistic-unit
v0.0.2
Published
Packaging hierarchies, quantity conversions and physical logistics units
Maintainers
Readme
@atmoner/logistic-unit
Bibliothèque npm sans dépendance pour modéliser les conditionnements d'un article et le contenu d'une unité physique d'expédition. JavaScript CommonJS et ESM, déclarations TypeScript incluses. Node.js ≥ 18.
Le modèle métier s'appuie sur l'article Blogistics : UVC (vente/consommation), SPCB (sous-colis), PCB (colis), couche et palette ; facteurs de conversion, dimensions, poids et identifiants par niveau. Les calculs et l'API sont une implémentation propre à ce package.
Installation
Installer le package depuis npm :
npm install @atmoner/logistic-unitPour une installation depuis le dépôt local, exécuter npm pack, puis installer l'archive .tgz générée avec npm install /chemin/vers/archive.tgz.
Exemple
const { PackagingHierarchy } = require('@atmoner/logistic-unit');
// ESM : import { PackagingHierarchy } from '@atmoner/logistic-unit';
const article = new PackagingHierarchy({
articleId: 'PATES-500G',
levels: [
{ id: 'UVC', pickable: true },
{ id: 'SPCB', quantity: 6, pickable: true },
{ id: 'PCB', quantity: 8, grossWeightKg: 25,
dimensions: { length: 40, width: 30, height: 25, unit: 'cm' } },
{ id: 'LAYER', quantity: 10 },
{ id: 'PALLET', quantity: 5 },
],
});
article.convert(1, 'PALLET', 'UVC'); // 2400
article.convert(3, 'UVC', 'SPCB'); // 0.5
article.convert(48, 'UVC', 'PCB', { whole: true }); // 1
article.breakdown(101); // { PCB: 2, UVC: 5 }
article.breakdown(101, 'UVC', { pickableOnly: true }); // { SPCB: 16, UVC: 5 }
article.volumeM3('PCB', 2); // ≈ 0.06 m³
article.weightKg('PCB', 2); // 50 kgModèle et API
PackagingHierarchy reçoit des niveaux ordonnés du plus petit au plus grand. quantity décrit le nombre d'unités du niveau immédiatement précédent ; le premier vaut 1. Les identifiants sont libres : les niveaux intermédiaires peuvent être omis et des conditionnements spécifiques ajoutés. LEVELS expose les noms usuels UVC, SPCB, PCB, LAYER, PALLET.
| Méthode | Résultat |
| --- | --- |
| level(id) | Définition immuable, avec baseQuantity |
| convert(q, from, to, { whole? }) | Quantité cible ; whole: true refuse une unité partielle |
| breakdown(q, from?, { pickableOnly? }) | Décomposition gloutonne, du plus grand niveau au plus petit |
| volumeM3(id, q = 1) | Volume mesuré, dimensions en mm, cm ou m |
| weightKg(id, q = 1, kind = 'gross') | Poids brut ou net, en kg |
| toJSON() | Définition sérialisable, réutilisable dans le constructeur |
Les quantités d'entrée et les facteurs sont des entiers positifs sûrs (zéro accepté pour les calculs). Les résultats de conversion peuvent être fractionnaires. Le package refuse les dépassements de précision entière, les niveaux inconnus et les incohérences de définition. Les calculs de volume et de poids utilisent la précision décimale native de JavaScript.
La décomposition sert une règle « plus grand conditionnement d'abord », sans optimiser le nombre de colis pour des facteurs arbitraires. Avec pickableOnly, seuls les niveaux explicitement marqués true sont utilisés ; un reliquat impossible à préparer déclenche une erreur.
Les gabarits et poids sont facultatifs, mais nécessaires pour les calculs correspondants. Ils sont mesurés par niveau, sans extrapolation depuis les niveaux inférieurs.
Unité physique et palettes panachées
const { LogisticUnit } = require('@atmoner/logistic-unit');
const palette = new LogisticUnit({
sscc: '000000000000000017', // Exemple de format, pas un SSCC attribué.
tareWeightKg: 20,
dimensions: { length: 120, width: 80, height: 150, unit: 'cm' },
contents: [{ hierarchy: article, level: 'PCB', quantity: 50, lot: 'LOT-001' }],
});
palette.totals(); // { 'PATES-500G': 2400 }
palette.grossWeightKg(); // 1270
palette.volumeM3(); // ≈ 1.44Ajouter des lignes avec d'autres articles permet de représenter une palette panachée. Réutiliser la même instance de hiérarchie pour les lignes d'un même article. totals() agrège par article dans son unité de base ; lot conserve la référence du lot dans chaque ligne.
Le poids brut additionne les poids des conditionnements contenus et la tare de l'unité. Ne compter chaque emballage qu'une fois. Le volume utilise les dimensions extérieures de l'unité physique.
isValidGTIN(string) vérifie les longueurs 8/12/13/14 et la clé ; isValidSSCC(string) vérifie 18 chiffres et la clé. checkDigit(body) retourne la clé modulo 10. Ces fonctions suivent les règles de contrôle GS1. Les codes sont des chaînes pour préserver les zéros initiaux. Deux GTIN équivalents après normalisation à 14 chiffres sont refusés dans une hiérarchie.
Le contrôle de format ne vérifie ni l'attribution GS1 ni l'unicité mondiale. L'application appelante assure l'attribution et l'unicité des SSCC. Ce package ne génère pas d'images de codes-barres et n'implémente pas de WMS, de stockage persistant ou de règles réglementaires.
Développement
npm test
npm run example
npm packLes tests s'exécutent également avant la création d'une archive. Licence ISC.
