brynq-sdk-acerta 1.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. brynq_sdk_acerta/__init__.py +14 -0
  2. brynq_sdk_acerta/acerta.py +118 -0
  3. brynq_sdk_acerta/addresses.py +99 -0
  4. brynq_sdk_acerta/agreements.py +426 -0
  5. brynq_sdk_acerta/bank_accounts.py +90 -0
  6. brynq_sdk_acerta/code_lists.py +264 -0
  7. brynq_sdk_acerta/company_cars.py +135 -0
  8. brynq_sdk_acerta/contact_information.py +79 -0
  9. brynq_sdk_acerta/cost_centers.py +94 -0
  10. brynq_sdk_acerta/employees.py +121 -0
  11. brynq_sdk_acerta/employees_additional_information.py +87 -0
  12. brynq_sdk_acerta/employer.py +179 -0
  13. brynq_sdk_acerta/family_members.py +99 -0
  14. brynq_sdk_acerta/family_situation.py +99 -0
  15. brynq_sdk_acerta/inservice.py +99 -0
  16. brynq_sdk_acerta/salaries.py +74 -0
  17. brynq_sdk_acerta/schemas/__init__.py +135 -0
  18. brynq_sdk_acerta/schemas/address.py +80 -0
  19. brynq_sdk_acerta/schemas/agreement.py +982 -0
  20. brynq_sdk_acerta/schemas/bank_account.py +87 -0
  21. brynq_sdk_acerta/schemas/company_car.py +124 -0
  22. brynq_sdk_acerta/schemas/contact_information.py +83 -0
  23. brynq_sdk_acerta/schemas/cost_center.py +82 -0
  24. brynq_sdk_acerta/schemas/employee.py +406 -0
  25. brynq_sdk_acerta/schemas/employer.py +71 -0
  26. brynq_sdk_acerta/schemas/family.py +220 -0
  27. brynq_sdk_acerta/schemas/in_service.py +243 -0
  28. brynq_sdk_acerta/schemas/in_service_config.py +28 -0
  29. brynq_sdk_acerta/schemas/planning.py +37 -0
  30. brynq_sdk_acerta/schemas/salaries.py +84 -0
  31. brynq_sdk_acerta-1.1.1.dist-info/METADATA +21 -0
  32. brynq_sdk_acerta-1.1.1.dist-info/RECORD +34 -0
  33. brynq_sdk_acerta-1.1.1.dist-info/WHEEL +5 -0
  34. brynq_sdk_acerta-1.1.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,87 @@
