From 06f169a0ee0f7508f861c47ee2f39467df7b6dc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 2 Dec 2019 14:30:18 +0000 Subject: [PATCH 1/8] [FIX] mail: give default void list instead of None when checking user groups for notification Some override of ``_notify_classify_recipients`` may not check that groups is None and expect a (maybe void) list. Task ID 2071556 PR #38692 --- addons/mail/models/mail_thread.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index 89b6818bc64..5e662e9db00 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -2402,7 +2402,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 From e2b33f460d0f2359e65107f8615c7e827350b4e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 24 Oct 2019 11:09:01 +0000 Subject: [PATCH 2/8] [REF] mail, various: rename subtype parameter of message_post to subtype_xmlid PURPOSE Clean posting process and improve mail.message definition and comprehension. SPECIFICATIONS In order to be more explicit subtype parameter is renamed to subtype_xmlid. It therefore clearly indicates it should be a valid subtype Xml ID. Support of ill formatted Xml IDs is removed because there is no reason to try to add some random prefix. Give something that exists or go to hell, punk ! LINKS Task ID 2071556 PR #38692 --- addons/calendar/models/calendar.py | 4 +-- addons/gamification/models/challenge.py | 8 +++--- addons/gamification/models/goal.py | 2 +- addons/hr_holidays/models/hr_leave.py | 2 +- .../hr_holidays/tests/test_access_rights.py | 4 +-- .../hr_recruitment/models/hr_recruitment.py | 2 +- addons/mail/controllers/bus.py | 2 +- addons/mail/controllers/home.py | 2 +- addons/mail/models/mail_channel.py | 8 +++--- addons/mail/models/mail_thread.py | 15 +++++----- addons/mail/models/update.py | 2 +- .../src/js/composers/chatter_composer.js | 4 +-- addons/mail/static/src/js/discuss.js | 2 +- .../static/src/js/models/threads/channel.js | 2 +- .../src/js/models/threads/document_thread.js | 2 +- addons/mail/static/tests/chatter_tests.js | 12 ++++---- addons/mail_bot/models/mail_channel.py | 2 +- addons/portal/controllers/mail.py | 2 +- addons/project/models/project.py | 4 +-- addons/rating/models/rating_mixin.py | 6 ++-- addons/sale/controllers/portal.py | 2 +- addons/test_mail/tests/test_discuss.py | 8 +++--- addons/test_mail/tests/test_mail_channel.py | 16 +++++------ addons/test_mail/tests/test_mail_gateway.py | 4 +-- addons/test_mail/tests/test_mail_message.py | 8 +++--- .../tests/test_message_management.py | 6 ++-- addons/test_mail/tests/test_message_post.py | 28 +++++++++---------- addons/test_mail/tests/test_odoobot.py | 2 +- addons/test_mail/tests/test_performance.py | 12 ++++---- .../tests/test_mail_channel.py | 2 +- addons/website_blog/models/website_blog.py | 8 ++---- .../tests/test_website_blog_flow.py | 2 +- addons/website_forum/controllers/main.py | 2 +- addons/website_forum/models/forum.py | 8 +++--- .../website_livechat/models/mail_channel.py | 2 +- addons/website_slides/models/slide_channel.py | 8 ++---- addons/website_slides/models/slide_slide.py | 2 +- 37 files changed, 101 insertions(+), 106 deletions(-) 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/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_thread.py b/addons/mail/models/mail_thread.py index 5e662e9db00..a4abcaae227 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -1777,7 +1777,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 +1791,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 +1812,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 +1832,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: 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_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..eddf8cb32ce 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 ) 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/models/rating_mixin.py b/addons/rating/models/rating_mixin.py index 77196e80c50..62fa232f12f 100644 --- a/addons/rating/models/rating_mixin.py +++ b/addons/rating/models/rating_mixin.py @@ -168,7 +168,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 +178,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 +194,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/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_slides/models/slide_channel.py b/addons/website_slides/models/slide_channel.py index 77aacea09d9..90fa7898eb9 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 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 From 46b9a97b56d74503d6e86b16466982c750a66422 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 14 Oct 2019 09:16:46 +0000 Subject: [PATCH 3/8] [MOV] {website_}mail: move description field of mail.message directly in mail PURPOSE Clean posting process and improve mail.message definition and comprehension. SPECIFCIATIONS Move description from website_mail directly to mail. Anyway it is a non stored computed field and therefore having it available directly in mail does not cost anything. LINKS Task ID 2071556 PR #38692 --- addons/mail/models/mail_message.py | 16 +++++++++++++--- addons/website_mail/models/mail_message.py | 10 ---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/addons/mail/models/mail_message.py b/addons/mail/models/mail_message.py index 0a038e381eb..539557f93e9 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', @@ -124,7 +126,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 +139,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([ @@ -1200,7 +1210,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()} diff --git a/addons/website_mail/models/mail_message.py b/addons/website_mail/models/mail_message.py index 8070c7d7fcc..2de32b9f4f0 100644 --- a/addons/website_mail/models/mail_message.py +++ b/addons/website_mail/models/mail_message.py @@ -3,7 +3,6 @@ from odoo import api, fields, models, _ from odoo.osv import expression -from odoo.tools import html2plaintext from odoo.exceptions import AccessError @@ -23,7 +22,6 @@ class MailMessage(models.Model): 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 @@ -31,14 +29,6 @@ class MailMessage(models.Model): 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 From 5649fc88e8f3022f4143400a124f2e3c1e5c0df8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 14 Oct 2019 11:05:55 +0000 Subject: [PATCH 4/8] [REF] {website_}mail: move and replace published field of mail.message to is_internal PURPOSE Clean posting process and improve mail.message definition and comprehension. SPECIFICATIONS Website mail defines a website_published field allowing to publish / unpublish comments on the frontend of some modules. This field has several drawbacks : * it is used only for front-end people (portal, public) and has no real effect in chatter / classic discussions; * it is used only in some advanced front-end module and is not available in portal by default; * its naming is not really correct as it is not linked to fields coming from the website_published mixin and its behavior is not really the same; * its use is a bit duplicated with internal flag coming from subtype allowing to hide messages related to an internal subtype; * there are overrides of standard mail.message methods just to handle this flag; In this commit we change that field by an is_internal flag directly on mail.message model itself. It tells if share people (customers, share users) are allowed to read the message. This field can be given through posting API or set manually using widgets. It is also used in access rights custom methods and managed like the internal flag of subtypes. Mailgateway was already using an internal flag for internal note replies. It is renamed to is_internal and propagated as it is now a standard field. It also eases code understanding. Portal is updated to allow managing the flag directly. It means customer portal now natively allows to moderate customer comments without any need of website modules. Rating is updated accordingly. An is_internal field is added, replacing the related on website published. LINKS Task ID 2071556 PR #38692 --- addons/im_livechat/controllers/main.py | 1 + addons/mail/models/mail_message.py | 12 +++- addons/mail/models/mail_thread.py | 11 ++-- addons/portal/controllers/mail.py | 9 ++- addons/portal/models/mail_message.py | 6 +- addons/portal/static/src/js/portal_chatter.js | 33 ++++++++++- addons/portal/static/src/scss/portal.scss | 12 ++++ .../portal/static/src/xml/portal_chatter.xml | 13 +++++ addons/rating/models/rating.py | 1 + addons/rating/models/rating_mixin.py | 3 +- addons/website_mail/__manifest__.py | 4 +- addons/website_mail/models/__init__.py | 1 - addons/website_mail/models/mail_message.py | 58 ------------------- .../security/website_mail_security.xml | 13 ----- .../static/src/js/portal_chatter.js | 13 ----- .../static/src/xml/portal_chatter.xml | 23 -------- addons/website_mail/views/assets.xml | 1 - addons/website_rating/models/rating.py | 2 - addons/website_sale/models/product.py | 2 +- addons/website_slides/controllers/mail.py | 4 +- addons/website_slides/controllers/main.py | 2 +- .../website_slides/data/slide_user_demo.xml | 5 -- addons/website_slides/models/slide_channel.py | 2 +- 23 files changed, 92 insertions(+), 139 deletions(-) delete mode 100644 addons/website_mail/models/mail_message.py delete mode 100644 addons/website_mail/security/website_mail_security.xml delete mode 100644 addons/website_mail/static/src/js/portal_chatter.js delete mode 100644 addons/website_mail/static/src/xml/portal_chatter.xml 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/models/mail_message.py b/addons/mail/models/mail_message.py index 539557f93e9..2b906074915 100644 --- a/addons/mail/models/mail_message.py +++ b/addons/mail/models/mail_message.py @@ -73,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( @@ -234,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, @@ -359,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) @@ -1279,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 a4abcaae227..91e9c7e16a1 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')} @@ -1441,14 +1441,14 @@ class MailThread(models.AbstractModel): 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 + msg_dict['is_internal'] = parent_ids.subtype_id and parent_ids.subtype_id.internal or False if msg_dict['references'] and 'parent_id' not in msg_dict: 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 + 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)) @@ -1996,6 +1996,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'), @@ -2024,6 +2025,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 @@ -2046,6 +2048,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 diff --git a/addons/portal/controllers/mail.py b/addons/portal/controllers/mail.py index eddf8cb32ce..1cbff66cde5 100644 --- a/addons/portal/controllers/mail.py +++ b/addons/portal/controllers/mail.py @@ -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..52a3d77c7bd 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/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 62fa232f12f..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] 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 2de32b9f4f0..00000000000 --- a/addons/website_mail/models/mail_message.py +++ /dev/null @@ -1,58 +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.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 - - 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)]]) - - @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/models/rating.py b/addons/website_rating/models/rating.py index 3c5f3586c59..bea77a45de9 100644 --- a/addons/website_rating/models/rating.py +++ b/addons/website_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_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/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 90fa7898eb9..0c70cc82f47 100644 --- a/addons/website_slides/models/slide_channel.py +++ b/addons/website_slides/models/slide_channel.py @@ -539,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 From 82f56ffddfc6aed21030214dc95c0a3e9f5d9a93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 2 Dec 2019 12:33:41 +0000 Subject: [PATCH 5/8] [IMP] mail: simplify parent and parent internal computation in routing PURPOSE Clean posting process and improve mail.message definition and comprehension. SPECIFICATIONS In this commit we use the is_internal flag to correctly propagate it from mail gateway and clean some parent check. In this commit some code is cleaned. No functional change should occur with this commit. LINKS Task ID 2071556 PR #38692 --- addons/mail/models/mail_thread.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index 91e9c7e16a1..6ca54653d87 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -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['is_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['is_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)) From 9e0677882d64ac2be92cd1ea147ce823e2d9f69b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 24 Oct 2019 14:05:48 +0000 Subject: [PATCH 6/8] [MOV] website_rating: move to portal_rating PURPOSE Clean posting process and improve mail.message definition and comprehension. Move as much possible content from website_* modules to portal_* modules to ease their use in customer portal SPECIFICATIONS Now that publish feature is replaced by internal directly in mail and portal rating portal inclusion can be done safely in a portal_ratign module instead of website_rating. It allows to remove the dependency and give the rating feature of customer chatter directly in portal applications. LINKS Task ID 2071556 PR #38692 --- addons/portal/static/src/xml/portal_chatter.xml | 2 +- .../__init__.py | 0 .../__manifest__.py | 10 +++++++--- .../controllers/__init__.py | 0 .../controllers/portal_chatter.py | 0 .../controllers/portal_rating.py | 0 .../{website_rating => portal_rating}/i18n/ar.po | 0 .../{website_rating => portal_rating}/i18n/az.po | 0 .../{website_rating => portal_rating}/i18n/bs.po | 0 .../{website_rating => portal_rating}/i18n/ca.po | 0 .../{website_rating => portal_rating}/i18n/cs.po | 0 .../{website_rating => portal_rating}/i18n/da.po | 0 .../{website_rating => portal_rating}/i18n/de.po | 0 .../{website_rating => portal_rating}/i18n/el.po | 0 .../{website_rating => portal_rating}/i18n/es.po | 0 .../{website_rating => portal_rating}/i18n/et.po | 0 .../{website_rating => portal_rating}/i18n/fa.po | 0 .../{website_rating => portal_rating}/i18n/fi.po | 0 .../{website_rating => portal_rating}/i18n/fr.po | 0 .../{website_rating => portal_rating}/i18n/gu.po | 0 .../{website_rating => portal_rating}/i18n/he.po | 0 .../{website_rating => portal_rating}/i18n/hr.po | 0 .../{website_rating => portal_rating}/i18n/hu.po | 0 .../{website_rating => portal_rating}/i18n/id.po | 0 .../{website_rating => portal_rating}/i18n/is.po | 0 .../{website_rating => portal_rating}/i18n/it.po | 0 .../{website_rating => portal_rating}/i18n/ja.po | 0 .../{website_rating => portal_rating}/i18n/km.po | 0 .../{website_rating => portal_rating}/i18n/ko.po | 0 .../{website_rating => portal_rating}/i18n/lb.po | 0 .../{website_rating => portal_rating}/i18n/lt.po | 0 .../{website_rating => portal_rating}/i18n/lv.po | 0 .../{website_rating => portal_rating}/i18n/mn.po | 0 .../{website_rating => portal_rating}/i18n/nb.po | 0 .../{website_rating => portal_rating}/i18n/nl.po | 0 .../{website_rating => portal_rating}/i18n/pl.po | 0 .../{website_rating => portal_rating}/i18n/pt.po | 0 .../i18n/pt_BR.po | 0 .../{website_rating => portal_rating}/i18n/ro.po | 0 .../{website_rating => portal_rating}/i18n/ru.po | 0 .../{website_rating => portal_rating}/i18n/sk.po | 0 .../{website_rating => portal_rating}/i18n/sl.po | 0 .../{website_rating => portal_rating}/i18n/sr.po | 0 .../i18n/sr@latin.po | 0 .../{website_rating => portal_rating}/i18n/sv.po | 0 .../{website_rating => portal_rating}/i18n/th.po | 0 .../{website_rating => portal_rating}/i18n/tr.po | 0 .../{website_rating => portal_rating}/i18n/uk.po | 0 .../{website_rating => portal_rating}/i18n/vi.po | 0 .../i18n/website_rating.pot | 0 .../i18n/zh_CN.po | 0 .../i18n/zh_TW.po | 0 .../models/__init__.py | 0 .../models/mail_message.py | 0 .../models/rating.py | 0 .../static/src/js/portal_chatter.js | 10 +++++----- .../static/src/js/portal_composer.js | 0 .../static/src/js/portal_rating_composer.js | 6 +++--- .../static/src/scss/portal_rating.scss} | 0 .../static/src/xml/portal_chatter.xml | 16 ++++++++-------- .../static/src/xml/portal_rating_composer.xml | 4 ++-- .../static/src/xml/portal_tools.xml | 8 ++++---- addons/portal_rating/views/assets.xml | 13 +++++++++++++ .../views/portal_templates.xml | 0 .../views/rating_templates.xml | 0 .../views/rating_views.xml | 0 addons/website_rating/views/assets.xml | 13 ------------- addons/website_sale/__manifest__.py | 2 +- addons/website_sale/controllers/main.py | 2 +- addons/website_slides/__manifest__.py | 3 ++- .../static/src/js/rating_field_backend.js | 6 +++--- .../views/website_slides_templates_course.xml | 2 +- 72 files changed, 51 insertions(+), 46 deletions(-) rename addons/{website_rating => portal_rating}/__init__.py (100%) rename addons/{website_rating => portal_rating}/__manifest__.py (61%) rename addons/{website_rating => portal_rating}/controllers/__init__.py (100%) rename addons/{website_rating => portal_rating}/controllers/portal_chatter.py (100%) rename addons/{website_rating => portal_rating}/controllers/portal_rating.py (100%) rename addons/{website_rating => portal_rating}/i18n/ar.po (100%) rename addons/{website_rating => portal_rating}/i18n/az.po (100%) rename addons/{website_rating => portal_rating}/i18n/bs.po (100%) rename addons/{website_rating => portal_rating}/i18n/ca.po (100%) rename addons/{website_rating => portal_rating}/i18n/cs.po (100%) rename addons/{website_rating => portal_rating}/i18n/da.po (100%) rename addons/{website_rating => portal_rating}/i18n/de.po (100%) rename addons/{website_rating => portal_rating}/i18n/el.po (100%) rename addons/{website_rating => portal_rating}/i18n/es.po (100%) rename addons/{website_rating => portal_rating}/i18n/et.po (100%) rename addons/{website_rating => portal_rating}/i18n/fa.po (100%) rename addons/{website_rating => portal_rating}/i18n/fi.po (100%) rename addons/{website_rating => portal_rating}/i18n/fr.po (100%) rename addons/{website_rating => portal_rating}/i18n/gu.po (100%) rename addons/{website_rating => portal_rating}/i18n/he.po (100%) rename addons/{website_rating => portal_rating}/i18n/hr.po (100%) rename addons/{website_rating => portal_rating}/i18n/hu.po (100%) rename addons/{website_rating => portal_rating}/i18n/id.po (100%) rename addons/{website_rating => portal_rating}/i18n/is.po (100%) rename addons/{website_rating => portal_rating}/i18n/it.po (100%) rename addons/{website_rating => portal_rating}/i18n/ja.po (100%) rename addons/{website_rating => portal_rating}/i18n/km.po (100%) rename addons/{website_rating => portal_rating}/i18n/ko.po (100%) rename addons/{website_rating => portal_rating}/i18n/lb.po (100%) rename addons/{website_rating => portal_rating}/i18n/lt.po (100%) rename addons/{website_rating => portal_rating}/i18n/lv.po (100%) rename addons/{website_rating => portal_rating}/i18n/mn.po (100%) rename addons/{website_rating => portal_rating}/i18n/nb.po (100%) rename addons/{website_rating => portal_rating}/i18n/nl.po (100%) rename addons/{website_rating => portal_rating}/i18n/pl.po (100%) rename addons/{website_rating => portal_rating}/i18n/pt.po (100%) rename addons/{website_rating => portal_rating}/i18n/pt_BR.po (100%) rename addons/{website_rating => portal_rating}/i18n/ro.po (100%) rename addons/{website_rating => portal_rating}/i18n/ru.po (100%) rename addons/{website_rating => portal_rating}/i18n/sk.po (100%) rename addons/{website_rating => portal_rating}/i18n/sl.po (100%) rename addons/{website_rating => portal_rating}/i18n/sr.po (100%) rename addons/{website_rating => portal_rating}/i18n/sr@latin.po (100%) rename addons/{website_rating => portal_rating}/i18n/sv.po (100%) rename addons/{website_rating => portal_rating}/i18n/th.po (100%) rename addons/{website_rating => portal_rating}/i18n/tr.po (100%) rename addons/{website_rating => portal_rating}/i18n/uk.po (100%) rename addons/{website_rating => portal_rating}/i18n/vi.po (100%) rename addons/{website_rating => portal_rating}/i18n/website_rating.pot (100%) rename addons/{website_rating => portal_rating}/i18n/zh_CN.po (100%) rename addons/{website_rating => portal_rating}/i18n/zh_TW.po (100%) rename addons/{website_rating => portal_rating}/models/__init__.py (100%) rename addons/{website_rating => portal_rating}/models/mail_message.py (100%) rename addons/{website_rating => portal_rating}/models/rating.py (100%) rename addons/{website_rating => portal_rating}/static/src/js/portal_chatter.js (97%) rename addons/{website_rating => portal_rating}/static/src/js/portal_composer.js (100%) rename addons/{website_rating => portal_rating}/static/src/js/portal_rating_composer.js (92%) rename addons/{website_rating/static/src/scss/website_rating.scss => portal_rating/static/src/scss/portal_rating.scss} (100%) rename addons/{website_rating => portal_rating}/static/src/xml/portal_chatter.xml (91%) rename addons/{website_rating => portal_rating}/static/src/xml/portal_rating_composer.xml (95%) rename addons/{website_rating => portal_rating}/static/src/xml/portal_tools.xml (95%) create mode 100644 addons/portal_rating/views/assets.xml rename addons/{website_rating => portal_rating}/views/portal_templates.xml (100%) rename addons/{website_rating => portal_rating}/views/rating_templates.xml (100%) rename addons/{website_rating => portal_rating}/views/rating_views.xml (100%) delete mode 100644 addons/website_rating/views/assets.xml diff --git a/addons/portal/static/src/xml/portal_chatter.xml b/addons/portal/static/src/xml/portal_chatter.xml index 52a3d77c7bd..179d4f70626 100644 --- a/addons/portal/static/src/xml/portal_chatter.xml +++ b/addons/portal/static/src/xml/portal_chatter.xml @@ -119,7 +119,7 @@ + title="Currently available to everyone viewing this document, click to restrict to internal employees.">Visible
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/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/website_rating.pot b/addons/portal_rating/i18n/website_rating.pot similarity index 100% rename from addons/website_rating/i18n/website_rating.pot rename to addons/portal_rating/i18n/website_rating.pot 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 100% rename from addons/website_rating/models/rating.py rename to addons/portal_rating/models/rating.py 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 100% rename from addons/website_rating/views/rating_views.xml rename to addons/portal_rating/views/rating_views.xml 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_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/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 @@
- + From 7fae045d48fb417035971d087b9594c4f886f27a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 7 Nov 2019 15:03:26 +0000 Subject: [PATCH 7/8] [MOV] website_rating: now move translations to portal_rating PURPOSE Clean posting process and improve mail.message definition and comprehension. Move as much possible content from website_* modules to portal_* modules to ease their use in customer portal SPECIFICATIONS Now that website_rating is now portal_rating, let us update translations files accordingly. LINKS Task ID 2071556 PR #38692 --- .tx/config | 6 +- addons/portal_rating/i18n/portal_rating.pot | 251 +++++++++++++++++++ addons/portal_rating/i18n/website_rating.pot | 251 ------------------- 3 files changed, 254 insertions(+), 254 deletions(-) create mode 100644 addons/portal_rating/i18n/portal_rating.pot delete mode 100644 addons/portal_rating/i18n/website_rating.pot 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/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/portal_rating/i18n/website_rating.pot b/addons/portal_rating/i18n/website_rating.pot deleted file mode 100644 index 1f28df3a669..00000000000 --- a/addons/portal_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 "" From dc89f58467aad18fa7f0b9905c543dd71bda66ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 2 Dec 2019 13:31:28 +0000 Subject: [PATCH 8/8] [IMP] mail, rating, portal_rating: improve message and rating views Purpose of this commit is to add some missing fields in message view, notably is_internal newly added flag and its ratings. Rating form view is also updated to display is_internal flag, and form view is a bit reorganized. Task ID 2071556 PR #38692 --- addons/mail/views/mail_blacklist_views.xml | 2 +- addons/mail/views/mail_followers_views.xml | 2 +- addons/mail/views/mail_message_views.xml | 21 ++++++++------- addons/mail/views/mail_notification_views.xml | 2 +- addons/portal_rating/views/rating_views.xml | 2 +- addons/rating/__manifest__.py | 5 ++-- addons/rating/views/mail_message_views.xml | 15 +++++++++++ ...ating_view.xml => rating_rating_views.xml} | 26 ++++++++++++++----- 8 files changed, 52 insertions(+), 23 deletions(-) create mode 100644 addons/rating/views/mail_message_views.xml rename addons/rating/views/{rating_view.xml => rating_rating_views.xml} (91%) 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/portal_rating/views/rating_views.xml b/addons/portal_rating/views/rating_views.xml index 2a9e5bf0866..c179d92e1fd 100644 --- a/addons/portal_rating/views/rating_views.xml +++ b/addons/portal_rating/views/rating_views.xml @@ -5,7 +5,7 @@ rating.rating - + 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/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 + + + + +