Update Route in Odoo 12 - odoo

How can I update the product Route_ids routes in Odoo 12 with a query?
The selection of products I can do with the answer from this link.
Odoo Make to Order Configuration for all products
Thanks
Maybe with these :
models.execute_kw(db, uid, password, 'product.template', 'write', [[id], {'route_ids': [(1, a, b)]}])
What is a and b? I think that 1 it's for the update, is right?
I think that the answer is that but i'm not sure :
models.execute_kw(db, uid, password, 'product.template', 'write', [[id], {'route_ids': [(1, 915, 17)]}])
1 is for the update, 915 is the product id, and 17 is the route_id.
The question is how can I do a list of products to update the routes?
According with the answer of CZoellner maybe is
models.execute_kw(db, uid, pw, 'product.template',
'write', [[17], {'route_ids': [(6, 0, [915,916])]}])
It's Right?
Ok Ive do :
import sys
import xmlrpclib
import ssl
url = "http://localhost:8069"
db = "*******"
username = "*******"
pw = "*******"
gcontext = ssl._create_unverified_context()
# Get the uid
sock_common = xmlrpclib.ServerProxy(
"http://localhost:8069/xmlrpc/common", context=gcontext)
uid = sock_common.login(db, username, pw)
models = xmlrpclib.ServerProxy("http://localhost:8069/xmlrpc/object", context=gcontext)
models.execute_kw(
db, uid, pw, "product.template", "write", [[916], {"route_ids": [(6, 0, [17])]}]
)
It thasn't work, where is my mistake?
It's these code work with odoo 12?

There are a lot of answers about how the magic triplets for many2many fields in Odoo have to be used already. My advice for this basic question: look into the docstring of BaseModel.write() because the answer to that is there for ages.
But for your special question: If you want to set a product route to only one route, just use the "override" triplet (6, 0, <list_of_ids_to_set>). If you just want to add another route to all current set routes use the "add" triplet (4, <id_of_route_to_add>, 0) (you could leave the 0 at the end).
So if your Make2order route is for example ID 3:
models.execute_kw(db, uid, pw, 'product.template',
'write', [[template_id], {'route_ids': [(6, 0, [3])]}])
or
models.execute_kw(db, uid, pw, 'product.template',
'write', [[template_id], {'route_ids': [(4, 3,)]}])

Related

Odoo : OpenERP7 _prepare_purchase_order_line method equivalent in Odoo 12

I'm working on migrating an old module from OpenERP 7 to Odoo 12. I'm stuck in this method called _prepare_purchase_order_line, you can find it in model purchase.requisition.
Here is its code :
def make_purchase_order(self, cr, uid, ids, partner_id, context=None):
"""
Create New RFQ for Supplier
"""
context = dict(context or {})
assert partner_id, 'Supplier should be specified'
purchase_order = self.pool.get('purchase.order')
purchase_order_line = self.pool.get('purchase.order.line')
res_partner = self.pool.get('res.partner')
supplier = res_partner.browse(cr, uid, partner_id, context=context)
res = {}
for requisition in self.browse(cr, uid, ids, context=context):
if not requisition.multiple_rfq_per_supplier and supplier.id in filter(lambda x: x, [rfq.state != 'cancel' and rfq.partner_id.id or None for rfq in requisition.purchase_ids]):
raise osv.except_osv(_('Warning!'), _('You have already one %s purchase order for this partner, you must cancel this purchase order to create a new quotation.') % rfq.state)
context.update({'mail_create_nolog': True})
purchase_id = purchase_order.create(cr, uid, self._prepare_purchase_order(cr, uid, requisition, supplier, context=context), context=context)
purchase_order.message_post(cr, uid, [purchase_id], body=_("RFQ created"), context=context)
res[requisition.id] = purchase_id
for line in requisition.line_ids:
purchase_order_line.create(cr, uid, self._prepare_purchase_order_line(cr, uid, requisition, line, purchase_id, supplier, context=context), context=context)
return res
I want to know what is the equivalent of this method in Odoo 12.
Can you help me?
I can see this method exist with the same name in odoo 12 but it is in purchase.requisition.line model.
#api.multi
def _prepare_purchase_order_line(self, name, product_qty=0.0, price_unit=0.0, taxes_ids=False):
self.ensure_one()
requisition = self.requisition_id
if requisition.schedule_date:
date_planned = datetime.combine(requisition.schedule_date, time.min)
else:
date_planned = datetime.now()
return {
'name': name,
'product_id': self.product_id.id,
'product_uom': self.product_id.uom_po_id.id,
'product_qty': product_qty,
'price_unit': price_unit,
'taxes_id': [(6, 0, taxes_ids)],
'date_planned': date_planned,
'account_analytic_id': self.account_analytic_id.id,
'analytic_tag_ids': self.analytic_tag_ids.ids,
'move_dest_ids': self.move_dest_id and [(4, self.move_dest_id.id)] or []
}

How to override create methode in odoo 10

i want to use same create method in odoo 10 as below means i want to convert below code in odoo 10, below code is working well for odoo 8
def create(self, cr, uid, vals, context=None):
phase_obj = self.pool.get('hr_evaluation.plan.phase')
survey_id = phase_obj.read(cr, uid, vals.get('phase_id'), fields=['survey_id'], context=context)['survey_id'][0]
if vals.get('user_id'):
user_obj = self.pool.get('res.users')
partner_id = user_obj.read(cr, uid, vals.get('user_id'), fields=['partner_id'], context=context)['partner_id'][0]
else:
partner_id = None
user_input_obj = self.pool.get('survey.user_input')
if not vals.get('deadline'):
vals['deadline'] = (datetime.now() + timedelta(days=28)).strftime(DF)
ret = user_input_obj.create(cr, uid, {'survey_id': survey_id,
'deadline': vals.get('deadline'),
'type': 'link',
'partner_id': partner_id}, context=context)
vals['request_id'] = ret
return super(hr_evaluation_interview, self).create(cr, uid, vals, context=context)
i am trying below code:
def create(self, vals):
survey_id = self.env['hr_evaluation.plan.phase'].read(vals.get('phase_id'),fields=['survey_id'])['survey_id'][0]
if vals.get('user_id'):
partner_id = self.env['res.users'].read(vals.get('user_id'), fields=['partner_id'])['partner_id'][0]
else:
partner_id = None
if not vals.get('deadline'):
vals['deadline'] = (datetime.now() + timedelta(days=28)).strftime(DF)
ret = self.env['survey.user_input'].create({'survey_id': survey_id,
'deadline': vals.get('deadline'),
'type': 'link',
'partner_id': partner_id})
vals['request_id'] = ret
return super(hr_evaluation_interview, self).create(vals)
but it is giving me error like TypeError: read() got multiple values for keyword argument 'fields' so please guide me how can i remove this error?
read method accept fields as argument and you give it two arguments.
read([fields])
Reads the requested fields for the records in self, low-level/RPC method. In Python code, prefer browse().
Parameters
fields -- list of field names to return (default is all fields)
Returns
a list of dictionaries mapping field names to their values, with one dictionary per record
Raises
AccessError -- if user has no read rights on some of the given records
Instead of calling read method it's better to call browse() method, you can read Browse() vs read() performance in Odoo 8
Your code should be:
def create(self, vals):
survey_id = self.env['hr_evaluation.plan.phase'].browse(vals.get('phase_id'))
if vals.get('user_id'):
partner_id = self.env['res.users'].browse(vals.get('user_id'))
else:
partner_id = None
if not vals.get('deadline'):
vals['deadline'] = (datetime.now() + timedelta(days=28)).strftime(DF)
ret = self.env['survey.user_input'].create({'survey_id': survey_id.id,
'deadline': vals.get('deadline'),
'type': 'link',
'partner_id': partner_id.id})
vals['request_id'] = ret.id
return super(hr_evaluation_interview, self).create(vals)

How to check whether two many2many fields are exactly equal or not in odoo9?

I have a many2many field "tag_ids" both in models "news.ads" and "blog.post".
I want to get all the records from "blog.post" whose "tag_ids" exactly matches the "tag_ids" in "news.ads".
I tried the following in my controller but it doesn't worked,
blog_obj = request.registry['blog.post']
p_id = blog_obj.search(cr, uid, ['&', ['id','=',post_id], ['website_published', '=', True]], context=context)
post = blog_obj.browse(cr, uid, p_id, context=context)
ad_obj = request.registry['news.ads']
banner_ads = ad_obj.search(cr, uid, [('state', '=', 'publish'), ('tag_ids', 'in', [post.tag_ids])], context=context)
How do I search such records in odoo9? Any workaround..!!
with the old api, search already returns a list of id's of the matching records, so there is no need to call browse again, you can use the returned list directly in your domain filter
blog_obj = request.registry['blog.post']
p_id = blog_obj.search(cr, uid, ['&', ['id','=',post_id], ['website_published', '=', True]], context=context)
# post = blog_obj.browse(cr, uid, p_id, context=context) you don't need this
ad_obj = request.registry['news.ads']
banner_ads = ad_obj.search(cr, uid, [('state', '=', 'publish'), ('tag_ids', 'in', p_id)], context=context)
in the new api, which is highly recommended you'll have to go an extra step and extract the id's yourself because search now returns a record set
p_id = blog_obj.search(['&', ['id','=',post_id], ['website_published', '=', True]])
p_id = [p.id for p in p_id]
Note 1: DON'T USE OLD API IN ODOO-8 AND ODOO-9
First phase:
To get all the many2many id list we are using .ids it will return list.
Second phase:
Situation: We have two list, and you want to get items from second list, if they are in first list.
>>> a
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> b
[2, 3, 5, 6, 7, 13]
>>> c = [x for x in b if x in a]
>>> c
[2, 3, 5, 6, 7]
Note 2: I'm odoo-8 developer.

Use ORM methods, to get the required data?

I need to get the value of field in a tree view of the fields_view_get method and a
I use ORM methods to achieve this. my code :
class res_partner(osv.osv):
_inherit = 'res.partner'
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
if context is None:
context = {}
partner_obj = self.pool.get('res.partner')
ids_partner = partner_obj.search(cr, uid, [], context=context)
partner_name = partner_obj.browse(cr, uid, ids_partner, context=context)
element = partner_obj.browse(cr,uid,ids_partner[0]).numcte
res = super(res_partner,self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu)
newcte=test_name.numcte
doc = etree.XML(res['arch'])
if view_type == 'tree':
for node in doc.xpath("//field[#name='numcte']"):
node.set('string', 'numcte')
for node in doc.xpath("//button[#name='icono']"):
node.set('icon', newcte)
res['arch'] = etree.tostring(doc)
return res
_columns = {
'numcte': fields.text('numero cliente'),
}
res_partner()
My problem is when I, use for instance :
element = partner_obj.browse(cr,uid,ids_partner[0]).numcte
It returns me the value of the field that I want, but in the treeView is the same for each row, like this A001, A001, A001, in instead of A001, A002, A003.
in this case ids_partner[0], How can I make this number to be dynamic and changing for each row ?
Or in the case that use this:
my_data = partner_obj.read(cr, uid, ids_partner, ["numcte"], context=context)
returns me the tuple like this:
[{'numcte': u'A001', 'id': 3}, {'numcte': u'A002', 'id': 2}, {'numcte': u'A003', 'id': 4}]
[{'numcte': u'A001', 'id': 3}, {'numcte': u'A002', 'id': 2}, {'numcte': u'A003', 'id': 4}]
[{'numcte': u'A001', 'id': 3}, {'numcte': u'A002', 'id': 2}, {'numcte': u'A003', 'id': 4}]
one for each row
How can I get the value of the field that I want for the correct row. ?
thank you all for your time, I been a while in this so any help is usefull.
fields_view_get is provided to allow you to change/create the XML that defines the view, not the data.
What you need to do in fields_view_get is drop your field onto the view. However, overriding fields_view_get is only done in very unusual cases where you need the view to by dynamic in a way that can't be achieved easily with attrs and states in the XML view.
The usual pattern is to create a view in XML that extends the partner tree view and adds your field in the correct place using an XPATH expression. If your field is a new field, you will need to also need to create a new model that inherits the res_partner model and add your new field in _columns.

