SlideShare a Scribd company logo
Tutorial: Develop an App with the Odoo Framework
Use case:
Plant Nursery
— Classy Cool Dev
Thanks Classy Cool Dev!
But, how can
you be so sure
Odoo is the
perfect
choice?
Architecture
● Three-tier client/server/database
Three-tier
● Presentation Layer (Client):
HTML5, JavaScript, CSS
● Application Layer (Server):
Python3
● Data Layer (Database):
PostgreSQL
Architecture
● Webclient in Javascript
Architecture
● Server and backend modules in Python
○ MVC framework
MVC framework
● Model: Data logic
● View: UI logic
● Controller: Interface
Architecture
● Server and backend modules in Python
○ ORM to interact with database
ORM:
Bridges the gap
between python
and postgreSQL.
class MyAwesomeCharacter(models.Model):
_name = 'my.awesome.character'
name = fields.Char(string="name",
required=True)
friend =
fields.Many2one('my.awesome.character',
string='Best Friend')
Model definition:
ORM
Table definition:
ORM Pros
● Less SQL
● Abstracts the DB
● Advanced features (cache, security, …)
● Better SQL queries
ORM Cons
● Performance (?)
● Training
● Initial config
● Less deep understanding
The Feature
Manage a plant nursery:
● List of plants
● Manage orders
● Keep a customers list
Technically
you will learn:
● Structure of a module
● Definition of data models
● Definition of views and menus
An Odoo module is:
● A manifest file
● Python code (models, logic)
● Data files, XML and CSV (base data, views, menus)
● Frontend resources (Javascript, CSS)
Plant
Nursery
The manifest file:
__manifest__.py
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and
licensing details.
{
'name': 'Plant Nursery',
'version': '1.0',
'category': 'Tools',
'summary': 'Plants and customers management',
'depends': ['web'],
'data': [
'security/ir.model.access.csv',
'data/data.xml',
'views/views.xml',
],
'demo': [
'data/demo.xml',
],
'css': [],
'installable': True,
'auto_install': False,
'application': True,
}
Describe the
models
plant_nursery/models.p
y
from odoo import fields, models
class Plants(models.Model):
_name = 'nursery.plant'
name = fields.Char("Plant Name")
price = fields.Float()
class Customer(models.Model):
_name = 'nursery.customer'
name = fields.Char("Customer Name", required=True)
email = fields.Char(help="To receive the newsletter")
Define the security
plant_nursery/security/ir.model.access.csv
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_nursery_plant,access_nursery_plant,plant_nursery.model_nursery_plant,base.group_user,1,1,1,1
access_nursery_customer,access_nursery_customer,plant_nursery.model_nursery_customer,base.group_user,
1,1,1,1
Define the
action
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record model="ir.actions.act_window"
id="action_nursery_plant">
<field name="name">Plants</field>
<field name="res_model">nursery.plant</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem name="Plant Nursery"
id="nursery_root_menu"
web_icon="plant_nursery,static/description/icon.png"/
>
<menuitem name="Plants" id="nursery_plant_menu"
parent="nursery_root_menu"
action="action_nursery_plant"
sequence="1"/>
</odoo>
plant_nursery/views/nursery_views.xml
Tutorial: Develop an App with the Odoo Framework
Define a form view
plant_nursery/views/nursery_views.xml
<record model="ir.ui.view" id="nursery_plant_view_form">
<field name="name">nursery.plant.view.form</field>
<field name="model">nursery.plant</field>
<field name="arch" type="xml">
<form string="Plant">
<sheet>
<h1>
<field name="name" placeholder="Plant Name"/>
</h1>
<notebook>
<page string="Shop">
<group>
<field name="price"/>
</group>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
Auto generated views
Relations:
● Many2one
● One2many
● Many2many
Relations
class Order(models.Model):
_name = 'nursery.order'
plant_id = fields.Many2one("nursery.plant", required=True)
customer_id = fields.Many2one("nursery.customer")
class Plants(models.Model):
_name = 'nursery.plant'
order_ids = fields.One2many("nursery.order", "plant_id", string="Orders")
Auto generated views
Basic Operations:
● Read
● Write
● Create
● Unlink
● Search
ORM Interactions
class Order(models.Model):
_name = 'nursery.order'
name = fields.Datetime(default=fields.Datetime.now)
plant_id = fields.Many2one("nursery.plant", required=True)
customer_id = fields.Many2one("nursery.customer")
state = fields.Selection([
('draft', 'Draft'),
('confirm', 'Confirmed'),
('cancel', 'Canceled')
], default='draft')
last_modification = fields.Datetime(readonly=True)
ORM Interactionsclass Order(model.Models):
_name = 'nursery.order'
def write(self, values):
# helper to "YYYY-MM-DD"
values['last_modification'] = fields.Datetime.now()
return super(Order, self).write(values)
def unlink(self):
# self is a recordset
for order in self:
if order.state == 'confirm':
raise UserError("You can not delete confirmed orders")
return super(Order, self).unlink()
ORM Interactions
<record model="ir.ui.view" id="nursery_order_form">
<field name="name">Order Form View</field>
<field name="model">nursery.order</field>
<field name="arch" type="xml">
<form string="Plant Order">
<header>
<field name="state" widget="statusbar" options="{'clickable': '1'}"/>
</header>
<sheet>
<group col="4">
<group colspan="2">
<field name="plant_id" />
<field name="customer_id" />
</group>
<group colspan="2">
<field name="last_modification" />
</group>
</group>
</sheet>
</form>
</field>
</record>
Auto generated views
— Classy Cool Dev
Thanks Classy Cool Dev!
What else
could you
show us?
Computed Fields:
● For complex values
● Trigger for recompute
● Stored or not in the
database
Computed Fields
class Plants(models.Model):
_name = 'nursery.plant'
order_count = fields.Integer(compute='_compute_order_count',
store=True,
string="Total sold")
@api.depends('order_ids')
def _compute_order_count(self):
for plant in self:
plant.order_count = len(plant.order_ids)
Model Constraints
● Triggered after every creation or
modification.
● Instead of overriding create & write
Model Constraints
class Plants(models.Model):
_name = 'nursery.plant'
number_in_stock = fields.Integer()
@api.constrains('order_count', 'number_in_stock')
def _check_available_in_stock(self):
for plant in self:
if plant.number_in_stock and 
plant.order_count > plant.number_in_stock:
raise UserError("There is only %s %s in stock but %s were sold"
% (plant.number_in_stock, plant.name, plant.order_count))
Kanban View:
● Display information
● Add pictures
● Aggregated view
Define a Kanban View:
class Plants(models.Model):
_name = 'nursery.plant'
image = fields.Binary("Plant Image", attachment=True)
<record model="ir.actions.act_window"
id="action_nursery_order">
<field name="name">Orders</field>
<field name="res_model">nursery.order</field>
<field name="view_mode">kanban,tree,form</field>
</record>
<record id="nursery_plant_view_kanban" model="ir.ui.view">
<field name="name">nursery.plant.view.kanban</field>
<field name="model">nursery.plant</field>
<field name="arch" type="xml">
<kanban>
<field name="id"/>
<field name="image"/>
<templates>
<t t-name="kanban-box">
<div class="oe_kanban_global_click">
<div class="o_kanban_image">
<img t-att-src="kanban_image('nursery.plant', 'image', record.id.raw_value)"/>
</div>
<div class="oe_kanban_details">
<strong class="o_kanban_record_title"><field name="name"/></strong>
<ul><li><strong>Price: <field name="price"></field></strong></li</ul>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
Define a Kanban View:
Auto generated views
Auto generated views
Define a Search View:
<record id="nursery_order_view_search" model="ir.ui.view">
<field name="name">nursery.order.view.search</field>
<field name="model">nursery.order</field>
<field name="arch" type="xml">
<search string="Search Orders">
<field name="plant_id" string="Plant"/>
<field name="customer_id" string="Customer"/>
<field name="state"/>
<filter string="Confirmed" name="confirmed"
domain="[('state', '=', 'confirm')]"/>
<separator />
<group expand="0" string="Group By">
<filter string="State" name="group_by_state"
domain="[]" context="{'group_by':'state'}"/>
</group>
</search>
</field>
</record>
Display all the states
class Order(models.Model):
_name = 'nursery.order'
state = fields.Selection([
('draft', 'Draft'),
('confirm', 'Confirmed'),
('cancel', 'Canceled')
], default='draft', group_expand="_expand_states")
def _expand_states(self, states, domain, order):
return [key for key, val in
type(self).state.selection]
Always group by state:
<record model="ir.actions.act_window"
id="action_nursery_order">
<field name="name">Orders</field>
<field name="res_model">nursery.order</field>
<field name="view_mode">kanban,tree,form</field>
<field
name="context">{'search_default_group_by_state': 1}</field>
</record>
Auto generated views
Onchange methods:
class Customer(models.Model):
_name = 'nursery.customer'
_description = 'Nursery Customer'
name = fields.Char('Customer Name', required=True)
email = fields.Char(help="To receive the newsletter")
mobile = fields.Char('Mobile')
image = fields.Binary('Photo', attachment=True)
address = fields.Char('Address')
country_id = fields.Many2one('res.country',
string='Country')
partner_id = fields.Many2one('res.partner',
string='Customer Address')
Onchange methods:
@api.onchange('partner_id')
def _onchange_partner_id(self):
if self.partner_id:
if self.partner_id.image_1920:
self.image = self.partner_id.image_1920
if self.partner_id.email:
self.email = self.partner_id.email
if self.partner_id.mobile:
self.mobile = self.partner_id.mobile
if self.partner_id.country_id:
self.country_id = self.partner_id.country_id.id
if not self.address:
self.address =
self.partner_id.with_context(show_address_only=True)._get_name()
Auto generated views
Sequences
<!-- Sequences for plant.orders -->
<record id="seq_plant_order" model="ir.sequence">
<field name="name">Plant Orders</field>
<field name="code">plant.order</field>
<field name="prefix">Order</field>
<field name="padding">3</field>
<field name="company_id" eval="False"/>
</record>
Sequences
@api.model
def create(self, vals):
if vals.get('name', _('New')) == _('New'):
if 'company_id' in vals:
vals['name'] = self.env['ir.sequence'].with_context(
force_company=vals['company_id']
).next_by_code('plant.order') or _('New')
else:
vals['name'] =
self.env['ir.sequence'].next_by_code('plant.order') or _('New')
return super(Order, self).create(vals)
Tutorial: Develop an App with the Odoo Framework
Thank You
https://github.com/tivisse/odoodays-
2020
Ad

