odoo-addon-account-financial-report 17.0.1.0.0.12__py3-none-any.whl → 17.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.

Potentially problematic release.


This version of odoo-addon-account-financial-report might be problematic. Click here for more details.

Files changed (28) hide show
  1. odoo/addons/account_financial_report/README.rst +38 -1
  2. odoo/addons/account_financial_report/__manifest__.py +4 -1
  3. odoo/addons/account_financial_report/i18n/account_financial_report.pot +111 -13
  4. odoo/addons/account_financial_report/i18n/es.po +112 -3
  5. odoo/addons/account_financial_report/i18n/tr.po +120 -120
  6. odoo/addons/account_financial_report/models/__init__.py +2 -0
  7. odoo/addons/account_financial_report/models/account_age_report_configuration.py +47 -0
  8. odoo/addons/account_financial_report/models/res_config_settings.py +14 -0
  9. odoo/addons/account_financial_report/readme/CONFIGURE.md +26 -0
  10. odoo/addons/account_financial_report/readme/CONTRIBUTORS.md +1 -0
  11. odoo/addons/account_financial_report/readme/DESCRIPTION.md +4 -0
  12. odoo/addons/account_financial_report/report/aged_partner_balance.py +79 -3
  13. odoo/addons/account_financial_report/report/aged_partner_balance_xlsx.py +144 -104
  14. odoo/addons/account_financial_report/report/templates/aged_partner_balance.xml +428 -333
  15. odoo/addons/account_financial_report/security/ir.model.access.csv +2 -0
  16. odoo/addons/account_financial_report/security/security.xml +8 -0
  17. odoo/addons/account_financial_report/static/description/index.html +47 -21
  18. odoo/addons/account_financial_report/tests/__init__.py +1 -0
  19. odoo/addons/account_financial_report/tests/test_age_report_configuration.py +42 -0
  20. odoo/addons/account_financial_report/tests/test_aged_partner_balance.py +84 -5
  21. odoo/addons/account_financial_report/view/account_age_report_configuration_views.xml +41 -0
  22. odoo/addons/account_financial_report/view/res_config_settings_views.xml +51 -0
  23. odoo/addons/account_financial_report/wizard/aged_partner_balance_wizard.py +4 -0
  24. odoo/addons/account_financial_report/wizard/aged_partner_balance_wizard_view.xml +2 -3
  25. {odoo_addon_account_financial_report-17.0.1.0.0.12.dist-info → odoo_addon_account_financial_report-17.0.1.1.0.dist-info}/METADATA +39 -2
  26. {odoo_addon_account_financial_report-17.0.1.0.0.12.dist-info → odoo_addon_account_financial_report-17.0.1.1.0.dist-info}/RECORD +28 -21
  27. {odoo_addon_account_financial_report-17.0.1.0.0.12.dist-info → odoo_addon_account_financial_report-17.0.1.1.0.dist-info}/WHEEL +0 -0
  28. {odoo_addon_account_financial_report-17.0.1.0.0.12.dist-info → odoo_addon_account_financial_report-17.0.1.1.0.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,6 @@
1
+ from . import account_age_report_configuration
1
2
  from . import account_group
2
3
  from . import account
3
4
  from . import account_move_line
4
5
  from . import ir_actions_report
6
+ from . import res_config_settings
@@ -0,0 +1,47 @@
1
+ # Copyright 2023 Ernesto García
2
+ # Copyright 2023 Carolina Fernandez
3
+ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
4
+ from odoo import _, api, fields, models
5
+ from odoo.exceptions import ValidationError
6
+
7
+
8
+ class AccountAgeReportConfiguration(models.Model):
9
+ _name = "account.age.report.configuration"
10
+ _description = "Model to set intervals for Age partner balance report"
11
+
12
+ name = fields.Char(required=True)
13
+ company_id = fields.Many2one(
14
+ "res.company", default=lambda self: self.env.company, readonly=True
15
+ )
16
+ line_ids = fields.One2many(
17
+ "account.age.report.configuration.line", "account_age_report_config_id"
18
+ )
19
+
20
+ @api.constrains("line_ids")
21
+ def _check_line_ids(self):
22
+ for rec in self:
23
+ if not rec.line_ids:
24
+ raise ValidationError(_("Must complete Configuration Lines"))
25
+
26
+
27
+ class AccountAgeReportConfigurationLine(models.Model):
28
+ _name = "account.age.report.configuration.line"
29
+ _description = "Model to set interval lines for Age partner balance report"
30
+
31
+ name = fields.Char(required=True)
32
+ account_age_report_config_id = fields.Many2one("account.age.report.configuration")
33
+ inferior_limit = fields.Integer()
34
+
35
+ @api.constrains("inferior_limit")
36
+ def _check_inferior_limit(self):
37
+ for rec in self:
38
+ if rec.inferior_limit <= 0:
39
+ raise ValidationError(_("Inferior Limit must be greather than zero"))
40
+
41
+ _sql_constraints = [
42
+ (
43
+ "unique_name_config_combination",
44
+ "UNIQUE(name,account_age_report_config_id)",
45
+ _("Name must be unique per report configuration"),
46
+ )
47
+ ]
@@ -0,0 +1,14 @@
1
+ # Copyright 2023 Tecnativa - Carolina Fernandez
2
+ # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
3
+
4
+ from odoo import fields, models
5
+
6
+
7
+ class ResConfigSettings(models.TransientModel):
8
+ _inherit = "res.config.settings"
9
+
10
+ default_age_partner_config_id = fields.Many2one(
11
+ "account.age.report.configuration",
12
+ string="Intervals configuration",
13
+ default_model="aged.partner.balance.report.wizard",
14
+ )
@@ -0,0 +1,26 @@
1
+ To configure dynamic intervals for Aged Partner Balance you need to:
2
+
3
+ Go on 'Settings' -> 'Invoicing' -> 'OCA Aged Report Configuration'.
4
+
5
+ Click on option 'Configurations' and create new record.
6
+
7
+ Create new interval.
8
+ The name established on line will be the column to display in Aged Partner Balance.
9
+ Inferior limit established on line is the interval
10
+
11
+ Example of configuration inferior limit:
12
+
13
+ -> 15
14
+ -> 30
15
+ -> 60
16
+
17
+ It means the first interval is from 0 to 15, the second from 16 to 30, and the third is 61+.
18
+
19
+ Go on 'Invoicing' -> 'Reports' -> 'OCA accounting reports' -> 'Aged Partner Balance'
20
+
21
+ When wizard is open, you need to select your interval configuration and print report.
22
+
23
+ If you want to get default interval configuration any time you wish to print Aged Partner Report,
24
+ you can set default interval configuration per company in:
25
+
26
+ 'Settings' -> 'Invoicing' -> 'OCA Aged Report Configuration'.
@@ -23,6 +23,7 @@
23
23
  - Jo??o Marques
24
24
  - Alexandre D. D??az
25
25
  - V??ctor Mart??nez
26
+ - Carolina Fernandez
26
27
  - [Sygel](https://www.sygel.es):
27
28
  - Harald Panten
28
29
  - Valentin Vinagre
@@ -15,3 +15,7 @@ properly shown.
15
15
 
16
16
  In case that in an account has not been configured a second currency
17
17
  foreign currency balances are not available.
18
+
19
+ Invoicing / Settings / Invoicing / OCA Aged Report Configuration you will be able to set
20
+ dynamic intervals that will appear on the Aged Partner Balance.
21
+ For further information, check CONFIGURE.rst
@@ -25,6 +25,8 @@ class AgedPartnerBalanceReport(models.AbstractModel):
25
25
  ag_pb_data[acc_id]["90_days"] = 0.0
26
26
  ag_pb_data[acc_id]["120_days"] = 0.0
27
27
  ag_pb_data[acc_id]["older"] = 0.0
28
+ for interval_line in self.env.context["age_partner_config"].line_ids:
29
+ ag_pb_data[acc_id][interval_line] = 0.0
28
30
  return ag_pb_data
29
31
 
30
32
  @api.model
@@ -39,6 +41,8 @@ class AgedPartnerBalanceReport(models.AbstractModel):
39
41
  ag_pb_data[acc_id][prt_id]["120_days"] = 0.0
40
42
  ag_pb_data[acc_id][prt_id]["older"] = 0.0
41
43
  ag_pb_data[acc_id][prt_id]["move_lines"] = []
44
+ for interval_line in self.env.context["age_partner_config"].line_ids:
45
+ ag_pb_data[acc_id][prt_id][interval_line] = 0.0
42
46
  return ag_pb_data
43
47
 
44
48
  @api.model
@@ -47,6 +51,7 @@ class AgedPartnerBalanceReport(models.AbstractModel):
47
51
  ):
48
52
  ag_pb_data[acc_id]["residual"] += residual
49
53
  ag_pb_data[acc_id][prt_id]["residual"] += residual
54
+ interval_lines = self.env.context["age_partner_config"].line_ids
50
55
  today = date_at_object
51
56
  if not due_date or today <= due_date:
52
57
  ag_pb_data[acc_id]["current"] += residual
@@ -66,8 +71,34 @@ class AgedPartnerBalanceReport(models.AbstractModel):
66
71
  else:
67
72
  ag_pb_data[acc_id]["older"] += residual
68
73
  ag_pb_data[acc_id][prt_id]["older"] += residual
74
+ if due_date:
75
+ days_difference = abs((today - due_date).days)
76
+ for index, line in enumerate(interval_lines):
77
+ lower_limit = (
78
+ 0 if not index else interval_lines[index - 1].inferior_limit
79
+ )
80
+ next_line = (
81
+ interval_lines[index] if index < len(interval_lines) else None
82
+ )
83
+ interval_range = self._get_values_for_range_intervals(
84
+ lower_limit, next_line.inferior_limit
85
+ )
86
+ if (
87
+ days_difference in interval_range
88
+ or days_difference == line.inferior_limit
89
+ ):
90
+ ag_pb_data[acc_id][line] += residual
91
+ ag_pb_data[acc_id][prt_id][line] += residual
92
+ break
69
93
  return ag_pb_data
70
94
 
95
+ def _get_values_for_range_intervals(self, num1, num2):
96
+ min_num = min(num1, num2)
97
+ max_num = max(num1, num2)
98
+ if abs(num2 - num1) == 1:
99
+ return [max_num]
100
+ return list(range(min_num + 1, max_num))
101
+
71
102
  def _get_account_partial_reconciled(self, company_id, date_at_object):
72
103
  domain = [("max_date", ">", date_at_object), ("company_id", "=", company_id)]
73
104
  fields = [
@@ -235,6 +266,9 @@ class AgedPartnerBalanceReport(models.AbstractModel):
235
266
  "older": 0.0,
236
267
  }
237
268
  )
