Skip to content

Api reference

components.core_price.public.api

PricingService

Public facade. Business logic lives in internal/domain/services/.

get_breakdown staticmethod

get_breakdown(
    *,
    on_date: date,
    pricing_source: PricingSource,
    contract_identifier: None = None,
    rounding_strategy: RoundingStrategy = RoundingStrategy.ARITHMETIC
) -> PriceBreakdown
get_breakdown(
    *,
    on_date: date,
    pricing_source: None = None,
    contract_identifier: ContractIdentifier,
    rounding_strategy: RoundingStrategy = RoundingStrategy.ARITHMETIC
) -> PriceBreakdown
get_breakdown(
    *,
    on_date: date,
    member_specs: Sequence[MemberSpec],
    pricing_source: PricingSource,
    rounding_strategy: RoundingStrategy = RoundingStrategy.ARITHMETIC
) -> PriceBreakdown
get_breakdown(
    *,
    on_date: date,
    additional_member_specs: Sequence[MemberSpec],
    pricing_source: PricingSource,
    rounding_strategy: RoundingStrategy = RoundingStrategy.ARITHMETIC
) -> PriceBreakdown
get_breakdown(
    *,
    on_date,
    pricing_source=None,
    contract_identifier=None,
    member_specs=None,
    additional_member_specs=None,
    rounding_strategy=RoundingStrategy.ARITHMETIC
)

Compute a price breakdown.

See internal/domain/services/calculate_price.py for the actual logic.

Parameters:

Name Type Description Default
on_date date

Reference date for coverage and affiliation data.

required
pricing_source PricingSource | None

Abstract identifier (policy_id, user_id, …).

None
contract_identifier ContractIdentifier | None

Currently not implemented.

None
member_specs Sequence[MemberSpec] | None

Replace the source's beneficiaries with these.

None
additional_member_specs Sequence[MemberSpec] | None

Append these to the source's beneficiaries.

None
rounding_strategy RoundingStrategy

Defaults to arithmetic rounding.

ARITHMETIC
Source code in components/core_price/public/api.py
@staticmethod
def get_breakdown(
    *,
    on_date: date,
    pricing_source: PricingSource | None = None,
    contract_identifier: "ContractIdentifier | None" = None,
    member_specs: Sequence[MemberSpec] | None = None,
    additional_member_specs: Sequence[MemberSpec] | None = None,
    rounding_strategy: RoundingStrategy = RoundingStrategy.ARITHMETIC,
) -> "PriceBreakdown":
    """Compute a price breakdown.

    See `internal/domain/services/calculate_price.py` for the actual logic.

    Args:
        on_date: Reference date for coverage and affiliation data.
        pricing_source: Abstract identifier (policy_id, user_id, …).
        contract_identifier: Currently not implemented.
        member_specs: Replace the source's beneficiaries with these.
        additional_member_specs: Append these to the source's beneficiaries.
        rounding_strategy: Defaults to arithmetic rounding.
    """
    from components.core_price.internal.domain.services.calculate_price import (
        calculate_price_breakdown,
    )

    return calculate_price_breakdown(
        on_date=on_date,
        pricing_source=pricing_source,
        contract_identifier=contract_identifier,
        member_specs=member_specs,
        additional_member_specs=additional_member_specs,
        rounding_strategy=rounding_strategy,
    )

resolve_member_specs staticmethod

resolve_member_specs(*, pricing_source, on_date)

Resolve member specs from a pricing source.

Returns the list of member specs (beneficiaries) that the pricing source resolves to on the given date. Useful when consumers need to inspect or modify specs before passing them to get_breakdown(member_specs=...).

Source code in components/core_price/public/api.py
@staticmethod
def resolve_member_specs(
    *,
    pricing_source: PricingSource,
    on_date: date,
) -> Sequence[MemberSpec]:
    """Resolve member specs from a pricing source.

    Returns the list of member specs (beneficiaries) that the pricing source
    resolves to on the given date. Useful when consumers need to inspect or
    modify specs before passing them to get_breakdown(member_specs=...).
    """
    from components.core_price.internal.domain.services.calculate_price import (
        resolve_member_specs,
    )

    return resolve_member_specs(pricing_source=pricing_source, on_date=on_date)

components.core_price.public.dependencies

