Skip to content

Api reference

components.global_customer_dashboard.public.actions

employee

generate_employees_export

generate_employees_export(
    file_format,
    company_ids,
    operational_scope_ids,
    filters=None,
)

Generate employees export using global_customer_dashboard component.

Source code in components/global_customer_dashboard/public/actions/employee.py
def generate_employees_export(
    file_format: ExportExtension,
    company_ids: list[str],
    operational_scope_ids: list[uuid.UUID],
    filters: dict[str, str | list[str]] | None = None,
) -> GeneratedExportData:
    """Generate employees export using global_customer_dashboard component."""
    from components.global_customer_dashboard.external.queries.employee import (
        export_employees_list,
        get_export_employees_list_as_of,
    )
    from components.global_customer_dashboard.public.entities import (
        EmployeesExportFileFormat,
    )

    # Convert file format from async_exports to global_customer_dashboard format
    file_format_mapping = {
        "csv": EmployeesExportFileFormat.csv,
        "xlsx": EmployeesExportFileFormat.xlsx,
    }

    employees_file_format = file_format_mapping.get(
        file_format, EmployeesExportFileFormat.csv
    )

    # Get employees data generator
    employees_generator = get_export_employees_list_as_of(
        company_ids=company_ids,
        operational_scope_ids=set(operational_scope_ids),
        as_of=None,  # We need to get the base employee list directly
        filters=filters,
    )

    if employees_generator is None:
        raise ValueError("Unable to generate employees export data")

    # Get count efficiently using existing count queries
    items_count = get_employees_count_for_export(
        company_ids=company_ids,
        operational_scope_ids=set(operational_scope_ids),
        employees_generator=employees_generator,
        filters=filters,
    )

    # Generate the export file
    employees_export_file = export_employees_list(
        file_format=employees_file_format,
        employee_base_file_generator=employees_generator,
    )

    # Use the generator/binary content directly for background job
    file_content = employees_export_file.employees

    return GeneratedExportData(
        file_content=file_content,
        mimetype=employees_export_file.mimetype,
        items_count=items_count,
    )

components.global_customer_dashboard.public.blueprint

global_customer_dashboard_api_blueprint module-attribute

global_customer_dashboard_api_blueprint = CustomBlueprint(
    "global_customer_dashboard_api_blueprint", __name__
)

components.global_customer_dashboard.public.dependencies

GlOBAL_CUSTOMER_DASHBOARD_COMPONENT_NAME module-attribute

GlOBAL_CUSTOMER_DASHBOARD_COMPONENT_NAME = (
    "global_customer_dashboard"
)

GlobalCustomerDashboardDependency

GlobalCustomerDashboardDependency defines the interface that apps using the global_customer_dashboard component need to implement

get_alerts

get_alerts(
    *,
    customer_dashboard_page,
    context_account_id,
    account_id,
    company_ids,
    operational_scope_ids,
    language
)

:return: The method will return a list of alerts to display on the given customer dashboard page

Source code in components/global_customer_dashboard/public/dependencies.py
def get_alerts(
    self,
    *,
    customer_dashboard_page: str,
    context_account_id: UUID,
    account_id: UUID | None,
    company_ids: set[str],
    operational_scope_ids: set[UUID],
    language: Lang,
) -> list[CustomerDashboardAlert]:
    """
    :return: The method will return a list of alerts to display
    on the given customer dashboard page
    """
    raise NotImplementedError()

get_company_details

get_company_details(company_id)

Get details of a company by its ID. :param company_id: The ID of the company to retrieve details for. :return: A CustomerDashboardCompany object containing the details of the company.

Source code in components/global_customer_dashboard/public/dependencies.py
def get_company_details(self, company_id: str) -> CustomerDashboardCompany:
    """
    Get details of a company by its ID.
    :param company_id:  The ID of the company to retrieve details for.
    :return: A CustomerDashboardCompany object containing the details of the company.
    """
    raise NotImplementedError()

get_app_dependency

get_app_dependency()

Retrieves at runtime the account_org_tree dependency set by set_app_dependency

Source code in components/global_customer_dashboard/public/dependencies.py
def get_app_dependency() -> GlobalCustomerDashboardDependency:
    """Retrieves at runtime the account_org_tree dependency set by set_app_dependency"""
    from flask import current_app

    app = cast("CustomFlask", current_app)
    return cast(
        "GlobalCustomerDashboardDependency",
        app.get_component_dependency(GlOBAL_CUSTOMER_DASHBOARD_COMPONENT_NAME),
    )

set_app_dependency

set_app_dependency(dependency)

Sets the account_org_tree dependency to the app so it can be accessed within this component at runtime

Source code in components/global_customer_dashboard/public/dependencies.py
def set_app_dependency(dependency: GlobalCustomerDashboardDependency) -> None:
    """
    Sets the account_org_tree dependency to the app so it can be accessed within this component at runtime
    """
    from flask import current_app

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

components.global_customer_dashboard.public.entities

AdminDashboardEmployee dataclass

AdminDashboardEmployee(
    user_id,
    first_name,
    last_name,
    company_id,
    invite_email,
    employee_type,
    external_employee_id,
    status_detail,
)

Bases: DataClassJsonMixin

company_id instance-attribute

company_id

employee_type instance-attribute

employee_type

external_employee_id instance-attribute

external_employee_id

first_name instance-attribute

first_name

invite_email instance-attribute

invite_email

last_name instance-attribute

last_name

status_detail instance-attribute

status_detail

user_id instance-attribute

user_id

AdminsCountForAdminDashboard dataclass

AdminsCountForAdminDashboard(
    *, admins_count, pending_admin_invitations_count
)

Bases: DataClassJsonMixin

admins_count instance-attribute

admins_count

pending_admin_invitations_count instance-attribute

pending_admin_invitations_count

AdminsSearchResult dataclass

AdminsSearchResult(
    *,
    result_type,
    id,
    email,
    first_name,
    last_name,
    admined_entity_type,
    company_ids
)

Bases: DataClassJsonMixin

Results found for a search on the admins and admin invitations

admined_entity_type instance-attribute

admined_entity_type

company_ids instance-attribute

company_ids

email instance-attribute

email

first_name instance-attribute

first_name

id instance-attribute

id

last_name instance-attribute

last_name

result_type instance-attribute

result_type

AdminsSearchResultType

Bases: AlanBaseEnum

Type of the result returned in an AdminsSearchResult.

admin class-attribute instance-attribute

admin = 'admin'

invitation class-attribute instance-attribute

invitation = 'invitation'

AnyCountryCustomerInsightsDashboard module-attribute

AnyCountryCustomerInsightsDashboard = TypeVar(
    "AnyCountryCustomerInsightsDashboard"
)

CriticalRole dataclass

CriticalRole(responsibility, level)

A critical role is a role that is required to be assigned (at the defined entity level) to at least one admin

level instance-attribute

level

responsibility instance-attribute

responsibility

CustomerDashboardAccount dataclass

