How to Get The field value dynamically in python? - python

I have a form view. I entered a value in a field. How can i retrieve that value and have it assigned to some variable in .py for making operations
For Example:
I have ActiveFrom field.I entered value 23-11-2011 to field in form view. I want to get that value dynamically in openerp. How can I do that?

I suspect you want the on_change event. It lets you trigger server-side code when the user changes a field's value. You can then change the value of other fields, or pop up a warning message.
Here's an example of how to pop up a warning from the warning module (slightly edited):
def onchange_partner_id(self, cr, uid, ids, part):
warning = {}
title = False
message = False
partner = self.pool.get('res.partner').browse(cr, uid, part)
if partner.sale_warn != 'no-message':
title = _("Warning for %s") % partner.name
message = partner.sale_warn_msg
warning = {
'title': title,
'message': message,
}
result = super(sale_order, self).onchange_partner_id(cr, uid, ids, part)
return {'value': result.get('value',{}), 'warning':warning}

Related

Set default value of field depends on other field in odoo

I am setting up default value of analytics_id in account.move.line by below code
class account_move_line(models.Model):
_inherit = 'account.move.line'
_name = "account.move.line"
def _get_default_account(self, cr, uid, context=None):
obj = self.pool.get('account.move')
value = obj.browse(cr, uid, uid)
if value.move_id.debit>0 or value.move_id.credit<0:
res = self.pool.get('account.analytic.plan.instance').search(cr, uid, [('code','=','LAL')], context=context)
return res and res[0] or False
_defaults = {
'analytics_id': _get_default_account,
}
it is working well for me but now i want to set this default value if debit field value is greater then zero OR credit field value less then zero otherwise analytics_id field remain empty.
Try to use this type of code
res = self.pool.get('account.analytic.plan.instance').search(cr, uid, [('code','=','LAL')], context=context)
if res:
br_analytic_plan=self.pool.get('account.analytic.plan.instance').browse(cr,uid,res[0],context=context)
if ---your Condition---- # You can access For example. br_analytic_plan.amount > 0
return res[0]
This same logic you can apply to both groups condition (it means under if and else on your current code).
Hope this helps.

What is difference between self.pool['res.partner'] and self.pool.get('res.partner')

What is main difference between following :
self.pool['res.partner'].browse(cr, uid, partner_id, context=context)
and
self.pool.get('res.partner').browse(cr, uid, partner_id, context)
As per my understanding both returns single record of type res.partner if partner_id e.g. 1
Then why it is used like this.
if self.pool is a dictionary (I hope :) ) then self.pool['res.partner'] will raise an exception (KeyError) if the 'res.partner' is not present in that dictionary.
self.pool.get('res.partner') in the same case will return default value (which is None).
If you want to specify a different default value, you can do it like that: self.pool.get('res.partner',some_def_value).

Onchange field not working OpenERP

