diff --git a/report_qweb_field_option/README.rst b/report_qweb_field_option/README.rst index ee4a44c..0905565 100644 --- a/report_qweb_field_option/README.rst +++ b/report_qweb_field_option/README.rst @@ -11,7 +11,7 @@ Report Qweb Field Option !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:6a839e0b8361541500cea7946ac9d7bfbcbe37ab2a102576061a2940c4343c5c + !! source digest: sha256:2e6250e04e346bc7f61b36e4fb244e8f744f480b1e42e0ba753a71342ebd648f !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png @@ -52,6 +52,9 @@ For each record: - Set **Model** and **Field** (required) - Set **UoM** and **UoM Field**, or **Currency** and **Currency Field** only for fields of float type (optional) +- Set **Domain** to specify a domain for more specific filtering (e.g., + ``[('secondary_uom_id', '=', 1)]`` to apply only when a specific + secondary UoM is used) (optional) - Set **Company** (optional) - Set **Options** as a string representation of a dictionary. E.g., ``{"widget": "date"}``, ``{"widget": "monetary"}``, or diff --git a/report_qweb_field_option/__manifest__.py b/report_qweb_field_option/__manifest__.py index 10d68fd..e88ab83 100644 --- a/report_qweb_field_option/__manifest__.py +++ b/report_qweb_field_option/__manifest__.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { "name": "Report Qweb Field Option", - "version": "18.0.1.0.1", + "version": "18.0.1.1.0", "category": "Technical Settings", "license": "AGPL-3", "author": "Quartile, Odoo Community Association (OCA)", diff --git a/report_qweb_field_option/i18n/it.po b/report_qweb_field_option/i18n/it.po index 9db58d4..8178dd1 100644 --- a/report_qweb_field_option/i18n/it.po +++ b/report_qweb_field_option/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-03-30 21:06+0000\n" +"PO-Revision-Date: 2026-03-19 16:48+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -14,12 +14,13 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.10.2\n" +"X-Generator: Weblate 5.15.2\n" #. module: report_qweb_field_option #: model:ir.model.fields,help:report_qweb_field_option.field_qweb_field_options__field_options msgid "" -"A string representation of a dictionary to specify field formatting options. Examples:\n" +"A string representation of a dictionary to specify field formatting options. " +"Examples:\n" "{'widget': 'date'}\n" "{'widget': 'monetary'}\n" "{'widget': 'contact', 'fields': ['name', 'phone']}" @@ -65,6 +66,11 @@ msgstr "Cifre" msgid "Display Name" msgstr "Nome visualizzato" +#. module: report_qweb_field_option +#: model:ir.model.fields,field_description:report_qweb_field_option.field_qweb_field_options__domain +msgid "Domain" +msgstr "Dominio" + #. module: report_qweb_field_option #: model:ir.model.fields,field_description:report_qweb_field_option.field_qweb_field_options__field_id msgid "Field" @@ -93,18 +99,22 @@ msgstr "ID" #. module: report_qweb_field_option #. odoo-python #: code:addons/report_qweb_field_option/models/qweb_field_options.py:0 -#, python-format msgid "" -"Invalid string for the Options field: %(field_options)s.\n" +"Invalid domain format: %(domain)s.\n" "Error: %(error)s" msgstr "" -"Stringa non valida per il campo opzioni: %(field_options)s.\n" +"Formato dominio errato: %(domain)s.\n" "Errore: %(error)s" #. module: report_qweb_field_option -#: model:ir.model.fields,field_description:report_qweb_field_option.field_qweb_field_options____last_update -msgid "Last Modified on" -msgstr "Ultima modifica il" +#. odoo-python +#: code:addons/report_qweb_field_option/models/qweb_field_options.py:0 +msgid "" +"Invalid string for the Options field: %(field_options)s.\n" +"Error: %(error)s" +msgstr "" +"Stringa non valida per il campo opzioni: %(field_options)s.\n" +"Errore: %(error)s" #. module: report_qweb_field_option #: model:ir.model.fields,field_description:report_qweb_field_option.field_qweb_field_options__write_uid @@ -127,6 +137,24 @@ msgstr "Modello" msgid "Model Name" msgstr "Nome modello" +#. module: report_qweb_field_option +#: model:ir.model.fields,help:report_qweb_field_option.field_qweb_field_options__domain +msgid "" +"Optional domain for additional filtering conditions.\n" +"This is evaluated in addition to UoM/Currency conditions.\n" +"Examples:\n" +"[('secondary_uom_id', '=', 1)]\n" +"[('secondary_uom_id.name', '=', 'Box')]\n" +"[('state', 'in', ['sale', 'done'])]" +msgstr "" +"Dominio opzionale per ulteriori condizioni di filtraggio.\n" +"Questo viene valutato in aggiunta alle condizioni relative all'unità di " +"misura/valuta.\n" +"Esempi:\n" +"[('secondary_uom_id', '=', 1)]\n" +"[('secondary_uom_id.name', '=', 'Box')]\n" +"[('state', 'in', ['sale', 'done'])]" + #. module: report_qweb_field_option #: model:ir.model.fields,field_description:report_qweb_field_option.field_qweb_field_options__field_options msgid "Options" @@ -135,7 +163,6 @@ msgstr "Opzioni" #. module: report_qweb_field_option #. odoo-python #: code:addons/report_qweb_field_option/models/qweb_field_options.py:0 -#, python-format msgid "Options must be a dictionary, but got %s" msgstr "Le opzioni devono essere un dizionario, ma sono %s" @@ -165,3 +192,6 @@ msgstr "UdM" #: model:ir.model.fields,field_description:report_qweb_field_option.field_qweb_field_options__uom_field_id msgid "UoM Field" msgstr "Campo UdM" + +#~ msgid "Last Modified on" +#~ msgstr "Ultima modifica il" diff --git a/report_qweb_field_option/i18n/ja.po b/report_qweb_field_option/i18n/ja.po index db30d3e..0f5edab 100644 --- a/report_qweb_field_option/i18n/ja.po +++ b/report_qweb_field_option/i18n/ja.po @@ -17,7 +17,8 @@ msgstr "" #. module: report_qweb_field_option #: model:ir.model.fields,help:report_qweb_field_option.field_qweb_field_options__field_options msgid "" -"A string representation of a dictionary to specify field formatting options. Examples:\n" +"A string representation of a dictionary to specify field formatting options. " +"Examples:\n" "{'widget': 'date'}\n" "{'widget': 'monetary'}\n" "{'widget': 'contact', 'fields': ['name', 'phone']}" @@ -58,6 +59,11 @@ msgstr "" msgid "Display Name" msgstr "" +#. module: report_qweb_field_option +#: model:ir.model.fields,field_description:report_qweb_field_option.field_qweb_field_options__domain +msgid "Domain" +msgstr "" + #. module: report_qweb_field_option #: model:ir.model.fields,field_description:report_qweb_field_option.field_qweb_field_options__field_id msgid "Field" @@ -83,6 +89,14 @@ msgstr "" msgid "ID" msgstr "" +#. module: report_qweb_field_option +#. odoo-python +#: code:addons/report_qweb_field_option/models/qweb_field_options.py:0 +msgid "" +"Invalid domain format: %(domain)s.\n" +"Error: %(error)s" +msgstr "" + #. module: report_qweb_field_option #. odoo-python #: code:addons/report_qweb_field_option/models/qweb_field_options.py:0 @@ -112,6 +126,17 @@ msgstr "" msgid "Model Name" msgstr "" +#. module: report_qweb_field_option +#: model:ir.model.fields,help:report_qweb_field_option.field_qweb_field_options__domain +msgid "" +"Optional domain for additional filtering conditions.\n" +"This is evaluated in addition to UoM/Currency conditions.\n" +"Examples:\n" +"[('secondary_uom_id', '=', 1)]\n" +"[('secondary_uom_id.name', '=', 'Box')]\n" +"[('state', 'in', ['sale', 'done'])]" +msgstr "" + #. module: report_qweb_field_option #: model:ir.model.fields,field_description:report_qweb_field_option.field_qweb_field_options__field_options msgid "Options" diff --git a/report_qweb_field_option/i18n/nl.po b/report_qweb_field_option/i18n/nl.po index 9df525e..a5465a4 100644 --- a/report_qweb_field_option/i18n/nl.po +++ b/report_qweb_field_option/i18n/nl.po @@ -17,7 +17,8 @@ msgstr "" #. module: report_qweb_field_option #: model:ir.model.fields,help:report_qweb_field_option.field_qweb_field_options__field_options msgid "" -"A string representation of a dictionary to specify field formatting options. Examples:\n" +"A string representation of a dictionary to specify field formatting options. " +"Examples:\n" "{'widget': 'date'}\n" "{'widget': 'monetary'}\n" "{'widget': 'contact', 'fields': ['name', 'phone']}" @@ -58,6 +59,11 @@ msgstr "" msgid "Display Name" msgstr "" +#. module: report_qweb_field_option +#: model:ir.model.fields,field_description:report_qweb_field_option.field_qweb_field_options__domain +msgid "Domain" +msgstr "" + #. module: report_qweb_field_option #: model:ir.model.fields,field_description:report_qweb_field_option.field_qweb_field_options__field_id msgid "Field" @@ -83,6 +89,14 @@ msgstr "" msgid "ID" msgstr "" +#. module: report_qweb_field_option +#. odoo-python +#: code:addons/report_qweb_field_option/models/qweb_field_options.py:0 +msgid "" +"Invalid domain format: %(domain)s.\n" +"Error: %(error)s" +msgstr "" + #. module: report_qweb_field_option #. odoo-python #: code:addons/report_qweb_field_option/models/qweb_field_options.py:0 @@ -112,6 +126,17 @@ msgstr "" msgid "Model Name" msgstr "" +#. module: report_qweb_field_option +#: model:ir.model.fields,help:report_qweb_field_option.field_qweb_field_options__domain +msgid "" +"Optional domain for additional filtering conditions.\n" +"This is evaluated in addition to UoM/Currency conditions.\n" +"Examples:\n" +"[('secondary_uom_id', '=', 1)]\n" +"[('secondary_uom_id.name', '=', 'Box')]\n" +"[('state', 'in', ['sale', 'done'])]" +msgstr "" + #. module: report_qweb_field_option #: model:ir.model.fields,field_description:report_qweb_field_option.field_qweb_field_options__field_options msgid "Options" diff --git a/report_qweb_field_option/i18n/nl_NL.po b/report_qweb_field_option/i18n/nl_NL.po index c6e2604..f206a28 100644 --- a/report_qweb_field_option/i18n/nl_NL.po +++ b/report_qweb_field_option/i18n/nl_NL.po @@ -19,7 +19,8 @@ msgstr "" #. module: report_qweb_field_option #: model:ir.model.fields,help:report_qweb_field_option.field_qweb_field_options__field_options msgid "" -"A string representation of a dictionary to specify field formatting options. Examples:\n" +"A string representation of a dictionary to specify field formatting options. " +"Examples:\n" "{'widget': 'date'}\n" "{'widget': 'monetary'}\n" "{'widget': 'contact', 'fields': ['name', 'phone']}" @@ -65,6 +66,11 @@ msgstr "Cijfers" msgid "Display Name" msgstr "Weergavenaam" +#. module: report_qweb_field_option +#: model:ir.model.fields,field_description:report_qweb_field_option.field_qweb_field_options__domain +msgid "Domain" +msgstr "" + #. module: report_qweb_field_option #: model:ir.model.fields,field_description:report_qweb_field_option.field_qweb_field_options__field_id msgid "Field" @@ -90,6 +96,14 @@ msgstr "Groeperen op" msgid "ID" msgstr "ID" +#. module: report_qweb_field_option +#. odoo-python +#: code:addons/report_qweb_field_option/models/qweb_field_options.py:0 +msgid "" +"Invalid domain format: %(domain)s.\n" +"Error: %(error)s" +msgstr "" + #. module: report_qweb_field_option #. odoo-python #: code:addons/report_qweb_field_option/models/qweb_field_options.py:0 @@ -121,6 +135,17 @@ msgstr "Model" msgid "Model Name" msgstr "Modelnaam" +#. module: report_qweb_field_option +#: model:ir.model.fields,help:report_qweb_field_option.field_qweb_field_options__domain +msgid "" +"Optional domain for additional filtering conditions.\n" +"This is evaluated in addition to UoM/Currency conditions.\n" +"Examples:\n" +"[('secondary_uom_id', '=', 1)]\n" +"[('secondary_uom_id.name', '=', 'Box')]\n" +"[('state', 'in', ['sale', 'done'])]" +msgstr "" + #. module: report_qweb_field_option #: model:ir.model.fields,field_description:report_qweb_field_option.field_qweb_field_options__field_options msgid "Options" diff --git a/report_qweb_field_option/i18n/report_qweb_field_option.pot b/report_qweb_field_option/i18n/report_qweb_field_option.pot index 7dd2a3f..d7c069d 100644 --- a/report_qweb_field_option/i18n/report_qweb_field_option.pot +++ b/report_qweb_field_option/i18n/report_qweb_field_option.pot @@ -57,6 +57,11 @@ msgstr "" msgid "Display Name" msgstr "" +#. module: report_qweb_field_option +#: model:ir.model.fields,field_description:report_qweb_field_option.field_qweb_field_options__domain +msgid "Domain" +msgstr "" + #. module: report_qweb_field_option #: model:ir.model.fields,field_description:report_qweb_field_option.field_qweb_field_options__field_id msgid "Field" @@ -82,6 +87,14 @@ msgstr "" msgid "ID" msgstr "" +#. module: report_qweb_field_option +#. odoo-python +#: code:addons/report_qweb_field_option/models/qweb_field_options.py:0 +msgid "" +"Invalid domain format: %(domain)s.\n" +"Error: %(error)s" +msgstr "" + #. module: report_qweb_field_option #. odoo-python #: code:addons/report_qweb_field_option/models/qweb_field_options.py:0 @@ -111,6 +124,17 @@ msgstr "" msgid "Model Name" msgstr "" +#. module: report_qweb_field_option +#: model:ir.model.fields,help:report_qweb_field_option.field_qweb_field_options__domain +msgid "" +"Optional domain for additional filtering conditions.\n" +"This is evaluated in addition to UoM/Currency conditions.\n" +"Examples:\n" +"[('secondary_uom_id', '=', 1)]\n" +"[('secondary_uom_id.name', '=', 'Box')]\n" +"[('state', 'in', ['sale', 'done'])]" +msgstr "" + #. module: report_qweb_field_option #: model:ir.model.fields,field_description:report_qweb_field_option.field_qweb_field_options__field_options msgid "Options" diff --git a/report_qweb_field_option/models/qweb_field_options.py b/report_qweb_field_option/models/qweb_field_options.py index 91c4b35..2dc6251 100644 --- a/report_qweb_field_option/models/qweb_field_options.py +++ b/report_qweb_field_option/models/qweb_field_options.py @@ -4,8 +4,10 @@ import ast import logging -from odoo import _, api, fields, models +from odoo import _, api, fields, models, tools from odoo.exceptions import ValidationError +from odoo.osv.expression import normalize_domain +from odoo.tools.safe_eval import safe_eval _logger = logging.getLogger(__name__) @@ -52,6 +54,14 @@ class QwebFieldOptions(models.Model): ) digits = fields.Integer() company_id = fields.Many2one("res.company", string="Company") + domain = fields.Char( + help="Optional domain for additional filtering conditions.\n" + "This is evaluated in addition to UoM/Currency conditions.\n" + "Examples:\n" + "[('secondary_uom_id', '=', 1)]\n" + "[('secondary_uom_id.name', '=', 'Box')]\n" + "[('state', 'in', ['sale', 'done'])]", + ) @api.constrains("field_options") def _check_field_options_format(self): @@ -74,6 +84,28 @@ def _check_field_options_format(self): _("Options must be a dictionary, but got %s") % type(field_options) ) + def _get_eval_context(self): + return { + "time": tools.safe_eval.time, + "datetime": tools.safe_eval.datetime, + "dateutil": tools.safe_eval.dateutil, + "timezone": tools.safe_eval.pytz.timezone, + "context_today": lambda: fields.Date.context_today(self), + } + + @api.constrains("domain") + def _check_domain_format(self): + for rec in self: + if not rec.domain: + continue + try: + normalize_domain(safe_eval(rec.domain, rec._get_eval_context())) + except Exception as e: + raise ValidationError( + _("Invalid domain format: %(domain)s.\n" "Error: %(error)s") + % {"domain": rec.domain, "error": e} + ) from e + def _get_score(self, record): self.ensure_one() score = 1 @@ -91,6 +123,22 @@ def _get_score(self, record): score += 1 else: return -1 + if self.domain: + try: + domain = normalize_domain( + safe_eval(self.domain, self._get_eval_context()) + ) + if not record.filtered_domain(domain): + return -1 + score += 1 + except Exception as e: + _logger.warning( + "Failed to evaluate domain %s for record %s: %s", + self.domain, + record, + e, + ) + return -1 return score def _update_field_options(self, record, field_options): diff --git a/report_qweb_field_option/readme/CONFIGURE.md b/report_qweb_field_option/readme/CONFIGURE.md index e8532ad..35be096 100644 --- a/report_qweb_field_option/readme/CONFIGURE.md +++ b/report_qweb_field_option/readme/CONFIGURE.md @@ -6,6 +6,9 @@ For each record: - Set **Model** and **Field** (required) - Set **UoM** and **UoM Field**, or **Currency** and **Currency Field** only for fields of float type (optional) +- Set **Domain** to specify a domain for more specific filtering + (e.g., `[('secondary_uom_id', '=', 1)]` to apply only when + a specific secondary UoM is used) (optional) - Set **Company** (optional) - Set **Options** as a string representation of a dictionary. E.g., `{"widget": "date"}`, `{"widget": "monetary"}`, or diff --git a/report_qweb_field_option/static/description/index.html b/report_qweb_field_option/static/description/index.html index 65f598b..0595bfb 100644 --- a/report_qweb_field_option/static/description/index.html +++ b/report_qweb_field_option/static/description/index.html @@ -372,7 +372,7 @@

Report Qweb Field Option

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:6a839e0b8361541500cea7946ac9d7bfbcbe37ab2a102576061a2940c4343c5c +!! source digest: sha256:2e6250e04e346bc7f61b36e4fb244e8f744f480b1e42e0ba753a71342ebd648f !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/reporting-engine Translate me on Weblate Try me on Runboat

This module allows administrators to define the decimal precision of @@ -402,6 +402,9 @@

Configuration

  • Set Model and Field (required)
  • Set UoM and UoM Field, or Currency and Currency Field only for fields of float type (optional)
  • +
  • Set Domain to specify a domain for more specific filtering (e.g., +[('secondary_uom_id', '=', 1)] to apply only when a specific +secondary UoM is used) (optional)
  • Set Company (optional)
  • Set Options as a string representation of a dictionary. E.g., {"widget": "date"}, {"widget": "monetary"}, or diff --git a/report_qweb_field_option/tests/test_report_qweb_field_options.py b/report_qweb_field_option/tests/test_report_qweb_field_options.py index e55e439..c5670ab 100644 --- a/report_qweb_field_option/tests/test_report_qweb_field_options.py +++ b/report_qweb_field_option/tests/test_report_qweb_field_options.py @@ -153,3 +153,39 @@ def test_qweb_field_option_with_uom(self): self.test_record, "quantity", False, False, {}, values ) self.assertEqual(content, "1.0") + + def test_domain_validation(self): + """Test that invalid domain raises validation error""" + with self.assertRaises(ValidationError): + self.env["qweb.field.options"].create( + { + "res_model_id": self.test_model.id, + "field_id": self.value_field.id, + "domain": "invalid domain", + "digits": 2, + } + ) + + def test_qweb_field_option_with_domain(self): + values = {"report_type": "pdf"} + jpy_currency = self.env.ref("base.JPY") + jpy_currency.active = True + self.qweb_options_rec.digits = 2 + self.env["qweb.field.options"].create( + { + "res_model_id": self.test_model.id, + "field_id": self.value_field.id, + "domain": f"[('currency_id', '=', {jpy_currency.id})]", + "digits": 0, + } + ) + _, content, _ = self.IrQweb._get_field( + self.test_record, "value", False, False, {}, values + ) + self.assertEqual(content, "1.00") + # Test with JPY: domain matches, uses JPY-specific option (0 digits) + self.test_record.currency_id = jpy_currency.id + _, content, _ = self.IrQweb._get_field( + self.test_record, "value", False, False, {}, values + ) + self.assertEqual(content, "1") diff --git a/report_qweb_field_option/views/qweb_field_options_views.xml b/report_qweb_field_option/views/qweb_field_options_views.xml index 679477d..776a4c1 100644 --- a/report_qweb_field_option/views/qweb_field_options_views.xml +++ b/report_qweb_field_option/views/qweb_field_options_views.xml @@ -27,6 +27,13 @@ readonly="currency_id == False" required="currency_id != False" /> + +