CustomerDashboardAccount(id, name)

Bases: DataClassJsonMixin

id instance-attribute

id

name instance-attribute

name

CustomerDashboardAdminInvitation dataclass

CustomerDashboardAdminInvitation(
    id,
    invite_email,
    invitation_date,
    responsibilities,
    type,
)

Bases: DataClassJsonMixin

id instance-attribute

id

invitation_date instance-attribute

invitation_date

invite_email instance-attribute

invite_email

responsibilities instance-attribute

responsibilities

type instance-attribute

type

CustomerDashboardAdminInvitationWithEntityIds dataclass

CustomerDashboardAdminInvitationWithEntityIds(
    id,
    invite_email,
    invitation_date,
    responsibilities,
    type,
    account_id,
    company_ids,
    scope_ids=None,
)

Bases: CustomerDashboardAdminInvitation

account_id instance-attribute

account_id

company_ids instance-attribute

company_ids

scope_ids class-attribute instance-attribute

scope_ids = None

CustomerDashboardAlert dataclass

CustomerDashboardAlert(
    topic,
    urgency,
    parameters,
    title,
    description,
    resolution_flow_label,
    entities,
)

Bases: DataClassJsonMixin

Alerts displayed in the admin dashboard pages and flagged in the menu via a small badge

description instance-attribute

description

entities instance-attribute

entities

parameters instance-attribute

parameters

resolution_flow_label instance-attribute

resolution_flow_label

title instance-attribute

title

topic instance-attribute

topic

urgency instance-attribute

urgency

CustomerDashboardCompanyAdminInvitationWithCompanies dataclass

CustomerDashboardCompanyAdminInvitationWithCompanies(
    id,
    invite_email,
    invitation_date,
    responsibilities,
    type,
    companies,
    scope_ids=None,
)

Bases: CustomerDashboardAdminInvitation

companies instance-attribute

companies

scope_ids class-attribute instance-attribute

scope_ids = None

CustomerDashboardEmployeeInvitation dataclass

CustomerDashboardEmployeeInvitation(
    id,
    invite_email,
    invitation_date,
    invitation_email_sent_at=None,
)

Bases: DataClassJsonMixin

Represents an employee invitation in the customer dashboard.

id instance-attribute

id

invitation_date instance-attribute

invitation_date

invitation_email_sent_at class-attribute instance-attribute

invitation_email_sent_at = None

invite_email instance-attribute

invite_email

CustomerDashboardEmployeeInvitationError dataclass

CustomerDashboardEmployeeInvitationError(
    invite_email, error_type
)

Bases: DataClassJsonMixin

Represents an error that occurred while inviting an employee in the customer dashboard.

error_type instance-attribute

error_type

invite_email instance-attribute

invite_email

CustomerDashboardEmployeeInvitationErrorType

Bases: AlanBaseEnum

Types of errors that can occur when inviting an employee in the customer dashboard. These errors are used to provide feedback to the user when an invitation fails. The error types are used to categorize the reasons for failure, such as: - already_exists: The employee already exists in the system. - employment_blocked_movement: The employee's movement is blocked within Employment's blocked movements. Will be reviewed internally, and re-submitted when underlying issue is resolved. - unknown_error: An unknown error occurred during the invitation process.

already_exists class-attribute instance-attribute

already_exists = 'already_exists'

employment_blocked_movement class-attribute instance-attribute

employment_blocked_movement = 'employment_blocked_movement'

unknown_error class-attribute instance-attribute

unknown_error = 'unknown_error'

CustomerDashboardEmployeesInvitationResponses dataclass

CustomerDashboardEmployeesInvitationResponses(
    invitations, errors
)

Bases: DataClassJsonMixin

Represents the responses to employee invitations in the customer dashboard.

errors instance-attribute

errors

invitations instance-attribute

invitations

CustomerInsightsDashboard dataclass

CustomerInsightsDashboard(
    insights, account_id=None, company_id=None
)

Bases: Generic[AnyCountryCustomerInsightsDashboard], DataClassJsonMixin

account_id class-attribute instance-attribute

account_id = None

company_id class-attribute instance-attribute

company_id = None

insights instance-attribute

insights

CustomerSubscription dataclass

CustomerSubscription(
    id, company_id, start_date, end_date, scope
)

Bases: DataClassJsonMixin

company_id instance-attribute

company_id

end_date instance-attribute

end_date

id instance-attribute

id

scope instance-attribute

scope

start_date instance-attribute

start_date

CustomerSubscriptionScope

Bases: AlanBaseEnum

es_insurance class-attribute instance-attribute

es_insurance = 'es_insurance'

healthy_benefits class-attribute instance-attribute

healthy_benefits = 'healthy_benefits'

DownloadFile dataclass

DownloadFile(file_name, file_to_download)

file_name instance-attribute

file_name

file_to_download instance-attribute

file_to_download

Employee dataclass

Employee(
    user_id,
    first_name,
    last_name,
    employment_id,
    company_id,
    invite_email,
    employee_type,
    external_employee_id,
)

Bases: DataClassJsonMixin

company_id instance-attribute

company_id

employee_type instance-attribute

employee_type

employment_id instance-attribute

employment_id

external_employee_id instance-attribute

external_employee_id

first_name instance-attribute

first_name

invite_email instance-attribute

invite_email

last_name instance-attribute

last_name

user_id instance-attribute

user_id

EmployeeCounts dataclass

EmployeeCounts(
    *,
    company,
    company_id_to_name,
    professional_category,
    ccn,
    ccn_id_to_name,
    employee_type,
    status_detail
)

Bases: DataClassJsonMixin

ccn instance-attribute

ccn

ccn_id_to_name instance-attribute

ccn_id_to_name

company instance-attribute

company

company_id_to_name instance-attribute

company_id_to_name

employee_type instance-attribute

employee_type

professional_category instance-attribute

professional_category

status_detail instance-attribute

status_detail

EmployeeDetails dataclass

EmployeeDetails(user_id, details)

Bases: Generic[_T], DataClassJsonMixin

details instance-attribute

details

user_id instance-attribute

user_id

EmployeeInvitationResult dataclass

EmployeeInvitationResult(
    id,
    email,
    success,
    employee=None,
    error=None,
    error_keys=None,
    meta=None,
)

Bases: DataClassJsonMixin, Generic[T]

email instance-attribute

email

employee class-attribute instance-attribute

employee = None

error class-attribute instance-attribute

error = None

error_keys class-attribute instance-attribute

error_keys = None

id instance-attribute

id

meta class-attribute instance-attribute

meta = None

success instance-attribute

success

EmployeeServiceEnrollment dataclass

EmployeeServiceEnrollment(
    id,
    user_id,
    company_id,
    subscription_id,
    service,
    start_date=isodate_field(),
    end_date=optional_isodate_field(),
)

Bases: DataClassJsonMixin

company_id instance-attribute

company_id

end_date class-attribute instance-attribute

end_date = optional_isodate_field()