More Related Content

What's hot (20)

The Odoo JS Framework
The Odoo JS FrameworkThe Odoo JS Framework
The Odoo JS Framework
Odoo
 
What is context? How to use context in Odoo by weblearns
What is context? How to use context in Odoo by weblearnsWhat is context? How to use context in Odoo by weblearns
What is context? How to use context in Odoo by weblearns
Web Learns
 
How to Use Constraint and SQL Constraint in Odoo 15
How to Use Constraint and SQL Constraint in Odoo 15How to Use Constraint and SQL Constraint in Odoo 15
How to Use Constraint and SQL Constraint in Odoo 15
Celine George
 
Odoo - Open chatter integration
Odoo - Open chatter integrationOdoo - Open chatter integration
Odoo - Open chatter integration
Odoo
 
Query all roles and duties and privileges Oracle Fusion Cloud
Query all roles and duties and privileges Oracle Fusion CloudQuery all roles and duties and privileges Oracle Fusion Cloud
Query all roles and duties and privileges Oracle Fusion Cloud
Feras Ahmad
 
Odoo's Test Framework - Learn Best Practices
Odoo's Test Framework - Learn Best PracticesOdoo's Test Framework - Learn Best Practices
Odoo's Test Framework - Learn Best Practices
Odoo
 
Query Pre Payment details Oracle Fusion Cloud
Query Pre Payment details Oracle Fusion CloudQuery Pre Payment details Oracle Fusion Cloud
Query Pre Payment details Oracle Fusion Cloud
Feras Ahmad
 
Odoo (Build module, Security, ORM)
Odoo (Build module, Security, ORM)Odoo (Build module, Security, ORM)
Odoo (Build module, Security, ORM)
sroo galal
 
URLs and Routing in the Odoo 17 Website App
URLs and Routing in the Odoo 17 Website AppURLs and Routing in the Odoo 17 Website App
URLs and Routing in the Odoo 17 Website App
Celine George
 
Solid NodeJS with TypeScript, Jest & NestJS
Solid NodeJS with TypeScript, Jest & NestJSSolid NodeJS with TypeScript, Jest & NestJS
Solid NodeJS with TypeScript, Jest & NestJS
Rafael Casuso Romate
 
Best Practices in Handling Performance Issues
Best Practices in Handling Performance IssuesBest Practices in Handling Performance Issues
Best Practices in Handling Performance Issues
Odoo
 
ASP.NET MVC Presentation
ASP.NET MVC PresentationASP.NET MVC Presentation
ASP.NET MVC Presentation
ivpol
 
Odoo - Smart buttons
Odoo - Smart buttonsOdoo - Smart buttons
Odoo - Smart buttons
Odoo
 
Basic Views in Odoo 16
Basic Views in Odoo 16Basic Views in Odoo 16
Basic Views in Odoo 16
Celine George
 
Personalization Validate Po Quantity With PR
Personalization Validate Po Quantity With PRPersonalization Validate Po Quantity With PR
Personalization Validate Po Quantity With PR
Ahmed Elshayeb
 
Intro to flask
Intro to flaskIntro to flask
Intro to flask
Mohamed Essam
 
Oracle EBS 12.1.3 : Integrate OA Framework BC4J components within java concur...
Oracle EBS 12.1.3 : Integrate OA Framework BC4J components within java concur...Oracle EBS 12.1.3 : Integrate OA Framework BC4J components within java concur...
Oracle EBS 12.1.3 : Integrate OA Framework BC4J components within java concur...
Amit Singh
 
Django for Beginners
Django for BeginnersDjango for Beginners
Django for Beginners
Jason Davies
 
