# -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import http from odoo.http import request, Response from datetime import datetime from markupsafe import Markup from odoo.addons.http_routing.models.ir_http import slug from odoo.addons.website_slides.controllers.main import WebsiteSlides class WebsiteSlidesORA(WebsiteSlides): @http.route('/ora/response/save/', type='http', auth="user", website=True) def save_response(self, **kwargs): user_response = self._get_access_data(kwargs) slide = request.env['slide.slide'].sudo().browse(int(kwargs.get('slide_id'))) if kwargs.get('submit') == 'save': self.add_answers(kwargs, user_response) if kwargs.get('submit') == 'resubmit_fresh': self._get_access_data(kwargs, resubmit=True) user_response.state = 'inactive' if kwargs.get('submit') == 'resubmit_copy': resubmit_copy_response = self._get_access_data(kwargs, resubmit=True) self.add_answers(kwargs, resubmit_copy_response) user_response.state = 'inactive' if kwargs.get('submit') == 'submit': user_response.state = 'submitted' user_response.submitted_date = datetime.now() self.add_answers(kwargs, user_response) if slide.peer_assessment: peer_limit = slide.peer_limit enrolled_users = slide.channel_id.partner_ids.filtered(lambda l: l.id != request.env.user.partner_id.id) if peer_limit <= len(enrolled_users): peer_limit = peer_limit else: peer_limit = len(enrolled_users) for _ in range(peer_limit): peer_user = slide._get_peer_user(user_response) if peer_user: request.env['open.response.rubric.staff'].create({ 'assess_type': 'peer', 'user_id': peer_user.id, 'state': 'in_progress', 'response_id': user_response.id }) user_response.message_post( body='This response has been submitted!', message_type='notification', subtype_xmlid='mail.mt_comment', author_id=request.env.user.partner_id.id, partner_ids=[user_response.staff_id.partner_id.id]) return request.redirect('/slides/slide/%s' % slug(slide)) def _get_access_data(self, post, resubmit=False): user = request.env.user slide_id = request.env['slide.slide'].sudo().browse(int(post.get('slide_id'))) if slide_id.response_ids and not resubmit: response = slide_id.response_ids.filtered(lambda x: x.state in ['active', 'submitted'] and x.user_id == user) if response: return response response = slide_id._create_answer(request.env.user.id) return response def add_answers(self, kwargs, response): if kwargs.get('response_id'): old_user_response = request.env['ora.response'].browse(int(kwargs.get('response_id'))) for line in response.user_response_line: for oline in old_user_response.user_response_line: if line.prompt_id == oline.prompt_id: if line.response_type == 'text': line.value_text_box = oline.value_text_box elif line.response_type == 'rich_text': line.value_richtext_box = Markup(oline.value_richtext_box) # query = ("update open_response_user_line set value_richtext_box='%s' where id=%s") % (oline.value_richtext_box, oline.id) # request.cr.execute(query) else: for line in response.user_response_line: if line.response_type == 'text': line.value_text_box = kwargs[str(line.prompt_id.id)] elif line.response_type == 'rich_text': line.value_richtext_box = Markup(kwargs[str(line.prompt_id.id)]) # query = ("update open_response_user_line set value_richtext_box='%s' where id='%s'") % (Markup(kwargs[str(line.prompt_id.id)]), line.id) # request.cr.execute(query) def _prepare_additional_channel_values(self, values, **kwargs): values = super(WebsiteSlidesORA, self)._prepare_additional_channel_values(values, **kwargs) slide = values.get('slide') submitted = False if slide and slide.prompt_ids: values.update({ 'slide_prompts': [{ 'id': prompt.id, 'sequence': prompt.sequence, 'question': Markup(prompt.question_name), 'response_type': prompt.response_type, 'submitted': submitted, 'name': prompt.name, } for prompt in slide.prompt_ids.sorted(key=lambda x: x.id)] }) if slide and slide.response_ids: total_responses = slide.response_ids.filtered(lambda l: l.user_id == request.env.user) submitted_response = total_responses.filtered(lambda l: l.state == 'submitted') active_response = total_responses.filtered(lambda l: l.state == 'active') inactive_response = total_responses.filtered(lambda l: l.state == 'inactive') assessed_response = total_responses.filtered(lambda l: l.state == 'assessed') values['submitted_response'] = submitted_response values['active_response'] = active_response values['inactive_response'] = inactive_response values['total_responses'] = total_responses values['assessed_response'] = assessed_response values['rubric_ids'] = slide.rubric_ids # if assessed_response: # values['channel_progress'][slide.id]['quiz_karma_gain'] += assessed_response.xp_points # values['channel_progress'][slide.id]['quiz_karma_won'] += assessed_response.xp_points for response in total_responses: if response.feedback == '


