Skip to main content

Create a Custom Model and Its View in Odoo

In this snippet, we will discuss how to create a custom model and its views in Odoo.

Models are used to represent the business data in Odoo. The models are defined in Python classes. Each model represents a table in the database. In order to create a model, we need to inherit our class from models.Model.

Views are used to define the user interface of the model. Views are defined in XML files. Each view represents a window or a page in the user interface.

Let’s take an example to understand how to create a custom model and its view in Odoo.

Model

from odoo import models, fields, api, _
class Payroll(models.Model):
    _name = 'custom.payroll'
    _description = 'Payroll'

    name = fields.Char(string="Number", readonly=True, copy=False, default='New')

    state = fields.Selection([
        ('draft', 'Draft'),
        ('verify', 'Waiting'),
        ('done', 'Done'),
        ('cancel', 'Rejected'),
    ], string='Status', index=True, readonly=True, copy=False, default='draft')

    @api.model
    def create(self, vals):
        if vals.get('name', 'New') == 'New':
            vals['name'] = self.env['ir.sequence'].next_by_code('salary.number') or 'New'
        result = super(Payroll, self).create(vals)
        return result

Views (views.xml)

<odoo>
    <data>

        <record id="custom_payroll_tree" model="ir.ui.view">
            <field name="name">custom.payroll.tree</field>
            <field name="model">custom.payroll</field>
            <field name="arch" type="xml">
                <tree string="Payrolls">
                    <field name="name"/>
                </tree>
            </field>
        </record>

        <record id="custom_payroll_form_view" model="ir.ui.view">
            <field name="name">custom.payroll.form</field>
            <field name="model">custom.payroll</field>
            <field name="arch" type="xml">
                <form string="Payroll">
                    <sheet>
                        <group>
                            <field name="name"/>
                        </group>
                    </sheet>
                </form>
            </field>
        </record>


        <!-- Salaray Sequence -->
        <record id="sequence_salary_number" model="ir.sequence">
            <field name="name">Salary Number</field>
            <field name="code">salary.number</field>
            <field name="active">TRUE</field>
            <field name="prefix">SLIP/%(year)s/</field>
            <field name="padding">5</field>
            <field name="number_next">1</field>
            <field name="number_increment">1</field>
        </record>

       <!-- we will add the Payroll module to Invoice menu items instead of creatign its own section -->
       <record id="action_payrolls" model="ir.actions.act_window">
            <field name="name">Payrolls</field>
            <field name="res_model">custom.payroll</field>
            <field name="view_mode">tree,form</field>
            <field name="view_type">form</field>
            <field name="target">inline</field>
            <field name="view_id" ref="custom_payroll_tree"/>
        </record>
        <menuitem id="menu_payrolls_parent" name="Paryolls" parent="account.menu_finance" sequence="100"/>
        <menuitem id="menu_payrolls" name="Paryolls" action="action_payrolls" parent="menu_payrolls_parent" sequence="0"/>

    </data>
</odoo>

Security (ir.model.access.csv)

id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
custom_payroll_manager,custom.payroll.manager,model_custom_payroll,base.group_user,1,1,1,1

Menu


Manifest

# -*- coding: utf-8 -*-
{
    'name': "Custom Payroll",

    'summary': """
        Payroll
    """,

    'description': """
        Payroll
    """,

    'author': "TLe Apps",
    'website': "https://tleapps.com",
    'category': 'Uncategorized',
    'version': '1.0.0',

    # any module necessary for this one to work correctly
    'depends': ['base','account'],

    # always loaded
    'data': [
        'security/ir.model.access.csv',
        'views/views.xml',
    ],
    'images': ['static/description/icon.png'],
}

By continuing to use the site, you agree to the use of cookies.