id instance-attribute

id

service instance-attribute

service

start_date class-attribute instance-attribute

start_date = isodate_field()

subscription_id instance-attribute

subscription_id

user_id instance-attribute

user_id

EmployeeWithInactiveReimbursements dataclass

EmployeeWithInactiveReimbursements(
    user_id, first_name, last_name, company_id, invite_email
)

Bases: DataClassJsonMixin

company_id instance-attribute

company_id

first_name instance-attribute

first_name

invite_email instance-attribute

invite_email

last_name instance-attribute

last_name

user_id instance-attribute

user_id

EmployeesByCcnIdCount dataclass

EmployeesByCcnIdCount(total, by_ccn_id)

Bases: DataClassJsonMixin

by_ccn_id instance-attribute

by_ccn_id

total instance-attribute

total

EmployeesByCompanyIdCount dataclass

EmployeesByCompanyIdCount(total, by_company_id)

Bases: DataClassJsonMixin

by_company_id instance-attribute

by_company_id

total instance-attribute

total

EmployeesByProfessionalCategoryCount dataclass

EmployeesByProfessionalCategoryCount(
    total, by_professional_category
)

Bases: DataClassJsonMixin

by_professional_category instance-attribute

by_professional_category

total instance-attribute

total

EmployeesByStatusDetailCount dataclass

EmployeesByStatusDetailCount(total, by_status_detail)

Bases: DataClassJsonMixin

by_status_detail instance-attribute

by_status_detail

total instance-attribute

total

EmployeesByTypeCount dataclass

EmployeesByTypeCount(total, by_type)

Bases: DataClassJsonMixin

by_type instance-attribute

by_type

total instance-attribute

total

EmployeesExportFile dataclass

EmployeesExportFile(employees, mimetype)

File containing an export of the employees list

employees instance-attribute

employees

mimetype instance-attribute

mimetype

EmployeesExportFileFormat

Bases: AlanBaseEnum

Available formats for the employees list file export

csv class-attribute instance-attribute

csv = 'csv'

xlsx class-attribute instance-attribute

xlsx = 'xlsx'

ExemptedEmployeeListItem dataclass

ExemptedEmployeeListItem(
    user_id,
    first_name,
    last_name,
    company_id,
    invite_email,
    employee_type,
    external_employee_id,
    status_detail,
    *,
    end_date,
    guess_gender
)

Bases: AdminDashboardEmployee

end_date instance-attribute

end_date

guess_gender instance-attribute

guess_gender

InsuredEmployeeListItem dataclass

InsuredEmployeeListItem(
    user_id,
    first_name,
    last_name,
    company_id,
    invite_email,
    employee_type,
    external_employee_id,
    status_detail,
    *,
    guess_gender,
    has_inactive_reimbursements
)

Bases: AdminDashboardEmployee

guess_gender instance-attribute

guess_gender

has_inactive_reimbursements instance-attribute

has_inactive_reimbursements

InviteEmployeesListInvitationParams dataclass

InviteEmployeesListInvitationParams(
    invite_email, additional_params
)

Represents an invitation to be sent to an employee in the customer dashboard.

additional_params instance-attribute

additional_params

invite_email instance-attribute

invite_email

InvitedEmployeeListItem dataclass

InvitedEmployeeListItem(
    user_id,
    first_name,
    last_name,
    company_id,
    invite_email,
    employee_type,
    external_employee_id,
    status_detail,
    *,
    invite_ssn,
    invite_ntt
)

Bases: AdminDashboardEmployee

invite_ntt instance-attribute

invite_ntt

invite_ssn instance-attribute

invite_ssn

LastAdminStanding dataclass

LastAdminStanding(
    contract_manager,
    people_manager,
    payroll_manager,
    invoice_manager,
    wellbeing_referent,
)

Bases: DataClassJsonMixin

contract_manager instance-attribute

contract_manager

invoice_manager instance-attribute

invoice_manager

payroll_manager instance-attribute

payroll_manager

people_manager instance-attribute

people_manager

wellbeing_referent instance-attribute

wellbeing_referent

LeanEntitiesByResponsibility dataclass

LeanEntitiesByResponsibility(
    contract_manager,
    people_manager,
    payroll_manager,
    invoice_manager,
    wellbeing_referent,
)

Bases: DataClassJsonMixin

contract_manager instance-attribute

contract_manager

invoice_manager instance-attribute

invoice_manager

payroll_manager instance-attribute

payroll_manager

people_manager instance-attribute

people_manager

wellbeing_referent instance-attribute

wellbeing_referent

PaginatedCustomerDashboardAdminInvitation dataclass

PaginatedCustomerDashboardAdminInvitation(
    *, pending_invitations, meta
)

Bases: DataClassJsonMixin

meta instance-attribute

meta

pending_invitations instance-attribute

pending_invitations

PaginatedEmployeeWithInactiveReimbursements dataclass

PaginatedEmployeeWithInactiveReimbursements(
    employees, meta
)

Bases: DataClassJsonMixin

employees instance-attribute

employees

meta instance-attribute

meta

PaginatedEmployeesForAdminDashboard dataclass

PaginatedEmployeesForAdminDashboard(*, employees, meta)

Bases: DataClassJsonMixin

employees instance-attribute

employees

meta instance-attribute

meta

PaginatedList dataclass

PaginatedList(*, data, meta)

Bases: DataClassJsonMixin, Generic[T]

Generic paginated list.

Attributes:

Name Type Description
data T

The list of paginated items.

meta PageInfoMeta

The page information of the returned list

data instance-attribute

data

meta instance-attribute

meta

PaginatedTerminatedEmployeesForAdminDashboard dataclass

PaginatedTerminatedEmployeesForAdminDashboard(
    employees, meta
)

Bases: DataClassJsonMixin

employees instance-attribute

employees

meta instance-attribute

meta

PayfitAffiliationIntegrationCompanySummary dataclass

PayfitAffiliationIntegrationCompanySummary(
    company_id,
    company_display_name,
    payfit_partner_activated,
    payfit_partner_integration_failed,
    payfit_partner_activated_on,
    payfit_partner_activated_by_admin_first_name,
)

Bases: DataClassJsonMixin

company_display_name instance-attribute

company_display_name

company_id instance-attribute

company_id

payfit_partner_activated instance-attribute

payfit_partner_activated

payfit_partner_activated_by_admin_first_name instance-attribute

payfit_partner_activated_by_admin_first_name

payfit_partner_activated_on instance-attribute

payfit_partner_activated_on

payfit_partner_integration_failed instance-attribute

payfit_partner_integration_failed

PayfitAffiliationIntegrationSummary dataclass

PayfitAffiliationIntegrationSummary(
    payfit_partner_activated,
    payfit_partner_integration_failed,
    payfit_partner_activated_on,
    payfit_partner_activated_by_admin_first_name,
    entities_not_using_payfit_partner_suspicion,
    company_summaries,
)

Bases: DataClassJsonMixin

