From 159ea37a4225931ccac0d7ace9185eff352ed033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Wed, 10 Jan 2024 13:05:47 +0100 Subject: [PATCH] feat: display teamers' average ratings in several locations --- src/Entity/Teamer.php | 17 +++++++++++++++++ src/Repository/ApplicationRepository.php | 3 ++- src/Repository/DispositionRepository.php | 3 ++- src/Repository/TeamerRepository.php | 3 ++- src/Twig/AppRuntime.php | 6 +++++- templates/_partials/_rating_stars.html.twig | 6 ++++++ templates/admin/assignment/detail.html.twig | 1 + templates/admin/teamer/index.html.twig | 21 ++++++++++++--------- templates/admin/teamer/info.html.twig | 3 ++- 9 files changed, 49 insertions(+), 14 deletions(-) create mode 100644 templates/_partials/_rating_stars.html.twig diff --git a/src/Entity/Teamer.php b/src/Entity/Teamer.php index 0aacdbb..bae6c86 100644 --- a/src/Entity/Teamer.php +++ b/src/Entity/Teamer.php @@ -496,6 +496,23 @@ class Teamer implements TimestampableEntityInterface return $this; } + public function getAverageRating(): ?int + { + $feedbackCount = $this->getFeedback()->count(); + + if (0 === $feedbackCount) { + return null; + } + + $sum = 0; + + foreach ($this->getFeedback() as $feedback) { + $sum += $feedback->getAverageRating(); + } + + return $sum / $feedbackCount; + } + /** * @return Collection */ diff --git a/src/Repository/ApplicationRepository.php b/src/Repository/ApplicationRepository.php index 85a498f..fdad510 100644 --- a/src/Repository/ApplicationRepository.php +++ b/src/Repository/ApplicationRepository.php @@ -69,8 +69,9 @@ class ApplicationRepository extends ServiceEntityRepository $qb = $this->createQueryBuilder('application'); return $qb - ->select('application', 'teamer') + ->select('application', 'teamer', 'feedback') ->innerJoin('application.teamer', 'teamer') + ->leftJoin('teamer.feedback', 'feedback') ->where($qb->expr()->andX( $qb->expr()->eq('application.assignment', ':assignment'), $qb->expr()->neq('application.status', ':status') diff --git a/src/Repository/DispositionRepository.php b/src/Repository/DispositionRepository.php index 9d8c6ca..7f0c4fa 100644 --- a/src/Repository/DispositionRepository.php +++ b/src/Repository/DispositionRepository.php @@ -96,8 +96,9 @@ class DispositionRepository extends ServiceEntityRepository $qb = $this->createQueryBuilder('disposition'); return $qb - ->select('disposition', 'teamer') + ->select('disposition', 'teamer', 'feedback') ->innerJoin('disposition.teamer', 'teamer') + ->leftJoin('teamer.feedback', 'feedback') ->where($qb->expr()->eq('disposition.assignment', ':assignment')) ->setParameter('assignment', $assignment) ->getQuery() diff --git a/src/Repository/TeamerRepository.php b/src/Repository/TeamerRepository.php index 7da027a..a2c3f12 100644 --- a/src/Repository/TeamerRepository.php +++ b/src/Repository/TeamerRepository.php @@ -32,10 +32,11 @@ class TeamerRepository extends ServiceEntityRepository $qb = $this->createQueryBuilder('teamer'); $qb - ->select('teamer', 'user') + ->select('teamer', 'user', 'feedback') ->leftJoin('teamer.availabilities', 'availability') ->leftJoin('teamer.jobProfiles', 'job_profile') ->leftJoin('teamer.licenses', 'license') + ->leftJoin('teamer.feedback', 'feedback') ->leftJoin('teamer.user', 'user') ; diff --git a/src/Twig/AppRuntime.php b/src/Twig/AppRuntime.php index 33e0b04..e53b648 100644 --- a/src/Twig/AppRuntime.php +++ b/src/Twig/AppRuntime.php @@ -89,8 +89,12 @@ class AppRuntime implements RuntimeExtensionInterface return $this->intlExtension->formatCurrency($amount, 'EUR'); } - public function formatRating(int $rating): string + public function formatRating(?int $rating): string { + if (null === $rating) { + return '-'; + } + // Ratings are stored as integers so divide by 100 first $rating = $rating / 100; diff --git a/templates/_partials/_rating_stars.html.twig b/templates/_partials/_rating_stars.html.twig new file mode 100644 index 0000000..3e87a7f --- /dev/null +++ b/templates/_partials/_rating_stars.html.twig @@ -0,0 +1,6 @@ +{% set averageRating = teamer.averageRating %} +
+ {% for grade in range(1, 6) %} + {{ icon('star', html_classes('w-3 h-3', { 'text-gray-200': averageRating < grade * 100, 'text-primary': averageRating >= grade * 100 })) }} + {% endfor %} +
\ No newline at end of file diff --git a/templates/admin/assignment/detail.html.twig b/templates/admin/assignment/detail.html.twig index 2b7f915..a586a07 100644 --- a/templates/admin/assignment/detail.html.twig +++ b/templates/admin/assignment/detail.html.twig @@ -134,6 +134,7 @@ {{ disposition.teamer }} {{ icon('info', 'w-4 h-4') }} + {% include '_partials/_rating_stars.html.twig' with { 'teamer': disposition.teamer } %} {{ disposition.remarks|nl2br|default('-') }} diff --git a/templates/admin/teamer/index.html.twig b/templates/admin/teamer/index.html.twig index a745d64..05a28b5 100644 --- a/templates/admin/teamer/index.html.twig +++ b/templates/admin/teamer/index.html.twig @@ -59,15 +59,18 @@ {% for teamer in pagination %} - {% if teamer.photo %} - {{ teamer.firstName }} - {% else %} -
- {{ icon('user', 'w-10 h-10 text-gray-200') }} -
- {% endif %} +
+ {% if teamer.photo %} + {{ teamer.firstName }} + {% else %} +
+ {{ icon('user', 'w-10 h-10 text-gray-200') }} +
+ {% endif %} + {% include '_partials/_rating_stars.html.twig' with { 'teamer': teamer } %} +
diff --git a/templates/admin/teamer/info.html.twig b/templates/admin/teamer/info.html.twig index 1c08e53..ea3fae0 100644 --- a/templates/admin/teamer/info.html.twig +++ b/templates/admin/teamer/info.html.twig @@ -29,7 +29,7 @@ {% endfor %} -
+
{% if teamer.photo %} {% endif %} + {% include '_partials/_rating_stars.html.twig' with { 'teamer': teamer } %}