brynq-sdk-alight 1.0.0.dev0__tar.gz → 1.0.0.dev1__tar.gz

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 (49) hide show
  1. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/PKG-INFO +1 -1
  2. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/__init__.py +27 -15
  3. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/address.py +4 -4
  4. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/job.py +4 -4
  5. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/leave.py +4 -4
  6. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/pay_elements.py +6 -2
  7. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/employee.py +29 -4
  8. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/termination.py +4 -4
  9. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/time_elements.py +3 -3
  10. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight.egg-info/PKG-INFO +1 -1
  11. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/setup.py +1 -1
  12. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/archive/flat_wrapper.py +0 -0
  13. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/archive/hrxml_generator.py +0 -0
  14. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/archive/managers.py +0 -0
  15. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/archive/managers_generic.py +0 -0
  16. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/archive/managers_old_complex.py +0 -0
  17. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/archive/managers_simple.py +0 -0
  18. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/employee.py +0 -0
  19. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/salary.py +0 -0
  20. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/__init__.py +0 -0
  21. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/absence.py +0 -0
  22. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/address.py +0 -0
  23. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/generated_envelope_xsd_schema/__init__.py +0 -0
  24. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/generated_envelope_xsd_schema/process_pay_serv_emp.py +0 -0
  25. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/generated_xsd_schemas/__init__.py +0 -0
  26. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/generated_xsd_schemas/csec_person.py +0 -0
  27. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/generated_xsd_schemas/hrxml_indicative_data.py +0 -0
  28. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/generated_xsd_schemas/openapplications_bod.py +0 -0
  29. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/generated_xsd_schemas/openapplications_code_list_currency_code_iso_7_04.py +0 -0
  30. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/generated_xsd_schemas/openapplications_code_list_language_code_iso_7_04.py +0 -0
  31. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/generated_xsd_schemas/openapplications_code_list_mimemedia_type_code_iana_7_04.py +0 -0
  32. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/generated_xsd_schemas/openapplications_code_list_unit_code_unece_7_04.py +0 -0
  33. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/generated_xsd_schemas/openapplications_code_lists.py +0 -0
  34. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/generated_xsd_schemas/openapplications_qualified_data_types.py +0 -0
  35. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/generated_xsd_schemas/openapplications_unqualified_data_types.py +0 -0
  36. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/job.py +0 -0
  37. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/leave.py +0 -0
  38. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/payments.py +0 -0
  39. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/salary.py +0 -0
  40. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/termination.py +0 -0
  41. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/timequota.py +0 -0
  42. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/schemas/utils.py +0 -0
  43. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight/time_quotas.py +0 -0
  44. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight.egg-info/SOURCES.txt +0 -0
  45. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight.egg-info/dependency_links.txt +0 -0
  46. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight.egg-info/not-zip-safe +0 -0
  47. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight.egg-info/requires.txt +0 -0
  48. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/brynq_sdk_alight.egg-info/top_level.txt +0 -0
  49. {brynq_sdk_alight-1.0.0.dev0 → brynq_sdk_alight-1.0.0.dev1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: brynq_sdk_alight
3
- Version: 1.0.0.dev0
3
+ Version: 1.0.0.dev1
4
4
  Summary: Alight SDK for the BrynQ.com platform
5
5
  Author: BrynQ
6
6
  Author-email: support@brynq.com
@@ -413,7 +413,6 @@ class Alight(BrynQ):
413
413
  # BOD REMOVAL: Always include creation_date_time and bodid for model validation (required fields)
414
414
  # We'll remove them from XML output later if exclude_bod_fields is True
415
415
  app_area_data["creation_date_time"] = {"value": XmlDateTime.from_datetime(timestamp)}
416
- # BOD REMOVAL: Only include bodid if not excluding BOD fields
417
416
  if not exclude_bod_fields:
418
417
  app_area_data["bodid"] = {"value": app_bodid_value}
419
418
  if application_language_code:
@@ -537,17 +536,21 @@ class Alight(BrynQ):
537
536
  pydantic_serializer = PydanticXmlSerializer()
538
537
  raw_xml = pydantic_serializer.render(envelope, ns_map=namespace_map)
539
538
 
540
- # BOD REMOVAL: Remove BOD fields from XML if exclude_bod_fields was set (for new hires)
539
+ # BOD REMOVAL: Remove BOD fields from XML if exclude_bod_fields was set (for new hires and updates)
541
540
  # Check if we should exclude by looking at the envelope's application_area
542
541
  # When exclude_bod_fields is True, bodid is not set, so it will be None
543
- if envelope.application_area and envelope.application_area.bodid is None:
544
- # Remove CreationDateTime and BODID elements from XML for new hires
545
- # Handle both single-line and multi-line XML formatting
546
- raw_xml = re.sub(r'<oa:CreationDateTime>.*?</oa:CreationDateTime>\s*', '', raw_xml, flags=re.DOTALL)
547
- raw_xml = re.sub(r'<oa:BODID>.*?</oa:BODID>\s*', '', raw_xml, flags=re.DOTALL)
548
- # Also handle self-closing tags if they exist
549
- raw_xml = re.sub(r'<oa:CreationDateTime\s*/>\s*', '', raw_xml)
550
- raw_xml = re.sub(r'<oa:BODID\s*/>\s*', '', raw_xml)
542
+ # We always remove creation_date_time and bodid from XML when exclude_bod_fields is True
543
+ if envelope.application_area:
544
+ bodid = getattr(envelope.application_area, 'bodid', None)
545
+ # If bodid is None, it means exclude_bod_fields was True, so remove both fields
546
+ if bodid is None:
547
+ # Remove CreationDateTime and BODID elements from XML
548
+ # Handle both single-line and multi-line XML formatting
549
+ raw_xml = re.sub(r'<oa:CreationDateTime>.*?</oa:CreationDateTime>\s*', '', raw_xml, flags=re.DOTALL)
550
+ raw_xml = re.sub(r'<oa:BODID>.*?</oa:BODID>\s*', '', raw_xml, flags=re.DOTALL)
551
+ # Also handle self-closing tags if they exist
552
+ raw_xml = re.sub(r'<oa:CreationDateTime\s*/>\s*', '', raw_xml)
553
+ raw_xml = re.sub(r'<oa:BODID\s*/>\s*', '', raw_xml)
551
554
 
552
555
  if pretty_print:
553
556
  # Pretty print the XML
@@ -807,11 +810,11 @@ class Alight(BrynQ):
807
810
  auth_token = self.session.headers.get('Authorization', 'Bearer <TOKEN>')
808
811
  subscription_key = self.session.headers.get('Ocp-Apim-Subscription-Key', '<SUBSCRIPTION_KEY>')
809
812
 
810
- print(f'curl {self.base_url}/bods/submit -X POST -H "Content-Type: application/json" -H "gcc: {self.gcc}" -H "env: {env}" -H "Authorization: {auth_token}" -H "Ocp-Apim-Subscription-Key: {subscription_key}" -d \'{{"bod": "{data}"}}\'')
813
+ # print(f'curl {self.base_url}/bods/submit -X POST -H "Content-Type: application/json" -H "gcc: {self.gcc}" -H "env: {env}" -H "Authorization: {auth_token}" -H "Ocp-Apim-Subscription-Key: {subscription_key}" -d \'{{"bod": "{data}"}}\'')
811
814
 
812
815
  resp = self.session.post(url=f"{self.base_url}/bods/submit", json={"bod": data})
813
816
  resp.raise_for_status()
814
- return resp.json().get("UUID")
817
+ return resp.json().get("bodId")
815
818
 
816
819
  def get_bods_status(self, bods_id: str):
817
820
  """
@@ -863,7 +866,16 @@ class Alight(BrynQ):
863
866
 
864
867
  try:
865
868
  # Convert Employee to IndicativeDataType model
866
- employee_model = employee if isinstance(employee, EmployeeCreate) else EmployeeCreate(**employee)
869
+ if isinstance(employee, EmployeeCreate):
870
+ employee_model = employee
871
+ # Set action_code if not already set
872
+ if not hasattr(employee_model, 'action_code') or employee_model.action_code is None:
873
+ employee_model.action_code = action_code
874
+ else:
875
+ # Pass action_code to model for CHANGE vs ADD detection
876
+ employee_dict = dict(employee)
877
+ employee_dict['action_code'] = action_code
878
+ employee_model = EmployeeCreate(**employee_dict)
867
879
  indicative_data = employee_model.to_model()
868
880
 
869
881
  # Process optional extensions
@@ -956,8 +968,8 @@ class Alight(BrynQ):
956
968
  envelope_kwargs.setdefault("bod_id", str(uuid.uuid4()).upper())
957
969
  envelope_kwargs.setdefault("logical_id", logical_id or "TST-GB003-1001")
958
970
 
959
- # BOD REMOVAL: Exclude BOD fields for new hires (action_code="ADD")
960
- if action_code == "ADD":
971
+ # BOD REMOVAL: Exclude BOD fields for new hires (action_code="ADD") and updates (action_code="CHANGE")
972
+ if action_code == "ADD" or action_code == "CHANGE":
961
973
  envelope_kwargs["exclude_bod_fields"] = True
962
974
 
963
975
  envelope = self.create_complete_alight_envelope(
@@ -24,7 +24,7 @@ class Address:
24
24
  data: Dict[str, Any],
25
25
  *,
26
26
  person_id: str,
27
- employee_id: str,
27
+ employee_id: Optional[str] = None,
28
28
  logical_id: Optional[str] = None,
29
29
  envelope_options: Optional[Dict[str, Any]] = None,
30
30
  employee_data: Optional[Dict[str, Any]] = None,
@@ -32,7 +32,7 @@ class Address:
32
32
  ) -> str:
33
33
  """
34
34
  Update address (actionCode=CHANGE). Returns XML string.
35
- Requires both person_id and employee_id per integration constraints.
35
+ Requires person_id. employee_id is optional for updates.
36
36
 
37
37
  Example:
38
38
  >>> alight.address.update(
@@ -43,13 +43,13 @@ class Address:
43
43
  ... "address_valid_from": "2024-01-01",
44
44
  ... },
45
45
  ... person_id="35561",
46
- ... employee_id="35561ZZGB",
47
46
  ... )