COMPONENT_NAME module-attribute

COMPONENT_NAME = 'core_price'

Canonical name of the core price component.

CorePriceDependency

Bases: PricingContextResolver, PriceBreakdownCalculator, ABC

Public dependency contract for the core price component.

Each country component provides a concrete implementation.

get_app_dependency

get_app_dependency()

Function used to fetch the dependencies from the flask app.

Source code in components/core_price/public/dependencies.py
def get_app_dependency() -> CorePriceDependency:
    """Function used to fetch the dependencies from the flask app."""
    from flask import current_app

    return cast("CustomFlask", current_app).get_component_dependency(COMPONENT_NAME)  # type: ignore[no-any-return]

set_app_dependency

set_app_dependency(dependency)

Function used to actually inject the dependency class in the component.

Source code in components/core_price/public/dependencies.py
def set_app_dependency(dependency: CorePriceDependency) -> None:
    """Function used to actually inject the dependency class in the component."""
    from flask import current_app

    cast("CustomFlask", current_app).add_component_dependency(
        COMPONENT_NAME, dependency
    )

components.core_price.public.entities

Pricing API domain entities.

BeDebtor

Bases: Payor

Entity paying for a BE health insurance price component. Will move to a proper core-stack definition once the BE plans are migrated

company class-attribute instance-attribute

company = 'company'

primary class-attribute instance-attribute

primary = 'primary'

BePriceComponentType

Bases: PriceComponentType

BE health insurance coverage module. Will move to a proper core-stack definition once the BE plans are migrated

base class-attribute instance-attribute

base = 'base'

extended class-attribute instance-attribute

extended = 'extended'

Base + option rolled into the same coverage module.

hospitalization class-attribute instance-attribute

hospitalization = 'hospitalization'

Neutral label for single-coverage plans (no base/extended distinction).

option class-attribute instance-attribute

option = 'option'

PolicyPricingSource dataclass

PolicyPricingSource(policy_id)

Resolve pricing from a policy_id directly.

policy_id instance-attribute

policy_id

PriceBreakdown dataclass

PriceBreakdown(*, price_components)

Represents the full price breakdown.

No safeties on price components

There are no checks verifying there are no duplicates in components. The caller is responsible for ensuring the components represent a valid price breakdown.

Source code in components/core_price/internal/domain/entities/price_breakdown.py
def __init__(self, *, price_components: list[PriceComponent]):
    self.price_components = price_components
    self.currency = price_components[0].currency if price_components else None

    # Compute some intermediary values frequently used by consumers, in O(n) time
    untaxed_amount_billed_to_primary = 0
    untaxed_amount_billed_to_company = 0

    taxes_billed_to_company = 0
    taxes_billed_to_primary = 0

    for component in price_components:
        if component.currency != self.currency:
            raise ValueError("Cannot mix different currencies.")

        # Compare by `value` to stay agnostic of the country-specific
        # `Debtor` subclass.
        match component.debtor.value:
            case "company":
                if component.contribution_type == PriceContributionType.taxes:
                    taxes_billed_to_company += component.amount
                else:
                    untaxed_amount_billed_to_company += component.amount
            case "primary":
                if component.contribution_type == PriceContributionType.taxes:
                    taxes_billed_to_primary += component.amount
                else:
                    untaxed_amount_billed_to_primary += component.amount
            case _:
                raise NotImplementedError(
                    f"Unimplemented billed entity: {component.debtor}"
                )

    taxed_amount_billed_to_primary = (
        untaxed_amount_billed_to_primary + taxes_billed_to_primary
    )
    taxed_amount_billed_to_company = (
        untaxed_amount_billed_to_company + taxes_billed_to_company
    )

    self.taxed_amount_billed_to_primary = taxed_amount_billed_to_primary
    self.untaxed_amount_billed_to_primary = untaxed_amount_billed_to_primary
    self.untaxed_amount_billed_to_company = untaxed_amount_billed_to_company
    self.taxed_amount_billed_to_company = taxed_amount_billed_to_company

    # Once initialised, the dataclass is frozen.
    # Enforced via custom __setattr__ implementation.
    self._initialized = True

__setattr__

__setattr__(name, value)

Setting attributes once the dataclass is initialized is forbidden. Reproducing the behavior of frozen=True.

