Skip to content
Snippets Groups Projects
Commit e8e8d7a9 authored by qmo-odoo's avatar qmo-odoo Committed by jem-odoo
Browse files

[FIX] website_slides_survey: certification slide url

Before this commit, in fullscreen mode, clicking on the "pass certification"
button would redirect the user to the "non-fullscreen" view.
After this commit, the button directly redirects the user to the survey page.

To avoid generating user_input of survey (test entry or not) for
certification slides in fullscreen mode (table of content), we decided
to create those user_input lazily: we redirect the user to a route that
create (or reuse) the correct user_input.

Task-1946511
parent 44ae98d3
Branches
Tags
No related merge requests found
......@@ -492,7 +492,7 @@ class WebsiteSlides(WebsiteProfile):
# sidebar: update with user channel progress
values['channel_progress'] = self._get_channel_progress(slide.channel_id, include_quiz=True)
if 'fullscreen' in kwargs:
if kwargs.get('fullscreen') == '1':
return request.render("website_slides.slide_fullscreen", values)
else:
values['slide_access'] = slide.sudo(request.env.user)._get_slide_action_access()[slide.id]
......
......@@ -2,54 +2,30 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import werkzeug
import werkzeug.utils
import werkzeug.exceptions
from odoo.addons.website_slides.controllers.main import WebsiteSlides
from odoo import _
from odoo import http
from odoo.http import request
from odoo.addons.website_slides.controllers.main import WebsiteSlides
class WebsiteSlides(WebsiteSlides):
def _get_valid_slide_post_values(self):
result = super(WebsiteSlides, self)._get_valid_slide_post_values()
result.append('survey_id')
return result
def _get_slide_detail(self, slide):
""" If the slide is a certification, we pass to the template additional information:
- The certification url, built with the latest attempt (survey.user_input) token
- A 'quizz_passed' boolean to know if we have to show the 'download certification' button
- The 'survey_id' to be able to download the certification
If the user is not a member of the channel, we give the opportunity to test the certification.
The user still has to have the necessary rights, please check survey.survey._check_answer_creation
for more info.
This is used in the context of a website_publisher designing a course."""
result = super(WebsiteSlides, self)._get_slide_detail(slide)
if not request.env.user._is_public() and slide.slide_type == 'certification' and slide.survey_id:
result['certification_test_entry'] = not slide.channel_id.is_member
result['certification_done'] = False
if slide.channel_id.is_member:
user_membership_id_sudo = slide.user_membership_id.sudo()
quizz_passed = user_membership_id_sudo.survey_quizz_passed
result['certification_done'] = quizz_passed
result['survey_id'] = slide.survey_id.id
if not quizz_passed:
last_user_input = next(user_input for user_input in user_membership_id_sudo.user_input_ids.sorted(
lambda user_input: user_input.create_date, reverse=True
))
result['certification_url'] = last_user_input._get_survey_url()
else:
user_input = slide.survey_id._create_answer(
partner=request.env.user.partner_id,
check_attempts=False,
test_entry=True, **{
'slide_id': slide.id
}
)
result['certification_url'] = user_input._get_survey_url()
class WebsiteSlides(WebsiteSlides):
return result
@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 werkzeug.utils.redirect(certification_url)
# Utils
# ---------------------------------------------------
......@@ -58,6 +34,11 @@ class WebsiteSlides(WebsiteSlides):
raise werkzeug.exceptions.Forbidden(_("Certification slides are completed when the survey is succeeded."))
return super(WebsiteSlides, self)._set_completed_slide(slide, quiz_attempts_inc=quiz_attempts_inc)
def _get_valid_slide_post_values(self):
result = super(WebsiteSlides, self)._get_valid_slide_post_values()
result.append('survey_id')
return result
# Profile
# ---------------------------------------------------
def _prepare_user_slides_profile(self, user):
......
......@@ -45,23 +45,41 @@ class Slide(models.Model):
('check_certification_preview', "CHECK(slide_type != 'certification' OR is_preview = False)", "A slide of type certification cannot be previewed."),
]
def _action_set_viewed(self, target_partner, quiz_attempts_inc=False):
""" If the slide viewed is a certification, we initialize the first survey.user_input
for the current partner. """
new_slide_partners = super(Slide, self)._action_set_viewed(target_partner, quiz_attempts_inc=quiz_attempts_inc)
certification_slides = self.search([
('id', 'in', new_slide_partners.mapped('slide_id').ids),
('slide_type', '=', 'certification'),
('survey_id', '!=', False)
])
for new_slide_partner in new_slide_partners:
if new_slide_partner.slide_id in certification_slides and not new_slide_partner.user_input_ids:
new_slide_partner.slide_id.survey_id._create_answer(
partner=target_partner,
@api.multi
def _generate_certification_url(self):
""" get a map of certification url for certification slide from `self`. The url will come from the survey user input:
1/ existing and not done user_input for member of the course
2/ create a new user_input for member
3/ for no member, a test user_input is created and the url is returned
Note: the slide.slides.partner should already exist
"""
certification_urls = {}
for slide in self.filtered(lambda slide: slide.slide_type == 'certification' and slide.survey_id):
if slide.channel_id.is_member:
user_membership_id_sudo = slide.user_membership_id.sudo()
quizz_passed = user_membership_id_sudo.survey_quizz_passed
if not quizz_passed and user_membership_id_sudo.user_input_ids:
last_user_input = next(user_input for user_input in user_membership_id_sudo.user_input_ids.sorted(
lambda user_input: user_input.create_date, reverse=True
))
certification_urls[slide.id] = last_user_input._get_survey_url()
elif not user_membership_id_sudo.user_input_ids:
user_input = slide.survey_id.sudo()._create_answer(
partner=self.env.user.partner_id,
check_attempts=False,
**{
'slide_id': slide.id,
'slide_partner_id': user_membership_id_sudo.id
}
)
certification_urls[slide.id] = user_input._get_survey_url()
else:
user_input = slide.survey_id.sudo()._create_answer(
partner=self.env.user.partner_id,
check_attempts=False,
**{
'slide_id': new_slide_partner.slide_id.id,
'slide_partner_id': new_slide_partner.id
test_entry=True, **{
'slide_id': slide.id
}
)
certification_urls[slide.id] = user_input._get_survey_url()
return certification_urls
odoo.define('website_slides_survey.fullscreen', function (require) {
"use strict";
var core = require('web.core');
var _t = core._t;
var Fullscreen = require('website_slides.fullscreen');
Fullscreen.include({
xmlDependencies: (Fullscreen.prototype.xmlDependencies || []).concat(
["/website_slides_survey/static/src/xml/website_slides_fullscreen.xml"]
),
});
});
\ No newline at end of file
"use strict";
var core = require('web.core');
var QWeb = core.qweb;
var Fullscreen = require('website_slides.fullscreen');
Fullscreen.include({
xmlDependencies: (Fullscreen.prototype.xmlDependencies || []).concat(
["/website_slides_survey/static/src/xml/website_slides_fullscreen.xml"]
),
_preprocessSlideData: function (slidesDataList){
slidesDataList = this._super.apply(this, arguments);
slidesDataList.forEach(function (slideData, index){
if (slideData.type === "certification"){
slideData.certificationUrl = '/slides_survey/slide/get_certification_url?slide_id=' + slideData.id;
}
});
return slidesDataList;
},
/**
* Extend the _renderSlide method so that slides of type "certification"
* are also taken into account and rendered correctly
*
* @private
* @override
*/
_renderSlide: function (){
var def = this._super.apply(this, arguments);
var $content = this.$('.o_wslides_fs_content');
if (this.get('slide').type === "certification"){
$content.html(QWeb.render('website.slides.fullscreen.certification',{widget: this}));
}
return $.when(def);
},
});
});
.o_wslides_fs_certification {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<templates>
<t t-extend="website.slides.fullscreen">
<t t-jquery="t:last" t-operation="after">
<div t-if="widget.get('slide').type === 'certification' &amp;&amp; !widget.get('slide').certificationDone" class="o_wslides_fs_certification">
<t t-name="website.slides.fullscreen.certification">
<div class="justify-content-center align-self-center">
<div t-if="widget.get('slide').type === 'certification' &amp;&amp; !widget.get('slide').completed" class="">
<a class="btn btn-primary" t-att-href="'/slides/slide/' + widget.get('slide').id" target="new"><i class="fa fa-trophy"/> Pass Certification</a>
</div>
<div class="o_wslides_fs_certification" t-if="widget.get('slide').type == 'certification' &amp;&amp; widget.get('slide').completed">
<div class="" t-if="widget.get('slide').type === 'certification' &amp;&amp; widget.get('slide').completed">
<a role="button" class="btn btn-primary" t-att-href="'/survey/' + widget.get('slide').certificationId + '/get_certification'">
<i class="fa fa-fw fa-trophy" role="img" aria-label="Download certification" title="Download certification"/> Download certification
</a>
</div>
</t>
</div>
</t>
<t t-extend="website.slides.fullscreen.title">
......
......@@ -2,9 +2,6 @@
<odoo>
<data>
<template id="assets_frontend" inherit_id="website.assets_frontend" name="Slides Certification">
<xpath expr="//link[last()]" position="after">
<link rel="stylesheet" type="text/scss" href="/website_slides_survey/static/src/scss/website_slides.scss" t-ignore="true"/>
</xpath>
<xpath expr="//script[last()]" position="after">
<script type="text/javascript" src="/website_slides_survey/static/src/js/slides_upload.js"/>
<link rel="stylesheet" type="text/scss" href="/website_slides_survey/static/src/scss/website_profile.scss"/>
......
......@@ -3,22 +3,18 @@
<data>
<template id="slide_content_detailed" inherit_id="website_slides.slide_content_detailed">
<xpath expr="//div[hasclass('o_wslides_lesson_content_type')]" position="inside">
<t t-if="not certification_test_entry" t-set="begin_certification_label" t-value="'Begin certification'" />
<t t-if="certification_test_entry" t-set="begin_certification_label" t-value="'Test certification'" />
<div t-if="slide.slide_type == 'certification' and not certification_done" class="col mt32 mb8 d-flex justify-content-center">
<div t-if="slide.slide_type == 'certification' and not channel_progress[slide.id].get('completed')" class="col mt32 mb8 d-flex justify-content-center">
<a role="button"
class="btn btn-primary btn-lg"
t-att-href="certification_url">
<i class="fa fa-fw fa-graduation-cap" role="img" t-att-aria-label="begin_certification_label" t-att-title="begin_certification_label"/>
<t t-esc="begin_certification_label" />
t-att-href="'/slides_survey/slide/get_certification_url?slide_id=%s' %(slide.id)">
<i class="fa fa-fw fa-graduation-cap" role="img"/>
<t t-if="slide.channel_id.is_member">Begin Certification</t>
<t t-else="">Test Certification</t>
</a>
</div>
<div t-if="slide.slide_type == 'certification' and certification_done" class="col mt32 mb8 d-flex justify-content-center">
<a role="button"
class="btn btn-primary btn-lg"
t-att-href="'/survey/%s/get_certification' % survey_id">
<i class="fa fa-fw fa-trophy" role="img" aria-label="Download certification" title="Download certification"/>
Download certification
<div t-if="slide.slide_type == 'certification' and channel_progress[slide.id].get('completed')" class="col mt32 mb8 d-flex justify-content-center">
<a role="button" class="btn btn-primary btn-lg" t-att-href="'/survey/%s/get_certification' % slide.survey_id.id">
<i class="fa fa-fw fa-trophy" role="img" aria-label="Download certification" title="Download certification"/> Download certification
</a>
</div>
</xpath>
......
......@@ -2,9 +2,9 @@
<odoo><data>
<template id="slide_fullscreen_sidebar_category" inherit_id="website_slides.slide_fullscreen_sidebar_category">
<xpath expr="//li[hasclass('o_wslides_fs_sidebar_list_item')]" position="attributes">
<attribute name="t-att-data-certification-done">channel_progress[slide.id].get('survey_quizz_passed')</attribute>
<attribute name="t-att-data-certification-id">slide.survey_id.id</attribute>
<xpath expr="//li[@t-att-data-id='slide.id']" position="attributes">
<attribute name="t-att-data-certification-id">slide.survey_id.id</attribute>
<attribute name="t-att-data-is-member">slide.channel_id.is_member</attribute>
</xpath>
</template>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment