layrz-sdk 3.1.3__py3-none-any.whl → 3.1.5__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.

Potentially problematic release.


This version of layrz-sdk might be problematic. Click here for more details.

Files changed (75) hide show
  1. layrz_sdk/__init__.py +1 -1
  2. layrz_sdk/constants.py +5 -5
  3. layrz_sdk/entities/__init__.py +129 -129
  4. layrz_sdk/entities/asset.py +70 -69
  5. layrz_sdk/entities/asset_operation_mode.py +31 -31
  6. layrz_sdk/entities/broadcast_request.py +12 -12
  7. layrz_sdk/entities/broadcast_response.py +12 -12
  8. layrz_sdk/entities/broadcast_result.py +20 -20
  9. layrz_sdk/entities/broadcast_status.py +28 -28
  10. layrz_sdk/entities/case.py +47 -47
  11. layrz_sdk/entities/case_ignored_status.py +26 -26
  12. layrz_sdk/entities/case_status.py +23 -23
  13. layrz_sdk/entities/charts/axis_config.py +15 -15
  14. layrz_sdk/entities/charts/bar_chart.py +171 -171
  15. layrz_sdk/entities/charts/chart_alignment.py +27 -27
  16. layrz_sdk/entities/charts/chart_color.py +44 -44
  17. layrz_sdk/entities/charts/chart_configuration.py +10 -10
  18. layrz_sdk/entities/charts/chart_data_serie.py +19 -19
  19. layrz_sdk/entities/charts/chart_data_serie_type.py +28 -28
  20. layrz_sdk/entities/charts/chart_data_type.py +27 -27
  21. layrz_sdk/entities/charts/chart_render_technology.py +30 -30
  22. layrz_sdk/entities/charts/column_chart.py +197 -197
  23. layrz_sdk/entities/charts/html_chart.py +34 -34
  24. layrz_sdk/entities/charts/line_chart.py +244 -244
  25. layrz_sdk/entities/charts/map_center_type.py +22 -22
  26. layrz_sdk/entities/charts/map_chart.py +104 -104
  27. layrz_sdk/entities/charts/map_point.py +22 -22
  28. layrz_sdk/entities/charts/number_chart.py +50 -50
  29. layrz_sdk/entities/charts/pie_chart.py +127 -127
  30. layrz_sdk/entities/charts/radar_chart.py +77 -77
  31. layrz_sdk/entities/charts/radial_bar_chart.py +127 -127
  32. layrz_sdk/entities/charts/scatter_chart.py +206 -206
  33. layrz_sdk/entities/charts/scatter_serie.py +15 -15
  34. layrz_sdk/entities/charts/scatter_serie_item.py +8 -8
  35. layrz_sdk/entities/charts/table_chart.py +50 -50
  36. layrz_sdk/entities/charts/table_header.py +8 -8
  37. layrz_sdk/entities/charts/table_row.py +9 -9
  38. layrz_sdk/entities/charts/timeline_chart.py +75 -75
  39. layrz_sdk/entities/charts/timeline_serie.py +12 -12
  40. layrz_sdk/entities/charts/timeline_serie_item.py +12 -12
  41. layrz_sdk/entities/checkpoint.py +18 -18
  42. layrz_sdk/entities/comment.py +16 -16
  43. layrz_sdk/entities/custom_field.py +10 -10
  44. layrz_sdk/entities/custom_report_page.py +16 -16
  45. layrz_sdk/entities/device.py +13 -13
  46. layrz_sdk/entities/event.py +23 -23
  47. layrz_sdk/entities/geofence.py +11 -11
  48. layrz_sdk/entities/last_message.py +12 -12
  49. layrz_sdk/entities/message.py +23 -23
  50. layrz_sdk/entities/outbound_service.py +10 -10
  51. layrz_sdk/entities/position.py +101 -101
  52. layrz_sdk/entities/presence_type.py +16 -16
  53. layrz_sdk/entities/report.py +257 -257
  54. layrz_sdk/entities/report_col.py +40 -40
  55. layrz_sdk/entities/report_configuration.py +8 -8
  56. layrz_sdk/entities/report_data_type.py +28 -28
  57. layrz_sdk/entities/report_format.py +27 -27
  58. layrz_sdk/entities/report_header.py +43 -43
  59. layrz_sdk/entities/report_page.py +17 -17
  60. layrz_sdk/entities/report_row.py +28 -28
  61. layrz_sdk/entities/sensor.py +11 -11
  62. layrz_sdk/entities/text_alignment.py +26 -26
  63. layrz_sdk/entities/trigger.py +11 -11
  64. layrz_sdk/entities/user.py +10 -10
  65. layrz_sdk/entities/waypoint.py +18 -18
  66. layrz_sdk/helpers/__init__.py +8 -8
  67. layrz_sdk/helpers/color.py +41 -41
  68. layrz_sdk/lcl/__init__.py +7 -7
  69. layrz_sdk/lcl/core.py +832 -832
  70. {layrz_sdk-3.1.3.dist-info → layrz_sdk-3.1.5.dist-info}/LICENSE +6 -6
  71. {layrz_sdk-3.1.3.dist-info → layrz_sdk-3.1.5.dist-info}/METADATA +48 -48
  72. layrz_sdk-3.1.5.dist-info/RECORD +75 -0
  73. layrz_sdk-3.1.3.dist-info/RECORD +0 -75
  74. {layrz_sdk-3.1.3.dist-info → layrz_sdk-3.1.5.dist-info}/WHEEL +0 -0
  75. {layrz_sdk-3.1.3.dist-info → layrz_sdk-3.1.5.dist-info}/top_level.txt +0 -0
