Api reference
components.premium.public.api ¶
PremiumAggregationService ¶
A service used to interact with subscription fees (AKA premiums in the context of insurance).
Fees are created to represent the consumption of Alan products. Many services throughout the stack need to consume fees to function: - invoicing aggregates fees into invoices - payroll reports the structure of the fees to give clarity to admins - data monitors general financial performance levels
This service is meant to become the one-stop-shop for all these consumers.
Additionally, the way we manage fees is evolving. Previously, each country & product had it's own engine for computing fees, and format to store them. We are moving toward a global solution: same engine and same format across all countries and products. However this is a still a work in progress, and this service also aims to protect consumers from having to deal with different formats. All functions are meant to function the same no matter which engine was used to compute the fees and how they were stored.
BELGIUM_PREMIUM_MIGRATION_WINDOW_END
class-attribute
instance-attribute
¶
After this date, no premiums in Belgium were generated using the local engine. From this point, all premiums are stored in the global engine repository only.
BELGIUM_PREMIUM_MIGRATION_WINDOW_START
class-attribute
instance-attribute
¶
The very first premium generated using the global engine in Belgium was generated for the month of December 2025. Before that date, all premiums in Belgium were generated using a local engine.
get_premium_entries_for_invoice
staticmethod
¶
Retrieve premium entries for a given invoice. If invoice has no components, then it retrieves legacy premium entries, and transforms them to PremiumEntry objects with components.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
invoice_id
|
UUID
|
The ID of the invoice to retrieve premium entries for. |
required |
Returns:
| Type | Description |
|---|---|
list[PremiumEntry]
|
List of PremiumEntry objects for the invoice. |
Source code in components/premium/public/api.py
get_premiums_for_local_payroll
staticmethod
¶
Retrieve all premium entries to be included in a local payroll CSV where
- payroll_csv_id IS NULL (global repo) or pay_csv_id IS NULL (legacy repo)
- period_start <= target_month
In practice the aggregation service is supposed to shield consumers from the 'source' of premiums. However in practice this function does not require that complexity, considering this is a temporary bridge between local & global callers know what they need.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
Session
|
SQLAlchemy session injected by @transactional decorator. |
required |
enrollment_ids
|
list[UUID]
|
UUIDs of enrollments to retrieve entries for. |
required |
target_month
|
date
|
Only entries with period_start <= last day of this month are returned. |
required |
force_premium_source
|
Literal['legacy', 'global']
|
Which SOT to use when fetching premiums |
required |
Source code in components/premium/public/api.py
get_premiums_for_payroll
staticmethod
¶
Retrieve all entries where
- at least some part of the total amount is meant to be billed to the company.
- the premiums's period_start is after cutoff_date
- the premium's created_at is after cutoff_date
To shield callers from the details of the progress into the various premium migrations, this function is able to read and reconcile from multiple sources.
Considering this function is meant for the usage of payroll batch jobs, it has been designed with a certain amount of care when it comes to performance: - the read happens on a read-replica - we guarantee a set number of queries no matter how many enrollment IDs are passed (no N+1) - the process of reading 1,000 entries consumes around 16 MB of memory at peak - once all transient objects have been released by the garbage collector and only the dataclass instances remain, 1,000 entries weigh around 5 MB - you can find methodology and instructions to reproduce the measurements in the component's README
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
Session
|
SQLAlchemy session injected by @transactional decorator. |
required |
enrollment_ids
|
list[int | UUID]
|
IDs of enrollments to retrieve entries for. |
required |
cutoff_date
|
date
|
Only entries with period_start or created_at after this date are returned. |
required |
Returns:
| Type | Description |
|---|---|
list[PremiumEntry]
|
List of complete PremiumEntry objects. |
Source code in components/premium/public/api.py
get_uninvoiced_premiums
staticmethod
¶
Retrieve premium entries with uninvoiced components, checking specifically if the company or primary part is invoiced.
Returns complete premium entries where at least one component has not been invoiced yet. The debtor is inferred from the contract type: - Policy: primary policy holder - Contract → company
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
policy
|
Policy | None
|
Policy to retrieve premiums for (mutually exclusive with contract). |
None
|
contract
|
Contract | None
|
Contract to retrieve premiums for (mutually exclusive with policy). |
None
|
up_to
|
date
|
Only returns entries where period_end <= up_to. |
required |
Returns:
| Type | Description |
|---|---|
list[PremiumEntry]
|
List of complete PremiumEntry objects with uninvoiced components. |
Source code in components/premium/public/api.py
mark_entries_for_payroll
staticmethod
¶
Mark premium entries as included in a payroll CSV.
Tries the global repository first. If no entries are found there, falls back to the legacy repository.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
Session
|
Database session. |
required |
premium_entry_ids
|
list[UUID]
|
IDs of the premium entries to mark. |
required |
payroll_csv_id
|
UUID
|
The payroll CSV ID to set on matching entries. |
required |
Source code in components/premium/public/api.py
mark_premiums_as_invoiced
staticmethod
¶
Mark premium entries as invoiced by setting invoice_id on matching components.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
Session
|
Database session. |
required |
premium_entries
|
list[PremiumEntry]
|
List of premium entries to mark as invoiced. |
required |
invoice_id
|
UUID
|
The invoice ID to set on matching components. |
required |
debtor
|
InsuranceBilledEntity
|
The billed entity whose components should be marked as invoiced. |
required |
Source code in components/premium/public/api.py
PremiumComputationService ¶
Compute premiums.
Not responsible for storing the computed premiums
compute_insurance_premiums
staticmethod
¶
compute_insurance_premiums(
session,
*,
policy,
contract,
start_month,
end_month,
engine_parameters=None
)
Compute how much money is owed to Alan and persist the results.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
Session
|
SQLAlchemy session injected by @transactional decorator |
required |
policy
|
Policy
|
The insurance policy containing enrollments |
required |
contract
|
Contract
|
The contract defining pricing terms |
required |
start_month
|
Month
|
First month to calculate premiums for |
required |
end_month
|
Month
|
Last month to include in premium calculations |
required |
engine_parameters
|
EngineParameters | None
|
Optional engine configuration. If not provided, uses defaults for current application |
None
|
Returns:
| Type | Description |
|---|---|
list[PremiumEntry]
|
All fresh entries returned by the computation. |
Source code in components/premium/public/api.py
components.premium.public.commands ¶
components.premium.public.cost_types ¶
Insurance cost types for the premium component.
This module contains premium's own definitions of insurance domain types, decoupling it from price_provider component implementations. Changes to price_provider's internal pricing logic should not require changes to premium's domain model.
Currency and rounding strategy are intentionally NOT duplicated - import them
from components.core_price.public.primitives.
InsuranceBeneficiary ¶
Bases: AlanBaseEnum
Represents the different types of insurance beneficiaries.
from_enrollment_type
classmethod
¶
Convert EnrollmentType to InsuranceBeneficiary.
Source code in components/premium/public/cost_types.py
to_enrollment_type ¶
Convert InsuranceBeneficiary to EnrollmentType.
Source code in components/premium/public/cost_types.py
InsuranceBilledEntity ¶
InsuranceCollectionMethod ¶
Bases: AlanBaseEnum
Methods for collecting an employee's participation.
direct_billing
class-attribute
instance-attribute
¶
The amount is paid directly by the employee or their partner, using the payment method of their choice.
flexben_fund
class-attribute
instance-attribute
¶
The amount is paid from the employee's flexben fund.
payroll
class-attribute
instance-attribute
¶
The amount is paid by the company but automatically deducted from the employee's payslip.
InsuranceContribution ¶
Bases: AlanBaseEnum
Represents how an amount is used, what the money is going towards.
InsuranceCost
dataclass
¶
Represents the entire cost of an insurance service.
No safeties on cost components
There are no checks verifying there are no duplicates in components. The caller is responsible for ensuring the components represent a valid cost breakdown.
Source code in components/premium/public/cost_types.py
__setattr__ ¶
Setting attributes once the dataclass is initialized is forbidden. Reproducing the behavior of frozen=True.
Source code in components/premium/public/cost_types.py
from_components
staticmethod
¶
Construct an InsuranceCost from several cost 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/premium/public/cost_types.py
merge
staticmethod
¶
Merge several costs into the same cost objects.
When we evaluate the costs of coverage modules individually, merging them is useful to get the total aggregated costs.
Source code in components/premium/public/cost_types.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
¶
InsuranceCostComponent
dataclass
¶
InsuranceCostComponent(
*,
service_type,
contribution_type,
beneficiary_type,
billed_entity,
collection_method=None,
enrollment_id=None,
currency,
amount,
periodicity="monthly"
)
Represents part of a cost of insurance service.
__post_init__ ¶
Validate that collection method is set when billed entity is not company.
Source code in components/premium/public/cost_types.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.
beneficiary_type
instance-attribute
¶
Who's coverage does this cost correspond to ?
collection_method
class-attribute
instance-attribute
¶
If an employee is responsible for paying this cost, how is the payment collected ?
compare_component_lists
staticmethod
¶
Compare two lists of insurance cost components for equality.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
left
|
list[InsuranceCostComponent]
|
First list of components to compare |
required |
right
|
list[InsuranceCostComponent]
|
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/premium/public/cost_types.py
contribution_type
instance-attribute
¶
What part of the service is paid for by this cost?
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 cost of adding their partner to their policy.
group_by_beneficiary_id
staticmethod
¶
Groups insurance cost components by enrollment ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
components
|
list[InsuranceCostComponent]
|
List of InsuranceCostComponent to group |
required |
Returns:
| Type | Description |
|---|---|
dict[int | UUID, list[InsuranceCostComponent]]
|
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/premium/public/cost_types.py
service_type
instance-attribute
¶
What insurance service does this cost correspond to ?
InsuranceService ¶
components.premium.public.dependencies ¶
COMPONENT_NAME
module-attribute
¶
Canonical name of the premium component.
PremiumDependency ¶
Bases: ABC
Represents all the dependency required by components/premium to function as
expected.
get_flexben_timeline_for_all_enrollments_of_the_policy
abstractmethod
¶
For each enrollment in the policy, return a list of periods where a flexben choice is enabled.
Considering flexben is a feature local to Belgium, we expect components/be to
be the only caller to actually inject this dependency.
Other components are expected to inject a function returning an empty dict.
Example
{ enrollment_id_1: [ ValidityPeriod(date(2024, 1, 1), date(2024, 6, 30)), ], enrollment_id_2: [ ValidityPeriod(date(2024, 3, 1), date(2024, 12, 31)), ], }
Source code in components/premium/public/dependencies.py
get_legacy_premium_entry_repository
abstractmethod
¶
Instantiate layer to retrieve premium entries based on legacy ones
get_premium_repository
abstractmethod
¶
get_app_dependency ¶
Function used to fetch the dependencies from the flask app.
Source code in components/premium/public/dependencies.py
set_app_dependency ¶
Function used to actually inject the dependency class in the component.
Source code in components/premium/public/dependencies.py
components.premium.public.entities ¶
AgeStrategy ¶
Bases: AlanBaseEnum
Strategy for handling age calculation in insurance premium calculations.
The effective birthday or age we use for pricing a beneficiary may differ from their actual birthday or age.
KEEP_EXACT_BIRTHDAY
class-attribute
instance-attribute
¶
Use the exact birthday for age calculation.
Example: If a member turns 23 on March 15, 2023, their age changes exactly on March 15, 2023.
MOVE_BIRTHDAY_TO_FIRST_DAY_OF_MONTH
class-attribute
instance-attribute
¶
Move birthday to the first day of the birth month for age calculation.
Example: If a member turns 23 on March 15, 2023, they will be priced as 23 years old starting March 1, 2023 for the entire month.
MOVE_BIRTHDAY_TO_JAN_OF_NEXT_YEAR
class-attribute
instance-attribute
¶
Move birthday to January 1st of the year following the birth year.
Example: If a member turns 23 on March 15, 2023, they will be priced as 22 years old for the entirety of 2023, and 23 years old starting January 1, 2024.
CostPeriod
dataclass
¶
Bases: GenericPeriodWithStartReason
Represents a timeline period with computed premium cost.
Final output of the premium calculation pipeline, containing the actual cost for the stable period. Each period guarantees the cost remains constant throughout its validity period.
Attributes:
| Name | Type | Description |
|---|---|---|
cost |
Cost
|
The computed insurance cost for this period, calculated based on the stable beneficiary composition and contract terms. |
EngineParameters
dataclass
¶
EngineParameters(
*,
age_strategy,
rounding_strategy,
prorata_strategy,
default_child_age,
default_adult_age
)
Parameters dictating how the engine behaves and which rules it follows.
Example
- which effective birth date to use
- which prorata formula to use
- which rounding strategy to use
default
staticmethod
¶
Get default engine parameters for a given application. Application is used as a proxy for country.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
The application name to get default parameters for |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the application is not yet supported |
Source code in components/premium/internal/domain/engine_parameters.py
default_adult_age
instance-attribute
¶
Optional strategy for normalizing ages into specific buckets for pricing. When None, ages are used directly from beneficiary birthdates or defaults. When specified, the strategy determines how to group beneficiaries by age.
FeeComponent
dataclass
¶
Bases: CostComponent
A fee component represents one part of a fee that we intend to bill to a customer.
__eq__ ¶
Source code in components/premium/internal/domain/fee.py
__hash__ ¶
Source code in components/premium/internal/domain/fee.py
amount_before_prorata
instance-attribute
¶
Amount for full period coverage without prorata applied. Expressed in the minor unit of the currency. This is the full monthly amount that would be charged for complete period coverage.
as_tuple ¶
Return (billed_entity, contribution_type, amount)
id
class-attribute
instance-attribute
¶
Unique identifier of the entry
inverted ¶
Returns a new FeeComponent offsetting the current one.
Source code in components/premium/internal/domain/fee.py
invoice_id
instance-attribute
¶
If the component is included in an invoice, it is represented here.
LegacyBelgianNormalization
dataclass
¶
Groups beneficiaries into specific age buckets: - Children are treated as adults if they are 25 or above - Young adults (18-25) are priced as 25 or above if they are the primary policy holder or their partner - No birthdate available: default to age 25 - Anyone not falling in one of the buckets above: use their actual age
normalize_age ¶
Source code in components/premium/internal/domain/age_normalization.py
Policy ¶
PremiumEntry
dataclass
¶
PremiumEntry(
*,
id=uuid4(),
enrollment_id,
components,
period_start,
period_end,
version=1,
cancelled_by_entry_id=None,
cancelled_entry_id=None,
payroll_csv_id=None
)
A subscription fee specific to insurance subscriptions.
__eq__ ¶
Source code in components/premium/internal/domain/fee.py
__hash__ ¶
cancelled ¶
Returns two new entries: one marking this entry as cancelled, and one offsetting it.
Returns:
| Type | Description |
|---|---|
tuple[PremiumEntry, PremiumEntry | None]
|
tuple[PremiumEntry, PremiumEntry]: - First entry: Same as self but marked as cancelled - Second entry: New entry to offset self. |
Source code in components/premium/internal/domain/fee.py
cancelled_by_entry_id
class-attribute
instance-attribute
¶
components_billed_to_debtor ¶
Returns components that are actually billed to the specified debtor.
This method accounts for collection methods: - If debtor is company: includes company components AND primary components with (payroll or flexben_fund) - If debtor is primary: only includes primary components with direct_billing
Source code in components/premium/internal/domain/fee.py
components_for_debtor ¶
The debtor is not necessarily the entity being billed
If a component's debtor is the primary but the collection method is payroll, the company gets billed.
If your purpose is to list components that should be invoiced to a given debtor,
use components_billed_to_debtor().
Source code in components/premium/internal/domain/fee.py
payroll_csv_id
class-attribute
instance-attribute
¶
Belgium & Spain's local payroll systems requires to keep track of which premiums are included in which file.
In order to maintain compatibility between Belgium payroll and Global premiums we need to maintain this property. However it's not required by the Global payroll system, therefore this property is temporary and will be dropped as soon as global payroll is online.
pretax_amount_billed_to_debtor ¶
Returns the total pretax amount (membership fees + costs) billed to the specified debtor.
This includes components with contribution_type of: - InsuranceContribution.membership_fee: Base membership fees - InsuranceContribution.cost: Insurance coverage costs
This method accounts for collection methods: - If debtor is company: includes company components AND primary components with (payroll or flexben_fund) - If debtor is primary: only includes primary components with direct_billing
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
debtor
|
InsuranceBilledEntity
|
The entity to which costs are billed |
required |
Returns:
| Type | Description |
|---|---|
int
|
Total pretax amount in minor currency units |
Source code in components/premium/internal/domain/fee.py
prorata_ratio ¶
Returns the prorata ratio for this premium entry.
The ratio is calculated as: - 1.0 (or -1.0 for negative days) if the premium covers the full month - num_days / 30 otherwise (using 30-day convention, rounded to 2 decimals)
Uses arithmetic rounding (ROUND_HALF_UP) for consistency with invoicing display.
Returns:
| Type | Description |
|---|---|
float
|
Prorata ratio as a float. Positive for regular premiums, negative for credits/reversals. |
Source code in components/premium/internal/domain/fee.py
taxes_billed_to_debtor ¶
Returns the total tax amount billed to the specified debtor.
This includes components with contribution_type of: - InsuranceContribution.taxes: Tax components
This method accounts for collection methods: - If debtor is company: includes company components AND primary components with (payroll or flexben_fund) - If debtor is primary: only includes primary components with direct_billing
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
debtor
|
InsuranceBilledEntity
|
The entity to which taxes are billed |
required |
Returns:
| Type | Description |
|---|---|
int
|
Total tax amount in minor currency units |
Source code in components/premium/internal/domain/fee.py
total_amount ¶
total_amount_billed_to_debtor ¶
Returns the total amount for components actually billed to the specified debtor.
This method accounts for collection methods: - If debtor is company: includes company components AND primary components with (payroll or flexben_fund) - If debtor is primary: only includes primary components with direct_billing
Source code in components/premium/internal/domain/fee.py
total_amount_for_debtor ¶
The debtor is not necessarily the entity being billed
If a component's debtor is the primary but the collection method is payroll, the company gets billed.
If your purpose is to compute the total amount that should be invoiced to a given debtor,
use total_amount_billed_to_debtor().
Source code in components/premium/internal/domain/fee.py
total_billed_to_debtor_without_prorata ¶
Returns the total amount before prorata for components actually billed to the specified debtor.
This method accounts for collection methods: - If debtor is company: includes company components AND primary components with (payroll or flexben_fund) - If debtor is primary: only includes primary components with direct_billing
Source code in components/premium/internal/domain/fee.py
total_for_debtor_without_prorata ¶
The debtor is not necessarily the entity being billed
If a component's debtor is the primary but the collection method is payroll, the company gets billed.
If your purpose is to compute the total amount without prorata that should be invoiced to a given debtor,
use total_billed_to_debtor_without_prorata().
Source code in components/premium/internal/domain/fee.py
with_components_marked_as_invoiced ¶
Returns a new PremiumEntry with components for the specified debtor marked as invoiced.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
invoice_id
|
UUID
|
The invoice ID to set on matching components. |
required |
debtor
|
InsuranceBilledEntity
|
The billed entity whose components should be marked as invoiced. |
required |
Returns:
| Type | Description |
|---|---|
PremiumEntry
|
New PremiumEntry with updated components. |
Source code in components/premium/internal/domain/fee.py
with_version ¶
Returns a new PremiumEntry with a different version.
Source code in components/premium/internal/domain/fee.py
PremiumEntryRepository ¶
Bases: Protocol
Repository protocol for persisting and retrieving premium entries.
get_all_entries ¶
Retrieve all premium entries for specified enrollments with an optional period.
Returns all stored premium entries including both cancelled and active entries.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
enrollment_ids
|
list[int | UUID]
|
IDs (int or UUID) of enrollments to retrieve entries for. Some implementations may only support UUID IDs and will raise an error if int IDs are provided. |
required |
period_start
|
Month | date | None
|
Optional lower bound for the entry period. If provided, only returns entries where entry.period_start == period_start. If Month is passed, use the first day of the month. If None, there is no filter on the start date of the period. |
required |
period_end
|
Month | date | None
|
Optional upper bound for the entry period. If provided, only returns entries where entry.period_end == period_end. If Month is passed, use the last day of the month. If None, there is no filter on the end date of the period. |
required |
Returns:
| Type | Description |
|---|---|
list[PremiumEntry]
|
List of PremiumEntry objects matching the filtering criteria. |
list[PremiumEntry]
|
If both date parameters are None, returns all entries for the enrollments. |
Source code in components/premium/internal/domain/repository.py
get_all_uninvoiced_entries_up_to ¶
Retrieve premium entries that have uninvoiced components for a specific debtor.
An entry is included if it has at least one component where the debtor has not been invoiced (invoice_id IS NULL). The returned entries are complete - they contain all components regardless of their invoice status or debtor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
enrollment_ids
|
list[int | UUID]
|
IDs (int or UUID) of enrollments to retrieve entries for. Some implementations may only support UUID IDs and will raise an error if int IDs are provided. |
required |
debtor
|
InsuranceBilledEntity
|
The billed entity (primary, company, etc.) to check for uninvoiced components. |
required |
up_to
|
date
|
Only returns entries where period_end <= up_to. |
required |
Returns:
| Type | Description |
|---|---|
list[PremiumEntry]
|
List of complete PremiumEntry objects. |
Source code in components/premium/internal/domain/repository.py
get_entries_for_local_payroll ¶
Retrieve all entries where payroll_csv_id IS NULL and period_start <= target_month.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
enrollment_ids
|
list[UUID]
|
IDs of enrollments to retrieve entries for. |
required |
target_month
|
date
|
Only entries with period_start on or before this date are returned. |
required |
Source code in components/premium/internal/domain/repository.py
get_entries_for_payroll ¶
Retrieve all entries where
- at least one component is billed to the company
- the premiums's period_start is after cutoff_date
- the premium's created_at is after cutoff_date
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
enrollment_ids
|
list[int | UUID]
|
IDs (int or UUID) of enrollments to retrieve entries for. |
required |
cutoff_date
|
date
|
Only entries with period_start or created_at after this date are returned. |
required |
Source code in components/premium/internal/domain/repository.py
get_latest_entries ¶
Retrieve the latest premium entries for specified enrollments for all periods contained within lower_bound and upper_bound.
Lower bound and upper bound may cover more than one period
The caller is free to pass any range they would like. We return one premium entry, per enrollment, per period in the range.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
enrollment_ids
|
list[int | UUID]
|
IDs (int or UUID) of enrollments to retrieve entries for. Some implementations may only support UUID IDs and will raise an error if int IDs are provided. |
required |
lower_bound
|
Month | date
|
Range start. If Month is passed, use the first day of the month. |
required |
upper_bound
|
Month | date
|
Range end. If Month is passed, use the last day of the month. |
required |
Returns:
| Type | Description |
|---|---|
list[PremiumEntry]
|
One premium entry per enrollment per period in the range. |
list[PremiumEntry]
|
For each period, the premium returned is the latest as defined by the |
list[PremiumEntry]
|
version. |
Examples:
>>> # Single month range returns 1 entry per enrollment
>>> repo.get_latest_entries(
... enrollment_ids=[uuid1, uuid2],
... lower_bound=Month(2024, 1),
... upper_bound=Month(2024, 1)
... )
[PremiumEntry(...period_start=2024-01-01...)]
>>> # Three month range returns 3 entries per enrollment
>>> repo.get_latest_entries(
... enrollment_ids=[uuid1],
... lower_bound=Month(2024, 1),
... upper_bound=Month(2024, 3)
... )
[
PremiumEntry(...period_start=2024-01-01...),
PremiumEntry(...period_start=2024-02-01...),
PremiumEntry(...period_start=2024-03-01...)
]
Source code in components/premium/internal/domain/repository.py
get_premium_entries_for_invoice ¶
Retrieve premium entries for a specific invoice. If invoice has no components, then it returns an empty list.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
invoice_id
|
HybridId
|
The ID of the invoice to retrieve premium entries for. |
required |
Returns:
| Type | Description |
|---|---|
list[PremiumEntry]
|
List of PremiumEntry objects for the invoice. |
Source code in components/premium/internal/domain/repository.py
insert ¶
Insert new premium entries into the database.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entries
|
list[PremiumEntry]
|
List of PremiumEntry objects to insert. Each entry's components will be added to the database. |
required |
Source code in components/premium/internal/domain/repository.py
mark_entries_for_payroll ¶
Mark premium entries as included in a payroll CSV by setting payroll_csv_id.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
premium_entry_ids
|
list[UUID]
|
IDs of the premium entries to mark. |
required |
payroll_csv_id
|
UUID
|
The payroll CSV ID to set on matching entries. |
required |
Returns:
| Type | Description |
|---|---|
int
|
Number of entries updated. |
Source code in components/premium/internal/domain/repository.py
update ¶
Update existing premium entries in the database.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entries
|
list[PremiumEntry]
|
List of PremiumEntry objects to update. Each entry's components will be merged into the database. |
required |
Source code in components/premium/internal/domain/repository.py
ProrataStrategy ¶
Bases: AlanBaseEnum
Strategy for applying prorata to cost components.
When multiple cost components need prorating (e.g., base cost, membership fee, taxes), different strategies can be used that may produce slightly different results due to rounding.
THIRTY_DAY_PRORATA
class-attribute
instance-attribute
¶
If the service covers the whole month, bill the full amount for 1 month. A month is a full month if the number of days covered equals the number of days in the month. If the service does not cover the whole month, prorate on the base of 30 days.
Formula: monthly_price * days_covered / 30
This prorata is applied to all the components of the subscription fee and may carry rounding errors, meaning the total of components may exceed the initial total.
THIRTY_DAY_PRORATA_WITH_LARGEST_REMAINDER_DISTRIBUTION_ACROSS_FEE_COMPONENTS
class-attribute
instance-attribute
¶
THIRTY_DAY_PRORATA_WITH_LARGEST_REMAINDER_DISTRIBUTION_ACROSS_FEE_COMPONENTS = "30_day_prorata_with_largest_remainder_distribution_across_fee_components"
Similar to THIRTY_DAY_PRORATA except rounding errors are avoided by using the largest remainder algorithm to distribute the last few cents across the component.
There is a risk of losing accuracy, for example attributing more to the membership fee than we should. But we have the guarantee the total of the components will never exceed the initial total and the inaccuracies should never exceed 1 cent.
components.premium.public.models ¶
premium_component ¶
PremiumComponentModel ¶
Bases: BaseModel
A model describing how to store global premium entries...
Each country is responsible for reimplementing their own model, inheriting from this one.
__table_args__
class-attribute
instance-attribute
¶
__table_args__ = (
UniqueConstraint(
"enrollment_id",
"premium_entry_id",
"coverage_type",
"beneficiary_type",
"debtor_type",
"period_start",
"period_end",
"contribution_type",
"version",
name="one_component_across_all_dimensions_per_version",
),
Index(
"ix_enrollment_id_version",
"enrollment_id",
"version",
),
Index(
"ix_period_start_end", "period_start", "period_end"
),
)
amount
class-attribute
instance-attribute
¶
Amount for num_days of coverage from period_start to period_end. Expressed in the minor unit of the currency.
amount_before_prorata
class-attribute
instance-attribute
¶
Amount for full coverage from period_start to period_end. Expressed in the minor unit of the currency. This is the amount that would be billed if we decided not to apply prorata.
beneficiary_type
class-attribute
instance-attribute
¶
cancelled_by_entry_id
class-attribute
instance-attribute
¶
cancelled_entry_id
class-attribute
instance-attribute
¶
collection_method
class-attribute
instance-attribute
¶
contribution_type
class-attribute
instance-attribute
¶
coverage_type
class-attribute
instance-attribute
¶
currency
class-attribute
instance-attribute
¶
ISO4217 compliant alpha code of the currency.
debtor_type
class-attribute
instance-attribute
¶
enrollment_id
class-attribute
instance-attribute
¶
invoice_id
class-attribute
instance-attribute
¶
num_days
class-attribute
instance-attribute
¶
Number of days this fee covers within the billing period.
payroll_csv_id
class-attribute
instance-attribute
¶
Belgium & Spain's local payroll systems requires to keep track of which premiums are included in which file.
In order to maintain compatibility between Belgium payroll and Global premiums we need to maintain this property. However it's not required by the Global payroll system, therefore this property is temporary and will be dropped as soon as global payroll is online.