ccnl_engine.inputs¶
Every fact a caller passes beyond the common path of the root: optional
fields of Employment, EmployerProfile and PeriodFacts, tax facts, the
calendar, the engine mode, the opening state and imported balances. See
Opening state and imported balances for the
state types.
Contract type, hours and seniority¶
ccnl_engine.inputs.Apprentice
dataclass
¶
Apprenticeship contract; salary is derived from CCNL apprenticeship rules.
Attributes:
| Name | Type | Description |
|---|---|---|
months_elapsed |
int
|
Months of apprenticeship service elapsed so far,
|
track |
str | None
|
Name of the CCNL apprenticeship track to apply. Required
only when more than one track covers the destination level;
|
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When |
ccnl_engine.inputs.FixedTerm
dataclass
¶
Fixed-term contract, which may owe the NASpI surcharge.
Attributes:
| Name | Type | Description |
|---|---|---|
renewals |
int | None
|
Renewals of the fixed-term contract with the same
employer, this contract being the last, signed from 14 July
2018 (INPS circ. 121/2019 par. 2.3: earlier renewals are not
counted). A prorogation of the term is not a renewal. Each
renewal raises the surcharge by 0.5 points. |
naspi_exclusion |
NaspiExclusion | None
|
The exclusion of c. 29 the contract falls in,
:attr: |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When |
ccnl_engine.inputs.NaspiExclusion
¶
Bases: StrEnum
Why the NASpI surcharge of a fixed-term contract is not charged.
Sources: L. 92/2012 art. 2 c. 28-29 and D.L. 87/2018 art. 1 c. 3, text
in force on Normattiva on 7 October 2026; INPS circ. 121/2019 par. 2.2
and 2.4. Apprentices (c. 29 lett. c) are not a reason here: an
apprenticeship is an :class:~ccnl_engine.employment.inputs.Apprentice contract,
which never pays the surcharge. Operai agricoli
(c. 3) are not a reason either: the bundle marks the categories of the
sector the whole article does not apply to.
Attributes:
| Name | Type | Description |
|---|---|---|
NONE |
No exclusion: the surcharge and its renewal increase apply. |
|
REPLACEMENT |
Hired to replace absent workers (c. 29 lett. a). |
|
SEASONAL |
Hired for the seasonal activities of DPR 1525/1963, or for those of the CCNLs of the provincia di Bolzano signed by 31 December 2019 (c. 29 lett. b and b-bis). |
|
PUBLIC_ADMINISTRATION |
Employed by a public administration of art. 1 c. 2 D.Lgs. 165/2001 (c. 29 lett. d). |
|
SHORT_SERVICE |
Special services of at most three days in tourism and public establishments, D.Lgs. 81/2015 art. 29 c. 2 lett. b (c. 29 lett. d-bis). |
|
RESEARCH |
Teaching or research at a private university, a public research institute, a public company promoting research or a private research body: the 1.4% applies, the renewal increase does not (D.L. 87/2018 art. 1 c. 3). |
ccnl_engine.inputs.Permanent
dataclass
¶
Standard open-ended (permanent) employment contract.
ccnl_engine.inputs.WorkerCategory
¶
Bases: StrEnum
Legal category of an employee under art. 2095 c.c.
The single category vocabulary shared by CCNL data (levels, seniority rules, employer funds), INPS contribution rules and employment facts. Values are the lowercase Italian names used in the bundled JSON.
Attributes:
| Name | Type | Description |
|---|---|---|
OPERAIO |
Manual worker. |
|
IMPIEGATO |
Clerical or technical employee. |
|
QUADRO |
Middle manager (L. 190/1985). |
|
DIRIGENTE |
Executive. |
ccnl_engine.inputs.EmploymentPeriod
dataclass
¶
Start and optional end of the employment relationship.
Attributes:
| Name | Type | Description |
|---|---|---|
started_on |
date
|
First day of employment. |
ended_on |
date | None
|
Last day of employment, or |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When a date is not a |
from_dates(started_on, ended_on)
classmethod
¶
Build a period from optional dates, as supplied by callers.
Returns:
| Type | Description |
|---|---|
EmploymentPeriod | None
|
|
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When only |
overlaps_month(year, month)
¶
Return whether the employment covers at least one day of a month.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
year
|
int
|
Calendar year of the month. |
required |
month
|
int
|
Calendar month, 1-12. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
covers_month(year, month)
¶
Return whether the employment covers every day of a month.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
year
|
int
|
Calendar year of the month. |
required |
month
|
int
|
Calendar month, 1-12. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
and does not end before the last day of the month. |
span_in_month(year, month)
¶
Return the first and last employed day of a calendar month.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
year
|
int
|
Calendar year of the month. |
required |
month
|
int
|
Calendar month, 1-12. |
required |
Returns:
| Type | Description |
|---|---|
tuple[date, date] | None
|
|
tuple[date, date] | None
|
when the employment has no day in it. |
clip_start(day)
¶
Return day, or the hire date when day precedes it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
day
|
date
|
A date, typically the first day of an accrual window. |
required |
Returns:
| Type | Description |
|---|---|
date
|
|
ccnl_engine.inputs.EmploymentSpell
dataclass
¶
Days of one employment within a tax year.
Attributes:
| Name | Type | Description |
|---|---|---|
first_day |
date
|
First day of the employment in the year. |
last_day |
date
|
Last day of the employment in the year: its end, or 31 December while the end is not stated. |
fixed_term |
bool
|
Whether the employment is fixed-term. |
unpaid_days |
tuple[date, ...]
|
Days of the spell for which no pay at all is due (aspettativa senza assegni), in order: they leave the days of the deductions (AdE circ. 15/E/2007 par. 1.5.1). |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When a field is not of its type, or the days are not of one year in order. |
with_unpaid(days)
¶
Return the spell with days added to its unpaid days.
Returns:
| Type | Description |
|---|---|
EmploymentSpell
|
The spell with the days of |
of(period, year, *, fixed_term)
classmethod
¶
Return the spell of period in year.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
period
|
EmploymentPeriod | None
|
The employment period; |
required |
year
|
int
|
The tax year. |
required |
fixed_term
|
bool
|
Whether the employment is fixed-term. |
required |
Returns:
| Type | Description |
|---|---|
EmploymentSpell | None
|
The spell, or |
ccnl_engine.inputs.WeeklyHours
dataclass
¶
Weekly working hours, contracted or full-time.
Attributes:
| Name | Type | Description |
|---|---|---|
value |
int
|
Hours per week, |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When |
ccnl_engine.inputs.ContributableHours
dataclass
¶
Hours worked and paid in a period that are subject to INPS contributions.
Zero is valid (a period with no paid hours).
Attributes:
| Name | Type | Description |
|---|---|---|
value |
Decimal
|
Finite :class: |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When |
ccnl_engine.inputs.SeniorityFact
dataclass
¶
Recognised seniority of the worker, for seniority increments.
The seniority is a fact as of a date: the engine ages it to each run.
The increments and the service-gated allowances of a run use the
months of service completed by the first day of its competence month,
so an increment matured during a month is paid from the next one, and
service starting within the month counts zero months (see
:meth:months_in_month). A month is complete on the same day of the
following month.
Use :meth:since when the caller knows the date the recognised
seniority starts from instead of a count of months.
Attributes:
| Name | Type | Description |
|---|---|---|
months |
int
|
Completed months of recognised service on |
as_of |
date
|
Date the months are counted at. |
source |
SenioritySource
|
Where the seniority was read from; a string value of
:class: |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When |
since(recognised_from, source)
classmethod
¶
Return the seniority that starts on recognised_from.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
recognised_from
|
date
|
First day of recognised service, which may precede the hire date when the employer recognises earlier service. |
required |
source
|
SenioritySource
|
Where the date was read from. |
required |
Returns:
| Type | Description |
|---|---|
SeniorityFact
|
Zero months as of |
months_at(day)
¶
Return the completed months of recognised service on day.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
day
|
date
|
The date to age the seniority to; it may precede
|
required |
Returns:
| Type | Description |
|---|---|
int
|
|
int
|
minus them when |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When |
months_in_month(year, month)
¶
Return the months of service a run of a month counts.
A run counts the months completed by the first day of its month. Service that starts within the month counts zero months: the hire month of a worker whose seniority is recognised from the hire date.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
year
|
int
|
Year of the competence month. |
required |
month
|
int
|
Competence month, 1-12. |
required |
Returns:
| Type | Description |
|---|---|
int
|
The completed months on the first day of the month, at least 0. |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When the recognised service starts after the last day of the month. |
ccnl_engine.inputs.SenioritySource
¶
Bases: StrEnum
Where the caller read the recognised seniority from.
Attributes:
| Name | Type | Description |
|---|---|---|
EMPLOYER_RECORDS |
The personnel file or the libro unico del lavoro. |
|
PAYSLIP |
A previous payslip of the same employment. |
|
EMPLOYMENT_CONTRACT |
The letter of hire, for a seniority recognised on hiring (anzianita convenzionale). |
ccnl_engine.inputs.ContributionHistory
dataclass
¶
The pension history that decides whether the IVS massimale applies.
L. 335/1995 art. 2 c. 18 caps the IVS contribution base at an annual massimale (EUR 122,295 in 2026) for workers without contributions before 1 January 1996 and for those who opted for the contributory system under art. 1 c. 23. Every other worker contributes on the full base. The engine derives the eligibility from these facts; the caller never states it.
The history is the one in force for the run being computed: the engine models no effective date of a change. Pre-1996 periods credited on request to a worker hired after 1995 lift the massimale only from the month after the request (L. 208/2015 art. 1 c. 280), and the option takes effect from when it is exercised: for the runs before those dates, supply the history as it stood then.
Attributes:
| Name | Type | Description |
|---|---|---|
first_enrolled_on |
date
|
Date of the first contribution credited to any mandatory pension scheme (prima iscrizione), from the worker's contribution statement. |
contributory_option |
bool
|
Whether the worker opted for the contributory
system (L. 335/1995 art. 1 c. 23). Defaults to |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When a field is not of its type. |
ccnl_engine.inputs.EmploymentSector
¶
Bases: StrEnum
Whether the worker is employed in the private or the public sector.
Attributes:
| Name | Type | Description |
|---|---|---|
PRIVATE |
Employer outside the public administrations. |
|
PUBLIC |
Public administration employer (D.Lgs. 165/2001 art. 1 c. 2). |
ccnl_engine.inputs.PensionFundEnrolment
dataclass
¶
The worker's enrolment in a pension fund of the CCNL.
Enrolment is voluntary (D.Lgs. 252/2005 art. 1 c. 2), so it is a fact
of the employment, never derived from the CCNL. The employer rate and
its base come from the fund in CCNL.parameters.employer_funds.
Attributes:
| Name | Type | Description |
|---|---|---|
fund_code |
str
|
Code of the fund in the CCNL data, e.g. |
employee_rate |
Decimal
|
Contribution the worker chose, as a fraction of the
same base as the employer rate, e.g. |
tfr_to_fund |
bool
|
Whether the TFR accrued is paid to the fund (D.Lgs. 252/2005 art. 8 c. 1-2). Required: the choice is the worker's, and it moves the TFR out of the company. |
young_member |
bool | None
|
Whether the worker belongs to the members the CCNL
favours for the age at enrolment (Cometa: enrolled after 5
February 2021 before turning 35), read only by a fund with a
|
conventional_base |
Decimal | None
|
Monthly base the fund applies to the worker, read
only by a fund on a conventional base (Previambiente: the base
pay of the level at 1 January 1997, its contingenza and one
scatto, e.g. 2077.84 for a quadro); |
seniority_to_fund |
bool
|
Whether the worker opted to convert the
seniority increments into fund contributions, read only by a
fund with a |
seniority_converted_on |
date | None
|
Date of the request of a worker already in
service (lett. A) bis c. 6): the increments matured by then stay
in the pay, frozen, and only the later ones are converted;
|
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When a field is not of its type, |
tfr_only
property
¶
Whether the worker confers the TFR alone, with no contribution.
ccnl_engine.inputs.NoPensionFund
dataclass
¶
The worker is stated not enrolled in a pension fund of the CCNL.
It is the fact Employment.pension_fund left None does not
state: on every CCNL but domestic work, an unknown enrolment leaves the
contributions to the fund undetermined. Whether the TFR of a worker
who expressed no choice goes to the fund (D.Lgs. 252/2005 art. 8 c. 7)
is for the caller to establish: the engine does not infer it.
ccnl_engine.inputs.PublicEndOfService
¶
Bases: StrEnum
End-of-service regime of a public employee (DPCM 20 dicembre 1999).
Values
TFS: Trattamento di fine servizio (buonuscita or indennità premio di servizio) of INPS Gestione Dipendenti Pubblici: the worker pays 2.50% of the contribution base, the administration the rest. TFR_INPS: Trattamento di fine rapporto accrued notionally by INPS (art. 1 c. 6): the administration pays the whole contribution and the gross is reduced by the 2.50% the worker no longer pays (c. 3). TFR_EMPLOYER: Trattamento di fine rapporto the employer accrues and pays (art. 1 c. 6 and 8: enti pubblici non economici, enti di ricerca): no contribution to the Gestione, no reduction.
ccnl_engine.inputs.TfrFundBalance
dataclass
¶
TFR the worker has accrued with the employer at 31 December of a year.
The fund at 31 December of year, after the revaluation of that date
and net of the substitute tax charged to it, less the advances paid:
the TFR the next year revalues (art. 2120 c. 4 c.c.: the quota accrued
in the year is excluded). It includes the part paid to the Fondo
Tesoreria INPS, whose share the Fondo pays out under art. 2120 c.c.
(DM 30 gennaio 2007 art. 2 c. 1), and excludes the TFR paid to a
complementary pension fund.
Attributes:
| Name | Type | Description |
|---|---|---|
year |
int
|
Year at whose 31 December the balance is struck. |
amount |
Decimal
|
Balance in EUR, non-negative, with at most two decimals. |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When |
ccnl_engine.inputs.EmployerActivity
¶
Bases: StrEnum
Activity of the employer, where a regime excludes some activities.
L. 199/2025 art. 1 c. 11 excludes from the night, holiday and shift substitute tax the activities of c. 18: "esercizi di somministrazione di alimenti e bevande, di cui all'articolo 5 della legge 25 agosto 1991, n. 287" and "comparto del turismo, ivi inclusi gli stabilimenti termali". Their workers receive the trattamento integrativo speciale of c. 18 instead.
Attributes:
| Name | Type | Description |
|---|---|---|
FOOD_AND_BEVERAGE_SERVICE |
Somministrazione di alimenti e bevande (L. 287/1991 art. 5). |
|
TOURISM |
Comparto del turismo, other than thermal establishments. |
|
THERMAL_ESTABLISHMENT |
Stabilimenti termali. |
|
OTHER |
Any activity not listed above. |
ccnl_engine.inputs.AgriculturalZone
¶
Bases: StrEnum
Zone of the agricultural land, for the reduced contributions.
Attributes:
| Name | Type | Description |
|---|---|---|
ORDINARY |
No reduction. |
|
DISADVANTAGED |
A "zona svantaggiata": 68% less. |
|
MOUNTAIN |
A "zona particolarmente svantaggiata (ex montana)": 75% less. |
Family and tax facts¶
ccnl_engine.inputs.FamilyComposition
dataclass
¶
Caller-supplied family unit for Art. 12 TUIR deductions.
Used to compute the family deductions the employer applies as
sostituto d'imposta, on the reddito complessivo of
:class:~ccnl_engine.irpef.other_income.inputs.CurrentYearTaxFacts.
Eligibility conditions the engine cannot verify (residency, disability
certification, the dependents' own income) are taken as declared; one
left unknown grants no deduction (see :class:Dependent). The children
also select the fringe-benefit threshold (L. 207/2024 art. 1 c. 390).
Attributes:
| Name | Type | Description |
|---|---|---|
dependents |
tuple[Dependent, ...]
|
The dependents; a list is accepted and stored as a tuple. |
sole_parent |
bool
|
|
has_any_dependent
property
¶
True when at least one dependent is declared.
ccnl_engine.inputs.Dependent
dataclass
¶
One fiscally dependent family member for Art. 12 TUIR purposes.
The caller declares the dependent and the dated interval in which the conditions it cannot verify hold (marriage, cohabitation, residency, custody); the engine derives from it, month by month, the months the deduction is due (art. 12 c. 3: "rapportate a mese e competono dal mese in cui si sono verificate a quello in cui sono cessate le condizioni richieste") and, for a child, the months of the age band.
A condition left None is unknown, never met by default: when the
dependant would give right to a deduction in some month, the family
deductions of the run are not determined and the run has a
missing_fact blocker naming the field. A condition is read only
where art. 12 makes it one: own_income and
residency_eligibility for every dependant (c. 2 and c. 2-bis refer
to every deduction of c. 1), cohabiting for an ascendant (c. 1
lett. d), allocation_pct for a child and an ascendant (lett. c and
lett. d share the deduction; the spouse deduction of lett. a is not
shared). The dependency interval has no default: None is an open
end the caller states.
Attributes:
| Name | Type | Description |
|---|---|---|
relationship |
DependentRelationship
|
Relationship to the worker. |
birth_date |
date | None
|
Date of birth. Required for a child: the age band of lett. c is evaluated in every month. Ignored for a spouse or an ascendant. |
disabled |
bool
|
|
own_income |
Decimal | None
|
Dependent's own reddito complessivo of the year (EUR),
checked against the limit of art. 12 c. 2; |
allocation_pct |
Decimal | None
|
Percentage of the deduction allocated to this worker
(0-100): the share between the parents of lett. c, or the pro
quota share of lett. d. |
cohabiting |
bool | None
|
|
residency_eligibility |
bool | None
|
|
dependent_from |
date | None
|
First day the conditions hold; |
dependent_until |
date | None
|
Last day the conditions hold; |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When a field is not of its type or is outside its range, a child has no birth date, a spouse is allocated less than the whole deduction, or the interval ends before it starts. |
share
property
¶
Percentage of the deduction to this worker; 100 when not stated.
A child or an ascendant without a stated share has a missing fact
(:attr:missing_facts) and no deduction, so the 100 is never
applied to one.
missing_facts
property
¶
Conditions of art. 12 this dependant leaves unknown.
Returns:
| Type | Description |
|---|---|
str
|
The names of the fields left |
...
|
the relationship, in field order. |
may_qualify(income_limit)
¶
Return whether no stated condition excludes the deduction.
An unknown condition does not exclude it: the dependant may qualify once the fact is stated.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
income_limit
|
Decimal
|
Own-income limit of art. 12 c. 2 for this dependant. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
stated as not met, or the stated own income exceeds the limit. |
dependency_months(year)
¶
Return the months of year the conditions hold on some day.
Returns:
| Type | Description |
|---|---|
frozenset[int]
|
Months 1-12 the interval touches, both ends included (c. 3). |
ccnl_engine.inputs.DependentRelationship
¶
Bases: StrEnum
Relationship category of a fiscally dependent family member.
ccnl_engine.inputs.PriorYearTaxFacts
dataclass
¶
Prior-year income, written waivers and requests of the tax year.
The single source of the requirements the preferential regimes check: the premio di risultato (L. 208/2015 art. 1 c. 182, prior-year income up to 80,000 EUR), the renewal increments (L. 199/2025 art. 1 c. 7, 2025 income up to 33,000 EUR) and the night, holiday and shift supplements (L. 199/2025 art. 1 cc. 10-11, 2025 income up to 40,000 EUR). For a 2026 payment the prior year is 2025, the reference year of both L. 199/2025 regimes.
Attributes:
| Name | Type | Description |
|---|---|---|
employment_income |
Decimal | None
|
Employment income (reddito di lavoro dipendente)
of the year before the tax year, in EUR, |
waived_regimes |
frozenset[SubstituteTaxRegime]
|
Regimes the worker renounced in writing; their amounts are taxed as ordinary income. String values are accepted and normalized. |
shortfall_deferral |
ShortfallDeferralRequest | None
|
The worker's written request to have the IRPEF
the conguaglio cannot withhold for lack of pay withheld on the
payslips of the next year, with interest (art. 23 c. 3 DPR
600/1973). |
foreign_taxes |
tuple[ForeignTaxPaid, ...]
|
Foreign tax paid on employment income of the tax year, one entry per State, credited at the conguaglio (art. 165 TUIR, art. 23 c. 3 DPR 600/1973). A list is accepted and stored as a tuple. |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When |
ccnl_engine.inputs.CurrentYearTaxFacts
dataclass
¶
Income of the tax year that enters the reddito complessivo.
The family deductions of art. 12 TUIR depend on the reddito complessivo of the worker, not on the income of this employment alone. The engine adds to its own projection of the employment income of the year:
reddito complessivo = this employment + other_employment_income
+ other_income - main_dwelling_income
The somma esente of L. 207/2024 art. 1 c. 4 adds the exempt share of
the impatriati and researcher regimes (c. 9), exempt_regime_income.
Every amount is required: declaring no other income is a fact, stated
with zeros (see :meth:employment_only). Without these facts the
reddito complessivo is unknown, and a run whose family deductions depend
on it is not payable; so is a run whose contributions could depend on
the INPS base of other employments, unless the opening state states it.
Attributes:
| Name | Type | Description |
|---|---|---|
tax_year |
int
|
The tax year the income belongs to. Facts of another tax year are not used. |
other_employment_income |
Decimal
|
Employment and pension income of the tax
year from other employers or payers (e.g. a previous employer of
the year), net of their exclusions, |
other_employment_inps_base |
Decimal
|
INPS base of the worker's other
employments of :attr: |
other_income |
Decimal
|
Every other income of the tax year in the reddito
complessivo (land and buildings, self-employment, rents under
cedolare secca, art. 3 c. 7 D.Lgs. 23/2011), |
main_dwelling_income |
Decimal
|
Income of the main dwelling and its
appurtenances included in |
exempt_regime_income |
Decimal
|
Exempt share of the income of the tax year
under art. 44 c. 1 D.L. 78/2010 (researchers), art. 16 D.Lgs.
147/2015 or art. 5 D.Lgs. 209/2023 (impatriati), |
estimated_on |
date
|
Date the amounts were stated. |
quality |
IncomeEstimateQuality
|
How the amounts are known. |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When a field is not of its type or in its range. |
external_income
property
¶
Reddito complessivo of the year beyond this employment.
somma_esente_income
property
¶
Reddito complessivo beyond this employment for the somma esente.
L. 207/2024 art. 1 c. 9 adds the exempt share of the impatriati and
researcher regimes to :attr:external_income.
employment_only(tax_year, estimated_on, quality=IncomeEstimateQuality.DECLARED)
classmethod
¶
Return the facts of a worker whose only income is this employment.
Returns:
| Type | Description |
|---|---|
CurrentYearTaxFacts
|
Facts with every other income and the INPS base of other |
CurrentYearTaxFacts
|
employments stated as zero. |
ccnl_engine.inputs.IncomeEstimateQuality
¶
Bases: StrEnum
How the income of :class:CurrentYearTaxFacts is known.
Attributes:
| Name | Type | Description |
|---|---|---|
CERTIFIED |
Final amounts from a certification (Certificazione Unica of another employer) or from the worker's tax return. |
|
DECLARED |
The worker's declaration to the employer of the income expected in the year. |
|
ESTIMATED |
The employer's own estimate: enough for the runs of the year, not for the conguaglio, which then stays provisional. |
ccnl_engine.inputs.ForeignTaxPaid
dataclass
¶
Tax paid in one foreign State on income taxed in Italy this year.
Attributes:
| Name | Type | Description |
|---|---|---|
country |
str
|
ISO 3166-1 alpha-2 code of the State, not |
income |
Decimal
|
Foreign-source employment income as it entered the Italian taxable income of the tax year (the conventional pay when art. 51 c. 8-bis TUIR applies), in EUR, positive. |
tax |
Decimal
|
Foreign tax paid on it "a titolo definitivo", in EUR, |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When |
ccnl_engine.inputs.ShortfallDeferralRequest
dataclass
¶
The worker's written authorization to defer the year-end shortfall.
Attributes:
| Name | Type | Description |
|---|---|---|
signed_on |
date
|
Date of the written request. It must fall between 1 January of the tax year and the end of February of the next one, the deadline of the conguaglio. |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When |
check_for(tax_year)
¶
Check that the request can defer the conguaglio of tax_year.
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When |
ccnl_engine.inputs.SubstituteTaxRegime
¶
Bases: StrEnum
Preferential regimes a worker can renounce in writing.
Each value is the regime_id of a bundled
:class:PreferentialTaxRegime.
Attributes:
| Name | Type | Description |
|---|---|---|
RINNOVO |
Contract-renewal increments (L. 199/2025 art. 1 c. 7). |
|
NOTTE_FESTIVI_TURNI |
Night, holiday and shift supplements (L. 199/2025 art. 1 cc. 10-11). |
Calendar and engine mode¶
ccnl_engine.inputs.WorkCalendar
dataclass
¶
Year-level payroll calendar with extra-month schedule.
Attributes:
| Name | Type | Description |
|---|---|---|
year |
int
|
The tax year this calendar applies to. |
extra_months |
tuple[ExtraMonthSchedule, ...]
|
Ordered tuple of extra-month payment schedules. A list is accepted and stored as a tuple. |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When |
entitlement
property
¶
Equivalent months of pay granted by this calendar.
Twelve regular months plus the max_fraction of each extra month,
so a full tredicesima and half a quattordicesima give 13.5.
from_additional_months(year, additional_months, *, thirteenth_payment_month=12, fourteenth_payment_month=6)
classmethod
¶
Build a calendar from a CCNL additional_months parameter.
Accepts fractional values (e.g. Decimal("13.5")). A fractional
fourteenth month is added with :attr:ExtraMonthSchedule.max_fraction
set to the fractional part so the caller receives the correct partial
entitlement without discarding it.
For additional_months=13 (12 regular + 1 tredicesima) this
produces one :class:ExtraMonthSchedule paid in December.
For additional_months=14 it produces tredicesima (December) and
quattordicesima in fourteenth_payment_month (default June).
For additional_months=13.5 it produces tredicesima (full) and a
half quattordicesima (max_fraction=Decimal("0.5")).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
year
|
int
|
Tax year. |
required |
additional_months
|
int | Decimal | ExtraMonthEntitlement
|
Value from CCNL parameters (13, 13.5 or 14),
as :class: |
required |
thirteenth_payment_month
|
int
|
Calendar month for the tredicesima. Defaults to December (12). |
12
|
fourteenth_payment_month
|
int
|
Calendar month for the quattordicesima. Defaults to June (6). |
6
|
Returns:
| Type | Description |
|---|---|
WorkCalendar
|
class: |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When |
ccnl_engine.inputs.CalendarOverride
dataclass
¶
A calendar that replaces the CCNL standard one, with its reason.
Attributes:
| Name | Type | Description |
|---|---|---|
calendar |
WorkCalendar
|
The calendar to run instead of the standard one. |
reason |
CalendarOverrideReason
|
Why the standard calendar does not apply. |
note |
str
|
Free-text justification kept for audit, e.g. the CCNL article or the agreement that sets the payment month. Must not be blank. |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When |
resolve(standard)
¶
Validate the override against the standard calendar and return it.
Rules, compared per :class:ExtraMonthKind on max_fraction
(names are free):
- the override is for the same year as
standard; - every extra month accrues over the 12 months ending in its payment
month (
accrual_window_start_month == payment_month % 12 + 1), so it pays its full fraction; a tredicesima is therefore paid in December; - every extra month of
standardis kept with at least its fraction, whatever the reason; - :attr:
CalendarOverrideReason.PAYMENT_MONTH: the fractions equal the standard ones, no extra month is added; - :attr:
CalendarOverrideReason.MORE_FAVOURABLE_TREATMENT: at least one extra month is added or has a larger fraction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
standard
|
WorkCalendar
|
Calendar derived from the CCNL for the same year. |
required |
Returns:
| Type | Description |
|---|---|
WorkCalendar
|
attr: |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When any rule is broken. |
ccnl_engine.inputs.CalendarOverrideReason
¶
Bases: StrEnum
Domain reason for replacing the standard calendar of a CCNL.
The list is deliberately short. Paying the ratei monthly inside the regular pay (mensilizzazione) is real practice, but the engine does not pay ratei in regular runs, so an override that drops extra-month runs would underpay the worker; no reason allows it.
Members
PAYMENT_MONTH: The CCNL article or the employer's practice pays an extra month in a different month than the engine default (quattordicesima in June), e.g. a quattordicesima paid with the July salary. The extra months and their fractions must equal the ones the CCNL grants. MORE_FAVOURABLE_TREATMENT: An individual or company agreement grants more than the CCNL (trattamento di miglior favore, art. 2077 c.c.): an extra month the CCNL does not grant, or a larger fraction of one it grants. Every CCNL extra month must be kept at least at its CCNL fraction, and at least one must be larger or added.
ccnl_engine.inputs.EngineMode
¶
Bases: StrEnum
Payability policy of a payroll engine.
Attributes:
| Name | Type | Description |
|---|---|---|
SIMULATION |
Amounts with their assurance; readiness is reported only. |
|
OPERATIONAL |
Amounts are payable only from |
Opening state and imported balances¶
ccnl_engine.inputs.PeriodState
dataclass
¶
State entering a payroll run: what is accrued and what is paid.
Pass :meth:zero for the first run of an employment. Between runs,
pass the closing_state of the previous run. To open the next tax
year, pass the closing state of the last run of the year to
:func:~ccnl_engine.year.tax_year.closing.rules.close_tax_year:
it restarts :attr:cash with its obligations and keeps :attr:accrual.
A run that opens without the history of the employment before it (a
zero state after the start of the employment, or a state descending
from such a run) is computed as a simulation with a missing_fact
opening_state blocker, and its closing state has :attr:history_known
False, so every later run of the chain blocks too. The same holds
for the closing state of a conguaglio of a withholding agent computed
without the worker's residence: it determines no surtax of the year
and opens none of the obligations of the next. Import the balances of
the previous provider, or recompute the chain with the missing facts,
to restart from a known history.
A run closes once (its competence run in :attr:accrual) and is paid
once (its payment in :attr:cash). The same request on the same
opening state yields the same closing state; a state that already closed
the run rejects it, so a retry never counts a payment twice.
Attributes:
| Name | Type | Description |
|---|---|---|
accrual |
EmploymentAccrualState
|
Competence runs closed over the employment; carried across tax years. |
cash |
TaxCashState
|
Payments, YTD accounts and carried obligations of the current tax year; the payments and accounts restart every tax year. |
history_known |
bool
|
Whether the state accounts for every run of the
employment before it. The engine sets it |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When a field is not of its type, or a payment of
:attr: |
tax_year
property
¶
Tax year of :attr:cash; None when not yet bound to a year.
check_next(payment)
¶
Check that payment and the run it settles can close next.
A run already closed or out of order in its competence year, or a
payment that cannot close in the tax year, raises
InvalidInputError.
zero()
classmethod
¶
Return the state of a new employment: no run closed, no obligation.
Returns:
| Name | Type | Description |
|---|---|---|
A |
PeriodState
|
class: |
ccnl_engine.inputs.period_state_from_json(text)
¶
Return the state written by :func:period_state_to_json.
A text that is not such JSON, written by another schema, engine or
knowledge-bundle version, or that names a type outside the persisted
state raises :class:~ccnl_engine.errors.InvalidInputError:
recompute the runs, or import the balances with
:class:~ccnl_engine.balance.opening.provider.services.OpeningBalances.
Returns:
| Type | Description |
|---|---|
PeriodState
|
The state, its invariants checked by its constructors. |
ccnl_engine.inputs.period_state_to_json(state)
¶
Return state as JSON text, with its schema, engine and bundle versions.
Returns:
| Type | Description |
|---|---|
str
|
The JSON text of the state. |
ccnl_engine.inputs.OpeningBalances
dataclass
¶
Progressive totals of a tax year computed outside the engine.
Every amount is in EUR, non-negative and with at most two decimals; an
amount left None (a *_due) is not known. The totals are
validated by the same rules as the state the engine produces
(:class:~ccnl_engine.balance.models.PeriodState); a
violation is raised as InvalidInputError. A tax-year total without
the payments that produced it is rejected: it could not be told apart
from the payments the engine would compute again. The INPS bases and
the obligations carried from an earlier run have no default: what the
previous provider determined is a fact the import states, () when
there is none.
Attributes:
| Name | Type | Description |
|---|---|---|
tax_year |
int
|
Tax year of the totals. |
payments |
tuple[PaymentId, ...]
|
The payments already made this tax year, in payment order
(:meth: |
competence_runs |
tuple[PayrollRunId, ...]
|
Runs closed in earlier tax years that a run still
to compute must follow: with December 2026 paid on 13 January
2027, the other 2026 runs paid in 2026. Payments of
|
inps_bases |
tuple[InpsBaseYtd, ...]
|
Required. INPS base toward the IVS massimale per
competence year: this employment's ( |
sickness_episodes |
tuple[SicknessEpisode, ...]
|
Sickness episodes of the employment up to the last processed day, in start order: they set the waiting period, INPS days and CCNL tier of later episodes. |
sickness_known_from |
date | None
|
First day from which |
gross |
Decimal
|
Contractual gross earnings paid. |
taxable |
Decimal
|
IRPEF taxable income. |
inps_employee |
Decimal
|
Employee INPS contributions withheld. |
pension_deducted |
Decimal
|
Pension fund contributions already deducted from the taxable income (D.Lgs. 252/2005 art. 8 c. 4). |
irpef_withheld |
Decimal
|
IRPEF withheld. |
surtax_withheld |
Decimal
|
Regional and municipal surtax withheld. |
municipal_advance_withheld |
Decimal
|
Part of |
regional_settled |
Decimal
|
Regional surtax of |
municipal_settled |
Decimal
|
Municipal saldo of |
fringe_value |
Decimal
|
Fringe benefit value granted (Art. 51 c. 3 TUIR). |
fringe_taxed |
Decimal
|
Part of |
pdr |
Decimal
|
Premio di Risultato taxed at the substitute rate. |
trattamento_recognized |
Decimal
|
Trattamento integrativo paid. |
trattamento_recovered |
Decimal
|
Trattamento integrativo already recovered. |
trattamento_due |
Decimal | None
|
Annual trattamento integrativo last computed by
the previous provider, |
trattamento_reason |
str | None
|
Lower snake case reason of that amount, e.g.
|
somma_esente_recognized |
Decimal
|
Somma esente (L. 207/2024) paid. |
somma_esente_recovered |
Decimal
|
Somma esente already recovered. |
somma_esente_due |
Decimal | None
|
Annual somma esente last computed, or |
somma_esente_reason |
str | None
|
Reason of that amount, or |
ulteriore_recognized |
Decimal
|
Ulteriore detrazione (L. 207/2024 art. 1 c. 6) already applied by the withholding. |
ulteriore_recovered |
Decimal
|
Ulteriore detrazione already taken back. |
ulteriore_due |
Decimal | None
|
Annual ulteriore detrazione last computed, or
|
ulteriore_reason |
str | None
|
Reason of that amount, or |
irpef_shortfall |
Decimal
|
IRPEF due on earlier runs and not yet withheld for lack of pay. |
surtax_shortfall |
Decimal
|
Surtax due on earlier runs and not yet withheld. |
credit_recovery_shortfall |
Decimal
|
Credit recoveries (trattamento integrativo, somma esente, installments) due on earlier runs and not yet withheld for lack of pay. |
work_time_regime_used |
Decimal
|
Night, holiday and shift supplements already taxed at the substitute rate (L. 199/2025 art. 1 cc. 10-11). |
recoveries |
tuple[RecoveryObligation, ...]
|
Required. Installment recoveries still running, from
this tax year or an earlier one; |
surtax_obligations |
tuple[SurtaxObligation, ...]
|
Surtax determined by the conguaglio of an
earlier tax year and not yet withheld: the regional surtax and
municipal saldo of |
deferred_shortfall |
DeferredShortfall | None
|
IRPEF the conguaglio of |
employment_spells |
tuple[EmploymentSpell, ...]
|
Days in |
ccnl_engine.inputs.InpsBaseYtd
dataclass
¶
INPS base of one competence year, toward the massimale and the 1% band.
Attributes:
| Name | Type | Description |
|---|---|---|
year |
int
|
The competence year. |
own |
Decimal
|
INPS base of the runs of this employment of :attr: |
other_employers |
Decimal | None
|
INPS base of the worker's other employments of
:attr: |
additional_ivs |
Decimal
|
Additional 1% IVS (D.L. 384/1992 art. 3-ter) this
employment withheld on the pay of :attr: |
other_employers_additional_ivs |
Decimal | None
|
Additional 1% IVS the other
employments withheld on :attr: |
month |
int | None
|
Competence month of the latest run of this employment,
|
month_base |
Decimal
|
INPS base of the runs of this employment of
:attr: |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When a field is not of its type, an amount other
than :attr: |
other_employers_known
property
¶
Whether the base of the other employments is stated.
total
property
¶
Base of the year toward the massimale: own and other employers.
An unknown base of other employers counts as zero: the run computes on this employment alone and reports the missing fact.
additional_ivs_withheld
property
¶
Additional 1% IVS withheld on the year by every employment.
An unstated 1% of other employers counts as zero here; see
:attr:other_employers_withheld_unknown.
other_employers_withheld_unknown
property
¶
Whether other employers have a base but their 1% is not stated.
stating_other_employers(amount)
¶
Return the base with the other employers' base stated as amount.
Returns:
| Type | Description |
|---|---|
InpsBaseYtd
|
A new base with |
InpsBaseYtd
|
unchanged. |
base_of_month(month)
¶
Return the INPS base this employment already declared for month.
Returns:
| Type | Description |
|---|---|
Decimal
|
attr: |
plus(amount, month, additional_ivs=_ZERO)
¶
Return the base after a run of this employment of month.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
amount
|
Decimal
|
INPS base of the run. |
required |
month
|
int
|
Competence month of the run. |
required |
additional_ivs
|
Decimal
|
Additional 1% IVS the run withheld, negative when its conguaglio gave some back. |
_ZERO
|
Returns:
| Type | Description |
|---|---|
InpsBaseYtd
|
A new base with |
InpsBaseYtd
|
|
ccnl_engine.inputs.PaymentId
dataclass
¶
Identifier of one payment: the run it pays and its payment date.
The text form is "{run_id}@{payment_date}", e.g.
"2026-12-regular@2027-01-13". A run is paid once, so the run id
alone identifies the payment within an employment; the date fixes the
tax year the payment belongs to.
Attributes:
| Name | Type | Description |
|---|---|---|
run_id |
PayrollRunId
|
The competence run the payment settles. |
payment_date |
date
|
Day the run is paid, not before the first day of the run month. |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
When a field is not of its type or the payment precedes the run month. |
competence
property
¶
First day of the run month.
tax_year
property
¶
Tax year of the payment (TUIR art. 51 c. 1, cassa allargata).
is_prior_competence
property
¶
Whether the payment settles a run of a year before its tax year.
parse(text)
classmethod
¶
Parse the text form "{run_id}@{payment_date}".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
A payment id such as |
required |
Returns:
| Type | Description |
|---|---|
PaymentId
|
The typed identifier. A |
PaymentId
|
payment id raises |
PaymentId
|
class: |
ccnl_engine.inputs.PayrollRunId
dataclass
¶
Typed identifier of a payroll run: year, month, kind and sequence.
The text form is "{year}-{month:02d}-{kind}", e.g.
"2026-12-thirteenth", as in :attr:PayrollRun.run_id. A month has
at most one run of each kind, except adjustment runs: the second and
later adjustments of a month carry their sequence number as a suffix,
e.g. "2026-12-adjustment-2".
Attributes:
| Name | Type | Description |
|---|---|---|
year |
int
|
Year of the run month (the competence year). The tax year of the run follows from its payment date and can be later. |
month |
int
|
Run month, 1-12. |
kind |
RunKind
|
Kind of the run. |
sequence |
int
|
Number of the run among the runs of its kind and month, from 1. Above 1 only for an adjustment run. |
order_key
property
¶
Key ordering the runs as they are paid: year, month, kind rank, sequence.
payment_key
property
¶
Key of what the run pays, closed once per employment.
A regular, termination or adjustment run pays its month, an adjustment once per sequence number; a tredicesima or quattordicesima pays the extra month of its year, whatever month it is paid in: the quattordicesima of 2027 is the same entitlement paid in June or in July.
parse(text)
classmethod
¶
Parse the text form of :meth:__str__.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
A run id such as |
required |
Returns:
| Type | Description |
|---|---|
PayrollRunId
|
The typed identifier. A |
PayrollRunId
|
id, or not in its canonical form (a |
PayrollRunId
|
suffix), raises |
PayrollRunId
|
class: |
ccnl_engine.inputs.RecoveryObligation
dataclass
¶
An installment recovery and the tax year of the credit it recovers.
Attributes:
| Name | Type | Description |
|---|---|---|
tax_year |
int
|
Tax year whose conguaglio found the credit not due. The
installments posted in that year enter the |
plan |
RecoveryPlan
|
The installment plan, with the installments still to post. |
post(run)
¶
Return what run recovers and the obligation after it.
Returns:
| Type | Description |
|---|---|
PostedInstallment
|
meth: |
RecoveryObligation | None
|
running, |
ccnl_engine.inputs.RecoveryPlan
dataclass
¶
Structured installment plan for recovering an over-paid tax credit.
Created when the amount to recover exceeds 60 EUR, to spread the recovery
over equal installments: eight for the trattamento integrativo (D.L.
3/2020 art. 1 co. 3), ten for the somma esente (L. 207/2024 art. 1 c. 7).
The last installment absorbs any rounding residual so the sum is always
exactly original_amount.
Attributes:
| Name | Type | Description |
|---|---|---|
kind |
str
|
Identifier for the credit being recovered, e.g.
|
original_amount |
Decimal
|
Total amount to recover (positive). |
installment_amount |
Decimal
|
Uniform per-period deduction (positive, rounded). |
installments_total |
int
|
Number of periods over which the recovery runs. |
installments_posted |
int
|
Number of installments already deducted. |
residual
property
¶
Amount not yet recovered.
next_installment
property
¶
Amount to deduct this period.
The last installment uses the residual to absorb rounding.
post(run)
¶
Return what run recovers of the plan.
The single rule shared by every recovered credit: the next installment on an ordinary or adjustment run, the whole residual on the final run of the employment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run
|
InstallmentRun
|
The run the installment is posted on. |
required |
Returns:
| Type | Description |
|---|---|
PostedInstallment
|
The amount recovered, its reason and the plan still running. |
advance()
¶
Return a plan with installments_posted incremented by one.
Returns:
| Type | Description |
|---|---|
RecoveryPlan
|
A new :class: |
create(kind, original_amount, installments_total)
classmethod
¶
Create a fresh plan from the original recovery amount.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kind
|
str
|
Credit identifier. |
required |
original_amount
|
Decimal
|
Total amount to recover (positive). |
required |
installments_total
|
int
|
Number of periods to spread across. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
RecoveryPlan
|
class: |
RecoveryPlan
|
|
|
RecoveryPlan
|
rounded to two decimal places. |
ccnl_engine.inputs.SurtaxComponent
¶
Bases: StrEnum
Part of the surtax a conguaglio determines.
REGIONAL_BALANCE = 'regional_balance'
class-attribute
instance-attribute
¶
Regional surtax of the tax year (it has no acconto).
MUNICIPAL_BALANCE = 'municipal_balance'
class-attribute
instance-attribute
¶
Municipal surtax of the tax year less the acconto withheld in it.
MUNICIPAL_ADVANCE = 'municipal_advance'
class-attribute
instance-attribute
¶
Municipal acconto of the next tax year.
ccnl_engine.inputs.SurtaxObligation
dataclass
¶
Surtax a conguaglio determined, still to withhold in the next year.
Attributes:
| Name | Type | Description |
|---|---|---|
component |
SurtaxComponent
|
What the amount is. |
tax_year |
int
|
Tax year whose conguaglio determined it; it is withheld
in |
jurisdiction |
str
|
Region code (ISO 3166-2:IT) or Belfiore code of the municipality it is due to: the one of the tax year of the conguaglio, not of the year it is withheld in. |
plan |
RecoveryPlan
|
The installments still to post; |
window
property
¶
Installment window of the component.
withheld_in
property
¶
Tax year whose payslips withhold the installments.
reference_year
property
¶
Tax year the surtax is due for: the next one for the acconto.
open(component, tax_year, jurisdiction, amount)
classmethod
¶
Return the obligation of amount over the window.
An amount below one cent per installment runs over fewer installments, so that none is zero.
Returns:
| Type | Description |
|---|---|
SurtaxObligation
|
The obligation with no installment posted. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When |
part(amount)
¶
Return amount withheld of this obligation as a run part.
Returns:
| Type | Description |
|---|---|
SurtaxPart
|
The part of the component and reference year. |
post(run, *, year, month, regular)
¶
Return what a run of year and month withholds of it.
The last run of the employment withholds the residual. Otherwise a
regular run of the window withholds the next installment, and the
one of the last month, or any regular run after the window, the
residual; nothing is withheld before the window, on another kind of
run, or before :attr:withheld_in.
Returns:
| Type | Description |
|---|---|
PostedInstallment | None
|
What the run withholds, |
SurtaxObligation | None
|
obligation after it, |
ccnl_engine.inputs.DeferredShortfall
dataclass
¶
IRPEF of a conguaglio deferred on the worker's written request.
Attributes:
| Name | Type | Description |
|---|---|---|
tax_year |
int
|
Tax year whose conguaglio found the shortfall; it is
withheld in |
signed_on |
date
|
Date of the written request. |
deferred_from |
date
|
First day of the pay period of the conguaglio: the interest runs from its month. |
irpef |
Decimal
|
IRPEF still to withhold, positive. |
withheld_in
property
¶
Tax year whose payslips withhold the deferred IRPEF.
months_to(year, month)
¶
Whole months from the conguaglio month to year and month.
Returns:
| Type | Description |
|---|---|
int
|
The number of months, at least zero. |
due_in(year, month)
¶
Whether a payslip of year and month may withhold it.
Returns:
| Type | Description |
|---|---|
bool
|
|
post(available, year, month)
¶
Return what a payslip leaving available pay withholds of it.
The principal is the largest amount whose interest still fits in
available, at most the residual.
Returns:
| Type | Description |
|---|---|
DeferredInstallment | None
|
The installment, |
DeferredShortfall | None
|
left after it, |