예제 #1
0
 def rating_apply(self, rate, token=None, feedback=None, subtype=None):
     """ Apply a rating given a token. If the current model inherits from
     mail.thread mixing, a message is posted on its chatter.
     :param rate : the rating value to apply
     :type rate : float
     :param token : access token
     :param feedback : additional feedback
     :type feedback : string
     :param subtype : subtype for mail
     :type subtype : string
     :returns rating.rating record
     """
     Rating, rating = self.env['rating.rating'], None
     if token:
         rating = self.env['rating.rating'].search([('access_token', '=', token)], limit=1)
     else:
         rating = Rating.search([('res_model', '=', self._name), ('res_id', '=', self.ids[0])], limit=1)
     if rating:
         rating.write({'rating': rate, 'feedback': feedback, 'consumed': True})
         if hasattr(self, 'message_post'):
             feedback = tools.plaintext2html(feedback or '')
             self.message_post(
                 body="<img src='/rating/static/src/img/rating_%s.png' alt=':%s/10' style='width:18px;height:18px;float:left;margin-right: 5px;'/>%s"
                 % (rate, rate, feedback),
                 subtype=subtype 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:
             if rating.rating > 5:
                 self.write({'kanban_state': 'done'})
             if rating.rating < 5:
                 self.write({'kanban_state': 'blocked'})
     return rating
예제 #2
0
    def portal_chatter_post(self, res_model, res_id, message, redirect=None, attachment_ids='', attachment_tokens='', **kw):
        """Create a new `mail.message` with the given `message` and/or
        `attachment_ids` and redirect the user to the newly created message.

        The message will be associated to the record `res_id` of the model
        `res_model`. The user must have access rights on this target document or
        must provide valid identifiers through `kw`. See `_message_post_helper`.
        """
        url = redirect or (request.httprequest.referrer and request.httprequest.referrer + "#discussion") or '/my'

        res_id = int(res_id)

        attachment_ids = [int(attachment_id) for attachment_id in attachment_ids.split(',') if attachment_id]
        attachment_tokens = [attachment_token for attachment_token in attachment_tokens.split(',') if attachment_token]
        self._portal_post_check_attachments(attachment_ids, attachment_tokens)

        if message or attachment_ids:
            # message is received in plaintext and saved in html
            if message:
                message = plaintext2html(message)
            post_values = {
                'res_model': res_model,
                'res_id': res_id,
                'message': message,
                'send_after_commit': False,
                'attachment_ids': attachment_ids,
            }
            post_values.update((fname, kw.get(fname)) for fname in self._portal_post_filter_params())
            message = _message_post_helper(**post_values)

        return request.redirect(url)
예제 #3
0
    def mail_chat_post(self, uuid, message_content, **kwargs):
        mail_channel = request.env["mail.channel"].sudo().search(
            [('uuid', '=', uuid)], limit=1)
        if not mail_channel:
            return False

        # find the author from the user session
        if request.session.uid:
            author = request.env['res.users'].sudo().browse(
                request.session.uid).partner_id
            author_id = author.id
            email_from = author.email_formatted
        else:  # If Public User, use catchall email from company
            author_id = False
            email_from = mail_channel.anonymous_name or mail_channel.create_uid.company_id.catchall
        # post a message without adding followers to the channel. email_from=False avoid to get author from email data
        body = tools.plaintext2html(message_content)
        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')
        return message and message.id or False
예제 #4
0
 def test_plaintext2html(self):
     cases = [
         ("First \nSecond \nThird\n \nParagraph\n\r--\nSignature paragraph",
          'div',
          "<div><p>First <br/>Second <br/>Third</p><p>Paragraph</p><p>--<br/>Signature paragraph</p></div>"
          ),
         ("First<p>It should be escaped</p>\nSignature", False,
          "<p>First&lt;p&gt;It should be escaped&lt;/p&gt;<br/>Signature</p>"
          )
     ]
     for content, container_tag, expected in cases:
         html = plaintext2html(content, container_tag)
         self.assertEqual(html, expected, 'plaintext2html is broken')
예제 #5
0
    def _message_sms(self, body, subtype_id=False, partner_ids=False, number_field=False,
                     sms_numbers=None, sms_pid_to_number=None, **kwargs):
        """ Main method to post a message on a record using SMS-based notification
        method.

        :param body: content of SMS;
        :param subtype_id: mail.message.subtype used in mail.message associated
          to the sms notification process;
        :param partner_ids: if set is a record set of partners to notify;
        :param number_field: if set is a name of field to use on current record
          to compute a number to notify;
        :param sms_numbers: see ``_notify_record_by_sms``;
        :param sms_pid_to_number: see ``_notify_record_by_sms``;
        """
        self.ensure_one()
        sms_pid_to_number = sms_pid_to_number if sms_pid_to_number is not None else {}

        if number_field or (partner_ids is False and sms_numbers is None):
            info = self._sms_get_recipients_info(force_field=number_field)[self.id]
            info_partner_ids = info['partner'].ids if info['partner'] else False
            info_number = info['sanitized'] if info['sanitized'] else info['number']
            if info_partner_ids and info_number:
                sms_pid_to_number[info_partner_ids[0]] = info_number
            if info_partner_ids:
                partner_ids = info_partner_ids + (partner_ids or [])
            if info_number and not info_partner_ids:
                sms_numbers = [info_number] + (sms_numbers or [])

        if subtype_id is False:
            subtype_id = self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note')

        return self.message_post(
            body=plaintext2html(html2plaintext(body)), partner_ids=partner_ids or [],  # TDE FIXME: temp fix otherwise crash mail_thread.py
            message_type='sms', subtype_id=subtype_id,
            sms_numbers=sms_numbers, sms_pid_to_number=sms_pid_to_number,
            **kwargs
        )
예제 #6
0
    def mail_update_message(self,
                            res_model,
                            res_id,
                            message,
                            message_id,
                            redirect=None,
                            attachment_ids='',
                            attachment_tokens='',
                            **post):
        # keep this mecanism intern to slide currently (saas 12.5) as it is
        # considered experimental
        if res_model != 'slide.channel':
            raise Forbidden()
        res_id = int(res_id)

        attachment_ids = [
            int(attachment_id) for attachment_id in attachment_ids.split(',')
            if attachment_id
        ]
        attachment_tokens = [
            attachment_token
            for attachment_token in attachment_tokens.split(',')
            if attachment_token
        ]
        self._portal_post_check_attachments(attachment_ids, attachment_tokens)

        pid = int(post['pid']) if post.get('pid') else False
        if not _check_special_access(res_model,
                                     res_id,
                                     token=post.get('token'),
                                     _hash=post.get('hash'),
                                     pid=pid):
            raise Forbidden()

        # fetch and update mail.message
        message_id = int(message_id)
        message_body = plaintext2html(message)
        domain = [('model', '=', res_model), ('res_id', '=', res_id),
                  ('website_published', '=', True),
                  ('author_id', '=', request.env.user.partner_id.id),
                  ('message_type', '=', 'comment'),
                  ('id', '=', message_id)]  # restrict to the given message_id
        message = request.env['mail.message'].search(domain, limit=1)
        if not message:
            raise NotFound()
        message.write({
            'body': message_body,
            'attachment_ids': [(4, aid) for aid in attachment_ids],
        })

        # update rating
        if post.get('rating_value'):
            domain = [('res_model', '=', res_model), ('res_id', '=', res_id),
                      ('website_published', '=', True),
                      ('message_id', '=', message.id)]
            rating = request.env['rating.rating'].search(
                domain, order='write_date DESC', limit=1)
            rating.write({
                'rating': float(post['rating_value']),
                'feedback': html2plaintext(message.body),
            })

        # redirect to specified or referrer or simply channel page as fallback
        redirect_url = redirect or (request.httprequest.referrer
                                    and request.httprequest.referrer +
                                    '#review') or '/slides/%s' % res_id
        return werkzeug.utils.redirect(redirect_url, 302)