How I Create Smart Button [Odoo]

That refers to filtered records

Amirul M.
3 min readMay 18, 2020
Photo by Juan Gomez on Unsplash

There are two easy ways to create Smart Button in Odoo. Object type and Action type. The difference is just the place of the logic code will be written. This button is created to call records of selected database table from the current place. Also when I call it, I can filter the records so the shown list will be just the one that accept a few condition.

Smart button is located in the top-right form Odoo.

Object Type

First, follow the existing template, I create button tag with open_patient_appointment name inside div. This button is placed in Patient model to call all appointments that related to current patient. This code is placed inside Form > Sheet tag.

<div class="oe_button_box" name="button_box">
<button name="open_patient_appointment"
type="object" class="oe_stat_button" icon="fa-calendar">
<field name="appointment_count" string="Appointment" widget="statinfo"/>
</button>
</div>

Then, create a method with the same name that return to hospital.appointment model in Patient python file. And fill the domain with a condition to filter the records.

@api.multi
def open_patient_appointment(self):
return {
'name': 'Appointment',
'domain': [('patient_id', '=', self.id)],
'view_type': 'form',
'res_model': 'hospital.appointment',
'view_id': False,
'view_mode': 'tree,form',
'type': 'ir.actions.act_window'
}

Action Type

For Action type button, all of these code will be written in views file. Almost close to the object type, button tag created with open_patient_appointment name attribute that wrap around these symbol: %( and )d .

<div class="oe_button_box" name="button_box">
<button name="%(open_patient_appointment)d"
type="action" class="oe_stat_button" icon="fa-calendar">
<field name="appointment_count" string="Appointment" widget="statinfo"/>
</button>
</div>

Then, write new record tag that refers to the same id and the same domain condition.

<record id="open_patient_appointment" model="ir.ui.view">
<field name="name">Appointments</field>
<field name="res_model">hospital.patient</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('patient_id', '=', active_id)]</field>
<field name="context">{}</field>
</record>

When you see the code above, I bold appointment_count field because it will compute on how many appointment records that related with current patient. That’s why search_count inside get_appointment_count method is fill with the same previous domain condition (or the same patient id).

def get_appointment_count(self):
count = self.env['hospital.appointment'].search_count([('patient_id', '=', self.id)])
self.appointment_count = count
appointment_count = fields.Integer(string='Appointment', compute='get_appointment_count')

Domain

In the prior paragraphs, I often call domain term. What is it?

Domain in Odoo is used to select the matched records from a Model in many different places. This can be write based on one condition, two conditions, or more. One condition I’ve been shown above. For two matched conditions, I have to write a logical operator in front of another two operators. And for multiple condition I explain with a simple syntax.

[operator1,
operator2,
[condition1],
[condition2],
operator3,
[condition3],
[condition4]
]

Operator1, 2, and 3 can be filled with logical operator like ‘|’ for or statements, ‘&’ for and statements, and etc. Operator2 is used for condition1 and condition2. Operator3 for condition3 and condition4. And operator1 for results of previous two operators.

For condition, it can be formed from a relational operator, membership operator, or other operator. I can give you this example of two conditions for better understanding.

['|',
['location_origin', '=', True],
['state', 'in', ('draft,'ready')]
]

The Last

For now, I write stories about main concept in Odoo development. What concepts I will explain in the next stories? It’s up to me because there are no specific requests. So if you want to know a specific part of Odoo, don’t be hesitate to reply.

--

--