Create a Basic App - vec-ltd/odoo-docs GitHub Wiki
This guide will give you the basic steps of how to create an App, which is a process I found very confusing the first time I did it.
I will basically follow the Official Docs in this, but supplement it with the information that I feel is really lacking from the Official Docs.
Scaffolding
To be honest, the Official Docs do a pretty decent job of explaining how to setup a development environment, so I won't bother expanding on that much here.
Personally I used docker-compose to setup Odoo, so I will include that file here:
version: '3.1'
services:
odoo:
image: odoo:16.0
platform: linux/amd64
depends_on:
- odoo_db
ports:
- "8069:8069"
environment:
- HOST=odoo_db
- USER=odoo
- PASSWORD=myodoo
# volumes:
# - ./custom-modules/my_basic_app:/mnt/extra-addons/my_basic_app
# command: odoo --addons-path=/mnt/extra-addons -u my_basic_app
odoo_db:
image: postgres:14
platform: linux/amd64
environment:
- POSTGRES_DB=postgres
- POSTGRES_PASSWORD=myodoo
- POSTGRES_USER=odoo
volumes:
- ./.docker-data/postgresql:/var/lib/postgresql/data
The most important thing to note, is your module must conform to a specific folder structure, and that it must be inside the /mnt/extra-addons folder.
To begin with, I'd run the containers first so you have an environment from which you can scaffold the new module. Jump into the container with 'docker-compose exec odoo bash' and run this command:
odoo scaffold my_basic_app /mnt/extra-addons
You can then copy these files to your host machine like so:
docker-compose cp odoo:/mnt/extra-addons/my_basic_app ./custom-modules/my_basic_app
From then on, if you uncomment the command line and the volume mounts in the docker-compose file, every time you boot Odoo it will refresh your module, which is quite useful.
You can then edit the scaffolded module to meet your requirements
Module Components
There are some points that I felt were not well explained in the Official Docs.
In the data field in the manifest file, you can add in as many xml files as you like. This allows you to split out the various types of module configuration into multiple files if you want to.
Models
A "model" in Odoo is just an entity. So in the Project module, you will have "Project" and "Task" as the basic models.
Odoo ships with a very powerful ORM, that handles all db migrations for you. All you have to do is define all the fields on your model, and all the relations (like one2Many, many2One etc), and it's all done.
This is quite a nice benefit of using Odoo, that you can just declare your data types as Models and then forget about all the complexities of data persistence and just let Odoo do all that for you.
This is a big, big time-saver when building web applications.
Menus
I personally like to add a menus.xml file, and put all my menu configuration in there. These configuration options will control the menus as they appear in the top-left of your module. For example, the Odoo ships a module called "Project". It has a menu that looks like this:
There are a couple of rules to know here.
- If you define a menu with no 'parent' attribute, then it will essentially be the root menu in your system. So it will appear as the left-most menu, and will be the most senior menu in your module.
Example:
<menuitem name="Project" id="unique_id" />
- If you create a menu item whose parent is the root menu item, then it will appear in the top bar as in the image. Examples like "My Tasks" or "Reporting". You would do it like this:
<menuitem name="Reporting" id="another_unique_id" parent="unique_id" />
- If you create a menu item whose parent is one of the things I mentioned above (i.e. one down from the root menu), then it will appear as a drop-down option if you click on that menu. Like so:
So you get 3 levels of menu items. The root, then the main ones along the top, then the drop-down options from the main ones along the top.
Actions
This one is a bit weird. But essentially, if you want to view any data, then the screen with which you can view the data and perform actions on it, is called a 'window action'.
Again, these are defined in XML.
Think of it from a resourceful routing perspective, and it makes a bit more sense. So in the project module, you have projects that have tasks. So you would expect routes like:
- /project
- /project/:id
- /project/:id/task
- /project/:project_id/task/:task_id
etc. So each resource has an index page where you can view a list of the items, then you can have an id based page where you can view an individual item. Then if this was a REST API you'd have the possibility to post to the /project endpoint to create a new project and so forth. In a server-side templated system (like Rails), you get served up a new form, and a show form, and an edit form based on different routes.
So to map this thinking onto Odoo actions, the following rules apply:
- Your action has to be attached to a particular model (i.e. entity).
- You can alter how you view this model by changing the view_type.
- To view a list of items (i.e. an index page) the view_type is actually called "tree". (Why is this? I have no idea)
- To view a single item, the view_type is called "form". Form is used to both create new instances of the model, as well as view and edit existing ones.
So for example, you could have it that when you click on the "My Tasks" menu, that it opens up a list of tasks (i.e. a "tree" view of the "project.task" model).
There, I just saved you 2 hours of wondering what the heck "actions" are and how they work.
You can also have other ways of viewing data in Odoo, for example "kanban" is another way of looking at the index page. A full list of these types is on the Odoo docs.
You can also create custom a view_type, but that is a much more advanced topic that I will cover elsewhere.
So this, in my mind, is where Odoo really shines. Instead of having to create a bunch of routes, build forms for your model and so forth. You have a bunch of pre-built "actions", that handle all that for you. You get data entry forms, searchable index page, all of that, for free. You just need a bit of XML and you are there.
Views
So even though you have the basic scaffolding of all these standard views (like tree and form). These can be customised somewhat.
So again, you can define an XML document that tells Odoo how to render your objects on the screen. So you might have a model with 20 attributes, which ones get rendered in the list (i.e. tree) view on your resource index page?
You can simply list them out in the XML "View".
Access Control
Another place you can get tripped up, is forgetting to set the security settings for each model in your module.
Basically every time you add a model, you need to set the access to it. This is quite nice because you can do things like, have certain configuration settings that only admins can change, or have some models that certain user groups can edit and others can only view.
So you can enforce your business domain rules in the security section. The only thing I would comment is that the CSV format is a bit unwieldy.
Summary
Ok so that's basically it. You can create entities (i.e. models), define the fields and relations between them, then define your menu options, and configure what screens are available to your users and who has access to them.
Your basic screens that you get out of the box are the normal CRUD type of views that you would want in any app.
To translate your thinking to Odoo you just have to become familiar with the terminology and approach that they uses.