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

trending-flavors-and-ingredients-in-salty-snacks-us-2024_Redacted-V2.pdf
trending-flavors-and-ingredients-in-salty-snacks-us-2024_Redacted-V2.pdftrending-flavors-and-ingredients-in-salty-snacks-us-2024_Redacted-V2.pdf
trending-flavors-and-ingredients-in-salty-snacks-us-2024_Redacted-V2.pdfMintel Group
 
How Generative AI Is Transforming Your Business | Byond Growth Insights | Apr...
How Generative AI Is Transforming Your Business | Byond Growth Insights | Apr...How Generative AI Is Transforming Your Business | Byond Growth Insights | Apr...
How Generative AI Is Transforming Your Business | Byond Growth Insights | Apr...Hector Del Castillo, CPM, CPMM
 
WSMM Media and Entertainment Feb_March_Final.pdf
WSMM Media and Entertainment Feb_March_Final.pdfWSMM Media and Entertainment Feb_March_Final.pdf
WSMM Media and Entertainment Feb_March_Final.pdfJamesConcepcion7
 
WSMM Technology February.March Newsletter_vF.pdf
WSMM Technology February.March Newsletter_vF.pdfWSMM Technology February.March Newsletter_vF.pdf
WSMM Technology February.March Newsletter_vF.pdfJamesConcepcion7
 
Cybersecurity Awareness Training Presentation v2024.03
Cybersecurity Awareness Training Presentation v2024.03Cybersecurity Awareness Training Presentation v2024.03
Cybersecurity Awareness Training Presentation v2024.03DallasHaselhorst
 
APRIL2024_UKRAINE_xml_0000000000000 .pdf
APRIL2024_UKRAINE_xml_0000000000000 .pdfAPRIL2024_UKRAINE_xml_0000000000000 .pdf
APRIL2024_UKRAINE_xml_0000000000000 .pdfRbc Rbcua
 
Memorándum de Entendimiento (MoU) entre Codelco y SQM
Memorándum de Entendimiento (MoU) entre Codelco y SQMMemorándum de Entendimiento (MoU) entre Codelco y SQM
Memorándum de Entendimiento (MoU) entre Codelco y SQMVoces Mineras
 
NAB Show Exhibitor List 2024 - Exhibitors Data
NAB Show Exhibitor List 2024 - Exhibitors DataNAB Show Exhibitor List 2024 - Exhibitors Data
NAB Show Exhibitor List 2024 - Exhibitors DataExhibitors Data
 
EUDR Info Meeting Ethiopian coffee exporters
EUDR Info Meeting Ethiopian coffee exportersEUDR Info Meeting Ethiopian coffee exporters
EUDR Info Meeting Ethiopian coffee exportersPeter Horsten
 
Send Files | Sendbig.comSend Files | Sendbig.com
Send Files | Sendbig.comSend Files | Sendbig.comSend Files | Sendbig.comSend Files | Sendbig.com
Send Files | Sendbig.comSend Files | Sendbig.comSendBig4
 
Technical Leaders - Working with the Management Team
Technical Leaders - Working with the Management TeamTechnical Leaders - Working with the Management Team
Technical Leaders - Working with the Management TeamArik Fletcher
 
Effective Strategies for Maximizing Your Profit When Selling Gold Jewelry
Effective Strategies for Maximizing Your Profit When Selling Gold JewelryEffective Strategies for Maximizing Your Profit When Selling Gold Jewelry
Effective Strategies for Maximizing Your Profit When Selling Gold JewelryWhittensFineJewelry1
 
20200128 Ethical by Design - Whitepaper.pdf
20200128 Ethical by Design - Whitepaper.pdf20200128 Ethical by Design - Whitepaper.pdf
20200128 Ethical by Design - Whitepaper.pdfChris Skinner
 
How To Simplify Your Scheduling with AI Calendarfly The Hassle-Free Online Bo...
How To Simplify Your Scheduling with AI Calendarfly The Hassle-Free Online Bo...How To Simplify Your Scheduling with AI Calendarfly The Hassle-Free Online Bo...
How To Simplify Your Scheduling with AI Calendarfly The Hassle-Free Online Bo...SOFTTECHHUB
 
BAILMENT & PLEDGE business law notes.pptx
BAILMENT & PLEDGE business law notes.pptxBAILMENT & PLEDGE business law notes.pptx
BAILMENT & PLEDGE business law notes.pptxran17april2001
 
The McKinsey 7S Framework: A Holistic Approach to Harmonizing All Parts of th...
The McKinsey 7S Framework: A Holistic Approach to Harmonizing All Parts of th...The McKinsey 7S Framework: A Holistic Approach to Harmonizing All Parts of th...
The McKinsey 7S Framework: A Holistic Approach to Harmonizing All Parts of th...Operational Excellence Consulting
 
Planetary and Vedic Yagyas Bring Positive Impacts in Life
Planetary and Vedic Yagyas Bring Positive Impacts in LifePlanetary and Vedic Yagyas Bring Positive Impacts in Life
Planetary and Vedic Yagyas Bring Positive Impacts in LifeBhavana Pujan Kendra
 
Pitch Deck Teardown: Xpanceo's $40M Seed deck
Pitch Deck Teardown: Xpanceo's $40M Seed deckPitch Deck Teardown: Xpanceo's $40M Seed deck
Pitch Deck Teardown: Xpanceo's $40M Seed deckHajeJanKamps
 
Driving Business Impact for PMs with Jon Harmer
Driving Business Impact for PMs with Jon HarmerDriving Business Impact for PMs with Jon Harmer
Driving Business Impact for PMs with Jon HarmerAggregage
 
