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.
Related
I want to override a original field function in Odoo.
According to the answer here: Odoo: How to override original function
i just have to define exactly the same method as in the original model. So here is my code:
class paiement_client_difference_montant(models.Model):
_inherit="account.voucher"
#writeoff_amount=fields.Float(compute='_get_writeoff_amount')
def _get_writeoff_amount(self, cr, uid, ids, name, args, context=None):
print '_get_writeoff_amount _inherit'
if not ids: return {}
currency_obj = self.pool.get('res.currency')
res = {}
for voucher in self.browse(cr, uid, ids, context=context):
debit = credit = 0.0
sign = voucher.type == 'payment' and -1 or 1
for l in voucher.line_dr_ids:
debit += l.amount
for l in voucher.line_cr_ids:
credit += l.amount
currency = voucher.currency_id or voucher.company_id.currency_id
res[voucher.id] = currency_obj.round(cr, uid, currency, voucher.amount - sign * (credit - debit))
return res
But that code is never reached.
Any help please. Thank you.
You have to override that field again in your class, to execute this newly created method.
I want to perform a constraint on the jrestant that returns me the number of days between two dates which must also be positive.
How to make constraint on a field?
def compa_date(self,cr,uid,ids,args,fields,context=None):
res = {}
for self_brow in self.browse(cr,uid,ids,context):
if self_brow.Date_ouv_pli or self_brow.date_depot:
date_debut = datetime.strptime(self_brow.Date_ouv_pli,'%Y-%m-%d')
date_fin = datetime.strptime(self_brow.date_depot,'%Y-%m-%d')
res[self_brow.id] = (date_debut - date_fin).days
return res
_columns = {
'date_depot' : fields.date('Date dépot de soumission'),
'Date_ouv_pli' : fields.date('Date Ouverture Plis'),
'jrestant': fields.function(compa_date,string='Jours restant')
}
def _check(self, cr, uid, ids, context=None):
for product in self.read(cr, uid, ids, ['jrestant'], context=context):
if jrestant < '0' :
return False
return True
_constraints = [(_check, 'Days must be positive', ['jrestant'])]
Set store to True so the value of the functional field will be stored in the database, which allows you to set constraints on it.
'jrestant': fields.function(compa_date, string='Jours restant', store=True)
I need to do two activities in my activity method.
one is need to return value for total_workers field.but need to return ID also because its necessary requirement in OpenERP when we override that method.
then have to return 2 things.please advice me how to implement this in my form.
with one return value this is worked for both things.but need to return both.
def create(self, cr, uid, values, context=None):
name = 'CheckRoll No = ' + str(values['checkroll_no']) + ' & Gang No = ' + str(values['gang_no'])
values.update({'name': name})
total_tea_workers = 0
offer_id = super(bpl_work_offer, self).create(cr, uid, values, context=context)
tea_worker_obj = self.browse(cr, uid, offer_id, context=context) or []
tea_worker_ids = self.pool.get('bpl.selected.tea.workers.line').search(cr, uid, [('tea_line_worker_id', '=', tea_worker_obj.id)])
for tea_worker in self.pool.get('bpl.selected.tea.workers.line').browse(cr, uid, tea_worker_ids):
if tea_worker.is_selected:
total_tea_workers += 1
return {'value': {'total_workers': total_tea_workers}}
return offer_id
EDITED
I sort it out in this way.hope this will help for others
:-)
i wrote a function for my field
def _compute_workers(self, cr, uid, ids, fieldname, arg, context=None):
total_workers = total_tea_workers = total_rubber_workers = total_sundry_workers = total_other_workers = 0
res = dict.fromkeys(ids, False)
for this in self.browse(cr, uid, ids, context=context):
tea_worker_ids = self.pool.get('bpl.selected.tea.workers.line').search(cr, uid, [('tea_line_worker_id', '=', this.id)])
for tea_worker in self.pool.get('bpl.selected.tea.workers.line').browse(cr, uid, tea_worker_ids):
if tea_worker.is_selected:
total_tea_workers += 1
rubber_worker_ids = self.pool.get('bpl.selected.rubber.workers.line').search(cr, uid, [('rubber_line_worker_id', '=', this.id)])
for rubber_worker in self.pool.get('bpl.selected.rubber.workers.line').browse(cr, uid, rubber_worker_ids):
if rubber_worker.is_selected:
total_rubber_workers += 1
sundry_worker_ids = self.pool.get('bpl.selected.sundry.workers.line').search(cr, uid, [('sundry_line_worker_id', '=', this.id)])
for sundry_worker in self.pool.get('bpl.selected.sundry.workers.line').browse(cr, uid, sundry_worker_ids):
if sundry_worker.is_selected:
total_sundry_workers += 1
other_worker_ids = self.pool.get('bpl.selected.other.workers.line').search(cr, uid, [('other_line_worker_id', '=', this.id)])
for other_worker in self.pool.get('bpl.selected.other.workers.line').browse(cr, uid, other_worker_ids):
if other_worker.is_selected:
total_other_workers += 1
total_workers = total_tea_workers + total_rubber_workers + total_sundry_workers + total_other_workers
res[this.id] = total_workers
return res
i changed my integer field to functional field
'total_workers': fields.function(_compute_workers, type="integer", string="Total Workers"),
You should never return anything else in create() except the ID of the record that was created. Usually this is done by returning the result of the call to the parent via super(myclass, self).create(...) indeed.
It's not clear what you are trying to achieve with your total_workers code. If total_workers is supposed to be a computed field, you don't have to override create at all: just declare this column as a fields.function and put the code to compute it in the corresponding function.
For example:
def _compute_workers(self, cr, uid, ids, fieldname, arg, context=None):
result = dict.fromkeys(ids, False) # default result for each id
for this in self.browse(cr, uid, ids, context=context):
# let's assume you have a one2many called worker_ids
result[this.id] = len(this.worker_ids)
return result
_columns = {
'total_workers': fields.function(_compute_workers, type="integer",
string="Total Workers")
}
At this point it would be a good idea to have a good look at the OpenERP technical memento and the OpenERP framework documentation, to get an overview of the OpenERP API and how it is supposed to be used :-)
Once you have a good understanding of the structure of models, the various field types, the CRUD methods and the inheritance patterns, you should be able to quickly browse the source code of the official modules and find examples of anything you want to accomplish. This should make your life much more easier!
I think that you're doing the counting of the workers in a very inefficient manner.
You're doing your SQL filter to obtain each of the workers matching an ID, and then testing for a single flag within them.
I think it would be much more efficient to just add another criteria to your select statement.
total_tea_workers = self.pool.get('bpl.selected.tea.workers.line').search(cr, uid, [('tea_line_worker_id', '=', id), ('is_selected', '=', True)]), count=True)
I want to calculate the value of a function field using its previous value ( = value of the record with previous id)
'testrest' : fields.function(get_reste, method=True, string='Restant',type='integer'),
def get_reste(self, cr, uid, ids, field_name, arg, context):
x = {}
for record in self.browse(cr, uid, ids ,context):
if record.statut != 'entree':
x[record.id]= a + record.entree_nbr # a should be the same field for the previous record
How can I do that? thank you
First point here about OE 6.1+ and fields.function() : it does not take a method parameter anymore [ Server rev 3495 revid odo#openerp.com-20110701232328-flgxulxva70vnyxr and addons rev 4844].So please do not use the "method" parameter anymore!
Now you want to calculate the value based on previous value so what you can do is you can use store=True param here that will store your previous value in data now in your calculation for your record you can read previous value and calculate new value and return it.
'testrest' : fields.function(get_reste, store=True, string='Restant',type='integer'),
def get_reste(self, cr, uid, ids, field_name, arg, context):
x = {}
for record in self.browse(cr, uid, ids ,context):
if record.statut != 'entree':
x[record.id]= record.testrest + record.entree_nbr
return x
Here benefit of string will be you can use this value any where out side OE or fro some external reporting tool and you can even expoer this field.
Hope this will help.
Some More Code :
'price': fields.function(_price_get, method=True, string="Price", store=True),
def get_reste(self, cr, uid, ids, field_name, arg, context):
x = {}
a = 0.0
for record in self.browse(cr, uid, ids ,context):
if record.statut != 'entree':
x[record.id]= a + record.entree_nbr
a =record.testrest
return x
If you need you can sort the list of ids by ids.sort()
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}