ccnl_engine.events¶
The work events of a run: pass them in PeriodFacts.events. Each changes
gross, net and employer cost according to its treatment; see
Work rules for the rules and the CCNL bands.
ccnl_engine.events.AbsenceEvent
dataclass
¶
Unpaid absence: deducted via EMPLOYEE_DEDUCTIONS; reduces INPS and TFR base.
Attributes:
| Name | Type | Description |
|---|---|---|
event_date |
date
|
Start date (or sole date) of the absence. |
hours |
Decimal
|
Number of absent hours. Must be > 0. |
hourly_rate |
Decimal
|
Rate at which the pay is deducted in EUR. Must be > 0. |
end_date |
date | None
|
Last day of the absence range. |
suspends_accrual |
bool | None
|
|
no_pay_due |
bool | None
|
|
days
property
¶
Calendar days of the absence, first to last.
ccnl_engine.events.ArrearsEvent
dataclass
¶
Contract renewal arrears, taxed by the year they refer to.
Arrears of a tax year earlier than the run are taxed separately (art. 17
c. 1 lett. b TUIR; art. 19 c. 1 lett. b D.Lgs. 117/2026 from 2027) at
:attr:separate_tax_rate; arrears of the tax year
of the run are ordinary income of the run and the rate is not used.
Attributes:
| Name | Type | Description |
|---|---|---|
event_date |
date
|
Date the arrears are attributed to. |
amount |
Decimal
|
Gross arrears amount in EUR. Must be >= 0. |
separate_tax_rate |
Decimal
|
Caller-supplied rate of the separate taxation: the rate on half the income of the two years before the year of receipt (art. 21 c. 1 TUIR; art. 23 c. 1 D.Lgs. 117/2026 from 2027). Must be in [0, 1]. |
reference_period |
PeriodId | None
|
The competence period the arrears refer to. An
earlier tax year selects the separate taxation, the tax year of
the run the ordinary one, a later year is rejected. |
ccnl_engine.events.BilateralFundEvent
dataclass
¶
Bilateral or health fund contribution (fondi bilaterali/sanitari).
Both employee and employer portions are expressed as gross amounts. The employee portion reduces net pay; the employer portion increases employer cost.
Attributes:
| Name | Type | Description |
|---|---|---|
event_date |
date
|
Date the contribution is attributed to. |
employee_amount |
Decimal
|
Employee-side contribution in EUR. Must be >= 0. |
employer_amount |
Decimal
|
EmployerProfile-side contribution in EUR. Must be >= 0. |
ccnl_engine.events.BonusEvent
dataclass
¶
One-off bonus: INPS + IRPEF (ordinary or substitute) + TFR excluded.
Attributes:
| Name | Type | Description |
|---|---|---|
event_date |
date
|
Date the bonus is attributed to. |
amount |
Decimal
|
Gross bonus amount in EUR. Must be >= 0. |
kind |
Literal['bonus', 'productivity_bonus', 'contract_renewal']
|
|
agreement_signed_on |
date | None
|
Signing date of the CCNL renewal a
|
The prior-year income and the written waiver the regimes check are
declared once in
:class:~ccnl_engine.irpef.declaration.inputs.PriorYearTaxFacts.
ccnl_engine.events.FringeEvent
dataclass
¶
Fringe benefit (art. 51 co. 3 TUIR).
The annual exemption threshold is resolved by calculate_period from
the year-level VariablePayRules.fringe_benefit policy — it is not
carried on the event itself. Taxability is determined cumulatively
across all fringe events in the year (YTD + current period).
Attributes:
| Name | Type | Description |
|---|---|---|
event_date |
date
|
Date the benefit is attributed to. |
amount |
Decimal
|
Value of the fringe benefit in EUR. Must be >= 0. |
ccnl_engine.events.HolidayWorkEvent
dataclass
¶
Holiday or weekly rest-day supplement: INPS + IRPEF on the supplement.
Covers the maggiorazioni and indennita for work on public holidays and on weekly rest days as identified by the CCNL, eligible for the 15% substitute tax within the 1,500 EUR annual cap. TFR is not accrued on holiday supplements under the standard Italian treatment (art. 2120 c.c. excludes accidental pay).
Attributes:
| Name | Type | Description |
|---|---|---|
event_date |
date
|
Calendar date the holiday or rest day was worked. |
supplement_amount |
Decimal
|
Flat supplement for the day in EUR. Must be >= 0. |
ccnl_engine.events.NightShiftEvent
dataclass
¶
Night-work supplement: INPS + IRPEF on the supplement amount.
Covers the maggiorazioni and indennita for night work (D.Lgs. 66/2003 art. 1 c. 2 and the CCNL), eligible for the 15% substitute tax within the 1,500 EUR annual cap.
Attributes:
| Name | Type | Description |
|---|---|---|
event_date |
date
|
Calendar date the shift was worked. |
supplement_amount |
Decimal
|
Flat supplement for the night period in EUR. Must be >= 0. |
ccnl_engine.events.OvertimeEvent
dataclass
¶
Overtime hours: INPS + IRPEF + TFR on computed gross.
Attributes:
| Name | Type | Description |
|---|---|---|
event_date |
date
|
Calendar date the overtime was worked. |
hours |
Decimal
|
Number of overtime hours, above 0 and at most the 744 hours of a month of 31 days. |
hourly_rate |
Decimal
|
Base hourly rate in EUR. Must be > 0. |
multiplier |
Decimal | None
|
Overtime multiplier applied to the hourly rate (e.g.
|
kind |
OvertimeKind
|
When the hours were worked, selecting the CCNL band. |
ccnl_engine.events.OvertimeKind
¶
Bases: StrEnum
When overtime hours were worked, selecting the CCNL overtime band.
The values match the work kinds the CCNL time_supplements bands
apply to.
Attributes:
| Name | Type | Description |
|---|---|---|
WEEKDAY |
Daytime overtime on a working day (straordinario diurno). |
|
NIGHT |
Night overtime (straordinario notturno). |
|
HOLIDAY |
Overtime on a public holiday or rest day (straordinario festivo). |
|
REST_DAY |
Overtime on the weekly rest day (Sunday, or the day the
rest moves to) where the CCNL pays it apart from the public
holidays; a CCNL without a rest-day band pays it as |
|
NIGHT_HOLIDAY |
Night overtime on a public holiday (straordinario festivo notturno). |
ccnl_engine.events.PeriodId
dataclass
¶
Identifies a single payroll period by calendar year and month.
Use this instead of relying on structural.employment.as_of to
identify the competence period. Both the period calculation request and
:class:~ccnl_engine.period.results.PeriodResult carry a
period_id so consumers can match requests to results without parsing
dates.
Attributes:
| Name | Type | Description |
|---|---|---|
year |
int
|
Calendar year (e.g. |
month |
int
|
Month of competence, 1-12. |
ccnl_engine.events.ShiftWorkEvent
dataclass
¶
Shift-work allowance: INPS + IRPEF on the supplement amount.
Covers the indennita di turno and the other shift-work pay set by the CCNL, eligible for the 15% substitute tax within the 1,500 EUR annual cap. TFR is not accrued, as for the other work-time supplements.
Attributes:
| Name | Type | Description |
|---|---|---|
event_date |
date
|
Calendar date the shift was worked. |
supplement_amount |
Decimal
|
Shift allowance in EUR. Must be >= 0. |
ccnl_engine.events.SickLeaveEvent
dataclass
¶
Sick pay amount set by the caller: an explicit, never payable override.
The engine computes sickness from a
:class:~ccnl_engine.sickness.models.SicknessEpisode. This
event overrides that computation with an employer-paid amount the
caller computed; the run records a caller-supplied decision for the
sickness capability, so its result is not payable. The amount is
subject to INPS and IRPEF but not TFR accrual.
The engine deducts the carenza (waiting-period) portion from amount:
net = amount - (amount / sick_days * waiting_period_days).
Attributes:
| Name | Type | Description |
|---|---|---|
event_date |
date
|
First day of the sick-leave period. |
amount |
Decimal
|
Total employer-liable sick-leave gross in EUR, before carenza deduction. |
sick_days |
int
|
Total working days of the sick-leave spell. Must be >= 1. Used to compute the daily rate for the carenza deduction. Defaults to 1. |
waiting_period_days |
int
|
Number of carenza days (waiting period) at the start of the sick-leave period. Must not exceed sick_days. Defaults to 0 (no carenza). |
ccnl_engine.events.SicknessEpisode
dataclass
¶
One sickness episode, a work event of every run whose month it touches.
Attributes:
| Name | Type | Description |
|---|---|---|
episode_id |
str
|
Stable identifier of the episode, the same in every run (e.g. the protocol number of the first certificate). |
started_on |
date
|
First day of illness. |
ended_on |
date
|
Last day of illness on the certificates known so far. A later run may pass a later day when the illness is extended. |
relapse_of |
str | None
|
Identifier of the episode this one continues, when the certificate marks it as a relapse (ricaduta): the days of both count as one episode, so no new waiting period applies. |
short_absence_exempt |
bool | None
|
Whether the CCNL exempts the absence from the
lower pay of repeated absences (for Federmeccanica: a hospital
stay or day hospital, sickness during a certified pregnancy, or
one of the diseases the CCNL lists; for Commercio, Art. 187: a
hospital stay, day hospital or dialysis, an initial prognosis of
at least 12 days, the listed diseases, or a pregnancy); |
hospital_stays |
tuple[tuple[date, date], ...] | None
|
Hospital stays within the episode, each its first
and last day; |
serious_illness |
bool | None
|
Whether the illness is one the CCNL treats as
particularly serious (Logistica: INPS circ. 95/2016); |
periodic_check |
bool | None
|
Whether the absence is a periodic check of a worker
who had an invalidating illness (Concia art. 60 B), which a CCNL
may leave out of the comporto; |
daily_contributions |
int | None
|
Daily contributions of the worker from 1
January of the year before the episode, every employer counted
(spettacolo: art. 66 D.L. 73/2021); |
prior_worked_days |
int | None
|
Days of work activity of a fixed-term worker in
the 12 months before the episode, with every employer (D.L.
463/1983 art. 5 c. 1); |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When the identifier is blank, a day is not a
date, |
event_date
property
¶
First day of the episode: the date of the event.
days
property
¶
Calendar days from :attr:started_on to :attr:ended_on.
long_stay_days(more_than, day)
¶
Return the days up to day of the stays longer than more_than.
Returns:
| Type | Description |
|---|---|
int
|
The days from the start of each such stay to |
int
|
of |
within(first, last)
¶
Return the days of the episode from first to last.
Returns:
| Type | Description |
|---|---|
tuple[date, date] | None
|
The first and last sick day of the interval, |
tuple[date, date] | None
|
episode does not touch it. |
through(day)
¶
Return the episode cut at day, the last day processed.
Returns:
| Type | Description |
|---|---|
SicknessEpisode
|
The episode ending on |
before(day)
¶
Return the part of the episode before day.
Returns:
| Type | Description |
|---|---|
SicknessEpisode | None
|
The episode cut on the day before |
SicknessEpisode | None
|
starts on or after |
ccnl_engine.events.StandbyEvent
dataclass
¶
Standby (reperibilità) paid at the CCNL rates of the worker's level.
The time of the calls and of the intervention is not standby: it is paid as overtime or ordinary hours with their own events.
Attributes:
| Name | Type | Description |
|---|---|---|
event_date |
date
|
Date the standby is attributed to: the rates in force on it apply. |
kind |
StandbyKind
|
Unit of the standby. |
quantity |
Decimal
|
Hours, days or weeks of the unit, above 0. |
calls |
int
|
Calls followed by an intervention, each paid the CCNL fee. |
ccnl_engine.events.StandbyKind
¶
Bases: StrEnum
Unit of a standby period, selecting the CCNL rate.
Attributes:
| Name | Type | Description |
|---|---|---|
HOURS |
Hours of standby, paid at the working-day rate per hour. |
|
WORKED_DAY |
Day of 16 hours on a working day. |
|
REST_DAY |
Day of 24 hours on a rest day. |
|
HOLIDAY |
Day of 24 hours on a public holiday. |
|
WEEK |
Week of 6 days. |
|
WEEK_HOLIDAY |
Week of 6 days with a public holiday. |
|
WEEK_HOLIDAY_REST_DAY |
Week of 6 days with a public holiday and a rest day. |
ccnl_engine.events.TerminationTFREvent
dataclass
¶
TFR settlement at cessazione (art. 19 TUIR, tassazione separata).
The caller supplies the applicable tax rate (determined via art. 19 TUIR using the employee's prior-year average IRPEF rate).
Attributes:
| Name | Type | Description |
|---|---|---|
event_date |
date
|
Date of cessazione. |
amount |
Decimal
|
Total TFR payout in EUR. Must be >= 0. |
separate_tax_rate |
Decimal
|
Applicable tassazione separata rate. Must be in [0, 1]. |
ccnl_engine.events.TravelAllowanceEvent
dataclass
¶
Daily travel allowance (indennità di trasferta) of a block of days.
The allowance outside the comune is income only above the daily cap of art. 51 c. 5 TUIR, for IRPEF and INPS alike (art. 12 c. 2 L. 153/1969); within the comune it is income in full. One event covers days with the same daily amount and the same conditions. Analytic reimbursements and travel costs are not pay and are not events.
Attributes:
| Name | Type | Description |
|---|---|---|
event_date |
date
|
Date the block of days is attributed to. |
days |
int
|
Days of trasferta, at least 1. |
outside_municipality |
bool
|
Whether the trasferta is outside the comune of the place of work: within it no part is exempt. |
meals_lodging |
Literal['none', 'one', 'both']
|
|
daily_amount |
Decimal | None
|
Allowance paid for each day in EUR, above 0; |
hours_away |
Decimal | None
|
Hours away of each day, read with |
tfr_base |
Literal['none', 'whole', 'above_exempt'] | None
|
What enters the TFR base: |
abroad |
bool
|
Whether the trasferta is abroad, with the higher cap. |
trasfertista |
bool
|
Whether the worker is bound by contract to work in places always different (art. 51 c. 6 TUIR, 50% exempt): not supported, the event is rejected. |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When a field is invalid, neither
|
ccnl_engine.events.WelfareEvent
dataclass
¶
Welfare benefit: exempt from INPS and IRPEF, no TFR accrual.
Attributes:
| Name | Type | Description |
|---|---|---|
event_date |
date
|
Date the benefit is attributed to. |
amount |
Decimal
|
Value of the welfare benefit in EUR. Must be >= 0. |