1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import werkzeug
import werkzeug.utils
import werkzeug.exceptions
from odoo import _
from odoo import http
from odoo.exceptions import AccessError
from odoo.http import request
from odoo.osv import expression
from odoo.addons.website_slides.controllers.main import WebsiteSlides
class WebsiteSlidesSurvey(WebsiteSlides):
@http.route(['/slides_survey/slide/get_certification_url'], type='http', auth='user', website=True)
def slide_get_certification_url(self, slide_id, **kw):
fetch_res = self._fetch_slide(slide_id)
if fetch_res.get('error'):
raise werkzeug.exceptions.NotFound()
slide = fetch_res['slide']
if slide.channel_id.is_member:
slide.action_set_viewed()
certification_url = slide._generate_certification_url().get(slide.id)
if not certification_url:
raise werkzeug.exceptions.NotFound()
return request.redirect(certification_url)
@http.route(['/slides_survey/certification/search_read'], type='json', auth='user', methods=['POST'], website=True)
def slides_certification_search_read(self, fields):
can_create = request.env['survey.survey'].has_access('create')
return {
'read_results': request.env['survey.survey'].search_read([('certification', '=', True)], fields),
'can_create': can_create,
}
# ------------------------------------------------------------
# Overrides
# ------------------------------------------------------------
@http.route()
def create_slide(self, *args, **post):
create_new_survey = post['slide_category'] == "certification" and post.get('survey') and not post['survey']['id']
linked_survey_id = int(post.get('survey', {}).get('id') or 0)
if create_new_survey:
# If user cannot create a new survey, no need to create the slide either.
if not request.env['survey.survey'].has_access('create'):
return {'error': _('You are not allowed to create a survey.')}
# Create survey first as certification slide needs a survey_id (constraint)
post['survey_id'] = request.env['survey.survey'].create({
'title': post['survey']['title'],
'questions_layout': 'page_per_question',
'is_attempts_limited': True,
'attempts_limit': 1,
'is_time_limited': False,
'scoring_type': 'scoring_without_answers',
'certification': True,
'scoring_success_min': 70.0,
'certification_mail_template_id': request.env.ref('survey.mail_template_certification').id,
}).id
elif linked_survey_id:
try:
request.env['survey.survey'].browse([linked_survey_id]).read(['title'])
except AccessError:
return {'error': _('You are not allowed to link a certification.')}
post['survey_id'] = post['survey']['id']
# Then create the slide
result = super(WebsiteSlidesSurvey, self).create_slide(*args, **post)
if post['slide_category'] == "certification":
# Set the url to redirect the user to the survey
slide = request.env['slide.slide'].browse(result['slide_id'])
result['url'] = f'/slides/slide/{request.env["ir.http"]._slug(slide)}?fullscreen=1'
return result
# Utils
# ---------------------------------------------------
def _slide_mark_completed(self, slide):
if slide.slide_category == 'certification':
raise werkzeug.exceptions.Forbidden(_("Certification slides are completed when the survey is succeeded."))
return super(WebsiteSlidesSurvey, self)._slide_mark_completed(slide)
def _get_valid_slide_post_values(self):
result = super(WebsiteSlidesSurvey, self)._get_valid_slide_post_values()
result.append('survey_id')
return result
# Profile
# ---------------------------------------------------
def _prepare_user_slides_profile(self, user):
values = super(WebsiteSlidesSurvey, self)._prepare_user_slides_profile(user)
values.update({
'certificates': self._get_users_certificates(user)[user.id]
})
return values
# All Users Page
# ---------------------------------------------------
def _prepare_all_users_values(self, users):
result = super(WebsiteSlidesSurvey, self)._prepare_all_users_values(users)
certificates_per_user = self._get_users_certificates(users)
for index, user in enumerate(users):
result[index].update({
'certification_count': len(certificates_per_user.get(user.id, []))
})
return result
def _get_users_certificates(self, users):
partner_ids = [user.partner_id.id for user in users]
domain = [
('slide_partner_id.partner_id', 'in', partner_ids),
('scoring_success', '=', True),
('slide_partner_id.survey_scoring_success', '=', True)
]
certificates = request.env['survey.user_input'].sudo().search(domain)
users_certificates = {
user.id: [
certificate for certificate in certificates if certificate.partner_id == user.partner_id
] for user in users
}
return users_certificates
# Badges & Ranks Page
# ---------------------------------------------------
def _prepare_ranks_badges_values(self, **kwargs):
""" Extract certification badges, to render them in ranks/badges page in another section.
Order them by number of granted users desc and show only badges linked to opened certifications."""
values = super(WebsiteSlidesSurvey, self)._prepare_ranks_badges_values(**kwargs)
# 1. Getting all certification badges, sorted by granted user desc
domain = expression.AND([[('survey_id', '!=', False)], self._prepare_badges_domain(**kwargs)])
certification_badges = request.env['gamification.badge'].sudo().search(domain)
# keep only the badge with challenge category = slides (the rest will be displayed under 'normal badges' section
certification_badges = certification_badges.filtered(
lambda b: 'slides' in b.challenge_ids.mapped('challenge_category'))
if not certification_badges:
return values
# 2. sort by granted users (done here, and not in search directly, because non stored field)
certification_badges = certification_badges.sorted("granted_users_count", reverse=True)
# 3. Remove certification badge from badges
badges = values['badges'] - certification_badges
# 4. Getting all course url for each badge
certification_slides = request.env['slide.slide'].sudo().search([('survey_id', 'in', certification_badges.mapped('survey_id').ids)])
certification_badge_urls = {slide.survey_id.certification_badge_id.id: slide.channel_id.website_url for slide in certification_slides}
# 5. Applying changes
values.update({
'badges': badges,
'certification_badges': certification_badges,
'certification_badge_urls': certification_badge_urls
})
return values
|