I'm trying to show a res.partner field, which is called phone into the treeview of a sale.order.
But it is not showing anything, just the name of the field without data. This is my code on sale.order
phone : fields.char('Telefono del Cliente'),
Onchange function for this field:
def onchange_phone(self, cr, uid, ids, phone, context=None):
res = {}
if phone:
obj = self.pool.get('res.partner')
browse(cr, uid, phone)
res['phone'] = obj.phone
return {'value' : res}
On res.partner the field is also called phone which is obviously the client's phone, i need to show it on the sale.order treeview, this is the code on my sale_view.xml:
<field name="phone" on_change="onchange_phone(phone)"/>
Any ideas?
Thanks in advance.
As a suggestion, If you want phone number of partner, than you should not create on_change of phone field. You can get phone number in 2 ways.
First way and best way, In sale.order, onchange_partner_id() method is their, you need to override that method and update vals with phone number of partner.
And Second way and long way, You may override create() method and write() method of sale.order.
create() method trick:
in create() method, you can take partner id from the context. For example vals.get('partner_id')
write() method trick:
in write() method, you have id of created record so you need to simply browse that record and write phone number of partner.
As Odedra suggested, you should do this like so (this is taken from sale.py file):
def onchange_partner_id(self, cr, uid, ids, part, context=None):
if not part:
return {'value': {'partner_invoice_id': False, 'partner_shipping_id': False, 'payment_term': False, 'fiscal_position': False}}
part = self.pool.get('res.partner').browse(cr, uid, part, context=context)
addr = self.pool.get('res.partner').address_get(cr, uid, [part.id], ['delivery', 'invoice', 'contact'])
pricelist = part.property_product_pricelist and part.property_product_pricelist.id or False
payment_term = part.property_payment_term and part.property_payment_term.id or False
fiscal_position = part.property_account_position and part.property_account_position.id or False
dedicated_salesman = part.user_id and part.user_id.id or uid
phone = part.phone or False
val = {
'partner_invoice_id': addr['invoice'],
'partner_shipping_id': addr['delivery'],
'payment_term': payment_term,
'fiscal_position': fiscal_position,
'user_id': dedicated_salesman,
'phone': phone,
}
if pricelist:
val['pricelist_id'] = pricelist
return {'value': val}
Note that you should not do that on base module, but instead create your own module and inherit it to sale.order model. What is more, onchange will not work on tree view (like you suggested), but you can easily show it on the tree - you have to first put it on your form with the onchange provided, then modify tree view to show phone number.

Onchange function in Openerp

I have a selection field in account.invoice.line named form_type. It has three selection options:
1) form_a
2) form_b
3) form_c
There is also an integer field named flag in account.invoice.line. When form_c is selected, the flag value should be set to 1; otherwise, if either form_a or form_b is selected, the flag value should be set to 0. I wrote an onchange function for the above case but it's not working. Can someone help me out? What is wrong in my code?
def onchange_form_type(self, cr, uid, ids, invoice, context=None):
val={}
flag=0
invoice = self.pool.get('account.invoice.line').browse(cr, uid, invoice)
for invoice in self.browse(cr, uid, ids, context=context):
if invoice.form_type=="form_c":
flag="1"
else:
flag="0"
print flag
val = { 'flag': flag, }
return {'value': val}
My XML code in account.invoice.line for onchange is:
<field name="form_type" on_change="onchange_form_type(form_type)"/>
In your on-change function you don't need to call the browse function of the object, because the values are not stored in the database yet. Also, you are passing the "form_type" value to the function and not the object id(as browse accepts object id).
So, below will be the on_change function, for the expected requirement:
def onchange_form_type(self, cr, uid, ids, form_type, context=None):
val={}
flag=0
if form_type == 'form_c':
flag="1"
val = { 'flag': flag }
return {'value': val}

OpenERP: get the database and show it in form

I do a project about Timesheet in OpenERP. I have this problem:
this is x_luong table.
class x_luong(osv.osv):
_name = 'x_luong'
_description = 'Luong'
_columns = {'name': fields.many2one('x_nhanvien', 'Mã nhân viên', size=10, required='1'),
'ma_luong': fields.integer('ma luong', size=10, required='1'),
'giolam': fields.float('Giờ làm', size=100, required='1'),
'giolamthuc': fields.char('Gio lam thuc te', size=5, required='1'),
'time_in': fields.char('Gio vào', size=20),
'time_out' :fields.char('Gio về', size=20),
'state' :fields.selection([('dangnhap','Đẳng nhập.'),('rave','Ra về')]),
'test': fields.integer('Kiem tra', size=20),
'phutvao': fields.integer('Phut vao ', size=20),
'phutra': fields.integer('phut ra', size=20),
}
_defaults = {'state':'dangnhap',
}
and this some function in it:
this 2 function mean get time when the staff sign_in or sign_out the system:
def get_timein(self,cr,uid,ids,context={}):
obj = self.browse(cr,uid,ids,context=context)[0]
timein = str(datetime.now())
self.write(cr, uid, ids, {'time_in':timein }, context=context)
return 1
def get_timeout(self,cr,uid,ids,context={}):
obj = self.browse(cr,uid,ids,context=context)[0]
timeout = str(datetime.now())
self.write(cr, uid, ids, {'time_out':timeout }, context=context)
return 1
and this 2 function for button sign_in and sign_out:
def cho_dangnhap(self,cr,uid,ids,context={}):
self.pool.get('x_luong').write(cr,uid,ids,{'state':'dangnhap'})
self.get_timein(cr,uid,ids)
return 1
def cho_rave(self,cr,uid,ids,context={}):
self.pool.get('x_luong').write(cr,uid,ids,{'state':'rave'})
self.get_timeout(cr,uid,ids)
self.tinh_thoigian(cr,uid,ids)
self.insert(cr,uid,ids)
function tinh_thoigian mean cut the string time for get ... hour or min for calculation
def _thoigianlam(self,cr,uid,ids,context={}):
obj = self.browse(cr,uid,ids,context=context)[0]
hour_den = int(obj.time_in[12:13])
hour_di = int(obj.time_out[12:13])
min_den = int(obj.time_in[15:16])
min_di = int(obj.time_out[15:16])
gl = int(hour_di)-int(hour_den)
pl = min_di-min_den
thucte = str(gl)+':'+pl
self.write(cr, uid, ids, {'giolam':gl }, context=context)
self.write(cr, uid, ids, {'giolamthuc':thucte }, context=context)
return 1
and last function insert() get ma_luong(i think this same the primary key in sql) and giolam(the hour of the staff work in company), time_in, time_out and this is function insert()
def insert(self,cr,uid,ids,context={}):
obj = self.browse(cr,uid,ids,context=context)
values = {'ma_luong':obj.name.id,
'giolam':obj.giolam,
'time_in':time_in,
'time_out':time_out,
self.pool.get('x_giolam').create(cr,uid,values,context=context)
with this function i want insert data in table x_giolam because when the staff sign in or sign out the system in day ... the data of it with save in this table and a other day when they do it again it with save it again ... and last month if you want calculation about salary of them you just select ma_luong=ma_luong(of table x_luong) and this table x_giolam:
class x_giolam(osv.osv):
_name = 'x_giolam'
_description = 'Gio Lam'
_columns = {'name': fields.integer('Lọai',size=64,required="true"),
'giolam' : fields.float('Gio lam',size=64,required="True"),
'time_in': fields.char('Gio vào',size=20),
'time_out' :fields.char('Gio về',size=20),
}
and i have 3 question with my project:
1) function insert have aerror:
AttributeError: 'browse_record_list' object has no attribute 'name'
How can i fix it ??? i data of it is save in table x_giolam
2) how can i select many row of table x_giolam which of thte employee' own.. give me some example about this function
3) how i can organization field.Xml when i show rows in
Sorry for your troubles because it is so long ... but i hope every body in here can help me. Python and open Erp so difference with c++ or c#. And this my project"research and write a module timesheet with OpenErp" of me and next week is deadline.
English of me not good, i'm sory about it!!!
Thanks!!
I can help with your first question. The problem is in this code:
def insert(self,cr,uid,ids,context={}):
obj=self.browse(cr,uid,ids,context=context)
values={'ma_luong':obj.name.id,
The error message was like this:
AttributeError: 'browse_record_list' object has no attribute 'name'
If you call orm.browse() with a list of ids, you will get back a list of browse records. You then have to enumerate through the list, or get a single entry from the list to work with.
For example:
for luong in self.browse(cr,uid,ids,context=context):
print luong.name
Or:
luongs = self.browse(cr,uid,ids,context=context)
luong = luongs[0]
print luong.name
Why don't you take a look at the standard hr_attendance module and go on from there?
For your model, the name is a reserved field name, so it would be best to keep it as achar. Try that change and see if it solves your error message.
For the other two questions, I think you should try to rephrase them a little better...
The type of obj is list of records, so for browse the list of records, you must define a one element.
in your case, you can type : obj[0].giolam --> for the giolam of the first record of obj.
forgive me for my bad english

Categories

Resources