269
+ interval_lines = self.env.context["age_partner_config"].line_ids
270
+ for interval_line in interval_lines:
271
+ ml[interval_line] = 0.0
238
272
  due_date = ml["due_date"]
239
273
  amount = ml["residual"]
240
274
  today = date_at_object
@@ -250,6 +284,24 @@ class AgedPartnerBalanceReport(models.AbstractModel):
250
284
  ml["120_days"] += amount
251
285
  else:
252
286
  ml["older"] += amount
287
+ if due_date:
288
+ days_difference = abs((today - due_date).days)
289
+ for index, interval_line in enumerate(interval_lines):
290
+ lower_limit = (
291
+ 0 if not index else interval_lines[index - 1].inferior_limit
292
+ )
293
+ next_line = (
294
+ interval_lines[index] if index < len(interval_lines) else None
295
+ )
296
+ interval_range = self._get_values_for_range_intervals(
297
+ lower_limit, next_line.inferior_limit
298
+ )
299
+ if (
300
+ days_difference in interval_range
301
+ or days_difference == interval_line.inferior_limit
302
+ ):
303
+ ml[interval_line] += amount
304
+ break
253
305
 
254
306
  def _create_account_list(
255
307
  self,
@@ -261,6 +313,7 @@ class AgedPartnerBalanceReport(models.AbstractModel):
261
313
  date_at_oject,
262
314
  ):
