Skip to content

ccnl_engine.results

The types read from a result: its assurance, blockers, decisions and issues, the model limitations, the capability gaps, the runs a year left out, the ledger account kinds and the remittance lines.

Assurance and payability

Every result answers "can these amounts be paid as they are?" with is_payable, and says why not with blockers, one ResultBlocker per reason, each with a stable BlockerCode, the feature it concerns, a machine-readable detail, a remediation and the totals it leaves unreliable (ResultTotal: net_pay, employer_cost, or both). Both come from assurance, a ResultAssurance derived from the run.

is_payable holds when both totals are reliable. Each total also has its own answer: is_net_pay_payable (no blocker touches the net pay) and is_employer_cost_complete (no blocker touches the employer cost). An open limitation on an amount only the employer owes, such as the mètaSalute health fund of the Metalmeccanico CCNL, leaves the employer cost short and the net pay payable. period_employer_cost never includes the INAIL premium, which rests on the tariff rate of the employer, nor IRAP.

The assurance axes:

Axis Type Derived from
calculation CalculationStatus Worst status of the issues and decisions
coverage CoverageStatus The capability report
evidence EvidenceStatus Weakest provenance of the payable rules read
rulesets RulesetAssurance tuple The CCNL ruleset and every ruleset a payable rule was read from, with readiness; also result.rulesets
mode EngineMode The mode of the engine; operational adds ruleset_not_production blockers
payability Payability payable exactly when there is no blocker
limitations ModelLimitation tuple The known model simplifications that apply to the run; an open one with monetary impact yes or unknown is also an open_limitation blocker

A result is payable only when it raised no issue, every decision is final, the capability report has no gap and no unresolved requirement, no executed rule is assumed or missing no rule was supplied by the caller and no open model limitation with a monetary impact applies; in operational mode, also only when the CCNL ruleset is production. A derived rule lowers evidence but does not block. See Assurance for the rules.

The year result combines the assurance of its runs (each axis the worst, rulesets, blockers and limitations each once; payable only when every run is) and lists their issues in payment order, each issue once: one repeated on every run (same code and message) is listed at its first run.

result = engine.calculate_period(period_input)
if not result.is_payable:
    for blocker in result.blockers:
        print(blocker.code.value, blocker.feature, blocker.detail)

The calculation axis:

Status Meaning
final Every capability decided from known rules and facts.
provisional Computed, but a decision rests on an assumption that may change the amounts.
incomplete At least one amount could not be determined; do not pay as is.
rejected The inputs cannot produce a meaningful result.

Compare statuses with severity or CalculationStatus.worst(): the string values do not sort in severity order.

An incomplete result still carries amounts, but at least one of them is missing, not zero: for example a surtax whose table is unknown is withheld as 0, flagged by the issue regional_surtax_unknown or municipal_surtax_unknown, recorded by a decision with no amount and reported as a blocker, so the result is not payable. result.decisions records what each capability decided, e.g. the surtax and tax credit decisions described in Fiscal computation. The year result exposes the decisions of its periods in payment order.

Capability report

result.capability_report compares what the run executed with the capability registry of the tax year. Each feature is traced from what actually ran, never from the presence of an input:

  • the core stages (base salary, INPS, TFR, IRPEF) run on every period;
  • an event feature (overtime, welfare, ...) is computed only when one of its events posted a non-zero amount or took a decision, otherwise skipped;
  • every other feature follows its decisions: final is computed (a zero amount with its reason counts), provisional is partial, incomplete or rejected is unresolved, and no decision is not applicable.

Each registry entry declares an applicability predicate, and capability_report.scope gives the result for the run: applicable, not_applicable (the predicate is false, or the handler ruled it out) or outside_input (the request has no field for the fact that makes it apply). An applicable capability is a gap when it is unsupported (the engine does not compute it, e.g. residual leave on the run that closes the employment), unresolved (e.g. a surtax without a table), a partial_result of a capability implemented in full, or a partial_implementation that executed (sickness, family deductions). Every gap is a capability_not_computed blocker.

