npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

cry-eracun

v2.1.1

Published

Knjižnica za izdajo e-računov po standardu e-SLOG 2.0

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 portalavalidateViaBizBox(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 idDdv brez predpone "SI")

Namestitev

bun install cry-eracun

Build

# Namestitev odvisnosti
bun install

# Build knjižnice
bun run build

# Zagon testov
bun test

Uporaba

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: true v fast-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 v G_SG3/S_RFF/C_C506 s kvalifikatorjem AHP (iz idDdv brez 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): firma ALI (ime + priimek)
  • Naslov (BR-10): ulica, hs, ps, posta
  • Pravne osebe (BR-CO-26): idDdv ALI maticnaSt

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:

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 string

Licenca

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