263
315
  aged_partner_data = []
316
+ interval_lines = self.env.context["age_partner_config"].line_ids
264
317
  for account in accounts_data.values():
265
318
  acc_id = account["id"]
266
319
  account.update(
@@ -275,6 +328,8 @@ class AgedPartnerBalanceReport(models.AbstractModel):
275
328
  "partners": [],
276
329
  }
277
330
  )
331
+ for interval_line in interval_lines:
332
+ account[interval_line] = ag_pb_data[acc_id][interval_line]
278
333
  for prt_id in ag_pb_data[acc_id]:
279
334
  if isinstance(prt_id, int):
280
335
  partner = {
@@ -287,6 +342,10 @@ class AgedPartnerBalanceReport(models.AbstractModel):
287
342
  "120_days": ag_pb_data[acc_id][prt_id]["120_days"],
288
343
  "older": ag_pb_data[acc_id][prt_id]["older"],
289
344
  }
345
+ for interval_line in interval_lines:
346
+ partner[interval_line] = ag_pb_data[acc_id][prt_id][
347
+ interval_line
348
+ ]
290
349
  if show_move_line_details:
291
350
  move_lines = []
292
351
  for ml in ag_pb_data[acc_id][prt_id]["move_lines"]:
@@ -306,6 +365,7 @@ class AgedPartnerBalanceReport(models.AbstractModel):
306
365
 
