Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
Odoo 15 Development Essentials - Fifth Edition

You're reading from  Odoo 15 Development Essentials - Fifth Edition

Product type Book
Published in Feb 2022
Publisher Packt
ISBN-13 9781800200067
Pages 548 pages
Edition 5th Edition
Languages
Author (1):
Daniel Reis Daniel Reis
Profile icon Daniel Reis

Table of Contents (22) Chapters

Preface 1. Section 1: Introduction to Odoo Development
2. Chapter 1: Quick Start Using the Developer Mode 3. Chapter 2: Preparing the Development Environment 4. Chapter 3: Your First Odoo Application 5. Chapter 4: Extending Modules 6. Section 2: Models
7. Chapter 5: Importing, Exporting, and Module Data 8. Chapter 6: Models – Structuring the Application Data 9. Section 3: Business Logic
10. Chapter 7: Recordsets – Working with Model Data 11. Chapter 8: Business Logic – Supporting Business Processes 12. Chapter 9: External API – Integrating with Other Systems 13. Section 4: Views
14. Chapter 10: Backend Views – Designing the User Interface 15. Chapter 11: Kanban Views and Client-Side QWeb 16. Chapter 12: Creating Printable PDF Reports with Server-Side QWeb 17. Chapter 13: Creating Web and Portal Frontend Features 18. Section 5: Deployment and Maintenance
19. Chapter 14: Understanding Odoo Built-In Models 20. Chapter 15: Deploying and Maintaining Production Instances 21. Other Books You May Enjoy

Chapter 8: Business Logic – Supporting Business Processes

In the previous chapters, we learned how to use models to build the application data structures, and then how to explore and interact with that data using the ORM API and recordsets.

In this chapter, we will put all this together to implement business logic patterns that are common in applications. We will learn about the several ways business logic can be triggered, as well as some common patterns that are used to support them. We will also learn about important development techniques, such as logging, debugging, and testing.

We'll cover the following topics in this chapter:

  • Learning project – the book checkout module
  • Ways to trigger business logic
  • Understanding ORM method decorators for recordsets
  • Exploring useful data model patterns
  • Using the ORM built-in methods
  • Adding onchange user interface logic
  • The message and activity features
  • Creating a wizard
  • Raising...

Technical requirements

In this chapter, we will create a new library_checkout add-on module. It depends on the library_app and library_member add-on modules, which we created in the previous chapters.

The code for these add-on modules can be found in this book's GitHub repository, at https://github.com/PacktPublishing/Odoo-15-Development-Essentials-Fifth-Edition, in the ch08 directory.

Both of these add-on modules need to be available in the Odoo add-ons path so that they can be installed and used.

Learning project – the book checkout module

The master data structures for the library application are in place. Now, we want to add transactions to our system. We would like library members to be able to borrow books. This means we should keep track of book availability and returns.

Each book checkout has a life cycle, from the moment they are created to the moment when the books are returned. It is a simple workflow that can be represented as a Kanban board, where the several stages are presented as columns, and the work items from the left-hand column are sent to the right until they are completed.

This chapter focuses on the data model and business logic that are needed to support this feature.

The basic user interface will be discussed in Chapter 10, Backend Views – Designing the User Interface, while the Kanban views will be discussed in Chapter 11, Kanban Views and Client-Side QWeb. Let's quickly have a rundown of the data model.

Preparing the...

Exploring ways to trigger business logic

Once the data model is in place, business logic is needed to perform some automatic actions on it. Business logic can either be directly initiated by the user, with an action such as a button click, or it can be triggered automatically when an event occurs, such as a write on a record.

Much of this business logic will involve reading and writing on recordsets. The details and techniques for this were discussed in Chapter 7, Recordsets – Working with Model Data, where we provided the tools for the actual business logic implementation.

The next question is how the business logic should be triggered. This will depend on when and why the business logic should be triggered. Here is a summary of the several options.

Some business logic is tightly connected to the model field definitions. Some of the instances of model definition-related business logic are as follows:

  • Data validation rules, to enforce conditions that the data...