Oracle Personalization How To Restricting users from assigning items to diffe...
Oracle Personalization How To Restricting users from assigning items to diffe...Oracle Personalization How To Restricting users from assigning items to diffe...
Oracle Personalization How To Restricting users from assigning items to diffe...
Ahmed Elshayeb
 
Local storage
Local storageLocal storage
Local storage
Adam Crabtree
 
The Odoo JS Framework
The Odoo JS FrameworkThe Odoo JS Framework
The Odoo JS Framework
Odoo
 
What is context? How to use context in Odoo by weblearns
What is context? How to use context in Odoo by weblearnsWhat is context? How to use context in Odoo by weblearns
What is context? How to use context in Odoo by weblearns
Web Learns
 
How to Use Constraint and SQL Constraint in Odoo 15
How to Use Constraint and SQL Constraint in Odoo 15How to Use Constraint and SQL Constraint in Odoo 15
How to Use Constraint and SQL Constraint in Odoo 15
Celine George
 
Odoo - Open chatter integration
Odoo - Open chatter integrationOdoo - Open chatter integration
Odoo - Open chatter integration
Odoo
 
Query all roles and duties and privileges Oracle Fusion Cloud
Query all roles and duties and privileges Oracle Fusion CloudQuery all roles and duties and privileges Oracle Fusion Cloud
Query all roles and duties and privileges Oracle Fusion Cloud
Feras Ahmad
 
Odoo's Test Framework - Learn Best Practices
Odoo's Test Framework - Learn Best PracticesOdoo's Test Framework - Learn Best Practices
Odoo's Test Framework - Learn Best Practices
Odoo
 
Query Pre Payment details Oracle Fusion Cloud
Query Pre Payment details Oracle Fusion CloudQuery Pre Payment details Oracle Fusion Cloud
Query Pre Payment details Oracle Fusion Cloud
Feras Ahmad
 
Odoo (Build module, Security, ORM)
Odoo (Build module, Security, ORM)Odoo (Build module, Security, ORM)
Odoo (Build module, Security, ORM)
sroo galal
 
URLs and Routing in the Odoo 17 Website App
URLs and Routing in the Odoo 17 Website AppURLs and Routing in the Odoo 17 Website App
URLs and Routing in the Odoo 17 Website App
Celine George
 
Solid NodeJS with TypeScript, Jest & NestJS
Solid NodeJS with TypeScript, Jest & NestJSSolid NodeJS with TypeScript, Jest & NestJS
Solid NodeJS with TypeScript, Jest & NestJS
Rafael Casuso Romate
 
Best Practices in Handling Performance Issues
Best Practices in Handling Performance IssuesBest Practices in Handling Performance Issues
Best Practices in Handling Performance Issues
Odoo
 
ASP.NET MVC Presentation
ASP.NET MVC PresentationASP.NET MVC Presentation
ASP.NET MVC Presentation
ivpol
 
Odoo - Smart buttons
Odoo - Smart buttonsOdoo - Smart buttons
Odoo - Smart buttons
Odoo
 
Basic Views in Odoo 16
Basic Views in Odoo 16Basic Views in Odoo 16
Basic Views in Odoo 16
Celine George
 
Personalization Validate Po Quantity With PR
Personalization Validate Po Quantity With PRPersonalization Validate Po Quantity With PR
Personalization Validate Po Quantity With PR
Ahmed Elshayeb
 
Oracle EBS 12.1.3 : Integrate OA Framework BC4J components within java concur...
Oracle EBS 12.1.3 : Integrate OA Framework BC4J components within java concur...Oracle EBS 12.1.3 : Integrate OA Framework BC4J components within java concur...
Oracle EBS 12.1.3 : Integrate OA Framework BC4J components within java concur...
Amit Singh
 
Django for Beginners
Django for BeginnersDjango for Beginners
Django for Beginners
Jason Davies
 
Oracle Personalization How To Restricting users from assigning items to diffe...
Oracle Personalization How To Restricting users from assigning items to diffe...Oracle Personalization How To Restricting users from assigning items to diffe...
Oracle Personalization How To Restricting users from assigning items to diffe...
Ahmed Elshayeb
 

Similar to Tutorial: Develop an App with the Odoo Framework (20)

Odoo Experience 2018 - Develop an App with the Odoo Framework
Odoo Experience 2018 - Develop an App with the Odoo FrameworkOdoo Experience 2018 - Develop an App with the Odoo Framework
Odoo Experience 2018 - Develop an App with the Odoo Framework
ElínAnna Jónasdóttir
 
Develop an App with the Odoo Framework
Develop an App with the Odoo FrameworkDevelop an App with the Odoo Framework
Develop an App with the Odoo Framework
Odoo
 
Database population in Odoo 18 - Odoo slides
Database population in Odoo 18 - Odoo slidesDatabase population in Odoo 18 - Odoo slides
Database population in Odoo 18 - Odoo slides
Celine George
 
Django design-patterns
Django design-patternsDjango design-patterns
Django design-patterns
Agiliq Info Solutions India Pvt Ltd
 
RubyOnRails-Cheatsheet-BlaineKendall
RubyOnRails-Cheatsheet-BlaineKendallRubyOnRails-Cheatsheet-BlaineKendall
RubyOnRails-Cheatsheet-BlaineKendall
tutorialsruby
 
RubyOnRails-Cheatsheet-BlaineKendall
RubyOnRails-Cheatsheet-BlaineKendallRubyOnRails-Cheatsheet-BlaineKendall
RubyOnRails-Cheatsheet-BlaineKendall
tutorialsruby
 
Ajax nested form and ajax upload in rails
Ajax nested form and ajax upload in railsAjax nested form and ajax upload in rails
Ajax nested form and ajax upload in rails
Tse-Ching Ho
 
날로 먹는 Django admin 활용
날로 먹는 Django admin 활용날로 먹는 Django admin 활용
날로 먹는 Django admin 활용
KyeongMook "Kay" Cha
 
ADO.NET Entity Framework by Jose A. Blakeley and Michael Pizzo
ADO.NET Entity Framework by Jose A. Blakeley and Michael PizzoADO.NET Entity Framework by Jose A. Blakeley and Michael Pizzo
ADO.NET Entity Framework by Jose A. Blakeley and Michael Pizzo
Hasnain Iqbal
 
Active record(1)
Active record(1)Active record(1)
Active record(1)
Ananta Lamichhane
 
Java Web Development with Stripes
Java Web Development with StripesJava Web Development with Stripes
Java Web Development with Stripes
Samuel Santos
 
How to disassemble one monster app into an ecosystem of 30
How to disassemble one monster app into an ecosystem of 30How to disassemble one monster app into an ecosystem of 30
How to disassemble one monster app into an ecosystem of 30
fiyuer
 
Connecting your Python App to OpenERP through OOOP
Connecting your Python App to OpenERP through OOOPConnecting your Python App to OpenERP through OOOP
Connecting your Python App to OpenERP through OOOP
raimonesteve
 
Stripes Framework
Stripes FrameworkStripes Framework
Stripes Framework
Johannes Carlén
 
Tips On Trick Odoo Add-On.pptx
Tips On Trick Odoo Add-On.pptxTips On Trick Odoo Add-On.pptx
Tips On Trick Odoo Add-On.pptx
Agusto Sipahutar
 