48
47
  """
49
48
  payload: dict[str, Any] = {
50
49
  "person_id": person_id,
51
- "employee_id": employee_id,
52
50
  }
51
+ if employee_id is not None:
52
+ payload["employee_id"] = employee_id
53
53
 
54
54
  # build from flat fields
55
55
  address_model = AddressModel(**data)
@@ -57,28 +57,28 @@ class Job:
57
57
  data: Mapping[str, Any],
58
58
  *,
59
59
  person_id: str,
60
- employee_id: str,
60
+ employee_id: Optional[str] = None,
61
61
  logical_id: Optional[str] = None,
62
62
  envelope_options: Optional[dict[str, Any]] = None,
63
63
  pretty_print: bool = True,
64
64
  ) -> str:
65
65
  """
66
66
  Update job/deployment data (actionCode=CHANGE). Returns XML string.
67
- Requires both person_id and employee_id.
67
+ Requires person_id. employee_id is optional for updates.
68
68
 
69
69
  Example:
70
70
  >>> alight.job.update(
71
71
  ... data={"job": {"job_code": "FIN-DIR", "effective_date": "2024-04-01"}},
72
72
  ... person_id="35561",
73
- ... employee_id="35561ZZGB",
74
73
  ... )
75
74
  """
76
75
  job_model = JobModel(**dict(data))
77
76
  payload = {
78
77
  "person_id": person_id,
79
- "employee_id": employee_id,
80
78
  "job": job_model.model_dump(exclude_none=True, by_alias=True),
81
79
  }
80
+ if employee_id is not None:
81
+ payload["employee_id"] = employee_id
82
82
 
83
83
  return self._client.generate_employee_xml(
84
84
  employee=payload,
@@ -61,20 +61,19 @@ class Leave:
61
61
  data: Dict[str, Any],
62
62
  *,
63
63
  person_id: str,
64
- employee_id: str,
64
+ employee_id: Optional[str] = None,
65
65
  logical_id: Optional[str] = None,
66
66
  envelope_options: Optional[dict[str, Any]] = None,
67
67
  pretty_print: bool = True,
68
68
  ) -> str:
69
69
  """
