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.
Files changed (31) hide show
  1. brynq_sdk_sage_germany/__init__.py +278 -0
  2. brynq_sdk_sage_germany/absences.py +175 -0
  3. brynq_sdk_sage_germany/allowances.py +100 -0
  4. brynq_sdk_sage_germany/contracts.py +145 -0
  5. brynq_sdk_sage_germany/cost_centers.py +89 -0
  6. brynq_sdk_sage_germany/employees.py +140 -0
  7. brynq_sdk_sage_germany/helpers.py +391 -0
  8. brynq_sdk_sage_germany/organization.py +90 -0
  9. brynq_sdk_sage_germany/payroll.py +167 -0
  10. brynq_sdk_sage_germany/payslips.py +106 -0
  11. brynq_sdk_sage_germany/salaries.py +95 -0
  12. brynq_sdk_sage_germany/schemas/__init__.py +44 -0
  13. brynq_sdk_sage_germany/schemas/absences.py +311 -0
  14. brynq_sdk_sage_germany/schemas/allowances.py +147 -0
  15. brynq_sdk_sage_germany/schemas/cost_centers.py +46 -0
  16. brynq_sdk_sage_germany/schemas/employees.py +487 -0
  17. brynq_sdk_sage_germany/schemas/organization.py +172 -0
  18. brynq_sdk_sage_germany/schemas/organization_assignment.py +61 -0
  19. brynq_sdk_sage_germany/schemas/payroll.py +287 -0
  20. brynq_sdk_sage_germany/schemas/payslips.py +34 -0
  21. brynq_sdk_sage_germany/schemas/salaries.py +101 -0
  22. brynq_sdk_sage_germany/schemas/start_end_dates.py +194 -0
  23. brynq_sdk_sage_germany/schemas/vacation_account.py +117 -0
  24. brynq_sdk_sage_germany/schemas/work_hours.py +94 -0
  25. brynq_sdk_sage_germany/start_end_dates.py +123 -0
  26. brynq_sdk_sage_germany/vacation_account.py +70 -0
  27. brynq_sdk_sage_germany/work_hours.py +97 -0
  28. brynq_sdk_sage_germany-1.0.0.dist-info/METADATA +21 -0
  29. brynq_sdk_sage_germany-1.0.0.dist-info/RECORD +31 -0
  30. brynq_sdk_sage_germany-1.0.0.dist-info/WHEEL +5 -0
  31. 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,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.10.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ brynq_sdk_sage_germany