Skip to content

Commit 59d6679

Browse files
committed
[IMP] new module: account_currency_reports_ux
1 parent be3c88a commit 59d6679

File tree

4 files changed

+182
-0
lines changed

4 files changed

+182
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# -*- coding: utf-8 -*-
2+
# Part of Odoo. See LICENSE file for full copyright and licensing details.
3+
4+
from .hooks import uninstall_hook
5+
from .monkey_patches import *
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
##############################################################################
2+
#
3+
# Copyright (C) 2024 ADHOC SA (http://www.adhoc.com.ar)
4+
# All Rights Reserved.
5+
#
6+
# This program is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU Affero General Public License as
8+
# published by the Free Software Foundation, either version 3 of the
9+
# License, or (at your option) any later version.
10+
#
11+
# This program is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU Affero General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU Affero General Public License
17+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
#
19+
##############################################################################
20+
{
21+
'name': 'Account Currency Reports UX',
22+
'version': "18.0.1.0.0",
23+
'category': 'Accounting',
24+
'sequence': 14,
25+
'summary': 'Restrict the use of certain journals to certain users',
26+
'author': 'ADHOC SA',
27+
'website': 'www.adhoc.com.ar',
28+
'license': 'AGPL-3',
29+
'images': [
30+
],
31+
'depends': [
32+
'account',
33+
],
34+
'data': [
35+
],
36+
'demo': [
37+
],
38+
'test': [
39+
],
40+
'installable': True,
41+
'auto_install': False,
42+
'application': False,
43+
'post_load': 'monkey_patches',
44+
'uninstall_hook': 'uninstall_hook'
45+
}

