Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MIG] 14.0 - smile_decimal_precision #123

Open
wants to merge 4 commits into
base: 14.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions smile_decimal_precision/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
=========================
Display Decimal Precision
=========================

.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-Smile_SA%2Fodoo_addons-lightgray.png?logo=github
:target: https://github.com/Smile-SA/odoo_addons/tree/15.0/smile_decimal_precision
:alt: Smile-SA/odoo_addons

|badge2| |badge3|


This module allows to distinguish computation digits and display digits in decimal precision.
It is also possible to manage a number of decimal places to display on devices.

Features:

* The administrator edit the decimal precision by specifying the name of digits parameter.
* The administrator put the number of digits he want to compute.
* The administrator put the number of digits he want to display.
* By default the display digits equals the the digits calculated.
* The administrator can make the display digits superior than the the digits calculated.
* The administrator can make the display digits inferior than the the digits calculated.

**Table of contents**

.. contents::
:local:

Usage
=====

To edit a decimal precision :

1. Choose a field that you want to edit its decimal accuracy (Ex. Product Price) :

.. figure:: static/description/choose_field.png
:alt: Choose field
:width: 900px

2. Go to ``Settings > Technical > Database Structure``> Decimal accuracy menu.
3. Select Decimal accuracy corresponding to field.

.. figure:: static/description/select_decimal_accuracy.png
:alt: Select Decimal accuracy
:width: 900px

4. Then edit the value of digits you want to compute, and the number of digits you want to display.

In this example we put 3 digits to display and 5 to compute

.. figure:: static/description/edit_decimal_accuracy.png
:alt: Decimal accuracy edited
:width: 900px

5. Now, go back to your interface to see the new decimal accuracy :

.. figure:: static/description/new_decimal_accuracy.png
:alt: New decimal accuracy
:width: 900px


Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/Smile-SA/odoo_addons/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback
`here <https://github.com/Smile-SA/odoo_addons/issues/new?body=module:%20smile_decimal_precision%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

GDPR / EU Privacy
=================

This addons does not collect any data and does not set any browser cookies.

Credits
=======

Contributors
------------

* Corentin POUHET-BRUNERIE
* Wafaa Jaouahar

Maintainer
----------

This module is maintained by Smile SA.

Since 1991 Smile has been a pioneer of technology and also the European expert in open source solutions.

.. image:: https://avatars0.githubusercontent.com/u/572339?s=200&v=4
:alt: Smile SA
:target: http://smile.fr

This module is part of the `odoo-addons <https://github.com/Smile-SA/odoo_addons>`_ project on GitHub.

You are welcome to contribute.
5 changes: 5 additions & 0 deletions smile_decimal_precision/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# (C) 2023 Smile (<http://www.smile.fr>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from . import models
from . import report
24 changes: 24 additions & 0 deletions smile_decimal_precision/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# (C) 2023 Smile (<http://www.smile.fr>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

{
"name": "Display Decimal Precision",
"version": "14.0.0.0.1",
"depends": ["web","account"],
"author": "Smile",
"license": 'AGPL-3',
"description": """
This module allows to distinguish computation digits
and display digits in decimal precision.
""",
"website": "",
"category": "Hidden/Dependency",
"sequence": 32,
"data": [
"views/decimal_precision_view.xml",
"views/res_currency_view.xml",
],
"auto_install": True,
"installable": True,
"application": False,
}
41 changes: 41 additions & 0 deletions smile_decimal_precision/i18n/fr.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * smile_decimal_precision
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-03-19 08:58+0000\n"
"PO-Revision-Date: 2018-03-19 08:58+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"

#. module: smile_decimal_precision
#: model:ir.model,name:smile_decimal_precision.model_res_currency
msgid "Currency"
msgstr "Devise"

#. module: smile_decimal_precision
#: model:ir.model.fields,field_description:smile_decimal_precision.field_res_currency_display_decimal_places
msgid "Display Decimal Places"
msgstr "Décimales affichées"

#. module: smile_decimal_precision
#: model:ir.model.fields,field_description:smile_decimal_precision.field_decimal_precision_display_digits
msgid "Display Digits"
msgstr "Décimales affichées"

#. module: smile_decimal_precision
#: model:ir.model.fields,field_description:smile_decimal_precision.field_res_currency_display_rounding
msgid "Display Rounding Factor"
msgstr "Facteur d'arrondi affiché"

#. module: smile_decimal_precision
#: model:ir.model,name:smile_decimal_precision.model_ir_http
msgid "HTTP routing"
msgstr "Routage HTTP"
8 changes: 8 additions & 0 deletions smile_decimal_precision/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# (C) 2023 Smile (<http://www.smile.fr>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from .decimal_precision import DecimalPrecision
from . import fields
from . import ir_http
from . import res_currency
from . import account_move
16 changes: 16 additions & 0 deletions smile_decimal_precision/models/account_move.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from odoo import api, fields, models, tools
from odoo.tools.misc import formatLang

class AccountTax(models.Model):
_inherit = 'account.move'
@api.depends('line_ids.price_subtotal', 'line_ids.tax_base_amount', 'line_ids.tax_line_id', 'partner_id', 'currency_id')
def _compute_invoice_taxes_by_group(self):
res = super()._compute_invoice_taxes_by_group()
for move in self:
elements = []
for element in move.amount_by_group:
item = list(element)
item[3] = formatLang(self.env,item[1], digits=move.currency_id.display_decimal_places, currency_obj=move.currency_id)
item[4] = formatLang(self.env,item[2], digits=move.currency_id.display_decimal_places, currency_obj=move.currency_id)
elements +=[tuple(item)]
move.amount_by_group = elements
27 changes: 27 additions & 0 deletions smile_decimal_precision/models/decimal_precision.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


class DecimalPrecision(models.Model):
_inherit = 'decimal.precision'

display_digits = fields.Integer('Display Digits', required=True, default=2)

@api.model
@tools.ormcache('application')
def display_precision_get(self, application):
self.env.cr.execute(
'select display_digits from decimal_precision where name=%s',
(application,))
res = self.env.cr.fetchone()
return res[0] if res else 2

@staticmethod
def get_display_precision(env, application):
res = 2
dp = env['decimal.precision']
if hasattr(dp, 'display_precision_get'):
res = dp.display_precision_get(application)
return 16, res
22 changes: 22 additions & 0 deletions smile_decimal_precision/models/fields.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# (C) 2023 Smile (<http://www.smile.fr>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo.fields import Field

from odoo.addons.smile_decimal_precision.models import DecimalPrecision as dp



native_get_description = Field.get_description


def new_get_description(self, env):
desc = native_get_description(self, env)
if hasattr(self, '_related__digits') and isinstance(self._related__digits, str):
application = self._related__digits
desc['digits'] = dp.get_display_precision(env, application)
return desc


Field.get_description = new_get_description

15 changes: 15 additions & 0 deletions smile_decimal_precision/models/ir_http.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# (C) 2023 Smile (<http://www.smile.fr>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import models


class IrHttp(models.AbstractModel):
_inherit = 'ir.http'

def get_currencies(self):
res = super(IrHttp, self).get_currencies()
currency_ids = list(res.keys())
for currency in self.env['res.currency'].browse(currency_ids):
res[currency.id]['digits'][1] = currency.display_decimal_places
return res
25 changes: 25 additions & 0 deletions smile_decimal_precision/models/res_currency.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# (C) 2023 Smile (<http://www.smile.fr>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

import math

from odoo import api, fields, models


class ResCurrency(models.Model):
_inherit = 'res.currency'

display_rounding = fields.Float('Display Rounding Factor', digits=(12, 6))
display_decimal_places = fields.Integer(
compute='_get_display_decimal_places')

@api.depends('rounding', 'display_rounding')
def _get_display_decimal_places(self):
for currency in self:
if not currency.display_rounding:
currency.display_decimal_places = currency.decimal_places
elif 0 < currency.display_rounding < 1:
currency.display_decimal_places = \
int(math.ceil(math.log10(1 / currency.display_rounding)))
else:
currency.display_decimal_places = 0
4 changes: 4 additions & 0 deletions smile_decimal_precision/report/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# (C) 2023 Smile (<http://www.smile.fr>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from . import ir_qweb
77 changes: 77 additions & 0 deletions smile_decimal_precision/report/ir_qweb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# (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, MonetaryConverter


def record_to_html_float(self, record, field_name, options):
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)
#raise Exception(precision)
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.currency_field:
options['display_currency'] = record[field.currency_field]
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 '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)
#raise Exception(options)
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' ', u'\N{NO-BREAK SPACE}').replace(r'-', u'-\N{ZERO WIDTH NO-BREAK SPACE}')

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

return u'{pre}<span class="oe_currency_value">{0}</span>{post}'.format(formatted_amount, pre=pre, post=post)
FloatConverter.record_to_html = record_to_html_float
MonetaryConverter.record_to_html = record_to_html_monetary
MonetaryConverter.value_to_html = value_to_html_monetary
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading