SlideShare a Scribd company logo
1 of 23
Download to read offline
OpenERP 8.0 Python API
Raphael Collet rco@openerp.com
MotivationFinal thoughts
Open Days 2013
1 of 23
More object-oriented style
Support for Pythonic style
Keep request parameters apart
Different API for specific features
Function fields
Default values
Constraints
Keep backwards compatibility
Open Days 2013
2 of 23
Object-oriented style
def write(self, cr, uid, ids, values, context=None):
super(C, self).write(cr, uid, ids, values, context=context)
for record in self.browse(cr, uid, ids, context=context):
if record.increment:
self.write(cr, uid, [record.id], {
'count': record.count + 1,
}, context=context)
@multi
def write(self, values):
super(C, self).write(values)
for record in self:
if record.increment:
record.count += 1
Open Days 2013
3 of 23
Every class instance is a recordset
A recordset is a collection of records; it encapsulates a list of
record ids.
records = model.browse(ids) # return a recordset
assert isinstance(records, Model)
print bool(records) # test for emptyness
print len(records) # size of collection
records1 = records[:3] # slicing
records2 = records[-3] # selection
records = records1 + records2 # concatenation
for record in records: # iteration returns
assert isinstance(record, Model) # recordsets, too
assert len(record) == 1
Open Days 2013
4 of 23
Recordsets to access data
Get/set a field on a recordset: do it on its first record.
records = model.browse(ids)
for record in records:
value = record.name
record.name = (value or '') + '!'
for record in records:
value = record['name']
record['name'] = (value or '') + '!'
assert records.name == records[0].name
# relational fields return recordsets
assert isinstance(records.parent_id, Model)
Compatible with old browse records.
Open Days 2013
5 of 23
Recordsets to access data
An empty recordset behaves as a null instance.
records = model.browse()
assert len(records) == 0
# data fields
assert records.name == False
# relational fields return empty recordsets
assert isinstance(records.parent_id, Model)
assert not records.parent_id
# no effect
records.name = 'Foo'
Open Days 2013
6 of 23
Model methods are called on recordsets
model = registry['res.partner']
assert isinstance(model, Model)
# get a recordset
records = model.create(values)
records = model.search(domain)
# perform operation on records
records.write({'name': 'Foo'})
result = records.read()
# call model method
defaults = records.default_get(['name'])
Open Days 2013
7 of 23
Method decorators: @model
self represents the model, its contents is irrelevant.
@model
def default_get(self, field_names):
...
def default_get(self, cr, uid, field_names, context=None):
...
stuff = model.browse(ids)
stuff.default_get(['name'])
model.default_get(cr, uid, ['name'], context=context)
Backwards compatible!
Open Days 2013
8 of 23
Method decorators: @multi
self is the recordset on which the operation applies.
@multi
def augment(self, arg):
for rec in self:
rec.value += arg
def augment(self, cr, uid, ids, arg, context=context):
...
stuff = model.browse(ids)
stuff.augment(42)
model.augment(cr, uid, ids, 42, context=context)
Backwards compatible!
Open Days 2013
9 of 23
Method decorators: @one
Automatic loop; self is a singleton.
@one
def name_get(self):
return (self.id, self.name)
def name_get(self, cr, uid, ids, context=None):
recs = self.browse(cr, uid, ids, context=context)
return [(rec.id, rec.name) for rec in recs]
stuff = model.browse(ids)
stuff.name_get()
model.name_get(cr, uid, ids, context=context)
Would become the default.
Open Days 2013
10 of 23
Method decorators: @returns
Automatic browse/unbrowse result.
@returns('res.partner')
def current_partner(self):
return registry['res.partner'].browse(42)
@returns('self')
def search(self, cr, uid, domain, ...):
return range(42)
# old-style calls return record ids
ids = model.current_partner(cr, uid, context=context)
ids = model.search(cr, uid, domain, context=context)
# new-style calls return a recordset
records = model.current_partner()
records = model.search(domain)
Open Days 2013
11 of 23
Encapsulation: scope(cr, uid, context)
Scopes are nestable with statement with.
# the scope object is a proxy to the current scope
from openerp import scope
with scope(cr, uid, context):
records.write({'name': 'Fool'})
with scope(lang='fr'):
# modifies French translation
records.write({'name': 'Fool'})
with scope.SUDO():
# write as superuser (with lang 'fr')
company.write({'name': 'Ma Compagnie'})
# retrieve parameters by deconstruction
cr, uid, context = scope
Open Days 2013
12 of 23
Every recordset is attached to a scope
Getting/setting a field is done in the attached scope.
with scope(lang='en'):
with scope(lang='fr'):
record1 = model.browse(id) # attached to French scope
print record1.name # French translation
print record1.name # still French translation!
record1.name = 'Jean-Pierre' # modify French translation
print record1.partner.name # still French translation
record2 = record1.scoped() # attached to English scope
print record2.name # English translation
Each scope carries a cache for records.
Open Days 2013
13 of 23
Automatic cache invalidation
No need to "rebrowse" records after an update.
record = model.browse(42)
assert record.name == 'Foo'
# simple update
record.write({'name': 'Bar'})
assert record.name == 'Bar'
# update of many2one field -> one2many invalidated
parent = record.parent_id
record.parent_id = another_record
assert record not in parent.child_ids
# explicit invalidation, in case you need it
record.invalidate_cache(['name', 'parent_id'], ids)
record.invalidate_cache(['name', 'parent_id'])
record.invalidate_cache()
Open Days 2013
14 of 23
Declaring fields
class res_partner(Model):
name = fields.Char(required=True)
customer = fields.Boolean(help="Check this box if ...")
parent_id = fields.Many2one('res.partner',
string='Related Company')
child_ids = fields.One2many('res.partner', 'parent_id',
string='Contacts')
display_name = fields.Char('Name', compute='_display_name',
store=False)
@one
@depends('name', 'email')
def _display_name(self):
self.display_name = self.name
if self.email:
self.display_name += " <%s>" % self.email
Open Days 2013
15 of 23
Function fields
Compute method must assign the field(s) on records.
class sale_order(Model):
amount = fields.Float(compute='_amounts')
taxes = fields.Float(compute='_amounts')
total = fields.Float(compute='_amounts')
@multi
@depends('lines.amount', 'lines.taxes')
def _amounts(self):
for order in self:
order.amount = sum(line.amount for line in order.lines)
order.taxes = sum(line.taxes for line in order.lines)
order.total = order.amount + order.taxes
Open Days 2013
16 of 23
Method decorators: @depends
Required for automating
cache invalidation
recomputation of stored fields
@one
@depends('product_id.price', 'quantity')
def _amounts(self):
self.amount = self.product_id.price * self.quantity
No need for complex "store" parameter anymore!
Open Days 2013
17 of 23
Function fields with inverse
foo = fields.Integer()
bar = fields.Integer(compute='_get_bar', inverse='_set_bar',
search='_search_bar')
@one
@depends('foo')
def _get_bar(self):
self.bar = self.foo + 1
@one
def _set_bar(self):
self.foo = self.bar - 1
@model
def _search_bar(self, operator, value):
... # return some domain on 'foo'
Currently under development.
Open Days 2013
18 of 23
Default values
Same mechanism as function fields
compute method has no dependency
from openerp import scope
class my_stuff(Model):
company_id = fields.Boolean(compute='_default_company')
@one
def _default_company(self):
self.company_id = scope.user.company_id
For function fields, compute method serves both purposes.
Open Days 2013
19 of 23
Onchange methods
Generic method
take all form values as input
automatically handle function fields
overridden to implement specific triggers
@one
def onchange(self, field_name):
super(C, self).onchange(field_name)
if field_name == 'partner':
self.delivery_address = self.partner
Currently under development.
Open Days 2013
20 of 23
Method decorators: @constraint
@one
@constraint("Name and description must be different")
@depends('name', 'description')
def _check_name_desc(self):
return self.name != self.description
Currently under development.
Open Days 2013
21 of 23
New domain syntax(es)
AST to represent the logic expression.
domain = AND(NE('name', 'Foo'), LT('age', 18))
Alternative construction with criteria (helper).
c = model.criteria()
domain = (c.name != 'Foo') & (c.age < 18)
Textual representation.
domain = "name != 'Foo' and age < 18"
This is speculative: maybe not for OpenERP 8.0.
Open Days 2013
22 of 23
It's a team work:
Raphael Collet, Vo Minh Thu, Xavier Morel
Work in progress
Server and addons branches on launchpad:
lp:~openerp-dev/openobject-server/trunk-apiculture
lp:~openerp-dev/openobject-addons/trunk-apiculture
Feedback: rco@openerp.com
Open Days 2013
23 of 23

