[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
This commit is contained in:
@@ -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 import _
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
|
||||
from odoo.addons.website_slides.controllers.main import WebsiteSlides
|
||||
from odoo import _
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
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()
|
||||
|
||||
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
|
||||
|
||||
@@ -1,15 +1,39 @@
|
||||
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"]
|
||||
),
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
"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);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
.o_wslides_fs_certification {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-50%);
|
||||
}
|
||||
@@ -1,16 +1,17 @@
|
||||
<?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' && !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' && !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' && widget.get('slide').completed">
|
||||
<div class="" t-if="widget.get('slide').type === 'certification' && 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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user