': response.feedback = False values['peer_responses'] = request.env['open.response.rubric.staff'].search([ ('user_id', '=', request.env.user.id), ('assess_type', '=', 'peer'), ('response_id.state', 'in', ['submitted', 'assessed']), ('response_id.slide_id', '=', slide.id) ]).mapped('response_id') return values @http.route('/slides/slide/get_values', website=True, type="json", auth="user") def slide_get_value(self, slide_id): csrf_token = request.csrf_token() slide = request.env['slide.slide'].browse(slide_id) if slide: values = {'slide': self._get_slide_values(slide), 'csrf_token': csrf_token} if slide.prompt_ids: values.update({ 'slide_prompts': [{ 'id': prompt.id, 'sequence': prompt.sequence, 'question': Markup(prompt.question_name), 'response_type': prompt.response_type, 'name': prompt.name, } for prompt in slide.prompt_ids.sorted(key=lambda x: x.id)] }) if slide.response_ids: total_responses = slide.response_ids.filtered(lambda l: l.user_id == request.env.user) values['total_responses'] = [] for ora_response in total_responses: if ora_response.feedback == '


' or ora_response.feedback == False: ora_response.feedback = '' values['total_responses'].append(self._get_total_responses(ora_response, slide)) peer_response_ids = request.env['open.response.rubric.staff'].search([ ('user_id', '=', request.env.user.id), ('assess_type', '=', 'peer'), ('response_id.state', 'in', ['submitted', 'assessed']), ('response_id.slide_id', '=', slide.id) ]) values['peer_responses'] = [] for staff_response in peer_response_ids: submitted_date = False if staff_response.submitted_date: submitted_date = staff_response.submitted_date.strftime('%d %B %Y') values['peer_responses'].append(({ 'id': staff_response.response_id.id, 'state': staff_response.state, 'assess_type': staff_response.assess_type, 'user_id': staff_response.user_id.id, 'submitted_date': submitted_date, 'option_ids': [{ 'id': rubric_id.criteria_id.id, 'criterian_name': rubric_id.criteria_id.criterian_name, 'criteria_desc': rubric_id.criteria_desc, 'name': rubric_id.option_id.name, 'criteria_option_point': rubric_id.criteria_option_point, 'criteria_option_desc': rubric_id.criteria_option_desc, 'assess_explanation': rubric_id.assess_explanation, } for rubric_id in staff_response.option_ids], 'user_response_line': [self._get_user_response(user_response_line) for user_response_line in staff_response.response_id.user_response_line] })) return values def _get_slide_values(self, slide): next_slide = slide.channel_id.slide_content_ids[((slide.channel_id.slide_content_ids.ids).index(slide.id))+1] if ((slide.channel_id.slide_content_ids.ids).index(slide.id)) < len(slide.channel_id.slide_content_ids.ids) - 1 else None return { 'id': slide.id, 'is_member': slide.channel_id.is_member, 'is_preview': slide.is_preview, 'peer_assessment': slide.peer_assessment, 'completed': (request.env['slide.slide.partner'].sudo().search([('slide_id', '=', slide.id),('partner_id', '=', request.env.user.partner_id.id)])).completed, 'hasNext' : next_slide if next_slide else None, 'ispro' : 1 if 'is_sequential' in request.env['slide.channel']._fields else None, 'next_slide_url': '/slides/slide/%s?fullscreen=1' % (slug(next_slide)) if next_slide else None, 'user': request.env.user.id, 'rubric_ids': [{ 'criterian_name': rubric.criterian_name, 'name': rubric.name, 'id': rubric.id, 'criterian_ids': [{ 'id': option.id, 'name': option.name, } for option in rubric.criterian_ids], }for rubric in slide.rubric_ids], } def _get_user_response(self, user_response_line): return { 'prompt_id': user_response_line.prompt_id.id, 'value_text_box': user_response_line.value_text_box, 'value_richtext_box': Markup(user_response_line.value_richtext_box), } def _get_total_responses(self, ora_response, slide): submitted_date = False if ora_response.submitted_date: submitted_date = ora_response.submitted_date.strftime('%d %B %Y') return { 'id': ora_response.id, 'user': request.env.user.id, 'state': ora_response.state, 'feedback': Markup(ora_response.feedback), 'staff_id': ora_response.sudo().staff_id.id, 'staff_name': ora_response.sudo().staff_id.name, 'user_name': ora_response.sudo().user_id.name, 'submitted_date': submitted_date, 'can_resubmit': ora_response.can_resubmit, 'feedback_user_image_url': request.website.image_url(ora_response.sudo().staff_id, 'image_1920', size=256), 'ora_res_user_image_url': request.website.image_url(ora_response.sudo().user_id, 'image_1920', size=256), 'user_response_line': [self._get_user_response(user_response_line) for user_response_line in ora_response.user_response_line], 'slide_rubric_staff_line': [{ 'state': staff_line.state, 'assess_type': staff_line.assess_type, 'user_id': staff_line.sudo().user_id.id, 'option_ids': [{ 'id': rubric_id.criteria_id.id, 'criterian_name': rubric_id.criteria_id.criterian_name, 'criteria_desc': rubric_id.criteria_desc, 'name': rubric_id.option_id.name, 'criteria_option_point': rubric_id.criteria_option_point, 'criteria_option_desc': rubric_id.criteria_option_desc, 'assess_explanation': rubric_id.assess_explanation, } for rubric_id in staff_line.option_ids], }for staff_line in ora_response.slide_rubric_staff_line], 'rubric_ids': [{ 'criterian_name': rubric.criterian_name, 'name': rubric.name, 'id': rubric.id, 'criterian_ids': [{ 'id': option.id, 'name': option.name, } for option in rubric.criterian_ids], }for rubric in slide.rubric_ids], } @http.route('/submit/peer/response', type='http', auth="user", website=True) def submit_peer_response(self, **kwargs): slide = request.env['slide.slide'].sudo().browse(int(kwargs.get('slide_id'))) if kwargs.get('response_id'): response_id = request.env['ora.response'].browse(int(kwargs.get('response_id'))) for line in response_id.slide_rubric_staff_line: if line.user_id == request.env.user and line.assess_type == 'peer': values = [] for criteria in response_id.slide_id.rubric_ids: opt_key = '' exp_key = '' for option_id in criteria.criterian_ids: opt_key = 'options_%s_%s' % (response_id.id, criteria.id) exp_key = 'exp_%s_%s' % (response_id.id, criteria.id) if opt_key in kwargs and exp_key in kwargs: break option_id = kwargs.get(opt_key) values.append((0, 0, { 'criteria_id': criteria.id, 'option_id': int(option_id) if option_id else False, 'assess_explanation': kwargs.get(exp_key) })) line.option_ids = values line.state = 'completed' line.submitted_date = datetime.now() return request.redirect('/slides/slide/%s' % slug(slide)) def _get_channel_progress(self, channel, include_quiz=False): result = super(WebsiteSlidesORA, self)._get_channel_progress(channel, include_quiz=include_quiz) slides = request.env['slide.slide'].sudo().search([('channel_id', '=', channel.id)]) ora_response_ids = request.env['ora.response'].sudo().search([ ('slide_id', 'in', slides.ids), ('state', '=', 'assessed'), ('user_id', '=', request.env.user.id) ]) for ora_response in ora_response_ids: result[ora_response.slide_id.id]['quiz_karma_gain'] += ora_response.xp_points result[ora_response.slide_id.id]['quiz_karma_won'] += ora_response.xp_points return result @http.route(['/slides/channel/leave'], type='json', auth='user', website=True) def slide_channel_leave(self, channel_id): slide_ids = request.env['slide.slide'].sudo().search([('channel_id','=',int(channel_id))]) for slide_id in slide_ids: request.env['ora.response'].sudo().search([('user_id','=',int(request.env.uid)),('slide_id','=', int(slide_id))]).unlink() res = super(WebsiteSlidesORA, self).slide_channel_leave(channel_id) return res