165 lines
7.3 KiB
Python
165 lines
7.3 KiB
Python
|
# -*- 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.addons.http_routing.models.ir_http import slug
|
||
|
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'].check_access_rights('create', raise_exception=False)
|
||
|
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'].check_access_rights('create', raise_exception=False):
|
||
|
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
|
||
|
result['url'] = '/slides/slide/%s?fullscreen=1' % (slug(request.env['slide.slide'].browse(result['slide_id']))),
|
||
|
|
||
|
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
|