brynq-sdk-sage-germany 1.0.0__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_sage_germany/__init__.py +278 -0
- brynq_sdk_sage_germany/absences.py +175 -0
- brynq_sdk_sage_germany/allowances.py +100 -0
- brynq_sdk_sage_germany/contracts.py +145 -0
- brynq_sdk_sage_germany/cost_centers.py +89 -0
- brynq_sdk_sage_germany/employees.py +140 -0
- brynq_sdk_sage_germany/helpers.py +391 -0
- brynq_sdk_sage_germany/organization.py +90 -0
- brynq_sdk_sage_germany/payroll.py +167 -0
- brynq_sdk_sage_germany/payslips.py +106 -0
- brynq_sdk_sage_germany/salaries.py +95 -0
- brynq_sdk_sage_germany/schemas/__init__.py +44 -0
- brynq_sdk_sage_germany/schemas/absences.py +311 -0
- brynq_sdk_sage_germany/schemas/allowances.py +147 -0
- brynq_sdk_sage_germany/schemas/cost_centers.py +46 -0
- brynq_sdk_sage_germany/schemas/employees.py +487 -0
- brynq_sdk_sage_germany/schemas/organization.py +172 -0
- brynq_sdk_sage_germany/schemas/organization_assignment.py +61 -0
- brynq_sdk_sage_germany/schemas/payroll.py +287 -0
- brynq_sdk_sage_germany/schemas/payslips.py +34 -0
- brynq_sdk_sage_germany/schemas/salaries.py +101 -0
- brynq_sdk_sage_germany/schemas/start_end_dates.py +194 -0
- brynq_sdk_sage_germany/schemas/vacation_account.py +117 -0
- brynq_sdk_sage_germany/schemas/work_hours.py +94 -0
- brynq_sdk_sage_germany/start_end_dates.py +123 -0
- brynq_sdk_sage_germany/vacation_account.py +70 -0
- brynq_sdk_sage_germany/work_hours.py +97 -0
- brynq_sdk_sage_germany-1.0.0.dist-info/METADATA +21 -0
- brynq_sdk_sage_germany-1.0.0.dist-info/RECORD +31 -0
- brynq_sdk_sage_germany-1.0.0.dist-info/WHEEL +5 -0
- brynq_sdk_sage_germany-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Vacation account endpoint implementations for Sage Germany.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from datetime import datetime, timezone
|
|
8
|
+
from typing import TYPE_CHECKING, Optional, Tuple
|
|
9
|
+
|
|
10
|
+
import pandas as pd
|
|
11
|
+
from brynq_sdk_functions import Functions
|
|
12
|
+
|
|
13
|
+
from .schemas.vacation_account import VacationAccountGet
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from .employees import Employees
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class VacationAccount:
|
|
20
|
+
"""
|
|
21
|
+
Handles vacation balance operations scoped to employees.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, sage) -> None:
|
|
25
|
+
self.sage = sage
|
|
26
|
+
self.base_url = "/employeenew/person/urlaubskonto"
|
|
27
|
+
|
|
28
|
+
def get(
|
|
29
|
+
self,
|
|
30
|
+
date: Optional[str] = None,
|
|
31
|
+
company_id: Optional[int] = None,
|
|
32
|
+
employee_number: Optional[int] = None,
|
|
33
|
+
) -> Tuple[pd.DataFrame, pd.DataFrame]:
|
|
34
|
+
"""
|
|
35
|
+
Retrieve vacation account data for a specific employee or all employees.
|
|
36
|
+
"""
|
|
37
|
+
try:
|
|
38
|
+
if company_id is not None and employee_number is not None:
|
|
39
|
+
employee_keys = [{"MdNr": company_id, "AnNr": employee_number}]
|
|
40
|
+
else:
|
|
41
|
+
employee_keys = self.sage._employee_search()
|
|
42
|
+
|
|
43
|
+
if not employee_keys:
|
|
44
|
+
return pd.DataFrame(), pd.DataFrame()
|
|
45
|
+
|
|
46
|
+
vacation_records = []
|
|
47
|
+
effective_date = date or datetime.now(timezone.utc).strftime("%Y-%m-%dT00:00:00")
|
|
48
|
+
|
|
49
|
+
for key in employee_keys:
|
|
50
|
+
response = self.sage.get(
|
|
51
|
+
path=self.base_url,
|
|
52
|
+
params={"MdNr": key["MdNr"], "AnNr": key["AnNr"], "date": effective_date},
|
|
53
|
+
)
|
|
54
|
+
response.raise_for_status()
|
|
55
|
+
payload = response.json()
|
|
56
|
+
if isinstance(payload, dict):
|
|
57
|
+
vacation_records.append(payload)
|
|
58
|
+
|
|
59
|
+
if not vacation_records:
|
|
60
|
+
return pd.DataFrame(), pd.DataFrame()
|
|
61
|
+
|
|
62
|
+
dataframe = pd.json_normalize(vacation_records, sep="__")
|
|
63
|
+
|
|
64
|
+
valid_data, invalid_data = Functions.validate_data(
|
|
65
|
+
df=dataframe,
|
|
66
|
+
schema=VacationAccountGet,
|
|
67
|
+
)
|
|
68
|
+
return valid_data, invalid_data
|
|
69
|
+
except Exception as exc:
|
|
70
|
+
raise RuntimeError("Failed to retrieve vacation account data.") from exc
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Work hours endpoint implementations for Sage Germany.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from datetime import datetime, timezone
|
|
8
|
+
from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple
|
|
9
|
+
|
|
10
|
+
import pandas as pd
|
|
11
|
+
from brynq_sdk_functions import Functions
|
|
12
|
+
|
|
13
|
+
from .schemas.work_hours import WorkHoursCreate, WorkHoursGet
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from .employees import Employees
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class WorkHours:
|
|
20
|
+
"""
|
|
21
|
+
Handles work-hours-related operations scoped to employees.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, sage) -> None:
|
|
25
|
+
self.sage = sage
|
|
26
|
+
self.base_url = "/employeenew/person/arbeitszeiten"
|
|
27
|
+
|
|
28
|
+
def get(
|
|
29
|
+
self,
|
|
30
|
+
date: Optional[str] = None,
|
|
31
|
+
company_id: Optional[int] = None,
|
|
32
|
+
employee_number: Optional[int] = None,
|
|
33
|
+
) -> Tuple[pd.DataFrame, pd.DataFrame]:
|
|
34
|
+
"""
|
|
35
|
+
Retrieve work hours for a single employee or all employees.
|
|
36
|
+
"""
|
|
37
|
+
try:
|
|
38
|
+
if company_id is not None and employee_number is not None:
|
|
39
|
+
employee_keys = [{"MdNr": company_id, "AnNr": employee_number}]
|
|
40
|
+
else:
|
|
41
|
+
employee_keys = self.sage._employee_search()
|
|
42
|
+
|
|
43
|
+
if not employee_keys:
|
|
44
|
+
return pd.DataFrame(), pd.DataFrame()
|
|
45
|
+
|
|
46
|
+
work_hours_records = []
|
|
47
|
+
effective_date = date or datetime.now(timezone.utc).strftime("%Y-%m-%dT00:00:00")
|
|
48
|
+
|
|
49
|
+
for key in employee_keys:
|
|
50
|
+
response = self.sage.get(
|
|
51
|
+
path=self.base_url,
|
|
52
|
+
params={"MdNr": key["MdNr"], "AnNr": key["AnNr"], "date": effective_date},
|
|
53
|
+
)
|
|
54
|
+
response.raise_for_status()
|
|
55
|
+
payload = response.json()
|
|
56
|
+
if isinstance(payload, dict):
|
|
57
|
+
work_hours_records.append(payload)
|
|
58
|
+
|
|
59
|
+
if not work_hours_records:
|
|
60
|
+
return pd.DataFrame(), pd.DataFrame()
|
|
61
|
+
|
|
62
|
+
dataframe = pd.json_normalize(work_hours_records, sep="__").copy()
|
|
63
|
+
# Create combined key manually as it's not present in the payload
|
|
64
|
+
if {"MdNr", "AnNr"}.issubset(dataframe.columns):
|
|
65
|
+
mdnr_numeric = pd.to_numeric(dataframe["MdNr"], errors="coerce").astype("Int64")
|
|
66
|
+
annr_numeric = pd.to_numeric(dataframe["AnNr"], errors="coerce").astype("Int64")
|
|
67
|
+
dataframe["combined_key"] = pd.NA
|
|
68
|
+
valid_mask = mdnr_numeric.notna() & annr_numeric.notna()
|
|
69
|
+
dataframe.loc[valid_mask, "combined_key"] = (
|
|
70
|
+
mdnr_numeric[valid_mask].astype("string")
|
|
71
|
+
+ "_"
|
|
72
|
+
+ annr_numeric[valid_mask].astype("string")
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
valid_data, invalid_data = Functions.validate_data(
|
|
76
|
+
df=dataframe,
|
|
77
|
+
schema=WorkHoursGet,
|
|
78
|
+
)
|
|
79
|
+
return valid_data, invalid_data
|
|
80
|
+
except Exception as exc:
|
|
81
|
+
raise RuntimeError("Failed to retrieve work hours data.") from exc
|
|
82
|
+
|
|
83
|
+
def create(self, data: Dict[str, Any]) -> Dict[str, Any]:
|
|
84
|
+
"""
|
|
85
|
+
Create or update work hours (Arbeitszeiten) for an employee.
|
|
86
|
+
"""
|
|
87
|
+
try:
|
|
88
|
+
validated_data = WorkHoursCreate(**data)
|
|
89
|
+
payload = validated_data.model_dump(by_alias=True, exclude_none=True, mode="json")
|
|
90
|
+
response = self.sage.post(
|
|
91
|
+
path=self.base_url,
|
|
92
|
+
body=payload,
|
|
93
|
+
)
|
|
94
|
+
response.raise_for_status()
|
|
95
|
+
return response
|
|
96
|
+
except Exception as exc:
|
|
97
|
+
raise RuntimeError("Failed to create Sage Germany work hours record.") from exc
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: brynq_sdk_sage_germany
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Sage Germany wrapper from BrynQ
|
|
5
|
+
Author: BrynQ
|
|
6
|
+
Author-email: support@brynq.com
|
|
7
|
+
License: BrynQ License
|
|
8
|
+
Requires-Dist: brynq-sdk-brynq<5,>=4
|
|
9
|
+
Requires-Dist: brynq-sdk-functions<3,>=2.1.3
|
|
10
|
+
Requires-Dist: pandas<3,>=2
|
|
11
|
+
Requires-Dist: pydantic>=2
|
|
12
|
+
Requires-Dist: requests>=2
|
|
13
|
+
Requires-Dist: pandera>=0.17
|
|
14
|
+
Dynamic: author
|
|
15
|
+
Dynamic: author-email
|
|
16
|
+
Dynamic: description
|
|
17
|
+
Dynamic: license
|
|
18
|
+
Dynamic: requires-dist
|
|
19
|
+
Dynamic: summary
|
|
20
|
+
|
|
21
|
+
Sage Germany wrapper from BrynQ
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
brynq_sdk_sage_germany/__init__.py,sha256=6bowHadUQZ678vRftuYv5B15lVWFpPMhnGSzq9V_awk,8815
|
|
2
|
+
brynq_sdk_sage_germany/absences.py,sha256=-9zjnI4QUeIBcg7GzdeGSKjJMn_yig7RnZoGsgbxbts,6252
|
|
3
|
+
brynq_sdk_sage_germany/allowances.py,sha256=6aZe4uJLHcCCHWfkpJ_gth16qNp4AA7jE2pibx69njg,3400
|
|
4
|
+
brynq_sdk_sage_germany/contracts.py,sha256=cqYU_eq4OJBV5PfXKrjtJyXMH2YIxO248b8osSPeii8,4162
|
|
5
|
+
brynq_sdk_sage_germany/cost_centers.py,sha256=wHuo7ytuSHJwqJlyhodAE4aEUByQnr8BWRkjb6oYBjY,3015
|
|
6
|
+
brynq_sdk_sage_germany/employees.py,sha256=Ymt69a6zBllnua_SSLmD3BQYIna36s9AyIqbN4GzJxI,5168
|
|
7
|
+
brynq_sdk_sage_germany/helpers.py,sha256=WmaDg5jd-k2AUpXwqYdbvV9D8QY08jqOvbvBEiJwNr8,14147
|
|
8
|
+
brynq_sdk_sage_germany/organization.py,sha256=JLe3CmowaexzJlW2g3idkOCw0i0tjXA0gvHBOQ9oo9M,3171
|
|
9
|
+
brynq_sdk_sage_germany/payroll.py,sha256=912KNRulXTEH36gO6htjvex1jzIFaqbZtnZwglJp6nM,6235
|
|
10
|
+
brynq_sdk_sage_germany/payslips.py,sha256=gyHIoP9YfI1Xp9vtyH_8L_vU-OPhAWTTWNaT5gVjf8c,3378
|
|
11
|
+
brynq_sdk_sage_germany/salaries.py,sha256=DUS-kurrXmW34KyPnTcpAWuiXuSWVE-Ci8SNVlN5I2Q,3402
|
|
12
|
+
brynq_sdk_sage_germany/start_end_dates.py,sha256=pET99m2VbSLFoIQ0PuyD5xNQGvLLBsCcSjDGO-UNtJI,4125
|
|
13
|
+
brynq_sdk_sage_germany/vacation_account.py,sha256=PiEtD3vJ5ULzBFkoyTZfyTa_5x8bDZpzRwsQIVZ_l1o,2256
|
|
14
|
+
brynq_sdk_sage_germany/work_hours.py,sha256=K3e40pmMDquXet0nlhDZmseeSUJXEXIzAefFXRcvz-c,3570
|
|
15
|
+
brynq_sdk_sage_germany/schemas/__init__.py,sha256=s3f9vKHWVZ5etWE2MnDlKfF2ynmtfTQuqrSjdPNBxFI,1254
|
|
16
|
+
brynq_sdk_sage_germany/schemas/absences.py,sha256=HP90mERkHJcO-N9fthcnp7919ib_7LJQ4Yx0Nw-pewA,31080
|
|
17
|
+
brynq_sdk_sage_germany/schemas/allowances.py,sha256=Avbe7OXu2bYdiu7PZyIZqqKLbEQbiVJCLqPond20B-Y,9253
|
|
18
|
+
brynq_sdk_sage_germany/schemas/cost_centers.py,sha256=XVEvXEMt2BWSQ8CqNw7zYyaJWnIiZN4Gc3vMgRMiO_s,1867
|
|
19
|
+
brynq_sdk_sage_germany/schemas/employees.py,sha256=mNfGUOcDdomo000th8EAXt5NQVUdne7jQjRmi7aFb2Q,32740
|
|
20
|
+
brynq_sdk_sage_germany/schemas/organization.py,sha256=_QQ6f_9G1ikNrA4cm6rO_Salqa2uCXWZpr7IQTSXRLc,13359
|
|
21
|
+
brynq_sdk_sage_germany/schemas/organization_assignment.py,sha256=KbatopHoRLNFA1UawYuez9UJJIwLzZmMgU69mLL_kOo,4689
|
|
22
|
+
brynq_sdk_sage_germany/schemas/payroll.py,sha256=baIPi7WUqTw93i_S0aS8CVz-jeoKHzyRdc29G1WPY5E,33969
|
|
23
|
+
brynq_sdk_sage_germany/schemas/payslips.py,sha256=K0yxUCpILe3mGgmhLDxx15u9FU6o2Gtn6Xg5u4G8Hv8,1970
|
|
24
|
+
brynq_sdk_sage_germany/schemas/salaries.py,sha256=WOr8w6cqTpco46tPlqASpGtf7n6AgYCbN7T3PE-2nPM,9709
|
|
25
|
+
brynq_sdk_sage_germany/schemas/start_end_dates.py,sha256=4hyUV-1p7GK0nHSMVg0z7me6npYAXuQqM7jSLrJrj4Y,7732
|
|
26
|
+
brynq_sdk_sage_germany/schemas/vacation_account.py,sha256=a88SGGzYr2iwX-cW3JrAxgswAGG13Bb1C3Sn6Cn3Avk,13648
|
|
27
|
+
brynq_sdk_sage_germany/schemas/work_hours.py,sha256=NWLnyo5Fo_-jF22jPSpvCofe-dQpY8gISu8RGTYjRl0,7527
|
|
28
|
+
brynq_sdk_sage_germany-1.0.0.dist-info/METADATA,sha256=_MfapzG041837fxCwzAfYxHqckwEFLxANqyOu36ipII,518
|
|
29
|
+
brynq_sdk_sage_germany-1.0.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
30
|
+
brynq_sdk_sage_germany-1.0.0.dist-info/top_level.txt,sha256=YhZNSFzDucaDPMjEkYY0jShXhMFgX1-JxRuosnHXbB0,23
|
|
31
|
+
brynq_sdk_sage_germany-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
brynq_sdk_sage_germany
|