@@ -1,257 +1,257 @@
1
- """Report class"""
2
-
3
- import logging
4
- import os
5
- import time
6
- import warnings
7
- from typing import Any, Dict, List, Optional
8
-
9
- import xlsxwriter
10
- from pydantic import BaseModel, Field, field_validator
11
-
12
- from layrz_sdk.helpers.color import use_black
13
-
14
- from .custom_report_page import CustomReportPage
15
- from .report_data_type import ReportDataType
16
- from .report_format import ReportFormat
17
- from .report_page import ReportPage
18
-
19
- log = logging.getLogger(__name__)
20
-
21
-
22
- class Report(BaseModel):
23
- """Report definition"""
24
-
25
- name: str = Field(description='Name of the report. Length should be less than 60 characters')
26
- pages: List[ReportPage | CustomReportPage] = Field(
27
- description='List of report pages',
28
- default_factory=list,
29
- )
30
- export_format: Optional[ReportFormat] = Field(description='Export format of the report', default=None)
31
-
32
- @field_validator('export_format', mode='before')
33
- def _validate_export_format(cls, value: Any) -> Any:
34
- if value is not None:
35
- warnings.warn(
36
- 'export_format is deprecated, use the export method instead',
37
- DeprecationWarning,
38
- stacklevel=2,
39
- )
40
-
41
- return value
42
-
43
- @property
44
- def filename(self) -> str:
45
- """Report filename"""
46
- return f'{self.name}_{int(time.time() * 1000)}.xlsx'
47
-
48
- def export(
49
- self,
50
- path: str,
51
- export_format: Optional[ReportFormat] = None,
52
- password: Optional[str] = None,
53
- msoffice_crypt_path: str = '/opt/msoffice/bin/msoffice-crypt.exe',
54
- ) -> str | Dict[str, Any]:
55
- """
56
- Export report to file
57
-
58
- :param path: Path to save the report
59
- :param export_format: Format to export the report
60
- :param password: Password to protect the file (Only works with Microsoft Excel format)
61
- :param msoffice_crypt_path: Path to the msoffice-crypt.exe executable, used to encrypt the file
62
- :return: Full path of the exported file or JSON representation of the report
63
- :rtype: str | dict
64
- :raises AttributeError: If the export format is not supported
65
- """
66
- if export_format:
67
- if export_format == ReportFormat.MICROSOFT_EXCEL:
68
- return self._export_xlsx(path=path, password=password, msoffice_crypt_path=msoffice_crypt_path)
69
- elif export_format == ReportFormat.JSON:
70
- if password:
71
- return {'name': self.name, 'is_protected': True, 'pages': []}
72
- return self._export_json()
73
- else:
74
- raise AttributeError(f'Unsupported export format: {export_format}')
75
-
76
- if self.export_format == ReportFormat.MICROSOFT_EXCEL:
77
- return self._export_xlsx(path=path, password=password, msoffice_crypt_path=msoffice_crypt_path)
78
- elif self.export_format == ReportFormat.JSON:
79
- if password:
80
- return {'name': self.name, 'is_protected': True, 'pages': []}
81
- return self._export_json()
82
- else:
83
- raise AttributeError(f'Unsupported export format: {self.export_format}')
84
-
85
- def export_as_json(self) -> Dict[str, Any]:
86
- """Returns the report as a JSON dict"""
87
- return self._export_json()
88
-
89
- def _export_json(self) -> Dict[str, Any]:
90
- """Returns a JSON dict of the report"""
91
- json_pages = []
92
- for page in self.pages:
93
- if isinstance(page, CustomReportPage):
94
- continue
95
-
96
- headers = []
97
- for header in page.headers:
98
- headers.append(
99
- {
100
- 'content': header.content,
101
- 'text_color': '#000000' if use_black(header.color) else '#ffffff',
102
- 'color': header.color,
103
- }
104
- )
105
- rows = []
106
- for row in page.rows:
107
- cells = []
108
- for cell in row.content:
109
- cells.append(
110
- {
111
- 'content': cell.content,
112
- 'text_color': '#000000' if use_black(cell.color) else '#ffffff',
113
- 'color': cell.color,
114
- 'data_type': cell.data_type.value,
115
- }
116
- )
117
- rows.append(
118
- {
119
- 'content': cells,
120
- 'compact': row.compact,
121
- }
122
- )
123
- json_pages.append(
124
- {
125
- 'name': page.name,
126
- 'headers': headers,
127
- 'rows': rows,
128
- }
129
- )
130
-
131
- return {
132
- 'name': self.name,
133
- 'pages': json_pages,
134
- }
135
-
136
- def _export_xlsx(
137
- self,
138
- path: str,
139
- password: Optional[str] = None,
140
- msoffice_crypt_path: Optional[str] = None,
141
- ) -> str:
142
- """
143
- Export to Microsoft Excel (.xslx)
144
- :param path: Path to save the report
145
- :param password: Password to protect the file
146
- :param msoffice_crypt_path: Path to the msoffice-crypt.exe executable, used to encrypt the file
147
- :return: Full path of the exported file
148
- """
149
-
150
- full_path = os.path.join(path, self.filename)
151
- book = xlsxwriter.Workbook(full_path)
152
-
153
- pages_name: List[str] = []
154
-
155
- for page in self.pages:
156
- sheet_name = page.name[0:20]
157
-
158
- if sheet_name in pages_name:
159
- sheet_name = f'{sheet_name} ({pages_name.count(sheet_name) + 1})'
160
-
161
- # Allow only numbers, letters, spaces and _ or - characters
162
- # Other characters will be removed
163
- sheet_name = ''.join(e for e in sheet_name if e.isalnum() or e in [' ', '_', '-'])
164
- sheet = book.add_worksheet(sheet_name)
165
-
166
- if isinstance(page, CustomReportPage):
167
- page.builder(sheet)
168
- sheet.autofit()
169
- continue
170
-
171
- if page.freeze_header:
172
- sheet.freeze_panes(1, 0)
173
-
174
- for i, header in enumerate(page.headers):
175
- style = book.add_format(
176
- {
177
- 'align': header.align.value,
178
- 'font_color': '#000000' if use_black(header.color) else '#ffffff',
179
- 'bg_color': header.color,
180
- 'bold': header.bold,
181
- 'valign': 'vcenter',
182
- 'font_size': 11,
183
- 'top': 1,
184
- 'left': 1,
185
- 'right': 1,
186
- 'bottom': 1,
187
- 'font_name': 'Aptos Narrow',
188
- }
189
- )
190
- sheet.write(0, i, header.content, style)
191
-
192
- for i, row in enumerate(page.rows):
193
- for j, cell in enumerate(row.content):
194
- style = {
195
- 'align': cell.align.value,
196
- 'font_color': '#000000' if use_black(cell.color) else '#ffffff',
197
- 'bg_color': cell.color,
198
- 'bold': cell.bold,
199
- 'valign': 'vcenter',
200
- 'font_size': 11,
201
- 'top': 1,
202
- 'left': 1,
203
- 'right': 1,
204
- 'bottom': 1,
205
- 'font_name': 'Aptos Narrow',
206
- }
207
-
208
- value: Any = None
209
-
210
- if cell.data_type == ReportDataType.BOOL:
211
- value = 'Yes' if cell.content else 'No'
212
- elif cell.data_type == ReportDataType.DATETIME:
213
- value = cell.content.strftime(cell.datetime_format)
214
- elif cell.data_type == ReportDataType.INT:
215
- try:
216
- value = int(cell.content)
217
- except ValueError:
218
- value = cell.content
219
- log.warning(f'Invalid int value: {cell.content} in cell {i + 1}, {j}')
220
- elif cell.data_type == ReportDataType.FLOAT:
221
- try:
222
- value = float(cell.content)
223
- style.update({'num_format': '0.00'})
224
- except ValueError:
225
- value = cell.content
226
- log.warning(f'Invalid float value: {cell.content} in cell {i + 1}, {j}')
227
- elif cell.data_type == ReportDataType.CURRENCY:
228
- value = float(cell.content)
229
- style.update(
230
- {'num_format': f'"{cell.currency_symbol}" * #,##0.00;[Red]"{cell.currency_symbol}" * #,##0.00'}
231
- )
232
- else:
233
- value = cell.content
234
-
235
- sheet.write(i + 1, j, value, book.add_format(style))
236
-
237
- if row.compact:
238
- sheet.set_row(i + 1, None, None, {'level': 1, 'hidden': True})
239
- else:
240
- sheet.set_row(i + 1, None, None, {'collapsed': True})
241
-
242
- sheet.autofit()
243
- book.close()
244
-
245
- if password and msoffice_crypt_path:
246
- new_path = os.path.join(path, f'encrypted_{self.filename}')
247
- log.debug(f'Executing `{msoffice_crypt_path} -e -p "{password}" "{full_path}" "{new_path}"`')
248
- os.system(f'{msoffice_crypt_path} -e -p "{password}" "{full_path}" "{new_path}"')
249
- os.remove(full_path)
250
-
251
- with open(new_path, 'rb') as f:
252
- with open(full_path, 'wb') as f2:
253
- f2.write(f.read())
254
-
255
- os.remove(new_path)
256
-
257
- return full_path
1
+ """Report class"""
2
+
3
+ import logging
4
+ import os
5
+ import time
6
+ import warnings
7
+ from typing import Any, Dict, List, Optional
8
+
9
+ import xlsxwriter
10
+ from pydantic import BaseModel, Field, field_validator
11
+
12
+ from layrz_sdk.helpers.color import use_black
13
+
14
+ from .custom_report_page import CustomReportPage
15
+ from .report_data_type import ReportDataType
16
+ from .report_format import ReportFormat
17
+ from .report_page import ReportPage
18
+
19
+ log = logging.getLogger(__name__)
20
+
21
+
22
+ class Report(BaseModel):
23
+ """Report definition"""
24
+
25
+ name: str = Field(description='Name of the report. Length should be less than 60 characters')
26
+ pages: List[ReportPage | CustomReportPage] = Field(
27
+ description='List of report pages',
28
+ default_factory=list,
29
+ )
30
+ export_format: Optional[ReportFormat] = Field(description='Export format of the report', default=None)
31
+
32
+ @field_validator('export_format', mode='before')
33
+ def _validate_export_format(cls, value: Any) -> Any:
34
+ if value is not None:
35
+ warnings.warn(
36
+ 'export_format is deprecated, use the export method instead',
37
+ DeprecationWarning,
38
+ stacklevel=2,
39
+ )
40
+
41
+ return value
42
+
43
+ @property
44
+ def filename(self) -> str:
45
+ """Report filename"""
46
+ return f'{self.name}_{int(time.time() * 1000)}.xlsx'
47
+
48
+ def export(
49
+ self,
50
+ path: str,
51
+ export_format: Optional[ReportFormat] = None,
52
+ password: Optional[str] = None,
53
+ msoffice_crypt_path: str = '/opt/msoffice/bin/msoffice-crypt.exe',
54
+ ) -> str | Dict[str, Any]:
55
+ """
56
+ Export report to file
57
+
58
+ :param path: Path to save the report
59
+ :param export_format: Format to export the report
60
+ :param password: Password to protect the file (Only works with Microsoft Excel format)
61
+ :param msoffice_crypt_path: Path to the msoffice-crypt.exe executable, used to encrypt the file
62
+ :return: Full path of the exported file or JSON representation of the report
63
+ :rtype: str | dict
64
+ :raises AttributeError: If the export format is not supported
65
+ """
66
+ if export_format:
67
+ if export_format == ReportFormat.MICROSOFT_EXCEL:
68
+ return self._export_xlsx(path=path, password=password, msoffice_crypt_path=msoffice_crypt_path)
69
+ elif export_format == ReportFormat.JSON:
70
+ if password:
71
+ return {'name': self.name, 'is_protected': True, 'pages': []}
72
+ return self._export_json()
73
+ else:
74
+ raise AttributeError(f'Unsupported export format: {export_format}')
75
+
76
+ if self.export_format == ReportFormat.MICROSOFT_EXCEL:
77
+ return self._export_xlsx(path=path, password=password, msoffice_crypt_path=msoffice_crypt_path)
78
+ elif self.export_format == ReportFormat.JSON:
79
+ if password:
80
+ return {'name': self.name, 'is_protected': True, 'pages': []}
81
+ return self._export_json()
82
+ else:
83
+ raise AttributeError(f'Unsupported export format: {self.export_format}')
84
+
85
+ def export_as_json(self) -> Dict[str, Any]:
86
+ """Returns the report as a JSON dict"""
87
+ return self._export_json()
88
+
89
+ def _export_json(self) -> Dict[str, Any]:
90
+ """Returns a JSON dict of the report"""
91
+ json_pages = []
92
+ for page in self.pages:
93
+ if isinstance(page, CustomReportPage):
94
+ continue
95
+
96
+ headers = []
97
+ for header in page.headers:
98
+ headers.append(
99
+ {
100
+ 'content': header.content,
101
+ 'text_color': '#000000' if use_black(header.color) else '#ffffff',
102
+ 'color': header.color,
103
+ }
104
+ )
105
+ rows = []
106
+ for row in page.rows:
107
+ cells = []
108
+ for cell in row.content:
109
+ cells.append(
110
+ {
111
+ 'content': cell.content,
112
+ 'text_color': '#000000' if use_black(cell.color) else '#ffffff',
113
+ 'color': cell.color,
114
+ 'data_type': cell.data_type.value,
115
+ }
116
+ )
117
+ rows.append(
118
+ {
119
+ 'content': cells,
120
+ 'compact': row.compact,
121
+ }
122
+ )
123
+ json_pages.append(
124
+ {
125
+ 'name': page.name,
126
+ 'headers': headers,
127
+ 'rows': rows,
128
+ }
129
+ )
130
+
131
+ return {
132
+ 'name': self.name,
133
+ 'pages': json_pages,
134
+ }
135
+
136
+ def _export_xlsx(
137
+ self,
138
+ path: str,
139
+ password: Optional[str] = None,
140
+ msoffice_crypt_path: Optional[str] = None,
141
+ ) -> str:
142
+ """
143
+ Export to Microsoft Excel (.xslx)
144
+ :param path: Path to save the report
145
+ :param password: Password to protect the file
146
+ :param msoffice_crypt_path: Path to the msoffice-crypt.exe executable, used to encrypt the file
147
+ :return: Full path of the exported file
148
+ """
149
+
150
+ full_path = os.path.join(path, self.filename)
151
+ book = xlsxwriter.Workbook(full_path)
152
+
153
+ pages_name: List[str] = []
154
+
155
+ for page in self.pages:
156
+ sheet_name = page.name[0:20]
157
+
158
+ if sheet_name in pages_name:
159
+ sheet_name = f'{sheet_name} ({pages_name.count(sheet_name) + 1})'
160
+
161
+ # Allow only numbers, letters, spaces and _ or - characters
162
+ # Other characters will be removed
163
+ sheet_name = ''.join(e for e in sheet_name if e.isalnum() or e in [' ', '_', '-'])
164
+ sheet = book.add_worksheet(sheet_name)
165
+
166
+ if isinstance(page, CustomReportPage):
167
+ page.builder(sheet)
168
+ sheet.autofit()
169
+ continue
170
+
171
+ if page.freeze_header:
172
+ sheet.freeze_panes(1, 0)
173
+
174
+ for i, header in enumerate(page.headers):
175
+ style = book.add_format(
176
+ {
177
+ 'align': header.align.value,
178
+ 'font_color': '#000000' if use_black(header.color) else '#ffffff',
179
+ 'bg_color': header.color,
180
+ 'bold': header.bold,
181
+ 'valign': 'vcenter',
182
+ 'font_size': 11,
183
+ 'top': 1,
184
+ 'left': 1,
185
+ 'right': 1,
186
+ 'bottom': 1,
187
+ 'font_name': 'Aptos Narrow',
188
+ }
189
+ )
190
+ sheet.write(0, i, header.content, style)
191
+
192
+ for i, row in enumerate(page.rows):
193
+ for j, cell in enumerate(row.content):
194
+ style = {
195
+ 'align': cell.align.value,
196
+ 'font_color': '#000000' if use_black(cell.color) else '#ffffff',
197
+ 'bg_color': cell.color,
198
+ 'bold': cell.bold,
199
+ 'valign': 'vcenter',
200
+ 'font_size': 11,
201
+ 'top': 1,
202
+ 'left': 1,
203
+ 'right': 1,
204
+ 'bottom': 1,
205
+ 'font_name': 'Aptos Narrow',
206
+ }
207
+
208
+ value: Any = None
209
+
210
+ if cell.data_type == ReportDataType.BOOL:
211
+ value = 'Yes' if cell.content else 'No'
212
+ elif cell.data_type == ReportDataType.DATETIME:
213
+ value = cell.content.strftime(cell.datetime_format)
214
+ elif cell.data_type == ReportDataType.INT:
215
+ try:
216
+ value = int(cell.content)
217
+ except ValueError:
218
+ value = cell.content
219
+ log.warning(f'Invalid int value: {cell.content} in cell {i + 1}, {j}')
220
+ elif cell.data_type == ReportDataType.FLOAT:
221
+ try:
222
+ value = float(cell.content)
223
+ style.update({'num_format': '0.00'})
224
+ except ValueError:
225
+ value = cell.content
226
+ log.warning(f'Invalid float value: {cell.content} in cell {i + 1}, {j}')
227
+ elif cell.data_type == ReportDataType.CURRENCY:
228
+ value = float(cell.content)
229
+ style.update(
230
+ {'num_format': f'"{cell.currency_symbol}" * #,##0.00;[Red]"{cell.currency_symbol}" * #,##0.00'}
231
+ )
232
+ else:
233
+ value = cell.content
234
+
235
+ sheet.write(i + 1, j, value, book.add_format(style))
236
+
237
+ if row.compact:
238
+ sheet.set_row(i + 1, None, None, {'level': 1, 'hidden': True})
239
+ else:
240
+ sheet.set_row(i + 1, None, None, {'collapsed': True})
241
+
242
+ sheet.autofit()
243
+ book.close()
244
+
245
+ if password and msoffice_crypt_path:
246
+ new_path = os.path.join(path, f'encrypted_{self.filename}')
247
+ log.debug(f'Executing `{msoffice_crypt_path} -e -p "{password}" "{full_path}" "{new_path}"`')
248
+ os.system(f'{msoffice_crypt_path} -e -p "{password}" "{full_path}" "{new_path}"')
249
+ os.remove(full_path)
250
+
251
+ with open(new_path, 'rb') as f:
252
+ with open(full_path, 'wb') as f2:
253
+ f2.write(f.read())
254
+
255
+ os.remove(new_path)
256
+
257
+ return full_path
@@ -1,40 +1,40 @@
1
- """Report col"""
2
-
3
- import sys
4
- import warnings
5
- from typing import Any, Optional
6
-
7
- from pydantic import BaseModel, Field, field_validator
8
-
9
- from .report_data_type import ReportDataType
10
- from .text_alignment import TextAlignment
11
-
12
- if sys.version_info >= (3, 11):
13
- from typing import Self
14
- else:
15
- from typing_extensions import Self
16
-
17
-
18
- class ReportCol(BaseModel):
19
- """Report column entity"""
20
-
21
- content: Any = Field(description='Column content')
22
- color: str = Field(description='Column color', default='#ffffff')
23
- text_color: Optional[str] = Field(description='Column text color', default=None)
24
- align: TextAlignment = Field(description='Column text alignment', default=TextAlignment.LEFT)
25
- data_type: ReportDataType = Field(description='Column data type', default=ReportDataType.STR)
26
- datetime_format: str = Field(description='Datetime format', default='%Y-%m-%d %H:%M:%S')
27
- currency_symbol: str = Field(description='Currency symbol', default='')
28
- bold: bool = Field(description='Bold text', default=False)
29
-
30
- @field_validator('text_color', mode='before')
31
- def _validate_text_color(cls: Self, value: Any) -> Any:
32
- """Validate text color"""
33
- if value is not None:
34
- warnings.warn(
35
- 'text_color is deprecated, the algorithm will calculate the rigth text color instead',
36
- DeprecationWarning,
37
- stacklevel=2,
38
- )
39
-
40
- return value
1
+ """Report col"""
2
+
3
+ import sys
4
+ import warnings
5
+ from typing import Any, Optional
6
+
7
+ from pydantic import BaseModel, Field, field_validator
8
+
9
+ from .report_data_type import ReportDataType
10
+ from .text_alignment import TextAlignment
11
+
12
+ if sys.version_info >= (3, 11):
13
+ from typing import Self
14
+ else:
15
+ from typing_extensions import Self
16
+
17
+
18
+ class ReportCol(BaseModel):
19
+ """Report column entity"""
20
+
21
+ content: Any = Field(description='Column content')
22
+ color: str = Field(description='Column color', default='#ffffff')
23
+ text_color: Optional[str] = Field(description='Column text color', default=None)
24
+ align: TextAlignment = Field(description='Column text alignment', default=TextAlignment.LEFT)
25
+ data_type: ReportDataType = Field(description='Column data type', default=ReportDataType.STR)
26
+ datetime_format: str = Field(description='Datetime format', default='%Y-%m-%d %H:%M:%S')
27
+ currency_symbol: str = Field(description='Currency symbol', default='')
28
+ bold: bool = Field(description='Bold text', default=False)
29
+
30
+ @field_validator('text_color', mode='before')
31
+ def _validate_text_color(cls: Self, value: Any) -> Any:
32
+ """Validate text color"""
33
+ if value is not None:
34
+ warnings.warn(
35
+ 'text_color is deprecated, the algorithm will calculate the rigth text color instead',
36
+ DeprecationWarning,
37
+ stacklevel=2,
38
+ )
39
+
40
+ return value
@@ -1,8 +1,8 @@
1
- from pydantic import BaseModel, Field
2
-
3
-
4
- class ReportConfiguration(BaseModel):
5
- """Report configuration entity"""
6
-
7
- title: str = Field(description='Report title')
8
- pages_count: int = Field(description='Number of pages in the report')
1
+ from pydantic import BaseModel, Field
2
+
3
+
4
+ class ReportConfiguration(BaseModel):
5
+ """Report configuration entity"""
6
+
7
+ title: str = Field(description='Report title')
8
+ pages_count: int = Field(description='Number of pages in the report')
@@ -1,28 +1,28 @@
1
- import sys
2
- from enum import Enum
3
-
4
- if sys.version_info >= (3, 11):
5
- from typing import Self
6
- else:
7
- from typing_extensions import Self
8
-
9
-
10
- class ReportDataType(Enum):
11
- """
12
- Report date type
13
- """
14
-
15
- STR = 'str'
16
- INT = 'int'
17
- FLOAT = 'float'
18
- DATETIME = 'datetime'
19
- BOOL = 'bool'
20
- CURRENCY = 'currency'
21
-
22
- def __str__(self: Self) -> str:
23
- """Readable property"""
24
- return self.name
25
-
26
- def __repr__(self: Self) -> str:
27
- """Readable property"""
28
- return f'ReportDataType.{self.value}'
1
+ import sys
2
+ from enum import Enum
3
+
4
+ if sys.version_info >= (3, 11):
5
+ from typing import Self
6
+ else:
7
+ from typing_extensions import Self
8
+
9
+
10
+ class ReportDataType(Enum):
11
+ """
12
+ Report date type
13
+ """
14
+
15
+ STR = 'str'
16
+ INT = 'int'
17
+ FLOAT = 'float'
18
+ DATETIME = 'datetime'
19
+ BOOL = 'bool'
20
+ CURRENCY = 'currency'
21
+
22
+ def __str__(self: Self) -> str:
23
+ """Readable property"""
24
+ return self.name
25
+
26
+ def __repr__(self: Self) -> str:
27
+ """Readable property"""
28
+ return f'ReportDataType.{self.value}'