Odoo: Two selection fields, second selection depends on the first selected value - odoo

I have a model with two selection fields. In the first selection field the user chooses a project, and in second the user chooses a tranche, depends on the selected first field. (for one project, we have many tranche)
I use this declaration to my function:
#api.multi
#api.onchange('project')
def _get_tranche(self):
print res
return res`
If I'll print in console the result of returned value is correct, and I have exactly what I search, but in the view, the second field value does not displays computed values to choose after setting the second field value.
Is there any method to make it work properly?
This is my code:
#api.model
def _get_project(self):
values = {'$top' : 100,
'$filter' : "'name==:1&&parent==null'",
'$params' : '\'["*"]\'' }
response = requests.get('http://localhost:8081/rest/Project/name',
auth=('admin', 'admin'),
params=values)
data = response.json()
res = []
for record in data['__ENTITIES']:
res.append((record['__KEY'], record['name']))
return res
#property
def ret_value(self):
return self.project
#api.multi
#api.onchange('project')
def _get_tranche(self):
if self.ret_value == False:
return []
values = {'$top' : 100,
'$filter' : "'parent.ID==:1'",
'$params' : '\'[' + self.ret_value + ']\'' }
response = requests.get('http://localhost:8081/rest/Project/name',
auth=('admin', 'admin'),
params=values)
data = response.json()
res = []
for record in data['__ENTITIES']:
res.append((record['__KEY'], record['name']))
print res
return res
_columns = {
'name': fields.char("Name", required=True),
'description' : fields.text(),
'project' :fields.selection(selection=_get_project, string="Project"),
'tranche' : fields.selection(selection=_get_tranche, string="Tranche"),
}
NB: a tranche is a project with parent_id (not null) = id of a project, I need do the following: when I select a project X from the first field selection "project", I can select the tranches of this project (project with parent_id=X) from the second field selection "tranche" what I can't understand is the result of print in the console is correct, but in the view the field tranche is empty??!!
Now I am trying this:
_columns = {
'name': fields.char("Name", required=True),
'description' : fields.text(),
'project' :fields.selection(selection=_get_project, string="Project"),
'tranche' : fields.selection(selection=_get_tranche,
string="Tranche", compute='_return_tranche'),
}
#api.depends('project')
def _return_tranche(self):
if self.ret_value == False:
self.tranche = []
return
values = {'$top' : 100,
'$filter' : "'parent.ID==:1'",
'$params' : '\'[' + self.ret_value + ']\'' }
response = requests.get('http://localhost:8081/rest/Project/name',
auth=('admin', 'admin'),
params=values)
data = response.json()
res = []
for record in data['__ENTITIES']:
res.append((str(record['__KEY']),str(record['name'])))
print res
self.tranche = res
return
#api.model
def _get_tranche(self):
values = {'$top' : 100,
'$filter' : "'name==:1&&parent!=null'",
'$params' : '\'["*"]\'' }
response = requests.get('http://localhost:8081/rest/Project/name',
auth=('admin', 'admin'),
params=values)
data = response.json()
res = []
for record in data['__ENTITIES']:
res.append((record['__KEY'], record['name']))
return res
But I get this error
File "/opt/odoo/odoo/openerp/fields.py", line 1529, in convert_to_cache
raise ValueError("Wrong value for %s: %r" % (self, value))
ValueError: Wrong value for crm.lead.tranche: [('6', 'Tranche I'), ('7', 'Tranche II'), ('8', 'Tranche III')]
Help me please...

Related

Update records on one2many fields in wizard for odoo16

Geting Issue 'TypeError: unhashable type: 'dict' for insert values in one2many field from onchange method in odoo16
My code is below:
class EmployeeAddWizard(models.TransientModel):
_name = 'employee.add.wizard'
line_ids = fields.One2many('employee.goal.add.line', 'wizard_id', string="Lines")
#api.onchange('challenge_id', 'employee_id')
def _onchange_action_goal_add(self):
r = []
value = {}
self.line_ids = {}
if self.challenge_id and self.employee_id:
goal_records = self.env['gamification.challenge.line'].search([('challenge_id', '=', self.challenge_id.id)])
for emp in self.employee_id:
for line in goal_records:
data = {'wizard_id': self.id, # Other table m2o
'goal_definition_id': line.definition_id.id,
'goal_rating': 0.0,
'goal_target': line.target_goal,
'employee_id': emp.id,
}
r.append(data)
value.update(records=r)
self.line_ids = value['records']
class GoalLine(models.Model):
_name = 'employee.goal.add.line'
wizard_id = fields.Integer()
goal_definition_id = fields.Many2one('gamification.goal.definition', string='Goal Definition', required=True, ondelete="cascade")
goal_rating = fields.Float('Rating', required=True)
goal_target = fields.Float('Target Value ', required=True)
employee_id = fields.Many2one('res.users', string="Employee", required=True, ondelete="cascade")
Thanks in advance
You passed a list of dicts which is not valid, you need to use special commands
Example:
r.append(Command.create(data))
or:
r.append((0, 0, data))
You can use Command.clear(), to remove previous lines if needed ( self.line_ids = {} should raise an error: ValueError: Wrong value).
Check this answer

Add values on One2many field onchange

I'm trying to add values in my one2many field onchange.
I tried using the [(0,0, {values})] but nothing happened. Any idea on how to implement it?
custom_line_ids = fields.One2many('mrp.production', 'product_id', 'Custom Line')
#api.onchange('product_id')
def add_custom_line_ids(self):
mrp = self.env['mrp.productions'].search([])
result = []
vals = {
'sequence': self.sequence,
'name': self.name,
'product_id': self.product_id,
'date_planned_start': self.date_planned_start,
'state': self.state,
}
self.update({'custom_line_ids':[(0, 0, vals)]})
Actually you are using update method, which only update the model's value but not yet stored on database. You should use write method instead.
You need to return the value in onchange. This would work:
custom_line_ids = fields.One2many('mrp.production', 'product_id', 'Custom Line')
#api.onchange('product_id')
def add_custom_line_ids(self):
vals = {}
mrp_ids = self.env['mrp.productions'].search([])
if mrp_ids:
for mrp in mrp_ids:
vals['custom_line_ids']=[(0,0,{
'date': mrp.date,
})]
return {'value': vals}

How to display external information on Odoo 11?

I'm working on Weather application using Odoo11, I have a Python script that fetches weather information from this API: https://openweathermap.org/api
The script works fine but I have no idea how to integrate it with Odoo.
Can you give guidelines about how to achieve this, for example how to show this information in a form view, tree or Kanban?
Any example will be very helpful for me.
If you only want to show some text that´s always updated you can use a computed field
from odoo import api
weather = fields.Text( # this can be an image or any other field type
string='Weather',
compute='_compute_weather'
)
#api.depends() # leave this empty, so this is executed always when the view with this field is loaded
def _compute_weather(self):
for record in self:
# retrieve the weather information here
record.weather = weather_information # assign the weather information to the variable
Show it in a form view as any other field
<field name="weather" />
Note: If you want to store the information on the database you can just create a button or a atomate task, for instance, to store or update the values in the fields (without compute method).
Note2: Check the source code of the user_weather_map module from Cybrosis, it may be helpful
You can use the module User Weather Notification.
This module uses external API.
def get_weather(self, user_id):
rec = self.env['user.weather.map.config'].search([('user_id', '=', user_id)], limit=1)
if rec:
weather_path = 'http://api.openweathermap.org/data/2.5/weather?'
if rec.u_longitude and rec.u_latitude:
params = urllib.urlencode(
{'lat': rec.u_latitude, 'lon': rec.u_longitude, 'APPID': rec.appid})
elif rec.city:
params = urllib.urlencode(
{'q': rec.city, 'APPID': rec.appid})
else:
return {
'issue': 'localization'
}
url = weather_path + params
try:
f = urllib.urlopen(url)
except Exception:
f = False
if f:
ret = f.read().decode('utf-8')
result = json.loads(ret)
if result:
if "cod" in result.keys():
if result['cod'] == 200:
city = False
city2 = False
if "name" in result.keys():
city = result['name']
if not city:
if rec.method == 'address':
city = rec.city
if rec.method == 'address':
city2 = rec.city
temp = pytemperature.k2c(result['main']['temp'])
min_temp = pytemperature.k2c(result['main']['temp_min'])
max_temp = pytemperature.k2c(result['main']['temp_max'])
weather_rec = self.search([('user_id', '=', rec.user_id.id)])
now_utc = datetime.now(timezone('UTC'))
user_list = self.env['res.users'].search([('id', '=', user_id)])
if user_list.partner_id.tz:
tz = pytz.timezone(user_list.partner_id.tz)
now_pacific = now_utc.astimezone(timezone(str(tz)))
current_time = now_pacific.strftime('%d %B %Y, %I:%M%p')
vals = {
'date_weather_update': current_time,
'name': city,
'city': city2,
'user_id': user_id,
'weather': result['weather'][0]['main'],
'description': result['weather'][0]['description'],
'temp': temp,
'pressure': result['main']['pressure'],
'humidity': result['main']['humidity'],
'min_temp': min_temp,
'max_temp': max_temp,
}
if weather_rec:
weather_rec.write(vals)
return {
'issue': ''
}
else:
weather_rec.create(vals)
return {
'issue': ''
}
else:
return {
'issue': 'timezone'
}
else:
return {
'issue': 'localization'
}
else:
return {
'issue': 'bad_request'
}
else:
return {
'issue': 'internet'
}
else:
return {
'issue': 'config'
}
This is the code that I use in that module. you can just convert it into odoo11.
Thank you.

How can I add From date to To date to print a set of records in report in odoo 10?

I am creating a Bank module, where the customers can buy loans from the bank. In that I want to print a report statement. Before printing the records of a particular customer, i want to filter the dates. I want to filter it by giving From date to To date. So the loan amounts where the customer bought from the bank in that given dates should print.
Thank You,
Hope I will gain some knowledge.
below code for wizard
class BankCustomer(models.TransientModel):
_name = 'bank.customer'
_description = 'Bank Customer Report'
date_from = fields.Date(string='From date', required=True,default=lambda *a: time.strftime('%Y-%m-01'))
date_to = fields.Date(string='To date', required=True,default=lambda *a: str(datetime.now() + relativedelta.relativedelta(months=+1, day=1, days=-1))[:10])
#api.multi
def pdf_bank_customer_report(self):
data = self.read()[0]
datas = {
'ids': [],
'model': 'bank.customer',
'form': data
}
return self.env['report'].with_context(landscape=True).get_action(self, 'module_name.template_name', data=datas)
class BankCustomerReport(models.AbstractModel):
_name = 'report.module_name.template_name
def get(self):
self.env.cr.execute(""" you query """+ datas['date_from'],datas['date_to'] ))
line_list = [i for i in self.env.cr.dictfetchall()]
finallist = []
import datetime
for fin in line_list:
#sale_date = datetime.datetime.strptime(fin['date'], '%Y-%m-%d').strftime('%d-%m-%y')
finallist.append({
'date': fin['date'],
'here gat you requirened field from query'
})
finally pass thislist to report template
return finallist
#api.model
def render_html(self, docids, data=None):
Report = self.env['report']
sale_report = Report._get_report_from_name('module_name.report_template_name')
context = dict(self._context or {})
active_ids = context.get('active_ids', [])
register = self.env['bank.customer'].browse(active_ids)
docargs = {
'doc_ids': self.ids,
'doc_model': sale_report.model,
'docs': register,
'details':self.get_det,
}
return Report.render('module_name.report_template_name', docargs)

odoo program add mail follower no default subtype

class jj_loan(models.Model):
_name = 'jj_loan.jj_loan'
name = fields.Char(required=True)
_inherit = ['mail.thread', 'ir.needaction_mixin']
state = fields.Selection([('Draft','Draft'),('Apply','Apply')] ,default="Draft")
manager_id = fields.Many2one('hr.employee', 'Approval',default=_supervisor_get)
def add_approve_follower(self):
vals={}
partner_id = []
ptn = self.env['res.partner'].search([('email', '=', self.manager_id.user_id.email)]) //get partner id by email
if not ptn:return vals //if get fail return {}
for x in self.message_follower_ids:
if x.partner_id.id == ptn.id:return vals //if already added in followers return {}
partner_id.append(ptn.id)
vals['message_follower_ids'] = [(0,0,{
'res_model':'jj_loan.jj_loan',
'partner_id':pid}) for pid in partner_id]
return vals; //return message_follower_ids
#api.one
def jj_loan_aprrove(self):
vals = self.add_account_follower(); //get now followers
vals['state'] = 'Approve'
self.write(vals)
self.send_followers( _("Approved") )
return True
#api.multi
def send_followers(self,body):
followers = [x.partner_id.id for x in self.message_follower_ids]
self.message_post(body=body,type="notification",subtype="mt_comment",parnter_ids=followers)
return True
when jj_loan_aprrove button clicked , manager_id is automatically added into the follower list, but ,when message created ,the manager can not get notification. and then I found this caused as bellowes:
I want to know how to add followers programmely and make the default checkbox checked
thanks
finally, after read the odoo default addons mail, I found message_follower_ids should have key for res_model so the solution for this question is :
default_subtypes = self.env['mail.message.subtype'].search([ ('default', '=', True), '|', ('res_model', '=', model_id), ('res_model', '=', False)])
vals['message_follower_ids'] = [(0,0,{
'res_model':model_id,
'subtype_ids': [(6, 0, default_subtypes.ids)],
'partner_id':pid}) for pid in partner_id]
return vals;