Understanding ORM method decorators for recordsets

The method definition can be preceded by an @, which applies a decorator to it. These decorators add specific behaviors for these methods and depending on the purpose of a method, different decorators can be used.

Decorators for computed fields and validation methods

A few decorators are useful for validation logic and computed fields. They are listed here:

  • @api.depends(fld1,...) is used for computed field functions to identify what changes the (re)calculation should be triggered on. It must set values on the computed fields; otherwise, an error will be shown.
  • @api.constrains(fld1,...) is used for model validation functions and performs checks for when any of the mentioned fields are changed. It should not write changes in the data. If the checks fail, an exception should be raised.

These were discussed in detail in Chapter 6, Models – Structuring the Application Data.

Another group of decorators...

Exploring useful data model patterns

There are a few data structures that are often needed for models that represent business documents. These can be seen in several Odoo apps, such as Sales Orders or Invoices.

A common pattern is the header/lines data structure. It will be used for a checkout request so that you can have several books. Another pattern is to use states or stages. These two have differences, and we will discuss them and provide a reference implementation shortly.

Finally, the ORM API provides a few methods that are relevant for the user interface. These will also be discussed in this section.

Using header and lines models

A common need for form views is to have header-line data structures. For example, a sales order includes several lines for the ordered items. In the case of the checkout feature, a checkout request can have several request lines, one for each of the borrowed items.

With Odoo, it is simple to implement this. Two models are needed for...

Using the ORM built-in methods

The model definition-related methods can do many things, but some business logic is not possible through them, so it needs to be attached to the ORM record writing operations.

ORM provides methods to perform Create, Read, Update, and Delete (CRUD) operations on our model data. Let's explore these write operations and how they can be extended to support custom logic.

To read data, the main methods that are provided are search() and browse(), as discussed in Chapter 7, Recordsets – Working with Model Data.

Methods for writing model data

The ORM provides three methods for the three basic write operations, shown as follows:

  • <Model>.create(values) creates a new record on the model. It returns the created record. values can be a dictionary or a list of dictionaries for mass-creating records.
  • <Recordset>.write(values) updates the recordset with the values dictionary. It returns nothing.
  • <Recordset>.unlink...

Adding onchange user interface logic

It is possible to make changes to the web client view while the user is editing it. This mechanism is known as onchange. It is implemented through methods decorated with @api.onchange, and they are triggered by the user interface view when the user edits a value on a particular field.

Since Odoo 13, the same effect can be achieved by using a particular form of computed fields, called computed writable fields. This ORM improvement aims to avoid some limitations of the classic onchange mechanism, and in the long run, it should replace it completely.

Classic onchange methods

Onchange methods can change other field values in the form, perform a validation, show a message to the user, or set a domain filter in relation fields, limiting the available options.

The onchange method is called asynchronously and returns data that's being used by the web client to update the fields in the current view.

Onchange methods are linked to the...

The message and activity features

Odoo has global messaging and activity planning features available, all of which are provided by the Discuss application, and a mail technical name.

The messaging features are added by the mail.thread model and make a message widget on form views available, also known as Chatter. This widget allows you to log notes or send messages to other people. It also keeps a history of the messages that have been sent, and it is also used by automatic processes to log progress tracking messages.

The same app also provides activity management features through the mail.activity.mixin model. The activity widget can be added to the form view to allow users to schedule and track the history of activities.

Adding message and activity features

The mail module provides the mail.thread abstract class, which is used to add the messaging features to any model, and mail.activity.mixin, which does the same for the planned activity features. In Chapter 4, Extending...

Creating a wizard

Wizards are user interface patterns that provide rich interaction for the user, usually to provide input for an automated process.

As an example, the checkout module will provide a wizard for library users to mass email borrowers. For example, they could select the oldest checkouts with borrowed books and send them all a message, requesting for the books to be returned.

Users start by going to the checkouts list view, selecting the checkout records to use, and then selecting a Send Messages option from the Action context menu. This will open the wizard form, allowing them to write the message subject and body. Clicking the Send button will send an email to each person that borrowed the selected checkouts.