Default Group By Expand Option In Odoo 17
Default Group By Expand Option In Odoo 17Default Group By Expand Option In Odoo 17
Default Group By Expand Option In Odoo 17
Celine George
 
Django
DjangoDjango
Django
Mohamed Ramadan
 
How to Show Sample Data in Tree and Kanban View in Odoo 17
How to Show Sample Data in Tree and Kanban View in Odoo 17How to Show Sample Data in Tree and Kanban View in Odoo 17
How to Show Sample Data in Tree and Kanban View in Odoo 17
Celine George
 
Odoo Experience 2018 - From a Web Controller to a Full CMS
Odoo Experience 2018 - From a Web Controller to a Full CMSOdoo Experience 2018 - From a Web Controller to a Full CMS
Odoo Experience 2018 - From a Web Controller to a Full CMS
ElínAnna Jónasdóttir
 
Optimization in django orm
Optimization in django ormOptimization in django orm
Optimization in django orm
Denys Levchenko
 
Odoo Experience 2018 - Develop an App with the Odoo Framework
Odoo Experience 2018 - Develop an App with the Odoo FrameworkOdoo Experience 2018 - Develop an App with the Odoo Framework
Odoo Experience 2018 - Develop an App with the Odoo Framework
ElínAnna Jónasdóttir
 
Develop an App with the Odoo Framework
Develop an App with the Odoo FrameworkDevelop an App with the Odoo Framework
Develop an App with the Odoo Framework
Odoo
 
Database population in Odoo 18 - Odoo slides
Database population in Odoo 18 - Odoo slidesDatabase population in Odoo 18 - Odoo slides
Database population in Odoo 18 - Odoo slides
Celine George
 
RubyOnRails-Cheatsheet-BlaineKendall
RubyOnRails-Cheatsheet-BlaineKendallRubyOnRails-Cheatsheet-BlaineKendall
RubyOnRails-Cheatsheet-BlaineKendall
tutorialsruby
 
RubyOnRails-Cheatsheet-BlaineKendall
RubyOnRails-Cheatsheet-BlaineKendallRubyOnRails-Cheatsheet-BlaineKendall
RubyOnRails-Cheatsheet-BlaineKendall
tutorialsruby
 
Ajax nested form and ajax upload in rails
Ajax nested form and ajax upload in railsAjax nested form and ajax upload in rails
Ajax nested form and ajax upload in rails
Tse-Ching Ho
 
날로 먹는 Django admin 활용
날로 먹는 Django admin 활용날로 먹는 Django admin 활용
날로 먹는 Django admin 활용
KyeongMook "Kay" Cha
 
ADO.NET Entity Framework by Jose A. Blakeley and Michael Pizzo
ADO.NET Entity Framework by Jose A. Blakeley and Michael PizzoADO.NET Entity Framework by Jose A. Blakeley and Michael Pizzo
ADO.NET Entity Framework by Jose A. Blakeley and Michael Pizzo
Hasnain Iqbal
 
Java Web Development with Stripes
Java Web Development with StripesJava Web Development with Stripes
Java Web Development with Stripes
Samuel Santos
 
How to disassemble one monster app into an ecosystem of 30
How to disassemble one monster app into an ecosystem of 30How to disassemble one monster app into an ecosystem of 30
How to disassemble one monster app into an ecosystem of 30
fiyuer
 
Connecting your Python App to OpenERP through OOOP
Connecting your Python App to OpenERP through OOOPConnecting your Python App to OpenERP through OOOP
Connecting your Python App to OpenERP through OOOP
raimonesteve
 
Tips On Trick Odoo Add-On.pptx
Tips On Trick Odoo Add-On.pptxTips On Trick Odoo Add-On.pptx
Tips On Trick Odoo Add-On.pptx
Agusto Sipahutar
 
Default Group By Expand Option In Odoo 17
Default Group By Expand Option In Odoo 17Default Group By Expand Option In Odoo 17
Default Group By Expand Option In Odoo 17
Celine George
 
How to Show Sample Data in Tree and Kanban View in Odoo 17
How to Show Sample Data in Tree and Kanban View in Odoo 17How to Show Sample Data in Tree and Kanban View in Odoo 17
How to Show Sample Data in Tree and Kanban View in Odoo 17
Celine George
 
Odoo Experience 2018 - From a Web Controller to a Full CMS
Odoo Experience 2018 - From a Web Controller to a Full CMSOdoo Experience 2018 - From a Web Controller to a Full CMS
Odoo Experience 2018 - From a Web Controller to a Full CMS
ElínAnna Jónasdóttir
 
Optimization in django orm
Optimization in django ormOptimization in django orm
Optimization in django orm
Denys Levchenko
 
Ad

More from Odoo (20)

Timesheet Workshop: The Timesheet App People Love!
Timesheet Workshop: The Timesheet App People Love!Timesheet Workshop: The Timesheet App People Love!
Timesheet Workshop: The Timesheet App People Love!
Odoo
 
Odoo 3D Product View with Google Model-Viewer
Odoo 3D Product View with Google Model-ViewerOdoo 3D Product View with Google Model-Viewer
Odoo 3D Product View with Google Model-Viewer
Odoo
 
Keynote - Vision & Strategy
Keynote - Vision & StrategyKeynote - Vision & Strategy
Keynote - Vision & Strategy
Odoo
 
Opening Keynote - Unveilling Odoo 14
Opening Keynote - Unveilling Odoo 14Opening Keynote - Unveilling Odoo 14
Opening Keynote - Unveilling Odoo 14
Odoo
 
Extending Odoo with a Comprehensive Budgeting and Forecasting Capability
Extending Odoo with a Comprehensive Budgeting and Forecasting CapabilityExtending Odoo with a Comprehensive Budgeting and Forecasting Capability
Extending Odoo with a Comprehensive Budgeting and Forecasting Capability
Odoo
 
Managing Multi-channel Selling with Odoo
Managing Multi-channel Selling with OdooManaging Multi-channel Selling with Odoo
Managing Multi-channel Selling with Odoo
Odoo
 
Product Configurator: Advanced Use Case
Product Configurator: Advanced Use CaseProduct Configurator: Advanced Use Case
Product Configurator: Advanced Use Case
Odoo
 
Accounting Automation: How Much Money We Saved and How?
Accounting Automation: How Much Money We Saved and How?Accounting Automation: How Much Money We Saved and How?
Accounting Automation: How Much Money We Saved and How?
Odoo
 
Rock Your Logistics with Advanced Operations
Rock Your Logistics with Advanced OperationsRock Your Logistics with Advanced Operations
Rock Your Logistics with Advanced Operations
Odoo
 
Transition from a cost to a flow-centric organization
Transition from a cost to a flow-centric organizationTransition from a cost to a flow-centric organization
Transition from a cost to a flow-centric organization
Odoo
 
Synchronization: The Supply Chain Response to Overcome the Crisis
Synchronization: The Supply Chain Response to Overcome the CrisisSynchronization: The Supply Chain Response to Overcome the Crisis
Synchronization: The Supply Chain Response to Overcome the Crisis
Odoo
 
