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,
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
resolve_member_specs
staticmethod
¶
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
components.core_price.public.dependencies ¶
COMPONENT_NAME
module-attribute
¶
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 ¶
Function used to fetch the dependencies from the flask app.
Source code in components/core_price/public/dependencies.py
set_app_dependency ¶
Function used to actually inject the dependency class in the component.
Source code in components/core_price/public/dependencies.py
components.core_price.public.entities ¶
Pricing API domain entities.
BeDebtor ¶
BePriceComponentType ¶
Bases: PriceComponentType
BE health insurance coverage module. Will move to a proper core-stack definition once the BE plans are migrated
PolicyPricingSource
dataclass
¶
Resolve pricing from a policy_id directly.
PriceBreakdown
dataclass
¶
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
__setattr__ ¶
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
for_member ¶
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
from_components
staticmethod
¶
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
merge
staticmethod
¶
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
taxed_amount_billed_to_company
instance-attribute
¶
taxed_amount_billed_to_primary
instance-attribute
¶
untaxed_amount_billed_to_company
instance-attribute
¶
untaxed_amount_billed_to_primary
instance-attribute
¶
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__ ¶
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
amount
instance-attribute
¶
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.
collection_method
class-attribute
instance-attribute
¶
If a member is responsible for paying, how is the payment collected?
compare_component_lists
staticmethod
¶
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
contribution_type
instance-attribute
¶
What part of the price does this component correspond to?
debtor
instance-attribute
¶
Who is responsible for paying this price (country-specific subclass of Debtor, e.g., BeDebtor).
enrollment_id
class-attribute
instance-attribute
¶
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
¶
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
member_id
class-attribute
instance-attribute
¶
Stable member identifier (core_stack path). None for legacy paths.
module_id
class-attribute
instance-attribute
¶
Module UUID (core_stack path). None for legacy paths.
service_type
instance-attribute
¶
Which subpart of the service this price covers (country-specific subclass of PriceComponentType, e.g., BePriceComponentType).
PricingContext
dataclass
¶
Shared inputs required to compute a price breakdown.
primary_spec
property
¶
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.
PricingSource
module-attribute
¶
Abstract identifier for pricing resolution.
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
¶
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:
Source code in components/core_price/public/primitives.py
Currency
dataclass
¶
Represents a currency. Attempting to comply with ISO4217.
__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
format_amount ¶
Format an amount in minor units as a string with currency code.
Examples:
Source code in components/core_price/public/primitives.py
format_amount_with_symbol ¶
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
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | |
from_minor_unit ¶
Convert from integer representation of the currency to a decimal representation.
Examples:
Source code in components/core_price/public/primitives.py
locale_formats
instance-attribute
¶
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
¶
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
to_minor_unit ¶
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
LocaleFormat
dataclass
¶
Configuration for locale-specific number and currency formatting.
decimal_separator
instance-attribute
¶
Character used as decimal separator (e.g., "." or ",")
display_format
instance-attribute
¶
Template for displaying amount with symbol. Should contain {amount} and {symbol} placeholders. Example: "{amount} {symbol}" or "{symbol}{amount}"
negative_sign_position
instance-attribute
¶
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
¶
Character used as thousands separator (e.g., ",", ".", or " ")
RoundingStrategy ¶
Bases: AlanBaseEnum
Strategy for rounding monetary amounts.