The gaps alone are a blocklist: a capability whose handler took no decision because a fact was left to its default looks not_applicable. An entry that declares applicability_facts (the residence for the regional and municipal surtaxes, the family composition for the family deductions) is therefore required in every run: it must be ruled out by a decision of the run or decided on the supplied facts, never on a default. Each such fact left to its default, on a run that did not rule the capability out, is an UnresolvedRequirement in capability_report.unresolved and a requirement_unresolved blocker. The report status is the coverage axis of the assurance: incomplete with an unresolved requirement, otherwise partial when every gap is partial and incomplete with any other gap.

ccnl_engine.results.AccountKind

Bases: StrEnum

The twenty-two logical accounts that partition a payroll pay period.

The three PENSION_FUND accounts hold what is paid to a complementary pension fund: the employee contribution withheld, the employer contribution and the TFR paid to the fund instead of accruing in the company. TFR_TREASURY_FUND holds the TFR the employer pays monthly to the Fondo Tesoreria INPS (L. 296/2006 art. 1 c. 756) instead of accruing it in the company.

Every entry of the tax and credit accounts is non-negative; the account gives the direction:

  • ORDINARY_TAX: IRPEF withheld, before any credit is offset;
  • TAX_REFUNDS: IRPEF refunded to the worker by the conguaglio;
  • SURTAX: regional and municipal surtax withheld;
  • SURTAX_REFUNDS: surtax withheld above what the conguaglio finds due (usually the municipal acconto), given back;
  • CREDITS: amounts paid to the worker that the withholding agent recovers as an F24 credit (trattamento integrativo, somma esente);
  • CREDIT_RECOVERIES: those amounts, or an ulteriore detrazione of an earlier year, taken back from the worker;
  • CREDIT_RECOVERY_SHORTFALL: a recovery of the run the pay could not cover, given back on the payslip and carried to the next runs.

ccnl_engine.results.BlockerCode

Bases: StrEnum

Stable machine-readable kind of a :class:ResultBlocker.

Attributes:

Name Type Description
CALCULATION_ISSUE

An issue was raised, or a decision is not final: an amount rests on an assumption, a fallback or a condition the worker must be told about.

MISSING_FACT

A fact the calculation needs was not supplied.

REQUIREMENT_UNRESOLVED

A capability required in every run was not ruled out by a decision of the run, and the fact that decides it was left to its default: a default never decides a capability.

CAPABILITY_NOT_COMPUTED

A capability the catalog promises was not computed, could not decide or came out partial.

RULE_SOURCE_WEAK

An executed capability read a rule whose provenance is assumed or missing, or no rule of the run carries a provenance record.

CALLER_SUPPLIED_RULE

The caller supplied a value in place of a rule of the bundle, so no source backs it.

RULESET_NOT_PRODUCTION

In operational mode only: a ruleset the run read is not production, or no ruleset of the run tracks a readiness tier.

OPEN_LIMITATION

An open model limitation whose monetary impact is yes or unknown concerns the run.

RUN_NOT_COMPUTED

In a competence or tax year only: a run of the plan was skipped because the bundle holds no base salary of its CCNL level on its competence date; the year is partial.

RULESET_CONFLICT

In a combined result only: two runs read the same ruleset id@version with a different hash, kind, readiness or confidence, so the version does not name one content.

ccnl_engine.results.CalculationDecision dataclass

What one capability decided in a calculation, and why.

Attributes:

Name Type Description
capability str

Catalog feature name, e.g. "regional_surtax".

status CalculationStatus

Status implied by this decision.

reason_code str

Stable machine-readable reason in lower snake case, e.g. "table_found".

rule str

Identifier of the rule applied.

rule_version str

Version of the rule applied, e.g. the tax year or the data bundle version.

inputs Mapping[str, Decimal | str]

