odoo-addon-mis-builder 16.0.5.1.11.2__py3-none-any.whl → 17.0.1.0.0.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. odoo/addons/mis_builder/README.rst +474 -429
  2. odoo/addons/mis_builder/__manifest__.py +1 -1
  3. odoo/addons/mis_builder/i18n/ca.po +5 -18
  4. odoo/addons/mis_builder/i18n/de.po +0 -16
  5. odoo/addons/mis_builder/i18n/el.po +0 -16
  6. odoo/addons/mis_builder/i18n/el_GR.po +0 -16
  7. odoo/addons/mis_builder/i18n/es.po +3 -16
  8. odoo/addons/mis_builder/i18n/fr.po +7 -20
  9. odoo/addons/mis_builder/i18n/hr.po +2 -18
  10. odoo/addons/mis_builder/i18n/it.po +12 -25
  11. odoo/addons/mis_builder/i18n/mis_builder.pot +1 -17
  12. odoo/addons/mis_builder/i18n/nl.po +3 -16
  13. odoo/addons/mis_builder/i18n/nl_NL.po +3 -16
  14. odoo/addons/mis_builder/i18n/pt.po +3 -16
  15. odoo/addons/mis_builder/i18n/pt_BR.po +3 -16
  16. odoo/addons/mis_builder/i18n/sv.po +8 -20
  17. odoo/addons/mis_builder/i18n/tr.po +0 -16
  18. odoo/addons/mis_builder/models/aep.py +1 -1
  19. odoo/addons/mis_builder/models/expression_evaluator.py +1 -1
  20. odoo/addons/mis_builder/models/kpimatrix.py +5 -2
  21. odoo/addons/mis_builder/models/mis_kpi_data.py +1 -3
  22. odoo/addons/mis_builder/models/mis_report.py +18 -19
  23. odoo/addons/mis_builder/models/mis_report_instance.py +4 -9
  24. odoo/addons/mis_builder/readme/CONTRIBUTORS.md +29 -0
  25. odoo/addons/mis_builder/readme/DESCRIPTION.md +5 -0
  26. odoo/addons/mis_builder/readme/DEVELOP.md +7 -0
  27. odoo/addons/mis_builder/readme/HISTORY.md +542 -0
  28. odoo/addons/mis_builder/readme/INSTALL.md +7 -0
  29. odoo/addons/mis_builder/readme/ROADMAP.md +5 -0
  30. odoo/addons/mis_builder/readme/USAGE.md +19 -0
  31. odoo/addons/mis_builder/static/description/index.html +305 -238
  32. odoo/addons/mis_builder/static/src/components/mis_report_widget.esm.js +7 -4
  33. odoo/addons/mis_builder/static/src/components/mis_report_widget.xml +5 -5
  34. odoo/addons/mis_builder/tests/test_aep.py +17 -2
  35. odoo/addons/mis_builder/views/mis_report.xml +7 -11
  36. odoo/addons/mis_builder/views/mis_report_instance.xml +38 -47
  37. odoo/addons/mis_builder/views/mis_report_style.xml +12 -46
  38. odoo_addon_mis_builder-17.0.1.0.0.3.dist-info/METADATA +778 -0
  39. {odoo_addon_mis_builder-16.0.5.1.11.2.dist-info → odoo_addon_mis_builder-17.0.1.0.0.3.dist-info}/RECORD +41 -44
  40. odoo/addons/mis_builder/migrations/16.0.5.0.0/end-migrate.py +0 -10
  41. odoo/addons/mis_builder/migrations/8.0.2.0.0/post-migration.py +0 -29
  42. odoo/addons/mis_builder/migrations/8.0.2.0.0/pre-migration.py +0 -20
  43. odoo/addons/mis_builder/readme/CONTRIBUTORS.rst +0 -27
  44. odoo/addons/mis_builder/readme/DESCRIPTION.rst +0 -5
  45. odoo/addons/mis_builder/readme/DEVELOP.rst +0 -6
  46. odoo/addons/mis_builder/readme/HISTORY.rst +0 -539
  47. odoo/addons/mis_builder/readme/INSTALL.rst +0 -7
  48. odoo/addons/mis_builder/readme/ROADMAP.rst +0 -3
  49. odoo/addons/mis_builder/readme/USAGE.rst +0 -26
  50. odoo_addon_mis_builder-16.0.5.1.11.2.dist-info/METADATA +0 -733
  51. {odoo_addon_mis_builder-16.0.5.1.11.2.dist-info → odoo_addon_mis_builder-17.0.1.0.0.3.dist-info}/WHEEL +0 -0
  52. {odoo_addon_mis_builder-16.0.5.1.11.2.dist-info → odoo_addon_mis_builder-17.0.1.0.0.3.dist-info}/top_level.txt +0 -0