307
366
  @api.model
308
367
  def _calculate_percent(self, aged_partner_data):
368
+ interval_lines = self.env.context["age_partner_config"].line_ids
309
369
  for account in aged_partner_data:
310
370
  if abs(account["residual"]) > 0.01:
311
371
  total = account["residual"]
@@ -331,6 +391,10 @@ class AgedPartnerBalanceReport(models.AbstractModel):
331
391
  ),
332
392
  }
333
393
  )
394
+ for interval_line in interval_lines:
395
+ account[f"percent_{interval_line.id}"] = abs(
396
+ round((account[interval_line] / total) * 100, 2)
397
+ )
334
398
  else:
335
399
  account.update(
336
400
  {
@@ -342,6 +406,8 @@ class AgedPartnerBalanceReport(models.AbstractModel):
342
406
  "percent_older": 0.0,
343
407
  }
344
408
  )
409
+ for interval_line in interval_lines:
410
+ account[f"percent_{interval_line.id}"] = 0.0
345
411
  return aged_partner_data
346
412
 
347
413
  def _get_report_values(self, docids, data):
@@ -355,12 +421,17 @@ class AgedPartnerBalanceReport(models.AbstractModel):
355
421
  date_from = data["date_from"]
356
422
  only_posted_moves = data["only_posted_moves"]
357
423
  show_move_line_details = data["show_move_line_details"]
424
+ aged_partner_configuration = self.env[
425
+ "account.age.report.configuration"
426
+ ].browse(data["age_partner_config_id"])
358
427
  (
359
428
  ag_pb_data,
360
429
  accounts_data,
361
430
  partners_data,
362
431
  journals_data,
363
- ) = self._get_move_lines_data(
432
+ ) = self.with_context(
433
+ age_partner_config=aged_partner_configuration
434
+ )._get_move_lines_data(
364
435
  company_id,
365
436
  account_ids,
366
437
  partner_ids,
@@ -369,7 +440,9 @@ class AgedPartnerBalanceReport(models.AbstractModel):
369
440
  only_posted_moves,
370
441
  show_move_line_details,
371
442
  )
