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.
- brynq_sdk_acerta/__init__.py +14 -0
- brynq_sdk_acerta/acerta.py +118 -0
- brynq_sdk_acerta/addresses.py +99 -0
- brynq_sdk_acerta/agreements.py +426 -0
- brynq_sdk_acerta/bank_accounts.py +90 -0
- brynq_sdk_acerta/code_lists.py +264 -0
- brynq_sdk_acerta/company_cars.py +135 -0
- brynq_sdk_acerta/contact_information.py +79 -0
- brynq_sdk_acerta/cost_centers.py +94 -0
- brynq_sdk_acerta/employees.py +121 -0
- brynq_sdk_acerta/employees_additional_information.py +87 -0
- brynq_sdk_acerta/employer.py +179 -0
- brynq_sdk_acerta/family_members.py +99 -0
- brynq_sdk_acerta/family_situation.py +99 -0
- brynq_sdk_acerta/inservice.py +99 -0
- brynq_sdk_acerta/salaries.py +74 -0
- brynq_sdk_acerta/schemas/__init__.py +135 -0
- brynq_sdk_acerta/schemas/address.py +80 -0
- brynq_sdk_acerta/schemas/agreement.py +982 -0
- brynq_sdk_acerta/schemas/bank_account.py +87 -0
- brynq_sdk_acerta/schemas/company_car.py +124 -0
- brynq_sdk_acerta/schemas/contact_information.py +83 -0
- brynq_sdk_acerta/schemas/cost_center.py +82 -0
- brynq_sdk_acerta/schemas/employee.py +406 -0
- brynq_sdk_acerta/schemas/employer.py +71 -0
- brynq_sdk_acerta/schemas/family.py +220 -0
- brynq_sdk_acerta/schemas/in_service.py +243 -0
- brynq_sdk_acerta/schemas/in_service_config.py +28 -0
- brynq_sdk_acerta/schemas/planning.py +37 -0
- brynq_sdk_acerta/schemas/salaries.py +84 -0
- brynq_sdk_acerta-1.1.1.dist-info/METADATA +21 -0
- brynq_sdk_acerta-1.1.1.dist-info/RECORD +34 -0
- brynq_sdk_acerta-1.1.1.dist-info/WHEEL +5 -0
- brynq_sdk_acerta-1.1.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
from typing import Dict, Any, Tuple
|
|
2
|
+
import pandas as pd
|
|
3
|
+
import requests
|
|
4
|
+
from brynq_sdk_functions import Functions
|
|
5
|
+
from .schemas.salaries import BasicSalaryGet, PatchBasicSalariesRequest
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from .acerta import Acerta
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Salaries:
|
|
12
|
+
"""Resource class for Agreement Basic Salaries endpoints"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, acerta):
|
|
15
|
+
self.acerta: Acerta = acerta
|
|
16
|
+
self.base_uri = "agreement-data-management/v1/agreements"
|
|
17
|
+
|
|
18
|
+
def get(self) -> Tuple[pd.DataFrame, pd.DataFrame]:
|
|
19
|
+
"""
|
|
20
|
+
GET /agreement-data-management/v1/agreements/{agreementId}/basic-salaries - Basic Salaries
|
|
21
|
+
|
|
22
|
+
Retrieves basic salary history segments and their salary elements for all cached agreements.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
Tuple[pd.DataFrame, pd.DataFrame]: (valid_df, invalid_df) after normalizing and validating
|
|
28
|
+
"""
|
|
29
|
+
if not self.acerta._agreement_ids:
|
|
30
|
+
self.acerta.agreements.get()
|
|
31
|
+
|
|
32
|
+
frames = []
|
|
33
|
+
for agreement_id in self.acerta._agreement_ids:
|
|
34
|
+
response = self.acerta.session.get(
|
|
35
|
+
url=f"{self.acerta.base_url}/{self.base_uri}/{agreement_id}/basic-salaries",
|
|
36
|
+
timeout=self.acerta.TIMEOUT,
|
|
37
|
+
)
|
|
38
|
+
response.raise_for_status()
|
|
39
|
+
raw = response.json()
|
|
40
|
+
df = pd.json_normalize(
|
|
41
|
+
raw,
|
|
42
|
+
record_path=["basicSalaries", "basicSalaryElements"],
|
|
43
|
+
meta=["agreementId", ["basicSalaries", "period", "startDate"], ["basicSalaries", "period", "endDate"]],
|
|
44
|
+
errors="ignore",
|
|
45
|
+
sep=".",
|
|
46
|
+
)
|
|
47
|
+
frames.append(df)
|
|
48
|
+
|
|
49
|
+
combined = pd.concat(frames, ignore_index=True) if frames else pd.DataFrame()
|
|
50
|
+
|
|
51
|
+
valid_df, invalid_df = Functions.validate_data(combined, BasicSalaryGet)
|
|
52
|
+
|
|
53
|
+
return valid_df, invalid_df
|
|
54
|
+
|
|
55
|
+
def update(self, agreement_id: str, data: Dict[str, Any]) -> requests.Response:
|
|
56
|
+
"""
|
|
57
|
+
PATCH /agreement-data-management/v1/agreements/{agreementId}/basic-salaries - Basic Salaries
|
|
58
|
+
|
|
59
|
+
Update basic salary elements for a given agreement in a time window.
|
|
60
|
+
"""
|
|
61
|
+
nested_data = Functions.flat_to_nested_with_prefix(data, PatchBasicSalariesRequest)
|
|
62
|
+
|
|
63
|
+
# Validate the nested data
|
|
64
|
+
validated_data = PatchBasicSalariesRequest(**nested_data)
|
|
65
|
+
|
|
66
|
+
# Make API request
|
|
67
|
+
response = self.acerta.session.patch(
|
|
68
|
+
url=f"{self.acerta.base_url}/{self.base_uri}/{agreement_id}/basic-salaries",
|
|
69
|
+
json=validated_data.model_dump(by_alias=True, exclude_none=True),
|
|
70
|
+
timeout=self.acerta.TIMEOUT,
|
|
71
|
+
)
|
|
72
|
+
response.raise_for_status()
|
|
73
|
+
|
|
74
|
+
return response
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Schemas module for Acerta SDK
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from .agreement import AgreementGet, AgreementRemunerationBankAccountCreate, AgreementRemunerationBankAccountUpdate
|
|
6
|
+
from .family import (
|
|
7
|
+
FamilyMemberGet,
|
|
8
|
+
FamilySituationGet,
|
|
9
|
+
FamilySituationUpdate,
|
|
10
|
+
FamilyMemberCreate,
|
|
11
|
+
FamilyMemberPersonalia,
|
|
12
|
+
FamilyMemberName,
|
|
13
|
+
FamilyMemberOther,
|
|
14
|
+
CivilStatus,
|
|
15
|
+
Partner,
|
|
16
|
+
DependantsChildren,
|
|
17
|
+
DependantsOver65,
|
|
18
|
+
DependantsOthers,
|
|
19
|
+
Dependants,
|
|
20
|
+
FiscalDetails
|
|
21
|
+
)
|
|
22
|
+
from .bank_account import BankAccountUpdate, BankOwner, OwnerName, BankDetails
|
|
23
|
+
from .employee import (
|
|
24
|
+
AdditionalInformationGet,
|
|
25
|
+
AdditionalInformationUpdate,
|
|
26
|
+
PersonalDetailsGet,
|
|
27
|
+
PersonalDetailsUpdate,
|
|
28
|
+
EmployeeName,
|
|
29
|
+
EmployeeBirth,
|
|
30
|
+
AddressBase,
|
|
31
|
+
ContactBase,
|
|
32
|
+
EmergencyContactBase,
|
|
33
|
+
EmployeePersonalDetails,
|
|
34
|
+
EmployeeAddressDetails,
|
|
35
|
+
EmployeeAdditionalInformation,
|
|
36
|
+
EmployeeContactInformation,
|
|
37
|
+
EmployeeCivilStatus,
|
|
38
|
+
EmployeePartner,
|
|
39
|
+
EmployeeDependants,
|
|
40
|
+
EmployeeDependantsChildren,
|
|
41
|
+
EmployeeDependantsOver65,
|
|
42
|
+
EmployeeDependantsOthers,
|
|
43
|
+
EmployeeFiscalDetails,
|
|
44
|
+
EmployeeFamilySituation,
|
|
45
|
+
EmployeeBankDetails,
|
|
46
|
+
EmployeeForeignBankAccount,
|
|
47
|
+
EmployeeBankAccountOwner,
|
|
48
|
+
EmployeeBankAccount,
|
|
49
|
+
EmployeeCreate
|
|
50
|
+
)
|
|
51
|
+
from .contact_information import ContactInformationGet, ContactInformationUpdate, Contact, EmergencyContact
|
|
52
|
+
from .address import AddressGet, AddressUpdate, Address, OfficialAddressUpdate, CorrespondenceAddressUpdate
|
|
53
|
+
from .planning import CountryGet, BelgianCityGet
|
|
54
|
+
from .employer import JointCommitteeGet, FunctionGet, SalaryCodeGet
|
|
55
|
+
from .in_service import EmploymentCreate, EmploymentRehire
|
|
56
|
+
from .cost_center import CostCenterGet, CostCenterCreate, CostCenterDescription, CostCenterPeriod
|
|
57
|
+
from .salaries import BasicSalaryGet, PatchBasicSalariesRequest
|
|
58
|
+
from .company_car import CompanyCarGet, CompanyCarCreate, CompanyCarUpdate
|
|
59
|
+
|
|
60
|
+
__all__ = [
|
|
61
|
+
'AgreementGet',
|
|
62
|
+
'AgreementRemunerationBankAccountCreate',
|
|
63
|
+
'AgreementRemunerationBankAccountUpdate',
|
|
64
|
+
'FamilyMemberGet',
|
|
65
|
+
'FamilySituationGet',
|
|
66
|
+
'FamilySituationUpdate',
|
|
67
|
+
'FamilyMemberCreate',
|
|
68
|
+
'FamilyMemberPersonalia',
|
|
69
|
+
'FamilyMemberName',
|
|
70
|
+
'FamilyMemberOther',
|
|
71
|
+
'CivilStatus',
|
|
72
|
+
'Partner',
|
|
73
|
+
'DependantsChildren',
|
|
74
|
+
'DependantsOver65',
|
|
75
|
+
'DependantsOthers',
|
|
76
|
+
'Dependants',
|
|
77
|
+
'FiscalDetails',
|
|
78
|
+
'BankAccountLinkGet',
|
|
79
|
+
'BankAccountUpdate',
|
|
80
|
+
'BankOwner',
|
|
81
|
+
'OwnerName',
|
|
82
|
+
'BankDetails',
|
|
83
|
+
'EmployeeGet',
|
|
84
|
+
'ContactInformationGet',
|
|
85
|
+
'ContactInformationUpdate',
|
|
86
|
+
'Contact',
|
|
87
|
+
'EmergencyContact',
|
|
88
|
+
'AddressGet',
|
|
89
|
+
'AddressUpdate',
|
|
90
|
+
'Address',
|
|
91
|
+
'OfficialAddressUpdate',
|
|
92
|
+
'CorrespondenceAddressUpdate',
|
|
93
|
+
'AdditionalInformationGet',
|
|
94
|
+
'AdditionalInformationUpdate',
|
|
95
|
+
'PersonalDetailsGet',
|
|
96
|
+
'PersonalDetailsUpdate',
|
|
97
|
+
'EmployeeName',
|
|
98
|
+
'EmployeeBirth',
|
|
99
|
+
'AddressBase',
|
|
100
|
+
'ContactBase',
|
|
101
|
+
'EmergencyContactBase',
|
|
102
|
+
'EmployeePersonalDetails',
|
|
103
|
+
'EmployeeAddressDetails',
|
|
104
|
+
'EmployeeAdditionalInformation',
|
|
105
|
+
'EmployeeContactInformation',
|
|
106
|
+
'EmployeeCivilStatus',
|
|
107
|
+
'EmployeePartner',
|
|
108
|
+
'EmployeeDependants',
|
|
109
|
+
'EmployeeDependantsChildren',
|
|
110
|
+
'EmployeeDependantsOver65',
|
|
111
|
+
'EmployeeDependantsOthers',
|
|
112
|
+
'EmployeeFiscalDetails',
|
|
113
|
+
'EmployeeFamilySituation',
|
|
114
|
+
'EmployeeBankDetails',
|
|
115
|
+
'EmployeeForeignBankAccount',
|
|
116
|
+
'EmployeeBankAccountOwner',
|
|
117
|
+
'EmployeeBankAccount',
|
|
118
|
+
'EmployeeCreate',
|
|
119
|
+
'CountryGet',
|
|
120
|
+
'BelgianCityGet',
|
|
121
|
+
'JointCommitteeGet',
|
|
122
|
+
'FunctionGet',
|
|
123
|
+
'SalaryCodeGet',
|
|
124
|
+
'EmploymentCreate',
|
|
125
|
+
'EmploymentRehire',
|
|
126
|
+
'CostCenterGet',
|
|
127
|
+
'CostCenterCreate',
|
|
128
|
+
'CostCenterDescription',
|
|
129
|
+
'CostCenterPeriod',
|
|
130
|
+
'BasicSalaryGet',
|
|
131
|
+
'PatchBasicSalariesRequest',
|
|
132
|
+
'CompanyCarGet',
|
|
133
|
+
'CompanyCarCreate',
|
|
134
|
+
'CompanyCarUpdate'
|
|
135
|
+
]
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Schema for GET /employee-data-management/v3/employees/{employeeId}/addresses
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import pandas as pd
|
|
6
|
+
import pandera as pa
|
|
7
|
+
from pandera.typing import Series
|
|
8
|
+
from typing import Optional
|
|
9
|
+
from pydantic import BaseModel, Field
|
|
10
|
+
from brynq_sdk_functions import BrynQPanderaDataFrameModel
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AddressGet(BrynQPanderaDataFrameModel):
|
|
14
|
+
"""Schema for GET /employee-data-management/v3/employees/{employeeId}/addresses endpoint."""
|
|
15
|
+
|
|
16
|
+
# Employee identification
|
|
17
|
+
employee_id: Series[pd.StringDtype] = pa.Field(coerce=True, description="Employee identifier", alias="employeeId")
|
|
18
|
+
|
|
19
|
+
# Period information
|
|
20
|
+
period_start_date: Series[pd.StringDtype] = pa.Field(coerce=True, description="Address period start date", alias="period.startDate")
|
|
21
|
+
period_end_date: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Address period end date", alias="period.endDate")
|
|
22
|
+
|
|
23
|
+
# Official address
|
|
24
|
+
official_street: Series[pd.StringDtype] = pa.Field(coerce=True, description="Official address street", alias="officialAddress.street")
|
|
25
|
+
official_house_number: Series[pd.StringDtype] = pa.Field(coerce=True, description="Official address house number", alias="officialAddress.houseNumber")
|
|
26
|
+
official_post_box: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Official address post box", alias="officialAddress.postBox")
|
|
27
|
+
official_postal_code: Series[pd.StringDtype] = pa.Field(coerce=True, description="Official address postal code", alias="officialAddress.postalCode")
|
|
28
|
+
official_community: Series[pd.StringDtype] = pa.Field(coerce=True, description="Official address community", alias="officialAddress.community")
|
|
29
|
+
official_country_name: Series[pd.StringDtype] = pa.Field(coerce=True, description="Official address country name", alias="officialAddress.country.name")
|
|
30
|
+
official_country_nis_code: Series[pd.StringDtype] = pa.Field(coerce=True, description="Official address country NIS code", alias="officialAddress.country.NISCode")
|
|
31
|
+
|
|
32
|
+
# Correspondence address (nullable)
|
|
33
|
+
correspondence_street: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Correspondence address street", alias="correspondenceAddress.street")
|
|
34
|
+
correspondence_house_number: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Correspondence address house number", alias="correspondenceAddress.houseNumber")
|
|
35
|
+
correspondence_post_box: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Correspondence address post box", alias="correspondenceAddress.postBox")
|
|
36
|
+
correspondence_postal_code: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Correspondence address postal code", alias="correspondenceAddress.postalCode")
|
|
37
|
+
correspondence_community: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Correspondence address community", alias="correspondenceAddress.community")
|
|
38
|
+
correspondence_country_name: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Correspondence address country name", alias="correspondenceAddress.country.name")
|
|
39
|
+
correspondence_country_nis_code: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Correspondence address country NIS code", alias="correspondenceAddress.country.NISCode")
|
|
40
|
+
|
|
41
|
+
class _Annotation:
|
|
42
|
+
primary_key = "employee_id"
|
|
43
|
+
foreign_keys = {}
|
|
44
|
+
|
|
45
|
+
class Config:
|
|
46
|
+
metadata = {"class": "Address", "dependencies": []}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# Pydantic schemas for PATCH address
|
|
50
|
+
# Uses json_schema_extra for prefix-based field mapping
|
|
51
|
+
|
|
52
|
+
class Address(BaseModel):
|
|
53
|
+
"""Reusable address schema (no prefix in field names)"""
|
|
54
|
+
street: str = Field(..., min_length=1, max_length=40, example="Bondgenotenlaan", description="Street name", alias="street")
|
|
55
|
+
house_number: str = Field(..., min_length=1, max_length=9, example="2", description="House number", alias="houseNumber")
|
|
56
|
+
post_box: Optional[str] = Field(None, min_length=1, max_length=4, example="A", description="Box number", alias="postBox")
|
|
57
|
+
postal_code: str = Field(..., min_length=1, max_length=14, example="3000", description="Postal code", alias="postalCode")
|
|
58
|
+
community: str = Field(..., min_length=1, max_length=35, example="Leuven", description="City name", alias="community")
|
|
59
|
+
country: str = Field(..., min_length=3, max_length=3, example="150", description="NIS Code of the country", alias="country")
|
|
60
|
+
|
|
61
|
+
class Config:
|
|
62
|
+
populate_by_name = True
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# Backward compatibility aliases
|
|
66
|
+
OfficialAddressUpdate = Address
|
|
67
|
+
CorrespondenceAddressUpdate = Address
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class AddressUpdate(BaseModel):
|
|
71
|
+
"""Schema for PATCH /employee-data-management/v3/employees/{employeeId}/addresses endpoint"""
|
|
72
|
+
# Function parameters
|
|
73
|
+
employee_id: str = Field(..., description="Employee identifier", alias="employeeId")
|
|
74
|
+
|
|
75
|
+
from_date: Optional[str] = Field(None, example="2022-01-01", description="Date from which this information is valid", alias="fromDate")
|
|
76
|
+
official_address: Optional[Address] = Field(None, description="Official address of the employee", alias="officialAddress", json_schema_extra={"prefix": "official_address_"})
|
|
77
|
+
correspondence_address: Optional[Address] = Field(None, description="Correspondence address of the employee", alias="correspondenceAddress", json_schema_extra={"prefix": "correspondence_address_"})
|
|
78
|
+
|
|
79
|
+
class Config:
|
|
80
|
+
populate_by_name = True
|