odoo-addon-mis-builder 17.0.1.3.0__py3-none-any.whl → 18.0.1.1.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.
Files changed (55) hide show
  1. odoo/addons/mis_builder/README.rst +7 -6
  2. odoo/addons/mis_builder/__manifest__.py +1 -1
  3. odoo/addons/mis_builder/datas/ir_cron.xml +1 -3
  4. odoo/addons/mis_builder/i18n/ca.po +8 -51
  5. odoo/addons/mis_builder/i18n/de.po +4 -39
  6. odoo/addons/mis_builder/i18n/el.po +4 -39
  7. odoo/addons/mis_builder/i18n/el_GR.po +4 -39
  8. odoo/addons/mis_builder/i18n/es.po +12 -65
  9. odoo/addons/mis_builder/i18n/fr.po +12 -65
  10. odoo/addons/mis_builder/i18n/hr.po +4 -39
  11. odoo/addons/mis_builder/i18n/it.po +13 -80
  12. odoo/addons/mis_builder/i18n/mis_builder.pot +18 -125
  13. odoo/addons/mis_builder/i18n/nl.po +4 -39
  14. odoo/addons/mis_builder/i18n/nl_NL.po +4 -39
  15. odoo/addons/mis_builder/i18n/pt.po +4 -39
  16. odoo/addons/mis_builder/i18n/pt_BR.po +13 -64
  17. odoo/addons/mis_builder/i18n/sv.po +12 -64
  18. odoo/addons/mis_builder/i18n/tr.po +4 -39
  19. odoo/addons/mis_builder/i18n/zh_CN.po +78 -154
  20. odoo/addons/mis_builder/models/aep.py +62 -160
  21. odoo/addons/mis_builder/models/aggregate.py +4 -4
  22. odoo/addons/mis_builder/models/kpimatrix.py +9 -10
  23. odoo/addons/mis_builder/models/mis_kpi_data.py +5 -7
  24. odoo/addons/mis_builder/models/mis_report.py +47 -58
  25. odoo/addons/mis_builder/models/mis_report_instance.py +43 -24
  26. odoo/addons/mis_builder/models/mis_report_style.py +9 -12
  27. odoo/addons/mis_builder/models/mis_report_subreport.py +5 -4
  28. odoo/addons/mis_builder/models/prorata_read_group_mixin.py +51 -31
  29. odoo/addons/mis_builder/models/simple_array.py +2 -2
  30. odoo/addons/mis_builder/readme/CONTRIBUTORS.md +1 -0
  31. odoo/addons/mis_builder/report/mis_report_instance_xlsx.py +2 -2
  32. odoo/addons/mis_builder/static/description/index.html +5 -4
  33. odoo/addons/mis_builder/static/src/components/mis_report_widget.esm.js +38 -22
  34. odoo/addons/mis_builder/static/src/components/mis_report_widget.scss +9 -0
  35. odoo/addons/mis_builder/static/src/components/mis_report_widget.xml +16 -14
  36. odoo/addons/mis_builder/tests/__init__.py +1 -0
  37. odoo/addons/mis_builder/tests/common.py +2 -4
  38. odoo/addons/mis_builder/tests/fake_models.py +18 -1
  39. odoo/addons/mis_builder/tests/test_aep.py +7 -69
  40. odoo/addons/mis_builder/tests/test_data_sources.py +4 -11
  41. odoo/addons/mis_builder/tests/test_kpi_data.py +1 -5
  42. odoo/addons/mis_builder/tests/test_mis_report_instance.py +21 -17
  43. odoo/addons/mis_builder/tests/test_multi_company_aep.py +3 -3
  44. odoo/addons/mis_builder/tests/test_pro_rata_read_group.py +105 -0
  45. odoo/addons/mis_builder/views/mis_report.xml +38 -43
  46. odoo/addons/mis_builder/views/mis_report_instance.xml +38 -40
  47. odoo/addons/mis_builder/views/mis_report_style.xml +6 -6
  48. odoo/addons/mis_builder/wizard/mis_builder_dashboard.py +3 -3
  49. odoo/addons/mis_builder/wizard/mis_builder_dashboard.xml +6 -6
  50. {odoo_addon_mis_builder-17.0.1.3.0.dist-info → odoo_addon_mis_builder-18.0.1.1.0.dist-info}/METADATA +12 -11
  51. odoo_addon_mis_builder-18.0.1.1.0.dist-info/RECORD +87 -0
  52. odoo/addons/mis_builder/static/src/components/mis_report_widget.css +0 -67
  53. odoo_addon_mis_builder-17.0.1.3.0.dist-info/RECORD +0 -87
  54. {odoo_addon_mis_builder-17.0.1.3.0.dist-info → odoo_addon_mis_builder-18.0.1.1.0.dist-info}/WHEEL +0 -0
  55. {odoo_addon_mis_builder-17.0.1.3.0.dist-info → odoo_addon_mis_builder-18.0.1.1.0.dist-info}/top_level.txt +0 -0