Source code in components/core_price/internal/domain/entities/price_breakdown.py
def __setattr__(self, name: str, value: object) -> None:
    """
    Setting attributes once the dataclass is initialized is forbidden.
    Reproducing the behavior of frozen=True.
    """
    if hasattr(self, "_initialized") and self._initialized:
        raise AttributeError(
            f"Cannot modify {name} after initialization. PriceBreakdown is immutable."
        )
    super().__setattr__(name, value)

currency instance-attribute

currency = currency if price_components else None

for_member

for_member(member_id)

Return a new PriceBreakdown containing only components for the given member.

Parameters:

Name Type Description Default
member_id int | UUID | None

The enrollment_id identifying the member. Use None for simulated (not-yet-enrolled) members.

required
Source code in components/core_price/internal/domain/entities/price_breakdown.py
def for_member(self, member_id: int | UUID | None) -> "PriceBreakdown":
    """Return a new PriceBreakdown containing only components for the given member.

    Args:
        member_id: The enrollment_id identifying the member. Use None for
            simulated (not-yet-enrolled) members.
    """
    filtered = [c for c in self.price_components if c.enrollment_id == member_id]
    return PriceBreakdown.from_components(filtered)

from_components staticmethod

from_components(price_components)

Construct a PriceBreakdown from several price components.

Raises:

Type Description
NotImplementedError

if the billed entity is not implemented yet

ValueError

if the currency used by all the components is not the same

Source code in components/core_price/internal/domain/entities/price_breakdown.py
@staticmethod
def from_components(
    price_components: list[PriceComponent],
) -> "PriceBreakdown":
    """
    Construct a PriceBreakdown from several price components.

    Raises:
        NotImplementedError: if the billed entity is not implemented yet
        ValueError: if the currency used by all the components is not the same
    """
    return PriceBreakdown(price_components=price_components)

merge staticmethod

merge(price_breakdowns)

Merge several price breakdowns into a single one.

When we evaluate the prices of coverage modules individually, merging them is useful to get the total aggregated prices.

Source code in components/core_price/internal/domain/entities/price_breakdown.py
@staticmethod
def merge(
    price_breakdowns: list["PriceBreakdown"],
) -> "PriceBreakdown":
    """
    Merge several price breakdowns into a single one.

    When we evaluate the prices of coverage modules individually, merging them is
    useful to get the total aggregated prices.
    """
    if len(price_breakdowns) == 1:
        return price_breakdowns[0]

    all_components: list[PriceComponent] = []
    for breakdown in price_breakdowns:
        all_components.extend(breakdown.price_components)
    return PriceBreakdown.from_components(all_components)

price_components instance-attribute

price_components = price_components

taxed_amount_billed_to_company instance-attribute

taxed_amount_billed_to_company = (
    taxed_amount_billed_to_company
)

taxed_amount_billed_to_primary instance-attribute

taxed_amount_billed_to_primary = (
    taxed_amount_billed_to_primary
)

untaxed_amount_billed_to_company instance-attribute

untaxed_amount_billed_to_company = (
    untaxed_amount_billed_to_company
)

untaxed_amount_billed_to_primary instance-attribute

untaxed_amount_billed_to_primary = (
    untaxed_amount_billed_to_primary
)

PriceComponent dataclass

PriceComponent(
    *,
    service_type,
    contribution_type,
    beneficiary_type,
    debtor,
    collection_method=None,
    member_id=None,
    module_id=None,
    enrollment_id=None,
    currency,
    amount,
    periodicity="monthly"
)

Contract-enriched price component (one billable line).

Downstream of shared.core_stack.outputs.price_component.PriceComponent (the Plan-side raw output of ModulePricingFunction). Adds Contract data: debtor, collection_method, service_type, beneficiary_type, enrollment_id, periodicity. Plan→Contract mapping happens in the orchestrator's mapping.py.

__post_init__

__post_init__()

Validate that collection method is set when the debtor is a member, not the company.

We compare by value so any country-specific Debtor subclass with a "company" member matches.

Source code in components/core_price/internal/domain/entities/price_breakdown.py
def __post_init__(self) -> None:
    """Validate that collection method is set when the debtor is a member, not the company.

    We compare by `value` so any country-specific `Debtor` subclass with a
    `"company"` member matches.
    """
    if self.debtor.value != "company" and self.collection_method is None:
        raise ValueError(
            f"Collection method must be set when billed entity is {self.debtor}"
        )

