Files
odoo_source/addons/website_slides_survey/controllers/slides.py
T
Leloup Loïc (lole) 65ae78b95d [FIX] website_slides_survey : fix certification badges display
Before this commit, when going to /profile/ranks_badges on the website,
an error 500 happened when it had to show certification badges.
This is because the certification badges use the "state" field of their linked
survey to check if it is still open.
This field has been removed in 15.0, where the active state of the survey is
used to know if it is still used instead of a state.  When archiving a
certification survey, their linked badge is automatically archived as well,
so there is no need for that line anymore.

opw-3373973

closes odoo/odoo#126834

X-original-commit: 6d99542da6bf7881043bdc204c409d64cf7672c1
Signed-off-by: Warnon Aurélien (awa) <awa@odoo.com>
2023-06-30 01:32:52 +02:00

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