mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-25 16:14:59 +00:00
Compare commits
45 Commits
master
...
285-cancel
Author | SHA1 | Date | |
---|---|---|---|
73ccdd8b6e | |||
4f170bf4cf | |||
cfbf7b4599 | |||
8941016038 | |||
f059edcc8e | |||
55c7dbf44e | |||
8336a93aeb | |||
caf0407451 | |||
e3b666921e | |||
0306af1a0c | |||
309cc64275 | |||
129690ca3f | |||
54d9f7152b | |||
809fda470b | |||
42b3ab3698 | |||
be532cb14c | |||
4ed3bec115 | |||
8f84b1e137 | |||
88a84ed996 | |||
d87523beb7 | |||
33edb22b50 | |||
607f1b7c3f | |||
57bc61b218 | |||
5efbec9b42 | |||
626a77b040 | |||
a0e0d600e6 | |||
f1221286f3 | |||
ed99d8d60b | |||
b2e27700bb | |||
63b207a2e7 | |||
b1c3daf246 | |||
761b0a3ecc | |||
e8587d5be8 | |||
9d159e79fa | |||
c779f53617 | |||
c4560b3d89 | |||
6472c45b42 | |||
c307aa5a12 | |||
5c85f0478b | |||
45be73161a | |||
e76e815c49 | |||
cce79de711 | |||
d0d3be9bc1 | |||
ace377abba | |||
fc3eda7b76 |
@@ -13,6 +13,7 @@ namespace Chill\CalendarBundle\Controller;
|
|||||||
|
|
||||||
use Chill\CalendarBundle\Entity\Calendar;
|
use Chill\CalendarBundle\Entity\Calendar;
|
||||||
use Chill\CalendarBundle\Form\CalendarType;
|
use Chill\CalendarBundle\Form\CalendarType;
|
||||||
|
use Chill\CalendarBundle\Form\CancelType;
|
||||||
use Chill\CalendarBundle\RemoteCalendar\Connector\RemoteCalendarConnectorInterface;
|
use Chill\CalendarBundle\RemoteCalendar\Connector\RemoteCalendarConnectorInterface;
|
||||||
use Chill\CalendarBundle\Repository\CalendarACLAwareRepositoryInterface;
|
use Chill\CalendarBundle\Repository\CalendarACLAwareRepositoryInterface;
|
||||||
use Chill\CalendarBundle\Security\Voter\CalendarVoter;
|
use Chill\CalendarBundle\Security\Voter\CalendarVoter;
|
||||||
@@ -30,6 +31,7 @@ use Chill\PersonBundle\Repository\PersonRepository;
|
|||||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use http\Exception\UnexpectedValueException;
|
use http\Exception\UnexpectedValueException;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
@@ -60,6 +62,7 @@ class CalendarController extends AbstractController
|
|||||||
private readonly UserRepositoryInterface $userRepository,
|
private readonly UserRepositoryInterface $userRepository,
|
||||||
private readonly TranslatorInterface $translator,
|
private readonly TranslatorInterface $translator,
|
||||||
private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry,
|
private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry,
|
||||||
|
private readonly EntityManagerInterface $em,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -111,6 +114,52 @@ class CalendarController extends AbstractController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[Route(path: '/{_locale}/calendar/calendar/{id}/cancel', name: 'chill_calendar_calendar_cancel')]
|
||||||
|
public function cancelAction(Calendar $calendar, Request $request): Response
|
||||||
|
{
|
||||||
|
// Deal with sms being sent or not
|
||||||
|
// Communicate cancellation with the remote calendar.
|
||||||
|
|
||||||
|
$this->denyAccessUnlessGranted(CalendarVoter::EDIT, $calendar);
|
||||||
|
|
||||||
|
[$person, $accompanyingPeriod] = [$calendar->getPerson(), $calendar->getAccompanyingPeriod()];
|
||||||
|
|
||||||
|
$form = $this->createForm(CancelType::class, $calendar);
|
||||||
|
$form->add('submit', SubmitType::class);
|
||||||
|
|
||||||
|
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
|
||||||
|
$view = '@ChillCalendar/Calendar/cancelCalendarByAccompanyingCourse.html.twig';
|
||||||
|
$redirectRoute = $this->generateUrl('chill_calendar_calendar_list_by_period', ['id' => $accompanyingPeriod->getId()]);
|
||||||
|
} elseif ($person instanceof Person) {
|
||||||
|
$view = '@ChillCalendar/Calendar/cancelCalendarByPerson.html.twig';
|
||||||
|
$redirectRoute = $this->generateUrl('chill_calendar_calendar_list_by_person', ['id' => $person->getId()]);
|
||||||
|
} else {
|
||||||
|
throw new \RuntimeException('nor person or accompanying period');
|
||||||
|
}
|
||||||
|
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
|
|
||||||
|
$calendar->setStatus($calendar::STATUS_CANCELED);
|
||||||
|
if ($calendar->getSendSMS()) {
|
||||||
|
$calendar->setSmsStatus($calendar::SMS_CANCEL_PENDING);
|
||||||
|
}
|
||||||
|
$this->em->flush();
|
||||||
|
|
||||||
|
$this->addFlash('success', $this->translator->trans('chill_calendar.calendar_canceled'));
|
||||||
|
|
||||||
|
return new RedirectResponse($redirectRoute);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render($view, [
|
||||||
|
'calendar' => $calendar,
|
||||||
|
'form' => $form->createView(),
|
||||||
|
'accompanyingCourse' => $accompanyingPeriod,
|
||||||
|
'person' => $person,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edit a calendar item.
|
* Edit a calendar item.
|
||||||
*/
|
*/
|
||||||
|
42
src/Bundle/ChillCalendarBundle/Form/CancelType.php
Normal file
42
src/Bundle/ChillCalendarBundle/Form/CancelType.php
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\CalendarBundle\Form;
|
||||||
|
|
||||||
|
use Chill\CalendarBundle\Entity\Calendar;
|
||||||
|
use Chill\CalendarBundle\Entity\CancelReason;
|
||||||
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
class CancelType extends AbstractType
|
||||||
|
{
|
||||||
|
public function __construct(private readonly TranslatableStringHelperInterface $translatableStringHelper) {}
|
||||||
|
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder->add('cancelReason', EntityType::class, [
|
||||||
|
'class' => CancelReason::class,
|
||||||
|
'required' => true,
|
||||||
|
'choice_label' => fn (CancelReason $cancelReason) => $this->translatableStringHelper->localize($cancelReason->getName()),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver->setDefaults([
|
||||||
|
'data_class' => Calendar::class,
|
||||||
|
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@@ -21,6 +21,7 @@ namespace Chill\CalendarBundle\Messenger\Doctrine;
|
|||||||
use Chill\CalendarBundle\Entity\Calendar;
|
use Chill\CalendarBundle\Entity\Calendar;
|
||||||
use Chill\CalendarBundle\Messenger\Message\CalendarMessage;
|
use Chill\CalendarBundle\Messenger\Message\CalendarMessage;
|
||||||
use Chill\CalendarBundle\Messenger\Message\CalendarRemovedMessage;
|
use Chill\CalendarBundle\Messenger\Message\CalendarRemovedMessage;
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
use Doctrine\ORM\Event\PostPersistEventArgs;
|
use Doctrine\ORM\Event\PostPersistEventArgs;
|
||||||
use Doctrine\ORM\Event\PostRemoveEventArgs;
|
use Doctrine\ORM\Event\PostRemoveEventArgs;
|
||||||
use Doctrine\ORM\Event\PostUpdateEventArgs;
|
use Doctrine\ORM\Event\PostUpdateEventArgs;
|
||||||
@@ -31,6 +32,17 @@ class CalendarEntityListener
|
|||||||
{
|
{
|
||||||
public function __construct(private readonly MessageBusInterface $messageBus, private readonly Security $security) {}
|
public function __construct(private readonly MessageBusInterface $messageBus, private readonly Security $security) {}
|
||||||
|
|
||||||
|
private function getAuthenticatedUser(): User
|
||||||
|
{
|
||||||
|
$user = $this->security->getUser();
|
||||||
|
|
||||||
|
if (!$user instanceof User) {
|
||||||
|
throw new \LogicException('Expected an instance of User.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
|
||||||
public function postPersist(Calendar $calendar, PostPersistEventArgs $args): void
|
public function postPersist(Calendar $calendar, PostPersistEventArgs $args): void
|
||||||
{
|
{
|
||||||
if (!$calendar->preventEnqueueChanges) {
|
if (!$calendar->preventEnqueueChanges) {
|
||||||
@@ -38,7 +50,7 @@ class CalendarEntityListener
|
|||||||
new CalendarMessage(
|
new CalendarMessage(
|
||||||
$calendar,
|
$calendar,
|
||||||
CalendarMessage::CALENDAR_PERSIST,
|
CalendarMessage::CALENDAR_PERSIST,
|
||||||
$this->security->getUser()
|
$this->getAuthenticatedUser()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -50,7 +62,7 @@ class CalendarEntityListener
|
|||||||
$this->messageBus->dispatch(
|
$this->messageBus->dispatch(
|
||||||
new CalendarRemovedMessage(
|
new CalendarRemovedMessage(
|
||||||
$calendar,
|
$calendar,
|
||||||
$this->security->getUser()
|
$this->getAuthenticatedUser()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -58,12 +70,21 @@ class CalendarEntityListener
|
|||||||
|
|
||||||
public function postUpdate(Calendar $calendar, PostUpdateEventArgs $args): void
|
public function postUpdate(Calendar $calendar, PostUpdateEventArgs $args): void
|
||||||
{
|
{
|
||||||
|
if ($calendar->getStatus() === $calendar::STATUS_CANCELED) {
|
||||||
|
$this->messageBus->dispatch(
|
||||||
|
new CalendarRemovedMessage(
|
||||||
|
$calendar,
|
||||||
|
$this->getAuthenticatedUser()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (!$calendar->preventEnqueueChanges) {
|
if (!$calendar->preventEnqueueChanges) {
|
||||||
$this->messageBus->dispatch(
|
$this->messageBus->dispatch(
|
||||||
new CalendarMessage(
|
new CalendarMessage(
|
||||||
$calendar,
|
$calendar,
|
||||||
CalendarMessage::CALENDAR_UPDATE,
|
CalendarMessage::CALENDAR_UPDATE,
|
||||||
$this->security->getUser()
|
$this->getAuthenticatedUser()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -70,6 +70,8 @@ class CalendarRemovedMessage
|
|||||||
|
|
||||||
public function getRemoteId(): string
|
public function getRemoteId(): string
|
||||||
{
|
{
|
||||||
|
dump($this->remoteId);
|
||||||
|
|
||||||
return $this->remoteId;
|
return $this->remoteId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,6 +10,9 @@
|
|||||||
<div class="item-col">
|
<div class="item-col">
|
||||||
<div class="wrap-header">
|
<div class="wrap-header">
|
||||||
<div class="wl-row">
|
<div class="wl-row">
|
||||||
|
{% if calendar.status == 'canceled' %}
|
||||||
|
<p class="badge rounded-pill bg-danger">{{ 'chill_calendar.canceled'|trans }}: <span>{{ calendar.cancelReason.name|localize_translatable_string }}</span></p>
|
||||||
|
{% endif %}
|
||||||
<div class="wl-col title">
|
<div class="wl-col title">
|
||||||
<p class="date-label">
|
<p class="date-label">
|
||||||
{% if context == 'person' and calendar.context == 'accompanying_period' %}
|
{% if context == 'person' and calendar.context == 'accompanying_period' %}
|
||||||
@@ -19,6 +22,9 @@
|
|||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if calendar.status == 'canceled' %}
|
||||||
|
<del>
|
||||||
|
{% endif %}
|
||||||
{% if calendar.endDate.diff(calendar.startDate).days >= 1 %}
|
{% if calendar.endDate.diff(calendar.startDate).days >= 1 %}
|
||||||
{{ calendar.startDate|format_datetime('short', 'short') }}
|
{{ calendar.startDate|format_datetime('short', 'short') }}
|
||||||
- {{ calendar.endDate|format_datetime('short', 'short') }}
|
- {{ calendar.endDate|format_datetime('short', 'short') }}
|
||||||
@@ -26,13 +32,21 @@
|
|||||||
{{ calendar.startDate|format_datetime('short', 'short') }}
|
{{ calendar.startDate|format_datetime('short', 'short') }}
|
||||||
- {{ calendar.endDate|format_datetime('none', 'short') }}
|
- {{ calendar.endDate|format_datetime('none', 'short') }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
{% if calendar.status == 'canceled' %}
|
||||||
|
</del>
|
||||||
|
{% endif %}
|
||||||
|
{# {% if calendar.status == 'canceled' %}#}
|
||||||
|
{# <p>#}
|
||||||
|
{# <span>{{ 'chill_calendar.cancel_reason'|trans }}:</span>#}
|
||||||
|
{##}
|
||||||
|
{# </p>#}
|
||||||
|
{# {% endif %}#}
|
||||||
|
|
||||||
<div class="duration short-message">
|
<div class="duration short-message">
|
||||||
<i class="fa fa-fw fa-hourglass-end"></i>
|
<i class="fa fa-fw fa-hourglass-end"></i>
|
||||||
{{ calendar.duration|date('%H:%I') }}
|
{{ calendar.duration|date('%H:%I') }}
|
||||||
{% if false == calendar.sendSMS or null == calendar.sendSMS %}
|
{% if false == calendar.sendSMS or null == calendar.sendSMS %}
|
||||||
<!-- no sms will be send -->
|
<!-- no sms will be sent -->
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if calendar.smsStatus == 'sms_sent' %}
|
{% if calendar.smsStatus == 'sms_sent' %}
|
||||||
<span title="{{ 'SMS already sent'|trans }}" class="badge bg-info">
|
<span title="{{ 'SMS already sent'|trans }}" class="badge bg-info">
|
||||||
@@ -63,8 +77,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if calendar.comment.comment is not empty
|
{% if calendar.users|length > 0
|
||||||
or calendar.users|length > 0
|
|
||||||
or calendar.thirdParties|length > 0
|
or calendar.thirdParties|length > 0
|
||||||
or calendar.users|length > 0 %}
|
or calendar.users|length > 0 %}
|
||||||
<div class="item-row details separator">
|
<div class="item-row details separator">
|
||||||
@@ -103,12 +116,13 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="item-row separator column">
|
{% if calendar.documents is not empty %}
|
||||||
<div>
|
<div class="item-row separator column">
|
||||||
|
<div>
|
||||||
{{ include('@ChillCalendar/Calendar/_documents.twig.html') }}
|
{{ include('@ChillCalendar/Calendar/_documents.twig.html') }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% endif %}
|
||||||
|
|
||||||
{% if calendar.activity is not null %}
|
{% if calendar.activity is not null %}
|
||||||
<div class="item-row separator">
|
<div class="item-row separator">
|
||||||
@@ -151,7 +165,7 @@
|
|||||||
|
|
||||||
<div class="item-row separator">
|
<div class="item-row separator">
|
||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
{% if is_granted('CHILL_CALENDAR_DOC_EDIT', calendar) %}
|
{% if is_granted('CHILL_CALENDAR_DOC_EDIT', calendar) and calendar.status is not constant('STATUS_CANCELED', calendar) %}
|
||||||
{% if templates|length == 0 %}
|
{% if templates|length == 0 %}
|
||||||
<li>
|
<li>
|
||||||
<a class="btn btn-create"
|
<a class="btn btn-create"
|
||||||
@@ -191,6 +205,7 @@
|
|||||||
or
|
or
|
||||||
(calendar.context == 'person' and is_granted('CHILL_ACTIVITY_CREATE', calendar.person))
|
(calendar.context == 'person' and is_granted('CHILL_ACTIVITY_CREATE', calendar.person))
|
||||||
)
|
)
|
||||||
|
and calendar.status is not constant('STATUS_CANCELED', calendar)
|
||||||
%}
|
%}
|
||||||
<li>
|
<li>
|
||||||
<a class="btn btn-create"
|
<a class="btn btn-create"
|
||||||
@@ -213,11 +228,16 @@
|
|||||||
class="btn btn-show "></a>
|
class="btn btn-show "></a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if is_granted('CHILL_CALENDAR_CALENDAR_EDIT', calendar) %}
|
|
||||||
|
{% if is_granted('CHILL_CALENDAR_CALENDAR_EDIT', calendar) and calendar.status is not constant('STATUS_CANCELED', calendar) %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ chill_path_add_return_path('chill_calendar_calendar_edit', { 'id': calendar.id }) }}"
|
<a href="{{ chill_path_add_return_path('chill_calendar_calendar_edit', { 'id': calendar.id }) }}"
|
||||||
class="btn btn-update "></a>
|
class="btn btn-update "></a>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="{{ chill_path_add_return_path('chill_calendar_calendar_cancel', { 'id': calendar.id } ) }}"
|
||||||
|
class="btn btn-remove">{{ 'Cancel'|trans }}</a>
|
||||||
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if is_granted('CHILL_CALENDAR_CALENDAR_DELETE', calendar) %}
|
{% if is_granted('CHILL_CALENDAR_CALENDAR_DELETE', calendar) %}
|
||||||
<li>
|
<li>
|
||||||
|
@@ -0,0 +1,29 @@
|
|||||||
|
{% extends "@ChillPerson/AccompanyingCourse/layout.html.twig" %}
|
||||||
|
|
||||||
|
{% set activeRouteKey = 'chill_calendar_calendar_list' %}
|
||||||
|
|
||||||
|
{% block title 'chill_calendar.cancel_calendar_item'|trans %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
{{ form_start(form) }}
|
||||||
|
|
||||||
|
{{ form_row(form.cancelReason) }}
|
||||||
|
|
||||||
|
<ul class="record_actions sticky-form-buttons">
|
||||||
|
<li class="save">
|
||||||
|
<a
|
||||||
|
class="btn btn-cancel"
|
||||||
|
href="{{ chill_return_path_or('chill_calendar_calendar_list', { 'id': accompanyingCourse.id } )}}"
|
||||||
|
>
|
||||||
|
{{ 'Cancel'|trans|chill_return_path_label }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
{{ form_widget(form.submit, { 'attr' : { 'class': 'btn btn-save' }, 'label': 'Save' } ) }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{{ form_end(form) }}
|
||||||
|
|
||||||
|
{% endblock %}
|
@@ -0,0 +1,29 @@
|
|||||||
|
{% extends "@ChillPerson/Person/layout.html.twig" %}
|
||||||
|
|
||||||
|
{% set activeRouteKey = 'chill_calendar_calendar_list' %}
|
||||||
|
|
||||||
|
{% block title 'chill_calendar.cancel_calendar_item'|trans %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
{{ form_start(form) }}
|
||||||
|
|
||||||
|
{{ form_row(form.cancelReason) }}
|
||||||
|
|
||||||
|
<ul class="record_actions sticky-form-buttons">
|
||||||
|
<li class="save">
|
||||||
|
<a
|
||||||
|
class="btn btn-cancel"
|
||||||
|
href="{{ chill_return_path_or('chill_calendar_calendar_list', { 'id': person.id } )}}"
|
||||||
|
>
|
||||||
|
{{ 'Cancel'|trans|chill_return_path_label }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
{{ form_widget(form.submit, { 'attr' : { 'class': 'btn btn-save' }, 'label': 'Save' } ) }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{{ form_end(form) }}
|
||||||
|
|
||||||
|
{% endblock %}
|
@@ -19,6 +19,7 @@ declare(strict_types=1);
|
|||||||
namespace Chill\CalendarBundle\Service\ShortMessageNotification;
|
namespace Chill\CalendarBundle\Service\ShortMessageNotification;
|
||||||
|
|
||||||
use Chill\CalendarBundle\Entity\Calendar;
|
use Chill\CalendarBundle\Entity\Calendar;
|
||||||
|
use Chill\CalendarBundle\Entity\CancelReason;
|
||||||
use libphonenumber\PhoneNumberFormat;
|
use libphonenumber\PhoneNumberFormat;
|
||||||
use libphonenumber\PhoneNumberUtil;
|
use libphonenumber\PhoneNumberUtil;
|
||||||
use Symfony\Component\Notifier\Message\SmsMessage;
|
use Symfony\Component\Notifier\Message\SmsMessage;
|
||||||
@@ -57,7 +58,7 @@ class DefaultShortMessageForCalendarBuilder implements ShortMessageForCalendarBu
|
|||||||
$this->phoneUtil->format($person->getMobilenumber(), PhoneNumberFormat::E164),
|
$this->phoneUtil->format($person->getMobilenumber(), PhoneNumberFormat::E164),
|
||||||
$this->engine->render('@ChillCalendar/CalendarShortMessage/short_message.txt.twig', ['calendar' => $calendar]),
|
$this->engine->render('@ChillCalendar/CalendarShortMessage/short_message.txt.twig', ['calendar' => $calendar]),
|
||||||
);
|
);
|
||||||
} elseif (Calendar::SMS_CANCEL_PENDING === $calendar->getSmsStatus()) {
|
} elseif (Calendar::SMS_CANCEL_PENDING === $calendar->getSmsStatus() && !(CancelReason::CANCELEDBY_PERSON === $calendar->getCancelReason()->getCanceledBy())) {
|
||||||
$toUsers[] = new SmsMessage(
|
$toUsers[] = new SmsMessage(
|
||||||
$this->phoneUtil->format($person->getMobilenumber(), PhoneNumberFormat::E164),
|
$this->phoneUtil->format($person->getMobilenumber(), PhoneNumberFormat::E164),
|
||||||
$this->engine->render('@ChillCalendar/CalendarShortMessage/short_message_canceled.txt.twig', ['calendar' => $calendar]),
|
$this->engine->render('@ChillCalendar/CalendarShortMessage/short_message_canceled.txt.twig', ['calendar' => $calendar]),
|
||||||
|
@@ -44,6 +44,10 @@ crud:
|
|||||||
title_edit: Modifier le motif d'annulation
|
title_edit: Modifier le motif d'annulation
|
||||||
|
|
||||||
chill_calendar:
|
chill_calendar:
|
||||||
|
canceled: Annulé
|
||||||
|
cancel_reason: Raison d'annulation
|
||||||
|
cancel_calendar_item: Annuler rendez-vous
|
||||||
|
calendar_canceled: Le rendez-vous a été annulé
|
||||||
Document: Document d'un rendez-vous
|
Document: Document d'un rendez-vous
|
||||||
form:
|
form:
|
||||||
The main user is mandatory. He will organize the appointment.: L'utilisateur principal est obligatoire. Il est l'organisateur de l'événement.
|
The main user is mandatory. He will organize the appointment.: L'utilisateur principal est obligatoire. Il est l'organisateur de l'événement.
|
||||||
@@ -66,8 +70,6 @@ chill_calendar:
|
|||||||
Are you sure you want to remove the doc?: Êtes-vous sûr·e de vouloir supprimer le document associé ?
|
Are you sure you want to remove the doc?: Êtes-vous sûr·e de vouloir supprimer le document associé ?
|
||||||
Document outdated: La date et l'heure du rendez-vous ont été modifiés après la création du document
|
Document outdated: La date et l'heure du rendez-vous ont été modifiés après la création du document
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
remote_ms_graph:
|
remote_ms_graph:
|
||||||
freebusy_statuses:
|
freebusy_statuses:
|
||||||
busy: Occupé
|
busy: Occupé
|
||||||
|
@@ -2,26 +2,26 @@
|
|||||||
<teleport to="body">
|
<teleport to="body">
|
||||||
<modal v-if="modalOpen" @close="modalOpen = false">
|
<modal v-if="modalOpen" @close="modalOpen = false">
|
||||||
<template v-slot:header>
|
<template v-slot:header>
|
||||||
<h2>{{ $t("signature_confirmation") }}</h2>
|
<h2>{{ trans(SIGNATURES_SIGNATURE_CONFIRMATION) }}</h2>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:body>
|
<template v-slot:body>
|
||||||
<div class="signature-modal-body text-center" v-if="loading">
|
<div class="signature-modal-body text-center" v-if="loading">
|
||||||
<p>{{ $t("electronic_signature_in_progress") }}</p>
|
<p>{{ trans(SIGNATURES_ELECTRONIC_SIGNATURE_IN_PROGRESS) }}</p>
|
||||||
<div class="loading">
|
<div class="loading">
|
||||||
<i
|
<i
|
||||||
class="fa fa-circle-o-notch fa-spin fa-3x"
|
class="fa fa-circle-o-notch fa-spin fa-3x"
|
||||||
:title="$t('loading')"
|
:title="trans(SIGNATURES_LOADING)"
|
||||||
></i>
|
></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="signature-modal-body text-center" v-else>
|
<div class="signature-modal-body text-center" v-else>
|
||||||
<p>{{ $t("you_are_going_to_sign") }}</p>
|
<p>{{ trans(SIGNATURES_YOU_ARE_GOING_TO_SIGN) }}</p>
|
||||||
<p>{{ $t("are_you_sure") }}</p>
|
<p>{{ trans(SIGNATURES_ARE_YOU_SURE) }}</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:footer>
|
<template v-slot:footer>
|
||||||
<button class="btn btn-action" @click.prevent="confirmSign">
|
<button class="btn btn-action" @click.prevent="confirmSign">
|
||||||
{{ $t("yes") }}
|
{{ trans(SIGNATURES_YES) }}
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
</modal>
|
</modal>
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
@change="toggleMultiPage"
|
@change="toggleMultiPage"
|
||||||
/>
|
/>
|
||||||
<label class="form-check-label" for="checkboxMulti">
|
<label class="form-check-label" for="checkboxMulti">
|
||||||
{{ $t("all_pages") }}
|
{{ trans(SIGNATURES_ALL_PAGES) }}
|
||||||
</label>
|
</label>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@@ -95,7 +95,7 @@
|
|||||||
class="btn btn-light btn-sm"
|
class="btn btn-light btn-sm"
|
||||||
@click="turnSignature(-1)"
|
@click="turnSignature(-1)"
|
||||||
>
|
>
|
||||||
{{ $t("last_zone") }}
|
{{ trans(SIGNATURES_LAST_ZONE) }}
|
||||||
</button>
|
</button>
|
||||||
<span>|</span>
|
<span>|</span>
|
||||||
<button
|
<button
|
||||||
@@ -103,7 +103,7 @@
|
|||||||
class="btn btn-light btn-sm"
|
class="btn btn-light btn-sm"
|
||||||
@click="turnSignature(1)"
|
@click="turnSignature(1)"
|
||||||
>
|
>
|
||||||
{{ $t("next_zone") }}
|
{{ trans(SIGNATURES_NEXT_ZONE) }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col text-end" v-if="signedState !== 'signed'">
|
<div class="col text-end" v-if="signedState !== 'signed'">
|
||||||
@@ -112,9 +112,9 @@
|
|||||||
:hidden="!userSignatureZone"
|
:hidden="!userSignatureZone"
|
||||||
@click="undoSign"
|
@click="undoSign"
|
||||||
v-if="signature.zones.length > 1"
|
v-if="signature.zones.length > 1"
|
||||||
:title="$t('choose_another_signature')"
|
:title="trans(SIGNATURES_CHOOSE_ANOTHER_SIGNATURE)"
|
||||||
>
|
>
|
||||||
{{ $t("another_zone") }}
|
{{ trans(SIGNATURES_ANOTHER_ZONE) }}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-misc btn-sm"
|
class="btn btn-misc btn-sm"
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
@click="undoSign"
|
@click="undoSign"
|
||||||
v-else
|
v-else
|
||||||
>
|
>
|
||||||
{{ $t("cancel") }}
|
{{ trans(SIGNATURES_CANCEL) }}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="userSignatureZone === null"
|
v-if="userSignatureZone === null"
|
||||||
@@ -134,7 +134,7 @@
|
|||||||
active: canvasEvent === 'add',
|
active: canvasEvent === 'add',
|
||||||
}"
|
}"
|
||||||
@click="toggleAddZone()"
|
@click="toggleAddZone()"
|
||||||
:title="$t('add_sign_zone')"
|
:title="trans(SIGNATURES_ADD_SIGN_ZONE)"
|
||||||
>
|
>
|
||||||
<template v-if="canvasEvent === 'add'">
|
<template v-if="canvasEvent === 'add'">
|
||||||
<div
|
<div
|
||||||
@@ -186,7 +186,7 @@
|
|||||||
@change="toggleMultiPage"
|
@change="toggleMultiPage"
|
||||||
/>
|
/>
|
||||||
<label class="form-check-label" for="checkboxMulti">
|
<label class="form-check-label" for="checkboxMulti">
|
||||||
{{ $t("see_all_pages") }}
|
{{ trans(SIGNATURES_SEE_ALL_PAGES) }}
|
||||||
</label>
|
</label>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@@ -199,7 +199,7 @@
|
|||||||
class="btn btn-light btn-sm"
|
class="btn btn-light btn-sm"
|
||||||
@click="turnSignature(-1)"
|
@click="turnSignature(-1)"
|
||||||
>
|
>
|
||||||
{{ $t("last_zone") }}
|
{{ trans(SIGNATURES_LAST_ZONE) }}
|
||||||
</button>
|
</button>
|
||||||
<span>|</span>
|
<span>|</span>
|
||||||
<button
|
<button
|
||||||
@@ -207,11 +207,20 @@
|
|||||||
class="btn btn-light btn-sm"
|
class="btn btn-light btn-sm"
|
||||||
@click="turnSignature(1)"
|
@click="turnSignature(1)"
|
||||||
>
|
>
|
||||||
{{ $t("next_zone") }}
|
{{ trans(SIGNATURES_NEXT_ZONE) }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div v-if="signature.zones.length === 1 && signedState !== 'signed'"
|
||||||
|
class="col-4 d-none d-xl-flex p-0 text-center turnSignature">
|
||||||
|
<button
|
||||||
|
class="btn btn-light btn-sm"
|
||||||
|
@click="goToSignatureZoneUnique"
|
||||||
|
>
|
||||||
|
{{ trans(SIGNATURES_GO_TO_SIGNATURE_UNIQUE) }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="signature.zones.length > 0 && signedState !== 'signed'"
|
v-if="signature.zones.length > 1 && signedState !== 'signed'"
|
||||||
class="col-4 d-none d-xl-flex p-0 text-center turnSignature"
|
class="col-4 d-none d-xl-flex p-0 text-center turnSignature"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
@@ -219,7 +228,7 @@
|
|||||||
class="btn btn-light btn-sm"
|
class="btn btn-light btn-sm"
|
||||||
@click="turnSignature(-1)"
|
@click="turnSignature(-1)"
|
||||||
>
|
>
|
||||||
{{ $t("last_sign_zone") }}
|
{{ trans(SIGNATURES_LAST_SIGN_ZONE) }}
|
||||||
</button>
|
</button>
|
||||||
<span>|</span>
|
<span>|</span>
|
||||||
<button
|
<button
|
||||||
@@ -227,7 +236,7 @@
|
|||||||
class="btn btn-light btn-sm"
|
class="btn btn-light btn-sm"
|
||||||
@click="turnSignature(1)"
|
@click="turnSignature(1)"
|
||||||
>
|
>
|
||||||
{{ $t("next_sign_zone") }}
|
{{ trans(SIGNATURES_NEXT_SIGN_ZONE) }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col text-end" v-if="signedState !== 'signed'">
|
<div class="col text-end" v-if="signedState !== 'signed'">
|
||||||
@@ -237,7 +246,7 @@
|
|||||||
@click="undoSign"
|
@click="undoSign"
|
||||||
v-if="signature.zones.length > 1"
|
v-if="signature.zones.length > 1"
|
||||||
>
|
>
|
||||||
{{ $t("choose_another_signature") }}
|
{{ trans(SIGNATURES_CHOOSE_ANOTHER_SIGNATURE) }}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-misc btn-sm"
|
class="btn btn-misc btn-sm"
|
||||||
@@ -245,7 +254,7 @@
|
|||||||
@click="undoSign"
|
@click="undoSign"
|
||||||
v-else
|
v-else
|
||||||
>
|
>
|
||||||
{{ $t("cancel") }}
|
{{ trans(SIGNATURES_CANCEL) }}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="userSignatureZone === null"
|
v-if="userSignatureZone === null"
|
||||||
@@ -257,13 +266,13 @@
|
|||||||
active: canvasEvent === 'add',
|
active: canvasEvent === 'add',
|
||||||
}"
|
}"
|
||||||
@click="toggleAddZone()"
|
@click="toggleAddZone()"
|
||||||
:title="$t('add_sign_zone')"
|
:title="trans(SIGNATURES_ADD_SIGN_ZONE)"
|
||||||
>
|
>
|
||||||
<template v-if="canvasEvent !== 'add'">
|
<template v-if="canvasEvent !== 'add'">
|
||||||
{{ $t("add_zone") }}
|
{{ trans(SIGNATURES_ADD_ZONE) }}
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
{{ $t("click_on_document") }}
|
{{ trans(SIGNATURES_CLICK_ON_DOCUMENT) }}
|
||||||
<div
|
<div
|
||||||
class="spinner-border spinner-border-sm"
|
class="spinner-border spinner-border-sm"
|
||||||
role="status"
|
role="status"
|
||||||
@@ -297,10 +306,10 @@
|
|||||||
v-if="signedState !== 'signed'"
|
v-if="signedState !== 'signed'"
|
||||||
:href="getReturnPath()"
|
:href="getReturnPath()"
|
||||||
>
|
>
|
||||||
{{ $t("cancel") }}
|
{{ trans(SIGNATURES_CANCEL) }}
|
||||||
</a>
|
</a>
|
||||||
<a class="btn btn-misc" v-else :href="getReturnPath()">
|
<a class="btn btn-misc" v-else :href="getReturnPath()">
|
||||||
{{ $t("return") }}
|
{{ trans(SIGNATURES_RETURN) }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col text-end" v-if="signedState !== 'signed'">
|
<div class="col text-end" v-if="signedState !== 'signed'">
|
||||||
@@ -309,7 +318,7 @@
|
|||||||
:disabled="!userSignatureZone"
|
:disabled="!userSignatureZone"
|
||||||
@click="sign"
|
@click="sign"
|
||||||
>
|
>
|
||||||
{{ $t("sign") }}
|
{{ trans(SIGNATURES_SIGN) }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4" v-else></div>
|
<div class="col-4" v-else></div>
|
||||||
@@ -329,13 +338,39 @@ import {
|
|||||||
SignedState,
|
SignedState,
|
||||||
ZoomLevel,
|
ZoomLevel,
|
||||||
} from "../../types";
|
} from "../../types";
|
||||||
import { makeFetch } from "../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
|
||||||
import * as pdfjsLib from "pdfjs-dist";
|
import * as pdfjsLib from "pdfjs-dist";
|
||||||
import {
|
import {
|
||||||
PDFDocumentProxy,
|
PDFDocumentProxy,
|
||||||
PDFPageProxy,
|
PDFPageProxy,
|
||||||
} from "pdfjs-dist/types/src/display/api";
|
} from "pdfjs-dist/types/src/display/api";
|
||||||
|
|
||||||
|
import {
|
||||||
|
SIGNATURES_YES,
|
||||||
|
SIGNATURES_ARE_YOU_SURE,
|
||||||
|
SIGNATURES_YOU_ARE_GOING_TO_SIGN,
|
||||||
|
SIGNATURES_SIGNATURE_CONFIRMATION,
|
||||||
|
SIGNATURES_SIGN,
|
||||||
|
SIGNATURES_CHOOSE_ANOTHER_SIGNATURE,
|
||||||
|
SIGNATURES_CANCEL,
|
||||||
|
SIGNATURES_LAST_SIGN_ZONE,
|
||||||
|
SIGNATURES_NEXT_SIGN_ZONE,
|
||||||
|
SIGNATURES_ADD_SIGN_ZONE,
|
||||||
|
SIGNATURES_CLICK_ON_DOCUMENT,
|
||||||
|
SIGNATURES_LAST_ZONE,
|
||||||
|
SIGNATURES_NEXT_ZONE,
|
||||||
|
SIGNATURES_ADD_ZONE,
|
||||||
|
SIGNATURES_ANOTHER_ZONE,
|
||||||
|
SIGNATURES_ELECTRONIC_SIGNATURE_IN_PROGRESS,
|
||||||
|
SIGNATURES_LOADING,
|
||||||
|
SIGNATURES_RETURN,
|
||||||
|
SIGNATURES_SEE_ALL_PAGES,
|
||||||
|
SIGNATURES_ALL_PAGES,
|
||||||
|
SIGNATURES_GO_TO_SIGNATURE_UNIQUE,
|
||||||
|
trans
|
||||||
|
} from "translator";
|
||||||
|
|
||||||
|
|
||||||
// @ts-ignore incredible but the console.log is needed
|
// @ts-ignore incredible but the console.log is needed
|
||||||
import * as PdfWorker from "pdfjs-dist/build/pdf.worker.mjs";
|
import * as PdfWorker from "pdfjs-dist/build/pdf.worker.mjs";
|
||||||
console.log(PdfWorker);
|
console.log(PdfWorker);
|
||||||
@@ -415,8 +450,10 @@ const $toast = useToast();
|
|||||||
|
|
||||||
const signature = window.signature;
|
const signature = window.signature;
|
||||||
|
|
||||||
const isFirstSignatureZone = () =>
|
const isFirstSignatureZone = () => {
|
||||||
userSignatureZone.value?.index ? userSignatureZone.value.index < 1 : false;
|
console.log(userSignatureZone.value?.index)
|
||||||
|
return userSignatureZone.value?.index ? userSignatureZone.value.index < 1 : false;
|
||||||
|
}
|
||||||
const isLastSignatureZone = () =>
|
const isLastSignatureZone = () =>
|
||||||
userSignatureZone.value?.index
|
userSignatureZone.value?.index
|
||||||
? userSignatureZone.value.index >= signature.zones.length - 1
|
? userSignatureZone.value.index >= signature.zones.length - 1
|
||||||
@@ -600,6 +637,15 @@ const turnPage = async (upOrDown: number) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const goToSignatureZoneUnique = () => {
|
||||||
|
let signatureZone = signature.zones[0];
|
||||||
|
|
||||||
|
page.value = signatureZone.PDFPage.index + 1;
|
||||||
|
const canvas = getCanvas(signatureZone.PDFPage.index + 1);
|
||||||
|
selectZone(signatureZone, canvas);
|
||||||
|
canvas.scrollIntoView();
|
||||||
|
}
|
||||||
|
|
||||||
const turnSignature = async (upOrDown: number) => {
|
const turnSignature = async (upOrDown: number) => {
|
||||||
let zoneIndex = userSignatureZone.value?.index ?? -1;
|
let zoneIndex = userSignatureZone.value?.index ?? -1;
|
||||||
if (zoneIndex < -1) {
|
if (zoneIndex < -1) {
|
||||||
|
@@ -99,3 +99,30 @@ CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE: Modifier un document
|
|||||||
entity_display_title:
|
entity_display_title:
|
||||||
Document (n°%doc%): "Document (n°%doc%)"
|
Document (n°%doc%): "Document (n°%doc%)"
|
||||||
Doc for evaluation (n°%eval%): Document de l'évaluation n°%eval%
|
Doc for evaluation (n°%eval%): Document de l'évaluation n°%eval%
|
||||||
|
|
||||||
|
|
||||||
|
# SIGNATURES
|
||||||
|
|
||||||
|
signatures:
|
||||||
|
yes: Oui
|
||||||
|
are_you_sure: Êtes-vous sûr·e?
|
||||||
|
you_are_going_to_sign: Vous allez signer le document
|
||||||
|
signature_confirmation: Confirmation de la signature
|
||||||
|
sign: Signer
|
||||||
|
choose_another_signature: Choisir une autre zone
|
||||||
|
cancel: Annuler
|
||||||
|
last_sign_zone: Zone de signature précédente
|
||||||
|
next_sign_zone: Zone de signature suivante
|
||||||
|
add_sign_zone: Ajouter une zone de signature
|
||||||
|
click_on_document: Cliquer sur le document
|
||||||
|
last_zone: Zone précédente
|
||||||
|
next_zone: Zone suivante
|
||||||
|
add_zone: Ajouter une zone
|
||||||
|
another_zone: Autre zone
|
||||||
|
electronic_signature_in_progress: Signature électronique en cours...
|
||||||
|
loading: Chargement...
|
||||||
|
remove_sign_zone: Enlever la zone
|
||||||
|
return: Retour
|
||||||
|
see_all_pages: Voir toutes les pages
|
||||||
|
all_pages: Toutes les pages
|
||||||
|
go_to_signature_unique: Aller vers zone de signature
|
||||||
|
Reference in New Issue
Block a user