How to get Odoo selection field labels with translation

Inside Model

    def _get_selections_label(self, field):
        return self._fields[field].get_description(self.env).get('selection')

    def _get_selection_label(self, field):
        return dict(self._get_selections_label(field)).get(getattr(self, field))

Inside template

<span t-out="object._get_selection_label('field')"/>

Odoo string domain to python domain

import ast

# String domain
domain_str = "[('field_name', '=', 'field_value')]"

# Convert string to domain
converted_domain = ast.literal_eval(domain_str)

print("Original domain:", domain_str, type(domain_str))
print("Converted domain:", converted_domain, type(converted_domain))

How to reuse model field selection choices in Odoo?

We will increase the available choices of a model and reuse those new choices in another model

class FleetVehicleModel(models.Model):
    _inherit = 'fleet.vehicle.model'

    vehicle_type = fields.Selection(selection_add=VEHICLE_TYPE,
        ondelete={'truck': 'set default', 'dredge': 'set default', 'bus': 'set default', 'micro_bus': 'set default'})

by default the vehicle type has car and bike choices and with the previous code it will have the new defined choices and the default ones.

class FleetVehicle(models.Model):
    _inherit = 'fleet.vehicle'

    def _selection_vehicle_type(self):
        return self.env['fleet.vehicle.model']._columns['vehicle_type'].selection

    vehicle_type = fields.Selection(_selection_vehicle_type, required=True)

Odoo 16 model creation guideline

  • Method conventions
    • Compute Field : the compute method pattern is _compute_<field_name>
    • Search method : the search method pattern is _search_<field_name>
    • Default method : the default method pattern is _default_<field_name>
    • Selection method: the selection method pattern is _selection_<field_name>
    • Onchange method : the onchange method pattern is _onchange_<field_name>
    • Constraint method : the constraint method pattern is _check_<constraint_name>
    • Action method : an object action method is prefix with action_. Since it uses only one record, add self.ensure_one() at the beginning of the method.
  • In a Model attribute order should be
    1. Private attributes (_name_description_inherit_sql_constraints, …)
    2. Default method and default_get
    3. Field declarations
    4. Compute, inverse and search methods in the same order as field declaration
    5. Selection method (methods used to return computed values for selection fields)
    6. Constrains methods (@api.constrains) and onchange methods (@api.onchange)
    7. CRUD methods (ORM overrides)
    8. Action methods
    9. And finally, other business methods.
class Event(models.Model):
    # Private attributes
    _name = 'event.event'
    _description = 'Event'

    # Default methods
    def _default_name(self):
        ...

    # Fields declaration
    name = fields.Char(string='Name', default=_default_name)
    seats_reserved = fields.Integer(string='Reserved Seats', store=True
        readonly=True, compute='_compute_seats')
    seats_available = fields.Integer(string='Available Seats', store=True
        readonly=True, compute='_compute_seats')
    price = fields.Integer(string='Price')
    event_type = fields.Selection(string="Type", selection='_selection_type')

    # compute and search fields, in the same order of fields declaration
    @api.depends('seats_max', 'registration_ids.state', 'registration_ids.nb_register')
    def _compute_seats(self):
        ...

    @api.model
    def _selection_type(self):
        return []

    # Constraints and onchanges
    @api.constrains('seats_max', 'seats_available')
    def _check_seats_limit(self):
        ...

    @api.onchange('date_begin')
    def _onchange_date_begin(self):
        ...

    # CRUD methods (and name_get, name_search, ...) overrides
    def create(self, values):
        ...

    # Action methods
    def action_validate(self):
        self.ensure_one()
        ...

    # Business methods
    def mail_user_confirm(self):
        ...

How to open gnome terminal from a cron job in Linux?

Open your user cron jobs using

crontab -e

Once inside your cron jobs insert the following at the bottom

00 * * * * env DISPLAY=:0 /usr/bin/dbus-launch /usr/bin/gnome-terminal

This will execute every hour at 00 minutes. Notice the full path for the dbus-launch and gnome-terminal

the env DISPLAY=:0 is to properly link the UI with the cron. The value :0 may vary so to make sure what value to use execute

echo $DISPLAY

Docker Main commands

#Pull image
docker pull image:version
#example 
docker pull nginx:1.22
#view all docker images
docker images
#start your Docker container
docker run -d -p 8080:80 --name <container-name> <image-name>
#example
docker run -d -p 8080:80 --name nginx-container nginx
# --name set containers name
# -p maps the ports of container
# -d detach from console
#view running container
docker ps
#display all containers running or not
docker ps -a
# start container
docker start <container-name>
# stop container
docker stop <container-name>
#build custom image from Docker file
touch Dockerfile
# Edit content with
FROM nginx:latest
COPY ./index.html /usr/share/nginx/html/index.html
#build command
docker build -t <image-name> .
#check image
docker images
#start your Docker container
docker run -d -p 8080:80 --name <container-name> <image-name>
#remove container
docker rm <id or name>
#remove image
docker image rm <id or name>
#list volume
docker volume ls
#remove volume
docker volume rm <name>

Docker resources that are dangling (not tagged or associated with a container):

docker system prune

Remove any stopped containers and all unused images:

docker system prune -a

How to prevent recreation of xml record data in Odoo

<odoo>
    <data noupdate="1">
        
        <record id="planning_full_organizer_manager_role" forcecreate="0" model="res.users.role">
            <field name="name">Full Organizer Manager Role</field>            
        </record>
        
    </data>
</odoo>

<odoo noupdate="1">
<!--        <delete search="[('id','=',ref('planning_event_app.planning_stock_client_manager_role'))]"-->
<!--                model='res.users.role'/>-->
        <delete search="[('id','=',ref('planning_event_app.planning_full_organizer_manager_role'))]"
                model='res.users.role'/>
</odoo>

Even while having noupdate = 1 if the record gets deleted using another xml data odoo will recreate the record. To prevent this behavior of recreation must use the attribute forcecreate=0 as shown previously.