More Related Content

What's hot

PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolveXSolve
 
Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)David de Boer
 
Hidden Gems in Swift
Hidden Gems in SwiftHidden Gems in Swift
Hidden Gems in SwiftNetguru
 
PHP Performance Trivia
PHP Performance TriviaPHP Performance Trivia
PHP Performance TriviaNikita Popov
 
Tools for Making Machine Learning more Reactive
Tools for Making Machine Learning more ReactiveTools for Making Machine Learning more Reactive
Tools for Making Machine Learning more ReactiveJeff Smith
 
All you need to know about JavaScript Functions
All you need to know about JavaScript FunctionsAll you need to know about JavaScript Functions
All you need to know about JavaScript FunctionsOluwaleke Fakorede
 
Type Driven Development with TypeScript
Type Driven Development with TypeScriptType Driven Development with TypeScript
Type Driven Development with TypeScriptGarth Gilmour
 
Object-Oriented Javascript
Object-Oriented JavascriptObject-Oriented Javascript
Object-Oriented Javascriptkvangork
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologyDaniel Knell
 
"Немного о функциональном программирование в JavaScript" Алексей Коваленко
"Немного о функциональном программирование в JavaScript" Алексей Коваленко"Немного о функциональном программирование в JavaScript" Алексей Коваленко
"Немного о функциональном программирование в JavaScript" Алексей КоваленкоFwdays
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web servicesMichelangelo van Dam
 
