mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-20 14:43:49 +00:00
Merge branch '111_exports_suite' into calendar/finalization
This commit is contained in:
@@ -13,6 +13,7 @@ namespace Chill\PersonBundle\Controller;
|
||||
|
||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||
use Chill\MainBundle\Serializer\Model\Collection;
|
||||
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
|
||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
@@ -39,9 +40,11 @@ class SocialWorkEvaluationApiController extends AbstractController
|
||||
*/
|
||||
public function listEvaluationBySocialAction(SocialAction $action): Response
|
||||
{
|
||||
$pagination = $this->paginatorFactory->create($action->getEvaluations()->count());
|
||||
$evaluations = $action->getEvaluations()->filter(static fn (Evaluation $eval) => $eval->isActive());
|
||||
|
||||
$evaluations = $action->getEvaluations()->slice(
|
||||
$pagination = $this->paginatorFactory->create($evaluations->count());
|
||||
|
||||
$evaluations = $evaluations->slice(
|
||||
$pagination->getCurrentPageFirstItemNumber(),
|
||||
$pagination->getItemsPerPage()
|
||||
);
|
||||
|
@@ -22,6 +22,7 @@ use Chill\MainBundle\Entity\Scope;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Entity\UserJob;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodLocationHistory;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodStepHistory;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
|
||||
@@ -341,6 +342,12 @@ class AccompanyingPeriod implements
|
||||
*/
|
||||
private string $step = self::STEP_DRAFT;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity=AccompanyingPeriodStepHistory::class,
|
||||
* mappedBy="period", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||
*/
|
||||
private Collection $stepHistories;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="datetime", nullable=true, options={"default": NULL})
|
||||
*/
|
||||
@@ -395,8 +402,7 @@ class AccompanyingPeriod implements
|
||||
*/
|
||||
public function __construct(?DateTime $dateOpening = null)
|
||||
{
|
||||
$this->setOpeningDate($dateOpening ?? new DateTime('now'));
|
||||
$this->calendars = new ArrayCollection();
|
||||
$this->calendars = new ArrayCollection(); // TODO we cannot add a dependency between AccompanyingPeriod and calendars
|
||||
$this->participations = new ArrayCollection();
|
||||
$this->scopes = new ArrayCollection();
|
||||
$this->socialIssues = new ArrayCollection();
|
||||
@@ -405,6 +411,8 @@ class AccompanyingPeriod implements
|
||||
$this->resources = new ArrayCollection();
|
||||
$this->userHistories = new ArrayCollection();
|
||||
$this->locationHistories = new ArrayCollection();
|
||||
$this->stepHistories = new ArrayCollection();
|
||||
$this->setOpeningDate($dateOpening ?? new DateTime('now'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -995,6 +1003,11 @@ class AccompanyingPeriod implements
|
||||
return $this->step;
|
||||
}
|
||||
|
||||
public function getStepHistories(): Collection
|
||||
{
|
||||
return $this->stepHistories;
|
||||
}
|
||||
|
||||
public function getUser(): ?User
|
||||
{
|
||||
return $this->user;
|
||||
@@ -1263,7 +1276,11 @@ class AccompanyingPeriod implements
|
||||
*/
|
||||
public function setOpeningDate($openingDate)
|
||||
{
|
||||
$this->openingDate = $openingDate;
|
||||
if ($this->openingDate !== $openingDate) {
|
||||
$this->openingDate = $openingDate;
|
||||
|
||||
$this->ensureStepContinuity();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -1362,6 +1379,14 @@ class AccompanyingPeriod implements
|
||||
$this->bootPeriod();
|
||||
}
|
||||
|
||||
if (self::STEP_DRAFT !== $this->step && $previous !== $step) {
|
||||
// we create a new history
|
||||
$history = new AccompanyingPeriodStepHistory();
|
||||
$history->setStep($this->step)->setStartDate(new DateTimeImmutable('now'));
|
||||
|
||||
$this->addStepHistory($history);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -1402,6 +1427,17 @@ class AccompanyingPeriod implements
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function addStepHistory(AccompanyingPeriodStepHistory $stepHistory): self
|
||||
{
|
||||
if (!$this->stepHistories->contains($stepHistory)) {
|
||||
$this->stepHistories[] = $stepHistory;
|
||||
$stepHistory->setPeriod($this);
|
||||
$this->ensureStepContinuity();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function bootPeriod(): void
|
||||
{
|
||||
// first location history
|
||||
@@ -1413,6 +1449,43 @@ class AccompanyingPeriod implements
|
||||
$this->addLocationHistory($locationHistory);
|
||||
}
|
||||
|
||||
private function ensureStepContinuity(): void
|
||||
{
|
||||
// ensure continuity of histories
|
||||
$criteria = new Criteria();
|
||||
$criteria->orderBy(['startDate' => Criteria::ASC, 'id' => Criteria::ASC]);
|
||||
|
||||
/** @var Iterator $steps */
|
||||
$steps = $this->getStepHistories()->matching($criteria)->getIterator();
|
||||
$steps->rewind();
|
||||
|
||||
// we set the start date of the first step as the opening date, only if it is
|
||||
// not greater than the end date
|
||||
/** @var AccompanyingPeriodStepHistory $current */
|
||||
$current = $steps->current();
|
||||
|
||||
if (null === $current) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->getOpeningDate()->format('Y-m-d') !== $current->getStartDate()->format('Y-m-d')
|
||||
&& ($this->getOpeningDate() <= $current->getEndDate() || null === $current->getEndDate())) {
|
||||
$current->setStartDate(DateTimeImmutable::createFromMutable($this->getOpeningDate()));
|
||||
}
|
||||
|
||||
// then we set all the end date to the start date of the next one
|
||||
do {
|
||||
/** @var AccompanyingPeriodStepHistory $current */
|
||||
$current = $steps->current();
|
||||
$steps->next();
|
||||
|
||||
if ($steps->valid()) {
|
||||
$next = $steps->current();
|
||||
$current->setEndDate($next->getStartDate());
|
||||
}
|
||||
} while ($steps->valid());
|
||||
}
|
||||
|
||||
private function setRequestorPerson(?Person $requestorPerson = null): self
|
||||
{
|
||||
$this->requestorPerson = $requestorPerson;
|
||||
|
@@ -0,0 +1,115 @@
|
||||
<?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\Entity\AccompanyingPeriod;
|
||||
|
||||
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
|
||||
use Chill\MainBundle\Doctrine\Model\TrackCreationTrait;
|
||||
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
|
||||
use Chill\MainBundle\Doctrine\Model\TrackUpdateTrait;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table("chill_person_accompanying_period_step_history")
|
||||
*/
|
||||
class AccompanyingPeriodStepHistory implements TrackCreationInterface, TrackUpdateInterface
|
||||
{
|
||||
use TrackCreationTrait;
|
||||
|
||||
use TrackUpdateTrait;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
|
||||
*/
|
||||
private ?DateTimeImmutable $endDate = null;
|
||||
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private ?int $id = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=AccompanyingPeriod::class)
|
||||
*/
|
||||
private AccompanyingPeriod $period;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="date_immutable")
|
||||
*/
|
||||
private ?DateTimeImmutable $startDate = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text", nullable=false)
|
||||
*/
|
||||
private string $step;
|
||||
|
||||
public function getEndDate(): ?DateTimeImmutable
|
||||
{
|
||||
return $this->endDate;
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getPeriod(): AccompanyingPeriod
|
||||
{
|
||||
return $this->period;
|
||||
}
|
||||
|
||||
public function getStartDate(): ?DateTimeImmutable
|
||||
{
|
||||
return $this->startDate;
|
||||
}
|
||||
|
||||
public function getStep(): string
|
||||
{
|
||||
return $this->step;
|
||||
}
|
||||
|
||||
public function setEndDate(?DateTimeImmutable $endDate): self
|
||||
{
|
||||
$this->endDate = $endDate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal use AccompanyingPeriod::addLocationHistory
|
||||
*/
|
||||
public function setPeriod(AccompanyingPeriod $period): self
|
||||
{
|
||||
$this->period = $period;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setStartDate(?DateTimeImmutable $startDate): self
|
||||
{
|
||||
$this->startDate = $startDate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setStep(string $step): AccompanyingPeriodStepHistory
|
||||
{
|
||||
$this->step = $step;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -36,7 +36,7 @@ class Comment implements TrackCreationInterface, TrackUpdateInterface
|
||||
* inversedBy="comments")
|
||||
* @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
|
||||
*/
|
||||
private ?AccompanyingPeriod $accompanyingPeriod;
|
||||
private ?AccompanyingPeriod $accompanyingPeriod = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text")
|
||||
|
@@ -1488,7 +1488,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
$participation = $this->participationsContainAccompanyingPeriod($accompanyingPeriod);
|
||||
|
||||
if (!null === $participation) {
|
||||
$participation->setEndDate(DateTimeImmutable::class);
|
||||
$participation->setEndDate(new DateTime());
|
||||
$this->accompanyingPeriodParticipations->removeElement($participation);
|
||||
}
|
||||
}
|
||||
@@ -1569,8 +1569,6 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
*/
|
||||
public function setCenter(Center $center): self
|
||||
{
|
||||
$this->center = $center;
|
||||
|
||||
$modification = new DateTimeImmutable('now');
|
||||
|
||||
foreach ($this->centerHistory as $centerHistory) {
|
||||
|
@@ -26,6 +26,11 @@ use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
*/
|
||||
class Evaluation
|
||||
{
|
||||
/**
|
||||
* @ORM\Column(type="boolean", nullable=false, options={"default": true})
|
||||
*/
|
||||
private bool $active = true;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="dateinterval", nullable=true, options={"default": null})
|
||||
* @Serializer\Groups({"read"})
|
||||
@@ -114,6 +119,11 @@ class Evaluation
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
public function isActive(): bool
|
||||
{
|
||||
return $this->active;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*
|
||||
@@ -128,6 +138,13 @@ class Evaluation
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setActive(bool $active): Evaluation
|
||||
{
|
||||
$this->active = $active;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setDelay(?DateInterval $delay): self
|
||||
{
|
||||
$this->delay = $delay;
|
||||
|
@@ -228,6 +228,22 @@ class SocialAction
|
||||
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
|
||||
{
|
||||
return $this->evaluations;
|
||||
@@ -274,6 +290,11 @@ class SocialAction
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function hasChildren(): bool
|
||||
{
|
||||
return 0 < $this->getChildren()->count();
|
||||
}
|
||||
|
||||
public function hasParent(): bool
|
||||
{
|
||||
return $this->getParent() instanceof self;
|
||||
@@ -369,6 +390,8 @@ class SocialAction
|
||||
{
|
||||
$this->parent = $parent;
|
||||
|
||||
$parent->addChild($this);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@@ -71,11 +71,17 @@ class SocialIssue
|
||||
$this->socialActions = new ArrayCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal use @see{SocialIssue::setParent} instead
|
||||
*
|
||||
* @param SocialIssue $child
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addChild(self $child): self
|
||||
{
|
||||
if (!$this->children->contains($child)) {
|
||||
$this->children[] = $child;
|
||||
$child->setParent($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
@@ -215,6 +221,22 @@ class SocialIssue
|
||||
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
|
||||
{
|
||||
return $this->id;
|
||||
@@ -262,6 +284,11 @@ class SocialIssue
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function hasChildren(): bool
|
||||
{
|
||||
return 0 < $this->getChildren()->count();
|
||||
}
|
||||
|
||||
public function hasParent(): bool
|
||||
{
|
||||
return null !== $this->parent;
|
||||
@@ -329,6 +356,8 @@ class SocialIssue
|
||||
{
|
||||
$this->parent = $parent;
|
||||
|
||||
$parent->addChild($this);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,131 @@
|
||||
<?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\Aggregator\AccompanyingCourseAggregators;
|
||||
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\PersonBundle\Entity\Household\HouseholdComposition;
|
||||
use Chill\PersonBundle\Entity\Household\HouseholdMember;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Chill\PersonBundle\Repository\Household\HouseholdCompositionTypeRepositoryInterface;
|
||||
use Doctrine\ORM\Query\Expr\Join;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use function in_array;
|
||||
|
||||
class ByHouseholdCompositionAggregator implements AggregatorInterface
|
||||
{
|
||||
private const PREFIX = 'acp_by_household_compo_agg';
|
||||
|
||||
private HouseholdCompositionTypeRepositoryInterface $householdCompositionTypeRepository;
|
||||
|
||||
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||
|
||||
public function __construct(HouseholdCompositionTypeRepositoryInterface $householdCompositionTypeRepository, TranslatableStringHelperInterface $translatableStringHelper)
|
||||
{
|
||||
$this->householdCompositionTypeRepository = $householdCompositionTypeRepository;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
}
|
||||
|
||||
public function addRole(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$p = self::PREFIX;
|
||||
|
||||
if (!in_array('acppart', $qb->getAllAliases(), true)) {
|
||||
$qb->leftJoin('acp.participations', 'acppart');
|
||||
}
|
||||
|
||||
$qb
|
||||
->leftJoin(
|
||||
HouseholdMember::class,
|
||||
"{$p}_hm",
|
||||
Join::WITH,
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull("{$p}_hm"),
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->lte("{$p}_hm.startDate", ":{$p}_date"),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull("{$p}_hm.endDate"),
|
||||
$qb->expr()->gt("{$p}_hm.endDate", ":{$p}_date")
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
->leftJoin(
|
||||
HouseholdComposition::class,
|
||||
"{$p}_compo",
|
||||
Join::WITH,
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull("{$p}_compo"),
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->lte("{$p}_compo.startDate", ":{$p}_date"),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull("{$p}_compo.endDate"),
|
||||
$qb->expr()->gt("{$p}_compo.endDate", ":{$p}_date")
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
->addSelect("IDENTITY({$p}_compo.householdCompositionType) AS {$p}_select")
|
||||
->setParameter("{$p}_date", $data['date_calc'])
|
||||
->addGroupBy("{$p}_select");
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
{
|
||||
return Declarations::ACP_TYPE;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add('date_calc', ChillDateType::class, [
|
||||
'label' => 'export.aggregator.course.by_household_composition.Calc date',
|
||||
'input_format' => 'datetime_immutable',
|
||||
'data' => new \DateTimeImmutable('now'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
return function ($value) {
|
||||
if ('_header' === $value) {
|
||||
return 'export.aggregator.course.by_household_composition.Household composition';
|
||||
}
|
||||
|
||||
if (null === $value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (null === $o = $this->householdCompositionTypeRepository->find($value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->translatableStringHelper->localize($o->getLabel());
|
||||
};
|
||||
}
|
||||
|
||||
public function getQueryKeys($data)
|
||||
{
|
||||
return [self::PREFIX . '_select'];
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return 'export.aggregator.course.by_household_composition.Group course by household composition';
|
||||
}
|
||||
}
|
@@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use LogicException;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
@@ -65,8 +66,6 @@ class ConfidentialAggregator implements AggregatorInterface
|
||||
default:
|
||||
throw new LogicException(sprintf('The value %s is not valid', $value));
|
||||
}
|
||||
|
||||
return $value;
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -13,12 +13,21 @@ namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
|
||||
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use LogicException;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
final class DurationAggregator implements AggregatorInterface
|
||||
{
|
||||
private const CHOICES = [
|
||||
'month',
|
||||
'week',
|
||||
'day',
|
||||
];
|
||||
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
public function __construct(TranslatorInterface $translator)
|
||||
@@ -33,19 +42,31 @@ final class DurationAggregator implements AggregatorInterface
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$qb->addSelect(
|
||||
'
|
||||
(acp.closingDate - acp.openingDate +15) *12/365
|
||||
AS duration_aggregator'
|
||||
);
|
||||
switch ($data['precision']) {
|
||||
case 'day':
|
||||
$qb->addSelect('(COALESCE(acp.closingDate, :now) - acp.openingDate) AS duration_aggregator');
|
||||
|
||||
// TODO Pour avoir un interval plus précis (nécessaire ?):
|
||||
// adapter la fonction extract pour pouvoir l'utiliser avec des intervals: extract(month from interval)
|
||||
// et ajouter une fonction custom qui calcule plus précisément les intervals, comme doctrineum/date-interval
|
||||
// https://packagist.org/packages/doctrineum/date-interval#3.1.0 (mais composer fait un conflit de dépendance)
|
||||
break;
|
||||
|
||||
$qb->addGroupBy('duration_aggregator');
|
||||
$qb->addOrderBy('duration_aggregator');
|
||||
case 'week':
|
||||
$qb->addSelect('(COALESCE(acp.closingDate, :now) - acp.openingDate) / 7 AS duration_aggregator');
|
||||
|
||||
break;
|
||||
|
||||
case 'month':
|
||||
$qb->addSelect('(EXTRACT (MONTH FROM AGE(COALESCE(acp.closingDate, :now), acp.openingDate)) * 12 +
|
||||
EXTRACT (MONTH FROM AGE(COALESCE(acp.closingDate, :now), acp.openingDate))) AS duration_aggregator');
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new LogicException('precision not supported: ' . $data['precision']);
|
||||
}
|
||||
|
||||
$qb
|
||||
->setParameter('now', new DateTimeImmutable('now'))
|
||||
->addGroupBy('duration_aggregator')
|
||||
->addOrderBy('duration_aggregator');
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
@@ -55,25 +76,27 @@ final class DurationAggregator implements AggregatorInterface
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
// no form
|
||||
$builder->add('precision', ChoiceType::class, [
|
||||
'choices' => array_combine(self::CHOICES, self::CHOICES),
|
||||
'label' => 'export.aggregator.course.duration.Precision',
|
||||
'choice_label' => static fn (string $c) => 'export.aggregator.course.duration.' . $c,
|
||||
'multiple' => false,
|
||||
'expanded' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
return function ($value): ?string {
|
||||
return static function ($value) use ($data) {
|
||||
if ('_header' === $value) {
|
||||
return 'Rounded month duration';
|
||||
return 'export.aggregator.course.duration.' . $data['precision'];
|
||||
}
|
||||
|
||||
if (null === $value) {
|
||||
return $this->translator->trans('current duration'); // when closingDate is null
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (0 === $value) {
|
||||
return $this->translator->trans('duration 0 month');
|
||||
}
|
||||
|
||||
return $value . $this->translator->trans(' months');
|
||||
return $value;
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use LogicException;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
@@ -65,8 +66,6 @@ class EmergencyAggregator implements AggregatorInterface
|
||||
default:
|
||||
throw new LogicException(sprintf('The value %s is not valid', $value));
|
||||
}
|
||||
|
||||
return $value;
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use LogicException;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
|
@@ -12,15 +12,20 @@ declare(strict_types=1);
|
||||
namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
|
||||
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||
use Chill\MainBundle\Repository\UserRepository;
|
||||
use Chill\MainBundle\Templating\Entity\UserRender;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use function in_array;
|
||||
|
||||
final class ReferrerAggregator implements AggregatorInterface
|
||||
{
|
||||
private const A = 'acp_ref_agg_uhistory';
|
||||
|
||||
private const P = 'acp_ref_agg_date';
|
||||
|
||||
private UserRender $userRender;
|
||||
|
||||
private UserRepository $userRepository;
|
||||
@@ -40,12 +45,23 @@ final class ReferrerAggregator implements AggregatorInterface
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
if (!in_array('acpuser', $qb->getAllAliases(), true)) {
|
||||
$qb->leftJoin('acp.user', 'acpuser');
|
||||
}
|
||||
|
||||
$qb->addSelect('acpuser.id AS referrer_aggregator');
|
||||
$qb->addGroupBy('referrer_aggregator');
|
||||
$qb
|
||||
->addSelect('IDENTITY(' . self::A . '.user) AS referrer_aggregator')
|
||||
->addGroupBy('referrer_aggregator')
|
||||
->leftJoin('acp.userHistories', self::A)
|
||||
->andWhere(
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull(self::A),
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->lte(self::A . '.startDate', ':' . self::P),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull(self::A . '.endDate'),
|
||||
$qb->expr()->gt(self::A . '.endDate', ':' . self::P)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
->setParameter(self::P, $data['date_calc']);
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
@@ -55,7 +71,13 @@ final class ReferrerAggregator implements AggregatorInterface
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
// no form
|
||||
$builder
|
||||
->add('date_calc', ChillDateType::class, [
|
||||
'input' => 'datetime_immutable',
|
||||
'data' => new DateTimeImmutable('now'),
|
||||
'label' => 'export.aggregator.course.by_referrer.Computation date for referrer',
|
||||
'required' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
|
@@ -12,19 +12,21 @@ declare(strict_types=1);
|
||||
namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
|
||||
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
//use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use DateTime;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Query\Expr\Andx;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use function in_array;
|
||||
|
||||
final class StepAggregator implements AggregatorInterface //, FilterInterface
|
||||
final class StepAggregator implements AggregatorInterface
|
||||
{
|
||||
private const A = 'acpstephistories';
|
||||
|
||||
private const P = 'acp_step_agg_date';
|
||||
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
public function __construct(
|
||||
@@ -40,30 +42,26 @@ final class StepAggregator implements AggregatorInterface //, FilterInterface
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$qb->addSelect('acp.step AS step_aggregator');
|
||||
$qb->addGroupBy('step_aggregator');
|
||||
|
||||
/*
|
||||
// add date in where clause
|
||||
$where = $qb->getDQLPart('where');
|
||||
|
||||
$clause = $qb->expr()->andX(
|
||||
$qb->expr()->lte('acp.openingDate', ':ondate'),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->gt('acp.closingDate', ':ondate'),
|
||||
$qb->expr()->isNull('acp.closingDate')
|
||||
)
|
||||
);
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
if (!in_array(self::A, $qb->getAllAliases(), true)) {
|
||||
$qb->leftJoin('acp.stepHistories', self::A);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('ondate', $data['on_date'], Types::DATE_MUTABLE);
|
||||
*/
|
||||
$qb
|
||||
->addSelect(self::A . '.step AS step_aggregator')
|
||||
->andWhere(
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull(self::A . '.step'),
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->lte(self::A . '.startDate', ':' . self::P),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull(self::A . '.endDate'),
|
||||
$qb->expr()->lt(self::A . '.endDate', ':' . self::P)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
->setParameter(self::P, $data['on_date'])
|
||||
->addGroupBy('step_aggregator');
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
@@ -94,8 +92,11 @@ final class StepAggregator implements AggregatorInterface //, FilterInterface
|
||||
case '_header':
|
||||
return 'Step';
|
||||
|
||||
case null:
|
||||
return '';
|
||||
|
||||
default:
|
||||
throw new LogicException(sprintf('The value %s is not valid', $value));
|
||||
return $value;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use function in_array;
|
||||
|
||||
final class CountryOfBirthAggregator implements AggregatorInterface, ExportElementValidatedInterface
|
||||
{
|
||||
@@ -83,16 +84,12 @@ final class CountryOfBirthAggregator implements AggregatorInterface, ExportEleme
|
||||
. ' is not known.');
|
||||
}
|
||||
|
||||
$qb->leftJoin('person.countryOfBirth', 'countryOfBirth');
|
||||
if (!in_array('countryOfBirth', $qb->getAllAliases(), true)) {
|
||||
$qb->leftJoin('person.countryOfBirth', 'countryOfBirth');
|
||||
}
|
||||
|
||||
// add group by
|
||||
$groupBy = $qb->getDQLPart('groupBy');
|
||||
|
||||
if (!empty($groupBy)) {
|
||||
$qb->addGroupBy('country_of_birth_aggregator');
|
||||
} else {
|
||||
$qb->groupBy('country_of_birth_aggregator');
|
||||
}
|
||||
$qb->addGroupBy('country_of_birth_aggregator');
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
|
@@ -70,14 +70,7 @@ final class HouseholdPositionAggregator implements AggregatorInterface, ExportEl
|
||||
$qb->setParameter('date', $data['date_position']);
|
||||
|
||||
$qb->addSelect('IDENTITY(householdmember.position) AS household_position_aggregator');
|
||||
|
||||
$groupBy = $qb->getDQLPart('groupBy');
|
||||
|
||||
if (!empty($groupBy)) {
|
||||
$qb->addGroupBy('household_position_aggregator');
|
||||
} else {
|
||||
$qb->groupBy('household_position_aggregator');
|
||||
}
|
||||
$qb->addGroupBy('household_position_aggregator');
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
|
@@ -43,14 +43,7 @@ final class MaritalStatusAggregator implements AggregatorInterface
|
||||
}
|
||||
|
||||
$qb->addSelect('personmarital.id as marital_status_aggregator');
|
||||
|
||||
$groupBy = $qb->getDQLPart('groupBy');
|
||||
|
||||
if (!empty($groupBy)) {
|
||||
$qb->addGroupBy('marital_status_aggregator');
|
||||
} else {
|
||||
$qb->groupBy('marital_status_aggregator');
|
||||
}
|
||||
$qb->addGroupBy('marital_status_aggregator');
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
|
@@ -83,15 +83,7 @@ final class NationalityAggregator implements AggregatorInterface, ExportElementV
|
||||
}
|
||||
|
||||
$qb->leftJoin('person.nationality', 'nationality');
|
||||
|
||||
// add group by
|
||||
$groupBy = $qb->getDQLPart('groupBy');
|
||||
|
||||
if (!empty($groupBy)) {
|
||||
$qb->addGroupBy('nationality_aggregator');
|
||||
} else {
|
||||
$qb->groupBy('nationality_aggregator');
|
||||
}
|
||||
$qb->addGroupBy('nationality_aggregator');
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
|
@@ -75,9 +75,9 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface
|
||||
return ['export_result'];
|
||||
}
|
||||
|
||||
public function getResult($qb, $data)
|
||||
public function getResult($query, $data)
|
||||
{
|
||||
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
@@ -99,6 +99,7 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface
|
||||
$qb = $this->repository->createQueryBuilder('acp');
|
||||
|
||||
$qb
|
||||
->andWhere('acp.step != :count_acp_step')
|
||||
->andWhere(
|
||||
$qb->expr()->exists(
|
||||
'SELECT 1 FROM ' . AccompanyingPeriodParticipation::class . ' acl_count_part
|
||||
@@ -107,6 +108,7 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface
|
||||
'
|
||||
)
|
||||
)
|
||||
->setParameter('count_acp_step', AccompanyingPeriod::STEP_DRAFT)
|
||||
->setParameter('authorized_centers', $centers);
|
||||
|
||||
$qb->select('COUNT(DISTINCT acp.id) AS export_result');
|
||||
|
@@ -22,6 +22,7 @@ use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\Query;
|
||||
use LogicException;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use function in_array;
|
||||
|
||||
@@ -74,9 +75,9 @@ class CountEvaluation implements ExportInterface, GroupedExportInterface
|
||||
return ['export_result'];
|
||||
}
|
||||
|
||||
public function getResult($qb, $data)
|
||||
public function getResult($query, $data)
|
||||
{
|
||||
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
|
@@ -23,6 +23,7 @@ use Chill\PersonBundle\Security\Authorization\HouseholdVoter;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\Query;
|
||||
use LogicException;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class CountHousehold implements ExportInterface, GroupedExportInterface
|
||||
@@ -74,9 +75,9 @@ class CountHousehold implements ExportInterface, GroupedExportInterface
|
||||
return ['export_result'];
|
||||
}
|
||||
|
||||
public function getResult($qb, $data)
|
||||
public function getResult($query, $data)
|
||||
{
|
||||
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
|
@@ -72,9 +72,9 @@ class CountPerson implements ExportInterface, GroupedExportInterface
|
||||
return ['export_result'];
|
||||
}
|
||||
|
||||
public function getResult($qb, $data)
|
||||
public function getResult($query, $data)
|
||||
{
|
||||
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
|
@@ -21,6 +21,7 @@ use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\Query;
|
||||
use LogicException;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use function in_array;
|
||||
|
||||
@@ -73,9 +74,9 @@ class CountPersonWithAccompanyingCourse implements ExportInterface, GroupedExpor
|
||||
return ['export_result'];
|
||||
}
|
||||
|
||||
public function getResult($qb, $data)
|
||||
public function getResult($query, $data)
|
||||
{
|
||||
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
|
@@ -75,9 +75,9 @@ class CountSocialWorkActions implements ExportInterface, GroupedExportInterface
|
||||
return ['export_result'];
|
||||
}
|
||||
|
||||
public function getResult($qb, $data)
|
||||
public function getResult($query, $data)
|
||||
{
|
||||
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
|
@@ -120,10 +120,7 @@ class ListPersonDuplicate implements DirectExportInterface, ExportElementValidat
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Create a list of duplicate people';
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use LogicException;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class StatAccompanyingCourseDuration implements ExportInterface, GroupedExportInterface
|
||||
@@ -79,9 +80,9 @@ class StatAccompanyingCourseDuration implements ExportInterface, GroupedExportIn
|
||||
return ['export_result'];
|
||||
}
|
||||
|
||||
public function getResult($qb, $data)
|
||||
public function getResult($query, $data)
|
||||
{
|
||||
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
|
@@ -11,13 +11,11 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
|
||||
|
||||
use Chill\MainBundle\Entity\Location;
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\MainBundle\Form\Type\PickUserLocationType;
|
||||
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;
|
||||
|
||||
class AdministrativeLocationFilter implements FilterInterface
|
||||
@@ -37,17 +35,10 @@ class AdministrativeLocationFilter implements FilterInterface
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$where = $qb->getDQLPart('where');
|
||||
$clause = $qb->expr()->in('acp.administrativeLocation', ':locations');
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('locations', $data['accepted_locations']);
|
||||
$qb
|
||||
->andWhere($clause)
|
||||
->setParameter('locations', $data['accepted_locations']);
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
@@ -57,13 +48,9 @@ class AdministrativeLocationFilter implements FilterInterface
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add('accepted_locations', EntityType::class, [
|
||||
'class' => Location::class,
|
||||
'choice_label' => function (Location $l) {
|
||||
return $l->getName() . ' (' . $this->translatableStringHelper->localize($l->getLocationType()->getTitle()) . ')';
|
||||
},
|
||||
$builder->add('accepted_locations', PickUserLocationType::class, [
|
||||
'label' => 'Accepted locations',
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -76,7 +63,7 @@ class AdministrativeLocationFilter implements FilterInterface
|
||||
}
|
||||
|
||||
return ['Filtered by administratives locations: only %locations%', [
|
||||
'%locations%' => implode(', ou ', $locations),
|
||||
'%locations%' => implode(', ', $locations),
|
||||
]];
|
||||
}
|
||||
|
||||
|
@@ -77,7 +77,7 @@ class ClosingMotiveFilter implements FilterInterface
|
||||
|
||||
return [
|
||||
'Filtered by closingmotive: only %closingmotives%', [
|
||||
'%closingmotives%' => implode(', ou ', $motives),
|
||||
'%closingmotives%' => implode(', ', $motives),
|
||||
], ];
|
||||
}
|
||||
|
||||
|
@@ -73,15 +73,11 @@ class ConfidentialFilter implements FilterInterface
|
||||
|
||||
public function describeAction($data, $format = 'string'): array
|
||||
{
|
||||
foreach (self::CHOICES as $k => $v) {
|
||||
if ($v === $data['accepted_confidentials']) {
|
||||
$choice = $k;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'Filtered by confidential: only %confidential%', [
|
||||
'%confidential%' => $this->translator->trans($choice),
|
||||
'%confidential%' => $this->translator->trans(
|
||||
$data['accepted_confidentials'] ? 'is confidential' : 'is not confidential'
|
||||
),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
@@ -1,90 +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\PersonBundle\Export\Filter\AccompanyingCourseFilters;
|
||||
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Entity\UserJob;
|
||||
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\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
class CurrentUserJobFilter implements FilterInterface
|
||||
{
|
||||
private Security $security;
|
||||
|
||||
private TranslatableStringHelper $translatableStringHelper;
|
||||
|
||||
public function __construct(
|
||||
TranslatableStringHelper $translatableStringHelper,
|
||||
Security $security
|
||||
) {
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
$this->security = $security;
|
||||
}
|
||||
|
||||
public function addRole(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$where = $qb->getDQLPart('where');
|
||||
$clause = $qb->expr()->eq('acp.job', ':userjob');
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('userjob', $this->getUserJob());
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
{
|
||||
return Declarations::ACP_TYPE;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string')
|
||||
{
|
||||
return [
|
||||
'Filtered by user job: only %job%', [
|
||||
'%job%' => $this->translatableStringHelper->localize(
|
||||
$this->getUserJob()->getLabel()
|
||||
),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return 'Filter by user job';
|
||||
}
|
||||
|
||||
private function getUserJob(): UserJob
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = $this->security->getUser();
|
||||
|
||||
return $user->getUserJob();
|
||||
}
|
||||
}
|
@@ -1,95 +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\PersonBundle\Export\Filter\AccompanyingCourseFilters;
|
||||
|
||||
use Chill\MainBundle\Entity\Scope;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
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\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use function in_array;
|
||||
|
||||
class CurrentUserScopeFilter implements FilterInterface
|
||||
{
|
||||
private Security $security;
|
||||
|
||||
private TranslatableStringHelper $translatableStringHelper;
|
||||
|
||||
public function __construct(
|
||||
TranslatableStringHelper $translatableStringHelper,
|
||||
Security $security
|
||||
) {
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
$this->security = $security;
|
||||
}
|
||||
|
||||
public function addRole(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
if (!in_array('acpscope', $qb->getAllAliases(), true)) {
|
||||
$qb->join('acp.scopes', 'acpscope');
|
||||
}
|
||||
|
||||
$where = $qb->getDQLPart('where');
|
||||
$clause = $qb->expr()->eq('acpscope.id', ':userscope');
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('userscope', $this->getUserMainScope());
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
{
|
||||
return Declarations::ACP_TYPE;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string')
|
||||
{
|
||||
return [
|
||||
'Filtered by user main scope: only %scope%', [
|
||||
'%scope%' => $this->translatableStringHelper->localize(
|
||||
$this->getUserMainScope()->getName()
|
||||
),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return 'Filter by user scope';
|
||||
}
|
||||
|
||||
private function getUserMainScope(): Scope
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = $this->security->getUser();
|
||||
|
||||
return $user->getMainScope();
|
||||
}
|
||||
}
|
@@ -73,15 +73,11 @@ class EmergencyFilter implements FilterInterface
|
||||
|
||||
public function describeAction($data, $format = 'string'): array
|
||||
{
|
||||
foreach (self::CHOICES as $k => $v) {
|
||||
if ($v === $data['accepted_emergency']) {
|
||||
$choice = $k;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'Filtered by emergency: only %emergency%', [
|
||||
'%emergency%' => $this->translator->trans($choice),
|
||||
'%emergency%' => $this->translator->trans(
|
||||
$data['accepted_emergency'] ? 'is emergency' : 'is not emergency'
|
||||
),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@ use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Doctrine\ORM\Query\Expr\Andx;
|
||||
use Chill\PersonBundle\Repository\SocialWork\EvaluationRepositoryInterface;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
@@ -23,11 +23,15 @@ use function in_array;
|
||||
|
||||
class EvaluationFilter implements FilterInterface
|
||||
{
|
||||
private EvaluationRepositoryInterface $evaluationRepository;
|
||||
|
||||
private TranslatableStringHelper $translatableStringHelper;
|
||||
|
||||
public function __construct(
|
||||
EvaluationRepositoryInterface $evaluationRepository,
|
||||
TranslatableStringHelper $translatableStringHelper
|
||||
) {
|
||||
$this->evaluationRepository = $evaluationRepository;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
}
|
||||
|
||||
@@ -50,16 +54,8 @@ class EvaluationFilter implements FilterInterface
|
||||
$qb->join('workeval.evaluation', 'eval');
|
||||
}
|
||||
|
||||
$where = $qb->getDQLPart('where');
|
||||
$clause = $qb->expr()->in('eval.id', ':evaluations');
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->andWhere($clause);
|
||||
$qb->setParameter('evaluations', $data['accepted_evaluations']);
|
||||
}
|
||||
|
||||
@@ -72,11 +68,13 @@ class EvaluationFilter implements FilterInterface
|
||||
{
|
||||
$builder->add('accepted_evaluations', EntityType::class, [
|
||||
'class' => Evaluation::class,
|
||||
'choices' => $this->evaluationRepository->findAllActive(),
|
||||
'choice_label' => function (Evaluation $ev) {
|
||||
return $this->translatableStringHelper->localize($ev->getTitle());
|
||||
},
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
'expanded' => false,
|
||||
'attr' => ['class' => 'select2'],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -89,7 +87,7 @@ class EvaluationFilter implements FilterInterface
|
||||
}
|
||||
|
||||
return ['Filtered by evaluations: only %evals%', [
|
||||
'%evals%' => implode(', ou ', $evaluations),
|
||||
'%evals%' => implode(', ', $evaluations),
|
||||
]];
|
||||
}
|
||||
|
||||
|
@@ -73,15 +73,9 @@ class IntensityFilter implements FilterInterface
|
||||
|
||||
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),
|
||||
'%intensity%' => $this->translator->trans($data['accepted_intensities']),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
@@ -76,7 +76,7 @@ class OriginFilter implements FilterInterface
|
||||
}
|
||||
|
||||
return ['Filtered by origins: only %origins%', [
|
||||
'%origins%' => implode(', ou ', $origins),
|
||||
'%origins%' => implode(', ', $origins),
|
||||
]];
|
||||
}
|
||||
|
||||
|
@@ -11,17 +11,23 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
|
||||
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||
use Chill\MainBundle\Form\Type\PickUserDynamicType;
|
||||
use Chill\MainBundle\Templating\Entity\UserRender;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Doctrine\ORM\Query\Expr\Andx;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class ReferrerFilter implements FilterInterface
|
||||
{
|
||||
private const A = 'acp_referrer_filter_uhistory';
|
||||
|
||||
private const P = 'acp_referrer_filter_date';
|
||||
|
||||
private const PU = 'acp_referrer_filter_users';
|
||||
|
||||
private UserRender $userRender;
|
||||
|
||||
public function __construct(UserRender $userRender)
|
||||
@@ -36,17 +42,22 @@ class ReferrerFilter implements FilterInterface
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$where = $qb->getDQLPart('where');
|
||||
$clause = $qb->expr()->in('acp.user', ':referrers');
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('referrers', $data['accepted_referrers']);
|
||||
$qb
|
||||
->join('acp.userHistories', self::A)
|
||||
->andWhere(
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->lte(self::A . '.startDate', ':' . self::P),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull(self::A . '.endDate'),
|
||||
$qb->expr()->gt(self::A . '.endDate', ':' . self::P)
|
||||
)
|
||||
)
|
||||
)
|
||||
->andWhere(
|
||||
$qb->expr()->in(self::A . '.user', ':' . self::PU)
|
||||
)
|
||||
->setParameter(self::PU, $data['accepted_referrers'])
|
||||
->setParameter(self::P, $data['date_calc']);
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
@@ -56,14 +67,16 @@ class ReferrerFilter implements FilterInterface
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add('accepted_referrers', EntityType::class, [
|
||||
'class' => User::class,
|
||||
'choice_label' => function (User $u) {
|
||||
return $this->userRender->renderString($u, []);
|
||||
},
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
]);
|
||||
$builder
|
||||
->add('accepted_referrers', PickUserDynamicType::class, [
|
||||
'multiple' => true,
|
||||
])
|
||||
->add('date_calc', ChillDateType::class, [
|
||||
'input' => 'datetime_immutable',
|
||||
'data' => new DateTimeImmutable('now'),
|
||||
'label' => 'export.filter.course.by_referrer.Computation date for referrer',
|
||||
'required' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string'): array
|
||||
@@ -76,7 +89,7 @@ class ReferrerFilter implements FilterInterface
|
||||
|
||||
return [
|
||||
'Filtered by referrer: only %referrers%', [
|
||||
'%referrers' => implode(', ou ', $users),
|
||||
'%referrers' => implode(', ', $users),
|
||||
], ];
|
||||
}
|
||||
|
||||
|
@@ -15,10 +15,9 @@ use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Chill\PersonBundle\Form\Type\PickSocialActionType;
|
||||
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
|
||||
use Doctrine\ORM\Query\Expr\Andx;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use function in_array;
|
||||
|
||||
@@ -51,17 +50,13 @@ class SocialActionFilter implements FilterInterface
|
||||
$qb->join('acpw.socialAction', 'acpwsocialaction');
|
||||
}
|
||||
|
||||
$where = $qb->getDQLPart('where');
|
||||
$clause = $qb->expr()->in('acpwsocialaction.id', ':socialactions');
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('socialactions', $data['accepted_socialactions']);
|
||||
$qb->andWhere($clause)
|
||||
->setParameter(
|
||||
'socialactions',
|
||||
SocialAction::getDescendantsWithThisForActions($data['accepted_socialactions'])->toArray()
|
||||
);
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
@@ -71,26 +66,25 @@ class SocialActionFilter implements FilterInterface
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add('accepted_socialactions', EntityType::class, [
|
||||
'class' => SocialAction::class,
|
||||
'choice_label' => function (SocialAction $sa) {
|
||||
return $this->actionRender->renderString($sa, []);
|
||||
},
|
||||
$builder->add('accepted_socialactions', PickSocialActionType::class, [
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string'): array
|
||||
{
|
||||
$socialactions = [];
|
||||
$actions = [];
|
||||
|
||||
foreach ($data['accepted_socialactions'] as $sa) {
|
||||
$socialactions[] = $this->actionRender->renderString($sa, []);
|
||||
$socialactions = $data['accepted_socialactions'];
|
||||
|
||||
foreach ($socialactions as $action) {
|
||||
$actions[] = $this->actionRender->renderString($action, [
|
||||
'show_and_children' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
return ['Filtered by socialactions: only %socialactions%', [
|
||||
'%socialactions%' => implode(', ou ', $socialactions),
|
||||
'%socialactions%' => implode(', ', $actions),
|
||||
]];
|
||||
}
|
||||
|
||||
|
@@ -15,10 +15,9 @@ use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Chill\PersonBundle\Form\Type\PickSocialIssueType;
|
||||
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;
|
||||
use function in_array;
|
||||
@@ -55,20 +54,13 @@ class SocialIssueFilter implements FilterInterface
|
||||
$qb->join('acp.socialIssues', 'acpsocialissue');
|
||||
}
|
||||
|
||||
$where = $qb->getDQLPart('where');
|
||||
$clause = $qb->expr()->in('acpsocialissue.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'])
|
||||
);
|
||||
$qb->andWhere($clause)
|
||||
->setParameter(
|
||||
'socialissues',
|
||||
SocialIssue::getDescendantsWithThisForIssues($data['accepted_socialissues'])
|
||||
);
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
@@ -78,74 +70,31 @@ class SocialIssueFilter implements FilterInterface
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add('accepted_socialissues', EntityType::class, [
|
||||
'class' => SocialIssue::class,
|
||||
'choice_label' => function ($socialIssue) {
|
||||
return $this->socialIssueRender->renderString($socialIssue, []);
|
||||
},
|
||||
$builder->add('accepted_socialissues', PickSocialIssueType::class, [
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string')
|
||||
public function describeAction($data, $format = 'string'): array
|
||||
{
|
||||
$issues = [];
|
||||
|
||||
$socialissues = $this->addParentIssues($data['accepted_socialissues']);
|
||||
$socialissues = $data['accepted_socialissues'];
|
||||
|
||||
foreach ($socialissues as $i) {
|
||||
if ('null' === $i) {
|
||||
$issues[] = $this->translator->trans('Not given');
|
||||
} else {
|
||||
$issues[] = $this->socialIssueRender->renderString($i, []);
|
||||
}
|
||||
foreach ($socialissues as $issue) {
|
||||
$issues[] = $this->socialIssueRender->renderString($issue, [
|
||||
'show_and_children' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
return [
|
||||
'Filtered by socialissues: only %socialissues%', [
|
||||
'%socialissues%' => implode(', ou ', $issues),
|
||||
'%socialissues%' => implode(', ', $issues),
|
||||
], ];
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
public function getTitle(): string
|
||||
{
|
||||
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,130 @@
|
||||
<?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\Entity\User;
|
||||
use Chill\MainBundle\Entity\UserJob;
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||
use Chill\MainBundle\Repository\UserJobRepositoryInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
class UserJobFilter implements FilterInterface
|
||||
{
|
||||
private const A = 'acp_ujob_filter_uhistory';
|
||||
|
||||
private const AU = 'acp_ujob_filter_uhistory_user';
|
||||
|
||||
private const P = 'acp_ujob_filter_date';
|
||||
|
||||
private const PJ = 'acp_ujob_filter_job';
|
||||
|
||||
private Security $security;
|
||||
|
||||
private TranslatableStringHelper $translatableStringHelper;
|
||||
|
||||
private UserJobRepositoryInterface $userJobRepository;
|
||||
|
||||
public function __construct(
|
||||
Security $security,
|
||||
TranslatableStringHelper $translatableStringHelper,
|
||||
UserJobRepositoryInterface $userJobRepository
|
||||
) {
|
||||
$this->security = $security;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
$this->userJobRepository = $userJobRepository;
|
||||
}
|
||||
|
||||
public function addRole(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$qb
|
||||
->join('acp.userHistories', self::A)
|
||||
->andWhere(
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->lte(self::A . '.startDate', ':' . self::P),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull(self::A . '.endDate'),
|
||||
$qb->expr()->gt(self::A . '.endDate', ':' . self::P)
|
||||
)
|
||||
)
|
||||
)
|
||||
->setParameter(self::P, $data['date_calc'])
|
||||
->join(self::A . '.user', self::AU)
|
||||
->andWhere(
|
||||
$qb->expr()->in(self::AU . '.userJob', ':' . self::PJ)
|
||||
)
|
||||
->setParameter(self::PJ, $data['jobs']);
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
{
|
||||
return Declarations::ACP_TYPE;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder
|
||||
->add('jobs', EntityType::class, [
|
||||
'class' => UserJob::class,
|
||||
'choices' => $this->userJobRepository->findAllActive(),
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
'choice_label' => fn (UserJob $job) => $this->translatableStringHelper->localize($job->getLabel()),
|
||||
'label' => 'Job',
|
||||
])
|
||||
->add('date_calc', ChillDateType::class, [
|
||||
'input' => 'datetime_immutable',
|
||||
'data' => new DateTimeImmutable('now'),
|
||||
'label' => 'export.filter.course.by_user_scope.Computation date for referrer',
|
||||
'required' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string')
|
||||
{
|
||||
return [
|
||||
'Filtered by user job: only %job%', [
|
||||
'%job%' => implode(
|
||||
', ',
|
||||
array_map(
|
||||
fn (UserJob $job) => $this->translatableStringHelper->localize($job->getLabel()),
|
||||
$data['jobs']->toArray()
|
||||
)
|
||||
),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return 'Filter by user job';
|
||||
}
|
||||
|
||||
private function getUserJob(): UserJob
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = $this->security->getUser();
|
||||
|
||||
return $user->getUserJob();
|
||||
}
|
||||
}
|
@@ -0,0 +1,129 @@
|
||||
<?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\Entity\Scope;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||
use Chill\MainBundle\Repository\ScopeRepositoryInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
class UserScopeFilter implements FilterInterface
|
||||
{
|
||||
private const A = 'acp_uscope_filter_uhistory';
|
||||
|
||||
private const AU = 'acp_uscope_filter_uhistory_user';
|
||||
|
||||
private const P = 'acp_uscope_filter_date';
|
||||
|
||||
private const PS = 'acp_uscope_filter_scopes';
|
||||
|
||||
private ScopeRepositoryInterface $scopeRepository;
|
||||
|
||||
private Security $security;
|
||||
|
||||
private TranslatableStringHelper $translatableStringHelper;
|
||||
|
||||
public function __construct(
|
||||
ScopeRepositoryInterface $scopeRepository,
|
||||
Security $security,
|
||||
TranslatableStringHelper $translatableStringHelper
|
||||
) {
|
||||
$this->scopeRepository = $scopeRepository;
|
||||
$this->security = $security;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
}
|
||||
|
||||
public function addRole(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$qb
|
||||
->join('acp.userHistories', self::A)
|
||||
->andWhere(
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->lte(self::A . '.startDate', ':' . self::P),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull(self::A . '.endDate'),
|
||||
$qb->expr()->gt(self::A . '.endDate', ':' . self::P)
|
||||
)
|
||||
)
|
||||
)
|
||||
->setParameter(self::P, $data['date_calc'])
|
||||
->join(self::A . '.user', self::AU)
|
||||
->andWhere(
|
||||
$qb->expr()->in(self::AU . '.mainScope', ':' . self::PS)
|
||||
)
|
||||
->setParameter(self::PS, $data['scopes']);
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
{
|
||||
return Declarations::ACP_TYPE;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder
|
||||
->add('scopes', EntityType::class, [
|
||||
'class' => Scope::class,
|
||||
'choices' => $this->scopeRepository->findAllActive(),
|
||||
'choice_label' => fn (Scope $s) => $this->translatableStringHelper->localize($s->getName()),
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
])
|
||||
->add('date_calc', ChillDateType::class, [
|
||||
'input' => 'datetime_immutable',
|
||||
'data' => new DateTimeImmutable('now'),
|
||||
'label' => 'export.filter.course.by_user_scope.Computation date for referrer',
|
||||
'required' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string')
|
||||
{
|
||||
return [
|
||||
'Filtered by user main scope: only %scope%', [
|
||||
'%scope%' => implode(
|
||||
', ',
|
||||
array_map(
|
||||
fn (Scope $s) => $this->translatableStringHelper->localize($s->getName()),
|
||||
$data['scopes']->toArray()
|
||||
)
|
||||
),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return 'Filter by user scope';
|
||||
}
|
||||
|
||||
private function getUserMainScope(): Scope
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = $this->security->getUser();
|
||||
|
||||
return $user->getMainScope();
|
||||
}
|
||||
}
|
@@ -76,7 +76,7 @@ final class EvaluationTypeFilter implements FilterInterface
|
||||
}
|
||||
|
||||
return ['Filtered by evaluation type: only %evals%', [
|
||||
'%evals%' => implode(', ou ', $evals),
|
||||
'%evals%' => implode(', ', $evals),
|
||||
]];
|
||||
}
|
||||
|
||||
|
@@ -13,7 +13,6 @@ namespace Chill\PersonBundle\Export\Filter\EvaluationFilters;
|
||||
|
||||
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;
|
||||
@@ -22,8 +21,8 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
class MaxDateFilter implements FilterInterface
|
||||
{
|
||||
private const MAXDATE_CHOICES = [
|
||||
'is specified' => true,
|
||||
'is not specified' => false,
|
||||
'maxdate is specified' => true,
|
||||
'maxdate is not specified' => false,
|
||||
];
|
||||
|
||||
private TranslatorInterface $translator;
|
||||
@@ -40,21 +39,13 @@ class MaxDateFilter implements FilterInterface
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$where = $qb->getDQLPart('where');
|
||||
|
||||
if (true === $data['maxdate']) {
|
||||
$clause = $qb->expr()->isNotNull('eval.maxDate');
|
||||
$clause = $qb->expr()->isNotNull('workeval.maxDate');
|
||||
} else {
|
||||
$clause = $qb->expr()->isNull('eval.maxDate');
|
||||
$clause = $qb->expr()->isNull('workeval.maxDate');
|
||||
}
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->andWhere($clause);
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
@@ -73,19 +64,15 @@ class MaxDateFilter implements FilterInterface
|
||||
|
||||
public function describeAction($data, $format = 'string'): array
|
||||
{
|
||||
foreach (self::MAXDATE_CHOICES as $k => $v) {
|
||||
if ($v === $data['maxdate']) {
|
||||
$choice = $k;
|
||||
}
|
||||
}
|
||||
|
||||
return ['Filtered by maxdate: only %choice%', [
|
||||
'%choice%' => $this->translator->trans($choice),
|
||||
'%choice%' => $this->translator->trans(
|
||||
$data['maxdate'] ? 'maxdate is specified' : 'maxdate is not specified'
|
||||
),
|
||||
]];
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Filter by maxdate';
|
||||
return 'Filter evaluations by maxdate mention';
|
||||
}
|
||||
}
|
||||
|
@@ -95,7 +95,7 @@ class CompositionFilter implements FilterInterface
|
||||
}
|
||||
|
||||
return ['Filtered by composition: only %compositions% on %ondate%', [
|
||||
'%compositions%' => implode(', ou ', $compositions),
|
||||
'%compositions%' => implode(', ', $compositions),
|
||||
'%ondate%' => $data['on_date']->format('d-m-Y'),
|
||||
]];
|
||||
}
|
||||
|
@@ -35,7 +35,7 @@ class AgeFilter implements ExportElementValidatedInterface, FilterInterface
|
||||
$where = $qb->getDQLPart('where');
|
||||
|
||||
$min = null !== $data['min_age'] ? $data['min_age'] : 0;
|
||||
$max = null !== $data['max_age'] ? $data['max_age'] : 3000;
|
||||
$max = null !== $data['max_age'] ? $data['max_age'] : 150;
|
||||
$calc = $data['date_calc'];
|
||||
|
||||
$minDate = $calc->sub(new DateInterval('P' . $max . 'Y'));
|
||||
|
@@ -12,12 +12,9 @@ declare(strict_types=1);
|
||||
namespace Chill\PersonBundle\Export\Filter\PersonFilters;
|
||||
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Chill\PersonBundle\Entity\MaritalStatus;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use DateTime;
|
||||
use Doctrine\ORM\Query\Expr\Andx;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
|
||||
class MaritalStatusFilter implements FilterInterface
|
||||
@@ -37,25 +34,10 @@ class MaritalStatusFilter implements FilterInterface
|
||||
|
||||
public function alterQuery(\Doctrine\ORM\QueryBuilder $qb, $data)
|
||||
{
|
||||
$where = $qb->getDQLPart('where');
|
||||
|
||||
$clause = $qb->expr()->andX(
|
||||
$qb->expr()->in('person.maritalStatus', ':maritalStatus'),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->eq('person.maritalStatusDate', ':calc_date'),
|
||||
$qb->expr()->isNull('person.maritalStatusDate')
|
||||
)
|
||||
$qb->andWhere(
|
||||
$qb->expr()->in('person.maritalStatus', ':maritalStatus')
|
||||
);
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('maritalStatus', $data['maritalStatus']);
|
||||
$qb->setParameter('calc_date', $data['calc_date']);
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
@@ -75,11 +57,6 @@ class MaritalStatusFilter implements FilterInterface
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
]);
|
||||
|
||||
$builder->add('calc_date', ChillDateType::class, [
|
||||
'label' => 'Marital status at this time',
|
||||
'data' => new DateTime(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string')
|
||||
|
@@ -90,7 +90,7 @@ class JobFilter implements FilterInterface
|
||||
}
|
||||
|
||||
return ['Filtered by treating agent job: only %jobs%', [
|
||||
'%jobs%' => implode(', ou ', $userjobs),
|
||||
'%jobs%' => implode(', ', $userjobs),
|
||||
]];
|
||||
}
|
||||
|
||||
|
@@ -81,7 +81,7 @@ class ReferrerFilter implements FilterInterface
|
||||
|
||||
return [
|
||||
'Filtered by treating agent: only %agents%', [
|
||||
'%agents' => implode(', ou ', $users),
|
||||
'%agents' => implode(', ', $users),
|
||||
], ];
|
||||
}
|
||||
|
||||
|
@@ -90,7 +90,7 @@ class ScopeFilter implements FilterInterface
|
||||
}
|
||||
|
||||
return ['Filtered by treating agent scope: only %scopes%', [
|
||||
'%scopes%' => implode(', ou ', $scopes),
|
||||
'%scopes%' => implode(', ', $scopes),
|
||||
]];
|
||||
}
|
||||
|
||||
|
@@ -16,6 +16,7 @@ use Chill\MainBundle\Form\Type\TranslatableStringFormType;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\UrlType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
@@ -52,6 +53,14 @@ class EvaluationType extends AbstractType
|
||||
->add('notificationDelay', DateIntervalType::class, [
|
||||
'label' => 'evaluation.notificationDelay',
|
||||
'required' => false,
|
||||
])
|
||||
->add('active', ChoiceType::class, [
|
||||
'label' => 'active',
|
||||
'choices' => [
|
||||
'active' => true,
|
||||
'inactive' => false,
|
||||
],
|
||||
'required' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -15,9 +15,8 @@ use Chill\PersonBundle\Entity\Household\Household;
|
||||
use Chill\PersonBundle\Entity\Household\HouseholdComposition;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
|
||||
class HouseholdCompositionRepository implements ObjectRepository
|
||||
final class HouseholdCompositionRepository implements HouseholdCompositionRepositoryInterface
|
||||
{
|
||||
private EntityRepository $repository;
|
||||
|
||||
|
@@ -0,0 +1,45 @@
|
||||
<?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\Repository\Household;
|
||||
|
||||
use Chill\PersonBundle\Entity\Household\Household;
|
||||
use Chill\PersonBundle\Entity\Household\HouseholdComposition;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
|
||||
interface HouseholdCompositionRepositoryInterface extends ObjectRepository
|
||||
{
|
||||
public function countByHousehold(Household $household): int;
|
||||
|
||||
public function find($id): ?HouseholdComposition;
|
||||
|
||||
/**
|
||||
* @return array|HouseholdComposition[]
|
||||
*/
|
||||
public function findAll(): array;
|
||||
|
||||
/**
|
||||
* @param int $limit
|
||||
* @param int $offset
|
||||
*
|
||||
* @return array|object[]|HouseholdComposition[]
|
||||
*/
|
||||
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array;
|
||||
|
||||
/**
|
||||
* @return array|HouseholdComposition[]|object[]
|
||||
*/
|
||||
public function findByHousehold(Household $household, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array;
|
||||
|
||||
public function findOneBy(array $criteria): ?HouseholdComposition;
|
||||
|
||||
public function getClassName(): string;
|
||||
}
|
@@ -14,9 +14,8 @@ namespace Chill\PersonBundle\Repository\Household;
|
||||
use Chill\PersonBundle\Entity\Household\HouseholdCompositionType;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
|
||||
class HouseholdCompositionTypeRepository implements ObjectRepository
|
||||
final class HouseholdCompositionTypeRepository implements HouseholdCompositionTypeRepositoryInterface
|
||||
{
|
||||
private EntityRepository $repository;
|
||||
|
||||
|
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Repository\Household;
|
||||
|
||||
use Chill\PersonBundle\Entity\Household\HouseholdCompositionType;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
|
||||
interface HouseholdCompositionTypeRepositoryInterface extends ObjectRepository
|
||||
{
|
||||
public function find($id): ?HouseholdCompositionType;
|
||||
|
||||
/**
|
||||
* @return array|HouseholdCompositionType[]|object[]
|
||||
*/
|
||||
public function findAll(): array;
|
||||
|
||||
/**
|
||||
* @return array|HouseholdCompositionType[]
|
||||
*/
|
||||
public function findAllActive(): array;
|
||||
|
||||
/**
|
||||
* @param $limit
|
||||
* @param $offset
|
||||
*
|
||||
* @return array|HouseholdCompositionType[]|object[]
|
||||
*/
|
||||
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array;
|
||||
|
||||
public function findOneBy(array $criteria): ?HouseholdCompositionType;
|
||||
|
||||
public function getClassName(): string;
|
||||
}
|
@@ -14,9 +14,8 @@ namespace Chill\PersonBundle\Repository\SocialWork;
|
||||
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
|
||||
final class EvaluationRepository implements ObjectRepository
|
||||
final class EvaluationRepository implements EvaluationRepositoryInterface
|
||||
{
|
||||
private EntityRepository $repository;
|
||||
|
||||
@@ -38,6 +37,11 @@ final class EvaluationRepository implements ObjectRepository
|
||||
return $this->repository->findAll();
|
||||
}
|
||||
|
||||
public function findAllActive(): array
|
||||
{
|
||||
return $this->findBy(['active' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed|null $limit
|
||||
* @param mixed|null $offset
|
||||
|
@@ -0,0 +1,45 @@
|
||||
<?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\Repository\SocialWork;
|
||||
|
||||
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
|
||||
interface EvaluationRepositoryInterface extends ObjectRepository
|
||||
{
|
||||
public function find($id, ?int $lockMode = null, ?int $lockVersion = null): ?Evaluation;
|
||||
|
||||
/**
|
||||
* @return array<int, Evaluation>
|
||||
*/
|
||||
public function findAll(): array;
|
||||
|
||||
/**
|
||||
* @return array<int, Evaluation>
|
||||
*/
|
||||
public function findAllActive(): array;
|
||||
|
||||
/**
|
||||
* @param mixed|null $limit
|
||||
* @param mixed|null $offset
|
||||
*
|
||||
* @return array<int, Evaluation>
|
||||
*/
|
||||
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array;
|
||||
|
||||
public function findOneBy(array $criteria, ?array $orderBy = null): ?Evaluation;
|
||||
|
||||
/**
|
||||
* @return class-string
|
||||
*/
|
||||
public function getClassName(): string;
|
||||
}
|
@@ -63,13 +63,9 @@ final class GoalRepository implements ObjectRepository
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed|null $orderBy
|
||||
* @param mixed|null $limit
|
||||
* @param mixed|null $offset
|
||||
*
|
||||
* @return Goal[]
|
||||
*/
|
||||
public function findBySocialActionWithDescendants(SocialAction $action, $orderBy = null, $limit = null, $offset = null): array
|
||||
public function findBySocialActionWithDescendants(SocialAction $action, array $orderBy = [], ?int $limit = null, ?int $offset = null): array
|
||||
{
|
||||
$qb = $this->buildQueryBySocialActionWithDescendants($action);
|
||||
$qb->select('g');
|
||||
|
@@ -96,13 +96,9 @@ final class ResultRepository implements ObjectRepository
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed|null $orderBy
|
||||
* @param mixed|null $limit
|
||||
* @param mixed|null $offset
|
||||
*
|
||||
* @return Result[]
|
||||
*/
|
||||
public function findBySocialActionWithDescendants(SocialAction $action, $orderBy = null, $limit = null, $offset = null): array
|
||||
public function findBySocialActionWithDescendants(SocialAction $action, array $orderBy = [], ?int $limit = null, ?int $offset = null): array
|
||||
{
|
||||
$qb = $this->buildQueryBySocialActionWithDescendants($action);
|
||||
$qb->select('r');
|
||||
|
@@ -12,6 +12,7 @@ declare(strict_types=1);
|
||||
namespace Chill\PersonBundle\Repository\SocialWork;
|
||||
|
||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||
use DateTime;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
@@ -44,6 +45,14 @@ final class SocialActionRepository implements ObjectRepository
|
||||
return $this->repository->findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|SocialAction[]
|
||||
*/
|
||||
public function findAllActive(): array
|
||||
{
|
||||
return $this->buildQueryWithDesactivatedDateCriteria()->getQuery()->getResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed|null $limit
|
||||
* @param mixed|null $offset
|
||||
@@ -67,4 +76,16 @@ final class SocialActionRepository implements ObjectRepository
|
||||
{
|
||||
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;
|
||||
|
||||
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
||||
use DateTime;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
|
||||
final class SocialIssueRepository implements ObjectRepository
|
||||
@@ -38,6 +40,14 @@ final class SocialIssueRepository implements ObjectRepository
|
||||
return $this->repository->findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|SocialIssue[]
|
||||
*/
|
||||
public function findAllActive(): array
|
||||
{
|
||||
return $this->buildQueryWithDesactivatedDateCriteria()->getQuery()->getResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed|null $limit
|
||||
* @param mixed|null $offset
|
||||
@@ -61,4 +71,16 @@ final class SocialIssueRepository implements ObjectRepository
|
||||
{
|
||||
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\PersonBundle\Entity\SocialWork\SocialAction;
|
||||
use Symfony\Component\Templating\EngineInterface;
|
||||
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use function array_merge;
|
||||
use function array_reverse;
|
||||
use function implode;
|
||||
|
||||
class SocialActionRender implements ChillEntityRenderInterface
|
||||
{
|
||||
public const AND_CHILDREN_MENTION = 'show_and_children_mention';
|
||||
|
||||
public const DEFAULT_ARGS = [
|
||||
self::SEPARATOR_KEY => ' > ',
|
||||
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';
|
||||
|
||||
/**
|
||||
* 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 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->engine = $engine;
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
public function renderBox($socialAction, array $options): string
|
||||
@@ -72,7 +88,13 @@ class SocialActionRender implements ChillEntityRenderInterface
|
||||
|
||||
$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
|
||||
|
@@ -15,26 +15,42 @@ use Chill\MainBundle\Templating\Entity\ChillEntityRenderInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
||||
use Symfony\Component\Templating\EngineInterface;
|
||||
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use function array_reverse;
|
||||
use function implode;
|
||||
|
||||
final class SocialIssueRender implements ChillEntityRenderInterface
|
||||
{
|
||||
public const AND_CHILDREN_MENTION = 'show_and_children_mention';
|
||||
|
||||
public const DEFAULT_ARGS = [
|
||||
self::SEPARATOR_KEY => ' > ',
|
||||
self::SHOW_AND_CHILDREN => false,
|
||||
self::AND_CHILDREN_MENTION => 'social_issue.and children',
|
||||
];
|
||||
|
||||
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 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->engine = $engine;
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,7 +94,13 @@ final class SocialIssueRender implements ChillEntityRenderInterface
|
||||
|
||||
$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
|
||||
|
@@ -0,0 +1,86 @@
|
||||
<?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\Controller;
|
||||
|
||||
use Chill\MainBundle\Test\PrepareClientTrait;
|
||||
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
|
||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @coversNothing
|
||||
*/
|
||||
final class SocialWorkEvaluationApiControllerTest extends WebTestCase
|
||||
{
|
||||
use PrepareClientTrait;
|
||||
|
||||
private EntityManagerInterface $em;
|
||||
|
||||
private ?Evaluation $evaluationToReset = null;
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
if (null === $this->evaluationToReset) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::bootKernel();
|
||||
|
||||
$em = self::$container->get(EntityManagerInterface::class);
|
||||
$evaluation = $em->find(Evaluation::class, $this->evaluationToReset->getId());
|
||||
|
||||
$evaluation->setActive(true);
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
public function dataGenerateSocialActionWithEvaluations(): iterable
|
||||
{
|
||||
self::bootKernel();
|
||||
|
||||
$this->em = self::$container->get(EntityManagerInterface::class);
|
||||
|
||||
/** @var SocialAction $socialAction */
|
||||
$socialAction = $this->em->createQuery(
|
||||
'SELECT s FROM ' . SocialAction::class . ' s WHERE SIZE(s.evaluations) >= 2'
|
||||
)
|
||||
->setMaxResults(1)
|
||||
->getSingleResult();
|
||||
|
||||
// set the first evaluation as inactive and save
|
||||
$this->evaluationToReset = $socialAction->getEvaluations()->first();
|
||||
$this->evaluationToReset->setActive(false);
|
||||
|
||||
$this->em->flush();
|
||||
|
||||
yield [$socialAction, $this->evaluationToReset];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataGenerateSocialActionWithEvaluations
|
||||
*/
|
||||
public function testListEvaluationBySocialAction(SocialAction $action, Evaluation $inactiveEvaluation): void
|
||||
{
|
||||
$client = $this->getClientAuthenticated();
|
||||
|
||||
$client->request('GET', sprintf('/api/1.0/person/social-work/evaluation/by-social-action/%d.json', $action->getId()));
|
||||
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
||||
$content = json_decode($client->getResponse()->getContent(), true);
|
||||
|
||||
$ids = array_map(static fn (array $item) => $item['id'], $content['results']);
|
||||
|
||||
$this->assertNotContains($inactiveEvaluation->getId(), $ids);
|
||||
}
|
||||
}
|
@@ -29,6 +29,38 @@ use function count;
|
||||
*/
|
||||
final class AccompanyingPeriodTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testChangeStepKeepHistory()
|
||||
{
|
||||
$period = new AccompanyingPeriod();
|
||||
|
||||
$this->assertCount(0, $period->getStepHistories(), 'at initialization, period should not have any step history');
|
||||
|
||||
$period->setStep(AccompanyingPeriod::STEP_DRAFT);
|
||||
|
||||
$this->assertCount(0, $period->getStepHistories(), 're applying a draft should not create a history');
|
||||
|
||||
$period->setStep(AccompanyingPeriod::STEP_CONFIRMED);
|
||||
|
||||
$this->assertCount(1, $period->getStepHistories());
|
||||
$this->assertEquals(AccompanyingPeriod::STEP_CONFIRMED, $period->getStepHistories()->first()->getStep());
|
||||
|
||||
$period->setOpeningDate($aMonthAgo = new DateTime('1 month ago'));
|
||||
|
||||
$this->assertCount(1, $period->getStepHistories());
|
||||
$this->assertEquals($aMonthAgo, $period->getStepHistories()->first()->getStartDate(), 'when changing the opening date, the start date of the first history should change');
|
||||
|
||||
$period->setOpeningDate($tenDaysAgo = new DateTime('10 days ago'));
|
||||
|
||||
$this->assertCount(1, $period->getStepHistories());
|
||||
$this->assertEquals($tenDaysAgo, $period->getStepHistories()->first()->getStartDate(), 'when changing the opening date, the start date of the first history should change');
|
||||
|
||||
$period->setStep(AccompanyingPeriod::STEP_CLOSED);
|
||||
$this->assertCount(2, $period->getStepHistories());
|
||||
|
||||
$period->setOpeningDate($tomorrow = new DateTime('tomorrow'));
|
||||
$this->assertEquals($tenDaysAgo, $period->getStepHistories()->first()->getStartDate(), 'when changing the opening date to a later one and no history after, start date should change');
|
||||
}
|
||||
|
||||
public function testClosingEqualOpening()
|
||||
{
|
||||
$datetime = new DateTime('now');
|
||||
|
@@ -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));
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
$parent = new SocialIssue();
|
||||
|
@@ -39,7 +39,9 @@ final class DurationAggregatorTest extends AbstractAggregatorTest
|
||||
public function getFormData(): array
|
||||
{
|
||||
return [
|
||||
[],
|
||||
['precision' => 'day'],
|
||||
['precision' => 'week'],
|
||||
['precision' => 'month'],
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Tests\Export\Aggregator\AccompanyingCourseAggregato
|
||||
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\GeographicalUnitStatAggregator;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
/**
|
||||
@@ -38,8 +39,9 @@ final class GeographicalUnitStatAggregatorTest extends AbstractAggregatorTest
|
||||
|
||||
public function getFormData(): array
|
||||
{
|
||||
// TODO: add geographical unit stat into fixtures and provide a level
|
||||
return [
|
||||
[],
|
||||
['date_calc' => new DateTimeImmutable('today'), 'level' => null],
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Tests\Export\Aggregator\AccompanyingCourseAggregato
|
||||
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\ReferrerAggregator;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
/**
|
||||
@@ -39,7 +40,7 @@ final class ReferrerAggregatorTest extends AbstractAggregatorTest
|
||||
public function getFormData(): array
|
||||
{
|
||||
return [
|
||||
[],
|
||||
['date_calc' => new DateTimeImmutable('now')],
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -13,6 +13,7 @@ namespace Export\Export;
|
||||
|
||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Chill\PersonBundle\Export\Export\CountSocialWorkActions;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
@@ -12,7 +12,7 @@ declare(strict_types=1);
|
||||
namespace Chill\PersonBundle\Tests\Export\Filter\AccompanyingCourseFilters;
|
||||
|
||||
use Chill\MainBundle\Test\Export\AbstractFilterTest;
|
||||
use Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\CurrentUserJobFilter;
|
||||
use Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\UserJobFilter;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
/**
|
||||
@@ -21,7 +21,7 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||
*/
|
||||
final class CurrentUserJobFilterTest extends AbstractFilterTest
|
||||
{
|
||||
private CurrentUserJobFilter $filter;
|
||||
private UserJobFilter $filter;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
|
@@ -12,7 +12,7 @@ declare(strict_types=1);
|
||||
namespace Chill\PersonBundle\Tests\Export\Filter\AccompanyingCourseFilters;
|
||||
|
||||
use Chill\MainBundle\Test\Export\AbstractFilterTest;
|
||||
use Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\CurrentUserScopeFilter;
|
||||
use Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\UserScopeFilter;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
/**
|
||||
@@ -21,7 +21,7 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||
*/
|
||||
final class CurrentUserScopeFilterTest extends AbstractFilterTest
|
||||
{
|
||||
private CurrentUserScopeFilter $filter;
|
||||
private UserScopeFilter $filter;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
|
@@ -1,264 +1,193 @@
|
||||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
## Indicators
|
||||
chill.person.export.count_accompanyingcourse:
|
||||
class: Chill\PersonBundle\Export\Export\CountAccompanyingCourse
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export, alias: count_accompanyingcourse }
|
||||
|
||||
chill.person.export.avg_accompanyingcourse_duration:
|
||||
class: Chill\PersonBundle\Export\Export\StatAccompanyingCourseDuration
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export, alias: avg_accompanyingcourse_duration }
|
||||
|
||||
## Filters
|
||||
chill.person.export.filter_current_userscope:
|
||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\CurrentUserScopeFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\UserScopeFilter:
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: accompanyingcourse_current_userscope_filter }
|
||||
- { name: chill.export_filter, alias: accompanyingcourse_userscope_filter }
|
||||
|
||||
chill.person.export.filter_current_userjob:
|
||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\CurrentUserJobFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\UserJobFilter:
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: accompanyingcourse_current_userjob_filter }
|
||||
- { name: chill.export_filter, alias: accompanyingcourse_userjob_filter }
|
||||
|
||||
chill.person.export.filter_socialissue:
|
||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\SocialIssueFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: accompanyingcourse_socialissue_filter }
|
||||
|
||||
chill.person.export.filter_step:
|
||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\StepFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: accompanyingcourse_step_filter }
|
||||
|
||||
chill.person.export.filter_geographicalunitstat:
|
||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\GeographicalUnitStatFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: accompanyingcourse_geographicalunitstat_filter }
|
||||
|
||||
chill.person.export.filter_socialaction:
|
||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\SocialActionFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: accompanyingcourse_socialaction_filter }
|
||||
|
||||
chill.person.export.filter_evaluation:
|
||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\EvaluationFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: accompanyingcourse_evaluation_filter }
|
||||
|
||||
chill.person.export.filter_origin:
|
||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\OriginFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: accompanyingcourse_origin_filter }
|
||||
|
||||
chill.person.export.filter_closingmotive:
|
||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\ClosingMotiveFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: accompanyingcourse_closingmotive_filter }
|
||||
|
||||
chill.person.export.filter_administrative_location:
|
||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\AdministrativeLocationFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: accompanyingcourse_administrative_location_filter }
|
||||
|
||||
chill.person.export.filter_requestor:
|
||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\RequestorFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: accompanyingcourse_requestor_filter }
|
||||
|
||||
chill.person.export.filter_confidential:
|
||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\ConfidentialFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: accompanyingcourse_confidential_filter }
|
||||
|
||||
chill.person.export.filter_emergency:
|
||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\EmergencyFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: accompanyingcourse_emergency_filter }
|
||||
|
||||
chill.person.export.filter_intensity:
|
||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\IntensityFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: accompanyingcourse_intensity_filter }
|
||||
|
||||
chill.person.export.filter_activeondate:
|
||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\ActiveOnDateFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: accompanyingcourse_activeondate_filter }
|
||||
|
||||
chill.person.export.filter_activeonedaybetweendates:
|
||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\ActiveOneDayBetweenDatesFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: accompanyingcourse_activeonedaybetweendates_filter }
|
||||
|
||||
chill.person.export.filter_referrer:
|
||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\ReferrerFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: accompanyingcourse_referrer_filter }
|
||||
|
||||
chill.person.export.filter_openbetweendates:
|
||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\OpenBetweenDatesFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: accompanyingcourse_openbetweendates_filter }
|
||||
|
||||
## Aggregators
|
||||
chill.person.export.aggregator_referrer_scope:
|
||||
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\ScopeAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: accompanyingcourse_scope_aggregator }
|
||||
|
||||
chill.person.export.aggregator_referrer_job:
|
||||
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\JobAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: accompanyingcourse_referrer_job_aggregator }
|
||||
|
||||
chill.person.export.aggregator_socialissue:
|
||||
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\SocialIssueAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: accompanyingcourse_socialissue_aggregator }
|
||||
|
||||
chill.person.export.aggregator_step:
|
||||
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\StepAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: accompanyingcourse_step_aggregator }
|
||||
|
||||
chill.person.export.aggregator_geographicalunitstat:
|
||||
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\GeographicalUnitStatAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: accompanyingcourse_geographicalunitstat_aggregator }
|
||||
|
||||
chill.person.export.aggregator_socialaction:
|
||||
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\SocialActionAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: accompanyingcourse_socialaction_aggregator }
|
||||
|
||||
chill.person.export.aggregator_evaluation:
|
||||
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\EvaluationAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: accompanyingcourse_evaluation_aggregator }
|
||||
|
||||
chill.person.export.aggregator_origin:
|
||||
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\OriginAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: accompanyingcourse_origin_aggregator }
|
||||
|
||||
chill.person.export.aggregator_closingmotive:
|
||||
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\ClosingMotiveAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: accompanyingcourse_closingmotive_aggregator }
|
||||
|
||||
chill.person.export.aggregator_administrative_location:
|
||||
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\AdministrativeLocationAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: accompanyingcourse_administrative_location_aggregator }
|
||||
|
||||
chill.person.export.aggregator_requestor:
|
||||
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\RequestorAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: accompanyingcourse_requestor_aggregator }
|
||||
|
||||
chill.person.export.aggregator_confidential:
|
||||
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\ConfidentialAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: accompanyingcourse_confidential_aggregator }
|
||||
|
||||
chill.person.export.aggregator_emergency:
|
||||
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\EmergencyAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: accompanyingcourse_emergency_aggregator }
|
||||
|
||||
chill.person.export.aggregator_intensity:
|
||||
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\IntensityAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: accompanyingcourse_intensity_aggregator }
|
||||
|
||||
chill.person.export.aggregator_referrer:
|
||||
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\ReferrerAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: accompanyingcourse_referrer_aggregator }
|
||||
|
||||
chill.person.export.aggregator_duration:
|
||||
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\DurationAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: accompanyingcourse_duration_aggregator }
|
||||
|
||||
Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\ReferrerScopeAggregator:
|
||||
autoconfigure: true
|
||||
autowire: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: accompanyingcourse_ref_scope_aggregator }
|
||||
|
||||
|
||||
Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\ByHouseholdCompositionAggregator:
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: accompanyingcourse_by_household_compo_aggregator }
|
||||
|
@@ -0,0 +1,33 @@
|
||||
<?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\Migrations\Person;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version20221013131221 extends AbstractMigration
|
||||
{
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_person_social_work_evaluation DROP active');
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Add an active column on evaluation';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_person_social_work_evaluation ADD active BOOLEAN DEFAULT true NOT NULL');
|
||||
}
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
<?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\Migrations\Person;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version20221014115500 extends AbstractMigration
|
||||
{
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('DROP SEQUENCE chill_person_accompanying_period_step_history_id_seq CASCADE');
|
||||
$this->addSql('DROP TABLE chill_person_accompanying_period_step_history');
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Add step history on accompanying periods';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('CREATE SEQUENCE chill_person_accompanying_period_step_history_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
||||
$this->addSql('CREATE TABLE chill_person_accompanying_period_step_history (id INT NOT NULL, period_id INT DEFAULT NULL,
|
||||
endDate DATE DEFAULT NULL, startDate DATE NOT NULL, step TEXT NOT NULL, createdAt TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL,
|
||||
updatedAt TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, createdBy_id INT DEFAULT NULL,
|
||||
updatedBy_id INT DEFAULT NULL, PRIMARY KEY(id))
|
||||
');
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period_step_history ADD CHECK (startDate <= endDate)');
|
||||
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period_step_history ADD CONSTRAINT ' .
|
||||
'chill_internal_acp_steps_not_overlaps EXCLUDE USING GIST(
|
||||
-- extension btree_gist required to include comparaison with integer
|
||||
period_id WITH =,
|
||||
daterange(startDate, endDate, \'[)\') WITH &&
|
||||
)
|
||||
INITIALLY DEFERRED');
|
||||
|
||||
$this->addSql('CREATE INDEX IDX_84D514ACEC8B7ADE ON chill_person_accompanying_period_step_history (period_id)');
|
||||
$this->addSql('CREATE INDEX IDX_84D514AC3174800F ON chill_person_accompanying_period_step_history (createdBy_id)');
|
||||
$this->addSql('COMMENT ON COLUMN chill_person_accompanying_period_step_history.endDate IS \'(DC2Type:date_immutable)\'');
|
||||
$this->addSql('COMMENT ON COLUMN chill_person_accompanying_period_step_history.startDate IS \'(DC2Type:date_immutable)\'');
|
||||
$this->addSql('COMMENT ON COLUMN chill_person_accompanying_period_step_history.createdAt IS \'(DC2Type:datetime_immutable)\'');
|
||||
$this->addSql('COMMENT ON COLUMN chill_person_accompanying_period_step_history.updatedAt IS \'(DC2Type:datetime_immutable)\'');
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period_step_history ADD CONSTRAINT FK_84D514ACEC8B7ADE FOREIGN KEY (period_id) REFERENCES chill_person_accompanying_period (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period_step_history ADD CONSTRAINT FK_84D514AC3174800F FOREIGN KEY (createdBy_id) REFERENCES users (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('CREATE INDEX IDX_84D514AC65FF1AEC ON chill_person_accompanying_period_step_history (updatedBy_id)');
|
||||
|
||||
// fill the tables with current state
|
||||
$this->addSql(
|
||||
'INSERT INTO chill_person_accompanying_period_step_history (id, period_id, startDate, endDate, step, createdAt, updatedAt)
|
||||
SELECT nextval(\'chill_person_accompanying_period_step_history_id_seq\'), id, openingDate, null, step, NOW(), NOW() FROM chill_person_accompanying_period WHERE step = \'CONFIRMED\'
|
||||
UNION
|
||||
SELECT nextval(\'chill_person_accompanying_period_step_history_id_seq\'), id, openingDate, closingDate, \'CONFIRMED\', NOW(), NOW() FROM chill_person_accompanying_period WHERE step = \'CLOSED\'
|
||||
UNION
|
||||
SELECT nextval(\'chill_person_accompanying_period_step_history_id_seq\'), id, closingDate, null, \'CLOSED\', NOW(), NOW() FROM chill_person_accompanying_period WHERE step = \'CLOSED\'
|
||||
'
|
||||
);
|
||||
}
|
||||
}
|
@@ -205,9 +205,11 @@ Resources: Interlocuteurs privilégiés
|
||||
Any requestor to this accompanying course: Aucun demandeur pour ce parcours
|
||||
Social action: Action 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
|
||||
Social issue: Problématique sociale
|
||||
Social issues: Problématiques sociales
|
||||
Pick a social issue: Choisir une problématique sociale
|
||||
Last events on accompanying course: Dernières actions de suivi
|
||||
Edit & activate accompanying course: Modifier et valider
|
||||
See accompanying periods: Voir toutes les périodes d'accompagnement
|
||||
@@ -581,10 +583,10 @@ Accepted evaluationtype: Évaluations
|
||||
Group by evaluation type: Grouper les évaluations par type
|
||||
Evaluation type: Type d'évaluation
|
||||
|
||||
Filter by maxdate: Filtrer les évaluations par date d'échéance
|
||||
Filter evaluations by maxdate mention: Filtrer les évaluations qui possèdent une date d'échéance
|
||||
Maxdate: ''
|
||||
is specified: La date d'échéance est spécifiée
|
||||
is not specified: La date d'échéance n'est pas spécifiée
|
||||
maxdate is specified: la date d'échéance est spécifiée
|
||||
maxdate is not specified: la date d'échéance n'est pas spécifiée
|
||||
"Filtered by maxdate: only %choice%": "Filtré par date d'échéance: uniquement si %choice%"
|
||||
|
||||
## household filters/aggr
|
||||
@@ -951,7 +953,30 @@ notification:
|
||||
export:
|
||||
aggregator:
|
||||
course:
|
||||
by_referrer:
|
||||
Computation date for referrer: Date à laquelle le référent était actif
|
||||
by_user_scope:
|
||||
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
|
||||
Referrer's scope: Service du référent de parcours
|
||||
duration:
|
||||
day: Durée du parcours en jours
|
||||
week: Durée du parcours en semaines
|
||||
month: Durée du parcours en mois
|
||||
Precision: Unité de la durée
|
||||
by_household_composition:
|
||||
Household composition: Composition du ménage
|
||||
Group course by household composition: Grouper les parcours par composition familiale des ménages des usagers concernés
|
||||
Calc date: Date de calcul de la composition du ménage
|
||||
filter:
|
||||
course:
|
||||
by_user_scope:
|
||||
Computation date for referrer: Date à laquelle le référent était actif
|
||||
by_referrer:
|
||||
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
|
||||
|
Reference in New Issue
Block a user