Vous êtes sur la page 1sur 26

Fields

Basic Fields

boolean() integer() date() datetime() time()

char(string,size,translate=False,..)
'name' : fields.char(Name',size=256,),

text(string, translate=False, ...)


'note' : fields.text('Note'),

float(string, digits=(precision,scale), ...)


'score' : fields.float('Score',digits=(2,1)),

class TestObject(orm.TransientModel):
_name = 'web_tests_demo.model'

selection(values, string, ...)


'state': fields.selection([
('draft','Draft'),
('confirmed','Confirmed')
],'State',required=True,readonly=True),

binary(string, filters=None, ...)


'picture': fields.binary(Picture',
filters='*.png,*.gif'),

!
!

_columns = {
'name': fields.char("Name", required=True),
'thing': fields.char("Thing"),
'other': fields.char("Other", required=True)
}
_defaults = {
'other': "bob"
}

class res_partner_bank(osv.osv):
'''Bank Accounts'''
_name = "res.partner.bank"
_rec_name = "acc_number"
_description = __doc__
_order = 'sequence'

Fields

Relational Fields

many2one(obj, ondelete='set null', ...)


# by convention, many2one fields end with '_id'
'inventor_id': fields.many2one('res.partner','Inventor'),

!
!

# Write values to a many2many field


# https://github.com/cormier/openerp-cookbook/blob/master/many2many-write.md

one2many(obj, field_id, ...)


# by convention, *2many fields end with '_ids'
'vote_ids': fields.one2many('idea.vote','idea_id','Votes'),

many2many(obj, rel, field1, field2, ...)


# obj is the related table,
# rel is th name of the go between table
# fields are the fields in the go between Table
'sponsor_ids': fields.many2many('res.partner','idea_sponsor_rel',
'idea_id','sponsor_id','Sponsors'),

related(f1, f2, ..., type='float', ...)


# Shortcut field equivalent to browsing chained fields f1,f2,...:
# chained fields to reach target (f1 required) (51)
# type: type of target field

!
!
!
!
!
!
!

'inventor_country_id': fields.related(
'inventor_id','country',
type='many2one', relation='res.country',
readonly=True, string=Country'),

Please take a look at your many2many It should be like this

fields.many2many('that object name',


'sql relation table name',
'this object id',
'that object id',
'Field Lable')
Eg: in your case the two many2many could be like this

!
first many2many
!

'tag_ids': fields.many2many(
'hello',
'notebook_hello_rel',
'notebook_id',
'hello_id',
string="Tags"
),
Second many2many

'note_ids': fields.many2many(
'notebook',
'notebook_hello_rel',
'hello_id',
'notebook_id',
string="Notebooks"
),

_defaults = {
'date_start': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'finance_inst': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).finance_inst,
}

#Use this to populate Origin


#print context and context.get('active_id', False) or False

Fields Relational Fields


reference(string, selection, size,..)
'contact': fields.reference('Contact',[
('res.partner','Partner'),
('res.partner.contact','Contact')
]),

!
!
!
!

'doc': fields.reference('Field Label', selection, size),


#
#
#
#

The fields.reference constructor takes 3 main parameters:


where selection contains the list of document models from which values can be selected
(e.g Partners, Products, etc.), in the same form as in a fields.selection declaration.
The key of the selection values must be the model names (e.g. 'res.partner').

function(fnct, arg=None, fnct_inv=None,


fnct_inv_arg=None, type='float', fnct_search=None, obj=None, store=False, multi=False,...)

# Functional field simulating a real field, computed rather than stored


# fnct: function to compute the field value (required)
def fnct(self, cr, uid, ids, field_name, arg, context):
returns a dictionary { idsvalues } with values of type type
# fnct_inv: function used to write a value in the field instead
def fnct_inv(obj, cr, uid, id, name, value, fnct_inv_arg, context):
# type: type of simulated field (can be any other type except 'function') fnct_search: function used to search on this
field
def fnct_search(obj, cr, uid, obj, name, args):
# returns a list of tuples arguments for search(), e.g. [('id','in',[1,3,5])]
obj: model _name of simulated field if it is a relational field
# store, multi: optimization mechanisms (see usage in Performance Section)

!
!
!

Fields Relational Fields


store Parameter

It will calculate the field and store the result in the table. The field will be recalculated when
certain fields are changed on other objects. It uses the following syntax:

!
!

store = {
'object_name': (
function_name,
['field_name1', 'field_name2'],
priority)
}

It will call function function_name when any changes are written to fields in the list
['field1','field2'] on object 'object_name'. The function should have the following signature:

def function_name(self, cr, uid, ids, context=None):


Where ids will be the ids of records in the other object's table that have changed values in the watched
fields. The function should return a list of ids of records in its own table that should have the field
recalculated. That list will be sent as a parameter for the main function of the field.

!
Here's an example from the membership module:
!
!

'membership_state':
fields.function(
_membership_state,
method=True,
string='Current membership state',
type='selection',
selection=STATE,
store={
'account.invoice': (_get_invoice_partner, ['state'], 10),
'membership.membership_line': (_get_partner_id,['state'], 10),
'res.partner': (
lambda self, cr, uid, ids, c={}: ids,
['free_member'],
10)
}),

Functions

Important Module Creation functions

#POPUP CONSOLE LOG


raise osv.except_osv('Test',context.get('active_ids', False) )

!
!
!
!
decode(replace(encode(m.image,'escape')::text,E'\012',''),'base64') as picture
!
!
!
!

!
!
!
!
!
!

def onchange_discount(self, cr, uid, ids, regular_price, default_discount, addl_discount):


res = {}
default_discount_price = regular_price - (regular_price * default_discount/100)
res['default_discount_amount'] = regular_price * default_discount/100
res['addl_discount_amount'] = default_discount_price * addl_discount/100
res['list_price'] = default_discount_price - (default_discount_price * addl_discount/100)
return {'value':res}
def onchange_city(self, cr, uid, ids, city_id, context=None):
if city_id:
state_id=self.pool.get('res.country.city').browse(cr, uid, city_id, context).state_id.id
zip_code=self.pool.get('res.country.city').browse(cr, uid, city_id, context).zip
country_id=self.pool.get('res.country.state').browse(cr, uid, state_id, context).country_id.id
return {'value':{'state_id':state_id,'country_id':country_id, 'zip':zip_code}}
return {}

if context is None:
context = {}
po = self.browse(cr, uid, ids[0], context=context)
current_user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
irmr_obj = self.pool.get('asi.irmr')
context.pop('default_state', False)

Functions
!
!
!

!
!
!

Populate a Many2many records

def assign_to_dr(self, cr, uid, ids, context=None):


obj_stock_move = self.pool.get('stock.move')
obj_delivery_batch = self.pool.get('delivery.batch')
if context is None:
context = {}
# Get the values(_columns) from the wizard
for wizard in self.browse(cr, uid, ids, context=context):
rec_ids = context.get('active_ids', False)
dr = {
'actual_delivery_date' : wizard.actual_delivery_date,
'truck_number' : wizard.truck_number,
'delivery_seq' : wizard.delivery_seq,
'shipping_address' : wizard.shipping_address,
'stock_ids': [(6, 0, rec_ids)],
}
#Create a Delivery Batch based on the vaules in the form
dr_id = obj_delivery_batch.create(cr, uid, dr, context=context)

The stock_ids field is a many-to-many relationship, and the (6, 0, tax_ids) means to replace any existing records with those in stock_move.
Because you're calling create(), there's nothing to replace.

!
A full list of options is in the documentation for the osv class.
!
For a many2many field, a list of tuples is expected. Here is the list of tuple that are accepted, with the corresponding semantics
!
(0, 0, { values }) link to a new record that needs to be created with the given values dictionary
!
(1, ID, { values }) update the linked record with id = ID (write values on it)
!

(2, ID) remove and delete the linked record with id = ID (calls unlink on ID, that will delete the object completely, and the link to it as
well)

(3, ID) cut the link to the linked record with id = ID (delete the relationship between the two objects but does not delete the target object
itself)

!
(4, ID) link to existing record with id = ID (adds a relationship)
!
(5) unlink all (like using (3,ID) for all linked records)
!
(6, 0, [IDs]) replace the list of linked IDs (like using (5) then (4,ID) for each ID in the list of IDs)
!
Add aMany2many values
'tax_id': [[6, False, taxes_id]], where taxes_id=[] taxes_id.append()

Functions

sum function for relational fields

class asi_irmr(osv.Model):
_name = "asi.irmr"

def get_result(self, cr, uid, ids, context=None):


total = {}
for obj in self.browse(cr, uid, ids, context=context):
total[obj.id] = sum(o2m.float_field for o2m in obj.o2m_field)
return total
def total_irmr_line(self, cr, uid, ids, field, arg, context=None):
total = {}
for current_obj in self.browse(cr, uid, ids, context=context):
total[current_obj.id] = sum(related_obj.quantity for related_obj in current_obj.irmr_line_ids)
return total
_columns = {
'po_id' : fields.char('POID', size=254),
'irmr_line_ids' : fields.one2many('asi.irmr_line','irmr_id', 'LOT'),
'total_irmr_line' : fields.function(total_irmr_line,type='float', string='Total IRMR'),
}

class asi_irmr_line(osv.Model):
_name = "asi.irmr_line"
_columns = {
'co_number' : fields.char('CO Number', size=254),
'quantity' : fields.float('Quantity', required="True"),
}

View

Important View functions

Specify a view to use


# You may define a custom tree view with the fields you want to show and explicitly use it for your many2many field
# doc.openerp.com/v6.0/developer/2_6_views_events/views/specify_view_to_use.html

<field name="order_line" colspan="4" nolabel="1" context="{'form_view_ref' : 'module.view_id', 'tree_view_ref' :


model.view_id'}"/>
# where 'tree_view_ref' points to your custom tree view

!
#display a different namein the selection
!
<field name="pos_config_id" widget="selection" eval="ref('pos.config.name')" />
!
!
!

#Compute for Gross Proceeds = installment_amt x 1000 / rate (Proceeds Rate)


cr.execute("SELECT rate FROM lending_rate_proceed WHERE rate_id=%s AND term=%s",(rate_id,terms))
result = cr.fetchone()
if result:
gross_proceeds = installment_amt*1000/result[0]
else:
gross_proceeds = 0

Module

account_invoice_state.py
from
from
from
from

openerp.osv import osv


openerp.tools.translate import _
openerp import netsvc
openerp import pooler

class account_invoice_confirm(osv.osv_memory):
"""
This wizard will confirm the all the selected draft invoices
"""

!
!
!
!

Add a function/action to the


More drop down

_name = "account.invoice.confirm"
_description = "Confirm the selected invoices"
def invoice_confirm(self, cr, uid, ids, context=None):
wf_service = netsvc.LocalService('workflow')
if context is None:
context = {}
pool_obj = pooler.get_pool(cr.dbname)
data_inv = pool_obj.get('account.invoice').read(cr, uid, context['active_ids'], ['state'], context=context)
for record in data_inv:
if record['state'] not in ('draft','proforma','proforma2'):
raise osv.except_osv(_('Warning!'), _("Selected invoice(s) cannot be confirmed as they are not in 'Draft' or 'Pro-Forma' state."))
wf_service.trg_validate(uid, 'account.invoice', record['id'], 'invoice_open', cr)
return {'type': 'ir.actions.act_window_close'}

account_invoice_confirm()

account_invoice_state_view.xml
!

<!-- Create a new action in the More dropdown

-->

<record id="account_invoice_confirm_view" model="ir.ui.view">


<field name="name">account.invoice.confirm.form</field>
<field name="model">account.invoice.confirm</field>
<field name="arch" type="xml">
<form string="Confirm Draft Invoices" version="7.0">
<p class="oe_grey">
Once draft invoices are confirmed, you will not be able to modify them. The invoices will receive a unique
number and journal items will be created in your chart of accounts.
</p>
<footer>
<button string="Confirm Invoices" name="invoice_confirm" type="object" default_focus="1" class="oe_highlight"/>
or <button string="Cancel" class="oe_link" special="cancel"/>
</footer>
</form>
</field>
</record>
<act_window id=action_account_invoice_confirm"
multi="True"
key2="client_action_multi" name="Confirm Draft Invoices"
res_model="account.invoice.confirm" src_model="account.invoice"
view_mode="form" target="new" view_type="form" />

Module
Create a new module

<?xml version="1.0" encoding="utf-8" ?>


<openerp>
<data>
<!-- Full User Interface Template -->
<record id="model_name_action" model="ir.actions.act_window">
<field name="name">model.name.action</field>
<field name="res_model">model.name</field>
<field name="view_mode">tree,form</field>
</record>

from osv import osv, fields


class idea(osv.Model):
_name = 'idea.idea'
_columns = {
'name': fields.char('Title', size=64, required=True, translate=True),
}
_defaults = {
'active': True, # ideas 'state': 'draft', # ideas
}

!!

def _check_name(self,cr,uid,ids):
for idea in self.browse(cr, uid, ids):
if 'spam' in idea.name: return False # Can't create ideas with spam!
return True
_sql_constraints = [('name_uniq','unique(name)', 'Ideas must be unique!')]
_constraints = [(_check_name, 'Please avoid spam in ideas !', ['name'])]

Create Secondary View:

<record id="irmr_line_tree2" model="ir.ui.view">


<field name="name">asi.irmr_line.tree2</field>
<field name="model">asi.irmr_line</field>
<field name="priority" eval="18"/>
<field name="arch" type="xml">
<tree string="BIN Card">
<field name="product_id"/>
<field name="lot_number"/>
<field name="co_number"/>
<field name="quantity"/>
<field name="remaining_qty"/>

!
!

</tree>
</field>
</record>

<record id="model_name_tree" model="ir.ui.view">


<field name="name">model.name.tree</field>
<field name="model">model.name</field>
<field name="arch" type="xml">
<tree string="Title">
<field name=""/>
</tree>
</field>
</record>
<record id="model_name_form" model="ir.ui.view">
<field name="name">model.name.form</field>
<field name="model">model.name</field>
<field name="arch" type="xml">
<form string="Form Name" version="7.0">
<header>
<button name="state_quality"
string=Quality"
type=object"
class="oe_highlight"/>
<field name="state" widget="statusbar"
statusbar_visible="draft,quality,released"/>
</header>
<sheet>
<group>
<field name=""/>
</group>
</sheet>
</form>
</field>
</record>
<record id="model_name_search" model="ir.ui.view">
<field name="name">model.name.search</field>
<field name="model">model.name</field>
<field name="arch" type="xml">
<search string="Title">
<field name="area" />
<group string="Group by ...">
<filter string="Area" name="area"
domain="[]" context="{'group_by':'area'}" />
</group>
</search>
</field>
</record>
<menuitem id="sidebar_menu"
parent="parent.menu"
name="MenuName" sequence="3"/>
<menuitem id="action_menu"
parent="sidebar_menu"
action="model_name_action"
name="Sidebar Link Name" sequence="8"/>

</data>
</openerp>

Module
Modify Existing Forms

<!-- Modify an Existing Form -->


<record model="ir.ui.view" id="model_name_form">
<field name="name">model.name.form</field>
<field name="model">model.name</field>
<field name="inherit_id" ref="external_id" />
<field name="arch" type="xml">
<field name='journal_id' position='before'>
<field name="card_name"/>
</field>
<xpath expr="//field[@name='name_of_field']/tree" position="attributes">
<attribute name="colors">red:product_qty==0</attribute>
# Note: Don't forget to do xml escaping when appropriate (> == &gt; < == &lt;).
</xpath>
</field>
</record>

Module
Modify Existing Forms

!!

!
!

<!-- Full User Interface Template -->


<record id="model_name_action" model="ir.actions.act_window">
<field name="name">model.name.action</field>
<field name="res_model">model.name</field>
<field name="view_mode">tree,form</field>
</record>
<record id="model_name_tree" model="ir.ui.view">
<field name="name">model.name.tree</field>
<field name="model">model.name</field>
<field name="arch" type="xml">
<tree string="Title">
<field name=""/>
</tree>
</field>
</record>
<record id="model_name_form" model="ir.ui.view">
<field name="name">model.name.form</field>
<field name="model">model.name</field>
<field name="arch" type="xml">
<form string="Form Name" version="7.0">
<header>
<button name="state_quality" string="Quality" type="object" class="oe_highlight"/>
<field name="state" widget="statusbar" statusbar_visible="draft,quality,released"/>
</header>
<sheet>
<group>
<field name=""/>
</group>
</sheet>
</form>
</field>
</record>
<record id="model_name_search" model="ir.ui.view">
<field name="name">model.name.search</field>
<field name="model">model.name</field>
<field name="arch" type="xml">
<search string="Title">
<field name="area" />
<group string="Group by ...">
<filter string="Area" name="area" domain="[]" context="{'group_by':'area'}" />
</group>
</search>
</field>
</record>
<menuitem id="sidebar_menu" parent="parent.menu" name="MenuName" sequence="3"/>
<menuitem id="action_menu" parent="sidebar_menu" action="model_name_action" name="Sidebar Link Name" sequence="8"/>

Module
Map a view to a particular action
You have to map your action with particular tree,form view.

!
!

Try this:
<record model="ir.actions.act_window" id="action_my_hr_employee_seq">
<field name="name">Angajati</field>
<field name="res_model">hr.employee</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>

<record model="ir.actions.act_window.view" id="act_hr_employee_tree_view">


<field eval="1" name="sequence"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="your_tree_view_id"/>
<field name="act_window_id" ref="action_my_hr_employee_seq"/>
</record>

<record model="ir.actions.act_window.view" id="act_hr_employee_form_view">


<field eval="2" name="sequence"/>
<field name="view_mode">form</field>
<field name="view_id" ref="your_form_view_id"/>
<field name="act_window_id" ref="action_my_hr_employee_seq"/>
</record>

<!-Here is the first view for the model 'client'.


We don't specify a priority field, which means
by default 16.
-->
<record model="ir.ui.view" id="client_form_view_1">
<field name="name">client.form.view1</field>
<field name="model">client</field>
<field name="type">form</fiel>
<field name="arch" type="xml">
<field name="firstname"/>
<field name="lastname"/>
</field>
</record>

<!-A second view, which show fields in an other order.


We specify a priority of 15.
-->
<record model="ir.ui.view" id="client_form_view_2">
<field name="name">client.form.view2</field>
<field name="model">client</field>
<field name="priority" eval="15"/>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="lastname"/>
<field name="firstname"/>
</field>
</record>

Module
Disable Create Button on Openerp
You can remove the Create Button by adding attributes to your form in view.xml file:

<record ...>
...
<form string="NAMEOFFORM" create="false" edit="false" version="7.0">
...
</form>
</record>
This way "Edit" and "Create" are removed from view for all Users.

!
!

In case you inherit from an existing view:


<record>
...
<field name="arch" type="xml">
<xpath expr='//form[@string="Product"]' position='attributes'>
<attribute name="create">false</attribute>
</xpath>
</field> ,
</record>

Module
Create A Sequence

<record forcecreate="1" id="seq_type_id" model="ir.sequence.type">


<field name="name">Name</field>
<field name="code">code</field>
</record>

<record forcecreate="1" id="seq_id" model="ir.sequence">


<field name="name">Name</field>
<field name="code">code</field>
<field name="padding" eval="pading"/>
<field name="prefix">prefix</field>
<field name="suffix">suffix</field>
</record>

!!
!!

_defaults = {
'field_name': lambda self,cr,uid,context={}: self.pool.get('ir.sequence').get(cr, uid, 'code'),
}

Module
Close a windows on click

return {'type': 'ir.actions.act_window_close'}

Module
Create a default Filter

!!
!!

<record id="irmr_action" model="ir.actions.act_window">


<field name="name">Incoming Raw Materials Report</field>
<field name="res_model">asi.irmr</field>
<field name="context">{"search_default_filter_quality":1}</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>

<record id="irmr_search" model="ir.ui.view">


<field name="name">asi.irmr.search</field>
<field name="model">asi.irmr</field>
<field name="arch" type="xml">
<search string="IRMR">
<field name="product_id"/>
<field name="supplier_id"/>
<group string="Group by ...">
<filter string="Quality" name="filter_quality" icon="terp-accessories-archiver-minus" domain="[('state','=','quality')]"/>
</group>
</search>
</field>
</record>

Module
Populate model from select statement
class account_populate(osv.osv_memory):
_name = 'account.populate'
_description = 'Account Parent'

!
!
!

!
!!
!!
!!
!!

def populate_accounts(self, cr, uid, ids, context=None):


res = {}
self = self.browse(cr, uid, ids[0], context=context)
fsline_obj = self.pool.get('account.fs.line')
cr.execute("select ac.id,ac.level\
FROM account_account ap\
JOIN account_account ac\
ON ac.parent_left between ap.parent_left and ap.parent_right\
WHERE ap.id = %s\
ORDER BY ac.parent_left",
(self.account.id,))
act=cr.fetchall()
sort = 1
for x in act:
res = {
'sort': sort,
'account': x[0],
'fs_id': context and context.get('active_id', False) or False,
}
sort += 1
fsline_obj.create(cr, uid, res, context=context)
return True
_columns ={
'account' : fields.many2one('account.account','Parent Account'),
}

#Compute for the totals of all items


cr.execute("select SUM(am.debit) - SUM(am.credit) as balance\
FROM account_account ap\
JOIN account_account ac ON ac.parent_left between ap.parent_left and ap.parent_right\
LEFT JOIN account_move_line am ON am.account_id = ac.id\
WHERE ap.id = %s AND am.date between %s::DATE AND %s::DATE",
(fs.account.id,self.date_from,self.date_to))
result = cr.fetchone()
if result:
res['balance'] = result[0]
else:
res['balance'] = 0

Module
Postgres search
WHERE (ml."date" BETWEEN ${date_from} AND ${date_to})
AND ml.account_id = ANY (translate(${code},'[]','{}')::int[])
)ORDER BY date ASC,journal_name ASC