Running a University with Odoo
Running a University with OdooRunning a University with Odoo
Running a University with Odoo
Odoo
 
Down Payments on Purchase Orders in Odoo
Down Payments on Purchase Orders in OdooDown Payments on Purchase Orders in Odoo
Down Payments on Purchase Orders in Odoo
Odoo
 
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach foodOdoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
Odoo
 
Migration from Salesforce to Odoo
Migration from Salesforce to OdooMigration from Salesforce to Odoo
Migration from Salesforce to Odoo
Odoo
 
Preventing User Mistakes by Using Machine Learning
Preventing User Mistakes by Using Machine LearningPreventing User Mistakes by Using Machine Learning
Preventing User Mistakes by Using Machine Learning
Odoo
 
Becoming an Odoo Expert: How to Prepare for the Certification
Becoming an Odoo Expert: How to Prepare for the Certification Becoming an Odoo Expert: How to Prepare for the Certification
Becoming an Odoo Expert: How to Prepare for the Certification
Odoo
 
Instant Printing of any Odoo Report or Shipping Label
Instant Printing of any Odoo Report or Shipping LabelInstant Printing of any Odoo Report or Shipping Label
Instant Printing of any Odoo Report or Shipping Label
Odoo
 
How Odoo helped an Organization Grow 3 Fold
How Odoo helped an Organization Grow 3 FoldHow Odoo helped an Organization Grow 3 Fold
How Odoo helped an Organization Grow 3 Fold
Odoo
 
From Shopify to Odoo
From Shopify to OdooFrom Shopify to Odoo
From Shopify to Odoo
Odoo
 
Timesheet Workshop: The Timesheet App People Love!
Timesheet Workshop: The Timesheet App People Love!Timesheet Workshop: The Timesheet App People Love!
Timesheet Workshop: The Timesheet App People Love!
Odoo
 
Odoo 3D Product View with Google Model-Viewer
Odoo 3D Product View with Google Model-ViewerOdoo 3D Product View with Google Model-Viewer
Odoo 3D Product View with Google Model-Viewer
Odoo
 
Keynote - Vision & Strategy
Keynote - Vision & StrategyKeynote - Vision & Strategy
Keynote - Vision & Strategy
Odoo
 
Opening Keynote - Unveilling Odoo 14
Opening Keynote - Unveilling Odoo 14Opening Keynote - Unveilling Odoo 14
Opening Keynote - Unveilling Odoo 14
Odoo
 
Extending Odoo with a Comprehensive Budgeting and Forecasting Capability
Extending Odoo with a Comprehensive Budgeting and Forecasting CapabilityExtending Odoo with a Comprehensive Budgeting and Forecasting Capability
Extending Odoo with a Comprehensive Budgeting and Forecasting Capability
Odoo
 
Managing Multi-channel Selling with Odoo
Managing Multi-channel Selling with OdooManaging Multi-channel Selling with Odoo
Managing Multi-channel Selling with Odoo
Odoo
 
Product Configurator: Advanced Use Case
Product Configurator: Advanced Use CaseProduct Configurator: Advanced Use Case
Product Configurator: Advanced Use Case
Odoo
 
Accounting Automation: How Much Money We Saved and How?
Accounting Automation: How Much Money We Saved and How?Accounting Automation: How Much Money We Saved and How?
Accounting Automation: How Much Money We Saved and How?
Odoo
 
Rock Your Logistics with Advanced Operations
Rock Your Logistics with Advanced OperationsRock Your Logistics with Advanced Operations
Rock Your Logistics with Advanced Operations
Odoo
 
Transition from a cost to a flow-centric organization
Transition from a cost to a flow-centric organizationTransition from a cost to a flow-centric organization
Transition from a cost to a flow-centric organization
Odoo
 
Synchronization: The Supply Chain Response to Overcome the Crisis
Synchronization: The Supply Chain Response to Overcome the CrisisSynchronization: The Supply Chain Response to Overcome the Crisis
Synchronization: The Supply Chain Response to Overcome the Crisis
Odoo
 
Running a University with Odoo
Running a University with OdooRunning a University with Odoo
Running a University with Odoo
Odoo
 
Down Payments on Purchase Orders in Odoo
Down Payments on Purchase Orders in OdooDown Payments on Purchase Orders in Odoo
Down Payments on Purchase Orders in Odoo
Odoo
 
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach foodOdoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
Odoo
 
Migration from Salesforce to Odoo
Migration from Salesforce to OdooMigration from Salesforce to Odoo
Migration from Salesforce to Odoo
Odoo
 
Preventing User Mistakes by Using Machine Learning
Preventing User Mistakes by Using Machine LearningPreventing User Mistakes by Using Machine Learning
Preventing User Mistakes by Using Machine Learning
Odoo
 
Becoming an Odoo Expert: How to Prepare for the Certification
Becoming an Odoo Expert: How to Prepare for the Certification Becoming an Odoo Expert: How to Prepare for the Certification
Becoming an Odoo Expert: How to Prepare for the Certification
Odoo
 
Instant Printing of any Odoo Report or Shipping Label
Instant Printing of any Odoo Report or Shipping LabelInstant Printing of any Odoo Report or Shipping Label
Instant Printing of any Odoo Report or Shipping Label
Odoo
 
How Odoo helped an Organization Grow 3 Fold
How Odoo helped an Organization Grow 3 FoldHow Odoo helped an Organization Grow 3 Fold
How Odoo helped an Organization Grow 3 Fold
Odoo
 
From Shopify to Odoo
From Shopify to OdooFrom Shopify to Odoo
From Shopify to Odoo
Odoo
 
Ad

Recently uploaded (20)

Alec Lawler - A Passion For Building Brand Awareness
Alec Lawler - A Passion For Building Brand AwarenessAlec Lawler - A Passion For Building Brand Awareness
Alec Lawler - A Passion For Building Brand Awareness
Alec Lawler
 
Comments on Cloud Stream Part II Mobile Hub V1 Hub Agency.pdf
Comments on Cloud Stream Part II Mobile Hub V1 Hub Agency.pdfComments on Cloud Stream Part II Mobile Hub V1 Hub Agency.pdf
Comments on Cloud Stream Part II Mobile Hub V1 Hub Agency.pdf
Brij Consulting, LLC
 
From Sunlight to Savings The Rise of Homegrown Solar Power.pdf
From Sunlight to Savings The Rise of Homegrown Solar Power.pdfFrom Sunlight to Savings The Rise of Homegrown Solar Power.pdf
From Sunlight to Savings The Rise of Homegrown Solar Power.pdf
Insolation Energy
 
Yuriy Chapran: Zero Trust and Beyond: OpenVPN’s Role in Next-Gen Network Secu...
Yuriy Chapran: Zero Trust and Beyond: OpenVPN’s Role in Next-Gen Network Secu...Yuriy Chapran: Zero Trust and Beyond: OpenVPN’s Role in Next-Gen Network Secu...
Yuriy Chapran: Zero Trust and Beyond: OpenVPN’s Role in Next-Gen Network Secu...
Lviv Startup Club
 