Swift internals
Swift internalsSwift internals
Swift internalsJung Kim
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful softwareJorn Oomen
 
Letswift19-clean-architecture
Letswift19-clean-architectureLetswift19-clean-architecture
Letswift19-clean-architectureJung Kim
 
LetSwift RxSwift 시작하기
LetSwift RxSwift 시작하기LetSwift RxSwift 시작하기
LetSwift RxSwift 시작하기Wanbok Choi
 

What's hot (19)

PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
 
Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)
 
Hidden Gems in Swift
Hidden Gems in SwiftHidden Gems in Swift
Hidden Gems in Swift
 
PHP Performance Trivia
PHP Performance TriviaPHP Performance Trivia
PHP Performance Trivia
 
Tools for Making Machine Learning more Reactive
Tools for Making Machine Learning more ReactiveTools for Making Machine Learning more Reactive
Tools for Making Machine Learning more Reactive
 
All you need to know about JavaScript Functions
All you need to know about JavaScript FunctionsAll you need to know about JavaScript Functions
All you need to know about JavaScript Functions
 
Type Driven Development with TypeScript
Type Driven Development with TypeScriptType Driven Development with TypeScript
Type Driven Development with TypeScript
 
Object-Oriented Javascript
Object-Oriented JavascriptObject-Oriented Javascript
Object-Oriented Javascript
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
 
"Немного о функциональном программирование в JavaScript" Алексей Коваленко
"Немного о функциональном программирование в JavaScript" Алексей Коваленко"Немного о функциональном программирование в JavaScript" Алексей Коваленко
"Немного о функциональном программирование в JavaScript" Алексей Коваленко
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web services
 
Swift internals
Swift internalsSwift internals
Swift internals
 
Pointers
PointersPointers
Pointers
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful software
 
P1
P1P1
P1
 
Letswift19-clean-architecture
Letswift19-clean-architectureLetswift19-clean-architecture
Letswift19-clean-architecture
 
LetSwift RxSwift 시작하기
LetSwift RxSwift 시작하기LetSwift RxSwift 시작하기
LetSwift RxSwift 시작하기
 
C++ file
C++ fileC++ file
C++ file
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 

Similar to Presentation of the new OpenERP API. Raphael Collet, OpenERP

Code is not text! How graph technologies can help us to understand our code b...
Code is not text! How graph technologies can help us to understand our code b...Code is not text! How graph technologies can help us to understand our code b...
Code is not text! How graph technologies can help us to understand our code b...Andreas Dewes
 
New Framework - ORM
New Framework - ORMNew Framework - ORM
New Framework - ORMOdoo
 
Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethodsdreampuf
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Jonathan Felch
 
Advanced Python, Part 1
Advanced Python, Part 1Advanced Python, Part 1
Advanced Python, Part 1Zaar Hai
 
Building an api using golang and postgre sql v1.0
Building an api using golang and postgre sql v1.0Building an api using golang and postgre sql v1.0
Building an api using golang and postgre sql v1.0Frost
 
Mongoskin - Guilin
Mongoskin - GuilinMongoskin - Guilin
Mongoskin - GuilinJackson Tian
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applicationschartjes
 
Object Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in PythonObject Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in PythonPython Ireland
 
Object.__class__.__dict__ - python object model and friends - with examples
Object.__class__.__dict__ - python object model and friends - with examplesObject.__class__.__dict__ - python object model and friends - with examples
Object.__class__.__dict__ - python object model and friends - with examplesRobert Lujo
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1Jano Suchal
 
mongodb-introduction
mongodb-introductionmongodb-introduction
mongodb-introductionTse-Ching Ho
 
From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)Night Sailer
 
PHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing InsanityPHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing InsanityGeorgePeterBanyard
 

Similar to Presentation of the new OpenERP API. Raphael Collet, OpenERP (20)

Code is not text! How graph technologies can help us to understand our code b...
Code is not text! How graph technologies can help us to understand our code b...Code is not text! How graph technologies can help us to understand our code b...
Code is not text! How graph technologies can help us to understand our code b...
 
New Framework - ORM
New Framework - ORMNew Framework - ORM
New Framework - ORM
 
Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethods
 
Odoo from 7.0 to 8.0 API
Odoo from 7.0 to 8.0 APIOdoo from 7.0 to 8.0 API
Odoo from 7.0 to 8.0 API
 
