ccnl-engine
A Python library for modeling Italian collective labor agreements (CCNL) as structured, versioned data and computing gross-to-net salary and employer cost from first principles.
Why
Italian payroll is governed by collective agreements (CCNL) that define base salaries, seniority increments, and allowances as time-series values — they change at negotiated renewal dates. Existing tools either lock this data inside proprietary systems or require a full HRMS. This library treats each CCNL as a validated JSON file and the computation as a pure function:
compute(ccnl, rules, scenario) → Payslip
Quickstart
from datetime import date
from ccnl_engine import Scenario, Permanent, TaxSector, compute, load_ccnl, load_year_rules
ccnl = load_ccnl("commercio-confcommercio.json")
scenario = Scenario(
level_code="4",
as_of=date(2026, 9, 1),
employment=Permanent(),
num_employees=50,
)
rules = load_year_rules(2026, TaxSector.TERZIARIO, scenario.num_employees)
payslip = compute(ccnl, rules, scenario)
print(payslip.net_annual) # → Decimal('...')
print(payslip.trattamento_integrativo) # → Decimal('...') — Art. 1 D.L. 3/2020 bonus
print(payslip.fiscal_simplifications) # → frozenset of items not computed by the engine
print(payslip.employer_cost_annual) # → Decimal('...')
CCNL coverage
Layers legend
| Layer | Meaning |
|---|---|
| Layer 1 | base salary, seniority increments (scatti di anzianità), fixed allowances, additional months. |
| Layer 2 | part-time, fixed-term (NASpI addizionale), apprenticeship (percentage or under-classification). |
Status legend
| Symbol | Meaning |
|---|---|
| ✅ | Fully modelled; all salary tables and rules for this layer are in scope |
| ⚠️ | Partially modelled; known gaps or simplifications apply — see coverage.notes in the contract's JSON data file |
| 🤖 | Extraction: extracted automatically via Claude Code — no manual human review |
| 🧑 | Extraction: verified manually against the official source |
CCNL Matrix
| # | Codice CNEL | CCNL | Sector | Lavoratori (~)1 | Layer 1 | Layer 2 | Extraction2 |
|---|---|---|---|---|---|---|---|
| 1 | H011 | Commercio — Confcommercio | Terziario | ~800k | ✅ | ✅ | 🤖 |
| 2 | C011 | Metalmeccanico — Federmeccanica/Assistal | Industria | ~1,7M | ✅ | ✅ | 🤖 |
| 3 | C018 | Metalmeccanico PMI — Unionmeccanica-Confapi | Industria | ~350k | ✅ | ✅ | 🤖 |
| 4 | B011 | Chimica-Farmaceutica — Federchimica/Farmindustria/Assistal | Industria | ~210k | ✅ | ✅ | 🤖 |
| 5 | H052 | Turismo — Confcommercio | Terziario | ~300k | ✅ | ✅ | 🤖 |
| 6 | F012 | Edilizia — ANCE | Edilizia | ~550k | ✅ | ✅ | 🤖 |
| 7 | T151 | Cooperative Sociali — Confcooperative/Legacoop/AGCI | Terziario | ~380k | ✅ | ✅ | 🤖 |
| 8 | I100 | Logistica, Trasporto Merci e Spedizione — Confetra | Industria | ~430k | ✅ | ✅ | 🤖 |
| 9 | K511 | Servizi di Pulizia e Multiservizi — ANIP-Confindustria | Terziario | ~580k | ✅ | ✅ | 🤖 |
| 10 | H442 | Studi e Attività Professionali — Confprofessioni | Terziario | ~350k | ✅ | ✅ | 🤖 |
| 11 | J241 | Credito — ABI | Credito | ~270k | ✅ | ✅ | 🤖 |
| 12 | D014 | Tessile Abbigliamento Moda — SMI | Industria | ~160k | ✅ | ✅ | 🤖 |
| 13 | E012 | Alimentari Industria — Federalimentare | Industria | ~145k | ✅ | ✅ | 🤖 |
| 14 | H008 | Distribuzione Moderna Organizzata — Federdistribuzione | Terziario | ~460k | ✅ | ✅ | 🤖 |
| 15 | C030 | Metalmeccanica e Installazione Impianti — Artigianato | Artigianato | ~350k | ✅ | ✅ | 🤖 |
| 16 | B371 | Gomma e Plastica Industria — Federazione Gomma Plastica | Industria | ~90k | ✅ | ✅ | 🤖 |
| 17 | G011 | Grafica e Editoria — AIEG-Acigraf | Industria | ~70k | ✅ | ✅ | 🤖 |
| 18 | G022 | Carta e Cartone — Assocarta | Industria | ~35k | ✅ | ✅ | 🤖 |
| 19 | K411 | Telecomunicazioni — Asstel | Industria | ~110k | ✅ | ✅ | 🤖 |
| 20 | HV40 | Vigilanza Privata — ASSIV/ANIVP/UNIV (GPG) | Terziario | ~85k | ✅ | ✅ | 🤖 |
| 21 | F051 | Legno e Arredamento — Federlegno-Arredo | Industria | ~90k | ✅ | ✅ | 🤖 |
| 22 | F015 | Edilizia e Affini — CNA/Confartigianato/Casartigiani | Artigianato | ~350k | ✅ | ✅ | 🤖 |
| 23 | K321 | Gas e Acqua — Utilitalia/Proxigas/Anfida/Assogas | Industria | ~65k | ✅ | ✅ | 🤖 |
| 24 | T141 | Istituzioni Socio-Assistenziali — UNEBA | Terziario | ~130k | ✅ | ✅ | 🤖 |
| 25 | H515 | Acconciatura ed Estetica — Confartigianato/CNA | Artigianato | ~95k | ✅ | ✅ | 🤖 |
| 26 | E015 | Area Alimentazione e Panificazione — Artigianato (Confartigianato/CNA) | Artigianato | ~90k | ✅ | ✅ | 🤖 |
| 27 | I022 | Autoferrotranvieri e Internavigatori (Mobilita/TPL) — AGENS/ASSTRA/ANAV | Terziario | ~120k | ✅ | ✅ | 🤖 |
| 28 | J271 | Credito Cooperativo (BCC/CRA) — Federcasse | Credito | ~33k | ✅ | ✅ | 🤖 |
| 29 | K051 | Elettrico (produzione/distribuzione energia) — Elettricita Futura | Industria | ~60k | ✅ | ✅ | 🤖 |
| 30 | D121 | Calzaturiero (industria delle calzature) — Assocalzaturifici | Industria | ~75k | ✅ | ✅ | 🤖 |
| 31 | V751 | Area Tessile-Moda e Chimica-Ceramica — Artigianato (Confartigianato/CNA) | Artigianato | ~120k | ✅ | ✅ | 🤖 |
| 32 | F060 | Area Legno-Lapidei — Artigianato (Confartigianato/CNA) | Artigianato | ~95k | ✅ | ✅ | 🤖 |
| 33 | G016 | Area Comunicazione — Artigianato (Confartigianato/CNA) | Artigianato | ~60k | ✅ | ✅ | 🤖 |
| 34 | B122 | Ceramica Industria — Confindustria Ceramica (Assopiastrelle) | Industria | ~23k | ✅ | ✅ | 🤖 |
| 35 | C021 | Orafi e Argentieri — Federorafi | Industria | ~18k | ✅ | ✅ | 🤖 |
| 36 | D111 | Pelli e Cuoio Industria — Assopellettieri | Industria | ~17k | ✅ | ✅ | 🤖 |
| 37 | H05Y | Pubblici Esercizi, Ristorazione Collettiva e Turismo — FIPE/ANGEM | Terziario | ~350k | ✅ | ✅ | 🤖 |
| 38 | H052 | Agenzie di Viaggio e Turismo — Fiavet/Confcommercio | Terziario | ~25k | ✅ | ✅ | 🤖 |
| 39 | H012 | Terziario Distribuzione e Servizi — Confesercenti | Terziario | ~230k | ✅ | ✅ | 🤖 |
| 40 | H052 | Turismo — Federalberghi/Faita | Terziario | ~220k | ✅ | ✅ | 🤖 |
| 41 | S005 | Funzioni Centrali 2022-2024 — ARAN (Ministeri, Agenzie, INPS, INAIL) | Pubblica Amministrazione | ~250k | ✅ | ✅ | 🤖 |
| 42 | S105 | Funzioni Locali 2022-2024 — ARAN (Comuni, Province, Regioni, Camere di Commercio) | Pubblica Amministrazione | ~400k | ✅ | ✅ | 🤖 |
| 43 | S205 | Comparto Sanità 2022-2024 — ARAN (SSN non-dirigenza) | Pubblica Amministrazione | ~580k | ✅ | ✅ | 🤖 |
| 44 | S225 | Area Sanità 2022-2024 — ARAN (Dirigenti Medici e Veterinari SSN) | Pubblica Amministrazione | ~100k | ✅ | ✅ | 🤖 |
| 45 | S225 | Area Sanità 2022-2024 — ARAN (Dirigenti Sanitari: psicologi, farmacisti, biologi) | Pubblica Amministrazione | ~37k | ✅ | ✅ | 🤖 |
| 46 | S125 | Area Dirigenza Funzioni Locali 2022-2024 — ARAN (Dirigenti enti locali, Segretari comunali) | Pubblica Amministrazione | ~13k | ✅ | ✅ | 🤖 |
| 47 | S025 | Area Dirigenza Funzioni Centrali 2022-2024 — ARAN (Dirigenti ministeri, agenzie fiscali, INPS, INAIL) | Pubblica Amministrazione | ~30k | ✅ | ✅ | 🤖 |
| 48 | S325 | Area Dirigenza Istruzione e Ricerca 2022-2024 — ARAN (Dirigenti scolastici, universitari, ricerca) | Pubblica Amministrazione | ~8k | ✅ | ✅ | 🤖 |
| 49 | S305 | Comparto Istruzione e Ricerca 2022-2024 — ARAN (Docenti e ATA scuola, università, ricerca) | Pubblica Amministrazione | ~1,2M | ✅ | ✅ | 🤖 |
| 50 | T011 | Case di Cura Private - Personale Non Medico (AIOP/ARIS) | Sanità privata | ~150k | ✅ | ✅ | 🤖 |
| 51 | H501 | Lavoro Domestico — DOMINA/FIDALDO/ASSINDATCOLF (conviventi) | Lavoro Domestico | ~900k | ✅ | ✅ | 🤖 |
| 52 | H501 | Lavoro Domestico — DOMINA/FIDALDO/ASSINDATCOLF (non conviventi) | Lavoro Domestico | ~900k | ✅ | ✅ | 🤖 |
| 53 | A011 | Operai Agricoli e Florovivaisti — Coldiretti/Confagricoltura/CIA | Agricoltura | ~600k | ✅ | ✅ | 🤖 |
| 54 | B018 | Chimica e Affini PMI — Unionchimica Confapi | Chimica | ~56k | ✅ | ✅ | 🤖 |
| 55 | E023 | Panificazione e Settori Affini Industria — Assipan/Fiesa/Federpanificatori | Alimentare | ~20k | ✅ | ✅ | 🤖 |
| 56 | I320 | Attività Ferroviarie — AGENS | Trasporto | ~75k | ✅ | ✅ | 🤖 |
| 57 | I810 | Trasporto Aereo — Gestori Aeroportuali (Assaeroporti) | Trasporto | ~40k | ✅ | ✅ | 🤖 |
| 58 | K540 | Igiene Ambientale — Servizi Ambientali e di Igiene Urbana (Utilitalia/FISE) | Industria | ~65k | ✅ | ✅ | 🤖 |
| 59 | A021 | Impiegati e Tecnici Agricoli — Confagricoltura/CIA/Coldiretti | Agricoltura | ~80k | ✅ | ✅ | 🤖 |
| 60 | — | Forze di Polizia ad ordinamento civile 2022-2024 — DPR 53/2025 (Polizia di Stato, Polizia Penitenziaria) | Pubblica Amministrazione | ~130k | ✅ | ✅ | 🤖 |
| 61 | G029 | Comunicazione, Informatica e Servizi Innovativi PMI — Unimatica-Confapi (Settore Informatico) | Industria | ~20k | ✅ | ✅ | 🤖 |
| 62 | T241 | Istituzioni Formative Private (Scuole Private Religiose) — AGIDAE | Terziario | ~50k | ✅ | ⚠️ | 🤖 |
| 63 | J121 | Assicurazioni — ANIA | Credito | ~45k | ✅ | ⚠️ | 🤖 |
| 64 | B254 | Energia e Petrolio — Confindustria Energia | Industria | ~38k | ✅ | ✅ | 🤖 |
| 65 | H016 | Distribuzione Cooperativa — ANCC-Coop | Terziario | ~63k | ✅ | ✅ | 🤖 |
| 66 | D0L1 | Lavanderie Industriali — Assosistema (turismo) | Industria | ~17k | ⚠️ | ✅ | 🤖 |
| 67 | H601 | CED, ICT, Professioni Digitali e STP — Assoced | Terziario | ~22k | ✅ | ✅ | 🤖 |
| 68 | A051 | Attivita Agromeccaniche (Contoterzismo) — CAI Agromec | Agricoltura | ~4k | ✅ | ✅ | 🤖 |
| 69 | A131 | Consorzi di Bonifica — SNEBI | Agricoltura | ~4k | ✅ | ✅ | 🤖 |
| 70 | A141 | Consorzi Agrari — ASSOCAP | Agricoltura | ~2k | ✅ | ✅ | 🤖 |
| 71 | A221 | Organizzazioni Allevatori e Enti Zootecnici — AIA | Agricoltura | ~2k | ✅ | ✅ | 🤖 |
| 72 | E018 | Dipendenti PMI Alimentare — Unionalimentari-Confapi | Alimentare | ~35k | ✅ | ✅ | 🤖 |
1. Approximate estimates. Sources: CNEL, INPS, Ministero del Lavoro, CCNL renewal communications.
2. Salary tables were extracted from official CCNL documents using Claude Code (AI-assisted), without manual human review. Values should be verified against the official source before use in production payroll systems.
The 62 contracts above cover approximately 14.5 million workers (sum of per-CCNL estimates; some overlap is possible where sector boundaries are not mutually exclusive, so the unique-worker count is somewhat lower). Italy has roughly 16 million employees covered by some collective agreement (ISTAT/CNEL 2024, public and private sectors combined). This library therefore reaches an estimated ~85–90% of CCNL-covered workers on a gross-headcount basis.
Advanced usage
Second-level bargaining (territorial and company agreements)
Supplements from territorial or company agreements (contrattazione di secondo livello) can be added at runtime via Scenario.second_level_allowances. Pass a tuple of SupplementaryAllowance objects, each with a plain monthly amount and relevance flags:
from ccnl_engine import SupplementaryAllowance
scenario = Scenario(
...,
second_level_allowances=(
# Territorial supplement paid every month, included in INPS and TFR bases.
SupplementaryAllowance(
code="ERT",
description="Elemento Retributivo Territoriale Veneto",
monthly=Decimal("150.00"),
),
# Result bonus paid once a year, not TFR-relevant.
SupplementaryAllowance(
code="PDR",
description="Premio di risultato aziendale",
monthly=Decimal("500.00"),
months_per_year=1,
tfr_relevant=False,
),
),
)
payslip = compute(ccnl, rules, scenario)
print(payslip.second_level_monthly) # scaled aggregate, already in gross_monthly
Each item is scaled by part_time_pct. The apprenticeship_pct_relevant flag controls whether the apprenticeship percentage also applies (default True). second_level_allowances is mutually exclusive with negotiated_ral / negotiated_destination_ral. The preferential 5% substitute tax on premio di risultato (Art. 1 c. 182 L. 208/2015) is not yet modelled.
IVS contributory ceiling split (Art. 1 L. 335/1995)
Workers enrolled in INPS on or after 1 January 1996 are subject to the massimale annuo della base contributiva (EUR 122,295 for 2026). Above this ceiling, only non-IVS contributions (NASpI, CUAF, CIG) continue:
scenario = Scenario(..., ivs_ceiling_applies=True)
When True and the relevant tax file carries a ceiling value, the engine applies INPS contributions in two parts: the IVS rate on min(gross_annual, ceiling) and the remaining rate on the full base. Defaults to False (no ceiling) for backward compatibility.
What is not modelled
- Detrazioni per carichi di famiglia (Art. 12 TUIR)
- Bilateral system contributions (EST, Fon.Te, …)
- Overtime, night/holiday premiums, leave accruals, sick-pay integrations
- Preferential 5% tax on premio di risultato (Art. 1 c. 182 L. 208/2015)
See API docs for full detail.
Disclaimer
This library is not legal or tax advice. Figures are computed from publicly available CCNL tables and statutory rates as of the dates indicated in the data files. Always verify results against official sources or a qualified payroll professional.
Metadata
Release files for ccnl-engine 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ccnl_engine-0.2.0.tar.gz | 339.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ccnl_engine-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 677.4 kB
Release files / ccnl_engine-0.2.0.tar.gz
| Download URL | ccnl_engine-0.2.0.tar.gz |
|---|---|
| Size | 339.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9233c742e11ff58e702fab3aadcfdd5123a7c33e8a4a7df4d3fb7aabbfc12f64
|
|
BLAKE2b-256 checksum How to use checksums |
09eed0547ef1c8793fa4a07cf48ea651b37b26939c2172f34e15b4aeac28e975
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 5, 2026.
Transparency logRelease files / ccnl_engine-0.2.0-py3-none-any.whl
| Download URL | ccnl_engine-0.2.0-py3-none-any.whl |
|---|---|
| Size | 338.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
711e5763c8303c1d97b75648fb5c618b49a551aacd9605b11870387f20a5ebb1
|
|
BLAKE2b-256 checksum How to use checksums |
0641e9b57d771be7a61f472eadc90c540bc9bae34b6285c6c2aee5c9f45ae61a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 5, 2026.
Transparency log