Alan Stalcup - The Enterprising CEO
Alan  Stalcup  -  The  Enterprising  CEOAlan  Stalcup  -  The  Enterprising  CEO
Alan Stalcup - The Enterprising CEO
Alan Stalcup
 
waterBeta white paper - 250202- two-column.docx
waterBeta white paper - 250202- two-column.docxwaterBeta white paper - 250202- two-column.docx
waterBeta white paper - 250202- two-column.docx
Peter Adriaens
 
Network Detection and Response (NDR): The Future of Intelligent Cybersecurity
Network Detection and Response (NDR): The Future of Intelligent CybersecurityNetwork Detection and Response (NDR): The Future of Intelligent Cybersecurity
Network Detection and Response (NDR): The Future of Intelligent Cybersecurity
GauriKale30
 
Web Design Creating User-Friendly and Visually Engaging Websites - April 2025...
Web Design Creating User-Friendly and Visually Engaging Websites - April 2025...Web Design Creating User-Friendly and Visually Engaging Websites - April 2025...
Web Design Creating User-Friendly and Visually Engaging Websites - April 2025...
TheoRuby
 
LDMMIA Bday celebration 2025 Gifts information
LDMMIA Bday celebration 2025 Gifts informationLDMMIA Bday celebration 2025 Gifts information
LDMMIA Bday celebration 2025 Gifts information
LDM Mia eStudios
 
PREDICTION%20AND%20ANALYSIS%20OF%20ADMET%20PROPERTIES%20OF%20NEW%20MOLECULE%2...
PREDICTION%20AND%20ANALYSIS%20OF%20ADMET%20PROPERTIES%20OF%20NEW%20MOLECULE%2...PREDICTION%20AND%20ANALYSIS%20OF%20ADMET%20PROPERTIES%20OF%20NEW%20MOLECULE%2...
PREDICTION%20AND%20ANALYSIS%20OF%20ADMET%20PROPERTIES%20OF%20NEW%20MOLECULE%2...
AMITKUMARVERMA479091
 
INTRODUCTION OF MANAGEMENT.pdf CA SUVIDHA CHAPLOT
INTRODUCTION OF MANAGEMENT.pdf CA SUVIDHA CHAPLOTINTRODUCTION OF MANAGEMENT.pdf CA SUVIDHA CHAPLOT
INTRODUCTION OF MANAGEMENT.pdf CA SUVIDHA CHAPLOT
CA Suvidha Chaplot
 
www.visualmedia.com digital markiting (1).pptx
www.visualmedia.com digital markiting (1).pptxwww.visualmedia.com digital markiting (1).pptx
www.visualmedia.com digital markiting (1).pptx
Davinder Singh
 
AlaskaSilver Corporate Presentation Apr 28 2025.pdf
AlaskaSilver Corporate Presentation Apr 28 2025.pdfAlaskaSilver Corporate Presentation Apr 28 2025.pdf
AlaskaSilver Corporate Presentation Apr 28 2025.pdf
Western Alaska Minerals Corp.
 
20250428 CDB Investor Deck_Apr25_vFF.pdf
20250428 CDB Investor Deck_Apr25_vFF.pdf20250428 CDB Investor Deck_Apr25_vFF.pdf
20250428 CDB Investor Deck_Apr25_vFF.pdf
yihong30
 
2_English_Vocabulary_In_Use_Pre-Intermediate_Cambridge_-_Fourth_Edition (1).pdf
2_English_Vocabulary_In_Use_Pre-Intermediate_Cambridge_-_Fourth_Edition (1).pdf2_English_Vocabulary_In_Use_Pre-Intermediate_Cambridge_-_Fourth_Edition (1).pdf
2_English_Vocabulary_In_Use_Pre-Intermediate_Cambridge_-_Fourth_Edition (1).pdf
ThiNgc22
 
Freeze-Dried Fruit Powder Market Trends & Growth
Freeze-Dried Fruit Powder Market Trends & GrowthFreeze-Dried Fruit Powder Market Trends & Growth
Freeze-Dried Fruit Powder Market Trends & Growth
chanderdeepseoexpert
 
NewBase 05 May 2025 Energy News issue - 1785 by Khaled Al Awadi_compressed.pdf
NewBase 05 May 2025  Energy News issue - 1785 by Khaled Al Awadi_compressed.pdfNewBase 05 May 2025  Energy News issue - 1785 by Khaled Al Awadi_compressed.pdf
NewBase 05 May 2025 Energy News issue - 1785 by Khaled Al Awadi_compressed.pdf
Khaled Al Awadi
 
CGG Deck English - Apr 2025-edit (1).pptx
CGG Deck English - Apr 2025-edit (1).pptxCGG Deck English - Apr 2025-edit (1).pptx
CGG Deck English - Apr 2025-edit (1).pptx
China_Gold_International_Resources
 
BeMetals_Presentation_May_2025 .pdf
BeMetals_Presentation_May_2025      .pdfBeMetals_Presentation_May_2025      .pdf
BeMetals_Presentation_May_2025 .pdf
DerekIwanaka2
 
Level Up Your Launch: Utilizing AI for Start-up Success
Level Up Your Launch: Utilizing AI for Start-up SuccessLevel Up Your Launch: Utilizing AI for Start-up Success
Level Up Your Launch: Utilizing AI for Start-up Success
Best Virtual Specialist
 
Alec Lawler - A Passion For Building Brand Awareness
Alec Lawler - A Passion For Building Brand AwarenessAlec Lawler - A Passion For Building Brand Awareness
Alec Lawler - A Passion For Building Brand Awareness
Alec Lawler
 
Comments on Cloud Stream Part II Mobile Hub V1 Hub Agency.pdf
Comments on Cloud Stream Part II Mobile Hub V1 Hub Agency.pdfComments on Cloud Stream Part II Mobile Hub V1 Hub Agency.pdf
Comments on Cloud Stream Part II Mobile Hub V1 Hub Agency.pdf
Brij Consulting, LLC
 
From Sunlight to Savings The Rise of Homegrown Solar Power.pdf
From Sunlight to Savings The Rise of Homegrown Solar Power.pdfFrom Sunlight to Savings The Rise of Homegrown Solar Power.pdf
From Sunlight to Savings The Rise of Homegrown Solar Power.pdf
Insolation Energy
 
Yuriy Chapran: Zero Trust and Beyond: OpenVPN’s Role in Next-Gen Network Secu...
Yuriy Chapran: Zero Trust and Beyond: OpenVPN’s Role in Next-Gen Network Secu...Yuriy Chapran: Zero Trust and Beyond: OpenVPN’s Role in Next-Gen Network Secu...
Yuriy Chapran: Zero Trust and Beyond: OpenVPN’s Role in Next-Gen Network Secu...
Lviv Startup Club
 
Alan Stalcup - The Enterprising CEO
Alan  Stalcup  -  The  Enterprising  CEOAlan  Stalcup  -  The  Enterprising  CEO
Alan Stalcup - The Enterprising CEO
Alan Stalcup
 
waterBeta white paper - 250202- two-column.docx
waterBeta white paper - 250202- two-column.docxwaterBeta white paper - 250202- two-column.docx
waterBeta white paper - 250202- two-column.docx
Peter Adriaens
 
Network Detection and Response (NDR): The Future of Intelligent Cybersecurity
Network Detection and Response (NDR): The Future of Intelligent CybersecurityNetwork Detection and Response (NDR): The Future of Intelligent Cybersecurity
Network Detection and Response (NDR): The Future of Intelligent Cybersecurity
GauriKale30
 
Web Design Creating User-Friendly and Visually Engaging Websites - April 2025...
Web Design Creating User-Friendly and Visually Engaging Websites - April 2025...Web Design Creating User-Friendly and Visually Engaging Websites - April 2025...
Web Design Creating User-Friendly and Visually Engaging Websites - April 2025...
TheoRuby
 
LDMMIA Bday celebration 2025 Gifts information
LDMMIA Bday celebration 2025 Gifts informationLDMMIA Bday celebration 2025 Gifts information
LDMMIA Bday celebration 2025 Gifts information
LDM Mia eStudios
 
PREDICTION%20AND%20ANALYSIS%20OF%20ADMET%20PROPERTIES%20OF%20NEW%20MOLECULE%2...
PREDICTION%20AND%20ANALYSIS%20OF%20ADMET%20PROPERTIES%20OF%20NEW%20MOLECULE%2...PREDICTION%20AND%20ANALYSIS%20OF%20ADMET%20PROPERTIES%20OF%20NEW%20MOLECULE%2...
PREDICTION%20AND%20ANALYSIS%20OF%20ADMET%20PROPERTIES%20OF%20NEW%20MOLECULE%2...
AMITKUMARVERMA479091
 
INTRODUCTION OF MANAGEMENT.pdf CA SUVIDHA CHAPLOT
INTRODUCTION OF MANAGEMENT.pdf CA SUVIDHA CHAPLOTINTRODUCTION OF MANAGEMENT.pdf CA SUVIDHA CHAPLOT
INTRODUCTION OF MANAGEMENT.pdf CA SUVIDHA CHAPLOT
CA Suvidha Chaplot
 
www.visualmedia.com digital markiting (1).pptx
www.visualmedia.com digital markiting (1).pptxwww.visualmedia.com digital markiting (1).pptx
www.visualmedia.com digital markiting (1).pptx
Davinder Singh
 
20250428 CDB Investor Deck_Apr25_vFF.pdf
20250428 CDB Investor Deck_Apr25_vFF.pdf20250428 CDB Investor Deck_Apr25_vFF.pdf
20250428 CDB Investor Deck_Apr25_vFF.pdf
yihong30
 
2_English_Vocabulary_In_Use_Pre-Intermediate_Cambridge_-_Fourth_Edition (1).pdf
2_English_Vocabulary_In_Use_Pre-Intermediate_Cambridge_-_Fourth_Edition (1).pdf2_English_Vocabulary_In_Use_Pre-Intermediate_Cambridge_-_Fourth_Edition (1).pdf
2_English_Vocabulary_In_Use_Pre-Intermediate_Cambridge_-_Fourth_Edition (1).pdf
ThiNgc22
 
Freeze-Dried Fruit Powder Market Trends & Growth
Freeze-Dried Fruit Powder Market Trends & GrowthFreeze-Dried Fruit Powder Market Trends & Growth
Freeze-Dried Fruit Powder Market Trends & Growth
chanderdeepseoexpert
 
NewBase 05 May 2025 Energy News issue - 1785 by Khaled Al Awadi_compressed.pdf
NewBase 05 May 2025  Energy News issue - 1785 by Khaled Al Awadi_compressed.pdfNewBase 05 May 2025  Energy News issue - 1785 by Khaled Al Awadi_compressed.pdf
NewBase 05 May 2025 Energy News issue - 1785 by Khaled Al Awadi_compressed.pdf
Khaled Al Awadi
 
BeMetals_Presentation_May_2025 .pdf
BeMetals_Presentation_May_2025      .pdfBeMetals_Presentation_May_2025      .pdf
BeMetals_Presentation_May_2025 .pdf
DerekIwanaka2
 
Level Up Your Launch: Utilizing AI for Start-up Success
Level Up Your Launch: Utilizing AI for Start-up SuccessLevel Up Your Launch: Utilizing AI for Start-up Success
Level Up Your Launch: Utilizing AI for Start-up Success
Best Virtual Specialist
 

