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,220 @@
1
+ """
2
+ Schemas for Family 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
+ class FamilyMemberGet(BrynQPanderaDataFrameModel):
13
+ """Schema for GET /v2/employees/{employeeId}/family-members endpoint"""
14
+
15
+ employee_id: Series[pd.StringDtype] = pa.Field(coerce=True, description="The employeeId is the unique identifier for an employee", alias="employeeId")
16
+ external_reference_type: Series[pd.StringDtype] = pa.Field(coerce=True, description="Identifies you as a consumer and is identical for each employee of the same consumer", alias="externalReferences.externalReferenceType")
17
+ external_reference_number: Series[pd.StringDtype] = pa.Field(coerce=True, description="Identifies the employee for this consumer and is unique for each employee of the same consumer", alias="externalReferences.externalReferenceNumber")
18
+ company_organisation_number: Series[pd.StringDtype] = pa.Field(coerce=True, description="Identifies the company organisation (COR/BOR) this employee is linked to", alias="externalReferences.companyOrganisationNumber")
19
+ period_start_date: Series[pd.StringDtype] = pa.Field(coerce=True, description="Start date of the family member period", alias="familyMembersSegments.period.startDate")
20
+ period_end_date: Series[pd.StringDtype] = pa.Field(coerce=True, description="End date of the family member period", alias="familyMembersSegments.period.endDate")
21
+ family_member_id: Series[pd.StringDtype] = pa.Field(coerce=True, description="The identifier of the family member in the associated history segment", alias="familyMemberId")
22
+ first_name: Series[pd.StringDtype] = pa.Field(coerce=True, description="First name of the family member", alias="personalData.name.firstName")
23
+ last_name: Series[pd.StringDtype] = pa.Field(coerce=True, description="Last name of the family member", alias="personalData.name.lastName")
24
+ birth_day: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Birth day of the family member", alias="personalData.birthDay")
25
+ decease_date: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Decease date of the family member", alias="personalData.deceaseDate")
26
+ relationship_code: Series[pd.StringDtype] = pa.Field(coerce=True, description="Relationship code", alias="personalData.relationship.code")
27
+ relationship_description: Series[pd.StringDtype] = pa.Field(coerce=True, description="Relationship description", alias="personalData.relationship.description")
28
+ gender_code: Series[pd.StringDtype] = pa.Field(coerce=True, description="Gender code", alias="personalData.gender.code")
29
+ gender_description: Series[pd.StringDtype] = pa.Field(coerce=True, description="Gender description", alias="personalData.gender.description")
30
+ dependent_persons: Series[pd.BooleanDtype] = pa.Field(coerce=True, description="Dependant indicator", alias="dependentDisabledPersons.dependentPersons")
31
+ disabled_person: Series[pd.BooleanDtype] = pa.Field(coerce=True, description="Disabled indicator", alias="dependentDisabledPersons.disabledPerson")
32
+ degree_self_reliance: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Disability degree", alias="dependentDisabledPersons.degreeSelfReliance")
33
+ in_group_insurance: Series[pd.BooleanDtype] = pa.Field(coerce=True, description="Group insurance indicator", alias="insurance.inGroupInsurance")
34
+ in_hospital_insurance: Series[pd.BooleanDtype] = pa.Field(coerce=True, description="Hospitalisation insurance indicator", alias="insurance.inHospitalInsurance")
35
+ comment: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Comment of the family member", alias="comment")
36
+
37
+ class _Annotation:
38
+ primary_key = "family_member_id"
39
+ foreign_keys = {
40
+ "employee_id": {"parent_schema": "EmployeeGet", "parent_column": "employee_id", "cardinality": "N:1"}
41
+ }
42
+
43
+ class Config:
44
+ metadata = {"class": "FamilyMember", "dependencies": []}
45
+
46
+
47
+ class CivilStatus(BaseModel):
48
+ """Reusable civil status schema - no prefix in field names"""
49
+ status: str = Field(..., min_length=2, max_length=2, example="06", description="Marital status code", alias="status")
50
+ in_effect_date: Optional[str] = Field(None, example="2022-01-01", description="Date from which the marital status is valid", alias="inEffectDate")
51
+ date_of_marriage_or_cohabitation: Optional[str] = Field(None, example="2022-01-01", description="Date of marriage or cohabitation", alias="dateOfMarriageOrCohabitation")
52
+
53
+ class Config:
54
+ populate_by_name = True
55
+
56
+
57
+ class Partner(BaseModel):
58
+ """Reusable partner schema - no prefix in field names"""
59
+ last_name: Optional[str] = Field(None, min_length=1, max_length=35, example="Achternaam", description="Partner last name", alias="lastName")
60
+ first_name: Optional[str] = Field(None, min_length=1, max_length=35, example="Voornaam", description="Partner first name", alias="firstName")
61
+ birth_date: Optional[str] = Field(None, example="2022-01-01", description="Partner birth date", alias="birthDate")
62
+ is_disabled: Optional[bool] = Field(None, description="Partner disabled indicator", alias="isDisabled")
63
+ income: Optional[str] = Field(None, min_length=2, max_length=2, example="01", description="Partner income code", alias="income")
64
+
65
+ class Config:
66
+ populate_by_name = True
67
+
68
+
69
+ class DependantsChildren(BaseModel):
70
+ """Reusable children dependants schema - no prefix in field names"""
71
+ not_disabled: Optional[int] = Field(None, ge=0, le=99, example=1, description="Number of dependant not disabled children", alias="notDisabled")
72
+ disabled: Optional[int] = Field(None, ge=0, le=99, example=1, description="Number of disabled dependant children", alias="disabled")
73
+
74
+ class Config:
75
+ populate_by_name = True
76
+
77
+
78
+ class DependantsOver65(BaseModel):
79
+ """Reusable over 65 dependants schema - no prefix in field names"""
80
+ not_disabled: Optional[int] = Field(None, ge=0, le=99, example=1, description="Number of not disabled dependants over 65", alias="notDisabled")
81
+ disabled: Optional[int] = Field(None, ge=0, le=99, example=1, description="Number of disabled dependants over 65", alias="disabled")
82
+ needing_care: Optional[int] = Field(None, ge=0, le=99, example=1, description="Number of dependants over 65 needing care", alias="needingCare")
83
+
84
+ class Config:
85
+ populate_by_name = True
86
+
87
+
88
+ class DependantsOthers(BaseModel):
89
+ """Reusable other dependants schema - no prefix in field names"""
90
+ not_disabled: Optional[int] = Field(None, ge=0, le=99, example=1, description="Number of not disabled other dependants", alias="notDisabled")
91
+ disabled: Optional[int] = Field(None, ge=0, le=99, example=1, description="Number of other disabled dependants", alias="disabled")
92
+
93
+ class Config:
94
+ populate_by_name = True
95
+
96
+
97
+ class Dependants(BaseModel):
98
+ """Dependants container schema - uses json_schema_extra for prefixes"""
99
+ children: Optional[DependantsChildren] = Field(None, description="Number of dependent children", alias="children", json_schema_extra={"prefix": "children_"})
100
+ over65: Optional[DependantsOver65] = Field(None, description="Number of dependent persons 65+", alias="over65", json_schema_extra={"prefix": "over65_"})
101
+ others: Optional[DependantsOthers] = Field(None, description="Number of other dependent persons", alias="others", json_schema_extra={"prefix": "others_"})
102
+
103
+ class Config:
104
+ populate_by_name = True
105
+
106
+
107
+ class FiscalDetails(BaseModel):
108
+ """Reusable fiscal details schema - no prefix in field names"""
109
+ has_family_burden: Optional[bool] = Field(None, description="Dependent family in case of early retirement", alias="hasFamilyBurden")
110
+ is_unmarried_with_dependant_child: Optional[bool] = Field(None, description="Not married with dependent child", alias="isUnmarriedWithDependantChild")
111
+ is_disabled: Optional[bool] = Field(None, description="Disabled indicator", alias="isDisabled")
112
+ merging_gross_net_calculation: Optional[str] = Field(None, min_length=2, max_length=2, example="02", description="Merging gross net calculation code", alias="mergingGrossNetCalculation")
113
+ is_young_employee: Optional[bool] = Field(None, description="Young employee", alias="isYoungEmployee")
114
+ tax_volunteerism_amount: Optional[float] = Field(None, description="Additional monthly payroll withholding tax amount", alias="taxVolunteerismAmount")
115
+
116
+ class Config:
117
+ populate_by_name = True
118
+
119
+
120
+ class FamilySituationUpdate(BaseModel):
121
+ """Schema for PATCH /v3/employees/{employeeId}/family-situation - uses json_schema_extra for prefixes"""
122
+ # Function parameters
123
+ employee_id: str = Field(..., description="Employee identifier", alias="employeeId")
124
+
125
+ from_date: Optional[str] = Field(None, example="2022-01-01", description="Date from when this data is valid", alias="fromDate")
126
+ civil_status: Optional[CivilStatus] = Field(None, description="Civil status of the employee", alias="civilStatus", json_schema_extra={"prefix": "civil_status_"})
127
+ partner: Optional[Partner] = Field(None, description="Information regarding the partner", alias="partner", json_schema_extra={"prefix": "partner_"})
128
+ dependants: Optional[Dependants] = Field(None, description="Number of dependent persons", alias="dependants", json_schema_extra={"prefix": "dependants_"})
129
+ fiscal_details: Optional[FiscalDetails] = Field(None, description="Fiscal details", alias="fiscalDetails", json_schema_extra={"prefix": "fiscal_details_"})
130
+
131
+ class Config:
132
+ populate_by_name = True
133
+
134
+
135
+ # POST Schemas for Family Members
136
+ class FamilyMemberName(BaseModel):
137
+ """Reusable family member name schema - no prefix in field names"""
138
+ first_name: str = Field(..., min_length=1, max_length=35, example="SAL", description="First name of the family member", alias="firstName")
139
+ last_name: str = Field(..., min_length=1, max_length=35, example="FERIT", description="Last name of the family member", alias="lastName")
140
+
141
+ class Config:
142
+ populate_by_name = True
143
+
144
+
145
+ class FamilyMemberPersonalia(BaseModel):
146
+ """Reusable family member personalia schema - no prefix in field names, uses json_schema_extra for name prefix"""
147
+ relationship: Optional[str] = Field(None, example="09", description="The relationship of this family member", alias="relationship")
148
+ name: FamilyMemberName = Field(..., description="Name", alias="name", json_schema_extra={"prefix": "name_"})
149
+ birth_date: Optional[str] = Field(None, example="2000-01-01", description="Birth date of the family member", alias="birthDate")
150
+ decease_date: Optional[str] = Field(None, example="2000-01-01", description="Death date of the family member", alias="deceaseDate")
151
+ gender: Optional[str] = Field(None, example="V", description="Gender of the family member", alias="gender")
152
+
153
+ class Config:
154
+ populate_by_name = True
155
+
156
+
157
+ class FamilyMemberOther(BaseModel):
158
+ """Reusable family member other data schema - no prefix in field names"""
159
+ dependant_persons: bool = Field(..., example=True, description="Dependant indicator", alias="dependantPersons")
160
+ disabled_person: bool = Field(..., example=True, description="Disabled indicator", alias="disabledPerson")
161
+ degree_self_reliance: Optional[int] = Field(None, ge=0, le=99, example=18, description="Disability degree", alias="degreeSelfReliance")
162
+ in_group_insurance: bool = Field(..., example=True, description="Group insurance indicator", alias="inGroupInsurance")
163
+ in_hospital_insurance: bool = Field(..., example=True, description="Hospitalisation insurance indicator", alias="inHospitalInsurance")
164
+
165
+ class Config:
166
+ populate_by_name = True
167
+
168
+
169
+ class FamilyMemberCreate(BaseModel):
170
+ """Schema for POST /v1/employees/{employeeId}/family-members endpoint - uses json_schema_extra for prefixes"""
171
+ # Function parameters
172
+ employee_id: str = Field(..., description="Employee identifier", alias="employeeId")
173
+
174
+ valid_from: str = Field(..., example="2025-10-16", description="Date when the change is registered", alias="validFrom")
175
+ history_from_date: Optional[str] = Field(None, example="2025-10-16", description="Date on which the value of the returned historical data is valid", alias="historyFromDate")
176
+ sequence: Optional[str] = Field(None, min_length=3, max_length=3, example="001", description="Unique number per family member", alias="sequence")
177
+ personalia: FamilyMemberPersonalia = Field(..., description="Personalia", alias="personalia", json_schema_extra={"prefix": "personalia_"})
178
+ other: Optional[FamilyMemberOther] = Field(None, description="Other", alias="other", json_schema_extra={"prefix": "other_"})
179
+
180
+ class Config:
181
+ populate_by_name = True
182
+
183
+
184
+ # GET Schema for Family Situations
185
+ class FamilySituationGet(BrynQPanderaDataFrameModel):
186
+ """Schema for GET /v3/employees/{employeeId}/family-situations endpoint"""
187
+
188
+ employee_id: Series[pd.StringDtype] = pa.Field(coerce=True, description="Employee identifier", alias="employeeId")
189
+ period_start_date: Series[pd.StringDtype] = pa.Field(coerce=True, description="Family situation period start date", alias="period.startDate")
190
+ period_end_date: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Family situation period end date", alias="period.endDate")
191
+ civil_status_code: Series[pd.StringDtype] = pa.Field(coerce=True, description="Marital status code", alias="civilStatus.status.code")
192
+ civil_status_description: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Marital status description", alias="civilStatus.status.description")
193
+ civil_status_in_effect_date: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Date from which the marital status is valid", alias="civilStatus.inEffectDate")
194
+ civil_status_date_of_marriage_or_cohabitation: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Date of marriage or cohabitation", alias="civilStatus.dateOfMarriageOrCohabitation")
195
+ partner_last_name: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Partner last name", alias="partner.lastName")
196
+ partner_first_name: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Partner first name", alias="partner.firstName")
197
+ partner_birth_date: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Partner birth date", alias="partner.birthDate")
198
+ partner_is_disabled: Series[pd.BooleanDtype] = pa.Field(coerce=True, nullable=True, description="Partner disabled indicator", alias="partner.isDisabled")
199
+ partner_income_code: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Partner income code", alias="partner.income.code")
200
+ partner_income_description: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Partner income description", alias="partner.income.description")
201
+ dependants_children_not_disabled: Series[pd.Int64Dtype] = pa.Field(coerce=True, description="Number of dependant not disabled children", alias="dependants.children.notDisabled")
202
+ dependants_children_disabled: Series[pd.Int64Dtype] = pa.Field(coerce=True, description="Number of disabled dependant children", alias="dependants.children.disabled")
203
+ dependants_over65_not_disabled: Series[pd.Int64Dtype] = pa.Field(coerce=True, description="Number of not disabled dependants over 65", alias="dependants.over65.notDisabled")
204
+ dependants_over65_disabled: Series[pd.Int64Dtype] = pa.Field(coerce=True, description="Number of disabled dependants over 65", alias="dependants.over65.disabled")
205
+ dependants_over65_needing_care: Series[pd.Int64Dtype] = pa.Field(coerce=True, description="Number of dependants over 65 needing care", alias="dependants.over65.needingCare")
206
+ dependants_others_not_disabled: Series[pd.Int64Dtype] = pa.Field(coerce=True, description="Number of not disabled other dependants", alias="dependants.others.notDisabled")
207
+ dependants_others_disabled: Series[pd.Int64Dtype] = pa.Field(coerce=True, description="Number of other disabled dependants", alias="dependants.others.disabled")
208
+ fiscal_details_has_family_burden: Series[pd.BooleanDtype] = pa.Field(coerce=True, nullable=True, description="Dependent family in case of early retirement", alias="fiscalDetails.hasFamilyBurden")
209
+ fiscal_details_is_unmarried_with_dependant_child: Series[pd.BooleanDtype] = pa.Field(coerce=True, nullable=True, description="Not married with dependent child", alias="fiscalDetails.isUnmarriedWithDependantChild")
210
+ fiscal_details_is_disabled: Series[pd.BooleanDtype] = pa.Field(coerce=True, description="Disabled indicator", alias="fiscalDetails.isDisabled")
211
+ fiscal_details_merging_gross_net_code: Series[pd.StringDtype] = pa.Field(coerce=True, description="Merging gross net calculation code", alias="fiscalDetails.mergingGrossNetCalculation.code")
212
+ fiscal_details_merging_gross_net_description: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Merging gross net calculation description", alias="fiscalDetails.mergingGrossNetCalculation.description")
213
+ fiscal_details_is_young_employee: Series[pd.BooleanDtype] = pa.Field(coerce=True, nullable=True, description="Young employee indicator", alias="fiscalDetails.isYoungEmployee")
214
+ fiscal_details_tax_volunteerism_amount: Series[pd.Float64Dtype] = pa.Field(coerce=True, nullable=True, description="Tax volunteerism amount", alias="fiscalDetails.taxVolunteerismAmount")
215
+
216
+ class _Annotation:
217
+ primary_key = "employee_id"
218
+
219
+ class Config:
220
+ metadata = {"class": "FamilySituation", "dependencies": []}
@@ -0,0 +1,243 @@
1
+ """
2
+ Schemas for Employment resource
3
+
4
+ Following BrynQ SDK standards:
5
+ - Base schemas have no prefixes (reusable building blocks)
6
+ - Composite schemas use json_schema_extra={"prefix": "..."} for flat-to-nested conversion
7
+ - Uses Functions.flat_to_nested_with_prefix() in resource methods
8
+ """
9
+
10
+ from pydantic import BaseModel, Field
11
+ from typing import Optional, List, Literal
12
+
13
+
14
+ # ============================================
15
+ # BASE SCHEMAS (Reusable, No Prefixes)
16
+ # ============================================
17
+
18
+ class Name(BaseModel):
19
+ """Reusable name schema - no prefix in field names"""
20
+ last_name: str = Field(..., min_length=1, max_length=35, example="Janssens", description="The last name", alias="lastName")
21
+ first_name: str = Field(..., min_length=1, max_length=35, example="Ben", description="The first name", alias="firstName")
22
+
23
+ class Config:
24
+ populate_by_name = True
25
+
26
+
27
+ class Birth(BaseModel):
28
+ """Reusable birth schema - no prefix in field names"""
29
+ date_of_birth: str = Field(..., example="2022-01-01", description="Date of birth", alias="dateOfBirth")
30
+ place_of_birth: Optional[str] = Field(None, min_length=1, max_length=35, example="Leuven", description="Place of birth", alias="placeOfBirth")
31
+ country_of_birth: Optional[str] = Field(None, min_length=3, max_length=3, example="150", description="NIS Code of the nationality", alias="countryOfBirth")
32
+
33
+ class Config:
34
+ populate_by_name = True
35
+
36
+
37
+ class Address(BaseModel):
38
+ """Reusable address schema - no prefix in field names"""
39
+ type: Literal["OFFICIAL", "CORRESPONDENCE"] = Field(..., example="OFFICIAL", description="Type of address", alias="type")
40
+ street: str = Field(..., min_length=1, max_length=40, example="Bondgenotenlaan", description="Street name", alias="street")
41
+ house_number: str = Field(..., min_length=1, max_length=9, example="2", description="House number", alias="houseNumber")
42
+ post_box: Optional[str] = Field(None, min_length=1, max_length=4, example="A", description="Post box", alias="postBox")
43
+ postal_code: str = Field(..., min_length=1, max_length=14, example="3000", description="Postal code", alias="postalCode")
44
+ community: str = Field(..., min_length=1, max_length=35, example="Leuven", description="Community name", alias="community")
45
+ country: str = Field(..., min_length=3, max_length=3, example="150", description="NIS Code of the country", alias="country")
46
+
47
+ class Config:
48
+ populate_by_name = True
49
+
50
+
51
+ class ContactInformation(BaseModel):
52
+ """Reusable contact information schema - no prefix in field names"""
53
+ contact_scope: Literal["WORK", "PERSONAL"] = Field(..., example="WORK", description="Contact scope", alias="contactScope")
54
+ contact_method: Literal["EMAIL", "TELEPHONE", "MOBILE"] = Field(..., example="EMAIL", description="Contact method", alias="contactMethod")
55
+ contact_value: str = Field(..., min_length=1, max_length=100, example="test@example.com", description="Contact value", alias="contactValue")
56
+
57
+ class Config:
58
+ populate_by_name = True
59
+
60
+
61
+ class Dependant(BaseModel):
62
+ """Reusable dependant schema - no prefix in field names"""
63
+ not_disabled: int = Field(..., ge=0, le=99, example=1, description="Number of not disabled dependants", alias="notDisabled")
64
+ disabled: int = Field(..., ge=0, le=99, example=0, description="Number of disabled dependants", alias="disabled")
65
+
66
+ class Config:
67
+ populate_by_name = True
68
+
69
+
70
+ class Dependant65plus(BaseModel):
71
+ """Reusable dependant 65+ schema - no prefix in field names"""
72
+ not_disabled: int = Field(..., ge=0, le=99, example=1, description="Number of not disabled dependants over 65", alias="notDisabled")
73
+ disabled: int = Field(..., ge=0, le=99, example=0, description="Number of disabled dependants over 65", alias="disabled")
74
+ needing_care: int = Field(..., ge=0, le=99, example=0, description="Number of dependants over 65 needing care", alias="needingCare")
75
+
76
+ class Config:
77
+ populate_by_name = True
78
+
79
+
80
+ class BankAccount(BaseModel):
81
+ """Reusable bank account schema - no prefix in field names"""
82
+ iban: str = Field(..., min_length=5, max_length=34, example="BE11456373772248", description="IBAN", alias="iban")
83
+ bic: Optional[str] = Field(None, min_length=8, max_length=11, example="NTSBDEB1XXX", description="BIC code", alias="bic")
84
+
85
+ class Config:
86
+ populate_by_name = True
87
+
88
+
89
+ class C32a(BaseModel):
90
+ """Reusable C32a schema - no prefix in field names"""
91
+ current_month: str = Field(..., min_length=3, max_length=13, description="Current month", alias="currentMonth")
92
+ next_month: str = Field(..., min_length=3, max_length=13, description="Next month", alias="nextMonth")
93
+
94
+ class Config:
95
+ populate_by_name = True
96
+
97
+
98
+ class EmploymentPeriod(BaseModel):
99
+ """Reusable employment period schema - no prefix in field names"""
100
+ start_date: str = Field(..., example="2025-10-16", description="Employment start date", alias="startDate")
101
+ end_date: Optional[str] = Field(None, example="2025-10-16", description="Employment end date", alias="endDate")
102
+
103
+ class Config:
104
+ populate_by_name = True
105
+
106
+
107
+ class PersonalData(BaseModel):
108
+ """Schema for personal data - uses json_schema_extra for prefixes"""
109
+ national_registration_number: str = Field(..., pattern=r"^\d{11}$", example="86022402508", description="National registration number", alias="nationalRegistrationNumber")
110
+ name: Name = Field(..., description="Full name of the employee", alias="name", json_schema_extra={"prefix": "name_"})
111
+ gender: Literal["M", "V"] = Field(..., example="M", description="Gender", alias="gender")
112
+ nationality: str = Field(..., pattern=r"^\d{3}$", example="150", description="NIS Code of the nationality", alias="nationality")
113
+ official_language: Optional[Literal["NL", "FR", "DE", "EN"]] = Field(None, example="NL", description="Official language", alias="officialLanguage")
114
+ spoken_language: Optional[Literal["NL", "FR", "DE", "EN"]] = Field(None, example="NL", description="Spoken language", alias="spokenLanguage")
115
+ birth: Birth = Field(..., description="Birth information", alias="birth", json_schema_extra={"prefix": "birth_"})
116
+ is_disabled: Optional[bool] = Field(None, description="Disabled indicator", alias="isDisabled")
117
+
118
+ class Config:
119
+ populate_by_name = True
120
+
121
+
122
+ class AddressData(BaseModel):
123
+ """Schema for address data - supports list with indexed prefixes"""
124
+ addresses: List[Address] = Field(..., min_items=1, max_items=2, description="List of addresses", alias="addresses", json_schema_extra={"prefix": "addresses_"})
125
+
126
+ class Config:
127
+ populate_by_name = True
128
+
129
+
130
+ class ContactInformationData(BaseModel):
131
+ """Schema for contact information data - supports list with indexed prefixes"""
132
+ contact_information: List[ContactInformation] = Field(..., max_items=6, description="List of contact information", alias="contactInformation", json_schema_extra={"prefix": "contact_information_"})
133
+
134
+ class Config:
135
+ populate_by_name = True
136
+
137
+
138
+ class Dependants(BaseModel):
139
+ """Schema for all dependants - uses json_schema_extra for prefixes"""
140
+ children: Optional[Dependant] = Field(None, description="Dependent children", alias="children", json_schema_extra={"prefix": "children_"})
141
+ sixty_five_plus: Optional[Dependant65plus] = Field(None, description="Dependent 65+", alias="65plus", json_schema_extra={"prefix": "65plus_"})
142
+ others: Optional[Dependant] = Field(None, description="Other dependents", alias="others", json_schema_extra={"prefix": "others_"})
143
+
144
+ class Config:
145
+ populate_by_name = True
146
+
147
+
148
+ class PartnerInformation(BaseModel):
149
+ """Schema for partner information - uses json_schema_extra for prefixes"""
150
+ name: Optional[Name] = Field(None, description="Partner name", alias="name", json_schema_extra={"prefix": "name_"})
151
+ date_of_birth: Optional[str] = Field(None, example="1956-10-30", description="Partner date of birth", alias="dateOfBirth")
152
+ income_type: Optional[Literal["SINGLE", "DOUBLE", "NO_INCOME"]] = Field(None, example="SINGLE", description="Income type", alias="incomeType")
153
+ is_disabled: Optional[bool] = Field(None, description="Partner disabled indicator", alias="isDisabled")
154
+
155
+ class Config:
156
+ populate_by_name = True
157
+
158
+
159
+ class FamilySituation(BaseModel):
160
+ """Schema for family situation - uses json_schema_extra for prefixes"""
161
+ marital_status: Literal["SINGLE", "MARRIED", "WIDOWED", "DIVORCED", "SEPARATED", "LEGAL_COHABITATION"] = Field(..., example="SINGLE", description="Marital status", alias="maritalStatus")
162
+ marital_status_date: Optional[str] = Field(None, example="1984-10-30", description="Date when civil status was applied", alias="maritalStatusDate")
163
+ date_of_marriage_or_cohabitation: Optional[str] = Field(None, example="1984-10-30", description="Date of marriage or cohabitation", alias="dateOfMarriageOrCohabitation")
164
+ partner_information: Optional[PartnerInformation] = Field(None, description="Partner information", alias="partnerInformation", json_schema_extra={"prefix": "partner_information_"})
165
+ dependants: Optional[Dependants] = Field(None, description="Dependants information", alias="dependants", json_schema_extra={"prefix": "dependants_"})
166
+
167
+ class Config:
168
+ populate_by_name = True
169
+
170
+
171
+ class EmployeeDetails(BaseModel):
172
+ """Schema for employee details - uses json_schema_extra for prefixes"""
173
+ personal_data: PersonalData = Field(..., description="Personal data", alias="personalData", json_schema_extra={"prefix": "personal_data_"})
174
+ address_data: AddressData = Field(..., description="Address data", alias="addressData", json_schema_extra={"prefix": "address_data_"})
175
+ contact_information_data: Optional[ContactInformationData] = Field(None, description="Contact information data", alias="contactInformationData", json_schema_extra={"prefix": "contact_information_data_"})
176
+ family_situation_data: Optional[FamilySituation] = Field(None, description="Family situation data", alias="familySituationData", json_schema_extra={"prefix": "family_situation_data_"})
177
+
178
+ class Config:
179
+ populate_by_name = True
180
+
181
+
182
+ class EmployerDetails(BaseModel):
183
+ """Schema for employer details - no nested prefixes needed"""
184
+ official_joint_committee: Optional[str] = Field(None, pattern=r"^\d{6}$", example="302000", description="Official joint committee code", alias="officialJointCommittee")
185
+ business_unit: Optional[str] = Field(None, pattern=r"^\d{10}$", example="2288734794", description="The code of the business unit", alias="businessUnit")
186
+
187
+ class Config:
188
+ populate_by_name = True
189
+
190
+
191
+ class EmploymentDetails(BaseModel):
192
+ """Schema for employment details - uses json_schema_extra for prefixes"""
193
+ employee_type: Literal["WHITE_COLLAR", "LABOURER", "BLUE_COLLAR", "STUDENT_BLUE_COLLAR", "STUDENT_WHITE_COLLAR", "FLEX_BLUE_COLLAR", "FLEX_WHITE_COLLAR"] = Field(..., description="Employee type", alias="employeeType")
194
+ agreement_type: Optional[Literal["INTERNAL", "EXTERNAL"]] = Field(None, description="Type of the agreement", alias="agreementType")
195
+ employment_period: EmploymentPeriod = Field(..., description="Employment period", alias="employmentPeriod", json_schema_extra={"prefix": "employment_period_"})
196
+ in_organization_date: Optional[str] = Field(None, example="2025-10-16", description="In organization date", alias="inOrganizationDate")
197
+ remuneration: Optional[BankAccount] = Field(None, description="Remuneration bank account", alias="remuneration", json_schema_extra={"prefix": "remuneration_"})
198
+ c32a: Optional[C32a] = Field(None, description="C32a information", alias="c32a", json_schema_extra={"prefix": "c32a_"})
199
+ function: Optional[str] = Field(None, min_length=1, max_length=8, description="Function code", alias="function")
200
+ hours_per_week_full_time: Optional[float] = Field(None, ge=0, le=99, description="Hours per week full time", alias="hoursPerWeekFullTime")
201
+ number_of_numerator_employment_fraction: Optional[float] = Field(None, description="Number of numerator employment fraction", alias="numberOfNumeratorEmploymentFraction")
202
+ number_of_work_regime: Optional[float] = Field(None, le=7, description="Number of work regime", alias="numberOfWorkRegime")
203
+ students_quarters: Optional[List[int]] = Field(None, min_items=1, max_items=5, example=[10], description="Students quarters", alias="studentsQuarters")
204
+ is_disabled_for_nsso: Optional[bool] = Field(None, description="Is disabled for NSSO", alias="isDisabledForNSSO")
205
+
206
+ class Config:
207
+ populate_by_name = True
208
+
209
+
210
+
211
+ class EmploymentCreate(BaseModel):
212
+ """
213
+ Schema for POST /employers/{employerId}/employments endpoint - New employee & agreement
214
+
215
+ Uses json_schema_extra with prefixes for flat-to-nested conversion support.
216
+ Works with Functions.flat_to_nested_with_prefix() to convert flat dictionaries
217
+ to properly nested structures.
218
+ """
219
+ employee: EmployeeDetails = Field(..., description="The details of a new employee", alias="employee", json_schema_extra={"prefix": "employee_"})
220
+ employer: Optional[EmployerDetails] = Field(None, description="Employer details", alias="employer", json_schema_extra={"prefix": "employer_"})
221
+ employment: EmploymentDetails = Field(..., description="Employment details", alias="employment", json_schema_extra={"prefix": "employment_"})
222
+
223
+ class Config:
224
+ populate_by_name = True
225
+
226
+
227
+ class EmploymentRehire(BaseModel):
228
+ """
229
+ Schema for POST /employers/{employerId}/employees/{employeeId}/employments endpoint - Existing employee
230
+
231
+ This endpoint enables rehiring a previously known employee. The employee is already known
232
+ within Connect for the employer (BOR level) and has an existing employeeId. Personal data
233
+ is not required.
234
+
235
+ Uses json_schema_extra with prefixes for flat-to-nested conversion support.
236
+ Works with Functions.flat_to_nested_with_prefix() to convert flat dictionaries
237
+ to properly nested structures.
238
+ """
239
+ employer: Optional[EmployerDetails] = Field(None, description="Employer details such as joint committee and business unit", alias="employer", json_schema_extra={"prefix": "employer_"})
240
+ employment: EmploymentDetails = Field(..., description="Employment details including period, employee type, etc.", alias="employment", json_schema_extra={"prefix": "employment_"})
241
+
242
+ class Config:
243
+ populate_by_name = True
@@ -0,0 +1,28 @@
1
+ import pandas as pd
2
+ import pandera as pa
3
+ from pandera.typing import Series
4
+ from brynq_sdk_functions import BrynQPanderaDataFrameModel
5
+
6
+
7
+ class JointCommitteeGet(BrynQPanderaDataFrameModel):
8
+ code: Series[pd.StringDtype] = pa.Field(coerce=True, description="Joint committee code")
9
+ description: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Description")
10
+
11
+ class _Annotation:
12
+ primary_key = "code"
13
+ foreign_keys = {}
14
+
15
+ class Config:
16
+ metadata = {"class": "JointCommittee", "dependencies": []}
17
+
18
+
19
+ class FunctionGet(BrynQPanderaDataFrameModel):
20
+ code: Series[pd.StringDtype] = pa.Field(coerce=True, description="Function code")
21
+ description: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Description")
22
+
23
+ class _Annotation:
24
+ primary_key = "code"
25
+ foreign_keys = {}
26
+
27
+ class Config:
28
+ metadata = {"class": "Function", "dependencies": []}
@@ -0,0 +1,37 @@
1
+ """
2
+ Schemas for Planning resource
3
+ """
4
+
5
+ import pandas as pd
6
+ import pandera as pa
7
+ from pandera.typing import Series
8
+ from brynq_sdk_functions import BrynQPanderaDataFrameModel
9
+
10
+
11
+ # GET Schema for Countries
12
+ class CountryGet(BrynQPanderaDataFrameModel):
13
+ """Schema for GET /v1/countries endpoint"""
14
+
15
+ description: Series[pd.StringDtype] = pa.Field(coerce=True, description="Country name", alias="description")
16
+ nis_code: Series[pd.StringDtype] = pa.Field(coerce=True, description="NISCode of the country", alias="NISCode")
17
+
18
+ class _Annotation:
19
+ primary_key = "nis_code"
20
+
21
+ class Config:
22
+ metadata = {"class": "Country", "dependencies": []}
23
+
24
+
25
+ # GET Schema for Belgian Cities
26
+ class BelgianCityGet(BrynQPanderaDataFrameModel):
27
+ """Schema for GET /v1/belgian-cities endpoint"""
28
+
29
+ postal_code: Series[pd.StringDtype] = pa.Field(coerce=True, description="Belgian city postal code", alias="postalCode")
30
+ name: Series[pd.StringDtype] = pa.Field(coerce=True, description="Belgian city name", alias="name")
31
+ nis_code: Series[pd.StringDtype] = pa.Field(coerce=True, description="Belgian city NIS code", alias="NISCode")
32
+
33
+ class _Annotation:
34
+ primary_key = "nis_code"
35
+
36
+ class Config:
37
+ metadata = {"class": "BelgianCity", "dependencies": []}
@@ -0,0 +1,84 @@
1
+ """
2
+ Schemas for Basic Salaries resource
3
+ """
4
+
5
+ from typing import Optional, List, Literal
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 BasicSalaryGet(BrynQPanderaDataFrameModel):
18
+ """Schema for GET /v1/agreements/{agreementId}/basic-salaries endpoint (rows per salary element)."""
19
+
20
+ # Meta
21
+ agreement_id: Series[pd.StringDtype] = pa.Field(coerce=True, description="Identifies the agreement and is unique for each agreement", alias="agreementId")
22
+
23
+ # Period (from parent basicSalaries segment)
24
+ period_start_date: Series[pd.StringDtype] = pa.Field(coerce=True, description="The start date of the record", alias="basicSalaries.period.startDate")
25
+ period_end_date: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="The end date of the record", alias="basicSalaries.period.endDate")
26
+
27
+ # Salary element details
28
+ salary_code_id: Series[pd.StringDtype] = pa.Field(coerce=True, description="The identifier of the salary code", alias="salaryCode.salaryCodeId")
29
+ salary_code_description: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="The description of the salary code", alias="salaryCode.description")
30
+
31
+ unit_quantity: Series[pd.Float64Dtype] = pa.Field(coerce=True, nullable=True, description="The number of units associated with the salary code", alias="unitQuantity")
32
+ unit_amount: Series[pd.Float64Dtype] = pa.Field(coerce=True, nullable=True, description="The amount per unit associated with the salary code", alias="unitAmount")
33
+ percentage: Series[pd.Float64Dtype] = pa.Field(coerce=True, nullable=True, description="The percentage associated with the salary code", alias="percentage")
34
+ amount: Series[pd.Float64Dtype] = pa.Field(coerce=True, nullable=True, description="The amount associated with the salary code", alias="amount")
35
+ number_of_days: Series[pd.Float64Dtype] = pa.Field(coerce=True, nullable=True, description="The number of days associated with the salary code", alias="numberOfDays")
36
+
37
+ cost_center_id: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="The service receiver unique cost center identifier", alias="costCenter.costCenterId")
38
+ cost_center_description: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="Description of the cost center", alias="costCenter.description")
39
+
40
+ reason: Series[pd.StringDtype] = pa.Field(coerce=True, nullable=True, description="The reason of the salary code", alias="reason")
41
+
42
+ class _Annotation:
43
+ primary_key = "agreement_id"
44
+
45
+ class Config:
46
+ metadata = {"class": "BasicSalary", "dependencies": []}
47
+
48
+
49
+ # ============================================
50
+ # PATCH SCHEMAS (Pydantic - Request)
51
+ # ============================================
52
+
53
+ class BasicSalaryAttributes(BaseModel):
54
+ """Attributes for an INSERT action in a basic salary element."""
55
+ unit_quantity: Optional[float] = Field(None, description="The number of units associated with the salary code", alias="unitQuantity")
56
+ unit_amount: Optional[float] = Field(None, description="The amount per unit associated with the salary code", alias="unitAmount")
57
+ percentage: Optional[float] = Field(None, description="The percentage associated with the salary code", alias="percentage")
58
+ amount: Optional[float] = Field(None, description="The amount associated with the salary code", alias="amount")
59
+ number_of_days: Optional[float] = Field(None, description="The number of days associated with the salary code", alias="numberOfDays")
60
+ cost_center_id: Optional[str] = Field(None, min_length=1, max_length=12, description="The service receiver unique cost center identifier", alias="costCenterId")
61
+ reason: Optional[str] = Field(None, min_length=1, max_length=50, description="The reason of the salary code", alias="reason")
62
+
63
+ class Config:
64
+ populate_by_name = True
65
+
66
+
67
+ class BasicSalaryElementUpdate(BaseModel):
68
+ """Schema for a single basic salary element update operation."""
69
+ action: Literal["DELETE", "INSERT"] = Field(..., description="DELETE will remove all elements with this salaryCodeId in the window; INSERT adds a new element", alias="action")
70
+ salary_code_id: str = Field(..., min_length=1, max_length=6, description="The identifier of the salary code", alias="salaryCodeId")
71
+ attributes: Optional[BasicSalaryAttributes] = Field(None, description="Attributes for INSERT action", alias="attributes", json_schema_extra={"prefix": "attributes_"})
72
+
73
+ class Config:
74
+ populate_by_name = True
75
+
76
+
77
+ class PatchBasicSalariesRequest(BaseModel):
78
+ """Schema for PATCH /v1/agreements/{agreementId}/basic-salaries endpoint."""
79
+ from_date: str = Field(..., description="The lower bound of the time window for which data will be altered", alias="fromDate")
80
+ until_date: Optional[str] = Field(None, description="The upper bound of the time window for which data will be altered", alias="untilDate")
81
+ basic_salary_elements: List[BasicSalaryElementUpdate] = Field(..., min_items=1, description="List of inserted or deleted salary elements for the given time window", alias="basicSalaryElements", json_schema_extra={"prefix": "basic_salary_elements_"})
82
+
83
+ class Config:
84
+ populate_by_name = True