diff --git a/base_custom_info/README.rst b/base_custom_info/README.rst index 78598f9d1..90bbbe13d 100644 --- a/base_custom_info/README.rst +++ b/base_custom_info/README.rst @@ -1,17 +1,33 @@ -.. 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 - ================ Base Custom Info ================ +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github + :target: https://github.com/OCA/server-tools/tree/12.0/base_custom_info + :alt: OCA/server-tools +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/server-tools-12-0/server-tools-12-0-base_custom_info + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/149/12.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + This module allows you to attach custom information to records without the need to alter the database structure too much. -Definitions -=========== - This module defines several concepts that you have to understand. Templates @@ -84,29 +100,6 @@ I.e., the "What weaknesses does he/she have?" *property* has some options: The *value* will always be one of these. -Recursive templates using options -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Oh dear customization lovers! Options can be used to customize the custom -information template! - -.. figure:: /base_custom_info/static/description/customizations-everywhere.jpg - :alt: Customizations Everywhere - -If you assign an *additional template* to an option, and while using the owner -form you choose that option, you can then press *reload custom information -templates* to make the owner update itself to include all the properties in all -the involved templates. If you do not press the button, anyway the reloading -will be performed when saving the owner record. - -.. figure:: /base_custom_info/static/description/templateception.jpg - :alt: Templateception - -I.e., if you select the option "Needs videogames" for the property "What -weaknesses does he/she have?" of a smart partner and press *reload custom -information templates*, you will get 2 new properties to fill: "Favourite -videogames genre" and "Favourite videogame". - Value ----- @@ -150,6 +143,11 @@ So, if you want to apply this to other models, you will have to develop a little additional addon that depends on this one. If you are a developer, refer to the *Development* section below. +**Table of contents** + +.. contents:: + :local: + Installation ============ @@ -201,10 +199,6 @@ To manage their values, you need to: * Go to *Custom Info > Values*. -.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas - :alt: Try me on Runbot - :target: https://runbot.odoo-community.org/runbot/135/10.0 - Development =========== @@ -218,38 +212,68 @@ Known issues / Roadmap * Custom properties cannot be shared among templates. * Required attributes are for now only set in the UI, not in the ORM itself. +* Support recursive templates using options + + .. figure:: https://raw.githubusercontent.com/base_custom_info/static/description/customizations-everywhere.jpg + :alt: Customizations Everywhere + + If you assign an *additional template* to an option, and while using the owner + form you choose that option, you can then press *reload custom information + templates* to make the owner update itself to include all the properties in all + the involved templates. If you do not press the button, anyway the reloading + will be performed when saving the owner record. + + .. figure:: https://raw.githubusercontent.com/base_custom_info/static/description/templateception.jpg + :alt: Templateception + + I.e., if you select the option "Needs videogames" for the property "What + weaknesses does he/she have?" of a smart partner and press *reload custom + information templates*, you will get 2 new properties to fill: "Favourite + videogames genre" and "Favourite videogame". 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 smashing it by providing a detailed and welcomed feedback. +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 smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. Credits ======= +Authors +~~~~~~~ + +* Tecnativa + Contributors ------------- +~~~~~~~~~~~~ -* Rafael Blasco -* Carlos Dauden -* Sergio Teruel -* Jairo Llopis -* Pedro M. Baeza +* `Tecnativa `__: -Maintainer ----------- + * Rafael Blasco + * Carlos Dauden + * Sergio Teruel + * Jairo Llopis + * Pedro M. Baeza + * Alexandre Díaz + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. .. 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. +This module is part of the `OCA/server-tools `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/base_custom_info/__init__.py b/base_custom_info/__init__.py index 95ffd47c5..57ba1d7be 100644 --- a/base_custom_info/__init__.py +++ b/base_custom_info/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2015 Antiun Ingeniería S.L. - Sergio Teruel # Copyright 2015 Antiun Ingeniería S.L. - Carlos Dauden # License LGPL-3 - See http://www.gnu.org/licenses/lgpl-3.0.html diff --git a/base_custom_info/__manifest__.py b/base_custom_info/__manifest__.py index 505cc4f61..23544f0ad 100644 --- a/base_custom_info/__manifest__.py +++ b/base_custom_info/__manifest__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2015 Antiun Ingeniería S.L. - Sergio Teruel # Copyright 2015 Antiun Ingeniería S.L. - Carlos Dauden # Copyright 2015-2016 Jairo Llopis @@ -8,13 +7,13 @@ 'name': "Base Custom Info", 'summary': "Add custom field in models", 'category': 'Tools', - 'version': '10.0.1.1.0', + 'version': '12.0.1.0.0', 'depends': [ 'base_setup', ], 'data': [ 'security/ir.model.access.csv', - 'security/res_groups.xml', + 'security/res_groups_security.xml', 'views/custom_info_category_view.xml', 'views/custom_info_option_view.xml', 'views/custom_info_template_view.xml', @@ -22,15 +21,15 @@ 'views/custom_info_value_view.xml', 'views/menu.xml', 'views/res_partner_view.xml', - 'wizard/base_config_settings_view.xml', + 'wizard/res_config_settings_view.xml', ], 'demo': [ 'demo/custom.info.category.csv', 'demo/custom.info.template.csv', 'demo/custom.info.property.csv', 'demo/custom.info.option.csv', - 'demo/custom_info_property_defaults.yml', 'demo/res_groups.xml', + 'demo/defaults.xml', ], "images": [ "images/menu.png", diff --git a/base_custom_info/demo/custom_info_property_defaults.yml b/base_custom_info/demo/custom_info_property_defaults.yml deleted file mode 100644 index 592efa6dd..000000000 --- a/base_custom_info/demo/custom_info_property_defaults.yml +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright 2016 Jairo Llopis -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). -- Setting default values after loading custom.info.option.csv - -- !record {model: custom.info.property, id: prop_weaknesses}: - default_value: Huge glasses diff --git a/base_custom_info/demo/defaults.xml b/base_custom_info/demo/defaults.xml new file mode 100644 index 000000000..f1588bce1 --- /dev/null +++ b/base_custom_info/demo/defaults.xml @@ -0,0 +1,11 @@ + + + + + + + Huge glasses + + + diff --git a/base_custom_info/migrations/9.0.2.0.0/pre-migrate.py b/base_custom_info/migrations/9.0.2.0.0/pre-migrate.py deleted file mode 100644 index 574e261dd..000000000 --- a/base_custom_info/migrations/9.0.2.0.0/pre-migrate.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2016 Jairo Llopis -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). -# pragma: no-cover - - -def migrate(cr, version): - """Update database from previous versions, before updating module.""" - cr.execute( - "ALTER TABLE custom_info_value RENAME COLUMN value TO value_str") diff --git a/base_custom_info/models/__init__.py b/base_custom_info/models/__init__.py index 4da484e8e..21969ab25 100644 --- a/base_custom_info/models/__init__.py +++ b/base_custom_info/models/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2015 Antiun Ingeniería S.L. - Sergio Teruel # Copyright 2015 Antiun Ingeniería S.L. - Carlos Dauden # Copyright 2016 Jairo Llopis diff --git a/base_custom_info/models/custom_info.py b/base_custom_info/models/custom_info.py index 351868fb0..1594d2ae5 100644 --- a/base_custom_info/models/custom_info.py +++ b/base_custom_info/models/custom_info.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2015 Sergio Teruel # Copyright 2015 Carlos Dauden # Copyright 2016 Jairo Llopis @@ -41,7 +40,7 @@ class CustomInfo(models.AbstractModel): field_onchange.setdefault( u"{}.{}".format(x2many_field, subfield), u"", ) - return super(CustomInfo, self).onchange( + return super().onchange( values, field_name, field_onchange, ) @@ -75,7 +74,7 @@ class CustomInfo(models.AbstractModel): automatically. """ info_values = self.mapped('custom_info_ids') - res = super(CustomInfo, self).unlink() + res = super().unlink() if res: info_values.unlink() return res diff --git a/base_custom_info/models/custom_info_category.py b/base_custom_info/models/custom_info_category.py index 7af3a2b00..3e69f5d12 100644 --- a/base_custom_info/models/custom_info_category.py +++ b/base_custom_info/models/custom_info_category.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2016 Jairo Llopis # License LGPL-3 - See http://www.gnu.org/licenses/lgpl-3.0.html @@ -22,13 +21,14 @@ class CustomInfoCategory(models.Model): @api.multi def check_access_rule(self, operation): """You access a category if you access at least one property.""" - last = None + last_error = None for prop in self.mapped("property_ids"): try: prop.check_access_rule(operation) return - except Exception as last: + except Exception as err: + last_error = err pass - if last: - raise last - return super(CustomInfoCategory, self).check_access_rule(operation) + if last_error: + raise last_error + return super().check_access_rule(operation) diff --git a/base_custom_info/models/custom_info_option.py b/base_custom_info/models/custom_info_option.py index e19e09c7d..70e43451d 100644 --- a/base_custom_info/models/custom_info_option.py +++ b/base_custom_info/models/custom_info_option.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2016 Jairo Llopis # Copyright 2017 Pedro M. Baeza # License LGPL-3 - See http://www.gnu.org/licenses/lgpl-3.0.html @@ -33,13 +32,14 @@ class CustomInfoOption(models.Model): @api.multi def check_access_rule(self, operation): """You access an option if you access at least one property.""" - last = None + last_error = None for prop in self.mapped("property_ids"): try: prop.check_access_rule(operation) return - except Exception as last: + except Exception as err: + last_error = err pass - if last: - raise last - return super(CustomInfoOption, self).check_access_rule(operation) + if last_error: + raise last_error + return super().check_access_rule(operation) diff --git a/base_custom_info/models/custom_info_property.py b/base_custom_info/models/custom_info_property.py index 4d1ba9d13..35e4b556f 100644 --- a/base_custom_info/models/custom_info_property.py +++ b/base_custom_info/models/custom_info_property.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2016 Jairo Llopis # Copyright 2017 Pedro M. Baeza # License LGPL-3 - See http://www.gnu.org/licenses/lgpl-3.0.html @@ -25,6 +24,7 @@ class CustomInfoProperty(models.Model): string="Category", ) category_sequence = fields.Integer( + string="Category Sequence", related="category_id.sequence", store=True, readonly=True, @@ -81,7 +81,7 @@ class CustomInfoProperty(models.Model): def check_access_rule(self, operation): """You access a property if you access its template.""" self.mapped("template_id").check_access_rule(operation) - return super(CustomInfoProperty, self).check_access_rule(operation) + return super().check_access_rule(operation) @api.constrains("default_value", "field_type") def _check_default_value(self): diff --git a/base_custom_info/models/custom_info_template.py b/base_custom_info/models/custom_info_template.py index d392a4a00..8f68b3424 100644 --- a/base_custom_info/models/custom_info_template.py +++ b/base_custom_info/models/custom_info_template.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2016 Jairo Llopis # Copyright 2017 Pedro M. Baeza # License LGPL-3 - See http://www.gnu.org/licenses/lgpl-3.0.html @@ -73,10 +72,10 @@ class CustomInfoTemplate(models.Model): model = self.env[record.model_id.model or record.model] model.check_access_rights(operation) model.check_access_rule(operation) - return super(CustomInfoTemplate, self).check_access_rule(operation) + return super().check_access_rule(operation) @api.multi def write(self, vals): if 'model_id' in vals: self._check_model_update_allowed(vals['model_id']) - return super(CustomInfoTemplate, self).write(vals) + return super().write(vals) diff --git a/base_custom_info/models/custom_info_value.py b/base_custom_info/models/custom_info_value.py index 33a85158c..8bc80abe6 100644 --- a/base_custom_info/models/custom_info_value.py +++ b/base_custom_info/models/custom_info_value.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2016 Jairo Llopis # Copyright 2017 Pedro M. Baeza # License LGPL-3 - See http://www.gnu.org/licenses/lgpl-3.0.html @@ -40,6 +39,7 @@ class CustomInfoValue(models.Model): related="property_id.sequence", store=True, index=True, readonly=True, ) category_sequence = fields.Integer( + string="Category Sequence", related="property_id.category_id.sequence", store=True, readonly=True, ) category_id = fields.Many2one( @@ -75,7 +75,7 @@ class CustomInfoValue(models.Model): for record in self.filtered('owner_id'): record.owner_id.check_access_rights(operation) record.owner_id.check_access_rule(operation) - return super(CustomInfoValue, self).check_access_rule(operation) + return super().check_access_rule(operation) @api.model def _selection_owner_id(self): @@ -128,8 +128,8 @@ class CustomInfoValue(models.Model): def _inverse_value(self): """Write the value correctly converted in the typed field.""" for record in self: - if (record.field_type == "id" and - record.value == record.value_id.display_name): + if (record.field_type == "id" + and record.value == record.value_id.display_name): # Avoid another search that can return a different value continue record[record.field_name] = self._transform_value( @@ -178,6 +178,8 @@ class CustomInfoValue(models.Model): for record in self: if not record.value and record.property_id.default_value: record.value = record.property_id.default_value + if not record.field_type and record.property_id.field_type: + record.field_type = record.property_id.field_type @api.onchange('value') def _onchange_value(self): @@ -238,4 +240,4 @@ class CustomInfoValue(models.Model): ("field_type", "=", fmt), ("value_" + fmt, operator, _value), ] - return ["|"] * (len(domain) / 3 - 1) + domain + return ["|"] * int(len(domain) / 3 - 1) + domain diff --git a/base_custom_info/models/res_partner.py b/base_custom_info/models/res_partner.py index ffb04de39..6b098e6de 100644 --- a/base_custom_info/models/res_partner.py +++ b/base_custom_info/models/res_partner.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2016 Jairo Llopis # Copyright 2017 Pedro M. Baeza # License LGPL-3 - See http://www.gnu.org/licenses/lgpl-3.0.html diff --git a/base_custom_info/readme/CONFIGURE.rst b/base_custom_info/readme/CONFIGURE.rst new file mode 100644 index 000000000..986a62731 --- /dev/null +++ b/base_custom_info/readme/CONFIGURE.rst @@ -0,0 +1,7 @@ +To enable the main *Custom Info* menu: + +#. Enable *Settings > General Settings > Manage custom information*. + +To enable partner's custom info tab: + +#. Enable *Settings > General Settings > Edit custom information in partners*. diff --git a/base_custom_info/readme/CONTRIBUTORS.rst b/base_custom_info/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..68554c340 --- /dev/null +++ b/base_custom_info/readme/CONTRIBUTORS.rst @@ -0,0 +1,8 @@ +* `Tecnativa `__: + + * Rafael Blasco + * Carlos Dauden + * Sergio Teruel + * Jairo Llopis + * Pedro M. Baeza + * Alexandre Díaz diff --git a/base_custom_info/readme/DESCRIPTION.rst b/base_custom_info/readme/DESCRIPTION.rst new file mode 100644 index 000000000..9ef71cbc7 --- /dev/null +++ b/base_custom_info/readme/DESCRIPTION.rst @@ -0,0 +1,117 @@ +This module allows you to attach custom information to records without the need +to alter the database structure too much. + +This module defines several concepts that you have to understand. + +Templates +--------- + +A *template* is a collection of *properties* that a record should have. +*Templates* always apply to a given model, and then you can choose among the +current templates for the model you are using when you edit a record of that +model. + +I.e., This addon includes a demo template called "Smart partners", that applies +to the model ``res.partner``, so if you edit any partner, you can choose that +template and get its properties autofilled. + +Properties +---------- + +A *property* is the "name" of the field. *Templates* can have any amount of +*properties*, and when you apply a *template* to a record, it automatically +gets all of its *properties* filled, empty (unless they have a *Default +value*), ready to assign *values*. + +You can set a property to as *required* to force it have a value, although you +should keep in mind that for yes/no properties, this would mean that only *yes* +can be selected, and for numeric properties, zero would be forbidden. + +Also you can set *Minimum* and *Maximum* limits for every *property*, but those +limits are only used when the data type is text (to constrain its length) or +number. To skip this constraint, just set a maximum smaller than the minimum. + +*Properties* always belong to a template, and as such, to a model. + +*Properties* define the data type (text, number, yes/no...), and when the type +is "Selection", then you can define what *options* are available. + +I.e., the "Smart partners" *template* has the following *properties*: + +- Name of his/her teacher +- Amount of people that hates him/her for being so smart +- Average note on all subjects +- Does he/she believe he/she is the smartest person on earth? +- What weaknesses does he/she have? + +When you set that template to any partner, you will then be able to fill these +*properties* with *values*. + +Categories +---------- + +*Properties* can also belong to a *category*, which allows you to sort them in +a logical way, and makes further development easier. + +For example, the ``website_sale_custom_info`` addon uses these to display a +technical datasheet per product in your online shop, sorted and separated by +category. + +You are not required to give a *category* to every *property*. + +Options +------- + +When a *property*'s type is "Selection", then you define the *options* +available, so the *value* must be one of these *options*. + +I.e., the "What weaknesses does he/she have?" *property* has some options: + +- Loves junk food +- Needs videogames +- Huge glasses + +The *value* will always be one of these. + +Value +----- + +When you assign a *template* to a partner, and then you get the *properties* it +should have, you still have to set a *value* for each property. + +*Values* can be of different types (whole numbers, constrained selection, +booleans...), depending on how the *property* was defined. However, there is +always the ``value`` field, that is a text string, and converts automatically +to/from the correct type. + +Why would I need this? +~~~~~~~~~~~~~~~~~~~~~~ + +Imagine you have some partners that are foreign, and that for those partners +you need some extra information that is not needed for others, and you do not +want to fill the partners model with a lot of fields that will be empty most of +the time. + +In this case, you could define a *template* called "Foreign partners", which +will be applied to ``res.partner`` objects, and defines some *properties* that +these are expected to have. + +Then you could assign that *template* to a partner, and automatically you will +get a subtable of all the properties it should have, with tools to fill their +*values* correctly. + +Does this work with any model? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Yes and no. + +Yes, because this is a base module that provides the tools to make this work +with any model. + +No, because, although the tools are provided, they are only applied to the +``res.partner`` model. This is by design, because different models can have +different needs, and we don't want to depend on every possible model. + +So, if you want to apply this to other models, you will have to develop a +little additional addon that depends on this one. If you are a developer, refer +to the *Development* section below. diff --git a/base_custom_info/readme/DEVELOP.rst b/base_custom_info/readme/DEVELOP.rst new file mode 100644 index 000000000..c61bd0b3b --- /dev/null +++ b/base_custom_info/readme/DEVELOP.rst @@ -0,0 +1,4 @@ +To create a module that supports custom information, just depend on this module +and inherit from the ``custom.info`` model. + +See an example in the ``product_custom_info`` addon. diff --git a/base_custom_info/readme/INSTALL.rst b/base_custom_info/readme/INSTALL.rst new file mode 100644 index 000000000..beac25d3f --- /dev/null +++ b/base_custom_info/readme/INSTALL.rst @@ -0,0 +1,5 @@ +This module serves as a base for other modules that implement this behavior in +concrete models. + +This module is a technical dependency and is to be installed in parallel to +other modules. diff --git a/base_custom_info/readme/ROADMAP.rst b/base_custom_info/readme/ROADMAP.rst new file mode 100644 index 000000000..414964992 --- /dev/null +++ b/base_custom_info/readme/ROADMAP.rst @@ -0,0 +1,20 @@ +* Custom properties cannot be shared among templates. +* Required attributes are for now only set in the UI, not in the ORM itself. +* Support recursive templates using options + + .. figure:: /base_custom_info/static/description/customizations-everywhere.jpg + :alt: Customizations Everywhere + + If you assign an *additional template* to an option, and while using the owner + form you choose that option, you can then press *reload custom information + templates* to make the owner update itself to include all the properties in all + the involved templates. If you do not press the button, anyway the reloading + will be performed when saving the owner record. + + .. figure:: /base_custom_info/static/description/templateception.jpg + :alt: Templateception + + I.e., if you select the option "Needs videogames" for the property "What + weaknesses does he/she have?" of a smart partner and press *reload custom + information templates*, you will get 2 new properties to fill: "Favourite + videogames genre" and "Favourite videogame". diff --git a/base_custom_info/readme/USAGE.rst b/base_custom_info/readme/USAGE.rst new file mode 100644 index 000000000..990dc304b --- /dev/null +++ b/base_custom_info/readme/USAGE.rst @@ -0,0 +1,27 @@ +This module defines *Custom Info Templates* that define what properties are +expected for a given record. + +To define a template, you need to: + +* Go to *Custom Info > Templates*. +* Create one. +* Add some *Properties* to it. + +All database records with that template enabled will automatically fill those +properties. + +To manage the properties, you need to: + +* Go to *Custom Info > Properties*. + +To manage the property categories, you need to: + +* Go to *Custom Info > Categories*. + +Some properties can have a number of options to choose, to manage them: + +* Go to *Custom Info > Options*. + +To manage their values, you need to: + +* Go to *Custom Info > Values*. diff --git a/base_custom_info/security/res_groups.xml b/base_custom_info/security/res_groups.xml deleted file mode 100644 index 684c141c8..000000000 --- a/base_custom_info/security/res_groups.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - Custom Information - - - - Display in partner form - - Will be able to edit custom information from partner's form. - - - - Basic management - - The user will be able to manage basic custom information. - - - - Advanced management - - The user will be able to manage advanced custom information. - - - - - diff --git a/base_custom_info/security/res_groups_security.xml b/base_custom_info/security/res_groups_security.xml new file mode 100644 index 000000000..70ebcf977 --- /dev/null +++ b/base_custom_info/security/res_groups_security.xml @@ -0,0 +1,33 @@ + + + + + + + + Custom Information + + + + Display in partner form + + Will be able to edit custom information from partner's form. + + + + Basic management + + The user will be able to manage basic custom information. + + + + Advanced management + + The user will be able to manage advanced custom information. + + + + + + diff --git a/base_custom_info/static/description/index.html b/base_custom_info/static/description/index.html new file mode 100644 index 000000000..c440fbacf --- /dev/null +++ b/base_custom_info/static/description/index.html @@ -0,0 +1,599 @@ + + + + + + +Base Custom Info + + + +
+

Base Custom Info

+ + +

Beta License: LGPL-3 OCA/server-tools Translate me on Weblate Try me on Runbot

+

This module allows you to attach custom information to records without the need +to alter the database structure too much.

+

This module defines several concepts that you have to understand.

+
+

Templates

+

A template is a collection of properties that a record should have. +Templates always apply to a given model, and then you can choose among the +current templates for the model you are using when you edit a record of that +model.

+

I.e., This addon includes a demo template called “Smart partners”, that applies +to the model res.partner, so if you edit any partner, you can choose that +template and get its properties autofilled.

+
+
+

Properties

+

A property is the “name” of the field. Templates can have any amount of +properties, and when you apply a template to a record, it automatically +gets all of its properties filled, empty (unless they have a Default +value), ready to assign values.

+

You can set a property to as required to force it have a value, although you +should keep in mind that for yes/no properties, this would mean that only yes +can be selected, and for numeric properties, zero would be forbidden.

+

Also you can set Minimum and Maximum limits for every property, but those +limits are only used when the data type is text (to constrain its length) or +number. To skip this constraint, just set a maximum smaller than the minimum.

+

Properties always belong to a template, and as such, to a model.

+

Properties define the data type (text, number, yes/no…), and when the type +is “Selection”, then you can define what options are available.

