Skip to content

Commit

Permalink
FIX depends and tax precision
Browse files Browse the repository at this point in the history
  • Loading branch information
micheledic committed Jul 5, 2024
1 parent e4b9354 commit 5d73cd5
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 3 deletions.
2 changes: 1 addition & 1 deletion smile_decimal_precision/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{
"name": "Display Decimal Precision",
"version": "0.3",
"depends": ["base"],
"depends": ["web","account"],
"author": "Smile",
"license": 'AGPL-3',
"description": """
Expand Down
1 change: 1 addition & 0 deletions smile_decimal_precision/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
from . import fields
from . import ir_http
from . import res_currency
from . import account_tax
27 changes: 27 additions & 0 deletions smile_decimal_precision/models/account_tax.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# (C) 2023 Smile (<http://www.smile.fr>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import api, fields, models, tools
from odoo.tools.misc import formatLang

class AccountTax(models.Model):
_inherit = 'account.tax'

@api.model
def _prepare_tax_totals(self, base_lines, currency, tax_lines=None):
res = super()._prepare_tax_totals(base_lines, currency, tax_lines)

groups = res.get('groups_by_subtotal',{})
subtotals = res.get('subtotals',{})
for group in groups:
items = groups.get(group)
for item in items:
item.update({'formatted_tax_group_amount':formatLang(self.env, item['tax_group_amount'], digits=currency.display_decimal_places, currency_obj=currency)})
for subtotal in subtotals:
subtotal.update({'formatted_amount':formatLang(self.env, subtotal['amount'], digits=currency.display_decimal_places, currency_obj=currency)})

res.update({'formatted_amount_total':formatLang(self.env, res['amount_total'], digits=currency.display_decimal_places, currency_obj=currency),
'formatted_amount_untaxed':formatLang(self.env, res['amount_untaxed'], digits=currency.display_decimal_places, currency_obj=currency)

})
return res
71 changes: 69 additions & 2 deletions smile_decimal_precision/report/ir_qweb.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,84 @@
# (C) 2023 Smile (<http://www.smile.fr>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo.addons.base.models.ir_qweb_fields import FloatConverter

from odoo.addons.base.models.ir_qweb_fields import FloatConverter, MonetaryConverter
from markupsafe import Markup, escape
from odoo.tools.misc import formatLang as formatLangOdoo

def record_to_html(self, record, field_name, options):
if 'precision' not in options and 'decimal_precision' not in options:
_, precision = \
record._fields[field_name].get_description(self.env)['digits'] or \
(None, None)
options = dict(options, precision=precision)
#raise Exception(options)
return super(FloatConverter, self).record_to_html(
record, field_name, options)

def record_to_html_monetary(self, record, field_name, options):
options = dict(options)
#currency should be specified by monetary field
field = record._fields[field_name]

if not options.get('display_currency') and field.type == 'monetary' and field.get_currency_field(record):
options['display_currency'] = record[field.get_currency_field(record)]
if not options.get('display_currency'):
# search on the model if they are a res.currency field to set as default
fields = record._fields.items()
currency_fields = [k for k, v in fields if v.type == 'many2one' and v.comodel_name == 'res.currency']
if currency_fields:
options['display_currency'] = record[currency_fields[0]]
if 'date' not in options:
options['date'] = record._context.get('date')
if 'company_id' not in options:
options['company_id'] = record._context.get('company_id')
if 'precision' not in options and 'decimal_precision' not in options and 'digits' in record._fields[field_name].get_description(self.env):

_, precision = \
record._fields[field_name].get_description(self.env)['digits'] or \
(None, None)
options = dict(options, precision=precision)
return super(MonetaryConverter, self).record_to_html(record, field_name, options)
def value_to_html_monetary(self, value, options):
display_currency = options['display_currency']

if not isinstance(value, (int, float)):
raise ValueError(_("The value send to monetary field is not a number."))

# lang.format mandates a sprintf-style format. These formats are non-
# minimal (they have a default fixed precision instead), and
# lang.format will not set one by default. currency.round will not
# provide one either. So we need to generate a precision value
# (integer > 0) from the currency's rounding (a float generally < 1.0).
fmt = "%.{0}f".format(display_currency.display_decimal_places)

if options.get('from_currency'):
date = options.get('date') or fields.Date.today()
company_id = options.get('company_id')
if company_id:
company = self.env['res.company'].browse(company_id)
else:
company = self.env.company
value = options['from_currency']._convert(value, display_currency, company, date)

lang = self.user_lang()
formatted_amount = lang.format(fmt, display_currency.round(value),
grouping=True, monetary=True).replace(r' ', '\N{NO-BREAK SPACE}').replace(r'-', '-\N{ZERO WIDTH NO-BREAK SPACE}')

pre = post = ''
if display_currency.position == 'before':
pre = '{symbol}\N{NO-BREAK SPACE}'.format(symbol=display_currency.symbol or '')
else:
post = '\N{NO-BREAK SPACE}{symbol}'.format(symbol=display_currency.symbol or '')

if options.get('label_price') and lang.decimal_point in formatted_amount:
sep = lang.decimal_point
integer_part, decimal_part = formatted_amount.split(sep)
integer_part += sep
return Markup('{pre}<span class="oe_currency_value">{0}</span><span class="oe_currency_value" style="font-size:0.5em">{1}</span>{post}').format(integer_part, decimal_part, pre=pre, post=post)

return Markup('{pre}<span class="oe_currency_value">{0}</span>{post}').format(formatted_amount, pre=pre, post=post)

FloatConverter.record_to_html = record_to_html
MonetaryConverter.value_to_html = value_to_html_monetary
MonetaryConverter.record_to_html = record_to_html_monetary

0 comments on commit 5d73cd5

Please sign in to comment.