Cannot format first column in WxPython's ListCtrl

If I set the format of the first column in a ListCtrl to align centre (or align right) nothing happens. It works for the other columns.
This only happens on Windows - I have tested it on Linux and it works fine.
Does anyone know if there is a work-round or other solution?
Here is an example based on code found at http://zetcode.com/wxpython/
import wx
import sys
packages = [('jessica alba', 'pomona', '1981'), ('sigourney weaver', 'new york', '1949'),
('angelina jolie', 'los angeles', '1975'), ('natalie portman', 'jerusalem', '1981'),
('rachel weiss', 'london', '1971'), ('scarlett johansson', 'new york', '1984' )]
class Actresses(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(380, 230))
hbox = wx.BoxSizer(wx.HORIZONTAL)
panel = wx.Panel(self, -1)
self.list = wx.ListCtrl(panel, -1, style=wx.LC_REPORT)
self.list.InsertColumn(0, 'name', wx.LIST_FORMAT_CENTRE,width=140)
self.list.InsertColumn(1, 'place', wx.LIST_FORMAT_CENTRE,width=130)
self.list.InsertColumn(2, 'year', wx.LIST_FORMAT_CENTRE, 90)
for i in packages:
index = self.list.InsertStringItem(sys.maxint, i[0])
self.list.SetStringItem(index, 1, i[1])
self.list.SetStringItem(index, 2, i[2])
hbox.Add(self.list, 1, wx.EXPAND)
panel.SetSizer(hbox)
self.Centre()
self.Show(True)
app = wx.App()
Actresses(None, -1, 'actresses')
app.MainLoop()
I have found that this works (notice I start inserting the columns at 1 rather than 0):
self.list = wx.ListCtrl(panel, -1, style=wx.LC_REPORT)
self.list.InsertColumn(1, 'name', wx.LIST_FORMAT_CENTRE,width=140)
self.list.InsertColumn(2, 'place', wx.LIST_FORMAT_CENTRE,width=130)
self.list.InsertColumn(3, 'year', wx.LIST_FORMAT_CENTRE, 90)
Not sure why this works, but it does. Hopefully, there will be no repercussions from doing this.
Thanks to robots.jpg for inspiring the idea.
Windows definitely treats the first column differently. One workaround is to create an empty column 0 and hide it:
class Actresses(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(380, 230))
#...
self.list = wx.ListCtrl(panel, -1, style=wx.LC_REPORT)
self.list.InsertColumn(0, '', width=0)
self.list.InsertColumn(1, 'name', wx.LIST_FORMAT_CENTRE,width=140)
self.list.InsertColumn(2, 'place', wx.LIST_FORMAT_CENTRE,width=130)
self.list.InsertColumn(3, 'year', wx.LIST_FORMAT_CENTRE, width=90)
for i in packages:
index = self.list.InsertStringItem(sys.maxint, '')
self.list.SetStringItem(index, 1, i[0])
self.list.SetStringItem(index, 2, i[1])
self.list.SetStringItem(index, 3, i[2])
# catch resize event
self.list.Bind(wx.EVT_LIST_COL_BEGIN_DRAG, self.OnColDrag)
#...
def OnColDrag(self, evt):
if evt.m_col == 0:
evt.Veto()
I can't think of any major side-effects from doing this, but let me know if I'm wrong. I guess GetItemText() or anything else that assumes there is useful data in the first column would no longer be useful.
Edit - added code to prevent resizing column 0.