The wizard model

A wizard displays a form view to the user, usually as a dialog window, with some fields to be filled in and buttons to trigger some business logic. These will then be used for the wizard's logic.

This is implemented using the...

Raising exceptions

There are times where the inputs are inappropriate for the task to perform, and the code needs to warn the user about it and interrupt the program's execution with an error message. This is done by raising an exception. Odoo provides exception classes that should be used in these situations.

The most useful Odoo exceptions are as follows:

from odoo import exceptions
raise exceptions.ValidationError("Inconsistent data")
raise exceptions.UserError("Wrong input")

The ValidationError exception should be used for validations in Python code, such as the ones in @api.constrains decorated methods.

The UserError exception should be used in all other cases where some action should not be allowed because it goes against business logic.

As a general rule, all data manipulation that's done during method execution is done in a database transaction and rolled back when an exception occurs. This means that, when an exception is raised...

Writing unit tests

Automated tests are generally accepted as a best practice in software. They not only help ensure code is correctly implemented, but more importantly, they provide a safety net for future code changes or rewrites.

In the case of dynamic programming languages, such as Python, there is no compilation step and syntax errors can go unnoticed. Ensuring there's test code coverage is particularly important for detecting code writing mistakes, such as a mistyped identifier name.

These two goals provide a guiding light to test writing. One goal should be test coverage – writing test cases that run all your lines of code.

This alone will usually make good progress on the second goal, which is to verify the correctness of the code. This is because, after working on code coverage tests, we will surely have a great starting point to build additional test cases for non-trivial use cases.

Changes in Odoo 12

In earlier Odoo versions, tests could also be...

Using log messages

Writing messages to the log file is useful for monitoring and auditing running systems. It can also help with code maintenance, making it easier to get debug information from running processes, without the need to change code.

To use logging in Odoo code, first, a logger object must be prepared. For this, add the following code lines at the top of the library_checkout/wizard/checkout_mass_message.py file:

import logging
_logger = logging.getLogger(__name__)

The logging Python standard library module is being used here. The _logger object is initialized using the name of the current code file, __name__. With this, the log messages will include information about the file that generated them.

There are several levels available for log messages. These are as follows:

_logger.debug('A DEBUG message') 
_logger.info('An INFO message') 
_logger.warning('A WARNING message') 
_logger.error('An ERROR message')

We can...

Learning about the available developer tools

There are a few tools to ease developers' work. The web interface's Developer Mode, which we introduced earlier in this book, is one of them. A server developer mode option is also available that provides some developer-friendly features. It will be explained in more detail next. After that, we will discuss how to debug code on the server.

Server development options

The Odoo server provides a --dev option, which enables developer features to speed up the development cycle, such as the following:

  • Entering the debugger when an exception is found in an add-on module. This is done by setting a debugger. pdb is the default one.
  • Reloading Python code automatically when a Python code file is saved, avoiding a manual server restart. This can be enabled with the reload option.
  • Reading view definitions directly from XML files, avoiding manual module upgrades. This can be enabled with the xml option.
  • A Python debugging...

Summary

In this chapter, we explored the various features of the ORM API and how to use them to create dynamic applications that react to users, which helps them avoid errors and automate tedious tasks.

The model validations and computed fields can cover a lot of use cases, but not all. We learned how to extend the API's create, write, and unlink methods to cover further use cases.

For rich user interaction, we used the mail core add-on mixins to add features for users to communicate about documents and plan activities on them. Wizards allow the application to dialogue with the user and gather the data that's needed to run particular processes. Exceptions allow the application to abort incorrect operations, informing the user of the problem and rolling back intermediate changes, keeping the system consistent.

We also discussed the tools that are available for developers to create and maintain their applications: logging messages, debugging tools, and unit tests.

...

Further reading

The following are the most relevant reference materials for the topics that were discussed in this chapter:

lock icon The rest of the chapter is locked
You have been reading a chapter from
Odoo 15 Development Essentials - Fifth Edition
Published in: Feb 2022 Publisher: Packt ISBN-13: 9781800200067
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime}