brynq-sdk-alight 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- brynq_sdk_alight/__init__.py +1019 -0
- brynq_sdk_alight/address.py +72 -0
- brynq_sdk_alight/archive/flat_wrapper.py +139 -0
- brynq_sdk_alight/archive/hrxml_generator.py +280 -0
- brynq_sdk_alight/archive/managers.py +132 -0
- brynq_sdk_alight/archive/managers_generic.py +114 -0
- brynq_sdk_alight/archive/managers_old_complex.py +294 -0
- brynq_sdk_alight/archive/managers_simple.py +229 -0
- brynq_sdk_alight/employee.py +81 -0
- brynq_sdk_alight/job.py +89 -0
- brynq_sdk_alight/leave.py +97 -0
- brynq_sdk_alight/pay_elements.py +97 -0
- brynq_sdk_alight/salary.py +89 -0
- brynq_sdk_alight/schemas/__init__.py +26 -0
- brynq_sdk_alight/schemas/absence.py +83 -0
- brynq_sdk_alight/schemas/address.py +113 -0
- brynq_sdk_alight/schemas/employee.py +641 -0
- brynq_sdk_alight/schemas/generated_envelope_xsd_schema/__init__.py +38683 -0
- brynq_sdk_alight/schemas/generated_envelope_xsd_schema/process_pay_serv_emp.py +622264 -0
- brynq_sdk_alight/schemas/generated_xsd_schemas/__init__.py +10965 -0
- brynq_sdk_alight/schemas/generated_xsd_schemas/csec_person.py +39808 -0
- brynq_sdk_alight/schemas/generated_xsd_schemas/hrxml_indicative_data.py +90318 -0
- brynq_sdk_alight/schemas/generated_xsd_schemas/openapplications_bod.py +33869 -0
- brynq_sdk_alight/schemas/generated_xsd_schemas/openapplications_code_list_currency_code_iso_7_04.py +365 -0
- brynq_sdk_alight/schemas/generated_xsd_schemas/openapplications_code_list_language_code_iso_7_04.py +16 -0
- brynq_sdk_alight/schemas/generated_xsd_schemas/openapplications_code_list_mimemedia_type_code_iana_7_04.py +16 -0
- brynq_sdk_alight/schemas/generated_xsd_schemas/openapplications_code_list_unit_code_unece_7_04.py +14 -0
- brynq_sdk_alight/schemas/generated_xsd_schemas/openapplications_code_lists.py +535 -0
- brynq_sdk_alight/schemas/generated_xsd_schemas/openapplications_qualified_data_types.py +84 -0
- brynq_sdk_alight/schemas/generated_xsd_schemas/openapplications_unqualified_data_types.py +1449 -0
- brynq_sdk_alight/schemas/job.py +129 -0
- brynq_sdk_alight/schemas/leave.py +58 -0
- brynq_sdk_alight/schemas/payments.py +207 -0
- brynq_sdk_alight/schemas/salary.py +67 -0
- brynq_sdk_alight/schemas/termination.py +48 -0
- brynq_sdk_alight/schemas/timequota.py +66 -0
- brynq_sdk_alight/schemas/utils.py +452 -0
- brynq_sdk_alight/termination.py +103 -0
- brynq_sdk_alight/time_elements.py +121 -0
- brynq_sdk_alight/time_quotas.py +114 -0
- brynq_sdk_alight-1.0.0.dist-info/METADATA +20 -0
- brynq_sdk_alight-1.0.0.dist-info/RECORD +44 -0
- brynq_sdk_alight-1.0.0.dist-info/WHEEL +5 -0
- brynq_sdk_alight-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,641 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Flat, user-friendly employee model for Alight SDK.
|
|
3
|
+
Automatically converts to complex nested HR-XML structure using schema introspection.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import datetime
|
|
7
|
+
from typing import Optional, Dict, Any, List, Union
|
|
8
|
+
from pydantic import Field, model_validator, BaseModel
|
|
9
|
+
|
|
10
|
+
from .utils import add_to_nested_path, post_process_nested_data, construct_model
|
|
11
|
+
from .salary import Salary # Import related models
|
|
12
|
+
from .address import Address
|
|
13
|
+
from .job import Job
|
|
14
|
+
from .leave import Leave
|
|
15
|
+
from .termination import Termination
|
|
16
|
+
from .generated_xsd_schemas.hrxml_indicative_data import IndicativeDataType
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class EmployeeCreate(BaseModel):
|
|
20
|
+
"""
|
|
21
|
+
Comprehensive employee model for Alight integration.
|
|
22
|
+
Automatically converts to complex nested HR-XML structure using pure schema introspection.
|
|
23
|
+
"""
|
|
24
|
+
model_config = {
|
|
25
|
+
"populate_by_name": True # Allow populating by field name in addition to alias
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
# Document Level Fields - Use aliases to map directly to XSD fields
|
|
29
|
+
document_id: Optional[str] = Field(
|
|
30
|
+
default=None,
|
|
31
|
+
description="Document identifier",
|
|
32
|
+
alias="document_id"
|
|
33
|
+
)
|
|
34
|
+
document_sequence: Optional[str] = Field(
|
|
35
|
+
default=None,
|
|
36
|
+
description="Document sequence number",
|
|
37
|
+
alias="document_sequence"
|
|
38
|
+
)
|
|
39
|
+
alternate_document_id: Optional[List[str]] = Field(
|
|
40
|
+
default=None,
|
|
41
|
+
description="Alternate document identifier (list in XSD)",
|
|
42
|
+
alias="alternate_document_id"
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# Core Identity - Use aliases to map directly to XSD fields
|
|
46
|
+
person_id: str = Field(
|
|
47
|
+
description="Unique person identifier",
|
|
48
|
+
alias="indicative_person_dossier.indicative_person.person_id"
|
|
49
|
+
)
|
|
50
|
+
person_legal_id: Optional[str] = Field(
|
|
51
|
+
default=None,
|
|
52
|
+
description="Legal ID (SSN/NI number)",
|
|
53
|
+
alias="indicative_person_dossier.indicative_person.person_legal_id"
|
|
54
|
+
)
|
|
55
|
+
person_legal_id_scheme_name: Optional[str] = Field(
|
|
56
|
+
default=None,
|
|
57
|
+
description="Legal ID scheme (GB-NI/US-SSN)",
|
|
58
|
+
alias="indicative_person_dossier.indicative_person.person_legal_id.scheme_name"
|
|
59
|
+
)
|
|
60
|
+
employee_id: Optional[str] = Field(
|
|
61
|
+
default=None,
|
|
62
|
+
description="Employee ID (defaults to person_id)",
|
|
63
|
+
alias="indicative_person_dossier.indicative_employee.employee_id"
|
|
64
|
+
)
|
|
65
|
+
employee_group_code: Optional[str] = Field(
|
|
66
|
+
default=None,
|
|
67
|
+
description="Employee group classification",
|
|
68
|
+
alias="indicative_person_dossier.indicative_employee.employee_group_code"
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
# Name Information - Use aliases to map directly to XSD fields
|
|
72
|
+
given_name: Optional[str] = Field(
|
|
73
|
+
default=None,
|
|
74
|
+
description="First name",
|
|
75
|
+
alias="indicative_person_dossier.indicative_person.person_name.given_name"
|
|
76
|
+
)
|
|
77
|
+
middle_name: Optional[str] = Field(
|
|
78
|
+
default=None,
|
|
79
|
+
description="Middle name",
|
|
80
|
+
alias="indicative_person_dossier.indicative_person.person_name.middle_name"
|
|
81
|
+
)
|
|
82
|
+
preferred_name: Optional[str] = Field(
|
|
83
|
+
default=None,
|
|
84
|
+
description="Preferred or nick name",
|
|
85
|
+
alias="indicative_person_dossier.indicative_person.person_name.preferred_name"
|
|
86
|
+
)
|
|
87
|
+
family_name: Optional[str] = Field(
|
|
88
|
+
default=None,
|
|
89
|
+
description="Last name/surname",
|
|
90
|
+
alias="indicative_person_dossier.indicative_person.person_name.family_name"
|
|
91
|
+
)
|
|
92
|
+
former_family_name: Optional[str] = Field(
|
|
93
|
+
default=None,
|
|
94
|
+
description="Maiden name",
|
|
95
|
+
alias="indicative_person_dossier.indicative_person.person_name.former_family_name"
|
|
96
|
+
)
|
|
97
|
+
preferred_salutation_code: Optional[str] = Field(
|
|
98
|
+
default=None,
|
|
99
|
+
description="Mr/Ms/Dr etc.",
|
|
100
|
+
alias="indicative_person_dossier.indicative_person.person_name.preferred_salutation_code"
|
|
101
|
+
)
|
|
102
|
+
generation_affix_code: Optional[str] = Field(
|
|
103
|
+
default=None,
|
|
104
|
+
description="Generation suffix (Sr., Jr., III, etc.)",
|
|
105
|
+
alias="indicative_person_dossier.indicative_person.person_name.generation_affix_code"
|
|
106
|
+
)
|
|
107
|
+
qualification_affix_code: Optional[List[str]] = Field(
|
|
108
|
+
default=None,
|
|
109
|
+
description="Qualification codes (e.g., MBA, PhD)",
|
|
110
|
+
alias="indicative_person_dossier.indicative_person.person_name.qualification_affix_code"
|
|
111
|
+
)
|
|
112
|
+
title_affix_code: Optional[List[str]] = Field(
|
|
113
|
+
default=None,
|
|
114
|
+
description="Title affix codes (e.g., Lord, Sir)",
|
|
115
|
+
alias="indicative_person_dossier.indicative_person.person_name.title_affix_code"
|
|
116
|
+
)
|
|
117
|
+
person_name_initials: Optional[str] = Field(
|
|
118
|
+
default=None,
|
|
119
|
+
description="Initials derived from person name",
|
|
120
|
+
alias="indicative_person_dossier.indicative_person.person_name.person_name_initials"
|
|
121
|
+
)
|
|
122
|
+
formatted_name: Optional[str] = Field(
|
|
123
|
+
default=None,
|
|
124
|
+
description="Formatted display name",
|
|
125
|
+
alias="indicative_person_dossier.indicative_person.person_name.formatted_name"
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# Personal Details - Use aliases to map directly to XSD fields
|
|
129
|
+
birth_date: Optional[datetime.date] = Field(
|
|
130
|
+
default=None,
|
|
131
|
+
description="Birth date",
|
|
132
|
+
alias="indicative_person_dossier.indicative_person.birth_date"
|
|
133
|
+
)
|
|
134
|
+
gender_code: Optional[str] = Field(
|
|
135
|
+
default=None,
|
|
136
|
+
description="Male/Female/Other",
|
|
137
|
+
alias="indicative_person_dossier.indicative_person.gender_code"
|
|
138
|
+
)
|
|
139
|
+
# Birth Place - nested under indicative_person.birth_place
|
|
140
|
+
birth_place_city_name: Optional[str] = Field(
|
|
141
|
+
default=None,
|
|
142
|
+
description="City of birth",
|
|
143
|
+
alias="indicative_person_dossier.indicative_person.birth_place.city_name"
|
|
144
|
+
)
|
|
145
|
+
birth_place_country_sub_division_code: Optional[List[str]] = Field(
|
|
146
|
+
default=None,
|
|
147
|
+
description="State/region code(s) of birth",
|
|
148
|
+
alias="indicative_person_dossier.indicative_person.birth_place.country_sub_division_code"
|
|
149
|
+
)
|
|
150
|
+
birth_place_country_code: Optional[str] = Field(
|
|
151
|
+
default=None,
|
|
152
|
+
description="Country code of birth",
|
|
153
|
+
alias="indicative_person_dossier.indicative_person.birth_place.country_code"
|
|
154
|
+
)
|
|
155
|
+
marital_status_code: Optional[str] = Field(
|
|
156
|
+
default=None,
|
|
157
|
+
description="Married/Unmarried/etc.",
|
|
158
|
+
alias="indicative_person_dossier.indicative_person.certified_marital_status.marital_status_code"
|
|
159
|
+
)
|
|
160
|
+
marital_status_certified_date: Optional[datetime.date] = Field(
|
|
161
|
+
default=None,
|
|
162
|
+
description="Certified marital status date",
|
|
163
|
+
alias="indicative_person_dossier.indicative_person.certified_marital_status.certified_date"
|
|
164
|
+
)
|
|
165
|
+
primary_language_code: Optional[str] = Field(
|
|
166
|
+
default=None,
|
|
167
|
+
description="Primary language code",
|
|
168
|
+
alias="indicative_person_dossier.indicative_person.primary_language_code"
|
|
169
|
+
)
|
|
170
|
+
citizenship_country_code: Optional[str] = Field(
|
|
171
|
+
default=None,
|
|
172
|
+
description="Citizenship country code",
|
|
173
|
+
alias="indicative_person_dossier.indicative_person.citizenship_country_code"
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
# Employment Status - Use aliases to map directly to XSD fields
|
|
177
|
+
employed_indicator: Optional[bool] = Field(
|
|
178
|
+
default=None,
|
|
179
|
+
description="Employment status indicator",
|
|
180
|
+
alias="indicative_person_dossier.indicative_employment.employed_indicator"
|
|
181
|
+
)
|
|
182
|
+
expected_duty_entry_date: Optional[datetime.date] = Field(
|
|
183
|
+
default=None,
|
|
184
|
+
description="Expected start date",
|
|
185
|
+
alias="indicative_person_dossier.indicative_employment.proposed_hire.expected_duty_entry_date"
|
|
186
|
+
)
|
|
187
|
+
hire_type_code: Optional[str] = Field(
|
|
188
|
+
default=None,
|
|
189
|
+
description="NewHire/Rehire/Transfer",
|
|
190
|
+
alias="indicative_person_dossier.indicative_employment.employment_lifecycle.hire.hire_type_code"
|
|
191
|
+
)
|
|
192
|
+
hire_date: Optional[datetime.date] = Field(
|
|
193
|
+
default=None,
|
|
194
|
+
description="Hire date",
|
|
195
|
+
alias="indicative_person_dossier.indicative_employment.employment_lifecycle.hire.hire_date"
|
|
196
|
+
)
|
|
197
|
+
original_hire_date: Optional[datetime.date] = Field(
|
|
198
|
+
default=None,
|
|
199
|
+
description="Original hire date",
|
|
200
|
+
alias="indicative_person_dossier.indicative_employment.employment_lifecycle.hire.original_hire_date"
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
# Contact Information - Use index-aware aliases to map items into communication list
|
|
204
|
+
mobile_phone: Optional[str] = Field(
|
|
205
|
+
default=None,
|
|
206
|
+
description="Mobile phone number",
|
|
207
|
+
alias="indicative_person_dossier.indicative_person.communication[0].dial_number"
|
|
208
|
+
)
|
|
209
|
+
mobile_phone_use_code: Optional[str] = Field(
|
|
210
|
+
default=None,
|
|
211
|
+
description="Mobile phone use context",
|
|
212
|
+
alias="indicative_person_dossier.indicative_person.communication[0].use_code"
|
|
213
|
+
)
|
|
214
|
+
mobile_phone_channel_code: Optional[str] = Field(
|
|
215
|
+
default=None,
|
|
216
|
+
description="Communication channel code for phone",
|
|
217
|
+
alias="indicative_person_dossier.indicative_person.communication[0].channel_code"
|
|
218
|
+
)
|
|
219
|
+
country_dialing: Optional[str] = Field(
|
|
220
|
+
default=None,
|
|
221
|
+
description="Country dialing code for phone",
|
|
222
|
+
alias="indicative_person_dossier.indicative_person.communication[0].country_dialing"
|
|
223
|
+
)
|
|
224
|
+
area_dialing: Optional[str] = Field(
|
|
225
|
+
default=None,
|
|
226
|
+
description="Area/region dialing code for phone",
|
|
227
|
+
alias="indicative_person_dossier.indicative_person.communication[0].area_dialing"
|
|
228
|
+
)
|
|
229
|
+
dial_number: Optional[str] = Field(
|
|
230
|
+
default=None,
|
|
231
|
+
description="Dialable phone number",
|
|
232
|
+
alias="indicative_person_dossier.indicative_person.communication[0].dial_number"
|
|
233
|
+
)
|
|
234
|
+
extension: Optional[str] = Field(
|
|
235
|
+
default=None,
|
|
236
|
+
description="Phone extension",
|
|
237
|
+
alias="indicative_person_dossier.indicative_person.communication[0].extension"
|
|
238
|
+
)
|
|
239
|
+
access: Optional[str] = Field(
|
|
240
|
+
default=None,
|
|
241
|
+
description="Phone access code",
|
|
242
|
+
alias="indicative_person_dossier.indicative_person.communication[0].access"
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
email: Optional[str] = Field(
|
|
246
|
+
default=None,
|
|
247
|
+
description="Email address",
|
|
248
|
+
alias="indicative_person_dossier.indicative_person.communication[1].uri"
|
|
249
|
+
)
|
|
250
|
+
email_use_code: Optional[str] = Field(
|
|
251
|
+
default=None,
|
|
252
|
+
description="Email use context",
|
|
253
|
+
alias="indicative_person_dossier.indicative_person.communication[1].use_code"
|
|
254
|
+
)
|
|
255
|
+
email_channel_code: Optional[str] = Field(
|
|
256
|
+
default=None,
|
|
257
|
+
description="Communication channel code for email",
|
|
258
|
+
alias="indicative_person_dossier.indicative_person.communication[1].channel_code"
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
# Relation to Address model
|
|
262
|
+
address: Optional[Address] = Field(default=None, description="Employee's home address")
|
|
263
|
+
address_valid_from: Optional[datetime.date] = Field(
|
|
264
|
+
default=None,
|
|
265
|
+
description="Valid from date applied to primary home address",
|
|
266
|
+
alias="indicative_person_dossier.indicative_person.communication[2].address.valid_from"
|
|
267
|
+
)
|
|
268
|
+
address_use_code: Optional[str] = Field(
|
|
269
|
+
default=None,
|
|
270
|
+
description="Address use context (HOME/WORK)",
|
|
271
|
+
alias="indicative_person_dossier.indicative_person.communication[2].use_code"
|
|
272
|
+
)
|
|
273
|
+
address_type: Optional[str] = Field(
|
|
274
|
+
default=None,
|
|
275
|
+
description="Address type attribute",
|
|
276
|
+
alias="indicative_person_dossier.indicative_person.communication[2].address.type"
|
|
277
|
+
)
|
|
278
|
+
# Flat person address fields (HOME address in communication[2])
|
|
279
|
+
line_1: Optional[str] = Field(
|
|
280
|
+
default=None,
|
|
281
|
+
description="Primary address line",
|
|
282
|
+
alias="indicative_person_dossier.indicative_person.communication[2].address.line_one"
|
|
283
|
+
)
|
|
284
|
+
city: Optional[str] = Field(
|
|
285
|
+
default=None,
|
|
286
|
+
description="City name",
|
|
287
|
+
alias="indicative_person_dossier.indicative_person.communication[2].address.city_name"
|
|
288
|
+
)
|
|
289
|
+
state_province: Optional[str] = Field(
|
|
290
|
+
default=None,
|
|
291
|
+
description="State/Province code",
|
|
292
|
+
alias="indicative_person_dossier.indicative_person.communication[2].address.country_sub_division_code"
|
|
293
|
+
)
|
|
294
|
+
postal_code: Optional[str] = Field(
|
|
295
|
+
default=None,
|
|
296
|
+
description="Postal code",
|
|
297
|
+
alias="indicative_person_dossier.indicative_person.communication[2].address.postal_code"
|
|
298
|
+
)
|
|
299
|
+
country: Optional[str] = Field(
|
|
300
|
+
default=None,
|
|
301
|
+
description="Country code",
|
|
302
|
+
alias="indicative_person_dossier.indicative_person.communication[2].address.country_code"
|
|
303
|
+
)
|
|
304
|
+
person_valid_from: Optional[datetime.date] = Field(
|
|
305
|
+
default=None,
|
|
306
|
+
description="Effective date for indicative person",
|
|
307
|
+
alias="indicative_person_dossier.indicative_person.valid_from"
|
|
308
|
+
)
|
|
309
|
+
employee_valid_from: Optional[datetime.date] = Field(
|
|
310
|
+
default=None,
|
|
311
|
+
description="Effective date for indicative employee",
|
|
312
|
+
alias="indicative_person_dossier.indicative_employee.valid_from"
|
|
313
|
+
)
|
|
314
|
+
employment_valid_from: Optional[datetime.date] = Field(
|
|
315
|
+
default=None,
|
|
316
|
+
description="Effective date for indicative employment",
|
|
317
|
+
alias="indicative_person_dossier.indicative_employment.valid_from"
|
|
318
|
+
)
|
|
319
|
+
employment_lifecycle_valid_from: Optional[datetime.date] = Field(
|
|
320
|
+
default=None,
|
|
321
|
+
description="Effective date for employment lifecycle",
|
|
322
|
+
alias="indicative_person_dossier.indicative_employment.employment_lifecycle.valid_from"
|
|
323
|
+
)
|
|
324
|
+
hire_valid_from: Optional[datetime.date] = Field(
|
|
325
|
+
default=None,
|
|
326
|
+
description="Effective date for hire node",
|
|
327
|
+
alias="indicative_person_dossier.indicative_employment.employment_lifecycle.hire.valid_from"
|
|
328
|
+
)
|
|
329
|
+
deployment_valid_from: Optional[datetime.date] = Field(
|
|
330
|
+
default=None,
|
|
331
|
+
description="Effective date for indicative deployment",
|
|
332
|
+
alias="indicative_person_dossier.indicative_deployment.valid_from"
|
|
333
|
+
)
|
|
334
|
+
pay_cycle_remuneration_valid_from: Optional[datetime.date] = Field(
|
|
335
|
+
default=None,
|
|
336
|
+
description="Effective date for pay cycle remuneration",
|
|
337
|
+
alias="indicative_person_dossier.pay_cycle_remuneration.valid_from"
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
# Employer/Organization Information - Use aliases to map directly to XSD fields
|
|
341
|
+
employer_organization_id: Optional[str] = Field(
|
|
342
|
+
default=None,
|
|
343
|
+
description="Employer organization ID (flat input; coerced to XSD list)",
|
|
344
|
+
alias="employer_identifiers.organization_id"
|
|
345
|
+
)
|
|
346
|
+
employer_organization_name: Optional[str] = Field(
|
|
347
|
+
default=None,
|
|
348
|
+
description="Employer organization name",
|
|
349
|
+
alias="employer_identifiers.organization_name"
|
|
350
|
+
)
|
|
351
|
+
employer_organization_tax_id: Optional[List[str]] = Field(
|
|
352
|
+
default=None,
|
|
353
|
+
description="Employer organization tax ID (list in XSD)",
|
|
354
|
+
alias="employer_identifiers.organization_tax_id"
|
|
355
|
+
)
|
|
356
|
+
employer_organization_legal_id: Optional[List[str]] = Field(
|
|
357
|
+
default=None,
|
|
358
|
+
description="Employer organization legal ID (list in XSD)",
|
|
359
|
+
alias="employer_identifiers.organization_legal_id"
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
# Deployment Organization - Use aliases to map directly to XSD fields
|
|
363
|
+
deployment_organization_id: Optional[str] = Field(
|
|
364
|
+
default=None,
|
|
365
|
+
description="Deployment organization ID",
|
|
366
|
+
alias="indicative_person_dossier.indicative_deployment.deployment_organization.organization_identifiers.organization_id"
|
|
367
|
+
)
|
|
368
|
+
deployment_organization_name: Optional[str] = Field(
|
|
369
|
+
default=None,
|
|
370
|
+
description="Deployment organization name",
|
|
371
|
+
alias="indicative_person_dossier.indicative_deployment.deployment_organization.organization_identifiers.organization_name"
|
|
372
|
+
)
|
|
373
|
+
deployment_organization_valid_from: Optional[datetime.date] = Field(
|
|
374
|
+
default=None,
|
|
375
|
+
description="Effective date for deployment organization",
|
|
376
|
+
alias="indicative_person_dossier.indicative_deployment.deployment_organization.valid_from"
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
# Work Location (flat) -> IndicativeDeployment.WorkLocation.Address
|
|
380
|
+
work_location_city_name: Optional[str] = Field(
|
|
381
|
+
default=None,
|
|
382
|
+
description="Work location city",
|
|
383
|
+
alias="indicative_person_dossier.indicative_deployment.work_location.address.city_name"
|
|
384
|
+
)
|
|
385
|
+
work_location_country_sub_division_code: Optional[str] = Field(
|
|
386
|
+
default=None,
|
|
387
|
+
description="Work location subdivision/state",
|
|
388
|
+
alias="indicative_person_dossier.indicative_deployment.work_location.address.country_sub_division_code"
|
|
389
|
+
)
|
|
390
|
+
work_location_postal_code: Optional[str] = Field(
|
|
391
|
+
default=None,
|
|
392
|
+
description="Work location postal code",
|
|
393
|
+
alias="indicative_person_dossier.indicative_deployment.work_location.address.postal_code"
|
|
394
|
+
)
|
|
395
|
+
|
|
396
|
+
# Legacy job fields (maintain backwards compatibility with flat payloads)
|
|
397
|
+
title: Optional[str] = Field(
|
|
398
|
+
default=None,
|
|
399
|
+
description="Job title",
|
|
400
|
+
alias="indicative_person_dossier.indicative_deployment.job.job_title"
|
|
401
|
+
)
|
|
402
|
+
department: Optional[str] = Field(
|
|
403
|
+
default=None,
|
|
404
|
+
description="Department name",
|
|
405
|
+
alias="indicative_person_dossier.indicative_deployment.department_name"
|
|
406
|
+
)
|
|
407
|
+
position_id: Optional[str] = Field(
|
|
408
|
+
default=None,
|
|
409
|
+
description="Position identifier",
|
|
410
|
+
alias="indicative_person_dossier.indicative_deployment.position_id"
|
|
411
|
+
)
|
|
412
|
+
position_title: Optional[str] = Field(
|
|
413
|
+
default=None,
|
|
414
|
+
description="Position title",
|
|
415
|
+
alias="indicative_person_dossier.indicative_deployment.position_title"
|
|
416
|
+
)
|
|
417
|
+
location_code: Optional[str] = Field(
|
|
418
|
+
default=None,
|
|
419
|
+
description="Work location identifier",
|
|
420
|
+
alias="indicative_person_dossier.indicative_deployment.work_location.location_id"
|
|
421
|
+
)
|
|
422
|
+
manager_id: Optional[str] = Field(
|
|
423
|
+
default=None,
|
|
424
|
+
description="Manager employee ID",
|
|
425
|
+
alias="indicative_person_dossier.indicative_deployment.manager_id.id"
|
|
426
|
+
)
|
|
427
|
+
weekly_hours: Optional[float] = Field(
|
|
428
|
+
default=None,
|
|
429
|
+
description="Weekly working hours",
|
|
430
|
+
alias="indicative_person_dossier.indicative_deployment.schedule.scheduled_hours[0].value"
|
|
431
|
+
)
|
|
432
|
+
weekly_hours_basis: Optional[str] = Field(
|
|
433
|
+
default="Week",
|
|
434
|
+
description="Schedule basis for weekly hours",
|
|
435
|
+
alias="indicative_person_dossier.indicative_deployment.schedule.scheduled_hours[0].schedule_basis"
|
|
436
|
+
)
|
|
437
|
+
pay_cycle_hours: Optional[float] = Field(
|
|
438
|
+
default=None,
|
|
439
|
+
description="Hours per pay cycle",
|
|
440
|
+
alias="indicative_person_dossier.indicative_deployment.schedule.scheduled_hours[1].value"
|
|
441
|
+
)
|
|
442
|
+
pay_cycle_hours_basis: Optional[str] = Field(
|
|
443
|
+
default=None,
|
|
444
|
+
description="Schedule basis for pay cycle hours",
|
|
445
|
+
alias="indicative_person_dossier.indicative_deployment.schedule.scheduled_hours[1].schedule_basis"
|
|
446
|
+
)
|
|
447
|
+
scheduled_days_per_week: Optional[float] = Field(
|
|
448
|
+
default=None,
|
|
449
|
+
description="Scheduled days per week",
|
|
450
|
+
alias="indicative_person_dossier.indicative_deployment.schedule.scheduled_days[0].value"
|
|
451
|
+
)
|
|
452
|
+
scheduled_days_basis: Optional[str] = Field(
|
|
453
|
+
default=None,
|
|
454
|
+
description="Schedule basis for scheduled days",
|
|
455
|
+
alias="indicative_person_dossier.indicative_deployment.schedule.scheduled_days[0].schedule_basis"
|
|
456
|
+
)
|
|
457
|
+
day_schedule_id: Optional[str] = Field(
|
|
458
|
+
default=None,
|
|
459
|
+
description="Day schedule ID",
|
|
460
|
+
alias="indicative_person_dossier.indicative_deployment.schedule.day_schedule[0].id"
|
|
461
|
+
)
|
|
462
|
+
fte_ratio: Optional[str] = Field(
|
|
463
|
+
default=None,
|
|
464
|
+
description="Full-time equivalent ratio",
|
|
465
|
+
alias="indicative_person_dossier.indicative_deployment.full_time_equivalent_ratio"
|
|
466
|
+
)
|
|
467
|
+
work_level_code: Optional[str] = Field(
|
|
468
|
+
default="FullTime",
|
|
469
|
+
description="Work level code",
|
|
470
|
+
alias="indicative_person_dossier.indicative_deployment.work_level_code"
|
|
471
|
+
)
|
|
472
|
+
|
|
473
|
+
# Work Location and Job Information fields removed - these belong in Job model
|
|
474
|
+
# Access these through the job relation
|
|
475
|
+
|
|
476
|
+
# Relation to Job model (replaces job fields)
|
|
477
|
+
job: Optional[Job] = Field(default=None, description="Employee's job information")
|
|
478
|
+
leave: Optional[Leave] = Field(default=None, description="Employee's leave information")
|
|
479
|
+
termination: Optional[Termination] = Field(default=None, description="Employee's termination information")
|
|
480
|
+
|
|
481
|
+
# Schedule Information and Work Level fields removed - these belong in Job model
|
|
482
|
+
# Access these through the job relation
|
|
483
|
+
|
|
484
|
+
# Pay Information - Use aliases to map directly to XSD fields
|
|
485
|
+
pay_group_code: Optional[str] = Field(
|
|
486
|
+
default=None,
|
|
487
|
+
description="Pay group classification",
|
|
488
|
+
alias="indicative_person_dossier.pay_cycle_remuneration.pay_group_code"
|
|
489
|
+
)
|
|
490
|
+
|
|
491
|
+
# Payment Instructions - Use aliases to map directly to XSD fields
|
|
492
|
+
payment_type: Optional[str] = Field(
|
|
493
|
+
default=None,
|
|
494
|
+
description="Payment type (MAIN/etc.)",
|
|
495
|
+
alias="payment_instruction.payment_type"
|
|
496
|
+
)
|
|
497
|
+
payment_method: Optional[str] = Field(
|
|
498
|
+
default=None,
|
|
499
|
+
description="Payment method (BANK_DOM/etc.)",
|
|
500
|
+
alias="payment_instruction.payment_method"
|
|
501
|
+
)
|
|
502
|
+
account_type_code: Optional[str] = Field(
|
|
503
|
+
default=None,
|
|
504
|
+
description="Account type (DDA/etc.)",
|
|
505
|
+
alias="payment_instruction.account_type_code"
|
|
506
|
+
)
|
|
507
|
+
name_on_account: Optional[str] = Field(
|
|
508
|
+
default=None,
|
|
509
|
+
description="Name on bank account",
|
|
510
|
+
alias="payment_instruction.name_on_account"
|
|
511
|
+
)
|
|
512
|
+
bank_routing_id: Optional[str] = Field(
|
|
513
|
+
default=None,
|
|
514
|
+
description="Bank routing number",
|
|
515
|
+
alias="payment_instruction.bank_routing_id"
|
|
516
|
+
)
|
|
517
|
+
account_id: Optional[str] = Field(
|
|
518
|
+
default=None,
|
|
519
|
+
description="Bank account number",
|
|
520
|
+
alias="payment_instruction.account_id"
|
|
521
|
+
)
|
|
522
|
+
iban: Optional[str] = Field(
|
|
523
|
+
default=None,
|
|
524
|
+
description="IBAN",
|
|
525
|
+
alias="payment_instruction.iban"
|
|
526
|
+
)
|
|
527
|
+
bank_country_code: Optional[str] = Field(
|
|
528
|
+
default=None,
|
|
529
|
+
description="Bank country code",
|
|
530
|
+
alias="payment_instruction.bank_country_code"
|
|
531
|
+
)
|
|
532
|
+
|
|
533
|
+
# Relation to Salary model
|
|
534
|
+
salary: Optional[Salary] = Field(default=None, description="Employee's salary information")
|
|
535
|
+
|
|
536
|
+
# Legacy Pay Elements - Use aliases to map directly to XSD fields
|
|
537
|
+
pay_element_id: Optional[str] = Field(
|
|
538
|
+
default=None,
|
|
539
|
+
description="Pay element ID",
|
|
540
|
+
alias="indicative_person_dossier.pay_cycle_remuneration.remuneration.pay_element.id"
|
|
541
|
+
)
|
|
542
|
+
pay_element_type: Optional[str] = Field(
|
|
543
|
+
default=None,
|
|
544
|
+
description="Pay element type",
|
|
545
|
+
alias="indicative_person_dossier.pay_cycle_remuneration.remuneration.pay_element.type_code"
|
|
546
|
+
)
|
|
547
|
+
pay_amount: Optional[str] = Field(
|
|
548
|
+
default=None,
|
|
549
|
+
description="Pay amount",
|
|
550
|
+
alias="indicative_person_dossier.pay_cycle_remuneration.remuneration.amount.value"
|
|
551
|
+
)
|
|
552
|
+
pay_currency_code: Optional[str] = Field(
|
|
553
|
+
default=None,
|
|
554
|
+
description="Pay currency code",
|
|
555
|
+
alias="indicative_person_dossier.pay_cycle_remuneration.remuneration.amount.currency_code"
|
|
556
|
+
)
|
|
557
|
+
|
|
558
|
+
# Common Dates - Use aliases to map to specific XSD fields
|
|
559
|
+
valid_from: Optional[datetime.date] = Field(
|
|
560
|
+
default=None,
|
|
561
|
+
description="Valid from date",
|
|
562
|
+
# Map to specific fields in the XSD schema
|
|
563
|
+
alias="indicative_person_dossier.valid_from"
|
|
564
|
+
)
|
|
565
|
+
|
|
566
|
+
# Additional fields - Use aliases to map directly to XSD fields
|
|
567
|
+
compensation_change_reason: Optional[str] = Field(
|
|
568
|
+
default=None,
|
|
569
|
+
description="Reason for compensation change",
|
|
570
|
+
alias="indicative_person_dossier.pay_cycle_remuneration.remuneration.compensation_change_reason"
|
|
571
|
+
)
|
|
572
|
+
effective_date: Optional[datetime.date] = Field(
|
|
573
|
+
default=None,
|
|
574
|
+
description="Effective date for changes",
|
|
575
|
+
alias="indicative_person_dossier.indicative_deployment.effective_date"
|
|
576
|
+
)
|
|
577
|
+
|
|
578
|
+
def to_nested_dict(self) -> Dict[str, Any]:
|
|
579
|
+
"""
|
|
580
|
+
Convert flat employee data to nested HR-XML structure using PURE schema-driven conversion.
|
|
581
|
+
Uses alias dot-paths expanded to nested dict to align with XSD structure.
|
|
582
|
+
"""
|
|
583
|
+
if IndicativeDataType is None:
|
|
584
|
+
raise ImportError("IndicativeDataType not available - cannot perform schema-driven conversion")
|
|
585
|
+
|
|
586
|
+
# Dump current model using aliases to get dot-path keys
|
|
587
|
+
flat_alias: Dict[str, Any] = self.model_dump(
|
|
588
|
+
exclude={"salary", "address", "job"}, exclude_none=True, by_alias=True
|
|
589
|
+
)
|
|
590
|
+
# print("[EMP] flat_alias keys:", list(flat_alias.keys())[:40])
|
|
591
|
+
|
|
592
|
+
# Minimal business logic
|
|
593
|
+
if not flat_alias.get('indicative_person_dossier.indicative_employee.employee_id') and self.person_id:
|
|
594
|
+
# Mirror employee_id default to person_id if missing
|
|
595
|
+
flat_alias['indicative_person_dossier.indicative_employee.employee_id'] = self.person_id
|
|
596
|
+
|
|
597
|
+
# Merge related models (they already dump with by_alias in their to_nested_dict)
|
|
598
|
+
if self.salary is not None:
|
|
599
|
+
for k, v in (self.salary.to_nested_dict() or {}).items():
|
|
600
|
+
flat_alias[k] = v
|
|
601
|
+
if self.address is not None:
|
|
602
|
+
for k, v in (self.address.to_nested_dict() or {}).items():
|
|
603
|
+
flat_alias[k] = v
|
|
604
|
+
if self.job is not None:
|
|
605
|
+
job_data = self.job.to_nested_dict() or {}
|
|
606
|
+
for k, v in job_data.items():
|
|
607
|
+
flat_alias[k] = v
|
|
608
|
+
if self.leave is not None:
|
|
609
|
+
for k, v in (self.leave.to_nested_dict() or {}).items():
|
|
610
|
+
flat_alias[k] = v
|
|
611
|
+
if self.termination is not None:
|
|
612
|
+
for k, v in (self.termination.to_nested_dict() or {}).items():
|
|
613
|
+
flat_alias[k] = v
|
|
614
|
+
|
|
615
|
+
# No ad-hoc communication aggregation; indices in aliases will build lists
|
|
616
|
+
# Delegate to generic converter (now dot-path aware)
|
|
617
|
+
# Build nested structure from dot-path aliases generically
|
|
618
|
+
nested: Dict[str, Any] = {}
|
|
619
|
+
for k, v in flat_alias.items():
|
|
620
|
+
add_to_nested_path(nested, k, v)
|
|
621
|
+
|
|
622
|
+
post_process_nested_data(nested, IndicativeDataType)
|
|
623
|
+
# print("[EMP] nested top-level keys:", list(nested.keys()))
|
|
624
|
+
return nested
|
|
625
|
+
|
|
626
|
+
def to_model(self) -> IndicativeDataType:
|
|
627
|
+
"""
|
|
628
|
+
Convert flat employee data directly to validated IndicativeDataType model.
|
|
629
|
+
Uses dot-separated aliases to map fields directly to the right places in the schema.
|
|
630
|
+
|
|
631
|
+
Returns:
|
|
632
|
+
IndicativeDataType: A validated model ready for XML serialization
|
|
633
|
+
"""
|
|
634
|
+
# Get the nested structure with only non-empty fields
|
|
635
|
+
nested_data = self.to_nested_dict()
|
|
636
|
+
|
|
637
|
+
try:
|
|
638
|
+
return construct_model(IndicativeDataType, nested_data)
|
|
639
|
+
except Exception:
|
|
640
|
+
# Fallback to full validation if fast-path construction fails
|
|
641
|
+
return IndicativeDataType.model_validate(nested_data)
|