diff --git a/.tx/config b/.tx/config index 237b350d406..4bb5619e733 100644 --- a/.tx/config +++ b/.tx/config @@ -1002,9 +1002,9 @@ file_filter = addons/website_profile/i18n/.po source_file = addons/website_profile/i18n/website_profile.pot source_lang = en -[odoo-master.website_rating] -file_filter = addons/website_rating/i18n/.po -source_file = addons/website_rating/i18n/website_rating.pot +[odoo-master.portal_rating] +file_filter = addons/portal_rating/i18n/.po +source_file = addons/portal_rating/i18n/portal_rating.pot source_lang = en [odoo-master.website_sale] diff --git a/addons/calendar/models/calendar.py b/addons/calendar/models/calendar.py index 98f25ab908a..97e131702ae 100644 --- a/addons/calendar/models/calendar.py +++ b/addons/calendar/models/calendar.py @@ -226,7 +226,7 @@ class Attendee(models.Model): result = self.write({'state': 'accepted'}) for attendee in self: if attendee.event_id: - attendee.event_id.message_post(body=_("%s has accepted invitation") % (attendee.common_name), subtype="calendar.subtype_invitation") + attendee.event_id.message_post(body=_("%s has accepted invitation") % (attendee.common_name), subtype_xmlid="calendar.subtype_invitation") return result def do_decline(self): @@ -234,7 +234,7 @@ class Attendee(models.Model): res = self.write({'state': 'declined'}) for attendee in self: if attendee.event_id: - attendee.event_id.message_post(body=_("%s has declined invitation") % (attendee.common_name), subtype="calendar.subtype_invitation") + attendee.event_id.message_post(body=_("%s has declined invitation") % (attendee.common_name), subtype_xmlid="calendar.subtype_invitation") return res diff --git a/addons/gamification/models/challenge.py b/addons/gamification/models/challenge.py index 868e46d1fdf..50254967205 100644 --- a/addons/gamification/models/challenge.py +++ b/addons/gamification/models/challenge.py @@ -562,13 +562,13 @@ class Challenge(models.Model): challenge.message_post( body=body_html, partner_ids=challenge.mapped('user_ids.partner_id.id'), - subtype='mail.mt_comment', + subtype_xmlid='mail.mt_comment', email_layout_xmlid='mail.mail_notification_light', ) if challenge.report_message_group_id: challenge.report_message_group_id.message_post( body=body_html, - subtype='mail.mt_comment') + subtype_xmlid='mail.mt_comment') else: # generate individual reports @@ -586,13 +586,13 @@ class Challenge(models.Model): challenge.message_notify( body=body_html, partner_ids=[user.partner_id.id], - subtype='mail.mt_comment', + subtype_xmlid='mail.mt_comment', email_layout_xmlid='mail.mail_notification_light', ) if challenge.report_message_group_id: challenge.report_message_group_id.message_post( body=body_html, - subtype='mail.mt_comment', + subtype_xmlid='mail.mt_comment', email_layout_xmlid='mail.mail_notification_light', ) return challenge.write({'last_report_date': fields.Date.today()}) diff --git a/addons/gamification/models/goal.py b/addons/gamification/models/goal.py index f78012d236b..80803449897 100644 --- a/addons/gamification/models/goal.py +++ b/addons/gamification/models/goal.py @@ -219,7 +219,7 @@ class Goal(models.Model): self.message_notify( body=body_html, partner_ids=[self.user_id.partner_id.id], - subtype='mail.mt_comment', + subtype_xmlid='mail.mt_comment', email_layout_xmlid='mail.mail_notification_light', ) diff --git a/addons/hr_holidays/models/hr_leave.py b/addons/hr_holidays/models/hr_leave.py index b5d5c1a3458..6c05fc2c61e 100644 --- a/addons/hr_holidays/models/hr_leave.py +++ b/addons/hr_holidays/models/hr_leave.py @@ -666,7 +666,7 @@ class HolidaysRequest(models.Model): # Automatic validation should be done in sudo, because user might not have the rights to do it by himself holiday_sudo.action_validate() holiday_sudo.message_subscribe(partner_ids=[holiday._get_responsible_for_approval().partner_id.id]) - holiday_sudo.message_post(body=_("The time off has been automatically approved"), subtype="mt_comment") # Message from OdooBot (sudo) + holiday_sudo.message_post(body=_("The time off has been automatically approved"), subtype_xmlid="mail.mt_comment") # Message from OdooBot (sudo) elif not self._context.get('import_file'): holiday_sudo.activity_update() return holiday diff --git a/addons/hr_holidays/tests/test_access_rights.py b/addons/hr_holidays/tests/test_access_rights.py index 1a8632f51a9..8781548ad27 100644 --- a/addons/hr_holidays/tests/test_access_rights.py +++ b/addons/hr_holidays/tests/test_access_rights.py @@ -608,7 +608,7 @@ class TestAccessRightsWrite(TestHrHolidaysAccessRightsCommon): """ User may communicate on its own leaves, even if validated """ self.employee_leave.with_user(self.user_employee_id).message_post( body='I haz messaging', - subtype='mail.mt_comment', + subtype_xmlid='mail.mt_comment', message_type='comment' ) @@ -616,7 +616,7 @@ class TestAccessRightsWrite(TestHrHolidaysAccessRightsCommon): self.employee_leave.with_user(self.user_employee_id).message_post( body='I still haz messaging', - subtype='mail.mt_comment', + subtype_xmlid='mail.mt_comment', message_type='comment' ) diff --git a/addons/hr_recruitment/models/hr_recruitment.py b/addons/hr_recruitment/models/hr_recruitment.py index ad0a2f32e84..2a6fca31b05 100644 --- a/addons/hr_recruitment/models/hr_recruitment.py +++ b/addons/hr_recruitment/models/hr_recruitment.py @@ -448,7 +448,7 @@ class Applicant(models.Model): applicant.job_id.write({'no_of_hired_employee': applicant.job_id.no_of_hired_employee + 1}) applicant.job_id.message_post( body=_('New Employee %s Hired') % applicant.partner_name if applicant.partner_name else applicant.name, - subtype="hr_recruitment.mt_job_applicant_hired") + subtype_xmlid="hr_recruitment.mt_job_applicant_hired") applicant.message_post_with_view( 'hr_recruitment.applicant_hired_template', values={'applicant': applicant}, diff --git a/addons/im_livechat/controllers/main.py b/addons/im_livechat/controllers/main.py index 84f8a83ac47..41c8c0042dd 100644 --- a/addons/im_livechat/controllers/main.py +++ b/addons/im_livechat/controllers/main.py @@ -112,6 +112,7 @@ class LivechatController(http.Controller): 'rating': rate, 'consumed': True, 'feedback': reason, + 'is_internal': False, } if not channel.rating_ids: res_model_id = request.env['ir.model'].sudo().search([('model', '=', channel._name)], limit=1).id diff --git a/addons/mail/controllers/bus.py b/addons/mail/controllers/bus.py index 81f1700987d..ccbe6bdeb5f 100644 --- a/addons/mail/controllers/bus.py +++ b/addons/mail/controllers/bus.py @@ -53,7 +53,7 @@ class MailChatController(BusController): message = mail_channel.with_context(mail_create_nosubscribe=True).message_post(author_id=author_id, email_from=email_from, body=body, message_type='comment', - subtype='mail.mt_comment') + subtype_xmlid='mail.mt_comment') return message and message.id or False @route(['/mail/chat_history'], type="json", auth="public", cors="*") diff --git a/addons/mail/controllers/home.py b/addons/mail/controllers/home.py index b4c4bd5d93d..9d54b6ebd1c 100644 --- a/addons/mail/controllers/home.py +++ b/addons/mail/controllers/home.py @@ -27,7 +27,7 @@ def _admin_password_warn(uid): .message_post( body=_("Your password is the default (admin)! If this system is exposed to untrusted users it is important to change it immediately for security reasons. I will keep nagging you about it!"), message_type='comment', - subtype='mail.mt_comment' + subtype_xmlid='mail.mt_comment' ) class Home(web.Home): diff --git a/addons/mail/models/mail_channel.py b/addons/mail/models/mail_channel.py index 2d3c54a9591..f78a415b522 100644 --- a/addons/mail/models/mail_channel.py +++ b/addons/mail/models/mail_channel.py @@ -280,7 +280,7 @@ class Channel(models.Model): if not self.email_send: notification = _('
left #%s
') % (self.id, self.name,) # post 'channel left' message as root since the partner just unsubscribed from the channel - self.sudo().message_post(body=notification, subtype="mail.mt_comment", author_id=partner.id) + self.sudo().message_post(body=notification, subtype_xmlid="mail.mt_comment", author_id=partner.id) return result def _notify_get_groups(self): @@ -780,7 +780,7 @@ class Channel(models.Model): } else: notification = _('
joined #%s
') % (channel.id, channel.name,) - self.message_post(body=notification, message_type="notification", subtype="mail.mt_comment", author_id=partner.id) + self.message_post(body=notification, message_type="notification", subtype_xmlid="mail.mt_comment", author_id=partner.id) # broadcast the channel header to the added partner self._broadcast(partner_ids) @@ -861,7 +861,7 @@ class Channel(models.Model): added = self.action_follow() if added and self.channel_type == 'channel' and not self.email_send: notification = _('
joined #%s
') % (self.id, self.name,) - self.message_post(body=notification, message_type="notification", subtype="mail.mt_comment") + self.message_post(body=notification, message_type="notification", subtype_xmlid="mail.mt_comment") if added and self.moderation_guidelines: self._send_guidelines(self.env.user.partner_id) @@ -886,7 +886,7 @@ class Channel(models.Model): 'channel_partner_ids': [(4, self.env.user.partner_id.id)] }) notification = _('
created #%s
') % (new_channel.id, new_channel.name,) - new_channel.message_post(body=notification, message_type="notification", subtype="mail.mt_comment") + new_channel.message_post(body=notification, message_type="notification", subtype_xmlid="mail.mt_comment") channel_info = new_channel.channel_info('creation')[0] self.env['bus.bus'].sendone((self._cr.dbname, 'res.partner', self.env.user.partner_id.id), channel_info) return channel_info diff --git a/addons/mail/models/mail_message.py b/addons/mail/models/mail_message.py index 0a038e381eb..2b906074915 100644 --- a/addons/mail/models/mail_message.py +++ b/addons/mail/models/mail_message.py @@ -12,7 +12,6 @@ from odoo import _, api, fields, models, modules, tools from odoo.exceptions import AccessError from odoo.http import request from odoo.osv import expression -from odoo.tools import groupby _logger = logging.getLogger(__name__) _image_dataurl = re.compile(r'(data:image/[a-z]+?);base64,([a-z0-9+/\n]{3,}=*)\n*([\'"])(?: data-filename="([^"]*)")?', re.I) @@ -43,6 +42,9 @@ class Message(models.Model): subject = fields.Char('Subject') date = fields.Datetime('Date', default=fields.Datetime.now) body = fields.Html('Contents', default='', sanitize_style=True) + description = fields.Char( + 'Short description', compute="_compute_description", + help='Message description: either the subject, or the beginning of the body') attachment_ids = fields.Many2many( 'ir.attachment', 'message_attachment_rel', 'message_id', 'attachment_id', @@ -71,6 +73,7 @@ class Message(models.Model): mail_activity_type_id = fields.Many2one( 'mail.activity.type', 'Mail Activity Type', index=True, ondelete='set null') + is_internal = fields.Boolean('Employee Only', help='Hide to public / portal users, independently from subtype configuration.') # origin email_from = fields.Char('From', help="Email address of the sender. This field is set when no matching partner is found and replaces the author_id field in the chatter.") author_id = fields.Many2one( @@ -124,7 +127,7 @@ class Message(models.Model): ('rejected', 'Rejected')], string="Moderation Status", index=True) moderator_id = fields.Many2one('res.users', string="Moderated By", index=True) need_moderation = fields.Boolean('Need moderation', compute='_compute_need_moderation', search='_search_need_moderation') - #keep notification layout informations to be able to generate mail again + # keep notification layout informations to be able to generate mail again email_layout_xmlid = fields.Char('Layout', copy=False) # xml id of layout add_sign = fields.Boolean(default=True) # `test_adv_activity`, `test_adv_activity_full`, `test_message_assignation_inbox`,... @@ -137,6 +140,14 @@ class Message(models.Model): mail_ids = fields.One2many('mail.mail', 'mail_message_id', string='Mails', groups="base.group_system") canned_response_ids = fields.One2many('mail.shortcode', 'message_ids', string="Canned Responses", store=False) + def _compute_description(self): + for message in self: + if message.subject: + message.description = message.subject + else: + plaintext_ct = '' if not message.body else tools.html2plaintext(message.body) + message.description = plaintext_ct[:30] + '%s' % (' [...]' if len(plaintext_ct) >= 30 else '') + def _get_needaction(self): """ Need action on a mail.message = notified on my channel """ my_messages = self.env['mail.notification'].sudo().search([ @@ -224,9 +235,9 @@ class Message(models.Model): return super(Message, self)._search( args, offset=offset, limit=limit, order=order, count=count, access_rights_uid=access_rights_uid) - # Non-employee see only messages with a subtype (aka, no internal logs) + # Non-employee see only messages with a subtype and not internal if not self.env['res.users'].has_group('base.group_user'): - args = ['&', '&', ('subtype_id', '!=', False), ('subtype_id.internal', '=', False)] + list(args) + args = expression.AND([self._get_search_domain_share(), args]) # Perform a super with count as False, to have the ids, not a counter ids = super(Message, self)._search( args, offset=offset, limit=limit, order=order, @@ -349,7 +360,9 @@ class Message(models.Model): FROM "%s" AS message LEFT JOIN "mail_message_subtype" as subtype ON message.subtype_id = subtype.id - WHERE message.message_type = %%s AND (message.subtype_id IS NULL OR subtype.internal IS TRUE) AND message.id = ANY (%%s)''' % (self._table), ('comment', self.ids,)) + WHERE message.message_type = %%s AND + (message.is_internal IS TRUE OR message.subtype_id IS NULL OR subtype.internal IS TRUE) AND + message.id = ANY (%%s)''' % (self._table), ('comment', self.ids,)) if self._cr.fetchall(): raise AccessError( _('The requested operation cannot be completed due to security restrictions. Please contact your system administrator.\n\n(Document type: %s, Operation: %s)') % (self._description, operation) @@ -1200,7 +1213,7 @@ class Message(models.Model): else: messages |= message - for author, author_messages in groupby(messages, itemgetter('author_id')): + for author, author_messages in tools.groupby(messages, itemgetter('author_id')): self.env['bus.bus'].sendone( (self._cr.dbname, 'res.partner', author.id), {'type': 'mail_failure', 'elements': self.env['mail.message'].concat(*author_messages)._format_mail_failures()} @@ -1269,3 +1282,6 @@ class Message(models.Model): 'message_needaction', 'message_needaction_counter', ], ids=[res_id]) + + def _get_search_domain_share(self): + return ['&', '&', ('is_internal', '=', False), ('subtype_id', '!=', False), ('subtype_id.internal', '=', False)] diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index 89b6818bc64..6ca54653d87 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -1056,7 +1056,7 @@ class MailThread(models.AbstractModel): parent_message = self.env['mail.message'].sudo().browse(message_dict['parent_id']) partner_ids = [] if not subtype_id: - if message_dict.pop('internal', False): + if message_dict.get('is_internal'): subtype_id = self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note') if parent_message and parent_message.author_id: partner_ids = [parent_message.author_id.id] @@ -1367,7 +1367,7 @@ class MailThread(models.AbstractModel): 'references': references, 'in_reply_to': in-reply-to, 'parent_id': parent mail.message based on in_reply_to or references, - 'internal': answer to an internal message (note), + 'is_internal': answer to an internal message (note), 'date': date, 'attachments': [('file1', 'bytes'), ('file2', 'bytes')} @@ -1437,18 +1437,15 @@ class MailThread(models.AbstractModel): stored_date = datetime.datetime.now() msg_dict['date'] = stored_date.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT) + parent_ids = False if msg_dict['in_reply_to']: parent_ids = self.env['mail.message'].search([('message_id', '=', msg_dict['in_reply_to'])], limit=1) - if parent_ids: - msg_dict['parent_id'] = parent_ids.id - msg_dict['internal'] = parent_ids.subtype_id and parent_ids.subtype_id.internal or False - - if msg_dict['references'] and 'parent_id' not in msg_dict: + if msg_dict['references'] and not parent_ids: references_msg_id_list = tools.mail_header_msgid_re.findall(msg_dict['references']) parent_ids = self.env['mail.message'].search([('message_id', 'in', [x.strip() for x in references_msg_id_list])], limit=1) - if parent_ids: - msg_dict['parent_id'] = parent_ids.id - msg_dict['internal'] = parent_ids.subtype_id and parent_ids.subtype_id.internal or False + if parent_ids: + msg_dict['parent_id'] = parent_ids.id + msg_dict['is_internal'] = parent_ids.subtype_id and parent_ids.subtype_id.internal or False msg_dict.update(self._message_parse_extract_payload(message, save_original=save_original)) msg_dict.update(self._message_parse_extract_bounce(message, msg_dict)) @@ -1777,7 +1774,7 @@ class MailThread(models.AbstractModel): def message_post(self, *, body='', subject=None, message_type='notification', email_from=None, author_id=None, parent_id=False, - subtype_id=False, subtype=None, partner_ids=None, channel_ids=None, + subtype_xmlid=None, subtype_id=False, partner_ids=None, channel_ids=None, attachments=None, attachment_ids=None, add_sign=True, record_name=False, **kwargs): @@ -1791,8 +1788,6 @@ class MailThread(models.AbstractModel): :param int parent_id: handle thread formation :param int subtype_id: subtype_id of the message, mainly use fore followers mechanism - :param int subtype: xmlid that will be used to compute subtype_id - if subtype_id is not given. :param list(int) partner_ids: partner_ids to notify :param list(int) channel_ids: channel_ids to notify :param list(tuple(str,str), tuple(str,str, dict) or int) attachments : list of attachment tuples in the form @@ -1814,7 +1809,9 @@ class MailThread(models.AbstractModel): raise ValueError('message_post should only be call to post message on record. Use message_notify instead') if 'model' in msg_kwargs or 'res_id' in msg_kwargs: - raise ValueError("message_post doesn't support model and res_id parameters anymore. Please call message_post on record") + raise ValueError("message_post doesn't support model and res_id parameters anymore. Please call message_post on record.") + if 'subtype' in kwargs: + raise ValueError("message_post doesn't support subtype parameter anymore. Please give a valid subtype_id or subtype_xmlid value instead.") self = self.with_lang() # add lang to context imediatly since it will be usefull in various flows latter. @@ -1832,11 +1829,10 @@ class MailThread(models.AbstractModel): # Find the message's author author_id, email_from = self._message_compute_author(author_id, email_from, raise_exception=True) + if subtype_xmlid: + subtype_id = self.env['ir.model.data'].xmlid_to_res_id(subtype_xmlid) if not subtype_id: - subtype = subtype or 'mt_note' - if '.' not in subtype: - subtype = 'mail.%s' % subtype - subtype_id = self.env['ir.model.data'].xmlid_to_res_id(subtype) + subtype_id = self.env['ir.model.data'].xmlid_to_res_id('mail_mt_note') # automatically subscribe recipients if asked to if self._context.get('mail_post_autofollow') and partner_ids: @@ -1997,6 +1993,7 @@ class MailThread(models.AbstractModel): 'email_from': email_from, 'partner_ids': partner_ids, 'subtype_id': self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'), + 'is_internal': True, 'record_name': False, 'reply_to': MailThread._notify_get_reply_to(default=email_from, records=None)[False], 'message_id': tools.generate_tracking_message_id('message-notify'), @@ -2025,6 +2022,7 @@ class MailThread(models.AbstractModel): 'model': kwargs.get('model', self._name), 'res_id': self.ids[0] if self.ids else False, 'subtype_id': self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'), + 'is_internal': True, 'record_name': False, 'reply_to': self.env['mail.thread']._notify_get_reply_to(default=email_from, records=None)[False], 'message_id': tools.generate_tracking_message_id('message-notify'), # why? this is all but a notify @@ -2047,6 +2045,7 @@ class MailThread(models.AbstractModel): 'message_type': message_type, 'model': self._name, 'subtype_id': self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'), + 'is_internal': True, 'record_name': False, 'reply_to': self.env['mail.thread']._notify_get_reply_to(default=email_from, records=None)[False], 'message_id': tools.generate_tracking_message_id('message-notify'), # why? this is all but a notify @@ -2402,7 +2401,7 @@ class MailThread(models.AbstractModel): if pid: if active is False: continue - pdata = {'id': pid, 'active': active, 'share': pshare, 'groups': groups} + pdata = {'id': pid, 'active': active, 'share': pshare, 'groups': groups or []} if notif == 'inbox': recipient_data['partners'].append(dict(pdata, notif=notif, type='user')) elif not pshare and notif: # has an user and is not shared, is therefore user diff --git a/addons/mail/models/update.py b/addons/mail/models/update.py index 573709a1377..edf5b4f2ced 100644 --- a/addons/mail/models/update.py +++ b/addons/mail/models/update.py @@ -104,7 +104,7 @@ class PublisherWarrantyContract(AbstractModel): poster = user for message in result["messages"]: try: - poster.message_post(body=message, subtype='mt_comment', partner_ids=[user.partner_id.id]) + poster.message_post(body=message, subtype_xmlid='mail.mt_comment', partner_ids=[user.partner_id.id]) except Exception: pass if result.get('enterprise_info'): diff --git a/addons/mail/static/src/js/composers/chatter_composer.js b/addons/mail/static/src/js/composers/chatter_composer.js index 4b20e5b2d25..04a01142ff3 100644 --- a/addons/mail/static/src/js/composers/chatter_composer.js +++ b/addons/mail/static/src/js/composers/chatter_composer.js @@ -205,14 +205,14 @@ var ChatterComposer = BasicComposer.extend({ return new Promise(function (resolve, reject) { self._super().then(function (message) { message = _.extend(message, { - subtype: 'mail.mt_comment', + subtype_xmlid: 'mail.mt_comment', message_type: 'comment', context: _.defaults({}, self.context, session.user_context), }); // Subtype if (self.options.isLog) { - message.subtype = 'mail.mt_note'; + message.subtype_xmlid = 'mail.mt_note'; } // Partner_ids diff --git a/addons/mail/static/src/js/discuss.js b/addons/mail/static/src/js/discuss.js index 3d8eda911be..0f2b7feff26 100644 --- a/addons/mail/static/src/js/discuss.js +++ b/addons/mail/static/src/js/discuss.js @@ -1496,7 +1496,7 @@ var Discuss = AbstractAction.extend({ var self = this; var options = {}; if (this._selectedMessage) { - messageData.subtype = this._selectedMessage.isNote() ? 'mail.mt_note': 'mail.mt_comment'; + messageData.subtype_xmlid = this._selectedMessage.isNote() ? 'mail.mt_note': 'mail.mt_comment'; messageData.subtype_id = false; messageData.message_type = 'comment'; diff --git a/addons/mail/static/src/js/models/threads/channel.js b/addons/mail/static/src/js/models/threads/channel.js index 6301018c01f..a47598e3147 100644 --- a/addons/mail/static/src/js/models/threads/channel.js +++ b/addons/mail/static/src/js/models/threads/channel.js @@ -443,7 +443,7 @@ var Channel = SearchableThread.extend(ThreadTypingMixin, { return this._super.apply(this, arguments).then(function (messageData) { _.extend(messageData, { message_type: 'comment', - subtype: 'mail.mt_comment', + subtype_xmlid: 'mail.mt_comment', command: data.command, }); return self._rpc({ diff --git a/addons/mail/static/src/js/models/threads/document_thread.js b/addons/mail/static/src/js/models/threads/document_thread.js index cb860b70beb..eefc8f9bd79 100644 --- a/addons/mail/static/src/js/models/threads/document_thread.js +++ b/addons/mail/static/src/js/models/threads/document_thread.js @@ -331,7 +331,7 @@ var DocumentThread = Thread.extend({ _.extend(messageData, { context: data.context, message_type: data.message_type, - subtype: data.subtype || "mail.mt_comment", + subtype_xmlid: data.subtype_xmlid || "mail.mt_comment", subtype_id: data.subtype_id, }); return self._rpc({ diff --git a/addons/mail/static/tests/chatter_tests.js b/addons/mail/static/tests/chatter_tests.js index d39be2af342..c108738bf94 100644 --- a/addons/mail/static/tests/chatter_tests.js +++ b/addons/mail/static/tests/chatter_tests.js @@ -1008,8 +1008,8 @@ QUnit.test('chatter: post, receive and star messages', async function (assert) { body: args.kwargs.body, date: "2016-12-20 10:35:40", id: messageID, - is_note: args.kwargs.subtype === 'mail.mt_note', - is_discussion: args.kwargs.subtype === 'mail.mt_comment', + is_note: args.kwargs.subtype_xmlid === 'mail.mt_note', + is_discussion: args.kwargs.subtype_xmlid === 'mail.mt_comment', is_notification: false, is_starred: false, model: 'partner', @@ -1403,8 +1403,8 @@ QUnit.test('chatter: post a message and switch in edit mode', async function (as body: args.kwargs.body, date: "2016-12-20 10:35:40", id: 42, - is_note: args.kwargs.subtype === 'mail.mt_note', - is_discussion: args.kwargs.subtype === 'mail.mt_comment', + is_note: args.kwargs.subtype_xmlid === 'mail.mt_note', + is_discussion: args.kwargs.subtype_xmlid === 'mail.mt_comment', is_starred: false, model: 'partner', res_id: 2, @@ -3061,8 +3061,8 @@ QUnit.test('chatter: suggested partner auto-follow on message post', async funct body: args.kwargs.body, date: "2016-12-20 10:35:40", id: messageID, - is_note: args.kwargs.subtype === 'mail.mt_note', - is_discussion: args.kwargs.subtype === 'mail.mt_comment', + is_note: args.kwargs.subtype_xmlid === 'mail.mt_note', + is_discussion: args.kwargs.subtype_xmlid === 'mail.mt_comment', is_notification: false, is_starred: false, model: 'partner', diff --git a/addons/mail/views/mail_blacklist_views.xml b/addons/mail/views/mail_blacklist_views.xml index 05c59ede18b..139344a38a2 100644 --- a/addons/mail/views/mail_blacklist_views.xml +++ b/addons/mail/views/mail_blacklist_views.xml @@ -62,6 +62,6 @@ name="Email Blacklist" action="mail_blacklist_action" parent="mail.mail_menu_technical" - sequence="20"/> + sequence="22"/> diff --git a/addons/mail/views/mail_followers_views.xml b/addons/mail/views/mail_followers_views.xml index d3d743482c7..bb098690b57 100644 --- a/addons/mail/views/mail_followers_views.xml +++ b/addons/mail/views/mail_followers_views.xml @@ -50,7 +50,7 @@ id="menu_email_followers" parent="mail.mail_menu_technical" action="action_view_followers" - sequence="20" + sequence="21" groups="base.group_no_one"/> diff --git a/addons/mail/views/mail_message_views.xml b/addons/mail/views/mail_message_views.xml index c9217f94db2..01015d7aea0 100644 --- a/addons/mail/views/mail_message_views.xml +++ b/addons/mail/views/mail_message_views.xml @@ -18,8 +18,8 @@ - - mail.message.form + + mail.message.view.form mail.message 20 @@ -31,16 +31,17 @@ - - - - - - - + + + + + + + + @@ -81,7 +82,7 @@ - + diff --git a/addons/mail/views/mail_notification_views.xml b/addons/mail/views/mail_notification_views.xml index 8ebbbb18c53..3167fb4cda4 100644 --- a/addons/mail/views/mail_notification_views.xml +++ b/addons/mail/views/mail_notification_views.xml @@ -52,7 +52,7 @@ id="mail_notification_menu" parent="mail.mail_menu_technical" action="mail_notification_action" - sequence="30" + sequence="20" groups="base.group_no_one"/> diff --git a/addons/mail_bot/models/mail_channel.py b/addons/mail_bot/models/mail_channel.py index 0fc6c6f056b..8b792780971 100644 --- a/addons/mail_bot/models/mail_channel.py +++ b/addons/mail_bot/models/mail_channel.py @@ -24,6 +24,6 @@ class Channel(models.Model): 'name': 'OdooBot' }) message = _("Hello,
Odoo's chat helps employees collaborate efficiently. I'm here to help you discover its features.
Try to send me an emoji :)") - channel.sudo().message_post(body=message, author_id=odoobot_id, message_type="comment", subtype="mail.mt_comment") + channel.sudo().message_post(body=message, author_id=odoobot_id, message_type="comment", subtype_xmlid="mail.mt_comment") self.env.user.odoobot_state = 'onboarding_emoji' return channel diff --git a/addons/portal/controllers/mail.py b/addons/portal/controllers/mail.py index 63999697ff3..1cbff66cde5 100644 --- a/addons/portal/controllers/mail.py +++ b/addons/portal/controllers/mail.py @@ -86,7 +86,7 @@ def _message_post_helper(res_model, res_id, message, token='', _hash=False, pid= message_post_args = dict( body=message, message_type=kw.pop('message_type', "comment"), - subtype=kw.pop('subtype', "mt_comment"), + subtype_xmlid=kw.pop('subtype_xmlid', "mail.mt_comment"), author_id=author_id, **kw ) @@ -158,6 +158,7 @@ class PortalChatter(http.Controller): 'options': { 'message_count': message_data['message_count'], 'is_user_public': is_user_public, + 'is_user_employee': request.env.user.has_group('base.group_user'), 'is_user_publisher': request.env.user.has_group('website.group_website_publisher'), 'display_composer': display_composer, 'partner_id': request.env.user.partner_id.id @@ -183,13 +184,19 @@ class PortalChatter(http.Controller): raise Forbidden() # Non-employee see only messages with not internal subtype (aka, no internal logs) if not request.env['res.users'].has_group('base.group_user'): - domain = expression.AND([Message._non_employee_message_domain(), domain]) + domain = expression.AND([Message._get_search_domain_share(), domain]) Message = request.env['mail.message'].sudo() return { 'messages': Message.search(domain, limit=limit, offset=offset).portal_message_format(), 'message_count': Message.search_count(domain) } + @http.route(['/mail/update_is_internal'], type='json', auth="user", website=True) + def portal_message_update_is_internal(self, message_id, is_internal): + message = request.env['mail.message'].browse(int(message_id)) + message.write({'is_internal': is_internal}) + return message.is_internal + class MailController(MailController): diff --git a/addons/portal/models/mail_message.py b/addons/portal/models/mail_message.py index 1d98ce7cf76..cfda6d5eaa0 100644 --- a/addons/portal/models/mail_message.py +++ b/addons/portal/models/mail_message.py @@ -10,7 +10,7 @@ class MailMessage(models.Model): def portal_message_format(self): return self._portal_message_format([ 'id', 'body', 'date', 'author_id', 'email_from', # base message fields - 'message_type', 'subtype_id', 'subject', # message specific + 'message_type', 'subtype_id', 'is_internal', 'subject', # message specific 'model', 'res_id', 'record_name', # document related ]) @@ -24,7 +24,3 @@ class MailMessage(models.Model): if not attachment.get('access_token'): attachment['access_token'] = IrAttachmentSudo.browse(attachment['id']).generate_access_token()[0] return message_values - - @api.model - def _non_employee_message_domain(self): - return ['&', ('subtype_id', '!=', False), ('subtype_id.internal', '=', False)] diff --git a/addons/portal/static/src/js/portal_chatter.js b/addons/portal/static/src/js/portal_chatter.js index 0b23ec2c386..8e5c0a3144f 100644 --- a/addons/portal/static/src/js/portal_chatter.js +++ b/addons/portal/static/src/js/portal_chatter.js @@ -20,7 +20,8 @@ var PortalChatter = publicWidget.Widget.extend({ template: 'portal.Chatter', xmlDependencies: ['/portal/static/src/xml/portal_chatter.xml'], events: { - "click .o_portal_chatter_pager_btn": '_onClickPager', + 'click .o_portal_chatter_pager_btn': '_onClickPager', + 'click .o_portal_chatter_js_is_internal': 'async _onClickUpdateIsInternal', }, /** @@ -45,6 +46,7 @@ var PortalChatter = publicWidget.Widget.extend({ 'pager_scope': 5, 'pager_start': 1, 'is_user_public': true, + 'is_user_employee': false, 'is_user_publisher': false, 'hash': false, 'pid': false, @@ -254,6 +256,35 @@ var PortalChatter = publicWidget.Widget.extend({ var page = $(ev.currentTarget).data('page'); this._changeCurrentPage(page); }, + + /** + * Toggle is_internal state of message. Update both node data and + * classes to ensure DOM is updated accordingly to RPC call result. + * @private + * @returns {Promise} + */ + _onClickUpdateIsInternal: function (ev) { + ev.preventDefault(); + + var $elem = $(ev.currentTarget); + return this._rpc({ + route: '/mail/update_is_internal', + params: { + message_id: $elem.data('message-id'), + is_internal: ! $elem.data('is-internal'), + }, + }).then(function (result) { + $elem.data('is-internal', result); + if (result === true) { + $elem.addClass('o_portal_message_internal_on'); + $elem.removeClass('o_portal_message_internal_off'); + } + else { + $elem.addClass('o_portal_message_internal_off'); + $elem.removeClass('o_portal_message_internal_on'); + } + }); + }, }); publicWidget.registry.portalChatter = publicWidget.Widget.extend({ diff --git a/addons/portal/static/src/scss/portal.scss b/addons/portal/static/src/scss/portal.scss index 471dc7f9c8b..bd59bfc1419 100644 --- a/addons/portal/static/src/scss/portal.scss +++ b/addons/portal/static/src/scss/portal.scss @@ -524,4 +524,16 @@ form label { opacity: 1; } } + + .o_portal_message_internal_off { + .btn-danger { + display: none; + } + } + + .o_portal_message_internal_on { + .btn-success { + display: none; + } + } } diff --git a/addons/portal/static/src/xml/portal_chatter.xml b/addons/portal/static/src/xml/portal_chatter.xml index 520dc46eaa7..179d4f70626 100644 --- a/addons/portal/static/src/xml/portal_chatter.xml +++ b/addons/portal/static/src/xml/portal_chatter.xml @@ -92,6 +92,7 @@
avatar
+
@@ -110,6 +111,18 @@
+ + +
+ + +
+
+
diff --git a/addons/website_rating/__init__.py b/addons/portal_rating/__init__.py similarity index 100% rename from addons/website_rating/__init__.py rename to addons/portal_rating/__init__.py diff --git a/addons/website_rating/__manifest__.py b/addons/portal_rating/__manifest__.py similarity index 61% rename from addons/website_rating/__manifest__.py rename to addons/portal_rating/__manifest__.py index 3a454763d21..273f594dad6 100644 --- a/addons/website_rating/__manifest__.py +++ b/addons/portal_rating/__manifest__.py @@ -2,13 +2,17 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. { - 'name': 'Website Rating', + 'name': 'Portal Rating', 'category': 'Hidden', 'version': '1.0', 'description': """ -Bridge module for rating on website stuff. +Bridge module adding rating capabilities on portal. It includes notably +inclusion of rating directly within the customer portal discuss widget. """, - 'depends': ['rating', 'website_mail'], + 'depends': [ + 'portal', + 'rating', + ], 'data': [ 'views/assets.xml', 'views/rating_views.xml', diff --git a/addons/website_rating/controllers/__init__.py b/addons/portal_rating/controllers/__init__.py similarity index 100% rename from addons/website_rating/controllers/__init__.py rename to addons/portal_rating/controllers/__init__.py diff --git a/addons/website_rating/controllers/portal_chatter.py b/addons/portal_rating/controllers/portal_chatter.py similarity index 100% rename from addons/website_rating/controllers/portal_chatter.py rename to addons/portal_rating/controllers/portal_chatter.py diff --git a/addons/website_rating/controllers/portal_rating.py b/addons/portal_rating/controllers/portal_rating.py similarity index 100% rename from addons/website_rating/controllers/portal_rating.py rename to addons/portal_rating/controllers/portal_rating.py diff --git a/addons/website_rating/i18n/ar.po b/addons/portal_rating/i18n/ar.po similarity index 100% rename from addons/website_rating/i18n/ar.po rename to addons/portal_rating/i18n/ar.po diff --git a/addons/website_rating/i18n/az.po b/addons/portal_rating/i18n/az.po similarity index 100% rename from addons/website_rating/i18n/az.po rename to addons/portal_rating/i18n/az.po diff --git a/addons/website_rating/i18n/bs.po b/addons/portal_rating/i18n/bs.po similarity index 100% rename from addons/website_rating/i18n/bs.po rename to addons/portal_rating/i18n/bs.po diff --git a/addons/website_rating/i18n/ca.po b/addons/portal_rating/i18n/ca.po similarity index 100% rename from addons/website_rating/i18n/ca.po rename to addons/portal_rating/i18n/ca.po diff --git a/addons/website_rating/i18n/cs.po b/addons/portal_rating/i18n/cs.po similarity index 100% rename from addons/website_rating/i18n/cs.po rename to addons/portal_rating/i18n/cs.po diff --git a/addons/website_rating/i18n/da.po b/addons/portal_rating/i18n/da.po similarity index 100% rename from addons/website_rating/i18n/da.po rename to addons/portal_rating/i18n/da.po diff --git a/addons/website_rating/i18n/de.po b/addons/portal_rating/i18n/de.po similarity index 100% rename from addons/website_rating/i18n/de.po rename to addons/portal_rating/i18n/de.po diff --git a/addons/website_rating/i18n/el.po b/addons/portal_rating/i18n/el.po similarity index 100% rename from addons/website_rating/i18n/el.po rename to addons/portal_rating/i18n/el.po diff --git a/addons/website_rating/i18n/es.po b/addons/portal_rating/i18n/es.po similarity index 100% rename from addons/website_rating/i18n/es.po rename to addons/portal_rating/i18n/es.po diff --git a/addons/website_rating/i18n/et.po b/addons/portal_rating/i18n/et.po similarity index 100% rename from addons/website_rating/i18n/et.po rename to addons/portal_rating/i18n/et.po diff --git a/addons/website_rating/i18n/fa.po b/addons/portal_rating/i18n/fa.po similarity index 100% rename from addons/website_rating/i18n/fa.po rename to addons/portal_rating/i18n/fa.po diff --git a/addons/website_rating/i18n/fi.po b/addons/portal_rating/i18n/fi.po similarity index 100% rename from addons/website_rating/i18n/fi.po rename to addons/portal_rating/i18n/fi.po diff --git a/addons/website_rating/i18n/fr.po b/addons/portal_rating/i18n/fr.po similarity index 100% rename from addons/website_rating/i18n/fr.po rename to addons/portal_rating/i18n/fr.po diff --git a/addons/website_rating/i18n/gu.po b/addons/portal_rating/i18n/gu.po similarity index 100% rename from addons/website_rating/i18n/gu.po rename to addons/portal_rating/i18n/gu.po diff --git a/addons/website_rating/i18n/he.po b/addons/portal_rating/i18n/he.po similarity index 100% rename from addons/website_rating/i18n/he.po rename to addons/portal_rating/i18n/he.po diff --git a/addons/website_rating/i18n/hr.po b/addons/portal_rating/i18n/hr.po similarity index 100% rename from addons/website_rating/i18n/hr.po rename to addons/portal_rating/i18n/hr.po diff --git a/addons/website_rating/i18n/hu.po b/addons/portal_rating/i18n/hu.po similarity index 100% rename from addons/website_rating/i18n/hu.po rename to addons/portal_rating/i18n/hu.po diff --git a/addons/website_rating/i18n/id.po b/addons/portal_rating/i18n/id.po similarity index 100% rename from addons/website_rating/i18n/id.po rename to addons/portal_rating/i18n/id.po diff --git a/addons/website_rating/i18n/is.po b/addons/portal_rating/i18n/is.po similarity index 100% rename from addons/website_rating/i18n/is.po rename to addons/portal_rating/i18n/is.po diff --git a/addons/website_rating/i18n/it.po b/addons/portal_rating/i18n/it.po similarity index 100% rename from addons/website_rating/i18n/it.po rename to addons/portal_rating/i18n/it.po diff --git a/addons/website_rating/i18n/ja.po b/addons/portal_rating/i18n/ja.po similarity index 100% rename from addons/website_rating/i18n/ja.po rename to addons/portal_rating/i18n/ja.po diff --git a/addons/website_rating/i18n/km.po b/addons/portal_rating/i18n/km.po similarity index 100% rename from addons/website_rating/i18n/km.po rename to addons/portal_rating/i18n/km.po diff --git a/addons/website_rating/i18n/ko.po b/addons/portal_rating/i18n/ko.po similarity index 100% rename from addons/website_rating/i18n/ko.po rename to addons/portal_rating/i18n/ko.po diff --git a/addons/website_rating/i18n/lb.po b/addons/portal_rating/i18n/lb.po similarity index 100% rename from addons/website_rating/i18n/lb.po rename to addons/portal_rating/i18n/lb.po diff --git a/addons/website_rating/i18n/lt.po b/addons/portal_rating/i18n/lt.po similarity index 100% rename from addons/website_rating/i18n/lt.po rename to addons/portal_rating/i18n/lt.po diff --git a/addons/website_rating/i18n/lv.po b/addons/portal_rating/i18n/lv.po similarity index 100% rename from addons/website_rating/i18n/lv.po rename to addons/portal_rating/i18n/lv.po diff --git a/addons/website_rating/i18n/mn.po b/addons/portal_rating/i18n/mn.po similarity index 100% rename from addons/website_rating/i18n/mn.po rename to addons/portal_rating/i18n/mn.po diff --git a/addons/website_rating/i18n/nb.po b/addons/portal_rating/i18n/nb.po similarity index 100% rename from addons/website_rating/i18n/nb.po rename to addons/portal_rating/i18n/nb.po diff --git a/addons/website_rating/i18n/nl.po b/addons/portal_rating/i18n/nl.po similarity index 100% rename from addons/website_rating/i18n/nl.po rename to addons/portal_rating/i18n/nl.po diff --git a/addons/website_rating/i18n/pl.po b/addons/portal_rating/i18n/pl.po similarity index 100% rename from addons/website_rating/i18n/pl.po rename to addons/portal_rating/i18n/pl.po diff --git a/addons/portal_rating/i18n/portal_rating.pot b/addons/portal_rating/i18n/portal_rating.pot new file mode 100644 index 00000000000..89a1c98351b --- /dev/null +++ b/addons/portal_rating/i18n/portal_rating.pot @@ -0,0 +1,251 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * portal_rating +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server saas~12.5\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-08-26 08:17+0000\n" +"PO-Revision-Date: 2019-08-26 08:17+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/xml/portal_chatter.xml:0 +#, python-format +msgid "" +"#{widget.options['force_submit_url'] ? widget.options['force_submit_url'] : " +"'/mail/chatter_post'}" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/xml/portal_rating_composer.xml:0 +#, python-format +msgid "×" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/xml/portal_rating_composer.xml:0 +#: code:addons/portal_rating/static/src/xml/portal_rating_composer.xml:0 +#, python-format +msgid "Add a review" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/xml/portal_tools.xml:0 +#, python-format +msgid "Average" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/xml/portal_chatter.xml:0 +#, python-format +msgid "Cancel" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/xml/portal_chatter.xml:0 +#, python-format +msgid "Comment" +msgstr "" + +#. module: portal_rating +#: model:ir.model.fields,field_description:portal_rating.field_rating_rating__publisher_id +msgid "Commented by" +msgstr "" + +#. module: portal_rating +#: model:ir.model.fields,field_description:portal_rating.field_rating_rating__publisher_datetime +msgid "Commented on" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/xml/portal_chatter.xml:0 +#, python-format +msgid "Delete" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/xml/portal_tools.xml:0 +#, python-format +msgid "Details" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/xml/portal_chatter.xml:0 +#, python-format +msgid "Edit" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/xml/portal_tools.xml:0 +#: code:addons/portal_rating/static/src/xml/portal_tools.xml:0 +#, python-format +msgid "Half a star" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/js/portal_composer.js:0 +#, python-format +msgid "I don't like it" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/js/portal_composer.js:0 +#, python-format +msgid "I hate it" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/js/portal_composer.js:0 +#, python-format +msgid "I like it" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/js/portal_composer.js:0 +#, python-format +msgid "I love it" +msgstr "" + +#. module: portal_rating +#: code:addons/portal_rating/controllers/portal_rating.py:0 +#, python-format +msgid "Invalid rating" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/js/portal_composer.js:0 +#, python-format +msgid "It's okay" +msgstr "" + +#. module: portal_rating +#: model:ir.model,name:portal_rating.model_mail_message +msgid "Message" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/xml/portal_rating_composer.xml:0 +#: code:addons/portal_rating/static/src/xml/portal_rating_composer.xml:0 +#, python-format +msgid "Modify your review" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/xml/portal_tools.xml:0 +#: code:addons/portal_rating/static/src/xml/portal_tools.xml:0 +#, python-format +msgid "One star" +msgstr "" + +#. module: portal_rating +#: code:addons/portal_rating/models/rating.py:0 +#, python-format +msgid "Only the publisher of the website can change the rating comment" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/xml/portal_chatter.xml:0 +#, python-format +msgid "Post comment" +msgstr "" + +#. module: portal_rating +#: model:ir.model.fields,field_description:portal_rating.field_rating_rating__website_published +msgid "Published" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/xml/portal_chatter.xml:0 +#: code:addons/portal_rating/static/src/xml/portal_chatter.xml:0 +#, python-format +msgid "Published on" +msgstr "" + +#. module: portal_rating +#: model:ir.model.fields,field_description:portal_rating.field_rating_rating__publisher_comment +msgid "Publisher Comment" +msgstr "" + +#. module: portal_rating +#: model_terms:ir.ui.view,arch_db:portal_rating.rating_rating_view_form +msgid "Publisher comment" +msgstr "" + +#. module: portal_rating +#: model:ir.model,name:portal_rating.model_rating_rating +msgid "Rating" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/xml/portal_tools.xml:0 +#, python-format +msgid "Remove Selection" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/xml/portal_chatter.xml:0 +#, python-format +msgid "Update comment" +msgstr "" + +#. module: portal_rating +#: model:ir.model.fields,help:portal_rating.field_rating_rating__website_published +msgid "Visible on the website as a comment" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/js/portal_chatter.js:0 +#, python-format +msgid "Write your comment" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/xml/portal_chatter.xml:0 +#: code:addons/portal_rating/static/src/xml/portal_chatter.xml:0 +#, python-format +msgid "avatar" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/xml/portal_rating_composer.xml:0 +#, python-format +msgid "ratings)" +msgstr "" + +#. module: portal_rating +#. openerp-web +#: code:addons/portal_rating/static/src/xml/portal_tools.xml:0 +#, python-format +msgid "stars" +msgstr "" diff --git a/addons/website_rating/i18n/pt.po b/addons/portal_rating/i18n/pt.po similarity index 100% rename from addons/website_rating/i18n/pt.po rename to addons/portal_rating/i18n/pt.po diff --git a/addons/website_rating/i18n/pt_BR.po b/addons/portal_rating/i18n/pt_BR.po similarity index 100% rename from addons/website_rating/i18n/pt_BR.po rename to addons/portal_rating/i18n/pt_BR.po diff --git a/addons/website_rating/i18n/ro.po b/addons/portal_rating/i18n/ro.po similarity index 100% rename from addons/website_rating/i18n/ro.po rename to addons/portal_rating/i18n/ro.po diff --git a/addons/website_rating/i18n/ru.po b/addons/portal_rating/i18n/ru.po similarity index 100% rename from addons/website_rating/i18n/ru.po rename to addons/portal_rating/i18n/ru.po diff --git a/addons/website_rating/i18n/sk.po b/addons/portal_rating/i18n/sk.po similarity index 100% rename from addons/website_rating/i18n/sk.po rename to addons/portal_rating/i18n/sk.po diff --git a/addons/website_rating/i18n/sl.po b/addons/portal_rating/i18n/sl.po similarity index 100% rename from addons/website_rating/i18n/sl.po rename to addons/portal_rating/i18n/sl.po diff --git a/addons/website_rating/i18n/sr.po b/addons/portal_rating/i18n/sr.po similarity index 100% rename from addons/website_rating/i18n/sr.po rename to addons/portal_rating/i18n/sr.po diff --git a/addons/website_rating/i18n/sr@latin.po b/addons/portal_rating/i18n/sr@latin.po similarity index 100% rename from addons/website_rating/i18n/sr@latin.po rename to addons/portal_rating/i18n/sr@latin.po diff --git a/addons/website_rating/i18n/sv.po b/addons/portal_rating/i18n/sv.po similarity index 100% rename from addons/website_rating/i18n/sv.po rename to addons/portal_rating/i18n/sv.po diff --git a/addons/website_rating/i18n/th.po b/addons/portal_rating/i18n/th.po similarity index 100% rename from addons/website_rating/i18n/th.po rename to addons/portal_rating/i18n/th.po diff --git a/addons/website_rating/i18n/tr.po b/addons/portal_rating/i18n/tr.po similarity index 100% rename from addons/website_rating/i18n/tr.po rename to addons/portal_rating/i18n/tr.po diff --git a/addons/website_rating/i18n/uk.po b/addons/portal_rating/i18n/uk.po similarity index 100% rename from addons/website_rating/i18n/uk.po rename to addons/portal_rating/i18n/uk.po diff --git a/addons/website_rating/i18n/vi.po b/addons/portal_rating/i18n/vi.po similarity index 100% rename from addons/website_rating/i18n/vi.po rename to addons/portal_rating/i18n/vi.po diff --git a/addons/website_rating/i18n/zh_CN.po b/addons/portal_rating/i18n/zh_CN.po similarity index 100% rename from addons/website_rating/i18n/zh_CN.po rename to addons/portal_rating/i18n/zh_CN.po diff --git a/addons/website_rating/i18n/zh_TW.po b/addons/portal_rating/i18n/zh_TW.po similarity index 100% rename from addons/website_rating/i18n/zh_TW.po rename to addons/portal_rating/i18n/zh_TW.po diff --git a/addons/website_rating/models/__init__.py b/addons/portal_rating/models/__init__.py similarity index 100% rename from addons/website_rating/models/__init__.py rename to addons/portal_rating/models/__init__.py diff --git a/addons/website_rating/models/mail_message.py b/addons/portal_rating/models/mail_message.py similarity index 100% rename from addons/website_rating/models/mail_message.py rename to addons/portal_rating/models/mail_message.py diff --git a/addons/website_rating/models/rating.py b/addons/portal_rating/models/rating.py similarity index 85% rename from addons/website_rating/models/rating.py rename to addons/portal_rating/models/rating.py index 3c5f3586c59..bea77a45de9 100644 --- a/addons/website_rating/models/rating.py +++ b/addons/portal_rating/models/rating.py @@ -6,8 +6,6 @@ from odoo import fields, models, exceptions, _ class Rating(models.Model): _inherit = 'rating.rating' - # Add this related field to mail.message for performance reason - website_published = fields.Boolean(related='message_id.website_published', store=True, readonly=False) # Adding information for comment a rating message publisher_comment = fields.Text("Publisher Comment") publisher_id = fields.Many2one('res.partner', 'Commented by', diff --git a/addons/website_rating/static/src/js/portal_chatter.js b/addons/portal_rating/static/src/js/portal_chatter.js similarity index 97% rename from addons/website_rating/static/src/js/portal_chatter.js rename to addons/portal_rating/static/src/js/portal_chatter.js index c67b82a9974..51b403b521b 100644 --- a/addons/website_rating/static/src/js/portal_chatter.js +++ b/addons/portal_rating/static/src/js/portal_chatter.js @@ -30,8 +30,8 @@ PortalChatter.include({ }), xmlDependencies: (PortalChatter.prototype.xmlDependencies || []) .concat([ - '/website_rating/static/src/xml/portal_tools.xml', - '/website_rating/static/src/xml/portal_chatter.xml' + '/portal_rating/static/src/xml/portal_tools.xml', + '/portal_rating/static/src/xml/portal_chatter.xml' ]), /** @@ -256,7 +256,7 @@ PortalChatter.include({ var oldRating = this.messages[messageIndex].rating; data.rating.publisher_comment = oldRating.publisher_comment ? oldRating.publisher_comment : ''; - this._getCommentContainer($source).html($(qweb.render("website_rating.chatter_rating_publisher_form", data))); + this._getCommentContainer($source).html($(qweb.render("portal_rating.chatter_rating_publisher_form", data))); this._focusTextComment($source); }, @@ -309,7 +309,7 @@ PortalChatter.include({ if (self.messages[messageIndex].rating.publisher_comment !== '') { // Remove the button comment if exist and render the comment self._getCommentButton($source).addClass('d-none'); - self._getCommentContainer($source).html($(qweb.render("website_rating.chatter_rating_publisher_comment", { + self._getCommentContainer($source).html($(qweb.render("portal_rating.chatter_rating_publisher_comment", { rating: self.messages[messageIndex].rating, is_publisher: self.options.is_user_publisher }))); @@ -335,7 +335,7 @@ PortalChatter.include({ rating: this.messages[messageIndex].rating, is_publisher: this.options.is_user_publisher }; - this._getCommentContainer($source).html($(qweb.render("website_rating.chatter_rating_publisher_comment", data))); + this._getCommentContainer($source).html($(qweb.render("portal_rating.chatter_rating_publisher_comment", data))); } else { this._getCommentContainer($source).empty(); } diff --git a/addons/website_rating/static/src/js/portal_composer.js b/addons/portal_rating/static/src/js/portal_composer.js similarity index 100% rename from addons/website_rating/static/src/js/portal_composer.js rename to addons/portal_rating/static/src/js/portal_composer.js diff --git a/addons/website_rating/static/src/js/portal_rating_composer.js b/addons/portal_rating/static/src/js/portal_rating_composer.js similarity index 92% rename from addons/website_rating/static/src/js/portal_rating_composer.js rename to addons/portal_rating/static/src/js/portal_rating_composer.js index d9a78f17255..8bf205a6cb8 100644 --- a/addons/website_rating/static/src/js/portal_rating_composer.js +++ b/addons/portal_rating/static/src/js/portal_rating_composer.js @@ -16,11 +16,11 @@ var STAR_RATING_RATIO = 2; // conversion factor from the star (1-5) to the db r * a popup with the portal composer when clicking on it. **/ var RatingPopupComposer = publicWidget.Widget.extend({ - template: 'website_rating.PopupComposer', + template: 'portal_rating.PopupComposer', xmlDependencies: [ '/portal/static/src/xml/portal_chatter.xml', - '/website_rating/static/src/xml/portal_tools.xml', - '/website_rating/static/src/xml/portal_rating_composer.xml', + '/portal_rating/static/src/xml/portal_tools.xml', + '/portal_rating/static/src/xml/portal_rating_composer.xml', ], init: function (parent, options) { diff --git a/addons/website_rating/static/src/scss/website_rating.scss b/addons/portal_rating/static/src/scss/portal_rating.scss similarity index 100% rename from addons/website_rating/static/src/scss/website_rating.scss rename to addons/portal_rating/static/src/scss/portal_rating.scss diff --git a/addons/website_rating/static/src/xml/portal_chatter.xml b/addons/portal_rating/static/src/xml/portal_chatter.xml similarity index 91% rename from addons/website_rating/static/src/xml/portal_chatter.xml rename to addons/portal_rating/static/src/xml/portal_chatter.xml index ba8fa74cc7c..5a397d8984b 100644 --- a/addons/website_rating/static/src/xml/portal_chatter.xml +++ b/addons/portal_rating/static/src/xml/portal_chatter.xml @@ -9,7 +9,7 @@ #{widget.options['force_submit_url'] ? widget.options['force_submit_url'] : '/mail/chatter_post'} - + @@ -19,7 +19,7 @@ - + @@ -28,7 +28,7 @@ - + @@ -38,7 +38,7 @@ - + @@ -49,7 +49,7 @@ - +
- +
- +
avatar
@@ -89,7 +89,7 @@
- +
avatar
diff --git a/addons/website_rating/static/src/xml/portal_rating_composer.xml b/addons/portal_rating/static/src/xml/portal_rating_composer.xml similarity index 95% rename from addons/website_rating/static/src/xml/portal_rating_composer.xml rename to addons/portal_rating/static/src/xml/portal_rating_composer.xml index 38d041a060e..e4f58c3ec81 100644 --- a/addons/website_rating/static/src/xml/portal_rating_composer.xml +++ b/addons/portal_rating/static/src/xml/portal_rating_composer.xml @@ -4,10 +4,10 @@ Popup Rating Composer Widget It can alse be used to modify a message --> - +
- + diff --git a/addons/website_rating/static/src/xml/portal_tools.xml b/addons/portal_rating/static/src/xml/portal_tools.xml similarity index 95% rename from addons/website_rating/static/src/xml/portal_tools.xml rename to addons/portal_rating/static/src/xml/portal_tools.xml index 0d790041d0b..18d8c7f8a77 100644 --- a/addons/website_rating/static/src/xml/portal_tools.xml +++ b/addons/portal_rating/static/src/xml/portal_tools.xml @@ -1,6 +1,6 @@ - + @@ -17,13 +17,13 @@
- +

Average

- + @@ -61,7 +61,7 @@
- +
diff --git a/addons/portal_rating/views/assets.xml b/addons/portal_rating/views/assets.xml new file mode 100644 index 00000000000..d962bea4e6d --- /dev/null +++ b/addons/portal_rating/views/assets.xml @@ -0,0 +1,13 @@ + + + + diff --git a/addons/website_rating/views/portal_templates.xml b/addons/portal_rating/views/portal_templates.xml similarity index 100% rename from addons/website_rating/views/portal_templates.xml rename to addons/portal_rating/views/portal_templates.xml diff --git a/addons/website_rating/views/rating_templates.xml b/addons/portal_rating/views/rating_templates.xml similarity index 100% rename from addons/website_rating/views/rating_templates.xml rename to addons/portal_rating/views/rating_templates.xml diff --git a/addons/website_rating/views/rating_views.xml b/addons/portal_rating/views/rating_views.xml similarity index 86% rename from addons/website_rating/views/rating_views.xml rename to addons/portal_rating/views/rating_views.xml index 2a9e5bf0866..c179d92e1fd 100644 --- a/addons/website_rating/views/rating_views.xml +++ b/addons/portal_rating/views/rating_views.xml @@ -5,7 +5,7 @@ rating.rating - + diff --git a/addons/project/models/project.py b/addons/project/models/project.py index e97754be5b8..decb61cc94b 100644 --- a/addons/project/models/project.py +++ b/addons/project/models/project.py @@ -930,8 +930,8 @@ class Task(models.Model): return self.project_id.partner_id return res - def rating_apply(self, rate, token=None, feedback=None, subtype=None): - return super(Task, self).rating_apply(rate, token=token, feedback=feedback, subtype="project.mt_task_rating") + def rating_apply(self, rate, token=None, feedback=None, subtype_xmlid=None): + return super(Task, self).rating_apply(rate, token=token, feedback=feedback, subtype_xmlid="project.mt_task_rating") def _rating_get_parent_field_name(self): return 'project_id' diff --git a/addons/rating/__manifest__.py b/addons/rating/__manifest__.py index db4e37c8609..6f05e8fd972 100644 --- a/addons/rating/__manifest__.py +++ b/addons/rating/__manifest__.py @@ -10,11 +10,12 @@ This module allows a customer to give rating. 'mail', ], 'data': [ - 'views/rating_view.xml', + 'views/rating_rating_views.xml', 'views/rating_template.xml', + 'views/mail_message_views.xml', 'views/assets.xml', 'security/ir.model.access.csv' - ], + ], 'installable': True, 'auto_install': False, } diff --git a/addons/rating/models/rating.py b/addons/rating/models/rating.py index 9e98d9af84b..fea471932dc 100644 --- a/addons/rating/models/rating.py +++ b/addons/rating/models/rating.py @@ -53,6 +53,7 @@ class Rating(models.Model): 'mail.message', string="Linked message", index=True, ondelete='cascade', help="Associated message when posting a review. Mainly used in website addons.") + is_internal = fields.Boolean('Employee Only', readonly=False, related='message_id.is_internal', store=True) access_token = fields.Char('Security Token', default=_default_access_token, help="Access token to set the rating of the value") consumed = fields.Boolean(string="Filled Rating", help="Enabled if the rating has been filled.") diff --git a/addons/rating/models/rating_mixin.py b/addons/rating/models/rating_mixin.py index 77196e80c50..c95bc3d5ed1 100644 --- a/addons/rating/models/rating_mixin.py +++ b/addons/rating/models/rating_mixin.py @@ -134,7 +134,8 @@ class RatingMixin(models.AbstractModel): 'partner_id': partner.id, 'rated_partner_id': rated_partner.id, 'res_model_id': record_model_id, - 'res_id': self.id + 'res_id': self.id, + 'is_internal': False, }) else: rating = ratings[0] @@ -168,7 +169,7 @@ class RatingMixin(models.AbstractModel): subtype_id=subtype_id ) - def rating_apply(self, rate, token=None, feedback=None, subtype=None): + def rating_apply(self, rate, token=None, feedback=None, subtype_xmlid=None): """ Apply a rating given a token. If the current model inherits from mail.thread mixin, a message is posted on its chatter. User going through this method should have at least employee rights because of rating @@ -178,7 +179,7 @@ class RatingMixin(models.AbstractModel): :param float rate : the rating value to apply :param string token : access token :param string feedback : additional feedback - :param string subtype : xml id of a valid mail.message.subtype + :param string subtype_xmlid : xml id of a valid mail.message.subtype :returns rating.rating record """ @@ -194,7 +195,7 @@ class RatingMixin(models.AbstractModel): self.message_post( body=":%s/10%s" % (rate, rate, feedback), - subtype=subtype or "mail.mt_comment", + subtype_xmlid=subtype_xmlid or "mail.mt_comment", author_id=rating.partner_id and rating.partner_id.id or None # None will set the default author in mail_thread.py ) if hasattr(self, 'stage_id') and self.stage_id and hasattr(self.stage_id, 'auto_validation_kanban_state') and self.stage_id.auto_validation_kanban_state: diff --git a/addons/rating/views/mail_message_views.xml b/addons/rating/views/mail_message_views.xml new file mode 100644 index 00000000000..887c7684526 --- /dev/null +++ b/addons/rating/views/mail_message_views.xml @@ -0,0 +1,15 @@ + + + + mail.message.view.form.inherit.rating + mail.message + + + + + + + + + + diff --git a/addons/rating/views/rating_view.xml b/addons/rating/views/rating_rating_views.xml similarity index 91% rename from addons/rating/views/rating_view.xml rename to addons/rating/views/rating_rating_views.xml index 7370d05c875..22f46276795 100644 --- a/addons/rating/views/rating_view.xml +++ b/addons/rating/views/rating_rating_views.xml @@ -32,22 +32,21 @@
- - + + - - + -
+ +
- - + @@ -169,4 +168,17 @@
+ + Ratings + rating.rating + kanban,tree,graph,pivot,form + + + + + diff --git a/addons/sale/controllers/portal.py b/addons/sale/controllers/portal.py index 52495a93316..e951dce54b2 100644 --- a/addons/sale/controllers/portal.py +++ b/addons/sale/controllers/portal.py @@ -159,7 +159,7 @@ class CustomerPortal(CustomerPortal): if order_sudo and request.session.get('view_quote_%s' % order_sudo.id) != now and request.env.user.share and access_token: request.session['view_quote_%s' % order_sudo.id] = now body = _('Quotation viewed by customer %s') % order_sudo.partner_id.name - _message_post_helper('sale.order', order_sudo.id, body, token=order_sudo.access_token, message_type='notification', subtype="mail.mt_note") + _message_post_helper('sale.order', order_sudo.id, body, token=order_sudo.access_token, message_type='notification', subtype_xmlid="mail.mt_note") values = { 'sale_order': order_sudo, diff --git a/addons/test_mail/tests/test_discuss.py b/addons/test_mail/tests/test_discuss.py index 5667568ead0..e2bda7dc8d9 100644 --- a/addons/test_mail/tests/test_discuss.py +++ b/addons/test_mail/tests/test_discuss.py @@ -15,7 +15,7 @@ class TestChatterTweaks(TestMailCommon, TestRecipients): def test_post_no_subscribe_author(self): original = self.test_record.message_follower_ids self.test_record.with_user(self.user_employee).with_context({'mail_create_nosubscribe': True}).message_post( - body='Test Body', message_type='comment', subtype='mt_comment') + body='Test Body', message_type='comment', subtype_xmlid='mail.mt_comment') self.assertEqual(self.test_record.message_follower_ids.mapped('partner_id'), original.mapped('partner_id')) self.assertEqual(self.test_record.message_follower_ids.mapped('channel_id'), original.mapped('channel_id')) @@ -23,7 +23,7 @@ class TestChatterTweaks(TestMailCommon, TestRecipients): def test_post_no_subscribe_recipients(self): original = self.test_record.message_follower_ids self.test_record.with_user(self.user_employee).with_context({'mail_create_nosubscribe': True}).message_post( - body='Test Body', message_type='comment', subtype='mt_comment', partner_ids=[self.partner_1.id, self.partner_2.id]) + body='Test Body', message_type='comment', subtype_xmlid='mail.mt_comment', partner_ids=[self.partner_1.id, self.partner_2.id]) self.assertEqual(self.test_record.message_follower_ids.mapped('partner_id'), original.mapped('partner_id')) self.assertEqual(self.test_record.message_follower_ids.mapped('channel_id'), original.mapped('channel_id')) @@ -31,7 +31,7 @@ class TestChatterTweaks(TestMailCommon, TestRecipients): def test_post_subscribe_recipients(self): original = self.test_record.message_follower_ids self.test_record.with_user(self.user_employee).with_context({'mail_create_nosubscribe': True, 'mail_post_autofollow': True}).message_post( - body='Test Body', message_type='comment', subtype='mt_comment', partner_ids=[self.partner_1.id, self.partner_2.id]) + body='Test Body', message_type='comment', subtype_xmlid='mail.mt_comment', partner_ids=[self.partner_1.id, self.partner_2.id]) self.assertEqual(self.test_record.message_follower_ids.mapped('partner_id'), original.mapped('partner_id') | self.partner_1 | self.partner_2) self.assertEqual(self.test_record.message_follower_ids.mapped('channel_id'), original.mapped('channel_id')) @@ -100,7 +100,7 @@ class TestDiscuss(TestMailCommon, TestRecipients): def test_set_message_done_user(self): with self.assertSinglePostNotifications([{'partner': self.partner_employee, 'type': 'inbox'}], message_info={'content': 'Test'}): message = self.test_record.message_post( - body='Test', message_type='comment', subtype='mail.mt_comment', + body='Test', message_type='comment', subtype_xmlid='mail.mt_comment', partner_ids=[self.user_employee.partner_id.id]) message.with_user(self.user_employee).set_message_done() self.assertMailNotifications(message, [{'notif': [{'partner': self.partner_employee, 'type': 'inbox', 'is_read': True}]}]) diff --git a/addons/test_mail/tests/test_mail_channel.py b/addons/test_mail/tests/test_mail_channel.py index 5dadf2690b7..8869ac21442 100644 --- a/addons/test_mail/tests/test_mail_channel.py +++ b/addons/test_mail/tests/test_mail_channel.py @@ -149,7 +149,7 @@ class TestChannelFeatures(TestMailCommon): self.assertEqual(self.test_channel.channel_partner_ids, self.env['res.partner']) def test_channel_post_nofollow(self): - self.test_channel.message_post(body='Test', message_type='comment', subtype='mt_comment') + self.test_channel.message_post(body='Test', message_type='comment', subtype_xmlid='mail.mt_comment') self.assertEqual(self.test_channel.message_channel_ids, self.test_channel) self.assertEqual(self.test_channel.message_partner_ids, self.env['res.partner']) @@ -168,7 +168,7 @@ class TestChannelFeatures(TestMailCommon): }) self._join_channel(self.test_channel, self.user_employee.partner_id | self.test_partner | nomail.partner_id) with self.mock_mail_gateway(): - self.test_channel.message_post(body="Test", message_type='comment', subtype='mt_comment') + self.test_channel.message_post(body="Test", message_type='comment', subtype_xmlid='mail.mt_comment') self.assertSentEmail(self.test_channel.env.user.partner_id, [self.partner_employee, self.test_partner]) @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') @@ -178,7 +178,7 @@ class TestChannelFeatures(TestMailCommon): self.test_channel.write({'email_send': False}) self._join_channel(self.test_channel, self.user_employee.partner_id | self.test_partner) with self.mock_mail_gateway(): - self.test_channel.message_post(body="Test", message_type='comment', subtype='mt_comment') + self.test_channel.message_post(body="Test", message_type='comment', subtype_xmlid='mail.mt_comment') self.assertNotSentEmail() self.assertEqual(len(self._mails), 0) @@ -188,7 +188,7 @@ class TestChannelFeatures(TestMailCommon): self.test_channel.write({'alias_name': False}) self.test_channel.message_subscribe([self.user_employee.partner_id.id, self.test_partner.id]) with self.mock_mail_gateway(): - self.test_channel.message_post(body="Test", message_type='comment', subtype='mt_comment') + self.test_channel.message_post(body="Test", message_type='comment', subtype_xmlid='mail.mt_comment') self.assertSentEmail(self.test_channel.env.user.partner_id, [self.test_partner]) @mute_logger('odoo.addons.mail.models.mail_mail') @@ -323,10 +323,10 @@ class TestChannelModeration(TestMailCommon): self.channel_1._update_moderation_email([email1], 'ban') self.channel_1._update_moderation_email([email2], 'allow') - msg_admin = self.channel_1.message_post(message_type='email', subtype='mt_comment', author_id=self.partner_admin.id) - msg_moderator = self.channel_1.message_post(message_type='comment', subtype='mt_comment', author_id=self.partner_employee.id) - msg_email1 = self.channel_1.message_post(message_type='comment', subtype='mt_comment', email_from=formataddr(("MyName", email1))) - msg_email2 = self.channel_1.message_post(message_type='email', subtype='mt_comment', email_from=email2) + msg_admin = self.channel_1.message_post(message_type='email', subtype_xmlid='mail.mt_comment', author_id=self.partner_admin.id) + msg_moderator = self.channel_1.message_post(message_type='comment', subtype_xmlid='mail.mt_comment', author_id=self.partner_employee.id) + msg_email1 = self.channel_1.message_post(message_type='comment', subtype_xmlid='mail.mt_comment', email_from=formataddr(("MyName", email1))) + msg_email2 = self.channel_1.message_post(message_type='email', subtype_xmlid='mail.mt_comment', email_from=email2) msg_notif = self.channel_1.message_post() messages = self.env['mail.message'].search([('model', '=', 'mail.channel'), ('res_id', '=', self.channel_1.id)]) diff --git a/addons/test_mail/tests/test_mail_gateway.py b/addons/test_mail/tests/test_mail_gateway.py index 9850243ba7c..d9da245a1e0 100644 --- a/addons/test_mail/tests/test_mail_gateway.py +++ b/addons/test_mail/tests/test_mail_gateway.py @@ -626,14 +626,14 @@ class TestMailgateway(TestMailCommon): record_msg = first_record.message_post( subject='Discussion', no_auto_thread=False, - subtype='mail.mt_comment', + subtype_xmlid='mail.mt_comment', ) self.assertEqual(record_msg.reply_to, formataddr(('%s %s' % (self.user_employee.company_id.name, first_record.name), '%s@%s' % ('catchall.test', 'test.com')))) mail_msg = first_record.message_post( subject='Replies to Record', reply_to='groups@test.com', no_auto_thread=True, - subtype='mail.mt_comment', + subtype_xmlid='mail.mt_comment', ) self.assertEqual(mail_msg.reply_to, 'groups@test.com') diff --git a/addons/test_mail/tests/test_mail_message.py b/addons/test_mail/tests/test_mail_message.py index 3f433496f4e..4f08f0abc18 100644 --- a/addons/test_mail/tests/test_mail_message.py +++ b/addons/test_mail/tests/test_mail_message.py @@ -360,13 +360,13 @@ class TestMessageAccess(TestMailCommon): ).with_context({'mail_create_nosubscribe': False}) # mark all as read clear needactions - group_private.message_post(body='Test', message_type='comment', subtype='mail.mt_comment', partner_ids=[emp_partner.id]) + group_private.message_post(body='Test', message_type='comment', subtype_xmlid='mail.mt_comment', partner_ids=[emp_partner.id]) emp_partner.env['mail.message'].mark_all_as_read(domain=[]) na_count = emp_partner.get_needaction_count() self.assertEqual(na_count, 0, "mark all as read should conclude all needactions") # mark all as read also clear inaccessible needactions - new_msg = group_private.message_post(body='Zest', message_type='comment', subtype='mail.mt_comment', partner_ids=[emp_partner.id]) + new_msg = group_private.message_post(body='Zest', message_type='comment', subtype_xmlid='mail.mt_comment', partner_ids=[emp_partner.id]) needaction_accessible = len(emp_partner.env['mail.message'].search([['needaction', '=', True]])) self.assertEqual(needaction_accessible, 1, "a new message to a partner is readable to that partner") @@ -388,13 +388,13 @@ class TestMessageAccess(TestMailCommon): portal_partner = self.user_portal.partner_id.with_user(self.user_portal) # mark all as read clear needactions - self.group_pigs.message_post(body='Test', message_type='comment', subtype='mail.mt_comment', partner_ids=[portal_partner.id]) + self.group_pigs.message_post(body='Test', message_type='comment', subtype_xmlid='mail.mt_comment', partner_ids=[portal_partner.id]) portal_partner.env['mail.message'].mark_all_as_read(domain=[]) na_count = portal_partner.get_needaction_count() self.assertEqual(na_count, 0, "mark all as read should conclude all needactions") # mark all as read also clear inaccessible needactions - new_msg = self.group_pigs.message_post(body='Zest', message_type='comment', subtype='mail.mt_comment', partner_ids=[portal_partner.id]) + new_msg = self.group_pigs.message_post(body='Zest', message_type='comment', subtype_xmlid='mail.mt_comment', partner_ids=[portal_partner.id]) needaction_accessible = len(portal_partner.env['mail.message'].search([['needaction', '=', True]])) self.assertEqual(needaction_accessible, 1, "a new message to a partner is readable to that partner") diff --git a/addons/test_mail/tests/test_message_management.py b/addons/test_mail/tests/test_message_management.py index cc3cb367574..b2c437ce2db 100644 --- a/addons/test_mail/tests/test_message_management.py +++ b/addons/test_mail/tests/test_message_management.py @@ -36,7 +36,7 @@ class TestMailResend(TestMailCommon): [{'partner': partner, 'type': 'email', 'status': 'exception'} for partner in self.partners], message_info={'message_type': 'notification'}, sim_error='connect_failure'): - message = self.test_record.with_user(self.user_admin).message_post(partner_ids=self.partners.ids, subtype='mail.mt_comment', message_type='notification') + message = self.test_record.with_user(self.user_admin).message_post(partner_ids=self.partners.ids, subtype_xmlid='mail.mt_comment', message_type='notification') wizard = self.env['mail.resend.message'].with_context({'mail_message_to_resend': message.id}).create({}) self.assertEqual(wizard.notification_ids.mapped('res_partner_id'), self.partners, "wizard should manage notifications for each failed partner") @@ -80,7 +80,7 @@ class TestMailResend(TestMailCommon): def test_remove_mail_become_canceled(self): # two failure sent on bus, one for each mail with self.mock_mail_gateway(), self.assertBus([(self.cr.dbname, 'res.partner', self.partner_admin.id)] * 2): - message = self.test_record.with_user(self.user_admin).message_post(partner_ids=self.partners.ids, subtype='mail.mt_comment', message_type='notification') + message = self.test_record.with_user(self.user_admin).message_post(partner_ids=self.partners.ids, subtype_xmlid='mail.mt_comment', message_type='notification') self.assertMailNotifications(message, [ {'content': '', 'message_type': 'notification', @@ -102,7 +102,7 @@ class TestMailResend(TestMailCommon): @mute_logger('odoo.addons.mail.models.mail_mail') def test_cancel_all(self): with self.mock_mail_gateway(), self.assertBus([(self.cr.dbname, 'res.partner', self.partner_admin.id)] * 2): - message = self.test_record.with_user(self.user_admin).message_post(partner_ids=self.partners.ids, subtype='mail.mt_comment', message_type='notification') + message = self.test_record.with_user(self.user_admin).message_post(partner_ids=self.partners.ids, subtype_xmlid='mail.mt_comment', message_type='notification') wizard = self.env['mail.resend.message'].with_context({'mail_message_to_resend': message.id}).create({}) # one update for cancell diff --git a/addons/test_mail/tests/test_message_post.py b/addons/test_mail/tests/test_message_post.py index bf894fafe12..8e0a06320fb 100644 --- a/addons/test_mail/tests/test_message_post.py +++ b/addons/test_mail/tests/test_message_post.py @@ -27,7 +27,7 @@ class TestMessagePost(TestMailCommon, TestRecipients): (self.user_employee | self.user_admin).write({'notification_type': 'inbox'}) with self.assertSinglePostNotifications([{'partner': self.partner_employee, 'type': 'inbox'}], {'content': 'Body'}): self.test_record.message_post( - body='Body', message_type='comment', subtype='mail.mt_comment', + body='Body', message_type='comment', subtype_xmlid='mail.mt_comment', partner_ids=[self.user_employee.partner_id.id]) self.test_record.message_subscribe([self.partner_1.id]) @@ -35,14 +35,14 @@ class TestMessagePost(TestMailCommon, TestRecipients): {'partner': self.partner_employee, 'type': 'inbox'}, {'partner': self.partner_1, 'type': 'email'}], {'content': 'NewBody'}): self.test_record.message_post( - body='NewBody', message_type='comment', subtype='mail.mt_comment', + body='NewBody', message_type='comment', subtype_xmlid='mail.mt_comment', partner_ids=[self.user_employee.partner_id.id]) with self.assertSinglePostNotifications([ {'partner': self.partner_1, 'type': 'email'}, {'partner': self.partner_portal, 'type': 'email'}], {'content': 'ToPortal'}): self.test_record.message_post( - body='ToPortal', message_type='comment', subtype='mail.mt_comment', + body='ToPortal', message_type='comment', subtype_xmlid='mail.mt_comment', partner_ids=[self.partner_portal.id]) def test_post_inactive_follower(self): @@ -52,14 +52,14 @@ class TestMessagePost(TestMailCommon, TestRecipients): self.test_record._message_subscribe(self.user_employee.partner_id.ids) with self.assertSinglePostNotifications([{'partner': self.partner_employee, 'type': 'inbox'}], {'content': 'Test'}): self.test_record.message_post( - body='Test', message_type='comment', subtype='mail.mt_comment') + body='Test', message_type='comment', subtype_xmlid='mail.mt_comment') self.user_employee.active = False # at this point, partner is still active and would receive an email notification self.user_employee.partner_id._write({'active': False}) with self.assertPostNotifications([{'content': 'Test', 'notif': []}]): self.test_record.message_post( - body='Test', message_type='comment', subtype='mail.mt_comment') + body='Test', message_type='comment', subtype_xmlid='mail.mt_comment') @mute_logger('odoo.addons.mail.models.mail_mail') def test_post_notifications(self): @@ -74,7 +74,7 @@ class TestMessagePost(TestMailCommon, TestRecipients): {'partner': self.partner_admin, 'type': 'email'}], {'content': _body}, mail_unlink_sent=True): msg = self.test_record.with_user(self.user_employee).message_post( body=_body, subject=_subject, - message_type='comment', subtype='mt_comment', + message_type='comment', subtype_xmlid='mail.mt_comment', partner_ids=[self.partner_1.id, self.partner_2.id] ) @@ -95,7 +95,7 @@ class TestMessagePost(TestMailCommon, TestRecipients): msg = self.test_record.with_user(self.user_employee).message_post( body='Test', subject='Test', - message_type='comment', subtype='mt_comment', + message_type='comment', subtype_xmlid='mail.mt_comment', partner_ids=[self.partner_1.id, self.partner_2.id], mail_auto_delete=False ) @@ -126,7 +126,7 @@ class TestMessagePost(TestMailCommon, TestRecipients): with self.mock_mail_gateway(): msg = self.test_record.with_user(self.user_employee).message_post( body='Test', subject='Test', - message_type='comment', subtype='mt_comment', + message_type='comment', subtype_xmlid='mail.mt_comment', attachment_ids=[_attach_1.id, _attach_2.id], partner_ids=[self.partner_1.id], attachments=_attachments, @@ -155,7 +155,7 @@ class TestMessagePost(TestMailCommon, TestRecipients): with self.mock_mail_gateway(): parent_msg = self.test_record.with_user(self.user_employee).message_post( body='

Test

', subject='Test Subject', - message_type='comment', subtype='mt_comment') + message_type='comment', subtype_xmlid='mail.mt_comment') self.assertEqual(parent_msg.partner_ids, self.env['res.partner']) self.assertNotSentEmail() @@ -163,7 +163,7 @@ class TestMessagePost(TestMailCommon, TestRecipients): with self.assertPostNotifications([{'content': '

Test Answer

', 'notif': [{'partner': self.partner_1, 'type': 'email'}]}]): msg = self.test_record.with_user(self.user_employee).message_post( body='

Test Answer

', - message_type='comment', subtype='mt_comment', + message_type='comment', subtype_xmlid='mail.mt_comment', partner_ids=[self.partner_1.id], parent_id=parent_msg.id) @@ -177,7 +177,7 @@ class TestMessagePost(TestMailCommon, TestRecipients): new_msg = self.test_record.with_user(self.user_employee).message_post( body='

Test Answer Bis

', - message_type='comment', subtype='mt_comment', + message_type='comment', subtype_xmlid='mail.mt_comment', parent_id=msg.id) self.assertEqual(new_msg.parent_id.id, parent_msg.id, 'message_post: flatten error') @@ -193,7 +193,7 @@ class TestMessagePost(TestMailCommon, TestRecipients): ]), patch.object(MailTestSimple, 'check_access_rights', return_value=True): new_msg = self.test_record.with_user(self.user_portal).message_post( body='

Test

', subject='Subject', - message_type='comment', subtype='mt_comment') + message_type='comment', subtype_xmlid='mail.mt_comment') self.assertEqual(new_msg.sudo().notified_partner_ids, (self.partner_1 | self.user_employee.partner_id)) @@ -201,14 +201,14 @@ class TestMessagePost(TestMailCommon, TestRecipients): with self.assertRaises(AccessError): self.test_record.with_user(self.user_portal).message_post( body='

Test

', subject='Subject', - message_type='comment', subtype='mt_comment') + message_type='comment', subtype_xmlid='mail.mt_comment') @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.addons.mail.models.mail_thread') def test_post_internal(self): self.test_record.message_subscribe([self.user_admin.partner_id.id]) msg = self.test_record.with_user(self.user_employee).message_post( body='My Body', subject='My Subject', - message_type='comment', subtype='mt_note') + message_type='comment', subtype_xmlid='mail.mt_note') self.assertEqual(msg.partner_ids, self.env['res.partner']) self.assertEqual(msg.notified_partner_ids, self.env['res.partner']) diff --git a/addons/test_mail/tests/test_odoobot.py b/addons/test_mail/tests/test_odoobot.py index 7766b5244dc..740a0444974 100644 --- a/addons/test_mail/tests/test_odoobot.py +++ b/addons/test_mail/tests/test_odoobot.py @@ -22,7 +22,7 @@ class TestOdoobot(TestMailCommon, TestRecipients): 'attachment_ids': [], 'message_type': 'comment', 'partner_ids': [], - 'subtype': 'mail.mt_comment' + 'subtype_xmlid': 'mail.mt_comment' } cls.odoobot_ping_body = '@OdooBot' % (cls.odoobot.id, cls.odoobot.id) cls.test_record_employe = cls.test_record.with_user(cls.user_employee) diff --git a/addons/test_mail/tests/test_performance.py b/addons/test_mail/tests/test_performance.py index b7948c23a4b..cf9852d6454 100644 --- a/addons/test_mail/tests/test_performance.py +++ b/addons/test_mail/tests/test_performance.py @@ -331,7 +331,7 @@ class TestMailAPIPerformance(BaseMailPerformance): with self.assertQueryCount(__system__=5, emp=6): record.message_post( body='

Test message_post as log

', - subtype='mail.mt_note', + subtype_xmlid='mail.mt_note', message_type='comment') @users('__system__', 'emp') @@ -344,7 +344,7 @@ class TestMailAPIPerformance(BaseMailPerformance): body='

Test Post Performances basic

', partner_ids=[], message_type='comment', - subtype='mail.mt_comment') + subtype_xmlid='mail.mt_comment') @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') @users('__system__', 'emp') @@ -357,7 +357,7 @@ class TestMailAPIPerformance(BaseMailPerformance): body='

Test Post Performances with an email ping

', partner_ids=self.customer.ids, message_type='comment', - subtype='mail.mt_comment') + subtype_xmlid='mail.mt_comment') @users('__system__', 'emp') @warmup @@ -369,7 +369,7 @@ class TestMailAPIPerformance(BaseMailPerformance): body='

Test Post Performances with an inbox ping

', partner_ids=self.user_test.partner_id.ids, message_type='comment', - subtype='mail.mt_comment') + subtype_xmlid='mail.mt_comment') @mute_logger('odoo.models.unlink') @users('__system__', 'emp') @@ -476,7 +476,7 @@ class TestMailComplexPerformance(BaseMailPerformance): record.message_post( body='

Test Post Performances

', message_type='comment', - subtype='mail.mt_comment') + subtype_xmlid='mail.mt_comment') self.assertEqual(record.message_ids[0].body, '

Test Post Performances

') self.assertEqual(record.message_ids[0].notified_partner_ids, self.partners | self.user_portal.partner_id) @@ -823,7 +823,7 @@ class TestMailHeavyPerformancePost(BaseMailPerformance): body='

Test body

', subject='Test Subject', message_type='notification', - subtype=None, + subtype_xmlid=None, partner_ids=partner_ids, channel_ids=channel_ids, parent_id=False, diff --git a/addons/test_mass_mailing/tests/test_mail_channel.py b/addons/test_mass_mailing/tests/test_mail_channel.py index b8bcd59d908..c5b903ff94d 100644 --- a/addons/test_mass_mailing/tests/test_mail_channel.py +++ b/addons/test_mass_mailing/tests/test_mail_channel.py @@ -40,7 +40,7 @@ class TestChannelPartnersNotification(common.TestMailCommon): self.test_channel.write({'email_send': True}) self._join_channel(self.test_channel, self.test_partner) with self.mock_mail_gateway(): - self.test_channel.message_post(body="Test", message_type='comment', subtype='mt_comment') + self.test_channel.message_post(body="Test", message_type='comment', subtype_xmlid='mail.mt_comment') self.assertEqual(len(self._mails), 1, 'Number of mail incorrect. Should be equal to 1.') for email in self._mails: diff --git a/addons/website_blog/models/website_blog.py b/addons/website_blog/models/website_blog.py index 47bff0f31aa..690d62a799c 100644 --- a/addons/website_blog/models/website_blog.py +++ b/addons/website_blog/models/website_blog.py @@ -37,7 +37,7 @@ class Blog(models.Model): return res @api.returns('mail.message', lambda value: value.id) - def message_post(self, *, parent_id=False, subtype=None, **kwargs): + def message_post(self, *, parent_id=False, subtype_id=False, **kwargs): """ Temporary workaround to avoid spam. If someone replies on a channel through the 'Presentation Published' email, it should be considered as a note as we don't want all channel followers to be notified of this answer. """ @@ -45,10 +45,8 @@ class Blog(models.Model): if parent_id: parent_message = self.env['mail.message'].sudo().browse(parent_id) if parent_message.subtype_id and parent_message.subtype_id == self.env.ref('website_blog.mt_blog_blog_published'): - if kwargs.get('subtype_id'): - kwargs['subtype_id'] = False - subtype = 'mail.mt_note' - return super(Blog, self).message_post(parent_id=parent_id, subtype=subtype, **kwargs) + subtype_id = self.env.ref('mail.mt_note').id + return super(Blog, self).message_post(parent_id=parent_id, subtype_id=subtype_id, **kwargs) def all_tags(self, join=False, min_limit=1): BlogTag = self.env['blog.tag'] diff --git a/addons/website_blog/tests/test_website_blog_flow.py b/addons/website_blog/tests/test_website_blog_flow.py index 0bca765d48c..d53bc8f7dc4 100644 --- a/addons/website_blog/tests/test_website_blog_flow.py +++ b/addons/website_blog/tests/test_website_blog_flow.py @@ -53,7 +53,7 @@ class TestWebsiteBlogFlow(TestWebsiteBlogCommon): body='Armande BlogUser Commented', message_type='comment', author_id=self.user_employee.partner_id.id, - subtype='mt_comment', + subtype_xmlid='mail.mt_comment', ) self.assertIn( self.user_employee.partner_id, test_blog_post.message_partner_ids, diff --git a/addons/website_forum/controllers/main.py b/addons/website_forum/controllers/main.py index d0f47befb7b..31606e41a9a 100644 --- a/addons/website_forum/controllers/main.py +++ b/addons/website_forum/controllers/main.py @@ -329,7 +329,7 @@ class WebsiteForum(WebsiteProfile): post.with_context(mail_create_nosubscribe=True).message_post( body=body, message_type='comment', - subtype='mt_comment') + subtype_xmlid='mail.mt_comment') return werkzeug.utils.redirect("/forum/%s/question/%s" % (slug(forum), slug(question))) @http.route('/forum//post//toggle_correct', type='json', auth="public", website=True) diff --git a/addons/website_forum/models/forum.py b/addons/website_forum/models/forum.py index f3738eb07e2..b21845bfd92 100644 --- a/addons/website_forum/models/forum.py +++ b/addons/website_forum/models/forum.py @@ -497,12 +497,12 @@ class Post(models.Model): if 'content' in vals or 'name' in vals: for post in self: if post.parent_id: - body, subtype = _('Answer Edited'), 'website_forum.mt_answer_edit' + body, subtype_xmlid = _('Answer Edited'), 'website_forum.mt_answer_edit' obj_id = post.parent_id else: - body, subtype = _('Question Edited'), 'website_forum.mt_question_edit' + body, subtype_xmlid = _('Question Edited'), 'website_forum.mt_question_edit' obj_id = post - obj_id.message_post(body=body, subtype=subtype) + obj_id.message_post(body=body, subtype_xmlid=subtype_xmlid) if 'active' in vals: answers = self.env['forum.post'].with_context(active_test=False).search([('parent_id', 'in', self.ids)]) if answers: @@ -717,7 +717,7 @@ class Post(models.Model): 'email_from': self_sudo.create_uid.email_formatted, # use sudo here because of access to res.users model 'body': tools.html_sanitize(self.content, sanitize_attributes=True, strip_style=True, strip_classes=True), 'message_type': 'comment', - 'subtype': 'mail.mt_comment', + 'subtype_xmlid': 'mail.mt_comment', 'date': self.create_date, } new_message = question.with_context(mail_create_nosubscribe=True).message_post(**values) diff --git a/addons/website_livechat/models/mail_channel.py b/addons/website_livechat/models/mail_channel.py index 5f3b05b2ccd..6f0ddee0fc7 100644 --- a/addons/website_livechat/models/mail_channel.py +++ b/addons/website_livechat/models/mail_channel.py @@ -69,7 +69,7 @@ class MailChannel(models.Model): message = _('has left the conversation.') leave_message = '%s %s' % (name, message) self.message_post(author_id=self.env.ref('base.user_root').sudo().partner_id.id, - body=leave_message, message_type='comment', subtype='mt_comment') + body=leave_message, message_type='comment', subtype_xmlid='mail.mt_comment') def message_post(self, **kwargs): """Override to mark the visitor as still connected. diff --git a/addons/website_mail/__manifest__.py b/addons/website_mail/__manifest__.py index fb4dc268da2..b91958c65f2 100644 --- a/addons/website_mail/__manifest__.py +++ b/addons/website_mail/__manifest__.py @@ -7,14 +7,12 @@ 'summary': 'Website Module for Mail', 'version': '0.1', 'description': """ -Module holding mail improvements for website. -It is responsible of comments moderation for published documents (forum, slides, blog, ...) +Module holding mail improvements for website. It holds the follow widget. """, 'depends': ['website', 'mail'], 'data': [ 'views/assets.xml', 'views/website_mail_templates.xml', - 'security/website_mail_security.xml', ], 'installable': True, 'auto_install': True, diff --git a/addons/website_mail/models/__init__.py b/addons/website_mail/models/__init__.py index 75ea63bd6d8..d138acf14cc 100644 --- a/addons/website_mail/models/__init__.py +++ b/addons/website_mail/models/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from . import mail_message from . import update diff --git a/addons/website_mail/models/mail_message.py b/addons/website_mail/models/mail_message.py deleted file mode 100644 index 8070c7d7fcc..00000000000 --- a/addons/website_mail/models/mail_message.py +++ /dev/null @@ -1,68 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from odoo import api, fields, models, _ -from odoo.osv import expression -from odoo.tools import html2plaintext -from odoo.exceptions import AccessError - - -class MailMessage(models.Model): - _inherit = 'mail.message' - - @api.model - def default_get(self, fields_list): - defaults = super(MailMessage, self).default_get(fields_list) - - # Note: explicitly implemented in default_get() instead of field default, - # to avoid setting to True for all existing messages during upgrades. - # TODO: this default should probably be dynamic according to the model - # on which the messages are attached, thus moved to create(). - if 'website_published' in fields_list: - defaults.setdefault('website_published', True) - - return defaults - - description = fields.Char(compute="_compute_description", help='Message description: either the subject, or the beginning of the body') - website_published = fields.Boolean(string='Published', help="Visible on the website as a comment", copy=False) - - @api.model - def _non_employee_message_domain(self): - domain = super(MailMessage, self)._non_employee_message_domain() - return expression.AND([domain, [('website_published', '=', True)]]) - - def _compute_description(self): - for message in self: - if message.subject: - message.description = message.subject - else: - plaintext_ct = '' if not message.body else html2plaintext(message.body) - message.description = plaintext_ct[:30] + '%s' % (' [...]' if len(plaintext_ct) >= 30 else '') - - @api.model - def _search(self, args, offset=0, limit=None, order=None, count=False, access_rights_uid=None): - """ Override that adds specific access rights of mail.message, to restrict - messages to published messages for public users. """ - if self.user_has_groups('base.group_public'): - args = expression.AND([[('website_published', '=', True)], list(args)]) - - return super(MailMessage, self)._search(args, offset=offset, limit=limit, order=order, - count=count, access_rights_uid=access_rights_uid) - - def check_access_rule(self, operation): - """ Add Access rules of mail.message for non-employee user: - - read: - - raise if the type is comment and subtype NULL (internal note) - """ - if self.user_has_groups('base.group_public'): - self.env.cr.execute('SELECT id FROM "%s" WHERE website_published IS FALSE AND id = ANY (%%s)' % (self._table), (self.ids,)) - if self.env.cr.fetchall(): - raise AccessError( - _('The requested operation cannot be completed due to security restrictions. Please contact your system administrator.\n\n(Document type: %s, Operation: %s)') % (self._description, operation) - + ' - ({} {}, {} {})'.format(_('Records:'), self.ids[:6], _('User:'), self._uid) - ) - return super(MailMessage, self).check_access_rule(operation=operation) - - def _portal_message_format(self, fields_list): - fields_list += ['website_published'] - return super(MailMessage, self)._portal_message_format(fields_list) diff --git a/addons/website_mail/security/website_mail_security.xml b/addons/website_mail/security/website_mail_security.xml deleted file mode 100644 index d814fff16ef..00000000000 --- a/addons/website_mail/security/website_mail_security.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - mail.message: portal/public: read published messages - - [('website_published', '=', True)] - - - - - diff --git a/addons/website_mail/static/src/js/portal_chatter.js b/addons/website_mail/static/src/js/portal_chatter.js deleted file mode 100644 index 923c17032fe..00000000000 --- a/addons/website_mail/static/src/js/portal_chatter.js +++ /dev/null @@ -1,13 +0,0 @@ -odoo.define('website_mail.thread', function (require) { -'use strict'; - -var portalChatter = require('portal.chatter'); - -/** - * Extends Frontend Chatter to handle rating - */ -portalChatter.PortalChatter.include({ - xmlDependencies: (portalChatter.PortalChatter.prototype.xmlDependencies || []) - .concat(['/website_mail/static/src/xml/portal_chatter.xml']), -}); -}); diff --git a/addons/website_mail/static/src/xml/portal_chatter.xml b/addons/website_mail/static/src/xml/portal_chatter.xml deleted file mode 100644 index 70f51435c3b..00000000000 --- a/addons/website_mail/static/src/xml/portal_chatter.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - -
- - -
-
-
- - - - - - - - - - - - -
diff --git a/addons/website_mail/views/assets.xml b/addons/website_mail/views/assets.xml index 30d581cf4a4..c0c293a1b39 100644 --- a/addons/website_mail/views/assets.xml +++ b/addons/website_mail/views/assets.xml @@ -3,7 +3,6 @@ diff --git a/addons/website_rating/i18n/website_rating.pot b/addons/website_rating/i18n/website_rating.pot deleted file mode 100644 index 1f28df3a669..00000000000 --- a/addons/website_rating/i18n/website_rating.pot +++ /dev/null @@ -1,251 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * website_rating -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:17+0000\n" -"PO-Revision-Date: 2019-08-26 08:17+0000\n" -"Last-Translator: \n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: \n" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/xml/portal_chatter.xml:0 -#, python-format -msgid "" -"#{widget.options['force_submit_url'] ? widget.options['force_submit_url'] : " -"'/mail/chatter_post'}" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/xml/portal_rating_composer.xml:0 -#, python-format -msgid "×" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/xml/portal_rating_composer.xml:0 -#: code:addons/website_rating/static/src/xml/portal_rating_composer.xml:0 -#, python-format -msgid "Add a review" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/xml/portal_tools.xml:0 -#, python-format -msgid "Average" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/xml/portal_chatter.xml:0 -#, python-format -msgid "Cancel" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/xml/portal_chatter.xml:0 -#, python-format -msgid "Comment" -msgstr "" - -#. module: website_rating -#: model:ir.model.fields,field_description:website_rating.field_rating_rating__publisher_id -msgid "Commented by" -msgstr "" - -#. module: website_rating -#: model:ir.model.fields,field_description:website_rating.field_rating_rating__publisher_datetime -msgid "Commented on" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/xml/portal_chatter.xml:0 -#, python-format -msgid "Delete" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/xml/portal_tools.xml:0 -#, python-format -msgid "Details" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/xml/portal_chatter.xml:0 -#, python-format -msgid "Edit" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/xml/portal_tools.xml:0 -#: code:addons/website_rating/static/src/xml/portal_tools.xml:0 -#, python-format -msgid "Half a star" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/js/portal_composer.js:0 -#, python-format -msgid "I don't like it" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/js/portal_composer.js:0 -#, python-format -msgid "I hate it" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/js/portal_composer.js:0 -#, python-format -msgid "I like it" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/js/portal_composer.js:0 -#, python-format -msgid "I love it" -msgstr "" - -#. module: website_rating -#: code:addons/website_rating/controllers/portal_rating.py:0 -#, python-format -msgid "Invalid rating" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/js/portal_composer.js:0 -#, python-format -msgid "It's okay" -msgstr "" - -#. module: website_rating -#: model:ir.model,name:website_rating.model_mail_message -msgid "Message" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/xml/portal_rating_composer.xml:0 -#: code:addons/website_rating/static/src/xml/portal_rating_composer.xml:0 -#, python-format -msgid "Modify your review" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/xml/portal_tools.xml:0 -#: code:addons/website_rating/static/src/xml/portal_tools.xml:0 -#, python-format -msgid "One star" -msgstr "" - -#. module: website_rating -#: code:addons/website_rating/models/rating.py:0 -#, python-format -msgid "Only the publisher of the website can change the rating comment" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/xml/portal_chatter.xml:0 -#, python-format -msgid "Post comment" -msgstr "" - -#. module: website_rating -#: model:ir.model.fields,field_description:website_rating.field_rating_rating__website_published -msgid "Published" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/xml/portal_chatter.xml:0 -#: code:addons/website_rating/static/src/xml/portal_chatter.xml:0 -#, python-format -msgid "Published on" -msgstr "" - -#. module: website_rating -#: model:ir.model.fields,field_description:website_rating.field_rating_rating__publisher_comment -msgid "Publisher Comment" -msgstr "" - -#. module: website_rating -#: model_terms:ir.ui.view,arch_db:website_rating.rating_rating_view_form -msgid "Publisher comment" -msgstr "" - -#. module: website_rating -#: model:ir.model,name:website_rating.model_rating_rating -msgid "Rating" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/xml/portal_tools.xml:0 -#, python-format -msgid "Remove Selection" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/xml/portal_chatter.xml:0 -#, python-format -msgid "Update comment" -msgstr "" - -#. module: website_rating -#: model:ir.model.fields,help:website_rating.field_rating_rating__website_published -msgid "Visible on the website as a comment" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/js/portal_chatter.js:0 -#, python-format -msgid "Write your comment" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/xml/portal_chatter.xml:0 -#: code:addons/website_rating/static/src/xml/portal_chatter.xml:0 -#, python-format -msgid "avatar" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/xml/portal_rating_composer.xml:0 -#, python-format -msgid "ratings)" -msgstr "" - -#. module: website_rating -#. openerp-web -#: code:addons/website_rating/static/src/xml/portal_tools.xml:0 -#, python-format -msgid "stars" -msgstr "" diff --git a/addons/website_rating/views/assets.xml b/addons/website_rating/views/assets.xml deleted file mode 100644 index f5f2dd2e8e9..00000000000 --- a/addons/website_rating/views/assets.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - diff --git a/addons/website_sale/__manifest__.py b/addons/website_sale/__manifest__.py index 5dfea3c026a..271cc58515e 100644 --- a/addons/website_sale/__manifest__.py +++ b/addons/website_sale/__manifest__.py @@ -6,7 +6,7 @@ 'website': 'https://www.odoo.com/page/e-commerce', 'version': '1.0', 'description': "", - 'depends': ['website', 'sale', 'website_payment', 'website_mail', 'website_form', 'website_rating', 'digest'], + 'depends': ['website', 'sale', 'website_payment', 'website_mail', 'website_form', 'portal_rating', 'digest'], 'data': [ 'security/ir.model.access.csv', 'security/website_sale.xml', diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index 405cd3f5690..79664e37c6c 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -1243,7 +1243,7 @@ class WebsiteSale(http.Controller): res_product.update(combination_info) res_product['price'] = FieldMonetary.value_to_html(res_product['price'], monetary_options) if rating: - res_product['rating'] = request.env["ir.ui.view"].render_template('website_rating.rating_widget_stars_static', values={ + res_product['rating'] = request.env["ir.ui.view"].render_template('portal_rating.rating_widget_stars_static', values={ 'rating_avg': product.rating_avg, 'rating_count': product.rating_count, }) diff --git a/addons/website_sale/models/product.py b/addons/website_sale/models/product.py index 5d56b3a3a90..876f4cba8cf 100644 --- a/addons/website_sale/models/product.py +++ b/addons/website_sale/models/product.py @@ -372,7 +372,7 @@ class ProductTemplate(models.Model): def _rating_domain(self): """ Only take the published rating into account to compute avg and count """ domain = super(ProductTemplate, self)._rating_domain() - return expression.AND([domain, [('website_published', '=', True)]]) + return expression.AND([domain, [('is_internal', '=', False)]]) def _get_images(self): """Return a list of records implementing `image.mixin` to diff --git a/addons/website_slides/__manifest__.py b/addons/website_slides/__manifest__.py index 604497299a5..b8d0520a792 100644 --- a/addons/website_slides/__manifest__.py +++ b/addons/website_slides/__manifest__.py @@ -20,10 +20,11 @@ Featuring * Statistics """, 'depends': [ + 'portal_rating', 'website', 'website_mail', 'website_profile', - 'website_rating'], + ], 'data': [ 'views/assets.xml', 'views/res_config_settings_views.xml', diff --git a/addons/website_slides/controllers/mail.py b/addons/website_slides/controllers/mail.py index 1940189a4d0..1d1c62bcee7 100644 --- a/addons/website_slides/controllers/mail.py +++ b/addons/website_slides/controllers/mail.py @@ -49,7 +49,7 @@ class SlidesPortalChatter(PortalChatter): domain = [ ('model', '=', res_model), ('res_id', '=', res_id), - ('website_published', '=', True), + ('is_internal', '=', False), ('author_id', '=', request.env.user.partner_id.id), ('message_type', '=', 'comment'), ('id', '=', message_id) @@ -64,7 +64,7 @@ class SlidesPortalChatter(PortalChatter): # update rating if post.get('rating_value'): - domain = [('res_model', '=', res_model), ('res_id', '=', res_id), ('website_published', '=', True), ('message_id', '=', message.id)] + domain = [('res_model', '=', res_model), ('res_id', '=', res_id), ('is_internal', '=', False), ('message_id', '=', message.id)] rating = request.env['rating.rating'].sudo().search(domain, order='write_date DESC', limit=1) rating.write({ 'rating': float(post['rating_value']) diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py index d903d5f1ffa..e183045e062 100644 --- a/addons/website_slides/controllers/main.py +++ b/addons/website_slides/controllers/main.py @@ -433,7 +433,7 @@ class WebsiteSlides(WebsiteProfile): ('res_id', '=', channel.id), ('author_id', '=', request.env.user.partner_id.id), ('message_type', '=', 'comment'), - ('website_published', '=', True) + ('is_internal', '=', False) ], order='write_date DESC', limit=1) if last_message: last_message_values = last_message.read(['body', 'rating_value', 'attachment_ids'])[0] diff --git a/addons/website_slides/data/slide_user_demo.xml b/addons/website_slides/data/slide_user_demo.xml index 78cf6138884..95fcc2cbd67 100644 --- a/addons/website_slides/data/slide_user_demo.xml +++ b/addons/website_slides/data/slide_user_demo.xml @@ -42,7 +42,6 @@ slide.channel - comment
I fear beginners could be lost... Isn't it a bit harsh for a "basics" course ?
@@ -60,7 +59,6 @@ slide.channel - comment
Back to basics and interesting. Just WOW !
@@ -132,7 +130,6 @@ slide.channel - comment
Very good course.
@@ -150,7 +147,6 @@ slide.channel - comment
Interesting !
@@ -168,7 +164,6 @@ slide.channel - comment
Interesting. Could be great to include more examples.
diff --git a/addons/website_slides/models/slide_channel.py b/addons/website_slides/models/slide_channel.py index 77aacea09d9..0c70cc82f47 100644 --- a/addons/website_slides/models/slide_channel.py +++ b/addons/website_slides/models/slide_channel.py @@ -398,7 +398,7 @@ class Channel(models.Model): return res @api.returns('mail.message', lambda value: value.id) - def message_post(self, *, parent_id=False, subtype=None, **kwargs): + def message_post(self, *, parent_id=False, subtype_id=False, **kwargs): """ Temporary workaround to avoid spam. If someone replies on a channel through the 'Presentation Published' email, it should be considered as a note as we don't want all channel followers to be notified of this answer. """ @@ -408,10 +408,8 @@ class Channel(models.Model): if parent_id: parent_message = self.env['mail.message'].sudo().browse(parent_id) if parent_message.subtype_id and parent_message.subtype_id == self.env.ref('website_slides.mt_channel_slide_published'): - if kwargs.get('subtype_id'): - kwargs['subtype_id'] = False - subtype = 'mail.mt_note' - return super(Channel, self).message_post(parent_id=parent_id, subtype=subtype, **kwargs) + subtype_id = self.env.ref('mail.mt_note').id + return super(Channel, self).message_post(parent_id=parent_id, subtype_id=subtype_id, **kwargs) # --------------------------------------------------------- # Business / Actions @@ -541,7 +539,7 @@ class Channel(models.Model): def _rating_domain(self): """ Only take the published rating into account to compute avg and count """ domain = super(Channel, self)._rating_domain() - return expression.AND([domain, [('website_published', '=', True)]]) + return expression.AND([domain, [('is_internal', '=', False)]]) # --------------------------------------------------------- # Data / Misc diff --git a/addons/website_slides/models/slide_slide.py b/addons/website_slides/models/slide_slide.py index 9e0730a1abb..57a40d140af 100644 --- a/addons/website_slides/models/slide_slide.py +++ b/addons/website_slides/models/slide_slide.py @@ -483,7 +483,7 @@ class Slide(models.Model): slide.channel_id.with_context(mail_create_nosubscribe=True).message_post( subject=subject, body=html_body, - subtype='website_slides.mt_channel_slide_published', + subtype_xmlid='website_slides.mt_channel_slide_published', email_layout_xmlid='mail.mail_notification_light', ) return True diff --git a/addons/website_slides/static/src/js/rating_field_backend.js b/addons/website_slides/static/src/js/rating_field_backend.js index 66e32986a00..12a6d8b63b7 100644 --- a/addons/website_slides/static/src/js/rating_field_backend.js +++ b/addons/website_slides/static/src/js/rating_field_backend.js @@ -10,8 +10,8 @@ var QWeb = core.qweb; var FieldFloatRating = basicFields.FieldFloat.extend({ xmlDependencies: !basicFields.FieldFloat.prototype.xmlDependencies ? - ['/website_rating/static/src/xml/portal_tools.xml'] : basicFields.FieldFloat.prototype.xmlDependencies.concat( - ['/website_rating/static/src/xml/portal_tools.xml'] + ['/portal_rating/static/src/xml/portal_tools.xml'] : basicFields.FieldFloat.prototype.xmlDependencies.concat( + ['/portal_rating/static/src/xml/portal_tools.xml'] ), //-------------------------------------------------------------------------- // Private @@ -25,7 +25,7 @@ var FieldFloatRating = basicFields.FieldFloat.extend({ var self = this; return Promise.resolve(this._super()).then(function () { - self.$el.html(QWeb.render('website_rating.rating_stars_static', { + self.$el.html(QWeb.render('portal_rating.rating_stars_static', { 'val': self.value / 2, 'inline_mode': true })); diff --git a/addons/website_slides/views/website_slides_templates_course.xml b/addons/website_slides/views/website_slides_templates_course.xml index e9bc8668a82..22826d6dcd1 100644 --- a/addons/website_slides/views/website_slides_templates_course.xml +++ b/addons/website_slides/views/website_slides_templates_course.xml @@ -137,7 +137,7 @@
- +