company_summaries instance-attribute

company_summaries

entities_not_using_payfit_partner_suspicion instance-attribute

entities_not_using_payfit_partner_suspicion

payfit_partner_activated instance-attribute

payfit_partner_activated

payfit_partner_activated_by_admin_first_name instance-attribute

payfit_partner_activated_by_admin_first_name

payfit_partner_activated_on instance-attribute

payfit_partner_activated_on

payfit_partner_integration_failed instance-attribute

payfit_partner_integration_failed

ScheduledEmployeeTransfer dataclass

ScheduledEmployeeTransfer(
    id,
    user_id,
    destination_company_id,
    current_company_id,
    status,
    transfer_date=isodate_field(),
    transferred_at=optional_isodate_field(),
)

Bases: DataClassJsonMixin

current_company_id instance-attribute

current_company_id

destination_company_id instance-attribute

destination_company_id

id instance-attribute

id

status instance-attribute

status

transfer_date class-attribute instance-attribute

transfer_date = isodate_field()

transferred_at class-attribute instance-attribute

transferred_at = optional_isodate_field()

user_id instance-attribute

user_id

ScheduledEmployeeTransferStatus

Bases: AlanBaseEnum

done class-attribute instance-attribute

done = 'done'

error class-attribute instance-attribute

error = 'error'

in_progress class-attribute instance-attribute

in_progress = 'in_progress'

pending class-attribute instance-attribute

pending = 'pending'

SignedDocument dataclass

SignedDocument(
    id, document_type, subscription_id, signed_at, lang=None
)

Bases: DataClassJsonMixin

document_type instance-attribute

document_type

id instance-attribute

id

lang class-attribute instance-attribute

lang = None

signed_at instance-attribute

signed_at

subscription_id instance-attribute

subscription_id

SignedDocumentType

Bases: AlanBaseEnum

es_fresa_general_conditions class-attribute instance-attribute

es_fresa_general_conditions = 'es_fresa_general_conditions'

es_fresa_information_notice class-attribute instance-attribute

es_fresa_information_notice = 'es_fresa_information_notice'

es_fresa_particular_conditions class-attribute instance-attribute

es_fresa_particular_conditions = (
    "es_fresa_particular_conditions"
)

es_manzana_general_conditions class-attribute instance-attribute

es_manzana_general_conditions = (
    "es_manzana_general_conditions"
)

es_manzana_information_notice class-attribute instance-attribute

es_manzana_information_notice = (
    "es_manzana_information_notice"
)

es_manzana_particular_conditions class-attribute instance-attribute

es_manzana_particular_conditions = (
    "es_manzana_particular_conditions"
)

healthy_benefits_general_conditions class-attribute instance-attribute

healthy_benefits_general_conditions = (
    "healthy_benefits_general_conditions"
)

healthy_benefits_particular_conditions class-attribute instance-attribute

healthy_benefits_particular_conditions = (
    "healthy_benefits_particular_conditions"
)

sepa_mandate class-attribute instance-attribute

sepa_mandate = 'sepa_mandate'

T module-attribute

T = TypeVar('T')

TerminatedEmployee dataclass

TerminatedEmployee(
    user_id,
    first_name,
    last_name,
    company_id,
    invite_email,
    terminated_employee_type,
)

Bases: DataClassJsonMixin

company_id instance-attribute

company_id

first_name instance-attribute

first_name

invite_email instance-attribute

invite_email

last_name instance-attribute

last_name

terminated_employee_type instance-attribute

terminated_employee_type

user_id instance-attribute

user_id

TerminatedEmployeeDetails dataclass

TerminatedEmployeeDetails(
    user_id,
    full_name,
    company_id,
    invite_email,
    terminated_employee_type,
    external_employee_id,
    start_date,
    end_date,
    termination_type,
    ani_start_date,
    theoretical_ani_end_date,
    employment_contract_end_date,
)

Bases: DataClassJsonMixin

ani_start_date instance-attribute

ani_start_date

company_id instance-attribute

company_id

employment_contract_end_date instance-attribute

employment_contract_end_date

end_date instance-attribute

end_date

external_employee_id instance-attribute

external_employee_id

full_name instance-attribute

full_name

invite_email instance-attribute

invite_email

start_date instance-attribute

start_date

terminated_employee_type instance-attribute

terminated_employee_type

termination_type instance-attribute

termination_type

theoretical_ani_end_date instance-attribute

theoretical_ani_end_date

user_id instance-attribute

user_id

TerminatedEmployeesByTypeCounts dataclass

TerminatedEmployeesByTypeCounts(total, by_type)

Bases: DataClassJsonMixin

by_type instance-attribute

by_type

total instance-attribute

total

UnpaidLeaveEmployeeListItem dataclass

UnpaidLeaveEmployeeListItem(
    user_id,
    first_name,
    last_name,
    company_id,
    invite_email,
    employee_type,
    external_employee_id,
    status_detail,
    *,
    guess_gender
)

Bases: AdminDashboardEmployee

guess_gender instance-attribute

guess_gender

WellbeingAssessmentDisplayUserInfo dataclass

WellbeingAssessmentDisplayUserInfo(
    id,
    normalized_full_name,
    full_name,
    name,
    email,
    pro_email,
)

Bases: DataClassJsonMixin

email instance-attribute

email

full_name instance-attribute

full_name

id instance-attribute

id

name instance-attribute

name

normalized_full_name instance-attribute

normalized_full_name

pro_email instance-attribute

pro_email

critical_roles module-attribute

critical_roles = [
    CriticalRole(
        responsibility=contract_manager, level=account
    )
]

file_format_to_mime_type module-attribute

file_format_to_mime_type = {
    csv: "text/csv",
    xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
}

components.global_customer_dashboard.public.enums

ACTIVE_EMPLOYEE_TYPES module-attribute

ACTIVE_EMPLOYEE_TYPES = (
    set(EmployeeType) - FORMER_EMPLOYEE_TYPES
)

CustomerDashboardAlertsUrgency

Bases: AlanBaseEnum

Impacts how the alerts are displayed in the admin dashboard. Error and warning error are flagged in the admin dashboard menu too.

error class-attribute instance-attribute

error = 'error'

routine_task class-attribute instance-attribute

routine_task = 'routine_task'

warning class-attribute instance-attribute

warning = 'warning'

CustomerDashboardCompanyAdminInvitationsSortField

Bases: AlanBaseEnum

created_at class-attribute instance-attribute

created_at = 'created_at'

invitation_email class-attribute instance-attribute

invitation_email = 'invitation_email'

invite_email class-attribute instance-attribute

invite_email = 'invite_email'

EmployeeType

Bases: AlanBaseEnum

Please make sure that each employee type corresponds to a disjoint subset of employees. Example: insured won't include fr_ani

fr_ani class-attribute instance-attribute

fr_ani = 'fr_ani'

fr_ex_employee_in_ani class-attribute instance-attribute