@@ -919,21 +919,6 @@ msgstr "Etiket"
919
919
  msgid "Landscape PDF"
920
920
  msgstr "Yatay PDF"
921
921
 
922
- #. module: mis_builder
923
- #: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard____last_update
924
- #: model:ir.model.fields,field_description:mis_builder.field_mis_report____last_update
925
- #: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance____last_update
926
- #: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period____last_update
927
- #: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum____last_update
928
- #: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi____last_update
929
- #: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression____last_update
930
- #: model:ir.model.fields,field_description:mis_builder.field_mis_report_query____last_update
931
- #: model:ir.model.fields,field_description:mis_builder.field_mis_report_style____last_update
932
- #: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi____last_update
933
- #: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport____last_update
934
- msgid "Last Modified on"
935
- msgstr ""
936
-
937
922
  #. module: mis_builder
938
923
  #: model:ir.actions.act_window,name:mis_builder.last_mis_report_instance_view_action
939
924
  #: model:ir.ui.menu,name:mis_builder.last_wizard_mis_report_instance_view_menu
@@ -1665,7 +1650,6 @@ msgstr ""
1665
1650
 
1666
1651
  #. module: mis_builder
1667
1652
  #: model:ir.actions.server,name:mis_builder.ir_cron_vacuum_temp_reports_ir_actions_server
1668
- #: model:ir.cron,cron_name:mis_builder.ir_cron_vacuum_temp_reports
1669
1653
  msgid "Vacuum temporary reports"
1670
1654
  msgstr ""
1671
1655
 
@@ -543,4 +543,4 @@ class AccountingExpressionProcessor:
543
543
  # TODO shoud we include here the accounts of type "unaffected"
544
544
  # or leave that to the caller?
545
545
  bals = cls._get_balances(cls.MODE_UNALLOCATED, companies, date, date)
546
- return tuple(map(sum, zip(*bals.values()))) # noqa: B905
546
+ return tuple(map(sum, zip(*bals.values(), strict=True)))
@@ -58,7 +58,7 @@ class ExpressionEvaluator:
58
58
  vals = []
59
59
  drilldown_args = []
60
60
  name_error = False
61
- for expr, replaced_expr in zip(exprs, replaced_exprs): # noqa: B905
61
+ for expr, replaced_expr in zip(exprs, replaced_exprs, strict=True):
62
62
  val = mis_safe_eval(replaced_expr, locals_dict)
63
63
  vals.append(val)
64
64
  if replaced_expr != expr:
@@ -234,7 +234,9 @@ class KpiMatrix:
234
234
  cell_tuple = []
235
235
  assert len(vals) == col.colspan
236
236
  assert len(drilldown_args) == col.colspan
237
- for val, drilldown_arg, subcol in zip(vals, drilldown_args, col.iter_subcols()): # noqa: B905
237
+ for val, drilldown_arg, subcol in zip(
238
+ vals, drilldown_args, col.iter_subcols(), strict=True
239
+ ):
238
240
  if isinstance(val, DataError):
239
241
  val_rendered = val.name
240
242
  val_comment = val.msg
@@ -345,10 +347,11 @@ class KpiMatrix:
345
347
  if not common_subkpis or cell.subcol.subkpi in common_subkpis
346
348
  ]
347
349
  comparison_cell_tuple = []
