layrz-sdk 4.0.11__py3-none-any.whl → 4.1.8__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 (104) hide show
  1. layrz_sdk/decorators/__init__.py +5 -0
  2. layrz_sdk/decorators/func_timing.py +103 -0
  3. layrz_sdk/entities/__init__.py +19 -0
  4. layrz_sdk/entities/action.py +28 -16
  5. layrz_sdk/entities/action_geofence_ownership.py +0 -2
  6. layrz_sdk/entities/action_kind.py +0 -2
  7. layrz_sdk/entities/action_subkind.py +0 -2
  8. layrz_sdk/entities/asset.py +20 -9
  9. layrz_sdk/entities/asset_constants.py +10 -9
  10. layrz_sdk/entities/asset_contact.py +7 -3
  11. layrz_sdk/entities/asset_operation_mode.py +0 -2
  12. layrz_sdk/entities/ats_entry.py +11 -4
  13. layrz_sdk/entities/ats_exit_history.py +21 -19
  14. layrz_sdk/entities/ats_operation.py +87 -0
  15. layrz_sdk/entities/ats_possible_entry.py +10 -7
  16. layrz_sdk/entities/ats_possible_exit.py +19 -9
  17. layrz_sdk/entities/ats_purchaseorder.py +106 -0
  18. layrz_sdk/entities/ats_reception.py +16 -4
  19. layrz_sdk/entities/broadcast/__init__.py +2 -1
  20. layrz_sdk/entities/broadcast/payload.py +40 -8
  21. layrz_sdk/entities/broadcast/result.py +72 -1
  22. layrz_sdk/entities/broadcast/service.py +12 -2
  23. layrz_sdk/entities/broadcast/status.py +2 -2
  24. layrz_sdk/entities/case.py +51 -8
  25. layrz_sdk/entities/case_ignored_status.py +1 -0
  26. layrz_sdk/entities/charts/axis_config.py +13 -5
  27. layrz_sdk/entities/charts/bar_chart.py +12 -1
  28. layrz_sdk/entities/charts/chart_data_serie.py +17 -1
  29. layrz_sdk/entities/charts/column_chart.py +12 -1
  30. layrz_sdk/entities/charts/html_chart.py +8 -4
  31. layrz_sdk/entities/charts/line_chart.py +12 -3
  32. layrz_sdk/entities/charts/map_chart.py +14 -5
  33. layrz_sdk/entities/charts/map_point.py +7 -1
  34. layrz_sdk/entities/charts/number_chart.py +8 -4
  35. layrz_sdk/entities/charts/pie_chart.py +11 -3
  36. layrz_sdk/entities/charts/radar_chart.py +11 -3
  37. layrz_sdk/entities/charts/radial_bar_chart.py +11 -3
  38. layrz_sdk/entities/charts/scatter_chart.py +12 -3
  39. layrz_sdk/entities/charts/scatter_serie.py +11 -1
  40. layrz_sdk/entities/charts/scatter_serie_item.py +7 -1
  41. layrz_sdk/entities/charts/table_chart.py +7 -3
  42. layrz_sdk/entities/charts/table_header.py +7 -1
  43. layrz_sdk/entities/charts/table_row.py +7 -1
  44. layrz_sdk/entities/charts/timeline_chart.py +11 -3
  45. layrz_sdk/entities/charts/timeline_serie.py +7 -1
  46. layrz_sdk/entities/charts/timeline_serie_item.py +7 -1
  47. layrz_sdk/entities/checkpoint.py +20 -13
  48. layrz_sdk/entities/command_series_ticket.py +29 -4
  49. layrz_sdk/entities/comment.py +22 -5
  50. layrz_sdk/entities/custom_field.py +12 -4
  51. layrz_sdk/entities/custom_report_page.py +3 -0
  52. layrz_sdk/entities/destination_phone.py +7 -1
  53. layrz_sdk/entities/device.py +11 -4
  54. layrz_sdk/entities/event.py +20 -4
  55. layrz_sdk/entities/exchange_service.py +12 -4
  56. layrz_sdk/entities/function.py +11 -4
  57. layrz_sdk/entities/geofence.py +20 -5
  58. layrz_sdk/entities/geofence_category.py +0 -2
  59. layrz_sdk/entities/last_message.py +7 -3
  60. layrz_sdk/entities/locator.py +95 -0
  61. layrz_sdk/entities/message.py +16 -9
  62. layrz_sdk/entities/modbus/config.py +7 -1
  63. layrz_sdk/entities/modbus/parameter.py +7 -1
  64. layrz_sdk/entities/modbus/wait.py +11 -1
  65. layrz_sdk/entities/notification_type.py +0 -2
  66. layrz_sdk/entities/operation.py +37 -16
  67. layrz_sdk/entities/operation_case_payload.py +39 -13
  68. layrz_sdk/entities/operation_payload.py +63 -26
  69. layrz_sdk/entities/operation_type.py +0 -2
  70. layrz_sdk/entities/outbound_service.py +11 -4
  71. layrz_sdk/entities/parameter_update.py +25 -0
  72. layrz_sdk/entities/platform.py +0 -2
  73. layrz_sdk/entities/position.py +7 -3
  74. layrz_sdk/entities/preset.py +15 -9
  75. layrz_sdk/entities/report.py +9 -5
  76. layrz_sdk/entities/report_col.py +17 -3
  77. layrz_sdk/entities/report_configuration.py +7 -1
  78. layrz_sdk/entities/report_data_type.py +1 -3
  79. layrz_sdk/entities/report_format.py +1 -5
  80. layrz_sdk/entities/report_header.py +12 -29
  81. layrz_sdk/entities/report_page.py +7 -3
  82. layrz_sdk/entities/report_row.py +7 -19
  83. layrz_sdk/entities/request_type.py +0 -2
  84. layrz_sdk/entities/sensor.py +21 -3
  85. layrz_sdk/entities/sensor_mask.py +28 -0
  86. layrz_sdk/entities/sound_effect.py +0 -2
  87. layrz_sdk/entities/static_position.py +6 -1
  88. layrz_sdk/entities/telemetry/assetmessage.py +14 -15
  89. layrz_sdk/entities/telemetry/devicemessage.py +19 -9
  90. layrz_sdk/entities/text_alignment.py +0 -2
  91. layrz_sdk/entities/timezone.py +12 -4
  92. layrz_sdk/entities/trigger.py +102 -17
  93. layrz_sdk/entities/trigger_kind.py +2 -5
  94. layrz_sdk/entities/user.py +11 -4
  95. layrz_sdk/entities/waypoint.py +38 -16
  96. layrz_sdk/entities/weekday.py +1 -3
  97. layrz_sdk/helpers/color.py +1 -6
  98. layrz_sdk/lcl/core.py +0 -1
  99. {layrz_sdk-4.0.11.dist-info → layrz_sdk-4.1.8.dist-info}/METADATA +2 -2
  100. layrz_sdk-4.1.8.dist-info/RECORD +123 -0
  101. layrz_sdk-4.0.11.dist-info/RECORD +0 -116
  102. {layrz_sdk-4.0.11.dist-info → layrz_sdk-4.1.8.dist-info}/WHEEL +0 -0
  103. {layrz_sdk-4.0.11.dist-info → layrz_sdk-4.1.8.dist-info}/licenses/LICENSE +0 -0
  104. {layrz_sdk-4.0.11.dist-info → layrz_sdk-4.1.8.dist-info}/top_level.txt +0 -0
