cadrumo.application.aggregation.currency_predicates module

Shared currency predicates for aggregation gates.

Used by iva_ledger, renta_ledger, renta_income_ledger, and renta_gasto_ledger to gate non-EUR rows and extract effective EUR amounts.

Provides two predicates that replace independent if transaction.raw.currency != "EUR": ... guards.

is_non_eur_without_conversion(transaction)[source]

Return whether a transaction is foreign-currency with no pre-converted EUR value.

Returns True only when both conditions hold: - the raw currency is not EUR, AND - value_in_eur is None (no conversion was applied at import).

Aggregation gates use this predicate to decide whether to emit UNSUPPORTED_CURRENCY. A non-EUR row with value_in_eur set can proceed through the gate using the pre-converted amount.

Parameters:

transaction (Transaction) – The transaction to inspect.

Return type:

bool

Returns:

True if the currency is foreign and no EUR equivalent is available.

effective_eur_amount(transaction)[source]

Return the EUR amount to use for this transaction in casilla projections.

Returns transaction.value_in_eur for foreign-currency rows whose conversion was pre-applied at import; otherwise returns transaction.raw.amount (the native EUR amount for domestic rows).

Raises AggregationConfigError when is_non_eur_without_conversion is True for the row, rather than documenting the precondition and trusting every caller to check it first. An unconverted foreign-currency row has no valid EUR projection to return, and a caller that skipped the gate must fail loud, not fold raw.amount into a EUR-denominated total in a foreign currency.

Parameters:

transaction (Transaction) – The transaction whose effective EUR amount is needed.

Return type:

Decimal

Returns:

A decimal.Decimal suitable for casilla arithmetic.

Raises:

AggregationConfigError – The row is foreign-currency with no EUR conversion applied.

effective_eur_taxable_base(transaction)[source]

Return the EUR-equivalent taxable_base, or None if unset.

transaction.taxable_base is denominated in the row’s NATIVE currency (the gross == base + iva + recargo invariant reconstitutes raw.amount, never value_in_eur – see domain.transactions.tests.test_gross_invariant). A converted foreign-currency row must apply the same fx_rate multiplier import used to derive value_in_eur from raw.amount (raw.amount * fx_rate == value_in_eur), so the base cannot be summed as EUR while still carrying its native-currency figure.

Raises the same way effective_eur_amount does when the row is foreign-currency with no conversion applied.

Parameters:

transaction (Transaction) – The transaction whose EUR-equivalent taxable base is needed.

Return type:

Decimal | None

Returns:

A decimal.Decimal, or None when taxable_base is unset.

Raises:

AggregationConfigError – The row is foreign-currency with no EUR conversion applied.

effective_eur_iva_amount(transaction)[source]

Return the EUR-equivalent iva_amount, or None if unset.

Same native-currency contract and fx_rate conversion as effective_eur_taxable_base(), applied to iva_amount.

Parameters:

transaction (Transaction) – The transaction whose EUR-equivalent IVA amount is needed.

Return type:

Decimal | None

Returns:

A decimal.Decimal, or None when iva_amount is unset.

Raises:

AggregationConfigError – The row is foreign-currency with no EUR conversion applied.