@@ -372,9 +372,9 @@ ul.auto-toc {
372
372
  !! This file is generated by oca-gen-addon-readme !!
373
373
  !! changes will be overwritten. !!
374
374
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
375
- !! source digest: sha256:2ed9706cd2c7f3f56656de55ed302d05a53454a8f2a9ecce54637bb6567b5095
375
+ !! source digest: sha256:c05ba1bbf62201faf2da2110acb172e61430e70cbaaa3c624a599c8f823405e0
376
376
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
377
- <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/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/mis-builder/tree/17.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-17-0/mis-builder-17-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&amp;target_branch=17.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
377
+ <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/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/mis-builder/tree/18.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-18-0/mis-builder-18-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&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
378
378
  <p>This module allows you to build Management Information Systems
379
379
  dashboards. Such style of reports presents KPI in rows and time periods
380
380
  in columns. Reports mainly fetch data from account moves, but can also
@@ -1086,7 +1086,7 @@ previews. <a class="reference external" href="https://github.com/OCA/account-fin
1086
1086
  <p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/mis-builder/issues">GitHub Issues</a>.
1087
1087
  In case of trouble, please check there if your issue has already been reported.
1088
1088
  If you spotted it first, help us to smash it by providing a detailed and welcomed
1089
- <a class="reference external" href="https://github.com/OCA/mis-builder/issues/new?body=module:%20mis_builder%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
1089
+ <a class="reference external" href="https://github.com/OCA/mis-builder/issues/new?body=module:%20mis_builder%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
1090
1090
  <p>Do not contact contributors directly about support or help with technical issues.</p>
1091
1091
  </div>
1092
1092
  <div class="section" id="credits">
@@ -1129,6 +1129,7 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
1129
1129
  <li>Hoang Diep &lt;<a class="reference external" href="mailto:hoang&#64;trobz.com">hoang&#64;trobz.com</a>&gt;</li>
1130
1130
  <li>Miquel Pascual &lt;<a class="reference external" href="mailto:mpascual&#64;apsl.net">mpascual&#64;apsl.net</a>&gt;</li>
1131
1131
  <li>Antoni Marroig &lt;<a class="reference external" href="mailto:amarroig&#64;apsl.net">amarroig&#64;apsl.net</a>&gt;</li>
1132
+ <li>Chau Le &lt;<a class="reference external" href="mailto:chaulb&#64;trobz.com">chaulb&#64;trobz.com</a>&gt;</li>
1132
1133
  </ul>
1133
1134
  </div>
1134
1135
  <div class="section" id="maintainers">
@@ -1142,7 +1143,7 @@ mission is to support the collaborative development of Odoo features and
1142
1143
  promote its widespread use.</p>
1143
1144
  <p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p>
1144
1145
  <p><a class="reference external image-reference" href="https://github.com/sbidoul"><img alt="sbidoul" src="https://github.com/sbidoul.png?size=40px" /></a></p>
1145
- <p>This module is part of the <a class="reference external" href="https://github.com/OCA/mis-builder/tree/17.0/mis_builder">OCA/mis-builder</a> project on GitHub.</p>
1146
+ <p>This module is part of the <a class="reference external" href="https://github.com/OCA/mis-builder/tree/18.0/mis_builder">OCA/mis-builder</a> project on GitHub.</p>
1146
1147
  <p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
1147
1148
  </div>
1148
1149
  </div>
@@ -1,6 +1,4 @@
1
- /** @odoo-module **/
2
-
3
- import {Component, onWillStart, useState, useSubEnv} from "@odoo/owl";
1
+ import {Component, onMounted, onWillStart, useState, useSubEnv} from "@odoo/owl";
4
2
  import {useBus, useService} from "@web/core/utils/hooks";
5
3
  import {DateTimeInput} from "@web/core/datetime/datetime_input";
6
4
  import {SearchBar} from "@web/search/search_bar/search_bar";
@@ -12,7 +10,6 @@ export class MisReportWidget extends Component {
12
10
  setup() {
13
11
  super.setup();
14
12
  this.orm = useService("orm");
15
- this.user = useService("user");
16
13
  this.action = useService("action");
17
14
  this.view = useService("view");
18
15
  this.JSON = JSON;
@@ -21,7 +18,6 @@ export class MisReportWidget extends Component {
21
18
  pivot_date: null,
22
19
  });
23
20
  this.searchModel = new SearchModel(this.env, {
24
- user: this.user,
25
21
  orm: this.orm,
26
22
  view: this.view,
27
23
  });
@@ -31,6 +27,8 @@ export class MisReportWidget extends Component {
31
27
  this.refresh();
32
28
  });
33
29
  onWillStart(this.willStart);
30
+
31
+ onMounted(this._onMounted);
34
32
  }