Tutorial: Develop an App with the Odoo Framework

  • 3. — Classy Cool Dev Thanks Classy Cool Dev! But, how can you be so sure Odoo is the perfect choice?
  • 5. Three-tier ● Presentation Layer (Client): HTML5, JavaScript, CSS ● Application Layer (Server): Python3 ● Data Layer (Database): PostgreSQL
  • 7. Architecture ● Server and backend modules in Python ○ MVC framework
  • 8. MVC framework ● Model: Data logic ● View: UI logic ● Controller: Interface
  • 9. Architecture ● Server and backend modules in Python ○ ORM to interact with database
  • 10. ORM: Bridges the gap between python and postgreSQL. class MyAwesomeCharacter(models.Model): _name = 'my.awesome.character' name = fields.Char(string="name", required=True) friend = fields.Many2one('my.awesome.character', string='Best Friend') Model definition:
  • 12. ORM Pros ● Less SQL ● Abstracts the DB ● Advanced features (cache, security, …) ● Better SQL queries
  • 13. ORM Cons ● Performance (?) ● Training ● Initial config ● Less deep understanding
  • 14. The Feature Manage a plant nursery: ● List of plants ● Manage orders ● Keep a customers list
  • 15. Technically you will learn: ● Structure of a module ● Definition of data models ● Definition of views and menus
  • 16. An Odoo module is: ● A manifest file ● Python code (models, logic) ● Data files, XML and CSV (base data, views, menus) ● Frontend resources (Javascript, CSS)
  • 17. Plant Nursery The manifest file: __manifest__.py # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. { 'name': 'Plant Nursery', 'version': '1.0', 'category': 'Tools', 'summary': 'Plants and customers management', 'depends': ['web'], 'data': [ 'security/ir.model.access.csv', 'data/data.xml', 'views/views.xml', ], 'demo': [ 'data/demo.xml', ], 'css': [], 'installable': True, 'auto_install': False, 'application': True, }
  • 18. Describe the models plant_nursery/models.p y from odoo import fields, models class Plants(models.Model): _name = 'nursery.plant' name = fields.Char("Plant Name") price = fields.Float() class Customer(models.Model): _name = 'nursery.customer' name = fields.Char("Customer Name", required=True) email = fields.Char(help="To receive the newsletter")
  • 20. Define the action <?xml version="1.0" encoding="UTF-8"?> <odoo> <record model="ir.actions.act_window" id="action_nursery_plant"> <field name="name">Plants</field> <field name="res_model">nursery.plant</field> <field name="view_mode">tree,form</field> </record> <menuitem name="Plant Nursery" id="nursery_root_menu" web_icon="plant_nursery,static/description/icon.png"/ > <menuitem name="Plants" id="nursery_plant_menu" parent="nursery_root_menu" action="action_nursery_plant" sequence="1"/> </odoo> plant_nursery/views/nursery_views.xml
  • 22. Define a form view plant_nursery/views/nursery_views.xml <record model="ir.ui.view" id="nursery_plant_view_form"> <field name="name">nursery.plant.view.form</field> <field name="model">nursery.plant</field> <field name="arch" type="xml"> <form string="Plant"> <sheet> <h1> <field name="name" placeholder="Plant Name"/> </h1> <notebook> <page string="Shop"> <group> <field name="price"/> </group> </page> </notebook> </sheet> </form> </field> </record>
  • 25. Relations class Order(models.Model): _name = 'nursery.order' plant_id = fields.Many2one("nursery.plant", required=True) customer_id = fields.Many2one("nursery.customer") class Plants(models.Model): _name = 'nursery.plant' order_ids = fields.One2many("nursery.order", "plant_id", string="Orders")
  • 27. Basic Operations: ● Read ● Write ● Create ● Unlink ● Search
  • 28. ORM Interactions class Order(models.Model): _name = 'nursery.order' name = fields.Datetime(default=fields.Datetime.now) plant_id = fields.Many2one("nursery.plant", required=True) customer_id = fields.Many2one("nursery.customer") state = fields.Selection([ ('draft', 'Draft'), ('confirm', 'Confirmed'), ('cancel', 'Canceled') ], default='draft') last_modification = fields.Datetime(readonly=True)
  • 29. ORM Interactionsclass Order(model.Models): _name = 'nursery.order' def write(self, values): # helper to "YYYY-MM-DD" values['last_modification'] = fields.Datetime.now() return super(Order, self).write(values) def unlink(self): # self is a recordset for order in self: if order.state == 'confirm': raise UserError("You can not delete confirmed orders") return super(Order, self).unlink()
  • 30. ORM Interactions <record model="ir.ui.view" id="nursery_order_form"> <field name="name">Order Form View</field> <field name="model">nursery.order</field> <field name="arch" type="xml"> <form string="Plant Order"> <header> <field name="state" widget="statusbar" options="{'clickable': '1'}"/> </header> <sheet> <group col="4"> <group colspan="2"> <field name="plant_id" /> <field name="customer_id" /> </group> <group colspan="2"> <field name="last_modification" /> </group> </group> </sheet> </form> </field> </record>
  • 32. — Classy Cool Dev Thanks Classy Cool Dev! What else could you show us?
  • 33. Computed Fields: ● For complex values ● Trigger for recompute ● Stored or not in the database
  • 34. Computed Fields class Plants(models.Model): _name = 'nursery.plant' order_count = fields.Integer(compute='_compute_order_count', store=True, string="Total sold") @api.depends('order_ids') def _compute_order_count(self): for plant in self: plant.order_count = len(plant.order_ids)
  • 35. Model Constraints ● Triggered after every creation or modification. ● Instead of overriding create & write
  • 36. Model Constraints class Plants(models.Model): _name = 'nursery.plant' number_in_stock = fields.Integer() @api.constrains('order_count', 'number_in_stock') def _check_available_in_stock(self): for plant in self: if plant.number_in_stock and plant.order_count > plant.number_in_stock: raise UserError("There is only %s %s in stock but %s were sold" % (plant.number_in_stock, plant.name, plant.order_count))
  • 37. Kanban View: ● Display information ● Add pictures ● Aggregated view
  • 38. Define a Kanban View: class Plants(models.Model): _name = 'nursery.plant' image = fields.Binary("Plant Image", attachment=True) <record model="ir.actions.act_window" id="action_nursery_order"> <field name="name">Orders</field> <field name="res_model">nursery.order</field> <field name="view_mode">kanban,tree,form</field> </record>
  • 39. <record id="nursery_plant_view_kanban" model="ir.ui.view"> <field name="name">nursery.plant.view.kanban</field> <field name="model">nursery.plant</field> <field name="arch" type="xml"> <kanban> <field name="id"/> <field name="image"/> <templates> <t t-name="kanban-box"> <div class="oe_kanban_global_click"> <div class="o_kanban_image"> <img t-att-src="kanban_image('nursery.plant', 'image', record.id.raw_value)"/> </div> <div class="oe_kanban_details"> <strong class="o_kanban_record_title"><field name="name"/></strong> <ul><li><strong>Price: <field name="price"></field></strong></li</ul> </div> </div> </t> </templates> </kanban> </field> </record> Define a Kanban View:
  • 42. Define a Search View: <record id="nursery_order_view_search" model="ir.ui.view"> <field name="name">nursery.order.view.search</field> <field name="model">nursery.order</field> <field name="arch" type="xml"> <search string="Search Orders"> <field name="plant_id" string="Plant"/> <field name="customer_id" string="Customer"/> <field name="state"/> <filter string="Confirmed" name="confirmed" domain="[('state', '=', 'confirm')]"/> <separator /> <group expand="0" string="Group By"> <filter string="State" name="group_by_state" domain="[]" context="{'group_by':'state'}"/> </group> </search> </field> </record>
  • 43. Display all the states class Order(models.Model): _name = 'nursery.order' state = fields.Selection([ ('draft', 'Draft'), ('confirm', 'Confirmed'), ('cancel', 'Canceled') ], default='draft', group_expand="_expand_states") def _expand_states(self, states, domain, order): return [key for key, val in type(self).state.selection]
  • 44. Always group by state: <record model="ir.actions.act_window" id="action_nursery_order"> <field name="name">Orders</field> <field name="res_model">nursery.order</field> <field name="view_mode">kanban,tree,form</field> <field name="context">{'search_default_group_by_state': 1}</field> </record>
  • 46. Onchange methods: class Customer(models.Model): _name = 'nursery.customer' _description = 'Nursery Customer' name = fields.Char('Customer Name', required=True) email = fields.Char(help="To receive the newsletter") mobile = fields.Char('Mobile') image = fields.Binary('Photo', attachment=True) address = fields.Char('Address') country_id = fields.Many2one('res.country', string='Country') partner_id = fields.Many2one('res.partner', string='Customer Address')
  • 47. Onchange methods: @api.onchange('partner_id') def _onchange_partner_id(self): if self.partner_id: if self.partner_id.image_1920: self.image = self.partner_id.image_1920 if self.partner_id.email: self.email = self.partner_id.email if self.partner_id.mobile: self.mobile = self.partner_id.mobile if self.partner_id.country_id: self.country_id = self.partner_id.country_id.id if not self.address: self.address = self.partner_id.with_context(show_address_only=True)._get_name()
  • 49. Sequences <!-- Sequences for plant.orders --> <record id="seq_plant_order" model="ir.sequence"> <field name="name">Plant Orders</field> <field name="code">plant.order</field> <field name="prefix">Order</field> <field name="padding">3</field> <field name="company_id" eval="False"/> </record>
  • 50. Sequences @api.model def create(self, vals): if vals.get('name', _('New')) == _('New'): if 'company_id' in vals: vals['name'] = self.env['ir.sequence'].with_context( force_company=vals['company_id'] ).next_by_code('plant.order') or _('New') else: vals['name'] = self.env['ir.sequence'].next_by_code('plant.order') or _('New') return super(Order, self).create(vals)