348
- for val, base_val, comparison_subcol in zip( # noqa: B905
350
+ for val, base_val, comparison_subcol in zip(
349
351
  vals,
350
352
  base_vals,
351
353
  comparison_col.iter_subcols(),
354
+ strict=True,
352
355
  ):
353
356
  # TODO FIXME average factors
354
357
  comparison = self._style_model.compare_and_render(
@@ -26,7 +26,7 @@ class MisKpiData(models.AbstractModel):
26
26
  _name = "mis.kpi.data"
27
27
  _description = "MIS Kpi Data Abtract class"
28
28
 
29
- name = fields.Char(compute="_compute_name", required=False, readonly=True)
29
+ name = fields.Char(compute="_compute_name", required=False)
30
30
  kpi_expression_id = fields.Many2one(
31
31
  comodel_name="mis.report.kpi.expression",
32
32
  required=True,
@@ -39,13 +39,11 @@ class MisKpiData(models.AbstractModel):
39
39
  seq1 = fields.Integer(
40
40
  related="kpi_expression_id.kpi_id.sequence",
41
41
  store=True,
42
- readonly=True,
43
42
  string="KPI Sequence",
44
43
  )
45
44
  seq2 = fields.Integer(
46
45
  related="kpi_expression_id.subkpi_id.sequence",
47
46
  store=True,
48
- readonly=True,
49
47
  string="Sub-KPI Sequence",
50
48
  )
51
49
 
@@ -147,18 +147,12 @@ class MisReportKpi(models.Model):
147
147
 
148
148
  _order = "sequence, id"
149
149
 
150
- def name_get(self):
151
- res = []
152
- for rec in self:
153
- name = f"{rec.description} ({rec.name})"
154
- res.append((rec.id, name))
155
- return res
150
+ _rec_names_search = ["name", "description"]
156
151
 
157
- @api.model
158
- def name_search(self, name="", args=None, operator="ilike", limit=100):
159
- domain = args or []
160
- domain += ["|", ("name", operator, name), ("description", operator, name)]
161
- return self.search(domain, limit=limit).name_get()
152
+ @api.depends("description", "name")
153
+ def _compute_display_name(self):
154
+ for rec in self:
155
+ rec.display_name = f"{rec.description} ({rec.name})"
162
156
 
163
157
  @api.constrains("name")
164
158
  def _check_name(self):
@@ -292,7 +286,7 @@ class MisReportKpiExpression(models.Model):
292
286
  _description = "MIS Report KPI Expression"
293
287
  _order = "sequence, name, id"
294
288
 
295
- sequence = fields.Integer(related="subkpi_id.sequence", store=True, readonly=True)
289
+ sequence = fields.Integer(related="subkpi_id.sequence", store=True)
296
290
  name = fields.Char(string="Expression")
297
291
  kpi_id = fields.Many2one("mis.report.kpi", required=True, ondelete="cascade")
298
292
  # TODO FIXME set readonly=True when onchange('subkpi_ids') below works
@@ -306,8 +300,14 @@ class MisReportKpiExpression(models.Model):
306
300
  )
307
301
  ]
308
302
 
309
- def name_get(self):
310
- res = []
303
+ @api.depends(
304
+ "kpi_id.description",
305
+ "subkpi_id.description",
306
+ "kpi_id.name",
307
+ "subkpi_id.name",
308
+ "kpi_id.display_name",
309
+ )
310
+ def _compute_display_name(self):
311
311
  for rec in self:
312
312
  kpi = rec.kpi_id
313
313
  subkpi = rec.subkpi_id
@@ -317,14 +317,13 @@ class MisReportKpiExpression(models.Model):
317
317
  )
318
318
  else:
319
319
  name = rec.kpi_id.display_name
320
- res.append((rec.id, name))
321
- return res
320
+ rec.display_name = name
322
321
 
323
322
  @api.model
324
- def name_search(self, name="", args=None, operator="ilike", limit=100):
323
+ def _name_search(self, name, domain=None, operator="ilike", limit=None, order=None):
325
324
  # TODO maybe implement negative search operators, although
326
325
  # there is not really a use case for that
327
- domain = args or []
326
+ domain = domain or []
328
327
  splitted_name = name.split(".", 2)
329
328
  name_search_domain = []
330
329
  if "." in name:
@@ -354,7 +353,7 @@ class MisReportKpiExpression(models.Model):
354
353
  ]
355
354
  )
356
355
  domain = osv_expression.AND([domain, name_search_domain])
357
- return self.search(domain, limit=limit).name_get()
356
+ return self._search(domain, limit=limit, order=order)
358
357
 
359
358
 
360
359
  class MisReportQuery(models.Model):
@@ -477,7 +477,7 @@ class MisReportInstance(models.Model):
477
477
  _description = "MIS Report Instance"
478
478
 
479
479
  name = fields.Char(required=True, translate=True)
480
- description = fields.Char(related="report_id.description", readonly=True)
480
+ description = fields.Char(related="report_id.description")
481
481
  date = fields.Date(
482
482
  string="Base date", help="Report base date " "(leave empty to use current date)"
483
483
  )
@@ -539,12 +539,10 @@ class MisReportInstance(models.Model):
539
539
  temporary = fields.Boolean(default=False)
540
540
  source_aml_model_id = fields.Many2one(
541
541
  related="report_id.move_lines_source",
542
- readonly=True,
543
542
  )