Normalized inputs the decision was taken from. Copied and read-only after construction.

source SourceLocation | None

Normative source of the rule, when recorded.

amount Decimal | None

Amount produced by the decision; None when the decision yields no amount or the amount is unknown.

origin DecisionOrigin

Whether the engine applied the rule or the caller supplied it. A caller-supplied decision cites no source.

Raises:

Type Description
ValueError

When reason_code is not lower snake case, when capability, rule or rule_version is empty, when amount is not finite, or when a caller-supplied decision cites a source.

ccnl_engine.results.CalculationIssue dataclass

A condition that lowers the status of a calculation result.

Attributes:

Name Type Description
code str

Stable machine-readable identifier in lower snake case, e.g. "surtax_table_unknown". Callers may branch on it.

message str

Human-readable explanation for the caller.

status CalculationStatus

Status the issue implies for the result that carries it.

source SourceLocation | None

Normative source behind the issue, when one applies.

fact str | None

Name of the public input field whose absence raised the issue, e.g. "employment_income"; one of :data:PUBLIC_FACTS, None when the issue is not about a missing fact.

Raises:

Type Description
ValueError

When code is not lower snake case, fact is not one of :data:PUBLIC_FACTS or message is empty.

ccnl_engine.results.CalculationStatus

Bases: StrEnum

How far the calculation of a result can be relied upon.

It is the calculation axis of :class:~ccnl_engine.assurance.models.ResultAssurance; whether the amounts can be paid is the assurance payability, not this status.

Members are listed from least to most severe. Compare them with :attr:severity or combine them with :meth:worst; the string values do not sort in severity order.

Attributes:

Name Type Description
FINAL

Every capability decided from known rules and facts.

PROVISIONAL

Computed, but at least one decision rests on an assumption that may change the amounts once confirmed.

INCOMPLETE

At least one amount could not be determined.

REJECTED

The inputs cannot produce a meaningful result.

severity property

Rank of this status, 0 for final up to 3 for rejected.

worst(statuses) classmethod

Return the most severe status in statuses.

Parameters:

Name Type Description Default
statuses Iterable[CalculationStatus]

Statuses to combine, possibly empty.

required

Returns:

Type Description
CalculationStatus

The status with the highest :attr:severity, or

CalculationStatus

attr:FINAL when statuses is empty.

ccnl_engine.results.CapabilityGap dataclass

An applicable capability the run does not cover in full.

Attributes:

Name Type Description
feature str

The capability name.

implementation CapabilityImplementation

How the registry says the engine implements it.

observed str

Trace state of the run, "absent" when untraced.

kind CapabilityGapKind

Why it is not covered.

ccnl_engine.results.CapabilityScope

Bases: StrEnum

Whether a capability concerns the run.

Attributes:

Name Type Description
APPLICABLE

It applies: it must be computed for the run to be covered.

NOT_APPLICABLE

Its predicate is false for the case, or its handler ruled it out.

OUTSIDE_INPUT

The fact that makes it apply has no field in the request; a case with that fact is outside the engine input.

ccnl_engine.results.CoverageStatus

Bases: StrEnum

How far the run covers the capabilities that apply to it.

Members are listed from the best to the worst coverage.

Attributes:

Name Type Description
COMPLETE

Every applicable capability was computed in full.

PARTIAL

Every gap is a partial result or a partially implemented capability that executed.

INCOMPLETE

An applicable capability is unsupported, untraced or could not decide.

worst(statuses) classmethod

Return the worst coverage in statuses.

Returns:

Type Description
CoverageStatus

The worst status, or :attr:COMPLETE when statuses is empty.

ccnl_engine.results.DecisionOrigin

Bases: StrEnum

Where the rule behind a decision comes from.

Attributes:

Name Type Description
ENGINE

The engine applied a rule of the bundled data or of the law.

CALLER_SUPPLIED

The caller supplied a value (a rate, a multiplier, an amount) that stands in for a rule the engine would otherwise apply; no bundled source backs it.

