brynq-sdk-zenegy 1.3.3__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 (33) hide show
  1. brynq_sdk_zenegy/__init__.py +23 -0
  2. brynq_sdk_zenegy/absence.py +100 -0
  3. brynq_sdk_zenegy/companies.py +43 -0
  4. brynq_sdk_zenegy/cost_center.py +80 -0
  5. brynq_sdk_zenegy/departments.py +77 -0
  6. brynq_sdk_zenegy/employee_documents.py +40 -0
  7. brynq_sdk_zenegy/employees.py +301 -0
  8. brynq_sdk_zenegy/global_value_sets.py +260 -0
  9. brynq_sdk_zenegy/global_values.py +265 -0
  10. brynq_sdk_zenegy/paychecks.py +119 -0
  11. brynq_sdk_zenegy/payroll.py +117 -0
  12. brynq_sdk_zenegy/payslips.py +43 -0
  13. brynq_sdk_zenegy/pensions.py +118 -0
  14. brynq_sdk_zenegy/schemas/__init__.py +30 -0
  15. brynq_sdk_zenegy/schemas/absences.py +393 -0
  16. brynq_sdk_zenegy/schemas/companies.py +42 -0
  17. brynq_sdk_zenegy/schemas/company_cost_centers.py +48 -0
  18. brynq_sdk_zenegy/schemas/company_departments.py +147 -0
  19. brynq_sdk_zenegy/schemas/employee_documents.py +30 -0
  20. brynq_sdk_zenegy/schemas/employee_pay_checks.py +169 -0
  21. brynq_sdk_zenegy/schemas/employee_pensions.py +140 -0
  22. brynq_sdk_zenegy/schemas/employees.py +2372 -0
  23. brynq_sdk_zenegy/schemas/global_value_sets.py +185 -0
  24. brynq_sdk_zenegy/schemas/global_values.py +433 -0
  25. brynq_sdk_zenegy/schemas/payrolls.py +134 -0
  26. brynq_sdk_zenegy/schemas/payslips.py +32 -0
  27. brynq_sdk_zenegy/schemas/supplements_and_deductions_rates.py +189 -0
  28. brynq_sdk_zenegy/supplements_and_deductions_rates.py +71 -0
  29. brynq_sdk_zenegy/zenegy.py +221 -0
  30. brynq_sdk_zenegy-1.3.3.dist-info/METADATA +16 -0
  31. brynq_sdk_zenegy-1.3.3.dist-info/RECORD +33 -0
  32. brynq_sdk_zenegy-1.3.3.dist-info/WHEEL +5 -0
  33. brynq_sdk_zenegy-1.3.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,185 @@
1
+ # Generated schemas for tag: GlobalValueSets
2
+
3
+ from pydantic import BaseModel, Field
4
+ from typing import Dict, List, Optional, Any
5
+ from uuid import UUID
6
+ from datetime import datetime
7
+
8
+ # Import EffectiveDate from global_values schema
9
+ from .global_values import EffectiveDate
10
+
11
+ # BrynQ Pandera DataFrame Model for Global Value Sets
12
+ from pandera.typing import Series
13
+ import pandera as pa
14
+ import pandas as pd
15
+ from brynq_sdk_functions import BrynQPanderaDataFrameModel
16
+
17
+ class GlobalValueSetCreate(BaseModel):
18
+ """Schema for creating global value sets - Based on Zalary.Models.GlobalValueSets.GlobalValueSetBaseDto."""
19
+ name: str = Field(description="Global value set name", example="Overtime Set")
20
+ number: str = Field(description="Global value set number/code", example="GVS-001")
21
+
22
+ class Config:
23
+ allow_population_by_field_name = True
24
+
25
+
26
+ class GlobalValueSetUpdate(BaseModel):
27
+ """Schema for updating global value sets - Based on Zalary.Models.GlobalValueSets.GlobalValueSetUpdateRequest."""
28
+ uid: Optional[str] = Field(default=None, description="Global value set UID", example="00000000-0000-0000-0000-000000000000")
29
+ name: str = Field(description="Global value set name", example="Updated Overtime Set")
30
+ number: str = Field(description="Global value set number/code", example="GVS-001-UPD")
31
+
32
+ class Config:
33
+ allow_population_by_field_name = True
34
+
35
+
36
+ class GlobalValueSetEmployeeAssignment(BaseModel):
37
+ """Schema for managing employee assignments to global value sets."""
38
+ add_employees: Optional[List[str]] = Field(alias="addEmployees", default=None, description="Array of employee UIDs to add", example=["00000000-0000-0000-0000-000000000000"])
39
+ remove_employees: Optional[List[str]] = Field(alias="removeEmployees", default=None, description="Array of employee UIDs to remove", example=["00000000-0000-0000-0000-000000000000"])
40
+
41
+ class Config:
42
+ allow_population_by_field_name = True
43
+
44
+
45
+ class GlobalValueSetEmployeeAssignmentResponse(BaseModel):
46
+ """Schema for employee assignment response."""
47
+ is_assignment_success: Optional[bool] = Field(alias="isAssignmentSuccess", default=None, description="Whether assignment was successful", example=True)
48
+ is_assignment_partial_success: Optional[bool] = Field(alias="isAssignmentPartialSuccess", default=None, description="Whether assignment was partially successful", example=True)
49
+ is_removal_success: Optional[bool] = Field(alias="isRemovalSuccess", default=None, description="Whether removal was successful", example=True)
50
+ assignment_operation_message: Optional[str] = Field(alias="assignmentOperationMessage", default=None, description="Assignment operation message", example="string")
51
+ removal_operation_message: Optional[str] = Field(alias="removalOperationMessage", default=None, description="Removal operation message", example="string")
52
+ has_employees_with_overlapping_values: Optional[bool] = Field(alias="hasEmployeesWithOverlappingValues", default=None, description="Whether there are employees with overlapping values", example=True)
53
+
54
+ class Config:
55
+ allow_population_by_field_name = True
56
+
57
+
58
+ class RemoveGlobalValuesFromSetRequest(BaseModel):
59
+ """Schema for removing global values from global value set."""
60
+ global_value_uids: List[UUID] = Field(description="Array of global value UIDs to remove from the set", example=["00000000-0000-0000-0000-000000000000"])
61
+
62
+ class Config:
63
+ allow_population_by_field_name = True
64
+
65
+
66
+ class GetAssignedEmployeesRequest(BaseModel):
67
+ """Schema for getting assigned employees with filters."""
68
+ skip: Optional[int] = Field(default=0, description="Pagination offset", example=0)
69
+ take: Optional[int] = Field(default=50, description="Pagination limit", example=50)
70
+ search: Optional[str] = Field(default=None, description="Search term for employee name/number", example="John")
71
+ department_uids: Optional[List[str]] = Field(alias="departmentUids", default=None, description="Filter by department UIDs", example=["00000000-0000-0000-0000-000000000000"])
72
+ salary_payout_periods: Optional[List[int]] = Field(alias="salaryPayoutPeriods", default=None, description="Filter by salary payout periods", example=[0, 1, 2])
73
+ salary_types: Optional[List[int]] = Field(alias="salaryTypes", default=None, description="Filter by salary types", example=[0, 1, 2])
74
+ assignment_status: Optional[List[int]] = Field(alias="assignmentStatus", default=None, description="Filter by assignment status", example=[0, 1])
75
+ employee_sort_by: Optional[int] = Field(alias="employeeSortBy", default=1, description="Sort employees by field", example=1)
76
+
77
+ class Config:
78
+ allow_population_by_field_name = True
79
+
80
+
81
+ class CompanyDepartmentBaseDto(BaseModel):
82
+ """Schema for company department base information."""
83
+ name: Optional[str] = Field(default=None, description="Department name", example="Sales")
84
+ number: Optional[str] = Field(default=None, description="Department number/code", example="DEPT-001")
85
+ has_work_schema: Optional[bool] = Field(alias="hasWorkSchema", default=None, description="Whether department has work schema", example=True)
86
+ id: Optional[int] = Field(default=None, description="Department ID", example=1)
87
+ uid: Optional[str] = Field(default=None, description="Department UID", example="00000000-0000-0000-0000-000000000000")
88
+
89
+ class Config:
90
+ allow_population_by_field_name = True
91
+
92
+
93
+ class EmployeesGlobalValueSetDto(BaseModel):
94
+ """Schema for employee information in global value set context."""
95
+ department: Optional[CompanyDepartmentBaseDto] = Field(default=None, description="Employee department information")
96
+ salary_type: Optional[int] = Field(alias="salaryType", default=None, description="Employee salary type", example=1)
97
+ salary_payout_period: Optional[int] = Field(alias="salaryPayoutPeriod", default=None, description="Employee salary payout period", example=1)
98
+ photo_url: Optional[str] = Field(alias="photoUrl", default=None, description="Employee photo URL", example="https://example.com/photo.jpg")
99
+ status_in_set: Optional[str] = Field(alias="statusInSet", default=None, description="Employee status in the set", example="Assigned")
100
+ name: Optional[str] = Field(default=None, description="Employee name", example="John Doe")
101
+ employee_number: Optional[str] = Field(alias="employeeNumber", default=None, description="Employee number", example="EMP-001")
102
+ id: Optional[int] = Field(default=None, description="Employee ID", example=1)
103
+ uid: Optional[str] = Field(default=None, description="Employee UID", example="00000000-0000-0000-0000-000000000000")
104
+
105
+ class Config:
106
+ allow_population_by_field_name = True
107
+
108
+
109
+ class GetAssignedEmployeesResponse(BaseModel):
110
+ """Schema for get assigned employees response."""
111
+ total_records: Optional[int] = Field(alias="totalRecords", default=None, description="Total number of records", example=100)
112
+ total_display_records: Optional[int] = Field(alias="totalDisplayRecords", default=None, description="Total display records", example=50)
113
+ data: Optional[List[EmployeesGlobalValueSetDto]] = Field(default=None, description="Array of employee data")
114
+
115
+ class Config:
116
+ allow_population_by_field_name = True
117
+
118
+
119
+ class AddCompanyGlobalValueRequest(BaseModel):
120
+ """Schema for adding a company global value to a global value set."""
121
+ is_date_managed: Optional[bool] = Field(alias="isDateManaged", default=None, description="Whether the value is date managed", example=True)
122
+
123
+ class Config:
124
+ allow_population_by_field_name = True
125
+
126
+
127
+ class GlobalValueSetsGet(BrynQPanderaDataFrameModel):
128
+ """Flattened schema for Zenegy Global Value Sets Output data"""
129
+ id: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Global value set ID", alias="id")
130
+ uid: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Global value set UID", alias="uid")
131
+ name: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Global value set name", alias="name")
132
+ number: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Global value set number", alias="number")
133
+ number_of_employees: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Number of employees", alias="numberOfEmployees")
134
+ number_of_global_values: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Number of global values", alias="numberOfGlobalValues")
135
+
136
+ class _Annotation:
137
+ primary_key = "uid"
138
+ foreign_keys = {}
139
+
140
+
141
+ class AssignedEmployeesGet(BrynQPanderaDataFrameModel):
142
+ """Flattened schema for assigned employees in global value set context"""
143
+ # Employee fields
144
+ id: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Employee ID", alias="id")
145
+ uid: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Employee UID", alias="uid")
146
+ name: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Employee name", alias="name")
147
+ employee_number: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Employee number", alias="employeeNumber")
148
+ salary_type: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Employee salary type", alias="salaryType")
149
+ salary_payout_period: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Employee salary payout period", alias="salaryPayoutPeriod")
150
+ photo_url: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Employee photo URL", alias="photoUrl")
151
+ status_in_set: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Employee status in the set", alias="statusInSet")
152
+
153
+ # Department fields (normalized)
154
+ department_name: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Department name", alias="department__name")
155
+ department_number: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Department number", alias="department__number")
156
+ department_has_work_schema: Optional[Series[pd.BooleanDtype]] = pa.Field(coerce=True, nullable=True, description="Department has work schema", alias="department__hasWorkSchema")
157
+ department_id: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Department ID", alias="department__id")
158
+ department_uid: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Department UID", alias="department__uid")
159
+
160
+ class _Annotation:
161
+ primary_key = "uid"
162
+ foreign_keys = {}
163
+
164
+
165
+ class CompanyGlobalValuesGet(BrynQPanderaDataFrameModel):
166
+ """Flattened schema for company global values in global value set context"""
167
+ # Basic global value fields
168
+ id: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Global value ID", alias="id")
169
+ uid: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Global value UID", alias="uid")
170
+ name: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Global value name", alias="name")
171
+ number: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Global value number", alias="number")
172
+ type: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Global value type", alias="type")
173
+ value: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Global value", alias="value")
174
+ is_used_in_set: Optional[Series[pd.BooleanDtype]] = pa.Field(coerce=True, nullable=True, description="Is used in set", alias="isUsedInSet")
175
+ has_employees: Optional[Series[pd.BooleanDtype]] = pa.Field(coerce=True, nullable=True, description="Has employees", alias="hasEmployees")
176
+ number_of_employees: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Number of employees", alias="numberOfEmployees")
177
+ is_date_managed: Optional[Series[pd.BooleanDtype]] = pa.Field(coerce=True, nullable=True, description="Is date managed", alias="isDateManaged")
178
+
179
+ # EffectiveFrom and EffectiveTo fields - handle as direct fields since they can be None
180
+ effective_from: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective from", alias="effectiveFrom")
181
+ effective_to: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective to", alias="effectiveTo")
182
+
183
+ class _Annotation:
184
+ primary_key = "uid"
185
+ foreign_keys = {}
@@ -0,0 +1,433 @@
1
+ # Generated schemas for tag: GlobalValues
2
+
3
+ from pydantic import BaseModel, Field
4
+ from typing import Dict, List, Optional, Any
5
+ from uuid import UUID
6
+ from datetime import datetime
7
+
8
+ class EffectiveDate(BaseModel):
9
+ effective_date: Optional[str] = Field(alias="effectiveDate", default=None, description="Effective date in ISO format", example="2025-08-26T10:37:46.223Z")
10
+ type: Optional[str] = Field(alias="type", default=None, description="Type", example="string")
11
+ point: Optional[str] = Field(alias="point", default=None, description="Point", example="string")
12
+ unit: Optional[str] = Field(alias="unit", default=None, description="Unit", example="string")
13
+ amount: Optional[int] = Field(alias="amount", default=None, description="Amount", example=0)
14
+ condition_point: Optional[str] = Field(alias="conditionPoint", default=None, description="Condition point", example="string")
15
+ condition_amount: Optional[int] = Field(alias="conditionAmount", default=None, description="Condition amount", example=0)
16
+
17
+ class Config:
18
+ allow_population_by_field_name = True
19
+
20
+
21
+ class CompanyGlobalValueCreate(BaseModel):
22
+ """Schema for creating global values."""
23
+ name: str = Field(description="Global value name", example="Overtime Rate")
24
+ number: str = Field(description="Global value number/code", example="GV-001")
25
+ global_value_type: int = Field(alias="type", description="Global value type", example=1)
26
+ value: str = Field(description="Global value value", example="1.5")
27
+ is_used_in_set: Optional[bool] = Field(alias="isUsedInSet", default=None, description="Is used in set", example=True)
28
+ has_employees: Optional[bool] = Field(alias="hasEmployees", default=None, description="Has employees", example=True)
29
+ number_of_employees: Optional[int] = Field(alias="numberOfEmployees", default=None, description="Number of employees", example=0)
30
+ is_date_managed: Optional[bool] = Field(alias="isDateManaged", default=None, description="Is date managed", example=True)
31
+ effective_from: Optional[EffectiveDate] = Field(alias="effectiveFrom", default=None, description="Effective from date")
32
+ effective_to: Optional[EffectiveDate] = Field(alias="effectiveTo", default=None, description="Effective to date")
33
+
34
+ # Flat field alternatives for effective_from
35
+ effective_from_effective_date: Optional[str] = Field(default=None, description="Effective from date in ISO format", example="2025-08-26T10:37:46.223Z")
36
+ effective_from_type: Optional[str] = Field(default=None, description="Effective from type", example="string")
37
+ effective_from_point: Optional[str] = Field(default=None, description="Effective from point", example="string")
38
+ effective_from_unit: Optional[str] = Field(default=None, description="Effective from unit", example="string")
39
+ effective_from_amount: Optional[int] = Field(default=None, description="Effective from amount", example=0)
40
+ effective_from_condition_point: Optional[str] = Field(default=None, description="Effective from condition point", example="string")
41
+ effective_from_condition_amount: Optional[int] = Field(default=None, description="Effective from condition amount", example=0)
42
+
43
+ # Flat field alternatives for effective_to
44
+ effective_to_effective_date: Optional[str] = Field(default=None, description="Effective to date in ISO format", example="2025-08-26T10:37:46.223Z")
45
+ effective_to_type: Optional[str] = Field(default=None, description="Effective to type", example="string")
46
+ effective_to_point: Optional[str] = Field(default=None, description="Effective to point", example="string")
47
+ effective_to_unit: Optional[str] = Field(default=None, description="Effective to unit", example="string")
48
+ effective_to_amount: Optional[int] = Field(default=None, description="Effective to amount", example=0)
49
+ effective_to_condition_point: Optional[str] = Field(default=None, description="Effective to condition point", example="string")
50
+ effective_to_condition_amount: Optional[int] = Field(default=None, description="Effective to condition amount", example=0)
51
+
52
+ def model_dump(self, **kwargs):
53
+ """Override model_dump to build nested structure from flat fields"""
54
+ data = super().model_dump(**kwargs)
55
+
56
+ # Build effectiveFrom if any flat fields are present
57
+ effective_from_fields = {
58
+ 'effectiveDate': data.pop('effective_from_effective_date', None),
59
+ 'type': data.pop('effective_from_type', None),
60
+ 'point': data.pop('effective_from_point', None),
61
+ 'unit': data.pop('effective_from_unit', None),
62
+ 'amount': data.pop('effective_from_amount', None),
63
+ 'conditionPoint': data.pop('effective_from_condition_point', None),
64
+ 'conditionAmount': data.pop('effective_from_condition_amount', None)
65
+ }
66
+
67
+ # Only add effectiveFrom if at least one field has a value
68
+ if any(v is not None for v in effective_from_fields.values()):
69
+ # Remove None values
70
+ effective_from_fields = {k: v for k, v in effective_from_fields.items() if v is not None}
71
+ if effective_from_fields:
72
+ data['effectiveFrom'] = effective_from_fields
73
+
74
+ # Build effectiveTo if any flat fields are present
75
+ effective_to_fields = {
76
+ 'effectiveDate': data.pop('effective_to_effective_date', None),
77
+ 'type': data.pop('effective_to_type', None),
78
+ 'point': data.pop('effective_to_point', None),
79
+ 'unit': data.pop('effective_to_unit', None),
80
+ 'amount': data.pop('effective_to_amount', None),
81
+ 'conditionPoint': data.pop('effective_to_condition_point', None),
82
+ 'conditionAmount': data.pop('effective_to_condition_amount', None)
83
+ }
84
+
85
+ # Only add effectiveTo if at least one field has a value
86
+ if any(v is not None for v in effective_to_fields.values()):
87
+ # Remove None values
88
+ effective_to_fields = {k: v for k, v in effective_to_fields.items() if v is not None}
89
+ if effective_to_fields:
90
+ data['effectiveTo'] = effective_to_fields
91
+
92
+ return data
93
+
94
+ class Config:
95
+ allow_population_by_field_name = True
96
+
97
+
98
+ class CompanyGlobalValueResponse(BaseModel):
99
+ """Schema for global values response with all fields."""
100
+ id: Optional[int] = Field(default=None, description="Global value ID", example=0)
101
+ uid: Optional[UUID] = Field(default=None, description="Global value UID", example="00000000-0000-0000-0000-000000000000")
102
+ name: Optional[str] = Field(default=None, description="Global value name", example="Overtime Rate")
103
+ number: Optional[str] = Field(default=None, description="Global value number/code", example="GV-001")
104
+ type: Optional[int] = Field(default=None, description="Global value type", example=1)
105
+ value: Optional[str] = Field(default=None, description="Global value value", example="1.5")
106
+ is_used_in_set: Optional[bool] = Field(alias="isUsedInSet", default=None, description="Is used in set", example=True)
107
+ has_employees: Optional[bool] = Field(alias="hasEmployees", default=None, description="Has employees", example=True)
108
+ number_of_employees: Optional[int] = Field(alias="numberOfEmployees", default=None, description="Number of employees", example=0)
109
+ is_date_managed: Optional[bool] = Field(alias="isDateManaged", default=None, description="Is date managed", example=True)
110
+ effective_from: Optional[EffectiveDate] = Field(alias="effectiveFrom", default=None, description="Effective from date")
111
+ effective_to: Optional[EffectiveDate] = Field(alias="effectiveTo", default=None, description="Effective to date")
112
+
113
+ class Config:
114
+ allow_population_by_field_name = True
115
+
116
+
117
+ class CompanyGlobalValueUpdate(BaseModel):
118
+ """Schema for updating global values - Based on Zalary.Models.GlobalValues.CompanyGlobalValueUpdateRequest."""
119
+ uid: Optional[str] = Field(default=None, description="Global value UID", example="00000000-0000-0000-0000-000000000000")
120
+ name: str = Field(description="Global value name", example="Overtime Rate")
121
+ number: str = Field(description="Global value number/code", example="GV-001")
122
+ global_value_type: int = Field(alias="type", description="Global value type", example=1)
123
+ value: str = Field(description="Global value value", example="1.5")
124
+ is_used_in_set: Optional[bool] = Field(alias="isUsedInSet", default=None, description="Is used in set", example=True)
125
+ has_employees: Optional[bool] = Field(alias="hasEmployees", default=None, description="Has employees", example=True)
126
+ number_of_employees: Optional[int] = Field(alias="numberOfEmployees", default=None, description="Number of employees", example=0)
127
+ is_date_managed: Optional[bool] = Field(alias="isDateManaged", default=None, description="Is date managed", example=True)
128
+ effective_from: Optional[EffectiveDate] = Field(alias="effectiveFrom", default=None, description="Effective from date")
129
+ effective_to: Optional[EffectiveDate] = Field(alias="effectiveTo", default=None, description="Effective to date")
130
+
131
+ # Flat field alternatives for effective_from
132
+ effective_from_effective_date: Optional[str] = Field(default=None, description="Effective from date in ISO format", example="2025-08-26T10:37:46.223Z")
133
+ effective_from_type: Optional[str] = Field(default=None, description="Effective from type", example="string")
134
+ effective_from_point: Optional[str] = Field(default=None, description="Effective from point", example="string")
135
+ effective_from_unit: Optional[str] = Field(default=None, description="Effective from unit", example="string")
136
+ effective_from_amount: Optional[int] = Field(default=None, description="Effective from amount", example=0)
137
+ effective_from_condition_point: Optional[str] = Field(default=None, description="Effective from condition point", example="string")
138
+ effective_from_condition_amount: Optional[int] = Field(default=None, description="Effective from condition amount", example=0)
139
+
140
+ # Flat field alternatives for effective_to
141
+ effective_to_effective_date: Optional[str] = Field(default=None, description="Effective to date in ISO format", example="2025-08-26T10:37:46.223Z")
142
+ effective_to_type: Optional[str] = Field(default=None, description="Effective to type", example="string")
143
+ effective_to_point: Optional[str] = Field(default=None, description="Effective to point", example="string")
144
+ effective_to_unit: Optional[str] = Field(default=None, description="Effective to unit", example="string")
145
+ effective_to_amount: Optional[int] = Field(default=None, description="Effective to amount", example=0)
146
+ effective_to_condition_point: Optional[str] = Field(default=None, description="Effective to condition point", example="string")
147
+ effective_to_condition_amount: Optional[int] = Field(default=None, description="Effective to condition amount", example=0)
148
+
149
+ def model_dump(self, **kwargs):
150
+ """Override model_dump to build nested structure from flat fields"""
151
+ data = super().model_dump(**kwargs)
152
+
153
+ # Build effectiveFrom if any flat fields are present
154
+ effective_from_fields = {
155
+ 'effectiveDate': data.pop('effective_from_effective_date', None),
156
+ 'type': data.pop('effective_from_type', None),
157
+ 'point': data.pop('effective_from_point', None),
158
+ 'unit': data.pop('effective_from_unit', None),
159
+ 'amount': data.pop('effective_from_amount', None),
160
+ 'conditionPoint': data.pop('effective_from_condition_point', None),
161
+ 'conditionAmount': data.pop('effective_from_condition_amount', None)
162
+ }
163
+
164
+ # Only add effectiveFrom if at least one field has a value
165
+ if any(v is not None for v in effective_from_fields.values()):
166
+ # Remove None values
167
+ effective_from_fields = {k: v for k, v in effective_from_fields.items() if v is not None}
168
+ if effective_from_fields:
169
+ data['effectiveFrom'] = effective_from_fields
170
+
171
+ # Build effectiveTo if any flat fields are present
172
+ effective_to_fields = {
173
+ 'effectiveDate': data.pop('effective_to_effective_date', None),
174
+ 'type': data.pop('effective_to_type', None),
175
+ 'point': data.pop('effective_to_point', None),
176
+ 'unit': data.pop('effective_to_unit', None),
177
+ 'amount': data.pop('effective_to_amount', None),
178
+ 'conditionPoint': data.pop('effective_to_condition_point', None),
179
+ 'conditionAmount': data.pop('effective_to_condition_amount', None)
180
+ }
181
+
182
+ # Only add effectiveTo if at least one field has a value
183
+ if any(v is not None for v in effective_to_fields.values()):
184
+ # Remove None values
185
+ effective_to_fields = {k: v for k, v in effective_to_fields.items() if v is not None}
186
+ if effective_to_fields:
187
+ data['effectiveTo'] = effective_to_fields
188
+
189
+ return data
190
+
191
+ class Config:
192
+ allow_population_by_field_name = True
193
+
194
+
195
+ class GlobalValueAssign(BaseModel):
196
+ """Schema for assigning global values to employees - Based on Zalary.Models.GlobalValues.AddEmployeesGlobalValueRequest."""
197
+ is_date_managed: Optional[bool] = Field(alias="isDateManaged", default=None, description="Is date managed", example=True)
198
+ effective_from: Optional[EffectiveDate] = Field(alias="effectiveFrom", default=None, description="Effective from date")
199
+ effective_to: Optional[EffectiveDate] = Field(alias="effectiveTo", default=None, description="Effective to date")
200
+ employee_uids: Optional[List[str]] = Field(alias="employeeUids", default=None, description="Array of employee UIDs to assign", example=["00000000-0000-0000-0000-000000000000"])
201
+
202
+ # Flat field alternatives for effective_from
203
+ effective_from_effective_date: Optional[str] = Field(default=None, description="Effective from date in ISO format", example="2025-08-26T10:37:46.223Z")
204
+ effective_from_type: Optional[str] = Field(default=None, description="Effective from type", example="string")
205
+ effective_from_point: Optional[str] = Field(default=None, description="Effective from point", example="string")
206
+ effective_from_unit: Optional[str] = Field(default=None, description="Effective from unit", example="string")
207
+ effective_from_amount: Optional[int] = Field(default=None, description="Effective from amount", example=0)
208
+ effective_from_condition_point: Optional[str] = Field(default=None, description="Effective from condition point", example="string")
209
+ effective_from_condition_amount: Optional[int] = Field(default=None, description="Effective from condition amount", example=0)
210
+
211
+ # Flat field alternatives for effective_to
212
+ effective_to_effective_date: Optional[str] = Field(default=None, description="Effective to date in ISO format", example="2025-08-26T10:37:46.223Z")
213
+ effective_to_type: Optional[str] = Field(default=None, description="Effective to type", example="string")
214
+ effective_to_point: Optional[str] = Field(default=None, description="Effective to point", example="string")
215
+ effective_to_unit: Optional[str] = Field(default=None, description="Effective to unit", example="string")
216
+ effective_to_amount: Optional[int] = Field(default=None, description="Effective to amount", example=0)
217
+ effective_to_condition_point: Optional[str] = Field(default=None, description="Effective to condition point", example="string")
218
+ effective_to_condition_amount: Optional[int] = Field(default=None, description="Effective to condition amount", example=0)
219
+
220
+ def model_dump(self, **kwargs):
221
+ """Override model_dump to build nested structure from flat fields"""
222
+ data = super().model_dump(**kwargs)
223
+
224
+ # Build effectiveFrom if any flat fields are present
225
+ effective_from_fields = {
226
+ 'effectiveDate': data.pop('effective_from_effective_date', None),
227
+ 'type': data.pop('effective_from_type', None),
228
+ 'point': data.pop('effective_from_point', None),
229
+ 'unit': data.pop('effective_from_unit', None),
230
+ 'amount': data.pop('effective_from_amount', None),
231
+ 'conditionPoint': data.pop('effective_from_condition_point', None),
232
+ 'conditionAmount': data.pop('effective_from_condition_amount', None)
233
+ }
234
+
235
+ # Only add effectiveFrom if at least one field has a value
236
+ if any(v is not None for v in effective_from_fields.values()):
237
+ # Remove None values
238
+ effective_from_fields = {k: v for k, v in effective_from_fields.items() if v is not None}
239
+ if effective_from_fields:
240
+ data['effectiveFrom'] = effective_from_fields
241
+
242
+ # Build effectiveTo if any flat fields are present
243
+ effective_to_fields = {
244
+ 'effectiveDate': data.pop('effective_to_effective_date', None),
245
+ 'type': data.pop('effective_to_type', None),
246
+ 'point': data.pop('effective_to_point', None),
247
+ 'unit': data.pop('effective_to_unit', None),
248
+ 'amount': data.pop('effective_to_amount', None),
249
+ 'conditionPoint': data.pop('effective_to_condition_point', None),
250
+ 'conditionAmount': data.pop('effective_to_condition_amount', None)
251
+ }
252
+
253
+ # Only add effectiveTo if at least one field has a value
254
+ if any(v is not None for v in effective_to_fields.values()):
255
+ # Remove None values
256
+ effective_to_fields = {k: v for k, v in effective_to_fields.items() if v is not None}
257
+ if effective_to_fields:
258
+ data['effectiveTo'] = effective_to_fields
259
+
260
+ return data
261
+
262
+ class Config:
263
+ allow_population_by_field_name = True
264
+
265
+
266
+
267
+ class GetGlobalValuesListPerCompanyAsyncRequest(BaseModel):
268
+ skip: Optional[int] = Field(default=None, description="Pagination offset", example=0)
269
+ take: Optional[int] = Field(default=None, description="Pagination limit", example=50)
270
+ search: Optional[str] = Field(default=None, description="Search term (name/number)", example="Overtime")
271
+ types: Optional[List[int]] = Field(default=None, description="Filter by types", example=[1,2])
272
+ override: Optional[int] = Field(default=None, description="Override filter flag", example=0)
273
+ sortby: Optional[int] = Field(alias="sortBy", default=None, description="Sort by field code", example=1)
274
+ employeeuids: Optional[List[UUID]] = Field(alias="employeeUids", default=None, description="Filter by employee UIDs", example=["00000000-0000-0000-0000-000000000000"])
275
+ class Config:
276
+ allow_population_by_field_name = True
277
+
278
+ class AssignEmployeesToGlobalValueAsyncRequest(BaseModel):
279
+ isdatemanaged: Optional[bool] = Field(alias="isDateManaged", default=None, description="Whether value is date managed", example=False)
280
+ effectivefrom: Optional[Dict[str, Any]] = Field(alias="effectiveFrom", default=None, description="Effective from date descriptor", example={"effectiveDate": "2024-01-01T00:00:00Z"})
281
+ effectiveto: Optional[Dict[str, Any]] = Field(alias="effectiveTo", default=None, description="Effective to date descriptor", example={"effectiveDate": "2024-12-31T23:59:59Z"})
282
+ employeeuids: Optional[List[UUID]] = Field(alias="employeeUids", default=None, description="Employee UIDs to assign", example=["00000000-0000-0000-0000-000000000000"])
283
+ class Config:
284
+ allow_population_by_field_name = True
285
+
286
+ class GetAssignedEmployeesToGlobalValueAsyncRequest(BaseModel):
287
+ skip: Optional[int] = Field(default=None, description="Pagination offset", example=0)
288
+ take: Optional[int] = Field(default=None, description="Pagination limit", example=50)
289
+ search: Optional[str] = Field(default=None, description="Search term", example="John")
290
+ departmentuids: Optional[List[str]] = Field(alias="departmentUids", default=None, description="Filter by department UIDs", example=["00000000-0000-0000-0000-000000000000"])
291
+ salarypayoutperiods: Optional[List[int]] = Field(alias="salaryPayoutPeriods", default=None, description="Filter by salary payout periods", example=[1,2])
292
+ salarytypes: Optional[List[int]] = Field(alias="salaryTypes", default=None, description="Filter by salary types", example=[1,2])
293
+ filterby: Optional[int] = Field(alias="filterBy", default=None, description="Filter by code", example=0)
294
+ employeesortby: Optional[int] = Field(alias="employeeSortBy", default=None, description="Sort by code", example=1)
295
+ class Config:
296
+ allow_population_by_field_name = True
297
+
298
+
299
+ # BrynQ Pandera DataFrame Model for Global Values
300
+ from pandera.typing import Series
301
+ import pandera as pa
302
+ import pandas as pd
303
+ from brynq_sdk_functions import BrynQPanderaDataFrameModel
304
+
305
+ class GlobalValuesGet(BrynQPanderaDataFrameModel):
306
+ """Flattened schema for Zenegy Global Values Output data"""
307
+ # Basic global value fields
308
+ id: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Global value ID", alias="id")
309
+ uid: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Global value UID", alias="uid")
310
+ name: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Global value name", alias="name")
311
+ number: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Global value number", alias="number")
312
+ type: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Global value type", alias="type")
313
+ value: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Global value", alias="value")
314
+ is_used_in_set: Optional[Series[pd.BooleanDtype]] = pa.Field(coerce=True, nullable=True, description="Is used in set", alias="isUsedInSet")
315
+ is_date_managed: Optional[Series[pd.BooleanDtype]] = pa.Field(coerce=True, nullable=True, description="Is date managed", alias="isDateManaged")
316
+ has_employees: Optional[Series[pd.BooleanDtype]] = pa.Field(coerce=True, nullable=True, description="Has employees", alias="hasEmployees")
317
+ number_of_employees: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Number of employees", alias="numberOfEmployees")
318
+
319
+ # EffectiveFrom fields (normalized)
320
+ effective_from_date: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective from date", alias="effectiveFrom__effectiveDate")
321
+ effective_from_type: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective from type", alias="effectiveFrom__type")
322
+ effective_from_point: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective from point", alias="effectiveFrom__point")
323
+ effective_from_unit: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective from unit", alias="effectiveFrom__unit")
324
+ effective_from_amount: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Effective from amount", alias="effectiveFrom__amount")
325
+ effective_from_condition_point: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective from condition point", alias="effectiveFrom__conditionPoint")
326
+ effective_from_condition_amount: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Effective from condition amount", alias="effectiveFrom__conditionAmount")
327
+
328
+ # EffectiveTo fields (normalized)
329
+ effective_to_date: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective to date", alias="effectiveTo__effectiveDate")
330
+ effective_to_type: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective to type", alias="effectiveTo__type")
331
+ effective_to_point: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective to point", alias="effectiveTo__point")
332
+ effective_to_unit: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective to unit", alias="effectiveTo__unit")
333
+ effective_to_amount: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Effective to amount", alias="effectiveTo__amount")
334
+ effective_to_condition_point: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective to condition point", alias="effectiveTo__conditionPoint")
335
+ effective_to_condition_amount: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Effective to condition amount", alias="effectiveTo__conditionAmount")
336
+
337
+ class _Annotation:
338
+ primary_key = "uid"
339
+ foreign_keys = {}
340
+
341
+ class GlobalValueSetsGet(BrynQPanderaDataFrameModel):
342
+ """Flattened schema for Zenegy Global Value Sets Output data"""
343
+ # Global value set fields
344
+ number_of_employees: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Number of employees", alias="numberOfEmployees")
345
+ number_of_global_values: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Number of global values", alias="numberOfGlobalValues")
346
+ uid: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Global value set UID", alias="uid")
347
+ name: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Global value set name", alias="name")
348
+ number: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Global value set number", alias="number")
349
+
350
+ # When API returns value-level details in sets payload
351
+ is_used_in_set: Optional[Series[pd.BooleanDtype]] = pa.Field(coerce=True, nullable=True, description="Is used in set", alias="isUsedInSet")
352
+ is_date_managed: Optional[Series[pd.BooleanDtype]] = pa.Field(coerce=True, nullable=True, description="Is date managed", alias="isDateManaged")
353
+ has_employees: Optional[Series[pd.BooleanDtype]] = pa.Field(coerce=True, nullable=True, description="Has employees", alias="hasEmployees")
354
+
355
+ # EffectiveFrom fields (normalized like GlobalValuesGet)
356
+ effective_from_date: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective from date", alias="effectiveFrom__effectiveDate")
357
+ effective_from_type: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective from type", alias="effectiveFrom__type")
358
+ effective_from_point: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective from point", alias="effectiveFrom__point")
359
+ effective_from_unit: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective from unit", alias="effectiveFrom__unit")
360
+ effective_from_amount: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Effective from amount", alias="effectiveFrom__amount")
361
+ effective_from_condition_point: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective from condition point", alias="effectiveFrom__conditionPoint")
362
+ effective_from_condition_amount: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Effective from condition amount", alias="effectiveFrom__conditionAmount")
363
+
364
+ # EffectiveTo fields (normalized like GlobalValuesGet)
365
+ effective_to_date: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective to date", alias="effectiveTo__effectiveDate")
366
+ effective_to_type: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective to type", alias="effectiveTo__type")
367
+ effective_to_point: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective to point", alias="effectiveTo__point")
368
+ effective_to_unit: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective to unit", alias="effectiveTo__unit")
369
+ effective_to_amount: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Effective to amount", alias="effectiveTo__amount")
370
+ effective_to_condition_point: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective to condition point", alias="effectiveTo__conditionPoint")
371
+ effective_to_condition_amount: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Effective to condition amount", alias="effectiveTo__conditionAmount")
372
+
373
+ class _Annotation:
374
+ primary_key = "uid"
375
+ foreign_keys = {}
376
+
377
+ class AssignedGlobalValuesGet(BrynQPanderaDataFrameModel):
378
+ """Schema for getting assigned global values for an employee."""
379
+ type: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Global value type", alias="type")
380
+ is_available_in_company: Optional[Series[pd.BooleanDtype]] = pa.Field(coerce=True, nullable=True, description="Is available in company", alias="isAvailableInCompany")
381
+ is_employee_assigned: Optional[Series[pd.BooleanDtype]] = pa.Field(coerce=True, nullable=True, description="Is employee assigned", alias="isEmployeeAssigned")
382
+
383
+ # CompanyGlobalValueReferenceUidsPairs fields (normalized)
384
+ company_global_value_uid: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Company global value UID", alias="companyGlobalValueReferenceUidsPairs__companyGlobalValueUid")
385
+ reference_uid: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Reference UID", alias="companyGlobalValueReferenceUidsPairs__referenceUid")
386
+
387
+ class _Annotation:
388
+ primary_key = "company_global_value_uid"
389
+ foreign_keys = {}
390
+
391
+
392
+ class AssignedEmployeesToGlobalValueGet(BrynQPanderaDataFrameModel):
393
+ """Flattened schema for employees assigned to a global value"""
394
+ # Basic employee fields
395
+ id: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Employee ID", alias="id")
396
+ uid: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Employee UID", alias="uid")
397
+ name: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Employee name", alias="name")
398
+ employee_number: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Employee number", alias="employeeNumber")
399
+ extra_employee_number: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Extra employee number", alias="extraEmployeeNumber")
400
+ title: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Employee title", alias="title")
401
+ photo_url: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Employee photo URL", alias="photoUrl")
402
+ has_profile_image: Optional[Series[pd.BooleanDtype]] = pa.Field(coerce=True, nullable=True, description="Has profile image", alias="hasProfileImage")
403
+ is_resigned: Optional[Series[pd.BooleanDtype]] = pa.Field(coerce=True, nullable=True, description="Is resigned", alias="isResigned")
404
+
405
+ # Salary and employment details
406
+ salary_type: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Employee salary type", alias="salaryType")
407
+ salary_payout_period: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Employee salary payout period", alias="salaryPayoutPeriod")
408
+ income_type: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Employee income type", alias="incomeType")
409
+ holiday_pay_receiver_type: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Holiday pay receiver type", alias="holidayPayReceiverType")
410
+ extra_holiday_entitlement_rule: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Extra holiday entitlement rule", alias="extraHolidayEntitlementRule")
411
+
412
+ # Global value assignment details
413
+ is_date_managed: Optional[Series[pd.BooleanDtype]] = pa.Field(coerce=True, nullable=True, description="Is date managed", alias="isDateManaged")
414
+ effective_from: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective from date", alias="effectiveFrom")
415
+ effective_to: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Effective to date", alias="effectiveTo")
416
+
417
+ # Department fields (normalized)
418
+ department_id: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="Department ID", alias="department__id")
419
+ department_uid: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Department UID", alias="department__uid")
420
+ department_name: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Department name", alias="department__name")
421
+ department_number: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="Department number", alias="department__number")
422
+ department_has_work_schema: Optional[Series[pd.BooleanDtype]] = pa.Field(coerce=True, nullable=True, description="Department has work schema", alias="department__hasWorkSchema")
423
+
424
+ # User fields (normalized)
425
+ user_id: Optional[Series[pd.Int64Dtype]] = pa.Field(coerce=True, nullable=True, description="User ID", alias="user__id")
426
+ user_uid: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="User UID", alias="user__uid")
427
+ user_name: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="User name", alias="user__name")
428
+ user_email: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="User email", alias="user__email")
429
+ user_photo_url: Optional[Series[pd.StringDtype]] = pa.Field(coerce=True, nullable=True, description="User photo URL", alias="user__photoUrl")
430
+
431
+ class _Annotation:
432
+ primary_key = "uid"
433
+ foreign_keys = {}