'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'

@api.multi
def rating_apply(self, rate, token=None, feedback=None, subtype=None):

    (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'    style='width:20px;height:20px;float:left;margin-right:    5px;'/>%s" % (rate, feedback)), subtype=(subtype or 'mail.mt_comment'), author_id=((rating.partner_id and rating.partner_id.id) or None))
        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