35
33
 
36
34
  // Lifecycle
@@ -45,16 +43,18 @@ export class MisReportWidget extends Component {
45
43
  "widget_search_view_id",
46
44
  "pivot_date",
47
45
  "widget_show_pivot_date",
46
+ "wide_display_by_default",
48
47
  ],
49
48
  {context: this.context}
50
49
  );
50
+
51
51
  this.source_aml_model_name = result.source_aml_model_name;
52
52
  this.widget_show_filters = result.widget_show_filters;
53
53
  this.widget_show_settings_button = result.widget_show_settings_button;
54
- this.widget_search_view_id =
55
- result.widget_search_view_id && result.widget_search_view_id[0];
54
+ this.widget_search_view_id = result.widget_search_view_id?.[0];
56
55
  this.state.pivot_date = parseDate(result.pivot_date);
57
56
  this.widget_show_pivot_date = result.widget_show_pivot_date;
57
+
58
58
  if (this.showSearchBar) {
59
59
  // Initialize the search model
60
60
  await this.searchModel.load({
@@ -63,10 +63,16 @@ export class MisReportWidget extends Component {
63
63
  });
64
64
  }
65
65
 
66
+ this.wide_display = result.wide_display_by_default;
67
+
66
68
  // Compute the report
67
69
  this.refresh();
68
70
  }
69
71
 
