Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show certificates in reverse chronological order #733

Merged
merged 2 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 49 additions & 7 deletions src/euphorie/client/browser/certificates.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,67 @@
from euphorie.client.model import SurveySession
from euphorie.client.model import Training
from plone import api
from plone.memoize.view import memoize
from Products.Five import BrowserView
from z3c.saconfig import Session


class View(BrowserView):
"""Certificates Overview Page"""

@property
@memoize
def trainings_portlet(self):
return api.content.get_view(
name="portlet-my-trainings", context=self.context, request=self.request
def trainings(self):
"""Get all trainings from all the current user's organisations."""
organisation_view = api.content.get_view(
name="organisation",
context=self.context,
request=self.request,
)
account_ids = [
organisation.owner_id for organisation in organisation_view.organisations
]
return [
training
for training in (
Session.query(Training)
.filter(
Training.session_id == SurveySession.id,
SurveySession.account_id.in_(account_ids),
)
.filter(Training.status == "correct")
.order_by(Training.time.desc())
.all()
)
if training.session.tool
]

def get_certificate(self, training):
traversed_session = training.session.traversed_session
certificate_view = api.content.get_view(
name="training-certificate-inner",
context=traversed_session,
request=self.request,
)
return certificate_view.index(training_id=training.id)

@property
@memoize
def my_certificates(self):
"""Get all certificates that I am allowed to view, grouped by year."""
certificates = {}
for training in self.trainings_portlet.my_certificates:
for training in self.trainings:
year = training.time.year
link = f"{training.session.absolute_url()}/@@training-certificate-view"
content = self.trainings_portlet.get_certificate(training.session)
certificates.setdefault(year, []).append({"link": link, "content": content})
link = (
f"{training.session.absolute_url()}/@@training-certificate-view"
f"?training_id={training.id}"
)
content = self.get_certificate(training)
certificates.setdefault(year, []).append(
{"link": link, "content": content, "date": training.time}
)
for year, year_certificates in certificates.items():
certificates[year] = sorted(
year_certificates, key=lambda c: c["date"], reverse=True
)
return certificates.items()
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<article class="style-7 type- certificate ${python: 'pat-auto-scale' if request.getURL().endswith('/@@training-certificate-view') else ''}"
tal:define="
webhelpers nocall:view/webhelpers;
account webhelpers/get_current_account;
toLocalizedTime nocall: context/@@plone/toLocalizedTime;
certificate view/get_or_create_training;
training_id request/training_id|options/training_id|nothing;
certificate python: view.get_training_by_id(training_id) if training_id else view.get_or_create_training();
"
i18n:domain="euphorie"
>
Expand All @@ -21,7 +21,7 @@
This certificate is presented to
</p>
<p class="certificate-user-name">
${python: account.title}
${python: certificate.account.title}
</p>
<p class="certificate-achievement"
i18n:translate=""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
</div>
<div class="four columns">
<a class="pat-button"
href="${here/absolute_url}/@@training-certificate"
href="${here/absolute_url}/@@training-certificate?training_id=${request/training_id}"
target="new"
i18n:translate=""
>Print certificate</a>
Expand Down
17 changes: 16 additions & 1 deletion src/euphorie/client/browser/training.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from random import shuffle
from sqlalchemy.orm.exc import NoResultFound
from z3c.saconfig import Session
from zExceptions import NotFound
from zExceptions import Unauthorized
from zope.interface import implementer
from zope.publisher.interfaces import IPublishTraverse
Expand Down Expand Up @@ -320,9 +321,23 @@ def get_initial_answers(self):
questions = sample(all_questions, k=num_training_questions)
return {q.getId(): None for q in questions}

def get_training_by_id(self, training_id):
"""Return the training for this session with the given id."""
# check the session id to make sure we are not displaying a training in the
# context of a different session
session_id = self.webhelpers.session_id
try:
return (
Session.query(Training)
.filter(Training.session_id == session_id, Training.id == training_id)
.one()
)
except NoResultFound as exc:
raise NotFound from exc

@memoize
def get_or_create_training(self):
"""Return the training for this session."""
"""Return the current user's training for this session."""
account_id = self.webhelpers.get_current_account().id
session_id = self.webhelpers.session_id
try:
Expand Down
Loading