mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-29 13:36:13 +00:00
Merge branch '641_issues_with_children' into '111_exports_suite'
Issue641, improve query, issues and actions with descendants See merge request Chill-Projet/chill-bundles!460
This commit is contained in:
commit
93713f2ac2
@ -14,10 +14,9 @@ namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
|
|||||||
use Chill\ActivityBundle\Export\Declarations;
|
use Chill\ActivityBundle\Export\Declarations;
|
||||||
use Chill\MainBundle\Export\FilterInterface;
|
use Chill\MainBundle\Export\FilterInterface;
|
||||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||||
|
use Chill\PersonBundle\Form\Type\PickSocialActionType;
|
||||||
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
|
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
|
||||||
use Doctrine\ORM\Query\Expr\Andx;
|
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use function in_array;
|
use function in_array;
|
||||||
|
|
||||||
@ -37,22 +36,17 @@ class BySocialActionFilter implements FilterInterface
|
|||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data)
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
{
|
{
|
||||||
$where = $qb->getDQLPart('where');
|
|
||||||
|
|
||||||
if (!in_array('actsocialaction', $qb->getAllAliases(), true)) {
|
if (!in_array('actsocialaction', $qb->getAllAliases(), true)) {
|
||||||
$qb->join('activity.socialActions', 'actsocialaction');
|
$qb->join('activity.socialActions', 'actsocialaction');
|
||||||
}
|
}
|
||||||
|
|
||||||
$clause = $qb->expr()->in('actsocialaction.id', ':socialactions');
|
$clause = $qb->expr()->in('actsocialaction.id', ':socialactions');
|
||||||
|
|
||||||
if ($where instanceof Andx) {
|
$qb->andWhere($clause)
|
||||||
$where->add($clause);
|
->setParameter(
|
||||||
} else {
|
'socialactions',
|
||||||
$where = $qb->expr()->andX($clause);
|
SocialAction::getDescendantsWithThisForActions($data['accepted_socialactions'])
|
||||||
}
|
);
|
||||||
|
|
||||||
$qb->add('where', $where);
|
|
||||||
$qb->setParameter('socialactions', $data['accepted_socialactions']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
@ -62,13 +56,8 @@ class BySocialActionFilter implements FilterInterface
|
|||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
{
|
{
|
||||||
$builder->add('accepted_socialactions', EntityType::class, [
|
$builder->add('accepted_socialactions', PickSocialActionType::class, [
|
||||||
'class' => SocialAction::class,
|
|
||||||
'choice_label' => function (SocialAction $sa) {
|
|
||||||
return $this->actionRender->renderString($sa, []);
|
|
||||||
},
|
|
||||||
'multiple' => true,
|
'multiple' => true,
|
||||||
'expanded' => true,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,8 +65,10 @@ class BySocialActionFilter implements FilterInterface
|
|||||||
{
|
{
|
||||||
$actions = [];
|
$actions = [];
|
||||||
|
|
||||||
foreach ($data['accepted_socialactions'] as $sa) {
|
foreach ($data['accepted_socialactions'] as $action) {
|
||||||
$actions[] = $this->actionRender->renderString($sa, []);
|
$actions[] = $this->actionRender->renderString($action, [
|
||||||
|
'show_and_children' => true,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ['Filtered activity by linked socialaction: only %actions%', [
|
return ['Filtered activity by linked socialaction: only %actions%', [
|
||||||
|
@ -14,10 +14,9 @@ namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
|
|||||||
use Chill\ActivityBundle\Export\Declarations;
|
use Chill\ActivityBundle\Export\Declarations;
|
||||||
use Chill\MainBundle\Export\FilterInterface;
|
use Chill\MainBundle\Export\FilterInterface;
|
||||||
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
||||||
|
use Chill\PersonBundle\Form\Type\PickSocialIssueType;
|
||||||
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
|
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
|
||||||
use Doctrine\ORM\Query\Expr\Andx;
|
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use function in_array;
|
use function in_array;
|
||||||
|
|
||||||
@ -37,22 +36,17 @@ class BySocialIssueFilter implements FilterInterface
|
|||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data)
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
{
|
{
|
||||||
$where = $qb->getDQLPart('where');
|
|
||||||
|
|
||||||
if (!in_array('actsocialissue', $qb->getAllAliases(), true)) {
|
if (!in_array('actsocialissue', $qb->getAllAliases(), true)) {
|
||||||
$qb->join('activity.socialIssues', 'actsocialissue');
|
$qb->join('activity.socialIssues', 'actsocialissue');
|
||||||
}
|
}
|
||||||
|
|
||||||
$clause = $qb->expr()->in('actsocialissue.id', ':socialissues');
|
$clause = $qb->expr()->in('actsocialissue.id', ':socialissues');
|
||||||
|
|
||||||
if ($where instanceof Andx) {
|
$qb->andWhere($clause)
|
||||||
$where->add($clause);
|
->setParameter(
|
||||||
} else {
|
'socialissues',
|
||||||
$where = $qb->expr()->andX($clause);
|
SocialIssue::getDescendantsWithThisForIssues($data['accepted_socialissues'])
|
||||||
}
|
);
|
||||||
|
|
||||||
$qb->add('where', $where);
|
|
||||||
$qb->setParameter('socialissues', $data['accepted_socialissues']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
@ -62,13 +56,8 @@ class BySocialIssueFilter implements FilterInterface
|
|||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
{
|
{
|
||||||
$builder->add('accepted_socialissues', EntityType::class, [
|
$builder->add('accepted_socialissues', PickSocialIssueType::class, [
|
||||||
'class' => SocialIssue::class,
|
|
||||||
'choice_label' => function (SocialIssue $si) {
|
|
||||||
return $this->issueRender->renderString($si, []);
|
|
||||||
},
|
|
||||||
'multiple' => true,
|
'multiple' => true,
|
||||||
'expanded' => true,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,8 +65,10 @@ class BySocialIssueFilter implements FilterInterface
|
|||||||
{
|
{
|
||||||
$issues = [];
|
$issues = [];
|
||||||
|
|
||||||
foreach ($data['accepted_socialissues'] as $si) {
|
foreach ($data['accepted_socialissues'] as $issue) {
|
||||||
$issues[] = $this->issueRender->renderString($si, []);
|
$issues[] = $this->issueRender->renderString($issue, [
|
||||||
|
'show_and_children' => true,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ['Filtered activity by linked socialissue: only %issues%', [
|
return ['Filtered activity by linked socialissue: only %issues%', [
|
||||||
|
@ -13,7 +13,7 @@ namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
|
|||||||
|
|
||||||
use Chill\ActivityBundle\Export\Declarations;
|
use Chill\ActivityBundle\Export\Declarations;
|
||||||
use Chill\MainBundle\Export\FilterInterface;
|
use Chill\MainBundle\Export\FilterInterface;
|
||||||
use Chill\MainBundle\Form\Type\Select2LocationTypeType;
|
use Chill\MainBundle\Form\Type\PickLocationTypeType;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
use Doctrine\ORM\Query\Expr\Andx;
|
use Doctrine\ORM\Query\Expr\Andx;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
@ -60,7 +60,7 @@ class LocationTypeFilter implements FilterInterface
|
|||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
{
|
{
|
||||||
$builder->add('accepted_locationtype', Select2LocationTypeType::class, [
|
$builder->add('accepted_locationtype', PickLocationTypeType::class, [
|
||||||
'multiple' => true,
|
'multiple' => true,
|
||||||
//'label' => false,
|
//'label' => false,
|
||||||
]);
|
]);
|
||||||
|
@ -15,7 +15,7 @@ use Chill\MainBundle\CRUD\Controller\CRUDController;
|
|||||||
use Chill\MainBundle\Entity\GroupCenter;
|
use Chill\MainBundle\Entity\GroupCenter;
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\MainBundle\Form\Type\ComposedGroupCenterType;
|
use Chill\MainBundle\Form\Type\ComposedGroupCenterType;
|
||||||
use Chill\MainBundle\Form\Type\Select2UserLocationType;
|
use Chill\MainBundle\Form\UserCurrentLocationType;
|
||||||
use Chill\MainBundle\Form\UserPasswordType;
|
use Chill\MainBundle\Form\UserPasswordType;
|
||||||
use Chill\MainBundle\Form\UserType;
|
use Chill\MainBundle\Form\UserType;
|
||||||
use Chill\MainBundle\Pagination\PaginatorInterface;
|
use Chill\MainBundle\Pagination\PaginatorInterface;
|
||||||
@ -234,7 +234,7 @@ class UserController extends CRUDController
|
|||||||
public function editCurrentLocationAction(Request $request)
|
public function editCurrentLocationAction(Request $request)
|
||||||
{
|
{
|
||||||
$user = $this->getUser();
|
$user = $this->getUser();
|
||||||
$form = $this->createForm(Select2UserLocationType::class, $user)
|
$form = $this->createForm(UserCurrentLocationType::class, $user)
|
||||||
->add('submit', SubmitType::class, ['label' => 'Save'])
|
->add('submit', SubmitType::class, ['label' => 'Save'])
|
||||||
->handleRequest($request);
|
->handleRequest($request);
|
||||||
|
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
<?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\MainBundle\Form\Type;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\LocationType;
|
||||||
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
class PickLocationTypeType extends AbstractType
|
||||||
|
{
|
||||||
|
private TranslatableStringHelper $translatableStringHelper;
|
||||||
|
|
||||||
|
public function __construct(TranslatableStringHelper $translatableStringHelper)
|
||||||
|
{
|
||||||
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver
|
||||||
|
->setDefaults([
|
||||||
|
'class' => LocationType::class,
|
||||||
|
'choice_label' => function (LocationType $type) {
|
||||||
|
return $this->translatableStringHelper->localize($type->getTitle());
|
||||||
|
},
|
||||||
|
'placeholder' => 'Pick a location type',
|
||||||
|
'required' => false,
|
||||||
|
'attr' => ['class' => 'select2'],
|
||||||
|
'label' => 'Location type',
|
||||||
|
'multiple' => false,
|
||||||
|
])
|
||||||
|
->setAllowedTypes('multiple', ['bool']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParent(): string
|
||||||
|
{
|
||||||
|
return EntityType::class;
|
||||||
|
}
|
||||||
|
}
|
@ -16,10 +16,9 @@ use Chill\MainBundle\Repository\LocationRepository;
|
|||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
class Select2UserLocationType extends AbstractType
|
class PickUserLocationType extends AbstractType
|
||||||
{
|
{
|
||||||
private LocationRepository $locationRepository;
|
private LocationRepository $locationRepository;
|
||||||
|
|
||||||
@ -31,10 +30,10 @@ class Select2UserLocationType extends AbstractType
|
|||||||
$this->locationRepository = $locationRepository;
|
$this->locationRepository = $locationRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
{
|
{
|
||||||
$builder
|
$resolver
|
||||||
->add('currentLocation', EntityType::class, [
|
->setDefaults([
|
||||||
'class' => Location::class,
|
'class' => Location::class,
|
||||||
'choices' => $this->locationRepository->findByPublicLocations(),
|
'choices' => $this->locationRepository->findByPublicLocations(),
|
||||||
'choice_label' => function (Location $entity) {
|
'choice_label' => function (Location $entity) {
|
||||||
@ -44,24 +43,15 @@ class Select2UserLocationType extends AbstractType
|
|||||||
},
|
},
|
||||||
'placeholder' => 'Pick a location',
|
'placeholder' => 'Pick a location',
|
||||||
'required' => false,
|
'required' => false,
|
||||||
'label' => $options['label'],
|
|
||||||
'label_attr' => $options['label_attr'],
|
|
||||||
'multiple' => $options['multiple'],
|
|
||||||
'attr' => ['class' => 'select2'],
|
'attr' => ['class' => 'select2'],
|
||||||
]);
|
'label' => 'Current location',
|
||||||
}
|
'multiple' => false,
|
||||||
|
])
|
||||||
public function configureOptions(OptionsResolver $resolver)
|
|
||||||
{
|
|
||||||
$resolver
|
|
||||||
->setDefault('label', 'Current location')
|
|
||||||
->setDefault('label_attr', [])
|
|
||||||
->setDefault('multiple', false)
|
|
||||||
->setAllowedTypes('multiple', ['bool']);
|
->setAllowedTypes('multiple', ['bool']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBlockPrefix(): string
|
public function getParent(): string
|
||||||
{
|
{
|
||||||
return 'select2_user_location_type';
|
return EntityType::class;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,59 +0,0 @@
|
|||||||
<?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\MainBundle\Form\Type;
|
|
||||||
|
|
||||||
use Chill\MainBundle\Entity\LocationType;
|
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
|
||||||
use Symfony\Component\Form\AbstractType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
|
||||||
|
|
||||||
class Select2LocationTypeType extends AbstractType
|
|
||||||
{
|
|
||||||
private TranslatableStringHelper $translatableStringHelper;
|
|
||||||
|
|
||||||
public function __construct(TranslatableStringHelper $translatableStringHelper)
|
|
||||||
{
|
|
||||||
$this->translatableStringHelper = $translatableStringHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
|
||||||
{
|
|
||||||
$builder->add('locationtype', EntityType::class, [
|
|
||||||
'class' => LocationType::class,
|
|
||||||
'choice_label' => function (LocationType $type) {
|
|
||||||
return $this->translatableStringHelper->localize($type->getTitle());
|
|
||||||
},
|
|
||||||
'placeholder' => 'Pick a location type',
|
|
||||||
'required' => false,
|
|
||||||
'label' => $options['label'],
|
|
||||||
'label_attr' => $options['label_attr'],
|
|
||||||
'multiple' => $options['multiple'],
|
|
||||||
'attr' => ['class' => 'select2'],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function configureOptions(OptionsResolver $resolver)
|
|
||||||
{
|
|
||||||
$resolver
|
|
||||||
->setDefault('label', 'Location type')
|
|
||||||
->setDefault('label_attr', [])
|
|
||||||
->setDefault('multiple', false)
|
|
||||||
->setAllowedTypes('multiple', ['bool']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBlockPrefix(): string
|
|
||||||
{
|
|
||||||
return 'select2_location_type_type';
|
|
||||||
}
|
|
||||||
}
|
|
24
src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php
Normal file
24
src/Bundle/ChillMainBundle/Form/UserCurrentLocationType.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?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\MainBundle\Form;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Form\Type\PickUserLocationType;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
|
||||||
|
class UserCurrentLocationType extends AbstractType
|
||||||
|
{
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder->add('currentLocation', PickUserLocationType::class);
|
||||||
|
}
|
||||||
|
}
|
@ -130,14 +130,6 @@ services:
|
|||||||
autowire: true
|
autowire: true
|
||||||
autoconfigure: true
|
autoconfigure: true
|
||||||
|
|
||||||
Chill\MainBundle\Form\Type\Select2UserLocationType:
|
|
||||||
autowire: true
|
|
||||||
autoconfigure: true
|
|
||||||
|
|
||||||
Chill\MainBundle\Form\Type\Select2LocationTypeType:
|
|
||||||
autowire: true
|
|
||||||
autoconfigure: true
|
|
||||||
|
|
||||||
Chill\MainBundle\Form\Type\LocationFormType: ~
|
Chill\MainBundle\Form\Type\LocationFormType: ~
|
||||||
|
|
||||||
Chill\MainBundle\Form\WorkflowStepType: ~
|
Chill\MainBundle\Form\WorkflowStepType: ~
|
||||||
|
@ -228,6 +228,22 @@ class SocialAction
|
|||||||
return $descendants;
|
return $descendants;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection|SocialAction[] $socialActions
|
||||||
|
*/
|
||||||
|
public static function getDescendantsWithThisForActions($socialActions): Collection
|
||||||
|
{
|
||||||
|
$unique = [];
|
||||||
|
|
||||||
|
foreach ($socialActions as $action) {
|
||||||
|
foreach ($action->getDescendantsWithThis() as $child) {
|
||||||
|
$unique[spl_object_hash($child)] = $child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ArrayCollection(array_values($unique));
|
||||||
|
}
|
||||||
|
|
||||||
public function getEvaluations(): Collection
|
public function getEvaluations(): Collection
|
||||||
{
|
{
|
||||||
return $this->evaluations;
|
return $this->evaluations;
|
||||||
@ -274,6 +290,11 @@ class SocialAction
|
|||||||
return $this->title;
|
return $this->title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function hasChildren(): bool
|
||||||
|
{
|
||||||
|
return 0 < $this->getChildren()->count();
|
||||||
|
}
|
||||||
|
|
||||||
public function hasParent(): bool
|
public function hasParent(): bool
|
||||||
{
|
{
|
||||||
return $this->getParent() instanceof self;
|
return $this->getParent() instanceof self;
|
||||||
@ -369,6 +390,8 @@ class SocialAction
|
|||||||
{
|
{
|
||||||
$this->parent = $parent;
|
$this->parent = $parent;
|
||||||
|
|
||||||
|
$parent->addChild($this);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,11 +71,17 @@ class SocialIssue
|
|||||||
$this->socialActions = new ArrayCollection();
|
$this->socialActions = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal use @see{SocialIssue::setParent} instead
|
||||||
|
*
|
||||||
|
* @param SocialIssue $child
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
public function addChild(self $child): self
|
public function addChild(self $child): self
|
||||||
{
|
{
|
||||||
if (!$this->children->contains($child)) {
|
if (!$this->children->contains($child)) {
|
||||||
$this->children[] = $child;
|
$this->children[] = $child;
|
||||||
$child->setParent($this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
@ -215,6 +221,22 @@ class SocialIssue
|
|||||||
return $descendants;
|
return $descendants;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array|SocialIssue[] $socialIssues
|
||||||
|
*/
|
||||||
|
public static function getDescendantsWithThisForIssues(array $socialIssues): Collection
|
||||||
|
{
|
||||||
|
$unique = [];
|
||||||
|
|
||||||
|
foreach ($socialIssues as $issue) {
|
||||||
|
foreach ($issue->getDescendantsWithThis() as $child) {
|
||||||
|
$unique[spl_object_hash($child)] = $child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ArrayCollection(array_values($unique));
|
||||||
|
}
|
||||||
|
|
||||||
public function getId(): ?int
|
public function getId(): ?int
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
@ -262,6 +284,11 @@ class SocialIssue
|
|||||||
return $this->title;
|
return $this->title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function hasChildren(): bool
|
||||||
|
{
|
||||||
|
return 0 < $this->getChildren()->count();
|
||||||
|
}
|
||||||
|
|
||||||
public function hasParent(): bool
|
public function hasParent(): bool
|
||||||
{
|
{
|
||||||
return null !== $this->parent;
|
return null !== $this->parent;
|
||||||
@ -329,6 +356,8 @@ class SocialIssue
|
|||||||
{
|
{
|
||||||
$this->parent = $parent;
|
$this->parent = $parent;
|
||||||
|
|
||||||
|
$parent->addChild($this);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ declare(strict_types=1);
|
|||||||
namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
|
namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
|
||||||
|
|
||||||
use Chill\MainBundle\Export\FilterInterface;
|
use Chill\MainBundle\Export\FilterInterface;
|
||||||
use Chill\MainBundle\Form\Type\Select2UserLocationType;
|
use Chill\MainBundle\Form\Type\PickUserLocationType;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
use Chill\PersonBundle\Export\Declarations;
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
@ -48,11 +48,8 @@ class AdministrativeLocationFilter implements FilterInterface
|
|||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
{
|
{
|
||||||
$builder->add('accepted_locations', Select2UserLocationType::class, [
|
$builder->add('accepted_locations', PickUserLocationType::class, [
|
||||||
'label' => 'Accepted locations',
|
'label' => 'Accepted locations',
|
||||||
'label_attr' => [
|
|
||||||
//'class' => 'd-none'
|
|
||||||
],
|
|
||||||
'multiple' => true,
|
'multiple' => true,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -15,10 +15,9 @@ use Chill\MainBundle\Export\FilterInterface;
|
|||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||||
use Chill\PersonBundle\Export\Declarations;
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
|
use Chill\PersonBundle\Form\Type\PickSocialActionType;
|
||||||
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
|
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
|
||||||
use Doctrine\ORM\Query\Expr\Andx;
|
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use function in_array;
|
use function in_array;
|
||||||
|
|
||||||
@ -51,17 +50,13 @@ class SocialActionFilter implements FilterInterface
|
|||||||
$qb->join('acpw.socialAction', 'acpwsocialaction');
|
$qb->join('acpw.socialAction', 'acpwsocialaction');
|
||||||
}
|
}
|
||||||
|
|
||||||
$where = $qb->getDQLPart('where');
|
|
||||||
$clause = $qb->expr()->in('acpwsocialaction.id', ':socialactions');
|
$clause = $qb->expr()->in('acpwsocialaction.id', ':socialactions');
|
||||||
|
|
||||||
if ($where instanceof Andx) {
|
$qb->andWhere($clause)
|
||||||
$where->add($clause);
|
->setParameter(
|
||||||
} else {
|
'socialactions',
|
||||||
$where = $qb->expr()->andX($clause);
|
SocialAction::getDescendantsWithThisForActions($data['accepted_socialactions'])->toArray()
|
||||||
}
|
);
|
||||||
|
|
||||||
$qb->add('where', $where);
|
|
||||||
$qb->setParameter('socialactions', $data['accepted_socialactions']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
@ -71,26 +66,25 @@ class SocialActionFilter implements FilterInterface
|
|||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
{
|
{
|
||||||
$builder->add('accepted_socialactions', EntityType::class, [
|
$builder->add('accepted_socialactions', PickSocialActionType::class, [
|
||||||
'class' => SocialAction::class,
|
|
||||||
'choice_label' => function (SocialAction $sa) {
|
|
||||||
return $this->actionRender->renderString($sa, []);
|
|
||||||
},
|
|
||||||
'multiple' => true,
|
'multiple' => true,
|
||||||
'expanded' => true,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function describeAction($data, $format = 'string'): array
|
public function describeAction($data, $format = 'string'): array
|
||||||
{
|
{
|
||||||
$socialactions = [];
|
$actions = [];
|
||||||
|
|
||||||
foreach ($data['accepted_socialactions'] as $sa) {
|
$socialactions = $data['accepted_socialactions'];
|
||||||
$socialactions[] = $this->actionRender->renderString($sa, []);
|
|
||||||
|
foreach ($socialactions as $action) {
|
||||||
|
$actions[] = $this->actionRender->renderString($action, [
|
||||||
|
'show_and_children' => true,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ['Filtered by socialactions: only %socialactions%', [
|
return ['Filtered by socialactions: only %socialactions%', [
|
||||||
'%socialactions%' => implode(', ou ', $socialactions),
|
'%socialactions%' => implode(', ou ', $actions),
|
||||||
]];
|
]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,10 +15,9 @@ use Chill\MainBundle\Export\FilterInterface;
|
|||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
||||||
use Chill\PersonBundle\Export\Declarations;
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
|
use Chill\PersonBundle\Form\Type\PickSocialIssueType;
|
||||||
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
|
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
|
||||||
use Doctrine\ORM\Query\Expr\Andx;
|
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
use function in_array;
|
use function in_array;
|
||||||
@ -55,19 +54,12 @@ class SocialIssueFilter implements FilterInterface
|
|||||||
$qb->join('acp.socialIssues', 'acpsocialissue');
|
$qb->join('acp.socialIssues', 'acpsocialissue');
|
||||||
}
|
}
|
||||||
|
|
||||||
$where = $qb->getDQLPart('where');
|
|
||||||
$clause = $qb->expr()->in('acpsocialissue.id', ':socialissues');
|
$clause = $qb->expr()->in('acpsocialissue.id', ':socialissues');
|
||||||
|
|
||||||
if ($where instanceof Andx) {
|
$qb->andWhere($clause)
|
||||||
$where->add($clause);
|
->setParameter(
|
||||||
} else {
|
|
||||||
$where = $qb->expr()->andX($clause);
|
|
||||||
}
|
|
||||||
|
|
||||||
$qb->add('where', $where);
|
|
||||||
$qb->setParameter(
|
|
||||||
'socialissues',
|
'socialissues',
|
||||||
$this->addParentIssues($data['accepted_socialissues'])
|
SocialIssue::getDescendantsWithThisForIssues($data['accepted_socialissues'])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,28 +70,21 @@ class SocialIssueFilter implements FilterInterface
|
|||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
{
|
{
|
||||||
$builder->add('accepted_socialissues', EntityType::class, [
|
$builder->add('accepted_socialissues', PickSocialIssueType::class, [
|
||||||
'class' => SocialIssue::class,
|
|
||||||
'choice_label' => function ($socialIssue) {
|
|
||||||
return $this->socialIssueRender->renderString($socialIssue, []);
|
|
||||||
},
|
|
||||||
'multiple' => true,
|
'multiple' => true,
|
||||||
'expanded' => true,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function describeAction($data, $format = 'string')
|
public function describeAction($data, $format = 'string'): array
|
||||||
{
|
{
|
||||||
$issues = [];
|
$issues = [];
|
||||||
|
|
||||||
$socialissues = $this->addParentIssues($data['accepted_socialissues']);
|
$socialissues = $data['accepted_socialissues'];
|
||||||
|
|
||||||
foreach ($socialissues as $i) {
|
foreach ($socialissues as $issue) {
|
||||||
if ('null' === $i) {
|
$issues[] = $this->socialIssueRender->renderString($issue, [
|
||||||
$issues[] = $this->translator->trans('Not given');
|
'show_and_children' => true,
|
||||||
} else {
|
]);
|
||||||
$issues[] = $this->socialIssueRender->renderString($i, []);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
@ -108,44 +93,8 @@ class SocialIssueFilter implements FilterInterface
|
|||||||
], ];
|
], ];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTitle()
|
public function getTitle(): string
|
||||||
{
|
{
|
||||||
return 'Filter by social issue';
|
return 'Filter by social issue';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* "Le filtre retiendra les parcours qui comportent cette problématique,
|
|
||||||
* ou une problématique parente à celles choisies.".
|
|
||||||
*
|
|
||||||
* Add parent of each socialissue selected, and remove duplicates
|
|
||||||
*
|
|
||||||
* @param $accepted_issues
|
|
||||||
*/
|
|
||||||
private function addParentIssues($accepted_issues): array
|
|
||||||
{
|
|
||||||
$array = [];
|
|
||||||
|
|
||||||
foreach ($accepted_issues as $i) {
|
|
||||||
/** @var SocialIssue $i */
|
|
||||||
if ($i->hasParent()) {
|
|
||||||
$array[] = $i->getParent();
|
|
||||||
}
|
|
||||||
$array[] = $i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->removeDuplicate($array);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function removeDuplicate(array $array): array
|
|
||||||
{
|
|
||||||
$ids = array_map(static function ($item) {
|
|
||||||
return $item->getId();
|
|
||||||
}, $array);
|
|
||||||
|
|
||||||
$unique_ids = array_unique($ids);
|
|
||||||
|
|
||||||
return array_values(
|
|
||||||
array_intersect_key($array, $unique_ids)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
<?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\Form\Type;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||||
|
use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository;
|
||||||
|
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
|
||||||
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
class PickSocialActionType extends AbstractType
|
||||||
|
{
|
||||||
|
private SocialActionRender $actionRender;
|
||||||
|
|
||||||
|
private SocialActionRepository $actionRepository;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
SocialActionRender $actionRender,
|
||||||
|
SocialActionRepository $actionRepository
|
||||||
|
) {
|
||||||
|
$this->actionRender = $actionRender;
|
||||||
|
$this->actionRepository = $actionRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver
|
||||||
|
->setDefaults([
|
||||||
|
'class' => SocialAction::class,
|
||||||
|
'choices' => $this->actionRepository->findAllActive(),
|
||||||
|
'choice_label' => function (SocialAction $sa) {
|
||||||
|
return $this->actionRender->renderString($sa, []);
|
||||||
|
},
|
||||||
|
'placeholder' => 'Pick a social action',
|
||||||
|
'required' => false,
|
||||||
|
'attr' => ['class' => 'select2'],
|
||||||
|
'label' => 'Social actions',
|
||||||
|
'multiple' => false,
|
||||||
|
])
|
||||||
|
->setAllowedTypes('multiple', ['bool']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParent(): string
|
||||||
|
{
|
||||||
|
return EntityType::class;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
<?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\Form\Type;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
||||||
|
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
|
||||||
|
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
|
||||||
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
class PickSocialIssueType extends AbstractType
|
||||||
|
{
|
||||||
|
private SocialIssueRender $issueRender;
|
||||||
|
|
||||||
|
private SocialIssueRepository $issueRepository;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
SocialIssueRender $issueRender,
|
||||||
|
SocialIssueRepository $issueRepository
|
||||||
|
) {
|
||||||
|
$this->issueRender = $issueRender;
|
||||||
|
$this->issueRepository = $issueRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver
|
||||||
|
->setDefaults([
|
||||||
|
'class' => SocialIssue::class,
|
||||||
|
'choices' => $this->issueRepository->findAllActive(),
|
||||||
|
'choice_label' => function (SocialIssue $si) {
|
||||||
|
return $this->issueRender->renderString($si, []);
|
||||||
|
},
|
||||||
|
'placeholder' => 'Pick a social issue',
|
||||||
|
'required' => false,
|
||||||
|
'attr' => ['class' => 'select2'],
|
||||||
|
'label' => 'Social issues',
|
||||||
|
'multiple' => false,
|
||||||
|
])
|
||||||
|
->setAllowedTypes('multiple', ['bool']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParent(): string
|
||||||
|
{
|
||||||
|
return EntityType::class;
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,7 @@ declare(strict_types=1);
|
|||||||
namespace Chill\PersonBundle\Repository\SocialWork;
|
namespace Chill\PersonBundle\Repository\SocialWork;
|
||||||
|
|
||||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||||
|
use DateTime;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
@ -44,6 +45,14 @@ final class SocialActionRepository implements ObjectRepository
|
|||||||
return $this->repository->findAll();
|
return $this->repository->findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|SocialAction[]
|
||||||
|
*/
|
||||||
|
public function findAllActive(): array
|
||||||
|
{
|
||||||
|
return $this->buildQueryWithDesactivatedDateCriteria()->getQuery()->getResult();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed|null $limit
|
* @param mixed|null $limit
|
||||||
* @param mixed|null $offset
|
* @param mixed|null $offset
|
||||||
@ -67,4 +76,16 @@ final class SocialActionRepository implements ObjectRepository
|
|||||||
{
|
{
|
||||||
return SocialAction::class;
|
return SocialAction::class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function buildQueryWithDesactivatedDateCriteria(): QueryBuilder
|
||||||
|
{
|
||||||
|
$qb = $this->repository->createQueryBuilder('sa');
|
||||||
|
|
||||||
|
$qb->where('sa.desactivationDate is null')
|
||||||
|
->orWhere('sa.desactivationDate > :now')
|
||||||
|
->orderBy('sa.ordering', 'ASC')
|
||||||
|
->setParameter('now', new DateTime('now'));
|
||||||
|
|
||||||
|
return $qb;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,10 @@ declare(strict_types=1);
|
|||||||
namespace Chill\PersonBundle\Repository\SocialWork;
|
namespace Chill\PersonBundle\Repository\SocialWork;
|
||||||
|
|
||||||
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
||||||
|
use DateTime;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Doctrine\Persistence\ObjectRepository;
|
use Doctrine\Persistence\ObjectRepository;
|
||||||
|
|
||||||
final class SocialIssueRepository implements ObjectRepository
|
final class SocialIssueRepository implements ObjectRepository
|
||||||
@ -38,6 +40,14 @@ final class SocialIssueRepository implements ObjectRepository
|
|||||||
return $this->repository->findAll();
|
return $this->repository->findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|SocialIssue[]
|
||||||
|
*/
|
||||||
|
public function findAllActive(): array
|
||||||
|
{
|
||||||
|
return $this->buildQueryWithDesactivatedDateCriteria()->getQuery()->getResult();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed|null $limit
|
* @param mixed|null $limit
|
||||||
* @param mixed|null $offset
|
* @param mixed|null $offset
|
||||||
@ -61,4 +71,16 @@ final class SocialIssueRepository implements ObjectRepository
|
|||||||
{
|
{
|
||||||
return SocialIssue::class;
|
return SocialIssue::class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function buildQueryWithDesactivatedDateCriteria(): QueryBuilder
|
||||||
|
{
|
||||||
|
$qb = $this->repository->createQueryBuilder('si');
|
||||||
|
|
||||||
|
$qb->where('si.desactivationDate is null')
|
||||||
|
->orWhere('si.desactivationDate > :now')
|
||||||
|
->orderBy('si.ordering', 'ASC')
|
||||||
|
->setParameter('now', new DateTime('now'));
|
||||||
|
|
||||||
|
return $qb;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,16 +15,20 @@ use Chill\MainBundle\Templating\Entity\ChillEntityRenderInterface;
|
|||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||||
use Symfony\Component\Templating\EngineInterface;
|
use Symfony\Component\Templating\EngineInterface;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
use function array_merge;
|
use function array_merge;
|
||||||
use function array_reverse;
|
use function array_reverse;
|
||||||
use function implode;
|
use function implode;
|
||||||
|
|
||||||
class SocialActionRender implements ChillEntityRenderInterface
|
class SocialActionRender implements ChillEntityRenderInterface
|
||||||
{
|
{
|
||||||
|
public const AND_CHILDREN_MENTION = 'show_and_children_mention';
|
||||||
|
|
||||||
public const DEFAULT_ARGS = [
|
public const DEFAULT_ARGS = [
|
||||||
self::SEPARATOR_KEY => ' > ',
|
self::SEPARATOR_KEY => ' > ',
|
||||||
self::NO_BADGE => false,
|
self::NO_BADGE => false,
|
||||||
|
self::SHOW_AND_CHILDREN => false,
|
||||||
|
self::AND_CHILDREN_MENTION => 'social_action.and children',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,14 +38,26 @@ class SocialActionRender implements ChillEntityRenderInterface
|
|||||||
|
|
||||||
public const SEPARATOR_KEY = 'default.separator';
|
public const SEPARATOR_KEY = 'default.separator';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a mention "and children" on each SocialAction, if the social action
|
||||||
|
* has at least one child.
|
||||||
|
*/
|
||||||
|
public const SHOW_AND_CHILDREN = 'show_and_children';
|
||||||
|
|
||||||
private EngineInterface $engine;
|
private EngineInterface $engine;
|
||||||
|
|
||||||
private TranslatableStringHelper $translatableStringHelper;
|
private TranslatableStringHelper $translatableStringHelper;
|
||||||
|
|
||||||
public function __construct(TranslatableStringHelper $translatableStringHelper, EngineInterface $engine)
|
private TranslatorInterface $translator;
|
||||||
{
|
|
||||||
|
public function __construct(
|
||||||
|
TranslatableStringHelper $translatableStringHelper,
|
||||||
|
EngineInterface $engine,
|
||||||
|
TranslatorInterface $translator
|
||||||
|
) {
|
||||||
$this->translatableStringHelper = $translatableStringHelper;
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
$this->engine = $engine;
|
$this->engine = $engine;
|
||||||
|
$this->translator = $translator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function renderBox($socialAction, array $options): string
|
public function renderBox($socialAction, array $options): string
|
||||||
@ -72,7 +88,13 @@ class SocialActionRender implements ChillEntityRenderInterface
|
|||||||
|
|
||||||
$titles = array_reverse($titles);
|
$titles = array_reverse($titles);
|
||||||
|
|
||||||
return implode($options[self::SEPARATOR_KEY], $titles);
|
$title = implode($options[self::SEPARATOR_KEY], $titles);
|
||||||
|
|
||||||
|
if ($options[self::SHOW_AND_CHILDREN] && $socialAction->hasChildren()) {
|
||||||
|
$title .= ' (' . $this->translator->trans($options[self::AND_CHILDREN_MENTION]) . ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $title;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function supports($entity, array $options): bool
|
public function supports($entity, array $options): bool
|
||||||
|
@ -15,26 +15,42 @@ use Chill\MainBundle\Templating\Entity\ChillEntityRenderInterface;
|
|||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
||||||
use Symfony\Component\Templating\EngineInterface;
|
use Symfony\Component\Templating\EngineInterface;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
use function array_reverse;
|
use function array_reverse;
|
||||||
use function implode;
|
use function implode;
|
||||||
|
|
||||||
final class SocialIssueRender implements ChillEntityRenderInterface
|
final class SocialIssueRender implements ChillEntityRenderInterface
|
||||||
{
|
{
|
||||||
|
public const AND_CHILDREN_MENTION = 'show_and_children_mention';
|
||||||
|
|
||||||
public const DEFAULT_ARGS = [
|
public const DEFAULT_ARGS = [
|
||||||
self::SEPARATOR_KEY => ' > ',
|
self::SEPARATOR_KEY => ' > ',
|
||||||
|
self::SHOW_AND_CHILDREN => false,
|
||||||
|
self::AND_CHILDREN_MENTION => 'social_issue.and children',
|
||||||
];
|
];
|
||||||
|
|
||||||
public const SEPARATOR_KEY = 'default.separator';
|
public const SEPARATOR_KEY = 'default.separator';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a mention "and children" on each SocialIssue, if the social issue
|
||||||
|
* has at least one child.
|
||||||
|
*/
|
||||||
|
public const SHOW_AND_CHILDREN = 'show_and_children';
|
||||||
|
|
||||||
private EngineInterface $engine;
|
private EngineInterface $engine;
|
||||||
|
|
||||||
private TranslatableStringHelper $translatableStringHelper;
|
private TranslatableStringHelper $translatableStringHelper;
|
||||||
|
|
||||||
public function __construct(TranslatableStringHelper $translatableStringHelper, EngineInterface $engine)
|
private TranslatorInterface $translator;
|
||||||
{
|
|
||||||
|
public function __construct(
|
||||||
|
TranslatableStringHelper $translatableStringHelper,
|
||||||
|
EngineInterface $engine,
|
||||||
|
TranslatorInterface $translator
|
||||||
|
) {
|
||||||
$this->translatableStringHelper = $translatableStringHelper;
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
$this->engine = $engine;
|
$this->engine = $engine;
|
||||||
|
$this->translator = $translator;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,7 +94,13 @@ final class SocialIssueRender implements ChillEntityRenderInterface
|
|||||||
|
|
||||||
$titles = array_reverse($titles);
|
$titles = array_reverse($titles);
|
||||||
|
|
||||||
return implode($options[self::SEPARATOR_KEY], $titles);
|
$title = implode($options[self::SEPARATOR_KEY], $titles);
|
||||||
|
|
||||||
|
if ($options[self::SHOW_AND_CHILDREN] && $socialIssue->hasChildren()) {
|
||||||
|
$title .= ' (' . $this->translator->trans($options[self::AND_CHILDREN_MENTION]) . ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $title;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function supports($entity, array $options): bool
|
public function supports($entity, array $options): bool
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
<?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\Tests\Entity\SocialWork;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
|
final class SocialActionTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testGetDescendantsWithThisForActions()
|
||||||
|
{
|
||||||
|
$parentA = new SocialAction();
|
||||||
|
$childA = (new SocialAction())->setParent($parentA);
|
||||||
|
$grandChildA = (new SocialAction())->setParent($childA);
|
||||||
|
$grandGrandChildA = (new SocialAction())->setParent($grandChildA);
|
||||||
|
$unrelatedA = new SocialAction();
|
||||||
|
|
||||||
|
$parentB = new SocialAction();
|
||||||
|
$childB = (new SocialAction())->setParent($parentB);
|
||||||
|
$grandChildB = (new SocialAction())->setParent($childB);
|
||||||
|
$grandGrandChildB = (new SocialAction())->setParent($grandChildB);
|
||||||
|
$unrelatedB = new SocialAction();
|
||||||
|
|
||||||
|
$actual = SocialAction::getDescendantsWithThisForActions([$parentA, $parentB]);
|
||||||
|
|
||||||
|
$this->assertContains($parentA, $actual);
|
||||||
|
$this->assertContains($parentB, $actual);
|
||||||
|
$this->assertContains($childA, $actual);
|
||||||
|
$this->assertContains($childB, $actual);
|
||||||
|
$this->assertContains($grandChildA, $actual);
|
||||||
|
$this->assertContains($grandChildB, $actual);
|
||||||
|
$this->assertContains($grandGrandChildA, $actual);
|
||||||
|
$this->assertContains($grandGrandChildB, $actual);
|
||||||
|
$this->assertCount(8, $actual);
|
||||||
|
$this->assertNotContains($unrelatedA, $actual);
|
||||||
|
$this->assertNotContains($unrelatedB, $actual);
|
||||||
|
}
|
||||||
|
}
|
@ -55,6 +55,35 @@ final class SocialIssueTest extends TestCase
|
|||||||
$this->assertCount(0, $unrelated->getAncestors(false));
|
$this->assertCount(0, $unrelated->getAncestors(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetDescendantsWithThisForIssues()
|
||||||
|
{
|
||||||
|
$parentA = new SocialIssue();
|
||||||
|
$childA = (new SocialIssue())->setParent($parentA);
|
||||||
|
$grandChildA = (new SocialIssue())->setParent($childA);
|
||||||
|
$grandGrandChildA = (new SocialIssue())->setParent($grandChildA);
|
||||||
|
$unrelatedA = new SocialIssue();
|
||||||
|
|
||||||
|
$parentB = new SocialIssue();
|
||||||
|
$childB = (new SocialIssue())->setParent($parentB);
|
||||||
|
$grandChildB = (new SocialIssue())->setParent($childB);
|
||||||
|
$grandGrandChildB = (new SocialIssue())->setParent($grandChildB);
|
||||||
|
$unrelatedB = new SocialIssue();
|
||||||
|
|
||||||
|
$actual = SocialIssue::getDescendantsWithThisForIssues([$parentA, $parentB]);
|
||||||
|
|
||||||
|
$this->assertContains($parentA, $actual);
|
||||||
|
$this->assertContains($parentB, $actual);
|
||||||
|
$this->assertContains($childA, $actual);
|
||||||
|
$this->assertContains($childB, $actual);
|
||||||
|
$this->assertContains($grandChildA, $actual);
|
||||||
|
$this->assertContains($grandChildB, $actual);
|
||||||
|
$this->assertContains($grandGrandChildA, $actual);
|
||||||
|
$this->assertContains($grandGrandChildB, $actual);
|
||||||
|
$this->assertCount(8, $actual);
|
||||||
|
$this->assertNotContains($unrelatedA, $actual);
|
||||||
|
$this->assertNotContains($unrelatedB, $actual);
|
||||||
|
}
|
||||||
|
|
||||||
public function testIsDescendantOf()
|
public function testIsDescendantOf()
|
||||||
{
|
{
|
||||||
$parent = new SocialIssue();
|
$parent = new SocialIssue();
|
||||||
|
@ -205,9 +205,11 @@ Resources: Interlocuteurs privilégiés
|
|||||||
Any requestor to this accompanying course: Aucun demandeur pour ce parcours
|
Any requestor to this accompanying course: Aucun demandeur pour ce parcours
|
||||||
Social action: Action d'accompagnement
|
Social action: Action d'accompagnement
|
||||||
Social actions: Actions d'accompagnement
|
Social actions: Actions d'accompagnement
|
||||||
|
Pick a social action: Choisir une action d'accompagnement
|
||||||
Last social actions: Les dernières actions d'accompagnement
|
Last social actions: Les dernières actions d'accompagnement
|
||||||
Social issue: Problématique sociale
|
Social issue: Problématique sociale
|
||||||
Social issues: Problématiques sociales
|
Social issues: Problématiques sociales
|
||||||
|
Pick a social issue: Choisir une problématique sociale
|
||||||
Last events on accompanying course: Dernières actions de suivi
|
Last events on accompanying course: Dernières actions de suivi
|
||||||
Edit & activate accompanying course: Modifier et valider
|
Edit & activate accompanying course: Modifier et valider
|
||||||
See accompanying periods: Voir toutes les périodes d'accompagnement
|
See accompanying periods: Voir toutes les périodes d'accompagnement
|
||||||
@ -953,6 +955,7 @@ export:
|
|||||||
Group course by referrer's scope: Grouper les parcours par service du référent
|
Group course by referrer's scope: Grouper les parcours par service du référent
|
||||||
Computation date for referrer: Date à laquelle le référent était actif
|
Computation date for referrer: Date à laquelle le référent était actif
|
||||||
Referrer's scope: Service du référent de parcours
|
Referrer's scope: Service du référent de parcours
|
||||||
|
|
||||||
duration:
|
duration:
|
||||||
day: Durée du parcours en jours
|
day: Durée du parcours en jours
|
||||||
week: Durée du parcours en semaines
|
week: Durée du parcours en semaines
|
||||||
@ -965,3 +968,8 @@ export:
|
|||||||
by_referrer:
|
by_referrer:
|
||||||
Computation date for referrer: Date à laquelle le référent était actif
|
Computation date for referrer: Date à laquelle le référent était actif
|
||||||
|
|
||||||
|
social_action:
|
||||||
|
and children: et dérivés
|
||||||
|
|
||||||
|
social_issue:
|
||||||
|
and children: et dérivés
|
||||||
|
Loading…
x
Reference in New Issue
Block a user