Reference Parent field


<record id="asi_stock_move_lot_form" model="ir.ui.view">
<field name="name">asi.stock.move.lot.form</field>
<field name="model">stock.move</field>
<field name="type">form</field>
<field name="priority" eval="18"/>
<field name="arch" type="xml">
<form string="Stock Move" version="7.0">
<sheet>
<group>
<field name="origin"/>
<field name="sale_line_id"/>
<field name="product_id" readonly="1"/>
<field name="product_qty_ref" readonly="1"/>
<!-- <field name="product_qty"/>-->
</group>
<notebook>
<page string="Delivered LOTs">
<field name="bincard_line_ids">
<tree editable="top">
<field name="product_id" invisible="1"/>
<field name="lot_id" domain="[('product_id','=',parent.product_id)]"/>
<field name="quantity"/>
</tree>
</field>
</page>
</notebook>
</sheet>
</form>
</field>
</record>

Module
Open a Wizard view by getting its own ID
<record model="ir.ui.view" id="survey_page_wizard_test1">
<field name="name">survey_page_wizard_test</field>
<field name="model">survey.page</field>
<field name="priority">20</field>
<field name="arch" type="xml">
<form string="Survey Pages">
<field name="title" colspan="4"/>
<field name="sequence"/>
<separator string="Description" colspan="4"/>
<field name="note" colspan="4" nolabel="1"/>
<group colspan="4">
<label string="" colspan="3"/>
<button name="survey_save" string="Ok" type="object"
icon="gtk-go-forward"/>
</group>
</form>
</field>
</record>

