odoo-addon-mis-builder 16.0.5.2.3.1__py3-none-any.whl → 16.0.5.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- odoo/addons/mis_builder/README.rst +1 -1
- odoo/addons/mis_builder/__manifest__.py +2 -1
- odoo/addons/mis_builder/i18n/mis_builder.pot +92 -0
- odoo/addons/mis_builder/models/__init__.py +1 -0
- odoo/addons/mis_builder/models/kpimatrix.py +39 -4
- odoo/addons/mis_builder/models/mis_report_instance.py +67 -1
- odoo/addons/mis_builder/models/mis_report_instance_annotation.py +113 -0
- odoo/addons/mis_builder/report/mis_report_instance_qweb.xml +23 -0
- odoo/addons/mis_builder/report/mis_report_instance_xlsx.py +11 -1
- odoo/addons/mis_builder/security/ir.model.access.csv +2 -0
- odoo/addons/mis_builder/security/res_groups.xml +17 -0
- odoo/addons/mis_builder/static/description/index.html +1 -1
- odoo/addons/mis_builder/static/src/components/mis_report_widget.css +32 -0
- odoo/addons/mis_builder/static/src/components/mis_report_widget.esm.js +83 -3
- odoo/addons/mis_builder/static/src/components/mis_report_widget.xml +94 -13
- odoo/addons/mis_builder/static/src/css/report.css +22 -0
- odoo/addons/mis_builder/tests/__init__.py +1 -0
- odoo/addons/mis_builder/tests/test_mis_report_instance_annotation.py +154 -0
- {odoo_addon_mis_builder-16.0.5.2.3.1.dist-info → odoo_addon_mis_builder-16.0.5.3.0.dist-info}/METADATA +2 -2
- {odoo_addon_mis_builder-16.0.5.2.3.1.dist-info → odoo_addon_mis_builder-16.0.5.3.0.dist-info}/RECORD +22 -19
- {odoo_addon_mis_builder-16.0.5.2.3.1.dist-info → odoo_addon_mis_builder-16.0.5.3.0.dist-info}/WHEEL +0 -0
- {odoo_addon_mis_builder-16.0.5.2.3.1.dist-info → odoo_addon_mis_builder-16.0.5.3.0.dist-info}/top_level.txt +0 -0
@@ -7,7 +7,7 @@ MIS Builder
|
|
7
7
|
!! This file is generated by oca-gen-addon-readme !!
|
8
8
|
!! changes will be overwritten. !!
|
9
9
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
10
|
-
!! source digest: sha256:
|
10
|
+
!! source digest: sha256:ce5435756f965a1651bfcff766931db176c696dbcedb0a99ce8e61f003c9b09d
|
11
11
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
12
12
|
|
13
13
|
.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
|
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
{
|
5
5
|
"name": "MIS Builder",
|
6
|
-
"version": "16.0.5.
|
6
|
+
"version": "16.0.5.3.0",
|
7
7
|
"category": "Reporting",
|
8
8
|
"summary": """
|
9
9
|
Build 'Management Information System' Reports and Dashboards
|
@@ -17,6 +17,7 @@
|
|
17
17
|
"date_range", # OCA/server-ux
|
18
18
|
],
|
19
19
|
"data": [
|
20
|
+
"security/res_groups.xml",
|
20
21
|
"wizard/mis_builder_dashboard.xml",
|
21
22
|
"views/mis_report.xml",
|
22
23
|
"views/mis_report_instance.xml",
|
@@ -13,6 +13,14 @@ msgstr ""
|
|
13
13
|
"Content-Transfer-Encoding: \n"
|
14
14
|
"Plural-Forms: \n"
|
15
15
|
|
16
|
+
#. module: mis_builder
|
17
|
+
#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_annotation__annotation_context
|
18
|
+
msgid ""
|
19
|
+
"\n"
|
20
|
+
" Context used when adding annotation\n"
|
21
|
+
" "
|
22
|
+
msgstr ""
|
23
|
+
|
16
24
|
#. module: mis_builder
|
17
25
|
#. odoo-python
|
18
26
|
#: code:addons/mis_builder/models/mis_report.py:0
|
@@ -292,6 +300,18 @@ msgstr ""
|
|
292
300
|
msgid "Analytic Domain"
|
293
301
|
msgstr ""
|
294
302
|
|
303
|
+
#. module: mis_builder
|
304
|
+
#. odoo-javascript
|
305
|
+
#: code:addons/mis_builder/static/src/components/mis_report_widget.xml:0
|
306
|
+
#, python-format
|
307
|
+
msgid "Annotate"
|
308
|
+
msgstr ""
|
309
|
+
|
310
|
+
#. module: mis_builder
|
311
|
+
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_annotation__annotation_context
|
312
|
+
msgid "Annotation Context"
|
313
|
+
msgstr ""
|
314
|
+
|
295
315
|
#. module: mis_builder
|
296
316
|
#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form
|
297
317
|
msgid "Auto expand"
|
@@ -333,8 +353,11 @@ msgid "Bold"
|
|
333
353
|
msgstr ""
|
334
354
|
|
335
355
|
#. module: mis_builder
|
356
|
+
#. odoo-javascript
|
357
|
+
#: code:addons/mis_builder/static/src/components/mis_report_widget.esm.js:0
|
336
358
|
#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view
|
337
359
|
#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form
|
360
|
+
#, python-format
|
338
361
|
msgid "Cancel"
|
339
362
|
msgstr ""
|
340
363
|
|
@@ -426,6 +449,7 @@ msgstr ""
|
|
426
449
|
#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_uid
|
427
450
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_uid
|
428
451
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_uid
|
452
|
+
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_annotation__create_uid
|
429
453
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_uid
|
430
454
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_uid
|
431
455
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_uid
|
@@ -441,6 +465,7 @@ msgstr ""
|
|
441
465
|
#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_date
|
442
466
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_date
|
443
467
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_date
|
468
|
+
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_annotation__create_date
|
444
469
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_date
|
445
470
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_date
|
446
471
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_date
|
@@ -547,6 +572,7 @@ msgstr ""
|
|
547
572
|
#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__display_name
|
548
573
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report__display_name
|
549
574
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_name
|
575
|
+
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_annotation__display_name
|
550
576
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__display_name
|
551
577
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__display_name
|
552
578
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__display_name
|
@@ -785,6 +811,7 @@ msgstr ""
|
|
785
811
|
#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__id
|
786
812
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report__id
|
787
813
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__id
|
814
|
+
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_annotation__id
|
788
815
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__id
|
789
816
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__id
|
790
817
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__id
|
@@ -826,6 +853,13 @@ msgstr ""
|
|
826
853
|
msgid "Indent level must be greater than or equal to 0"
|
827
854
|
msgstr ""
|
828
855
|
|
856
|
+
#. module: mis_builder
|
857
|
+
#. odoo-javascript
|
858
|
+
#: code:addons/mis_builder/static/src/components/mis_report_widget.xml:0
|
859
|
+
#, python-format
|
860
|
+
msgid "Insert note here"
|
861
|
+
msgstr ""
|
862
|
+
|
829
863
|
#. module: mis_builder
|
830
864
|
#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__italic
|
831
865
|
msgid "Italic"
|
@@ -882,6 +916,7 @@ msgid "KPIs of this report and subreports."
|
|
882
916
|
msgstr ""
|
883
917
|
|
884
918
|
#. module: mis_builder
|
919
|
+
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_annotation__kpi_id
|
885
920
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__kpi_id
|
886
921
|
msgid "Kpi"
|
887
922
|
msgstr ""
|
@@ -900,6 +935,7 @@ msgstr ""
|
|
900
935
|
#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard____last_update
|
901
936
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report____last_update
|
902
937
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance____last_update
|
938
|
+
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_annotation____last_update
|
903
939
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period____last_update
|
904
940
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum____last_update
|
905
941
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi____last_update
|
@@ -921,6 +957,7 @@ msgstr ""
|
|
921
957
|
#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_uid
|
922
958
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_uid
|
923
959
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_uid
|
960
|
+
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_annotation__write_uid
|
924
961
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_uid
|
925
962
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_uid
|
926
963
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_uid
|
@@ -936,6 +973,7 @@ msgstr ""
|
|
936
973
|
#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_date
|
937
974
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_date
|
938
975
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_date
|
976
|
+
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_annotation__write_date
|
939
977
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_date
|
940
978
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_date
|
941
979
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_date
|
@@ -1042,6 +1080,16 @@ msgstr ""
|
|
1042
1080
|
msgid "MIS Report Templates"
|
1043
1081
|
msgstr ""
|
1044
1082
|
|
1083
|
+
#. module: mis_builder
|
1084
|
+
#: model:res.groups,name:mis_builder.group_edit_annotation
|
1085
|
+
msgid "MIS Report: add annotations"
|
1086
|
+
msgstr ""
|
1087
|
+
|
1088
|
+
#. module: mis_builder
|
1089
|
+
#: model:res.groups,name:mis_builder.group_read_annotation
|
1090
|
+
msgid "MIS Report: view annotations"
|
1091
|
+
msgstr ""
|
1092
|
+
|
1045
1093
|
#. module: mis_builder
|
1046
1094
|
#: model:ir.ui.menu,name:mis_builder.mis_report_conf_menu
|
1047
1095
|
#: model:ir.ui.menu,name:mis_builder.mis_report_finance_menu
|
@@ -1080,6 +1128,11 @@ msgstr ""
|
|
1080
1128
|
msgid "Min"
|
1081
1129
|
msgstr ""
|
1082
1130
|
|
1131
|
+
#. module: mis_builder
|
1132
|
+
#: model:ir.model,name:mis_builder.model_mis_report_instance_annotation
|
1133
|
+
msgid "Mis Report Instance Annotation"
|
1134
|
+
msgstr ""
|
1135
|
+
|
1083
1136
|
#. module: mis_builder
|
1084
1137
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__mode
|
1085
1138
|
msgid "Mode"
|
@@ -1167,6 +1220,11 @@ msgstr ""
|
|
1167
1220
|
msgid "Normal"
|
1168
1221
|
msgstr ""
|
1169
1222
|
|
1223
|
+
#. module: mis_builder
|
1224
|
+
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_annotation__note
|
1225
|
+
msgid "Note"
|
1226
|
+
msgstr ""
|
1227
|
+
|
1170
1228
|
#. module: mis_builder
|
1171
1229
|
#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form
|
1172
1230
|
msgid "Number"
|
@@ -1210,6 +1268,11 @@ msgstr ""
|
|
1210
1268
|
msgid "Percentage"
|
1211
1269
|
msgstr ""
|
1212
1270
|
|
1271
|
+
#. module: mis_builder
|
1272
|
+
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_annotation__period_id
|
1273
|
+
msgid "Period"
|
1274
|
+
msgstr ""
|
1275
|
+
|
1213
1276
|
#. module: mis_builder
|
1214
1277
|
#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_name_unique
|
1215
1278
|
msgid "Period name should be unique by report"
|
@@ -1298,6 +1361,13 @@ msgstr ""
|
|
1298
1361
|
msgid "Relative to report base date"
|
1299
1362
|
msgstr ""
|
1300
1363
|
|
1364
|
+
#. module: mis_builder
|
1365
|
+
#. odoo-javascript
|
1366
|
+
#: code:addons/mis_builder/static/src/components/mis_report_widget.esm.js:0
|
1367
|
+
#, python-format
|
1368
|
+
msgid "Remove"
|
1369
|
+
msgstr ""
|
1370
|
+
|
1301
1371
|
#. module: mis_builder
|
1302
1372
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__report_id
|
1303
1373
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_id
|
@@ -1334,8 +1404,11 @@ msgid "Rounding inherit"
|
|
1334
1404
|
msgstr ""
|
1335
1405
|
|
1336
1406
|
#. module: mis_builder
|
1407
|
+
#. odoo-javascript
|
1408
|
+
#: code:addons/mis_builder/static/src/components/mis_report_widget.esm.js:0
|
1337
1409
|
#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form
|
1338
1410
|
#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form
|
1411
|
+
#, python-format
|
1339
1412
|
msgid "Save"
|
1340
1413
|
msgstr ""
|
1341
1414
|
|
@@ -1497,6 +1570,7 @@ msgid "Sub-KPI name ({}) must be a valid python identifier"
|
|
1497
1570
|
msgstr ""
|
1498
1571
|
|
1499
1572
|
#. module: mis_builder
|
1573
|
+
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_annotation__subkpi_id
|
1500
1574
|
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__subkpi_id
|
1501
1575
|
msgid "Subkpi"
|
1502
1576
|
msgstr ""
|
@@ -1646,6 +1720,16 @@ msgstr ""
|
|
1646
1720
|
msgid "Unsupported operator %s for searching on date"
|
1647
1721
|
msgstr ""
|
1648
1722
|
|
1723
|
+
#. module: mis_builder
|
1724
|
+
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__user_can_edit_annotation
|
1725
|
+
msgid "User Can Edit Annotation"
|
1726
|
+
msgstr ""
|
1727
|
+
|
1728
|
+
#. module: mis_builder
|
1729
|
+
#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__user_can_read_annotation
|
1730
|
+
msgid "User Can Read Annotation"
|
1731
|
+
msgstr ""
|
1732
|
+
|
1649
1733
|
#. module: mis_builder
|
1650
1734
|
#: model:ir.actions.server,name:mis_builder.ir_cron_vacuum_temp_reports_ir_actions_server
|
1651
1735
|
#: model:ir.cron,cron_name:mis_builder.ir_cron_vacuum_temp_reports
|
@@ -1710,6 +1794,14 @@ msgstr ""
|
|
1710
1794
|
msgid "You cannot sum period %s with itself."
|
1711
1795
|
msgstr ""
|
1712
1796
|
|
1797
|
+
#. module: mis_builder
|
1798
|
+
#. odoo-python
|
1799
|
+
#: code:addons/mis_builder/models/mis_report_instance_annotation.py:0
|
1800
|
+
#: code:addons/mis_builder/models/mis_report_instance_annotation.py:0
|
1801
|
+
#, python-format
|
1802
|
+
msgid "You do not have the rights to edit annotations"
|
1803
|
+
msgstr ""
|
1804
|
+
|
1713
1805
|
#. module: mis_builder
|
1714
1806
|
#. odoo-python
|
1715
1807
|
#: code:addons/mis_builder/models/aep.py:0
|
@@ -45,10 +45,7 @@ class KpiMatrixRow:
|
|
45
45
|
|
46
46
|
@property
|
47
47
|
def row_id(self):
|
48
|
-
|
49
|
-
return self.kpi.name
|
50
|
-
else:
|
51
|
-
return f"{self.kpi.name}:{self.account_id}"
|
48
|
+
self._matrix._make_row_id(self.kpi.id, self.account_id)
|
52
49
|
|
53
50
|
def iter_cell_tuples(self, cols=None):
|
54
51
|
if cols is None:
|
@@ -143,6 +140,7 @@ class KpiMatrixCell: # noqa: B903 (immutable data class)
|
|
143
140
|
self.style_props = style_props
|
144
141
|
self.drilldown_arg = drilldown_arg
|
145
142
|
self.val_type = val_type
|
143
|
+
self.cell_id = KpiMatrix._pack_cell_id(self)
|
146
144
|
|
147
145
|
|
148
146
|
class KpiMatrix:
|
@@ -524,12 +522,15 @@ class KpiMatrix:
|
|
524
522
|
else:
|
525
523
|
val = cell.val
|
526
524
|
col_data = {
|
525
|
+
"cell_id": cell.cell_id,
|
527
526
|
"val": val,
|
528
527
|
"val_r": cell.val_rendered,
|
529
528
|
"val_c": cell.val_comment,
|
530
529
|
"style": self._style_model.to_css_style(
|
531
530
|
cell.style_props, no_indent=True
|
532
531
|
),
|
532
|
+
# notes can not be added on 'details by account' lines
|
533
|
+
"can_be_annotated": not cell.row.account_id,
|
533
534
|
}
|
534
535
|
if cell.drilldown_arg:
|
535
536
|
col_data["drilldown_arg"] = cell.drilldown_arg
|
@@ -537,3 +538,37 @@ class KpiMatrix:
|
|
537
538
|
body.append(row_data)
|
538
539
|
|
539
540
|
return {"header": header, "body": body}
|
541
|
+
|
542
|
+
# Logic to convert semantic coordinates (period, kpi, subkpi)
|
543
|
+
# to visual coordinates (cell id) and back. The rendering logic musn't know
|
544
|
+
# about semantic concepts such as periods and kpis. Having these well identified
|
545
|
+
# methods allow us to easily spot where the conversion between the rendering and
|
546
|
+
# semantic domain occur.
|
547
|
+
|
548
|
+
@classmethod
|
549
|
+
def _make_row_id(cls, kpi_id: int, account_id: int | None) -> str:
|
550
|
+
return f"{kpi_id}:{account_id or ''}"
|
551
|
+
|
552
|
+
@classmethod
|
553
|
+
def _make_cell_id(
|
554
|
+
cls, kpi_id: int, account_id: int | None, period_id: int, subkpi_id: int | None
|
555
|
+
) -> str:
|
556
|
+
return f"{kpi_id}#{account_id or ''}#{period_id}#{subkpi_id or ''}"
|
557
|
+
|
558
|
+
@classmethod
|
559
|
+
def _pack_cell_id(cls, cell: KpiMatrixCell) -> str:
|
560
|
+
return cls._make_cell_id(
|
561
|
+
cell.row.kpi.id,
|
562
|
+
cell.row.account_id,
|
563
|
+
cell.subcol.col.key,
|
564
|
+
cell.subcol.subkpi and cell.subcol.subkpi.id,
|
565
|
+
)
|
566
|
+
|
567
|
+
@classmethod
|
568
|
+
def _unpack_cell_id(cls, cell_id: str) -> tuple[int, int | None, int, int | None]:
|
569
|
+
kpi_id, account_id, col_key, subkpi_id = cell_id.split("#")
|
570
|
+
kpi_id = int(kpi_id)
|
571
|
+
account_id = int(account_id) if account_id else None
|
572
|
+
period_id = int(col_key)
|
573
|
+
subkpi_id = int(subkpi_id) if subkpi_id else None
|
574
|
+
return kpi_id, account_id, period_id, subkpi_id
|
@@ -13,6 +13,7 @@ from odoo.exceptions import UserError, ValidationError
|
|
13
13
|
|
14
14
|
from .aep import AccountingExpressionProcessor as AEP
|
15
15
|
from .expression_evaluator import ExpressionEvaluator
|
16
|
+
from .kpimatrix import KpiMatrix
|
16
17
|
|
17
18
|
_logger = logging.getLogger(__name__)
|
18
19
|
|
@@ -580,6 +581,12 @@ class MisReportInstance(models.Model):
|
|
580
581
|
string="Filter box search view",
|
581
582
|
help="Search view to customize the filter box in the report widget.",
|
582
583
|
)
|
584
|
+
user_can_read_annotation = fields.Boolean(
|
585
|
+
compute="_compute_user_can_read_annotation",
|
586
|
+
)
|
587
|
+
user_can_edit_annotation = fields.Boolean(
|
588
|
+
compute="_compute_user_can_edit_annotation",
|
589
|
+
)
|
583
590
|
|
584
591
|
@api.depends("report_id.move_lines_source")
|
585
592
|
def _compute_widget_search_view_id(self):
|
@@ -877,7 +884,44 @@ class MisReportInstance(models.Model):
|
|
877
884
|
def compute(self):
|
878
885
|
self.ensure_one()
|
879
886
|
kpi_matrix = self._compute_matrix()
|
880
|
-
|
887
|
+
ret = kpi_matrix.as_dict()
|
888
|
+
|
889
|
+
ret["notes"] = self.get_notes_by_cell_id()
|
890
|
+
return ret
|
891
|
+
|
892
|
+
def get_notes_by_cell_id(self) -> dict:
|
893
|
+
self.ensure_one()
|
894
|
+
if not self.user_can_read_annotation:
|
895
|
+
return {}
|
896
|
+
|
897
|
+
annotations = self.env["mis.report.instance.annotation"].search(
|
898
|
+
[
|
899
|
+
("period_id", "in", self.period_ids.ids),
|
900
|
+
]
|
901
|
+
)
|
902
|
+
annotation_context = self._get_annotation_context()
|
903
|
+
annotations = annotations.filtered(
|
904
|
+
lambda rec: rec.annotation_context == annotation_context
|
905
|
+
)
|
906
|
+
|
907
|
+
annotations_sorted = sorted(
|
908
|
+
annotations,
|
909
|
+
key=lambda r: (
|
910
|
+
r.kpi_id.sequence,
|
911
|
+
r.period_id.sequence,
|
912
|
+
r.subkpi_id.sequence,
|
913
|
+
),
|
914
|
+
)
|
915
|
+
|
916
|
+
return {
|
917
|
+
KpiMatrix._make_cell_id(
|
918
|
+
annotation.kpi_id.id,
|
919
|
+
False,
|
920
|
+
annotation.period_id.id,
|
921
|
+
annotation.subkpi_id and annotation.subkpi_id.id,
|
922
|
+
): {"text": annotation.note, "sequence": sequence}
|
923
|
+
for sequence, annotation in enumerate(annotations_sorted, 1)
|
924
|
+
}
|
881
925
|
|
882
926
|
@api.model
|
883
927
|
def _get_drilldown_views_and_orders(self):
|
@@ -940,3 +984,25 @@ class MisReportInstance(models.Model):
|
|
940
984
|
return f"{kpi.description} - {account.display_name} - {period.display_name}"
|
941
985
|
else:
|
942
986
|
return f"{kpi.description} - {period.display_name}"
|
987
|
+
|
988
|
+
def _get_annotation_context(self):
|
989
|
+
"""Return the context used to filter annotation linked to this instance."""
|
990
|
+
self.ensure_one()
|
991
|
+
annotation_context = {}
|
992
|
+
if query_company_ids := self.query_company_ids.ids:
|
993
|
+
# sort ids to make the comparaison easier
|
994
|
+
annotation_context["query_company_ids"] = sorted(query_company_ids)
|
995
|
+
|
996
|
+
return annotation_context
|
997
|
+
|
998
|
+
@api.depends_context("uid")
|
999
|
+
def _compute_user_can_read_annotation(self):
|
1000
|
+
self.user_can_read_annotation = self.env.user.has_group(
|
1001
|
+
"mis_builder.group_read_annotation"
|
1002
|
+
)
|
1003
|
+
|
1004
|
+
@api.depends_context("uid")
|
1005
|
+
def _compute_user_can_edit_annotation(self):
|
1006
|
+
self.user_can_edit_annotation = self.env.user.has_group(
|
1007
|
+
"mis_builder.group_edit_annotation"
|
1008
|
+
)
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# Copyright 2025 ACSONE SA/NV
|
2
|
+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
3
|
+
|
4
|
+
|
5
|
+
from odoo import _, api, fields, models
|
6
|
+
from odoo.exceptions import AccessError
|
7
|
+
|
8
|
+
from .kpimatrix import KpiMatrix
|
9
|
+
|
10
|
+
|
11
|
+
class MisReportInstanceAnnotation(models.Model):
|
12
|
+
_name = "mis.report.instance.annotation"
|
13
|
+
_description = "Mis Report Instance Annotation"
|
14
|
+
|
15
|
+
period_id = fields.Many2one(
|
16
|
+
comodel_name="mis.report.instance.period",
|
17
|
+
ondelete="cascade",
|
18
|
+
required=True,
|
19
|
+
)
|
20
|
+
kpi_id = fields.Many2one(
|
21
|
+
comodel_name="mis.report.kpi",
|
22
|
+
ondelete="cascade",
|
23
|
+
required=True,
|
24
|
+
)
|
25
|
+
subkpi_id = fields.Many2one(
|
26
|
+
comodel_name="mis.report.subkpi",
|
27
|
+
ondelete="cascade",
|
28
|
+
)
|
29
|
+
note = fields.Char()
|
30
|
+
annotation_context = fields.Json(
|
31
|
+
help="""
|
32
|
+
Context used when adding annotation
|
33
|
+
"""
|
34
|
+
)
|
35
|
+
|
36
|
+
def init(self):
|
37
|
+
self.env.cr.execute(
|
38
|
+
"""
|
39
|
+
CREATE INDEX IF NOT EXISTS
|
40
|
+
mis_report_instance_annotation_period_id_kpi_id_subkpi_id_idx
|
41
|
+
ON mis_report_instance_annotation(period_id,kpi_id,subkpi_id);
|
42
|
+
"""
|
43
|
+
)
|
44
|
+
|
45
|
+
@api.model
|
46
|
+
def _get_first_matching_annotation(self, cell_id, instance_id):
|
47
|
+
"""
|
48
|
+
Return first annoation
|
49
|
+
matching exactly the period,kpi,subkpi and annotation context
|
50
|
+
"""
|
51
|
+
|
52
|
+
kpi_id, _, period_id, subkpi_id = KpiMatrix._unpack_cell_id(cell_id)
|
53
|
+
|
54
|
+
annotations = self.env["mis.report.instance.annotation"].search(
|
55
|
+
[
|
56
|
+
("period_id", "=", period_id),
|
57
|
+
("kpi_id", "=", kpi_id),
|
58
|
+
("subkpi_id", "=", subkpi_id),
|
59
|
+
],
|
60
|
+
)
|
61
|
+
annotation_context = (
|
62
|
+
self.env["mis.report.instance"]
|
63
|
+
.browse(instance_id)
|
64
|
+
._get_annotation_context()
|
65
|
+
)
|
66
|
+
annotation = fields.first(
|
67
|
+
annotations.filtered(
|
68
|
+
lambda rec: rec.annotation_context == annotation_context
|
69
|
+
)
|
70
|
+
)
|
71
|
+
return annotation
|
72
|
+
|
73
|
+
@api.model
|
74
|
+
def set_annotation(self, cell_id, instance_id, note):
|
75
|
+
if (
|
76
|
+
not self.env["mis.report.instance"]
|
77
|
+
.browse(instance_id)
|
78
|
+
.user_can_edit_annotation
|
79
|
+
):
|
80
|
+
raise AccessError(_("You do not have the rights to edit annotations"))
|
81
|
+
|
82
|
+
annotation = self._get_first_matching_annotation(cell_id, instance_id)
|
83
|
+
|
84
|
+
if annotation:
|
85
|
+
annotation.note = note
|
86
|
+
else:
|
87
|
+
kpi_id, _account_id, period_id, subkpi_id = KpiMatrix._unpack_cell_id(
|
88
|
+
cell_id
|
89
|
+
)
|
90
|
+
self.env["mis.report.instance.annotation"].create(
|
91
|
+
{
|
92
|
+
"period_id": period_id,
|
93
|
+
"kpi_id": kpi_id,
|
94
|
+
"subkpi_id": subkpi_id,
|
95
|
+
"note": note,
|
96
|
+
"annotation_context": self.env["mis.report.instance"]
|
97
|
+
.browse(instance_id)
|
98
|
+
._get_annotation_context(),
|
99
|
+
}
|
100
|
+
)
|
101
|
+
|
102
|
+
@api.model
|
103
|
+
def remove_annotation(self, cell_id, instance_id):
|
104
|
+
if (
|
105
|
+
not self.env["mis.report.instance"]
|
106
|
+
.browse(instance_id)
|
107
|
+
.user_can_edit_annotation
|
108
|
+
):
|
109
|
+
raise AccessError(_("You do not have the rights to edit annotations"))
|
110
|
+
|
111
|
+
annotation = self._get_first_matching_annotation(cell_id, instance_id)
|
112
|
+
if annotation:
|
113
|
+
annotation.unlink()
|
@@ -17,6 +17,7 @@
|
|
17
17
|
<t t-foreach="docs" t-as="o">
|
18
18
|
<t t-call="web.internal_layout">
|
19
19
|
<t t-set="matrix" t-value="o._compute_matrix()" />
|
20
|
+
<t t-set="notes" t-value="o.get_notes_by_cell_id()" />
|
20
21
|
<t t-set="style_obj" t-value="o.env['mis.report.style']" />
|
21
22
|
<div class="page">
|
22
23
|
<h3>
|
@@ -97,12 +98,34 @@
|
|
97
98
|
<t
|
98
99
|
t-out="cell and cell.val_rendered or ''"
|
99
100
|
/>
|
101
|
+
<span
|
102
|
+
class="oe_mis_builder_footnote"
|
103
|
+
t-if="cell"
|
104
|
+
>
|
105
|
+
<t
|
106
|
+
t-out="notes.get(cell.cell_id,{}).get('sequence','')"
|
107
|
+
/>
|
108
|
+
</span>
|
100
109
|
</div>
|
101
110
|
</t>
|
102
111
|
</div>
|
103
112
|
</t>
|
104
113
|
</div>
|
105
114
|
</div>
|
115
|
+
<!-- Foot notes -->
|
116
|
+
<div class="oe_mis_builder_footnote_div">
|
117
|
+
<table class="oe_mis_builder_footnote_table">
|
118
|
+
<t
|
119
|
+
t-foreach="sorted(notes.values(),key=lambda r:r['sequence'])"
|
120
|
+
t-as="note"
|
121
|
+
>
|
122
|
+
<tr>
|
123
|
+
<td><t t-out="note['sequence']" />. </td>
|
124
|
+
<td><t t-out="note['text']" /></td>
|
125
|
+
</tr>
|
126
|
+
</t>
|
127
|
+
</table>
|
128
|
+
</div>
|
106
129
|
</div>
|
107
130
|
</t>
|
108
131
|
</t>
|
@@ -6,7 +6,7 @@ import numbers
|
|
6
6
|
from collections import defaultdict
|
7
7
|
from datetime import datetime
|
8
8
|
|
9
|
-
from odoo import _, fields, models
|
9
|
+
from odoo import _, api, fields, models
|
10
10
|
|
11
11
|
from ..models.accounting_none import AccountingNone
|
12
12
|
from ..models.data_error import DataError
|
@@ -26,9 +26,18 @@ class MisBuilderXlsx(models.AbstractModel):
|
|
26
26
|
_description = "MIS Builder XLSX report"
|
27
27
|
_inherit = "report.report_xlsx.abstract"
|
28
28
|
|
29
|
+
@api.model
|
30
|
+
def _mis_builder_add_annotation(self, sheet, cell, row_pos, col_pos, notes):
|
31
|
+
"""
|
32
|
+
Add anotation as a comment on cell in .xls
|
33
|
+
"""
|
34
|
+
if cell and (annotation := notes.get(cell.cell_id, {}).get("text")):
|
35
|
+
sheet.write_comment(row_pos, col_pos, annotation)
|
36
|
+
|
29
37
|
def generate_xlsx_report(self, workbook, data, objects):
|
30
38
|
# get the computed result of the report
|
31
39
|
matrix = objects._compute_matrix()
|
40
|
+
notes = objects.get_notes_by_cell_id()
|
32
41
|
style_obj = self.env["mis.report.style"]
|
33
42
|
|
34
43
|
# create worksheet
|
@@ -120,6 +129,7 @@ class MisBuilderXlsx(models.AbstractModel):
|
|
120
129
|
)
|
121
130
|
for cell in row.iter_cells():
|
122
131
|
col_pos += 1
|
132
|
+
self._mis_builder_add_annotation(sheet, cell, row_pos, col_pos, notes)
|
123
133
|
if not cell or cell.val is AccountingNone:
|
124
134
|
# TODO col/subcol format
|
125
135
|
sheet.write(row_pos, col_pos, "", row_format)
|
@@ -20,3 +20,5 @@ access_mis_report_subreport,access_mis_report_subreport,model_mis_report_subrepo
|
|
20
20
|
manage_mis_report_style,access_mis_report_style,model_mis_report_style,account.group_account_manager,1,1,1,1
|
21
21
|
access_mis_report_style,access_mis_report_style,model_mis_report_style,base.group_user,1,0,0,0
|
22
22
|
access_add_to_dashboard_wizard,access_add_to_dashboard_wizard,model_add_mis_report_instance_dashboard_wizard,base.group_user,1,1,1,0
|
23
|
+
access_read_mis_report_annotation, access_read_mis_report_annotation,model_mis_report_instance_annotation,mis_builder.group_read_annotation,1,0,0,0
|
24
|
+
access_edit_mis_report_annotation, access_edit_mis_report_annotation,model_mis_report_instance_annotation,mis_builder.group_edit_annotation,1,1,1,1
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8" ?>
|
2
|
+
<odoo>
|
3
|
+
<record model="res.groups" id="group_read_annotation">
|
4
|
+
<field name="name">MIS Report: view annotations</field>
|
5
|
+
</record>
|
6
|
+
<record model="res.groups" id="group_edit_annotation">
|
7
|
+
<field name="name">MIS Report: add annotations</field>
|
8
|
+
<field
|
9
|
+
name="implied_ids"
|
10
|
+
eval="[Command.link(ref('mis_builder.group_read_annotation'))]"
|
11
|
+
/>
|
12
|
+
<field
|
13
|
+
name="users"
|
14
|
+
eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"
|
15
|
+
/>
|
16
|
+
</record>
|
17
|
+
</odoo>
|
@@ -367,7 +367,7 @@ ul.auto-toc {
|
|
367
367
|
!! This file is generated by oca-gen-addon-readme !!
|
368
368
|
!! changes will be overwritten. !!
|
369
369
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
370
|
-
!! source digest: sha256:
|
370
|
+
!! source digest: sha256:ce5435756f965a1651bfcff766931db176c696dbcedb0a99ce8e61f003c9b09d
|
371
371
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
372
372
|
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Production/Stable" src="https://img.shields.io/badge/maturity-Production%2FStable-green.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/mis-builder/tree/16.0/mis_builder"><img alt="OCA/mis-builder" src="https://img.shields.io/badge/github-OCA%2Fmis--builder-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/mis-builder-16-0/mis-builder-16-0-mis_builder"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/mis-builder&target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
|
373
373
|
<p>This module allows you to build Management Information Systems dashboards.
|
@@ -65,3 +65,35 @@
|
|
65
65
|
flex-grow: 1;
|
66
66
|
justify-content: flex-end;
|
67
67
|
}
|
68
|
+
|
69
|
+
.oe_mis_builder_dropdown {
|
70
|
+
overflow: visible !important;
|
71
|
+
}
|
72
|
+
|
73
|
+
.oe_mis_builder_footnote {
|
74
|
+
font-size: 80%;
|
75
|
+
color: red;
|
76
|
+
position: relative;
|
77
|
+
bottom: 1ex;
|
78
|
+
width: 1em;
|
79
|
+
display: inline-block;
|
80
|
+
padding-right: 1px;
|
81
|
+
}
|
82
|
+
|
83
|
+
.oe_mis_builder_footnote_table {
|
84
|
+
list-style: none;
|
85
|
+
white-space: pre-wrap;
|
86
|
+
display: inline-block;
|
87
|
+
|
88
|
+
td {
|
89
|
+
vertical-align: top;
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
.oe_mis_builder_footnote_div {
|
94
|
+
padding-top: 1em;
|
95
|
+
}
|
96
|
+
|
97
|
+
.oe_mis_builder_menu_disabled {
|
98
|
+
color: gainsboro;
|
99
|
+
}
|
@@ -1,13 +1,15 @@
|
|
1
1
|
/** @odoo-module **/
|
2
2
|
|
3
|
+
import Dialog from "web.Dialog";
|
3
4
|
import {Component, onWillStart, useState, useSubEnv} from "@odoo/owl";
|
4
|
-
import {useBus, useService} from "@web/core/utils/hooks";
|
5
5
|
import {DatePicker} from "@web/core/datepicker/datepicker";
|
6
6
|
import {FilterMenu} from "@web/search/filter_menu/filter_menu";
|
7
7
|
import {SearchBar} from "@web/search/search_bar/search_bar";
|
8
8
|
import {SearchModel} from "@web/search/search_model";
|
9
9
|
import {parseDate} from "@web/core/l10n/dates";
|
10
|
+
import {qweb} from "web.core";
|
10
11
|
import {registry} from "@web/core/registry";
|
12
|
+
import {useBus, useService} from "@web/core/utils/hooks";
|
11
13
|
|
12
14
|
export class MisReportWidget extends Component {
|
13
15
|
setup() {
|
@@ -18,8 +20,10 @@ export class MisReportWidget extends Component {
|
|
18
20
|
this.view = useService("view");
|
19
21
|
this.JSON = JSON;
|
20
22
|
this.state = useState({
|
21
|
-
mis_report_data: {header: [], body: []},
|
23
|
+
mis_report_data: {header: [], body: [], notes: {}},
|
22
24
|
pivot_date: null,
|
25
|
+
can_edit_annotation: false,
|
26
|
+
can_read_annotation: false,
|
23
27
|
});
|
24
28
|
this.searchModel = new SearchModel(this.env, {
|
25
29
|
user: this.user,
|
@@ -46,6 +50,8 @@ export class MisReportWidget extends Component {
|
|
46
50
|
"widget_search_view_id",
|
47
51
|
"pivot_date",
|
48
52
|
"widget_show_pivot_date",
|
53
|
+
"user_can_read_annotation",
|
54
|
+
"user_can_edit_annotation",
|
49
55
|
],
|
50
56
|
{context: this.context}
|
51
57
|
);
|
@@ -66,6 +72,8 @@ export class MisReportWidget extends Component {
|
|
66
72
|
|
67
73
|
// Compute the report
|
68
74
|
this.refresh();
|
75
|
+
this.state.can_edit_annotation = result.user_can_edit_annotation;
|
76
|
+
this.state.can_read_annotation = result.user_can_read_annotation;
|
69
77
|
}
|
70
78
|
|
71
79
|
get showSearchBar() {
|
@@ -121,7 +129,7 @@ export class MisReportWidget extends Component {
|
|
121
129
|
}
|
122
130
|
|
123
131
|
async drilldown(event) {
|
124
|
-
const drilldown =
|
132
|
+
const drilldown = JSON.parse(event.target.dataset.drilldown);
|
125
133
|
const action = await this.orm.call(
|
126
134
|
"mis.report.instance",
|
127
135
|
"drilldown",
|
@@ -140,6 +148,15 @@ export class MisReportWidget extends Component {
|
|
140
148
|
);
|
141
149
|
}
|
142
150
|
|
151
|
+
async refresh_annotation() {
|
152
|
+
this.state.mis_report_data.notes = await this.orm.call(
|
153
|
+
"mis.report.instance",
|
154
|
+
"get_notes_by_cell_id",
|
155
|
+
[this._instanceId()],
|
156
|
+
{context: this.context}
|
157
|
+
);
|
158
|
+
}
|
159
|
+
|
143
160
|
async printPdf() {
|
144
161
|
const action = await this.orm.call(
|
145
162
|
"mis.report.instance",
|
@@ -170,6 +187,69 @@ export class MisReportWidget extends Component {
|
|
170
187
|
this.action.doAction(action);
|
171
188
|
}
|
172
189
|
|
190
|
+
async _remove_annotation(cell_id) {
|
191
|
+
await this.orm.call(
|
192
|
+
"mis.report.instance.annotation",
|
193
|
+
"remove_annotation",
|
194
|
+
[cell_id, this._instanceId()],
|
195
|
+
{context: this.context}
|
196
|
+
);
|
197
|
+
this.refresh_annotation();
|
198
|
+
}
|
199
|
+
|
200
|
+
async _save_annotation(cell_id) {
|
201
|
+
const text = document.querySelector(".o_mis_builder_annotation_text").value;
|
202
|
+
await this.orm.call(
|
203
|
+
"mis.report.instance.annotation",
|
204
|
+
"set_annotation",
|
205
|
+
[cell_id, this._instanceId(), text],
|
206
|
+
{context: this.context}
|
207
|
+
);
|
208
|
+
await this.refresh_annotation();
|
209
|
+
}
|
210
|
+
|
211
|
+
async annotate(event) {
|
212
|
+
const cell_id = event.target.dataset.cellId;
|
213
|
+
const note = this.state.mis_report_data.notes[cell_id];
|
214
|
+
const note_text = (note && note.text) || "";
|
215
|
+
var buttons = [
|
216
|
+
{
|
217
|
+
text: this.env._t("Save"),
|
218
|
+
classes: "btn-primary",
|
219
|
+
close: true,
|
220
|
+
click: this._save_annotation.bind(this, cell_id),
|
221
|
+
},
|
222
|
+
{
|
223
|
+
text: this.env._t("Cancel"),
|
224
|
+
close: true,
|
225
|
+
},
|
226
|
+
];
|
227
|
+
if (typeof note !== "undefined") {
|
228
|
+
buttons.push({
|
229
|
+
text: this.env._t("Remove"),
|
230
|
+
classes: "btn-secondary",
|
231
|
+
close: true,
|
232
|
+
click: this._remove_annotation.bind(this, cell_id),
|
233
|
+
});
|
234
|
+
}
|
235
|
+
|
236
|
+
new Dialog(this, {
|
237
|
+
title: "Annotate",
|
238
|
+
size: "medium",
|
239
|
+
$content: $(
|
240
|
+
qweb.render("mis_builder.annotation_dialog", {
|
241
|
+
text: note_text,
|
242
|
+
})
|
243
|
+
),
|
244
|
+
buttons: buttons,
|
245
|
+
}).open();
|
246
|
+
}
|
247
|
+
|
248
|
+
async remove_annotation(event) {
|
249
|
+
const cell_id = event.target.dataset.cellId;
|
250
|
+
this._remove_annotation(cell_id);
|
251
|
+
}
|
252
|
+
|
173
253
|
onDateTimeChanged(ev) {
|
174
254
|
this.state.pivot_date = ev;
|
175
255
|
this.refresh();
|
@@ -4,6 +4,7 @@
|
|
4
4
|
<t t-name="mis_builder.MisReportWidget" owl="1">
|
5
5
|
<div class="oe_mis_builder_content">
|
6
6
|
<t t-if="state.mis_report_data">
|
7
|
+
<t t-set="notes" t-value="state.mis_report_data.notes" />
|
7
8
|
<div class="oe_mis_builder_cp">
|
8
9
|
<div class="oe_mis_builder_cp_left">
|
9
10
|
</div>
|
@@ -85,21 +86,65 @@
|
|
85
86
|
t-as="cell"
|
86
87
|
t-key="cell_index"
|
87
88
|
t-att="{'style': cell.style, 'title': cell.val_c}"
|
88
|
-
class="mis_builder_amount"
|
89
|
+
class="mis_builder_amount oe_mis_builder_dropdown"
|
89
90
|
>
|
90
|
-
<
|
91
|
-
<
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
91
|
+
<div>
|
92
|
+
<t t-if="cell.drilldown_arg">
|
93
|
+
<a
|
94
|
+
href="javascript:void(0)"
|
95
|
+
class="mis_builder_drilldown"
|
96
|
+
t-on-click="drilldown"
|
97
|
+
t-att-data-drilldown="JSON.stringify(cell.drilldown_arg)"
|
98
|
+
>
|
99
|
+
<t t-esc="cell.val_r" />
|
100
|
+
</a>
|
101
|
+
</t>
|
102
|
+
<t t-else="">
|
97
103
|
<t t-esc="cell.val_r" />
|
98
|
-
</
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
104
|
+
</t>
|
105
|
+
<span class="oe_mis_builder_footnote">
|
106
|
+
<div t-if="notes[cell.cell_id]">
|
107
|
+
<a
|
108
|
+
t-att-id="'note_'+notes[cell.cell_id].sequence"
|
109
|
+
t-out="notes[cell.cell_id] and notes[cell.cell_id].sequence"
|
110
|
+
t-att="{'title': notes[cell.cell_id].text}"
|
111
|
+
href="#footnotes"
|
112
|
+
/>
|
113
|
+
</div>
|
114
|
+
</span>
|
115
|
+
|
116
|
+
<div id="dropdown_menu" class="btn-group">
|
117
|
+
<div
|
118
|
+
class="dropdown"
|
119
|
+
t-if="state.can_edit_annotation and cell.can_be_annotated"
|
120
|
+
>
|
121
|
+
<div
|
122
|
+
data-bs-toggle="dropdown"
|
123
|
+
t-attf-class="dropdown-toggle"
|
124
|
+
/>
|
125
|
+
|
126
|
+
<div
|
127
|
+
class="dropdown-menu o_filter_menu"
|
128
|
+
role="menu"
|
129
|
+
>
|
130
|
+
<a
|
131
|
+
href="javascript:void(0)"
|
132
|
+
t-on-click="annotate"
|
133
|
+
t-att-data-cell-id="cell.cell_id"
|
134
|
+
role="menuitem"
|
135
|
+
class="dropdown-item js_tag"
|
136
|
+
>
|
137
|
+
Annotate
|
138
|
+
</a>
|
139
|
+
</div>
|
140
|
+
</div>
|
141
|
+
<!-- show menu as disabled -->
|
142
|
+
<div
|
143
|
+
t-else=""
|
144
|
+
class="dropdown-toggle oe_mis_builder_menu_disabled"
|
145
|
+
/>
|
146
|
+
</div>
|
147
|
+
</div>
|
103
148
|
</td>
|
104
149
|
</tr>
|
105
150
|
</tbody>
|
@@ -108,8 +153,44 @@
|
|
108
153
|
</tfoot>
|
109
154
|
</table>
|
110
155
|
</div>
|
156
|
+
<!-- Adding notes -->
|
157
|
+
<div class="oe_mis_builder_footnote_div" id="footnotes">
|
158
|
+
<table class="oe_mis_builder_footnote_table">
|
159
|
+
<t
|
160
|
+
t-foreach="state.mis_report_data.notes"
|
161
|
+
t-as="cell_id"
|
162
|
+
t-key="cell_id"
|
163
|
+
>
|
164
|
+
<tr>
|
165
|
+
<td><a
|
166
|
+
t-out="notes[cell_id].sequence"
|
167
|
+
t-att-href="'#note_'+notes[cell_id].sequence"
|
168
|
+
/>. </td>
|
169
|
+
<td><t t-out="notes[cell_id].text" /></td>
|
170
|
+
<td><i
|
171
|
+
href="javascript:void(0)"
|
172
|
+
t-on-click="remove_annotation"
|
173
|
+
t-att-data-cell-id="cell_id"
|
174
|
+
class="btn fa fa-trash-o"
|
175
|
+
t-if="state.can_edit_annotation"
|
176
|
+
/></td>
|
177
|
+
</tr>
|
178
|
+
</t>
|
179
|
+
</table>
|
180
|
+
</div>
|
111
181
|
</t>
|
112
182
|
</div>
|
113
183
|
</t>
|
114
184
|
|
185
|
+
<t t-name="mis_builder.annotation_dialog">
|
186
|
+
<form role="form">
|
187
|
+
<textarea
|
188
|
+
class="o_mis_builder_annotation_text"
|
189
|
+
name="note"
|
190
|
+
rows='4'
|
191
|
+
placeholder="Insert note here"
|
192
|
+
><t t-out="text" t-att-data-textnote="text" /></textarea>
|
193
|
+
</form>
|
194
|
+
</t>
|
195
|
+
|
115
196
|
</templates>
|
@@ -44,3 +44,25 @@
|
|
44
44
|
.mis_table .mis_cell.mis_amount {
|
45
45
|
text-align: right;
|
46
46
|
}
|
47
|
+
.oe_mis_builder_footnote {
|
48
|
+
font-size: 70%;
|
49
|
+
color: red;
|
50
|
+
position: relative;
|
51
|
+
bottom: 1ex;
|
52
|
+
width: 1em;
|
53
|
+
display: inline-block;
|
54
|
+
padding-right: 1px;
|
55
|
+
}
|
56
|
+
.oe_mis_builder_footnote_div {
|
57
|
+
padding-top: 1em;
|
58
|
+
}
|
59
|
+
|
60
|
+
.oe_mis_builder_footnote_table {
|
61
|
+
list-style: none;
|
62
|
+
white-space: pre-wrap;
|
63
|
+
display: inline-block;
|
64
|
+
|
65
|
+
td {
|
66
|
+
vertical-align: top;
|
67
|
+
}
|
68
|
+
}
|
@@ -0,0 +1,154 @@
|
|
1
|
+
# Copyright 2025 ACSONE SA/NV
|
2
|
+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
3
|
+
|
4
|
+
from odoo import Command
|
5
|
+
from odoo.tests.common import TransactionCase
|
6
|
+
|
7
|
+
|
8
|
+
class TestMisReportInstanceAnnotation(TransactionCase):
|
9
|
+
def setUp(self):
|
10
|
+
super().setUp()
|
11
|
+
self.report = self.env["mis.report"].create(
|
12
|
+
dict(
|
13
|
+
name="test report",
|
14
|
+
subkpi_ids=[
|
15
|
+
Command.create(
|
16
|
+
dict(
|
17
|
+
name="subkpi1_report2",
|
18
|
+
description="subkpi 1, report 2",
|
19
|
+
sequence=1,
|
20
|
+
)
|
21
|
+
),
|
22
|
+
Command.create(
|
23
|
+
dict(
|
24
|
+
name="subkpi2_report2",
|
25
|
+
description="subkpi 2, report 2",
|
26
|
+
sequence=2,
|
27
|
+
),
|
28
|
+
),
|
29
|
+
],
|
30
|
+
)
|
31
|
+
)
|
32
|
+
|
33
|
+
self.kpi = self.env["mis.report.kpi"].create(
|
34
|
+
dict(
|
35
|
+
report_id=self.report.id,
|
36
|
+
description="kpi 1",
|
37
|
+
name="k1",
|
38
|
+
multi=True,
|
39
|
+
expression_ids=[
|
40
|
+
Command.create(
|
41
|
+
dict(name="bale[200%]", subkpi_id=self.report.subkpi_ids[0].id),
|
42
|
+
),
|
43
|
+
Command.create(
|
44
|
+
dict(name="balp[200%]", subkpi_id=self.report.subkpi_ids[1].id),
|
45
|
+
),
|
46
|
+
],
|
47
|
+
)
|
48
|
+
)
|
49
|
+
|
50
|
+
self.report_instance = self.env["mis.report.instance"].create(
|
51
|
+
dict(
|
52
|
+
name="test instance",
|
53
|
+
report_id=self.report.id,
|
54
|
+
company_id=self.env.ref("base.main_company").id,
|
55
|
+
period_ids=[
|
56
|
+
Command.create(
|
57
|
+
dict(
|
58
|
+
name="p1",
|
59
|
+
mode="fix",
|
60
|
+
manual_date_from="2013-01-01",
|
61
|
+
manual_date_to="2013-12-31",
|
62
|
+
sequence=1,
|
63
|
+
),
|
64
|
+
),
|
65
|
+
Command.create(
|
66
|
+
dict(
|
67
|
+
name="p2",
|
68
|
+
mode="fix",
|
69
|
+
manual_date_from="2014-01-01",
|
70
|
+
manual_date_to="2014-12-31",
|
71
|
+
sequence=2,
|
72
|
+
),
|
73
|
+
),
|
74
|
+
],
|
75
|
+
)
|
76
|
+
)
|
77
|
+
|
78
|
+
def test_adding_note(self):
|
79
|
+
notes = self.report_instance.get_notes_by_cell_id()
|
80
|
+
|
81
|
+
self.assertEqual({}, notes)
|
82
|
+
|
83
|
+
# report with 4 cells, 2 periods and 2 subkpis
|
84
|
+
matrix = self.report_instance._compute_matrix()
|
85
|
+
cell_ids = [c.cell_id for row in matrix.iter_rows() for c in row.iter_cells()]
|
86
|
+
self.assertEqual(len(cell_ids), 4)
|
87
|
+
|
88
|
+
first_cell_id, second_cell_id, third_cell_id, _fourth_cell_id = cell_ids
|
89
|
+
|
90
|
+
# adding one note
|
91
|
+
self.env["mis.report.instance.annotation"].set_annotation(
|
92
|
+
first_cell_id, self.report_instance.id, "This is a note"
|
93
|
+
)
|
94
|
+
notes = self.report_instance.get_notes_by_cell_id()
|
95
|
+
self.assertDictEqual(
|
96
|
+
{first_cell_id: {"text": "This is a note", "sequence": 1}}, notes
|
97
|
+
)
|
98
|
+
|
99
|
+
# adding another note
|
100
|
+
self.env["mis.report.instance.annotation"].set_annotation(
|
101
|
+
third_cell_id, self.report_instance.id, "This is another note"
|
102
|
+
)
|
103
|
+
notes = self.report_instance.get_notes_by_cell_id()
|
104
|
+
self.assertDictEqual(
|
105
|
+
{
|
106
|
+
first_cell_id: {"text": "This is a note", "sequence": 1},
|
107
|
+
third_cell_id: {"text": "This is another note", "sequence": 2},
|
108
|
+
},
|
109
|
+
notes,
|
110
|
+
)
|
111
|
+
|
112
|
+
self.env["mis.report.instance.annotation"].set_annotation(
|
113
|
+
second_cell_id, self.report_instance.id, "This is third note"
|
114
|
+
)
|
115
|
+
|
116
|
+
notes = self.report_instance.get_notes_by_cell_id()
|
117
|
+
# Last note added should have a sequence of
|
118
|
+
# 2 since it is deplayed in the second cell
|
119
|
+
self.assertDictEqual(
|
120
|
+
{
|
121
|
+
first_cell_id: {"text": "This is a note", "sequence": 1},
|
122
|
+
second_cell_id: {"text": "This is third note", "sequence": 2},
|
123
|
+
third_cell_id: {"text": "This is another note", "sequence": 3},
|
124
|
+
},
|
125
|
+
notes,
|
126
|
+
)
|
127
|
+
|
128
|
+
def test_remove_note(self):
|
129
|
+
notes = self.report_instance.get_notes_by_cell_id()
|
130
|
+
|
131
|
+
self.assertEqual({}, notes)
|
132
|
+
|
133
|
+
# report with 4 cells, 2 periods and 2 subkpis
|
134
|
+
matrix = self.report_instance._compute_matrix()
|
135
|
+
cell_ids = [c.cell_id for row in matrix.iter_rows() for c in row.iter_cells()]
|
136
|
+
self.assertEqual(len(cell_ids), 4)
|
137
|
+
|
138
|
+
first_cell_id = cell_ids[0]
|
139
|
+
|
140
|
+
# adding one note
|
141
|
+
self.env["mis.report.instance.annotation"].set_annotation(
|
142
|
+
first_cell_id, self.report_instance.id, "This is a note"
|
143
|
+
)
|
144
|
+
notes = self.report_instance.get_notes_by_cell_id()
|
145
|
+
self.assertDictEqual(
|
146
|
+
{first_cell_id: {"text": "This is a note", "sequence": 1}}, notes
|
147
|
+
)
|
148
|
+
|
149
|
+
# remove note
|
150
|
+
self.env["mis.report.instance.annotation"].remove_annotation(
|
151
|
+
first_cell_id, self.report_instance.id
|
152
|
+
)
|
153
|
+
notes = self.report_instance.get_notes_by_cell_id()
|
154
|
+
self.assertEqual({}, notes)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: odoo-addon-mis_builder
|
3
|
-
Version: 16.0.5.
|
3
|
+
Version: 16.0.5.3.0
|
4
4
|
Requires-Python: >=3.10
|
5
5
|
Requires-Dist: odoo-addon-date_range>=16.0dev,<16.1dev
|
6
6
|
Requires-Dist: odoo-addon-report_xlsx>=16.0dev,<16.1dev
|
@@ -25,7 +25,7 @@ MIS Builder
|
|
25
25
|
!! This file is generated by oca-gen-addon-readme !!
|
26
26
|
!! changes will be overwritten. !!
|
27
27
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
28
|
-
!! source digest: sha256:
|
28
|
+
!! source digest: sha256:ce5435756f965a1651bfcff766931db176c696dbcedb0a99ce8e61f003c9b09d
|
29
29
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
30
30
|
|
31
31
|
.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
|
{odoo_addon_mis_builder-16.0.5.2.3.1.dist-info → odoo_addon_mis_builder-16.0.5.3.0.dist-info}/RECORD
RENAMED
@@ -1,6 +1,6 @@
|
|
1
|
-
odoo/addons/mis_builder/README.rst,sha256=
|
1
|
+
odoo/addons/mis_builder/README.rst,sha256=vD9IMU_ZgvijmmuWHq7fMwDgkha1csTL9vSlpVq6TDQ,29747
|
2
2
|
odoo/addons/mis_builder/__init__.py,sha256=-8wG-57WxKfMMA5_TFzpubBcfthcsAP5vjTkhXKf7ds,185
|
3
|
-
odoo/addons/mis_builder/__manifest__.py,sha256=
|
3
|
+
odoo/addons/mis_builder/__manifest__.py,sha256=0yG-VBuTKtWqgltaDCRSGvz-XFozsleRMqigYogDuNo,1591
|
4
4
|
odoo/addons/mis_builder/datas/ir_cron.xml,sha256=H5nnz-4CqZPVveJdRoJ_DrBOOsihK4XwOjWcSMYv68A,558
|
5
5
|
odoo/addons/mis_builder/i18n/ca.po,sha256=Bs3X0lNAg5u9K4j3FV6AfrtnWax3TahYE2qJE_ZxfMQ,91012
|
6
6
|
odoo/addons/mis_builder/i18n/de.po,sha256=72QoPmri0QrOKlyON0yeHmlkbeiB7iuScqg7WOZZktg,66321
|
@@ -10,7 +10,7 @@ odoo/addons/mis_builder/i18n/es.po,sha256=ABKI06IcLNihS_yMcWnahn3ewfFdEml-pgvipb
|
|
10
10
|
odoo/addons/mis_builder/i18n/fr.po,sha256=4R-V6LFBJ-CJ-oFFC3gA3M-TVU7F59UWDyqvJDkzdac,84367
|
11
11
|
odoo/addons/mis_builder/i18n/hr.po,sha256=0HSRENH2cNYTqLKEFi-5ZXlUPfA7-FlsBwqZs1gAAYk,68399
|
12
12
|
odoo/addons/mis_builder/i18n/it.po,sha256=2kAHlHSa1Lwz1QmCbbzNumQYpCWhmaWSYmbrYLnSg9M,78909
|
13
|
-
odoo/addons/mis_builder/i18n/mis_builder.pot,sha256=
|
13
|
+
odoo/addons/mis_builder/i18n/mis_builder.pot,sha256=YrzJvZAjN8ndgvW0pTw6CCpgVYgaUyhGIluLjodpN8k,66494
|
14
14
|
odoo/addons/mis_builder/i18n/nl.po,sha256=iLVCTcly1KjsdpKbGPcZo_8j-rXKq_5HmT_GbOFkJag,75742
|
15
15
|
odoo/addons/mis_builder/i18n/nl_NL.po,sha256=gkYGrBvveKcYLBVVKcdMPKFh80E-zTvNaRDgISRHNro,75834
|
16
16
|
odoo/addons/mis_builder/i18n/pt.po,sha256=xU0QA-OajdZo21p_lGZSSPoyyFdVO7Tyc_9W7DCmBfo,65110
|
@@ -19,16 +19,17 @@ odoo/addons/mis_builder/i18n/sv.po,sha256=KvJGM3bbk5fkcQanHIkYUXgInUKAZuIJYH_dxo
|
|
19
19
|
odoo/addons/mis_builder/i18n/tr.po,sha256=gzpQKxv6kF0jDC3Ejm2voQkXIRQgeVNeCvKJBdRF44Y,65266
|
20
20
|
odoo/addons/mis_builder/migrations/16.0.1.0.1/post-migration.py,sha256=kSvTOKc5R8JGQtOAEGQV2pnwW3HHN9KkKf9KsCJXjaE,851
|
21
21
|
odoo/addons/mis_builder/migrations/16.0.5.0.0/end-migrate.py,sha256=YquWWej_lW3mhkYTSQPqEC_BucmxtLRgwGWU1My7fo8,326
|
22
|
-
odoo/addons/mis_builder/models/__init__.py,sha256=
|
22
|
+
odoo/addons/mis_builder/models/__init__.py,sha256=Ou1WincLWBDDFogq4SYTyrJUDwgBbaTEBpZ_WzYbgFI,376
|
23
23
|
odoo/addons/mis_builder/models/accounting_none.py,sha256=6EE6x4slUbyP2TVnHpilsWu8XqWhGZMt79uBOmNLcVs,4156
|
24
24
|
odoo/addons/mis_builder/models/aep.py,sha256=h2FmNgHRJqL8JK0GyhzS03z5yQ83Zo3vPFrKdPuQT8U,26542
|
25
25
|
odoo/addons/mis_builder/models/aggregate.py,sha256=ffOZq2-R7st-1Hsw-lFfiwkMa46ToJZ7m0K6Z9P_gwQ,2892
|
26
26
|
odoo/addons/mis_builder/models/data_error.py,sha256=ltTIrFCbsxYXmdPTVFVJj3ejZxyc83NEsIFQs2s3-L0,442
|
27
27
|
odoo/addons/mis_builder/models/expression_evaluator.py,sha256=honBPA9VOg0q_BOPuB8CkMA_wcoMUMxDbB-ULnjRpb4,2459
|
28
|
-
odoo/addons/mis_builder/models/kpimatrix.py,sha256=
|
28
|
+
odoo/addons/mis_builder/models/kpimatrix.py,sha256=NR3vUKj9Hzi2FVKyAsAC-038FiMN891SxAFo8OLBAAw,21372
|
29
29
|
odoo/addons/mis_builder/models/mis_kpi_data.py,sha256=5lEEXn-j-xBmToJsluitpETQwrtRq5mfcFCv0xaXboM,4185
|
30
30
|
odoo/addons/mis_builder/models/mis_report.py,sha256=Aet1YOlpadf3Cu9XoAnx8GI0kDa5UktI0U_mnj44jZ8,37775
|
31
|
-
odoo/addons/mis_builder/models/mis_report_instance.py,sha256=
|
31
|
+
odoo/addons/mis_builder/models/mis_report_instance.py,sha256=wXYr6T9BpkBDteyGRMpzfHwtb0HO_RFIJbialQr2dAQ,38940
|
32
|
+
odoo/addons/mis_builder/models/mis_report_instance_annotation.py,sha256=NmBTU2sVx39vPmr_3Xv4rH6VwrXKadhWz-WBVYe0Ffc,3496
|
32
33
|
odoo/addons/mis_builder/models/mis_report_style.py,sha256=wN4YVE7oFNXDSoYEIy5oA1qhfTJyJ9LlRHWhaVnQwMw,10668
|
33
34
|
odoo/addons/mis_builder/models/mis_report_subreport.py,sha256=FAGXqbc2XWRAwnRNndBnyemdQE7UtUJ7akTJIn6DM7g,2102
|
34
35
|
odoo/addons/mis_builder/models/mis_safe_eval.py,sha256=F2Xgtmy-gHDvstzq4_yi5BtdWBgyxjpta5fHG2NxRTI,1061
|
@@ -44,21 +45,22 @@ odoo/addons/mis_builder/readme/USAGE.rst,sha256=6LM-M2rlOhx92yghymhJuteAsmxpURqe
|
|
44
45
|
odoo/addons/mis_builder/readme/newsfragments/.gitignore,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
45
46
|
odoo/addons/mis_builder/report/__init__.py,sha256=pSBq9B467Ayg7O9UXh39Zt-B6Fpw7YBbOYkcA6q2avs,200
|
46
47
|
odoo/addons/mis_builder/report/mis_report_instance_qweb.py,sha256=gbI3CoZnsqEEupc0UN874sA3JKjApjRmP5OdsQPSDgM,986
|
47
|
-
odoo/addons/mis_builder/report/mis_report_instance_qweb.xml,sha256=
|
48
|
-
odoo/addons/mis_builder/report/mis_report_instance_xlsx.py,sha256=
|
48
|
+
odoo/addons/mis_builder/report/mis_report_instance_qweb.xml,sha256=6uY04JHKy-IkUmVn_Kwc5CjQ5IHL4EN7fx0W7iMEcNQ,7368
|
49
|
+
odoo/addons/mis_builder/report/mis_report_instance_xlsx.py,sha256=nNH4H50RNXxlf-6XCocyOyOz96Cqg8qWTrT8vxT4Oq8,7054
|
49
50
|
odoo/addons/mis_builder/report/mis_report_instance_xlsx.xml,sha256=mSf1LuG7o32zg3W5rVBSEWIZwGgORanvmkHEIPAil68,487
|
50
|
-
odoo/addons/mis_builder/security/ir.model.access.csv,sha256=
|
51
|
+
odoo/addons/mis_builder/security/ir.model.access.csv,sha256=n7MnRh8Rnwzf7a7OULSwtPwpl7D9XAt2-jzwiJl-gec,2760
|
51
52
|
odoo/addons/mis_builder/security/mis_builder_security.xml,sha256=7ZMedlUf05UKm3bvXgjIxkcm68Jnic4rJdLQGMWNOqM,479
|
53
|
+
odoo/addons/mis_builder/security/res_groups.xml,sha256=IqTHCGCnXshI8yN_M79w4HR62TWxOYOnHmkK7lTwoBs,589
|
52
54
|
odoo/addons/mis_builder/static/description/ex_report_preview.png,sha256=NKBRn70E4m7c8mN3ujhaTRWx8B6sXgZJ0LXHcjc7mFI,96172
|
53
55
|
odoo/addons/mis_builder/static/description/ex_report_settings.png,sha256=T7j_3DUUtdZ6XKsAvJ3uKsK_-GtRl0sRPD68ZOa6ebA,103790
|
54
56
|
odoo/addons/mis_builder/static/description/ex_report_template.png,sha256=c8KgzyGD5QiZNCmxaVR4u3h1K0TJN50uXZWoNsieN8A,100278
|
55
57
|
odoo/addons/mis_builder/static/description/icon.png,sha256=0OCahdqDvaS_CHV97ZCbajW0_AcBLVVvja_EJA2mC6s,4770
|
56
|
-
odoo/addons/mis_builder/static/description/index.html,sha256=
|
57
|
-
odoo/addons/mis_builder/static/src/components/mis_report_widget.css,sha256=
|
58
|
-
odoo/addons/mis_builder/static/src/components/mis_report_widget.esm.js,sha256=
|
59
|
-
odoo/addons/mis_builder/static/src/components/mis_report_widget.xml,sha256=
|
60
|
-
odoo/addons/mis_builder/static/src/css/report.css,sha256=
|
61
|
-
odoo/addons/mis_builder/tests/__init__.py,sha256=
|
58
|
+
odoo/addons/mis_builder/static/description/index.html,sha256=nuCs4Fvh4M7akMHd2kfiKIOyZBlwpwsYhgiYf08MJ3o,55964
|
59
|
+
odoo/addons/mis_builder/static/src/components/mis_report_widget.css,sha256=xN89icJkeHNJH-ZRpUeizAsxDjCLIqi4iHJzXraQHEs,1706
|
60
|
+
odoo/addons/mis_builder/static/src/components/mis_report_widget.esm.js,sha256=2CWXMO4CsaMkT28xbt9jEW6cPvQPhn5hkPmr8hW9awA,8100
|
61
|
+
odoo/addons/mis_builder/static/src/components/mis_report_widget.xml,sha256=p5uQ25jbbDSI99-sO4VV1XT-kGJYpkw2ax5LFySEWpM,10251
|
62
|
+
odoo/addons/mis_builder/static/src/css/report.css,sha256=8JMN0iI83VSZb8faOzDhQfsEmPvkmsg050vP5NOGyWs,1271
|
63
|
+
odoo/addons/mis_builder/tests/__init__.py,sha256=57qzVitbNHIj4Kxj4fb-1sXlajzP0EMSe3P62meboL8,581
|
62
64
|
odoo/addons/mis_builder/tests/common.py,sha256=7LqnpPyJ8yOi5gA4CwiKZaep6NGY_vIDnK36u8WVC1o,1918
|
63
65
|
odoo/addons/mis_builder/tests/fake_models.py,sha256=DWJsXiIVVXZwXfLQ-9TmUs3eM5KBCXibS2qRXgkFt1c,177
|
64
66
|
odoo/addons/mis_builder/tests/test_accounting_none.py,sha256=satnhbRuI4DdWIOpe-mG7sW9KlamgnyvoVaPQlqZ9FA,239
|
@@ -67,6 +69,7 @@ odoo/addons/mis_builder/tests/test_aggregate.py,sha256=ZXEVW0hMZYUIJM6ikQpmBH9Xc
|
|
67
69
|
odoo/addons/mis_builder/tests/test_data_sources.py,sha256=KK8sycuYtaa6o8s2Lzehi3XbYwGVViL-cE3eReOggAk,7792
|
68
70
|
odoo/addons/mis_builder/tests/test_kpi_data.py,sha256=PrgfJIkrw5liJ8InLoXCGXMD-uc7y23J-7R-UYxWIO8,4860
|
69
71
|
odoo/addons/mis_builder/tests/test_mis_report_instance.py,sha256=t3D-0zwr0qTn9ycQKVAGnIyiUzoAf3qEvzYGPhhd8cE,23831
|
72
|
+
odoo/addons/mis_builder/tests/test_mis_report_instance_annotation.py,sha256=o9AUOJBe4tj_VNi5nNA_6cn7LEZ0-8Nhb6QJOYMnB3I,5514
|
70
73
|
odoo/addons/mis_builder/tests/test_mis_safe_eval.py,sha256=Qge84h5xt09ibjMFeho2kKJcBXeAnYElfdHWoyc7j08,900
|
71
74
|
odoo/addons/mis_builder/tests/test_multi_company_aep.py,sha256=hKRjqvHzDvjI7PJGjIB62WLPl9rs_vbtRhdKaJYhcWw,8246
|
72
75
|
odoo/addons/mis_builder/tests/test_period_dates.py,sha256=qUa3qhDAAsjhUwom6SszFdT5h1rCUpYs70U3IqYEfyM,6510
|
@@ -81,7 +84,7 @@ odoo/addons/mis_builder/views/mis_report_style.xml,sha256=HRsXhEZZYbuZg7qJyfhdnE
|
|
81
84
|
odoo/addons/mis_builder/wizard/__init__.py,sha256=qlc_LcwA6U3Wgv-qC9uacPjZXV3jShrV_RBiuKCBNPA,158
|
82
85
|
odoo/addons/mis_builder/wizard/mis_builder_dashboard.py,sha256=DIas3iie9fb2WzJ2eGcrVc7y64IuRyxSG7tJrcV-53g,3404
|
83
86
|
odoo/addons/mis_builder/wizard/mis_builder_dashboard.xml,sha256=ArG86hdyRWm531nK0hYU-j1N87yXtpDVpSuKTmOB47I,1440
|
84
|
-
odoo_addon_mis_builder-16.0.5.
|
85
|
-
odoo_addon_mis_builder-16.0.5.
|
86
|
-
odoo_addon_mis_builder-16.0.5.
|
87
|
-
odoo_addon_mis_builder-16.0.5.
|
87
|
+
odoo_addon_mis_builder-16.0.5.3.0.dist-info/METADATA,sha256=hDp-Vlf6JsMFa_aFx-wykQ5_sYyt4fL9PfQFYWHlIUU,30461
|
88
|
+
odoo_addon_mis_builder-16.0.5.3.0.dist-info/WHEEL,sha256=9fEMia4zL7ZuZbnCOrcYogUhmn4XFIVaJ8G4YGI31xc,81
|
89
|
+
odoo_addon_mis_builder-16.0.5.3.0.dist-info/top_level.txt,sha256=QE6RBQ0QX5f4eFuUcGgU5Kbq1A_qJcDs-e_vpr6pmfU,4
|
90
|
+
odoo_addon_mis_builder-16.0.5.3.0.dist-info/RECORD,,
|
{odoo_addon_mis_builder-16.0.5.2.3.1.dist-info → odoo_addon_mis_builder-16.0.5.3.0.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|