ccnl_engine.results.EvidenceStatus

Bases: StrEnum

How far the payable rules a run read are backed by their sources.

The values are those of the rule provenance status, listed from the strongest to the weakest backing.

Attributes:

Name Type Description
VERIFIED

Every rule was checked by a named reviewer.

DERIVED

The weakest rule is taken from a cited location, unchecked.

ASSUMED

A rule is adopted without a located citation.

MISSING

A rule has no source, or no rule carries a record.

weakest(statuses) classmethod

Return the weakest of statuses, given as provenance values.

Returns:

Type Description
EvidenceStatus

The weakest status, or :attr:MISSING when statuses is empty:

EvidenceStatus

nothing backs a run whose rules carry no record.

ccnl_engine.results.LimitationStatus

Bases: StrEnum

Whether a limitation still holds.

Attributes:

Name Type Description
OPEN

The engine still computes the simplified amount.

RESOLVED

The model was corrected, with a source and a test.

ccnl_engine.results.ModelLimitation

Bases: BaseModel

A known simplification of the engine, typed and executable.

Attributes:

Name Type Description
id str

Stable identifier: <ccnl id>/<variant> for a CCNL note, the bare variant name for an engine limitation.

capability str

Registry capability the limitation concerns.

variant str

Variant of the capability it concerns.

summary str

What the engine does differently, for a human reader.

monetary_impact MonetaryImpact

Whether it can change an amount.

status LimitationStatus

Whether it still holds.

rulesets tuple[str, ...]

Ids of the CCNLs it affects.

applies_when LimitationScope

The runs it concerns.

totals frozenset[ResultTotal]

The totals of a run it can make wrong: both by default, the employer cost alone for an amount only the employer pays.

source str

Where it is declared: the CCNL file or the engine module.

remediation str

What closes it.

blocks property

Whether it makes a result it applies to not payable.

Returns:

Type Description
bool

True for an open limitation whose monetary impact is

bool

yes or unknown.

applies_to(facts)

Return whether the limitation concerns the run of facts.

An owed limitation concerns every run of an affected CCNL. Otherwise the capability must concern the run: a path limitation concerns it when the run traversed its path, whatever the CCNL; a run limitation when the CCNL is affected; an outside_input one never. The scope must match in every case.

Returns:

Type Description
bool

True when the limitation concerns the run.

ccnl_engine.results.MonetaryImpact

Bases: StrEnum

Whether a limitation can change an amount the engine computes.

Attributes:

Name Type Description
YES

In the cases it applies to, an amount is known to differ from the contract.

NO

No amount the engine computes from the bundle changes: the engine refuses the case, or reads the value from the caller.

UNKNOWN

An amount may differ; the contract reading or the source is not confirmed.

ccnl_engine.results.Payability

Bases: StrEnum

Whether the amounts of a result can be paid as they are.

Attributes:

Name Type Description
PAYABLE

Nothing blocks the amounts.

NOT_PAYABLE

At least one :class:ResultBlocker applies.

ccnl_engine.results.RemittanceColumn

Bases: StrEnum

F24 column an amount is reported in.

DEBIT = 'debit' class-attribute instance-attribute

"importi a debito versati": tax withheld or credit recovered.

CREDIT = 'credit' class-attribute instance-attribute

"importi a credito compensati": credit paid to the worker.

ccnl_engine.results.RemittanceLine dataclass

Total of one account and codice tributo over a set of entries.

Attributes:

Name Type Description
account AccountKind

Tax or credit account of the entries.

remittance_code str | None

Their codice tributo, None when not verified.

column RemittanceColumn | None

F24 column of a coded amount; None for an uncoded line or an account that is never remitted.

amount Decimal

Sum of the entries, in EUR.

ccnl_engine.results.ResultAssurance dataclass

Whether the amounts of a result can be relied upon and paid.

Attributes:

Name Type Description
calculation CalculationStatus