+

I.e., the “Smart partners” template has the following properties:

+
    +
  • Name of his/her teacher
  • +
  • Amount of people that hates him/her for being so smart
  • +
  • Average note on all subjects
  • +
  • Does he/she believe he/she is the smartest person on earth?
  • +
  • What weaknesses does he/she have?
  • +
+

When you set that template to any partner, you will then be able to fill these +properties with values.

+
+
+

Categories

+

Properties can also belong to a category, which allows you to sort them in +a logical way, and makes further development easier.

+

For example, the website_sale_custom_info addon uses these to display a +technical datasheet per product in your online shop, sorted and separated by +category.

+

You are not required to give a category to every property.

+
+
+

Options

+

When a property’s type is “Selection”, then you define the options +available, so the value must be one of these options.

+

I.e., the “What weaknesses does he/she have?” property has some options:

+
    +
  • Loves junk food
  • +
  • Needs videogames
  • +
  • Huge glasses
  • +
+

The value will always be one of these.

+
+
+

Value

+

When you assign a template to a partner, and then you get the properties it +should have, you still have to set a value for each property.

+

Values can be of different types (whole numbers, constrained selection, +booleans…), depending on how the property was defined. However, there is +always the value field, that is a text string, and converts automatically +to/from the correct type.

+
+