@@ -1,14 +1,22 @@
1
- """Exchange Service entity"""
2
-
3
1
  from typing import Any
4
2
 
5
- from pydantic import BaseModel, Field
3
+ from pydantic import BaseModel, ConfigDict, Field
6
4
 
7
5
 
8
6
  class ExchangeService(BaseModel):
9
7
  """Exchange service definition"""
10
8
 
11
- pk: int = Field(..., description='Service ID', alias='id')
9
+ model_config = ConfigDict(
10
+ validate_by_name=False,
11
+ validate_by_alias=True,
12
+ serialize_by_alias=True,
13
+ )
14
+
15
+ pk: int = Field(
16
+ ...,
17
+ description='Service ID',
18
+ alias='id',
19
+ )
12
20
  name: str = Field(..., description='Service name')
13
21
  credentials: dict[str, Any] = Field(
14
22
  description='Service credentials',
@@ -1,9 +1,7 @@
1
- """Geofence entity"""
2
-
3
1
  from datetime import timedelta
4
2
  from typing import Any
5
3
 
6
- from pydantic import BaseModel, Field
4
+ from pydantic import BaseModel, ConfigDict, Field
7
5
 
8
6
  from .asset import Asset
9
7
 
@@ -11,7 +9,16 @@ from .asset import Asset
11
9
  class Function(BaseModel):
12
10
  """Function entity"""
13
11
 
14
- pk: int = Field(description='Defines the primary key of the Function', alias='id')
12
+ model_config = ConfigDict(
13
+ validate_by_name=False,
14
+ validate_by_alias=True,
15
+ serialize_by_alias=True,
16
+ )
17
+
18
+ pk: int = Field(
19
+ description='Defines the primary key of the Function',
20
+ alias='id',
21
+ )
15
22
  name: str = Field(description='Name of the function')
16
23
 
17
24
  maximum_time: timedelta | None = Field(
@@ -1,11 +1,26 @@
1
- """Geofence entity"""
1
+ from typing import Any
2
2
 
3
- from pydantic import BaseModel, Field
3
+ from pydantic import BaseModel, ConfigDict, Field
4
4
 
5
5
 
6
6
  class Geofence(BaseModel):
7
7
  """Geofence entity"""
8
8
 
9
- pk: int = Field(description='Defines the primary key of the geofence', alias='id')
10
- name: str = Field(description='Defines the name of the geofence')
11
- color: str = Field(description='Defines the color of the geofence')
9
+ model_config = ConfigDict(
10
+ validate_by_name=False,
11
+ validate_by_alias=True,
12
+ serialize_by_alias=True,
13
+ )
14
+
15
+ pk: int = Field(
16
+ ...,
17
+ description='Defines the primary key of the geofence',
18
+ alias='id',
19
+ )
20
+ name: str = Field(..., description='Defines the name of the geofence')
21
+ color: str = Field(..., description='Defines the color of the geofence')
22
+
23
+ geom_wgs84: dict[str, Any] = Field(description='GeoJSON geometry', default_factory=dict)
24
+ geom_web_mercator: dict[str, Any] = Field(description='GeoJSON geometry in Web Mercator', default_factory=dict)
25
+
26
+ owner_id: int | None = Field(default=None, description='Defines the owner ID of the geofence')
@@ -1,5 +1,3 @@
1
- """Geofence category"""
2
-
3
1
  from enum import StrEnum
4
2
  from typing import Self
5
3
 
@@ -1,6 +1,4 @@
1
- """LastMessage entity"""
2
-
3
- from pydantic import BaseModel, Field
1
+ from pydantic import BaseModel, ConfigDict, Field
4
2
 
5
3
  from .asset import Asset
6
4
  from .message import Message
@@ -9,4 +7,10 @@ from .message import Message
9
7
  class LastMessage(Message, BaseModel):
10
8
  """LastMessage definition"""
11
9
 
10
+ model_config = ConfigDict(
11
+ validate_by_name=False,
12
+ validate_by_alias=True,
13
+ serialize_by_alias=True,
14
+ )
15
+
12
16
  asset: Asset = Field(description='Defines the asset of the last message')
@@ -0,0 +1,95 @@
1
+ from datetime import datetime
2
+ from typing import Any
3
+ from uuid import UUID
4
+
5
+ from pydantic import BaseModel, ConfigDict, Field, field_serializer, field_validator
6
+
7
+ from .asset import Asset
8
+ from .geofence import Geofence
9
+ from .trigger import Trigger
10
+
11
+
12
+ class LocatorMqttConfig(BaseModel):
13
+ model_config = ConfigDict(
14
+ validate_by_name=False,
15
+ validate_by_alias=True,
16
+ serialize_by_alias=True,
17
+ )
18
+ host: str = Field(..., description='Defines the MQTT host of the locator')
19
+ port: int = Field(..., description='Defines the MQTT port of the locator')
20
+ username: str | None = Field(default=None, description='Defines the MQTT username of the locator')
21
+ password: str | None = Field(default=None, description='Defines the MQTT password of the locator')
22
+ topic: str = Field(..., description='Defines the MQTT topic of the locator')
23
+
24
+
25
+ class Locator(BaseModel):
26
+ model_config = ConfigDict(
27
+ validate_by_name=False,
28
+ validate_by_alias=True,
29
+ serialize_by_alias=True,
30
+ )
31
+ pk: str = Field(
32
+ ...,
33
+ description='Defines the primary key of the locator',
34
+ alias='id',
35
+ )
36
+
37
+ @field_validator('pk', mode='before')
38
+ def validate_pk(cls, v: Any) -> str:
39
+ if isinstance(v, int):
40
+ return str(v)
41
+ if isinstance(v, str):
42
+ return v
43
+ if isinstance(v, UUID):
44
+ return str(v)
45
+ raise ValueError('Invalid type for pk')
46
+
47
+ token: str = Field(..., description='Defines the token of the locator')
48
+ owner_id: int = Field(..., description='Defines the owner ID of the locator')
49
+
50
+ created_at: datetime = Field(..., description='Defines the creation date of the locator')
51
+
52
+ @field_serializer('created_at', when_used='always')
53
+ def serialize_created_at(self, created_at: datetime) -> float:
54
+ return created_at.timestamp()
55
+
56
+ updated_at: datetime = Field(..., description='Defines the last update date of the locator')
57
+
58
+ @field_serializer('updated_at', when_used='always')
59
+ def serialize_updated_at(self, updated_at: datetime) -> float:
60
+ return updated_at.timestamp()
61
+
62
+ mqtt_config: LocatorMqttConfig | None = Field(..., description='Defines the MQTT configuration of the locator')
63
+ assets: list[Asset] = Field(
64
+ default_factory=list,
65
+ description='Defines the list of assets associated with the locator',
66
+ )
67
+
68
+ geofences: list[Geofence] = Field(
69
+ default_factory=list,
70
+ description='Defines the list of geofences associated with the locator',
71
+ )
72
+
73
+ triggers: list[Trigger] = Field(
74
+ default_factory=list,
75
+ description='Defines the list of triggers associated with the locator',
76
+ )
77
+
78
+ is_expired: bool = Field(
79
+ default=False,
80
+ description='Indicates whether the locator is expired',
81
+ )
82
+
83
+ expires_at: datetime | None = Field(
84
+ default=None,
85
+ description='Defines the expiration date of the locator, if applicable',
86
+ )
87
+
88
+ @field_serializer('expires_at', when_used='always')
89
+ def serialize_expires_at(self, expires_at: datetime | None) -> float | None:
90
+ return expires_at.timestamp() if expires_at else None
91
+
92
+ customization_id: int | None = Field(
93
+ default=None,
94
+ description='Defines the customization ID associated with the locator, if applicable',
95
+ )
@@ -1,9 +1,7 @@
1
- """Message entity"""
2
-
3
1
  from datetime import datetime
4
2
  from typing import Any
5
3
 
6
- from pydantic import BaseModel, Field, field_validator
4
+ from pydantic import BaseModel, ConfigDict, Field, field_serializer, field_validator
7
5
 
8
6
  from layrz_sdk.constants import UTC
9
7
  from layrz_sdk.entities.geofence import Geofence
@@ -13,13 +11,17 @@ from layrz_sdk.entities.position import Position
13
11
  class Message(BaseModel):
14
12
  """Message definition"""
15
13
 
16
- model_config = {
17
- 'json_encoders': {
18
- datetime: lambda v: v.timestamp(),
19
- }
20
- }
14
+ model_config = ConfigDict(
15
+ validate_by_name=False,
16
+ validate_by_alias=True,
17
+ serialize_by_alias=True,
18
+ )
21
19
 
22
- pk: int = Field(..., description='Message ID', alias='id')
20
+ pk: int = Field(
21
+ ...,
22
+ description='Message ID',
23
+ alias='id',
24
+ )
23
25
  asset_id: int = Field(..., description='Asset ID')
24
26
  position: Position = Field(
25
27
  default_factory=lambda: Position(),
@@ -38,6 +40,11 @@ class Message(BaseModel):
38
40
  description='Timestamp when the message was received',
39
41
  )
40
42
 
43
+ @field_serializer('received_at', when_used='always')
44
+ def serialize_received_at(self, value: datetime) -> float:
45
+ """Serialize received_at to a timestamp."""
46
+ return value.timestamp()
47
+
41
48
  geofences: list[Geofence] = Field(
42
49
  default_factory=list,
43
50
  description='List of geofences associated with the message',
@@ -1,9 +1,15 @@
1
- from pydantic import BaseModel, Field
1
+ from pydantic import BaseModel, ConfigDict, Field
2
2
 
3
3
  from .parameter import ModbusParameter
4
4
 
5
5
 
6
6
  class ModbusConfig(BaseModel):
7
+ model_config = ConfigDict(
8
+ validate_by_name=False,
9
+ validate_by_alias=True,
10
+ serialize_by_alias=True,
11
+ )
12
+
7
13
  port_id: str = Field(
8
14
  ...,
9
15
  description='Port ID for Modbus communication',
@@ -1,6 +1,6 @@
1
1
  from typing import Any
2
2
 
3
- from pydantic import BaseModel, Field, field_validator
3
+ from pydantic import BaseModel, ConfigDict, Field, field_validator
4
4
 
5
5
  from .schema import ModbusSchema
6
6
 
@@ -8,6 +8,12 @@ from .schema import ModbusSchema
8
8
  class ModbusParameter(BaseModel):
9
9
  """Modbus parameter model"""
10
10
 
11
+ model_config = ConfigDict(
12
+ validate_by_name=False,
13
+ validate_by_alias=True,
14
+ serialize_by_alias=True,
15
+ )
16
+
11
17
  schema_: ModbusSchema = Field(
12
18
  ...,
13
19
  description='Modbus schema',
@@ -1,6 +1,6 @@
1
1
  from typing import Any
2
2
 
3
- from pydantic import BaseModel, Field, field_validator
3
+ from pydantic import BaseModel, ConfigDict, Field, field_serializer, field_validator
4
4
 
5
5
  from .schema import ModbusSchema
6
6
  from .status import ModbusStatus
@@ -9,11 +9,21 @@ from .status import ModbusStatus
9
9
  class ModbusWait(BaseModel):
10
10
  """Modbus parameter model"""
11
11
 
12
+ model_config = ConfigDict(
13
+ validate_by_name=False,
14
+ validate_by_alias=True,
15
+ serialize_by_alias=True,
16
+ )
17
+
12
18
  status: ModbusStatus = Field(
13
19
  ...,
14
20
  description='Status of the Modbus command',
15
21
  )
16
22
 
23
+ @field_serializer('status', when_used='always')
24
+ def serialize_status(self, status: ModbusStatus) -> str:
25
+ return status.value
26
+
17
27
  structure: ModbusSchema = Field(
18
28
  ...,
19
29
  description='Modbus structure schema',
@@ -1,5 +1,3 @@
1
- """Twilio Notification Type Enum"""
2
-
3
1
  from enum import StrEnum
4
2
  from typing import Self
5
3
 
@@ -1,9 +1,7 @@
1
- """Operation entity"""
2
-
3
- from datetime import time, timedelta
1
+ from datetime import timedelta
4
2
  from typing import Any, Self
5
3
 
6
- from pydantic import BaseModel, Field, field_validator
4
+ from pydantic import BaseModel, ConfigDict, Field, field_serializer, field_validator
7
5
 
8
6
  from .destination_phone import DestinationPhone
9
7
  from .notification_type import TwilioNotificationType
@@ -17,18 +15,16 @@ from .timezone import Timezone
17
15
  class Operation(BaseModel):
18
16
  """Operation entity"""
19
17
 
20
- model_config = {
21
- 'json_encoders': {
22
- timedelta: lambda v: v.total_seconds(),
23
- OperationType: lambda v: v.value,
24
- HttpRequestType: lambda v: v.value,
25
- TwilioNotificationType: lambda v: v.value,
26
- SoundEffect: lambda v: v.value,
27
- Platform: lambda v: v.value,
28
- },
29
- }
30
-
31
- pk: int = Field(description='Defines the primary key of the trigger', alias='id')
18
+ model_config = ConfigDict(
19
+ validate_by_name=False,
20
+ validate_by_alias=True,
21
+ serialize_by_alias=True,
22
+ )
23
+
24
+ pk: int = Field(
25
+ description='Defines the primary key of the trigger',
26
+ alias='id',
27
+ )
32
28
  name: str = Field(description='Defines the name of the trigger')
33
29
 
34
30
  cooldown_time: timedelta = Field(
@@ -36,11 +32,19 @@ class Operation(BaseModel):
36
32
  description='Defines the cooldown time of the trigger',
37
33
  )
38
34
 
35
+ @field_serializer('cooldown_time', when_used='always')
36
+ def serialize_cooldown_time(self, value: timedelta) -> float:
37
+ return value.total_seconds()
38
+
39
39
  operation_type: OperationType = Field(
40
40
  ...,
41
41
  description='Defines the kind of the operation',
42
42
  )
43
43
 
44
+ @field_serializer('operation_type', when_used='always')
45
+ def serialize_operation_type(self, value: OperationType) -> str:
46
+ return value.value
47
+
44
48
  @property
45
49
  def kind(self: Self) -> OperationType:
46
50
  """Get the kind of the operation"""
@@ -51,6 +55,10 @@ class Operation(BaseModel):
51
55
  description='Defines the HTTP method of the operation',
52
56
  )
53
57
 
58
+ @field_serializer('request_type', when_used='always')
59
+ def serialize_request_type(self, value: HttpRequestType | None) -> str | None:
60
+ return value.value if value else None
61
+
54
62
  @property
55
63
  def http_method(self: Self) -> HttpRequestType | None:
56
64
  """Get the HTTP method of the operation"""
@@ -125,6 +133,11 @@ class Operation(BaseModel):
125
133
  description='Defines the Twilio notification type of the operation',
126
134
  )
127
135
 
136
+ @field_serializer('notification_type', when_used='always')
137
+ def serialize_notification_type(self, value: TwilioNotificationType) -> str:
138
+ """Serialize notification_type to its value."""
139
+ return value.value
140
+
128
141
  @property
129
142
  def twilio_notification_type(self: Self) -> TwilioNotificationType:
130
143
  """Get the Twilio notification type of the operation"""
@@ -201,6 +214,10 @@ class Operation(BaseModel):
201
214
  description='Defines the sound effect for the operation',
202
215
  )
203
216
 
217
+ @field_serializer('sound_effect', when_used='always')
218
+ def serialize_sound_effect(self, value: SoundEffect) -> str:
219
+ return value.value
220
+
204
221
  sound_effect_uri: str | None = Field(
205
222
  default=None,
206
223
  description='Defines the URI for the sound effect of the operation. Only when sound_effect is set to CUSTOM.',
@@ -211,6 +228,10 @@ class Operation(BaseModel):
211
228
  description='Defines the duration of the operation',
212
229
  )
213
230
 
231
+ @field_serializer('duration', when_used='always')
232
+ def serialize_duration(self, value: timedelta | None) -> float | None:
233
+ return value.total_seconds() if value else None
234
+
214
235
  @field_validator('duration', mode='before')
215
236
  def validate_duration(cls, value: Any) -> timedelta:
216
237
  if value is None:
@@ -1,9 +1,7 @@
1
- """Operation case payload entity"""
2
-
3
1
  from datetime import datetime, timedelta
4
2
  from typing import Any
5
3
 
6
- from pydantic import BaseModel, Field, field_validator
4
+ from pydantic import BaseModel, ConfigDict, Field, field_serializer, field_validator
7
5
 
8
6
  from layrz_sdk.constants import UTC
9
7
  from layrz_sdk.entities.trigger import Trigger
@@ -12,7 +10,17 @@ from layrz_sdk.entities.trigger import Trigger
12
10
  class OperationCaseCommentPayload(BaseModel):
13
11
  """Operation case comment payload entity"""
14
12
 
15
- pk: int = Field(..., description='Defines the primary key of the operation case comment', alias='id')
13
+ model_config = ConfigDict(
14
+ validate_by_name=False,
15
+ validate_by_alias=True,
16
+ serialize_by_alias=True,
17
+ )
18
+
19
+ pk: int = Field(
20
+ ...,
21
+ description='Defines the primary key of the operation case comment',
22
+ alias='id',
23
+ )
16
24
  user: str = Field(..., description='Defines the user who created the operation case comment')
17
25
  content: str = Field(..., description='Defines the content of the operation case comment')
18
26
  created_at: datetime = Field(
@@ -20,28 +28,42 @@ class OperationCaseCommentPayload(BaseModel):
20
28
  description='Defines the creation date of the operation case comment',
21
29
  )
22
30
 
31
+ @field_serializer('created_at', when_used='always')
32
+ def serialize_created_at(self, created_at: datetime) -> float:
33
+ return created_at.timestamp()
34
+
23
35
 
24
36
  class OperationCasePayload(BaseModel):
25
37
  """Operation case payload entity"""
26
38
 
27
- model_config = {
28
- 'json_encoders': {
29
- timedelta: lambda v: v.total_seconds(),
30
- datetime: lambda v: v.timestamp(),
31
- Trigger: lambda v: v.model_dump(by_alias=True, exclude_none=True),
32
- },
33
- }
39
+ model_config = ConfigDict(
40
+ validate_by_name=False,
41
+ validate_by_alias=True,
42
+ serialize_by_alias=True,
43
+ )
34
44
 
35
- pk: int = Field(description='Defines the primary key of the operation case payload', alias='id')
45
+ pk: int = Field(
46
+ description='Defines the primary key of the operation case payload',
47
+ alias='id',
48
+ )
36
49
  created_at: datetime = Field(
37
50
  default_factory=lambda: datetime.now(UTC),
38
51
  description='Defines the creation date of the operation case payload',
39
52
  )
53
+
54
+ @field_serializer('created_at', when_used='always')
55
+ def serialize_created_at(self, created_at: datetime) -> float:
56
+ return created_at.timestamp()
57
+
40
58
  updated_at: datetime = Field(
41
59
  default_factory=lambda: datetime.now(UTC),
42
60
  description='Defines the last update date of the operation case payload',
43
61
  )
44
62
 
63
+ @field_serializer('updated_at', when_used='always')
64
+ def serialize_updated_at(self, updated_at: datetime) -> float:
65
+ return updated_at.timestamp()
66
+
45
67
  trigger: Trigger = Field(
46
68
  ...,
47
69
  description='Defines the trigger associated with the operation case payload',
@@ -52,7 +74,7 @@ class OperationCasePayload(BaseModel):
52
74
  """Serialize trigger to a dictionary"""
53
75
  if isinstance(value, Trigger):
54
76
  return Trigger(
55
- id=value.pk,
77
+ id=value.pk, # ty: ignore
56
78
  name=value.name,
57
79
  code=value.code,
58
80
  )
@@ -71,6 +93,10 @@ class OperationCasePayload(BaseModel):
71
93
  description='Defines the creation date of the file associated with the operation case payload',
72
94
  )
73
95
 
96
+ @field_serializer('file_created_at', when_used='always')
97
+ def serialize_file_created_at(self, file_created_at: datetime | None) -> float | None:
98
+ return file_created_at.timestamp() if file_created_at else None
99
+
74
100
  comment: OperationCaseCommentPayload | None = Field(
75
101
  default=None,
76
102
  description='Defines the comment associated with the operation case payload',