amount instance-attribute

amount

The amount for an entire period of service.

Can be negative, for example if the amount corresponds to a discount. Must be expressed in the minor unit of the chosen currency.

beneficiary_type instance-attribute

beneficiary_type

Which member does this price correspond to?

collection_method class-attribute instance-attribute

collection_method = None

If a member is responsible for paying, how is the payment collected?

compare_component_lists staticmethod

compare_component_lists(left, right)

Compare two lists of price components for equality.

Parameters:

Name Type Description Default
left list[PriceComponent]

First list of components to compare

required
right list[PriceComponent]

Second list of components to compare

required

Returns:

Type Description
bool

True if both lists contain the same components in any order, False otherwise

Source code in components/core_price/internal/domain/entities/price_breakdown.py
@staticmethod
def compare_component_lists(
    left: list["PriceComponent"], right: list["PriceComponent"]
) -> bool:
    """
    Compare two lists of price components for equality.

    Args:
        left: First list of components to compare
        right: Second list of components to compare

    Returns:
        True if both lists contain the same components in any order, False otherwise
    """
    return set(left) == set(right)

contribution_type instance-attribute

contribution_type

What part of the price does this component correspond to?

currency instance-attribute

currency

debtor instance-attribute

debtor

Who is responsible for paying this price (country-specific subclass of Debtor, e.g., BeDebtor).

enrollment_id class-attribute instance-attribute

enrollment_id = None

An optional enrollment ID, in case the component corresponds to an enrolled member. It would typically be set when computing the prices for an existing policy. It would be None when a member projects the price of adding their partner to their policy.

group_by_beneficiary_id staticmethod

group_by_beneficiary_id(components)

Groups price components by enrollment ID.

Parameters:

Name Type Description Default
components list[PriceComponent]

List of PriceComponent to group

required

Returns:

Type Description
dict[int | UUID, list[PriceComponent]]

Dictionary mapping enrollment ID (int or UUID) to list of components

Raises:

Type Description
ValueError

If any component does not have an enrollment ID

Source code in components/core_price/internal/domain/entities/price_breakdown.py
@staticmethod
def group_by_beneficiary_id(
    components: list["PriceComponent"],
) -> dict[int | UUID, list["PriceComponent"]]:
    """
    Groups price components by enrollment ID.

    Args:
        components: List of PriceComponent to group

    Returns:
        Dictionary mapping enrollment ID (int or UUID) to list of components

    Raises:
        ValueError: If any component does not have an enrollment ID
    """
    grouped: dict[int | UUID, list[PriceComponent]] = {}

    for component in components:
        if component.enrollment_id is None:
            raise ValueError("All components must have an enrollment ID")

        enrollment_id = component.enrollment_id
        if enrollment_id not in grouped:
            grouped[enrollment_id] = []
        grouped[enrollment_id].append(component)

    return grouped

member_id class-attribute instance-attribute

member_id = None

Stable member identifier (core_stack path). None for legacy paths.

module_id class-attribute instance-attribute

module_id = None

Module UUID (core_stack path). None for legacy paths.

periodicity class-attribute instance-attribute

periodicity = 'monthly'

service_type instance-attribute

service_type

Which subpart of the service this price covers (country-specific subclass of PriceComponentType, e.g., BePriceComponentType).

PricingContext dataclass

PricingContext(
    *,
    member_specs,
    rounding_strategy=RoundingStrategy.ARITHMETIC
)

Shared inputs required to compute a price breakdown.

member_specs instance-attribute

member_specs

primary_spec property

primary_spec

Return the primary member spec.

Uses first instead of one because the BE coverage upgrade flow can inject a simulated primary spec (with member_id=None) via additional_member_specs, resulting in 2 primaries in the list. Real specs always come first (api.py merges policy specs before additional ones). TODO @cfollet: revert to one once upgrade flow uses dedicated pricing endpoint.

rounding_strategy class-attribute instance-attribute

rounding_strategy = ARITHMETIC

PricingSource module-attribute

PricingSource = UserPricingSource | PolicyPricingSource

Abstract identifier for pricing resolution.

UserPricingSource dataclass

UserPricingSource(user_id)

Resolve pricing from a user_id (looks up active enrollment → policy).

user_id instance-attribute

user_id

components.core_price.public.primitives

Shared primitives for pricing.

These are stable, cross-component technical types (currency, rounding strategy, etc.). It is OK to import these broadly.

Currencies

Common currencies supported by this component.

EUR class-attribute instance-attribute

EUR = Currency(
    alphabetic_code="EUR",
    numeric_code=978,
    minor_unit=2,
    symbol="€",
    locale_formats={
        "fr": LocaleFormat(
            decimal_separator=",",
            thousands_separator="\u202f",
            display_format="{amount}\xa0{symbol}",
            negative_sign_position="before_number",
        ),
        "nl": LocaleFormat(
            decimal_separator=",",
            thousands_separator=".",
            display_format="{symbol}\xa0{amount}",
            negative_sign_position="after_symbol",
        ),
        "en": LocaleFormat(
            decimal_separator=".",
            thousands_separator=",",
            display_format="{symbol}{amount}",
            negative_sign_position="before_symbol",
        ),
    },
)

from_alphabetic_code classmethod

from_alphabetic_code(code)

Get a Currency instance by its ISO4217 alphabetic code.

Parameters:

Name Type Description Default
code str

The ISO4217 alphabetic code (e.g., "EUR")

required

Returns:

Type Description
Currency

The Currency instance matching the code

Raises:

Type Description
ValueError

If the currency code is not supported

Examples:

>>> currency = Currencies.from_alphabetic_code("EUR")
>>> currency.alphabetic_code
'EUR'
Source code in components/core_price/public/primitives.py
@classmethod
def from_alphabetic_code(cls, code: str) -> Currency:
    """
    Get a Currency instance by its ISO4217 alphabetic code.

    Args:
        code: The ISO4217 alphabetic code (e.g., "EUR")

    Returns:
        The Currency instance matching the code

    Raises:
        ValueError: If the currency code is not supported

    Examples:
        >>> currency = Currencies.from_alphabetic_code("EUR")
        >>> currency.alphabetic_code
        'EUR'
    """
    for attr_name in dir(cls):
        if attr_name.startswith("_"):
            continue
        attr_value = getattr(cls, attr_name)
        if isinstance(attr_value, Currency) and (
            attr_value.alphabetic_code == code
        ):
            return attr_value

    supported_codes = [
        getattr(cls, attr).alphabetic_code
        for attr in dir(cls)
        if not attr.startswith("_") and isinstance(getattr(cls, attr), Currency)
    ]
    raise ValueError(
        f"Unsupported currency code: {code}. "
        f"Supported codes: {', '.join(supported_codes)}"
    )

Currency dataclass

Currency(
    *,
    alphabetic_code,
    numeric_code,
    minor_unit,
    symbol,
    locale_formats
)

Represents a currency. Attempting to comply with ISO4217.

__hash__

__hash__()

Hash the currency using its alphabetic code.

The alphabetic code (e.g., "EUR", "USD") uniquely identifies each currency according to ISO4217 standards, making it the ideal hash key.

Source code in components/core_price/public/primitives.py
def __hash__(self) -> int:
    """
    Hash the currency using its alphabetic code.

    The alphabetic code (e.g., "EUR", "USD") uniquely identifies each
    currency according to ISO4217 standards, making it the ideal hash key.
    """
    return hash(self.alphabetic_code)

alphabetic_code instance-attribute

alphabetic_code

ISO4217 compliant alpha code of the currency.

format_amount

format_amount(amount)

Format an amount in minor units as a string with currency code.

Examples:

formatted = Currencies.EUR.format_amount(1032)
print(formatted) # "10.32 EUR"
Source code in components/core_price/public/primitives.py
def format_amount(self, amount: int) -> str:
    """Format an amount in minor units as a string with currency code.

    Examples:
        ```python
        formatted = Currencies.EUR.format_amount(1032)
        print(formatted) # "10.32 EUR"
        ```
    """
    decimal_amount = self.from_minor_unit(amount)
    return f"{decimal_amount} {self.alphabetic_code}"

format_amount_with_symbol

format_amount_with_symbol(amount, locale)

Format an amount in minor units with currency symbol for display.