72
+ async _onMounted() {
73
+ this.resize_sheet();
74
+ }
75
+
70
76
  get showSearchBar() {
71
77
  return (
72
78
  this.source_aml_model_name &&
@@ -96,31 +102,25 @@ export class MisReportWidget extends Component {
96
102
  * of Odoo dashboards that are not designed to contain forms but
97
103
  * rather tree views or charts.
98
104
  */
99
- var context = this.props.record.context;
105
+ const context = this.props.record.context;
100
106
  if (context.active_model === "mis.report.instance") {
101
107
  return context.active_id;
102
108
  }
103
109
  }
104
110
 
105
111
  get context() {
106
- var ctx = super.context;
107
- if (this.showSearchBar) {
108
- ctx = {
109
- ...ctx,
112
+ return {
113
+ ...super.context,
114
+ ...(this.showSearchBar && {
110
115
  mis_analytic_domain: this.searchModel.searchDomain,
111
- };
112
- }
113
- if (this.showPivotDate && this.state.pivot_date) {
114
- ctx = {
115
- ...ctx,
116
- mis_pivot_date: this.state.pivot_date,
117
- };
118
- }
119
- return ctx;
116
+ }),
117
+ ...(this.showPivotDate &&
118
+ this.state.pivot_date && {mis_pivot_date: this.state.pivot_date}),
119
+ };
120
120
  }
121
121
 
122
122
  async drilldown(event) {
123
- const drilldown = $(event.target).data("drilldown");
123
+ const drilldown = JSON.parse(event.target.dataset.drilldown);
124
124
  const action = await this.orm.call(
125
125
  "mis.report.instance",
126
126
  "drilldown",
@@ -173,6 +173,22 @@ export class MisReportWidget extends Component {
173
173
  this.state.pivot_date = ev;
174
174
  this.refresh();
175
175
  }
176
+
177
+ async toggle_wide_display() {
178
+ this.wide_display = !this.wide_display;
179
+ this.resize_sheet();
180
+ }
181
+
182
+ async resize_sheet() {
183
+ var sheet_element = document.getElementsByClassName("o_form_sheet_bg")[0];
184
+ sheet_element.classList.toggle(
185
+ "oe_mis_builder_report_wide_sheet",
186
+ this.wide_display
187
+ );
188
+ var button_resize_element = document.getElementById("icon_resize");
189
+ button_resize_element.classList.toggle("fa-expand", !this.wide_display);
190
+ button_resize_element.classList.toggle("fa-compress", this.wide_display);
191
+ }
176
192
  }
177
193
 
178
194
  MisReportWidget.components = {SearchBar, DateTimeInput};
@@ -26,6 +26,10 @@
26
26
 
27
27
  /* style for the control panel (search box and buttons) */
28
28
 
29
+ .oe_mis_builder_report_wide_sheet {
30
+ max-width: 100% !important;
31
+ }
32
+
29
33
  .oe_mis_builder_cp {
30
34
  display: flex;
31
35
  flex-direction: row;
@@ -65,4 +69,9 @@
65
69
  justify-content: flex-end;
66
70
  }
67
71
  }
72
+
73
+ .oe_mis_builder_cp_right_top_right {
74
+ display: flex;
75
+ flex-direction: row;
76
+ }
68
77
  }
@@ -1,13 +1,18 @@
1
1
  <?xml version="1.0" encoding="utf-8" ?>
2
2
  <templates>
3
-
4
3
  <t t-name="mis_builder.MisReportWidget">
5
4
  <div class="oe_mis_builder_content">
6
5
  <t t-if="state.mis_report_data">
7
6
  <div class="oe_mis_builder_cp">
8
- <div class="oe_mis_builder_cp_left">
9
- </div>
7
+ <div class="oe_mis_builder_cp_left" />
10
8
  <div class="oe_mis_builder_cp_right">
9
+ <div class="oe_mis_builder_cp_right_top_right">
10
+ <div class="oe_mis_builder_action_buttons">
11
+ <button t-on-click="toggle_wide_display" class="btn">
12
+ <i id="icon_resize" class="fa" />
13
+ </button>
14
+ </div>
15
+ </div>
11
16
  <div class="oe_mis_builder_cp_right_top">
12
17
  <SearchBar t-if="showSearchBar" />
13
18
  </div>
@@ -18,7 +23,7 @@
18
23
  placeholder="'Base date...'"
19
24
  type="'date'"
20
25
  t-if="showPivotDate"
21
- onChange="onDateTimeChanged.bind(this)"
26
+ onChange.bind="onDateTimeChanged"
22
27
  />
23
28
  </div>
24
29
  <div class="oe_mis_builder_action_buttons">
@@ -49,9 +54,7 @@
49
54
  t-key="row_index"
50
55
  class="oe_list_header_columns"
51
56
  >
52
- <th class="oe_list_header_char">
53
-
54
- </th>
57
+ <th class="oe_list_header_char" />
55
58
  <th
56
59
  t-foreach="row.cols"
57
60
  t-as="col"
@@ -59,10 +62,10 @@
59
62
  class="oe_list_header_char mis_builder_collabel"
60
63
  t-att-colspan="col.colspan"
61
64
  >
62
- <t t-esc="col.label" />
65
+ <t t-out="col.label" />
63
66
  <t t-if="col.description">
64
67
  <br />
65
- <t t-esc="col.description" />
68
+ <t t-out="col.description" />
66
69
  </t>
67
70
  </th>
68
71
  </tr>
@@ -74,10 +77,10 @@
74
77
  t-key="row_index"
75
78
  >
76
79
  <td t-att="{'style': row.style}">
77
- <t t-esc="row.label" />
80
+ <t t-out="row.label" />
78
81
  <t t-if="row.description">
79
82
  <br />
80
- <t t-esc="row.description" />
83
+ <t t-out="row.description" />
81
84
  </t>
82
85
  </td>
83
86
  <td
@@ -94,11 +97,11 @@
94
97
  t-on-click="drilldown"
95
98
  t-att-data-drilldown="JSON.stringify(cell.drilldown_arg)"
96
99
  >
97
- <t t-esc="cell.val_r" />
100
+ <t t-out="cell.val_r" />
98
101
  </a>
99
102
  </t>
100
103
  <t t-if="!cell.drilldown_arg">
101
- <t t-esc="cell.val_r" />
104
+ <t t-out="cell.val_r" />
102
105
  </t>
103
106
  </td>
104
107
  </tr>
@@ -111,5 +114,4 @@
111
114
  </t>
112
115
  </div>
113
116
  </t>
114
-
115
117
  </templates>
@@ -10,6 +10,7 @@ from . import test_kpi_data
10
10
  from . import test_mis_report_instance
11
11
  from . import test_mis_safe_eval
12
12
  from . import test_period_dates
13
+ from . import test_pro_rata_read_group
13
14
  from . import test_render
14
15
  from . import test_simple_array
15
16
  from . import test_target_move
@@ -27,10 +27,8 @@ def assert_matrix(matrix, expected):
27
27
  raise AssertionError("too many rows")
28
28
  for j, cell, expected_val in _zip(row.iter_cells(), expected_row):
29
29
  assert (
30
- cell and cell.val
31
- ) == expected_val, "{} != {} in row {} col {}".format(
32
- cell and cell.val, expected_val, i, j
33
- )
30
+ (cell and cell.val) == expected_val
31
+ ), f"{cell and cell.val} != {expected_val} in row {i} col {j}"
34
32
 