544
543
  source_aml_model_name = fields.Char(
545
544
  related="source_aml_model_id.model",
546
545
  related_sudo=True,
547
- readonly=True,
548
546
  )
549
547
  analytic_domain = fields.Text(
550
548
  default="[]",
@@ -885,13 +883,10 @@ class MisReportInstance(models.Model):
885
883
  @api.model
886
884
  def _get_drilldown_model_views(self, model_name):
887
885
  self.ensure_one()
888
- types = (
889
- self.env["ir.ui.view"]
890
- .sudo()
891
- ._read_group([("model", "=", model_name)], ["type"], ["type"])
892
- )
886
+ views_records = self.env["ir.ui.view"].search([("model", "=", model_name)])
887
+ views_records = set(views_records.mapped("type"))
893
888
  views_order = self._get_drilldown_views_and_orders()
894
- views = {type["type"] for type in types if type["type"] in views_order}
889
+ views = {view_type for view_type in views_records if view_type in views_order}
895
890
  return sorted(list(views), key=lambda x: views_order[x])
896
891
 
897
892
  def drilldown(self, arg):
@@ -0,0 +1,29 @@
1
+ - Stéphane Bidoul \<<stephane.bidoul@acsone.eu>\>
2
+ - Laetitia Gangloff \<<laetitia.gangloff@acsone.eu>\>
3
+ - Adrien Peiffer \<<adrien.peiffer@acsone.eu>\>
4
+ - Alexis de Lattre \<<alexis.delattre@akretion.com>\>
5
+ - Alexandre Fayolle \<<alexandre.fayolle@camptocamp.com>\>
6
+ - Jordi Ballester \<<jordi.ballester@eficent.com>\>
7
+ - Thomas Binsfeld \<<thomas.binsfeld@gmail.com>\>
8
+ - Giovanni Capalbo \<<giovanni@therp.nl>\>
9
+ - Marco Calcagni \<<mcalcagni@dinamicheaziendali.it>\>
10
+ - Sébastien Beau \<<sebastien.beau@akretion.com>\>
11
+ - Laurent Mignon \<<laurent.mignon@acsone.eu>\>
12
+ - Luc De Meyer \<<luc.demeyer@noviat.com>\>
13
+ - Benjamin Willig \<<benjamin.willig@acsone.eu>\>
14
+ - Martronic SA \<<info@martronic.ch>\>
15
+ - nicomacr \<<nmr@adhoc.com.ar>\>
16
+ - Juan Jose Scarafia \<<jjs@adhoc.com.ar>\>
17
+ - Richard deMeester \<<richard@willowit.com.au>\>
18
+ - Eric Caudal \<<eric.caudal@elico-corp.com>\>
19
+ - Andrea Stirpe \<<a.stirpe@onestein.nl>\>
20
+ - Maxence Groine \<<mgroine@fiefmanage.ch>\>
21
+ - Arnaud Pineux \<<arnaud.pineux@acsone.eu>\>
22
+ - Ernesto Tejeda \<<ernesto.tejeda@tecnativa.com>\>
23
+ - Pedro M. Baeza \<<pedro.baeza@tecnativa.com>\>
24
+ - Alexey Pelykh \<<alexey.pelykh@corphub.eu>\>
25
+ - Jairo Llopis (<https://www.moduon.team/>)
26
+ - Dzung Tran \<<dungtd@trobz.com>\>
27
+ - Hoang Diep \<<hoang@trobz.com>\>
28
+ - Miquel Pascual \<<mpascual@apsl.net>\>
29
+ - Antoni Marroig \<<amarroig@apsl.net>\>
@@ -0,0 +1,5 @@
1
+ This module allows you to build Management Information Systems
2
+ dashboards. Such style of reports presents KPI in rows and time periods
3
+ in columns. Reports mainly fetch data from account moves, but can also
4
+ combine data coming from arbitrary Odoo models. Reports can be exported
5
+ to PDF, Excel and they can be added to Odoo dashboards.
@@ -0,0 +1,7 @@
1
+ A typical extension is to provide a mechanism to filter reports on
2
+ analytic dimensions or operational units. To implement this, you can
3
+ override \_get_additional_move_line_filter and \_get_additional_filter
4
+ to further filter move lines or queries based on a user selection. A
5
+ typical use case could be to add an analytic account field on
6
+ mis.report.instance, or even on mis.report.instance.period if you want
7
+ different columns to show different analytic accounts.