educommon 3.12.0__py3-none-any.whl → 3.13.2__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.
- educommon/__init__.py +0 -1
- educommon/about/ui/actions.py +16 -30
- educommon/about/ui/ui.py +3 -12
- educommon/about/utils.py +6 -5
- educommon/async_task/__init__.py +0 -1
- educommon/async_task/actions.py +18 -13
- educommon/async_task/apps.py +4 -0
- educommon/async_task/locker.py +2 -5
- educommon/async_task/migrations/0001_initial.py +55 -9
- educommon/async_task/migrations/0002_task_type_and_status_data.py +94 -89
- educommon/async_task/migrations/0003_alter_runningtask_options.py +0 -1
- educommon/async_task/models.py +9 -6
- educommon/async_task/tasks.py +11 -7
- educommon/async_task/ui.py +16 -35
- educommon/async_tasks/__init__.py +0 -1
- educommon/async_tasks/apps.py +4 -0
- educommon/async_tasks/locks.py +11 -21
- educommon/async_tasks/migrations/0001_initial.py +68 -8
- educommon/async_tasks/migrations/0002_load_initial_data.py +0 -1
- educommon/async_tasks/models.py +9 -29
- educommon/async_tasks/tasks.py +25 -54
- educommon/audit_log/__init__.py +1 -0
- educommon/audit_log/actions.py +27 -36
- educommon/audit_log/app_meta.py +7 -4
- educommon/audit_log/apps.py +44 -29
- educommon/audit_log/constants.py +7 -4
- educommon/audit_log/error_log/actions.py +1 -3
- educommon/audit_log/helpers.py +2 -4
- educommon/audit_log/management/commands/reinstall_audit_log.py +11 -7
- educommon/audit_log/migrations/0001_initial.py +91 -16
- educommon/audit_log/migrations/0002_install_audit_log.py +13 -13
- educommon/audit_log/migrations/0003_logproxy.py +1 -3
- educommon/audit_log/migrations/0004_reinstall_audit_log.py +1 -4
- educommon/audit_log/migrations/0005_postgresql_error.py +4 -2
- educommon/audit_log/migrations/0006_auto_20200806_1707.py +3 -4
- educommon/audit_log/migrations/0007_create_selective_tables_function.py +8 -5
- educommon/audit_log/migrations/0008_table_logged.py +0 -1
- educommon/audit_log/migrations/0009_reinstall_audit_log.py +0 -1
- educommon/audit_log/models.py +36 -42
- educommon/audit_log/permissions.py +11 -9
- educommon/audit_log/proxies.py +12 -23
- educommon/audit_log/ui.py +18 -15
- educommon/audit_log/utils/__init__.py +28 -60
- educommon/audit_log/utils/operations.py +16 -2
- educommon/auth/__init__.py +0 -3
- educommon/auth/rbac/__init__.py +2 -4
- educommon/auth/rbac/actions.py +148 -145
- educommon/auth/rbac/app_meta.py +9 -6
- educommon/auth/rbac/backends/base.py +2 -8
- educommon/auth/rbac/backends/caching.py +27 -37
- educommon/auth/rbac/backends/simple.py +1 -4
- educommon/auth/rbac/checker.py +1 -3
- educommon/auth/rbac/management/commands/rbac.py +6 -11
- educommon/auth/rbac/manager.py +18 -47
- educommon/auth/rbac/migrations/0001_initial.py +73 -12
- educommon/auth/rbac/migrations/0002_model_modifier_metaclass_fix.py +7 -6
- educommon/auth/rbac/migrations/0003_permission_hidden.py +1 -5
- educommon/auth/rbac/migrations/0004_auto_20171024_1245.py +26 -19
- educommon/auth/rbac/models.py +63 -68
- educommon/auth/rbac/permissions.py +6 -7
- educommon/auth/rbac/ui.py +83 -84
- educommon/auth/rbac/utils.py +10 -11
- educommon/auth/rbac/validators.py +4 -5
- educommon/auth/simple_auth/__init__.py +1 -5
- educommon/auth/simple_auth/actions.py +79 -92
- educommon/auth/simple_auth/app_meta.py +2 -9
- educommon/auth/simple_auth/checkers.py +3 -3
- educommon/auth/simple_auth/migrations/0001_initial.py +23 -4
- educommon/auth/simple_auth/validators.py +0 -1
- educommon/contingent/actions.py +7 -7
- educommon/contingent/app_meta.py +1 -4
- educommon/contingent/base.py +10 -15
- educommon/contingent/catalogs.py +424 -540
- educommon/contingent/contingent_plugin/actions.py +4 -15
- educommon/contingent/contingent_plugin/apps.py +10 -4
- educommon/contingent/contingent_plugin/migrations/0001_initial.py +5 -6
- educommon/contingent/contingent_plugin/migrations/0002_add_contingent_model_deleted.py +6 -11
- educommon/contingent/contingent_plugin/model_views.py +2 -12
- educommon/contingent/contingent_plugin/models.py +2 -7
- educommon/contingent/contingent_plugin/observer.py +14 -13
- educommon/contingent/contingent_plugin/plugin_meta.py +1 -3
- educommon/contingent/contingent_plugin/storage.py +8 -7
- educommon/contingent/contingent_plugin/utils.py +6 -6
- educommon/django/db/fields.py +72 -86
- educommon/django/db/migration/__init__.py +3 -7
- educommon/django/db/migration/operations.py +29 -51
- educommon/django/db/mixins/__init__.py +16 -10
- educommon/django/db/mixins/date_interval.py +47 -75
- educommon/django/db/mixins/validation.py +26 -26
- educommon/django/db/model_view/__init__.py +18 -22
- educommon/django/db/models.py +9 -8
- educommon/django/db/observer.py +9 -27
- educommon/django/db/partitioning/__init__.py +66 -92
- educommon/django/db/partitioning/management/commands/apply_partitioning.py +3 -13
- educommon/django/db/partitioning/management/commands/clear_table.py +18 -14
- educommon/django/db/partitioning/management/commands/split_table.py +18 -13
- educommon/django/db/routers.py +6 -15
- educommon/django/db/signals.py +149 -2
- educommon/django/db/utils.py +14 -19
- educommon/django/db/validators/__init__.py +1 -0
- educommon/django/db/validators/simple.py +72 -100
- educommon/django/storages/atcfs/api.py +39 -53
- educommon/django/storages/atcfs/app_meta.py +1 -1
- educommon/django/storages/atcfs/management/commands/atcfs_migrate.py +42 -55
- educommon/django/storages/atcfs/models.py +0 -3
- educommon/django/storages/atcfs/monkey_patching.py +18 -12
- educommon/django/storages/atcfs/storage.py +14 -23
- educommon/extjs/fields/input_params.py +15 -45
- educommon/importer/XLSReader.py +143 -241
- educommon/importer/__init__.py +86 -4
- educommon/importer/api.py +53 -84
- educommon/importer/constants.py +4 -14
- educommon/importer/loggers.py +16 -26
- educommon/importer/proxy.py +131 -176
- educommon/importer/proxy_import.py +11 -12
- educommon/importer/report.py +4 -6
- educommon/importer/ui.py +32 -26
- educommon/importer/validators.py +4 -7
- educommon/integration_entities/helpers.py +14 -18
- educommon/ioc/__init__.py +3 -6
- educommon/logger/loggers.py +10 -14
- educommon/m3/__init__.py +20 -38
- educommon/m3/extensions/__init__.py +1 -0
- educommon/m3/extensions/listeners/__init__.py +22 -38
- educommon/m3/extensions/listeners/delete_check/listeners.py +31 -41
- educommon/m3/extensions/listeners/delete_check/mixins.py +20 -25
- educommon/m3/extensions/listeners/delete_check/signals.py +2 -2
- educommon/m3/extensions/listeners/delete_check/ui.py +15 -14
- educommon/m3/extensions/listeners/delete_check/utils.py +9 -11
- educommon/m3/extensions/ui.py +15 -33
- educommon/m3/transaction_context.py +17 -19
- educommon/objectpack/actions.py +70 -88
- educommon/objectpack/apps.py +5 -0
- educommon/objectpack/filters.py +9 -15
- educommon/objectpack/ui.py +59 -77
- educommon/report/__init__.py +9 -5
- educommon/report/actions.py +29 -32
- educommon/report/constructor/__init__.py +5 -8
- educommon/report/constructor/app_meta.py +1 -3
- educommon/report/constructor/apps.py +1 -0
- educommon/report/constructor/base.py +33 -80
- educommon/report/constructor/builders/excel/_base.py +138 -286
- educommon/report/constructor/builders/excel/_header.py +2 -9
- educommon/report/constructor/builders/excel/product.py +13 -34
- educommon/report/constructor/builders/excel/with_merged_cells.py +18 -14
- educommon/report/constructor/config.py +2 -0
- educommon/report/constructor/editor/actions.py +101 -215
- educommon/report/constructor/editor/ui.py +71 -93
- educommon/report/constructor/exceptions.py +6 -12
- educommon/report/constructor/migrations/0001_initial.py +36 -44
- educommon/report/constructor/migrations/0002_report_filters.py +86 -72
- educommon/report/constructor/migrations/0003_reportfilter_exclude.py +5 -5
- educommon/report/constructor/migrations/0004_reportfilter_fields.py +22 -18
- educommon/report/constructor/migrations/0005_reportcolumn_visible.py +5 -4
- educommon/report/constructor/migrations/0006_reportsorting.py +21 -17
- educommon/report/constructor/migrations/0007_include_available_units.py +14 -14
- educommon/report/constructor/migrations/0008_auto_20170407_1318.py +4 -5
- educommon/report/constructor/migrations/0009_auto_20180405_0642.py +1 -4
- educommon/report/constructor/migrations/0010_add_aggregate_fields.py +7 -8
- educommon/report/constructor/mixins.py +14 -15
- educommon/report/constructor/models.py +76 -124
- educommon/report/constructor/utils.py +3 -8
- educommon/report/constructor/validators.py +1 -3
- educommon/report/reporter.py +25 -43
- educommon/report/utils.py +14 -40
- educommon/rest/actions.py +7 -11
- educommon/rest/context.py +6 -16
- educommon/rest/controllers.py +10 -10
- educommon/rest/mixins.py +29 -27
- educommon/secure_media/app_meta.py +9 -9
- educommon/utils/__init__.py +3 -2
- educommon/utils/caching.py +1 -3
- educommon/utils/conversion.py +1 -3
- educommon/utils/crypto.py +1 -2
- educommon/utils/date.py +13 -26
- educommon/utils/db/__init__.py +17 -26
- educommon/utils/db/postgresql.py +1 -4
- educommon/utils/fonts/__init__.py +3 -4
- educommon/utils/licence/__init__.py +5 -16
- educommon/utils/misc.py +9 -18
- educommon/utils/object_grid.py +55 -62
- educommon/utils/phone_number/modelfields.py +1 -3
- educommon/utils/phone_number/phone_number.py +5 -8
- educommon/utils/phone_number/validators.py +8 -23
- educommon/utils/plugins.py +15 -28
- educommon/utils/registry.py +2 -1
- educommon/utils/seqtools.py +1 -3
- educommon/utils/serializer.py +9 -16
- educommon/utils/storage.py +3 -2
- educommon/utils/system.py +1 -3
- educommon/utils/system_app/management/commands/delete_objects.py +17 -34
- educommon/utils/ui.py +87 -84
- educommon/utils/xml/__init__.py +2 -7
- educommon/utils/xml/resolver.py +1 -0
- educommon/ws_log/actions.py +31 -76
- educommon/ws_log/base.py +6 -20
- educommon/ws_log/migrations/0001_initial.py +25 -8
- educommon/ws_log/migrations/0002_auto_20160628_1334.py +0 -1
- educommon/ws_log/migrations/0003_add_fields_to_smev_logs.py +20 -4
- educommon/ws_log/migrations/0004_auto_20160727_1600.py +7 -6
- educommon/ws_log/migrations/0005_auto_20161130_1615.py +14 -4
- educommon/ws_log/migrations/0006_auto_20170327_1027.py +3 -2
- educommon/ws_log/migrations/0007_auto_20180607_1040.py +8 -9
- educommon/ws_log/migrations/0008_auto_20180713_1445.py +23 -10
- educommon/ws_log/migrations/0009_auto_20201130_1553.py +7 -2
- educommon/ws_log/models.py +21 -35
- educommon/ws_log/provider.py +2 -1
- educommon/ws_log/report.py +8 -13
- educommon/ws_log/smev/applications.py +12 -27
- educommon/ws_log/smev/exceptions.py +2 -3
- educommon/ws_log/ui.py +32 -32
- educommon/ws_log/utils.py +1 -3
- educommon-3.13.2.dist-info/METADATA +57 -0
- educommon-3.13.2.dist-info/RECORD +354 -0
- {educommon-3.12.0.dist-info → educommon-3.13.2.dist-info}/WHEEL +1 -1
- educommon/utils/patches.py +0 -27
- educommon/version.conf +0 -11
- educommon-3.12.0.dist-info/METADATA +0 -47
- educommon-3.12.0.dist-info/RECORD +0 -357
- educommon-3.12.0.dist-info/dependency_links.txt +0 -1
- {educommon-3.12.0.dist-info → educommon-3.13.2.dist-info}/top_level.txt +0 -0
@@ -106,23 +106,15 @@ class ColumnsAction(BaseAction):
|
|
106
106
|
if context.parent_column_name == '-1':
|
107
107
|
context.parent_column_name = None
|
108
108
|
|
109
|
-
data_source = registry.get(
|
110
|
-
context.data_source_name
|
111
|
-
).get_data_source_descriptor()
|
109
|
+
data_source = registry.get(context.data_source_name).get_data_source_descriptor()
|
112
110
|
|
113
111
|
if context.parent_column_name:
|
114
|
-
parent_column = ColumnDescriptor.create(
|
115
|
-
data_source.model, context.parent_column_name, data_source
|
116
|
-
)
|
112
|
+
parent_column = ColumnDescriptor.create(data_source.model, context.parent_column_name, data_source)
|
117
113
|
columns = parent_column.get_nested_columns()
|
118
114
|
else:
|
119
|
-
columns = tuple(
|
120
|
-
data_source.get_available_columns()
|
121
|
-
)
|
115
|
+
columns = tuple(data_source.get_available_columns())
|
122
116
|
|
123
|
-
return PreJsonResult(tuple(
|
124
|
-
map(ColumnsAction._get_column_params, columns)
|
125
|
-
))
|
117
|
+
return PreJsonResult(tuple(map(ColumnsAction._get_column_params, columns)))
|
126
118
|
|
127
119
|
|
128
120
|
_BUILDERS_PACKAGE = 'educommon.report.constructor.builders'
|
@@ -132,10 +124,8 @@ class BuildAction(BaseAction):
|
|
132
124
|
"""Сборка отчета на основе указанного шаблона."""
|
133
125
|
|
134
126
|
_builders = {
|
135
|
-
ReportTemplate.EXCEL_SIMPLE:
|
136
|
-
|
137
|
-
ReportTemplate.EXCEL_MERGED:
|
138
|
-
_BUILDERS_PACKAGE + '.excel.with_merged_cells.ReportBuilder',
|
127
|
+
ReportTemplate.EXCEL_SIMPLE: f'{_BUILDERS_PACKAGE}.excel.product.ReportBuilder',
|
128
|
+
ReportTemplate.EXCEL_MERGED: f'{_BUILDERS_PACKAGE}.excel.with_merged_cells.ReportBuilder',
|
139
129
|
}
|
140
130
|
|
141
131
|
def context_declaration(self):
|
@@ -147,9 +137,7 @@ class BuildAction(BaseAction):
|
|
147
137
|
def _get_report_template(self, request, context):
|
148
138
|
# Загрузка шаблона
|
149
139
|
try:
|
150
|
-
return ReportTemplate.objects.get(
|
151
|
-
pk=get_id_value(context, self.parent)
|
152
|
-
)
|
140
|
+
return ReportTemplate.objects.get(pk=get_id_value(context, self.parent))
|
153
141
|
except ReportTemplate.DoesNotExist:
|
154
142
|
raise ApplicationLogicException(self.parent.MSG_DOESNOTEXISTS)
|
155
143
|
|
@@ -158,41 +146,29 @@ class BuildAction(BaseAction):
|
|
158
146
|
# шаблоне.
|
159
147
|
if report_template.data_source_name not in registry:
|
160
148
|
raise ApplicationLogicException(
|
161
|
-
'Источник данных {} не существует.'
|
162
|
-
.format(report_template.data_source_name)
|
149
|
+
'Источник данных {} не существует.'.format(report_template.data_source_name)
|
163
150
|
)
|
164
151
|
|
165
|
-
data_source = registry.get(
|
166
|
-
report_template.data_source_name
|
167
|
-
).get_data_source_descriptor()
|
152
|
+
data_source = registry.get(report_template.data_source_name).get_data_source_descriptor()
|
168
153
|
|
169
154
|
if ReportInfo(report_template).ignored_columns_ids:
|
170
|
-
raise ApplicationLogicException(
|
171
|
-
'Некоторые колонки шаблона неактуальны, '
|
172
|
-
'требуется редактирование'
|
173
|
-
)
|
155
|
+
raise ApplicationLogicException('Некоторые колонки шаблона неактуальны, требуется редактирование')
|
174
156
|
|
175
157
|
# Проверка доступности данных для всех столбцов шаблона отчета.
|
176
158
|
try:
|
177
|
-
for col_name in report_template.columns.values_list(
|
178
|
-
'name', flat=True):
|
159
|
+
for col_name in report_template.columns.values_list('name', flat=True):
|
179
160
|
if data_source.is_column_ignored(col_name):
|
180
161
|
continue
|
181
162
|
data_source.get_column_descriptor(col_name)
|
182
163
|
except FieldDoesNotExist as error:
|
183
|
-
raise ApplicationLogicException(
|
184
|
-
'Колонка {} недоступна'.format(str(error))
|
185
|
-
)
|
164
|
+
raise ApplicationLogicException('Колонка {} недоступна'.format(str(error)))
|
186
165
|
|
187
166
|
def _check_params(self, request, context, report_template):
|
188
167
|
"""Возвращает True, если параметры сборки указаны верно."""
|
189
168
|
if context.format is None:
|
190
169
|
return report_template.format in self._builders
|
191
170
|
|
192
|
-
if
|
193
|
-
report_template.format == ReportTemplate.USER_DEFINED and
|
194
|
-
context.format in self._builders
|
195
|
-
):
|
171
|
+
if report_template.format == ReportTemplate.USER_DEFINED and context.format in self._builders:
|
196
172
|
return True
|
197
173
|
|
198
174
|
return False
|
@@ -206,15 +182,19 @@ class BuildAction(BaseAction):
|
|
206
182
|
data=ReportTemplate.FORMAT_CHOICES[1:],
|
207
183
|
)
|
208
184
|
|
209
|
-
win.form.items.extend(
|
210
|
-
|
211
|
-
|
185
|
+
win.form.items.extend(
|
186
|
+
anchor100(
|
187
|
+
win.field__format,
|
188
|
+
)
|
189
|
+
)
|
212
190
|
|
213
|
-
win.set_params(
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
191
|
+
win.set_params(
|
192
|
+
dict(
|
193
|
+
form_url=self.get_absolute_url(),
|
194
|
+
height=100,
|
195
|
+
title='Параметры сборки',
|
196
|
+
)
|
197
|
+
)
|
218
198
|
|
219
199
|
return ExtUIScriptResult(win, context)
|
220
200
|
|
@@ -231,13 +211,12 @@ class BuildAction(BaseAction):
|
|
231
211
|
'object_id': user.id,
|
232
212
|
'content_type': content_type,
|
233
213
|
'report_template_id': report_template_id,
|
234
|
-
'format': context.format or None
|
214
|
+
'format': context.format or None,
|
235
215
|
}
|
236
216
|
report_constructor_config.async_task.apply_async(None, params)
|
237
217
|
|
238
218
|
return OperationResult(
|
239
|
-
message='Внимание! Задача поставлена в очередь! Результаты '
|
240
|
-
'будут доступны в реестре Асинхронных задач.'
|
219
|
+
message='Внимание! Задача поставлена в очередь! Результаты будут доступны в реестре Асинхронных задач.'
|
241
220
|
)
|
242
221
|
|
243
222
|
def run(self, request, context):
|
@@ -262,9 +241,7 @@ class ReportInfo:
|
|
262
241
|
:type report_template:
|
263
242
|
educommon.report.constructor.models.ReportTemplate
|
264
243
|
"""
|
265
|
-
assert isinstance(report_template, ReportTemplate), type(
|
266
|
-
report_template
|
267
|
-
)
|
244
|
+
assert isinstance(report_template, ReportTemplate), type(report_template)
|
268
245
|
|
269
246
|
self.report_template = report_template
|
270
247
|
|
@@ -274,9 +251,7 @@ class ReportInfo:
|
|
274
251
|
|
275
252
|
:rtype: educommon.report.constructor.base.ModelDataSourceDescriptor
|
276
253
|
"""
|
277
|
-
data_source = registry.get(
|
278
|
-
self.report_template.data_source_name
|
279
|
-
).get_data_source_descriptor()
|
254
|
+
data_source = registry.get(self.report_template.data_source_name).get_data_source_descriptor()
|
280
255
|
return data_source
|
281
256
|
|
282
257
|
@cached_property
|
@@ -288,10 +263,8 @@ class ReportInfo:
|
|
288
263
|
:rtype: set
|
289
264
|
"""
|
290
265
|
ignored_columns = set()
|
291
|
-
for col_id, col_name in self.report_template.columns.values_list(
|
292
|
-
|
293
|
-
if (self._data_source.is_column_ignored(col_name) or
|
294
|
-
not self._data_source.is_column_exist(col_name)):
|
266
|
+
for col_id, col_name in self.report_template.columns.values_list('id', 'name'):
|
267
|
+
if self._data_source.is_column_ignored(col_name) or not self._data_source.is_column_exist(col_name):
|
295
268
|
ignored_columns.add(col_id)
|
296
269
|
|
297
270
|
return ignored_columns
|
@@ -304,10 +277,7 @@ class ReportInfo:
|
|
304
277
|
"""
|
305
278
|
columns = self.report_template.columns.order_by('index')
|
306
279
|
|
307
|
-
return OrderedDict(
|
308
|
-
(report_column.id, report_column)
|
309
|
-
for report_column in columns
|
310
|
-
)
|
280
|
+
return OrderedDict((report_column.id, report_column) for report_column in columns)
|
311
281
|
|
312
282
|
@cached_property
|
313
283
|
def _report_columns_by_name(self):
|
@@ -315,10 +285,7 @@ class ReportInfo:
|
|
315
285
|
|
316
286
|
:rtype: collections.OrderedDict
|
317
287
|
"""
|
318
|
-
return OrderedDict(
|
319
|
-
(report_column.name, report_column)
|
320
|
-
for report_column in self._report_columns_by_id.values()
|
321
|
-
)
|
288
|
+
return OrderedDict((report_column.name, report_column) for report_column in self._report_columns_by_id.values())
|
322
289
|
|
323
290
|
@cached_property
|
324
291
|
def _field_descriptors(self):
|
@@ -353,9 +320,7 @@ class ReportInfo:
|
|
353
320
|
|
354
321
|
for descriptor in self._field_descriptors.values():
|
355
322
|
if not descriptor.is_root():
|
356
|
-
hierarchy[descriptor.parent.full_accessor_name].append(
|
357
|
-
descriptor
|
358
|
-
)
|
323
|
+
hierarchy[descriptor.parent.full_accessor_name].append(descriptor)
|
359
324
|
|
360
325
|
return hierarchy
|
361
326
|
|
@@ -370,20 +335,13 @@ class ReportInfo:
|
|
370
335
|
full_name=full_accessor_name,
|
371
336
|
title=descriptor.title,
|
372
337
|
leaf=not descriptor.has_nested_columns(),
|
373
|
-
nested=tuple(
|
374
|
-
self._get_descriptor_data(descriptor)
|
375
|
-
for descriptor in nested_descriptors
|
376
|
-
),
|
338
|
+
nested=tuple(self._get_descriptor_data(descriptor) for descriptor in nested_descriptors),
|
377
339
|
)
|
378
340
|
column = self._report_columns_by_name.get(full_accessor_name, None)
|
379
341
|
column_id = getattr(column, 'id', 0)
|
380
|
-
result['is_fake'] =
|
381
|
-
not column_id or column_id in self.ignored_columns_ids
|
382
|
-
)
|
342
|
+
result['is_fake'] = not column_id or column_id in self.ignored_columns_ids
|
383
343
|
if full_accessor_name in self._report_columns_by_name:
|
384
|
-
result['visible'] =
|
385
|
-
self._report_columns_by_name[full_accessor_name].visible
|
386
|
-
)
|
344
|
+
result['visible'] = self._report_columns_by_name[full_accessor_name].visible
|
387
345
|
result['visible_title'] = 'Да' if result['visible'] else 'Нет'
|
388
346
|
|
389
347
|
# "Количество"
|
@@ -429,16 +387,11 @@ class ReportInfo:
|
|
429
387
|
"""
|
430
388
|
tree_manager = getattr(ReportFilterGroup, '_tree_manager')
|
431
389
|
filter_groups_query = tree_manager.get_queryset_descendants(
|
432
|
-
self.report_template.filter_groups.exclude(
|
433
|
-
|
434
|
-
),
|
435
|
-
include_self=True
|
390
|
+
self.report_template.filter_groups.exclude(filters__column_id__in=self.ignored_columns_ids),
|
391
|
+
include_self=True,
|
436
392
|
).prefetch_related('filters')
|
437
393
|
|
438
|
-
return OrderedDict(
|
439
|
-
(filter_group.pk, filter_group)
|
440
|
-
for filter_group in filter_groups_query
|
441
|
-
)
|
394
|
+
return OrderedDict((filter_group.pk, filter_group) for filter_group in filter_groups_query)
|
442
395
|
|
443
396
|
def _get_filter_data(self, report_filter):
|
444
397
|
"""Возвращает параметры фильтра.
|
@@ -448,13 +401,13 @@ class ReportInfo:
|
|
448
401
|
column = self._report_columns_by_id[report_filter.column_id]
|
449
402
|
|
450
403
|
return dict(
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
404
|
+
column=column.name,
|
405
|
+
index=report_filter.index,
|
406
|
+
operator=report_filter.operator,
|
407
|
+
exclude=report_filter.exclude,
|
408
|
+
case_sensitive=report_filter.case_sensitive,
|
409
|
+
values=report_filter.values or [],
|
410
|
+
comment=report_filter.comment,
|
458
411
|
)
|
459
412
|
|
460
413
|
def _get_filter_group_data(self, filter_group):
|
@@ -463,18 +416,12 @@ class ReportInfo:
|
|
463
416
|
:rtype: dict
|
464
417
|
"""
|
465
418
|
nested_groups = (
|
466
|
-
nested_group
|
467
|
-
for nested_group in self._filter_groups.values()
|
468
|
-
if nested_group.parent_id == filter_group.pk
|
419
|
+
nested_group for nested_group in self._filter_groups.values() if nested_group.parent_id == filter_group.pk
|
469
420
|
)
|
470
421
|
|
471
422
|
return {
|
472
423
|
self._OPERATOR_MAP[filter_group.operator]: tuple(
|
473
|
-
(
|
474
|
-
self._get_filter_group_data(obj)
|
475
|
-
if isinstance(obj, ReportFilterGroup) else
|
476
|
-
self._get_filter_data(obj)
|
477
|
-
)
|
424
|
+
(self._get_filter_group_data(obj) if isinstance(obj, ReportFilterGroup) else self._get_filter_data(obj))
|
478
425
|
for obj in chain(nested_groups, filter_group.filters.all())
|
479
426
|
)
|
480
427
|
}
|
@@ -546,11 +493,9 @@ class ReportInfo:
|
|
546
493
|
:rtype: tuple
|
547
494
|
"""
|
548
495
|
result = tuple(
|
549
|
-
ReportSorting.objects.filter(
|
550
|
-
|
551
|
-
|
552
|
-
column_id__in=self.ignored_columns_ids
|
553
|
-
).order_by('index')
|
496
|
+
ReportSorting.objects.filter(column__report_template=self.report_template)
|
497
|
+
.exclude(column_id__in=self.ignored_columns_ids)
|
498
|
+
.order_by('index')
|
554
499
|
)
|
555
500
|
|
556
501
|
for sorting_params in result:
|
@@ -571,17 +516,13 @@ class ReportInfo:
|
|
571
516
|
|
572
517
|
def get_sorting_data(self):
|
573
518
|
"""Возвращает параметры сортировки."""
|
574
|
-
return tuple(
|
575
|
-
self._get_sorting_data(sorting_params)
|
576
|
-
for sorting_params in self._sorting_params_by_column_name
|
577
|
-
)
|
519
|
+
return tuple(self._get_sorting_data(sorting_params) for sorting_params in self._sorting_params_by_column_name)
|
578
520
|
|
579
521
|
|
580
522
|
class ReportTemplateWriter:
|
581
523
|
"""Класс, сохраняющий в БД данные шаблона отчета."""
|
582
524
|
|
583
|
-
def __init__(self, report_template, columns_data, filters_data,
|
584
|
-
sorting_data):
|
525
|
+
def __init__(self, report_template, columns_data, filters_data, sorting_data):
|
585
526
|
"""Инициализация экземпляра класса.
|
586
527
|
|
587
528
|
:param report_template: Шаблон отчета
|
@@ -619,10 +560,7 @@ class ReportTemplateWriter:
|
|
619
560
|
:rtype: bool
|
620
561
|
"""
|
621
562
|
if report_template.data_source_name not in registry:
|
622
|
-
self.errors.append(
|
623
|
-
'Источник данных "{}" не существует.'
|
624
|
-
.format(report_template.data_source_name)
|
625
|
-
)
|
563
|
+
self.errors.append('Источник данных "{}" не существует.'.format(report_template.data_source_name))
|
626
564
|
|
627
565
|
return not self.errors
|
628
566
|
|
@@ -639,9 +577,7 @@ class ReportTemplateWriter:
|
|
639
577
|
# ---------------------------------------------------------------------
|
640
578
|
# Проверка наличия в источнике данных указанных столбцов.
|
641
579
|
|
642
|
-
data_source = registry.get(
|
643
|
-
self._report_template.data_source_name
|
644
|
-
).get_data_source_descriptor()
|
580
|
+
data_source = registry.get(self._report_template.data_source_name).get_data_source_descriptor()
|
645
581
|
|
646
582
|
for column_params in columns_data:
|
647
583
|
if 'accessor_name' not in column_params:
|
@@ -650,29 +586,18 @@ class ReportTemplateWriter:
|
|
650
586
|
|
651
587
|
full_accessor_name = column_params['accessor_name']
|
652
588
|
if full_accessor_name in self._column_descriptors:
|
653
|
-
self.errors.append(
|
654
|
-
'Колонка {} указана более одного раза.'
|
655
|
-
.format(full_accessor_name)
|
656
|
-
)
|
589
|
+
self.errors.append('Колонка {} указана более одного раза.'.format(full_accessor_name))
|
657
590
|
else:
|
658
591
|
try:
|
659
|
-
column_descriptor = data_source.get_column_descriptor(
|
660
|
-
full_accessor_name
|
661
|
-
)
|
592
|
+
column_descriptor = data_source.get_column_descriptor(full_accessor_name)
|
662
593
|
except FieldDoesNotExist:
|
663
594
|
self.errors.append(
|
664
|
-
'Колонки "{}" нет в источнике данных "{}".'
|
665
|
-
.format(full_accessor_name, data_source.title)
|
595
|
+
'Колонки "{}" нет в источнике данных "{}".'.format(full_accessor_name, data_source.title)
|
666
596
|
)
|
667
597
|
else:
|
668
|
-
self._column_descriptors[full_accessor_name] =
|
669
|
-
column_descriptor
|
670
|
-
)
|
598
|
+
self._column_descriptors[full_accessor_name] = column_descriptor
|
671
599
|
|
672
|
-
if not any(
|
673
|
-
column_params.get('visible', False)
|
674
|
-
for column_params in columns_data
|
675
|
-
):
|
600
|
+
if not any(column_params.get('visible', False) for column_params in columns_data):
|
676
601
|
self.errors.append('В отчете нет ни одного видимого столбца.')
|
677
602
|
# ---------------------------------------------------------------------
|
678
603
|
|
@@ -695,12 +620,8 @@ class ReportTemplateWriter:
|
|
695
620
|
return False
|
696
621
|
|
697
622
|
# Проверка вложенной группы фильтров.
|
698
|
-
if (
|
699
|
-
'
|
700
|
-
not self._is_filters_data_valid(filter_params['AND'])
|
701
|
-
) or (
|
702
|
-
'OR' in filter_params and
|
703
|
-
not self._is_filters_data_valid(filter_params['OR'])
|
623
|
+
if ('AND' in filter_params and not self._is_filters_data_valid(filter_params['AND'])) or (
|
624
|
+
'OR' in filter_params and not self._is_filters_data_valid(filter_params['OR'])
|
704
625
|
):
|
705
626
|
return False
|
706
627
|
|
@@ -711,12 +632,9 @@ class ReportTemplateWriter:
|
|
711
632
|
'values',
|
712
633
|
)
|
713
634
|
if (
|
714
|
-
'AND' not in filter_params
|
715
|
-
'OR' not in filter_params
|
716
|
-
any(
|
717
|
-
param_name not in filter_params
|
718
|
-
for param_name in param_names
|
719
|
-
)
|
635
|
+
'AND' not in filter_params
|
636
|
+
and 'OR' not in filter_params
|
637
|
+
and any(param_name not in filter_params for param_name in param_names)
|
720
638
|
):
|
721
639
|
return False
|
722
640
|
|
@@ -736,10 +654,7 @@ class ReportTemplateWriter:
|
|
736
654
|
'column',
|
737
655
|
'direction',
|
738
656
|
)
|
739
|
-
if any(
|
740
|
-
param_name not in sorting_params
|
741
|
-
for param_name in param_names
|
742
|
-
):
|
657
|
+
if any(param_name not in sorting_params for param_name in param_names):
|
743
658
|
return False
|
744
659
|
|
745
660
|
return True
|
@@ -751,21 +666,13 @@ class ReportTemplateWriter:
|
|
751
666
|
найдены ошибки.
|
752
667
|
"""
|
753
668
|
if not self._is_report_template_valid(self._report_template):
|
754
|
-
raise ValidationError(
|
755
|
-
'Параметры шаблона указаны некорректно.'
|
756
|
-
)
|
669
|
+
raise ValidationError('Параметры шаблона указаны некорректно.')
|
757
670
|
if not self._is_columns_data_valid(self._columns_data):
|
758
|
-
raise ValidationError(
|
759
|
-
'Параметры столбцов указаны некорректно.'
|
760
|
-
)
|
671
|
+
raise ValidationError('Параметры столбцов указаны некорректно.')
|
761
672
|
if not self._is_filters_data_valid(self._filters_data):
|
762
|
-
raise ValidationError(
|
763
|
-
'Параметры фильтров указаны некорректно.'
|
764
|
-
)
|
673
|
+
raise ValidationError('Параметры фильтров указаны некорректно.')
|
765
674
|
if not self._is_sorting_data_valid(self._sorting_data):
|
766
|
-
raise ValidationError(
|
767
|
-
'Параметры сортировки указаны некорректно.'
|
768
|
-
)
|
675
|
+
raise ValidationError('Параметры сортировки указаны некорректно.')
|
769
676
|
|
770
677
|
def _write_template(self):
|
771
678
|
"""Сохранение в БД шаблона отчета."""
|
@@ -774,20 +681,13 @@ class ReportTemplateWriter:
|
|
774
681
|
def _write_columns(self):
|
775
682
|
"""Сохранение в БД столбцов."""
|
776
683
|
column_descriptor_names = set(
|
777
|
-
column_descriptor.full_accessor_name
|
778
|
-
for column_descriptor in self._column_descriptors.values()
|
684
|
+
column_descriptor.full_accessor_name for column_descriptor in self._column_descriptors.values()
|
779
685
|
)
|
780
686
|
|
781
687
|
columns_query = self._report_template.columns.order_by('index')
|
782
|
-
report_columns = OrderedDict(
|
783
|
-
(report_column.name, report_column)
|
784
|
-
for report_column in columns_query
|
785
|
-
)
|
688
|
+
report_columns = OrderedDict((report_column.name, report_column) for report_column in columns_query)
|
786
689
|
|
787
|
-
columns_data = {
|
788
|
-
column_data['accessor_name']: column_data
|
789
|
-
for column_data in self._columns_data
|
790
|
-
}
|
690
|
+
columns_data = {column_data['accessor_name']: column_data for column_data in self._columns_data}
|
791
691
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
792
692
|
# Сначала нужно удалить столбцы, которых нет в запросе.
|
793
693
|
|
@@ -797,12 +697,8 @@ class ReportTemplateWriter:
|
|
797
697
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
798
698
|
|
799
699
|
created_report_columns = []
|
800
|
-
for index, column_descriptor in enumerate(
|
801
|
-
|
802
|
-
):
|
803
|
-
report_column = report_columns.get(
|
804
|
-
column_descriptor.full_accessor_name
|
805
|
-
)
|
700
|
+
for index, column_descriptor in enumerate(self._column_descriptors.values(), 1):
|
701
|
+
report_column = report_columns.get(column_descriptor.full_accessor_name)
|
806
702
|
|
807
703
|
column_data = columns_data[column_descriptor.full_accessor_name]
|
808
704
|
visible = column_data.get('visible', False)
|
@@ -818,17 +714,17 @@ class ReportTemplateWriter:
|
|
818
714
|
title=column_descriptor.title,
|
819
715
|
visible=visible,
|
820
716
|
by_value=by_value,
|
821
|
-
total=total
|
717
|
+
total=total,
|
822
718
|
)
|
823
719
|
)
|
824
720
|
|
825
721
|
elif (
|
826
|
-
report_column.name != column_descriptor.full_accessor_name
|
827
|
-
report_column.index != index
|
828
|
-
report_column.title != column_descriptor.title
|
829
|
-
report_column.visible != visible
|
830
|
-
report_column.by_value != by_value
|
831
|
-
report_column.total != total
|
722
|
+
report_column.name != column_descriptor.full_accessor_name
|
723
|
+
or report_column.index != index
|
724
|
+
or report_column.title != column_descriptor.title
|
725
|
+
or report_column.visible != visible
|
726
|
+
or report_column.by_value != by_value
|
727
|
+
or report_column.total != total
|
832
728
|
):
|
833
729
|
report_column.name = column_descriptor.full_accessor_name
|
834
730
|
report_column.index = index
|
@@ -841,8 +737,7 @@ class ReportTemplateWriter:
|
|
841
737
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
842
738
|
# Сохранение столбцов для дальнейшего использования.
|
843
739
|
|
844
|
-
for report_column in chain(report_columns.values(),
|
845
|
-
created_report_columns):
|
740
|
+
for report_column in chain(report_columns.values(), created_report_columns):
|
846
741
|
self._report_columns[report_column.name] = report_column
|
847
742
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
848
743
|
|
@@ -963,26 +858,26 @@ class Pack(PackValidationMixin, ObjectPack):
|
|
963
858
|
add_window = edit_window = EditWindow
|
964
859
|
|
965
860
|
def __init__(self):
|
966
|
-
super(
|
967
|
-
|
861
|
+
super().__init__()
|
862
|
+
|
968
863
|
self.columns_action = ColumnsAction()
|
969
864
|
self.build_action = BuildAction()
|
970
865
|
|
971
|
-
self.actions.extend(
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
866
|
+
self.actions.extend(
|
867
|
+
(
|
868
|
+
self.columns_action,
|
869
|
+
self.build_action,
|
870
|
+
)
|
871
|
+
)
|
976
872
|
|
977
873
|
def prepare_row(self, obj, request, context):
|
978
|
-
obj = super(
|
979
|
-
|
980
|
-
)
|
874
|
+
obj = super().prepare_row(obj, request, context)
|
875
|
+
|
981
876
|
obj.valid = not (ReportInfo(obj).ignored_columns_ids)
|
982
877
|
return obj
|
983
878
|
|
984
879
|
def declare_context(self, action):
|
985
|
-
result = super(
|
880
|
+
result = super().declare_context(action)
|
986
881
|
|
987
882
|
if action is self.save_action:
|
988
883
|
result.update(
|
@@ -996,24 +891,18 @@ class Pack(PackValidationMixin, ObjectPack):
|
|
996
891
|
return result
|
997
892
|
|
998
893
|
def get_list_window_params(self, params, request, context):
|
999
|
-
result = super(
|
1000
|
-
params, request, context
|
1001
|
-
)
|
894
|
+
result = super().get_list_window_params(params, request, context)
|
1002
895
|
|
1003
896
|
result['build_action_url'] = self.build_action.get_absolute_url()
|
1004
897
|
|
1005
898
|
return result
|
1006
899
|
|
1007
900
|
def get_edit_window_params(self, params, request, context):
|
1008
|
-
result = super(
|
1009
|
-
params, request, context
|
1010
|
-
)
|
901
|
+
result = super().get_edit_window_params(params, request, context)
|
1011
902
|
|
1012
903
|
result['maximized'] = True
|
1013
904
|
|
1014
|
-
result['available_columns_action_url'] = (
|
1015
|
-
self.columns_action.get_absolute_url()
|
1016
|
-
)
|
905
|
+
result['available_columns_action_url'] = self.columns_action.get_absolute_url()
|
1017
906
|
|
1018
907
|
# pylint: disable=dict-iter-method
|
1019
908
|
result['data_sources_params'] = registry.iteritems()
|
@@ -1044,10 +933,7 @@ class Pack(PackValidationMixin, ObjectPack):
|
|
1044
933
|
try:
|
1045
934
|
writer.validate()
|
1046
935
|
except ValidationError as error:
|
1047
|
-
raise ValidationError('\n'.join((
|
1048
|
-
str(error),
|
1049
|
-
'\n'.join(writer.errors)
|
1050
|
-
)))
|
936
|
+
raise ValidationError('\n'.join((str(error), '\n'.join(writer.errors))))
|
1051
937
|
|
1052
938
|
writer.write()
|
1053
939
|
|
@@ -1073,7 +959,7 @@ class Pack(PackValidationMixin, ObjectPack):
|
|
1073
959
|
).iterator():
|
1074
960
|
report_column.safe_delete()
|
1075
961
|
|
1076
|
-
super(
|
962
|
+
super().delete_row(obj_id, request, context)
|
1077
963
|
|
1078
964
|
def extend_menu(self, menu):
|
1079
965
|
return menu.SubMenu(
|
@@ -1081,5 +967,5 @@ class Pack(PackValidationMixin, ObjectPack):
|
|
1081
967
|
menu.SubMenu(
|
1082
968
|
'Конструктор отчетов',
|
1083
969
|
menu.Item('Редактор шаблонов', self.list_window_action),
|
1084
|
-
)
|
970
|
+
),
|
1085
971
|
)
|