From 7eeb9dddcb5661a250e2e9c806c1fb4ecf5d1144 Mon Sep 17 00:00:00 2001 From: Dave Lasley Date: Thu, 10 Aug 2017 15:15:05 -0700 Subject: [PATCH] [ADD] base_locale_uom_default: Add default unit of measure by lang * Create module to allow for the selection of default units of measure at the language level. --- base_locale_uom_default/README.rst | 73 +++++++++++++++++++ base_locale_uom_default/__init__.py | 5 ++ base_locale_uom_default/__manifest__.py | 26 +++++++ .../demo/res_lang_demo.xml | 14 ++++ base_locale_uom_default/models/__init__.py | 5 ++ base_locale_uom_default/models/res_lang.py | 55 ++++++++++++++ base_locale_uom_default/tests/__init__.py | 5 ++ .../tests/test_res_lang.py | 44 +++++++++++ .../views/res_lang_view.xml | 15 ++++ 9 files changed, 242 insertions(+) create mode 100644 base_locale_uom_default/README.rst create mode 100644 base_locale_uom_default/__init__.py create mode 100644 base_locale_uom_default/__manifest__.py create mode 100644 base_locale_uom_default/demo/res_lang_demo.xml create mode 100644 base_locale_uom_default/models/__init__.py create mode 100644 base_locale_uom_default/models/res_lang.py create mode 100644 base_locale_uom_default/tests/__init__.py create mode 100644 base_locale_uom_default/tests/test_res_lang.py create mode 100644 base_locale_uom_default/views/res_lang_view.xml diff --git a/base_locale_uom_default/README.rst b/base_locale_uom_default/README.rst new file mode 100644 index 000000000..8f14f3292 --- /dev/null +++ b/base_locale_uom_default/README.rst @@ -0,0 +1,73 @@ +.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 + +==================== +Locale - Default UoM +==================== + +This module adds a concept of a default unit of measure on languages, unique by +unit category type. + +It also provides a method that can be used in fields to work from said defaults. + +Configuration +============= + +Set default unit of measures in the `Languages` menu in settings. + +Usage +===== + +Fields that want to implement the language default should use the provided method, +such as in the below example:: + + class MyModel(models.Model): + _name = 'my.model' + time_uom_id = fields.Many2one( + string='Time Units', + comodel_name='product.uom', + default=lambda s: s.env['res.lang'].default_uom_by_category('Time'), + ) + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/149/10.0 + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smash it by providing detailed and welcomed feedback. + +Credits +======= + +Images +------ + +* Odoo Community Association: `Icon `_. + +Contributors +------------ + +* Dave Lasley + +Do not contact contributors directly about support or help with technical issues. + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/base_locale_uom_default/__init__.py b/base_locale_uom_default/__init__.py new file mode 100644 index 000000000..579492fb8 --- /dev/null +++ b/base_locale_uom_default/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 LasLabs Inc. +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from . import models diff --git a/base_locale_uom_default/__manifest__.py b/base_locale_uom_default/__manifest__.py new file mode 100644 index 000000000..e4676291a --- /dev/null +++ b/base_locale_uom_default/__manifest__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 LasLabs Inc. +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +{ + 'name': 'Locale - Default UoM', + 'summary': 'This provides settings to select default UoMs at the ' + 'language level.', + 'version': '10.0.1.0.0', + 'category': 'Extra Tools', + 'website': 'https://laslabs.com/', + 'author': 'LasLabs, ' + 'Odoo Community Association (OCA)', + 'license': 'LGPL-3', + 'application': False, + 'installable': True, + 'depends': [ + 'product', + ], + 'data': [ + 'views/res_lang_view.xml', + ], + 'demo': [ + 'demo/res_lang_demo.xml', + ], +} diff --git a/base_locale_uom_default/demo/res_lang_demo.xml b/base_locale_uom_default/demo/res_lang_demo.xml new file mode 100644 index 000000000..f9d5f6636 --- /dev/null +++ b/base_locale_uom_default/demo/res_lang_demo.xml @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/base_locale_uom_default/models/__init__.py b/base_locale_uom_default/models/__init__.py new file mode 100644 index 000000000..71e1c6656 --- /dev/null +++ b/base_locale_uom_default/models/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 LasLabs Inc. +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from . import res_lang diff --git a/base_locale_uom_default/models/res_lang.py b/base_locale_uom_default/models/res_lang.py new file mode 100644 index 000000000..b3408856b --- /dev/null +++ b/base_locale_uom_default/models/res_lang.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 LasLabs Inc. +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from odoo import api, fields, models, _ +from odoo.exceptions import ValidationError + + +class ResLang(models.Model): + + _inherit = 'res.lang' + + default_uom_ids = fields.Many2many( + string='Default Units', + comodel_name='product.uom', + ) + + @api.multi + @api.constrains('default_uom_ids') + def _check_default_uom_ids(self): + for record in self: + categories = set(record.default_uom_ids.mapped('category_id')) + if len(categories) != len(record.default_uom_ids): + raise ValidationError(_( + 'Only one default unit of measure per category may ' + 'be selected.', + )) + + @api.model + def default_uom_by_category(self, category_name, lang=None): + """Return the default UoM for language for the input UoM Category. + + Args: + category_name (str): Name of the UoM category to get the default + for. + lang (ResLang or str, optional): Recordset or code of the language + to get the default for. Will use the current user language if + omitted. + + Returns: + ProductUom: Unit of measure representing the default, if set. + Empty recordset otherwise. + """ + if lang is None: + lang = self.env.user.lang + if isinstance(lang, basestring): + lang = self.env['res.lang'].search([ + ('code', '=', lang), + ], + limit=1, + ) + results = lang.default_uom_ids.filtered( + lambda r: r.category_id.name == category_name, + ) + return results[:1] diff --git a/base_locale_uom_default/tests/__init__.py b/base_locale_uom_default/tests/__init__.py new file mode 100644 index 000000000..0ce07c65b --- /dev/null +++ b/base_locale_uom_default/tests/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 LasLabs Inc. +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from . import test_res_lang diff --git a/base_locale_uom_default/tests/test_res_lang.py b/base_locale_uom_default/tests/test_res_lang.py new file mode 100644 index 000000000..843e6f6fe --- /dev/null +++ b/base_locale_uom_default/tests/test_res_lang.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 LasLabs Inc. +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from odoo.tests.common import TransactionCase +from odoo.exceptions import ValidationError + + +class TestResLang(TransactionCase): + + def setUp(self): + super(TestResLang, self).setUp() + self.lang = self.env.ref('base.lang_en') + self.env.user.lang = self.lang.code + self.uom = self.env.ref('product.product_uom_dozen') + self.lang.default_uom_ids = [(6, 0, self.uom.ids)] + + def test_check_default_uom_ids_fail(self): + """It should not allow multiple UoMs of the same category.""" + with self.assertRaises(ValidationError): + self.lang.default_uom_ids = [ + (4, self.env.ref('product.product_uom_unit').id), + ] + + def test_check_default_uom_ids_pass(self): + """It should allow multiple UoMs of different categories.""" + self.lang.default_uom_ids = [ + (4, self.env.ref('product.product_uom_kgm').id), + ] + self.assertEqual(len(self.lang.default_uom_ids), 2) + + def test_default_uom_by_category_exist(self): + """It should return the default UoM if existing.""" + self.assertEqual( + self.env['res.lang'].default_uom_by_category('Unit'), + self.uom, + ) + + def test_default_uom_by_category_no_exist(self): + """It should return empty recordset when no default UoM.""" + self.assertEqual( + self.env['res.lang'].default_uom_by_category('Volume'), + self.env['product.uom'].browse(), + ) diff --git a/base_locale_uom_default/views/res_lang_view.xml b/base_locale_uom_default/views/res_lang_view.xml new file mode 100644 index 000000000..239e72dfa --- /dev/null +++ b/base_locale_uom_default/views/res_lang_view.xml @@ -0,0 +1,15 @@ + + + + + Res Lang Form - Default UoMs + res.lang + + + + + + + + +