Trailing zeros after the decimal point are removed unless needed. The formatting respects the currency's ISO 4217 minor unit specification. Negative amounts are formatted according to locale-specific conventions.

Parameters:

Name Type Description Default
amount int

The amount in minor units (e.g., cents for EUR)

required
locale str

The locale to use for formatting ("fr", "nl", or "en")

required

Returns:

Type Description
str

Formatted string with locale-specific symbol position and

str

separators

Examples:

# French locale: symbol after with space, comma as decimal, thin
# space as thousands
formatted = Currencies.EUR.format_amount_with_symbol(12020, "fr")
print(formatted)  # "120,20 €"

formatted = Currencies.EUR.format_amount_with_symbol(10000, "fr")
print(formatted)  # "100 €"

formatted = Currencies.EUR.format_amount_with_symbol(-12020, "fr")
print(formatted)  # "‑120,20 €"

# English locale: symbol before no space, dot as decimal, comma as
# thousands
formatted = Currencies.EUR.format_amount_with_symbol(12020, "en")
print(formatted)  # "€120.20"

formatted = Currencies.EUR.format_amount_with_symbol(-12020, "en")
print(formatted)  # "‑€120.20"

# Dutch locale: symbol before with space, comma as decimal, dot as
# thousands
formatted = Currencies.EUR.format_amount_with_symbol(12020, "nl")
print(formatted)  # "€ 120,20"

formatted = Currencies.EUR.format_amount_with_symbol(-12020, "nl")
print(formatted)  # "€ ‑120,20"

formatted = Currencies.EUR.format_amount_with_symbol(
    12345678900, "fr"
)
print(formatted)  # "123 456 789 €"
Source code in components/core_price/public/primitives.py
def format_amount_with_symbol(self, amount: int, locale: str) -> str:
    """Format an amount in minor units with currency symbol for display.

    Trailing zeros after the decimal point are removed unless needed.
    The formatting respects the currency's ISO 4217 minor unit
    specification. Negative amounts are formatted according to
    locale-specific conventions.

    Args:
        amount: The amount in minor units (e.g., cents for EUR)
        locale: The locale to use for formatting ("fr", "nl", or "en")

    Returns:
        Formatted string with locale-specific symbol position and
        separators

    Examples:
        ```python
        # French locale: symbol after with space, comma as decimal, thin
        # space as thousands
        formatted = Currencies.EUR.format_amount_with_symbol(12020, "fr")
        print(formatted)  # "120,20 €"

        formatted = Currencies.EUR.format_amount_with_symbol(10000, "fr")
        print(formatted)  # "100 €"

        formatted = Currencies.EUR.format_amount_with_symbol(-12020, "fr")
        print(formatted)  # "\u2011120,20\u00a0€"

        # English locale: symbol before no space, dot as decimal, comma as
        # thousands
        formatted = Currencies.EUR.format_amount_with_symbol(12020, "en")
        print(formatted)  # "€120.20"

        formatted = Currencies.EUR.format_amount_with_symbol(-12020, "en")
        print(formatted)  # "\u2011€120.20"

        # Dutch locale: symbol before with space, comma as decimal, dot as
        # thousands
        formatted = Currencies.EUR.format_amount_with_symbol(12020, "nl")
        print(formatted)  # "€\u00a0120,20"

        formatted = Currencies.EUR.format_amount_with_symbol(-12020, "nl")
        print(formatted)  # "€\u00a0\u2011120,20"

        formatted = Currencies.EUR.format_amount_with_symbol(
            12345678900, "fr"
        )
        print(formatted)  # "123 456 789 €"
        ```
    """
    locale_format = self.locale_formats[locale]
    is_negative = amount < 0
    currency_amount = self.from_minor_unit(abs(amount))

    if int(currency_amount) == currency_amount:
        formatted_string = f"{int(currency_amount):,}"
    else:
        formatted_string = f"{currency_amount:,.{self.minor_unit}f}"

    # Use a temporary placeholder to avoid conflicts when thousands and
    # decimal separators are swapped (e.g., Dutch uses "." for thousands
    # and "," for decimals)
    number_part = (
        formatted_string.replace(",", "{{THOUSANDS}}")
        .replace(".", "{{DECIMAL}}")
        .replace("{{THOUSANDS}}", locale_format.thousands_separator)
        .replace("{{DECIMAL}}", locale_format.decimal_separator)
    )

    formatted_result = locale_format.display_format.format(
        amount=number_part, symbol=self.symbol
    )

    if is_negative:
        if locale_format.negative_sign_position == "before_symbol":
            formatted_result = f"\u2011{formatted_result}"
        elif locale_format.negative_sign_position == "after_symbol":
            formatted_result = formatted_result.replace(
                f"{self.symbol}\u00a0", f"{self.symbol}\u00a0\u2011", 1
            )
        elif locale_format.negative_sign_position == "before_number":
            formatted_result = formatted_result.replace(
                number_part, f"\u2011{number_part}", 1
            )

    return formatted_result

from_minor_unit

from_minor_unit(amount)

Convert from integer representation of the currency to a decimal representation.

Examples:

decimal_representation = Currencies.EUR.from_minor_unit(1032)
print(decimal_representation) # 10.32
Source code in components/core_price/public/primitives.py
def from_minor_unit(self, amount: int) -> Decimal:
    """Convert from integer representation of the currency to a decimal
    representation.

    Examples:
        ```python
        decimal_representation = Currencies.EUR.from_minor_unit(1032)
        print(decimal_representation) # 10.32
        ```
    """
    return Decimal(amount) / Decimal(10**self.minor_unit)

locale_formats instance-attribute

locale_formats

Locale-specific formatting configuration for displaying amounts.

Examples:

  • "fr": LocaleFormat(decimal=",", thousands=" ", format="{amount} {symbol}") produces "123 456,78 €"
  • "nl": LocaleFormat(decimal=",", thousands=".", format="{symbol} {amount}") produces "€ 123.456,78"
  • "en": LocaleFormat(decimal=".", thousands=",", format="{symbol}{amount}") produces "€123,456.78"

minor_unit instance-attribute

minor_unit

The number of digits after the decimal separator to represent as the minor unit. Helps us represent amounts as integers instead of floats, for example representing euros as cents.

Certain currenceis are naturally representable as ints and have 0 digits after the decimal place.

Examples: Japanese yen, South Korean won

numeric_code instance-attribute

numeric_code

ISO4217 compliant code of the currency.

symbol instance-attribute

symbol

The currency symbol used for display (e.g., "€", "$", "£").

to_minor_unit

to_minor_unit(amount)

Convert from floating point representation of the currency to an integer representation.

Useful to avoid precision errors of large floats.

Examples:

integer_representation = Currencies.EUR.to_minor_unit(10.32)
print(integer_representation) # 1032 cents
Source code in components/core_price/public/primitives.py
def to_minor_unit(self, amount: Decimal) -> int:
    """Convert from floating point representation of the currency to an
    integer representation.

    Useful to avoid precision errors of large floats.

    Examples:
        ```python
        integer_representation = Currencies.EUR.to_minor_unit(10.32)
        print(integer_representation) # 1032 cents
        ```
    """
    return int(amount * (10**self.minor_unit))

LocaleFormat dataclass

LocaleFormat(
    *,
    decimal_separator,
    thousands_separator,
    display_format,
    negative_sign_position
)

Configuration for locale-specific number and currency formatting.

decimal_separator instance-attribute

decimal_separator

Character used as decimal separator (e.g., "." or ",")

display_format instance-attribute

display_format

Template for displaying amount with symbol. Should contain {amount} and {symbol} placeholders. Example: "{amount} {symbol}" or "{symbol}{amount}"

negative_sign_position instance-attribute

negative_sign_position

Where to place the minus sign for negative amounts.

Examples:

  • "before_symbol": -€120.20 (English)
  • "after_symbol": € -120,20 (Dutch)
  • "before_number": -120,20 € (French)

thousands_separator instance-attribute

thousands_separator

Character used as thousands separator (e.g., ",", ".", or " ")

RoundingStrategy

Bases: AlanBaseEnum

Strategy for rounding monetary amounts.

ARITHMETIC class-attribute instance-attribute

ARITHMETIC = 'arithmetic'

Round half up (0.5 -> 1). Traditional rounding method.

BANKERS class-attribute instance-attribute

BANKERS = 'bankers'

Round half to even (0.5 -> 0, 1.5 -> 2). Reduces systematic bias.