diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml
index a7b71a072..ecc595987 100644
--- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml
+++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml
@@ -46,6 +46,11 @@ Back to the list: Retour à la liste
#interval
Years: Années
+# misc date
+Since %date%: Depuis le %date%
+since %date%: depuis le %date%
+Until %date%: Jusqu'au %date%
+until %date%: jusqu'au %date%
#elements used in software
centers: centres
Centers: Centres
@@ -78,6 +83,9 @@ Results %start%-%end% of %total%: Résultats %start%-%end% sur %total%
See all results: Voir tous les résultats
Advanced search: Recherche avancée
+# timeline
+Global timeline: Historique global
+
#admin
Create: Créer
show: voir
diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php
index 18ee535b8..d7420bf57 100644
--- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php
+++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php
@@ -302,13 +302,9 @@ class AccompanyingPeriod
return false;
}
- public function setRemark(string $remark): self
+ public function setRemark(string $remark = null): self
{
- if ($remark === null) {
- $remark = '';
- }
-
- $this->remark = $remark;
+ $this->remark = (string) $remark;
return $this;
}
diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Entity/person.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Entity/person.html.twig
index 54482ee29..afcd2799c 100644
--- a/src/Bundle/ChillPersonBundle/Resources/views/Entity/person.html.twig
+++ b/src/Bundle/ChillPersonBundle/Resources/views/Entity/person.html.twig
@@ -1,18 +1,15 @@
- {% if addLink and is_granted('CHILL_PERSON_SEE', person) %}
- {% set showLink = true %}
-
- {% endif %}
- {{ person.firstName }}
+ {%- if addLink and is_granted('CHILL_PERSON_SEE', person) -%}
+ {%- set showLink = true -%}{%- endif -%}
+ {{ person.firstName }}
{{ person.lastName }}
- {% if addAltNames %}
- {% for n in person.altNames %}
- {% if loop.first %}({% else %} {% endif %}
+ {%- if addAltNames -%}
+ {%- for n in person.altNames -%}
+ {%- if loop.first -%}({% else %} {%- endif -%}
{{ n.label }}
- {% if loop.last %}){% endif %}
- {% endfor %}
- {% endif %}
- {% if showLink is defined %}{% endif %}
-
+ {%- if loop.last %}) {% endif -%}
+ {%- endfor -%}
+ {%- endif -%}
+ {%- if showLink is defined -%}{%- endif -%}
diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Timeline/closing_period.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Timeline/closing_period.html.twig
index 27f13fc96..76224636a 100644
--- a/src/Bundle/ChillPersonBundle/Resources/views/Timeline/closing_period.html.twig
+++ b/src/Bundle/ChillPersonBundle/Resources/views/Timeline/closing_period.html.twig
@@ -1,11 +1,19 @@
-
+
+
+
/
+ {{ 'An accompanying period ends'|trans }}
+
+
+
+
+ - {{ 'Participants'|trans }} :
+ -
+
+ {% for p in period.participations %}
+ - {{ p.person|chill_entity_render_box({ 'addLink': true }) }}: {{ 'since %date%'|trans({'%date%': p.startDate|format_date("long") } ) }}, {{ 'until %date%'|trans({'%date%': (p.endDate is not null ? p.endDate : period.closingDate)|format_date("long") }) }}
+ {% endfor %}
+
+
+
+
diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Timeline/opening_period.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Timeline/opening_period.html.twig
index e6fa5752c..6987aee2b 100644
--- a/src/Bundle/ChillPersonBundle/Resources/views/Timeline/opening_period.html.twig
+++ b/src/Bundle/ChillPersonBundle/Resources/views/Timeline/opening_period.html.twig
@@ -1,11 +1,19 @@
-
+
+
+
/
+ {{ 'An accompanying period starts'|trans }}
+
+
+
+
+ - {{ 'Participants'|trans }} :
+ -
+
+ {% for p in period.participations %}
+ - {{ 'Since %date%'|trans( {'%date%': p.startDate|format_date("long") } ) }} : {{ p.person|chill_entity_render_box({ 'addLink': true }) }}
+ {% endfor %}
+
+
+
+
diff --git a/src/Bundle/ChillPersonBundle/Timeline/AbstractTimelineAccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Timeline/AbstractTimelineAccompanyingPeriod.php
index 37f185bb2..6b5b0cfd8 100644
--- a/src/Bundle/ChillPersonBundle/Timeline/AbstractTimelineAccompanyingPeriod.php
+++ b/src/Bundle/ChillPersonBundle/Timeline/AbstractTimelineAccompanyingPeriod.php
@@ -21,6 +21,13 @@ namespace Chill\PersonBundle\Timeline;
use Chill\MainBundle\Timeline\TimelineProviderInterface;
use Doctrine\ORM\EntityManager;
+use Chill\PersonBundle\Entity\AccompanyingPeriod;
+use Chill\PersonBundle\Entity\Person;
+use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
+use Chill\MainBundle\Entity\Center;
+use Chill\PersonBundle\Security\Authorization\PersonVoter;
+use Symfony\Component\Security\Core\Security;
+use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
/**
* Provide method to build timeline for accompanying periods
@@ -28,19 +35,22 @@ use Doctrine\ORM\EntityManager;
* This class is resued by TimelineAccompanyingPeriodOpening (for opening)
* and TimelineAccompanyingPeriodClosing (for closing)
*
- * @author Julien Fastré
*/
abstract class AbstractTimelineAccompanyingPeriod implements TimelineProviderInterface
{
- /**
- *
- * @var EntityManager
- */
- protected $em;
+ protected EntityManager $em;
+
+ private Security $security;
+
+ private AuthorizationHelper $authorizationHelper;
+
+ private const SUPPORTED_CONTEXTS = [ 'person', 'center' ];
- public function __construct(EntityManager $em)
+ public function __construct(EntityManager $em, Security $security, AuthorizationHelper $authorizationHelper)
{
$this->em = $em;
+ $this->security = $security;
+ $this->authorizationHelper = $authorizationHelper;
}
/**
@@ -72,25 +82,74 @@ abstract class AbstractTimelineAccompanyingPeriod implements TimelineProviderInt
*/
protected function basicFetchQuery($context, array $args)
{
- if ($context !== 'person') {
+ if (FALSE === \in_array($context, self::SUPPORTED_CONTEXTS)) {
throw new \LogicException('TimelineAccompanyingPeriod is not able '
. 'to render context '.$context);
}
$metadata = $this->em
- ->getClassMetadata('ChillPersonBundle:AccompanyingPeriod')
+ ->getClassMetadata(AccompanyingPeriodParticipation::class)
;
return array(
- 'id' => $metadata->getColumnName('id'),
- 'FROM' => $metadata->getTableName(),
- 'WHERE' => sprintf('%s = %d',
- $metadata
- ->getAssociationMapping('person')['joinColumns'][0]['name'],
- $args['person']->getId())
+ 'id' => "{$metadata->getTableName()}.{$metadata->getColumnName('id')}",
+ 'FROM' => $this->buildFromClause($context),
+ 'WHERE' => $this->buildWhereClause($context, $args)
);
}
+ private function buildFromClause($context)
+ {
+ $period = $this->em->getClassMetadata(AccompanyingPeriod::class);
+ $participation = $this->em->getClassMetadata(AccompanyingPeriodParticipation::class);
+ $person = $this->em->getClassMetadata(Person::class);
+ $join = $participation->getAssociationMapping('accompanyingPeriod')['joinColumns'][0];
+ $joinPerson = $participation->getAssociationMapping('person')['joinColumns'][0];
+
+ if ($context === 'person') {
+ return "{$period->getTableName()} ".
+ "JOIN {$participation->getTableName()} ".
+ "ON {$participation->getTableName()}.{$join['name']} = ".
+ "{$period->getTableName()}.{$join['referencedColumnName']}";
+ } else {
+ return "{$period->getTableName()} ".
+ "JOIN {$participation->getTableName()} ".
+ "ON {$participation->getTableName()}.{$join['name']} = ".
+ "{$period->getTableName()}.{$join['referencedColumnName']} ".
+ "JOIN {$person->getTableName()} ".
+ "ON {$participation->getTableName()}.{$joinPerson['name']} = ".
+ "{$person->getTableName()}.{$joinPerson['referencedColumnName']}"
+ ;
+ }
+
+ }
+
+ protected function buildWhereClause($context, array $args): array
+ {
+ $participation = $this->em->getClassMetadata(AccompanyingPeriodParticipation::class);
+ $join = $participation->getAssociationMapping('person')['joinColumns'][0];
+ $person = $this->em->getClassMetadata(Person::class);
+ $joinCenter = $person->getAssociationMapping('center')['joinColumns'][0];
+ $allowedCenters = $this->authorizationHelper->filterReachableCenters($this->security->getUser(), $args['centers'], PersonVoter::SEE);
+
+ if ($context === 'center') {
+ $params = [];
+ $questionMarks = [];
+ $query = "{$person->getTableName()}.{$joinCenter['name']} IN (";
+ foreach ($allowedCenters as $c) {
+ $questionMarks[] = '?';
+ $params[] = $c->getId();
+ }
+ $query .= \implode(", ", $questionMarks).")";
+
+ return [$query, $params];
+ } elseif ($context === 'person') {
+ return [ "{$participation->getTableName()}.{$join['name']} = ?", [ $args['person']->getId() ]];
+ }
+
+ throw new \LogicException("this context is not supported: $context");
+ }
+
/**
* return the expected response for TimelineProviderInterface::getEntityTemplate
*
@@ -104,7 +163,7 @@ abstract class AbstractTimelineAccompanyingPeriod implements TimelineProviderInt
{
return array(
'template' => $template,
- 'template_data' => ['person' => $args['person'], 'period' => $entity]
+ 'template_data' => ['period' => $entity, 'context' => $context]
);
}
}
diff --git a/src/Bundle/ChillPersonBundle/Timeline/TimelineAccompanyingPeriodClosing.php b/src/Bundle/ChillPersonBundle/Timeline/TimelineAccompanyingPeriodClosing.php
index 05aebbfd4..2e3d953fa 100644
--- a/src/Bundle/ChillPersonBundle/Timeline/TimelineAccompanyingPeriodClosing.php
+++ b/src/Bundle/ChillPersonBundle/Timeline/TimelineAccompanyingPeriodClosing.php
@@ -21,6 +21,7 @@ namespace Chill\PersonBundle\Timeline;
use Chill\MainBundle\Timeline\TimelineProviderInterface;
use Doctrine\ORM\EntityManager;
+use Chill\PersonBundle\Entity\AccompanyingPeriod;
/**
* Provide information for opening periods to timeline
@@ -46,22 +47,27 @@ class TimelineAccompanyingPeriodClosing extends AbstractTimelineAccompanyingPeri
public function fetchQuery($context, array $args)
{
$metadata = $this->em
- ->getClassMetadata('ChillPersonBundle:AccompanyingPeriod');
+ ->getClassMetadata(AccompanyingPeriod::class);
$data = $this->basicFetchQuery($context, $args);
$data['type'] = 'accompanying_period_closing';
$data['date'] = $metadata->getColumnName('closingDate');
- $data['WHERE'] = sprintf('%s = %d AND %s IS NOT NULL',
- $metadata
- ->getAssociationMapping('person')['joinColumns'][0]['name'],
- $args['person']->getId(),
- $metadata->getColumnName('closingDate'))
- ;
+ $data['WHERE'] = $this->buildWhereClause($context, $args);
return $data;
}
+ protected function buildWhereClause($context, array $args): array
+ {
+ list($query, $params) = parent::buildWhereClause($context, $args);
+ $period = $this->em->getClassMetadata(AccompanyingPeriod::class);
+
+ $query .= " AND {$period->getColumnName('closingDate')} IS NOT NULL ";
+
+ return [ $query, $params ];
+ }
+
/**
*
* {@inheritDoc}
diff --git a/src/Bundle/ChillPersonBundle/Timeline/TimelineAccompanyingPeriodOpening.php b/src/Bundle/ChillPersonBundle/Timeline/TimelineAccompanyingPeriodOpening.php
index f8789b088..5d3222789 100644
--- a/src/Bundle/ChillPersonBundle/Timeline/TimelineAccompanyingPeriodOpening.php
+++ b/src/Bundle/ChillPersonBundle/Timeline/TimelineAccompanyingPeriodOpening.php
@@ -21,11 +21,10 @@ namespace Chill\PersonBundle\Timeline;
use Chill\MainBundle\Timeline\TimelineProviderInterface;
use Doctrine\ORM\EntityManager;
+use Chill\PersonBundle\Entity\AccompanyingPeriod;
/**
* Provide information for opening periods to timeline
- *
- * @author Julien Fastré
*/
class TimelineAccompanyingPeriodOpening extends AbstractTimelineAccompanyingPeriod
{
@@ -46,7 +45,7 @@ class TimelineAccompanyingPeriodOpening extends AbstractTimelineAccompanyingPeri
public function fetchQuery($context, array $args)
{
$metadata = $this->em
- ->getClassMetadata('ChillPersonBundle:AccompanyingPeriod');
+ ->getClassMetadata(AccompanyingPeriod::class);
$data = $this->basicFetchQuery($context, $args);
diff --git a/src/Bundle/ChillPersonBundle/config/services.yaml b/src/Bundle/ChillPersonBundle/config/services.yaml
index bccb69b0d..3d257dc7b 100644
--- a/src/Bundle/ChillPersonBundle/config/services.yaml
+++ b/src/Bundle/ChillPersonBundle/config/services.yaml
@@ -16,17 +16,23 @@ services:
class: Chill\PersonBundle\Timeline\TimelineAccompanyingPeriodOpening
arguments:
- "@doctrine.orm.entity_manager"
+ - '@Symfony\Component\Security\Core\Security'
+ - '@Chill\MainBundle\Security\Authorization\AuthorizationHelper'
public: true
tags:
- { name: chill.timeline, context: 'person' }
+ - { name: chill.timeline, context: 'center' }
chill.person.timeline.accompanying_period_closing:
class: Chill\PersonBundle\Timeline\TimelineAccompanyingPeriodClosing
arguments:
- "@doctrine.orm.entity_manager"
+ - '@Symfony\Component\Security\Core\Security'
+ - '@Chill\MainBundle\Security\Authorization\AuthorizationHelper'
public: true
tags:
- { name: chill.timeline, context: 'person' }
+ - { name: chill.timeline, context: 'center' }
chill.person.security.authorization.person:
class: Chill\PersonBundle\Security\Authorization\PersonVoter
diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml
index 1fe6e3956..0918f8864 100644
--- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml
+++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml
@@ -150,6 +150,8 @@ Update accompanying period: Mettre à jour une période d'accompagnement
'Closing motive': 'Motif de clôture'
'Person details': 'Détails de la personne'
'Update details for %name%': 'Modifier détails de %name%'
+An accompanying period ends: Une periode d'accompagnement se clôture
+An accompanying period starts: Une période d'accompagnement est ouverte
Any accompanying periods are open: Aucune période d'accompagnement ouverte
An accompanying period is open: Une période d'accompagnement est ouverte
Accompanying period list: Périodes d'accompagnement
@@ -162,11 +164,10 @@ Pediod closing form is not valid: Le formulaire n'est pas valide
Accompanying user: Accompagnant
No accompanying user: Aucun accompagnant
No data given: Pas d'information
+Participants: Personnes impliquées
# pickAPersonType
Pick a person: Choisir une personne
-#address
-Since %date%: Depuis le %date%
No address given: Pas d'adresse renseignée
The address has been successfully updated: L'adresse a été mise à jour avec succès
Update address for %name%: Mettre à jour une adresse pour %name%