brynq-sdk-nmbrs 2.3.1.dev0__py3-none-any.whl → 2.3.2.dev0__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_nmbrs/__init__.py +86 -80
- brynq_sdk_nmbrs/address.py +82 -2
- brynq_sdk_nmbrs/children.py +96 -61
- brynq_sdk_nmbrs/companies.py +45 -1
- brynq_sdk_nmbrs/debtors.py +76 -2
- brynq_sdk_nmbrs/department.py +113 -1
- brynq_sdk_nmbrs/document.py +50 -0
- brynq_sdk_nmbrs/employee_wage_tax_settings.py +16 -9
- brynq_sdk_nmbrs/function.py +128 -2
- brynq_sdk_nmbrs/leave.py +105 -8
- brynq_sdk_nmbrs/salaries.py +75 -3
- brynq_sdk_nmbrs/schedules.py +77 -3
- brynq_sdk_nmbrs/schemas/address.py +26 -0
- brynq_sdk_nmbrs/schemas/children.py +67 -0
- brynq_sdk_nmbrs/schemas/company.py +16 -0
- brynq_sdk_nmbrs/schemas/debtor.py +23 -1
- brynq_sdk_nmbrs/schemas/department.py +33 -0
- brynq_sdk_nmbrs/schemas/document.py +13 -0
- brynq_sdk_nmbrs/schemas/employees.py +3 -1
- brynq_sdk_nmbrs/schemas/function.py +28 -0
- brynq_sdk_nmbrs/schemas/leave.py +12 -0
- brynq_sdk_nmbrs/schemas/salary.py +18 -0
- brynq_sdk_nmbrs/schemas/schedules.py +49 -0
- brynq_sdk_nmbrs/schemas/social_insurance.py +39 -6
- brynq_sdk_nmbrs/schemas/wage_tax.py +65 -5
- brynq_sdk_nmbrs/schemas/wage_tax_settings.py +42 -29
- brynq_sdk_nmbrs/social_insurance.py +81 -3
- brynq_sdk_nmbrs/wage_tax.py +104 -3
- {brynq_sdk_nmbrs-2.3.1.dev0.dist-info → brynq_sdk_nmbrs-2.3.2.dev0.dist-info}/METADATA +1 -1
- brynq_sdk_nmbrs-2.3.2.dev0.dist-info/RECORD +55 -0
- brynq_sdk_nmbrs-2.3.1.dev0.dist-info/RECORD +0 -52
- {brynq_sdk_nmbrs-2.3.1.dev0.dist-info → brynq_sdk_nmbrs-2.3.2.dev0.dist-info}/WHEEL +0 -0
- {brynq_sdk_nmbrs-2.3.1.dev0.dist-info → brynq_sdk_nmbrs-2.3.2.dev0.dist-info}/top_level.txt +0 -0
brynq_sdk_nmbrs/schedules.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import pandas as pd
|
|
2
2
|
import requests
|
|
3
|
-
import math
|
|
4
3
|
from brynq_sdk_functions import Functions
|
|
5
|
-
from .schemas.schedules import ScheduleGet, ScheduleCreate
|
|
4
|
+
from .schemas.schedules import ScheduleGet, ScheduleCreate, ScheduleUpdate
|
|
6
5
|
from datetime import datetime
|
|
7
|
-
from typing import Dict, Any,
|
|
6
|
+
from typing import Dict, Any, Tuple, Union
|
|
7
|
+
from zeep.exceptions import Fault
|
|
8
|
+
from zeep.helpers import serialize_object
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
class Schedule:
|
|
@@ -82,3 +83,76 @@ class Schedule:
|
|
|
82
83
|
|
|
83
84
|
except Exception as e:
|
|
84
85
|
raise ValueError(f"Schedule validation failed: {str(e)}")
|
|
86
|
+
|
|
87
|
+
def update(self, data: Dict[str, Any]):
|
|
88
|
+
"""
|
|
89
|
+
Update a schedule for an employee using SOAP API.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
data: Dictionary containing schedule data with fields matching ScheduleUpdate schema:
|
|
93
|
+
- employeeId: Employee ID
|
|
94
|
+
- startDate: Start date of the schedule
|
|
95
|
+
- parttimePercentage: Part-time percentage (0-100)
|
|
96
|
+
- hoursMonday, hoursTuesday, etc.: Hours for each day of week 1
|
|
97
|
+
- hoursMonday2, hoursTuesday2, etc.: Hours for each day of week 2
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
Response from the API
|
|
101
|
+
"""
|
|
102
|
+
try:
|
|
103
|
+
schedule_model = ScheduleUpdate(**data)
|
|
104
|
+
|
|
105
|
+
if self.nmbrs.mock_mode:
|
|
106
|
+
return schedule_model
|
|
107
|
+
|
|
108
|
+
# Convert to SOAP object
|
|
109
|
+
schedule_soap = schedule_model.to_soap_schedule(self.nmbrs.soap_client_employees)
|
|
110
|
+
|
|
111
|
+
# Make SOAP request - CompanyRoosterNr is separate parameter (0 = no template)
|
|
112
|
+
response = self.nmbrs.soap_client_employees.service.Schedule_UpdateCurrent(
|
|
113
|
+
EmployeeId=schedule_model.employee_id,
|
|
114
|
+
Schedule=schedule_soap,
|
|
115
|
+
CompanyRoosterNr=schedule_model.company_rooster_nr or 0,
|
|
116
|
+
_soapheaders={'AuthHeaderWithDomain': self.nmbrs.soap_auth_header_employees}
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
return response
|
|
120
|
+
|
|
121
|
+
except Fault as e:
|
|
122
|
+
raise Exception(f"SOAP request failed: {str(e)}")
|
|
123
|
+
except Exception as e:
|
|
124
|
+
raise Exception(f"Failed to update Schedule: {str(e)}")
|
|
125
|
+
|
|
126
|
+
def get_current(self, employee_id: Union[int, str]) -> pd.DataFrame:
|
|
127
|
+
"""
|
|
128
|
+
Get current schedule for an employee via SOAP.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
employee_id: The ID of the employee
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
DataFrame with current schedule
|
|
135
|
+
"""
|
|
136
|
+
if self.nmbrs.mock_mode:
|
|
137
|
+
return pd.DataFrame()
|
|
138
|
+
|
|
139
|
+
try:
|
|
140
|
+
response = self.nmbrs.soap_client_employees.service.Schedule_GetCurrent(
|
|
141
|
+
EmployeeId=int(employee_id),
|
|
142
|
+
_soapheaders={'AuthHeaderWithDomain': self.nmbrs.soap_auth_header_employees}
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
if response:
|
|
146
|
+
serialized = serialize_object(response)
|
|
147
|
+
if not isinstance(serialized, list):
|
|
148
|
+
serialized = [serialized]
|
|
149
|
+
df = pd.DataFrame(serialized)
|
|
150
|
+
df['employee_id'] = str(employee_id)
|
|
151
|
+
return df
|
|
152
|
+
else:
|
|
153
|
+
return pd.DataFrame()
|
|
154
|
+
|
|
155
|
+
except Fault as e:
|
|
156
|
+
raise Exception(f"SOAP request failed: {str(e)}")
|
|
157
|
+
except Exception as e:
|
|
158
|
+
raise Exception(f"Failed to get Schedule: {str(e)}")
|
|
@@ -73,3 +73,29 @@ class AddressCreate(BaseModel):
|
|
|
73
73
|
)
|
|
74
74
|
] = Field(..., example="NL", description="Country ISO Code", alias="countryISOCode")
|
|
75
75
|
period: Period
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class AddressDelete(BaseModel):
|
|
79
|
+
"""Schema for deleting an address via SOAP API."""
|
|
80
|
+
employee_id: int = Field(..., example=12345, description="Employee ID", alias="employeeId")
|
|
81
|
+
address_id: int = Field(..., example=67890, description="Address ID to delete", alias="addressId")
|
|
82
|
+
|
|
83
|
+
class Config:
|
|
84
|
+
populate_by_name = True
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class AddressUpdate(BaseModel):
|
|
88
|
+
"""Schema for updating an address via SOAP API."""
|
|
89
|
+
id: int = Field(..., example=67890, description="Address ID to update", alias="id")
|
|
90
|
+
default: bool = Field(False, example=False, description="Is default address", alias="default")
|
|
91
|
+
street: str = Field(..., min_length=1, max_length=200, example="Naritaweg", description="Street", alias="street")
|
|
92
|
+
house_number: Optional[str] = Field(None, max_length=20, example="70", description="House Number", alias="houseNumber")
|
|
93
|
+
house_number_addition: Optional[str] = Field(None, max_length=20, example="A", description="House Number Addition", alias="houseNumberAddition")
|
|
94
|
+
postal_code: Optional[str] = Field(None, max_length=15, example="1043BZ", description="Postal Code", alias="postalCode")
|
|
95
|
+
city: str = Field(..., min_length=1, max_length=100, example="Amsterdam", description="City", alias="city")
|
|
96
|
+
state_province: Optional[str] = Field(None, max_length=100, example="Noord-Holland", description="State or Province", alias="stateProvince")
|
|
97
|
+
country_iso_code: str = Field(..., min_length=2, max_length=3, example="NL", description="Country ISO Code", alias="countryISOCode")
|
|
98
|
+
address_type: str = Field("HomeAddress", example="HomeAddress", description="Address type", alias="type")
|
|
99
|
+
|
|
100
|
+
class Config:
|
|
101
|
+
populate_by_name = True
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
import pandera as pa
|
|
3
|
+
from pandera import Bool
|
|
4
|
+
from pandera.typing import Series, String, DateTime
|
|
5
|
+
from brynq_sdk_functions import BrynQPanderaDataFrameModel
|
|
6
|
+
from typing import Optional, Literal
|
|
7
|
+
from pydantic import BaseModel, Field
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
|
|
10
|
+
# ---------------------------
|
|
11
|
+
# Get Schemas
|
|
12
|
+
# ---------------------------
|
|
13
|
+
class ChildrenGet(BrynQPanderaDataFrameModel):
|
|
14
|
+
employee_id: Series[String] = pa.Field(coerce=True, description="Employee ID", alias="employeeId")
|
|
15
|
+
child_id: Series[String] = pa.Field(coerce=True, description="Child ID", alias="childId")
|
|
16
|
+
name: Series[String] = pa.Field(coerce=True, description="Last Name", alias="name")
|
|
17
|
+
first_name: Series[String] = pa.Field(coerce=True, description="First Name", alias="firstName")
|
|
18
|
+
initials: Series[String] = pa.Field(coerce=True, nullable=True, description="Initials", alias="initials")
|
|
19
|
+
gender: Series[String] = pa.Field(coerce=True, description="Gender", alias="gender")
|
|
20
|
+
birthday: Series[DateTime] = pa.Field(coerce=True, description="Birthday", alias="birthday")
|
|
21
|
+
|
|
22
|
+
class _Annotation:
|
|
23
|
+
primary_key = "child_id"
|
|
24
|
+
foreign_keys = {
|
|
25
|
+
"employee_id": {
|
|
26
|
+
"parent_schema": "EmployeeSchema",
|
|
27
|
+
"parent_column": "employee_id",
|
|
28
|
+
"cardinality": "N:1"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# ---------------------------
|
|
33
|
+
# Upload Schemas
|
|
34
|
+
# ---------------------------
|
|
35
|
+
class ChildCreate(BaseModel):
|
|
36
|
+
"""Schema for creating a child via SOAP API."""
|
|
37
|
+
name: str = Field(..., min_length=1, max_length=100, example="Doe", description="Last Name", alias="name")
|
|
38
|
+
first_name: str = Field(..., min_length=1, max_length=100, example="John", description="First Name", alias="firstName")
|
|
39
|
+
initials: Optional[str] = Field(None, max_length=20, example="J.D.", description="Initials", alias="initials")
|
|
40
|
+
gender: Literal["male", "female", "unknown", "undefined"] = Field(..., example="male", description="Gender", alias="gender")
|
|
41
|
+
birthday: datetime = Field(..., example="2020-01-01T00:00:00", description="Birthday", alias="birthday")
|
|
42
|
+
|
|
43
|
+
class Config:
|
|
44
|
+
populate_by_name = True
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class ChildDelete(BaseModel):
|
|
48
|
+
"""Schema for deleting a child via SOAP API."""
|
|
49
|
+
employee_id: int = Field(..., example=12345, description="Employee ID", alias="employeeId")
|
|
50
|
+
child_id: int = Field(..., example=67890, description="Child ID to delete", alias="childId")
|
|
51
|
+
|
|
52
|
+
class Config:
|
|
53
|
+
populate_by_name = True
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class ChildUpdate(BaseModel):
|
|
57
|
+
"""Schema for updating a child via SOAP API."""
|
|
58
|
+
id: int = Field(..., example=67890, description="Child ID to update", alias="id")
|
|
59
|
+
name: str = Field(..., min_length=1, max_length=100, example="Doe", description="Last Name", alias="name")
|
|
60
|
+
first_name: str = Field(..., min_length=1, max_length=100, example="John", description="First Name", alias="firstName")
|
|
61
|
+
initials: Optional[str] = Field(None, max_length=20, example="J.D.", description="Initials", alias="initials")
|
|
62
|
+
gender: Literal["male", "female", "unknown", "undefined"] = Field(..., example="male", description="Gender", alias="gender")
|
|
63
|
+
birthday: datetime = Field(..., example="2020-01-01T00:00:00", description="Birthday", alias="birthday")
|
|
64
|
+
|
|
65
|
+
class Config:
|
|
66
|
+
populate_by_name = True
|
|
67
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from pydantic import BaseModel, Field
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class CompanyCreate(BaseModel):
|
|
6
|
+
"""Schema for creating a company via SOAP API."""
|
|
7
|
+
debtor_id: int = Field(..., description="Debtor ID", alias="debtorId", example=34548)
|
|
8
|
+
company_name: str = Field(..., min_length=1, max_length=200, description="Company name", alias="companyName", example="New Company BV")
|
|
9
|
+
period_type: int = Field(1, ge=1, le=4, description="Period type (1=Monthly, 2=4-Weekly, 3=Weekly, 4=Quarterly)", alias="periodType", example=1)
|
|
10
|
+
default_company_id: int = Field(0, description="Default company ID to copy settings from (0 for none)", alias="defaultCompanyId", example=0)
|
|
11
|
+
labour_agreement_settings_group_guid: Optional[str] = Field(None, description="Labour agreement settings group GUID", alias="labourAgreementSettingsGroupGuid", example="00000000-0000-0000-0000-000000000000")
|
|
12
|
+
pay_in_advance: bool = Field(False, description="Pay in advance", alias="payInAdvance", example=False)
|
|
13
|
+
|
|
14
|
+
class Config:
|
|
15
|
+
populate_by_name = True
|
|
16
|
+
|
|
@@ -13,4 +13,26 @@ from pydantic import BaseModel, Field, StringConstraints
|
|
|
13
13
|
class DebtorsGet(BrynQPanderaDataFrameModel):
|
|
14
14
|
debtor_id: Series[String] = pa.Field(coerce=True, description="Debtor ID", alias="debtorId")
|
|
15
15
|
number: Series[String] = pa.Field(coerce=True, description="Debtor number", alias="number")
|
|
16
|
-
name: Series[Bool] = pa.Field(coerce=True, description="Debtor name", alias="name")
|
|
16
|
+
name: Series[Bool] = pa.Field(coerce=True, description="Debtor name", alias="name")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# ---------------------------
|
|
20
|
+
# SOAP Schemas
|
|
21
|
+
# ---------------------------
|
|
22
|
+
class DebtorCreate(BaseModel):
|
|
23
|
+
"""Schema for creating a debtor via SOAP API."""
|
|
24
|
+
number: int = Field(..., ge=1, description="Debtor number", alias="number", example=1001)
|
|
25
|
+
name: str = Field(..., min_length=1, max_length=200, description="Debtor name", alias="name", example="New Debtor Company")
|
|
26
|
+
|
|
27
|
+
class Config:
|
|
28
|
+
populate_by_name = True
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class DebtorUpdate(BaseModel):
|
|
32
|
+
"""Schema for updating a debtor via SOAP API."""
|
|
33
|
+
debtor_id: int = Field(..., description="Debtor ID", alias="debtorId", example=34548)
|
|
34
|
+
number: int = Field(..., ge=1, description="Debtor number", alias="number", example=1001)
|
|
35
|
+
name: str = Field(..., min_length=1, max_length=200, description="Debtor name", alias="name", example="Updated Debtor Company")
|
|
36
|
+
|
|
37
|
+
class Config:
|
|
38
|
+
populate_by_name = True
|
|
@@ -56,3 +56,36 @@ class EmployeeDepartmentUpdate(BaseModel):
|
|
|
56
56
|
|
|
57
57
|
class Config:
|
|
58
58
|
primary_key = "departmentId"
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
# ---------------------------
|
|
62
|
+
# SOAP Schemas (DebtorService)
|
|
63
|
+
# ---------------------------
|
|
64
|
+
class DepartmentMasterCreate(BaseModel):
|
|
65
|
+
"""Schema for creating a master department via SOAP API."""
|
|
66
|
+
debtor_id: int = Field(..., description="Debtor ID", alias="debtorId", example=34548)
|
|
67
|
+
code: int = Field(..., ge=1, description="Department Code", alias="code", example=101)
|
|
68
|
+
description: str = Field(..., min_length=1, max_length=200, description="Department Description", alias="description", example="Engineering")
|
|
69
|
+
|
|
70
|
+
class Config:
|
|
71
|
+
populate_by_name = True
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class DepartmentMasterUpdate(BaseModel):
|
|
75
|
+
"""Schema for updating a master department via SOAP API."""
|
|
76
|
+
debtor_id: int = Field(..., description="Debtor ID", alias="debtorId", example=34548)
|
|
77
|
+
department_id: int = Field(..., description="Department ID", alias="departmentId", example=12345)
|
|
78
|
+
code: int = Field(..., ge=1, description="Department Code", alias="code", example=101)
|
|
79
|
+
description: str = Field(..., min_length=1, max_length=200, description="Department Description", alias="description", example="Engineering Updated")
|
|
80
|
+
|
|
81
|
+
class Config:
|
|
82
|
+
populate_by_name = True
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class DepartmentMasterDelete(BaseModel):
|
|
86
|
+
"""Schema for deleting a master department via SOAP API."""
|
|
87
|
+
debtor_id: int = Field(..., description="Debtor ID", alias="debtorId", example=34548)
|
|
88
|
+
department_id: int = Field(..., description="Department ID to delete", alias="departmentId", example=12345)
|
|
89
|
+
|
|
90
|
+
class Config:
|
|
91
|
+
populate_by_name = True
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from pydantic import BaseModel, Field
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class DocumentUpload(BaseModel):
|
|
6
|
+
"""Schema for uploading a document to an employee via SOAP API."""
|
|
7
|
+
employee_id: int = Field(..., description="Employee ID", alias="employeeId", example=276967)
|
|
8
|
+
document_name: str = Field(..., description="Document name (with extension)", alias="documentName", example="contract.pdf")
|
|
9
|
+
document_type_guid: str = Field(..., description="Document type GUID", alias="documentTypeGuid", example="00000000-0000-0000-0000-000000000000")
|
|
10
|
+
|
|
11
|
+
class Config:
|
|
12
|
+
populate_by_name = True
|
|
13
|
+
|
|
@@ -25,7 +25,9 @@ class EmployeeGet(BrynQPanderaDataFrameModel):
|
|
|
25
25
|
last_name: Series[String] = pa.Field(coerce=True, description="Last Name", alias="basicInfo.lastName")
|
|
26
26
|
employee_type: Series[String] = pa.Field(coerce=True, description="Employee Type", alias="basicInfo.employeeType")
|
|
27
27
|
birth_date: Series[DateTime] = pa.Field(coerce=True, description="Birth Date", alias="birthInfo.birthDate")
|
|
28
|
-
birth_country_code_iso: Series[String] = pa.Field(coerce=True, nullable=True, description="Birth Country Code ISO", alias="birthInfo.birthCountry")
|
|
28
|
+
birth_country_code_iso: Optional[Series[String]] = pa.Field(coerce=True, nullable=True, description="Birth Country Code ISO", alias="birthInfo.birthCountry")
|
|
29
|
+
birth_country: Optional[Series[String]] = pa.Field(coerce=True, nullable=True, description="Birth Country Code ISO", alias="birthInfo.birthCountry.codeISO")
|
|
30
|
+
birth_country_description: Optional[Series[String]] = pa.Field(coerce=True, nullable=True, description="Birth Country Code ISO", alias="birthInfo.birthCountry.description")
|
|
29
31
|
nationality_code_iso: Series[String] = pa.Field(coerce=True, nullable=True, description="Nationality Code ISO", alias="birthInfo.nationality.codeISO")
|
|
30
32
|
gender: Series[String] = pa.Field(coerce=True, nullable=True, description="Gender", alias="birthInfo.gender")
|
|
31
33
|
private_email: Series[String] = pa.Field(coerce=True, nullable=True, description="Private Email", alias="contactInfo.privateEmail")
|
|
@@ -47,3 +47,31 @@ class FunctionGet(BrynQPanderaDataFrameModel):
|
|
|
47
47
|
class FunctionUpdate(BaseModel):
|
|
48
48
|
function_id: str = Field(..., example="5981", description="Function ID", alias="functionId")
|
|
49
49
|
period_details: Period = Field(..., alias="periodDetails")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# SOAP Schemas for DebtorService Functions
|
|
53
|
+
class FunctionCreate(BaseModel):
|
|
54
|
+
"""Schema for creating a master function via SOAP API."""
|
|
55
|
+
code: int = Field(..., example=101, description="Function Code", alias="code")
|
|
56
|
+
description: str = Field(..., example="Software Developer", description="Function Description", alias="description")
|
|
57
|
+
|
|
58
|
+
class Config:
|
|
59
|
+
populate_by_name = True
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class FunctionDelete(BaseModel):
|
|
63
|
+
"""Schema for deleting a master function via SOAP API."""
|
|
64
|
+
function_id: int = Field(..., example=12345, description="Function ID to delete", alias="functionId")
|
|
65
|
+
|
|
66
|
+
class Config:
|
|
67
|
+
populate_by_name = True
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class FunctionMasterUpdate(BaseModel):
|
|
71
|
+
"""Schema for updating a master function via SOAP API."""
|
|
72
|
+
function_id: int = Field(..., example=12345, description="Function ID", alias="functionId")
|
|
73
|
+
code: int = Field(..., example=101, description="Function Code", alias="code")
|
|
74
|
+
description: str = Field(..., example="Senior Software Developer", description="Function Description", alias="description")
|
|
75
|
+
|
|
76
|
+
class Config:
|
|
77
|
+
populate_by_name = True
|
brynq_sdk_nmbrs/schemas/leave.py
CHANGED
|
@@ -46,6 +46,18 @@ class LeaveDelete(BaseModel):
|
|
|
46
46
|
leave_request_id: str = Field(..., example="49a69eda-252e-4ccb-a220-38ea90511d4f", description="Leave Request ID", alias="leaveRequestId")
|
|
47
47
|
|
|
48
48
|
|
|
49
|
+
class LeaveUpdate(BaseModel):
|
|
50
|
+
"""Schema for updating leave via SOAP API."""
|
|
51
|
+
employee_id: int = Field(..., example=12345, description="Employee ID", alias="employeeId")
|
|
52
|
+
leave_id: int = Field(..., example=67890, description="Leave ID", alias="leaveId")
|
|
53
|
+
start_date: datetime = Field(..., example="2025-01-01T00:00:00", description="Leave Start Date", alias="startDate")
|
|
54
|
+
end_date: datetime = Field(..., example="2025-01-02T00:00:00", description="Leave End Date", alias="endDate")
|
|
55
|
+
description: Optional[str] = Field(None, example="Vacation leave", description="Description", alias="description")
|
|
56
|
+
|
|
57
|
+
class Config:
|
|
58
|
+
populate_by_name = True
|
|
59
|
+
|
|
60
|
+
|
|
49
61
|
class LeaveBalanceGet(BrynQPanderaDataFrameModel):
|
|
50
62
|
employee_id: Series[String] = pa.Field(coerce=True, description="Employee ID", alias="employeeId")
|
|
51
63
|
leave_group_id: Series[String] = pa.Field(coerce=True, nullable=True, description="Leave Group ID", alias="leaveGroupId")
|
|
@@ -76,6 +76,24 @@ class SalaryCreate(BaseModel):
|
|
|
76
76
|
data.pop('salaryTable')
|
|
77
77
|
return data
|
|
78
78
|
|
|
79
|
+
class Config:
|
|
80
|
+
populate_by_name = True
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class SalaryUpdate(BaseModel):
|
|
84
|
+
"""Schema for updating salary via SOAP API (Salary_UpdateCurrent)."""
|
|
85
|
+
employee_id: int = Field(..., example=12345, description="Employee ID", alias="employeeId")
|
|
86
|
+
salary_value: float = Field(..., ge=0, example=5000.00, description="Salary value (gross amount)", alias="salaryValue")
|
|
87
|
+
salary_type: str = Field(
|
|
88
|
+
"Bruto_Salaris_Fulltime",
|
|
89
|
+
example="Bruto_Salaris_Fulltime",
|
|
90
|
+
description="Salary type enum: Bruto_Salaris_Fulltime, Bruto_Salaris_Parttime, Bruto_Uurloon, etc.",
|
|
91
|
+
alias="salaryType"
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
class Config:
|
|
95
|
+
populate_by_name = True
|
|
96
|
+
|
|
79
97
|
class SalaryTableGet(BrynQPanderaDataFrameModel):
|
|
80
98
|
code: Series[String] = pa.Field(coerce=True, description="Salary Code", alias="Code")
|
|
81
99
|
description: Series[String] = pa.Field(coerce=True, description="Salary Description", alias="Description")
|
|
@@ -93,3 +93,52 @@ class ScheduleCreate(BaseModel):
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class ScheduleUpdate(BaseModel):
|
|
99
|
+
"""
|
|
100
|
+
Pydantic model for updating a schedule via SOAP API
|
|
101
|
+
"""
|
|
102
|
+
employee_id: int = Field(..., example=12345, description="Employee ID", alias="employeeId")
|
|
103
|
+
start_date: datetime = Field(..., example="2025-01-01T00:00:00", description="Start date of the schedule", alias="startDate")
|
|
104
|
+
parttime_percentage: float = Field(..., ge=0, le=100, example=100.0, description="Part-time percentage", alias="parttimePercentage")
|
|
105
|
+
company_rooster_nr: Optional[int] = Field(0, example=0, description="Company Rooster Number (schedule template)", alias="companyRoosterNr")
|
|
106
|
+
hours_monday: Optional[float] = Field(0, ge=0, le=24, example=8.0, description="Hours Monday", alias="hoursMonday")
|
|
107
|
+
hours_tuesday: Optional[float] = Field(0, ge=0, le=24, example=8.0, description="Hours Tuesday", alias="hoursTuesday")
|
|
108
|
+
hours_wednesday: Optional[float] = Field(0, ge=0, le=24, example=8.0, description="Hours Wednesday", alias="hoursWednesday")
|
|
109
|
+
hours_thursday: Optional[float] = Field(0, ge=0, le=24, example=8.0, description="Hours Thursday", alias="hoursThursday")
|
|
110
|
+
hours_friday: Optional[float] = Field(0, ge=0, le=24, example=8.0, description="Hours Friday", alias="hoursFriday")
|
|
111
|
+
hours_saturday: Optional[float] = Field(0, ge=0, le=24, example=0.0, description="Hours Saturday", alias="hoursSaturday")
|
|
112
|
+
hours_sunday: Optional[float] = Field(0, ge=0, le=24, example=0.0, description="Hours Sunday", alias="hoursSunday")
|
|
113
|
+
hours_monday2: Optional[float] = Field(0, ge=0, le=24, example=8.0, description="Hours Monday Week 2", alias="hoursMonday2")
|
|
114
|
+
hours_tuesday2: Optional[float] = Field(0, ge=0, le=24, example=8.0, description="Hours Tuesday Week 2", alias="hoursTuesday2")
|
|
115
|
+
hours_wednesday2: Optional[float] = Field(0, ge=0, le=24, example=8.0, description="Hours Wednesday Week 2", alias="hoursWednesday2")
|
|
116
|
+
hours_thursday2: Optional[float] = Field(0, ge=0, le=24, example=8.0, description="Hours Thursday Week 2", alias="hoursThursday2")
|
|
117
|
+
hours_friday2: Optional[float] = Field(0, ge=0, le=24, example=8.0, description="Hours Friday Week 2", alias="hoursFriday2")
|
|
118
|
+
hours_saturday2: Optional[float] = Field(0, ge=0, le=24, example=0.0, description="Hours Saturday Week 2", alias="hoursSaturday2")
|
|
119
|
+
hours_sunday2: Optional[float] = Field(0, ge=0, le=24, example=0.0, description="Hours Sunday Week 2", alias="hoursSunday2")
|
|
120
|
+
|
|
121
|
+
def to_soap_schedule(self, soap_client):
|
|
122
|
+
"""Convert to SOAP Schedule object"""
|
|
123
|
+
ScheduleType = soap_client.get_type('ns0:Schedule')
|
|
124
|
+
return ScheduleType(
|
|
125
|
+
StartDate=self.start_date,
|
|
126
|
+
ParttimePercentage=self.parttime_percentage,
|
|
127
|
+
HoursMonday=self.hours_monday or 0,
|
|
128
|
+
HoursTuesday=self.hours_tuesday or 0,
|
|
129
|
+
HoursWednesday=self.hours_wednesday or 0,
|
|
130
|
+
HoursThursday=self.hours_thursday or 0,
|
|
131
|
+
HoursFriday=self.hours_friday or 0,
|
|
132
|
+
HoursSaturday=self.hours_saturday or 0,
|
|
133
|
+
HoursSunday=self.hours_sunday or 0,
|
|
134
|
+
HoursMonday2=self.hours_monday2 or 0,
|
|
135
|
+
HoursTuesday2=self.hours_tuesday2 or 0,
|
|
136
|
+
HoursWednesday2=self.hours_wednesday2 or 0,
|
|
137
|
+
HoursThursday2=self.hours_thursday2 or 0,
|
|
138
|
+
HoursFriday2=self.hours_friday2 or 0,
|
|
139
|
+
HoursSaturday2=self.hours_saturday2 or 0,
|
|
140
|
+
HoursSunday2=self.hours_sunday2 or 0
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
class Config:
|
|
144
|
+
populate_by_name = True
|
|
@@ -1,14 +1,47 @@
|
|
|
1
|
-
import math
|
|
2
1
|
import pandas as pd
|
|
3
2
|
import pandera as pa
|
|
4
3
|
from pandera import Bool
|
|
5
|
-
from pandera.typing import Series, String,
|
|
6
|
-
import pandera.extensions as extensions
|
|
4
|
+
from pandera.typing import Series, String, DateTime
|
|
7
5
|
from brynq_sdk_functions import BrynQPanderaDataFrameModel
|
|
8
|
-
from typing import Optional
|
|
9
|
-
from pydantic import BaseModel, Field
|
|
10
|
-
from datetime import datetime
|
|
6
|
+
from typing import Optional
|
|
7
|
+
from pydantic import BaseModel, Field
|
|
11
8
|
|
|
9
|
+
# ---------------------------
|
|
10
|
+
# Get Schemas
|
|
11
|
+
# ---------------------------
|
|
12
|
+
class SocialInsuranceGet(BrynQPanderaDataFrameModel):
|
|
13
|
+
employee_id: Series[String] = pa.Field(coerce=True, description="Employee ID", alias="employee_id")
|
|
14
|
+
id: Series[String] = pa.Field(coerce=True, description="SVW Settings ID", alias="Id")
|
|
15
|
+
creation_date: Series[DateTime] = pa.Field(coerce=True, nullable=True, description="Creation Date", alias="CreationDate")
|
|
16
|
+
start_period: Series[pd.Int64Dtype] = pa.Field(coerce=True, nullable=True, description="Start Period", alias="StartPeriod")
|
|
17
|
+
start_year: Series[pd.Int64Dtype] = pa.Field(coerce=True, nullable=True, description="Start Year", alias="StartYear")
|
|
18
|
+
influence_obliged_insurance: Series[Bool] = pa.Field(coerce=True, nullable=True, description="Whether employee influences obligatory insurance status", alias="InfluenceObligedInsurance")
|
|
19
|
+
wage_cost_benefit: Series[Bool] = pa.Field(coerce=True, nullable=True, description="Eligible for wage cost subsidy (LKV - Loonkostenvoordeel)", alias="WageCostBenefit")
|
|
20
|
+
cao: Series[String] = pa.Field(coerce=True, nullable=True, description="Collectieve Arbeidsovereenkomst (Collective Labor Agreement)", alias="CAO")
|
|
21
|
+
wao_wia: Series[Bool] = pa.Field(coerce=True, nullable=True, description="Disability Insurance (WAO/WIA - Wet Arbeidsongeschiktheid)", alias="Wao_Wia")
|
|
22
|
+
ww: Series[Bool] = pa.Field(coerce=True, nullable=True, description="Unemployment Insurance (WW - Werkloosheidswet)", alias="Ww")
|
|
23
|
+
zw: Series[Bool] = pa.Field(coerce=True, nullable=True, description="Sickness Benefits (ZW - Ziektewet)", alias="Zw")
|
|
24
|
+
income_related_contribution_zvw: Series[Bool] = pa.Field(coerce=True, nullable=True, description="Income Related Health Insurance Contribution (ZVW - Zorgverzekeringswet)", alias="IncomeRelatedContributionZvw")
|
|
25
|
+
code_zvw: Series[String] = pa.Field(coerce=True, nullable=True, description="Health Insurance Code (ZVW)", alias="CodeZvw")
|
|
26
|
+
risk_group: Series[String] = pa.Field(coerce=True, nullable=True, description="Risk Group for premium calculation", alias="RiskGroup")
|
|
27
|
+
sector: Series[String] = pa.Field(coerce=True, nullable=True, description="Industry Sector code", alias="Sector")
|
|
28
|
+
employment_type: Series[pd.Int64Dtype] = pa.Field(coerce=True, nullable=True, description="Employment Type", alias="EmploymentType")
|
|
29
|
+
phase_classification: Series[pd.Int64Dtype] = pa.Field(coerce=True, nullable=True, description="Phase Classification", alias="PhaseClassification")
|
|
30
|
+
employment_sequence_tax_id: Series[pd.Int64Dtype] = pa.Field(coerce=True, nullable=True, description="Employment Sequence Tax ID", alias="EmploymentSequenceTaxId")
|
|
31
|
+
|
|
32
|
+
class _Annotation:
|
|
33
|
+
primary_key = "id"
|
|
34
|
+
foreign_keys = {
|
|
35
|
+
"employee_id": {
|
|
36
|
+
"parent_schema": "EmployeeSchema",
|
|
37
|
+
"parent_column": "employee_id",
|
|
38
|
+
"cardinality": "N:1"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
# ---------------------------
|
|
43
|
+
# Upload Schemas
|
|
44
|
+
# ---------------------------
|
|
12
45
|
class SocialInsuranceUpdate(BaseModel):
|
|
13
46
|
employee_id: int = Field(None, example="1234567890", description="Employee ID", alias="EmployeeId")
|
|
14
47
|
influence_obliged_insurance: Optional[bool] = Field(None, example="1234567890", description="Influence Obliged Insurance", alias="InfluenceObligedInsurance")
|
|
@@ -1,16 +1,76 @@
|
|
|
1
1
|
import math
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from typing import Annotated, Optional, Union
|
|
4
|
+
|
|
2
5
|
import pandas as pd
|
|
3
6
|
import pandera as pa
|
|
4
|
-
from pandera import Bool
|
|
5
|
-
from pandera.typing import Series, String, Float, DateTime
|
|
6
7
|
import pandera.extensions as extensions
|
|
7
|
-
from
|
|
8
|
-
from typing import
|
|
8
|
+
from pandera import Bool
|
|
9
|
+
from pandera.typing import DateTime, Float, Series, String
|
|
9
10
|
from pydantic import BaseModel, Field, StringConstraints
|
|
10
|
-
|
|
11
|
+
|
|
12
|
+
from brynq_sdk_functions import BrynQPanderaDataFrameModel
|
|
11
13
|
|
|
12
14
|
|
|
15
|
+
# ---------------------------
|
|
16
|
+
# REST API Get Schema (Wage Tax Settings History)
|
|
17
|
+
# ---------------------------
|
|
13
18
|
class WageTaxSettingsGet(BrynQPanderaDataFrameModel):
|
|
19
|
+
"""Schema for REST API: GET /companies/{companyId}/employees/wagetaxsettings"""
|
|
20
|
+
employee_id: Series[String] = pa.Field(coerce=True, description="Employee ID", alias="employeeId")
|
|
21
|
+
wage_tax_setting_id: Series[String] = pa.Field(coerce=True, description="Wage Tax Setting ID", alias="wageTaxSettingId")
|
|
22
|
+
start_date: Series[DateTime] = pa.Field(coerce=True, description="Start Date", alias="startDate")
|
|
23
|
+
created_at: Series[DateTime] = pa.Field(coerce=True, description="Created At", alias="createdAt")
|
|
24
|
+
payroll_tax_reduction: Series[Bool] = pa.Field(coerce=True, nullable=True, description="Payroll Tax Reduction", alias="payrollTaxReduction")
|
|
25
|
+
type_of_income: Series[pd.Int64Dtype] = pa.Field(coerce=True, nullable=True, description="Type of Income", alias="typeOfIncome")
|
|
26
|
+
color_table: Series[pd.Int64Dtype] = pa.Field(coerce=True, nullable=True, description="Color Table", alias="colorTable")
|
|
27
|
+
period_table: Series[pd.Int64Dtype] = pa.Field(coerce=True, nullable=True, description="Period Table", alias="periodTable")
|
|
28
|
+
special_table: Series[pd.Int64Dtype] = pa.Field(coerce=True, nullable=True, description="Special Table", alias="specialTable")
|
|
29
|
+
payroll_tax: Series[Bool] = pa.Field(coerce=True, nullable=True, description="Payroll Tax", alias="payrollTax")
|
|
30
|
+
benefit_scheme: Series[Bool] = pa.Field(coerce=True, nullable=True, description="Benefit Scheme", alias="benefitScheme")
|
|
31
|
+
auto_small_jobs: Series[Bool] = pa.Field(coerce=True, nullable=True, description="Auto Small Jobs Regulation", alias="autoSmallJobs")
|
|
32
|
+
yearly_salary: Series[pd.Float64Dtype] = pa.Field(coerce=True, nullable=True, description="Yearly Salary", alias="yearlySalary")
|
|
33
|
+
deviation_special_rate: Series[pd.Float64Dtype] = pa.Field(coerce=True, nullable=True, description="Deviation Special Rate Payroll Tax Deduction", alias="deviationSpecialRatePayrollTaxDeduction")
|
|
34
|
+
code_tax_reduction: Series[pd.Int64Dtype] = pa.Field(coerce=True, nullable=True, description="Code Tax Reduction", alias="codeTaxReduction")
|
|
35
|
+
holiday_vouchers: Series[pd.Int64Dtype] = pa.Field(coerce=True, nullable=True, description="Holiday Vouchers", alias="holidayVouchers")
|
|
36
|
+
code_30_percent_rule: Series[pd.Int64Dtype] = pa.Field(coerce=True, nullable=True, description="Code Calculate 30 Percent Rule", alias="codeCalculate30PercentRule")
|
|
37
|
+
|
|
38
|
+
class _Annotation:
|
|
39
|
+
primary_key = "wage_tax_setting_id"
|
|
40
|
+
foreign_keys = {
|
|
41
|
+
"employee_id": {
|
|
42
|
+
"parent_schema": "EmployeeSchema",
|
|
43
|
+
"parent_column": "employee_id",
|
|
44
|
+
"cardinality": "N:1"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class WageTaxSettingsCreate(BaseModel):
|
|
50
|
+
"""Schema for REST API: POST /employees/{employeeId}/wagetaxsetting"""
|
|
51
|
+
start_date: datetime = Field(..., example="2024-01-01T00:00:00Z", description="Start Date", alias="startDate")
|
|
52
|
+
payroll_tax_reduction: Optional[bool] = Field(None, example=True, description="Payroll Tax Reduction", alias="payrollTaxReduction")
|
|
53
|
+
type_of_income: Optional[int] = Field(None, example=15, description="Type of Income", alias="typeOfIncome")
|
|
54
|
+
color_table: Optional[int] = Field(None, example=1, description="Color Table", alias="colorTable")
|
|
55
|
+
period_table: Optional[int] = Field(None, example=2, description="Period Table", alias="periodTable")
|
|
56
|
+
special_table: Optional[int] = Field(None, example=0, description="Special Table", alias="specialTable")
|
|
57
|
+
payroll_tax: Optional[bool] = Field(None, example=True, description="Payroll Tax", alias="payrollTax")
|
|
58
|
+
benefit_scheme: Optional[bool] = Field(None, example=True, description="Benefit Scheme", alias="benefitScheme")
|
|
59
|
+
auto_small_jobs: Optional[bool] = Field(None, example=False, description="Auto Small Jobs Regulation", alias="autoSmallJobs")
|
|
60
|
+
yearly_salary: Optional[float] = Field(None, example=45000.00, description="Yearly Salary", alias="yearlySalary")
|
|
61
|
+
deviation_special_rate: Optional[float] = Field(None, example=0.0, description="Deviation Special Rate Payroll Tax Deduction", alias="deviationSpecialRatePayrollTaxDeduction")
|
|
62
|
+
code_tax_reduction: Optional[int] = Field(None, example=0, description="Code Tax Reduction", alias="codeTaxReduction")
|
|
63
|
+
holiday_vouchers: Optional[int] = Field(None, example=0, description="Holiday Vouchers", alias="holidayVouchers")
|
|
64
|
+
code_30_percent_rule: Optional[int] = Field(None, example=0, description="Code Calculate 30 Percent Rule", alias="codeCalculate30PercentRule")
|
|
65
|
+
|
|
66
|
+
class Config:
|
|
67
|
+
populate_by_name = True
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# ---------------------------
|
|
71
|
+
# SOAP API Get Schema (Company Wage Tax List)
|
|
72
|
+
# ---------------------------
|
|
73
|
+
class CompanyWageTaxGet(BrynQPanderaDataFrameModel):
|
|
14
74
|
wagetax_id: Series[pd.Int64Dtype] = pa.Field(coerce=True, description="Loonaangifte ID", alias="LoonaangifteID")
|
|
15
75
|
serial_number: Series[pd.Int64Dtype] = pa.Field(coerce=True, description="Serial Number", alias="SerialNumber")
|
|
16
76
|
payment_reference: Series[String] = pa.Field(coerce=True, description="Payment Reference", alias="PaymentReference")
|