cry-eracun
v2.1.1
Published
Knjižnica za izdajo e-računov po standardu e-SLOG 2.0
Maintainers
Readme
cry-eracun
Knjižnica za izdelavo in polno validacijo e-računov po standardu e-SLOG 2.0 za Slovenijo (skladno z evropskim standardom EN 16931).
Funkcionalnosti
- Generiranje XML e-računov v formatu e-SLOG 2.0 (
urn:eslog:2.00) - Polna validacija brez zunanjih orodij:
- XSD strukturna validacija iz uradne sheme GZS (vgrajena v knjižnico)
- Semantična validacija EN 16931 (BR-, BR-CO-, BR-CL-, BR-S- pravila)
- Validacija kodnih seznamov (UNCL1001, UNCL5305, UNCL4461, ISO 3166, ISO 4217)
- IBAN mod-97 in BIC (ISO 9362) preverjanje
- Validacija preko uradnega bizBox portala —
validateViaBizBox(xml)pošlje e-račun v validacijo na https://bizbox.zzi.si - Podpora za več davčnih stopenj (22%, 9.5%, 5%, 0%, oproščeno)
- Popusti na postavkah (G_SG39 z indikatorjem A)
- Avtomatski izračun BIC iz slovenskega IBAN
- Pravilno zaokroževanje skladno z BR-CO-10/14/15/17 (cent-perfect agregacija)
- BT-32 (AHP) — avtomatsko generiranje izdajateljeve davčne številke (iz
idDdvbrez predpone "SI")
Namestitev
bun install cry-eracunBuild
# Namestitev odvisnosti
bun install
# Build knjižnice
bun run build
# Zagon testov
bun testUporaba
import { sestaviERacun, validateEslog20 } from "cry-eracun";
import type { PodatkiERacuna, PostavkaERacuna } from "cry-eracun";
// Podatki računa
const racun: PodatkiERacuna = {
_id: "racun-001",
stevilka: "2024-0001",
datum: "2024-01-15",
postavke: [
{ text: "Storitev A", quantity: 2, netPrice: 100, taxRate: 0.22 },
{ text: "Storitev B", quantity: 1, netPrice: 50, discountPrc: 0.1, taxRate: 0.22 },
{ text: "Knjiga", quantity: 3, netPrice: 25, taxRate: 0.095 },
],
sklic: "01-2024", // Sklic
modelSklica: "00", // Model sklica
prc: NaN, // NaN = izračunaj iz postavk
dav: NaN,
mpc: NaN,
valutaDni: 30,
};
// Podatki stranke (kupec)
const stranka = {
_id: "kupec-1",
firma: "Podjetje d.o.o.",
ulica: "Glavna ulica",
hs: 1,
ps: 1000,
posta: "Ljubljana",
idDdv: "SI12345678",
maticnaSt: "1234567000",
TRR: "SI56 1234 5678 9012 345",
};
// Podatki izdajatelja (prodajalec)
const izdajatelj = {
_id: "prodajalec-1",
firma: "Moje podjetje d.o.o.",
ulica: "Poslovna cesta",
hs: 10,
ps: 1000,
posta: "Ljubljana",
idDdv: "SI87654321",
maticnaSt: "7654321000",
TRR: "SI56 9876 5432 1098 765",
};
// Generiranje XML
const xml = sestaviERacun(racun, stranka, izdajatelj, "Mesečna naročnina");
// Polna validacija (XSD struktura + EN 16931 semantika)
const validacija = validateEslog20(xml);
if (validacija.ok) {
console.log("E-račun je v celoti skladen z e-SLOG 2.0 in EN 16931");
} else {
console.error("Napake:", validacija.errors);
console.warn("Opozorila:", validacija.warnings);
// Strukturni dostop:
// validacija.details.xsd → [{ rule, path, message }]
// validacija.details.semantic → [{ rule, severity, message }]
}Validacija — kaj točno preverja
validateEslog20() izvede tri faze:
1. XML well-formedness
Preverja pravilen XML sintakso (manjkajoči zaključki, nepravilno ugnezdenje ipd.).
2. XSD strukturna validacija
Razčleni vgrajeni uradni XSD (spec/eSLOG20_INVOIC_v200.xsd, ~70 KB) in preveri:
| Pravilo | Pomen |
|---------|-------|
| XSD-MIN-OCCURS / MAX-OCCURS | Kardinalnost otroških elementov (npr. S_DTM 1–35×) |
| XSD-UNEXPECTED-CHILD | Element ni dovoljen v starševskem |
| XSD-MINLENGTH / MAXLENGTH / LENGTH | Dolžina nizov (npr. D_1004 ≤ 70 znakov) |
| XSD-DATE | Datumi v formatu YYYY-MM-DD in semantično pravilni |
| XSD-DECIMAL-PATTERN | Decimalna polja v dovoljenih vzorcih |
| XSD-FRACTIONDIGITS / TOTALDIGITS | Števke za decimalno vejico, skupaj števk |
3. Semantična validacija EN 16931
Obvezni elementi — BR-01 (specification ID), BR-02 (številka), BR-03 (datum), BR-04 (tip), BR-05 (valuta), BR-06 (prodajalec), BR-07 (kupec), BR-08/10 (naslova), BR-09/11 (kode držav), BR-12..16 (vsote, postavke).
Računske kontrole (BR-CO-*) — po EN 16931:
- BR-CO-04: bruto znesek vrstice ≈ neto × (1 + stopnja/100)
- BR-CO-09: format VAT ID-ja (
^[A-Z]{2}\d{6,12}$) za vse stranke (ne le SE/BY) - BR-CO-10: vsota neto vrstic (MOA 79) = vsota MOA 203 po vrsticah
- BR-CO-13: znesek brez DDV (MOA 389) = MOA 79 − popusti + dodatki
- BR-CO-14: skupni DDV (MOA 176) = vsota DDV po kategorijah (G_SG52)
- BR-CO-15: znesek z DDV (MOA 388) = MOA 389 + MOA 176
- BR-CO-16: znesek za plačilo (MOA 9) = MOA 388 − plačano − zaokroženje
- BR-CO-17: DDV kategorije =
round(osnova × stopnja) - BR-CO-18: DDV vsote zahtevajo razdelitev po kategorijah
- BR-CO-25: če je znesek > 0, je obvezen rok plačila
- BR-CO-26: prodajalec mora imeti vsaj eno identifikacijo (VAT/AHP/0199)
- BR-CO-27: IBAN prodajalca (samo
D_3035=RB) mora biti veljaven (mod-97)
Kodne liste (BR-CL-*): tip dokumenta (UNCL1001), DDV kategorija (UNCL5305 ∈ {S, Z, E, AE, K, G, O, L, M, B}), način plačila (UNCL4461), kode držav (ISO 3166-1), valuta (ISO 4217 — zdaj preverja proti konkretnemu seznamu CURRENCY_CODES), kvalifikatorji datumov in strank.
Strukturna/sektorska pravila (BR-S-*) obvezna pri slovenski implementaciji EN 16931:
- BR-S-01: DDV vsota (MOA 176) zahteva DDV razčlenitev (
G_SG52) - BR-S-02: standardno obdavčene postavke (
D_5305=S) zahtevajo seller VA/AHP/TL ali LC/VA identifikatorje
Dodatna preverjanja:
- BR-CL-21: indikator
D_5463(A/C) se preverja na dokumentnem (G_SG53) in vrstičnem nivoju (G_SG39) - BR-BIC: BIC prodajalca mora ustrezati ISO 9362 formatu (8/11 znakov)
Cross-validation z xmllint --schema (uradni libxml2 XSD validator) potrjuje 100% ujemanje na realnem vzorcu 1088 računov. Validator se dodatno križno preverja preko uradnega bizBox portala (validateViaBizBox), ki pokriva GZS specifična pravila (BR-ESL-, BR-XML-).
Opomba: v različici 1.5.0 je bil odpravljen hrošč
parseTagValue: truevfast-xml-parser, ki je pretvarjal RFF kvalifikatorje z vodilno ničlo (0199,0088,0147) v števila — to je povzročalo lažne BR-CO-26 napake za prodajalce brez VAT ID-ja. V različici 1.6.0 je dodana podpora za BT-32 (AHP) — izdajateljeva davčna številka se avtomatsko zapiše vG_SG3/S_RFF/C_C506s kvalifikatorjemAHP(izidDdvbrez predpone "SI").
validateViaBizBox(xml, options?) — validacija preko bizBox portala
Poleg lokalne validacije lahko e-račun pošljete tudi v uradno bizBox validacijo na https://bizbox.zzi.si/bizBoxUtils/views/eslog20/validate.xhtml.
import { validateViaBizBox } from "cry-eracun"
// Prebere BIZBOX_USERNAME/BIZBOX_PASSWORD iz okolice
const result = await validateViaBizBox(xml)
if (result.ok) {
console.log("✅ E-račun je veljaven")
} else {
console.error("❌ Napake:", result.errors)
}
// Z eksplicitnimi kredenciali
const result = await validateViaBizBox(xml, {
username: "uporabnik",
password: "geslo",
})| Parameter | Tip | Opis |
|-----------|-----|------|
| xml | string | e-SLOG 2.0 XML |
| options.username | string? | privzeto process.env.BIZBOX_USERNAME |
| options.password | string? | privzeto process.env.BIZBOX_PASSWORD |
| options.baseUrl | string? | privzeto https://bizbox.zzi.si |
Vrne { ok: boolean, errors: string[], warnings?: string[], details?: { rule, message }[] }.
Opomba: Funkcija se avtenticira na bizBox preko JSF prijave, zato morata biti kredenciala veljavna in dostopna. Ob neuspešni prijavi vrne napako, ne meče izjeme.
Tipi
PostavkaERacuna
interface PostavkaERacuna {
text: string; // Opis postavke
quantity: number; // Količina
unitOfMeasure?: string; // Merska enota (privzeto "C62" = kos)
netPrice: number; // Cena brez DDV in popusta
discountPrc?: number; // Popust (0-1, npr. 0.1 = 10%)
taxRate: number; // Davčna stopnja (0-1, npr. 0.22 = 22%)
}PodatkiERacuna
interface PodatkiERacuna {
_id: string;
stevilka: string; // Številka računa
datum: string; // Datum (YYYY-MM-DD)
sklic: string; // Sklic (npr. "01-2024")
modelSklica: string; // Model sklica (privzeto "00")
postavke: PostavkaERacuna[];
prc: number; // Neto znesek (NaN = izračunaj)
mpc: number; // Bruto znesek (NaN = izračunaj)
dav: number; // Znesek DDV (NaN = izračunaj)
valutaDni: number; // Rok plačila v dneh
}Pomožne funkcije
strankaOkZaERacun
Preveri, ali ima kupec dovolj podatkov za izdajo e-računa po EN 16931.
import { strankaOkZaERacun } from "cry-eracun";
if (strankaOkZaERacun(stranka)) {
// Stranka ima vse potrebne podatke
} else {
// Manjkajo podatki
}Preverja:
- Identifikacija (BR-07):
firmaALI (ime+priimek) - Naslov (BR-10):
ulica,hs,ps,posta - Pravne osebe (BR-CO-26):
idDdvALImaticnaSt
Po EN 16931 TRR kupca ni obvezen — plačilni tok poteka prek IBAN izdajatelja.
iban2bic
Pretvori slovenski IBAN (TRR) v BIC kodo banke.
import { iban2bic } from "cry-eracun";
iban2bic("SI56 0201 0001 1234 567"); // "LJBASI2X" (NLB)
iban2bic("SI56 3300 0000 0297 296"); // "HAABSI22" (Addiko Bank)
iban2bic("SI56 6100 0001 0541 822"); // "HLONSI22" (Hranilnica LON)
iban2bic("DE89 3704 0044 0532 0130"); // "" (ni slovenski IBAN)Podprte banke (vir: Banka Slovenije):
- NLB, OTP Banka, Gorenjska banka, Banka Intesa Sanpaolo
- Deželna banka Slovenije, UniCredit, Addiko Bank, Banka Sparkasse
- BKS Banka, SID banka, Hranilnica LON, Delavska hranilnica
- Primorska hranilnica Vipava, KDD, Paywiser
Specifikacija
Knjižnica implementira standard e-SLOG 2.0 po uradni specifikaciji GZS / ePOS:
- ePOS — Slovenian National eBusiness Centre
- e-SLOG 2.0 dokumentacija (PDF)
- bizBox testni portal
- Evropski temeljni standard: EN 16931-1 (semantika), CEN/TS 16931-2 (sintaksa)
Uradni XSD (spec/e-SLOG-2.0-08-2020-SL 2/eSLOG20_INVOIC_v200.xsd) je vgrajen v knjižnico kot niz preko scripts/embed-xsd.ts (poganja se v prebuild).
Arhitektura
src/
├── index.ts # javni API
├── sestaviERacun.ts # generator XML
├── strankaOkZaERacun.ts # preverjanje kupca
├── iban2bic.ts # SI IBAN → BIC
├── validateEslog20.ts # validator (orchestrator)
├── types/ERacun.ts # vhodni tipi
└── validation/
├── xsdContent.ts # vgrajeni XSD niz (auto-gen)
├── xsdSchema.ts # razčleni XSD v memory schema
├── xsdValidator.ts # walker XML proti shemi
├── semanticValidator.ts # pravila EN 16931
└── codeLists.ts # UNCL/ISO kodni seznami + IBAN/BIC
scripts/
└── embed-xsd.ts # prebuild: XSD → TS stringLicenca
CC-BY-NC-ND-4.0 (Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International)
Copyright (c) 2026 Primož Krajnik
- Dovoljeno: deljenje nespremenjenega materiala za nekomercialne namene
- Prepovedano: komercialna uporaba, spreminjanje, predelava
Celotno besedilo licence: https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode
