how to write a value into sales orderlines using button - odoo-8

i would like to add values to a field(ship) in sales orderlines using a button when i tring below mentioned code i got error Expected singleton: sale.order.line(41, 42)
def writes(self, cr, uid, ids, context=None):
sale_order_obj = self.browse(cr, uid, ids, context=context)
sale_order_line_obj = self.pool.get('sale.order.line')
sale_obj=sale_order_obj.order_line
for line in sale_obj:
sale_order_line_obj.write(cr, uid, line.id, {'ship': sale_obj.ship.id}, context=context)

If i correctly understood i think you need edit your loop
for line in sale_obj:
for line_obj in sale_order_line_obj:
line_obj.write(cr, uid, line.id, {'ship': sale_obj.ship.id}, context=context)

Related

Inserting dynamic instance variables into a ruby sqlite query

I have a problem trying to create a dynamic save method. This method should work for all children of this parent method. I have set the instance variables to be set dynamically using instance_variable_set and a hash. This is my save method as it exists now:
def save
if DB.execute("SELECT id FROM '#{self.class.name.downcase}s' WHERE id = ?", #id).empty?
DB.execute("INSERT INTO '#{self.class.name.downcase}s' (url, votes, title) VALUES (?, ?, ?)", #url, #votes, #title)
#id = DB.last_insert_row_id
else
DB.execute("UPDATE '#{self.class.name.downcase}s' SET url = ?, votes = ?, title = ? WHERE id = ?", #url, #votes, #title, #id)
end
end
As you can see, the variables currently have a set number (determined by the number of question marks in the query) and set names (determined by the variable names). How do I make it so that it will take any number of instance variables and names and saves them?

ODOO - How to filter Many2Many field containing zero items

How can I filter an Odoo Many2Many field for containing zero items.
Example: I'm trying to filter tasks that have 0 followers (message_follower_ids).
[['message_follower_ids','=',False]] Returns no results, but there should be many.
Odoo version: 8.0
Frank
message_follower_ids is a compute field.
If you want to search by any compute field you have to write the search method of it in old api it is fnct_search and in that method you can return domain.
In your case message_follower_ids is compute one and also having the fnct_search method. so, whenever you search for follower in search bar in top right corner that method will call and return the domain and you will get your filtered list.
But in that fnct_search You need to change to accomplish your need.
Like this.
class mail_thread(osv.AbstractModel):
_inherit = 'mail.thread'
def _get_followers(self, cr, uid, ids, name, arg, context=None):
fol_obj = self.pool.get('mail.followers')
fol_ids = fol_obj.search(cr, SUPERUSER_ID, [('res_model', '=', self._name), ('res_id', 'in', ids)])
res = dict((id, dict(message_follower_ids=[], message_is_follower=False)) for id in ids)
user_pid = self.pool.get('res.users').read(cr, uid, [uid], ['partner_id'], context=context)[0]['partner_id'][0]
for fol in fol_obj.browse(cr, SUPERUSER_ID, fol_ids):
res[fol.res_id]['message_follower_ids'].append(fol.partner_id.id)
if fol.partner_id.id == user_pid:
res[fol.res_id]['message_is_follower'] = True
return res
def _search_followers(self, cr, uid, obj, name, args, context):
"""Search function for message_follower_ids
Do not use with operator 'not in'. Use instead message_is_followers
"""
fol_obj = self.pool.get('mail.followers')
res = []
for field, operator, value in args:
assert field == name
# TOFIX make it work with not in
assert operator != "not in", "Do not search message_follower_ids with 'not in'"
fol_ids = fol_obj.search(cr, SUPERUSER_ID, [('res_model', '=', self._name), ('partner_id', operator, value)])
if not fol_ids and operator == '=' and value==False:
fol_ids = fol_obj.search(cr, SUPERUSER_ID, [('res_model', '=', self._name), ('partner_id', '!=', value)])
res_ids = [fol.res_id for fol in fol_obj.browse(cr, SUPERUSER_ID, fol_ids)]
res.append(('id', 'not in', res_ids))
else:
res_ids = [fol.res_id for fol in fol_obj.browse(cr, SUPERUSER_ID, fol_ids)]
res.append(('id', 'in', res_ids))
return res
_columns = {
'message_follower_ids': fields.function(_get_followers,fnct_search=_search_followers),
}
Also need to add mail module in dependency list.

Rewrite an OpenERP 7 method to Odoo 8 syntax?

I have the following OpenERP 7 method:
# Function to get the vat number (CIF/NIF) and then show it on invoice form view
def _get_vat_num(self, cr, uid, ids, field_name, args=None, context=None):
partner_pool = self.pool.get('res.partner')
invoice_pool = self.pool.get('account.invoice')
res = {}
for inv in self.browse(cr, uid, ids, context=context):
invoice = invoice_pool.browse(cr,uid, inv.id, context=None)
partner = partner_pool.browse(cr, uid, invoice.partner_id.id, context=None)
res[inv.id] = partner.vat
return res
inv_vat = fields.Char(compute='_get_vat_num', string="CIF/NIF")
I need to rewrite it to Odoo v8 syntax. I have tried but it doesn't work:
def _get_vat_num(self):
partner_pool = self.env['res.partner']
invoice_pool = self.env['account.invoice']
res = {}
for inv in self.browse(self.id):
invoice = invoice_pool.browse(inv.id)
partner = partner_pool.browse(invoice.partner_id.id)
res[inv.id] = partner.vat
return res
What should be the correct code?
It looks like you're setting a functional field. You should instead be able to define the field as a related field like so:
inv_vat = fields.Char(string="VAT", related="partner_id.vat")
If you really want it as a functional field, this is how you would do it
inv_vat = fields.Char(string="VAT", compute="_get_vat_num")
def _get_vat_num(self):
# self is a recordset of account.invoice records
for invoice in self:
# to set a functional field, you just assign it
invoice.inv_vat = invoice.partner_id.vat
Check out the recordset documentation: https://www.odoo.com/documentation/8.0/reference/orm.html#recordsets
And the computed fields documentation:
https://www.odoo.com/documentation/8.0/reference/orm.html#computed-fields

Openerp calculate qty and date listing

I am very new to openerp, and have been given a task. My firts question which sounds silly is, how can I stirp datefield to just a month on openerp. 2. with the code below am trying to get a balance of water in reservoirs basically calculating from water meter in - meter out to get balance this has to work like a quantity in stock control
def _water_balance(self, cr, uid, ids, field_name, arg, context):
res = {}
bal = 0.0
for rec in self.browse(cr, uid, ids, context=context):
for traject in rec.trajectory_ids:
trajectory_balance = self.pool.get('supply.trajectory').browse(cr, uid, traject.id , context=context).trajectory_balance
bal += float(trajectory_balance)
res[rec.id] = bal
return res
You can get month from datetime field using strftime function like,
month = datetimefield.strftime("%m") # Month of the datetimefield
month = datetime.now().strftime("%m") # Current month
Just changed few code try following,
def _water_balance(self, cr, uid, ids, field_name, arg, context):
res = {}
for rec in self.browse(cr, uid, ids, context=context):
res[rec.id] = 0.00
bal = 0.0
for traject in rec.trajectory_ids:
bal += float(traject.trajectory_balance)
res[rec.id] = bal
return res

openerp domain filters how to compare 2 fields in object?

In Odoo/OpenERP I want to make a filter to compare field1 and field2 of the same object like below.
Plz let me know how to make this filter work, adding filter on partners search form:
<field name="credit_limit"/>
<field name="credit"/>
<filter name="credit limit" domain="[('credit','>',credit_limit)]"/>
Applying this filter gives below error:
Uncaught Error: Failed to evaluate search criterions:
{"code":400,"message":"Evaluation Error","data":{"type":"local_exception","debug":"Local evaluation failure\nNameError: name 'credit_limit' is not defined\n\n{\"domains\":[[],\"[('customer','=',1)]\",\"[('credit','=',credit_limit)]\"],\"contexts\":[{\"lang\":\"en_US\",\"tz\":\"Africa/Cairo\",\"uid\":1,\"search_default_customer\":1}],\"group_by_seq\":[]}"}}
I googled many times to find a solution without finding anyone .
the simple form [('credit_limit','<',credit)] always returns the error "can not convert string to float" where string is credit and float is credit_limit.
is there any way to say [('credit_limit','<',valueof(credit))] or [('field1','=',valueof(field2))] ??
Regards,
You need to create a function field with a search function to do that.
Here is an example, using the 'old api' syntax:
class SomeModel(orm.Model):
_name = 'some.model'
def _func_credit_limit_exceeded(self, cr, uid, ids,
field_name, arg, context):
"""compute the value of the function field"""
res = {}
for record in self.browse(cr, uid, ids, context=context):
res[record.id] = record.credit > record.credit_limit
return res
def _func_search_credit_limit_exceeded(self, cr, uid, obj,
name, criterion, context):
"""we only support a search on the form
('column_name', '=', boolean) or ('column_name', '!=', boolean)
"""
match_ids = []
field, op, value = criterion
# argument processing
if op == '!=':
value = not value
elif op != '=':
raise ValueError('Unsupported operator')
# build the search query
if value = True:
comparison = '>'
else:
comparison = '<='
query = 'SELECT id FROM some_model ' \
'WHERE credit %s credit_limit' % comparison
# get the ids matching the search
# and return the corresponding domain
cr.execute(query)
for row in cr.fetchall():
match_ids.append(row[0])
if match_ids:
# return domain matching the selected ids
return [('id', 'in', match_ids)]
else:
# return a domain which will never yield a result
return [('id', '=', 0)]
_columns = {'credit': fields.float('Credit'),
'credit_limit': fields.float('Credit Limit'),
'credit_limit_exceeded':
fields.function(_func_credit_limit_exceeded,
fnct_search=_func_search_credit_limit_exceeded,
string='Credit Limit Exceeded',
type='boolean'),
}
For numeric fields, you can create a computed field which counts the difference of the two field. if the result is 0 they are equal, if negative the 2nd is greater if positive the first is greater.

Resources