fr_ex_employee_in_ani = 'fr_ex_employee_in_ani'

fr_ex_employee_invited_as_ani class-attribute instance-attribute

fr_ex_employee_invited_as_ani = (
    "fr_ex_employee_invited_as_ani"
)

fr_exempted class-attribute instance-attribute

fr_exempted = 'fr_exempted'

fr_invited class-attribute instance-attribute

fr_invited = 'fr_invited'

insured class-attribute instance-attribute

insured = 'insured'

unpaid_leave class-attribute instance-attribute

unpaid_leave = 'unpaid_leave'

FORMER_EMPLOYEE_TYPES module-attribute

FORMER_EMPLOYEE_TYPES = {
    fr_ani,
    fr_ex_employee_in_ani,
    fr_ex_employee_invited_as_ani,
}

ProfessionalCategory

Bases: AlanBaseEnum

This enum is used to model both the professional category of persons and abstract objects, such as contracts: - persons can be "cadres", "non_cadres", or NULL which models we don't know their professional category; - abstract entities can be "cadres", "non_cadres", or NULL which models we don't have to apply any constraint on the object regarding the professional category.

cadres class-attribute instance-attribute

cadres = 'cadres'

non_cadres class-attribute instance-attribute

non_cadres = 'non_cadres'

StatusDetail

Bases: AlanBaseEnum

Will be used to display more information about the status of an employee.

already_covered_by_alan class-attribute instance-attribute

already_covered_by_alan = 'already_covered_by_alan'

already_covered_by_alan_under_review class-attribute instance-attribute

already_covered_by_alan_under_review = (
    "already_covered_by_alan_under_review"
)

exemption_rejected class-attribute instance-attribute

exemption_rejected = 'exemption_rejected'

exemption_requested class-attribute instance-attribute

exemption_requested = 'exemption_requested'

exemption_started class-attribute instance-attribute

exemption_started = 'exemption_started'

fr_ani_default class-attribute instance-attribute

fr_ani_default = 'fr_ani_default'

fr_exempted_default class-attribute instance-attribute

fr_exempted_default = 'fr_exempted_default'

fr_invited_default class-attribute instance-attribute

fr_invited_default = 'fr_invited_default'

insured_default class-attribute instance-attribute

insured_default = 'insured_default'

no_email class-attribute instance-attribute

no_email = 'no_email'

not_reimbursed class-attribute instance-attribute

not_reimbursed = 'not_reimbursed'

unpaid_leave_default class-attribute instance-attribute

unpaid_leave_default = 'unpaid_leave_default'

wrong_email class-attribute instance-attribute

wrong_email = 'wrong_email'

TerminatedEmployeeType

Bases: AlanBaseEnum

Please make sure that each employee type corresponds to a disjoint subset of employees.

fr_ani class-attribute instance-attribute

fr_ani = 'fr_ani'

fr_ex_employee_in_ani class-attribute instance-attribute

fr_ex_employee_in_ani = 'fr_ex_employee_in_ani'

fr_ex_employee_invited_as_ani class-attribute instance-attribute

fr_ex_employee_invited_as_ani = (
    "fr_ex_employee_invited_as_ani"
)

terminated class-attribute instance-attribute

terminated = 'terminated'

components.global_customer_dashboard.public.helpers

admined_entities_api_helper

AdminedEntitiesFiltersParams

Bases: TypedDict

Useful to type your endpoint params if you don't have any other parameter.

company_ids instance-attribute
company_ids
context_account_id instance-attribute
context_account_id
operational_scope_ids instance-attribute
operational_scope_ids

T module-attribute

T = TypeVar('T', bound=Mapping[str, Any])

admined_entities_filters_request_arguments

admined_entities_filters_request_arguments(
    transition_mode=False,
)

Helper to easily add the request arguments for the customer dashboard default entity filtering. This should be used in tandem with auth_check_and_preprocess_admined_entities_params to make some API level conventions transparent for the caller.

@:param transition_mode Set it to True when backward compatibility is needed, for example, when updating an existing API endpoint code.

Source code in components/global_customer_dashboard/public/helpers/admined_entities_api_helper.py
def admined_entities_filters_request_arguments(
    transition_mode: bool = False,
) -> list[Callable[[Callable[..., Any]], Callable[..., Any]]]:
    """
    Helper to easily add the request arguments for the customer dashboard default entity filtering.
    This should be used in tandem with auth_check_and_preprocess_admined_entities_params
    to make some API level conventions transparent for the caller.

    @:param transition_mode
    Set it to True when backward compatibility is needed,
    for example, when updating an existing API endpoint code.
    """
    return [
        request_argument(
            "context_account_id",
            type=UUID,
            location="args",
            required=not transition_mode,
            owner_controller=NoOwner,
        ),
        request_argument(
            "company_ids",
            type=str,
            action="split",  # using split over append to have shorter URLs and avoid hitting size limits.
            location="args",
            required=False,
        ),
        request_argument(
            "operational_scope_ids",
            type=str,
            action="split",  # using split over append to have shorter URLs and avoid hitting size limits.
            location="args",
            required=False,
        ),
    ]

auth_check_and_preprocess_admined_entities_params

auth_check_and_preprocess_admined_entities_params(
    params, transition_mode=False
)

Pre-process the request arguments defined by the function admined_entities_filters_request_arguments. This helper aims at enforcing and automating away some API convention.

Warning: if you type the input params, you must type it as the result of the transformation by this helper. You need to add:

context_account_id: str
company_ids: set[str]
operational_scope_ids: set[UUID]

company_ids is typed as set[str] as a compromise between FR where ids are int and other apps rely on UUID

@param transition_mode: set to True if backward compatibility is needed. Advice is to not use this and create a new API endpoint instead for simplicity. Typical migration path proposed: - use the 2 functions defined in this file to an existing API endpoint code with the flag transition_mode set to True - update the frontend code to send entities filters using the new shared system - remove the transition_mode flag to disable the transition mode.

More details in this doc: https://www.notion.so/alaninsurance/New-entities-filter-how-to-step-by-step-guide-1c81426e8be780ffba28d81f54236302?d=1ca1426e8be780418682001cb5632d81#1c81426e8be7808abb4bd991d0df273c ⧉

