Api reference
components.occupational_health.public.actions ¶
account ¶
move_occupational_health_account_models_from_source_to_target_account ¶
move_occupational_health_account_models_from_source_to_target_account(
source_account_id, target_account_id
)
Function to move all occupational health models linked to an account from a source account to a target account in case of an account being deleted/merged
Source code in components/occupational_health/public/actions/account.py
billing ¶
Public actions for occupational health billing invoice emails.
send_billing_invoices_email ¶
Send billing invoice emails to all HR contacts of an account.
Source code in components/occupational_health/public/actions/billing.py
billing_entity ¶
Public actions for managing occupational health billed entities.
create_billed_entity ¶
create_billed_entity(
entity_name,
siren,
postal_street,
postal_code,
postal_city,
postal_country_code,
account_id,
subscription_ref,
emails_to_notify,
siret=None,
has_installment_plan_per_year=None,
save=True,
)
Create a new billed entity for occupational health billing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entity_name
|
str
|
Legal name of the entity |
required |
siren
|
str
|
French company identifier (9 digits) |
required |
postal_street
|
str
|
Street address |
required |
postal_code
|
str
|
Postal code |
required |
postal_city
|
str
|
City name |
required |
postal_country_code
|
str
|
ISO 3166-1 alpha-2 country code (e.g. 'FR', 'BE') |
required |
account_id
|
AccountId
|
Account ID this entity belongs to |
required |
subscription_ref
|
UUID
|
Reference of the subscription |
required |
emails_to_notify
|
list[str]
|
List of HR email addresses to notify |
required |
siret
|
str | None
|
French establishment identifier (14 digits, optional) |
None
|
has_installment_plan_per_year
|
dict[str, bool] | None
|
Year-specific boolean for installment plan |
None
|
save
|
bool
|
Whether to commit the transaction |
True
|
Returns:
| Type | Description |
|---|---|
OccupationalHealthBilledEntity
|
The created billed entity |
Source code in components/occupational_health/public/actions/billing_entity.py
update_billed_entity ¶
update_billed_entity(
billed_entity_id,
entity_name=NOT_SET,
siren=NOT_SET,
siret=NOT_SET,
postal_street=NOT_SET,
postal_code=NOT_SET,
postal_city=NOT_SET,
postal_country_code=NOT_SET,
subscription_ref=NOT_SET,
emails_to_notify=NOT_SET,
has_installment_plan_per_year=NOT_SET,
save=True,
)
Update an existing billed entity.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
billed_entity_id
|
UUID
|
ID of the billed entity to update |
required |
entity_name
|
NotSet[str]
|
Legal name of the entity |
NOT_SET
|
siren
|
NotSet[str]
|
French company identifier (9 digits) |
NOT_SET
|
siret
|
NotSet[str | None]
|
French establishment identifier (14 digits, optional) |
NOT_SET
|
postal_street
|
NotSet[str]
|
Street address |
NOT_SET
|
postal_code
|
NotSet[str]
|
Postal code |
NOT_SET
|
postal_city
|
NotSet[str]
|
City name |
NOT_SET
|
postal_country_code
|
NotSet[str]
|
ISO 3166-1 alpha-2 country code (e.g. 'FR', 'BE') |
NOT_SET
|
subscription_ref
|
NotSet[UUID]
|
Reference of the subscription |
NOT_SET
|
emails_to_notify
|
NotSet[list[str]]
|
List of HR email addresses to notify |
NOT_SET
|
has_installment_plan_per_year
|
NotSet[dict[str, bool] | None]
|
Year-specific boolean for installment plan |
NOT_SET
|
save
|
bool
|
Whether to commit the transaction |
True
|
Returns:
| Type | Description |
|---|---|
OccupationalHealthBilledEntity
|
The updated billed entity |
Source code in components/occupational_health/public/actions/billing_entity.py
doctolib_matching ¶
employee_export ¶
AffiliationStatus ¶
HEADERS
module-attribute
¶
HEADERS = [
"Prénom",
"Nom",
"SIREN/SIRET",
"Entité",
"Matricule",
"Email d'invitation",
"Numéro de sécurité sociale",
"NTT",
"Catégorie de risque",
"Date de dernière visite périodique",
"Date de prochaine visite périodique",
"Date de début de contrat",
"Statut de visite",
"Statut d'affiliation",
]
VisitStatus ¶
generate_employees_export ¶
Generate an export of occupational health employees for the given account.
Source code in components/occupational_health/public/actions/employee_export.py
members ¶
update_dmst ¶
Updates the DMST data for a given occupational health profile. We also create the medical secrecy worker record ID, which will be created by the caller on the next request using this ID
See update_curriculum_laboris_job: also creates or updates jobs for the profile
Source code in components/occupational_health/internal/business_logic/actions/members/update_dmst.py
on_demand_visit ¶
Public facade for on-demand visit actions.
OnDemandVisitInput
dataclass
¶
OnDemandVisitInput(
first_name,
last_name,
email,
phone_number,
account_name,
account_id,
visit_format,
visit_type,
if_return_visit_specify_motive,
if_on_demand_visit_specify_motive,
if_pre_return_visit_specify_request_initiator,
work_stoppage_start_date,
work_stoppage_end_date,
return_to_work_date,
utm_source,
utm_content,
is_hr_informed,
is_employee_submitting_the_request,
person_submitting_request,
additional_comments,
submitted_at,
)
Input data for creating an on-demand visit request.
if_pre_return_visit_specify_request_initiator
instance-attribute
¶
create_on_demand_visit ¶
Create an on-demand visit: Append row to GSheet.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
visit_input
|
OnDemandVisitInput
|
The visit request data from the automation/typeform. |
required |
Source code in components/occupational_health/internal/business_logic/actions/on_demand_visit.py
subscriber_documents ¶
soft_delete_subscriber_document ¶
Source code in components/occupational_health/internal/business_logic/actions/subscriber_documents.py
update_subscriber_document ¶
Source code in components/occupational_health/internal/business_logic/actions/subscriber_documents.py
upload_subscriber_documents ¶
Source code in components/occupational_health/internal/business_logic/actions/subscriber_documents.py
workspace_actions ¶
create_workspace_action ¶
create_workspace_action(
thesaurus_mean_id,
target_type,
target_id,
status,
creator_full_name,
prevention_type,
eta_date=None,
note=None,
siret=None,
commit=True,
)
Create a new WorkspaceAction for a company or a member
Returns:
| Type | Description |
|---|---|
UUID
|
The ID of the newly created AMT |
Source code in components/occupational_health/internal/business_logic/actions/workspace_actions.py
delete_workspace_action ¶
Delete an existing WorkspaceAction
Source code in components/occupational_health/internal/business_logic/actions/workspace_actions.py
update_workspace_action ¶
update_workspace_action(
workspace_action_id,
status,
prevention_type=None,
eta_date=None,
note=None,
commit=True,
)
Update an existing WorkspaceAction
Only updates the fields: status, prevention_type, eta_date, note The target and action (thesaurus_mean) cannot be changed
Source code in components/occupational_health/internal/business_logic/actions/workspace_actions.py
components.occupational_health.public.business_logic ¶
actions ¶
merge_users ¶
merge_occupational_health_users ¶
Merge all occupational health data from source user to target user.
This function handles merging of all occupational health entities that reference user_id: - Dashboard admins - Notifies oncall to update spreadsheets if visits exist for the user
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source_user_id
|
UserId | str
|
User ID to merge from |
required |
target_user_id
|
UserId | str
|
User ID to merge into |
required |
commit
|
bool
|
Whether to commit the transaction (default: False) |
False
|
event_bus
|
EventBus[CommittableFunction] | None
|
If provided, notifications are deferred until event_bus.apply(commit=True) |
None
|
Returns:
| Type | Description |
|---|---|
list[str]
|
List of log messages describing actions taken |
Source code in components/occupational_health/public/business_logic/actions/merge_users.py
components.occupational_health.public.dependencies ¶
AccountSearchResult
dataclass
¶
OCCUPATIONAL_HEALTH_COMPONENT_NAME
module-attribute
¶
OccupationalHealthDependency ¶
Bases: ABC
Dependency interface for occupational_health component to access country-specific functionality.
This interface abstracts away direct dependencies on country-specific components, allowing the occupational_health component to work with different country implementations.
create_profile_with_user
abstractmethod
¶
Create user profile with user data.
get_account_admins_profile_ids
abstractmethod
¶
get_account_id
abstractmethod
¶
get_account_id_and_siret
abstractmethod
¶
Get account ID and SIRET for a company.
get_account_name
abstractmethod
¶
get_company_admins_profile_ids
abstractmethod
¶
get_company_display_name_and_account_id
abstractmethod
¶
Get company display name and associated account ID.
get_company_entities_by_account_id
abstractmethod
¶
Get all DSN companies in an account.
get_company_from_siret
abstractmethod
¶
get_company_ids_in_account
abstractmethod
¶
get_company_names_by_ids
abstractmethod
¶
get_company_siren
abstractmethod
¶
get_company_siret
abstractmethod
¶
Get company SIRET, optionally forcing a specific NIC.
get_global_profile_id
abstractmethod
¶
Get global profile ID for a user.
Raises:
| Type | Description |
|---|---|
UserIdNotFound
|
If the user ID does not exist. |
Source code in components/occupational_health/public/dependencies.py
get_ssn_and_ntt_for_user
abstractmethod
¶
get_ssn_and_ntt_for_users
abstractmethod
¶
Get SSN and NTT for multiple users.
get_user_id_by_global_profile_id_mapping_from_global_profile_ids
abstractmethod
¶
Get global profile ID -> user ID mapping from global health profile IDs.
Source code in components/occupational_health/public/dependencies.py
get_user_id_by_global_profile_id_mapping_from_user_ids
abstractmethod
¶
Get global profile ID -> user ID mapping from user IDs.
Source code in components/occupational_health/public/dependencies.py
get_user_id_from_global_profile_id
abstractmethod
¶
Get user ID from global profile ID.
get_user_slack_id
abstractmethod
¶
Get Slack handle for an Alan user.
Returns Slack handle (e.g., "john.doe") or None if not found. Used for pinging users in Slack notifications.
Source code in components/occupational_health/public/dependencies.py
get_work_stoppages_for_users
abstractmethod
¶
Get work stoppages for users.
Source code in components/occupational_health/public/dependencies.py
prepare_mailer_params_for_billing_invoice_email
abstractmethod
¶
prepare_mailer_params_for_billing_invoice_email(
email_address,
template_name,
template_args,
attachments,
invoice_ids,
)
Return a MailerParam instance to be used for sending billing invoice emails.
Source code in components/occupational_health/public/dependencies.py
search_accounts_by_name
abstractmethod
¶
set_ssn_ntt_on_user
abstractmethod
¶
ProfileData
dataclass
¶
ProfileData(
email=None,
first_name=None,
last_name=None,
birth_date=None,
language=None,
phone_number=None,
gender=None,
)
The profile data used to create a user and profile.
get_app_dependency ¶
Retrieves the occupational_health dependency
Source code in components/occupational_health/public/dependencies.py
set_app_dependency ¶
Sets the occupational_health dependency to the app
Source code in components/occupational_health/public/dependencies.py
components.occupational_health.public.employment ¶
employment_consumer ¶
Note: Do not import local country code here, do it in the internal component after checking the country code.
occupational_health_employment_change_consumer ¶
Source code in components/occupational_health/public/employment/employment_consumer.py
requires_siret_information ¶
requires_siret_information ¶
Return whether the given account ID requires SIRET information to be provided when tracking employment movements.
Source code in components/occupational_health/public/employment/requires_siret_information.py
components.occupational_health.public.entities ¶
billing ¶
BillingStrategy ¶
ContractInvoicesData
dataclass
¶
CustomerAddress
dataclass
¶
CustomerData
dataclass
¶
Bases: DataClassJsonMixin
Customer data needed for billing purposes.
InvoiceFileData
dataclass
¶
InvoiceToGenerateData
dataclass
¶
InvoiceToGenerateData(
*,
billing_period,
billing_year,
contract_type,
contract_ref,
entity_name,
siren,
siret,
contract_yearly_price_per_employee_in_cents,
contract_has_installment_plan=None,
references_of_employees_affiliated_over_the_year
)
Bases: DataClassJsonMixin
Data needed to generate an invoice for a customer.
billing_year
instance-attribute
¶
The year of the billing period. END_OF_YEAR_REGUL invoices are issued on 01/01 of the year Y+1 but will hold the original year Y in billing_year.
contract_has_installment_plan
class-attribute
instance-attribute
¶
contract_yearly_price_per_employee_in_cents
instance-attribute
¶
references_of_employees_affiliated_over_the_year
instance-attribute
¶
List of opaque references of all employees affiliated on this subscription/contract, during the entire year of the billing period (not just the specified billing period).
IssuedInvoiceData
dataclass
¶
IssuedInvoiceData(
*,
invoice_id,
invoice_number,
event_date,
issued_date,
due_date,
total_invoice_amount,
remaining_balance,
contract_ref,
entity_name,
siren,
siret,
has_appendix,
email_sent_at
)
Bases: DataClassJsonMixin
Data representing an actual issued invoice from the Invoice model. Used to display invoices in the company admin dashboard.
OccupationalHealthBillingPeriod ¶
Bases: AlanBaseEnum
Billing period for occupational health services.
to_validity_period ¶
The period during which we'd consider affiliations for billing purposes.
Source code in components/occupational_health/public/entities/billing.py
dmst ¶
AdministrativeProfile
dataclass
¶
AdministrativeProfile(
*,
ssn,
health_statuses,
risk_category,
notes,
medical_record_sharing_consent,
medical_record_access_consent,
health_data_sharing_consent,
video_consultation_consent,
orient_prevention_of_work_consent,
transfer_dmst_to_spsti_consent,
medical_record_sharing_consent_collected_at=None,
medical_record_access_consent_collected_at=None,
health_data_sharing_consent_collected_at=None,
video_consultation_consent_collected_at=None,
orient_prevention_of_work_consent_collected_at=None,
transfer_dmst_to_spsti_consent_collected_at=None,
personal_email=None,
professional_email=None,
phone_number=None
)
Bases: DataClassJsonMixin
Administrative information about a member's occupational health status.
Keep in sync with: frontend/apps/medical-software/app/hooks/useProfileDmstQuery.ts
Used in the HP medical app (DMST) for the "Administrative side modal"
health_data_sharing_consent_collected_at
class-attribute
instance-attribute
¶
medical_record_access_consent_collected_at
class-attribute
instance-attribute
¶
medical_record_sharing_consent_collected_at
class-attribute
instance-attribute
¶
orient_prevention_of_work_consent_collected_at
class-attribute
instance-attribute
¶
transfer_dmst_to_spsti_consent_collected_at
class-attribute
instance-attribute
¶
video_consultation_consent_collected_at
class-attribute
instance-attribute
¶
ContractType ¶
Bases: AlanBaseEnum
Contract types from Présanse thesaurus level 1.
contrat_accompagnement_emploi
class-attribute
instance-attribute
¶
contrat_apprentissage
class-attribute
instance-attribute
¶
contrat_groupements_employeurs
class-attribute
instance-attribute
¶
contrat_initiative_emploi
class-attribute
instance-attribute
¶
contrat_intermittent
class-attribute
instance-attribute
¶
contrat_professionnalisation
class-attribute
instance-attribute
¶
contrat_unique_insertion
class-attribute
instance-attribute
¶
CurriculumLaboris
dataclass
¶
Bases: DataClassJsonMixin
Member curriculum laboris (work information): previous job, description of work, tasks, etc.
Keep in sync with: frontend/apps/medical-software/app/hooks/useProfileDmstQuery.ts
Used in the HP medical app (DMST) for the "Professional" tab
Dmst
dataclass
¶
Dmst(
*,
occupational_health_profile_id,
first_name,
last_name,
gender,
birthdate,
medical_secrecy_worker_record_id,
curriculum_laboris,
administrative_profile,
health_history=None,
google_drive_folder_id=None
)
Bases: DataClassJsonMixin
Information about a member, such as their name, gender, birthdate, etc.
Keep in sync with: frontend/apps/medical-software/app/hooks/useProfileDmstQuery.ts
Used in the HP medical app (DMST)
MemberJob
dataclass
¶
MemberJob(
*,
id,
title,
start_date,
end_date,
employer,
is_past_job,
medical_secrecy_worker_job_id,
description,
working_hours,
missions,
physical_conditions,
organizational_conditions,
mental_conditions,
tools,
worn_equipment,
risks_and_advice,
contract_type,
exposition_notations
)
Bases: DataClassJsonMixin
Represents a single job held by a member, including employment details and duration.
Keep in sync with: frontend/apps/medical-software/app/hooks/useProfileDmstQuery.ts
Used in the HP medical app (DMST) for the "Professional" tab
OccupationalMedicalHistory
dataclass
¶
OccupationalMedicalHistoryType ¶
doctolib_matching ¶
Entity dataclasses for Doctolib matching v2.
These mirror the output buckets of the ActivePieces automation "Matching Doctolib bookings and VIP spreadsheet v3".
Automation correspondence: - DoctolibCsvRow: parsed row from the Doctolib CSV export (automation step "Parse CSV") - NewlyScheduledItem: automation step "Map matched rows" → newly_scheduled bucket - ReschedulingItem: automation step "Map matched rows" → rescheduling bucket - CancelledItem: automation step "Filter cancelled" → cancelled bucket - NewRowItem: automation step "Map unmatched to new rows" → new_rows bucket - UnmatchedItem: rows that could not be matched to any Alan user (for manual resolution) - MatchingV2Response: final aggregated response sent to the frontend
ApplyResultSummary
dataclass
¶
CancelledItem
dataclass
¶
Bases: DataClassJsonMixin
A gsheet row whose user was expected to reschedule but is absent from the CSV.
ConsultationType ¶
DoctolibCsvRow
dataclass
¶
DoctolibCsvRow(
csv_row_index,
doctolib_patient_id,
first_name,
last_name,
birth_name,
birth_date,
email,
phone,
appointment_date,
appointment_start,
appointment_end,
duration,
agenda,
motif,
consultation_type,
id="",
notes="",
date_saisie="",
date_derniere_mise_a_jour="",
cree_par="",
statut="",
rdv_internet="",
nouveau_patient="",
honoraires_cb="",
honoraires_especes="",
honoraires_cheques="",
honoraires_tiers_payant="",
honoraires_total_regle="",
honoraires_restant_a_regler="",
agenda_ressource="",
civilite="",
adresse="",
code_postal="",
ville="",
heure_arrivee="",
heure_prise_en_charge="",
heure_depart="",
symptomes_covid19="",
identifiant_externe="",
temps_reservation_secondes="",
a_ete_importe="",
a_ete_reserve_absence="",
a_ete_reserve_creneau_deja_reserve="",
a_ete_reserve_hors_horaires="",
dispositif_reservation_patients="",
personne_referente="",
patient_notification_consent="",
patient_legal_gender="",
telephone_secondaire="",
patient_insurance_sector="",
)
MatchingV2Response
dataclass
¶
Bases: DataClassJsonMixin
Full matching response returned to the frontend.
NewRowItem
dataclass
¶
NewRowItem(
first_name,
last_name,
email,
phone,
birth_date,
consultation_type,
date_planned,
hour_start,
hour_end,
hp,
docto_patient_id,
match_priority,
candidates=list(),
)
Bases: DataClassJsonMixin
A matched row for a user not currently tracked in the gsheet.
consultation_type
class-attribute
instance-attribute
¶
consultation_type = field(
metadata={
"marshmallow_field": Enum(
ConsultationType, by_value=True
)
}
)
NewlyScheduledItem
dataclass
¶
NewlyScheduledItem(
gsheet_row_index,
user_id,
first_name,
last_name,
doctolib_email,
doctolib_phone,
doctolib_birth_date,
hp,
consultation_type,
date_planned,
hour_start,
hour_end,
docto_patient_id,
match_priority,
)
Bases: DataClassJsonMixin
A matched row that fills a pending visit slot in the predictable gsheet.
consultation_type
class-attribute
instance-attribute
¶
consultation_type = field(
metadata={
"marshmallow_field": Enum(
ConsultationType, by_value=True
)
}
)
ReschedulingItem
dataclass
¶
ReschedulingItem(
gsheet_row_index,
user_id,
first_name,
last_name,
old_date,
old_hour,
old_hp,
new_date,
new_hour,
new_hp,
hour_end,
consultation_type,
docto_patient_id,
match_priority,
)
Bases: DataClassJsonMixin
A matched row where the visit was already scheduled but date/hour/HP changed.
consultation_type
class-attribute
instance-attribute
¶
consultation_type = field(
metadata={
"marshmallow_field": Enum(
ConsultationType, by_value=True
)
}
)
health_history ¶
Health data entities for occupational health worker medical records.
These entities correspond to the TypeScript interfaces in: frontend/apps/medical-software/app/hooks/types.ts
NOTE: This is a duplicate of components.medical_secrecy.internal.entities.occupational_health_worker_medical_record_health_history to avoid cross-component dependencies. Keep in sync manually. TODO: @david.barthelemy: clean this after talking with Alexandre and Mickael
AlcoholStatus ¶
AllergyItem
dataclass
¶
Bases: DataClassJsonMixin
Allergy item.
Corresponds to AllergyItem TypeScript interface.
AllergyStatus ¶
EyeHealthItem
dataclass
¶
Bases: DataClassJsonMixin
Corresponds to EyeHealthItem TypeScript interface.
FamilyHistoryItem
dataclass
¶
Bases: DataClassJsonMixin
Family history item.
Corresponds to FamilyHistoryItem TypeScript interface.
FamilyHistoryMember
dataclass
¶
FamilyStatus ¶
Bases: AlanBaseEnum
Family member status.
HealthHistory
dataclass
¶
HealthHistory(
*,
medical_surgical_history=list(),
allergies=list(),
treatment=None,
vaccine=None,
family_history=list(),
lifestyle=None,
transport_mode=None,
personal_situation=None,
gynecological_follow_up=None,
gynecological_observation=None,
contraceptives=None,
eye_health=None,
medical_observation=None,
health_measures=list()
)
Bases: DataClassJsonMixin
Health history for occupational health worker medical record.
This dataclass contains all health-related information that needs to be encrypted and stored in the OccupationalHealthWorkerMedicalRecord.health_history field.
All fields correspond to the forms defined in: frontend/apps/medical-software/app/pages/MemberHealthTab.tsx
medical_surgical_history
class-attribute
instance-attribute
¶
LifestyleItem
dataclass
¶
LifestyleItem(
*,
alcohol_status=None,
alcohol_observation=None,
smoking_status=None,
smoking_observation=None,
other_addictive_behaviors=None,
physical_activity_status=None,
physical_activity_observations=None,
food=None,
sleep=None,
lifestyle_observations=None
)
Bases: DataClassJsonMixin
Lifestyle information.
Corresponds to LifestyleItem TypeScript interface.
physical_activity_observations
class-attribute
instance-attribute
¶
LivingStatus ¶
MedicalSurgicalHistoryItem
dataclass
¶
Bases: DataClassJsonMixin
Medical and surgical history item.
Corresponds to MedicalSurgicalHistoryItem TypeScript interface.
MedicalSurgicalHistoryStatus ¶
Bases: AlanBaseEnum
Status of a medical or surgical history item.
PersonalSituationItem
dataclass
¶
PhysicalActivityStatus ¶
Bases: AlanBaseEnum
Physical activity status.
SmokingStatus ¶
Bases: AlanBaseEnum
Smoking status.
TransportModeItem
dataclass
¶
TreatmentItem
dataclass
¶
Bases: DataClassJsonMixin
Treatment item.
Corresponds to TreatmentItem TypeScript interface.
VaccineItem
dataclass
¶
health_measure ¶
Health measure entity for occupational health.
NOTE: This is a duplicate of components.medical_secrecy.internal.entities.health_measure.HealthMeasureItem to avoid cross-component dependencies. Keep in sync manually.
HealthMeasureItem
dataclass
¶
Bases: DataClassJsonMixin
Single health measure stored as individual encrypted columns in DB.
Corresponds to HealthMeasureItem TypeScript interface.
member_info ¶
MemberInfo
dataclass
¶
MemberInfo(
*,
occupational_health_profile_id,
user_id,
member_first_name,
member_last_name,
member_gender,
member_birthdate
)
Bases: DataClassJsonMixin
Information about a member, such as their name, gender, birthdate, etc.
Note: we'll be using other structures for the rest of the data e.g. MemberActivity, etc.
Used in the HP medical app.
search ¶
subscribers ¶
thesaurus ¶
ThesaurusMean
dataclass
¶
ThesaurusOccupationalExposure
dataclass
¶
ThesaurusOccupationalExposure(
*,
notation,
label,
dc_type,
status,
created_at,
version,
line_number,
risk_category,
parent_notation,
class_label=None,
subclass_label=None,
class_notation=None,
subclass_notation=None
)
Bases: DataClassJsonMixin
A TEP (Thésaurus des Expositions Professionnelles) exposition entry.
visit ¶
PlannedVisit
dataclass
¶
PlannedVisitWithDetails
dataclass
¶
PlannedVisitWithDetails(
*,
visit_id,
profile_id,
timestamp_planned,
visit_table,
visit_type,
visit_setup,
health_professional_name
)
Bases: DataClassJsonMixin
Planned visit with extra details for monitoring exports.
VisitInfo
dataclass
¶
VisitInfo(
*,
visit_id,
member_first_name,
member_last_name,
member_gender,
member_birthdate,
visit_date,
visit_hour_booked,
visit_type,
health_professional_name,
health_professional_id,
visit_status,
occupational_health_profile_id,
visit_setup
)
Bases: DataClassJsonMixin
Information about a visit scheduled for a specific date.
Used in the HP medical app.
workspace_action ¶
WorkspaceAction
dataclass
¶
WorkspaceAction(
id,
title,
target_type,
status,
created_at,
siret=None,
company_name=None,
company_address=None,
members_count=None,
member_full_name=None,
job_title=None,
health_professional_fullname=None,
profile_id=None,
account_id=None,
account_name=None,
eta_date=None,
prevention_type=None,
note=None,
)
Bases: DataClassJsonMixin
Represents a WorkspaceAction (an AMT in France) in the context of occupational health.
health_professional_fullname
class-attribute
instance-attribute
¶
WorkspaceActionPreventionType ¶
WorkspaceActionStatus ¶
components.occupational_health.public.enums ¶
AffiliationDecision ¶
Bases: AlanBaseEnum
Possible decisions for occupational health affiliation.
RiskCategory ¶
Bases: AlanBaseEnum
Risk categories / "type de suivi" for occupational health visits.
These determine the frequency and type of required medical visits.
SubscriberDocumentType ¶
Bases: AlanBaseEnum
Type of subscriber document.
See https://www.notion.so/alaninsurance/Occupational-Health-Glossary-2d81426e8be7801cba9ed5dacdc24c60 ⧉
COLLECTIVE_WORKSTATION_ASSESSMENT
class-attribute
instance-attribute
¶
SINGLE_OCCUPATIONAL_RISK_ASSESSMENT
class-attribute
instance-attribute
¶
STAFF_INTERNAL_REGULATIONS
class-attribute
instance-attribute
¶
STOPPAGES_ACCIDENTS_ILLNESSES_SUMMARY
class-attribute
instance-attribute
¶
WORKPLACE_RISK_FILE
class-attribute
instance-attribute
¶
components.occupational_health.public.events ¶
subscription ¶
subscribe_to_events ¶
All event subscriptions for the occupational health component should be done here.
Source code in components/occupational_health/public/events/subscription.py
components.occupational_health.public.exceptions ¶
CompanyIdNotFound ¶
Bases: ConsumerError
The company ID mentioned in the employment change could not be found.
Should only happen within unit tests, or if a blocked movement has its company deleted (very rare)
Source code in components/occupational_health/public/exceptions.py
UserIdNotFound ¶
Bases: UserNotFoundError
A user ID cannot be found.
This happens generally after a user merge event, when the employment change still refers the old user ID.
Source code in components/occupational_health/public/exceptions.py
components.occupational_health.public.marmot ¶
actions ¶
Actions for use in Marmot controllers.
AffiliationRequest
dataclass
¶
AffiliationRequest(
user_id,
start_date,
end_date,
risk_category,
extra_data,
last_visit=None,
personal_email=None,
professional_email=None,
)
Bases: DataClassJsonMixin
DuplicateAdminError ¶
Bases: Exception
Raised when trying to add a duplicate occupational health dashboard admin.
RuleAction ¶
add_discrepancy_note_for_marmot ¶
Add a note on a discrepancy.
Upserts: if a note already exists for (account_id, user_id), update comment and noted_by; otherwise create a new record.
Source code in components/occupational_health/public/marmot/actions.py
add_occupational_health_dashboard_admin_to_account ¶
Add an occupational health dashboard admin to an account.
Raises:
| Type | Description |
|---|---|
DuplicateAdminError
|
If the user is already an admin for this account. |
Source code in components/occupational_health/internal/business_logic/actions/dashboard_admin.py
affiliate_multiple_members ¶
Affiliate multiple members to Prévenir in a single transaction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
account_id
|
AccountId
|
The account ID to affiliate members to |
required |
affiliations
|
list[AffiliationRequest]
|
List of affiliation requests with user_id, start_date, optional last_visit, and optional risk_category |
required |
Returns:
| Type | Description |
|---|---|
list[UUID]
|
List of affiliation IDs |
Source code in components/occupational_health/internal/business_logic/actions/affiliation_tool.py
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | |
affiliate_new_member_for_marmot ¶
affiliate_new_member_for_marmot(
*,
user_id,
account_id,
start_date,
end_date=None,
personal_email=None,
professional_email=None,
last_visit=None,
risk_category=None,
actor_user_id=None
)
Affiliate a new member to occupational health.
Source code in components/occupational_health/public/marmot/actions.py
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 | |
cancel_affiliation_for_marmot ¶
Cancel an affiliation for a profile.
This is a wrapper around cancel_affiliation that adds logging.
Source code in components/occupational_health/public/marmot/actions.py
create_affiliation_strategy_rule_for_marmot ¶
create_affiliation_strategy_rule_for_marmot(
*, account_id, company_id=None, siret=None, name, action
)
Create a new affiliation strategy rule for a company or SIRET.
Either company_id or siret must be provided, but not both.
Source code in components/occupational_health/public/marmot/actions.py
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 | |
create_contract ¶
Source code in components/occupational_health/internal/business_logic/contracting/actions.py
update_employment_nic ¶
Update the NIC of an employment.
Source code in components/occupational_health/public/marmot/actions.py
entities ¶
AccountForMarmot
dataclass
¶
AffiliatedMemberForMarmot
dataclass
¶
AffiliatedMemberForMarmot(
affiliation_id,
start_date,
end_date,
is_cancelled,
user_id,
occupational_health_profile_id,
global_profile_id,
first_name,
last_name,
birth_date,
professional_email,
personal_email,
is_vip,
employments,
account_id,
)
Bases: DataClassJsonMixin
Represent a member affiliated to Prévenir, to be displayed in Marmot
AffiliationDecisionInfo
dataclass
¶
AffiliationMovementForMarmot
dataclass
¶
AffiliationMovementForMarmot(
movement_id,
account_id,
profile_id,
movement_type,
date_of_movement,
first_name,
last_name,
birth_date,
created_at,
decision_id,
company_id,
company_name,
company_name_enriched_from_dsn,
)
Bases: DataClassJsonMixin
Represent an affiliation movement for display in Marmot
CancelledAffiliationInfo
dataclass
¶
CompanyWithAffiliatedCount
dataclass
¶
CompanyWithAffiliatedCount(
company_id,
company_display_name,
ever_affiliated_members_count,
sirets,
)
Bases: DataClassJsonMixin
Represent a company with its count of affiliated members for display in Marmot.
ContractInfo
dataclass
¶
DiscrepancyFixProposition
dataclass
¶
DiscrepancyForMarmot
dataclass
¶
DiscrepancyForMarmot(
account_id,
profile_id,
user_id,
category,
message,
employments_timeline=None,
affiliations_timeline=None,
*,
first_name,
last_name,
birth_date,
employments,
discrepancy_note=None,
cancelled_affiliations=list(),
affiliation_decisions=list()
)
DiscrepancyNoteInfo
dataclass
¶
LastVisit
dataclass
¶
MemberToAffiliate
dataclass
¶
MemberToAffiliate(
row_index,
first_name,
last_name,
birthdate,
ssn,
professional_email,
personal_email,
proposed_user_id,
proposed_user_name,
proposed_birthdate,
matched_name,
matched_birthdate,
matching_result,
affiliations,
employments,
target_start_date,
target_end_date,
last_visit,
risk_category,
extra_data,
)
Bases: DataClassJsonMixin
Result of matching a spreadsheet row.
NicTimelineEntry
dataclass
¶
OccupationalHealthAffiliationDecisionForMarmot
dataclass
¶
OccupationalHealthAffiliationDecisionForMarmot(
id,
created_at,
decision,
employment_change_payload,
core_employment_id,
rule_id,
rule_name,
)
Bases: DataClassJsonMixin
Affiliation decision data for display in Marmot.
OccupationalHealthAffiliationDecisionWithProfileForMarmot
dataclass
¶
OccupationalHealthAffiliationDecisionWithProfileForMarmot(
id,
created_at,
decision,
manual_decision,
employment_change_payload,
core_employment_id,
rule_id,
rule_name,
first_name,
last_name,
birth_date,
company_id,
company_name,
company_name_enriched_from_dsn,
)
Bases: DataClassJsonMixin
Affiliation decision data with profile information for display in Marmot.
OccupationalHealthProfileData
dataclass
¶
OccupationalHealthProfileData(
profile_id,
past_visits,
affiliations,
affiliation_decisions,
next_visit_result,
)
Bases: DataClassJsonMixin
All occupational health data for a profile
RiskCategory ¶
Bases: AlanBaseEnum
Risk categories / "type de suivi" for occupational health visits.
These determine the frequency and type of required medical visits.
SiretWithMemberCount
dataclass
¶
VisitType ¶
Bases: AlanBaseEnum
EXAMEN_MEDICAL_APTITUDE_EMBAUCHE
class-attribute
instance-attribute
¶
EXAMEN_MEDICAL_APTITUDE_PERIODIQUE
class-attribute
instance-attribute
¶
VISITE_CESSATION_EXPOSITION
class-attribute
instance-attribute
¶
VISITE_CESSATION_EXPOSITION_COURS_CARRIERE
class-attribute
instance-attribute
¶
VISITE_CESSATION_EXPOSITION_COURS_CARRIERE_INITIATIVE_EMPLOYEUR
class-attribute
instance-attribute
¶
VISITE_CESSATION_EXPOSITION_COURS_CARRIERE_INITIATIVE_EMPLOYEUR = "32.visite_cessation_exposition_cours_carriere_initiative_employeur"
VISITE_CESSATION_EXPOSITION_COURS_CARRIERE_INITIATIVE_TRAVAILLEUR
class-attribute
instance-attribute
¶
VISITE_CESSATION_EXPOSITION_COURS_CARRIERE_INITIATIVE_TRAVAILLEUR = "33.visite_cessation_exposition_cours_carriere_initiative_travailleur"
VISITE_CESSATION_EXPOSITION_FIN_CARRIERE
class-attribute
instance-attribute
¶
VISITE_CESSATION_EXPOSITION_FIN_CARRIERE_INITIATIVE_EMPLOYEUR
class-attribute
instance-attribute
¶
VISITE_CESSATION_EXPOSITION_FIN_CARRIERE_INITIATIVE_EMPLOYEUR = "35.visite_cessation_exposition_fin_carriere_initiative_employeur"
VISITE_CESSATION_EXPOSITION_FIN_CARRIERE_INITIATIVE_TRAVAILLEUR
class-attribute
instance-attribute
¶
VISITE_CESSATION_EXPOSITION_FIN_CARRIERE_INITIATIVE_TRAVAILLEUR = "36.visite_cessation_exposition_fin_carriere_initiative_travailleur"
VISITE_DEMANDE_EMPLOYEUR
class-attribute
instance-attribute
¶
VISITE_DEMANDE_MEDECIN_TRAVAIL
class-attribute
instance-attribute
¶
VISITE_DEMANDE_MEDECIN_TRAVAIL_ORIENTATION_INFIRMIER
class-attribute
instance-attribute
¶
VISITE_DEMANDE_MEDECIN_TRAVAIL_ORIENTATION_INFIRMIER = "15.visite_demande_medecin_travail_orientation_infirmier"
VISITE_DEMANDE_TRAVAILLEUR
class-attribute
instance-attribute
¶
VISITE_INFORMATION_PREVENTION_INITIALE
class-attribute
instance-attribute
¶
VISITE_INFORMATION_PREVENTION_PERIODIQUE
class-attribute
instance-attribute
¶
VISITE_INTERMEDIAIRE_ENTRE_DEUX_EXAMENS
class-attribute
instance-attribute
¶
VISITE_MI_CARRIERE
class-attribute
instance-attribute
¶
VISITE_PREREPRISE_INITIATIVE_MEDECIN_CONSEIL
class-attribute
instance-attribute
¶
VISITE_PREREPRISE_INITIATIVE_MEDECIN_TRAITANT
class-attribute
instance-attribute
¶
VISITE_PREREPRISE_INITIATIVE_MEDECIN_TRAITANT = (
"8.visite_prereprise_initiative_medecin_traitant"
)
VISITE_PREREPRISE_INITIATIVE_MEDECIN_TRAVAIL
class-attribute
instance-attribute
¶
VISITE_PREREPRISE_INITIATIVE_MEDECIN_TRAVAIL = (
"10.visite_prereprise_initiative_medecin_travail"
)
VISITE_PREREPRISE_INITIATIVE_TRAVAILLEUR
class-attribute
instance-attribute
¶
VISITE_REPRISE_ABSENCE_30_JOURS_ACCIDENT_TRAVAIL
class-attribute
instance-attribute
¶
VISITE_REPRISE_ABSENCE_30_JOURS_ACCIDENT_TRAVAIL = (
"20.visite_reprise_absence_30_jours_accident_travail"
)
VISITE_REPRISE_ABSENCE_30_JOURS_ACCIDENT_TRAVAIL_INITIATIVE_EMPLOYEUR
class-attribute
instance-attribute
¶
VISITE_REPRISE_ABSENCE_30_JOURS_ACCIDENT_TRAVAIL_INITIATIVE_EMPLOYEUR = "21.visite_reprise_absence_30_jours_accident_travail_initiative_employeur"
VISITE_REPRISE_ABSENCE_30_JOURS_ACCIDENT_TRAVAIL_INITIATIVE_TRAVAILLEUR
class-attribute
instance-attribute
¶
VISITE_REPRISE_ABSENCE_30_JOURS_ACCIDENT_TRAVAIL_INITIATIVE_TRAVAILLEUR = "22.visite_reprise_absence_30_jours_accident_travail_initiative_travailleur"
VISITE_REPRISE_ABSENCE_MALADIE_PROFESSIONNELLE
class-attribute
instance-attribute
¶
VISITE_REPRISE_ABSENCE_MALADIE_PROFESSIONNELLE = (
"23.visite_reprise_absence_maladie_professionnelle"
)
VISITE_REPRISE_ABSENCE_MALADIE_PROFESSIONNELLE_INITIATIVE_EMPLOYEUR
class-attribute
instance-attribute
¶
VISITE_REPRISE_ABSENCE_MALADIE_PROFESSIONNELLE_INITIATIVE_EMPLOYEUR = "24.visite_reprise_absence_maladie_professionnelle_initiative_employeur"
VISITE_REPRISE_ABSENCE_MALADIE_PROFESSIONNELLE_INITIATIVE_TRAVAILLEUR
class-attribute
instance-attribute
¶
VISITE_REPRISE_ABSENCE_MALADIE_PROFESSIONNELLE_INITIATIVE_TRAVAILLEUR = "25.visite_reprise_absence_maladie_professionnelle_initiative_travailleur"
VISITE_REPRISE_CAUSE_MALADIE_ACCIDENT_NON_PRO
class-attribute
instance-attribute
¶
VISITE_REPRISE_CAUSE_MALADIE_ACCIDENT_NON_PRO = (
"17.visite_reprise_cause_maladie_accident_non_pro"
)
VISITE_REPRISE_CAUSE_MALADIE_ACCIDENT_NON_PRO_INITIATIVE_EMPLOYEUR
class-attribute
instance-attribute
¶
VISITE_REPRISE_CAUSE_MALADIE_ACCIDENT_NON_PRO_INITIATIVE_EMPLOYEUR = "18.visite_reprise_cause_maladie_accident_non_pro_initiative_employeur"
VISITE_REPRISE_CAUSE_MALADIE_ACCIDENT_NON_PRO_INITIATIVE_TRAVAILLEUR
class-attribute
instance-attribute
¶
VISITE_REPRISE_CAUSE_MALADIE_ACCIDENT_NON_PRO_INITIATIVE_TRAVAILLEUR = "19.visite_reprise_cause_maladie_accident_non_pro_initiative_travailleur"
VISITE_REPRISE_CONGE_MATERNITE
class-attribute
instance-attribute
¶
VISITE_REPRISE_CONGE_MATERNITE_INITIATIVE_EMPLOYEUR
class-attribute
instance-attribute
¶
VISITE_REPRISE_CONGE_MATERNITE_INITIATIVE_EMPLOYEUR = (
"27.visite_reprise_conge_maternite_initiative_employeur"
)
VISITE_REPRISE_CONGE_MATERNITE_INITIATIVE_TRAVAILLEUR
class-attribute
instance-attribute
¶
VISITE_REPRISE_CONGE_MATERNITE_INITIATIVE_TRAVAILLEUR = "28.visite_reprise_conge_maternite_initiative_travailleur"
detect_from_string
classmethod
¶
Detect the visit type from a string.
Source code in components/occupational_health/internal/enums/visit_type.py
enums ¶
MovementType ¶
Bases: AlanBaseEnum
The recorded movement: either an affiliation, or a termination, or a cancellation.
Transfers are composed by a termination and an affiliation, if they moved between two distinct accounts.
queries ¶
Queries for use in Marmot controllers.
InvalidInputDataError ¶
Bases: ValueError
The input data is not valid.
analyze_discrepancy_fixes_for_marmot ¶
Analyze multiple discrepancies and suggest fixes.
Returns a mapping of user_id to fix proposition (or None if no fix found).
Source code in components/occupational_health/public/marmot/queries.py
865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 | |
get_accounts_list_for_marmot ¶
Return the list of accounts with occupational health contracts for Marmot.
Source code in components/occupational_health/public/marmot/queries.py
get_admin_accounts_from_user_for_marmot ¶
Returns the list of accounts for the current admin user
Source code in components/occupational_health/public/marmot/queries.py
get_affiliated_members_for_marmot ¶
Return the list of affiliated members (including past ones) for display in Marmot.
Source code in components/occupational_health/public/marmot/queries.py
get_affiliation_decisions_for_marmot ¶
get_affiliation_decisions_for_marmot(
profile_service,
account_id,
decision=None,
not_older_than=None,
)
Return the list of affiliation decisions, optionally filtered by decision type and date.
Source code in components/occupational_health/public/marmot/queries.py
get_all_admins_for_account ¶
Get all admins for a given account.
Source code in components/occupational_health/internal/business_logic/queries/admin_dashboard/admin_authorization.py
get_companies_with_affiliated_count_for_marmot ¶
Return the list of all companies in an account with their count of affiliated members.
Source code in components/occupational_health/public/marmot/queries.py
525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 | |
get_contract_info_for_account ¶
Get contract information for an account.
Source code in components/occupational_health/internal/business_logic/queries/affiliation/affiliation_tool.py
get_occupational_health_profile_data_for_marmot ¶
Return all occupational health data for a profile, for display in Marmot.
Source code in components/occupational_health/public/marmot/queries.py
get_recent_affiliation_movements ¶
Return the list of affiliation decisions made since the given date for the given account.
Source code in components/occupational_health/public/marmot/queries.py
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 | |
parse_and_match_spreadsheet ¶
parse_and_match_spreadsheet(
profile_service,
account_id,
spreadsheet_data,
raise_on_invalid_data=False,
)
Parse spreadsheet data and return matching results (members that will could affiliate)
Source code in components/occupational_health/internal/business_logic/queries/affiliation/affiliation_tool.py
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 | |
components.occupational_health.public.queries ¶
billed_entity ¶
get_flask_admin_url_from_contract_ref ¶
Return the flask admin url linking to a billed entity from the contract reference (used for invoice)
Source code in components/occupational_health/public/queries/billed_entity.py
billing ¶
Set of queries used by the Billing stack.
See https://github.com/alan-eu/Topics/discussions/30344?sort=old#discussioncomment-14080373 ⧉
ContractRefNotFound ¶
Bases: Exception
A contract reference was not found.
UnableToDetermineCustomerToBill ¶
Bases: Exception
Unable to determine which customer to bill.
build_invoices_data_for_period ¶
Build the data required to generate all invoices for the given billing period and invoice year.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
billing_period
|
OccupationalHealthBillingPeriod
|
The billing period to build data for. |
required |
billing_year
|
int
|
The year of the billing period to build data for. |
required |
The data is not guaranteed to be stable over time for past billing periods, as retroactive affiliation changes can occur.
Returns:
| Name | Type | Description |
|---|---|---|
tuple |
tuple[list[InvoiceToGenerateData], dict[UUID, dict[str, int | str]]]
|
A tuple containing: - list[InvoiceToGenerateData]: The data about all invoices to generate for the given period. - dict[UUID, dict[str, int | str]]: Statistics per account with keys "account_name", "invoices_count" and "errors_count". |
Source code in components/occupational_health/public/queries/billing.py
build_invoices_data_for_period_and_account ¶
Build the data required to generate all invoices for the given billing period, invoice year and account.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
billing_period
|
OccupationalHealthBillingPeriod
|
The billing period to build data for. |
required |
billing_year
|
int
|
The year of the billing period to build data for. |
required |
account_id
|
UUID | AccountId
|
The account ID to build invoices for. |
required |
The data is not guaranteed to be stable over time for past billing periods, as retroactive affiliation changes can occur.
Returns:
| Name | Type | Description |
|---|---|---|
tuple |
tuple[list[InvoiceToGenerateData], dict[UUID, str]]
|
A tuple containing: - list[InvoiceToGenerateData]: The data about all invoices to generate for the given period. - dict[UUID, str]: Mapping of affiliation IDs to rejection reasons for affiliations that couldn't be matched. |
Source code in components/occupational_health/public/queries/billing.py
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 | |
get_active_employee_count_for_account ¶
Return the number of currently active affiliations for the given account.
Note: billing is the first external consumer of this function which is why it was defined in billing.py - don't hesitate to move it
Source code in components/occupational_health/public/queries/billing.py
get_billed_entities_for_account ¶
Get all billed entities for a given account.
Source code in components/occupational_health/public/queries/billing.py
get_customer_data ¶
Fetch customer data for the billing system.
Until we decide how to store this customer data (on the Billing side?), here is a query to serve it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contract_ref
|
str
|
The contract reference to look up customer data for |
required |
Returns:
| Name | Type | Description |
|---|---|---|
CustomerData |
CustomerData
|
The customer data for the given contract reference |
Raises:
| Type | Description |
|---|---|
ContractRefNotFound
|
If the contract reference is not found in the customer data mapping |
Source code in components/occupational_health/public/queries/billing.py
get_profile_list_from_invoice_data ¶
Build a list of profiles with customer names from invoice data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
invoices
|
list[InvoiceToGenerateData]
|
List of invoice objects, each with contract_ref and references_of_employees_affiliated_over_the_year attributes. |
required |
Returns:
| Type | Description |
|---|---|
list[dict[str, str | ProfileId]]
|
List of dicts with profile_id, first_name, last_name, and customer_name. |
Source code in components/occupational_health/public/queries/billing.py
doctolib_matching ¶
Public facade for Doctolib export matching.
Thin re-export layer so the Marmot controller (in components/fr/) can import everything from a single public module.
build_doctolib_patient_id_to_user_id_lookup ¶
Build doctolib_patient_id -> user_id from predictable gsheet rows.
Only includes entries where helper_docto_patient_id maps to exactly 1 distinct user_id.
Source code in components/occupational_health/internal/business_logic/doctolib/profile_indexes.py
categorize_matched_rows ¶
Categorize matched rows into buckets — strict step_28 transposition.
Mirrors automation step_28 JavaScript exactly: 1. Build predictableById, rescheduleCheckById maps 2. Loop doctoExportData: reschedule check → newly_scheduled → new_rows 3. Detect cancellations 4. Filter new_rows with ErrorFilterSheet
Note: on-demand filtering must be done BEFORE calling this function via filter_on_demand_visits(). matched_rows and unmatched_csv_rows should already be filtered.
Source code in components/occupational_health/internal/business_logic/doctolib/categorizer.py
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | |
filter_on_demand_visits ¶
Filter out CSV rows that already have an on-demand visit booked.
Mirrors the Metabase SQL LEFT JOIN filter: removes rows where the user+date already exists in the on-demand gsheet tab (future dates only). Must be called BEFORE categorize_matched_rows, just like the SQL does before step_28.
Source code in components/occupational_health/internal/business_logic/doctolib/categorizer.py
find_candidates_for_new_rows ¶
Find candidate users for new_rows so Ops can pick the right one in the UI.
Lightweight search: only returns basic user info, no SSN/employment enrichment. Mutates each NewRowItem in place by populating its candidates list.
Source code in components/occupational_health/internal/business_logic/doctolib/queries.py
get_all_occupational_health_profiles_with_user_data ¶
Source code in components/occupational_health/internal/business_logic/doctolib/queries.py
match_all_csv_rows ¶
Match all CSV rows to Alan users.
Each row goes through an 8-priority cascade (see match_csv_row_to_user). Lower priority number = higher confidence match. If the best priority yields multiple distinct user_ids, the row is marked as ambiguous.
Logs group counts so results can be compared with the original SQL query.
Source code in components/occupational_health/internal/business_logic/doctolib/matching_engine.py
normalize_doctolib_csv_rows ¶
Normalize raw CSV dicts into typed DoctolibCsvRow objects.
Full normalization pipeline: - Map French headers → English field names - Normalize dates (DD/MM/YYYY) and times (HH:MM:SS) - Derive consultation_type from motif - Compute appointment_end = start + duration
Source code in components/occupational_health/internal/business_logic/doctolib/csv_normalizer.py
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 | |
parse_doctolib_csv ¶
Parse semicolon-separated Doctolib CSV export.
Handles BOM (byte order mark) and strips whitespace from headers.
Source code in components/occupational_health/internal/business_logic/doctolib/csv_normalizer.py
read_gsheet_visit_rows ¶
Read all rows from on-demand and predictable visit gsheets.
Source code in components/occupational_health/internal/business_logic/doctolib/queries.py
doctolib_user_matching_v1 ¶
Queries for Occupational Health doctolib export matching tool in Marmot
TODO @david.barthelemy: clean this after the visit management tool v2 is released¶
find_matching_candidates ¶
Find all matching candidates for a user from the doctolib export
Source code in components/occupational_health/public/queries/doctolib_user_matching_v1.py
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | |
parse_rows_from_gsheet_data ¶
Parse TSV data from spreadsheet into MatchingUserVisitData objects
Source code in components/occupational_health/public/queries/doctolib_user_matching_v1.py
search_users_matching_candidates ¶
Search for matching candidates for each row
Source code in components/occupational_health/public/queries/doctolib_user_matching_v1.py
has_active_occupational_health_contract ¶
has_active_occupational_health_contract ¶
Return whether the given account ID has an active occupational health contract at the moment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
account_id
|
UUID
|
The ID of the account to check. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the account has an active occupational health contract, False otherwise. |
Source code in components/occupational_health/public/queries/has_active_occupational_health_contract.py
has_active_or_upcoming_occupational_health_contract ¶
Return whether the given account ID has an active or upcoming occupational health contract.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
account_id
|
UUID
|
The ID of the account to check. |
required |
Returns: bool: True if the account has an active or upcoming occupational health contract, False otherwise.
Source code in components/occupational_health/public/queries/has_active_occupational_health_contract.py
health_professional ¶
get_or_raise_health_professional ¶
Get or raise health professional by ID.
Source code in components/occupational_health/internal/queries/health_professional.py
invoices ¶
Public interface for invoice queries.
Re-exports internal query functions for use by external components.
get_invoice_appendix_employee_data_for_profile_ids ¶
Returns the data needed to build the invoice appendix for each employee per profile id.
:param profile_ids: iterable of profile ids :return: dict of InvoiceAppendixEmployeeData per profile id
Source code in components/occupational_health/public/queries/invoices.py
get_invoice_file_for_account ¶
Get file data for a specific invoice that belongs to the given account.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
account_id
|
AccountId
|
The account ID to verify ownership |
required |
invoice_id
|
int
|
The invoice ID to fetch |
required |
file_type
|
Literal['invoice', 'appendix']
|
Which file to return — "invoice" for the PDF, "appendix" for the CSV |
'invoice'
|
Returns:
| Type | Description |
|---|---|
InvoiceFileData
|
InvoiceFileData with the filename and raw file |
Raises:
| Type | Description |
|---|---|
missing_resource
|
If invoice not found or doesn't belong to account |
remote_file_retrieval
|
If the requested file is not attached |
Source code in components/occupational_health/internal/queries/invoices.py
get_issued_invoices_for_account ¶
Get all actual issued invoices for all billed entities of an account.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
account_id
|
UUID
|
The account ID to fetch invoices for |
required |
Returns:
| Type | Description |
|---|---|
list[IssuedInvoiceData]
|
List of IssuedInvoiceData for all invoices linked to this account's billed entities, |
list[IssuedInvoiceData]
|
sorted by event_date descending. |
Source code in components/occupational_health/internal/queries/invoices.py
is_currently_affiliated_to_prevenir ¶
is_currently_affiliated_to_occupational_health ¶
Check if the user is currently affiliated to Prevenir.
Will create a OccupationalHealthProfile if it doesn't exist, hence the commit parameter.
Returns True if the user has active affiliations, otherwise False.
Source code in components/occupational_health/public/queries/is_currently_affiliated_to_prevenir.py
profiles ¶
get_profile_dmst ¶
Returns the member information for a given occupational health profile ID.
Source code in components/occupational_health/internal/business_logic/queries/profiles/profiles.py
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | |
search ¶
get_search_results ¶
Search for members and accounts based on provided search input.
Note
The function currently only searches for members by full name
Source code in components/occupational_health/internal/business_logic/queries/search/search.py
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | |
strategy_rules ¶
AffiliationStrategyRuleForMarmot
dataclass
¶
AffiliationStrategyRuleForMarmot(
rule_id,
account_id,
name,
company_id,
company_name,
siret,
company_name_from_siret,
is_missing_siret,
action,
decisions_count,
created_at,
updated_at,
)
Bases: DataClassJsonMixin
Affiliation strategy rules displayed in Marmot.
get_affiliation_strategy_rules_for_account ¶
Get all affiliation strategy rules for a given account.
Source code in components/occupational_health/public/queries/strategy_rules.py
subscriber_documents ¶
get_documents_for_subscriber ¶
Returns all non-deleted documents for a given subscriber account ID.
Source code in components/occupational_health/internal/business_logic/queries/subscriber_documents.py
subscribers ¶
get_affiliated_members_for_account ¶
Return the list of currently affiliated members for a subscriber profile.
Source code in components/occupational_health/internal/business_logic/queries/subscribers/members.py
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | |
get_subscriber_entities_for_account ¶
Get all potential entities (SIRET) for an account.
Note: "potential" because not all entities returned will be affiliated to the account.
Source code in components/occupational_health/internal/business_logic/queries/subscribers/subscribers.py
get_subscriber_for_account ¶
Get a subscriber for an account.
Source code in components/occupational_health/internal/business_logic/queries/subscribers/subscribers.py
visits ¶
get_all_visits_for_member ¶
Get all visits for a specific member
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
profile_service
|
ProfileService
|
The profile service for fetching member information |
required |
occupational_health_profile_id
|
ProfileId | UUID
|
Optional filter by occupational health profile ID |
required |
Returns:
| Type | Description |
|---|---|
list[VisitInfo]
|
List[VisitInfo]: List of visits scheduled for the specified date |
Source code in components/occupational_health/internal/business_logic/queries/visits/medical_app.py
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 | |
get_closest_visit_by_health_professional_and_timestamp ¶
Retrieves the closest occupational health visit by a health professional for a given day.
Gets all visits for the day and returns the one closest to on_datetime within allowed time window:
- max 10 minutes before planned time (recording started early)
- max 20 minutes after planned time (recording started late)
Warning: only querying turing tables for now, could refactor with code above
Source code in components/occupational_health/internal/business_logic/queries/visits/visits.py
676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 | |
get_visit_details_by_hp_and_date ¶
get_visit_details_by_hp_and_date(
health_professional_id,
visit_date,
occupational_health_profile_id,
)
Find a turing visit by HP ID, date, and occupational health profile ID.
Source code in components/occupational_health/internal/business_logic/queries/visits/visits.py
get_visits ¶
Get all visits scheduled for a specific date. If no date is provided, return visits for today.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
profile_service
|
ProfileService
|
The profile service for fetching member information |
required |
on_date
|
date | None
|
The date to fetch visits for. If None, uses today's date. |
required |
Returns:
| Type | Description |
|---|---|
list[VisitInfo]
|
List[VisitInfo]: List of visits scheduled for the specified date |
Source code in components/occupational_health/internal/business_logic/queries/visits/medical_app.py
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 | |
workspace_actions ¶
get_all_workspace_actions ¶
Get all workspace actions, optionally filtered by occupational health profile ID or account ID (XOR).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
occupational_health_profile_id
|
Optional[UUID]
|
Optional profile ID to filter member-type actions |
None
|
account_id
|
Optional[UUID]
|
Optional account ID to filter company-type actions |
None
|
Returns:
| Type | Description |
|---|---|
list[WorkspaceAction]
|
List of WorkspaceAction entities |
Source code in components/occupational_health/public/queries/workspace_actions.py
components.occupational_health.public.testing ¶
OccupationalHealthHealthProfessionalFactory ¶
Bases: AlanBaseFactory['OccupationalHealthHealthProfessional']
components.occupational_health.public.thesaurus ¶
expositions ¶
actions ¶
parse_and_store_tep_rdf ¶
Parse a TEP RDF file (compressed or not) and store expositions in the database.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_path
|
str | Path
|
Path to the RDF file to parse (can be gzip compressed with .gz extension) |
required |
Raises:
| Type | Description |
|---|---|
TepParsingError
|
If there is an error parsing the file or if the file is invalid |
FileNotFoundError
|
If the file does not exist |
Source code in components/occupational_health/internal/thesaurus/expositions/parser.py
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | |
queries ¶
get_expositions ¶
Return the exposition data matching the given notations
Source code in components/occupational_health/internal/thesaurus/expositions/queries.py
search_expositions ¶
Return the exposition data matching the given search input (case-insensitive and accent-insensitive)
Note: adds the class and subclass labels to the exposition objects
Source code in components/occupational_health/internal/thesaurus/expositions/queries.py
means ¶
actions ¶
parse_and_store_thesaurus_means ¶
Import Thesaurus mean data from an xlsx file (extracted logic)
Source code in components/occupational_health/internal/thesaurus/means/parse_and_store_thesaurus_means.py
terminologies ¶
queries ¶
search_terminologies ¶
Return the terminology data matching the given search input (case-insensitive and accent-insensitive)
Source code in components/occupational_health/internal/thesaurus/terminologies/queries.py
components.occupational_health.public.types ¶
CompanyId
module-attribute
¶
The Company ID type. We use 'str' to not make assumption on the country's representation of the ID.
GlobalProfileId
module-attribute
¶
The Global Profile ID type.
ProfileId
module-attribute
¶
The Occupational Health Profile ID type.
UserId
module-attribute
¶
The country-specific User ID type. We use 'str' to not make assumption on the country's representation of the ID.