merge 111 branch into this one

This commit is contained in:
2022-07-26 11:57:54 +02:00
17 changed files with 927 additions and 85 deletions

View File

@@ -93,9 +93,6 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface
$qb->select('COUNT(acp.id) AS export_result')
->from('ChillPersonBundle:AccompanyingPeriod', 'acp')
->where($expr->neq(
'acp.step', $expr->literal('DRAFT')
))
;
return $qb;

View File

@@ -131,9 +131,6 @@ class StatAccompanyingCourseDuration implements ExportInterface, GroupedExportIn
ELSE :force_closingDate
END ) - acp.openingDate
) AS export_result')
->where($expr->neq(
'acp.step', $expr->literal('DRAFT')
))
->setParameter('force_closingDate', $force_closingdate)
;

View File

@@ -0,0 +1,100 @@
<?php
namespace Chill\PersonBundle\Export\Filter;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive;
class ClosingMotiveFilter implements FilterInterface
{
/**
* @var TranslatableStringHelper
*/
private TranslatableStringHelper $translatableStringHelper;
public function __construct(
TranslatableStringHelper $translatableStringHelper
) {
$this->translatableStringHelper = $translatableStringHelper;
}
/**
* @inheritDoc
*/
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_closingmotives', EntityType::class, [
'class' => ClosingMotive::class,
'choice_label' => function (ClosingMotive $cm) {
return $this->translatableStringHelper->localize($cm->getName());
},
'multiple' => true,
'expanded' => true,
]);
}
/**
* @inheritDoc
*/
public function getTitle(): string
{
return 'Filter by closing motive';
}
/**
* @inheritDoc
*/
public function describeAction($data, $format = 'string'): array
{
$motives = [];
foreach ($data['accepted_closingmotives'] as $k => $v) {
$motives[] = $this->translatableStringHelper->localize($v->getName());
}
return [
'Filtered by closingmotive: only %closingmotives%', [
'%closingmotives%' => implode(', ou ', $motives)
]];
}
/**
* @inheritDoc
*/
public function addRole()
{
return null;
}
/**
* @inheritDoc
*/
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->in('acp.closingMotive', ':closingmotive');
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('closingmotive', $data['accepted_closingmotives']);
}
/**
* @inheritDoc
*/
public function applyOn(): string
{
return Declarations::ACP_TYPE;
}
}

View File

@@ -0,0 +1,87 @@
<?php
namespace Chill\PersonBundle\Export\Filter;
use Chill\MainBundle\Export\FilterInterface;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class ConfidentialFilter implements FilterInterface
{
private const CHOICES = [
'is not confidential' => false,
'is confidential' => true,
];
private CONST DEFAULT_CHOICE = false;
private TranslatorInterface $translator;
public function __construct(TranslatorInterface $translator)
{
$this->translator = $translator;
}
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_confidentials', ChoiceType::class, [
'choices' => self::CHOICES,
'multiple' => false,
'expanded' => true,
'empty_data' => self::DEFAULT_CHOICE,
'data' => self::DEFAULT_CHOICE,
]);
}
public function getTitle(): string
{
return 'Filter by confidential';
}
public function describeAction($data, $format = 'string'): array
{
dump($data, self::CHOICES);
foreach (self::CHOICES as $k => $v) {
if ($v === $data['accepted_confidentials']) {
$choice = $k;
}
}
return [
'Filtered by confidential: only %confidential%', [
'%confidential%' => $this->translator->trans($choice)
]
];
}
public function addRole()
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->eq('acp.confidential', ':confidential');
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('confidential', $data['accepted_confidentials']);
}
public function applyOn(): string
{
return Declarations::ACP_TYPE;
}
}

View File

@@ -0,0 +1,85 @@
<?php
namespace Chill\PersonBundle\Export\Filter;
use Chill\MainBundle\Export\FilterInterface;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class EmergencyFilter implements FilterInterface
{
private const CHOICES = [
'is not emergency' => false,
'is emergency' => true,
];
private CONST DEFAULT_CHOICE = false;
private TranslatorInterface $translator;
public function __construct(TranslatorInterface $translator)
{
$this->translator = $translator;
}
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_emergencies', ChoiceType::class, [
'choices' => self::CHOICES,
'multiple' => false,
'expanded' => true,
'empty_data' => self::DEFAULT_CHOICE,
'data' => self::DEFAULT_CHOICE,
]);
}
public function getTitle(): string
{
return 'Filter by emergency';
}
public function describeAction($data, $format = 'string'): array
{
foreach (self::CHOICES as $k => $v) {
if ($v === $data['accepted_emergencies']) {
$choice = $k;
}
}
return [
'Filtered by emergency: only %emergency%', [
'%emergency%' => $this->translator->trans($choice)
]
];
}
public function addRole()
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->eq('acp.emergency', ':emergency');
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('emergency', $data['accepted_emergencies']);
}
public function applyOn(): string
{
return Declarations::ACP_TYPE;
}
}

View File

@@ -0,0 +1,85 @@
<?php
namespace Chill\PersonBundle\Export\Filter;
use Chill\MainBundle\Export\FilterInterface;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class IntensityFilter implements FilterInterface
{
private const CHOICES = [
'is occasional' => 'occasional',
'is regular' => 'regular',
];
private CONST DEFAULT_CHOICE = 'occasional';
private TranslatorInterface $translator;
public function __construct(TranslatorInterface $translator)
{
$this->translator = $translator;
}
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_intensities', ChoiceType::class, [
'choices' => self::CHOICES,
'multiple' => false,
'expanded' => true,
'empty_data' => self::DEFAULT_CHOICE,
'data' => self::DEFAULT_CHOICE,
]);
}
public function getTitle(): string
{
return 'Filter by intensity';
}
public function describeAction($data, $format = 'string'): array
{
foreach (self::CHOICES as $k => $v) {
if ($v === $data['accepted_intensities']) {
$choice = $k;
}
}
return [
'Filtered by intensity: only %intensity%', [
'%intensity%' => $this->translator->trans($choice)
]
];
}
public function addRole()
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->eq('acp.intensity', ':intensity');
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('intensity', $data['accepted_intensities']);
}
public function applyOn(): string
{
return Declarations::ACP_TYPE;
}
}

View File

@@ -0,0 +1,100 @@
<?php
namespace Chill\PersonBundle\Export\Filter;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Origin;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use phpDocumentor\Reflection\Types\Boolean;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
class OriginFilter implements FilterInterface
{
/**
* @var TranslatableStringHelper
*/
private TranslatableStringHelper $translatableStringHelper;
public function __construct(
TranslatableStringHelper $translatableStringHelper
) {
$this->translatableStringHelper = $translatableStringHelper;
}
/**
* @inheritDoc
*/
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_origins', EntityType::class, [
'class' => Origin::class,
'choice_label' => function (Origin $o) {
return $this->translatableStringHelper->localize($o->getLabel());
},
'multiple' => true,
'expanded' => true
]);
}
/**
* @inheritDoc
*/
public function getTitle(): string
{
return 'Filter by origin';
}
/**
* @inheritDoc
*/
public function describeAction($data, $format = 'string'): array
{
$origins = [];
foreach ($data['accepted_origins'] as $v) {
$origins[] = $this->translatableStringHelper->localize($v->getLabel());
}
return ['Filtered by origins: only %origins%', [
'%origins%' => implode(', ou ', $origins)
]];
}
/**
* @inheritDoc
*/
public function addRole()
{
return null;
}
/**
* @inheritDoc
*/
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->in('acp.origin', ':origin');
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('origin', $data['accepted_origins']);
}
/**
* @inheritDoc
*/
public function applyOn(): string
{
return Declarations::ACP_TYPE;
}
}

View File

@@ -0,0 +1,144 @@
<?php
namespace Chill\PersonBundle\Export\Filter;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Chill\PersonBundle\Export\Declarations;
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class SocialIssueFilter implements FilterInterface
{
/**
* @var TranslatorInterface
*/
protected $translator;
/**
* @var TranslatableStringHelper
*/
private TranslatableStringHelper $translatableStringHelper;
/**
* @var SocialIssueRender
*/
private SocialIssueRender $socialIssueRender;
public function __construct(
TranslatorInterface $translator,
TranslatableStringHelper $translatableStringHelper,
SocialIssueRender $socialIssueRender
) {
$this->translator = $translator;
$this->translatableStringHelper = $translatableStringHelper;
$this->socialIssueRender = $socialIssueRender;
}
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_socialissues', EntityType::class, [
'class' => SocialIssue::class,
'choice_label' => function ($socialIssue) {
return $this->socialIssueRender->renderString($socialIssue, []);
},
'multiple' => true,
'expanded' => true,
]);
}
public function getTitle()
{
return 'Filter by social issue';
}
public function describeAction($data, $format = 'string')
{
$issues = [];
$socialissues = $this->addParentIssues($data['accepted_socialissues']);
foreach ($socialissues as $i) {
if ('null' === $i) {
$issues[] = $this->translator->trans('Not given');
} else {
$issues[] = $this->socialIssueRender->renderString($i, []);
}
}
return [
'Filtered by socialissues: only %socialissues%', [
'%socialissues%' => implode(', ou ', $issues)
]];
}
public function addRole()
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$qb->join('acp.socialIssues', 'si');
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->in('si.id', ':socialissues');
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('socialissues',
$this->addParentIssues($data['accepted_socialissues'])
);
}
/**
* "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
* @return array
*/
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(function ($item) {
return $item->getId();
}, $array);
$unique_ids = array_unique($ids);
return array_values(
array_intersect_key($array, $unique_ids));
}
public function applyOn()
{
return Declarations::ACP_TYPE;
}
}

View File

@@ -0,0 +1,88 @@
<?php
namespace Chill\PersonBundle\Export\Filter;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\FilterInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class StepFilter implements FilterInterface
{
private const STEPS = [
'Draft' => AccompanyingPeriod::STEP_DRAFT,
'Confirmed' => AccompanyingPeriod::STEP_CONFIRMED,
'Closed' => AccompanyingPeriod::STEP_CLOSED,
];
private const DEFAULT_CHOICE = AccompanyingPeriod::STEP_CONFIRMED;
/**
* @var TranslatorInterface
*/
protected $translator;
public function __construct(TranslatorInterface $translator)
{
$this->translator = $translator;
}
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_steps', ChoiceType::class, [
'choices' => self::STEPS,
'multiple' => false,
'expanded' => true,
'empty_data' => self::DEFAULT_CHOICE,
'data' => self::DEFAULT_CHOICE,
]);
}
public function getTitle()
{
return 'Filter by step';
}
public function describeAction($data, $format = 'string')
{
$step = array_flip(self::STEPS)[$data['accepted_steps']];
return ["Filtered by steps: only %step%", [
'%step%' => $this->translator->trans($step)
]];
}
public function addRole()
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->eq('acp.step', ':step');
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('step', $data['accepted_steps']);
}
public function applyOn()
{
return Declarations::ACP_TYPE;
}
}

View File

@@ -22,6 +22,7 @@ use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;
class UserJobFilter implements FilterInterface
@@ -31,6 +32,8 @@ class UserJobFilter implements FilterInterface
*/
protected $translator;
private Security $security;
/**
* @var TranslatableStringHelper
*/
@@ -38,16 +41,23 @@ class UserJobFilter implements FilterInterface
public function __construct(
TranslatorInterface $translator,
TranslatableStringHelper $translatableStringHelper
TranslatableStringHelper $translatableStringHelper,
Security $security
) {
$this->translator = $translator;
$this->translatableStringHelper = $translatableStringHelper;
$this->security = $security;
}
public function describeAction($data, $format = 'string')
{
// to complete..
return ['Filtered by user jobs'];
return [
'Filtered by user job: only %job%', [
'%job%' => $this->translatableStringHelper->localize(
$this->getUserJob()->getLabel()
)
],
];
}
public function addRole()
@@ -57,13 +67,8 @@ class UserJobFilter implements FilterInterface
public function alterQuery(QueryBuilder $qb, $data)
{
$qb
->join('acp.user', 'u')
->join('u.userJob', 'j')
;
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->in('u.userJob', ':userjob');
$clause = $qb->expr()->eq('acp.job', ':userjob');
if ($where instanceof Andx) {
$where->add($clause);
@@ -72,8 +77,7 @@ class UserJobFilter implements FilterInterface
}
$qb->add('where', $where);
$qb->setParameter('userjob', $data['accepted_userjob']);
$qb->setParameter('userjob', $this->getUserJob());
}
public function applyOn()
@@ -83,20 +87,18 @@ class UserJobFilter implements FilterInterface
public function buildForm(FormBuilderInterface $builder)
{
$builder
->add('accepted_userjob', EntityType::class, [
'class' => UserJob::class,
'choice_label' => function(UserJob $j) {
return $this->translatableStringHelper->localize($j->getLabel());
},
'multiple' => true,
'expanded' => true,
])
;
}
public function getTitle()
{
return 'Filter by user job';
}
private function getUserJob():UserJob
{
/** @var User $user */
$user = $this->security->getUser();
return $user->getUserJob();
}
}

View File

@@ -21,6 +21,7 @@ use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;
class UserScopeFilter implements FilterInterface
@@ -30,6 +31,8 @@ class UserScopeFilter implements FilterInterface
*/
protected $translator;
private Security $security;
/**
* @var TranslatableStringHelper
*/
@@ -37,16 +40,23 @@ class UserScopeFilter implements FilterInterface
public function __construct(
TranslatorInterface $translator,
TranslatableStringHelper $translatableStringHelper
TranslatableStringHelper $translatableStringHelper,
Security $security
) {
$this->translator = $translator;
$this->translatableStringHelper = $translatableStringHelper;
$this->security = $security;
}
public function describeAction($data, $format = 'string')
{
// to complete..
return ['Filtered by user scopes'];
return [
'Filtered by user main scope: only %scope%', [
'%scope%' => $this->translatableStringHelper->localize(
$this->getUserMainScope()->getName()
)
]
];
}
public function addRole()
@@ -56,13 +66,10 @@ class UserScopeFilter implements FilterInterface
public function alterQuery(QueryBuilder $qb, $data)
{
$qb
->join('acp.user', 'u')
->join('u.mainScope', 's')
;
$qb->join('acp.scopes', 's');
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->in('u.mainScope', ':userscope');
$clause = $qb->expr()->eq('s.id', ':userscope');
if ($where instanceof Andx) {
$where->add($clause);
@@ -71,7 +78,7 @@ class UserScopeFilter implements FilterInterface
}
$qb->add('where', $where);
$qb->setParameter('userscope', $data['accepted_userscope']);
$qb->setParameter('userscope', $this->getUserMainScope());
}
@@ -82,20 +89,18 @@ class UserScopeFilter implements FilterInterface
public function buildForm(FormBuilderInterface $builder)
{
$builder
->add('accepted_userscope', EntityType::class, [
'class' => Scope::class,
'choice_label' => function(Scope $s) {
return $this->translatableStringHelper->localize($s->getName());
},
'multiple' => true,
'expanded' => true,
])
;
}
public function getTitle()
{
return 'Filter by user scope';
}
private function getUserMainScope():Scope
{
/** @var User $user */
$user = $this->security->getUser();
return $user->getMainScope();
}
}