Source code in components/global_customer_dashboard/public/helpers/admined_entities_api_helper.py
def auth_check_and_preprocess_admined_entities_params(
    params: T, transition_mode: bool = False
) -> T:
    """
    Pre-process the request arguments defined by the function `admined_entities_filters_request_arguments`.
    This helper aims at enforcing and automating away some API convention.

    Warning: if you type the input params, you must type it as the result of the transformation by this helper.
    You need to add:
    ```
    context_account_id: str
    company_ids: set[str]
    operational_scope_ids: set[UUID]
    ```

    `company_ids` is typed as `set[str]` as a compromise between FR where ids are `int` and other apps rely on `UUID`

    @param transition_mode: set to True if backward compatibility is needed.
    Advice is to not use this and create a new API endpoint instead for simplicity.
    Typical migration path proposed:
     - use the 2 functions defined in this file to an existing API endpoint code with the flag transition_mode set to True
     - update the frontend code to send entities filters using the new shared system
     - remove the `transition_mode` flag to disable the transition mode.

    More details in this doc: https://www.notion.so/alaninsurance/New-entities-filter-how-to-step-by-step-guide-1c81426e8be780ffba28d81f54236302?d=1ca1426e8be780418682001cb5632d81#1c81426e8be7808abb4bd991d0df273c
    """
    from components.customer_admin.public.dependencies import (
        get_app_dependency as get_customer_admin_dependency,
    )
    from components.customer_admin.public.queries import (
        user_can_admin_entities,
    )

    context_account_id: UUID | None = params.get("context_account_id")
    account_id: UUID | None = params.get("account_id")
    company_ids = params.get("company_ids")
    company_ids = (
        company_ids.split(",")
        if (company_ids and type(company_ids) is str)
        else company_ids
    )
    params["company_ids"] = set(company_ids) if company_ids else set()  # type: ignore[index]

    operational_scope_ids = params.get("operational_scope_ids")
    operational_scope_ids = (
        operational_scope_ids.split(",")
        if (operational_scope_ids and type(operational_scope_ids) is str)
        else operational_scope_ids
    )

    if context_account_id is None:
        if transition_mode:
            if not user_can_admin_entities(
                g.current_user.id,
                account_ids={str(account_id)} if account_id else set(),
                company_ids=set(company_ids) if company_ids else set(),
                scope_ids=set(operational_scope_ids)
                if operational_scope_ids
                else set(),
            ):
                raise BaseErrorCode.forbidden()
            return params
        else:
            raise BaseErrorCode.invalid_arguments(
                message="context_account_id param is required"
            )

    admined_entities_trees = (
        get_customer_admin_dependency()
        .get_admined_entities_api()
        .get_admin_account_trees(
            user_id=g.current_user.id, account_id=context_account_id
        )
    )
    is_account_admin = any(
        tree.find_first(
            match=lambda node: node.data.id == str(context_account_id)
            and node.data.type == EntityType.account
        )
        for tree in admined_entities_trees
    )

    should_use_default_values = company_ids is None and operational_scope_ids is None

    if company_ids is not None:
        company_ids = set(company_ids)
    elif should_use_default_values:
        pending_onboardings = get_pending_onboardings_for_admined_entity_selector(
            user_id=str(g.current_user.id)
        )

        company_ids = (
            {
                node.data.id
                for node in one(
                    one(admined_entities_trees).system_root.children
                ).children
            }
            if is_account_admin
            else {
                one(tree.system_root.children).data.id
                for tree in admined_entities_trees
                if one(tree.system_root.children).data.type == EntityType.company
            }
        ) - {
            str(pending_onboarding.company_id)
            for pending_onboarding in pending_onboardings
        }
    else:
        company_ids = set()

    if operational_scope_ids is not None:
        operational_scope_ids = set(operational_scope_ids)
    elif should_use_default_values:
        operational_scope_ids = (
            set()
            if is_account_admin
            else {
                one(tree.system_root.children).data.id
                for tree in admined_entities_trees
                if one(tree.system_root.children).data.type
                == EntityType.operational_scope
            }
        )
    else:
        operational_scope_ids = set()

    if not user_can_admin_entities(
        g.current_user.id,
        account_ids={str(context_account_id)} if is_account_admin else set(),
        company_ids=company_ids,
        scope_ids=operational_scope_ids,
    ):
        raise BaseErrorCode.forbidden()

    # The 2 type ignore below are a compromise.
    # TypedDict is a subtype of subtype but not of dict,
    # see https://mypy.readthedocs.io/en/stable/typed_dict.html#typeddict.
    # Using Mapping is the best solution found so far to type this function.
    params["account_id"] = context_account_id if is_account_admin else None  # type: ignore[index]
    params["company_ids"] = company_ids  # type: ignore[index]
    params["operational_scope_ids"] = {  # type: ignore[index]
        UUID(scope_id) for scope_id in operational_scope_ids
    }

    return params

backoffice_preprocess_admined_entities_params

backoffice_preprocess_admined_entities_params(params)

Very similar to auth_check_and_preprocess_admined_entities_params but: - doesn't check if the user can admin entities, it's an Alaner admin. - doesn't filter out pending companies. In the backoffice we want all admins. - doesn't expect any entity filtering, just the context_account_id.


Pre-process the request arguments defined by the function admined_entities_filters_request_arguments. This helper aims at enforcing and automating away some API convention.

Warning: if you type the input params, you must type it as the result of the transformation by this helper. You need to add:

context_account_id: str
company_ids: set[str]
operational_scope_ids: set[UUID]

company_ids is typed as set[str] as a compromise between FR where ids are int and other apps rely on UUID

Source code in components/global_customer_dashboard/public/helpers/admined_entities_api_helper.py
def backoffice_preprocess_admined_entities_params(params: T) -> T:
    """
    Very similar to `auth_check_and_preprocess_admined_entities_params` but:
    - doesn't check if the user can admin entities, it's an Alaner admin.
    - doesn't filter out pending companies. In the backoffice we want all admins.
    - doesn't expect any entity filtering, just the context_account_id.

    __________________________________________________________________________________________

    Pre-process the request arguments defined by the function `admined_entities_filters_request_arguments`.
    This helper aims at enforcing and automating away some API convention.

    Warning: if you type the input params, you must type it as the result of the transformation by this helper.
    You need to add:
    ```
    context_account_id: str
    company_ids: set[str]
    operational_scope_ids: set[UUID]
    ```

    `company_ids` is typed as `set[str]` as a compromise between FR where ids are `int` and other apps rely on `UUID`

    """
    from components.customer_admin.public.dependencies import (
        get_app_dependency as get_customer_admin_dependency,
    )

    context_account_id: UUID = mandatory_type(UUID, params.get("context_account_id"))

    account_org_tree = (
        get_customer_admin_dependency()
        .get_account_org_tree_query_api()
        .get_account_org_tree(context_account_id)
    )

    company_ids = {
        node.data.id for node in one(account_org_tree.system_root.children).children
    }

    # The 2 type ignore below are a compromise.
    # TypedDict is a subtype of subtype but not of dict,
    # see https://mypy.readthedocs.io/en/stable/typed_dict.html#typeddict.
    # Using Mapping is the best solution found so far to type this function.
    params["account_id"] = context_account_id  # type: ignore[index]
    params["company_ids"] = company_ids  # type: ignore[index]
    params["operational_scope_ids"] = set()  # type: ignore[index]

    return params

user_is_not_only_operational_scope_admin

user_is_not_only_operational_scope_admin(
    user_id, context_account_id
)

:param user_id: typed as str to hide differences between countries (FR use int, others UUID) :param context_account_id: :return: true if the current user is only operational scope admin in the context account This is useful to block some API endpoint for operational scope admins, on top the existing data filtering logic that is baked in different place.