372
- aged_partner_data = self._create_account_list(
443
+ aged_partner_data = self.with_context(
444
+ age_partner_config=aged_partner_configuration
445
+ )._create_account_list(
373
446
  ag_pb_data,
374
447
  accounts_data,
375
448
  partners_data,
@@ -377,7 +450,9 @@ class AgedPartnerBalanceReport(models.AbstractModel):
377
450
  show_move_line_details,
378
451
  date_at_object,
379
452
  )
380
- aged_partner_data = self._calculate_percent(aged_partner_data)
453
+ aged_partner_data = self.with_context(
454
+ age_partner_config=aged_partner_configuration
455
+ )._calculate_percent(aged_partner_data)
381
456
  return {
382
457
  "doc_ids": [wizard_id],
383
458
  "doc_model": "open.items.report.wizard",
@@ -388,6 +463,7 @@ class AgedPartnerBalanceReport(models.AbstractModel):
388
463
  "only_posted_moves": only_posted_moves,
389
464
  "aged_partner_balance": aged_partner_data,
390
465
  "show_move_lines_details": show_move_line_details,
466
+ "age_partner_config": aged_partner_configuration,
391
467
  }
392
468
 
393
469
  def _get_ml_fields(self):
@@ -20,67 +20,84 @@ class AgedPartnerBalanceXslx(models.AbstractModel):
20
20
  report_name = report_name + suffix
21
21
  return report_name
22
22
 
23
- def _get_report_columns(self, report):
24
- if not report.show_move_line_details:
25
- return {
26
- 0: {"header": _("Partner"), "field": "name", "width": 70},
27
- 1: {
28
- "header": _("Residual"),
29
- "field": "residual",
30
- "field_footer_total": "residual",
31
- "type": "amount",
32
- "width": 14,
33
- },
34
- 2: {
35
- "header": _("Current"),
36
- "field": "current",
37
- "field_footer_total": "current",
38
- "field_footer_percent": "percent_current",
39
- "type": "amount",
40
- "width": 14,
41
- },
42
- 3: {
43
- "header": _("Age ??? 30 d."),
44
- "field": "30_days",
45
- "field_footer_total": "30_days",
46
- "field_footer_percent": "percent_30_days",
47
- "type": "amount",
48
- "width": 14,
49
- },
50
- 4: {
51
- "header": _("Age ??? 60 d."),
52
- "field": "60_days",
53
- "field_footer_total": "60_days",
54
- "field_footer_percent": "percent_60_days",
55
- "type": "amount",
56
- "width": 14,
57
- },
58
- 5: {
59
- "header": _("Age ??? 90 d."),
60
- "field": "90_days",
61
- "field_footer_total": "90_days",
62
- "field_footer_percent": "percent_90_days",
63
- "type": "amount",
64
- "width": 14,
65
- },
66
- 6: {
67
- "header": _("Age ??? 120 d."),
68
- "field": "120_days",
69
- "field_footer_total": "120_days",
70
- "field_footer_percent": "percent_120_days",
71
- "type": "amount",
72
- "width": 14,
73
- },
74
- 7: {
75
- "header": _("Older"),
76
- "field": "older",
77
- "field_footer_total": "older",
78
- "field_footer_percent": "percent_older",
79
- "type": "amount",
80
- "width": 14,
81
- },
23
+ def _get_report_columns_without_move_line_details(self, report, column_index):
24
+ report_columns = {
25
+ 0: {"header": _("Partner"), "field": "name", "width": 70},
26
+ 1: {
27
+ "header": _("Residual"),
28
+ "field": "residual",
29
+ "field_footer_total": "residual",
30
+ "type": "amount",
31
+ "width": 14,
32
+ },
33
+ 2: {
34
+ "header": _("Current"),
35
+ "field": "current",
36
+ "field_footer_total": "current",
37
+ "field_footer_percent": "percent_current",
38
+ "type": "amount",
39
+ "width": 14,
40
+ },
41
+ }
42
+ if not report.age_partner_config_id:
43
+ report_columns.update(
44
+ {
45
+ 3: {
46
+ "header": _("Age ≤ 30 d."),
47
+ "field": "30_days",
48
+ "field_footer_total": "30_days",
49
+ "field_footer_percent": "percent_30_days",
50
+ "type": "amount",
51
+ "width": 14,
52
+ },
53
+ 4: {
54
+ "header": _("Age ≤ 60 d."),
55
+ "field": "60_days",
56
+ "field_footer_total": "60_days",
57
+ "field_footer_percent": "percent_60_days",
58
+ "type": "amount",
59
+ "width": 14,
60
+ },
61
+ 5: {
62
+ "header": _("Age ≤ 90 d."),
63
+ "field": "90_days",
64
+ "field_footer_total": "90_days",
65
+ "field_footer_percent": "percent_90_days",
66
+ "type": "amount",
67
+ "width": 14,
68
+ },
69
+ 6: {
70
+ "header": _("Age ≤ 120 d."),
71
+ "field": "120_days",
72
+ "field_footer_total": "120_days",
73
+ "field_footer_percent": "percent_120_days",
74
+ "type": "amount",
75
+ "width": 14,
76
+ },
77
+ 7: {
78
+ "header": _("Older"),
79
+ "field": "older",
80
+ "field_footer_total": "older",
81
+ "field_footer_percent": "percent_older",
82
+ "type": "amount",
83
+ "width": 14,
84
+ },
85
+ }
86
+ )
87
+ for interval in report.age_partner_config_id.line_ids:
88
+ report_columns[column_index] = {
89
+ "header": interval.name,
90
+ "field": interval,
91
+ "field_footer_total": interval,
92
+ "field_footer_percent": f"percent_{interval.id}",
93
+ "type": "amount",
94
+ "width": 14,
82
95
  }
83
- return {
96
+ column_index += 1
97
+ return report_columns
98
+
99
+ def _get_report_columns_with_move_line_details(self, report, column_index):
100
+ report_columns = {
84
101
  0: {"header": _("Date"), "field": "date", "width": 11},
85
102
  1: {"header": _("Entry"), "field": "entry", "width": 18},
86
103
  2: {"header": _("Journal"), "field": "journal", "width": 8},
@@ -105,52 +122,75 @@ class AgedPartnerBalanceXslx(models.AbstractModel):
105
122
  "type": "amount",
106
123
  "width": 14,
107
124
  },
108
- 9: {
109
- "header": _("Age ??? 30 d."),
110
- "field": "30_days",
111
- "field_footer_total": "30_days",
112
- "field_footer_percent": "percent_30_days",
113
- "field_final_balance": "30_days",
114
- "type": "amount",
115
- "width": 14,
116
- },
117
- 10: {
118
- "header": _("Age ??? 60 d."),
119
- "field": "60_days",
120
- "field_footer_total": "60_days",
121
- "field_footer_percent": "percent_60_days",
122
- "field_final_balance": "60_days",
123
- "type": "amount",
124
- "width": 14,
125
- },
126
- 11: {
127
- "header": _("Age ??? 90 d."),
128
- "field": "90_days",
129
- "field_footer_total": "90_days",
130
- "field_footer_percent": "percent_90_days",
131
- "field_final_balance": "90_days",
132
- "type": "amount",
133
- "width": 14,
134
- },
135
- 12: {
136
- "header": _("Age ??? 120 d."),
137
- "field": "120_days",
138
- "field_footer_total": "120_days",
139
- "field_footer_percent": "percent_120_days",
140
- "field_final_balance": "120_days",
141
- "type": "amount",
142
- "width": 14,
143
- },
144
- 13: {
145
- "header": _("Older"),
146
- "field": "older",
147
- "field_footer_total": "older",
148
- "field_footer_percent": "percent_older",
149
- "field_final_balance": "older",
125
+ }
126
+ if not report.age_partner_config_id:
127
+ report_columns.update(
128
+ {
129
+ 9: {
130
+ "header": _("Age ≤ 30 d."),
131
+ "field": "30_days",
132
+ "field_footer_total": "30_days",
133
+ "field_footer_percent": "percent_30_days",
134
+ "field_final_balance": "30_days",
135
+ "type": "amount",
136
+ "width": 14,
137
+ },
138
+ 10: {
139
+ "header": _("Age ≤ 60 d."),
140
+ "field": "60_days",
141
+ "field_footer_total": "60_days",
142
+ "field_footer_percent": "percent_60_days",
143
+ "field_final_balance": "60_days",
144
+ "type": "amount",
145
+ "width": 14,
146
+ },
147
+ 11: {
148
+ "header": _("Age ≤ 90 d."),
149
+ "field": "90_days",
150
+ "field_footer_total": "90_days",
151
+ "field_footer_percent": "percent_90_days",
152
+ "field_final_balance": "90_days",
153
+ "type": "amount",
154
+ "width": 14,
155
+ },
156
+ 12: {
157
+ "header": _("Age ≤ 120 d."),
158
+ "field": "120_days",
159
+ "field_footer_total": "120_days",
160
+ "field_footer_percent": "percent_120_days",
161
+ "field_final_balance": "120_days",
162
+ "type": "amount",
163
+ "width": 14,
164
+ },
165
+ 13: {
166
+ "header": _("Older"),
167
+ "field": "older",
168
+ "field_footer_total": "older",
169
+ "field_footer_percent": "percent_older",
170
+ "field_final_balance": "older",
171
+ "type": "amount",
172
+ "width": 14,
173
+ },
174
+ }
175
+ )
176
+ for interval in report.age_partner_config_id.line_ids:
177
+ report_columns[column_index] = {
178
+ "header": interval.name,
179
+ "field": interval,
180
+ "field_footer_total": interval,
181
+ "field_footer_percent": f"percent_{interval.id}",
150
182
  "type": "amount",
151
183
  "width": 14,
152
- },
153
- }
184
+ }
185
+ column_index += 1
186
+ return report_columns
187
+
188
+ def _get_report_columns(self, report):
189
+ if not report.show_move_line_details:
190
+ return self._get_report_columns_without_move_line_details(
191
+ report, column_index=3
192
+ )
193
+ return self._get_report_columns_with_move_line_details(report, column_index=9)
154
194
 
155
195
  def _get_report_filters(self, report):
156
196
  return [