From 414dfde69712834efe0ca2974d332e7910ba2089 Mon Sep 17 00:00:00 2001 From: "Tiffany Chang (tic)" Date: Tue, 14 Sep 2021 16:14:56 +0200 Subject: [PATCH 1/3] [IMP] developer/howtos: encourage linters more There have been complaints of newbies not setting up their linters therefore let's emphasize their use/setup more in the tutorial and hope for the best. --- content/developer/howtos/rdtraining/02_setup.rst | 12 ++++++++++++ .../developer/howtos/rdtraining/16_guidelines_pr.rst | 6 +++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/content/developer/howtos/rdtraining/02_setup.rst b/content/developer/howtos/rdtraining/02_setup.rst index 1f851b39a1..f14e3c2372 100644 --- a/content/developer/howtos/rdtraining/02_setup.rst +++ b/content/developer/howtos/rdtraining/02_setup.rst @@ -337,6 +337,18 @@ For Python, we use PEP8 with these options ignored: For JavaScript, we use ESLint and you can find a `configuration file example here`_. +If you do not know how to set up a linter: + +- `Here is an explanation of how to set up a Python linter in VSCode `_. There are multiple + linter options you are free to choose from, but `Flake8 `_ is a popular choice. +- To setup ESLint in VSCode, you must download the `ESLint extension`_ and follow its instructions + for installing ESLint. Don't forget to create and set up the `.eslintrc` file to follow the + configuration file mentioned above. +- Another useful VSCode plugin is `Trailing Spaces`_ to quickly notice trailing spaces while + you're working. + +.. _Trailing Spaces: https://marketplace.visualstudio.com/items?itemName=shardulm94.trailing-spaces +.. _ESLint extension: https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint .. _configuration file example here: https://github.com/odoo/odoo/wiki/Javascript-coding-guidelines#use-a-linter .. _VSCode: https://code.visualstudio.com/ .. _VSCodium: https://vscodium.com/ diff --git a/content/developer/howtos/rdtraining/16_guidelines_pr.rst b/content/developer/howtos/rdtraining/16_guidelines_pr.rst index 63c7a17d0d..2879e85581 100644 --- a/content/developer/howtos/rdtraining/16_guidelines_pr.rst +++ b/content/developer/howtos/rdtraining/16_guidelines_pr.rst @@ -18,9 +18,9 @@ to improve the quality of the Odoo Apps code. .. exercise:: Polish your code. - Refactor your code to respect the coding guidelines. Don't forget to respect the module - structure, the variable names, the method name convention, the model attribute order and the - xml ids. + Refactor your code to respect the coding guidelines. Don't forget to run your linter and + respect the module structure, the variable names, the method name convention, the model + attribute order and the xml ids. Your first Pull Request (PR) ============================ From 893b43d684dd4bdfd0fce094f8fe974a1c376691 Mon Sep 17 00:00:00 2001 From: "Tiffany Chang (tic)" Date: Tue, 14 Sep 2021 16:18:40 +0200 Subject: [PATCH 2/3] [IMP] developer/howtos: proofread adv topics - Cleaned up the language a tiny bit - Fixed small errors/typos - Add some missing info for dashboard topic - Updated unit test exercise to match what's in the solutions repo --- .../howtos/rdtraining/B_acl_irrules.rst | 30 +++++------ .../developer/howtos/rdtraining/C_data.rst | 45 +++++++--------- .../howtos/rdtraining/E_unittest.rst | 52 +++++++++++-------- .../howtos/rdtraining/K_dashboard.rst | 16 +++++- 4 files changed, 78 insertions(+), 65 deletions(-) diff --git a/content/developer/howtos/rdtraining/B_acl_irrules.rst b/content/developer/howtos/rdtraining/B_acl_irrules.rst index a01a8a3c26..a30732d675 100644 --- a/content/developer/howtos/rdtraining/B_acl_irrules.rst +++ b/content/developer/howtos/rdtraining/B_acl_irrules.rst @@ -33,7 +33,7 @@ However: * Real-estate agents don't need or get to decide what property types or tags are *available*. * Real-estate agents can have *exclusive* properties, we do not want one agent - to be able to manage another's exclusivities. + to be able to manage another's exclusives. * All real-estate agents should be able to confirm the sale of a property they can manage, but we do not want them to be able to validate or mark as paid any invoice in the system. @@ -44,7 +44,7 @@ However: Because it's easier for users to disable unnecessary security rules than it is to create them from nothing, it's better to err on the side of caution - and limiting access: users can relax that access if necessary or convenient. + and limit access: users can relax that access if necessary or convenient. Groups ====== @@ -294,7 +294,7 @@ do so. There are two main ways to bypass existing security checks in Odoo, either wilfully or as a side-effect: -* The ``sudo()`` method will create a new recorset in "sudo mode", this ignores +* The ``sudo()`` method will create a new recordset in "sudo mode", this ignores all access rules and access rights (although hard-coded group and user checks may still apply). * Performing raw SQL queries will bypass access rules and access rights as a @@ -366,9 +366,9 @@ Explicit security checks can be performed by: specific models or records. * Checking that the current user has specific groups hard-coded to allow or deny an operation (``self.env.user.has_group``). -* Calling the ``check_access_rights(operation)`` method on a recorset, this +* Calling the ``check_access_rights(operation)`` method on a recordset, this verifies whether the current user has access to the model itself. -* Calling ``check_access_rule(operations)`` on a non-empty recorset, this +* Calling ``check_access_rule(operations)`` on a non-empty recordset, this verifies that the current user is allowed to perform the operation on *every* record of the set. @@ -380,7 +380,7 @@ Explicit security checks can be performed by: Before creating the invoice, use ``check_access_rights`` and ``check_access_rule`` to ensure that the current user can update properties - in general, and this specific property in particular. + in general as well as the specific property the invoice is for. Re-run the bypass script, check that the error occurs before the print. @@ -393,7 +393,7 @@ Multi-company security :ref:`reference/howtos/company` for an overview of multi-company facilities in general, and :ref:`multi-company security rules ` - this in particular. + in particular. Documentation on rules in general can, again, be found at :ref:`reference/security/rules`. @@ -403,15 +403,15 @@ Multi-company security At the end of this section, agents should only have access to properties of their agency (or agencies). -For one reason or an other we might need to manage our real-estate business -as multiple companies e.g. we might have largely autonomous agencies, or a +For one reason or another we might need to manage our real-estate business +as multiple companies e.g. we might have largely autonomous agencies, a franchise setup, or multiple brands (possibly from having acquired other real-estate businesses) which remain legally or financially separate from one another. Odoo can be used to manage multiple companies inside the same system, however the actual handling is up to individual modules: Odoo itself provides the tools -to manage the issue like company-dependent fields and *multi-company rules*, +to manage the issue of company-dependent fields and *multi-company rules*, which is what we're going to concern ourselves with. We want different agencies to be "siloed" from one another, with properties @@ -447,7 +447,7 @@ associated with *one* of the companies the user has access to: Multi-company rules are usually :ref:`global `, otherwise there is a high risk that additional rules would allow bypassing - the muti-company rules. + the multi-company rules. .. exercise:: @@ -472,7 +472,7 @@ Visibility != security .. admonition:: **Goal** At the end of this section, real-estate agents should not see the Settings - menu of the rea-estate application, but should still be able to set the + menu of the real-estate application, but should still be able to set the property type or tags. Specific Odoo models can be associated directly with groups (or companies, or @@ -480,7 +480,7 @@ users). It is important to figure out whether this association is a *security* or a *visibility* feature before using it: * *Visibility* features mean a user can still access the model or record - otherwise, either through an other part of the interface or by :doc:`perform + otherwise, either through another part of the interface or by :doc:`performing operations remotely using RPC <../../misc/api/odoo>`, things might just not be visible in the web interface in some contexts. * *Security* features mean a user can not access records, fields or operations. @@ -507,10 +507,10 @@ Here are some examples: .. exercise:: - Real Estate agents can not add property types or tags, and can see their + Real Estate agents can not add property types or tags, but can see their options from the Property form view when creating it. - The Settings menu just adds noise to their interface, it should only be + The Settings menu just adds noise to their interface, make it only visible to managers. Despite not having access to the Property Types and Property Tags menus anymore, diff --git a/content/developer/howtos/rdtraining/C_data.rst b/content/developer/howtos/rdtraining/C_data.rst index 86cee280ef..63ab2ae26c 100644 --- a/content/developer/howtos/rdtraining/C_data.rst +++ b/content/developer/howtos/rdtraining/C_data.rst @@ -23,23 +23,23 @@ We already met technical data previously since we have defined :ref:`security rules`, :ref:`views` and :ref:`actions`. Those are one kind of master data. -On top of technical data, business data can be defined: countries, currencies, units of measure but -also complete country localization (legal reports, tax definitions, chart of account), and much +On top of technical data, business data can be defined, e.g. countries, currencies, units of measure, +as well as complete country localization (legal reports, tax definitions, chart of account), and much more... Demo Data --------- -Next to master data which are requirements for the modules to work properly, we also like having -data for demonstration purpose setups: +In additional to master data, which are requirements for a module to work properly, we also like +having data for demonstration purposes: -* Help the sales representatives to make their demos quickly. -* Have a set of working data for developers to test the new features and see what it looks like - with something they might not have created without it. +* Help the sales representatives make their demos quickly. +* Have a set of working data for developers to test new features and see how these new features look + with data they might not have added themselves. * Test that the data is loaded correctly, without raising an error. -* Be ready to use most of the features quickly when creating a new database. +* Setup most of the features to be used quickly when creating a new database. -Demo data is automatically loaded when you start the server if you didn't say explicitly you don't +Demo data is automatically loaded when you start the server if you don't explicitly say you don't want it. This can be done in the database manager or with the command line. .. code-block:: console @@ -70,15 +70,15 @@ Manifest **Reference**: the documentation related to this topic can be found in :ref:`Module Manifests`. -The data is declared either in CSV either in XML. +Data is declared either in CSV or in XML. Each file containing data must be added in the manifest for them to be loaded. The keys to use in the manifest to add new data are ``data`` for the master data and ``demo`` for -the demo data. Both values should be a list of strings representing the relative path to the files +the demo data. Both values should be a list of strings representing the relative paths to the files declaring the data. -Usually, the demo data is set in a ``demo`` folder, the views and actions are put in a ``views`` -folder, the security related data is put in a ``security`` folder, and the other data is set in a +Usually, demo data is in a ``demo`` folder, views and actions are in a ``views`` +folder, security related data is in a ``security`` folder, and other data is in a ``data`` folder. If your work tree looks like this: @@ -129,7 +129,7 @@ CSV :ref:`CSV data files`. The easiest way to declare simple data is by using the CSV format. This is however limited in terms -of features: use it for long lists of simple models, but prefer XML in the other cases. +of features: use it for long lists of simple models, but prefer XML otherwise. .. code-block:: text @@ -153,7 +153,7 @@ XML **Reference**: the documentation related to this topic can be found in :ref:`Data Files`. -When the data to create is a bit more complex it can be useful, or even needed, to do it in XML. +When the data to create is more complex it can be useful, or even necessary, to do it in XML. .. code-block:: xml @@ -243,7 +243,7 @@ works too if you are in the module declaring it). Deco Addict Big Villa 1500001 14 ============== ========= ======= ======== -.. exercise:: Both properties should be Residential properties. +.. exercise:: Ensure both of your demo properties are created with their Property Type set to Residential. ``eval`` ~~~~~~~~ @@ -279,13 +279,13 @@ Sometimes, you need to call the ORM to do a ``search``. This is not feasible wit -In this code snippet, it is needed because the master data actually depends on the localization +In this code snippet, it is needed because the master data depends on the localization installed. ``function`` ~~~~~~~~~~~~ -You might also need to execute python code when loading the data. +You might also need to execute python code when loading data. .. code-block:: xml @@ -324,15 +324,8 @@ common ORM methods. -.. code-block:: text - - id,parent_id:id,name - "child1","module.parent","Name1" - "child2","module.parent","Name2" - "child3","module.parent","Name3" - .. exercise:: Create one new Property, but this time with some offers created directly inside the - One2many field linking to the Offers. + One2many field linked to the Offers. Accessing the data ================== diff --git a/content/developer/howtos/rdtraining/E_unittest.rst b/content/developer/howtos/rdtraining/E_unittest.rst index 4a48365209..e530845376 100644 --- a/content/developer/howtos/rdtraining/E_unittest.rst +++ b/content/developer/howtos/rdtraining/E_unittest.rst @@ -15,11 +15,11 @@ Advanced E: Python Unit Tests Writing tests is a necessity for multiple reasons. Here is a non exhaustive list: -* Ensure it will not be broken in the future +* Ensure code will not be broken in the future * Define the scope of your code * Give examples of use cases * It is one way to technically document the code -* Help you develop by defining your goal before working towards it +* Help your coding by defining your goal before working towards it Running Tests ============= @@ -79,7 +79,7 @@ Integration Bots ================ .. note:: This section is only for Odoo employees and people that are contributing to - `github.com/odoo`. We highly recommend having your own CI if it is not the case. + `github.com/odoo`. We highly recommend having your own CI otherwise. When a test is written, it is important to make sure it always passes when modifications are applied to the source code. To automate this task, we use a development practice called @@ -100,7 +100,7 @@ GitHub. You can see the state of a commit/branch by filtering on the runbot dashboard. -A **bundle** is created for each branch. A bundle consists of a configuration and contains the +A **bundle** is created for each branch. A bundle consists of a configuration and batches. A **batch** is a set of builds, depending on the parameters of the bundle. @@ -116,17 +116,17 @@ process. Generally it is used to split the post install tests in 4 parallel inst A sub-build is green if all the tests are passing and there are no errors/warnings logged. .. note:: - * All tests are run whatever the modifications done. Correcting a typo in an error message or - refactoring a whole module triggers the same tests. It will install all the modules. This means - something might not work if Runbot green but your changes depend on something you don't depend - on. + * All tests are run regardless of the modifications done. Correcting a typo in an error message or + refactoring a whole module triggers the same tests. All modules will be installed as well. This means + something might not work even if the Runbot is green, i.e. your changes depend on a module that the + module the changes are in doesn't depend on. * The localization modules (i.e. country-specific modules) are not installed on Runbot (except - the generic one), some modules with external dependencies can be excluded also. - * There is a nightly build running additional tests, like module operations, localization, single + the generic one). Some modules with external dependencies can also be excluded. + * There is a nightly build running additional tests: module operations, localization, single module installs, multi-builds for nondeterministic bugs, etc. These are not kept in the standard CI to shorten the time of execution. -You can also login on a build built by Runbot. There are 3 users usable: `admin`, `demo` and +You can also login to a build built by Runbot. There are 3 users usable: `admin`, `demo` and `portal`. The password is the same as the login. This is useful to quickly test things on different versions without having to build it locally. The full logs are also available; these are used for monitoring. @@ -138,9 +138,9 @@ You will most likely have to gain a little bit more experience before having the robodoo, but here are a few remarks anyways. Robodoo is the guy spamming the CI status as tags on your PRs, but he is also the guy that kindly -integrates your commits on the main repositories. +integrates your commits into the main repositories. -When the last batch is green, the reviewer can ask robodoo to merge your PR (actually it is more +When the last batch is green, the reviewer can ask robodoo to merge your PR (it is more a `rebase` than a `merge`). It will then go to the mergebot. Mergebot @@ -166,8 +166,8 @@ your branch on the target and rerun the tests locally. Modules ======= -Because Odoo is modular, the tests need to be modular also. This means the modules are defined in -the module that adds the functionality you add; and that tests cannot depend on functionality +Because Odoo is modular, the tests need to be also modular. This means tests are defined in +the module that adds the functionality you are adding in and tests cannot depend on functionality coming from modules your module doesn't depend on. **Reference**: the documentation related to this topic can be found in @@ -193,7 +193,7 @@ coming from modules your module doesn't depend on. If the behavior you want to test can be changed by the installation of another module, you need to ensure that the tag `at_install` is set; otherwise you can use the tag `post_install` to speed up -the CI, and ensure it is not changed if it shouldn't. +the CI and ensure it is not changed if it shouldn't. Writing a test ============== @@ -233,13 +233,13 @@ import the test folder/module in the ``__init__.py`` of the module. ├── __init__.py └── __manifest__.py -.. note:: Some older tests are extending ``odoo.tests.common.TransactionCase``, but they are less +.. note:: Some older tests extend ``odoo.tests.common.TransactionCase``, but they are less scalable. The difference is that the setup is done per test method and not per test class. - The data changed are rollbacked between each test in `SavepointCase` to have the same behavior as - in `TransactionCase`. + Changed data is rolled back between each test in `SavepointCase` to have the same behavior as + `TransactionCase`. All the tests should extend ``odoo.tests.common.SavepointCase``. You usually define a -``setUpClass``, and the tests. After doing the `setUpClass`, you have an `env` available on the +``setUpClass`` and the tests. After writing the `setUpClass`, you have an `env` available in the class and can start interacting with the ORM. These test classes are built on top of the ``unittest`` python module. @@ -285,12 +285,18 @@ These test classes are built on top of the ``unittest`` python module. with self.assertRaises(UserError): self.properties.forbidden_action_on_sold_property() -.. note:: For more readability, split your tests into multiple files depending on the scope of the - tests. You can also have a Common class that most of the tests should inherit from; that common +.. note:: For better readability, split your tests into multiple files depending on the scope of the + tests. You can also have a Common class that most of the tests should inherit from; this common class can define the whole set up for the module. For instance in `account `__. -.. exercise:: Ensure no one can create an offer for a sold Property, and create a test for it. +.. exercise:: Update the code so no one can: + + - Create an offer for a sold property + - Sell a property with no accepted offers on it + + and create tests for both of these cases. Additionally check that selling a property that can + be sold is correctly marked as sold after selling it. .. exercise:: Someone keeps breaking the reset of Garden Area and Orientation when you uncheck the diff --git a/content/developer/howtos/rdtraining/K_dashboard.rst b/content/developer/howtos/rdtraining/K_dashboard.rst index 6eebcc3417..0006c0316a 100644 --- a/content/developer/howtos/rdtraining/K_dashboard.rst +++ b/content/developer/howtos/rdtraining/K_dashboard.rst @@ -319,7 +319,7 @@ View Now that we have our model, we can make its dashboard view. There is no difference to how its made except that its file is located in the ``report`` folder. Since it is a new model not linked to any other model, we will also have to add a new menuitem to view our dashboard. Typically SQL views -are added under a first level menu called ``Reporting` (because it's a report, surprise!). Do you +are added under a first level menu called *Reporting* (because it's a report, surprise!). Do you remember how to add a ``menuitem``? If not, revisit :ref:`howto/rdtraining/06_firstui`) again. .. exercise:: Create report view. @@ -352,3 +352,17 @@ from this report. **Tip 2** If you have a field that you do not want as a measure (i.e. in your pivot or graph views), then you can add ``store=False`` to it and it will not show. + +**Tip 3** If you have a SQL View that depends on context then instead of overriding +``BaseModel.init()`` set the ``_table_query`` property:: + + @property + def _table_query(self): + return 'SELECT %s FROM %s' % (self._select(), self._from()) + +The *select* and *from* methods remain the same. + +`Here is an example `__ +of a report that depends on the currently selected companies (in a multi-company environment) context to +determine the currency exchange rates to use for accurately displaying amounts when the selected companies +have different currencies. \ No newline at end of file From a231914da21b6ff2fd2be18556dcbffeaec66ef9 Mon Sep 17 00:00:00 2001 From: "Tiffany Chang (tic)" Date: Wed, 15 Sep 2021 15:03:24 +0200 Subject: [PATCH 3/3] [IMP] developer/{howtos,reference}: update training to match v15 changes - Reference v15 training solutions - Refer to Command namespace instead of triplets (e.g. Command.create(values) instead of (0, 0, values) - Add notice about OWL transition - Add reference to @api.ondelete (instead of override unlink()) - Remove references to SavepointCase (now only TransactionCase) from unit test topic - Also add missing reference documentation for ondelete --- .../howtos/rdtraining/01_architecture.rst | 6 +++++ .../howtos/rdtraining/13_inheritance.rst | 10 ++++++-- .../howtos/rdtraining/14_other_module.rst | 24 +++++++++---------- .../howtos/rdtraining/B_acl_irrules.rst | 7 +++--- .../developer/howtos/rdtraining/C_data.rst | 13 +++++----- .../howtos/rdtraining/E_unittest.rst | 20 +++++++--------- .../developer/howtos/rdtraining/J_reports.rst | 9 +++---- .../howtos/rdtraining/K_dashboard.rst | 11 +++++---- content/developer/reference/addons/orm.rst | 2 +- 9 files changed, 57 insertions(+), 45 deletions(-) diff --git a/content/developer/howtos/rdtraining/01_architecture.rst b/content/developer/howtos/rdtraining/01_architecture.rst index 76be120e10..85d54c0531 100644 --- a/content/developer/howtos/rdtraining/01_architecture.rst +++ b/content/developer/howtos/rdtraining/01_architecture.rst @@ -29,6 +29,12 @@ on your background. For reference this is the official `Python tutorial`_. +.. note:: + Since version 15.0, Odoo is actively transitioning to using its own in-house developed `OWL + framework `_ as part of its presentation tier. The legacy JavaScript + framework is still supported but will be depreciated over time. This will be discussed further in + advanced topics. + Odoo modules ============ diff --git a/content/developer/howtos/rdtraining/13_inheritance.rst b/content/developer/howtos/rdtraining/13_inheritance.rst index 311f9f4bfa..79645ab452 100644 --- a/content/developer/howtos/rdtraining/13_inheritance.rst +++ b/content/developer/howtos/rdtraining/13_inheritance.rst @@ -71,6 +71,12 @@ The decorator :func:`~odoo.api.model` is necessary for the :meth:`~odoo.models.M method because the content of the recordset ``self`` is not relevant in the context of creation, but it is not necessary for the other CRUD methods. +It is also important to note that even though we can directly override the +:meth:`~odoo.models.Model.unlink` method, you will almost always want to write a new method with +the decorator :func:`~odoo.api.ondelete` instead. Methods marked with this decorator will be +called during :meth:`~odoo.models.Model.unlink` and avoids some issues that can occur during +uninstalling the model's module when :meth:`~odoo.models.Model.unlink` is directly overridden. + In Python 3, ``super()`` is equivalent to ``super(TestModel, self)``. The latter may be necessary when you need to call the parent method with a modified recordset. @@ -85,8 +91,8 @@ when you need to call the parent method with a modified recordset. - Prevent deletion of a property if its state is not 'New' or 'Canceled' - Tip: override :meth:`~odoo.models.Model.unlink` and remember that ``self`` can be a recordset - with more than one record. + Tip: create a new method with the :func:`~odoo.api.ondelete` decorator and remember that + ``self`` can be a recordset with more than one record. - At offer creation, set the property state to 'Offer Received'. Also raise an error if the user tries to create an offer with a lower amount than an existing offer. diff --git a/content/developer/howtos/rdtraining/14_other_module.rst b/content/developer/howtos/rdtraining/14_other_module.rst index 5473a24264..de03511472 100644 --- a/content/developer/howtos/rdtraining/14_other_module.rst +++ b/content/developer/howtos/rdtraining/14_other_module.rst @@ -133,24 +133,24 @@ information: Moreover, an invoice line needs to be linked to an invoice. The easiest and most efficient way to link a line to an invoice is to include all lines at invoice creation. To do this, the ``invoice_line_ids`` field is included in the ``account.move`` creation, which is a -:class:`~odoo.fields.One2many`. One2many and Many2many use special 'commands' described in -:ref:`reference/orm/models/crud`. This format is a list of triplets executed sequentially, where -each triplet is a command to execute on the set of records. Here is a simple example to include -a One2many field ``line_ids`` at creation of a ``test.model``:: +:class:`~odoo.fields.One2many`. One2many and Many2many use special 'commands' which have been +made human readable with the :class:`~odoo.fields.Command` namespace. This namespace represents +a triplet command to execute on a set of records. The triplet was originally the only option to +do these commands, but it is now standard to use the namespace instead. The format is to place +them in a list which is executed sequentially. Here is a simple example to include a One2many +field ``line_ids`` at creation of a ``test.model``:: + + from odoo import Command def inherited_action(self): self.env["test.model"].create( { "name": "Test", "line_ids": [ - ( - 0, - 0, - { - "field_1": "value_1", - "field_2": "value_2", - }, - ) + Command.create({ + "field_1": "value_1", + "field_2": "value_2", + }) ], } ) diff --git a/content/developer/howtos/rdtraining/B_acl_irrules.rst b/content/developer/howtos/rdtraining/B_acl_irrules.rst index a30732d675..cc9e6dd7d2 100644 --- a/content/developer/howtos/rdtraining/B_acl_irrules.rst +++ b/content/developer/howtos/rdtraining/B_acl_irrules.rst @@ -10,8 +10,9 @@ Advanced B: ACL and Record Rules `. To follow the exercise, it is recommended that you fetch the branch - 14.0-core from the repository XXX, it - contains a version of the module created during the core training we can use + 15.0-core from the + `technical training solutions `__ repository. + It contains a version of the module created during the core training we can use as a starting point. So far we have mostly concerned ourselves with implementing useful features. @@ -223,7 +224,7 @@ individual records: A description of the rule's role - + [ '|', ('user_id', '=', user.id), ('user_id', '=', False) diff --git a/content/developer/howtos/rdtraining/C_data.rst b/content/developer/howtos/rdtraining/C_data.rst index 63ab2ae26c..691aa33c10 100644 --- a/content/developer/howtos/rdtraining/C_data.rst +++ b/content/developer/howtos/rdtraining/C_data.rst @@ -6,7 +6,8 @@ Advanced C: Master and Demo Data .. tip:: This tutorial assumes you followed the Core Training. - To do the exercise, fetch the branch 14.0-core from the repository XXX. + To do the exercise, fetch the branch 15.0-core from the + `technical training solutions `__ repository. It contains a basic module we will use as a starting point Data Types @@ -303,23 +304,23 @@ Add X2many fields ----------------- **Reference**: the documentation related to this topic can be found in -:ref:`Common ORM methods`. +:class:`~odoo.fields.Command`. If you need to add related data in a One2many or a Many2many field, you can do so by using the -common ORM methods. +:class:`~odoo.fields.Command` methods. .. code-block:: xml diff --git a/content/developer/howtos/rdtraining/E_unittest.rst b/content/developer/howtos/rdtraining/E_unittest.rst index e530845376..90f4c398fe 100644 --- a/content/developer/howtos/rdtraining/E_unittest.rst +++ b/content/developer/howtos/rdtraining/E_unittest.rst @@ -6,7 +6,8 @@ Advanced E: Python Unit Tests .. tip:: This tutorial assumes you followed the Core Training. - To do the exercise, fetch the branch 14.0-core from the repository XXX. + To do the exercise, fetch the branch 15.0-core from the + `technical training solutions `__ repository. It contains a basic module we will use as a starting point **Reference**: @@ -175,18 +176,18 @@ coming from modules your module doesn't depend on. .. code-block:: python - from odoo.tests.common import SavepointCase + from odoo.tests.common import TransactionCase from odoo.tests import tagged # The CI will run these tests after all the modules are installed, # not right after installing the one defining it. @tagged('post_install', '-at_install') # add `post_install` and remove `at_install` - class PostInstallTestCase(SavepointCase): + class PostInstallTestCase(TransactionCase): def test_01(self): ... @tagged('at_install') # this is the default - class AtInstallTestCase(SavepointCase): + class AtInstallTestCase(TransactionCase): def test_01(self): ... @@ -233,12 +234,7 @@ import the test folder/module in the ``__init__.py`` of the module. ├── __init__.py └── __manifest__.py -.. note:: Some older tests extend ``odoo.tests.common.TransactionCase``, but they are less - scalable. The difference is that the setup is done per test method and not per test class. - Changed data is rolled back between each test in `SavepointCase` to have the same behavior as - `TransactionCase`. - -All the tests should extend ``odoo.tests.common.SavepointCase``. You usually define a +All the tests should extend ``odoo.tests.common.TransactionCase``. You usually define a ``setUpClass`` and the tests. After writing the `setUpClass`, you have an `env` available in the class and can start interacting with the ORM. @@ -246,14 +242,14 @@ These test classes are built on top of the ``unittest`` python module. .. code-block:: python - from odoo.tests.common import SavepointCase + from odoo.tests.common import TransactionCase from odoo.exceptions import UserError from odoo.tests import tagged # The CI will run these tests after all the modules are installed, # not right after installing the one defining it. @tagged('post_install', '-at_install') - class EstateTestCase(SavepointCase): + class EstateTestCase(TransactionCase): @classmethod def setUpClass(cls): diff --git a/content/developer/howtos/rdtraining/J_reports.rst b/content/developer/howtos/rdtraining/J_reports.rst index 368b3442a9..d87f53a01d 100644 --- a/content/developer/howtos/rdtraining/J_reports.rst +++ b/content/developer/howtos/rdtraining/J_reports.rst @@ -10,8 +10,9 @@ Advanced J: PDF Reports and have installed :ref:`wkhtmltopdf `. To follow the exercise, it is recommended that you fetch the branch - 14.0-core from the repository XXX, it - contains a version of the module created during the core training we can use + 15.0-core from the + `technical training solutions `__ repository. + It contains a version of the module created during the core training we can use as a starting point. We were previously :ref:`introduced to QWeb ` @@ -95,9 +96,9 @@ If you don't have a set of data like this already, you can either: * Complete :ref:`howto/rdtraining/C_data` (if you haven't done so already) and add the extra cases to your demo data (you may need to create a new database to load in the demo data). * Manually create the data in your database. -* Copy this `data file `__ +* Copy this `data file `__ into a new directory (data) in your estate module and copy - `these lines `__ + `these lines `__ into your __manifest__.py file (you may need to create a new database to load in the demo data). Before continuing, click through your data in your database and make sure your data is as expected. diff --git a/content/developer/howtos/rdtraining/K_dashboard.rst b/content/developer/howtos/rdtraining/K_dashboard.rst index 0006c0316a..29a79e7faa 100644 --- a/content/developer/howtos/rdtraining/K_dashboard.rst +++ b/content/developer/howtos/rdtraining/K_dashboard.rst @@ -10,8 +10,9 @@ Advanced K: Dashboards access to Odoo Enterprise features. To follow the exercise, it is recommended that you fetch the branch - 14.0-core from the repository XXX, it - contains a version of the module created during the core training we can use + 15.0-core from the + `technical training solutions `__ repository. + It contains a version of the module created during the core training we can use as a starting point. The term "Dashboard" is used in Odoo for objects that display data, but involves different @@ -118,9 +119,9 @@ If you don't have a set of data like this already, you can either: * Complete :ref:`howto/rdtraining/C_data` (if you haven't done so already) and add the extra cases to your demo data (you may need to create a new database to load in the demo data). * Manually create the data in your database. -* Copy this `data file `__ +* Copy this `data file `__ into a new directory called ``data`` in your estate module and copy - `these lines `__ + `these lines `__ into your __manifest__.py file (you may need to create a new database to load in the demo data). Click through your database data and make sure it is what you expect. Of course you can add the @@ -208,7 +209,7 @@ no xml id is provided for a graph or pivot view then the default view will be us The cohort view will not work in the dashboard without a specific xml id. If you have already created some of these views then you are welcome to add them to your dashboard! Sample graph and pivot views are included in the -`solution code `__ +`solution code `__ that you are welcome to use as well. .. exercise:: Add subviews. diff --git a/content/developer/reference/addons/orm.rst b/content/developer/reference/addons/orm.rst index a021693676..dc00e6dfbc 100644 --- a/content/developer/reference/addons/orm.rst +++ b/content/developer/reference/addons/orm.rst @@ -611,7 +611,7 @@ Method decorators ================= .. automodule:: odoo.api - :members: depends, depends_context, constrains, onchange, returns, autovacuum, model, model_create_multi + :members: depends, depends_context, constrains, onchange, returns, autovacuum, model, model_create_multi, ondelete .. .. currentmodule:: odoo.api