I try to display a message after create a product object that tell user product with product.name is created successful This is the code:
def log_prod(self, cr,
I have had this problem, but this way helped me and is wonderful: from this link
Create a module to save messages and show them in form:
from osv import osv
from osv import fields
from openerp.tools.translate import _
WARNING_TYPES = [('warning','Warning'),('info','Information'),('error','Error')]
class warning(osv.osv_memory):
_name = 'warning'
_description = 'warning'
_columns = {
'type': fields.selection(WARNING_TYPES, string='Type', readonly=True),
'title': fields.char(string="Title", size=100, readonly=True),
'message': fields.text(string="Message", readonly=True)}
_req_name = 'title'
def _get_view_id(self, cr, uid):
"""Get the view id
@return: view id, or False if no view found
"""
res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'osc_integ', 'warning_form')
return res and res[1] or False
def message(self, cr, uid, id, context):
message = self.browse(cr, uid, id)
message_type = [t[1]for t in WARNING_TYPES if message.type == t[0]][0]
print '%s: %s' % (_(message_type), _(message.title))
res = {
'name': '%s: %s' % (_(message_type), _(message.title)),
'view_type': 'form',
'view_mode': 'form',
'view_id': self._get_view_id(cr, uid),
'res_model': 'warning',
'domain': [],
'context': context,
'type': 'ir.actions.act_window',
'target': 'new',
'res_id': message.id
}
return res
def warning(self, cr, uid, title, message, context=None):
id = self.create(cr, uid, {'title': title, 'message': message, 'type': 'warning'})
res = self.message(cr, uid, id, context)
return res
def info(self, cr, uid, title, message, context=None):
id = self.create(cr, uid, {'title': title, 'message': message, 'type': 'info'})
res = self.message(cr, uid, id, context)
return res
def error(self, cr, uid, title, message, context=None):
id = self.create(cr, uid, {'title': title, 'message': message, 'type': 'error'})
res = self.message(cr, uid, id, context)
return res
Create View form XML:
<openerp>
<data>
<record id="warning_form" model="ir.ui.view">
<field name="name">warning.form</field>
<field name="model">warning</field>
<field eval="20" name="priority"/>
<field name="arch" type="xml">
<form string="Warning" version="7.0">
<field name="message" nolabel="1" />
<footer>
<button string="OK" class="oe_highlight" special="cancel" />
</footer>
</form>
</field>
</record>
<record model="ir.actions.act_window" id="action_warning">
<field name="name">Warning</field>
<field name="res_model">warning</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="warning_form" />
<field name="target">new</field>
</record>
</data>
</openerp>
And at last you can call method every where you need:
return self.pool.get('warning').info(cr, uid, title='Export imformation', message="%s products Created, %s products Updated "%(str(prod_new),str(prod_update)))
def log_prod(self, cr, uid, ids, context=None):
product=self.pool.get('product.product').browse(cr, uid, ids)
msg=_("Product %s has been created") % product.name
self.message_post(cr, uid, ids, body=msg, context=context)
return True
def create(self, cr, uid, data, context=None):
new_id = super(product_product,self).create(cr, uid, data, context)
self.log_prod(cr,uid,new_id,context)
return new_id
Like this code try.
Hope this will help you. :)
there's no widget for this AFAIK. you should develop your own. You can find a starting point here
def message_post(self, cr, uid, thread_id, body='', subject=None, type='notification',
subtype=None, parent_id=False, attachments=None, context=None,
content_subtype='html', **kwargs):
""" Post a new message in an existing thread, returning the new
mail.message ID.
:param int thread_id: thread ID to post into, or list with one ID;
if False/0, mail.message model will also be set as False
:param str body: body of the message, usually raw HTML that will
be sanitized
:param str type: see mail_message.type field
:param str content_subtype:: if plaintext: convert body into html
:param int parent_id: handle reply to a previous message by adding the
parent partners to the message in case of private discussion
:param tuple(str,str) attachments or list id: list of attachment tuples in the form
``(name,content)``, where content is NOT base64 encoded
Extra keyword arguments will be used as default column values for the
new mail.message record. Special cases:
- attachment_ids: supposed not attached to any document; attach them
to the related document. Should only be set by Chatter.
:return int: ID of newly created mail.message
"""
if context is None:
context = {}
if attachments is None:
attachments = {}
mail_message = self.pool.get('mail.message')
ir_attachment = self.pool.get('ir.attachment')
assert (not thread_id) or \
isinstance(thread_id, (int, long)) or \
(isinstance(thread_id, (list, tuple)) and len(thread_id) == 1), \
"Invalid thread_id; should be 0, False, an ID or a list with one ID"
if isinstance(thread_id, (list, tuple)):
thread_id = thread_id[0]
# if we're processing a message directly coming from the gateway, the destination model was
# set in the context.
model = False
if thread_id:
model = context.get('thread_model', self._name) if self._name == 'mail.thread' else self._name
if model != self._name:
del context['thread_model']
return self.pool.get(model).message_post(cr, uid, thread_id, body=body, subject=subject, type=type, subtype=subtype, parent_id=parent_id, attachments=attachments, context=context, content_subtype=content_subtype, **kwargs)
# 0: Parse email-from, try to find a better author_id based on document's followers for incoming emails
email_from = kwargs.get('email_from')
if email_from and thread_id and type == 'email' and kwargs.get('author_id'):
email_list = tools.email_split(email_from)
doc = self.browse(cr, uid, thread_id, context=context)
if email_list and doc:
author_ids = self.pool.get('res.partner').search(cr, uid, [
('email', 'ilike', email_list[0]),
('id', 'in', [f.id for f in doc.message_follower_ids])
], limit=1, context=context)
if author_ids:
kwargs['author_id'] = author_ids[0]
author_id = kwargs.get('author_id')
if author_id is None: # keep False values
author_id = self.pool.get('mail.message')._get_default_author(cr, uid, context=context)
# 1: Handle content subtype: if plaintext, converto into HTML
if content_subtype == 'plaintext':
body = tools.plaintext2html(body)
# 2: Private message: add recipients (recipients and author of parent message) - current author
# + legacy-code management (! we manage only 4 and 6 commands)
partner_ids = set()
kwargs_partner_ids = kwargs.pop('partner_ids', [])
for partner_id in kwargs_partner_ids:
if isinstance(partner_id, (list, tuple)) and partner_id[0] == 4 and len(partner_id) == 2:
partner_ids.add(partner_id[1])
if isinstance(partner_id, (list, tuple)) and partner_id[0] == 6 and len(partner_id) == 3:
partner_ids |= set(partner_id[2])
elif isinstance(partner_id, (int, long)):
partner_ids.add(partner_id)
else:
pass # we do not manage anything else
if parent_id and not model:
parent_message = mail_message.browse(cr, uid, parent_id, context=context)
private_followers = set([partner.id for partner in parent_message.partner_ids])
if parent_message.author_id:
private_followers.add(parent_message.author_id.id)
private_followers -= set([author_id])
partner_ids |= private_followers
# 3. Attachments
# - HACK TDE FIXME: Chatter: attachments linked to the document (not done JS-side), load the message
attachment_ids = kwargs.pop('attachment_ids', []) or [] # because we could receive None (some old code sends None)
if attachment_ids:
filtered_attachment_ids = ir_attachment.search(cr, SUPERUSER_ID, [
('res_model', '=', 'mail.compose.message'),
('res_id', '=', 0),
('create_uid', '=', uid),
('id', 'in', attachment_ids)], context=context)
if filtered_attachment_ids:
ir_attachment.write(cr, SUPERUSER_ID, filtered_attachment_ids, {'res_model': model, 'res_id': thread_id}, context=context)
attachment_ids = [(4, id) for id in attachment_ids]
# Handle attachments parameter, that is a dictionary of attachments
for name, content in attachments:
if isinstance(content, unicode):
content = content.encode('utf-8')
data_attach = {
'name': name,
'datas': base64.b64encode(str(content)),
'datas_fname': name,
'description': name,
'res_model': model,
'res_id': thread_id,
}
attachment_ids.append((0, 0, data_attach))
# 4: mail.message.subtype
subtype_id = False
if subtype:
if '.' not in subtype:
subtype = 'mail.%s' % subtype
ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, *subtype.split('.'))
subtype_id = ref and ref[1] or False
# automatically subscribe recipients if asked to
if context.get('mail_post_autofollow') and thread_id and partner_ids:
partner_to_subscribe = partner_ids
if context.get('mail_post_autofollow_partner_ids'):
partner_to_subscribe = filter(lambda item: item in context.get('mail_post_autofollow_partner_ids'), partner_ids)
self.message_subscribe(cr, uid, [thread_id], list(partner_to_subscribe), context=context)
# _mail_flat_thread: automatically set free messages to the first posted message
if self._mail_flat_thread and not parent_id and thread_id:
message_ids = mail_message.search(cr, uid, ['&', ('res_id', '=', thread_id), ('model', '=', model)], context=context, order="id ASC", limit=1)
parent_id = message_ids and message_ids[0] or False
# we want to set a parent: force to set the parent_id to the oldest ancestor, to avoid having more than 1 level of thread
elif parent_id:
message_ids = mail_message.search(cr, SUPERUSER_ID, [('id', '=', parent_id), ('parent_id', '!=', False)], context=context)
# avoid loops when finding ancestors
processed_list = []
if message_ids:
message = mail_message.browse(cr, SUPERUSER_ID, message_ids[0], context=context)
while (message.parent_id and message.parent_id.id not in processed_list):
processed_list.append(message.parent_id.id)
message = message.parent_id
parent_id = message.id
values = kwargs
values.update({
'author_id': author_id,
'model': model,
'res_id': thread_id or False,
'body': body,
'subject': subject or False,
'type': type,
'parent_id': parent_id,
'attachment_ids': attachment_ids,
'subtype_id': subtype_id,
'partner_ids': [(4, pid) for pid in partner_ids],
})
# Avoid warnings about non-existing fields
for x in ('from', 'to', 'cc'):
values.pop(x, None)
# Create and auto subscribe the author
msg_id = mail_message.create(cr, uid, values, context=context)
message = mail_message.browse(cr, uid, msg_id, context=context)
if message.author_id and thread_id and type != 'notification' and not context.get('mail_create_nosubscribe'):
self.message_subscribe(cr, uid, [thread_id], [message.author_id.id], context=context)
return msg_id
In my opinion, the easiest way is to use either the "action_info" or "action_warn" client action. They both produce Growl-like notifications, but they use different icons. To invoke either one, return a dictionary from your server action like the following:
{
'type': 'ir.actions.client',
'tag': 'action_info',
'name': 'Notification',
'params': {
'title': 'Notification Title',
'text': 'Notification text.',
'sticky': True
}
}
Most of this should be self-explanatory aside from the sticky
parameter. sticky
indicates whether the notification should remain until the user dismisses it. If it's set to False
, it'll fade away on its own after a few seconds.
There's a somewhat fuller example on my blog, if you need one.