Skip to content

Commit

Permalink
presence management
Browse files Browse the repository at this point in the history
  • Loading branch information
WolfyWin committed Oct 14, 2024
1 parent 62ee780 commit 1281002
Show file tree
Hide file tree
Showing 12 changed files with 162 additions and 46 deletions.
36 changes: 22 additions & 14 deletions src/plugin/cursus/Controller/EventPresenceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,34 +91,39 @@ public function signStatusAction(Request $request): JsonResponse
return new JsonResponse(['success' => false]);
}

$presenceData = $this->serializer->serialize($presence);
$presenceData['status'] = EventPresence::PRESENT;
$presenceData['signature'] = $signature;
$presence->setStatus(EventPresence::PRESENT);
$presence->setSignature($signature);
$presence->setPresenceUpdatedBy($this->tokenStorage->getToken()->getUser());
$presence->setPresenceUpdatedAt(new \DateTime());

$this->crud->update($presence, $presenceData);
$this->om->persist($presence);
$this->om->flush();

return new JsonResponse(['success' => true]);
}

/**
* Confirm the status of a EventPresence for current user.
* Confirm the status of a EventPresence for current event.
*
* @Route("/confirm/{id}", name="apiv2_cursus_event_presence_confirm", methods={"PUT"})
*
* @Route("/confirm", name="apiv2_cursus_event_presence_confirm", methods={"PUT"})
* @EXT\ParamConverter("event", class="Claroline\CursusBundle\Entity\Event", options={"mapping": {"id": "uuid"}})
*/
public function confirmStatusAction(Request $request): JsonResponse
public function confirmStatusAction(Event $event): JsonResponse
{
$data = $this->decodeRequest($request);
if (empty($data)) {
throw new InvalidDataException('Invalid data');
}
$this->checkPermission('ADMINISTRATE', $event, [], true);

$presences = $this->om->getRepository(EventPresence::class)->findBy(['event' => $event]);
$presencesToValidate = array_filter($presences, function (EventPresence $presence) {
return EventPresence::UNKNOWN !== $presence->getStatus();
});

$presences = $this->om->getRepository(EventPresence::class)->findBy(['uuid' => $data]);
$this->om->startFlushSuite();
foreach ($presences as $presence) {
$this->checkPermission('ADMINISTRATE', $presence, [], true);

foreach ($presencesToValidate as $presence) {
$this->manager->setValidationDate([$presence], new \DateTime());
}

$this->om->endFlushSuite();

return new JsonResponse();
Expand Down Expand Up @@ -211,6 +216,9 @@ public function updateStatusAction(string $status, Request $request): JsonRespon
$this->checkPermission('EDIT', $presence, [], true);

$this->manager->setStatus([$presence], $status);

$presence->setPresenceUpdatedBy($this->tokenStorage->getToken()->getUser());
$presence->setPresenceUpdatedAt(new \DateTime());
}

$this->om->endFlushSuite();
Expand Down
33 changes: 33 additions & 0 deletions src/plugin/cursus/Entity/EventPresence.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,17 @@ class EventPresence
*/
private ?array $evidences = null;

/**
* @ORM\ManyToOne(targetEntity="Claroline\CoreBundle\Entity\User")
* @ORM\JoinColumn(name="presence_updated_by", referencedColumnName="id", nullable=true)
*/
private ?User $presenceUpdatedBy = null;

/**
* @ORM\Column(name="presence_updated_at", type="datetime", nullable=true)
*/
private ?\DateTimeInterface $presenceUpdatedAt = null;

public function __construct()
{
$this->refreshUuid();
Expand Down Expand Up @@ -126,4 +137,26 @@ public function setEvidences(?array $evidences): void
{
$this->evidences = $evidences;
}

public function getPresenceUpdatedBy(): ?User
{
return $this->presenceUpdatedBy;
}

public function setPresenceUpdatedBy(?User $user): self
{
$this->presenceUpdatedBy = $user;
return $this;
}

public function getPresenceUpdatedAt(): ?\DateTimeInterface
{
return $this->presenceUpdatedAt;
}

public function setPresenceUpdatedAt(?\DateTimeInterface $date): self
{
$this->presenceUpdatedAt = $date;
return $this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Claroline\CursusBundle\Installation\Migrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated migration based on mapping information: modify it with caution.
*
* Generation date: 2024/10/14 08:40:17
*/
final class Version20241014084016 extends AbstractMigration
{
public function up(Schema $schema): void
{
$this->addSql('
ALTER TABLE claro_cursusbundle_presence_status
ADD presence_updated_by INT DEFAULT NULL,
ADD presence_updated_at DATETIME DEFAULT NULL
');
$this->addSql('
ALTER TABLE claro_cursusbundle_presence_status
ADD CONSTRAINT FK_DFE5E1FE349A94C7 FOREIGN KEY (presence_updated_by)
REFERENCES claro_user (id)
');
$this->addSql('
CREATE INDEX IDX_DFE5E1FE349A94C7 ON claro_cursusbundle_presence_status (presence_updated_by)
');
}

public function down(Schema $schema): void
{
$this->addSql('
ALTER TABLE claro_cursusbundle_presence_status
DROP FOREIGN KEY FK_DFE5E1FE349A94C7
');
$this->addSql('
DROP INDEX IDX_DFE5E1FE349A94C7 ON claro_cursusbundle_presence_status
');
$this->addSql('
ALTER TABLE claro_cursusbundle_presence_status
DROP presence_updated_by,
DROP presence_updated_at
');
}
}
2 changes: 1 addition & 1 deletion src/plugin/cursus/Manager/EventPresenceManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public function setStatus(array $presences, string $status): array
return $presences;
}

public function setValidationDate(array $presences, \DateTimeInterface $date): array
public function setValidationDate(array $presences, ?\DateTimeInterface $date): array
{
foreach ($presences as $presence) {
$presence->setValidationDate($date);
Expand Down

This file was deleted.

13 changes: 13 additions & 0 deletions src/plugin/cursus/Resources/modules/event/components/list.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,19 @@ const Events = (props) =>
displayed: hasPermission('edit', rows[0]),
group: trans('presences', {}, 'cursus'),
target: ['apiv2_cursus_event_presence_download', {id: rows[0].id, filled: 1}]
}, {
name: 'confirm-status',
type: ASYNC_BUTTON,
icon: 'fa fa-fw fa-clipboard-check',
label: trans('presence_validation', {}, 'presence'),
displayed: hasPermission('edit', rows[0]),
group: trans('validation', {}, 'presence'),
request: {
url: ['apiv2_cursus_event_presence_confirm', {id: rows[0].id}],
request: {
method: 'PUT'
}
}
}
].concat(props.customActions(rows))}
delete={{
Expand Down
15 changes: 14 additions & 1 deletion src/plugin/cursus/Resources/modules/event/components/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import isEmpty from 'lodash/isEmpty'

import {trans} from '#/main/app/intl/translation'
import {hasPermission} from '#/main/app/security'
import {MODAL_BUTTON, URL_BUTTON} from '#/main/app/buttons'
import {MODAL_BUTTON, URL_BUTTON, ASYNC_BUTTON} from '#/main/app/buttons'
import {ContentLoader} from '#/main/app/content/components/loader'
import {ToolPage} from '#/main/core/tool'

Expand Down Expand Up @@ -82,6 +82,19 @@ const EventPage = (props) => {
displayed: hasPermission('edit', props.event),
group: trans('presences', {}, 'cursus'),
target: ['apiv2_cursus_event_presence_download', {id: props.event.id, filled: 1}]
}, {
name: 'confirm-status',
type: ASYNC_BUTTON,
icon: 'fa fa-fw fa-clipboard-check',
label: trans('presence_validation', {}, 'presence'),
displayed: hasPermission('edit', props.event),
group: trans('validation', {}, 'presence'),
request: {
url: ['apiv2_cursus_event_presence_confirm', {id: props.event.id}],
request: {
method: 'PUT'
}
}
}
]}

Expand Down
1 change: 0 additions & 1 deletion src/plugin/cursus/Resources/modules/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ registry.add('ClarolineCursusBundle', {
'mark-absent-unjustified': () => { return import(/* webpackChunkName: "training-action-presence-absent-unjustified" */ '#/plugin/cursus/actions/presence/mark-absent-unjustified') },
'mark-absent-present' : () => { return import(/* webpackChunkName: "training-action-presence-present" */ '#/plugin/cursus/actions/presence/mark-present') },
'mark-unknown' : () => { return import(/* webpackChunkName: "training-action-presence-unknown" */ '#/plugin/cursus/actions/presence/mark-unknown') },
'confirm-presence' : () => { return import(/* webpackChunkName: "training-action-presence-confirm" */ '#/plugin/cursus/actions/presence/confirm-presence') },
'add-evidence' : () => { return import(/* webpackChunkName: "training-action-presence-add-evidence" */ '#/plugin/cursus/actions/presence/add-evidence') }
}
},
Expand Down
13 changes: 13 additions & 0 deletions src/plugin/cursus/Resources/modules/presence/components/list.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@ const Presences = props => {
),
displayed: true
}, {
name: 'presence_updated_by',
type: 'user',
label: trans('presence_updated_by', {}, 'presence'),
displayed: true
}, {
name: 'presence_updated_at',
type: 'date',
label: trans('presence_updated_at', {}, 'presence'),
displayed: true,
options: {
time: true
}
},{
name: 'validation_date',
type: 'date',
label: trans('presence_confirmation_date', {}, 'presence'),
Expand Down
6 changes: 4 additions & 2 deletions src/plugin/cursus/Resources/translations/presence.en.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
"presence_confirm_title": "Presence confirmation",
"presence_confirm_desc": "Your %event_title% event signature has been successfully recorded.",
"presence_confirm_other": "Confirm another presence",
"presence_confirmation_date": "Confirmation date",
"presence_confirmation_date": "Validation date",
"presence_validation_date": "Validation date by tutor",
"presence_info": "Me, %user%, was present at the event %event_title% from %event_date_start% to %event_date_end%.",
"presence_validation": "Validate presence",
"presence_validation": "Validate status",
"presence_updated_by": "Status updated by",
"presence_updated_at": "Update date",

"validate": "Validate",
"validation": "Validation"
Expand Down
6 changes: 4 additions & 2 deletions src/plugin/cursus/Resources/translations/presence.fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
"presence_confirm_title": "Confirmation de présence",
"presence_confirm_desc": "Votre présence à la séance %event_title% a bien été enregistrée.",
"presence_confirm_other": "Confirmer une autre présence",
"presence_confirmation_date": "Date de confirmation",
"presence_confirmation_date": "Date de validation",
"presence_validation_date": "Date de validation par le formateur",
"presence_info": "Moi, %user%, étais présent à la séance %event_title% du %event_datetime_start% au %event_datetime_end%.",
"presence_validation": "Confirmer la présence",
"presence_validation": "Valider les statuts",
"presence_updated_by": "Statut mis à jour par",
"presence_updated_at": "Date de mise à jour",

"validate": "Valider",
"validation": "Validation"
Expand Down
11 changes: 11 additions & 0 deletions src/plugin/cursus/Serializer/EventPresenceSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ public function serialize(EventPresence $eventPresence, array $options = []): ar
'signature' => $eventPresence->getSignature(),
'validation_date' => DateNormalizer::normalize($eventPresence->getValidationDate()),
'evidences' => $eventPresence->getEvidences(),
'presence_updated_by' => $eventPresence->getPresenceUpdatedBy() ? $this->userSerializer->serialize($eventPresence->getPresenceUpdatedBy(), [SerializerInterface::SERIALIZE_MINIMAL]) : null,
'presence_updated_at' => DateNormalizer::normalize($eventPresence->getPresenceUpdatedAt()),
];

if (!in_array(SerializerInterface::SERIALIZE_TRANSFER, $options)) {
Expand Down Expand Up @@ -88,6 +90,15 @@ public function deserialize(array $data, EventPresence $eventPresence): EventPre
$eventPresence->setEvidences($data['evidences'] ?? null);
}

if (isset($data['presence_updated_by'])) {
$updatedBy = $this->om->getRepository(User::class)->findOneBy(['uuid' => $data['presence_updated_by']['id']]);
$eventPresence->setPresenceUpdatedBy($updatedBy);
}

if (isset($data['presence_updated_at'])) {
$eventPresence->setPresenceUpdatedAt(DateNormalizer::denormalize($data['presence_updated_at']));
}

return $eventPresence;
}
}

0 comments on commit 1281002

Please sign in to comment.