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,311 @@
1
+ """
2
+ Schemas for Sage Germany absence payloads.
3
+ """
4
+
5
+ from typing import Optional, Any, List
6
+
7
+ import pandas as pd
8
+ import pandera as pa
9
+ from pandera.typing import Series
10
+ from pydantic import BaseModel, Field, ConfigDict
11
+
12
+ from brynq_sdk_functions import BrynQPanderaDataFrameModel
13
+
14
+ __all__ = ["AbsencesGet", "AbsenceTypesGet", "AbsenceCreate", "AbsenceDelete"]
15
+
16
+
17
+ class AbsencesGet(BrynQPanderaDataFrameModel):
18
+ """
19
+ Pandera schema for flattened absence records.
20
+ """
21
+
22
+ # Base identifiers
23
+ absence_id: Series[pd.Int64Dtype] = pa.Field(alias="Id", coerce=True, nullable=False, description="Unique absence identifier.")
24
+ tenant_number: Series[pd.Int64Dtype] = pa.Field(alias="MdNr", coerce=True, nullable=False, description="Tenant (Mandant) number.")
25
+ employee_number: Series[pd.Int64Dtype] = pa.Field(alias="AnNr", coerce=True, nullable=False, description="Employee number.")
26
+
27
+ #Absence details
28
+ date_from: Optional[Series[pd.StringDtype]] = pa.Field(alias="From", coerce=True, nullable=True, description="Absence start timestamp.")
29
+ from_day_type: Optional[Series[pd.StringDtype]] = pa.Field(alias="FromDayType", coerce=True, nullable=True, description="Start day granularity.")
30
+ date_to: Optional[Series[pd.StringDtype]] = pa.Field(alias="To", coerce=True, nullable=True, description="Absence end timestamp.")
31
+ to_day_type: Optional[Series[pd.StringDtype]] = pa.Field(alias="ToDayType", coerce=True, nullable=True, description="End day granularity.")
32
+ last_working_day: Optional[Series[pd.StringDtype]] = pa.Field(alias="LastWorkingDay", coerce=True, nullable=True, description="Last working day before absence.")
33
+ absence_category: Optional[Series[pd.StringDtype]] = pa.Field(alias="AbsenceType", coerce=True, nullable=True, description="Absence category.")
34
+ absence_category_text: Optional[Series[pd.StringDtype]] = pa.Field(alias="AbsenceTypeText", coerce=True, nullable=True, description="Absence category description.")
35
+ open_end: Optional[Series[bool]] = pa.Field(alias="OpenEnd", coerce=True, nullable=True, description="Indicates an open-ended absence.")
36
+ state: Optional[Series[pd.StringDtype]] = pa.Field(alias="State", coerce=True, nullable=True, description="Absence state.")
37
+ accepted_in_payroll: Optional[Series[bool]] = pa.Field(alias="AcceptedPayroll", coerce=True, nullable=True, description="Indicates acceptance in payroll.")
38
+
39
+
40
+ # Absence type metadata
41
+ absence_type_id: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="Type__Id", coerce=True, nullable=True, description="Absence type identifier.")
42
+ absence_type_tenant_number: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="Type__MdNr", coerce=True, nullable=True, description="Absence type tenant number.")
43
+ absence_type_number: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="Type__Number", coerce=True, nullable=True, description="Absence type number.")
44
+ absence_type_name: Optional[Series[pd.StringDtype]] = pa.Field(alias="Type__Name", coerce=True, nullable=True, description="Absence type name.")
45
+ absence_type_status_id: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="Type__Status__Id", coerce=True, nullable=True, description="Absence type status identifier.")
46
+ absence_type_status: Optional[Series[pd.StringDtype]] = pa.Field(alias="Type__Status__Status", coerce=True, nullable=True, description="Absence type status.")
47
+ absence_type_status_short: Optional[Series[pd.StringDtype]] = pa.Field(alias="Type__Status__StatusShort", coerce=True, nullable=True, description="Absence type status short label.")
48
+ absence_day_type: Optional[Series[pd.StringDtype]] = pa.Field(alias="Type__DayType", coerce=True, nullable=True, description="Absence day type.")
49
+ absence_color: Optional[Series[pd.StringDtype]] = pa.Field(alias="Type__Color", coerce=True, nullable=True, description="Primary calendar color.")
50
+ absence_is_historic: Optional[Series[bool]] = pa.Field(alias="Type__IsHistoric", coerce=True, nullable=True, description="Indicates historic absence type.")
51
+ absence_is_holiday: Optional[Series[bool]] = pa.Field(alias="Type__IsHoliday", coerce=True, nullable=True, description="Indicates holiday type.")
52
+ absence_is_sick: Optional[Series[bool]] = pa.Field(alias="Type__IsSick", coerce=True, nullable=True, description="Indicates sickness type.")
53
+ absence_color_previous_year: Optional[Series[pd.StringDtype]] = pa.Field(alias="Type__ColorPreviousYear", coerce=True, nullable=True, description="Previous year color code.")
54
+ absence_priority: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="Type__Priority", coerce=True, nullable=True, description="Absence priority.")
55
+ absence_has_last_working_day: Optional[Series[bool]] = pa.Field(alias="Type__HasLastWorkingDay", coerce=True, nullable=True, description="Indicates requirement for last working day.")
56
+ absence_acquisition_unit: Optional[Series[pd.StringDtype]] = pa.Field(alias="Type__AcquisitionUnit", coerce=True, nullable=True, description="Absence acquisition unit.")
57
+ absence_valid_from: Optional[Series[pd.StringDtype]] = pa.Field(alias="Type__ValidFrom", coerce=True, nullable=True, description="Type valid-from date.")
58
+ absence_valid_to: Optional[Series[pd.StringDtype]] = pa.Field(alias="Type__ValidTo", coerce=True, nullable=True, description="Type valid-to date.")
59
+ holiday_calculation_id: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="Type__HolidayCalculation__Id", coerce=True, nullable=True, description="Holiday calculation identifier.")
60
+ holiday_calculation_description: Optional[Series[pd.StringDtype]] = pa.Field(alias="Type__HolidayCalculation__Description", coerce=True, nullable=True, description="Holiday calculation description.")
61
+ holiday_calculation_code: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="Type__HolidayCalculation__Calculation", coerce=True, nullable=True, description="Holiday calculation code.")
62
+
63
+ # Replacement and deputy metadata
64
+ replacement_employee_number: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="AbsencePlaning__Replacement__AnNr", coerce=True, nullable=True, description="Replacement employee number.")
65
+ replacement_first_name: Optional[Series[pd.StringDtype]] = pa.Field(alias="AbsencePlaning__Replacement__Name__Firstname", coerce=True, nullable=True, description="Replacement first name.")
66
+ replacement_last_name: Optional[Series[pd.StringDtype]] = pa.Field(alias="AbsencePlaning__Replacement__Name__Lastname", coerce=True, nullable=True, description="Replacement last name.")
67
+ replacement_full_name: Optional[Series[pd.StringDtype]] = pa.Field(alias="AbsencePlaning__Replacement__Name__Fullname", coerce=True, nullable=True, description="Replacement full name.")
68
+ deputy_tenant_number: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="Deputy__MdNr", coerce=True, nullable=True, description="Deputy tenant number.")
69
+ deputy_employee_number: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="Deputy__AnNr", coerce=True, nullable=True, description="Deputy employee number.")
70
+ deputy_combined_key: Optional[Series[pd.StringDtype]] = pa.Field(alias="Deputy__CombinedKey", coerce=True, nullable=True, description="Deputy combined key.")
71
+ deputy_is_empty: Optional[Series[bool]] = pa.Field(alias="Deputy__IsEmpty", coerce=True, nullable=True, description="Indicates whether deputy payload is empty.")
72
+
73
+
74
+ # Duration and accident statistics
75
+ days_count: Optional[Series[pd.Float64Dtype]] = pa.Field(alias="DaysCount", coerce=True, nullable=True, description="Total number of days.")
76
+ days_count_own: Optional[Series[pd.Float64Dtype]] = pa.Field(alias="DaysCountOwn", coerce=True, nullable=True, description="Own quota days.")
77
+ days_count_previous_year: Optional[Series[pd.Float64Dtype]] = pa.Field(alias="DaysCountPrevYear", coerce=True, nullable=True, description="Days counted from previous year.")
78
+ days_divergent: Optional[Series[pd.Float64Dtype]] = pa.Field(alias="DaysDivergent", coerce=True, nullable=True, description="Divergent day count.")
79
+ accident_at_work: Optional[Series[bool]] = pa.Field(alias="AccidentAtWork", coerce=True, nullable=True, description="Work accident flag.")
80
+ day_of_accident: Optional[Series[pd.StringDtype]] = pa.Field(alias="DayOfAccident", coerce=True, nullable=True, description="Accident day timestamp.")
81
+ accident_insurance_number: Optional[Series[pd.StringDtype]] = pa.Field(alias="AccidentInsuranceNumber", coerce=True, nullable=True, description="Accident insurance number.")
82
+ accident_insurance_reference_number: Optional[Series[pd.StringDtype]] = pa.Field(alias="AccidentInsuranceReferenceNumber", coerce=True, nullable=True, description="Accident insurance reference number.")
83
+ third_party_harm: Optional[Series[bool]] = pa.Field(alias="ThirdPartyHarm", coerce=True, nullable=True, description="Third-party harm flag.")
84
+ worked_on_first_absence_day: Optional[Series[bool]] = pa.Field(alias="WorkedOnFirstAbsenceday", coerce=True, nullable=True, description="Indicates if employee worked on first absence day.")
85
+
86
+ # Audit trail
87
+ created_at: Optional[Series[pd.StringDtype]] = pa.Field(alias="CreatedAt", coerce=True, nullable=True, description="Creation timestamp.")
88
+ created_by: Optional[Series[pd.StringDtype]] = pa.Field(alias="CreatedBy", coerce=True, nullable=True, description="Creator identifier.")
89
+ changed_at: Optional[Series[pd.StringDtype]] = pa.Field(alias="ChangedAt", coerce=True, nullable=True, description="Last modification timestamp.")
90
+ changed_by: Optional[Series[pd.StringDtype]] = pa.Field(alias="ChangedBy", coerce=True, nullable=True, description="Modifier identifier.")
91
+ comment: Optional[Series[pd.StringDtype]] = pa.Field(alias="Comment", coerce=True, nullable=True, description="Absence comment.")
92
+
93
+ # Workflow and validation payloads
94
+ follow_absence_time_id: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="FollowAbsenceTimeId", coerce=True, nullable=True, description="Follow-up absence identifier.")
95
+ absence_planing_payload: Optional[Series[pd.StringDtype]] = pa.Field(alias="AbsencePlaning", coerce=True, nullable=True, description="Absence planning payload.")
96
+ is_task: Optional[Series[bool]] = pa.Field(alias="IsTask", coerce=True, nullable=True, description="Absence is linked to a task.")
97
+ task_id: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="TaskId", coerce=True, nullable=True, description="Task identifier.")
98
+ workflow_plan_value_id: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="WorkflowPlanValID", coerce=True, nullable=True, description="Workflow plan value identifier.")
99
+ additional_input_id: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="AdditionalInputId", coerce=True, nullable=True, description="Additional input identifier.")
100
+ deputy_payload: Optional[Series[pd.StringDtype]] = pa.Field(alias="Deputy", coerce=True, nullable=True, description="Deputy payload.")
101
+ deputy_name: Optional[Series[pd.StringDtype]] = pa.Field(alias="DeputyName", coerce=True, nullable=True, description="Deputy name.")
102
+ previous_sickness: Optional[Series[bool]] = pa.Field(alias="PreviousSickness", coerce=True, nullable=True, description="Previous sickness flag.")
103
+ previous_sickness_request: Optional[Series[pd.StringDtype]] = pa.Field(alias="PreviousSicknessRequest", coerce=True, nullable=True, description="Previous sickness request state.")
104
+ previous_sickness_absence_time_id: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="PreviousSicknessAbsenceTimeId", coerce=True, nullable=True, description="Previous sickness absence time identifier.")
105
+ previous_sickness_absence_time_task_id: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="PreviousSicknessAbsenceTimeTaskId", coerce=True, nullable=True, description="Previous sickness task identifier.")
106
+ previous_sickness_absence_time_ids: Optional[Series[pd.StringDtype]] = pa.Field(alias="PreviousSicknessAbsenceTimeIds", coerce=True, nullable=True, description="Previous sickness related ids.")
107
+ end_of_payment_for_longtime_sickness: Optional[Series[pd.StringDtype]] = pa.Field(alias="EndOfPaymentForLongtimeSickness", coerce=True, nullable=True, description="End of payment date for long-time sickness.")
108
+ errors_payload: Optional[Series[pd.StringDtype]] = pa.Field(alias="Errors", coerce=True, nullable=True, description="Errors payload.")
109
+ deputies_payload: Optional[Series[pd.StringDtype]] = pa.Field(alias="Deputies", coerce=True, nullable=True, description="Deputies payload.")
110
+ approver_payload: Optional[Series[pd.StringDtype]] = pa.Field(alias="Approver", coerce=True, nullable=True, description="Approver payload.")
111
+ status_eau_anfrage_id: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="StatusEauAnfrage__Id", coerce=True, nullable=True, description="Electronic AU status identifier.")
112
+ status_eau_anfrage_text: Optional[Series[pd.StringDtype]] = pa.Field(alias="StatusEauAnfrage__Text", coerce=True, nullable=True, description="Electronic AU status text.")
113
+ status_eau_anfrage_id_text: Optional[Series[pd.StringDtype]] = pa.Field(alias="StatusEauAnfrage__IdMitText", coerce=True, nullable=True, description="Electronic AU status id-text.")
114
+ absence_time_eau_anfrage: Optional[Series[pd.StringDtype]] = pa.Field(alias="AbsenceTimeEauAnfrage", coerce=True, nullable=True, description="Absence time electronic AU payload.")
115
+ hours_payload: Optional[Series[pd.StringDtype]] = pa.Field(alias="Hours", coerce=True, nullable=True, description="Hours payload.")
116
+ manual_different_days: Optional[Series[bool]] = pa.Field(alias="ManualDifferentDays", coerce=True, nullable=True, description="Manual different days flag.")
117
+
118
+ class _Annotation:
119
+ primary_key = "absence_id"
120
+
121
+ class Config:
122
+ coerce = True
123
+ strict = "filter"
124
+
125
+
126
+ class AbsenceStatus(BaseModel):
127
+ id: Optional[int] = Field(default=None, alias="Id", description="Status identifier.", example=1)
128
+ status: Optional[str] = Field(default=None, alias="Status", description="Status text.", example="Approved")
129
+ status_short: Optional[str] = Field(default=None, alias="StatusShort", description="Short status text.", example="APP")
130
+
131
+ model_config = ConfigDict(populate_by_name=True)
132
+
133
+
134
+ class AbsenceHolidayCalculation(BaseModel):
135
+ id: Optional[int] = Field(default=None, alias="Id", description="Holiday calculation identifier.", example=1)
136
+ description: Optional[str] = Field(default=None, alias="Description", description="Description text.", example="Standard calculation")
137
+ calculation: Optional[int] = Field(default=None, alias="Calculation", description="Calculation code.", example=1)
138
+
139
+ model_config = ConfigDict(populate_by_name=True)
140
+
141
+
142
+ class AbsenceTypePayload(BaseModel):
143
+ id: int = Field(alias="Id", description="Absence type identifier.", example=1, json_schema_extra={"prefix": "type_"})
144
+ company_id: int = Field(alias="MdNr", description="Company id (Mandant).", example=1, json_schema_extra={"prefix": "type_"})
145
+ number: Optional[int] = Field(default=None, alias="Number", description="Absence type number.", example=100, json_schema_extra={"prefix": "type_"})
146
+ name: Optional[str] = Field(default=None, alias="Name", description="Absence type name.", example="Vacation", json_schema_extra={"prefix": "type_"})
147
+ show_in_web: Optional[bool] = Field(default=None, alias="ShowInWeb", description="Visible on web.", example=True, json_schema_extra={"prefix": "type_"})
148
+ is_historic: Optional[bool] = Field(default=None, alias="IsHistoric", description="Historic flag.", example=False, json_schema_extra={"prefix": "type_"})
149
+ is_holiday: Optional[bool] = Field(default=None, alias="IsHoliday", description="Holiday flag.", example=True, json_schema_extra={"prefix": "type_"})
150
+ is_chargeable_workingtime: Optional[bool] = Field(default=None, alias="IsChargeableWorkingtime", description="Chargeable working time flag.", example=False, json_schema_extra={"prefix": "type_"})
151
+ day_type: Optional[str] = Field(default=None, alias="DayType", description="Day type.", example="FullDay", json_schema_extra={"prefix": "type_"})
152
+ workflow_plan_id: Optional[int] = Field(default=None, alias="WorkFlowPlanId", description="Workflow plan id.", example=1, json_schema_extra={"prefix": "type_"})
153
+ storno_workflow_plan_id: Optional[int] = Field(default=None, alias="StornoWorkFlowPlanId", description="Storno workflow plan id.", example=2, json_schema_extra={"prefix": "type_"})
154
+ status: Optional[AbsenceStatus] = Field(default=None, alias="Status", description="Status payload.", json_schema_extra={"prefix": "type_status_"})
155
+ holiday_calculation: Optional[AbsenceHolidayCalculation] = Field(default=None, alias="HolidayCalculation", description="Holiday calculation payload.", json_schema_extra={"prefix": "type_holiday_calculation_"})
156
+ acquisition_unit: Optional[str] = Field(default=None, alias="AcquisitionUnit", description="Acquisition unit.", example="Days", json_schema_extra={"prefix": "type_"})
157
+ valid_from: Optional[str] = Field(default=None, alias="ValidFrom", description="Valid-from date.", example="2024-01-01", json_schema_extra={"prefix": "type_"})
158
+ valid_to: Optional[str] = Field(default=None, alias="ValidTo", description="Valid-to date.", example="2024-12-31", json_schema_extra={"prefix": "type_"})
159
+ pre_existing_condition: Optional[bool] = Field(default=None, alias="PreExistingCondition", description="Pre-existing condition.", example=False, json_schema_extra={"prefix": "type_"})
160
+
161
+ model_config = ConfigDict(populate_by_name=True)
162
+
163
+
164
+ class AbsenceEmployeeKey(BaseModel):
165
+ company_id: Optional[int] = Field(default=None, alias="MdNr", description="Company id.", example=1, json_schema_extra={"prefix": "absence_planing_employee_key_"})
166
+ employee_number: Optional[int] = Field(default=None, alias="AnNr", description="Employee number.", example=100, json_schema_extra={"prefix": "absence_planing_employee_key_"})
167
+ combined_key: Optional[str] = Field(default=None, alias="CombinedKey", description="Combined key.", example="1_100", json_schema_extra={"prefix": "absence_planing_employee_key_"})
168
+ is_empty: Optional[bool] = Field(default=None, alias="IsEmpty", description="Empty flag.", example=False, json_schema_extra={"prefix": "absence_planing_employee_key_"})
169
+
170
+ model_config = ConfigDict(populate_by_name=True)
171
+
172
+
173
+ class AbsencePlaning(BaseModel):
174
+ employee_key: Optional[AbsenceEmployeeKey] = Field(default=None, alias="EmployeeKey", description="Employee key.", json_schema_extra={"prefix": "absence_planing_"})
175
+ id: Optional[int] = Field(default=None, alias="Id", description="Absence planning id.", example=1, json_schema_extra={"prefix": "absence_planing_"})
176
+ replacement: Optional[Any] = Field(default=None, alias="Replacement", description="Replacement payload.", example=None, json_schema_extra={"prefix": "absence_planing_"})
177
+
178
+ model_config = ConfigDict(populate_by_name=True)
179
+
180
+
181
+ class AbsenceCreate(BaseModel):
182
+ """
183
+ Pydantic schema for absence creation payloads.
184
+ """
185
+
186
+ id: Optional[int] = Field(default=None, alias="Id", description="Absence id.", example=1)
187
+ company_id: int = Field(alias="MdNr", description="Company id (Mandant).", example=1)
188
+ employee_number: int = Field(alias="AnNr", description="Employee number.", example=100)
189
+ type: AbsenceTypePayload = Field(alias="Type", description="Absence type payload.")
190
+ date_from: str = Field(alias="From", description="Start timestamp.", example="2024-01-15T00:00:00")
191
+ date_to: str = Field(alias="To", description="End timestamp.", example="2024-01-20T00:00:00")
192
+ from_day_type: Optional[str] = Field(default=None, alias="FromDayType", description="Start day type.", example="FullDay")
193
+ to_day_type: Optional[str] = Field(default=None, alias="ToDayType", description="End day type.", example="FullDay")
194
+ last_working_day: Optional[str] = Field(default=None, alias="LastWorkingDay", description="Last working day before absence.", example="2024-01-14")
195
+ absence_planing: Optional[AbsencePlaning] = Field(default=None, alias="AbsencePlaning", description="Absence planning payload.")
196
+ follow_absence_time_id: Optional[int] = Field(default=None, alias="FollowAbsenceTimeId", description="Follow-up absence id.", example=2)
197
+ absence_type: Optional[str] = Field(default=None, alias="AbsenceType", description="Absence type category.", example="Vacation")
198
+ absence_type_text: Optional[str] = Field(default=None, alias="AbsenceTypeText", description="Absence type description.", example="Annual Leave")
199
+ open_end: bool = Field(alias="OpenEnd", description="Open-end flag.", example=False)
200
+ state: Optional[str] = Field(default=None, alias="State", description="State value.", example="Approved")
201
+ days_count: Optional[float] = Field(default=None, alias="DaysCount", description="Total days.", example=5.0)
202
+ days_previous_year: Optional[float] = Field(default=None, alias="DaysVJ", description="Previous year days.", example=0.0)
203
+ days_current_year: Optional[float] = Field(default=None, alias="DaysKJ", description="Current year days.", example=5.0)
204
+ days_divergent: Optional[float] = Field(default=None, alias="DaysDivergent", description="Divergent days.", example=0.0)
205
+ accident_at_work: Optional[bool] = Field(default=None, alias="AccidentAtWork", description="Accident at work flag.", example=False)
206
+ day_of_accident: Optional[str] = Field(default=None, alias="DayOfAccident", description="Day of accident.", example="2024-01-15")
207
+ accident_insurance_number: Optional[str] = Field(default=None, alias="AccidentInsuranceNumber", description="Accident insurance number.", example="INS123")
208
+ accident_insurance_reference_number: Optional[str] = Field(default=None, alias="AccidentInsuranceReferenceNumber", description="Accident insurance reference number.", example="REF456")
209
+ third_party_harm: Optional[bool] = Field(default=None, alias="ThirdPartyHarm", description="Third party harm flag.", example=False)
210
+ worked_on_first_absence_day: Optional[bool] = Field(default=None, alias="WorkedOnFirstAbsenceday", description="Worked on first absence day flag.", example=False)
211
+ changed_at: Optional[str] = Field(default=None, alias="ChangedAt", description="Changed at timestamp.", example="2024-01-10T10:00:00")
212
+ created_by: Optional[str] = Field(default=None, alias="CreatedBy", description="Created by.", example="admin")
213
+ created_at: Optional[str] = Field(default=None, alias="CreatedAt", description="Created at timestamp.", example="2024-01-10T09:00:00")
214
+ changed_by: Optional[str] = Field(default=None, alias="ChangedBy", description="Changed by.", example="admin")
215
+ comment: Optional[str] = Field(default=None, alias="Comment", description="Comment text.", example="Vacation request")
216
+ is_task: Optional[bool] = Field(default=None, alias="IsTask", description="Task flag.", example=False)
217
+ task_id: Optional[int] = Field(default=None, alias="TaskId", description="Task id.", example=1)
218
+ workflow_plan_val_id: Optional[int] = Field(default=None, alias="WorkflowPlanValID", description="Workflow plan validation id.", example=1)
219
+ deputy: Optional[Any] = Field(default=None, alias="Deputy", description="Deputy payload.", example=None)
220
+ deputy_name: Optional[Any] = Field(default=None, alias="DeputyName", description="Deputy name payload.", example=None)
221
+ previous_sickness: Optional[bool] = Field(default=None, alias="PreviousSickness", description="Previous sickness flag.", example=False)
222
+ previous_sickness_request: Optional[str] = Field(default=None, alias="PreviousSicknessRequest", description="Previous sickness request.", example="None")
223
+ previous_sickness_absence_time_id: Optional[int] = Field(default=None, alias="PreviousSicknessAbsenceTimeId", description="Previous sickness absence time id.", example=0)
224
+ previous_sickness_absence_time_task_id: Optional[int] = Field(default=None, alias="PreviousSicknessAbsenceTimeTaskId", description="Previous sickness absence task id.", example=0)
225
+ end_of_payment_for_longtime_sickness: Optional[str] = Field(default=None, alias="EndOfPaymentForLongtimeSickness", description="End of payment for long sickness.", example="2024-12-31")
226
+ errors: Optional[List[Any]] = Field(default=None, alias="Errors", description="Errors payload.", example=[])
227
+ deputies: Optional[List[Any]] = Field(default=None, alias="Deputies", description="Deputies payload.", example=[])
228
+ approver: Optional[Any] = Field(default=None, alias="Approver", description="Approver payload.", example=None)
229
+
230
+ model_config = ConfigDict(populate_by_name=True)
231
+
232
+
233
+ class AbsenceDelete(BaseModel):
234
+ """
235
+ Minimal payload for deleting an absence entry.
236
+ """
237
+
238
+ id: int = Field(alias="Id", description="Absence identifier.", example=1)
239
+ company_id: int = Field(alias="MdNr", description="Company id (Mandant).", example=1)
240
+ employee_number: int = Field(alias="AnNr", description="Employee number.", example=100)
241
+
242
+ model_config = ConfigDict(populate_by_name=True)
243
+
244
+
245
+ class AbsenceTypesGet(BrynQPanderaDataFrameModel):
246
+ """
247
+ Pandera schema for absence type reference data.
248
+ """
249
+
250
+ # Base identifiers
251
+ type_id: Series[pd.Int64Dtype] = pa.Field(alias="Id", coerce=True, nullable=False, description="Absence type identifier.")
252
+ tenant_number: Series[pd.Int64Dtype] = pa.Field(alias="MdNr", coerce=True, nullable=False, description="Tenant (Mandant) number.")
253
+ type_number: Series[pd.Int64Dtype] = pa.Field(alias="Number", coerce=True, nullable=False, description="Absence type number.")
254
+
255
+ # Labels and descriptions
256
+ name: Optional[Series[pd.StringDtype]] = pa.Field(alias="Name", coerce=True, nullable=True, description="Absence type name.")
257
+ name_short: Optional[Series[pd.StringDtype]] = pa.Field(alias="NameShort", coerce=True, nullable=True, description="Short name.")
258
+ description: Optional[Series[pd.StringDtype]] = pa.Field(alias="Description", coerce=True, nullable=True, description="Description text.")
259
+
260
+ # Visuals
261
+ color: Optional[Series[pd.StringDtype]] = pa.Field(alias="Color", coerce=True, nullable=True, description="Primary color.")
262
+ color_previous_year: Optional[Series[pd.StringDtype]] = pa.Field(alias="ColorPreviousYear", coerce=True, nullable=True, description="Previous year color.")
263
+
264
+ # Flags
265
+ show_in_web: Optional[Series[bool]] = pa.Field(alias="ShowInWeb", coerce=True, nullable=True, description="Display in web flag.")
266
+ is_used_for_training: Optional[Series[bool]] = pa.Field(alias="IsUsedForTraining", coerce=True, nullable=True, description="Training flag.")
267
+ is_historic: Optional[Series[bool]] = pa.Field(alias="IsHistoric", coerce=True, nullable=True, description="Historic flag.")
268
+ is_holiday: Optional[Series[bool]] = pa.Field(alias="IsHoliday", coerce=True, nullable=True, description="Holiday flag.")
269
+ is_sick: Optional[Series[bool]] = pa.Field(alias="IsSick", coerce=True, nullable=True, description="Sickness flag.")
270
+ day_type: Optional[Series[pd.StringDtype]] = pa.Field(alias="DayType", coerce=True, nullable=True, description="Day type.")
271
+ acquisition_unit: Optional[Series[pd.StringDtype]] = pa.Field(alias="AcquisitionUnit", coerce=True, nullable=True, description="Acquisition unit.")
272
+
273
+ # Status info
274
+ status_id: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="Status__Id", coerce=True, nullable=True, description="Status identifier.")
275
+ status_name: Optional[Series[pd.StringDtype]] = pa.Field(alias="Status__Status", coerce=True, nullable=True, description="Status name.")
276
+ status_short: Optional[Series[pd.StringDtype]] = pa.Field(alias="Status__StatusShort", coerce=True, nullable=True, description="Status short code.")
277
+
278
+ # Holiday calculation
279
+ holiday_calculation_id: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="HolidayCalculation__Id", coerce=True, nullable=True, description="Holiday calc identifier.")
280
+ holiday_calculation_description: Optional[Series[pd.StringDtype]] = pa.Field(alias="HolidayCalculation__Description", coerce=True, nullable=True, description="Holiday calc description.")
281
+ holiday_calculation_code: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="HolidayCalculation__Calculation", coerce=True, nullable=True, description="Holiday calc code.")
282
+
283
+ # Lifecycle
284
+ valid_from: Optional[Series[pd.StringDtype]] = pa.Field(alias="ValidFrom", coerce=True, nullable=True, description="Valid from timestamp.")
285
+ valid_to: Optional[Series[pd.StringDtype]] = pa.Field(alias="ValidTo", coerce=True, nullable=True, description="Valid to timestamp.")
286
+ used_until: Optional[Series[pd.StringDtype]] = pa.Field(alias="UsedUntil", coerce=True, nullable=True, description="Used until timestamp.")
287
+ gueltig_ab: Optional[Series[pd.StringDtype]] = pa.Field(alias="GueltigAb", coerce=True, nullable=True, description="Localized valid from.")
288
+ gueltig_bis: Optional[Series[pd.StringDtype]] = pa.Field(alias="GueltigBis", coerce=True, nullable=True, description="Localized valid to.")
289
+
290
+ # Behavioral flags
291
+ is_sickness_without_eau: Optional[Series[bool]] = pa.Field(alias="IsSicknessWithoutEAU", coerce=True, nullable=True, description="Sickness without EAU flag.")
292
+ pre_existing_condition: Optional[Series[bool]] = pa.Field(alias="PreExistingCondition", coerce=True, nullable=True, description="Pre-existing condition flag.")
293
+ book_interruption: Optional[Series[bool]] = pa.Field(alias="BookInterruption", coerce=True, nullable=True, description="Book interruption flag.")
294
+ fill_to_target_time: Optional[Series[bool]] = pa.Field(alias="FillToTargetTime", coerce=True, nullable=True, description="Fill to target time flag.")
295
+ ignore_rules_on_half_holidays: Optional[Series[bool]] = pa.Field(alias="IgnoreRulesOnHalfHolidays", coerce=True, nullable=True, description="Ignore half-holiday rules flag.")
296
+ full_time_statistics_deduction: Optional[Series[bool]] = pa.Field(alias="MinderungVollbeschaeftigtenStatistik", coerce=True, nullable=True, description="Full-time statistics deduction flag.")
297
+ has_last_working_day: Optional[Series[bool]] = pa.Field(alias="HasLastWorkingDay", coerce=True, nullable=True, description="Requires last working day flag.")
298
+
299
+ # Priorities and workflow
300
+ priority: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="Priority", coerce=True, nullable=True, description="Priority value.")
301
+ is_not_deletable: Optional[Series[bool]] = pa.Field(alias="IsNotDeletable", coerce=True, nullable=True, description="Deletion protection flag.")
302
+ is_in_use: Optional[Series[bool]] = pa.Field(alias="IsInUse", coerce=True, nullable=True, description="In-use flag.")
303
+ workflow_plan_cancel_id: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="WorkflowPlanCancelId", coerce=True, nullable=True, description="Workflow cancel plan id.")
304
+ workflow_plan_request_id: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="WorkflowPlanRequestId", coerce=True, nullable=True, description="Workflow request plan id.")
305
+
306
+ class _Annotation:
307
+ primary_key = "type_id"
308
+
309
+ class Config:
310
+ coerce = True
311
+ strict = "filter"
@@ -0,0 +1,147 @@
1
+ """
2
+ Schemas for Sage Germany employee allowances payloads.
3
+ """
4
+
5
+ from datetime import datetime
6
+ from typing import Optional
7
+
8
+ import pandas as pd
9
+ import pandera as pa
10
+ from pandera.typing import Series
11
+ from pydantic import BaseModel, Field, ConfigDict
12
+
13
+ from brynq_sdk_functions import BrynQPanderaDataFrameModel
14
+
15
+
16
+ class AllowanceKey(BaseModel):
17
+ """
18
+ Snapshot key for a single allowance record.
19
+ """
20
+
21
+ date: datetime = Field(alias="Date", description="Snapshot date.", example="2024-01-01T00:00:00")
22
+ company_id: int = Field(alias="MdNr", description="Company id (Mandant).", example=1)
23
+ employee_number: int = Field(alias="AnNr", description="Employee number.", example=100)
24
+ combined_key: str = Field(alias="CombinedKey", description="Combined key string.", example="1_100")
25
+ is_empty: bool = Field(alias="IsEmpty", description="Empty marker.", example=False)
26
+
27
+ model_config = ConfigDict(populate_by_name=True)
28
+
29
+
30
+ class WageType(BaseModel):
31
+ """
32
+ Wage type metadata used in allowances.
33
+ """
34
+
35
+ number: int = Field(alias="LaNr", description="Wage type number.", example=1000)
36
+ display_name: Optional[str] = Field(default=None, alias="AnzeigeName", description="Display name.", example="Bonus")
37
+ company_id: Optional[int] = Field(default=None, alias="MdNr", description="Company id.", example=1)
38
+ description: Optional[str] = Field(default=None, alias="Bezeichnung", description="Description.", example="Monthly Bonus")
39
+ is_deduction: Optional[bool] = Field(default=None, alias="IstAbzug", description="Deduction flag.", example=False)
40
+ surcharge: Optional[float] = Field(default=None, alias="Zuschlag", description="Surcharge value.", example=0.0)
41
+ surcharge_unit: Optional[str] = Field(default=None, alias="ZuschlagEinheit", description="Surcharge unit.", example="EUR")
42
+
43
+ model_config = ConfigDict(populate_by_name=True)
44
+
45
+
46
+ class PaymentFrequency(BaseModel):
47
+ """
48
+ Payment rhythm block.
49
+ """
50
+
51
+ id: int = Field(alias="Id", description="Payment rhythm identifier.", example=1)
52
+ text: Optional[str] = Field(default=None, alias="Text", description="Payment rhythm text.", example="Monthly")
53
+ id_with_text: Optional[str] = Field(default=None, alias="IdMitText", description="Payment rhythm id-text.", example="1 - Monthly")
54
+
55
+ model_config = ConfigDict(populate_by_name=True)
56
+
57
+
58
+ class AllowanceCreateRequest(BaseModel):
59
+ """
60
+ Pydantic schema for posting allowance payloads to Sage Germany.
61
+ """
62
+
63
+ id: Optional[int] = Field(default=None, alias="Id", description="Allowance identifier.", example=1)
64
+ key: AllowanceKey = Field(
65
+ alias="Key",
66
+ description="Key block for the allowance.",
67
+ json_schema_extra={"prefix": "key_"},
68
+ )
69
+ wage_type: WageType = Field(
70
+ alias="Lohnart",
71
+ description="Wage type metadata.",
72
+ json_schema_extra={"prefix": "wage_type_"},
73
+ )
74
+ amount: Optional[float] = Field(default=None, alias="Betrag", description="Allowance amount.", example=500.00)
75
+ quantity: Optional[float] = Field(default=None, alias="Anzahl", description="Allowance quantity.", example=1.0)
76
+ payment_frequency: Optional[PaymentFrequency] = Field(
77
+ default=None,
78
+ alias="Zahlungsrhythmus",
79
+ description="Payment rhythm.",
80
+ json_schema_extra={"prefix": "payment_frequency_"},
81
+ )
82
+ payment_month: Optional[str] = Field(default=None, alias="Zahlungsmonat", description="Payment month.", example="01")
83
+ cost_center: Optional[str] = Field(default=None, alias="Kostenstelle", description="Cost center.", example="CC001")
84
+ cost_unit: Optional[str] = Field(default=None, alias="Kostentraeger", description="Cost unit.", example="CU001")
85
+ valid_from: Optional[datetime] = Field(default=None, alias="GueltigAb", description="Validity start.", example="2024-01-01T00:00:00")
86
+ valid_to: Optional[datetime] = Field(default=None, alias="GueltigBis", description="Validity end.", example="2024-12-31T00:00:00")
87
+ text: Optional[str] = Field(default=None, alias="Text", description="Free text.", example="Monthly allowance")
88
+ dimension_one: Optional[str] = Field(default=None, alias="Dimension1", description="Dimension 1.", example="D1")
89
+ dimension_two: Optional[str] = Field(default=None, alias="Dimension2", description="Dimension 2.", example="D2")
90
+ dimension_three: Optional[str] = Field(default=None, alias="Dimension3", description="Dimension 3.", example="D3")
91
+ read_only: Optional[bool] = Field(default=None, alias="ReadOnly", description="Read-only flag.", example=False)
92
+
93
+ model_config = ConfigDict(populate_by_name=True)
94
+
95
+
96
+ class AllowancesGet(BrynQPanderaDataFrameModel):
97
+ """
98
+ Pandera schema for employee allowances (fixed earnings/deductions).
99
+ """
100
+
101
+ # Base identifiers
102
+ allowance_id: Series[pd.Int64Dtype] = pa.Field(alias="Id", coerce=True, nullable=False, description="Allowance identifier.")
103
+ key_date: Series[pd.StringDtype] = pa.Field(alias="Key__Date", coerce=True, nullable=False, description="Snapshot date.")
104
+ company_id: Series[pd.Int64Dtype] = pa.Field(alias="Key__MdNr", coerce=True, nullable=False, description="Company id.")
105
+ employee_number: Series[pd.Int64Dtype] = pa.Field(alias="Key__AnNr", coerce=True, nullable=False, description="Employee number.")
106
+ combined_key: Series[pd.StringDtype] = pa.Field(alias="Key__CombinedKey", coerce=True, nullable=False, description="Combined key.")
107
+ key_is_empty: Optional[Series[bool]] = pa.Field(alias="Key__IsEmpty", coerce=True, nullable=True, description="Indicates empty key payload.")
108
+
109
+ # Wage type metadata
110
+ wage_type_number: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="Lohnart__LaNr", coerce=True, nullable=True, description="Wage type number.")
111
+ wage_type_display_name: Optional[Series[pd.StringDtype]] = pa.Field(alias="Lohnart__AnzeigeName", coerce=True, nullable=True, description="Display name.")
112
+ wage_type_company_id: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="Lohnart__MdNr", coerce=True, nullable=True, description="Wage type company id.")
113
+ wage_type_description: Optional[Series[pd.StringDtype]] = pa.Field(alias="Lohnart__Bezeichnung", coerce=True, nullable=True, description="Wage type description.")
114
+ wage_type_is_deduction: Optional[Series[bool]] = pa.Field(alias="Lohnart__IstAbzug", coerce=True, nullable=True, description="Deduction flag.")
115
+ wage_type_surcharge: Optional[Series[pd.Float64Dtype]] = pa.Field(alias="Lohnart__Zuschlag", coerce=True, nullable=True, description="Surcharge value.")
116
+ wage_type_surcharge_unit: Optional[Series[pd.StringDtype]] = pa.Field(alias="Lohnart__ZuschlagEinheit", coerce=True, nullable=True, description="Surcharge unit.")
117
+
118
+ # Amounts
119
+ amount: Optional[Series[pd.Float64Dtype]] = pa.Field(alias="Betrag", coerce=True, nullable=True, description="Allowance amount.")
120
+ surcharge_amount: Optional[Series[pd.Float64Dtype]] = pa.Field(alias="Zuschlag", coerce=True, nullable=True, description="Allowance surcharge.")
121
+ quantity: Optional[Series[pd.Float64Dtype]] = pa.Field(alias="Anzahl", coerce=True, nullable=True, description="Allowance quantity.")
122
+
123
+ # Payment rhythm
124
+ payment_frequency_id: Optional[Series[pd.Int64Dtype]] = pa.Field(alias="Zahlungsrhythmus__Id", coerce=True, nullable=True, description="Payment rhythm identifier.")
125
+ payment_frequency_text: Optional[Series[pd.StringDtype]] = pa.Field(alias="Zahlungsrhythmus__Text", coerce=True, nullable=True, description="Payment rhythm text.")
126
+ payment_frequency_id_text: Optional[Series[pd.StringDtype]] = pa.Field(alias="Zahlungsrhythmus__IdMitText", coerce=True, nullable=True, description="Payment rhythm id-text.")
127
+ payment_month: Optional[Series[pd.StringDtype]] = pa.Field(alias="Zahlungsmonat", coerce=True, nullable=True, description="Specific payment month.")
128
+
129
+ # Cost objects
130
+ cost_center: Optional[Series[pd.StringDtype]] = pa.Field(alias="Kostenstelle", coerce=True, nullable=True, description="Cost center.")
131
+ cost_unit: Optional[Series[pd.StringDtype]] = pa.Field(alias="Kostentraeger", coerce=True, nullable=True, description="Cost unit.")
132
+
133
+ # Validity & dimensions
134
+ valid_from: Optional[Series[pd.StringDtype]] = pa.Field(alias="GueltigAb", coerce=True, nullable=True, description="Valid from date.")
135
+ valid_to: Optional[Series[pd.StringDtype]] = pa.Field(alias="GueltigBis", coerce=True, nullable=True, description="Valid to date.")
136
+ wage_type_text: Optional[Series[pd.StringDtype]] = pa.Field(alias="LgaText", coerce=True, nullable=True, description="Additional wage type text.")
137
+ dimension_one: Optional[Series[pd.StringDtype]] = pa.Field(alias="Dimension1", coerce=True, nullable=True, description="Dimension 1.")
138
+ dimension_two: Optional[Series[pd.StringDtype]] = pa.Field(alias="Dimension2", coerce=True, nullable=True, description="Dimension 2.")
139
+ dimension_three: Optional[Series[pd.StringDtype]] = pa.Field(alias="Dimension3", coerce=True, nullable=True, description="Dimension 3.")
140
+ read_only: Optional[Series[bool]] = pa.Field(alias="ReadOnly", coerce=True, nullable=True, description="Read-only flag.")
141
+
142
+ class _Annotation:
143
+ primary_key = "allowance_id"
144
+
145
+ class Config:
146
+ coerce = True
147
+ strict = "filter"
@@ -0,0 +1,46 @@
1
+ """
2
+ Schemas for Sage Germany cost center payloads.
3
+ """
4
+
5
+ from typing import Optional
6
+
7
+ import pandas as pd
8
+ import pandera as pa
9
+ from pandera.typing import Series
10
+ from pydantic import BaseModel, ConfigDict, Field
11
+
12
+ from brynq_sdk_functions import BrynQPanderaDataFrameModel
13
+
14
+ __all__ = ["CostCentersGet", "CostCenterCreate"]
15
+
16
+
17
+ class CostCentersGet(BrynQPanderaDataFrameModel):
18
+ """
19
+ Pandera schema for company cost center records.
20
+ """
21
+
22
+ company_id: Series[pd.Int64Dtype] = pa.Field(alias="MdNr", coerce=True, nullable=False, description="Company id (Mandant).")
23
+ cost_center_number: Series[pd.StringDtype] = pa.Field(alias="Nr", coerce=True, nullable=False, description="Cost center number.")
24
+ cost_center_id: Series[pd.Int64Dtype] = pa.Field(alias="Id", coerce=True, nullable=False, description="Cost center identifier.")
25
+ cost_center_name: Optional[Series[pd.StringDtype]] = pa.Field(alias="Bezeichnung", coerce=True, nullable=True, description="Cost center label.")
26
+ address: Optional[Series[pd.StringDtype]] = pa.Field(alias="Anschrift", coerce=True, nullable=True, description="Cost center address.")
27
+
28
+ class _Annotation:
29
+ primary_key = "cost_center_id"
30
+
31
+ class Config:
32
+ coerce = True
33
+ strict = "filter"
34
+
35
+
36
+ class CostCenterCreate(BaseModel):
37
+ """
38
+ Pydantic schema for creating or updating cost centers.
39
+ """
40
+
41
+ company_id: int = Field(alias="MdNr", description="Company id (Mandant).", example=1)
42
+ cost_center_number: str = Field(alias="Nr", description="Cost center number.", example="CC001")
43
+ cost_center_name: str = Field(alias="Bezeichnung", description="Cost center label.", example="Engineering Department")
44
+ address: Optional[str] = Field(default=None, alias="Anschrift", description="Cost center address.", example="Main Street 123")
45
+
46
+ model_config = ConfigDict(populate_by_name=True)