1
+ """
2
+ Schemas for Bank Accounts resource
3
+ """
4
+
5
+ import pandas as pd
6
+ import pandera as pa
7
+ from pandera.typing import Series
8
+ from pydantic import BaseModel, Field
9
+ from typing import Optional, Literal
10
+ from brynq_sdk_functions import BrynQPanderaDataFrameModel
11
+
12
+
13
+ # GET via Agreements Remuneration
14
+ class AgreementBankAccountsGet(BrynQPanderaDataFrameModel):
15
+ """Schema for bank account fields within GET /v3/agreements/{agreementId}/remuneration."""
16
+
17
+ agreement_id: Series[pd.StringDtype] = pa.Field(coerce=True, alias="agreementId")
18
+ period_start_date: Series[pd.StringDtype] = pa.Field(coerce=True, alias="period.startDate")
19
+ period_end_date: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, alias="period.endDate")
20
+
21
+ payment_method_type_code: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, alias="methodOfPayment.type.code")
22
+ payment_method_type_description: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, alias="methodOfPayment.type.description")
23
+
24
+ employee_main_iban: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, alias="methodOfPayment.employeeBankAccounts.mainAccount.iban")
25
+ employee_main_bic: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, alias="methodOfPayment.employeeBankAccounts.mainAccount.bic")
26
+ employee_second_iban: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, alias="methodOfPayment.employeeBankAccounts.secondAccount.iban")
27
+ employee_second_bic: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, alias="methodOfPayment.employeeBankAccounts.secondAccount.bic")
28
+
29
+ employer_main_iban: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, alias="methodOfPayment.employerBankAccounts.mainAccount.iban")
30
+ employer_main_bic: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, alias="methodOfPayment.employerBankAccounts.mainAccount.bic")
31
+ employer_second_iban: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, alias="methodOfPayment.employerBankAccounts.secondAccount.iban")
32
+ employer_second_bic: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, alias="methodOfPayment.employerBankAccounts.secondAccount.bic")
33
+
34
+ class Config:
35
+ strict = False
36
+ metadata = {"class": "AgreementBankAccounts", "dependencies": []}
37
+
38
+ # POST/PUT Schemas (Pydantic - Request)
39
+ class OwnerName(BaseModel):
40
+ """Reusable bank account owner name schema (no prefix)"""
41
+ first_name: str = Field(..., min_length=1, max_length=35, example="John", description="Owner first name of the bank account", alias="firstName")
42
+ last_name: str = Field(..., min_length=1, max_length=35, example="Doe", description="Owner last name of the bank account", alias="lastName")
43
+
44
+ class Config:
45
+ populate_by_name = True
46
+
47
+
48
+ class BankOwner(BaseModel):
49
+ """Reusable bank account owner schema (no prefix)"""
50
+ name: OwnerName = Field(..., description="Owner name of the bank account", alias="name", json_schema_extra={"prefix": "name_"})
51
+ street: str = Field(..., min_length=1, max_length=40, example="Main Street", description="Owner street name of the bank account", alias="street")
52
+ house_number: str = Field(..., min_length=1, max_length=9, example="123", description="Owner house number of the bank account", alias="houseNumber")
53
+ box_number: Optional[str] = Field(None, min_length=1, max_length=4, example="A", description="Owner box number of the bank account", alias="boxNumber")
54
+ postal_code: str = Field(..., min_length=1, max_length=14, example="1000", description="Owner zip code of the bank account", alias="postalCode")
55
+ city: str = Field(..., min_length=1, max_length=35, example="Brussels", description="Owner city name of the bank account", alias="city")
56
+ country: str = Field(..., min_length=3, max_length=3, example="BEL", description="Owner country code", alias="country")
57
+
58
+ class Config:
59
+ populate_by_name = True
60
+
61
+
62
+ class BankDetails(BaseModel):
63
+ """Reusable bank details schema (no prefix)"""
64
+ bic: str = Field(..., min_length=8, max_length=11, pattern=r"^([A-Z]{4}[A-Z]{2}[A-Z0-9]{2}[A-Z0-9]{3}|[A-Z]{4}[A-Z]{2}[A-Z0-9]{2})$", example="SZNBDLYL", description="BIC Number", alias="bic")
65
+ name: Optional[str] = Field(None, min_length=1, max_length=35, example="Bank Name", description="Name of the bank account", alias="name")
66
+ street: Optional[str] = Field(None, min_length=1, max_length=40, example="Bank Street", description="Street name of the bank account", alias="street")
67
+ house_number: Optional[str] = Field(None, min_length=1, max_length=9, example="456", description="House number of the bank account", alias="houseNumber")
68
+ box_number: Optional[str] = Field(None, min_length=1, max_length=4, example="B", description="Box number of the bank account", alias="boxNumber")
69
+ postal_code: Optional[str] = Field(None, min_length=1, max_length=14, example="2000", description="Zip code of the bank account", alias="postalCode")
70
+ city: Optional[str] = Field(None, min_length=1, max_length=35, example="Antwerp", description="City name of the bank account", alias="city")
71
+ country: Optional[str] = Field(None, min_length=3, max_length=3, example="BEL", description="Country code", alias="country")
72
+ costs: Literal["DEBT", "CRED", "SHAR"] = Field(..., example="DEBT", description="Costs code", alias="costs")
73
+
74
+ class Config:
75
+ populate_by_name = True
76
+
77
+
78
+ class BankAccountUpdate(BaseModel):
79
+ """Schema for PUT /v1/employees/{employeeId}/bank-accounts/{bankAccountId} endpoint"""
80
+
81
+ iban: str = Field(..., min_length=1, max_length=34, example="BE68539007547034", description="Bank account number", alias="iban")
82
+ text: Optional[str] = Field(None, min_length=1, max_length=40, example="Notice text", description="Notice text", alias="text")
83
+ bank_details: Optional[BankDetails] = Field(None, description="If not a Belgian account, bankDetails must be specified", alias="bankDetails", json_schema_extra={"prefix": "bank_details_"})
84
+ owner: Optional[BankOwner] = Field(None, description="If the owner is not the owner of the bankaccount, some extra data must be provided", alias="owner", json_schema_extra={"prefix": "owner_"})
85
+
86
+ class Config:
87
+ populate_by_name = True
@@ -0,0 +1,124 @@
1
+ """
2
+ Schemas for Company Cars resource
3
+ """
4
+
5
+ from typing import Optional
6
+ import pandas as pd
7
+ import pandera as pa
8
+ from pandera.typing import Series
9
+ from pydantic import BaseModel, Field
10
+ from brynq_sdk_functions import BrynQPanderaDataFrameModel
11
+
12
+
13
+ # ============================================
14
+ # GET SCHEMA (Pandera - DataFrame)
15
+ # ============================================
16
+
17
+ class CompanyCarGet(BrynQPanderaDataFrameModel):
18
+ """Schema for GET /v1/employers/{employerId}/company-cars endpoints."""
19
+
20
+ # Period
21
+ period_start_date: Series[pd.StringDtype] = pa.Field(coerce=True, description="The start date of the record", alias="period.startDate")
22
+ period_end_date: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="The end date of the record", alias="period.endDate")
23
+
24
+ # Identification
25
+ company_car_id: Series[pd.StringDtype] = pa.Field(coerce=True, description="Unique identifier of the company car", alias="companyCarId")
26
+ license_plate: Series[pd.StringDtype] = pa.Field(coerce=True, description="License plate of the car", alias="licensePlate")
27
+
28
+ # Vehicle details
29
+ brand: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Brand of the car", alias="brand")
30
+ type: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Type/model of the car", alias="type")
31
+ co2: Series[pd.Int64Dtype] = pa.Field(coerce=True, description="CO2 value of the car", alias="co2")
32
+ fuel_code: Series[pd.StringDtype] = pa.Field(coerce=True, description="Fuel type code of the car", alias="fuel.code")
33
+ fuel_description: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Fuel type description", alias="fuel.description")
34
+ catalogue_value: Series[pd.Float64Dtype] = pa.Field(coerce=True, nullable=True, description="Catalogue value of the car", alias="catalogueValue")
35
+ fiscal_hp: Series[pd.Int64Dtype] = pa.Field(coerce=True, nullable=True, description="Fiscal horsepower of the car", alias="fiscalHp")
36
+ is_light_cargo: Series[pd.BooleanDtype] = pa.Field(coerce=True, description="Is the car Light commercial only used for commuting?", alias="isLightCargo")
37
+ first_subscription_date: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="First subscription date of the car", alias="firstSubscriptionDate")
38
+ acquire_date: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Date of acquisition of the car", alias="acquireDate")
39
+ is_hybrid: Series[pd.BooleanDtype] = pa.Field(coerce=True, nullable=True, description="Is it a hybrid car?", alias="isHybrid")
40
+ is_fake_hybrid: Series[pd.BooleanDtype] = pa.Field(coerce=True, nullable=True, description="Is the car a fake hybrid?", alias="isFakeHybrid")
41
+ co2_fake_hybrid: Series[pd.Int64Dtype] = pa.Field(coerce=True, nullable=True, description="CO2 of the fake hybrid car", alias="co2FakeHybrid")
42
+ is_pool_car: Series[pd.BooleanDtype] = pa.Field(coerce=True, nullable=True, description="Whether the company car is a poolcar", alias="isPoolCar")
43
+
44
+ class _Annotation:
45
+ primary_key = "company_car_id"
46
+ foreign_keys = {}
47
+
48
+ class Config:
49
+ metadata = {"class": "CompanyCar", "dependencies": []}
50
+
51
+
52
+ # ============================================
53
+ # POST/PATCH SCHEMAS (Pydantic - Request)
54
+ # ============================================
55
+
56
+ class CompanyCarPeriod(BaseModel):
57
+ """Reusable company car period schema - no prefix in field names"""
58
+ start_date: str = Field(..., example="1984-10-30", description="The start date of the record", alias="startDate")
59
+ end_date: Optional[str] = Field(None, example="1984-10-30", description="The end date of the record", alias="endDate")
60
+
61
+ class Config:
62
+ populate_by_name = True
63
+
64
+
65
+ class CompanyCarCreate(BaseModel):
66
+ """
67
+ Schema for POST /v1/employers/{employerId}/company-cars endpoint
68
+ """
69
+ # Function parameters
70
+ employer_id: str = Field(..., description="Employer identifier", alias="employerId")
71
+
72
+ period: CompanyCarPeriod = Field(..., description="The time span of the record for which this data is valid", alias="period", json_schema_extra={"prefix": "period_"})
73
+ license_plate: str = Field(..., min_length=1, max_length=10, example="2-DCR-765", description="License plate of the car", alias="licensePlate")
74
+ brand: Optional[str] = Field(None, min_length=1, max_length=35, example="Renault", description="Brand of the car", alias="brand")
75
+ type: Optional[str] = Field(None, min_length=1, max_length=50, example="megane", description="Type/model of the car", alias="type")
76
+ co2: int = Field(..., ge=0, le=99999, example=110, description="CO2 value of the car", alias="co2")
77
+ fuel: str = Field(..., min_length=2, max_length=2, example="02", description="Fuel type of the car (COD: B11_Fuel)", alias="fuel")
78
+ catalogue_value: Optional[float] = Field(None, ge=0, le=999999999.99, multiple_of=0.01, example=49649.99, description="Catalogue value of the car", alias="catalogueValue")
79
+ fiscal_hp: Optional[int] = Field(None, ge=0, le=99, example=8, description="Fiscal horsepower of the car", alias="fiscalHp")
80
+ is_light_cargo: bool = Field(..., description="Is the car Light commercial only used for commuting?", alias="isLightCargo")
81
+ first_subscription_date: Optional[str] = Field(None, example="2020-09-08", description="Date of first subscription of the car", alias="firstSubscriptionDate")
82
+ acquire_date: Optional[str] = Field(None, example="2020-09-08", description="Date of acquisition of the car", alias="acquireDate")
83
+ is_hybrid: Optional[bool] = Field(None, description="Is it a hybrid car?", alias="isHybrid")
84
+ is_fake_hybrid: Optional[bool] = Field(None, description="Is the car a fake hybrid?", alias="isFakeHybrid")
85
+ co2_fake_hybrid: Optional[int] = Field(None, ge=0, le=99999, example=50, description="CO2 of the fake hybrid car", alias="co2FakeHybrid")
86
+ is_pool_car: Optional[bool] = Field(None, description="Is the car a pool car?", alias="isPoolCar")
87
+
88
+ class Config:
89
+ populate_by_name = True
90
+
91
+
92
+ class CompanyCarPeriodPatch(BaseModel):
93
+ """Period for PATCH - start date required, end date optional"""
94
+ start_date: str = Field(..., example="1984-10-30", description="The start date of the record", alias="startDate")
95
+ end_date: Optional[str] = Field(None, example="1984-10-30", description="The end date of the record", alias="endDate")
96
+
97
+ class Config:
98
+ populate_by_name = True
99
+
100
+
101
+ class CompanyCarUpdate(BaseModel):
102
+ """Schema for PATCH /v1/employers/{employerId}/company-cars/{companyCarId}"""
103
+ # Function parameters
104
+ employer_id: str = Field(..., description="Employer identifier", alias="employerId")
105
+ company_car_id: str = Field(..., description="Company car identifier", alias="companyCarId")
106
+
107
+ period: Optional[CompanyCarPeriodPatch] = Field(None, description="The time span of the record for which this data is valid", alias="period", json_schema_extra={"prefix": "period_"})
108
+ license_plate: Optional[str] = Field(None, min_length=1, max_length=10, example="2-DCR-765", description="License plate of the car", alias="licensePlate")
109
+ brand: Optional[str] = Field(None, min_length=1, max_length=35, example="Renault", description="Brand of the car", alias="brand")
110
+ type: Optional[str] = Field(None, min_length=1, max_length=50, example="megane", description="Type/model of the car", alias="type")
111
+ co2: Optional[int] = Field(None, ge=0, le=99999, example=110, description="CO2 value of the car", alias="co2")
112
+ fuel: Optional[str] = Field(None, min_length=2, max_length=2, example="02", description="Fuel type of the car (COD: B11_Fuel)", alias="fuel")
113
+ catalogue_value: Optional[float] = Field(None, ge=0, le=999999999.99, multiple_of=0.01, example=49649.99, description="Catalogue value of the car", alias="catalogueValue")
114
+ fiscal_hp: Optional[int] = Field(None, ge=0, le=99, example=8, description="Fiscal horsepower of the car", alias="fiscalHp")
115
+ is_light_cargo: Optional[bool] = Field(None, description="Is the car Light commercial only used for commuting?", alias="isLightCargo")
116
+ first_subscription_date: Optional[str] = Field(None, example="2020-09-08", description="Date of first subscription of the car", alias="firstSubscriptionDate")
117
+ acquire_date: Optional[str] = Field(None, example="2020-09-08", description="Date of acquisition of the car", alias="acquireDate")
118
+ is_hybrid: Optional[bool] = Field(None, description="Is it a hybrid car?", alias="isHybrid")
119
+ is_fake_hybrid: Optional[bool] = Field(None, description="Is the car a fake hybrid?", alias="isFakeHybrid")
120
+ co2_fake_hybrid: Optional[int] = Field(None, ge=0, le=99999, example=50, description="CO2 of the fake hybrid car", alias="co2FakeHybrid")
121
+ is_pool_car: Optional[bool] = Field(None, description="Whether the company car is a poolcar", alias="isPoolCar")
122
+
123
+ class Config:
124
+ populate_by_name = True
@@ -0,0 +1,83 @@
1
+ """
2
+ Schema for GET /employee-data-management/v3/employees/{employeeId}/contact-information
3
+ """
4
+
5
+ import pandas as pd
6
+ import pandera as pa
7
+ from pandera.typing import Series
8
+ from pydantic import BaseModel, Field
9
+ from typing import Optional
10
+ from brynq_sdk_functions import BrynQPanderaDataFrameModel
11
+
12
+
13
+ class ContactInformationGet(BrynQPanderaDataFrameModel):
14
+ """Schema for GET /employee-data-management/v3/employees/{employeeId}/contact-information endpoint"""
15
+
16
+ # Employee identification
17
+ employee_id: Series[pd.StringDtype] = pa.Field(coerce=True, description="Employee identifier", alias="employeeId")
18
+
19
+ # Personal contact information
20
+ personal_telephone: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Personal phone number", alias="personal.telephone")
21
+ personal_mobile: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Personal mobile number", alias="personal.mobile")
22
+ personal_email: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Personal email", alias="personal.email")
23
+
24
+ # Work contact information
25
+ work_telephone: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Work phone number", alias="work.telephone")
26
+ work_mobile: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Work mobile number", alias="work.mobile")
27
+ work_email: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Work email", alias="work.email")
28
+
29
+ # Primary emergency contact
30
+ primary_emergency_relationship_code: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Primary emergency contact relationship code", alias="primaryEmergencyContact.relationship.code")
31
+ primary_emergency_relationship_description: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Primary emergency contact relationship description", alias="primaryEmergencyContact.relationship.description")
32
+ primary_emergency_name: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Primary emergency contact name", alias="primaryEmergencyContact.name")
33
+ primary_emergency_number: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Primary emergency contact number", alias="primaryEmergencyContact.number")
34
+
35
+ # Secondary emergency contact
36
+ secondary_emergency_relationship_code: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Secondary emergency contact relationship code", alias="secondaryEmergencyContact.relationship.code")
37
+ secondary_emergency_relationship_description: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Secondary emergency contact relationship description", alias="secondaryEmergencyContact.relationship.description")
38
+ secondary_emergency_name: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Secondary emergency contact name", alias="secondaryEmergencyContact.name")
39
+ secondary_emergency_number: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Secondary emergency contact number", alias="secondaryEmergencyContact.number")
40
+
41
+ class _Annotation:
42
+ primary_key = "employee_id"
43
+ foreign_keys = {}
44
+
45
+ class Config:
46
+ metadata = {"class": "ContactInformation", "dependencies": []}
47
+
48
+
49
+
50
+
51
+ # Reusable base schemas - no prefix in field names
52
+ class Contact(BaseModel):
53
+ """Reusable contact schema - no prefix in field names"""
54
+ telephone: Optional[str] = Field(None, min_length=1, max_length=100, example="016588774", description="Phone number", alias="telephone")
55
+ mobile: Optional[str] = Field(None, min_length=1, max_length=100, example="0479877458", description="Mobile number", alias="mobile")
56
+ email: Optional[str] = Field(None, min_length=1, max_length=100, pattern=r"^[^@\s]+@[^@\s]+\.[^@\s]+$", example="contact@example.com", description="E-mail", alias="email")
57
+
58
+ class Config:
59
+ populate_by_name = True
60
+
61
+
62
+ class EmergencyContact(BaseModel):
63
+ """Reusable emergency contact schema - no prefix in field names"""
64
+ relationship: Optional[str] = Field(None, min_length=2, max_length=2, example="10", description="Relationship with the person", alias="relationship")
65
+ name: Optional[str] = Field(None, min_length=1, max_length=50, example="John Emergency", description="Name of the person", alias="name")
66
+ number: Optional[str] = Field(None, min_length=1, max_length=100, example="0498778855", description="Contact phone number", alias="number")
67
+
68
+ class Config:
69
+ populate_by_name = True
70
+
71
+
72
+ class ContactInformationUpdate(BaseModel):
73
+ """Schema for PATCH /employee-data-management/v3/employees/{employeeId}/contact-information - uses json_schema_extra for prefixes"""
74
+ # Function parameters
75
+ employee_id: str = Field(..., description="Employee identifier", alias="employeeId")
76
+
77
+ personal: Optional[Contact] = Field(None, description="Personal contact information", alias="personal", json_schema_extra={"prefix": "personal_"})
78
+ work: Optional[Contact] = Field(None, description="Work contact information", alias="work", json_schema_extra={"prefix": "work_"})
79
+ primary_emergency_contact: Optional[EmergencyContact] = Field(None, description="Primary emergency contact", alias="primaryEmergencyContact", json_schema_extra={"prefix": "primary_emergency_"})
80
+ secondary_emergency_contact: Optional[EmergencyContact] = Field(None, description="Secondary emergency contact", alias="secondaryEmergencyContact", json_schema_extra={"prefix": "secondary_emergency_"})
81
+
82
+ class Config:
83
+ populate_by_name = True
@@ -0,0 +1,82 @@
1
+ """
2
+ Schemas for Cost Centers resource
3
+ """
4
+
5
+ import pandas as pd
6
+ import pandera as pa
7
+ from pandera.typing import Series
8
+ from pydantic import BaseModel, Field
9
+ from typing import Optional, List, Literal
10
+ from brynq_sdk_functions import BrynQPanderaDataFrameModel
11
+
12
+
13
+ # ============================================
14
+ # GET SCHEMA (Pandera - DataFrame)
15
+ # ============================================
16
+
17
+ class CostCenterGet(BrynQPanderaDataFrameModel):
18
+ """Schema for GET /v1/employers/{employerId}/cost-centers endpoint."""
19
+
20
+ # Cost Center identification
21
+ cost_center_id: Series[pd.StringDtype] = pa.Field(coerce=True, description="The service receiver cost center number", alias="costCenterId")
22
+
23
+ # Period information
24
+ period_start_date: Series[pd.StringDtype] = pa.Field(coerce=True, description="The start date of the record", alias="period.startDate")
25
+ period_end_date: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="The end date of the record", alias="period.endDate")
26
+
27
+ # Optional fields
28
+ accountancy: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="The accountancy cost center linked to the service receiver cost center number", alias="accountancy")
29
+ acknowledgement_number: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="The acknowledgement number linked to the service receiver cost center number", alias="acknowledgementNumber")
30
+
31
+ # Descriptions (handled as JSON string since it's a list)
32
+ descriptions: Series[pd.StringDtype] = pa.Field(coerce=True, description="Cost center descriptions per language (as JSON)", alias="descriptions")
33
+
34
+ class _Annotation:
35
+ primary_key = "cost_center_id"
36
+ foreign_keys = {}
37
+
38
+ class Config:
39
+ metadata = {"class": "CostCenter", "dependencies": []}
40
+
41
+
42
+ # ============================================
43
+ # POST SCHEMAS (Pydantic - Request)
44
+ # ============================================
45
+
46
+ class CostCenterDescription(BaseModel):
47
+ """Reusable cost center description schema - no prefix in field names"""
48
+ language: Literal["EN", "en", "NL", "nl", "FR", "fr"] = Field(..., example="EN", description="Language of the description", alias="language")
49
+ description: str = Field(..., min_length=1, max_length=100, example="Cost center for business line 4454-01.", description="Description of the cost center", alias="description")
50
+
51
+ class Config:
52
+ populate_by_name = True
53
+
54
+
55
+ class CostCenterPeriod(BaseModel):
56
+ """Reusable cost center period schema - no prefix in field names"""
57
+ start_date: str = Field(..., example="1984-10-30", description="The start date of the record", alias="startDate")
58
+ end_date: Optional[str] = Field(None, example="1984-10-30", description="The end date of the record", alias="endDate")
59
+
60
+ class Config:
61
+ populate_by_name = True
62
+
63
+
64
+ class CostCenterCreate(BaseModel):
65
+ """
66
+ Schema for POST /v1/employers/{employerId}/cost-centers endpoint
67
+
68
+ Uses json_schema_extra with prefixes for flat-to-nested conversion support.
69
+ Works with Functions.flat_to_nested_with_prefix() to convert flat dictionaries
70
+ to properly nested structures.
71
+ """
72
+ # Function parameters
73
+ employer_id: str = Field(..., description="Employer identifier", alias="employerId")
74
+
75
+ cost_center_id: str = Field(..., min_length=1, max_length=12, example="4454-01", description="The service receiver cost center number", alias="costCenterId")
76
+ descriptions: List[CostCenterDescription] = Field(..., min_items=1, max_items=3, description="Cost center descriptions per language", alias="descriptions", json_schema_extra={"prefix": "descriptions_"})
77
+ period: CostCenterPeriod = Field(..., description="The time span of the record for which this data is valid", alias="period", json_schema_extra={"prefix": "period_"})
78
+ accountancy: Optional[str] = Field(None, min_length=1, max_length=12, example="ADMINISTR1", description="The accountancy cost center linked to the service receiver cost center number", alias="accountancy")
79
+ acknowledgement_number: Optional[str] = Field(None, min_length=1, max_length=8, example="975", description="The acknowledgement number linked to the service receiver cost center number", alias="acknowledgementNumber")
80
+
81
+ class Config:
82
+ populate_by_name = True