[IMP] website_slides_survey: add certification badges section to ranks badge page

This commit adds a section to distinguish the certification badges from the
other badges users may obtain in eLearning. Certification badges are available
on the ranks page, linked to a running survey. Clicking on them directly
redirects into the linked course.

Task ID : 1961053
PR #32594
This commit is contained in:
David Beguin
2019-11-22 15:30:53 +00:00
committed by Thibault Delavallée
parent 1f52435966
commit 5ac64d6e02
6 changed files with 110 additions and 28 deletions
+1 -1
View File
@@ -91,7 +91,7 @@
<field name="challenge_ids" mode="kanban" widget="many2many" nolabel="1" context="{'default_reward_id': active_id}" />
<field name="level"/>
</group>
<group string="Statistics">
<group id="badge_statistics" string="Statistics">
<group>
<field name="granted_count"/>
<field name="stat_this_month"/>
+7 -3
View File
@@ -171,8 +171,7 @@ class WebsiteProfile(http.Controller):
domain = expression.AND([[('challenge_ids.challenge_category', '=', kwargs.get('badge_category'))], domain])
return domain
@http.route('/profile/ranks_badges', type='http', auth="public", website=True, sitemap=True)
def view_ranks_badges(self, **kwargs):
def _prepare_ranks_badges_values(self, **kwargs):
ranks = []
if 'badge_category' not in kwargs:
Rank = request.env['gamification.karma.rank']
@@ -180,7 +179,7 @@ class WebsiteProfile(http.Controller):
Badge = request.env['gamification.badge']
badges = Badge.sudo().search(self._prepare_badges_domain(**kwargs))
badges = sorted(badges, key=lambda b: b.granted_users_count, reverse=True)
badges = badges.sorted("granted_users_count", reverse=True)
values = self._prepare_user_values(searches={'badges': True})
values.update({
@@ -188,6 +187,11 @@ class WebsiteProfile(http.Controller):
'badges': badges,
'user': request.env.user,
})
return values
@http.route('/profile/ranks_badges', type='http', auth="public", website=True, sitemap=True)
def view_ranks_badges(self, **kwargs):
values = self._prepare_ranks_badges_values(**kwargs)
return request.render("website_profile.rank_badge_main", values)
# All Users Page
@@ -228,6 +228,10 @@ $owprofile-color-bg: mix($body-bg, #efeff4);
}
}
.wprofile_badge_img {
height: 2.5em;
}
// Other stuffs
.country_flag {
@@ -423,33 +423,40 @@
</template>
<template id="badge_content" name="Badges Page content">
<div class="row">
<div class="col-12">
<h1 class="mt-4 mt-lg-2">Badges</h1>
<p class="lead">
Besides gaining reputation with your questions and answers,
you receive badges for being especially helpful.<br class="d-none d-lg-inline-block"/>Badges
appear on your profile page, and your posts.
</p>
<div id="website_profile_badges">
<div class="row">
<div class="col-12">
<h1 class="mt-4 mt-lg-2">Badges</h1>
<p class="lead">
Besides gaining reputation with your questions and answers,
you receive badges for being especially helpful.<br class="d-none d-lg-inline-block"/>Badges
appear on your profile page, and your posts.
</p>
</div>
</div>
</div>
<table class="table table-sm mb64">
<tr t-foreach="badges" t-as="badge">
<td class="align-middle">
<img t-if="not badge.image_1920 and badge.level" t-attf-src="/website_profile/static/src/img/badge_#{badge.level}.svg"
class="my-1" style="height:2.5em" t-att-alt="badge.name"/>
<img t-else="" t-att-src="website.image_url(badge, 'image_1024')" class="my-1" style="height:2.5em" t-att-alt="badge.name"/>
<h6 t-field="badge.name" class="d-inline my-0"/>
</td>
<td class="align-middle d-none d-md-table-cell">
<div class="row col-12 align-items-center p-0" t-foreach="badges" t-as="badge">
<div class="col-3 d-flex align-items-center">
<t t-call="website_profile.badge_header"/>
</div>
<div class="col-6">
<span t-field="badge.description"/>
</div>
<div class="col-3 text-right">
<b t-esc="badge.granted_users_count"/>
<i class="text-muted"> awarded users</i>
</td>
<td class="align-middle">
<span t-field="badge.description"/>
</td>
</tr>
</table>
</div>
</div>
</div>
</template>
<template id="badge_header">
<img t-if="not badge.image_1920 and badge.level" t-attf-src="/website_profile/static/src/img/badge_#{badge.level}.svg"
class="my-1 mr-1 wprofile_badge_img" t-att-alt="badge.name"/>
<img t-else="" t-att-src="website.image_url(badge, 'image_1024')" class="my-1 mr-1 wprofile_badge_img" t-att-alt="badge.name"/>
<a t-if="badge_url" t-att-href="badge_url">
<h6 t-field="badge.name" class="d-inline my-0"/>
</a>
<h6 t-else="" t-field="badge.name" class="d-inline my-0"/>
</template>
<!--Private profile-->
@@ -8,6 +8,7 @@ import werkzeug.exceptions
from odoo import _
from odoo import http
from odoo.http import request
from odoo.osv import expression
from odoo.addons.website_slides.controllers.main import WebsiteSlides
from collections import defaultdict
@@ -74,3 +75,39 @@ class WebsiteSlides(WebsiteSlides):
] 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(WebsiteSlides, 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 and keep only certification badge linked to opened survey
badges = values['badges'] - certification_badges
certification_badges = certification_badges.filtered(lambda b: b.survey_id.state == 'open')
# 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
@@ -62,4 +62,34 @@
</td>
</xpath>
</template>
<template id="badge_content" inherit_id="website_profile.badge_content">
<xpath expr="//div[@id='website_profile_badges']" position="after">
<t t-if="certification_badges">
<div class="row">
<div class="col-12">
<h1 class="mt-4 mt-lg-2">Certification Badges</h1>
<p class="lead">
You can gain badges by passing certifications. Here is a list of all available certification badges.
<br />Follow the links to reach new heights and skill up!
</p>
<div class="row col-12 align-items-center p-0" t-foreach="certification_badges" t-as="badge">
<div class="col-3">
<t t-call="website_profile.badge_header">
<t t-if="badge.id in certification_badge_urls" t-set="badge_url" t-value="certification_badge_urls[badge.id]"/>
</t>
</div>
<div class="col-6">
<span t-field="badge.description"/>
</div>
<div class="col-3 text-right">
<b t-esc="badge.granted_users_count"/>
<i class="text-muted"> awarded users</i>
</div>
</div>
</div>
</div>
</t>
</xpath>
</template>
</data></odoo>