Django Good Practices
Django Good PracticesDjango Good Practices
Django Good Practices
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)
 
Python basic
Python basicPython basic
Python basic
 
Advanced Python, Part 1
Advanced Python, Part 1Advanced Python, Part 1
Advanced Python, Part 1
 
Building an api using golang and postgre sql v1.0
Building an api using golang and postgre sql v1.0Building an api using golang and postgre sql v1.0
Building an api using golang and postgre sql v1.0
 
Effective PHP. Part 1
Effective PHP. Part 1Effective PHP. Part 1
Effective PHP. Part 1
 
Mongoskin - Guilin
Mongoskin - GuilinMongoskin - Guilin
Mongoskin - Guilin
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
Object Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in PythonObject Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in Python
 
Object.__class__.__dict__ - python object model and friends - with examples
Object.__class__.__dict__ - python object model and friends - with examplesObject.__class__.__dict__ - python object model and friends - with examples
Object.__class__.__dict__ - python object model and friends - with examples
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
 
Dsl
DslDsl
Dsl
 
mongodb-introduction
mongodb-introductionmongodb-introduction
mongodb-introduction
 
Django design-patterns
Django design-patternsDjango design-patterns
Django design-patterns
 
From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)
 
PHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing InsanityPHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing Insanity
 

More from 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-ViewerOdoo
 
Keynote - Vision & Strategy
Keynote - Vision & StrategyKeynote - Vision & Strategy
Keynote - Vision & StrategyOdoo
 
Opening Keynote - Unveilling Odoo 14
Opening Keynote - Unveilling Odoo 14Opening Keynote - Unveilling Odoo 14
Opening Keynote - Unveilling Odoo 14Odoo
 
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 CapabilityOdoo
 
Managing Multi-channel Selling with Odoo
Managing Multi-channel Selling with OdooManaging Multi-channel Selling with Odoo
Managing Multi-channel Selling with OdooOdoo
 
Product Configurator: Advanced Use Case
Product Configurator: Advanced Use CaseProduct Configurator: Advanced Use Case
Product Configurator: Advanced Use CaseOdoo
 
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 OperationsOdoo
 
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 organizationOdoo
 
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 CrisisOdoo
 
Running a University with Odoo
Running a University with OdooRunning a University with Odoo
Running a University with OdooOdoo
 
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 OdooOdoo
 
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 foodOdoo
 
Migration from Salesforce to Odoo
Migration from Salesforce to OdooMigration from Salesforce to Odoo
Migration from Salesforce to OdooOdoo
 
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 LearningOdoo
 
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 LabelOdoo
 
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 FoldOdoo
 
From Shopify to Odoo
From Shopify to OdooFrom Shopify to Odoo
From Shopify to OdooOdoo
 

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 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
 
Keynote - Vision & Strategy
Keynote - Vision & StrategyKeynote - Vision & Strategy
Keynote - Vision & Strategy
 
Opening Keynote - Unveilling Odoo 14
Opening Keynote - Unveilling Odoo 14Opening Keynote - Unveilling Odoo 14
Opening Keynote - Unveilling Odoo 14
 
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
 
Managing Multi-channel Selling with Odoo
Managing Multi-channel Selling with OdooManaging Multi-channel Selling with Odoo
Managing Multi-channel Selling with Odoo
 
Product Configurator: Advanced Use Case
Product Configurator: Advanced Use CaseProduct Configurator: Advanced Use Case
Product Configurator: Advanced Use Case
 
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?
 
Rock Your Logistics with Advanced Operations
Rock Your Logistics with Advanced OperationsRock Your Logistics with Advanced Operations
Rock Your Logistics with Advanced Operations
 
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
 
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
 
Running a University with Odoo
Running a University with OdooRunning a University with Odoo
Running a University with 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 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
 
Migration from Salesforce to Odoo
Migration from Salesforce to OdooMigration from Salesforce to Odoo
Migration from Salesforce to 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
 
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
 
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
 
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
 
From Shopify to Odoo
From Shopify to OdooFrom Shopify to Odoo
From Shopify to Odoo
 

Recently uploaded

BEST Call Girls In Greater Noida ✨ 9773824855 ✨ Escorts Service In Delhi Ncr,
BEST Call Girls In Greater Noida ✨ 9773824855 ✨ Escorts Service In Delhi Ncr,BEST Call Girls In Greater Noida ✨ 9773824855 ✨ Escorts Service In Delhi Ncr,
BEST Call Girls In Greater Noida ✨ 9773824855 ✨ Escorts Service In Delhi Ncr,noida100girls
 
Call Girls Miyapur 7001305949 all area service COD available Any Time
Call Girls Miyapur 7001305949 all area service COD available Any TimeCall Girls Miyapur 7001305949 all area service COD available Any Time
Call Girls Miyapur 7001305949 all area service COD available Any Timedelhimodelshub1
 
rishikeshgirls.in- Rishikesh call girl.pdf
rishikeshgirls.in- Rishikesh call girl.pdfrishikeshgirls.in- Rishikesh call girl.pdf
rishikeshgirls.in- Rishikesh call girl.pdfmuskan1121w
 
Pitch Deck Teardown: NOQX's $200k Pre-seed deck
Pitch Deck Teardown: NOQX's $200k Pre-seed deckPitch Deck Teardown: NOQX's $200k Pre-seed deck
Pitch Deck Teardown: NOQX's $200k Pre-seed deckHajeJanKamps
 
Vip Female Escorts Noida 9711199171 Greater Noida Escorts Service
Vip Female Escorts Noida 9711199171 Greater Noida Escorts ServiceVip Female Escorts Noida 9711199171 Greater Noida Escorts Service
Vip Female Escorts Noida 9711199171 Greater Noida Escorts Serviceankitnayak356677
 
Call Girls in Mehrauli Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Mehrauli Delhi 💯Call Us 🔝8264348440🔝Call Girls in Mehrauli Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Mehrauli Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
RE Capital's Visionary Leadership under Newman Leech
RE Capital's Visionary Leadership under Newman LeechRE Capital's Visionary Leadership under Newman Leech
RE Capital's Visionary Leadership under Newman LeechNewman George Leech
 
Case study on tata clothing brand zudio in detail
Case study on tata clothing brand zudio in detailCase study on tata clothing brand zudio in detail
Case study on tata clothing brand zudio in detailAriel592675
 
Islamabad Escorts | Call 03274100048 | Escort Service in Islamabad
Islamabad Escorts | Call 03274100048 | Escort Service in IslamabadIslamabad Escorts | Call 03274100048 | Escort Service in Islamabad
Islamabad Escorts | Call 03274100048 | Escort Service in IslamabadAyesha Khan
 
Sales & Marketing Alignment: How to Synergize for Success
Sales & Marketing Alignment: How to Synergize for SuccessSales & Marketing Alignment: How to Synergize for Success
Sales & Marketing Alignment: How to Synergize for SuccessAggregage
 
(8264348440) 🔝 Call Girls In Keshav Puram 🔝 Delhi NCR
(8264348440) 🔝 Call Girls In Keshav Puram 🔝 Delhi NCR(8264348440) 🔝 Call Girls In Keshav Puram 🔝 Delhi NCR
(8264348440) 🔝 Call Girls In Keshav Puram 🔝 Delhi NCRsoniya singh
 
Call Girls In Connaught Place Delhi ❤️88604**77959_Russian 100% Genuine Escor...
Call Girls In Connaught Place Delhi ❤️88604**77959_Russian 100% Genuine Escor...Call Girls In Connaught Place Delhi ❤️88604**77959_Russian 100% Genuine Escor...
Call Girls In Connaught Place Delhi ❤️88604**77959_Russian 100% Genuine Escor...lizamodels9
 
Lean: From Theory to Practice — One City’s (and Library’s) Lean Story… Abridged
Lean: From Theory to Practice — One City’s (and Library’s) Lean Story… AbridgedLean: From Theory to Practice — One City’s (and Library’s) Lean Story… Abridged
Lean: From Theory to Practice — One City’s (and Library’s) Lean Story… AbridgedKaiNexus
 
Marketing Management Business Plan_My Sweet Creations
Marketing Management Business Plan_My Sweet CreationsMarketing Management Business Plan_My Sweet Creations
Marketing Management Business Plan_My Sweet Creationsnakalysalcedo61
 
M.C Lodges -- Guest House in Jhang.
M.C Lodges --  Guest House in Jhang.M.C Lodges --  Guest House in Jhang.
M.C Lodges -- Guest House in Jhang.Aaiza Hassan
 
Call Girls In Kishangarh Delhi ❤️8860477959 Good Looking Escorts In 24/7 Delh...
Call Girls In Kishangarh Delhi ❤️8860477959 Good Looking Escorts In 24/7 Delh...Call Girls In Kishangarh Delhi ❤️8860477959 Good Looking Escorts In 24/7 Delh...
Call Girls In Kishangarh Delhi ❤️8860477959 Good Looking Escorts In 24/7 Delh...lizamodels9
 
VIP Call Girl Jamshedpur Aashi 8250192130 Independent Escort Service Jamshedpur
VIP Call Girl Jamshedpur Aashi 8250192130 Independent Escort Service JamshedpurVIP Call Girl Jamshedpur Aashi 8250192130 Independent Escort Service Jamshedpur
VIP Call Girl Jamshedpur Aashi 8250192130 Independent Escort Service JamshedpurSuhani Kapoor
 
2024 Numerator Consumer Study of Cannabis Usage
2024 Numerator Consumer Study of Cannabis Usage2024 Numerator Consumer Study of Cannabis Usage
2024 Numerator Consumer Study of Cannabis UsageNeil Kimberley
 