70
70
  Update leave entry (actionCode=CHANGE). Returns XML string.
71
- Requires both person_id and employee_id.
71
+ Requires person_id. employee_id is optional for updates.
72
72
 
73
73
  Example:
74
74
  >>> alight.leave.update(
75
75
  ... data={"leave": {"leave_type": "SICK", "status": "Cancelled"}},
76
76
  ... person_id="35561",
77
- ... employee_id="35561ZZGB",
78
77
  ... )
79
78
  """
80
79
  if 'leave' in data and data['leave'] is not None:
@@ -84,9 +83,10 @@ class Leave:
84
83
  leave_model = LeaveModel(**data)
85
84
  payload = {
86
85
  "person_id": person_id,
87
- "employee_id": employee_id,
88
86
  "leave": leave_model.model_dump(exclude_none=True, by_alias=True),
89
87
  }
88
+ if employee_id is not None:
89
+ payload["employee_id"] = employee_id
90
90
 
91
91
  return self._client.generate_employee_xml(
92
92
  employee=payload,
@@ -74,7 +74,7 @@ class PayElements:
74
74
  *,
75
75
  elements: List[Dict[str, Any]],
76
76
  person_id: str,
77
- employee_id: str,
77
+ employee_id: Optional[str] = None,
78
78
  logical_id: Optional[str] = None,
79
79
  envelope_options: Optional[Dict[str, Any]] = None,
80
80
  pretty_print: bool = True,
@@ -87,8 +87,12 @@ class PayElements:
87
87
  """