35
33
 
36
34
  @tagged("doctest")
@@ -1,7 +1,24 @@
1
- from odoo import models
1
+ from odoo import fields, models
2
2
 
3
3
 
4
4
  class MisKpiDataTestItem(models.Model):
5
5
  _name = "mis.kpi.data.test.item"
6
6
  _inherit = "mis.kpi.data"
7
7
  _description = "MIS Kpi Data test item"
8
+
9
+
10
+ class ProrataReadGroupThing(models.Model):
11
+ _name = "prorata.read.group.thing"
12
+ _inherit = "prorata.read_group.mixin"
13
+ _description = "Prorata Read Group Thing"
14
+
15
+ date_from = fields.Date(required=True)
16
+ date_to = fields.Date(required=True)
17
+ account_code = fields.Char(required=True)
18
+ debit = fields.Float()
19
+ credit = fields.Float()
20
+ company_id = fields.Many2one(
21
+ "res.company",
22
+ required=True,
23
+ default=lambda self: self.env.company,
24
+ )
@@ -9,13 +9,9 @@ from odoo import fields
9
9
  from odoo.exceptions import UserError
10
10
  from odoo.tools.safe_eval import safe_eval
11
11
 
12
- from ..models import aep
13
12
  from ..models.accounting_none import AccountingNone
14
13
  from ..models.aep import AccountingExpressionProcessor as AEP
15
14
  from ..models.aep import _is_domain
16
- from .common import load_doctests
17
-
18
- load_tests = load_doctests(aep)
19
15
 
20
16
 
21
17
  class TestAEP(common.TransactionCase):
@@ -39,7 +35,7 @@ class TestAEP(common.TransactionCase):
39
35
  # create receivable bs account
40
36
  self.account_ar = self.account_model.create(
41
37
  {
42
- "company_id": self.company.id,
38
+ "company_ids": self.company.ids,
43
39
  "code": "400AR",
44
40
  "name": "Receivable",
45
41
  "account_type": "asset_receivable",
@@ -49,20 +45,12 @@ class TestAEP(common.TransactionCase):
49
45
  # create income pl account
50
46
  self.account_in = self.account_model.create(
51
47
  {
52
- "company_id": self.company.id,
48
+ "company_ids": self.company.ids,
53
49
  "code": "700IN",
54
50
  "name": "Income",
55
51
  "account_type": "income",
56
52
  }
57
53
  )
58
- self.account_in_no_data = self.account_model.create(
59
- {
60
- "company_id": self.company.id,
61
- "code": "700INNODATA",
62
- "name": "Income (no data)",
63
- "account_type": "income",
64
- }
65
- )
66
54
  # create journal
67
55
  self.journal = self.journal_model.create(
68
56
  {
@@ -85,7 +73,6 @@ class TestAEP(common.TransactionCase):
85
73
  amount=300,
86
74
  debit_acc=self.account_ar,
87
75
  credit_acc=self.account_in,
88
- credit_quantity=3,
89
76
  )
90
77
  # create move in March this year
91
78
  self._create_move(
@@ -111,8 +98,6 @@ class TestAEP(common.TransactionCase):
111
98
  self.aep.parse_expr("crdp[700I%]")
112
99
  self.aep.parse_expr("bali[400%]")
113
100
  self.aep.parse_expr("bale[700%]")
114
- self.aep.parse_expr("balp[700I%]")
115
- self.aep.parse_expr("fldp.quantity[700%]")
116
101
  self.aep.parse_expr("balp[]" "[('account_id.code', '=', '400AR')]")
117
102
  self.aep.parse_expr(
118
103
  "balp[]" "[('account_id.account_type', '=', " " 'asset_receivable')]"
@@ -127,32 +112,17 @@ class TestAEP(common.TransactionCase):
127
112
  self.aep.parse_expr("bal_700IN") # deprecated
128
113
  self.aep.parse_expr("bals[700IN]") # deprecated
129
114
 
130
- def _create_move(
131
- self, date, amount, debit_acc, credit_acc, post=True, credit_quantity=0
132
- ):
115
+ def _create_move(self, date, amount, debit_acc, credit_acc, post=True):
133
116
  move = self.move_model.create(
134
117
  {
135
118
  "journal_id": self.journal.id,
136
119
  "date": fields.Date.to_string(date),
137
120
  "line_ids": [
121
+ (0, 0, {"name": "/", "debit": amount, "account_id": debit_acc.id}),
138
122
  (
139
123
  0,
140
124
  0,
141
- {
142
- "name": "/",
143
- "debit": amount,
144
- "account_id": debit_acc.id,
145
- },
146
- ),
147
- (
148
- 0,
149
- 0,
150
- {
151
- "name": "/",
152
- "credit": amount,
153
- "account_id": credit_acc.id,
154
- "quantity": credit_quantity,
155
- },
125
+ {"name": "/", "credit": amount, "account_id": credit_acc.id},
156
126
  ),
157
127
  ],
158
128
  }
@@ -182,20 +152,6 @@ class TestAEP(common.TransactionCase):
182
152
  self.assertEqual(self.company.fiscalyear_last_day, 31)
183
153
  self.assertEqual(self.company.fiscalyear_last_month, "12")
184
154
 
185
- def test_parse_expr_error_handling(self):
186
- aep = AEP(self.company)
187
- with self.assertRaises(UserError) as cm:
188
- aep.parse_expr("fldi.quantity[700%]")
189
- self.assertIn(
190
- "`fld` can only be used with mode `p` (variation)", str(cm.exception)
191
- )
192
- with self.assertRaises(UserError) as cm:
193
- aep.parse_expr("fldp[700%]")
194
- self.assertIn("`fld` must have a field name", str(cm.exception))
195
- with self.assertRaises(UserError) as cm:
196
- aep.parse_expr("balp.quantity[700%]")
197
- self.assertIn("`bal` cannot have a field name", str(cm.exception))
198
-
199
155
  def test_aep_basic(self):
200
156
  self.aep.done_parsing()
201
157
  # let's query for december
@@ -247,8 +203,6 @@ class TestAEP(common.TransactionCase):
247
203
  self.assertEqual(self._eval("bale[700IN]"), -300)
248
204
  # check result for non existing account
249
205
  self.assertIs(self._eval("bale[700NA]"), AccountingNone)
250
- # check fldp.quantity
251
- self.assertEqual(self._eval("fldp.quantity[700%]"), 3)
252
206
 
253
207
  # let's query for March
254
208
  self._do_queries(
@@ -280,8 +234,6 @@ class TestAEP(common.TransactionCase):
280
234
  self.assertEqual(self._eval("debp[400A%]"), 500)
281
235
  self.assertEqual(self._eval("bal_700IN"), -500)
282
236
  self.assertEqual(self._eval("bals[700IN]"), -800)
283
- # check fldp.quantity
284
- self.assertEqual(self._eval("fldp.quantity[700%]"), 0)
285
237
 
286
238
  # unallocated p&l from previous year
287
239
  self.assertEqual(self._eval("balu[]"), -100)
@@ -315,17 +267,6 @@ class TestAEP(common.TransactionCase):
315
267
  end = self._eval_by_account_id("bale[]")
316
268
  self.assertEqual(end, {self.account_ar.id: 900, self.account_in.id: -800})
317
269
 
318
- def test_aep_by_account_no_data(self):
319
- """Test that accounts with no data are not returned."""
320
- self.aep.done_parsing()
321
- self._do_queries(
322
- datetime.date(self.curr_year, 3, 1), datetime.date(self.curr_year, 3, 31)
323
- )
324
- variation = self._eval("balp[700I%]")
325
- self.assertEqual(variation, -500)
326
- variation_by_account = self._eval_by_account_id("balp[700I%]")
327
- self.assertEqual(variation_by_account, {self.account_in.id: -500})
328
-
329
270
  def test_aep_convenience_methods(self):
330
271
  initial = AEP.get_balances_initial(self.company, time.strftime("%Y") + "-03-01")
331
272
  self.assertEqual(
@@ -378,13 +319,10 @@ class TestAEP(common.TransactionCase):
378
319
  self.assertEqual(account_ids, {self.account_in.id})
379
320
  expr = "balp[700%]"
380
321
  account_ids = self.aep.get_account_ids_for_expr(expr)
381
- self.assertEqual(account_ids, {self.account_in.id, self.account_in_no_data.id})
322
+ self.assertEqual(account_ids, {self.account_in.id})
382
323
  expr = "bali[400%], bale[700%]" # subkpis combined expression
383
324
  account_ids = self.aep.get_account_ids_for_expr(expr)
384
- self.assertEqual(
385
- account_ids,
386
- {self.account_in.id, self.account_ar.id, self.account_in_no_data.id},
387
- )
325
+ self.assertEqual(account_ids, {self.account_in.id, self.account_ar.id})
388
326
 
389
327
  def test_get_aml_domain_for_expr(self):
390
328
  self.aep.done_parsing()
@@ -2,6 +2,7 @@
2
2
  # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
3
3
 
4
4
  import odoo.tests.common as common
5
+ from odoo import Command
5
6
 
6
7
  from ..models.accounting_none import AccountingNone
7
8
  from ..models.mis_report import CMP_DIFF
@@ -35,14 +36,6 @@ class TestMisReportInstanceDataSources(common.TransactionCase):
35
36
  move._post()
36
37
  return move
37
38
 
38
- @classmethod
39
- def setUpClass(cls):
40
- super().setUpClass()
41
- # Perform the tests with a brand new company to avoid intrusive data from other
42
- # modules added to the default company
43
- cls.company = cls.env["res.company"].create({"name": "Company Test"})
44
- cls.env.user.company_id = cls.company
45
-
46
39
  def setUp(self):
47
40
  super().setUp()
48
41
  self.account_model = self.env["account.account"]
@@ -51,7 +44,7 @@ class TestMisReportInstanceDataSources(common.TransactionCase):
51
44
  # create receivable bs account
52
45
  self.account_ar = self.account_model.create(
53
46
  {
54
- "company_id": self.env.user.company_id.id,
47
+ "company_ids": [Command.link(self.env.user.company_id.id)],
55
48
  "code": "400AR",
56
49
  "name": "Receivable",
57
50
  "account_type": "asset_receivable",
@@ -61,7 +54,7 @@ class TestMisReportInstanceDataSources(common.TransactionCase):
61
54
  # create income account
62
55
  self.account_in = self.account_model.create(
63
56
  {
64
- "company_id": self.env.user.company_id.id,
57
+ "company_ids": [Command.link(self.env.user.company_id.id)],
65
58
  "code": "700IN",
66
59
  "name": "Income",
67
60
  "account_type": "income",
@@ -69,7 +62,7 @@ class TestMisReportInstanceDataSources(common.TransactionCase):
69
62
  )
70
63
  self.account_in2 = self.account_model.create(
71
64
  {
72
- "company_id": self.env.user.company_id.id,
65
+ "company_ids": [Command.link(self.env.user.company_id.id)],
73
66
  "code": "700IN2",
74
67
  "name": "Income",
75
68
  "account_type": "income",
@@ -18,6 +18,7 @@ class TestKpiData(TransactionCase):
18
18
  from .fake_models import MisKpiDataTestItem
19
19
 
20
20
  cls.loader.update_registry((MisKpiDataTestItem,))
21
+ cls.addClassCleanup(cls.loader.restore_registry)
21
22
 
22
23
  report = cls.env["mis.report"].create(dict(name="test report"))
23
24
  cls.kpi1 = cls.env["mis.report.kpi"].create(
@@ -71,11 +72,6 @@ class TestKpiData(TransactionCase):
71
72
  )
72
73
  )
73
74
 
74
- @classmethod
75
- def tearDownClass(cls):
76
- cls.loader.restore_registry()
77
- return super().tearDownClass()
78
-
79
75
  def test_kpi_data_name(self):
80
76
  self.assertEqual(self.kd11.name, "k1: 2017-05-01 - 2017-05-10")
81
77
  self.assertEqual(self.kd12.name, "k1: 2017-05-11 - 2017-05-20")
@@ -412,7 +412,7 @@ class TestMisReportInstance(common.HttpCase):
412
412
  .search(
413
413
  [
414
414
  ("code", "=like", "200%"),
415
- ("company_id", "=", self.env.ref("base.main_company").id),
415
+ ("company_ids", "in", [self.env.ref("base.main_company").id]),
416
416
  ]
417
417
  )
418
418
  .ids
@@ -429,10 +429,8 @@ class TestMisReportInstance(common.HttpCase):
429
429
  "account_id": account.id,
430
430
  }
431
431
  action_name = self.report_instance._get_drilldown_action_name(args)
432
- expected_name = "{kpi} - {account} - {period}".format(
433
- kpi=self.kpi1.description,
434
- account=account.display_name,
435
- period=period.display_name,
432
+ expected_name = (
433
+ f"{self.kpi1.description} - {account.display_name} - {period.display_name}"
436
434
  )
437
435
  assert action_name == expected_name
438
436
 
@@ -458,7 +456,7 @@ class TestMisReportInstance(common.HttpCase):
458
456
  "arch": "<graph><field name='name'/></graph>",
459
457
  },
460
458
  {
461
- "name": "mis_report_test_drilldown_views_tree",
459
+ "name": "mis_report_test_drilldown_views_list",
462
460
  "model": model_name,
463
461
  "arch": "<pivot><field name='name'/></pivot>",
464
462
  },
@@ -477,19 +475,19 @@ class TestMisReportInstance(common.HttpCase):
477
475
  "arch": "<form><field name='name'/></form>",
478
476
  },
479
477
  {
480
- "name": "mis_report_test_drilldown_views_tree",
478
+ "name": "mis_report_test_drilldown_views_list",
481
479
  "model": model_name,
482
- "arch": "<tree><field name='name'/></tree>",
480
+ "arch": "<list><field name='name'/></list>",
483
481
  },
484
482
  ]
485
483
  )
486
484
  action = self.report_instance.drilldown(
487
485
  dict(expr="balp[200%]", period_id=self.report_instance.period_ids[0].id)
488
486
  )
489
- self.assertEqual(action["view_mode"], "tree,form,pivot,graph")
487
+ self.assertEqual(action["view_mode"], "list,form,pivot,graph")
490
488
  self.assertEqual(
491
489
  action["views"],
492
- [[False, "tree"], [False, "form"], [False, "pivot"], [False, "graph"]],
490
+ [[False, "list"], [False, "form"], [False, "pivot"], [False, "graph"]],
493
491
  )
494
492
 
495
493
  def test_qweb(self):
@@ -504,12 +502,18 @@ class TestMisReportInstance(common.HttpCase):
504
502
 
505
503
  def test_xlsx(self):
506
504
  self.report_instance.export_xls() # get action
507
- test_reports.try_report(
508
- self.env.cr,
509
- self.env.uid,
510
- "mis_builder.mis_report_instance_xlsx",
511
- [self.report_instance.id],
512
- report_type="xlsx",
505
+ with self.assertLogs("odoo.tools.test_reports", level="WARNING") as log_catcher:
506
+ test_reports.try_report(
507
+ self.env.cr,
508
+ self.env.uid,
509
+ "mis_builder.mis_report_instance_xlsx",
510
+ [self.report_instance.id],
511
+ report_type="xlsx",
512
+ )
513
+ self.assertIn(
514
+ 'Report mis_builder.mis_report_instance_xlsx produced a "xlsx" chunk, '
515
+ "cannot examine it",
516
+ log_catcher.output[0],
513
517
  )
514
518
 
515
519
  def test_get_kpis_by_account_id(self):
@@ -518,7 +522,7 @@ class TestMisReportInstance(common.HttpCase):
518
522
  .search(
519
523
  [
520
524
  ("code", "=like", "200%"),
521
- ("company_id", "=", self.env.ref("base.main_company").id),
525
+ ("company_ids", "in", [self.env.ref("base.main_company").id]),
522
526
  ]
523
527
  )
524
528
  .ids