Recently uploaded (20)

BEST Call Girls In Greater Noida ✨ 9773824855 ✨ Escorts Service In Delhi Ncr,
BEST Call Girls In Greater Noida ✨ 9773824855 ✨ Escorts Service In Delhi Ncr,BEST Call Girls In Greater Noida ✨ 9773824855 ✨ Escorts Service In Delhi Ncr,
BEST Call Girls In Greater Noida ✨ 9773824855 ✨ Escorts Service In Delhi Ncr,
 
Call Girls Miyapur 7001305949 all area service COD available Any Time
Call Girls Miyapur 7001305949 all area service COD available Any TimeCall Girls Miyapur 7001305949 all area service COD available Any Time
Call Girls Miyapur 7001305949 all area service COD available Any Time
 
rishikeshgirls.in- Rishikesh call girl.pdf
rishikeshgirls.in- Rishikesh call girl.pdfrishikeshgirls.in- Rishikesh call girl.pdf
rishikeshgirls.in- Rishikesh call girl.pdf
 
Pitch Deck Teardown: NOQX's $200k Pre-seed deck
Pitch Deck Teardown: NOQX's $200k Pre-seed deckPitch Deck Teardown: NOQX's $200k Pre-seed deck
Pitch Deck Teardown: NOQX's $200k Pre-seed deck
 
Vip Female Escorts Noida 9711199171 Greater Noida Escorts Service
Vip Female Escorts Noida 9711199171 Greater Noida Escorts ServiceVip Female Escorts Noida 9711199171 Greater Noida Escorts Service
Vip Female Escorts Noida 9711199171 Greater Noida Escorts Service
 
Call Girls in Mehrauli Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Mehrauli Delhi 💯Call Us 🔝8264348440🔝Call Girls in Mehrauli Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Mehrauli Delhi 💯Call Us 🔝8264348440🔝
 
RE Capital's Visionary Leadership under Newman Leech
RE Capital's Visionary Leadership under Newman LeechRE Capital's Visionary Leadership under Newman Leech
RE Capital's Visionary Leadership under Newman Leech
 
Case study on tata clothing brand zudio in detail
Case study on tata clothing brand zudio in detailCase study on tata clothing brand zudio in detail
Case study on tata clothing brand zudio in detail
 
Islamabad Escorts | Call 03274100048 | Escort Service in Islamabad
Islamabad Escorts | Call 03274100048 | Escort Service in IslamabadIslamabad Escorts | Call 03274100048 | Escort Service in Islamabad
Islamabad Escorts | Call 03274100048 | Escort Service in Islamabad
 
Sales & Marketing Alignment: How to Synergize for Success
Sales & Marketing Alignment: How to Synergize for SuccessSales & Marketing Alignment: How to Synergize for Success
Sales & Marketing Alignment: How to Synergize for Success
 
Best Practices for Implementing an External Recruiting Partnership
Best Practices for Implementing an External Recruiting PartnershipBest Practices for Implementing an External Recruiting Partnership
Best Practices for Implementing an External Recruiting Partnership
 
(8264348440) 🔝 Call Girls In Keshav Puram 🔝 Delhi NCR
(8264348440) 🔝 Call Girls In Keshav Puram 🔝 Delhi NCR(8264348440) 🔝 Call Girls In Keshav Puram 🔝 Delhi NCR
(8264348440) 🔝 Call Girls In Keshav Puram 🔝 Delhi NCR
 
Call Girls In Connaught Place Delhi ❤️88604**77959_Russian 100% Genuine Escor...
Call Girls In Connaught Place Delhi ❤️88604**77959_Russian 100% Genuine Escor...Call Girls In Connaught Place Delhi ❤️88604**77959_Russian 100% Genuine Escor...
Call Girls In Connaught Place Delhi ❤️88604**77959_Russian 100% Genuine Escor...
 
Lean: From Theory to Practice — One City’s (and Library’s) Lean Story… Abridged
Lean: From Theory to Practice — One City’s (and Library’s) Lean Story… AbridgedLean: From Theory to Practice — One City’s (and Library’s) Lean Story… Abridged
Lean: From Theory to Practice — One City’s (and Library’s) Lean Story… Abridged
 
Marketing Management Business Plan_My Sweet Creations
Marketing Management Business Plan_My Sweet CreationsMarketing Management Business Plan_My Sweet Creations
Marketing Management Business Plan_My Sweet Creations
 
M.C Lodges -- Guest House in Jhang.
M.C Lodges --  Guest House in Jhang.M.C Lodges --  Guest House in Jhang.
M.C Lodges -- Guest House in Jhang.
 
Call Girls In Kishangarh Delhi ❤️8860477959 Good Looking Escorts In 24/7 Delh...
Call Girls In Kishangarh Delhi ❤️8860477959 Good Looking Escorts In 24/7 Delh...Call Girls In Kishangarh Delhi ❤️8860477959 Good Looking Escorts In 24/7 Delh...
Call Girls In Kishangarh Delhi ❤️8860477959 Good Looking Escorts In 24/7 Delh...
 