Supercharge Your eCommerce Stores-acowebs
Supercharge Your eCommerce Stores-acowebsSupercharge Your eCommerce Stores-acowebs
Supercharge Your eCommerce Stores-acowebsGOKUL JS
 

Recently uploaded (20)

trending-flavors-and-ingredients-in-salty-snacks-us-2024_Redacted-V2.pdf
trending-flavors-and-ingredients-in-salty-snacks-us-2024_Redacted-V2.pdftrending-flavors-and-ingredients-in-salty-snacks-us-2024_Redacted-V2.pdf
trending-flavors-and-ingredients-in-salty-snacks-us-2024_Redacted-V2.pdf
 
How Generative AI Is Transforming Your Business | Byond Growth Insights | Apr...
How Generative AI Is Transforming Your Business | Byond Growth Insights | Apr...How Generative AI Is Transforming Your Business | Byond Growth Insights | Apr...
How Generative AI Is Transforming Your Business | Byond Growth Insights | Apr...
 
WSMM Media and Entertainment Feb_March_Final.pdf
WSMM Media and Entertainment Feb_March_Final.pdfWSMM Media and Entertainment Feb_March_Final.pdf
WSMM Media and Entertainment Feb_March_Final.pdf
 
WSMM Technology February.March Newsletter_vF.pdf
WSMM Technology February.March Newsletter_vF.pdfWSMM Technology February.March Newsletter_vF.pdf
WSMM Technology February.March Newsletter_vF.pdf
 
Cybersecurity Awareness Training Presentation v2024.03
Cybersecurity Awareness Training Presentation v2024.03Cybersecurity Awareness Training Presentation v2024.03
Cybersecurity Awareness Training Presentation v2024.03
 
APRIL2024_UKRAINE_xml_0000000000000 .pdf
APRIL2024_UKRAINE_xml_0000000000000 .pdfAPRIL2024_UKRAINE_xml_0000000000000 .pdf
APRIL2024_UKRAINE_xml_0000000000000 .pdf
 
Memorándum de Entendimiento (MoU) entre Codelco y SQM
Memorándum de Entendimiento (MoU) entre Codelco y SQMMemorándum de Entendimiento (MoU) entre Codelco y SQM
Memorándum de Entendimiento (MoU) entre Codelco y SQM
 
NAB Show Exhibitor List 2024 - Exhibitors Data
NAB Show Exhibitor List 2024 - Exhibitors DataNAB Show Exhibitor List 2024 - Exhibitors Data
NAB Show Exhibitor List 2024 - Exhibitors Data
 
EUDR Info Meeting Ethiopian coffee exporters
EUDR Info Meeting Ethiopian coffee exportersEUDR Info Meeting Ethiopian coffee exporters
EUDR Info Meeting Ethiopian coffee exporters
 
Send Files | Sendbig.comSend Files | Sendbig.com
Send Files | Sendbig.comSend Files | Sendbig.comSend Files | Sendbig.comSend Files | Sendbig.com
Send Files | Sendbig.comSend Files | Sendbig.com
 
Technical Leaders - Working with the Management Team
Technical Leaders - Working with the Management TeamTechnical Leaders - Working with the Management Team
Technical Leaders - Working with the Management Team
 
Effective Strategies for Maximizing Your Profit When Selling Gold Jewelry
Effective Strategies for Maximizing Your Profit When Selling Gold JewelryEffective Strategies for Maximizing Your Profit When Selling Gold Jewelry
Effective Strategies for Maximizing Your Profit When Selling Gold Jewelry
 
20200128 Ethical by Design - Whitepaper.pdf
20200128 Ethical by Design - Whitepaper.pdf20200128 Ethical by Design - Whitepaper.pdf
20200128 Ethical by Design - Whitepaper.pdf
 
How To Simplify Your Scheduling with AI Calendarfly The Hassle-Free Online Bo...
How To Simplify Your Scheduling with AI Calendarfly The Hassle-Free Online Bo...How To Simplify Your Scheduling with AI Calendarfly The Hassle-Free Online Bo...
How To Simplify Your Scheduling with AI Calendarfly The Hassle-Free Online Bo...
 
BAILMENT & PLEDGE business law notes.pptx
BAILMENT & PLEDGE business law notes.pptxBAILMENT & PLEDGE business law notes.pptx
BAILMENT & PLEDGE business law notes.pptx
 
The McKinsey 7S Framework: A Holistic Approach to Harmonizing All Parts of th...
The McKinsey 7S Framework: A Holistic Approach to Harmonizing All Parts of th...The McKinsey 7S Framework: A Holistic Approach to Harmonizing All Parts of th...
The McKinsey 7S Framework: A Holistic Approach to Harmonizing All Parts of th...
 
Planetary and Vedic Yagyas Bring Positive Impacts in Life
Planetary and Vedic Yagyas Bring Positive Impacts in LifePlanetary and Vedic Yagyas Bring Positive Impacts in Life
Planetary and Vedic Yagyas Bring Positive Impacts in Life
 
Pitch Deck Teardown: Xpanceo's $40M Seed deck
Pitch Deck Teardown: Xpanceo's $40M Seed deckPitch Deck Teardown: Xpanceo's $40M Seed deck
Pitch Deck Teardown: Xpanceo's $40M Seed deck
 
Driving Business Impact for PMs with Jon Harmer
Driving Business Impact for PMs with Jon HarmerDriving Business Impact for PMs with Jon Harmer
Driving Business Impact for PMs with Jon Harmer
 
Supercharge Your eCommerce Stores-acowebs
Supercharge Your eCommerce Stores-acowebsSupercharge Your eCommerce Stores-acowebs
Supercharge Your eCommerce Stores-acowebs
 

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