Why would I need this?

+

Imagine you have some partners that are foreign, and that for those partners +you need some extra information that is not needed for others, and you do not +want to fill the partners model with a lot of fields that will be empty most of +the time.

+

In this case, you could define a template called “Foreign partners”, which +will be applied to res.partner objects, and defines some properties that +these are expected to have.

+

Then you could assign that template to a partner, and automatically you will +get a subtable of all the properties it should have, with tools to fill their +values correctly.

+
+
+

Does this work with any model?

+

Yes and no.

+

Yes, because this is a base module that provides the tools to make this work +with any model.

+

No, because, although the tools are provided, they are only applied to the +res.partner model. This is by design, because different models can have +different needs, and we don’t want to depend on every possible model.

+

So, if you want to apply this to other models, you will have to develop a +little additional addon that depends on this one. If you are a developer, refer +to the Development section below.

+

Table of contents

+ +
+

Installation

+

This module serves as a base for other modules that implement this behavior in +concrete models.

+

This module is a technical dependency and is to be installed in parallel to +other modules.

+
+
+

Configuration

+

To enable the main Custom Info menu:

+
    +
  1. Enable Settings > General Settings > Manage custom information.
  2. +
+

To enable partner’s custom info tab:

+
    +
  1. Enable Settings > General Settings > Edit custom information in partners.
  2. +
+
+
+

Usage

+

This module defines Custom Info Templates that define what properties are +expected for a given record.

+

To define a template, you need to:

+
    +
  • Go to Custom Info > Templates.
  • +
  • Create one.
  • +
  • Add some Properties to it.
  • +
+

All database records with that template enabled will automatically fill those +properties.

+

To manage the properties, you need to:

+
    +
  • Go to Custom Info > Properties.
  • +
+

To manage the property categories, you need to:

+
    +
  • Go to Custom Info > Categories.
  • +
+

Some properties can have a number of options to choose, to manage them:

+
    +
  • Go to Custom Info > Options.
  • +
+

To manage their values, you need to:

+
    +
  • Go to Custom Info > Values.
  • +
+
+
+

Development

+

To create a module that supports custom information, just depend on this module +and inherit from the custom.info model.

+

See an example in the product_custom_info addon.

+
+
+

Known issues / Roadmap

+
    +
  • Custom properties cannot be shared among templates.

    +
  • +
  • Required attributes are for now only set in the UI, not in the ORM itself.

    +
  • +
  • Support recursive templates using options

    +
    +Customizations Everywhere +
    +

    If you assign an additional template to an option, and while using the owner +form you choose that option, you can then press reload custom information +templates to make the owner update itself to include all the properties in all +the involved templates. If you do not press the button, anyway the reloading +will be performed when saving the owner record.

    +
    +Templateception +
    +

    I.e., if you select the option “Needs videogames” for the property “What +weaknesses does he/she have?” of a smart partner and press reload custom +information templates, you will get 2 new properties to fill: “Favourite +videogames genre” and “Favourite videogame”.

    +
  • +