88
88
  pay_elements_data = self._build_pay_elements(elements)
89
89
 
90
+ employee_payload = {"person_id": person_id}
91
+ if employee_id is not None:
92
+ employee_payload["employee_id"] = employee_id
93
+
90
94
  return self._client.generate_employee_xml(
91
- employee={"person_id": person_id, "employee_id": employee_id},
95
+ employee=employee_payload,
92
96
  action_code="CHANGE",
93
97
  logical_id=logical_id,
94
98
  pay_elements_data=pay_elements_data,
@@ -258,6 +258,22 @@ class EmployeeCreate(BaseModel):
258
258
  alias="indicative_person_dossier.indicative_person.communication[1].channel_code"
259
259
  )
260
260
 
261
+ personal_email: Optional[str] = Field(
262
+ default=None,
263
+ description="Personal email address",
264
+ alias="indicative_person_dossier.indicative_person.communication[3].uri"
265
+ )
266
+ personal_email_use_code: Optional[str] = Field(
267
+ default=None,
268
+ description="Personal email use context",
269
+ alias="indicative_person_dossier.indicative_person.communication[3].use_code"
270
+ )
271
+ personal_email_channel_code: Optional[str] = Field(
272
+ default=None,
273
+ description="Communication channel code for personal email",
274
+ alias="indicative_person_dossier.indicative_person.communication[3].channel_code"
275
+ )
276
+
261
277
  # Relation to Address model
262
278
  address: Optional[Address] = Field(default=None, description="Employee's home address")
263
279
  address_valid_from: Optional[datetime.date] = Field(
@@ -477,6 +493,9 @@ class EmployeeCreate(BaseModel):
477
493
  job: Optional[Job] = Field(default=None, description="Employee's job information")
478
494
  leave: Optional[Leave] = Field(default=None, description="Employee's leave information")
479
495
  termination: Optional[Termination] = Field(default=None, description="Employee's termination information")
496
+
497
+ # Internal field to track action code (excluded from model dump)
498
+ action_code: Optional[str] = Field(default=None, exclude=True, description="Internal: action code (ADD/CHANGE)")
480
499
 
481
500
  # Schedule Information and Work Level fields removed - these belong in Job model
482
501
  # Access these through the job relation
@@ -584,8 +603,10 @@ class EmployeeCreate(BaseModel):
584
603
  raise ImportError("IndicativeDataType not available - cannot perform schema-driven conversion")
585
604
 
586
605
  # Dump current model using aliases to get dot-path keys
606
+ # exclude_unset=True prevents default values (like work_level_code="FullTime") from being included
607
+ # unless they were explicitly set, which is important for CHANGE updates
587
608
  flat_alias: Dict[str, Any] = self.model_dump(
588
- exclude={"salary", "address", "job"}, exclude_none=True, by_alias=True
609
+ exclude={"salary", "address", "job", "action_code"}, exclude_none=True, exclude_unset=True, by_alias=True
589
610
  )
590
611
  # print("[EMP] flat_alias keys:", list(flat_alias.keys())[:40])
591
612
 
@@ -605,9 +626,13 @@ class EmployeeCreate(BaseModel):
605
626
  del flat_alias[basis_path]
606
627
 
607
628
  # Minimal business logic
608
- if not flat_alias.get('indicative_person_dossier.indicative_employee.employee_id') and self.person_id:
609
- # Mirror employee_id default to person_id if missing
610
- flat_alias['indicative_person_dossier.indicative_employee.employee_id'] = self.person_id
629
+ # Only auto-add employee_id for ADD operations, not for CHANGE
630
+ employee_id_key = 'indicative_person_dossier.indicative_employee.employee_id'
631
+ if employee_id_key not in flat_alias and self.person_id:
632
+ # Only auto-add employee_id for ADD operations
633
+ # For CHANGE operations, employee_id should be explicitly provided if needed
634
+ if self.action_code != "CHANGE":
635
+ flat_alias[employee_id_key] = self.person_id
611
636
 
612
637
  # Merge related models (they already dump with by_alias in their to_nested_dict)
613
638
  if self.salary is not None:
@@ -64,7 +64,7 @@ class Termination:
64
64
  data: Dict[str, Any],
65
65
  *,
66
66
  person_id: str,
67
- employee_id: str,
67
+ employee_id: Optional[str] = None,
68
68
  extension_data: Optional[Dict[str, Any]] = None,
69
69
  employee_data: Optional[Dict[str, Any]] = None,
70
70
  logical_id: Optional[str] = None,
@@ -73,22 +73,22 @@ class Termination:
73
73
  ) -> str:
74
74
  """
75
75
  Update termination entry (actionCode=CHANGE). Returns XML string.
76
- Requires both person_id and employee_id.
76
+ Requires person_id. employee_id is optional for updates.
77
77
 
78
78
  Example:
79
79
  >>> alight.termination.update(
80
80
  ... data={"termination_reason": "DISMISSAL", "termination_date": "2024-07-15"},
81
81
  ... person_id="35561",
82
- ... employee_id="35561ZZGB",
83
82
  ... employee_data={"last_day_worked": "2024-07-10"},
84
83
  ... )
85
84
  """
86
85
  termination_model = TerminationModel(**data)
87
86
  payload: Dict[str, Any] = {
88
87
  "person_id": person_id,
89
- "employee_id": employee_id,
90
88
  "termination": termination_model.model_dump(exclude_none=True, by_alias=True),
91
89
  }
90
+ if employee_id is not None:
91
+ payload["employee_id"] = employee_id
92
92
 
93
93
  if employee_data:
94
94
  payload.update(employee_data)
@@ -84,7 +84,7 @@ class TimeElements:
84
84
  *,
85
85
  absences: Union[Dict[str, Any], List[Dict[str, Any]]],
86
86
  person_id: str,
87
- employee_id: str,
87
+ employee_id: Optional[str] = None,
88
88
  logical_id: Optional[str] = None,
89
89
  envelope_options: Optional[Dict[str, Any]] = None,
90
90
  pretty_print: bool = True,
@@ -101,15 +101,15 @@ class TimeElements:
101
101
  ... {"absence_reason": "VAC", "valid_from": "2024-01-01", "valid_to": "2024-01-02", "units": "16"}
102
102
  ... ],
103
103
  ... person_id="35561",
104
- ... employee_id="35561ZZGB",
105
104
  ... )
106
105
  """
107
106
  extension_data = self._build_extension_with_time_elements(absences)
108
107
 
109
108
  payload = {
110
109
  "person_id": person_id,
111
- "employee_id": employee_id,
112
110
  }
111
+ if employee_id is not None:
112
+ payload["employee_id"] = employee_id
113
113
 
114
114
  return self._client.generate_employee_xml(
115
115
  employee=payload,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: brynq_sdk_alight
3
- Version: 1.0.0.dev0
3
+ Version: 1.0.0.dev1
4
4
  Summary: Alight SDK for the BrynQ.com platform
5
5
  Author: BrynQ
6
6
  Author-email: support@brynq.com
@@ -2,7 +2,7 @@ from setuptools import find_namespace_packages, setup
2
2
 
3
3
  setup(
4
4
  name='brynq_sdk_alight',
5
- version='1.0.0.dev0',
5
+ version='1.0.0.dev1',
6
6
  description='Alight SDK for the BrynQ.com platform',
7
7
  long_description='Alight SDK for the BrynQ.com platform',
8
8
  author='BrynQ',