Source code in components/global_customer_dashboard/public/helpers/admined_entities_api_helper.py
def user_is_not_only_operational_scope_admin(
    user_id: str, context_account_id: UUID
) -> bool:
    """
    :param user_id: typed as str to hide differences between countries (FR use int, others UUID)
    :param context_account_id:
    :return: true if the current user is only operational scope admin in the context account
    This is useful to block some API endpoint for operational scope admins,
    on top the existing data filtering logic that is baked in different place.
    """
    from components.customer_admin.public.dependencies import (
        get_app_dependency as get_customer_admin_dependency,
    )

    admined_entities_trees = (
        get_customer_admin_dependency()
        .get_admined_entities_api()
        .get_admin_account_trees(user_id=user_id, account_id=context_account_id)
    )
    is_not_only_operational_scope_admin = any(
        tree.find_first(
            match=lambda node: node.data.type != EntityType.operational_scope
        )
        for tree in admined_entities_trees
    )

    return is_not_only_operational_scope_admin

filter_parser

parse_employee_export_filters

parse_employee_export_filters(
    filters, default_employee_types=None
)

Parse employee export filter parameters into typed filter objects. @param: filters: Raw filter parameters from HTTP requests (strings only) @param: default_employee_types: Default employee types to use if not specified in filters. If None, no default is applied Returns: Dictionary containing parsed filter objects: - filter_employee_types: set[EmployeeType] | None - filter_professional_categories: set[ProfessionalCategory | None] | None - filter_ccn_ids: set[int | None] | None - filter_status_details: set[StatusDetail] | None

Source code in components/global_customer_dashboard/public/helpers/filter_parser.py
def parse_employee_export_filters(
    filters: dict[str, str | list[str]] | None,
    default_employee_types: set[EmployeeType] | None = None,
) -> dict[str, Any]:
    """
    Parse employee export filter parameters into typed filter objects.
    @param: filters: Raw filter parameters from HTTP requests (strings only)
    @param: default_employee_types: Default employee types to use if not specified in filters. If None, no default is applied
    Returns:
        Dictionary containing parsed filter objects:
        - filter_employee_types: set[EmployeeType] | None
        - filter_professional_categories: set[ProfessionalCategory | None] | None
        - filter_ccn_ids: set[int | None] | None
        - filter_status_details: set[StatusDetail] | None
    """
    # Initialize with defaults
    filter_employee_types = default_employee_types
    filter_professional_categories = None
    filter_ccn_ids = None
    filter_status_details = None

    if not filters:
        return {
            "filter_employee_types": filter_employee_types,
            "filter_professional_categories": filter_professional_categories,
            "filter_ccn_ids": filter_ccn_ids,
            "filter_status_details": filter_status_details,
        }

    # Parse employee_types filter (comma-separated string)
    if "employee_types" in filters:
        employee_types_raw = filters["employee_types"]
        employee_types = (
            str(employee_types_raw).split(",")
            if isinstance(employee_types_raw, str)
            else employee_types_raw
        )
        filter_employee_types = {
            EmployeeType[et.strip()] for et in employee_types if et.strip()
        }
    # Parse professional_categories filter (comma-separated string)
    if "professional_categories" in filters:
        professional_categories_raw = filters["professional_categories"]
        professional_categories = (
            str(professional_categories_raw).split(",")
            if isinstance(professional_categories_raw, str)
            else professional_categories_raw
        )
        filter_professional_categories = {
            ProfessionalCategory[pc.strip()] if pc.strip() != "none" else None
            for pc in professional_categories
            if pc.strip()
        }

    # Parse ccn_ids filter (comma-separated string)
    if "ccn_ids" in filters:
        ccn_ids_raw = filters["ccn_ids"]
        ccn_ids = (
            str(ccn_ids_raw).split(",") if isinstance(ccn_ids_raw, str) else ccn_ids_raw
        )
        filter_ccn_ids = {
            int(ccn_id.strip()) if ccn_id.strip() != "none" else None
            for ccn_id in ccn_ids
            if ccn_id.strip()
        }

    # Parse status_details filter (comma-separated string)
    if "status_details" in filters:
        status_details_raw = filters["status_details"]
        status_details = (
            str(status_details_raw).split(",")
            if isinstance(status_details_raw, str)
            else status_details_raw
        )
        filter_status_details = {
            StatusDetail[sd.strip()] for sd in status_details if sd.strip()
        }

    return {
        "filter_employee_types": filter_employee_types,
        "filter_professional_categories": filter_professional_categories,
        "filter_ccn_ids": filter_ccn_ids,
        "filter_status_details": filter_status_details,
    }

parse_employee_export_filters_with_defaults

parse_employee_export_filters_with_defaults(filters)

Parse employee export filters with ACTIVE_EMPLOYEE_TYPES as default.

This is the standard behavior for both employee count and export queries to ensure consistency between the reported count and actual export data.

Source code in components/global_customer_dashboard/public/helpers/filter_parser.py
def parse_employee_export_filters_with_defaults(
    filters: dict[str, str | list[str]] | None,
) -> dict[str, Any]:
    """
    Parse employee export filters with ACTIVE_EMPLOYEE_TYPES as default.

    This is the standard behavior for both employee count and export queries
    to ensure consistency between the reported count and actual export data.
    """
    return parse_employee_export_filters(
        filters, default_employee_types=ACTIVE_EMPLOYEE_TYPES
    )

components.global_customer_dashboard.public.queries

admin

user_can_admin_admined_entities

user_can_admin_admined_entities(user_id, admined_entities)
Source code in components/customer_admin/public/queries.py
def user_can_admin_admined_entities(  # noqa: D103
    user_id: int | UUID, admined_entities: Iterable[AdminedEntity]
) -> bool:
    account_ids = set()
    company_ids = set()
    operational_scope_ids = set()

    # TODO: Better handle the operational scopes by:
    #  - dealing differently with company_for_operational_scope (checking user can admin at least one scope?)
    for admin_entity in admined_entities:
        match admin_entity.type:
            case AdminedEntityType.account:
                account_ids.add(admin_entity.id)
            case (
                AdminedEntityType.single_company
                | AdminedEntityType.company_for_operational_scope
            ):
                company_ids.add(admin_entity.id)
            case AdminedEntityType.operational_scope:
                operational_scope_ids.add(admin_entity.id)

    return user_can_admin_entities(
        user_id=user_id,
        company_ids=company_ids,
        account_ids=account_ids,
        scope_ids=operational_scope_ids,
    )

user_can_admin_entities_ignore_operational_scopes

user_can_admin_entities_ignore_operational_scopes(
    user_id, company_ids, account_ids
)

⚠️ This function relies on local logic, and doesn't handle operational scopes It should only be used in places where we didn't update for operational scopes yet :param user_id: The id of the admin user :param company_ids: Ids of companies to check :param account_ids: Ids of accounts to check :return: Return true if the given user is a direct or indirect admin of all the given entities