Worst status of the issues and decisions.

coverage CoverageStatus

Status of the capability report.

evidence EvidenceStatus

Weakest provenance of the payable rules read; missing when no rule carries a record.

rulesets tuple[RulesetAssurance, ...]

Assurance of the rulesets the rules were read from: identity, hash, readiness and confidence.

mode EngineMode

Payability policy the blockers were derived under.

payability Payability

:attr:Payability.PAYABLE exactly when :attr:blockers is empty.

blockers tuple[ResultBlocker, ...]

Every reason the amounts cannot be paid, in the order they were found.

limitations tuple[ModelLimitation, ...]

Model limitations that concern the run, open or resolved, whatever their monetary impact; those that block are also listed in :attr:blockers.

is_payable property

Whether nothing blocks the amounts: every total is reliable.

is_net_pay_payable property

Whether no blocker leaves the net pay unreliable.

is_employer_cost_complete property

Whether no blocker leaves the employer cost unreliable.

with_blockers(blockers)

Return the assurance with blockers added after its own.

Returns:

Type Description
ResultAssurance

The assurance, its payability decided again on every blocker.

combine(assurances) classmethod

Aggregate the assurance of several runs, e.g. those of a year.

Each axis takes its worst value; rulesets, blockers and limitations are listed once each, in the order they first appear. Rulesets that share an id@version but differ in content are all kept, and each such id@version adds a ruleset_conflict blocker.

Returns:

Type Description
ResultAssurance

The aggregated assurance.

Raises:

Type Description
ValueError

When assurances is empty, or mixes modes.

ccnl_engine.results.ResultBlocker dataclass

One reason the amounts of a result cannot be paid.

Attributes:

Name Type Description
code BlockerCode

Kind of blocker; callers may branch on it.

feature str | None

Capability the blocker concerns, None when it concerns the run as a whole (an issue, a missing fact).

detail str

Machine-readable specifics in lower snake case where the source allows: the issue code, the decision reason, the missing fact, the fact left to its default, the gap kind, the provenance status, the caller fields, the id of the ruleset short of production, the id of the open limitation, or the id of the run not computed.

remediation str

What removes the blocker, for a human reader.

totals frozenset[ResultTotal]

The totals the blocker leaves unreliable; both unless it concerns an amount that only one of them holds (an open limitation on an employer-only fund leaves the net pay alone).

ccnl_engine.results.ResultTotal

Bases: StrEnum

A total of a result that a blocker leaves unreliable.

Attributes:

Name Type Description
NET_PAY

The net pay of the worker.

EMPLOYER_COST

The employer cost of the result.

ccnl_engine.results.UncoveredRun dataclass

A run of a competence year that was not computed.

The bundle holds no base salary of the CCNL level on the competence date of the run: the pay tables start later, or the date falls in a gap the bundle declares. The year computes its other runs and is not payable (see :attr:blocker). The fields are those of the :class:~ccnl_engine.errors.MissingRuleError a run of that date raises, rebuilt by :attr:error.

Attributes:

Name Type Description
payment PaymentId

The run and the date it would have been paid.

ruleset str | None

Id of the CCNL whose rule is missing.

feature str | None

The rule with no value (base_salary).

as_of date

The date the rule was read on: the competence date.

gap_kind str | None

Kind of the declared gap, None before the rule starts.

detail str

Why the rule has no value on :attr:as_of.

remediation str | None

What the caller can do about it.

error property

The error a run of :attr:payment raises.

blocker property

The run_not_computed blocker of the run, detail its run id.

of(payment, error) classmethod

Return the run left out with the error a run of its date raises.

Returns:

Type Description
UncoveredRun

The run, with the fields of error.

ccnl_engine.results.UnresolvedRequirement dataclass

A required capability left undecided by a default.

Attributes:

Name Type Description
feature str

The capability, as named by the registry.

fact str

The request fact that decides whether it applies, left to its default, e.g. "facts.regione".