odoo-addon-account-financial-report 15.0.1.1.0.1__py3-none-any.whl → 18.0.1.4.4.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.
- odoo/addons/account_financial_report/README.rst +131 -74
- odoo/addons/account_financial_report/__manifest__.py +6 -9
- odoo/addons/account_financial_report/i18n/account_financial_report.pot +313 -188
- odoo/addons/account_financial_report/i18n/ar.po +579 -433
- odoo/addons/account_financial_report/i18n/ca.po +474 -289
- odoo/addons/account_financial_report/i18n/{fr_FR.po → ca_AD.po} +539 -491
- odoo/addons/account_financial_report/i18n/ca_ES.po +1891 -0
- odoo/addons/account_financial_report/i18n/de.po +455 -295
- odoo/addons/account_financial_report/i18n/es.po +458 -394
- odoo/addons/account_financial_report/i18n/es_AR.po +464 -283
- odoo/addons/account_financial_report/i18n/es_MX.po +315 -220
- odoo/addons/account_financial_report/i18n/fr.po +620 -435
- odoo/addons/account_financial_report/i18n/fr_CH.po +616 -462
- odoo/addons/account_financial_report/i18n/hr.po +506 -355
- odoo/addons/account_financial_report/i18n/hr_HR.po +331 -232
- odoo/addons/account_financial_report/i18n/it.po +538 -356
- odoo/addons/account_financial_report/i18n/ja.po +339 -240
- odoo/addons/account_financial_report/i18n/nl.po +462 -324
- odoo/addons/account_financial_report/i18n/nl_NL.po +318 -220
- odoo/addons/account_financial_report/i18n/pt.po +429 -242
- odoo/addons/account_financial_report/i18n/pt_BR.po +588 -438
- odoo/addons/account_financial_report/i18n/ro.po +499 -342
- odoo/addons/account_financial_report/i18n/sl.po +1945 -0
- odoo/addons/account_financial_report/i18n/sv.po +1997 -0
- odoo/addons/account_financial_report/i18n/tr.po +1947 -0
- odoo/addons/account_financial_report/menuitems.xml +1 -1
- odoo/addons/account_financial_report/models/__init__.py +2 -0
- odoo/addons/account_financial_report/models/account_age_report_configuration.py +49 -0
- odoo/addons/account_financial_report/models/account_group.py +62 -23
- odoo/addons/account_financial_report/models/account_move_line.py +33 -3
- odoo/addons/account_financial_report/models/ir_actions_report.py +6 -4
- odoo/addons/account_financial_report/models/res_config_settings.py +36 -0
- odoo/addons/account_financial_report/readme/CONFIGURE.md +26 -0
- odoo/addons/account_financial_report/readme/CONTRIBUTORS.md +38 -0
- odoo/addons/account_financial_report/readme/CREDITS.md +1 -0
- odoo/addons/account_financial_report/readme/DESCRIPTION.md +21 -0
- odoo/addons/account_financial_report/readme/HISTORY.md +16 -0
- odoo/addons/account_financial_report/readme/ROADMAP.md +6 -0
- odoo/addons/account_financial_report/report/abstract_report.py +73 -23
- odoo/addons/account_financial_report/report/abstract_report_xlsx.py +28 -23
- odoo/addons/account_financial_report/report/aged_partner_balance.py +131 -30
- odoo/addons/account_financial_report/report/aged_partner_balance_xlsx.py +158 -118
- odoo/addons/account_financial_report/report/general_ledger.py +421 -340
- odoo/addons/account_financial_report/report/general_ledger_xlsx.py +127 -75
- odoo/addons/account_financial_report/report/journal_ledger.py +84 -68
- odoo/addons/account_financial_report/report/journal_ledger_xlsx.py +14 -8
- odoo/addons/account_financial_report/report/open_items.py +113 -70
- odoo/addons/account_financial_report/report/open_items_xlsx.py +152 -19
- odoo/addons/account_financial_report/report/templates/aged_partner_balance.xml +408 -311
- odoo/addons/account_financial_report/report/templates/general_ledger.xml +273 -213
- odoo/addons/account_financial_report/report/templates/journal_ledger.xml +70 -76
- odoo/addons/account_financial_report/report/templates/layouts.xml +12 -1
- odoo/addons/account_financial_report/report/templates/open_items.xml +181 -55
- odoo/addons/account_financial_report/report/templates/trial_balance.xml +304 -195
- odoo/addons/account_financial_report/report/templates/vat_report.xml +10 -10
- odoo/addons/account_financial_report/report/trial_balance.py +463 -211
- odoo/addons/account_financial_report/report/trial_balance_xlsx.py +37 -38
- odoo/addons/account_financial_report/report/vat_report.py +36 -25
- odoo/addons/account_financial_report/report/vat_report_xlsx.py +1 -1
- odoo/addons/account_financial_report/security/ir.model.access.csv +2 -0
- odoo/addons/account_financial_report/security/security.xml +8 -0
- odoo/addons/account_financial_report/static/description/index.html +106 -55
- odoo/addons/account_financial_report/static/src/css/report.css +77 -42
- odoo/addons/account_financial_report/static/src/css/report_html.css +10 -0
- odoo/addons/account_financial_report/static/src/js/report.esm.js +72 -0
- odoo/addons/account_financial_report/static/src/js/report_action.esm.js +39 -0
- odoo/addons/account_financial_report/static/src/xml/report.xml +10 -9
- odoo/addons/account_financial_report/tests/__init__.py +1 -0
- odoo/addons/account_financial_report/tests/test_age_report_configuration.py +42 -0
- odoo/addons/account_financial_report/tests/test_aged_partner_balance.py +99 -9
- odoo/addons/account_financial_report/tests/test_general_ledger.py +19 -9
- odoo/addons/account_financial_report/tests/test_journal_ledger.py +18 -9
- odoo/addons/account_financial_report/tests/test_open_items.py +42 -2
- odoo/addons/account_financial_report/tests/test_trial_balance.py +114 -223
- odoo/addons/account_financial_report/tests/test_vat_report.py +17 -9
- odoo/addons/account_financial_report/view/account_age_report_configuration_views.xml +41 -0
- odoo/addons/account_financial_report/view/res_config_settings_views.xml +51 -0
- odoo/addons/account_financial_report/wizard/abstract_wizard.py +23 -0
- odoo/addons/account_financial_report/wizard/aged_partner_balance_wizard.py +22 -8
- odoo/addons/account_financial_report/wizard/aged_partner_balance_wizard_view.xml +2 -3
- odoo/addons/account_financial_report/wizard/general_ledger_wizard.py +42 -36
- odoo/addons/account_financial_report/wizard/general_ledger_wizard_view.xml +26 -41
- odoo/addons/account_financial_report/wizard/journal_ledger_wizard.py +19 -7
- odoo/addons/account_financial_report/wizard/journal_ledger_wizard_view.xml +15 -14
- odoo/addons/account_financial_report/wizard/open_items_wizard.py +34 -8
- odoo/addons/account_financial_report/wizard/open_items_wizard_view.xml +16 -14
- odoo/addons/account_financial_report/wizard/trial_balance_wizard.py +68 -45
- odoo/addons/account_financial_report/wizard/trial_balance_wizard_view.xml +40 -39
- odoo/addons/account_financial_report/wizard/vat_report_wizard.py +9 -3
- odoo/addons/account_financial_report/wizard/vat_report_wizard_view.xml +14 -14
- odoo_addon_account_financial_report-18.0.1.4.4.3.dist-info/METADATA +234 -0
- odoo_addon_account_financial_report-18.0.1.4.4.3.dist-info/RECORD +107 -0
- {odoo_addon_account_financial_report-15.0.1.1.0.1.dist-info → odoo_addon_account_financial_report-18.0.1.4.4.3.dist-info}/WHEEL +1 -1
- odoo_addon_account_financial_report-18.0.1.4.4.3.dist-info/top_level.txt +1 -0
- odoo/addons/account_financial_report/readme/CONTRIBUTORS.rst +0 -35
- odoo/addons/account_financial_report/readme/DESCRIPTION.rst +0 -16
- odoo/addons/account_financial_report/readme/HISTORY.rst +0 -19
- odoo/addons/account_financial_report/readme/ROADMAP.rst +0 -7
- odoo/addons/account_financial_report/static/src/js/action_manager_report.js +0 -37
- odoo/addons/account_financial_report/static/src/js/client_action.js +0 -58
- odoo/addons/account_financial_report/static/src/js/report.js +0 -58
- odoo_addon_account_financial_report-15.0.1.1.0.1.dist-info/METADATA +0 -179
- odoo_addon_account_financial_report-15.0.1.1.0.1.dist-info/RECORD +0 -95
- odoo_addon_account_financial_report-15.0.1.1.0.1.dist-info/top_level.txt +0 -1
|
@@ -17,7 +17,7 @@ class JournalLedgerXslx(models.AbstractModel):
|
|
|
17
17
|
report_name = _("Journal Ledger")
|
|
18
18
|
if company_id:
|
|
19
19
|
company = self.env["res.company"].browse(company_id)
|
|
20
|
-
suffix = " - {} - {
|
|
20
|
+
suffix = f" - {company.name} - {company.currency_id.name}"
|
|
21
21
|
report_name = report_name + suffix
|
|
22
22
|
return report_name
|
|
23
23
|
|
|
@@ -149,7 +149,7 @@ class JournalLedgerXslx(models.AbstractModel):
|
|
|
149
149
|
_("Journals"),
|
|
150
150
|
", ".join(
|
|
151
151
|
[
|
|
152
|
-
"{} - {
|
|
152
|
+
f"{report_journal.code} - {report_journal.name}"
|
|
153
153
|
for report_journal in report.journal_ids
|
|
154
154
|
]
|
|
155
155
|
),
|
|
@@ -178,13 +178,17 @@ class JournalLedgerXslx(models.AbstractModel):
|
|
|
178
178
|
def _generate_journal_content(
|
|
179
179
|
self, workbook, report, res_data, ledger, report_data
|
|
180
180
|
):
|
|
181
|
-
journal =
|
|
181
|
+
journal = (
|
|
182
|
+
self.env["account.journal"]
|
|
183
|
+
.with_context(active_test=False)
|
|
184
|
+
.browse(ledger["id"])
|
|
185
|
+
)
|
|
182
186
|
currency_name = (
|
|
183
187
|
journal.currency_id
|
|
184
188
|
and journal.currency_id.name
|
|
185
189
|
or journal.company_id.currency_id.name
|
|
186
190
|
)
|
|
187
|
-
sheet_name = "{} ({}) - {
|
|
191
|
+
sheet_name = f"{journal.code} ({currency_name}) - {journal.name}"
|
|
188
192
|
self._generate_moves_content(
|
|
189
193
|
workbook, sheet_name, report, res_data, ledger["report_moves"], report_data
|
|
190
194
|
)
|
|
@@ -196,15 +200,17 @@ class JournalLedgerXslx(models.AbstractModel):
|
|
|
196
200
|
)
|
|
197
201
|
|
|
198
202
|
def _generate_journal_taxes_summary(self, workbook, ledger, report_data):
|
|
199
|
-
journal =
|
|
203
|
+
journal = (
|
|
204
|
+
self.env["account.journal"]
|
|
205
|
+
.with_context(active_test=False)
|
|
206
|
+
.browse(ledger["id"])
|
|
207
|
+
)
|
|
200
208
|
currency_name = (
|
|
201
209
|
journal.currency_id
|
|
202
210
|
and journal.currency_id.name
|
|
203
211
|
or journal.company_id.currency_id.name
|
|
204
212
|
)
|
|
205
|
-
sheet_name = "Tax - {} ({}) - {}"
|
|
206
|
-
journal.code, currency_name, journal.name
|
|
207
|
-
)
|
|
213
|
+
sheet_name = f"Tax - {journal.code} ({currency_name}) - {journal.name}"
|
|
208
214
|
self._generate_taxes_summary(
|
|
209
215
|
workbook, sheet_name, ledger["tax_lines"], report_data
|
|
210
216
|
)
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# © 2016 Julien Coux (Camptocamp)
|
|
2
2
|
# Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com)
|
|
3
|
+
# Copyright 2024 Tecnativa - Carolina Fernandez
|
|
3
4
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|
4
5
|
|
|
5
6
|
import operator
|
|
6
7
|
from datetime import date, datetime
|
|
7
8
|
|
|
8
|
-
from odoo import api, models
|
|
9
|
+
from odoo import _, api, models
|
|
9
10
|
from odoo.tools import float_is_zero
|
|
10
11
|
|
|
11
12
|
|
|
@@ -16,25 +17,47 @@ class OpenItemsReport(models.AbstractModel):
|
|
|
16
17
|
|
|
17
18
|
def _get_account_partial_reconciled(self, company_id, date_at_object):
|
|
18
19
|
domain = [("max_date", ">", date_at_object), ("company_id", "=", company_id)]
|
|
19
|
-
fields = [
|
|
20
|
+
fields = [
|
|
21
|
+
"debit_move_id",
|
|
22
|
+
"credit_move_id",
|
|
23
|
+
"amount",
|
|
24
|
+
"debit_amount_currency",
|
|
25
|
+
"credit_amount_currency",
|
|
26
|
+
]
|
|
20
27
|
accounts_partial_reconcile = self.env["account.partial.reconcile"].search_read(
|
|
21
28
|
domain=domain, fields=fields
|
|
22
29
|
)
|
|
23
30
|
debit_amount = {}
|
|
31
|
+
debit_amount_currency = {}
|
|
24
32
|
credit_amount = {}
|
|
33
|
+
credit_amount_currency = {}
|
|
25
34
|
for account_partial_reconcile_data in accounts_partial_reconcile:
|
|
26
35
|
debit_move_id = account_partial_reconcile_data["debit_move_id"][0]
|
|
27
36
|
credit_move_id = account_partial_reconcile_data["credit_move_id"][0]
|
|
28
37
|
if debit_move_id not in debit_amount.keys():
|
|
29
38
|
debit_amount[debit_move_id] = 0.0
|
|
39
|
+
debit_amount_currency[debit_move_id] = 0.0
|
|
30
40
|
debit_amount[debit_move_id] += account_partial_reconcile_data["amount"]
|
|
41
|
+
debit_amount_currency[debit_move_id] += account_partial_reconcile_data[
|
|
42
|
+
"debit_amount_currency"
|
|
43
|
+
]
|
|
31
44
|
if credit_move_id not in credit_amount.keys():
|
|
32
45
|
credit_amount[credit_move_id] = 0.0
|
|
46
|
+
credit_amount_currency[credit_move_id] = 0.0
|
|
33
47
|
credit_amount[credit_move_id] += account_partial_reconcile_data["amount"]
|
|
48
|
+
credit_amount_currency[credit_move_id] += account_partial_reconcile_data[
|
|
49
|
+
"credit_amount_currency"
|
|
50
|
+
]
|
|
34
51
|
account_partial_reconcile_data.update(
|
|
35
52
|
{"debit_move_id": debit_move_id, "credit_move_id": credit_move_id}
|
|
36
53
|
)
|
|
37
|
-
return
|
|
54
|
+
return (
|
|
55
|
+
accounts_partial_reconcile,
|
|
56
|
+
debit_amount,
|
|
57
|
+
credit_amount,
|
|
58
|
+
debit_amount_currency,
|
|
59
|
+
credit_amount_currency,
|
|
60
|
+
)
|
|
38
61
|
|
|
39
62
|
def _get_data(
|
|
40
63
|
self,
|
|
@@ -44,39 +67,25 @@ class OpenItemsReport(models.AbstractModel):
|
|
|
44
67
|
only_posted_moves,
|
|
45
68
|
company_id,
|
|
46
69
|
date_from,
|
|
70
|
+
grouped_by,
|
|
47
71
|
):
|
|
48
72
|
domain = self._get_move_lines_domain_not_reconciled(
|
|
49
73
|
company_id, account_ids, partner_ids, only_posted_moves, date_from
|
|
50
74
|
)
|
|
51
|
-
ml_fields =
|
|
52
|
-
"id",
|
|
53
|
-
"name",
|
|
54
|
-
"date",
|
|
55
|
-
"move_id",
|
|
56
|
-
"journal_id",
|
|
57
|
-
"account_id",
|
|
58
|
-
"partner_id",
|
|
59
|
-
"amount_residual",
|
|
60
|
-
"date_maturity",
|
|
61
|
-
"ref",
|
|
62
|
-
"debit",
|
|
63
|
-
"credit",
|
|
64
|
-
"reconciled",
|
|
65
|
-
"currency_id",
|
|
66
|
-
"amount_currency",
|
|
67
|
-
"amount_residual_currency",
|
|
68
|
-
]
|
|
75
|
+
ml_fields = self._get_ml_fields()
|
|
69
76
|
move_lines = self.env["account.move.line"].search_read(
|
|
70
77
|
domain=domain, fields=ml_fields
|
|
71
78
|
)
|
|
72
79
|
journals_ids = set()
|
|
73
|
-
|
|
80
|
+
group_ids = set()
|
|
74
81
|
partners_data = {}
|
|
75
82
|
if date_at_object < date.today():
|
|
76
83
|
(
|
|
77
84
|
acc_partial_rec,
|
|
78
85
|
debit_amount,
|
|
79
86
|
credit_amount,
|
|
87
|
+
debit_amount_currency,
|
|
88
|
+
credit_amount_currency,
|
|
80
89
|
) = self._get_account_partial_reconciled(company_id, date_at_object)
|
|
81
90
|
if acc_partial_rec:
|
|
82
91
|
ml_ids = list(map(operator.itemgetter("id"), move_lines))
|
|
@@ -97,6 +106,8 @@ class OpenItemsReport(models.AbstractModel):
|
|
|
97
106
|
company_id,
|
|
98
107
|
partner_ids,
|
|
99
108
|
only_posted_moves,
|
|
109
|
+
debit_amount_currency,
|
|
110
|
+
credit_amount_currency,
|
|
100
111
|
)
|
|
101
112
|
move_lines = [
|
|
102
113
|
move_line
|
|
@@ -110,35 +121,33 @@ class OpenItemsReport(models.AbstractModel):
|
|
|
110
121
|
journals_ids.add(move_line["journal_id"][0])
|
|
111
122
|
acc_id = move_line["account_id"][0]
|
|
112
123
|
# Partners data
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
124
|
+
partner = self.env["res.partner"]
|
|
125
|
+
if move_line.get("partner_id"):
|
|
126
|
+
partner = self.env["res.partner"].browse(move_line["partner_id"][0])
|
|
127
|
+
if grouped_by == "salesperson":
|
|
128
|
+
user = partner.user_id
|
|
129
|
+
group_id = user.id or 0
|
|
130
|
+
group_name = user.name or _("Missing Salesperson")
|
|
116
131
|
else:
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if
|
|
120
|
-
partners_data.update({
|
|
121
|
-
|
|
122
|
-
|
|
132
|
+
group_id = partner.id or 0
|
|
133
|
+
group_name = partner.name or _("Missing Partner")
|
|
134
|
+
if group_id not in group_ids:
|
|
135
|
+
partners_data.update({group_id: {"id": group_id, "name": group_name}})
|
|
136
|
+
group_ids.add(group_id)
|
|
123
137
|
# Move line update
|
|
124
|
-
original = 0
|
|
125
|
-
|
|
126
138
|
if not float_is_zero(move_line["credit"], precision_digits=2):
|
|
127
139
|
original = move_line["credit"] * (-1)
|
|
128
|
-
|
|
140
|
+
else:
|
|
129
141
|
original = move_line["debit"]
|
|
130
142
|
|
|
131
143
|
if move_line["ref"] == move_line["name"]:
|
|
132
|
-
|
|
133
|
-
ref_label = move_line["ref"]
|
|
134
|
-
else:
|
|
135
|
-
ref_label = ""
|
|
144
|
+
ref_label = move_line["ref"] or ""
|
|
136
145
|
elif not move_line["ref"]:
|
|
137
146
|
ref_label = move_line["name"]
|
|
138
147
|
elif not move_line["name"]:
|
|
139
148
|
ref_label = move_line["ref"]
|
|
140
149
|
else:
|
|
141
|
-
ref_label = move_line["ref"] +
|
|
150
|
+
ref_label = move_line["ref"] + " - " + move_line["name"]
|
|
142
151
|
|
|
143
152
|
move_line.update(
|
|
144
153
|
{
|
|
@@ -146,11 +155,11 @@ class OpenItemsReport(models.AbstractModel):
|
|
|
146
155
|
"date_maturity": move_line["date_maturity"]
|
|
147
156
|
and move_line["date_maturity"].strftime("%d/%m/%Y"),
|
|
148
157
|
"original": original,
|
|
149
|
-
"partner_id":
|
|
150
|
-
"partner_name":
|
|
158
|
+
"partner_id": partner.id or 0,
|
|
159
|
+
"partner_name": partner.name or "",
|
|
151
160
|
"ref_label": ref_label,
|
|
152
161
|
"journal_id": move_line["journal_id"][0],
|
|
153
|
-
"move_name": move_line["
|
|
162
|
+
"move_name": move_line["move_name"],
|
|
154
163
|
"entry_id": move_line["move_id"][0],
|
|
155
164
|
"currency_id": move_line["currency_id"][0]
|
|
156
165
|
if move_line["currency_id"]
|
|
@@ -163,12 +172,12 @@ class OpenItemsReport(models.AbstractModel):
|
|
|
163
172
|
|
|
164
173
|
# Open Items Move Lines Data
|
|
165
174
|
if acc_id not in open_items_move_lines_data.keys():
|
|
166
|
-
open_items_move_lines_data[acc_id] = {
|
|
175
|
+
open_items_move_lines_data[acc_id] = {group_id: [move_line]}
|
|
167
176
|
else:
|
|
168
|
-
if
|
|
169
|
-
open_items_move_lines_data[acc_id][
|
|
177
|
+
if group_id not in open_items_move_lines_data[acc_id].keys():
|
|
178
|
+
open_items_move_lines_data[acc_id][group_id] = [move_line]
|
|
170
179
|
else:
|
|
171
|
-
open_items_move_lines_data[acc_id][
|
|
180
|
+
open_items_move_lines_data[acc_id][group_id].append(move_line)
|
|
172
181
|
journals_data = self._get_journals_data(list(journals_ids))
|
|
173
182
|
accounts_data = self._get_accounts_data(open_items_move_lines_data.keys())
|
|
174
183
|
return (
|
|
@@ -197,11 +206,18 @@ class OpenItemsReport(models.AbstractModel):
|
|
|
197
206
|
|
|
198
207
|
@api.model
|
|
199
208
|
def _order_open_items_by_date(
|
|
200
|
-
self,
|
|
209
|
+
self,
|
|
210
|
+
open_items_move_lines_data,
|
|
211
|
+
show_partner_details,
|
|
212
|
+
partners_data,
|
|
213
|
+
accounts_data,
|
|
201
214
|
):
|
|
215
|
+
# We need to order by account code, partner_name and date
|
|
216
|
+
accounts_data_sorted = sorted(accounts_data.items(), key=lambda x: x[1]["code"])
|
|
217
|
+
account_ids_sorted = [account[0] for account in accounts_data_sorted]
|
|
202
218
|
new_open_items = {}
|
|
203
219
|
if not show_partner_details:
|
|
204
|
-
for acc_id in
|
|
220
|
+
for acc_id in account_ids_sorted:
|
|
205
221
|
new_open_items[acc_id] = {}
|
|
206
222
|
move_lines = []
|
|
207
223
|
for prt_id in open_items_move_lines_data[acc_id]:
|
|
@@ -210,18 +226,24 @@ class OpenItemsReport(models.AbstractModel):
|
|
|
210
226
|
move_lines = sorted(move_lines, key=lambda k: (k["date"]))
|
|
211
227
|
new_open_items[acc_id] = move_lines
|
|
212
228
|
else:
|
|
213
|
-
for acc_id in
|
|
229
|
+
for acc_id in account_ids_sorted:
|
|
214
230
|
new_open_items[acc_id] = {}
|
|
215
|
-
for prt_id in
|
|
231
|
+
for prt_id in sorted(
|
|
232
|
+
open_items_move_lines_data[acc_id],
|
|
233
|
+
key=lambda i: partners_data[i]["name"],
|
|
234
|
+
):
|
|
216
235
|
new_open_items[acc_id][prt_id] = {}
|
|
217
236
|
move_lines = []
|
|
218
237
|
for move_line in open_items_move_lines_data[acc_id][prt_id]:
|
|
219
238
|
move_lines += [move_line]
|
|
220
|
-
move_lines = sorted(
|
|
239
|
+
move_lines = sorted(
|
|
240
|
+
move_lines, key=lambda k: (k["date"], k["partner_id"])
|
|
241
|
+
)
|
|
221
242
|
new_open_items[acc_id][prt_id] = move_lines
|
|
222
243
|
return new_open_items
|
|
223
244
|
|
|
224
245
|
def _get_report_values(self, docids, data):
|
|
246
|
+
res = super()._get_report_values(docids, data)
|
|
225
247
|
wizard_id = data["wizard_id"]
|
|
226
248
|
company = self.env["res.company"].browse(data["company_id"])
|
|
227
249
|
company_id = data["company_id"]
|
|
@@ -232,7 +254,7 @@ class OpenItemsReport(models.AbstractModel):
|
|
|
232
254
|
date_from = data["date_from"]
|
|
233
255
|
only_posted_moves = data["only_posted_moves"]
|
|
234
256
|
show_partner_details = data["show_partner_details"]
|
|
235
|
-
|
|
257
|
+
grouped_by = data["grouped_by"]
|
|
236
258
|
(
|
|
237
259
|
move_lines_data,
|
|
238
260
|
partners_data,
|
|
@@ -246,26 +268,47 @@ class OpenItemsReport(models.AbstractModel):
|
|
|
246
268
|
only_posted_moves,
|
|
247
269
|
company_id,
|
|
248
270
|
date_from,
|
|
271
|
+
grouped_by,
|
|
249
272
|
)
|
|
250
273
|
|
|
251
274
|
total_amount = self._calculate_amounts(open_items_move_lines_data)
|
|
252
275
|
open_items_move_lines_data = self._order_open_items_by_date(
|
|
253
|
-
open_items_move_lines_data,
|
|
276
|
+
open_items_move_lines_data,
|
|
277
|
+
show_partner_details,
|
|
278
|
+
partners_data,
|
|
279
|
+
accounts_data,
|
|
280
|
+
)
|
|
281
|
+
res.update(
|
|
282
|
+
{
|
|
283
|
+
"doc_ids": [wizard_id],
|
|
284
|
+
"doc_model": "open.items.report.wizard",
|
|
285
|
+
"docs": self.env["open.items.report.wizard"].browse(wizard_id),
|
|
286
|
+
"foreign_currency": data["foreign_currency"],
|
|
287
|
+
"show_partner_details": data["show_partner_details"],
|
|
288
|
+
"company_name": company.display_name,
|
|
289
|
+
"currency_name": company.currency_id.name,
|
|
290
|
+
"date_at": date_at_object.strftime("%d/%m/%Y"),
|
|
291
|
+
"hide_account_at_0": data["hide_account_at_0"],
|
|
292
|
+
"target_move": data["target_move"],
|
|
293
|
+
"journals_data": journals_data,
|
|
294
|
+
"partners_data": partners_data,
|
|
295
|
+
"accounts_data": accounts_data,
|
|
296
|
+
"total_amount": total_amount,
|
|
297
|
+
"Open_Items": open_items_move_lines_data,
|
|
298
|
+
"grouped_by": grouped_by,
|
|
299
|
+
}
|
|
254
300
|
)
|
|
255
|
-
return
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
"
|
|
260
|
-
"
|
|
261
|
-
"
|
|
262
|
-
"
|
|
263
|
-
"
|
|
264
|
-
"
|
|
265
|
-
"
|
|
266
|
-
"
|
|
267
|
-
"
|
|
268
|
-
|
|
269
|
-
"total_amount": total_amount,
|
|
270
|
-
"Open_Items": open_items_move_lines_data,
|
|
271
|
-
}
|
|
301
|
+
return res
|
|
302
|
+
|
|
303
|
+
def _get_ml_fields(self):
|
|
304
|
+
return self.COMMON_ML_FIELDS + [
|
|
305
|
+
"amount_residual",
|
|
306
|
+
"reconciled",
|
|
307
|
+
"currency_id",
|
|
308
|
+
"credit",
|
|
309
|
+
"date_maturity",
|
|
310
|
+
"amount_residual_currency",
|
|
311
|
+
"debit",
|
|
312
|
+
"amount_currency",
|
|
313
|
+
"move_name",
|
|
314
|
+
]
|
|
@@ -16,7 +16,7 @@ class OpenItemsXslx(models.AbstractModel):
|
|
|
16
16
|
report_name = _("Open Items")
|
|
17
17
|
if company_id:
|
|
18
18
|
company = self.env["res.company"].browse(company_id)
|
|
19
|
-
suffix = " - {} - {
|
|
19
|
+
suffix = f" - {company.name} - {company.currency_id.name}"
|
|
20
20
|
report_name = report_name + suffix
|
|
21
21
|
return report_name
|
|
22
22
|
|
|
@@ -101,11 +101,126 @@ class OpenItemsXslx(models.AbstractModel):
|
|
|
101
101
|
def _get_col_pos_final_balance_label(self):
|
|
102
102
|
return 5
|
|
103
103
|
|
|
104
|
-
def
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
104
|
+
def _calculate_amounts_by_partner(self, account_id, open_items_move_lines_data):
|
|
105
|
+
total_amount = {}
|
|
106
|
+
for line in open_items_move_lines_data:
|
|
107
|
+
partner_id_key = line["partner_id"]
|
|
108
|
+
if account_id not in total_amount:
|
|
109
|
+
total_amount[account_id] = {}
|
|
110
|
+
if partner_id_key not in total_amount[account_id]:
|
|
111
|
+
total_amount[account_id][partner_id_key] = {"residual": 0.0}
|
|
112
|
+
total_amount[account_id][partner_id_key]["residual"] += line[
|
|
113
|
+
"amount_residual"
|
|
114
|
+
]
|
|
115
|
+
return total_amount
|
|
116
|
+
|
|
117
|
+
def _generate_report_content_by_salesperson(
|
|
118
|
+
self, workbook, report, data, report_data, res_data
|
|
119
|
+
):
|
|
120
|
+
Open_items = res_data["Open_Items"]
|
|
121
|
+
accounts_data = res_data["accounts_data"]
|
|
122
|
+
partners_data = res_data["partners_data"]
|
|
123
|
+
journals_data = res_data["journals_data"]
|
|
124
|
+
total_amount = res_data["total_amount"]
|
|
125
|
+
|
|
126
|
+
for partner_id in partners_data.keys():
|
|
127
|
+
# Create a new sheet for each partner
|
|
128
|
+
partner_totals = {}
|
|
129
|
+
partner_name = partners_data[partner_id]["name"]
|
|
130
|
+
new_sheet = workbook.add_worksheet(partner_name[:31])
|
|
131
|
+
report_data["sheet"] = new_sheet
|
|
132
|
+
report_data["row_pos"] = 0
|
|
133
|
+
|
|
134
|
+
for account_id in Open_items.keys():
|
|
135
|
+
if partner_id in Open_items[account_id]:
|
|
136
|
+
self.write_array_title(
|
|
137
|
+
accounts_data[account_id]["code"]
|
|
138
|
+
+ " - "
|
|
139
|
+
+ accounts_data[account_id]["name"],
|
|
140
|
+
report_data,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
# For each partner
|
|
144
|
+
if Open_items[account_id]:
|
|
145
|
+
type_object = "partner"
|
|
146
|
+
# Write partner title
|
|
147
|
+
self.write_array_title(
|
|
148
|
+
partners_data[partner_id]["name"], report_data
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
# Calculate totals by partner_id
|
|
152
|
+
partner_totals = self._calculate_amounts_by_partner(
|
|
153
|
+
account_id, Open_items[account_id][partner_id]
|
|
154
|
+
)
|
|
155
|
+
# Display array header for move lines
|
|
156
|
+
self.write_array_header(report_data)
|
|
157
|
+
# Display account move lines
|
|
158
|
+
has_lines = False
|
|
159
|
+
for partner_id_key, total_amount_dict in partner_totals.get(
|
|
160
|
+
account_id, {}
|
|
161
|
+
).items():
|
|
162
|
+
for line in Open_items[account_id][partner_id]:
|
|
163
|
+
if line["partner_id"] == partner_id_key:
|
|
164
|
+
line.update(
|
|
165
|
+
{
|
|
166
|
+
"account": accounts_data[account_id][
|
|
167
|
+
"code"
|
|
168
|
+
],
|
|
169
|
+
"journal": journals_data[
|
|
170
|
+
line["journal_id"]
|
|
171
|
+
]["code"],
|
|
172
|
+
}
|
|
173
|
+
)
|
|
174
|
+
self.write_line_from_dict(line, report_data)
|
|
175
|
+
has_lines = True
|
|
176
|
+
if has_lines:
|
|
177
|
+
partner = self.env["res.partner"].browse(partner_id_key)
|
|
178
|
+
# Display ending balance line for partner
|
|
179
|
+
partner_data = {
|
|
180
|
+
"id": partner_id_key,
|
|
181
|
+
"name": partner.name
|
|
182
|
+
if partner
|
|
183
|
+
else _("Missing Partner"),
|
|
184
|
+
"currency_id": accounts_data[account_id][
|
|
185
|
+
"currency_id"
|
|
186
|
+
],
|
|
187
|
+
"currency_name": accounts_data[account_id][
|
|
188
|
+
"currency_name"
|
|
189
|
+
],
|
|
190
|
+
"residual": total_amount_dict,
|
|
191
|
+
}
|
|
192
|
+
self.write_ending_balance_from_dict(
|
|
193
|
+
partner_data,
|
|
194
|
+
"partner_subtotal",
|
|
195
|
+
partner_totals,
|
|
196
|
+
report_data,
|
|
197
|
+
account_id=account_id,
|
|
198
|
+
partner_id=partner_id_key,
|
|
199
|
+
)
|
|
200
|
+
has_lines = False
|
|
201
|
+
# Display ending balance line for salesperson
|
|
202
|
+
partners_data[partner_id].update(
|
|
203
|
+
{
|
|
204
|
+
"currency_id": accounts_data[account_id]["currency_id"],
|
|
205
|
+
"currency_name": accounts_data[account_id][
|
|
206
|
+
"currency_name"
|
|
207
|
+
],
|
|
208
|
+
}
|
|
209
|
+
)
|
|
210
|
+
self.write_ending_balance_from_dict(
|
|
211
|
+
partners_data[partner_id],
|
|
212
|
+
type_object,
|
|
213
|
+
total_amount,
|
|
214
|
+
report_data,
|
|
215
|
+
account_id=account_id,
|
|
216
|
+
partner_id=partner_id,
|
|
217
|
+
)
|
|
218
|
+
# Line break
|
|
219
|
+
report_data["row_pos"] += 1
|
|
220
|
+
|
|
221
|
+
def _generate_report_content_by_partner(
|
|
222
|
+
self, workbook, report, data, report_data, res_data
|
|
223
|
+
):
|
|
109
224
|
Open_items = res_data["Open_Items"]
|
|
110
225
|
accounts_data = res_data["accounts_data"]
|
|
111
226
|
partners_data = res_data["partners_data"]
|
|
@@ -120,7 +235,6 @@ class OpenItemsXslx(models.AbstractModel):
|
|
|
120
235
|
+ accounts_data[account_id]["name"],
|
|
121
236
|
report_data,
|
|
122
237
|
)
|
|
123
|
-
|
|
124
238
|
# For each partner
|
|
125
239
|
if Open_items[account_id]:
|
|
126
240
|
if show_partner_details:
|
|
@@ -180,18 +294,33 @@ class OpenItemsXslx(models.AbstractModel):
|
|
|
180
294
|
)
|
|
181
295
|
self.write_line_from_dict(line, report_data)
|
|
182
296
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
297
|
+
# Display ending balance line for account
|
|
298
|
+
type_object = "account"
|
|
299
|
+
self.write_ending_balance_from_dict(
|
|
300
|
+
accounts_data[account_id],
|
|
301
|
+
type_object,
|
|
302
|
+
total_amount,
|
|
303
|
+
report_data,
|
|
304
|
+
account_id=account_id,
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
# 2 lines break
|
|
308
|
+
report_data["row_pos"] += 2
|
|
192
309
|
|
|
193
|
-
|
|
194
|
-
|
|
310
|
+
def _generate_report_content(self, workbook, report, data, report_data):
|
|
311
|
+
res_data = self.env[
|
|
312
|
+
"report.account_financial_report.open_items"
|
|
313
|
+
]._get_report_values(report, data)
|
|
314
|
+
show_partner_details = res_data["show_partner_details"]
|
|
315
|
+
grouped_by = res_data["grouped_by"]
|
|
316
|
+
if grouped_by == "salesperson" and show_partner_details:
|
|
317
|
+
return self._generate_report_content_by_salesperson(
|
|
318
|
+
workbook, report, data, report_data, res_data
|
|
319
|
+
)
|
|
320
|
+
else:
|
|
321
|
+
return self._generate_report_content_by_partner(
|
|
322
|
+
workbook, report, data, report_data, res_data
|
|
323
|
+
)
|
|
195
324
|
|
|
196
325
|
def write_ending_balance_from_dict(
|
|
197
326
|
self,
|
|
@@ -211,6 +340,10 @@ class OpenItemsXslx(models.AbstractModel):
|
|
|
211
340
|
name = my_object["code"] + " - " + my_object["name"]
|
|
212
341
|
my_object["residual"] = total_amount[account_id]["residual"]
|
|
213
342
|
label = _("Ending balance")
|
|
214
|
-
|
|
343
|
+
elif type_object == "partner_subtotal":
|
|
344
|
+
name = my_object["name"]
|
|
345
|
+
my_object["residual"] = total_amount[account_id][partner_id]["residual"]
|
|
346
|
+
label = _("Ending balance")
|
|
347
|
+
return super().write_ending_balance_from_dict(
|
|
215
348
|
my_object, name, label, report_data
|
|
216
349
|
)
|