mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge remote-tracking branch 'origin/master' into 110-export-editable
This commit is contained in:
commit
9f0fdb031a
6
.changes/unreleased/Fixed-20230621-132851.yaml
Normal file
6
.changes/unreleased/Fixed-20230621-132851.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
kind: Fixed
|
||||||
|
body: '[Accompanying period comments]: order comments from the most recent to the
|
||||||
|
oldest, in the list'
|
||||||
|
time: 2023-06-21T13:28:51.282714011+02:00
|
||||||
|
custom:
|
||||||
|
Issue: ""
|
5
.changes/unreleased/Fixed-20230621-135912.yaml
Normal file
5
.changes/unreleased/Fixed-20230621-135912.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
kind: Fixed
|
||||||
|
body: 'Api: filter social action to keep only the currently activated'
|
||||||
|
time: 2023-06-21T13:59:12.57760217+02:00
|
||||||
|
custom:
|
||||||
|
Issue: ""
|
5
.changes/unreleased/Fixed-20230621-141828.yaml
Normal file
5
.changes/unreleased/Fixed-20230621-141828.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
kind: Fixed
|
||||||
|
body: Fix deletion and re-creation of filiation relationship
|
||||||
|
time: 2023-06-21T14:18:28.437876316+02:00
|
||||||
|
custom:
|
||||||
|
Issue: "82"
|
17
.changes/v2.1.0.md
Normal file
17
.changes/v2.1.0.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
## v2.1.0 - 2023-06-12
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* [docgen] allow to pick a third party when generating a document in context Activity, AccompanyingPeriod
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
* ([#111](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/111)) List of "my accompanying periods": separate the active and closed periods in two different lists, and show the inactive_long and inactive_short periods
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
* ([#105](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/105)) Rights are checked for display of 'accompanying period' tab in household menu. Rights are also checked for creation of 'accompanying period' from within household context
|
||||||
|
|
||||||
|
### DX
|
||||||
|
|
||||||
|
* Add methods to RegroupmentRepository and fullfill Center / Regroupment Doctrine mapping
|
12
.changes/v2.2.0.md
Normal file
12
.changes/v2.2.0.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
## v2.2.0 - 2023-06-18
|
||||||
|
### Feature
|
||||||
|
* When navigating from a workflow regarding to an evaluation's document to an accompanying course, scroll directly to the document, and blink to highlight this document
|
||||||
|
* Add notification to accompanying period work and work's evaluation's documents
|
||||||
|
* ([#113](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/113))[Export] Filter accompanying period by step at date: allow to pick multiple steps
|
||||||
|
* ([#113](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/113))[export] add a filter on accompanying period: filter by step between two dates
|
||||||
|
### Fixed
|
||||||
|
* use the correct annotation for the association between PersonCurrentCenter and Person
|
||||||
|
* ([#58](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/58))Fix birthdate timezone in PersonRenderBox
|
||||||
|
* ([#55](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/55))Fix the notification counter
|
||||||
|
### DX
|
||||||
|
* DQL function OVERLAPSI: simplify expression in postgresql
|
3
.changes/v2.2.1.md
Normal file
3
.changes/v2.2.1.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
## v2.2.1 - 2023-06-19
|
||||||
|
### Fixed
|
||||||
|
* ([#114](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/114)) [notification on document evaluation] fix entityId and return path when adding a notification on a document in an evaluation
|
@ -6,7 +6,7 @@ versionExt: md
|
|||||||
versionFormat: '## {{.Version}} - {{.Time.Format "2006-01-02"}}'
|
versionFormat: '## {{.Version}} - {{.Time.Format "2006-01-02"}}'
|
||||||
kindFormat: '### {{.Kind}}'
|
kindFormat: '### {{.Kind}}'
|
||||||
changeFormat: >-
|
changeFormat: >-
|
||||||
* {{ if not (eq .Custom.Issue "") }}([#{{ .Custom.Issue }}](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/{{ .Custom.Issue }})) {{- end }}{{.Body}}
|
* {{ if not (eq .Custom.Issue "") }}([#{{ .Custom.Issue }}](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/{{ .Custom.Issue }})) {{ end }}{{.Body}}
|
||||||
custom:
|
custom:
|
||||||
- key: Issue
|
- key: Issue
|
||||||
label: Issue number (on chill-bundles repository) (optional)
|
label: Issue number (on chill-bundles repository) (optional)
|
||||||
|
35
CHANGELOG.md
35
CHANGELOG.md
@ -6,6 +6,41 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
|
|||||||
and is generated by [Changie](https://github.com/miniscruff/changie).
|
and is generated by [Changie](https://github.com/miniscruff/changie).
|
||||||
|
|
||||||
|
|
||||||
|
## v2.2.1 - 2023-06-19
|
||||||
|
### Fixed
|
||||||
|
* ([#114](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/114)) [notification on document evaluation] fix entityId and return path when adding a notification on a document in an evaluation
|
||||||
|
|
||||||
|
## v2.2.0 - 2023-06-18
|
||||||
|
### Feature
|
||||||
|
* When navigating from a workflow regarding to an evaluation's document to an accompanying course, scroll directly to the document, and blink to highlight this document
|
||||||
|
* Add notification to accompanying period work and work's evaluation's documents
|
||||||
|
* ([#113](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/113))[Export] Filter accompanying period by step at date: allow to pick multiple steps
|
||||||
|
* ([#113](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/113))[export] add a filter on accompanying period: filter by step between two dates
|
||||||
|
### Fixed
|
||||||
|
* use the correct annotation for the association between PersonCurrentCenter and Person
|
||||||
|
* ([#58](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/58))Fix birthdate timezone in PersonRenderBox
|
||||||
|
* ([#55](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/55))Fix the notification counter
|
||||||
|
### DX
|
||||||
|
* DQL function OVERLAPSI: simplify expression in postgresql
|
||||||
|
|
||||||
|
## v2.1.0 - 2023-06-12
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* [docgen] allow to pick a third party when generating a document in context Activity, AccompanyingPeriod
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
* ([#111](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/111)) List of "my accompanying periods": separate the active and closed periods in two different lists, and show the inactive_long and inactive_short periods
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
* ([#105](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/105)) Rights are checked for display of 'accompanying period' tab in household menu. Rights are also checked for creation of 'accompanying period' from within household context
|
||||||
|
|
||||||
|
### DX
|
||||||
|
|
||||||
|
* Add methods to RegroupmentRepository and fullfill Center / Regroupment Doctrine mapping
|
||||||
|
|
||||||
## 2.0.0
|
## 2.0.0
|
||||||
|
|
||||||
* this is a release to relaunch our proceess of release with semantic versioning
|
* this is a release to relaunch our proceess of release with semantic versioning
|
||||||
|
@ -44,3 +44,9 @@ async function download_and_open(event: Event): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="sass">
|
||||||
|
i.fa::before {
|
||||||
|
color: var(--bs-dropdown-link-hover-color);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -88,3 +88,9 @@ async function download_and_open(event: Event): Promise<void> {
|
|||||||
console.log('open button should have been clicked');
|
console.log('open button should have been clicked');
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="sass">
|
||||||
|
i.fa::before {
|
||||||
|
color: var(--bs-dropdown-link-hover-color);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -40,5 +40,8 @@ async function beforeLeave(event: Event): Promise<true> {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="sass">
|
<style scoped lang="sass">
|
||||||
|
i.fa::before {
|
||||||
|
color: var(--bs-dropdown-link-hover-color);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{%- import "@ChillDocStore/Macro/macro.html.twig" as m -%}
|
{%- import "@ChillDocStore/Macro/macro.html.twig" as m -%}
|
||||||
<div
|
<div class="d-inline-flex"
|
||||||
data-download-buttons
|
data-download-buttons
|
||||||
data-stored-object="{{ document_json|json_encode|escape('html_attr') }}"
|
data-stored-object="{{ document_json|json_encode|escape('html_attr') }}"
|
||||||
data-can-edit="{{ can_edit ? '1' : '0' }}"
|
data-can-edit="{{ can_edit ? '1' : '0' }}"
|
||||||
|
@ -18,6 +18,7 @@ No document found: Aucun document trouvé
|
|||||||
The document is successfully registered: Le document est enregistré
|
The document is successfully registered: Le document est enregistré
|
||||||
The document is successfully updated: Le document est mis à jour
|
The document is successfully updated: Le document est mis à jour
|
||||||
Any description: Aucune description
|
Any description: Aucune description
|
||||||
|
See the document: Voir le document
|
||||||
|
|
||||||
document:
|
document:
|
||||||
Any title: Aucun titre
|
Any title: Aucun titre
|
||||||
|
@ -90,16 +90,14 @@ class OverlapsI extends FunctionNode
|
|||||||
|
|
||||||
if ($part instanceof PathExpression) {
|
if ($part instanceof PathExpression) {
|
||||||
return sprintf(
|
return sprintf(
|
||||||
"CASE WHEN %s IS NOT NULL THEN %s ELSE '%s'::date END",
|
"COALESCE(%s, '%s'::date)",
|
||||||
$part->dispatch($sqlWalker),
|
|
||||||
$part->dispatch($sqlWalker),
|
$part->dispatch($sqlWalker),
|
||||||
$p
|
$p
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sprintf(
|
return sprintf(
|
||||||
"CASE WHEN %s::date IS NOT NULL THEN %s::date ELSE '%s'::date END",
|
"COALESCE(%s::date, '%s'::date)",
|
||||||
$part->dispatch($sqlWalker),
|
|
||||||
$part->dispatch($sqlWalker),
|
$part->dispatch($sqlWalker),
|
||||||
$p
|
$p
|
||||||
);
|
);
|
||||||
|
@ -48,12 +48,19 @@ class Center implements HasCenterInterface
|
|||||||
*/
|
*/
|
||||||
private string $name = '';
|
private string $name = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Collection<Regroupment>
|
||||||
|
* @ORM\ManyToMany(targetEntity=Regroupment::class, mappedBy="centers")
|
||||||
|
*/
|
||||||
|
private Collection $regroupments;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Center constructor.
|
* Center constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->groupCenters = new \Doctrine\Common\Collections\ArrayCollection();
|
$this->groupCenters = new ArrayCollection();
|
||||||
|
$this->regroupments = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -106,6 +113,14 @@ class Center implements HasCenterInterface
|
|||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection<Regroupment>
|
||||||
|
*/
|
||||||
|
public function getRegroupments(): Collection
|
||||||
|
{
|
||||||
|
return $this->regroupments;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $name
|
* @param $name
|
||||||
*
|
*
|
||||||
|
@ -22,11 +22,12 @@ use Doctrine\ORM\Mapping as ORM;
|
|||||||
class Regroupment
|
class Regroupment
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var Center
|
|
||||||
* @ORM\ManyToMany(
|
* @ORM\ManyToMany(
|
||||||
* targetEntity=Center::class
|
* targetEntity=Center::class,
|
||||||
|
* inversedBy="regroupments"
|
||||||
* )
|
* )
|
||||||
* @ORM\Id
|
* @ORM\Id
|
||||||
|
* @var Collection<Center>
|
||||||
*/
|
*/
|
||||||
private Collection $centers;
|
private Collection $centers;
|
||||||
|
|
||||||
@ -52,6 +53,26 @@ class Regroupment
|
|||||||
$this->centers = new ArrayCollection();
|
$this->centers = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function addCenter(Center $center): self
|
||||||
|
{
|
||||||
|
if (!$this->centers->contains($center)) {
|
||||||
|
$this->centers->add($center);
|
||||||
|
$center->getRegroupments()->add($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeCenter(Center $center): self
|
||||||
|
{
|
||||||
|
if ($this->centers->contains($center)) {
|
||||||
|
$this->centers->removeElement($center);
|
||||||
|
$center->getRegroupments()->removeElement($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function getCenters(): Collection
|
public function getCenters(): Collection
|
||||||
{
|
{
|
||||||
return $this->centers;
|
return $this->centers;
|
||||||
|
@ -31,7 +31,7 @@ class RegroupmentType extends AbstractType
|
|||||||
->add('centers', EntityType::class, [
|
->add('centers', EntityType::class, [
|
||||||
'class' => Center::class,
|
'class' => Center::class,
|
||||||
'multiple' => true,
|
'multiple' => true,
|
||||||
'attr' => ['class' => 'select2'],
|
'expanded' => true,
|
||||||
])
|
])
|
||||||
->add('isActive', CheckboxType::class, [
|
->add('isActive', CheckboxType::class, [
|
||||||
'label' => 'Actif ?',
|
'label' => 'Actif ?',
|
||||||
|
@ -34,9 +34,13 @@ class NotificationPresence
|
|||||||
$this->notificationRepository = $notificationRepository;
|
$this->notificationRepository = $notificationRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function countNotificationsForClassAndEntity(string $relatedEntityClass, int $relatedEntityId): array
|
/**
|
||||||
|
* @param list<array{relatedEntityClass: class-string, relatedEntityId: int}> $more
|
||||||
|
* @return array{unread: int, sent: int, total: int}
|
||||||
|
*/
|
||||||
|
public function countNotificationsForClassAndEntity(string $relatedEntityClass, int $relatedEntityId, array $more = [], array $options = []): array
|
||||||
{
|
{
|
||||||
if (array_key_exists($relatedEntityClass, $this->cache) && array_key_exists($relatedEntityId, $this->cache[$relatedEntityClass])) {
|
if ([] === $more && array_key_exists($relatedEntityClass, $this->cache) && array_key_exists($relatedEntityId, $this->cache[$relatedEntityClass])) {
|
||||||
return $this->cache[$relatedEntityClass][$relatedEntityId];
|
return $this->cache[$relatedEntityClass][$relatedEntityId];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,21 +50,25 @@ class NotificationPresence
|
|||||||
$counter = $this->notificationRepository->countNotificationByRelatedEntityAndUserAssociated(
|
$counter = $this->notificationRepository->countNotificationByRelatedEntityAndUserAssociated(
|
||||||
$relatedEntityClass,
|
$relatedEntityClass,
|
||||||
$relatedEntityId,
|
$relatedEntityId,
|
||||||
$user
|
$user,
|
||||||
|
$more
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ([] === $more) {
|
||||||
$this->cache[$relatedEntityClass][$relatedEntityId] = $counter;
|
$this->cache[$relatedEntityClass][$relatedEntityId] = $counter;
|
||||||
|
}
|
||||||
|
|
||||||
return $counter;
|
return $counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ['unread' => 0, 'read' => 0];
|
return ['unread' => 0, 'sent' => 0, 'total' => 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param list<array{relatedEntityClass: class-string, relatedEntityId: int}> $more
|
||||||
* @return array|Notification[]
|
* @return array|Notification[]
|
||||||
*/
|
*/
|
||||||
public function getNotificationsForClassAndEntity(string $relatedEntityClass, int $relatedEntityId): array
|
public function getNotificationsForClassAndEntity(string $relatedEntityClass, int $relatedEntityId, array $more = []): array
|
||||||
{
|
{
|
||||||
$user = $this->security->getUser();
|
$user = $this->security->getUser();
|
||||||
|
|
||||||
@ -68,7 +76,8 @@ class NotificationPresence
|
|||||||
return $this->notificationRepository->findNotificationByRelatedEntityAndUserAssociated(
|
return $this->notificationRepository->findNotificationByRelatedEntityAndUserAssociated(
|
||||||
$relatedEntityClass,
|
$relatedEntityClass,
|
||||||
$relatedEntityId,
|
$relatedEntityId,
|
||||||
$user
|
$user,
|
||||||
|
$more
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,24 +34,30 @@ class NotificationTwigExtensionRuntime implements RuntimeExtensionInterface
|
|||||||
$this->urlGenerator = $urlGenerator;
|
$this->urlGenerator = $urlGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function counterNotificationFor(Environment $environment, string $relatedEntityClass, int $relatedEntityId, array $options = []): string
|
public function counterNotificationFor(Environment $environment, string $relatedEntityClass, int $relatedEntityId, array $more = [], array $options = []): string
|
||||||
{
|
{
|
||||||
return $environment->render(
|
return $environment->render(
|
||||||
'@ChillMain/Notification/extension_counter_notifications_for.html.twig',
|
'@ChillMain/Notification/extension_counter_notifications_for.html.twig',
|
||||||
[
|
[
|
||||||
'counter' => $this->notificationPresence->countNotificationsForClassAndEntity($relatedEntityClass, $relatedEntityId),
|
'counter' => $this->notificationPresence->countNotificationsForClassAndEntity($relatedEntityClass, $relatedEntityId, $more),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function countNotificationsFor(string $relatedEntityClass, int $relatedEntityId, array $options = []): array
|
/**
|
||||||
|
* @param list<array{relatedEntityClass: class-string, relatedEntityId: int}> $more
|
||||||
|
*/
|
||||||
|
public function countNotificationsFor(string $relatedEntityClass, int $relatedEntityId, array $more = [], array $options = []): array
|
||||||
{
|
{
|
||||||
return $this->notificationPresence->countNotificationsForClassAndEntity($relatedEntityClass, $relatedEntityId);
|
return $this->notificationPresence->countNotificationsForClassAndEntity($relatedEntityClass, $relatedEntityId, $more);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function listNotificationsFor(Environment $environment, string $relatedEntityClass, int $relatedEntityId, array $options = []): string
|
/**
|
||||||
|
* @param list<array{relatedEntityClass: class-string, relatedEntityId: int}> $more
|
||||||
|
*/
|
||||||
|
public function listNotificationsFor(Environment $environment, string $relatedEntityClass, int $relatedEntityId, array $more = [], array $options = []): string
|
||||||
{
|
{
|
||||||
$notifications = $this->notificationPresence->getNotificationsForClassAndEntity($relatedEntityClass, $relatedEntityId);
|
$notifications = $this->notificationPresence->getNotificationsForClassAndEntity($relatedEntityClass, $relatedEntityId, $more);
|
||||||
|
|
||||||
if ([] === $notifications) {
|
if ([] === $notifications) {
|
||||||
return '';
|
return '';
|
||||||
|
@ -29,6 +29,15 @@ final class NotificationRepository implements ObjectRepository
|
|||||||
|
|
||||||
private EntityRepository $repository;
|
private EntityRepository $repository;
|
||||||
|
|
||||||
|
private const BASE_COUNTER_SQL = <<<'SQL'
|
||||||
|
SELECT
|
||||||
|
SUM((EXISTS (SELECT 1 AS c FROM chill_main_notification_addresses_unread cmnau WHERE user_id = :userid and cmnau.notification_id = cmn.id))::int) AS unread,
|
||||||
|
SUM((cmn.sender_id = :userid)::int) AS sent,
|
||||||
|
SUM((EXISTS (SELECT 1 AS c FROM chill_main_notification_addresses_user cmnau_all WHERE user_id = :userid and cmnau_all.notification_id = cmn.id))::int) + SUM((cmn.sender_id = :userid)::int) AS total
|
||||||
|
FROM chill_main_notification cmn
|
||||||
|
SQL;
|
||||||
|
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $entityManager)
|
public function __construct(EntityManagerInterface $entityManager)
|
||||||
{
|
{
|
||||||
$this->em = $entityManager;
|
$this->em = $entityManager;
|
||||||
@ -51,29 +60,45 @@ final class NotificationRepository implements ObjectRepository
|
|||||||
->getSingleScalarResult();
|
->getSingleScalarResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function countNotificationByRelatedEntityAndUserAssociated(string $relatedEntityClass, int $relatedEntityId, User $user): array
|
/**
|
||||||
|
* @param list<array{relatedEntityClass: class-string, relatedEntityId: int}> $more
|
||||||
|
* @return array{unread: int, sent: int, total: int}
|
||||||
|
*/
|
||||||
|
public function countNotificationByRelatedEntityAndUserAssociated(string $relatedEntityClass, int $relatedEntityId, User $user, array $more = []): array
|
||||||
{
|
{
|
||||||
|
$sqlParams = ['relatedEntityClass' => $relatedEntityClass, 'relatedEntityId' => $relatedEntityId, 'userid' => $user->getId()];
|
||||||
|
|
||||||
|
if ([] === $more) {
|
||||||
if (null === $this->notificationByRelatedEntityAndUserAssociatedStatement) {
|
if (null === $this->notificationByRelatedEntityAndUserAssociatedStatement) {
|
||||||
$sql =
|
$sql = self::BASE_COUNTER_SQL . ' WHERE relatedentityclass = :relatedEntityClass AND relatedentityid = :relatedEntityId AND sender_id IS NOT NULL';
|
||||||
'SELECT
|
|
||||||
SUM((EXISTS (SELECT 1 AS c FROM chill_main_notification_addresses_unread cmnau WHERE user_id = :userid and cmnau.notification_id = cmn.id))::int) AS unread,
|
|
||||||
SUM((cmn.sender_id = :userid)::int) AS sent,
|
|
||||||
COUNT(cmn.*) AS total
|
|
||||||
FROM chill_main_notification cmn
|
|
||||||
WHERE relatedentityclass = :relatedEntityClass AND relatedentityid = :relatedEntityId AND sender_id IS NOT NULL';
|
|
||||||
|
|
||||||
$this->notificationByRelatedEntityAndUserAssociatedStatement =
|
$this->notificationByRelatedEntityAndUserAssociatedStatement =
|
||||||
$this->em->getConnection()->prepare($sql);
|
$this->em->getConnection()->prepare($sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
$results = $this->notificationByRelatedEntityAndUserAssociatedStatement
|
$results = $this->notificationByRelatedEntityAndUserAssociatedStatement
|
||||||
->executeQuery(['relatedEntityClass' => $relatedEntityClass, 'relatedEntityId' => $relatedEntityId, 'userid' => $user->getId()]);
|
->executeQuery($sqlParams);
|
||||||
|
|
||||||
$result = $results->fetchAssociative();
|
$result = $results->fetchAssociative();
|
||||||
|
|
||||||
$results->free();
|
$results->free();
|
||||||
|
} else {
|
||||||
|
$wheres = [];
|
||||||
|
foreach ([
|
||||||
|
['relatedEntityClass' => $relatedEntityClass, 'relatedEntityId' => $relatedEntityId],
|
||||||
|
...$more
|
||||||
|
] as $k => ['relatedEntityClass' => $relClass, 'relatedEntityId' => $relId]) {
|
||||||
|
$wheres[] = "(relatedEntityClass = :relatedEntityClass_{$k} AND relatedEntityId = :relatedEntityId_{$k})";
|
||||||
|
$sqlParams["relatedEntityClass_{$k}"] = $relClass;
|
||||||
|
$sqlParams["relatedEntityId_{$k}"] = $relId;
|
||||||
|
}
|
||||||
|
|
||||||
return $result;
|
$sql = self::BASE_COUNTER_SQL . ' WHERE sender_id IS NOT NULL AND (' . implode(' OR ', $wheres) . ')';
|
||||||
|
|
||||||
|
$result = $this->em->getConnection()->fetchAssociative($sql, $sqlParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_map(fn (?int $number) => $number ?? 0, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function countUnreadByUser(User $user): int
|
public function countUnreadByUser(User $user): int
|
||||||
@ -167,8 +192,8 @@ final class NotificationRepository implements ObjectRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed|null $limit
|
* @param int|null $limit
|
||||||
* @param mixed|null $offset
|
* @param int|null $offset
|
||||||
*
|
*
|
||||||
* @return Notification[]
|
* @return Notification[]
|
||||||
*/
|
*/
|
||||||
@ -178,13 +203,15 @@ final class NotificationRepository implements ObjectRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param list<array{relatedEntityClass: class-string, relatedEntityId: int}> $more
|
||||||
* @return array|Notification[]
|
* @return array|Notification[]
|
||||||
*/
|
*/
|
||||||
public function findNotificationByRelatedEntityAndUserAssociated(string $relatedEntityClass, int $relatedEntityId, User $user): array
|
public function findNotificationByRelatedEntityAndUserAssociated(string $relatedEntityClass, int $relatedEntityId, User $user, array $more): array
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
$this->buildQueryNotificationByRelatedEntityAndUserAssociated($relatedEntityClass, $relatedEntityId, $user)
|
$this->buildQueryNotificationByRelatedEntityAndUserAssociated($relatedEntityClass, $relatedEntityId, $user, $more)
|
||||||
->select('n')
|
->select('n')
|
||||||
|
->addOrderBy('n.date', 'DESC')
|
||||||
->getQuery()
|
->getQuery()
|
||||||
->getResult();
|
->getResult();
|
||||||
}
|
}
|
||||||
@ -222,13 +249,36 @@ final class NotificationRepository implements ObjectRepository
|
|||||||
return Notification::class;
|
return Notification::class;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildQueryNotificationByRelatedEntityAndUserAssociated(string $relatedEntityClass, int $relatedEntityId, User $user): QueryBuilder
|
/**
|
||||||
|
* @param list<array{relatedEntityClass: class-string, relatedEntityId: int}> $more
|
||||||
|
*/
|
||||||
|
private function buildQueryNotificationByRelatedEntityAndUserAssociated(string $relatedEntityClass, int $relatedEntityId, User $user, array $more = []): QueryBuilder
|
||||||
{
|
{
|
||||||
$qb = $this->repository->createQueryBuilder('n');
|
$qb = $this->repository->createQueryBuilder('n');
|
||||||
|
|
||||||
|
// add condition for related entity (in main arguments, and in more)
|
||||||
|
$or = $qb->expr()->orX($qb->expr()->andX(
|
||||||
|
$qb->expr()->eq('n.relatedEntityClass', ':relatedEntityClass'),
|
||||||
|
$qb->expr()->eq('n.relatedEntityId', ':relatedEntityId')
|
||||||
|
));
|
||||||
$qb
|
$qb
|
||||||
->where($qb->expr()->eq('n.relatedEntityClass', ':relatedEntityClass'))
|
->setParameter('relatedEntityClass', $relatedEntityClass)
|
||||||
->andWhere($qb->expr()->eq('n.relatedEntityId', ':relatedEntityId'))
|
->setParameter('relatedEntityId', $relatedEntityId);
|
||||||
|
|
||||||
|
foreach ($more as $k => ['relatedEntityClass' => $relatedClass, 'relatedEntityId' => $relatedId]) {
|
||||||
|
$or->add(
|
||||||
|
$qb->expr()->andX(
|
||||||
|
$qb->expr()->eq('n.relatedEntityClass', ':relatedEntityClass_'.$k),
|
||||||
|
$qb->expr()->eq('n.relatedEntityId', ':relatedEntityId_'.$k)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$qb
|
||||||
|
->setParameter('relatedEntityClass_'.$k, $relatedClass)
|
||||||
|
->setParameter('relatedEntityId_'.$k, $relatedId);
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb
|
||||||
|
->andWhere($or)
|
||||||
->andWhere($qb->expr()->isNotNull('n.sender'))
|
->andWhere($qb->expr()->isNotNull('n.sender'))
|
||||||
->andWhere(
|
->andWhere(
|
||||||
$qb->expr()->orX(
|
$qb->expr()->orX(
|
||||||
@ -236,8 +286,6 @@ final class NotificationRepository implements ObjectRepository
|
|||||||
$qb->expr()->eq('n.sender', ':user')
|
$qb->expr()->eq('n.sender', ':user')
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->setParameter('relatedEntityClass', $relatedEntityClass)
|
|
||||||
->setParameter('relatedEntityId', $relatedEntityId)
|
|
||||||
->setParameter('user', $user);
|
->setParameter('user', $user);
|
||||||
|
|
||||||
return $qb;
|
return $qb;
|
||||||
|
@ -14,6 +14,8 @@ namespace Chill\MainBundle\Repository;
|
|||||||
use Chill\MainBundle\Entity\Regroupment;
|
use Chill\MainBundle\Entity\Regroupment;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
use Doctrine\ORM\NonUniqueResultException;
|
||||||
|
use Doctrine\ORM\NoResultException;
|
||||||
use Doctrine\Persistence\ObjectRepository;
|
use Doctrine\Persistence\ObjectRepository;
|
||||||
|
|
||||||
final class RegroupmentRepository implements ObjectRepository
|
final class RegroupmentRepository implements ObjectRepository
|
||||||
@ -59,6 +61,30 @@ final class RegroupmentRepository implements ObjectRepository
|
|||||||
return $this->repository->findOneBy($criteria, $orderBy);
|
return $this->repository->findOneBy($criteria, $orderBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws NonUniqueResultException
|
||||||
|
* @throws NoResultException
|
||||||
|
*/
|
||||||
|
public function findOneByName(string $name): ?Regroupment
|
||||||
|
{
|
||||||
|
return $this->repository->createQueryBuilder('r')
|
||||||
|
->where('LOWER(r.name) = LOWER(:searched)')
|
||||||
|
->setParameter('searched', $name)
|
||||||
|
->getQuery()
|
||||||
|
->getSingleResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<Regroupment>
|
||||||
|
*/
|
||||||
|
public function findRegroupmentAssociatedToNoCenter(): array
|
||||||
|
{
|
||||||
|
return $this->repository->createQueryBuilder('r')
|
||||||
|
->where('SIZE(r.centers) = 0')
|
||||||
|
->getQuery()
|
||||||
|
->getResult();
|
||||||
|
}
|
||||||
|
|
||||||
public function getClassName()
|
public function getClassName()
|
||||||
{
|
{
|
||||||
return Regroupment::class;
|
return Regroupment::class;
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
const buildLinkCreate = function (relatedEntityClass: string, relatedEntityId: number, to: number | null, returnPath: string | null): string
|
||||||
|
{
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
params.append('entityClass', relatedEntityClass);
|
||||||
|
params.append('entityId', relatedEntityId.toString());
|
||||||
|
|
||||||
|
if (null !== to) {
|
||||||
|
params.append('tos[0]', to.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null !== returnPath) {
|
||||||
|
params.append('returnPath', returnPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return `/fr/notification/create?${params.toString()}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
buildLinkCreate,
|
||||||
|
}
|
@ -16,21 +16,19 @@ use Chill\MainBundle\Pagination\PaginatorFactory;
|
|||||||
use Chill\MainBundle\Serializer\Model\Collection;
|
use Chill\MainBundle\Serializer\Model\Collection;
|
||||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||||
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
|
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
|
||||||
|
use Symfony\Component\Clock\ClockInterface;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
use function count;
|
use function count;
|
||||||
|
|
||||||
class SocialWorkSocialActionApiController extends ApiController
|
final class SocialWorkSocialActionApiController extends ApiController
|
||||||
{
|
{
|
||||||
private PaginatorFactory $paginator;
|
public function __construct(
|
||||||
|
private readonly SocialIssueRepository $socialIssueRepository,
|
||||||
private SocialIssueRepository $socialIssueRepository;
|
private readonly PaginatorFactory $paginator,
|
||||||
|
private readonly ClockInterface $clock,
|
||||||
public function __construct(SocialIssueRepository $socialIssueRepository, PaginatorFactory $paginator)
|
) {
|
||||||
{
|
|
||||||
$this->socialIssueRepository = $socialIssueRepository;
|
|
||||||
$this->paginator = $paginator;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function listBySocialIssueApi($id, Request $request)
|
public function listBySocialIssueApi($id, Request $request)
|
||||||
@ -42,7 +40,10 @@ class SocialWorkSocialActionApiController extends ApiController
|
|||||||
throw $this->createNotFoundException('socialIssue not found');
|
throw $this->createNotFoundException('socialIssue not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
$socialActions = $socialIssue->getRecursiveSocialActions()->toArray();
|
$socialActions = SocialAction::filterRemoveDeactivatedActions(
|
||||||
|
$socialIssue->getRecursiveSocialActions()->toArray(),
|
||||||
|
\DateTime::createFromImmutable($this->clock->now())
|
||||||
|
);
|
||||||
|
|
||||||
usort($socialActions, static fn (SocialAction $sa, SocialAction $sb) => $sa->getOrdering() <=> $sb->getOrdering());
|
usort($socialActions, static fn (SocialAction $sa, SocialAction $sb) => $sa->getOrdering() <=> $sb->getOrdering());
|
||||||
|
|
||||||
|
@ -12,9 +12,11 @@ declare(strict_types=1);
|
|||||||
namespace Chill\PersonBundle\Controller;
|
namespace Chill\PersonBundle\Controller;
|
||||||
|
|
||||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
use Chill\PersonBundle\Repository\AccompanyingPeriodRepository;
|
use Chill\PersonBundle\Repository\AccompanyingPeriodRepository;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
|
||||||
class UserAccompanyingPeriodController extends AbstractController
|
class UserAccompanyingPeriodController extends AbstractController
|
||||||
@ -32,12 +34,24 @@ class UserAccompanyingPeriodController extends AbstractController
|
|||||||
/**
|
/**
|
||||||
* @Route("/{_locale}/person/accompanying-periods/my", name="chill_person_accompanying_period_user")
|
* @Route("/{_locale}/person/accompanying-periods/my", name="chill_person_accompanying_period_user")
|
||||||
*/
|
*/
|
||||||
public function listAction(Request $request)
|
public function listAction(Request $request): Response
|
||||||
{
|
{
|
||||||
$total = $this->accompanyingPeriodRepository->countBy(['user' => $this->getUser(), 'step' => ['CONFIRMED', 'CLOSED']]);
|
$active = $request->query->getBoolean('active', true);
|
||||||
|
$steps = match ($active) {
|
||||||
|
true => [
|
||||||
|
AccompanyingPeriod::STEP_CONFIRMED,
|
||||||
|
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG,
|
||||||
|
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT,
|
||||||
|
],
|
||||||
|
false => [
|
||||||
|
AccompanyingPeriod::STEP_CLOSED,
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
$total = $this->accompanyingPeriodRepository->countBy(['user' => $this->getUser(), 'step' => $steps]);
|
||||||
$pagination = $this->paginatorFactory->create($total);
|
$pagination = $this->paginatorFactory->create($total);
|
||||||
$accompanyingPeriods = $this->accompanyingPeriodRepository->findBy(
|
$accompanyingPeriods = $this->accompanyingPeriodRepository->findBy(
|
||||||
['user' => $this->getUser(), 'step' => ['CONFIRMED', 'CLOSED']],
|
['user' => $this->getUser(), 'step' => $steps],
|
||||||
['openingDate' => 'DESC'],
|
['openingDate' => 'DESC'],
|
||||||
$pagination->getItemsPerPage(),
|
$pagination->getItemsPerPage(),
|
||||||
$pagination->getCurrentPageFirstItemNumber()
|
$pagination->getCurrentPageFirstItemNumber()
|
||||||
@ -46,13 +60,14 @@ class UserAccompanyingPeriodController extends AbstractController
|
|||||||
return $this->render('@ChillPerson/AccompanyingPeriod/user_periods_list.html.twig', [
|
return $this->render('@ChillPerson/AccompanyingPeriod/user_periods_list.html.twig', [
|
||||||
'accompanyingPeriods' => $accompanyingPeriods,
|
'accompanyingPeriods' => $accompanyingPeriods,
|
||||||
'pagination' => $pagination,
|
'pagination' => $pagination,
|
||||||
|
'active' => $active,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/{_locale}/person/accompanying-periods/my/drafts", name="chill_person_accompanying_period_draft_user")
|
* @Route("/{_locale}/person/accompanying-periods/my/drafts", name="chill_person_accompanying_period_draft_user")
|
||||||
*/
|
*/
|
||||||
public function listDraftsAction(Request $request)
|
public function listDraftsAction(): Response
|
||||||
{
|
{
|
||||||
$total = $this->accompanyingPeriodRepository->countBy(['user' => $this->getUser(), 'step' => 'DRAFT']);
|
$total = $this->accompanyingPeriodRepository->countBy(['user' => $this->getUser(), 'step' => 'DRAFT']);
|
||||||
$pagination = $this->paginatorFactory->create($total);
|
$pagination = $this->paginatorFactory->create($total);
|
||||||
|
@ -185,7 +185,9 @@ class AccompanyingPeriod implements
|
|||||||
* cascade={"persist", "remove"},
|
* cascade={"persist", "remove"},
|
||||||
* orphanRemoval=true
|
* orphanRemoval=true
|
||||||
* )
|
* )
|
||||||
|
* @ORM\OrderBy({"createdAt": "DESC", "id": "DESC"})
|
||||||
* @Assert\NotBlank(groups={AccompanyingPeriod::STEP_DRAFT})
|
* @Assert\NotBlank(groups={AccompanyingPeriod::STEP_DRAFT})
|
||||||
|
* @var Collection<Comment>
|
||||||
*/
|
*/
|
||||||
private Collection $comments;
|
private Collection $comments;
|
||||||
|
|
||||||
@ -705,10 +707,11 @@ class AccompanyingPeriod implements
|
|||||||
->comments
|
->comments
|
||||||
->filter(
|
->filter(
|
||||||
static fn (Comment $c): bool => $c !== $pinnedComment
|
static fn (Comment $c): bool => $c !== $pinnedComment
|
||||||
);
|
)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCreatedAt(): ?DateTime
|
public function getCreatedAt(): DateTimeInterface
|
||||||
{
|
{
|
||||||
return $this->createdAt;
|
return $this->createdAt;
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,7 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
|
|||||||
* )
|
* )
|
||||||
* @Serializer\Groups({"read", "docgen:read"})
|
* @Serializer\Groups({"read", "docgen:read"})
|
||||||
* @ORM\OrderBy({"startDate": "DESC", "id": "DESC"})
|
* @ORM\OrderBy({"startDate": "DESC", "id": "DESC"})
|
||||||
|
* @var Collection<AccompanyingPeriodWorkEvaluation>
|
||||||
*
|
*
|
||||||
* @internal /!\ the serialization for write evaluations is handled in `AccompanyingPeriodWorkDenormalizer`
|
* @internal /!\ the serialization for write evaluations is handled in `AccompanyingPeriodWorkDenormalizer`
|
||||||
*/
|
*/
|
||||||
@ -278,6 +279,9 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
|
|||||||
return $this->accompanyingPeriod;
|
return $this->accompanyingPeriod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection<AccompanyingPeriodWorkEvaluation>
|
||||||
|
*/
|
||||||
public function getAccompanyingPeriodWorkEvaluations(): Collection
|
public function getAccompanyingPeriodWorkEvaluations(): Collection
|
||||||
{
|
{
|
||||||
return $this->accompanyingPeriodWorkEvaluations;
|
return $this->accompanyingPeriodWorkEvaluations;
|
||||||
|
@ -79,6 +79,7 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU
|
|||||||
* )
|
* )
|
||||||
* @ORM\OrderBy({"createdAt": "DESC", "id": "DESC"})
|
* @ORM\OrderBy({"createdAt": "DESC", "id": "DESC"})
|
||||||
* @Serializer\Groups({"read"})
|
* @Serializer\Groups({"read"})
|
||||||
|
* @var Collection<AccompanyingPeriodWorkEvaluationDocument>
|
||||||
*/
|
*/
|
||||||
private Collection $documents;
|
private Collection $documents;
|
||||||
|
|
||||||
@ -204,7 +205,7 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Collection
|
* @return Collection<AccompanyingPeriodWorkEvaluationDocument>
|
||||||
*/
|
*/
|
||||||
public function getDocuments()
|
public function getDocuments()
|
||||||
{
|
{
|
||||||
|
@ -45,7 +45,7 @@ class PersonCenterCurrent
|
|||||||
private ?int $id = null;
|
private ?int $id = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToOne(targetEntity=Person::class, inversedBy="centerCurrent")
|
* @ORM\OneToOne(targetEntity=Person::class, inversedBy="centerCurrent")
|
||||||
*/
|
*/
|
||||||
private Person $person;
|
private Person $person;
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ use DateInterval;
|
|||||||
use DateTimeInterface;
|
use DateTimeInterface;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
|
use Doctrine\Common\Collections\ReadableCollection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||||
|
|
||||||
@ -295,6 +296,19 @@ class SocialAction
|
|||||||
return 0 < $this->getChildren()->count();
|
return 0 < $this->getChildren()->count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isDesactivated(\DateTime $atDate): bool
|
||||||
|
{
|
||||||
|
if (null !== $this->desactivationDate && $this->desactivationDate < $atDate) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->hasParent()) {
|
||||||
|
return $this->parent->isDesactivated($atDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function hasParent(): bool
|
public function hasParent(): bool
|
||||||
{
|
{
|
||||||
return $this->getParent() instanceof self;
|
return $this->getParent() instanceof self;
|
||||||
@ -401,4 +415,14 @@ class SocialAction
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function filterRemoveDeactivatedActions(ReadableCollection|array $actions, \DateTime $comparisonDate): ReadableCollection|array
|
||||||
|
{
|
||||||
|
$filterFn = fn (SocialAction $socialAction) => !$socialAction->isDesactivated($comparisonDate);
|
||||||
|
|
||||||
|
return match ($actions instanceof ReadableCollection) {
|
||||||
|
true => $actions->filter($filterFn),
|
||||||
|
false => array_filter($actions, $filterFn)
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,7 +253,7 @@ class SocialIssue
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Collection|SocialAction[] All the descendant social actions of all
|
* @return Collection<SocialAction> All the descendant social actions of all
|
||||||
* the descendants of the entity
|
* the descendants of the entity
|
||||||
*/
|
*/
|
||||||
public function getRecursiveSocialActions(): Collection
|
public function getRecursiveSocialActions(): Collection
|
||||||
@ -272,7 +272,7 @@ class SocialIssue
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Collection|SocialAction[]
|
* @return Collection<SocialAction>
|
||||||
*/
|
*/
|
||||||
public function getSocialActions(): Collection
|
public function getSocialActions(): Collection
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,125 @@
|
|||||||
|
<?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\PersonBundle\Export\Filter\AccompanyingCourseFilters;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Export\FilterInterface;
|
||||||
|
use Chill\MainBundle\Form\Type\PickRollingDateType;
|
||||||
|
use Chill\MainBundle\Service\RollingDate\RollingDate;
|
||||||
|
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
use function in_array;
|
||||||
|
|
||||||
|
class StepFilterBetweenDates implements FilterInterface
|
||||||
|
{
|
||||||
|
private const DEFAULT_CHOICE = [
|
||||||
|
AccompanyingPeriod::STEP_CONFIRMED,
|
||||||
|
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT,
|
||||||
|
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG,
|
||||||
|
];
|
||||||
|
|
||||||
|
private const STEPS = [
|
||||||
|
'course.draft' => AccompanyingPeriod::STEP_DRAFT,
|
||||||
|
'course.confirmed' => AccompanyingPeriod::STEP_CONFIRMED,
|
||||||
|
'course.closed' => AccompanyingPeriod::STEP_CLOSED,
|
||||||
|
'course.inactive_short' => AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT,
|
||||||
|
'course.inactive_long' => AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG,
|
||||||
|
];
|
||||||
|
|
||||||
|
private RollingDateConverterInterface $rollingDateConverter;
|
||||||
|
|
||||||
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
RollingDateConverterInterface $rollingDateConverter,
|
||||||
|
TranslatorInterface $translator
|
||||||
|
) {
|
||||||
|
$this->rollingDateConverter = $rollingDateConverter;
|
||||||
|
$this->translator = $translator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addRole(): ?string
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
|
{
|
||||||
|
$alias = 'acp_filter_by_step_between_dat_alias';
|
||||||
|
$steps = 'acp_filter_by_step_between_dat_steps';
|
||||||
|
$from = 'acp_filter_by_step_between_dat_from';
|
||||||
|
$to = 'acp_filter_by_step_between_dat_to';
|
||||||
|
|
||||||
|
$qb
|
||||||
|
->andWhere(
|
||||||
|
$qb->expr()->exists(
|
||||||
|
"SELECT 1 FROM " . AccompanyingPeriod\AccompanyingPeriodStepHistory::class . " {$alias} " .
|
||||||
|
"WHERE {$alias}.step IN (:{$steps}) AND OVERLAPSI ({$alias}.startDate, {$alias}.endDate),(:{$from}, :{$to}) = TRUE " .
|
||||||
|
"AND {$alias}.period = acp"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
->setParameter($from, $this->rollingDateConverter->convert($data['date_from']))
|
||||||
|
->setParameter($to, $this->rollingDateConverter->convert($data['date_to']))
|
||||||
|
->setParameter($steps, $data['accepted_steps_multi']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function applyOn()
|
||||||
|
{
|
||||||
|
return Declarations::ACP_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
|
{
|
||||||
|
$builder
|
||||||
|
->add('accepted_steps_multi', ChoiceType::class, [
|
||||||
|
'label' => 'export.filter.course.by_step.steps',
|
||||||
|
'choices' => self::STEPS,
|
||||||
|
'multiple' => true,
|
||||||
|
'expanded' => true,
|
||||||
|
])
|
||||||
|
->add('date_from', PickRollingDateType::class, [
|
||||||
|
'label' => 'export.filter.course.by_step.date_from',
|
||||||
|
])
|
||||||
|
->add('date_to', PickRollingDateType::class, [
|
||||||
|
'label' => 'export.filter.course.by_step.date_to',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFormDefaultData(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'accepted_steps_multi' => self::DEFAULT_CHOICE,
|
||||||
|
'date_from' => new RollingDate(RollingDate::T_YEAR_CURRENT_START),
|
||||||
|
'date_to' => new RollingDate(RollingDate::T_TODAY),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function describeAction($data, $format = 'string')
|
||||||
|
{
|
||||||
|
$steps = array_map(fn (string $step) => $this->translator->trans(array_flip(self::STEPS)[$step]), $data['accepted_steps_multi']);
|
||||||
|
|
||||||
|
return ['export.filter.course.by_step.Filtered by steps: only %step% and between %date_from% and %date_to%', [
|
||||||
|
'%step%' => implode(', ', $steps),
|
||||||
|
'%date_from%' => $this->rollingDateConverter->convert($data['date_from'])->format('d-m-Y'),
|
||||||
|
'%date_to%' => $this->rollingDateConverter->convert($data['date_to'])->format('d-m-Y'),
|
||||||
|
]];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle()
|
||||||
|
{
|
||||||
|
return 'export.filter.course.by_step.Filter by step between dates';
|
||||||
|
}
|
||||||
|
}
|
@ -23,11 +23,15 @@ use Symfony\Component\Form\FormBuilderInterface;
|
|||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
use function in_array;
|
use function in_array;
|
||||||
|
|
||||||
class StepFilter implements FilterInterface
|
class StepFilterOnDate implements FilterInterface
|
||||||
{
|
{
|
||||||
private const A = 'acp_filter_bystep_stephistories';
|
private const A = 'acp_filter_bystep_stephistories';
|
||||||
|
|
||||||
private const DEFAULT_CHOICE = AccompanyingPeriod::STEP_CONFIRMED;
|
private const DEFAULT_CHOICE = [
|
||||||
|
AccompanyingPeriod::STEP_CONFIRMED,
|
||||||
|
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT,
|
||||||
|
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG,
|
||||||
|
];
|
||||||
|
|
||||||
private const P = 'acp_step_filter_date';
|
private const P = 'acp_step_filter_date';
|
||||||
|
|
||||||
@ -79,7 +83,7 @@ class StepFilter implements FilterInterface
|
|||||||
$qb->expr()->in(self::A . '.step', ':acp_filter_by_step_steps')
|
$qb->expr()->in(self::A . '.step', ':acp_filter_by_step_steps')
|
||||||
)
|
)
|
||||||
->setParameter(self::P, $this->rollingDateConverter->convert($data['calc_date']))
|
->setParameter(self::P, $this->rollingDateConverter->convert($data['calc_date']))
|
||||||
->setParameter('acp_filter_by_step_steps', $data['accepted_steps']);
|
->setParameter('acp_filter_by_step_steps', $data['accepted_steps_multi']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn()
|
public function applyOn()
|
||||||
@ -90,32 +94,36 @@ class StepFilter implements FilterInterface
|
|||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
{
|
{
|
||||||
$builder
|
$builder
|
||||||
->add('accepted_steps', ChoiceType::class, [
|
->add('accepted_steps_multi', ChoiceType::class, [
|
||||||
|
'label' => 'export.filter.course.by_step.steps',
|
||||||
'choices' => self::STEPS,
|
'choices' => self::STEPS,
|
||||||
'multiple' => false,
|
'multiple' => true,
|
||||||
'expanded' => true,
|
'expanded' => true,
|
||||||
'empty_data' => self::DEFAULT_CHOICE,
|
|
||||||
])
|
])
|
||||||
->add('calc_date', PickRollingDateType::class, [
|
->add('calc_date', PickRollingDateType::class, [
|
||||||
'label' => 'export.filter.course.by_step.date_calc',
|
'label' => 'export.filter.course.by_step.date_calc',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFormDefaultData(): array
|
public function getFormDefaultData(): array
|
||||||
{
|
{
|
||||||
return ['accepted_steps' => self::DEFAULT_CHOICE, 'calc_date' => new RollingDate(RollingDate::T_TODAY)];
|
return [
|
||||||
|
'accepted_steps_multi' => self::DEFAULT_CHOICE,
|
||||||
|
'calc_date' => new RollingDate(RollingDate::T_TODAY),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function describeAction($data, $format = 'string')
|
public function describeAction($data, $format = 'string')
|
||||||
{
|
{
|
||||||
$step = array_flip(self::STEPS)[$data['accepted_steps']];
|
$steps = array_map(fn (string $step) => $this->translator->trans(array_flip(self::STEPS)[$step]), $data['accepted_steps_multi']);
|
||||||
|
|
||||||
return ['Filtered by steps: only %step%', [
|
return ['Filtered by steps: only %step%', [
|
||||||
'%step%' => $this->translator->trans($step),
|
'%step%' => implode(', ', $steps),
|
||||||
]];
|
]];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTitle()
|
public function getTitle()
|
||||||
{
|
{
|
||||||
return 'Filter by step';
|
return 'export.filter.course.by_step.Filter by step';
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -12,7 +12,9 @@ declare(strict_types=1);
|
|||||||
namespace Chill\PersonBundle\Menu;
|
namespace Chill\PersonBundle\Menu;
|
||||||
|
|
||||||
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
||||||
|
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||||
use Knp\Menu\MenuItem;
|
use Knp\Menu\MenuItem;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
class HouseholdMenuBuilder implements LocalMenuBuilderInterface
|
class HouseholdMenuBuilder implements LocalMenuBuilderInterface
|
||||||
@ -22,9 +24,12 @@ class HouseholdMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
*/
|
*/
|
||||||
protected $translator;
|
protected $translator;
|
||||||
|
|
||||||
public function __construct(TranslatorInterface $translator)
|
private Security $security;
|
||||||
|
|
||||||
|
public function __construct(TranslatorInterface $translator, Security $security)
|
||||||
{
|
{
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
|
$this->security = $security;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildMenu($menuId, MenuItem $menu, array $parameters): void
|
public function buildMenu($menuId, MenuItem $menu, array $parameters): void
|
||||||
@ -53,12 +58,14 @@ class HouseholdMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
], ])
|
], ])
|
||||||
->setExtras(['order' => 17]);
|
->setExtras(['order' => 17]);
|
||||||
|
|
||||||
|
if ($this->security->isGranted(AccompanyingPeriodVoter::SEE, $parameters['household'])) {
|
||||||
$menu->addChild($this->translator->trans('household.Accompanying period'), [
|
$menu->addChild($this->translator->trans('household.Accompanying period'), [
|
||||||
'route' => 'chill_person_household_accompanying_period',
|
'route' => 'chill_person_household_accompanying_period',
|
||||||
'routeParameters' => [
|
'routeParameters' => [
|
||||||
'household_id' => $household->getId(),
|
'household_id' => $household->getId(),
|
||||||
],])
|
],])
|
||||||
->setExtras(['order' => 20]);
|
->setExtras(['order' => 20]);
|
||||||
|
}
|
||||||
|
|
||||||
$menu->addChild($this->translator->trans('household.Addresses'), [
|
$menu->addChild($this->translator->trans('household.Addresses'), [
|
||||||
'route' => 'chill_person_household_addresses',
|
'route' => 'chill_person_household_addresses',
|
||||||
|
@ -27,7 +27,7 @@ final class AccompanyingPeriodNotificationHandler implements NotificationHandler
|
|||||||
|
|
||||||
public function getTemplate(Notification $notification, array $options = []): string
|
public function getTemplate(Notification $notification, array $options = []): string
|
||||||
{
|
{
|
||||||
return 'ChillPersonBundle:AccompanyingPeriod:showInNotification.html.twig';
|
return '@ChillPerson/AccompanyingPeriod/showInNotification.html.twig';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTemplateData(Notification $notification, array $options = []): array
|
public function getTemplateData(Notification $notification, array $options = []): array
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
<?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\PersonBundle\Notification;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Notification;
|
||||||
|
use Chill\MainBundle\Notification\NotificationHandlerInterface;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
||||||
|
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocumentRepository;
|
||||||
|
|
||||||
|
final class AccompanyingPeriodWorkEvaluationDocumentNotificationHandler implements NotificationHandlerInterface
|
||||||
|
{
|
||||||
|
private AccompanyingPeriodWorkEvaluationDocumentRepository $accompanyingPeriodWorkEvaluationDocumentRepository;
|
||||||
|
|
||||||
|
public function __construct(AccompanyingPeriodWorkEvaluationDocumentRepository $accompanyingPeriodWorkEvaluationDocumentRepository)
|
||||||
|
{
|
||||||
|
$this->accompanyingPeriodWorkEvaluationDocumentRepository = $accompanyingPeriodWorkEvaluationDocumentRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTemplate(Notification $notification, array $options = []): string
|
||||||
|
{
|
||||||
|
return '@ChillPerson/AccompanyingCourseWork/showEvaluationDocumentInNotification.html.twig';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTemplateData(Notification $notification, array $options = []): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'notification' => $notification,
|
||||||
|
'document' => $doc = $this->accompanyingPeriodWorkEvaluationDocumentRepository->find($notification->getRelatedEntityId()),
|
||||||
|
'evaluation' => $doc?->getAccompanyingPeriodWorkEvaluation(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supports(Notification $notification, array $options = []): bool
|
||||||
|
{
|
||||||
|
return $notification->getRelatedEntityClass() === AccompanyingPeriodWorkEvaluationDocument::class;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
<?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\PersonBundle\Notification;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Notification;
|
||||||
|
use Chill\MainBundle\Notification\NotificationHandlerInterface;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
|
||||||
|
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository;
|
||||||
|
|
||||||
|
final class AccompanyingPeriodWorkNotificationHandler implements NotificationHandlerInterface
|
||||||
|
{
|
||||||
|
private AccompanyingPeriodWorkRepository $accompanyingPeriodWorkRepository;
|
||||||
|
|
||||||
|
public function __construct(AccompanyingPeriodWorkRepository $accompanyingPeriodWorkRepository)
|
||||||
|
{
|
||||||
|
$this->accompanyingPeriodWorkRepository = $accompanyingPeriodWorkRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTemplate(Notification $notification, array $options = []): string
|
||||||
|
{
|
||||||
|
return '@ChillPerson/AccompanyingCourseWork/showInNotification.html.twig';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTemplateData(Notification $notification, array $options = []): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'notification' => $notification,
|
||||||
|
'work' => $this->accompanyingPeriodWorkRepository->find($notification->getRelatedEntityId()),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supports(Notification $notification, array $options = []): bool
|
||||||
|
{
|
||||||
|
return $notification->getRelatedEntityClass() === AccompanyingPeriodWork::class;
|
||||||
|
}
|
||||||
|
}
|
@ -122,7 +122,8 @@
|
|||||||
<add-evaluation
|
<add-evaluation
|
||||||
v-for="e in pickedEvaluations"
|
v-for="e in pickedEvaluations"
|
||||||
v-bind:key="e.key"
|
v-bind:key="e.key"
|
||||||
v-bind:evaluation="e">
|
v-bind:evaluation="e"
|
||||||
|
v-bind:docAnchorId="this.docAnchorId">
|
||||||
</add-evaluation>
|
</add-evaluation>
|
||||||
|
|
||||||
<!-- box to add new evaluation -->
|
<!-- box to add new evaluation -->
|
||||||
@ -297,6 +298,20 @@
|
|||||||
></list-workflow-modal>
|
></list-workflow-modal>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<button v-if="AmIRefferer"
|
||||||
|
class="btn btn-notify"
|
||||||
|
@click="goToGenerateNotification(false)"
|
||||||
|
></button>
|
||||||
|
<template v-else>
|
||||||
|
<button id="btnGroupNotifyButtons" type="button" class="btn btn-notify dropdown-toggle" :title="$t('notification_send')" data-bs-toggle="dropdown" aria-expanded="false"> </button>
|
||||||
|
<ul class="dropdown-menu" aria-labelledby="btnGroupNotifyButtons">
|
||||||
|
<li><a class="dropdown-item" @click="goToGenerateNotification(true)">{{ $t('notification_notify_referrer') }}</a></li>
|
||||||
|
<li><a class="dropdown-item" @click="goToGenerateNotification(false)">{{ $t('notification_notify_any') }}</a></li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li v-if="!isPosting">
|
<li v-if="!isPosting">
|
||||||
<button class="btn btn-save" @click="submit">
|
<button class="btn btn-save" @click="submit">
|
||||||
{{ $t('action.save') }}
|
{{ $t('action.save') }}
|
||||||
@ -366,7 +381,10 @@ const i18n = {
|
|||||||
no_referrers: "Aucun agent traitant",
|
no_referrers: "Aucun agent traitant",
|
||||||
choose_referrers: "Choisir des agents traitants",
|
choose_referrers: "Choisir des agents traitants",
|
||||||
remove_referrer: "Enlever l'agent",
|
remove_referrer: "Enlever l'agent",
|
||||||
private_comment: "Commentaire privé"
|
private_comment: "Commentaire privé",
|
||||||
|
notification_notify_referrer: "Notifier le référent",
|
||||||
|
notification_notify_any: "Notifier d'autres utilisateurs",
|
||||||
|
notification_send: "Envoyer une notification",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -389,6 +407,7 @@ export default {
|
|||||||
i18n,
|
i18n,
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
docAnchorId: null,
|
||||||
isExpanded: false,
|
isExpanded: false,
|
||||||
editor: ClassicEditor,
|
editor: ClassicEditor,
|
||||||
showAddObjective: false,
|
showAddObjective: false,
|
||||||
@ -428,6 +447,13 @@ export default {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
beforeMount() {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
this.docAnchorId = urlParams.get('doc_id');
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.scrollToElement(this.docAnchorId);
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState([
|
...mapState([
|
||||||
'work',
|
'work',
|
||||||
@ -441,6 +467,7 @@ export default {
|
|||||||
'isPosting',
|
'isPosting',
|
||||||
'errors',
|
'errors',
|
||||||
'templatesAvailablesForAction',
|
'templatesAvailablesForAction',
|
||||||
|
'me',
|
||||||
]),
|
]),
|
||||||
...mapGetters([
|
...mapGetters([
|
||||||
'hasResultsForAction',
|
'hasResultsForAction',
|
||||||
@ -498,6 +525,10 @@ export default {
|
|||||||
this.$store.commit('setPersonsPickedIds', v);
|
this.$store.commit('setPersonsPickedIds', v);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
AmIRefferer() {
|
||||||
|
return (!(this.work.accompanyingPeriod.user && this.me
|
||||||
|
&& (this.work.accompanyingPeriod.user.id !== this.me.id)));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggleSelect() {
|
toggleSelect() {
|
||||||
@ -548,6 +579,19 @@ export default {
|
|||||||
return this.$store.dispatch('submit', callback)
|
return this.$store.dispatch('submit', callback)
|
||||||
.catch(e => { console.log(e); throw e; });
|
.catch(e => { console.log(e); throw e; });
|
||||||
},
|
},
|
||||||
|
goToGenerateNotification(tos) {
|
||||||
|
console.log('save before leave to notification');
|
||||||
|
const callback = (data) => {
|
||||||
|
if (tos === true) {
|
||||||
|
window.location.assign(`/fr/notification/create?entityClass=Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork&entityId=${this.work.id}&tos[0]=${this.work.accompanyingPeriod.user.id}&returnPath=/fr/person/accompanying-period/${this.work.accompanyingPeriod.id}/work`);
|
||||||
|
} else {
|
||||||
|
window.location.assign(`/fr/notification/create?entityClass=Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork&entityId=${this.work.id}&returnPath=/fr/person/accompanying-period/${this.work.accompanyingPeriod.id}/work`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.$store.dispatch('submit', callback)
|
||||||
|
.catch(e => {console.log(e); throw e});
|
||||||
|
},
|
||||||
submit() {
|
submit() {
|
||||||
this.$store.dispatch('submit').catch((error) => {
|
this.$store.dispatch('submit').catch((error) => {
|
||||||
if (error.name === 'ValidationException' || error.name === 'AccessException') {
|
if (error.name === 'ValidationException' || error.name === 'AccessException') {
|
||||||
@ -559,7 +603,7 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
saveFormOnTheFly(payload) {
|
saveFormOnTheFly(payload) {
|
||||||
console.log('saveFormOnTheFly: type', payload.type, ', data', payload.data);
|
// console.log('saveFormOnTheFly: type', payload.type, ', data', payload.data);
|
||||||
|
|
||||||
let body = { type: payload.type };
|
let body = { type: payload.type };
|
||||||
body.name = payload.data.text;
|
body.name = payload.data.text;
|
||||||
@ -581,6 +625,12 @@ export default {
|
|||||||
this.$toast.open({message: 'An error occurred'});
|
this.$toast.open({message: 'An error occurred'});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
scrollToElement(docAnchorId) {
|
||||||
|
const documentEl = document.getElementById(`document_${docAnchorId}`);
|
||||||
|
if (documentEl) {
|
||||||
|
documentEl.scrollIntoView({behavior: 'smooth'});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<form-evaluation ref="FormEvaluation" :key="evaluation.key" :evaluation="evaluation"></form-evaluation>
|
<form-evaluation ref="FormEvaluation" :key="evaluation.key" :evaluation="evaluation" :docAnchorId="docAnchorId"></form-evaluation>
|
||||||
|
|
||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
<li v-if="evaluation.workflows_availables.length > 0">
|
<li v-if="evaluation.workflows_availables.length > 0">
|
||||||
@ -85,7 +85,7 @@ export default {
|
|||||||
Modal,
|
Modal,
|
||||||
ListWorkflowModal,
|
ListWorkflowModal,
|
||||||
},
|
},
|
||||||
props: ['evaluation'],
|
props: ['evaluation', 'docAnchorId'],
|
||||||
i18n,
|
i18n,
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -79,8 +79,8 @@
|
|||||||
<h5>{{ $t('Documents') }} :</h5>
|
<h5>{{ $t('Documents') }} :</h5>
|
||||||
|
|
||||||
<div class="flex-table">
|
<div class="flex-table">
|
||||||
<div class="item-bloc" v-for="(d, i) in evaluation.documents" :key="d.id">
|
<div class="item-bloc" v-for="(d, i) in evaluation.documents" :key="d.id" :class="[parseInt(this.docAnchorId) === d.id ? 'bg-blink' : 'nothing']">
|
||||||
<div class="item-row">
|
<div :id="`document_${d.id}`" class="item-row">
|
||||||
<div class="input-group input-group-lg mb-3 row">
|
<div class="input-group input-group-lg mb-3 row">
|
||||||
<label class="col-sm-3 col-form-label">Titre du document:</label>
|
<label class="col-sm-3 col-form-label">Titre du document:</label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@ -116,13 +116,18 @@
|
|||||||
></list-workflow-modal>
|
></list-workflow-modal>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<add-async-upload
|
<button
|
||||||
:buttonTitle="$t('replace')"
|
v-if="AmIRefferer"
|
||||||
:options="asyncUploadOptions"
|
class="btn btn-notify"
|
||||||
:btnClasses="{'btn': true, 'btn-edit': true}"
|
@click="goToGenerateDocumentNotification(d, false)">
|
||||||
@addDocument="(arg) => replaceDocument(d, arg)"
|
</button>
|
||||||
>
|
<template v-else>
|
||||||
</add-async-upload>
|
<button id="btnGroupNotifyButtons" type="button" class="btn btn-notify dropdown-toggle" :title="$t('notification_send')" data-bs-toggle="dropdown" aria-expanded="false"> </button>
|
||||||
|
<ul class="dropdown-menu" aria-labelledby="btnGroupNotifyButtons">
|
||||||
|
<li><a class="dropdown-item" @click="goToGenerateDocumentNotification(d, true)">{{ $t('notification_notify_referrer') }}</a></li>
|
||||||
|
<li><a class="dropdown-item" @click="goToGenerateDocumentNotification(d, false)">{{ $t('notification_notify_any') }}</a></li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<document-action-buttons-group
|
<document-action-buttons-group
|
||||||
@ -133,6 +138,15 @@
|
|||||||
@on-stored-object-status-change="onStatusDocumentChanged"
|
@on-stored-object-status-change="onStatusDocumentChanged"
|
||||||
></document-action-buttons-group>
|
></document-action-buttons-group>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<add-async-upload
|
||||||
|
:buttonTitle="$t('replace')"
|
||||||
|
:options="asyncUploadOptions"
|
||||||
|
:btnClasses="{'btn': true, 'btn-edit': true}"
|
||||||
|
@addDocument="(arg) => replaceDocument(d, arg)"
|
||||||
|
>
|
||||||
|
</add-async-upload>
|
||||||
|
</li>
|
||||||
<li v-if="d.workflows.length === 0">
|
<li v-if="d.workflows.length === 0">
|
||||||
<a class="btn btn-delete" @click="removeDocument(d)">
|
<a class="btn btn-delete" @click="removeDocument(d)">
|
||||||
</a>
|
</a>
|
||||||
@ -187,6 +201,7 @@ import AddAsyncUpload from 'ChillDocStoreAssets/vuejs/_components/AddAsyncUpload
|
|||||||
import AddAsyncUploadDownloader from 'ChillDocStoreAssets/vuejs/_components/AddAsyncUploadDownloader.vue';
|
import AddAsyncUploadDownloader from 'ChillDocStoreAssets/vuejs/_components/AddAsyncUploadDownloader.vue';
|
||||||
import ListWorkflowModal from 'ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflowModal.vue';
|
import ListWorkflowModal from 'ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflowModal.vue';
|
||||||
import {buildLinkCreate} from 'ChillMainAssets/lib/entity-workflow/api.js';
|
import {buildLinkCreate} from 'ChillMainAssets/lib/entity-workflow/api.js';
|
||||||
|
import {buildLinkCreate as buildLinkCreateNotification} from 'ChillMainAssets/lib/entity-notification/api';
|
||||||
import DocumentActionButtonsGroup from "ChillDocStoreAssets/vuejs/DocumentActionButtonsGroup.vue";
|
import DocumentActionButtonsGroup from "ChillDocStoreAssets/vuejs/DocumentActionButtonsGroup.vue";
|
||||||
|
|
||||||
const i18n = {
|
const i18n = {
|
||||||
@ -214,14 +229,17 @@ const i18n = {
|
|||||||
template_title: "Nom du template",
|
template_title: "Nom du template",
|
||||||
browse: "Ajouter un document",
|
browse: "Ajouter un document",
|
||||||
replace: "Remplacer",
|
replace: "Remplacer",
|
||||||
download: "Télécharger le fichier existant"
|
download: "Télécharger le fichier existant",
|
||||||
|
notification_notify_referrer: "Notifier le référent",
|
||||||
|
notification_notify_any: "Notifier d'autres utilisateurs",
|
||||||
|
notification_send: "Envoyer une notification",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "FormEvaluation",
|
name: "FormEvaluation",
|
||||||
props: ['evaluation'],
|
props: ['evaluation', 'docAnchorId'],
|
||||||
components: {
|
components: {
|
||||||
ckeditor: CKEditor.component,
|
ckeditor: CKEditor.component,
|
||||||
PickTemplate,
|
PickTemplate,
|
||||||
@ -260,8 +278,14 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState([
|
...mapState([
|
||||||
'isPosting'
|
'isPosting',
|
||||||
|
'work',
|
||||||
|
'me',
|
||||||
]),
|
]),
|
||||||
|
AmIRefferer() {
|
||||||
|
return (!(this.$store.state.work.accompanyingPeriod.user && this.$store.state.me
|
||||||
|
&& (this.$store.state.work.accompanyingPeriod.user.id !== this.$store.state.me.id)));
|
||||||
|
},
|
||||||
getTemplatesAvailables() {
|
getTemplatesAvailables() {
|
||||||
return this.$store.getters.getTemplatesAvailablesForEvaluation(this.evaluation.evaluation);
|
return this.$store.getters.getTemplatesAvailablesForEvaluation(this.evaluation.evaluation);
|
||||||
},
|
},
|
||||||
@ -390,6 +414,20 @@ export default {
|
|||||||
return this.$store.dispatch('submit', callback)
|
return this.$store.dispatch('submit', callback)
|
||||||
.catch(e => { console.log(e); throw e; });
|
.catch(e => { console.log(e); throw e; });
|
||||||
},
|
},
|
||||||
|
goToGenerateDocumentNotification(document, tos) {
|
||||||
|
const callback = (data) => {
|
||||||
|
let evaluation = data.accompanyingPeriodWorkEvaluations.find(e => e.key === this.evaluation.key);
|
||||||
|
let updatedDocument = evaluation.documents.find(d => d.key === document.key);
|
||||||
|
window.location.assign(buildLinkCreateNotification(
|
||||||
|
'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument',
|
||||||
|
updatedDocument.id,
|
||||||
|
tos === true ? this.$store.state.work.accompanyingPeriod.user.id : null,
|
||||||
|
window.location.pathname + window.location.search + window.location.hash
|
||||||
|
));
|
||||||
|
};
|
||||||
|
return this.$store.dispatch('submit', callback)
|
||||||
|
.catch(e => {console.log(e); throw e});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -402,4 +440,19 @@ export default {
|
|||||||
ul.document-upload {
|
ul.document-upload {
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bg-blink{
|
||||||
|
color: #050000;
|
||||||
|
padding: 10px;
|
||||||
|
display: inline-block;
|
||||||
|
border-radius: 5px;
|
||||||
|
animation: blinkingBackground 2.2s infinite;
|
||||||
|
animation-iteration-count: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blinkingBackground{
|
||||||
|
0% { background-color: #ed776d;}
|
||||||
|
50% { background-color: #ffffff;}
|
||||||
|
100% { background-color: #ed776d;}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -35,6 +35,7 @@ const store = createStore({
|
|||||||
referrers: window.accompanyingCourseWork.referrers,
|
referrers: window.accompanyingCourseWork.referrers,
|
||||||
isPosting: false,
|
isPosting: false,
|
||||||
errors: [],
|
errors: [],
|
||||||
|
me: null
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
socialAction(state) {
|
socialAction(state) {
|
||||||
@ -130,6 +131,9 @@ const store = createStore({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
|
setWhoAmiI(state, me) {
|
||||||
|
state.me = me;
|
||||||
|
},
|
||||||
setEvaluationsPicked(state, evaluations) {
|
setEvaluationsPicked(state, evaluations) {
|
||||||
state.evaluationsPicked = evaluations.map((e, index) => {
|
state.evaluationsPicked = evaluations.map((e, index) => {
|
||||||
var k = Object.assign(e, {
|
var k = Object.assign(e, {
|
||||||
@ -385,6 +389,19 @@ const store = createStore({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
getWhoAmI({ commit }) {
|
||||||
|
let url = `/api/1.0/main/whoami.json`;
|
||||||
|
window.fetch(url)
|
||||||
|
.then(response => {
|
||||||
|
if (response.ok) {
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
throw { m: 'Error while retriving results for goal', s: response.status, b: response.body };
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
commit('setWhoAmiI', data);
|
||||||
|
});
|
||||||
|
},
|
||||||
updateThirdParty({ commit }, payload) {
|
updateThirdParty({ commit }, payload) {
|
||||||
commit('updateThirdParty', payload);
|
commit('updateThirdParty', payload);
|
||||||
},
|
},
|
||||||
@ -514,6 +531,7 @@ store.commit('setEvaluationsPicked', window.accompanyingCourseWork.accompanyingP
|
|||||||
store.dispatch('getReachablesResultsForAction');
|
store.dispatch('getReachablesResultsForAction');
|
||||||
store.dispatch('getReachablesGoalsForAction');
|
store.dispatch('getReachablesGoalsForAction');
|
||||||
store.dispatch('getReachablesEvaluationsForAction');
|
store.dispatch('getReachablesEvaluationsForAction');
|
||||||
|
store.dispatch('getWhoAmI');
|
||||||
|
|
||||||
store.state.evaluationsPicked.forEach(evaluation => {
|
store.state.evaluationsPicked.forEach(evaluation => {
|
||||||
store.dispatch('fetchTemplatesAvailablesForEvaluation', evaluation.evaluation)
|
store.dispatch('fetchTemplatesAvailablesForEvaluation', evaluation.evaluation)
|
||||||
|
@ -207,7 +207,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {dateToISO} from 'ChillMainAssets/chill/js/date';
|
import {dateToISO, ISOToDate} from 'ChillMainAssets/chill/js/date';
|
||||||
import AddressRenderBox from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
|
import AddressRenderBox from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
|
||||||
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
|
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
|
||||||
import BadgeEntity from 'ChillMainAssets/vuejs/_components/BadgeEntity.vue';
|
import BadgeEntity from 'ChillMainAssets/vuejs/_components/BadgeEntity.vue';
|
||||||
@ -262,7 +262,7 @@ export default {
|
|||||||
},
|
},
|
||||||
birthdate: function () {
|
birthdate: function () {
|
||||||
if (this.person.birthdate !== null || this.person.birthdate === "undefined") {
|
if (this.person.birthdate !== null || this.person.birthdate === "undefined") {
|
||||||
return new Date(this.person.birthdate.datetime);
|
return ISOToDate(this.person.birthdate.datetime);
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
# - displayAction: [true|false] default: false
|
# - displayAction: [true|false] default: false
|
||||||
# - displayFontSmall: [true|false] default: false
|
# - displayFontSmall: [true|false] default: false
|
||||||
#}
|
#}
|
||||||
<div class="item-bloc{% if displayContent is defined %} {{ displayContent }}{% endif %}{% if itemBlocClass is defined %} {{ itemBlocClass }}{% endif %}">
|
<div
|
||||||
|
class="item-bloc{% if displayContent is defined %} {{ displayContent }}{% endif %}{% if itemBlocClass is defined %} {{ itemBlocClass }}{% endif %}">
|
||||||
|
|
||||||
<div class="item-row">
|
<div class="item-row">
|
||||||
<h2 class="badge-title">
|
<h2 class="badge-title">
|
||||||
@ -111,9 +112,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if displayContent is not defined or displayContent == 'short' %}
|
{% if displayContent is not defined or displayContent == 'short' %}
|
||||||
<div class="item-row column{% if displayFontSmall is defined and displayFontSmall == true %} smallfont{% endif %}">
|
<div
|
||||||
{% include 'ChillPersonBundle:AccompanyingCourseWork:_objectifs_results_evaluations.html.twig' with {
|
class="item-row column{% if displayFontSmall is defined and displayFontSmall == true %} smallfont{% endif %}">
|
||||||
'displayContent': displayContent
|
{% include '@ChillPerson/AccompanyingCourseWork/_objectifs_results_evaluations.html.twig' with {
|
||||||
|
'displayContent': displayContent,
|
||||||
|
'onlyone': false
|
||||||
} %}
|
} %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -130,6 +133,27 @@
|
|||||||
{% if displayAction is defined and displayAction == true %}
|
{% if displayAction is defined and displayAction == true %}
|
||||||
<ul class="item-col record_actions">
|
<ul class="item-col record_actions">
|
||||||
<li>{{ macro.workflowButton(w) }}</li>
|
<li>{{ macro.workflowButton(w) }}</li>
|
||||||
|
{% if displayNotification is defined and displayNotification == true %}
|
||||||
|
<li>
|
||||||
|
<div class="d-grid gap-2 {% if accompanyingCourse.hasUser and accompanyingCourse.user is not same as(app.user) %}btn-group{% endif %}" {% if accompanyingCourse.hasUser and accompanyingCourse.user is not same as(app.user) %}role="group"{% endif %}>
|
||||||
|
{% if accompanyingCourse.hasUser and accompanyingCourse.user is not same as(app.user) %}
|
||||||
|
<button id="btnGroupNotifyButtons" type="button" class="btn btn-notify dropdown-toggle" title="{{ 'notification.Notify'|trans }}" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" aria-labelledby="btnGroupNotifyButtons">
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item" href="{{ chill_path_add_return_path('chill_main_notification_create', {'entityClass': 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork', 'entityId': w.id, 'tos': [accompanyingCourse.user.id]}) }}">{{ 'notification.Notify referrer'|trans }}</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item" href="{{ chill_path_add_return_path('chill_main_notification_create', {'entityClass': 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork', 'entityId': w.id}) }}">{{ 'notification.Notify any'|trans }}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<a class="btn btn-notify" title="{{ 'notification.Notify'|trans }}" href="{{ chill_path_add_return_path('chill_main_notification_create', {'entityClass': 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork', 'entityId': w.id}) }}">
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
<li>
|
<li>
|
||||||
<a class="btn btn-show" title="{{ 'Show'|trans }}"
|
<a class="btn btn-show" title="{{ 'Show'|trans }}"
|
||||||
href="{{ chill_path_add_return_path('chill_person_accompanying_period_work_show', {'id': w.id }) }}"
|
href="{{ chill_path_add_return_path('chill_person_accompanying_period_work_show', {'id': w.id }) }}"
|
||||||
@ -169,9 +193,11 @@
|
|||||||
<h2 class="chill-blue">{{ 'Dispositifs' }}</h2>
|
<h2 class="chill-blue">{{ 'Dispositifs' }}</h2>
|
||||||
|
|
||||||
<div class="flex-table">{# new flex-table wrapper #}
|
<div class="flex-table">{# new flex-table wrapper #}
|
||||||
<div class="item-bloc colored{% if displayContent is defined %} {{ displayContent }}{% endif %}{% if itemBlocClass is defined %} {{ itemBlocClass }}{% endif %}">
|
<div
|
||||||
|
class="item-bloc colored{% if displayContent is defined %} {{ displayContent }}{% endif %}{% if itemBlocClass is defined %} {{ itemBlocClass }}{% endif %}">
|
||||||
{% include 'ChillPersonBundle:AccompanyingCourseWork:_objectifs_results_evaluations.html.twig' with {
|
{% include 'ChillPersonBundle:AccompanyingCourseWork:_objectifs_results_evaluations.html.twig' with {
|
||||||
'displayContent': displayContent
|
'displayContent': displayContent,
|
||||||
|
'onlyone' : false
|
||||||
} %}
|
} %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -180,7 +206,8 @@
|
|||||||
<h2 class="chill-blue">{{ 'Comments'|trans }}</h2>
|
<h2 class="chill-blue">{{ 'Comments'|trans }}</h2>
|
||||||
|
|
||||||
<div class="flex-table">
|
<div class="flex-table">
|
||||||
<div class="item-bloc no-altern{% if displayContent is defined %} {{ displayContent }}{% endif %}{% if itemBlocClass is defined %} {{ itemBlocClass }}{% endif %}">
|
<div
|
||||||
|
class="item-bloc no-altern{% if displayContent is defined %} {{ displayContent }}{% endif %}{% if itemBlocClass is defined %} {{ itemBlocClass }}{% endif %}">
|
||||||
<h3 class="chill-beige">Public</h3>
|
<h3 class="chill-beige">Public</h3>
|
||||||
{% if w.note is not empty %}
|
{% if w.note is not empty %}
|
||||||
<blockquote class="chill-user-quote">
|
<blockquote class="chill-user-quote">
|
||||||
@ -191,7 +218,8 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if w.privateComment.hasCommentForUser(app.user) %}
|
{% if w.privateComment.hasCommentForUser(app.user) %}
|
||||||
<div class="item-bloc no-altern{% if displayContent is defined %} {{ displayContent }}{% endif %}{% if itemBlocClass is defined %} {{ itemBlocClass }}{% endif %}">
|
<div
|
||||||
|
class="item-bloc no-altern{% if displayContent is defined %} {{ displayContent }}{% endif %}{% if itemBlocClass is defined %} {{ itemBlocClass }}{% endif %}">
|
||||||
<h3 class="chill-beige">Privé</h3>
|
<h3 class="chill-beige">Privé</h3>
|
||||||
<blockquote class="chill-user-quote private-quote">
|
<blockquote class="chill-user-quote private-quote">
|
||||||
{{ w.privateComment.commentForUser(app.user)|chill_markdown_to_html }}
|
{{ w.privateComment.commentForUser(app.user)|chill_markdown_to_html }}
|
||||||
|
@ -1,7 +1,17 @@
|
|||||||
{% macro metadata(w) %}
|
{% macro metadata(w, include_notif_counter = true) %}
|
||||||
{% set notif_counter = chill_count_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork', w.id) %}
|
{% if include_notif_counter == true %}
|
||||||
|
{% set more = [] %}
|
||||||
|
{% for e in w.accompanyingPeriodWorkEvaluations %}
|
||||||
|
{% for d in e.documents %}
|
||||||
|
{% set more = more|merge([{'relatedEntityClass': 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument', 'relatedEntityId': d.id}]) %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% set notif_counter = chill_count_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork', w.id, more) %}
|
||||||
|
|
||||||
{% if notif_counter.total > 0 %}
|
{% if notif_counter.total > 0 %}
|
||||||
{{ chill_counter_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork', w.id) }}
|
{{ chill_counter_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork', w.id, more) }}
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% import '@ChillPerson/Macro/updatedBy.html.twig' as macro %}
|
{% import '@ChillPerson/Macro/updatedBy.html.twig' as macro %}
|
||||||
{{ macro.updatedBy(w) }}
|
{{ macro.updatedBy(w) }}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
# - displayContent: [short|long] default: short
|
# - displayContent: [short|long] default: short
|
||||||
#}
|
#}
|
||||||
{% if w.results|length > 0 %}
|
{% if w.results|length > 0 %}
|
||||||
|
|
||||||
<table class="obj-res-eval">
|
<table class="obj-res-eval">
|
||||||
<thead>
|
<thead>
|
||||||
<th class="obj"><h4 class="title_label">{{ 'accompanying_course_work.goal'|trans }}</h4></th>
|
<th class="obj"><h4 class="title_label">{{ 'accompanying_course_work.goal'|trans }}</h4></th>
|
||||||
@ -64,7 +65,9 @@
|
|||||||
</th>
|
</th>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
{% if onlyone|default(false) %}
|
||||||
{% for e in w.accompanyingPeriodWorkEvaluations %}
|
{% for e in w.accompanyingPeriodWorkEvaluations %}
|
||||||
|
{% if evalId is defined and evalId == e.id %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="eval">
|
<td class="eval">
|
||||||
<ul class="eval_title">
|
<ul class="eval_title">
|
||||||
@ -78,13 +81,15 @@
|
|||||||
|
|
||||||
{% if e.endDate %}
|
{% if e.endDate %}
|
||||||
<li>
|
<li>
|
||||||
<span class="item-key">{{ 'accompanying_course_work.end_date'|trans ~ ' : ' }}</span>
|
<span
|
||||||
|
class="item-key">{{ 'accompanying_course_work.end_date'|trans ~ ' : ' }}</span>
|
||||||
<b>{{ e.endDate|format_date('short') }}</b>
|
<b>{{ e.endDate|format_date('short') }}</b>
|
||||||
</li>
|
</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if displayContent is defined and displayContent == 'long' %}
|
{% if displayContent is defined and displayContent == 'long' %}
|
||||||
<li>
|
<li>
|
||||||
<span class="item-key">{{ 'accompanying_course_work.end_date'|trans ~ ' : ' }}</span>
|
<span
|
||||||
|
class="item-key">{{ 'accompanying_course_work.end_date'|trans ~ ' : ' }}</span>
|
||||||
<span class="chill-no-data-statement">{{ 'Not given'|trans }}</span>
|
<span class="chill-no-data-statement">{{ 'Not given'|trans }}</span>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -92,13 +97,15 @@
|
|||||||
|
|
||||||
{% if e.maxDate %}
|
{% if e.maxDate %}
|
||||||
<li>
|
<li>
|
||||||
<span class="item-key">{{ 'accompanying_course_work.max_date'|trans ~ ' : ' }}</span>
|
<span
|
||||||
|
class="item-key">{{ 'accompanying_course_work.max_date'|trans ~ ' : ' }}</span>
|
||||||
<b>{{ e.maxDate|format_date('short') }}</b>
|
<b>{{ e.maxDate|format_date('short') }}</b>
|
||||||
</li>
|
</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if displayContent is defined and displayContent == 'long' %}
|
{% if displayContent is defined and displayContent == 'long' %}
|
||||||
<li>
|
<li>
|
||||||
<span class="item-key">{{ 'accompanying_course_work.max_date'|trans ~ ' : ' }}</span>
|
<span
|
||||||
|
class="item-key">{{ 'accompanying_course_work.max_date'|trans ~ ' : ' }}</span>
|
||||||
<span class="chill-no-data-statement">{{ 'Not given'|trans }}</span>
|
<span class="chill-no-data-statement">{{ 'Not given'|trans }}</span>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -107,13 +114,15 @@
|
|||||||
{% if e.warningInterval and e.warningInterval.d > 0 %}
|
{% if e.warningInterval and e.warningInterval.d > 0 %}
|
||||||
<li>
|
<li>
|
||||||
{% set days = (e.warningInterval.d + e.warningInterval.m * 30) %}
|
{% set days = (e.warningInterval.d + e.warningInterval.m * 30) %}
|
||||||
<span class="item-key">{{ 'accompanying_course_work.warning_interval'|trans ~ ' : ' }}</span>
|
<span
|
||||||
|
class="item-key">{{ 'accompanying_course_work.warning_interval'|trans ~ ' : ' }}</span>
|
||||||
{{ 'accompanying_course_work.%days% days before max_date'|trans({'%days%': days }) }}
|
{{ 'accompanying_course_work.%days% days before max_date'|trans({'%days%': days }) }}
|
||||||
</li>
|
</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if displayContent is defined and displayContent == 'long' %}
|
{% if displayContent is defined and displayContent == 'long' %}
|
||||||
<li>
|
<li>
|
||||||
<span class="item-key">{{ 'accompanying_course_work.warning_interval'|trans ~ ' : ' }}</span>
|
<span
|
||||||
|
class="item-key">{{ 'accompanying_course_work.warning_interval'|trans ~ ' : ' }}</span>
|
||||||
<span class="chill-no-data-statement">{{ 'Not given'|trans }}</span>
|
<span class="chill-no-data-statement">{{ 'Not given'|trans }}</span>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -122,33 +131,153 @@
|
|||||||
{% if e.timeSpent is not null and e.timeSpent > 0 %}
|
{% if e.timeSpent is not null and e.timeSpent > 0 %}
|
||||||
<li>
|
<li>
|
||||||
{% set minutes = (e.timeSpent / 60) %}
|
{% set minutes = (e.timeSpent / 60) %}
|
||||||
<span class="item-key">{{ 'accompanying_course_work.timeSpent'|trans ~ ' : ' }}</span> {{ 'duration.minute'|trans({ '{m}' : minutes }) }}
|
<span
|
||||||
|
class="item-key">{{ 'accompanying_course_work.timeSpent'|trans ~ ' : ' }}</span> {{ 'duration.minute'|trans({ '{m}' : minutes }) }}
|
||||||
</li>
|
</li>
|
||||||
{% elseif displayContent is defined and displayContent == 'long' %}
|
{% elseif displayContent is defined and displayContent == 'long' %}
|
||||||
<li>
|
<li>
|
||||||
<span class="item-key">{{ 'accompanying_course_work.timeSpent'|trans ~ ' : ' }}</span>
|
<span
|
||||||
|
class="item-key">{{ 'accompanying_course_work.timeSpent'|trans ~ ' : ' }}</span>
|
||||||
<span class="chill-no-data-statement">{{ 'Not given'|trans }}</span>
|
<span class="chill-no-data-statement">{{ 'Not given'|trans }}</span>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
{% if recordAction is defined %}
|
||||||
|
{{ recordAction }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% for e in w.accompanyingPeriodWorkEvaluations %}
|
||||||
|
<tr>
|
||||||
|
<td class="eval">
|
||||||
|
<ul class="eval_title">
|
||||||
|
<li>
|
||||||
|
{{ e.evaluation.title|localize_translatable_string }}
|
||||||
|
<ul class="columns">
|
||||||
|
<li>
|
||||||
|
<span
|
||||||
|
class="item-key">{{ 'accompanying_course_work.start_date'|trans ~ ' : ' }}</span>
|
||||||
|
<b>{{ e.startDate|format_date('short') }}</b>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{% if e.endDate %}
|
||||||
|
<li>
|
||||||
|
<span
|
||||||
|
class="item-key">{{ 'accompanying_course_work.end_date'|trans ~ ' : ' }}</span>
|
||||||
|
<b>{{ e.endDate|format_date('short') }}</b>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
{% if displayContent is defined and displayContent == 'long' %}
|
||||||
|
<li>
|
||||||
|
<span
|
||||||
|
class="item-key">{{ 'accompanying_course_work.end_date'|trans ~ ' : ' }}</span>
|
||||||
|
<span class="chill-no-data-statement">{{ 'Not given'|trans }}</span>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if e.maxDate %}
|
||||||
|
<li>
|
||||||
|
<span
|
||||||
|
class="item-key">{{ 'accompanying_course_work.max_date'|trans ~ ' : ' }}</span>
|
||||||
|
<b>{{ e.maxDate|format_date('short') }}</b>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
{% if displayContent is defined and displayContent == 'long' %}
|
||||||
|
<li>
|
||||||
|
<span
|
||||||
|
class="item-key">{{ 'accompanying_course_work.max_date'|trans ~ ' : ' }}</span>
|
||||||
|
<span class="chill-no-data-statement">{{ 'Not given'|trans }}</span>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if e.warningInterval and e.warningInterval.d > 0 %}
|
||||||
|
<li>
|
||||||
|
{% set days = (e.warningInterval.d + e.warningInterval.m * 30) %}
|
||||||
|
<span
|
||||||
|
class="item-key">{{ 'accompanying_course_work.warning_interval'|trans ~ ' : ' }}</span>
|
||||||
|
{{ 'accompanying_course_work.%days% days before max_date'|trans({'%days%': days }) }}
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
{% if displayContent is defined and displayContent == 'long' %}
|
||||||
|
<li>
|
||||||
|
<span
|
||||||
|
class="item-key">{{ 'accompanying_course_work.warning_interval'|trans ~ ' : ' }}</span>
|
||||||
|
<span class="chill-no-data-statement">{{ 'Not given'|trans }}</span>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if e.timeSpent is not null and e.timeSpent > 0 %}
|
||||||
|
<li>
|
||||||
|
{% set minutes = (e.timeSpent / 60) %}
|
||||||
|
<span
|
||||||
|
class="item-key">{{ 'accompanying_course_work.timeSpent'|trans ~ ' : ' }}</span> {{ 'duration.minute'|trans({ '{m}' : minutes }) }}
|
||||||
|
</li>
|
||||||
|
{% elseif displayContent is defined and displayContent == 'long' %}
|
||||||
|
<li>
|
||||||
|
<span
|
||||||
|
class="item-key">{{ 'accompanying_course_work.timeSpent'|trans ~ ' : ' }}</span>
|
||||||
|
<span class="chill-no-data-statement">{{ 'Not given'|trans }}</span>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
{% if recordAction is defined %}
|
||||||
|
{{ recordAction }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if displayContent is defined and displayContent == 'long' %}
|
{% if displayContent is defined and displayContent == 'long' %}
|
||||||
|
|
||||||
{% if e.comment is not empty %}
|
{% if e.comment is not empty %}
|
||||||
<blockquote class="chill-user-quote">{{ e.comment|chill_entity_render_box }}</blockquote>
|
<blockquote
|
||||||
|
class="chill-user-quote">{{ e.comment|chill_entity_render_box }}</blockquote>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% import "@ChillDocStore/Macro/macro.html.twig" as m %}
|
{% import "@ChillDocStore/Macro/macro.html.twig" as m %}
|
||||||
{% import "@ChillDocStore/Macro/macro_mimeicon.html.twig" as mm %}
|
{% import "@ChillDocStore/Macro/macro_mimeicon.html.twig" as mm %}
|
||||||
|
|
||||||
{% if e.documents|length > 0 %}
|
{% if e.documents|length > 0 %}
|
||||||
<table class="table mt-4 mx-auto">
|
<table class="table table-hover align-middle mt-4 mx-auto">
|
||||||
{% for d in e.documents %}
|
{% for d in e.documents %}
|
||||||
<tr class="border-0">
|
<tr>
|
||||||
<td class="border-0">{{ d.title }}</td>
|
<td class="border-0">{{ d.title }}</td>
|
||||||
<td class="border-0">{{ mm.mimeIcon(d.storedObject.type) }}</td>
|
<td class="border-0">{{ mm.mimeIcon(d.storedObject.type) }}</td>
|
||||||
<td class="border-0 text-end">{{ d.storedObject|chill_document_button_group(d.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', w), {'small': true}) }}</td>
|
<td class="border-0 text-end">
|
||||||
|
{% if accompanyingCourse.hasUser and accompanyingCourse.user is not same as(app.user) %}
|
||||||
|
<button id="btnGroupNotifyButtons" type="button" class="btn btn-sm btn-notify dropdown-toggle" title="{{ 'notification.Notify'|trans }}"
|
||||||
|
data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" aria-labelledby="btnGroupNotifyButtons">
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item"
|
||||||
|
href="{{ chill_path_add_return_path('chill_main_notification_create', {
|
||||||
|
'entityClass': 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument',
|
||||||
|
'entityId': d.id, 'tos': [accompanyingCourse.user.id]}) }}">{{ 'notification.Notify referrer'|trans }}</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item"
|
||||||
|
href="{{ chill_path_add_return_path('chill_main_notification_create', {
|
||||||
|
'entityClass': 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument',
|
||||||
|
'entityId': d.id}) }}">{{ 'notification.Notify any'|trans }}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<a class="btn btn-notify btn-sm"
|
||||||
|
title="{{ 'notification.Notify'|trans }}"
|
||||||
|
href="{{ chill_path_add_return_path('chill_main_notification_create', {
|
||||||
|
'entityClass': 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument',
|
||||||
|
'entityId': d.id }) }}"></a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{{ d.storedObject|chill_document_button_group(d.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', w), {'small': true}) }}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
@ -161,6 +290,7 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -26,7 +26,8 @@
|
|||||||
'displayAction': true,
|
'displayAction': true,
|
||||||
'displayContent': 'short',
|
'displayContent': 'short',
|
||||||
'displayFontSmall': true,
|
'displayFontSmall': true,
|
||||||
'itemBlocClass': ''
|
'itemBlocClass': '',
|
||||||
|
'displayNotification': true
|
||||||
} %}
|
} %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -27,7 +27,20 @@
|
|||||||
'displayContent': 'long',
|
'displayContent': 'long',
|
||||||
'itemBlocClass': 'uniq extended',
|
'itemBlocClass': 'uniq extended',
|
||||||
} %}
|
} %}
|
||||||
<div class="p-3 mt-3">{{ macro.metadata(work) }}</div>
|
<div class="p-3 mt-3">{{ macro.metadata(work, false) }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="notification notification-list">
|
||||||
|
{% set more = [] %}
|
||||||
|
{% for e in work.accompanyingPeriodWorkEvaluations %}
|
||||||
|
{% for d in e.documents %}
|
||||||
|
{% set more = more|merge([{'relatedEntityClass': 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument', 'relatedEntityId': d.id}]) %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
{% set notifications = chill_list_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork', work.id, more) %}
|
||||||
|
{% if notifications is not empty %}
|
||||||
|
{{ notifications|raw }}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul class="record_actions sticky-form-buttons">
|
<ul class="record_actions sticky-form-buttons">
|
||||||
@ -36,6 +49,25 @@
|
|||||||
class="btn btn-cancel">{{ 'Back to the list'|trans }}</a>
|
class="btn btn-cancel">{{ 'Back to the list'|trans }}</a>
|
||||||
</li>
|
</li>
|
||||||
<li>{{ macro.workflowButton(work) }}</li>
|
<li>{{ macro.workflowButton(work) }}</li>
|
||||||
|
<li>
|
||||||
|
<div class="d-grid gap-2 {% if accompanyingCourse.hasUser and accompanyingCourse.user is not same as(app.user) %}btn-group{% endif %}" {% if accompanyingCourse.hasUser and accompanyingCourse.user is not same as(app.user) %}role="group"{% endif %}>
|
||||||
|
{% if accompanyingCourse.hasUser and accompanyingCourse.user is not same as(app.user) %}
|
||||||
|
<button id="btnGroupNotifyButtons" type="button" class="btn btn-notify dropdown-toggle" title="{{ 'notification.Notify'|trans }}" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" aria-labelledby="btnGroupNotifyButtons">
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item" href="{{ chill_path_add_return_path('chill_main_notification_create', {'entityClass': 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork', 'entityId': work.id, 'tos': [accompanyingCourse.user.id]}) }}">{{ 'notification.Notify referrer'|trans }}</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item" href="{{ chill_path_add_return_path('chill_main_notification_create', {'entityClass': 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork', 'entityId': work.id}) }}">{{ 'notification.Notify any'|trans }}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<a class="btn btn-notify" title="{{ 'notification.Notify'|trans }}" href="{{ chill_path_add_return_path('chill_main_notification_create', {'entityClass': 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork', 'entityId': work.id}) }}">
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
{% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', work) %}
|
{% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', work) %}
|
||||||
<li>
|
<li>
|
||||||
<a class="btn btn-edit"
|
<a class="btn btn-edit"
|
||||||
@ -47,7 +79,8 @@
|
|||||||
<li>
|
<li>
|
||||||
<a class="btn btn-delete"
|
<a class="btn btn-delete"
|
||||||
href="{{ path('chill_person_accompanying_period_work_delete', { 'id': work.id } ) }}"
|
href="{{ path('chill_person_accompanying_period_work_delete', { 'id': work.id } ) }}"
|
||||||
>{{ 'Delete'|trans }}</a>
|
title = "{{ 'Delete'|trans }}"
|
||||||
|
></a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -0,0 +1,134 @@
|
|||||||
|
{% if document is not null %}
|
||||||
|
{% import "@ChillDocStore/Macro/macro_mimeicon.html.twig" as mm %}
|
||||||
|
<div class="flex-table accompanying-course-work">
|
||||||
|
{% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_EVALUATION_DOCUMENT_SHOW', document) %}
|
||||||
|
{% set doc = document %}
|
||||||
|
<div class="item-bloc evaluation-item bg-chill-llight-gray">
|
||||||
|
<div class="item-row mb-2">
|
||||||
|
<h1>{{ "Document"|trans }}: {{ doc.title }}</h1>
|
||||||
|
</div>
|
||||||
|
<div class="item-row mb-2">
|
||||||
|
<h2 class="badge-title">
|
||||||
|
<span class="title_label"></span>
|
||||||
|
<span class="title_action">
|
||||||
|
{{ evaluation.accompanyingPeriodWork.socialAction|chill_entity_render_string }}
|
||||||
|
<ul class="small_in_title columns mt-1">
|
||||||
|
<li>
|
||||||
|
<span class="item-key">{{ 'accompanying_course_work.start_date'|trans ~ ' : ' }}</span>
|
||||||
|
<b>{{ evaluation.accompanyingPeriodWork.startDate|format_date('short') }}</b>
|
||||||
|
</li>
|
||||||
|
{% if evaluation.accompanyingPeriodWork.endDate %}
|
||||||
|
<li>
|
||||||
|
<span class="item-key">{{ 'accompanying_course_work.end_date'|trans ~ ' : ' }}</span>
|
||||||
|
<b>{{ evaluation.accompanyingPeriodWork.endDate|format_date('short') }}</b>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</span>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div class="item-row mb-2">
|
||||||
|
<div class="item-col" style="width: 17%;">
|
||||||
|
<h4 class="title_label">
|
||||||
|
{{ 'Participants'|trans }}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
<div class="item-col list">
|
||||||
|
{% for p in evaluation.accompanyingPeriodWork.persons %}
|
||||||
|
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||||
|
targetEntity: { name: 'person', id: p.id },
|
||||||
|
action: 'show',
|
||||||
|
displayBadge: true,
|
||||||
|
buttonText: p|chill_entity_render_string,
|
||||||
|
isDead: p.deathdate is not null
|
||||||
|
} %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-row column">
|
||||||
|
<table class="obj-res-eval my-3">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="eval">
|
||||||
|
<h4 class="title_label">
|
||||||
|
{{ 'Évaluation'|trans }}
|
||||||
|
</h4>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="eval">
|
||||||
|
<ul class="eval_title">
|
||||||
|
<li class="my-2">
|
||||||
|
{{ evaluation.evaluation.title|localize_translatable_string }}
|
||||||
|
<ul class="columns pt-2">
|
||||||
|
<li>
|
||||||
|
<span class="item-key">{{ 'accompanying_course_work.start_date'|trans ~ ' : ' }}</span>
|
||||||
|
<b>{{ evaluation.startDate|format_date('short') }}</b>
|
||||||
|
</li>
|
||||||
|
{% if evaluation.endDate %}
|
||||||
|
<li>
|
||||||
|
<span class="item-key">{{ 'accompanying_course_work.end_date'|trans ~ ' : ' }}</span>
|
||||||
|
<b>{{ evaluation.endDate|format_date('short') }}</b>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% if evaluation.maxDate %}
|
||||||
|
<li>
|
||||||
|
<span class="item-key">{{ 'accompanying_course_work.max_date'|trans ~ ' : ' }}</span>
|
||||||
|
<b>{{ evaluation.maxDate|format_date('short') }}</b>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% if evaluation.warningInterval and evaluation.warningInterval.d > 0 %}
|
||||||
|
<li>
|
||||||
|
{% set days = (evaluation.warningInterval.d + evaluation.warningInterval.m * 30) %}
|
||||||
|
<span class="item-key">{{ 'accompanying_course_work.warning_interval'|trans ~ ' : ' }}</span>
|
||||||
|
{{ 'accompanying_course_work.%days% days before max_date'|trans({'%days%': days }) }}
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
<li>
|
||||||
|
{% if evaluation.createdBy is not null %}
|
||||||
|
<span class="item-key">créé par</span>
|
||||||
|
<b>{{ evaluation.createdBy.username }}</b>
|
||||||
|
{% endif %}
|
||||||
|
{% if evaluation.createdAt is not null %}
|
||||||
|
<span class="item-key">{{ 'le'|trans }}</span>
|
||||||
|
<b>{{ evaluation.createdAt|format_date('short') }}</b>
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
{% if evaluation.comment %}
|
||||||
|
<blockquote class="chill-user-quote" style="margin-left: 0;">
|
||||||
|
{{ evaluation.comment }}
|
||||||
|
</blockquote>
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="item-row">
|
||||||
|
<ul class="record_actions">
|
||||||
|
<li>
|
||||||
|
<a class="btn btn-show"
|
||||||
|
href="{{ path('chill_person_accompanying_period_work_show', { 'id': document.accompanyingPeriodWorkEvaluation.accompanyingPeriodWork.id }) }}"
|
||||||
|
title="{{ 'See the document'|trans }}"></a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-warning border-warning border-1">
|
||||||
|
{{ 'This is the minimal period details'|trans ~ ': ' ~ document.id }}<br>
|
||||||
|
{{ 'You are getting a notification for a period you are not allowed to see'|trans }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-warning border-warning border-1">
|
||||||
|
{{ 'You are getting a notification for a period which does not exists any more'|trans }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
@ -0,0 +1,30 @@
|
|||||||
|
{% macro recordAction(work) %}
|
||||||
|
<li>
|
||||||
|
<a class="btn btn-show" title="{{ 'Show'|trans }}"
|
||||||
|
href="{{ chill_path_add_return_path('chill_person_accompanying_period_work_show', {'id': work.id }) }}"
|
||||||
|
></a>
|
||||||
|
</li>
|
||||||
|
{% endmacro %}
|
||||||
|
{% if work is not null %}
|
||||||
|
<div class="flex-table accompanying-course-work">
|
||||||
|
{% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_SEE', work) %}
|
||||||
|
{% include "@ChillPerson/AccompanyingCourseWork/_item.html.twig" with {
|
||||||
|
'itemBlocClass': 'bg-chill-llight-gray',
|
||||||
|
'displayAction': true,
|
||||||
|
'displayContent': 'short',
|
||||||
|
'displayFontSmall': true,
|
||||||
|
'displayNotification:':true,
|
||||||
|
'w': work
|
||||||
|
} %}
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-warning border-warning border-1">
|
||||||
|
{{ 'This is the minimal period details'|trans ~ ': ' ~ work.id }}<br>
|
||||||
|
{{ 'You are getting a notification for a period you are not allowed to see'|trans }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-warning border-warning border-1">
|
||||||
|
{{ 'You are getting a notification for a period which does not exists any more'|trans }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
@ -8,7 +8,7 @@
|
|||||||
{% if period is not null %}
|
{% if period is not null %}
|
||||||
<div class="flex-table">
|
<div class="flex-table">
|
||||||
{% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', period) %}
|
{% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', period) %}
|
||||||
{% include 'ChillPersonBundle:AccompanyingPeriod:_list_item.html.twig' with {
|
{% include "@ChillPerson/AccompanyingPeriod/_list_item.html.twig" with {
|
||||||
'recordAction': _self.recordAction(notification.relatedEntityId),
|
'recordAction': _self.recordAction(notification.relatedEntityId),
|
||||||
'itemBlocClass': 'bg-chill-llight-gray'
|
'itemBlocClass': 'bg-chill-llight-gray'
|
||||||
} %}
|
} %}
|
||||||
|
@ -17,6 +17,15 @@
|
|||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<h1>{{ 'My accompanying periods'|trans }}</h1>
|
<h1>{{ 'My accompanying periods'|trans }}</h1>
|
||||||
|
|
||||||
|
<ul class="nav nav-pills justify-content-center">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link {% if active == true %}active{% endif %}" aria-current="page" href="{{ chill_path_forward_return_path('chill_person_accompanying_period_user', {'active': true}) }}">{{ ['Confirmed'|trans, 'course.inactive_short'|trans, 'course.inactive_long'|trans]|join(', ') }}</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item ">
|
||||||
|
<a class="nav-link {% if active == false %}active{% endif %}" href="{{ chill_path_forward_return_path('chill_person_accompanying_period_user', {'active': false}) }}">{{ 'course.closed'|trans }}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<p>{{ 'Number of periods'|trans }}: <span class="badge rounded-pill bg-primary">{{ pagination.totalItems }}</span></p>
|
<p>{{ 'Number of periods'|trans }}: <span class="badge rounded-pill bg-primary">{{ pagination.totalItems }}</span></p>
|
||||||
|
|
||||||
<div class="flex-table accompanyingcourse-list">
|
<div class="flex-table accompanyingcourse-list">
|
||||||
|
@ -40,13 +40,14 @@
|
|||||||
{{ 'Household summary'|trans }}
|
{{ 'Household summary'|trans }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{# TODO: add ACL to check if user is allowed to edit household? #}
|
{% if is_granted('CHILL_PERSON_HOUSEHOLD_EDIT', household) %}
|
||||||
<li>
|
<li>
|
||||||
<a class="btn btn-create"
|
<a class="btn btn-create"
|
||||||
href="{{ path ('chill_household_accompanying_course_new', {'household_id' : household.id } ) }}" role="button">
|
href="{{ path ('chill_household_accompanying_course_new', {'household_id' : household.id } ) }}" role="button">
|
||||||
{{ 'Create an accompanying period'|trans }}
|
{{ 'Create an accompanying period'|trans }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
<td>{{ entity.ordering }}</td>
|
<td>{{ entity.ordering }}</td>
|
||||||
<td>
|
<td>
|
||||||
{% if entity.desactivationDate is not null %}
|
{% if entity.desactivationDate is not null %}
|
||||||
{{ entity.desactivationDate|date('Y-m-d') }}
|
{{ entity.desactivationDate|format_date('medium') }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -123,7 +123,7 @@
|
|||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
<li>{{ doc.storedObject|chill_document_button_group(doc.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', evaluation.accompanyingPeriodWork)) }}</li>
|
<li>{{ doc.storedObject|chill_document_button_group(doc.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', evaluation.accompanyingPeriodWork)) }}</li>
|
||||||
<li>
|
<li>
|
||||||
<a class="btn btn-show" href="{{ path('chill_person_accompanying_period_work_edit', {'id': evaluation.accompanyingPeriodWork.id}) }}">
|
<a class="btn btn-show" href="{{ path('chill_person_accompanying_period_work_edit', {'id': evaluation.accompanyingPeriodWork.id, 'doc_id': doc.id}) }}">
|
||||||
{{ 'Show'|trans }}
|
{{ 'Show'|trans }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -13,7 +13,7 @@ namespace Chill\PersonBundle\Tests\Export\Filter\AccompanyingCourseFilters;
|
|||||||
|
|
||||||
use Chill\MainBundle\Test\Export\AbstractFilterTest;
|
use Chill\MainBundle\Test\Export\AbstractFilterTest;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
use Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\StepFilter;
|
use Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\StepFilterOnDate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
@ -21,7 +21,7 @@ use Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\StepFilter;
|
|||||||
*/
|
*/
|
||||||
final class StepFilterTest extends AbstractFilterTest
|
final class StepFilterTest extends AbstractFilterTest
|
||||||
{
|
{
|
||||||
private StepFilter $filter;
|
private StepFilterOnDate $filter;
|
||||||
|
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
|
@ -46,11 +46,13 @@ class RelationshipNoDuplicateValidator extends ConstraintValidator
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
foreach ($relationships as $r) {
|
foreach ($relationships as $r) {
|
||||||
if (
|
if (spl_object_hash($r) !== spl_object_hash($value)
|
||||||
$r->getFromPerson() === $fromPerson
|
and
|
||||||
|| $r->getFromPerson() === $toPerson
|
(
|
||||||
|| $r->getToPerson() === $fromPerson
|
($r->getFromPerson() === $fromPerson and $r->getToPerson() === $toPerson)
|
||||||
|| $r->getToPerson() === $toPerson
|
||
|
||||||
|
($r->getFromPerson() === $toPerson and $r->getToPerson() === $fromPerson)
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
$this->context->buildViolation($constraint->message)
|
$this->context->buildViolation($constraint->message)
|
||||||
->addViolation();
|
->addViolation();
|
||||||
|
@ -28,11 +28,14 @@ services:
|
|||||||
tags:
|
tags:
|
||||||
- { name: chill.export_filter, alias: accompanyingcourse_socialissue_filter }
|
- { name: chill.export_filter, alias: accompanyingcourse_socialissue_filter }
|
||||||
|
|
||||||
chill.person.export.filter_step:
|
Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\StepFilterOnDate:
|
||||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\StepFilter
|
|
||||||
tags:
|
tags:
|
||||||
- { name: chill.export_filter, alias: accompanyingcourse_step_filter }
|
- { name: chill.export_filter, alias: accompanyingcourse_step_filter }
|
||||||
|
|
||||||
|
Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\StepFilterBetweenDates:
|
||||||
|
tags:
|
||||||
|
- { name: chill.export_filter, alias: accompanyingcourse_step_filter_between_dates }
|
||||||
|
|
||||||
chill.person.export.filter_geographicalunitstat:
|
chill.person.export.filter_geographicalunitstat:
|
||||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\GeographicalUnitStatFilter
|
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\GeographicalUnitStatFilter
|
||||||
tags:
|
tags:
|
||||||
|
@ -2,3 +2,9 @@ services:
|
|||||||
Chill\PersonBundle\Notification\AccompanyingPeriodNotificationHandler:
|
Chill\PersonBundle\Notification\AccompanyingPeriodNotificationHandler:
|
||||||
autowire: true
|
autowire: true
|
||||||
autoconfigure: true
|
autoconfigure: true
|
||||||
|
Chill\PersonBundle\Notification\AccompanyingPeriodWorkNotificationHandler:
|
||||||
|
autowire: true
|
||||||
|
autoconfigure: true
|
||||||
|
Chill\PersonBundle\Notification\AccompanyingPeriodWorkEvaluationDocumentNotificationHandler:
|
||||||
|
autowire: true
|
||||||
|
autoconfigure: true
|
||||||
|
@ -473,7 +473,6 @@ Accepted socialissues: Problématiques sociales
|
|||||||
"Filtered by socialissues: only %socialissues%": "Filtré par problématique sociale: uniquement %socialissues%"
|
"Filtered by socialissues: only %socialissues%": "Filtré par problématique sociale: uniquement %socialissues%"
|
||||||
Group by social issue: Grouper les parcours par problématiques sociales
|
Group by social issue: Grouper les parcours par problématiques sociales
|
||||||
|
|
||||||
Filter by step: Filtrer les parcours par statut du parcours
|
|
||||||
Accepted steps: Statuts
|
Accepted steps: Statuts
|
||||||
Step: Statut
|
Step: Statut
|
||||||
"Filtered by steps: only %step%": "Filtré par statut du parcours: uniquement %step%"
|
"Filtered by steps: only %step%": "Filtré par statut du parcours: uniquement %step%"
|
||||||
@ -1085,7 +1084,13 @@ export:
|
|||||||
title: Filter les parcours par intervenant
|
title: Filter les parcours par intervenant
|
||||||
'Filtered by user working on course: only %users%': 'Filtré par intervenants sur le parcours: seulement %users%'
|
'Filtered by user working on course: only %users%': 'Filtré par intervenants sur le parcours: seulement %users%'
|
||||||
by_step:
|
by_step:
|
||||||
|
Filter by step: Filtrer les parcours par statut du parcours
|
||||||
|
Filter by step between dates: Filtrer les parcours par statut du parcours entre deux dates
|
||||||
|
steps: Statuts retenus
|
||||||
date_calc: Date de prise en compte du statut
|
date_calc: Date de prise en compte du statut
|
||||||
|
date_from: Statuts acquis après cette date
|
||||||
|
date_to: Statuts acquis avant cette date
|
||||||
|
'Filtered by steps: only %step% and between %date_from% and %date_to%': 'Filtré par statut: seulement %step%, entre %date_from% et %date_to%'
|
||||||
by_user_scope:
|
by_user_scope:
|
||||||
Computation date for referrer: Date à laquelle le référent était actif
|
Computation date for referrer: Date à laquelle le référent était actif
|
||||||
by_referrer:
|
by_referrer:
|
||||||
|
@ -166,7 +166,7 @@ class LoadReports extends AbstractFixture implements ContainerAwareInterface, Or
|
|||||||
/**
|
/**
|
||||||
* pick a random choice.
|
* pick a random choice.
|
||||||
*
|
*
|
||||||
* @return string|string[] the array of slug if multiple, a single slug otherwise
|
* @return string|string[]
|
||||||
*/
|
*/
|
||||||
private function getRandomChoice(CustomField $field)
|
private function getRandomChoice(CustomField $field)
|
||||||
{
|
{
|
||||||
@ -211,6 +211,8 @@ class LoadReports extends AbstractFixture implements ContainerAwareInterface, Or
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $picked;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -226,7 +228,7 @@ class LoadReports extends AbstractFixture implements ContainerAwareInterface, Or
|
|||||||
/**
|
/**
|
||||||
* pick a choice within a 'choices' options (for choice type).
|
* pick a choice within a 'choices' options (for choice type).
|
||||||
*
|
*
|
||||||
* @return the slug of the selected choice
|
* @return string the slug of the selected choice
|
||||||
*/
|
*/
|
||||||
private function pickChoice(array $choices)
|
private function pickChoice(array $choices)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user