account_currency_reports_ux/hooks.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
##############################################################################
2+
# For copyright and license notices, see __manifest__.py file in module root
3+
# directory
4+
##############################################################################
5+
from odoo.addons.account.report.account_invoice_report import AccountInvoiceReport
6+
7+
def _revert_method(cls, name):
8+
""" Revert the original method called ``name`` in the given class.
9+
See :meth:`~._patch_method`.
10+
"""
11+
method = getattr(cls, name)
12+
setattr(cls, name, method.origin)
13+
14+
15+
def uninstall_hook(cr, registry):
16+
_revert_method(AccountInvoiceReport, '_select')
17+
_revert_method(AccountInvoiceReport, '_from')
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
from odoo import api
2+
from odoo.tools import SQL
3+
from odoo.addons.account.report.account_invoice_report import AccountInvoiceReport
4+
5+
def monkey_patches():
6+
7+
# monkey patch
8+
@api.model
9+
def _select_patch(self) -> SQL:
10+
return SQL(
11+
'''
12+
WITH currency_rate AS MATERIALIZED (
13+
SELECT
14+
r.currency_id,
15+
COALESCE(r.company_id, c.id) as company_id,
16+
1/r.rate as rate,
17+
r.name AS date_start,
18+
(SELECT name FROM res_currency_rate r2
19+
WHERE r2.name > r.name AND
20+
r2.currency_id = r.currency_id AND
21+
(r2.company_id = c.id)
22+
ORDER BY r2.name ASC
23+
LIMIT 1) AS date_end
24+
FROM res_currency_rate r
25+
JOIN res_company c ON (r.company_id = c.id)
26+
WHERE c.id = %s
27+
)
28+
SELECT
29+
line.id,
30+
line.move_id,
31+
line.product_id,
32+
line.account_id,
33+
line.journal_id,
34+
line.company_id,
35+
line.company_currency_id,
36+
line.partner_id AS commercial_partner_id,
37+
account.account_type AS user_type,
38+
move.state,
39+
move.move_type,
40+
move.partner_id,
41+
move.invoice_user_id,
42+
move.fiscal_position_id,
43+
move.payment_state,
44+
move.invoice_date,
45+
move.invoice_date_due,
46+
uom_template.id AS product_uom_id,
47+
template.categ_id AS product_categ_id,
48+
line.quantity / NULLIF(COALESCE(uom_line.factor, 1) / COALESCE(uom_template.factor, 1), 0.0) * (CASE WHEN move.move_type IN ('in_invoice','out_refund','in_receipt') THEN -1 ELSE 1 END)
49+
AS quantity,
50+
line.price_subtotal * (CASE WHEN move.move_type IN ('in_invoice','out_refund','in_receipt') THEN -1 ELSE 1 END)
51+
AS price_subtotal_currency,
52+
CASE WHEN rc.currency_id <> line.company_currency_id THEN -line.balance * currency_table.rate ELSE -line.balance END AS price_subtotal,
53+
line.price_total * (CASE WHEN move.move_type IN ('in_invoice','out_refund','in_receipt') THEN -1 ELSE 1 END)
54+
AS price_total,
55+
CASE WHEN rc.currency_id <> line.company_currency_id THEN
56+
-COALESCE(
57+
-- Average line price
58+
(line.balance / NULLIF(line.quantity, 0.0)) * (CASE WHEN move.move_type IN ('in_invoice','out_refund','in_receipt') THEN -1 ELSE 1 END)
59+
-- convert to template uom
60+
* (NULLIF(COALESCE(uom_line.factor, 1), 0.0) / NULLIF(COALESCE(uom_template.factor, 1), 0.0)),
61+
0.0) * currency_table.rate
62+
ELSE -COALESCE(
63+
-- Average line price
64+
(line.balance / NULLIF(line.quantity, 0.0)) * (CASE WHEN move.move_type IN ('in_invoice','out_refund','in_receipt') THEN -1 ELSE 1 END)
65+
-- convert to template uom
66+
* (NULLIF(COALESCE(uom_line.factor, 1), 0.0) / NULLIF(COALESCE(uom_template.factor, 1), 0.0)),
67+
0.0) END
68+
AS price_average,
69+
CASE
70+
WHEN move.move_type NOT IN ('out_invoice', 'out_receipt', 'out_refund') THEN 0.0
71+
WHEN move.move_type = 'out_refund' AND rc.currency_id <> line.company_currency_id THEN -line.balance * currency_table.rate + (line.quantity / NULLIF(COALESCE(uom_line.factor, 1) / COALESCE(uom_template.factor, 1), 0.0)) * COALESCE(product.standard_price -> line.company_id::text, to_jsonb(0.0))::float
72+
WHEN move.move_type = 'out_refund' AND rc.currency_id = line.company_currency_id THEN -line.balance * 1.0 + (line.quantity / NULLIF(COALESCE(uom_line.factor, 1) / COALESCE(uom_template.factor, 1), 0.0)) * COALESCE(product.standard_price -> line.company_id::text, to_jsonb(0.0))::float
73+
WHEN move.move_type IN ('out_invoice', 'out_receipt') AND rc.currency_id <> line.company_currency_id THEN -line.balance * currency_table.rate - (line.quantity / NULLIF(COALESCE(uom_line.factor, 1) / COALESCE(uom_template.factor, 1), 0.0)) * COALESCE(product.standard_price -> line.company_id::text, to_jsonb(0.0))::float
74+
ELSE -line.balance * 1.0 + (line.quantity / NULLIF(COALESCE(uom_line.factor, 1) / COALESCE(uom_template.factor, 1), 0.0)) * COALESCE(product.standard_price -> line.company_id::text, to_jsonb(0.0))::float
75+
END
76+
AS price_margin,
77+
line.quantity / NULLIF(COALESCE(uom_line.factor, 1) / COALESCE(uom_template.factor, 1), 0.0) * (CASE WHEN move.move_type IN ('out_invoice','in_refund','out_receipt') THEN -1 ELSE 1 END)
78+
* COALESCE(product.standard_price -> line.company_id::text, to_jsonb(0.0))::float AS inventory_value,
79+
COALESCE(partner.country_id, commercial_partner.country_id) AS country_id,
80+
line.currency_id AS currency_id
81+
''', self.env.company.id
82+
)
83+
84+
@api.model
85+
def _from_patch(self) -> SQL:
86+
return SQL(
87+
'''
88+
FROM account_move_line line
89+
LEFT JOIN res_partner partner ON partner.id = line.partner_id
90+
LEFT JOIN product_product product ON product.id = line.product_id
91+
LEFT JOIN account_account account ON account.id = line.account_id
92+
LEFT JOIN product_template template ON template.id = product.product_tmpl_id
93+
LEFT JOIN uom_uom uom_line ON uom_line.id = line.product_uom_id
94+
LEFT JOIN uom_uom uom_template ON uom_template.id = template.uom_id
95+
INNER JOIN account_move move ON move.id = line.move_id
96+
LEFT JOIN res_partner commercial_partner ON commercial_partner.id = move.commercial_partner_id
97+
lEFT JOIN currency_rate currency_table on
98+
(
99+
(currency_table.currency_id = line.currency_id or currency_table.company_id = %s)and
100+
currency_table.date_start <= COALESCE(line.date, NOW()) and
101+
(currency_table.date_end IS NULL OR currency_table.date_end > COALESCE(line.date, NOW())))
102+
LEFT JOIN res_company rc on rc.id=currency_table.company_id
103+
''', self.env.company.id
104+
)
105+
106+
def _patch_method(cls, name, method):
107+
origin = getattr(cls, name)
108+
method.origin = origin
109+
# propagate decorators from origin to method, and apply api decorator
110+
wrapped = api.propagate(origin, method)
111+
wrapped.origin = origin
112+
setattr(cls, name, wrapped)
113+
114+
_patch_method(AccountInvoiceReport, '_select', _select_patch)
115+
_patch_method(AccountInvoiceReport, '_from', _from_patch)

0 commit comments

Comments
 (0)