diff --git a/base_autocomplete_template/README.rst b/base_autocomplete_template/README.rst new file mode 100644 index 00000000000..2d3130bca31 --- /dev/null +++ b/base_autocomplete_template/README.rst @@ -0,0 +1,254 @@ +=========================== +Base Autocomplete Templates +=========================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:36224729669f87589f45a941303e973d1a2404ebb481dda00f67b66dc568aad6 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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-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-OCA%2Fserver--tools-lightgray.png?logo=github + :target: https://github.com/OCA/server-tools/tree/17.0/base_autocomplete_template + :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-17-0/server-tools-17-0-base_autocomplete_template + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/server-tools&target_branch=17.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module provides a **generic**, reusable mechanism to **save** and +**apply** named templates that autocomplete any Odoo wizard/form using a +**JSON payload** stored in a template record. + +It is designed to be **framework-like**: other modules can inherit the +mixin and add a few buttons in XML. + +-------------- + +What you get +------------ + +1) Template model +~~~~~~~~~~~~~~~~~ + +``data.autocomplete.template`` + +Each template stores: + +- ``name``: template name +- ``model_id``: the target Odoo model (``ir.model``) the template + applies to +- ``company_id``: company scoping (global or per company) +- ``user_id``: optional owner (personal templates) +- ``values_json``: a JSON dictionary holding serialized default values + +2) Mixin +~~~~~~~~ + +``data.template.mixin`` + +Add it to any wizard/model to get: + +- ``template_id`` field (select a template) +- actions (for buttons): + + - ``action_open_create_template_wizard()`` + - ``action_update_current_template()`` + - ``action_apply_template(overwrite=True)`` + +3) Create Template Wizard +~~~~~~~~~~~~~~~~~~~~~~~~~ + +``data.wizard.template.create`` + +This popup asks for a **name** (and personal/global scope) and creates +the template using the current wizard/model values. + +JSON serialization +~~~~~~~~~~~~~~~~~~ + +The mixin serializes current values into a JSON-safe dict: + +- ``many2one`` -> the record ``id`` (or ``false``) +- ``many2many`` -> a list of record ids +- basic fields + (char/int/float/bool/date/datetime/selection/text/monetary) -> stored + as-is +- ``one2many`` is ignored +- computed fields without inverse and readonly fields are ignored (by + default) + +Applying templates safely with onchanges +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Applying a template uses a **phased write**: + +1. **Drivers**: fields returned by ``_template_driver_fields()`` are + written first +2. **Rest**: everything else (excluding protected fields) +3. **Protected**: fields returned by ``_template_protected_fields()`` + are written last + +This solves common wizard issues where changing a driver field triggers +an onchange that clears other fields (e.g. changing ``plan_id`` clears +``account_ids``). + +While applying, ``apply_template=True`` is present in the context so you +can skip destructive onchanges in your own code. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +1) Inherit the mixin in Python +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: python + + from odoo import models, api + + class MyWizard(models.TransientModel): + _inherit = ["my.wizard.model", "data.template.mixin"] + + # Optional: define drivers/protected fields to survive onchanges + def _template_driver_fields(self): + return {"plan_id"} + + def _template_protected_fields(self): + return {"account_ids", "show_months"} + + @api.onchange("plan_id") + def _onchange_plan_id(self): + # Skip destructive behavior when applying templates + if self.env.context.get("apply_template"): + return + return super()._onchange_plan_id() + +.. + + Note: This module only provides the base. + +2) Add UI in XML (template selector + buttons) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Insert this into your wizard form view (adapt ``inherit_id`` and the +``xpath``): + +.. code:: xml + + + + + +