+
+
+

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 smashing it by providing a detailed and welcomed +feedback.

+

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

+
+ +
+
+

Authors

+
    +
  • Tecnativa
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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.

+

This module is part of the OCA/server-tools project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/base_custom_info/views/custom_info_property_view.xml b/base_custom_info/views/custom_info_property_view.xml index 054a76ad3..8a787d6d3 100644 --- a/base_custom_info/views/custom_info_property_view.xml +++ b/base_custom_info/views/custom_info_property_view.xml @@ -50,7 +50,7 @@ /> - diff --git a/base_custom_info/views/custom_info_template_view.xml b/base_custom_info/views/custom_info_template_view.xml index 17c0da42f..65b52232a 100644 --- a/base_custom_info/views/custom_info_template_view.xml +++ b/base_custom_info/views/custom_info_template_view.xml @@ -45,7 +45,7 @@ - + diff --git a/base_custom_info/views/custom_info_value_view.xml b/base_custom_info/views/custom_info_value_view.xml index 41355c7fa..d9fdff38a 100644 --- a/base_custom_info/views/custom_info_value_view.xml +++ b/base_custom_info/views/custom_info_value_view.xml @@ -8,7 +8,7 @@ custom.info.value - + @@ -28,6 +28,7 @@ bottom + -
+ @@ -89,12 +90,15 @@ diff --git a/base_custom_info/wizard/__init__.py b/base_custom_info/wizard/__init__.py index f798667d1..13ae90f83 100644 --- a/base_custom_info/wizard/__init__.py +++ b/base_custom_info/wizard/__init__.py @@ -1,6 +1,5 @@ -# -*- coding: utf-8 -*- # Copyright 2015 Antiun Ingeniería S.L. - Sergio Teruel # Copyright 2015 Antiun Ingeniería S.L. - Carlos Dauden # License LGPL-3 - See http://www.gnu.org/licenses/lgpl-3.0.html -from . import base_config_settings +from . import res_config_settings diff --git a/base_custom_info/wizard/base_config_settings_view.xml b/base_custom_info/wizard/base_config_settings_view.xml deleted file mode 100644 index 095b60943..000000000 --- a/base_custom_info/wizard/base_config_settings_view.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - Allow to enable partners custom info - base.config.settings - - - - - - - - - - - - diff --git a/base_custom_info/wizard/base_config_settings.py b/base_custom_info/wizard/res_config_settings.py similarity index 84% rename from base_custom_info/wizard/base_config_settings.py rename to base_custom_info/wizard/res_config_settings.py index c1e7d4794..63424a43f 100644 --- a/base_custom_info/wizard/base_config_settings.py +++ b/base_custom_info/wizard/res_config_settings.py @@ -1,12 +1,11 @@ -# -*- coding: utf-8 -*- # Copyright 2016 Jairo Llopis # License LGPL-3 - See http://www.gnu.org/licenses/lgpl-3.0.html from odoo import fields, models -class BaseConfigSettings(models.TransientModel): - _inherit = "base.config.settings" +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" group_custom_info_manager = fields.Boolean( string="Manage custom information", diff --git a/base_custom_info/wizard/res_config_settings_view.xml b/base_custom_info/wizard/res_config_settings_view.xml new file mode 100644 index 000000000..b70c51177 --- /dev/null +++ b/base_custom_info/wizard/res_config_settings_view.xml @@ -0,0 +1,41 @@ + + + + + + Allow to enable custom information + res.config.settings + + + +

Custom Information

+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+ +