VIP Call Girl Jamshedpur Aashi 8250192130 Independent Escort Service Jamshedpur
VIP Call Girl Jamshedpur Aashi 8250192130 Independent Escort Service JamshedpurVIP Call Girl Jamshedpur Aashi 8250192130 Independent Escort Service Jamshedpur
VIP Call Girl Jamshedpur Aashi 8250192130 Independent Escort Service Jamshedpur
 
2024 Numerator Consumer Study of Cannabis Usage
2024 Numerator Consumer Study of Cannabis Usage2024 Numerator Consumer Study of Cannabis Usage
2024 Numerator Consumer Study of Cannabis Usage
 
Enjoy ➥8448380779▻ Call Girls In Sector 18 Noida Escorts Delhi NCR
Enjoy ➥8448380779▻ Call Girls In Sector 18 Noida Escorts Delhi NCREnjoy ➥8448380779▻ Call Girls In Sector 18 Noida Escorts Delhi NCR
Enjoy ➥8448380779▻ Call Girls In Sector 18 Noida Escorts Delhi NCR
 

Presentation of the new OpenERP API. Raphael Collet, OpenERP

  • 1. OpenERP 8.0 Python API Raphael Collet rco@openerp.com MotivationFinal thoughts Open Days 2013 1 of 23
  • 2. More object-oriented style Support for Pythonic style Keep request parameters apart Different API for specific features Function fields Default values Constraints Keep backwards compatibility Open Days 2013 2 of 23
  • 3. Object-oriented style def write(self, cr, uid, ids, values, context=None): super(C, self).write(cr, uid, ids, values, context=context) for record in self.browse(cr, uid, ids, context=context): if record.increment: self.write(cr, uid, [record.id], { 'count': record.count + 1, }, context=context) @multi def write(self, values): super(C, self).write(values) for record in self: if record.increment: record.count += 1 Open Days 2013 3 of 23
  • 4. Every class instance is a recordset A recordset is a collection of records; it encapsulates a list of record ids. records = model.browse(ids) # return a recordset assert isinstance(records, Model) print bool(records) # test for emptyness print len(records) # size of collection records1 = records[:3] # slicing records2 = records[-3] # selection records = records1 + records2 # concatenation for record in records: # iteration returns assert isinstance(record, Model) # recordsets, too assert len(record) == 1 Open Days 2013 4 of 23
  • 5. Recordsets to access data Get/set a field on a recordset: do it on its first record. records = model.browse(ids) for record in records: value = record.name record.name = (value or '') + '!' for record in records: value = record['name'] record['name'] = (value or '') + '!' assert records.name == records[0].name # relational fields return recordsets assert isinstance(records.parent_id, Model) Compatible with old browse records. Open Days 2013 5 of 23
  • 6. Recordsets to access data An empty recordset behaves as a null instance. records = model.browse() assert len(records) == 0 # data fields assert records.name == False # relational fields return empty recordsets assert isinstance(records.parent_id, Model) assert not records.parent_id # no effect records.name = 'Foo' Open Days 2013 6 of 23
  • 7. Model methods are called on recordsets model = registry['res.partner'] assert isinstance(model, Model) # get a recordset records = model.create(values) records = model.search(domain) # perform operation on records records.write({'name': 'Foo'}) result = records.read() # call model method defaults = records.default_get(['name']) Open Days 2013 7 of 23
  • 8. Method decorators: @model self represents the model, its contents is irrelevant. @model def default_get(self, field_names): ... def default_get(self, cr, uid, field_names, context=None): ... stuff = model.browse(ids) stuff.default_get(['name']) model.default_get(cr, uid, ['name'], context=context) Backwards compatible! Open Days 2013 8 of 23
  • 9. Method decorators: @multi self is the recordset on which the operation applies. @multi def augment(self, arg): for rec in self: rec.value += arg def augment(self, cr, uid, ids, arg, context=context): ... stuff = model.browse(ids) stuff.augment(42) model.augment(cr, uid, ids, 42, context=context) Backwards compatible! Open Days 2013 9 of 23
  • 10. Method decorators: @one Automatic loop; self is a singleton. @one def name_get(self): return (self.id, self.name) def name_get(self, cr, uid, ids, context=None): recs = self.browse(cr, uid, ids, context=context) return [(rec.id, rec.name) for rec in recs] stuff = model.browse(ids) stuff.name_get() model.name_get(cr, uid, ids, context=context) Would become the default. Open Days 2013 10 of 23
  • 11. Method decorators: @returns Automatic browse/unbrowse result. @returns('res.partner') def current_partner(self): return registry['res.partner'].browse(42) @returns('self') def search(self, cr, uid, domain, ...): return range(42) # old-style calls return record ids ids = model.current_partner(cr, uid, context=context) ids = model.search(cr, uid, domain, context=context) # new-style calls return a recordset records = model.current_partner() records = model.search(domain) Open Days 2013 11 of 23
  • 12. Encapsulation: scope(cr, uid, context) Scopes are nestable with statement with. # the scope object is a proxy to the current scope from openerp import scope with scope(cr, uid, context): records.write({'name': 'Fool'}) with scope(lang='fr'): # modifies French translation records.write({'name': 'Fool'}) with scope.SUDO(): # write as superuser (with lang 'fr') company.write({'name': 'Ma Compagnie'}) # retrieve parameters by deconstruction cr, uid, context = scope Open Days 2013 12 of 23
  • 13. Every recordset is attached to a scope Getting/setting a field is done in the attached scope. with scope(lang='en'): with scope(lang='fr'): record1 = model.browse(id) # attached to French scope print record1.name # French translation print record1.name # still French translation! record1.name = 'Jean-Pierre' # modify French translation print record1.partner.name # still French translation record2 = record1.scoped() # attached to English scope print record2.name # English translation Each scope carries a cache for records. Open Days 2013 13 of 23
  • 14. Automatic cache invalidation No need to "rebrowse" records after an update. record = model.browse(42) assert record.name == 'Foo' # simple update record.write({'name': 'Bar'}) assert record.name == 'Bar' # update of many2one field -> one2many invalidated parent = record.parent_id record.parent_id = another_record assert record not in parent.child_ids # explicit invalidation, in case you need it record.invalidate_cache(['name', 'parent_id'], ids) record.invalidate_cache(['name', 'parent_id']) record.invalidate_cache() Open Days 2013 14 of 23
  • 15. Declaring fields class res_partner(Model): name = fields.Char(required=True) customer = fields.Boolean(help="Check this box if ...") parent_id = fields.Many2one('res.partner', string='Related Company') child_ids = fields.One2many('res.partner', 'parent_id', string='Contacts') display_name = fields.Char('Name', compute='_display_name', store=False) @one @depends('name', 'email') def _display_name(self): self.display_name = self.name if self.email: self.display_name += " <%s>" % self.email Open Days 2013 15 of 23
  • 16. Function fields Compute method must assign the field(s) on records. class sale_order(Model): amount = fields.Float(compute='_amounts') taxes = fields.Float(compute='_amounts') total = fields.Float(compute='_amounts') @multi @depends('lines.amount', 'lines.taxes') def _amounts(self): for order in self: order.amount = sum(line.amount for line in order.lines) order.taxes = sum(line.taxes for line in order.lines) order.total = order.amount + order.taxes Open Days 2013 16 of 23
  • 17. Method decorators: @depends Required for automating cache invalidation recomputation of stored fields @one @depends('product_id.price', 'quantity') def _amounts(self): self.amount = self.product_id.price * self.quantity No need for complex "store" parameter anymore! Open Days 2013 17 of 23
  • 18. Function fields with inverse foo = fields.Integer() bar = fields.Integer(compute='_get_bar', inverse='_set_bar', search='_search_bar') @one @depends('foo') def _get_bar(self): self.bar = self.foo + 1 @one def _set_bar(self): self.foo = self.bar - 1 @model def _search_bar(self, operator, value): ... # return some domain on 'foo' Currently under development. Open Days 2013 18 of 23
  • 19. Default values Same mechanism as function fields compute method has no dependency from openerp import scope class my_stuff(Model): company_id = fields.Boolean(compute='_default_company') @one def _default_company(self): self.company_id = scope.user.company_id For function fields, compute method serves both purposes. Open Days 2013 19 of 23
  • 20. Onchange methods Generic method take all form values as input automatically handle function fields overridden to implement specific triggers @one def onchange(self, field_name): super(C, self).onchange(field_name) if field_name == 'partner': self.delivery_address = self.partner Currently under development. Open Days 2013 20 of 23
  • 21. Method decorators: @constraint @one @constraint("Name and description must be different") @depends('name', 'description') def _check_name_desc(self): return self.name != self.description Currently under development. Open Days 2013 21 of 23
  • 22. New domain syntax(es) AST to represent the logic expression. domain = AND(NE('name', 'Foo'), LT('age', 18)) Alternative construction with criteria (helper). c = model.criteria() domain = (c.name != 'Foo') & (c.age < 18) Textual representation. domain = "name != 'Foo' and age < 18" This is speculative: maybe not for OpenERP 8.0. Open Days 2013 22 of 23
  • 23. It's a team work: Raphael Collet, Vo Minh Thu, Xavier Morel Work in progress Server and addons branches on launchpad: lp:~openerp-dev/openobject-server/trunk-apiculture lp:~openerp-dev/openobject-addons/trunk-apiculture Feedback: rco@openerp.com Open Days 2013 23 of 23