def action_new_question(self, cr, uid, ids, context=None):


"""
New survey.Question form.
"""
if context is None:
context = {}
for key,val in context.items():
if type(key) == type(True):
context.pop(key)
view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question'),\
('name','=','survey_question_wizard_test')])
return {
'view_type': 'form',
"view_mode": 'form',
'res_model': 'survey.question',
'type': 'ir.actions.act_window',
'target': 'new',
'view_id': view_id,
'page_id': int(context.get('page_id',0)),
'context': context
}
def action_new_page(self, cr, uid, ids, context=None):
"""
New survey.Page form.
"""
if context is None:
context = {}
for key,val in context.items():
if type(key) == type(True):
context.pop(key)
view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.page'),\
('name','=','survey_page_wizard_test')])
return {
'view_type': 'form',
"view_mode": 'form',
'res_model': 'survey.page',
'type': 'ir.actions.act_window',
'target': 'new',
'view_id': view_id,
'context': context
}

Module

Pass value to method

<button name="add_lot" icon="STOCK_DND_MULTIPLE" type="object" class="oe_highlight" help="Done"


context={'lot_nos':lot_nos,}"/>

!!
!!
!

def add_lot(self, cr, uid, ids, context=None):


print ids

!!
!!

this = self.browse(cr, uid, ids[0], context=context)


view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','add.wirf.lot'),('name','=','add.wirf.lot.form')])
res = {
'view_type': 'form',
"view_mode": 'form',
'res_model': 'add.wirf.lot',
'type': 'ir.actions.act_window',
'target': 'new',
'view_id': view_id,
'context': context
#print this
return res

class add_wirf_lot(osv.osv_memory):
"""
Get
"""
_name = 'add.wirf.lot'
_description = 'Combine to Wirf'

!
!
!!
!

def combine_to_wirf(self, cr, uid, ids, context=None):


stock_move_obj = self.pool.get('stock.move')
return True
def _get_default_objects(self, cr, uid, context=None):
return context.get('lot_nos', False)
_columns = {
'name' : fields.char('Name'),
'move_id': fields.many2one('stock.move','Stock Move Reference'),
'product_id': fields.related('move_id','product_id', type='many2one', relation='product.product', string='Product'),
'lot_ids': fields.many2many('asi.production.lot','asi_wirflot_prodlot_rel','wirflot_id','prodlot_id', 'Lot IDs'),
}
_defaults ={
'name': _get_default_objects
}

Module

OVERRIDE AN EXISTING FUNCTION

you need to overide the onchange function(you can use super() ) for the field 'product_id' and update the
result. for example

def onchange_product(self,cr,uid,ids,product_id,context=None):
values = super(<your_class_name>,self).onchange_product(cr, uid,ids,product_id,context=context)
# values will be a dictionary containing 'value' as a key.
# You need to add all the newly added related fields and other fields to the values['value'].
# if 'aaa' is the newly added field, then values['value'].update({'aaa':<value for aaa>})
# then return values
return values

!
!
modify
!

you onchange to the following

def onchange_product_id(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id,


partner_id, date_order=False, fiscal_position_id=False, date_planned=False,
name=False, price_unit=False, context=None):
values = super(purchase_order_line_custom, self).onchange_product_id(cr, uid, ids, pricelist_id,
product_id, qty, uom_id, partner_id, date_order, fiscal_position_id, date_planned,name, price_unit,
context=context)
if product_id:
product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
values['value'].update({
'product_type' : product.product_type,
'product_subtype' : product.product_subtype,
'qualified_name' : product.qualified_name,
'count_id' : product.count_id
})
return values

Module

Domain Filtering

Simple condition in programming:

!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!

if field1 = 10
In OpenERP domain filter, it will be written as:
syntax : Each tuple in the domain has three fields ->

('field_name', 'operator', value)

field_name : a valid name of field of the object model or in the database table
operator : valid operators are =, !=, >, >=, <, <=, like, ilike, in, not in, child_of, parent_left, parent_right (openerp/osv/expression.py)
value : a valid value to compare with the values of field_name, depending on its type.
ie, domain = [('field1','=',10)] # where field1 should be a field in the model and 10 will be the value
or domain = [('field1','=',field2)] # where field1 and field2 should be the fields in the model
Condition AND
Simple condition in programming:
if field1 = 5 and field2 = 10
In OpenERP domain filter, it will be written as:
ie, domain = [('field1','=',5),('field2','=',10)]
or domain = [('field1','=',field3),('field1','=',field3)]
Note : Note that if you don't specify any condition at the beginning and condition will be applied.
Condition OR
Simple condition in programming:
if field1 = 5 or field2 = 10
In OpenERP domain filter, it will be written as:
ie, domain = ['|', ('field1','=',5),('field2','=',10)]
or domain = ['|', ('field1','=',field3),('field1','=',field3)]

Multiple Condition
Simple condition in programming:
if field1 = 5 or (field2 ! = 10 and field3 = 12)
In OpenERP domain filter, it will be written as:
domain = ['|',('field1','=',5),('&',('field2','!=',10),('field3','=','12'))]

SUPER
!
!
!

Domain Filtering

def write(self, cr, uid, ids, vals, context=None):


student = self.pool.get('lsgh.student')
# if student_id has been changed, update alias_model_id accordingly
if vals.get('student_id'):
print vals.get('student_id')
student_with_this_partner = student.search(cr, uid, [('partner_id','=',vals.get('id'))], context=context)
student.write(cr, uid, student_with_this_partner, {'partner_id': False})
student.write(cr, uid, student_id, {'partner_id': vals.get('id')})
else:
student_with_this_partner = student.search(cr, uid, [('partner_id','=',vals.get('id'))], context=context)
student.write(cr, uid, student_with_this_partner, {'partner_id': False})
return super(lsgh_res_partner, self).write(cr, uid, ids, vals, context=context)
def create(self, cr, uid, vals, context=None):
if vals.get('student_id'):
print vals.get('student_id')
return super(lsgh_res_partner, self).create(
cr, uid, vals, context=None)

WARNING Domain Filtering


raise osv.except_osv('Test',context.get('active_ids', False) )

!!

def on_change_method(self, cr, uid, ids, field_name, field_value2,..., context):


#The result will be stored in a dictionary
res = {}
#Now you can change other fields with the updated values passed as parameters
res['field_name_3'] = field_value2
warning = {
'title': _("Warning"),
'message': _('Warning message'),
}
return {'value': res.get('value',{}), 'warning':warning}

!!

<button name="student_no_reset" string="Reset Student Number"


type="object" attrs="{'invisible': [('is_student_no_reset','==', True)]}"
class="oe_inline" confirm="Are you sure you want Reset the Student Number? WARNING: This CANNOT be undone"/>

Modify form inherit


from openerp.osv import fields,osv
from openerp import tools

!!

class prostar_account_move(osv.Model):
_inherit = "account.move"
_columns = {
'jv_num': fields.char('JV Number'),
}

!!

<record id="x_tree" model="ir.ui.view">


<field name="name">x.tree</field>
<field name="model">x</field>
<field name="inherit_id" ref=""/>
<field name="arch" type="xml">
<field name="" position="">
<field name=""/>
</field>
</field>
</record>
<record id="x_form" model="ir.ui.view">
<field name="name">x.form</field>
<field name="model">x</field>
<field name="inherit_id" ref=""/>
<field name="arch" type="xml">
<field name="" position="">
<field name=""/>
</field>
</field>
</record>

<record id="x_search" model="ir.ui.view">


<field name="name">x.search</field>
<field name="model">x</field>
<field name="inherit_id" ref=""/>
<field name="arch" type="xml">
<field name="filter">
<field name="area" />
<group string="Group by ...">
<filter string="Area" name="area" domain="[]"
context="{'group_by':'area'}" />
</group>
</field>
</field>
</record>

Vous aimerez peut-être aussi