Source code in components/customer_admin/public/queries.py
@deprecated(
    "This sees Operational Scope admins like Company admins. Use user_can_admin_entities instead",
    category=AlanDeprecationWarning,
)
def user_can_admin_entities_ignore_operational_scopes(
    user_id: int | UUID, company_ids: set[str], account_ids: set[str]
) -> bool:
    """
    ⚠️ This function relies on local logic, and doesn't handle operational scopes
    It should only be used in places where we didn't update for operational scopes yet
    :param user_id: The id of the admin user
    :param company_ids: Ids of companies to check
    :param account_ids: Ids of accounts to check
    :return: Return true if the given user is a direct or indirect admin of all the given entities
    """
    app_name = get_current_app_name()
    match app_name:
        case AppName.ALAN_FR:
            from components.fr.internal.business_logic.global_customer_dashboard.admin import (  # noqa: ALN043, ALN039
                user_can_admin_entities as user_can_admin_entities_fr,
            )

            if not isinstance(user_id, int):
                raise TypeError("user_id has to be an int in FR")
            return user_can_admin_entities_fr(
                user_id=user_id,
                company_ids={int(id) for id in company_ids},
                account_ids={UUID(id) for id in account_ids},
            )
        case AppName.ALAN_BE:
            from components.be.public.global_customer_dashboard.admin import (
                user_can_admin_entities as user_can_admin_entities_be,
            )

            if not isinstance(user_id, UUID):
                raise TypeError("user_id has to be a UUID in BE")
            return user_can_admin_entities_be(
                user_id=user_id,
                company_ids={UUID(id) for id in company_ids},
                account_ids={UUID(id) for id in account_ids},
            )
        case AppName.ALAN_ES:
            from components.es.public.global_customer_dashboard.admin import (
                user_can_admin_entities as user_can_admin_entities_es,
            )

            if not isinstance(user_id, UUID):
                raise TypeError("user_id has to be a UUID in ES")
            return user_can_admin_entities_es(
                user_id=user_id,
                company_ids={UUID(id) for id in company_ids},
                account_ids={UUID(id) for id in account_ids},
            )
        case _:
            raise NotImplementedError(
                f"can't find user_can_admin_entities for app {current_app}"
            )

user_can_read_entities

user_can_read_entities(user_id, admined_entities)
Source code in components/global_customer_dashboard/external/queries/user.py
def user_can_read_entities(user_id: int, admined_entities: list[AdminedEntity]) -> bool:
    user_admined_entities = get_admined_entities_api().get_admined_entities_for_user(
        str(user_id)
    )

    return set(user_admined_entities) & set(admined_entities) != set()

admined_entities

get_admined_entities_for_entity_selector

get_admined_entities_for_entity_selector(user_id)
Source code in components/global_customer_dashboard/external/queries/admined_entities.py
def get_admined_entities_for_entity_selector(
    user_id: str,
) -> list["AdminedEntityForEntitySelector"]:
    app_name = get_current_app_name()
    match app_name:
        case AppName.ALAN_FR:
            from components.fr.public.global_customer_dashboard.admin import (  # noqa: ALN043
                get_admined_entities_for_entity_selector_fr,
            )

            admined_entities = get_admined_entities_for_entity_selector_fr(
                user_id=user_id
            )
        case AppName.ALAN_BE:
            from components.be.public.global_customer_dashboard.admin import (
                get_admined_entities_for_entity_selctor_be,
            )

            admined_entities = get_admined_entities_for_entity_selctor_be(
                user_id=user_id
            )
        case AppName.ALAN_ES:
            from components.es.public.global_customer_dashboard.admin import (
                get_admined_entities_for_entity_selector_es,
            )

            admined_entities = get_admined_entities_for_entity_selector_es(
                user_id=user_id
            )
        case _:
            raise NotImplementedError(
                f"can't find get_admined_entities_api for app {current_app}"
            )

    pending_onboarding_company_ids = {
        po.company_id
        for po in get_pending_onboardings_for_admined_entity_selector(user_id)
    }

    return [
        admined_entity
        for admined_entity in admined_entities
        # Only keep entities which are or have at least one onboarded company
        if any(
            company_id not in pending_onboarding_company_ids
            for company_id in admined_entity.companies_ids
        )
    ]

employee

get_employees_count_for_export

get_employees_count_for_export(
    company_ids,
    operational_scope_ids,
    employees_generator,
    filters=None,
)

Get the count of employees for export efficiently.

Uses existing count queries when possible to avoid materializing the entire dataset in memory.

Parameters:

Name Type Description Default
company_ids list[str]

List of company IDs to count employees for

required
operational_scope_ids set[UUID] | None

Optional operational scope filtering

required
employees_generator Any

Fallback generator if efficient count isn't available

required
filters dict[str, str | list[str]] | None

Additional filters to apply (status_details, professional_categories, ccn_ids, employee_types)

None

Returns:

Type Description
int

Total count of employees matching the criteria

Source code in components/global_customer_dashboard/public/queries/employee.py
def get_employees_count_for_export(
    company_ids: list[str],
    operational_scope_ids: set[uuid.UUID] | None,
    employees_generator: Any,
    filters: dict[str, str | list[str]] | None = None,
) -> int:
    """
    Get the count of employees for export efficiently.

    Uses existing count queries when possible to avoid materializing
    the entire dataset in memory.

    Params:
        company_ids: List of company IDs to count employees for
        operational_scope_ids: Optional operational scope filtering
        employees_generator: Fallback generator if efficient count isn't available
        filters: Additional filters to apply (status_details, professional_categories, ccn_ids, employee_types)

    Returns:
        Total count of employees matching the criteria
    """
    from components.global_customer_dashboard.external.queries.employee import (
        get_employee_counts,
    )
    from components.global_customer_dashboard.public.helpers.filter_parser import (
        parse_employee_export_filters_with_defaults,
    )

    try:
        # Parse filters using shared helper with ACTIVE_EMPLOYEE_TYPES default
        parsed_filters = parse_employee_export_filters_with_defaults(filters)
        filter_employee_types = parsed_filters["filter_employee_types"]
        filter_professional_categories = parsed_filters[
            "filter_professional_categories"
        ]
        filter_ccn_ids = parsed_filters["filter_ccn_ids"]
        filter_status_details = parsed_filters["filter_status_details"]

        # Try to use the efficient count query with the same filters as the export
        employee_counts = get_employee_counts(
            company_ids=company_ids,
            operational_scope_ids=operational_scope_ids,
            employee_types_set=filter_employee_types,
            professional_categories_set=filter_professional_categories,
            ccn_ids=filter_ccn_ids,
            status_details=filter_status_details,
        )
        # Extract the total count from the structured response
        return employee_counts.employee_type.total

    except (NotImplementedError, Exception):
        # Fallback to materializing the generator if count query fails
        employees_list = list(employees_generator)
        return len(employees_list)