"""Post-calculation advisory coordination for bucket aggregation calculations.
The bucket aggregation calculate path first resolves source-backed values,
executes the registry formula engine, and persists the calculated revision. This
module then fans out advisory-only checks over the loaded
:class:`ModeloRevision` and the computed :class:`CasillaId` value map, returning
non-blocking
:class:`~application.aggregation.source_mesh.CalculationSourceDiagnostic` rows for the
caller to append to source mesh diagnostics. It does not compute, override, or
persist casilla values.
The prior-payment collectors need persisted filing observations, so the
coordinator shares one
:class:`~application.calculations.observations_repository.CalculationObservationRepositoryProtocol` instance
across them. The official-box and settlement collectors read only the revision
structure and calculated casilla values. Together the collectors extend the
source mesh's no-silent-under-declaration diagnostics with checks whose evidence
only exists after the revision has been calculated.
See Also:
:func:`~application.modelo.calculation_actions.calculate_modelo_revision_from_bucket_aggregation_with_diagnostics`:
Calls this coordinator after the calculation revision has been created.
:func:`~application.modelo._official_box_advisory.collect_official_box_unpopulated_diagnostics`:
Mirrors registry-authored ADVISORY predicates as calculate diagnostics.
:mod:`~application.modelo.prior_payment_advisory`:
Emits Modelo 130 prior-payment carry degradation advisories.
:func:`~application.modelo._settlement_grade_advisory.collect_settlement_not_computed_diagnostics`:
Emits structural settlement-completeness advisories for partially modelled revisions.
:func:`~application.modelo._bienes_inversion_advisory.collect_bienes_inversion_regularizacion_diagnostics`:
Emits the Modelo 303 capital-goods IVA regularización proposed-casilla-43 advisory.
:func:`~application.modelo.prorrata_regularizacion_advisory.collect_prorrata_regularizacion_diagnostics`:
Emits the Modelo 303 annual prorrata-general regularización proposed-casilla-44 advisory.
"""
from __future__ import annotations
from collections.abc import Mapping
from decimal import Decimal
from ...core.casilla_id import CasillaId
from ...domain.calculations.registry.authority import bundled_indexed_authority
from ...domain.calculations.registry.schema import ModeloRevision
from ...domain.transactions.protocols import TransactionCatalogueRepositoryProtocol
from ..aggregation.source_mesh import CalculationSourceDiagnostic
from ..bienes_inversion.ports import BienesInversionIvaRegisterRepositoryProtocol
from ..calculations.observations_repository import CalculationObservationRepositoryProtocol
from ..prorrata_register.ports import ProrrataRegisterServiceRepositoryProtocol
from ._bienes_inversion_advisory import collect_bienes_inversion_regularizacion_diagnostics
from ._minimo_descendientes_advisory import (
collect_descendientes_count_desync_diagnostics,
collect_guarderia_madre_meses_undeclared_diagnostics,
collect_guarderia_spend_shape_diagnostics,
collect_minimo_descendientes_dependencia_diagnostics,
collect_minimo_descendientes_entry_date_missing_diagnostics,
collect_minimo_descendientes_prorrata_inferred_diagnostics,
collect_minimo_descendientes_rentas_undeclared_diagnostics,
collect_minimo_descendientes_undeclared_diagnostics,
)
from ._official_box_advisory import collect_official_box_unpopulated_diagnostics
from ._rate_box_advisory import collect_rate_box_coverage_diagnostics
from ._settlement_grade_advisory import collect_settlement_not_computed_diagnostics
from .prior_payment_advisory import (
collect_prior_payment_minoracion_not_captured_diagnostics,
collect_prior_payment_not_deducted_diagnostics,
)
from .prorrata_regularizacion_advisory import collect_prorrata_regularizacion_diagnostics
from .work_profile import ModeloWorkProfile
__all__ = ["collect_bucket_aggregation_advisory_diagnostics"]
[docs]
def collect_bucket_aggregation_advisory_diagnostics(
revision: ModeloRevision,
casilla_values: Mapping[CasillaId, Decimal],
*,
modelo: str,
period_token: str,
filing_year: int,
bucket_id: str,
observation_repository: CalculationObservationRepositoryProtocol,
prorrata_register_repository: ProrrataRegisterServiceRepositoryProtocol,
bienes_inversion_repository: BienesInversionIvaRegisterRepositoryProtocol,
transaction_repository: TransactionCatalogueRepositoryProtocol,
profile: ModeloWorkProfile | None = None,
) -> tuple[CalculationSourceDiagnostic, ...]:
"""Return advisory diagnostics raised after bucket aggregation calculation.
Runs the calculate-path advisory collectors in tuple order:
official-box transcription, Modelo 130 prior-payment under-deduction, Modelo
130 prior-payment minoracion capture, settlement-not-computed structure, the
Modelo 100 mínimo-por-descendientes undeclared-facts advisory, the Modelo
303 capital-goods IVA regularización (LIVA arts. 107-110) proposed-casilla-43
advisory, and the Modelo 303 annual prorrata-general regularización (LIVA
arts. 104-105) proposed-casilla-44 advisory. These diagnostics are
informational and non-blocking; the
calculation result already exists, and the caller merely appends these rows
to the source mesh's existing
:class:`~application.aggregation.source_mesh.CalculationSourceDiagnostic`
sequence.
The Modelo 100 mínimo-por-descendientes casillas (0513/0514) are no longer
advisory-only for the halving/blank-entry checks a prior interim module
raised: a computed engine (:func:`~application.modelo.profile_binding.inject_derived_minimo_descendientes_facts`)
that derives the Art. 58/61 LIRPF aggregate — including the custodia-compartida
halving — directly from the active profile, so those two checks are structurally
unreachable and were retired. A new, narrower advisory
(:func:`~application.modelo._minimo_descendientes_advisory.collect_minimo_descendientes_undeclared_diagnostics`)
replaces them: because a genuinely childless profile and a profile that simply
never declared its descendientes both resolve 0513 to the same zero, this
collector flags the ambiguous case (0513 = 0 and no descendiente facts declared
at all) and points the operator at ``aeat config profile descendiente add``.
Args:
revision: The :class:`ModeloRevision` whose predicates, casillas, and
formulas are inspected.
casilla_values: Computed engine values keyed by :class:`CasillaId`.
modelo: Target modelo identifier used by modelo-specific advisory
collectors.
period_token: Bare registry period token for the filing being
calculated.
filing_year: Filing year whose same-ejercicio prior observations may be
inspected.
bucket_id: Bucket identifier used by profile-backed advisory
collectors.
observation_repository: Required bucket-bound observation repository used
by prior-payment advisory collectors.
prorrata_register_repository: Required bucket-bound prorrata register
capability used by the Modelo 303 regularización advisory.
bienes_inversion_repository: Required bucket-bound capital-goods register
capability used by the Modelo 303 regularización advisory.
transaction_repository: Required bucket-bound transaction catalogue
capability used by the annual IVA settlement advisory.
profile: The bucket's profile when the calculation already loaded it;
when omitted, the profile-backed collectors read it themselves.
Returns:
Tuple of
:class:`~application.aggregation.source_mesh.CalculationSourceDiagnostic`
advisory rows, or an empty tuple when no post-calculation advisory fires.
See Also:
:class:`~application.calculations.observations_repository.CalculationObservationRepositoryProtocol`:
Supplies the prior-filing observation catalogue used by the Modelo
130 prior-payment advisory collectors.
:func:`~application.modelo.calculation_actions.calculate_modelo_revision_from_bucket_aggregation_with_diagnostics`:
Appends this tuple to the source mesh diagnostics on the returned
bucket aggregation result.
"""
with bundled_indexed_authority().operation() as operation:
minimo_descendientes_undeclared_diagnostics = collect_minimo_descendientes_undeclared_diagnostics(
revision,
casilla_values,
modelo=modelo,
period_token=period_token,
filing_year=filing_year,
bucket_id=bucket_id,
operation=operation,
profile=profile,
)
minimo_descendientes_rentas_undeclared_diagnostics = collect_minimo_descendientes_rentas_undeclared_diagnostics(
revision,
casilla_values,
modelo=modelo,
period_token=period_token,
filing_year=filing_year,
bucket_id=bucket_id,
operation=operation,
profile=profile,
)
guarderia_spend_shape_diagnostics = collect_guarderia_spend_shape_diagnostics(
revision,
casilla_values,
modelo=modelo,
period_token=period_token,
filing_year=filing_year,
bucket_id=bucket_id,
operation=operation,
profile=profile,
)
guarderia_madre_meses_undeclared_diagnostics = collect_guarderia_madre_meses_undeclared_diagnostics(
revision,
casilla_values,
modelo=modelo,
period_token=period_token,
filing_year=filing_year,
bucket_id=bucket_id,
operation=operation,
profile=profile,
)
return (
collect_official_box_unpopulated_diagnostics(revision, casilla_values)
+ collect_prior_payment_not_deducted_diagnostics(
revision,
casilla_values,
modelo=modelo,
period_token=period_token,
filing_year=filing_year,
observation_repository=observation_repository,
)
+ collect_prior_payment_minoracion_not_captured_diagnostics(
revision,
modelo=modelo,
period_token=period_token,
filing_year=filing_year,
observation_repository=observation_repository,
)
+ collect_settlement_not_computed_diagnostics(revision)
+ minimo_descendientes_undeclared_diagnostics
+ collect_minimo_descendientes_prorrata_inferred_diagnostics(
revision,
casilla_values,
modelo=modelo,
period_token=period_token,
filing_year=filing_year,
bucket_id=bucket_id,
)
+ minimo_descendientes_rentas_undeclared_diagnostics
+ collect_minimo_descendientes_entry_date_missing_diagnostics(
revision,
casilla_values,
modelo=modelo,
period_token=period_token,
filing_year=filing_year,
bucket_id=bucket_id,
)
+ collect_minimo_descendientes_dependencia_diagnostics(
revision,
casilla_values,
modelo=modelo,
period_token=period_token,
filing_year=filing_year,
bucket_id=bucket_id,
)
+ guarderia_spend_shape_diagnostics
+ guarderia_madre_meses_undeclared_diagnostics
+ collect_descendientes_count_desync_diagnostics(
revision,
modelo=modelo,
period_token=period_token,
filing_year=filing_year,
bucket_id=bucket_id,
)
+ collect_bienes_inversion_regularizacion_diagnostics(
revision,
modelo=modelo,
period_token=period_token,
filing_year=filing_year,
bucket_id=bucket_id,
register_repository=bienes_inversion_repository,
)
+ collect_rate_box_coverage_diagnostics(revision, casilla_values)
+ collect_prorrata_regularizacion_diagnostics(
revision,
casilla_values,
modelo=modelo,
period_token=period_token,
filing_year=filing_year,
bucket_id=bucket_id,
observation_repository=observation_repository,
prorrata_register_repository=prorrata_register_repository,
transaction_repository=transaction_repository,
)
)