I need to copy many2many field content to another class' many2many field.
#api.multi
def tester(self):
context = self._context.copy()
list = []
confs = self.risque.rubrique_ids
for rec in confs:
list.append(rec.id)
self.env['test.test'].create({
'nom_risque': self.risque.nom_risque,
'rubrique_ids': [0, 0, list]
})
return {
'name': 'Evaluation',
'view_type': 'form',
'view_mode': 'tree,form',
# 'views': [{'view_mode': 'form', 'view_id': 'rub_id'}],
'res_model': 'test.test',
'type': 'ir.actions.act_window',
'res_id': self.id,
# 'target': 'new',
'flags': {'initial_mode': 'edit'},
'context': context,
}
My XML code:
<button name="tester" string="Evaluer" type="object" class="oe_highlight" />
But it returns the nom_risque and for the rubrique_ids only the last one.
Hi try out the following and please try to understand my comments, too :-)
#api.multi
# even if it's trying out something, give it an understandable name
def tester(self):
# seems to be a singleton call, so restrict it with self.ensure_one()
# no need to copy the context here, just pass it in the end
context = self._context.copy()
# odoo's recordsets has some cool functions, e.g. mapped()
# but that's only usefull on other scenarios
list = []
confs = self.risque.rubrique_ids
for rec in confs:
list.append(rec.id)
# you will call this new record later so don't forget to 'save' it
self.env['test.test'].create({
'nom_risque': self.risque.nom_risque,
# that's just plain wrong, read the __doc__ on models.BaseModel.write()
'rubrique_ids': [0, 0, list]
})
return {
'name': 'Evaluation',
'view_type': 'form',
'view_mode': 'tree,form',
# 'views': [{'view_mode': 'form', 'view_id': 'rub_id'}],
'res_model': 'test.test',
'type': 'ir.actions.act_window',
# here is the mistake: take the id of your created record above
'res_id': self.id,
# 'target': 'new',
'flags': {'initial_mode': 'edit'},
'context': context,
}
And now the hopefully working example:
#api.multi
def create_test_record(self):
self.ensure_one()
test = self.env['test.test'].create({
'nom_risque': self.risque.nom_risque,
'rubrique_ids': [(6, 0, self.risque.rubrique_ids.ids)]
})
return {
'name': 'Evaluation',
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'test.test',
'type': 'ir.actions.act_window',
'res_id': test.id,
'flags': {'initial_mode': 'edit'},
'context': self.env.context
}
Related
I am developing a custom module.
I tried to add it through an object button with the following code but doesn't seem to work
def create_invoice(self):
rslt = self.env['account.invoice'].create({
'partner_id': self.instructor.id,
'name': 'customer invoice',
'type': 'out_invoice',
'date_invoice': 'create_date'
})
return rslt
How can I add a button that generates an invoice?
desu
From Odoo13 there is a change in invoice object, It is now account.move instead of account.invoice.You can take this reference demo example.
invoice = self.env['account.move'].create({
'type': 'out_invoice',
'journal_id': journal.id,
'partner_id': product_id.id,
'invoice_date': date_invoice,
'date': date_invoice,
'invoice_line_ids': [(0, 0, {
'product_id': product_id.id,
'quantity': 40.0,
'name': 'product test 1',
'discount': 10.00,
'price_unit': 2.27,
})]
})
I have a class salesin which has a one2many field emidetails . Here i defined abutton that directs to a wizard saleswizard . What i need to acheive is when i click the button , the wizard that opens should contain the emidetails one2many field of salesin class .. How to
'''
class Salesin(models.Model):
_inherit = 'sale.order'
amount = fields.Integer(string="Total Amount")
product = fields.Char(string="Product")
paymenttype = fields.Selection([('Full Payment', 'Full Payment'), ('EMI', 'EMI'), ],
string=" Payment Type : ", default='Full Payment')
emidetails = fields.One2many(comodel_name="emidetails",inverse_name="saleorder",string="Emi Details",onchange="restrict")
#api.multi
def cnfirm(self):
result = {
'view_type': 'form',
'view_mode': 'form',
'res_model': 'confirmbox',
'name': 'Confirm the Quantities Currently Have',
'type': 'ir.actions.act_window',
'target': 'new',
}
return result
class emidetails(models.Model):
_name = "emidetails"
saleorder = fields.Many2one( comodel_name="sale.order' ,string="SO")
installment = fields.Selection([('Level 1', '1st Installment'), ('Level 2', '2nd
Installment'), ('Level 3', '3rd Installment'), ],
string=" Installment : ",)
amount = fields.Char(string="Amount:",onchange="calculate_med")
date = fields.Date(string="Due Date")
cust = fields.Many2one(comodel_name="sale.order")
status = fields.Selection([('Pending', 'Pending'), ('Paid', 'Paid'), ],
string=" Status : ",)
class saleswizard(models.TransientMOdel) :
_name = saleswiz
emidetails = fields.One2many
(comodel_name="emidetails",inverse_name="saleorder",string="Emi
Details",onchange="restrict")
Use a Many2many field:
emidetails = fields.Many2many("emidetails", string="EmiDetails")
And passe default values in context:
#api.multi
def cnfirm(self):
self.ensure_one()
emidetails = [(4, emit.id, 0) for emit in self.emidetails]
result = {
'view_type': 'form',
'view_mode': 'form',
'res_model': 'saleswiz',
'name': 'Confirm the Quantities Currently Have',
'type': 'ir.actions.act_window',
'target': 'new',
'context': {'default_emidetails': emidetails}
}
return result
i'm using a context to send data to my wizard, but i always get this error "KeyError: 'default_new_name"
i tried doing the example here but still getting the same error
here's my code
model creating a wizard
#api.multi
def open_x2m_matrix(self):
wiz = self.env['x2m.matrix.demo.wiz'].create({})
return {
'name': self.name,
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'x2m.matrix.demo.wiz',
'target': 'new',
'res_id': wiz.id,
'context': self.env.context,
'context': {'default_new_name': self.name},
}
model creating 2d matrix
line_ids = fields.Many2many(
'x2m.demo.line', default=lambda self: self._default_line_ids())
def _default_line_ids(self):
recs =self.env['x2m.demo'].search([("name","!=",self._context['default_new_name'])])
# same with users
users = self.env['x2m.demo.line'].search([]).mapped('new_user_id')
return [
(0, 0, {
'demo_id': rec.id,
'new_user_id': usr.id,
'value': 0,
})
# if the project doesn't have a task for the user, create a new one
if not rec.line_ids.filtered(lambda x: x.new_user_id == usr) else
# otherwise, return the task
(4, rec.line_ids.filtered(lambda x: x.new_user_id == usr)[0].id)
for rec in recs
for usr in users
]
The create is already calling the default method for line_ids. So you should either don't create a wizard record and just call without an ID or you create it with your context flag on the right line:
open wizard without creating one
#api.multi
def open_x2m_matrix(self):
context = dict(self.env.context or {})
context.update({'default_new_name': self.name})
return {
'name': self.name,
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'x2m.matrix.demo.wiz',
'target': 'new',
# 'res_id': wiz.id, # not needed
'context': context
}
use your context flag on creation, because that's the call where it's really needed
#api.multi
def open_x2m_matrix(self):
wiz = self.env['x2m.matrix.demo.wiz'].with_context(
default_new_name=self.name).create({})
return {
'name': self.name,
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'x2m.matrix.demo.wiz',
'target': 'new',
'res_id': wiz.id,
'context': self.env.context,
}
def create_file(self):
opportunity_id = self.convert_to_file()
return self.env['trademark.process'].view_file(opportunity_id)
I used convert file function to pass some values of current model to trademark.process
def convert_to_file(self, partner_id=False):
tm_process_obj = self.env['trademark.process']
tm_search_record = self.env['trademark.search'].browse(self.id)
for rec in tm_search_record:
opportunity_id = tm_process_obj.create({
'search_name_char': rec.search_name or False,
'classification_no_id':rec.classification_no_id.id or False,
'partner_id': rec.partner_id.id or False,
'user_id': rec.user_id.id or False,
'search_date': rec.search_date or False,
'search_seq_no': rec.seq_no or False,
})
vals = {
'file_no': opportunity_id.seq_no,
}
self.write(vals)
return opportunity_id
Then finally i return opportunity id and passed to view file function.
def view_file(self, opportunity_id):
view_id=self.env.ref('trademark_services.trademark_process_form_view').id
return {
'name': _('File Details'),
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'trademark.process',
'view_id': view_id,
'res_id': opportunity_id,
'target':'current'
}
But an error occured when i click the button .
Traceback (most recent call last):
File "/home/ubuntu/workspace/amzsys_erp/odoo/http.py", line 638, in
_handle_exception
return super(JsonRequest, self)._handle_exception(exception)
File "/home/ubuntu/workspace/amzsys_erp/odoo/http.py", line 689, in
dispatch
return self._json_response(result)
File "/home/ubuntu/workspace/amzsys_erp/odoo/http.py", line 627, in
_json_response
body = json.dumps(response)
File "/usr/lib/python2.7/json/__init__.py", line 243, in dumps
return _default_encoder.encode(obj)
File "/usr/lib/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
File "/usr/lib/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: trademark.process(131,) is not JSON serializable
How to solve this issue.How to open new form when i clicking the button.
I want to pass some values to that form.
What is the mistake in my code?
Note:using odoo10
Problem in this method where you are passing res_id.
Use opportunity_id.id.
def view_file(self, opportunity_id):
view_id=self.env.ref('trademark_services.trademark_process_form_view').id
return {
'name': _('File Details'),
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'trademark.process',
'view_id': view_id,
'res_id': opportunity_id.id,
'target':'current'
}
How can i solve this error Odoo throws a MissingError on TreeView Second line button when clicked .
The first Record line works but i need such that for each record on the tree the code below will be able to pass the contexts and open the appropriate view .
Kindly assist
Here is the code called on the button
#api.multi
def action_four_weeks_schedule_form(self):
self.ensure_one()
res = {}
ids = self._ids
cr = self._cr
uid = self._uid
context = self._context.copy()
for id in self.browse(self.ids):
print 'id in ++++ ' , id
order_obj = self.pool.get('ratecard.multiple').browse(cr,uid,ids)[0]
ratecard_multiple_id=order_obj.id #int(order_obj.id)
# self.copy(cr,uid, id,ids, {},context)
print '##############################################'
print 'ratecard_multiple_id', ratecard_multiple_id
print 'action_four_weeks_schedule_form ratecard_multiple_id ' , ratecard_multiple_id
scheduled_for= order_obj.scheduled_for
code= order_obj.code
print 'order_obj.multiple_ratecard_id.code' ,[ x.code for x in order_obj.multiple_ratecard_id[0]]
print '##################################################################'
for lineitems in order_obj.multiple_ratecard_id:
print 'Ratecard Codes of selected ' , lineitems.code
singular_code = [ x.code for x in order_obj.multiple_ratecard_id[0]]
for ln in lineitems:
print '***************************************'
print 'ratecard singular name' , ln.name
print 'ratecard singular code' , ln.code
print '#######################################'
# self.copy(cr,uid,id, ids , {},context)
scheduled_for= order_obj.scheduled_for
code= order_obj.code
singular_code = [ x.code for x in order_obj.multiple_ratecard_id[0]]
print '[ x.code for x in order_obj.multiple_ratecard_id[0]]' , singular_code
# for line in id:
# line_obj = self.pool.get('ratecard.multiple').browse(cr,uid,ids)[0]
# print 'line_obj contains' , line_obj
# print '***************************************'
# print 'INNER LOOP action_four_weeks_schedule_form scheduled_for ' , line_obj.scheduled_for
# print ' INNER LOOP action_four_weeks_schedule_form code ' , line_obj.code
# print 'Can i get code of selected line_obj.multiple_ratecard_id.code ' , line_obj.multiple_ratecard_id.code
# print '#######################################'
# ratecard_multiple_id=line.id
# print 'inner line_obj action_four_weeks_schedule_form ratecard_multiple_id ' , ratecard_multiple_id
# scheduled_for= line_obj.scheduled_for
# code= line_obj.code
scheduled_for= order_obj.scheduled_for
code= order_obj.code
singular_code = [ x.code for x in order_obj.multiple_ratecard_id[0]]
print 'action_four_weeks_schedule_form scheduled_for ' , scheduled_for
print 'action_four_weeks_schedule_form code ' , code
print 'singular ratecard selected is ' , singular_code
res = {}
if scheduled_for == 2:
view_id = self.env.ref('ragtimeorder.view_two_weeks_schedule_form').id
form_id = self.env.ref('ragtimeorder.view_two_weeks_schedule_form').id
tree_id = self.env.ref('ragtimeorder.view_two_weeks_schedule_tree').id
res = {
'name': _('TWO WEEKS SCHEDULE FOR RATECARD'),
'view_type': 'form',
'view_mode': 'form',
'views': [(view_id, 'form'), ],
'res_model': 'two.weeks.schedule',
# 'res_id':self.id,
'type': 'ir.actions.act_window',
'nodestroy': True,
'target': 'new',
'domain': '[]',
'context':{'default_scheduled_for':scheduled_for,'default_code':code , 'default_singular_code':singular_code},
'flags': {'form': {'action_buttons': True}}
}
elif scheduled_for == 3:
view_id = self.env.ref('ragtimeorder.view_three_weeks_schedule_form').id
form_id = self.env.ref('ragtimeorder.view_three_weeks_schedule_form').id
tree_id = self.env.ref('ragtimeorder.view_three_weeks_schedule_tree').id
res = {
'name': _('THREE WEEKS SCHEDULE FOR RATECARD'),
'view_type': 'form',
'view_mode': 'form',
'views': [(view_id, 'form'), ],
'res_model': 'three.weeks.schedule',
# 'res_id':self.id,
'type': 'ir.actions.act_window',
'nodestroy': True,
'target': 'new',
'domain': '[]',
'context': context,
'flags': {'form': {'action_buttons': True}}
}
elif scheduled_for == 4:
view_id = self.env.ref('ragtimeorder.view_four_weeks_schedule_form').id
form_id = self.env.ref('ragtimeorder.view_four_weeks_schedule_form').id
tree_id = self.env.ref('ragtimeorder.view_four_weeks_schedule_tree').id
res = {
'name': _('FOUR WEEKS SCHEDULE FOR RATECARD'),
'view_type': 'form',
'view_mode': 'form',
'views': [(view_id, 'form'), ],
'res_model': 'four.weeks.schedule',
# 'res_id':self.id,
'type': 'ir.actions.act_window',
'nodestroy': True,
'target': 'new',
'domain': '[]',
'context':{'default_scheduled_for':scheduled_for,'default_code':code ,'default_singular_code':singular_code },
'flags': {'form': {'action_buttons': True}}
}
elif scheduled_for == 1:
view_id = self.env.ref('ragtimeorder.view_one_week_schedule_form').id
form_id = self.env.ref('ragtimeorder.view_one_week_schedule_form').id
tree_id = self.env.ref('ragtimeorder.view_one_week_schedule_tree').id
res = {
'name': _('ONE WEEK SCHEDULE FOR RATECARD'),
'view_type': 'form',
'view_mode': 'form',
'views': [(view_id, 'form'), ],
'res_model': 'one.week.schedule',
# 'res_id':self.id,
'type': 'ir.actions.act_window',
'nodestroy': True,
'target': 'new',
'domain': '[]',
'context':{'default_scheduled_for':scheduled_for,'default_code':code , 'default_singular_code':singular_code},
'flags': {'form': {'action_buttons': True}}
}
else:
view_obj = self.pool.get('ir.ui.view')
view_id = view_obj.search(cr, uid, [('model', '=', self._name), \
('name', '=', self._name + '.view')])
res = {
'view_mode': 'form',
'view_type': 'form',
'view_id': view_id or False,
'res_model': self._name,
'context': context,
'type': 'ir.actions.act_window',
'target': 'new',
'flags': {'form': {'action_buttons': True}}
}
id.update({
'radio_scheduled_for': scheduled_for,
'update_code' : code,
'singular_code' : singular_code ,
})
return res
This is the screenshot of the error the button pressed throws this error