mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-20 14:43:49 +00:00
Merge branch 'master' into export/allow-check-multiple-geographical-zones
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\AccompanyingPeriod\Lifecycle;
|
||||
|
||||
use Chill\MainBundle\Cron\CronJobInterface;
|
||||
use Chill\MainBundle\Entity\CronJobExecution;
|
||||
use Symfony\Component\Clock\ClockInterface;
|
||||
|
||||
readonly class AccompanyingPeriodStepChangeCronjob implements CronJobInterface
|
||||
{
|
||||
public function __construct(
|
||||
private ClockInterface $clock,
|
||||
private AccompanyingPeriodStepChangeRequestor $requestor,
|
||||
) {
|
||||
}
|
||||
|
||||
public function canRun(?CronJobExecution $cronJobExecution): bool
|
||||
{
|
||||
$now = $this->clock->now();
|
||||
|
||||
if (null !== $cronJobExecution && $now->sub(new \DateInterval('P1D')) < $cronJobExecution->getLastStart()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return in_array((int) $now->format('H'), [1, 2, 3, 4, 5, 6], true);
|
||||
}
|
||||
|
||||
public function getKey(): string
|
||||
{
|
||||
return 'accompanying-period-step-change';
|
||||
}
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
($this->requestor)();
|
||||
}
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
<?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\AccompanyingPeriod\Lifecycle;
|
||||
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriodRepository;
|
||||
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
|
||||
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
|
||||
|
||||
#[AsMessageHandler]
|
||||
class AccompanyingPeriodStepChangeMessageHandler implements MessageHandlerInterface
|
||||
{
|
||||
private const LOG_PREFIX = '[accompanying period step change message handler] ';
|
||||
|
||||
public function __construct(
|
||||
private AccompanyingPeriodRepository $accompanyingPeriodRepository,
|
||||
private AccompanyingPeriodStepChanger $changer,
|
||||
) {
|
||||
}
|
||||
|
||||
public function __invoke(AccompanyingPeriodStepChangeRequestMessage $message): void
|
||||
{
|
||||
if (null === $period = $this->accompanyingPeriodRepository->find($message->getPeriodId())) {
|
||||
throw new \RuntimeException(self::LOG_PREFIX . 'Could not find period with this id: '. $message->getPeriodId());
|
||||
}
|
||||
|
||||
($this->changer)($period, $message->getTransition());
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\AccompanyingPeriod\Lifecycle;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
|
||||
/**
|
||||
* Message which will request a change in the step of accompanying period
|
||||
*/
|
||||
class AccompanyingPeriodStepChangeRequestMessage
|
||||
{
|
||||
private int $periodId;
|
||||
|
||||
public function __construct(
|
||||
AccompanyingPeriod|int $period,
|
||||
private string $transition,
|
||||
) {
|
||||
if (is_int($period)) {
|
||||
$this->periodId = $period;
|
||||
} else {
|
||||
if (null !== $id = $period->getId()) {
|
||||
$this->periodId = $id;
|
||||
}
|
||||
|
||||
throw new \LogicException("This AccompanyingPeriod does not have and id yet");
|
||||
}
|
||||
}
|
||||
|
||||
public function getPeriodId(): int
|
||||
{
|
||||
return $this->periodId;
|
||||
}
|
||||
|
||||
public function getTransition(): string
|
||||
{
|
||||
return $this->transition;
|
||||
}
|
||||
}
|
@@ -0,0 +1,88 @@
|
||||
<?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\AccompanyingPeriod\Lifecycle;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodInfoRepositoryInterface;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\Messenger\MessageBusInterface;
|
||||
|
||||
/**
|
||||
* Gather all the accompanying period which needs a change in step
|
||||
*/
|
||||
class AccompanyingPeriodStepChangeRequestor
|
||||
{
|
||||
private \DateInterval $intervalForShortInactive;
|
||||
|
||||
private \DateInterval $intervalForLongInactive;
|
||||
|
||||
private bool $isMarkInactive;
|
||||
|
||||
public function __construct(
|
||||
private AccompanyingPeriodInfoRepositoryInterface $accompanyingPeriodInfoRepository,
|
||||
private LoggerInterface $logger,
|
||||
private MessageBusInterface $messageBus,
|
||||
ParameterBagInterface $parameterBag,
|
||||
) {
|
||||
$config = $parameterBag->get('chill_person')['accompanying_period_lifecycle_delays'];
|
||||
$this->isMarkInactive = $config['mark_inactive'];
|
||||
$this->intervalForShortInactive = new \DateInterval($config['mark_inactive_short_after']);
|
||||
$this->intervalForLongInactive = new \DateInterval($config['mark_inactive_long_after']);
|
||||
}
|
||||
|
||||
public function __invoke(): void
|
||||
{
|
||||
if (!$this->isMarkInactive) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get the oldest ones first
|
||||
foreach (
|
||||
$olders = $this->accompanyingPeriodInfoRepository->findAccompanyingPeriodIdInactiveAfter(
|
||||
$this->intervalForLongInactive,
|
||||
[AccompanyingPeriod::STEP_CONFIRMED, AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT]
|
||||
) as $accompanyingPeriodId
|
||||
) {
|
||||
$this->logger->debug('request mark period as inactive_short', ['period' => $accompanyingPeriodId]);
|
||||
$this->messageBus->dispatch(new AccompanyingPeriodStepChangeRequestMessage($accompanyingPeriodId, 'mark_inactive_long'));
|
||||
}
|
||||
|
||||
// the newest
|
||||
foreach (
|
||||
$this->accompanyingPeriodInfoRepository->findAccompanyingPeriodIdInactiveAfter(
|
||||
$this->intervalForShortInactive,
|
||||
[AccompanyingPeriod::STEP_CONFIRMED]
|
||||
) as $accompanyingPeriodId
|
||||
) {
|
||||
if (in_array($accompanyingPeriodId, $olders, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->logger->debug('request mark period as inactive_long', ['period' => $accompanyingPeriodId]);
|
||||
$this->messageBus->dispatch(new AccompanyingPeriodStepChangeRequestMessage($accompanyingPeriodId, 'mark_inactive_short'));
|
||||
}
|
||||
|
||||
// a new event has been created => remove inactive long, or short
|
||||
foreach (
|
||||
$this->accompanyingPeriodInfoRepository->findAccompanyingPeriodIdActiveSince(
|
||||
$this->intervalForShortInactive,
|
||||
[AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT, AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG]
|
||||
) as $accompanyingPeriodId
|
||||
) {
|
||||
$this->logger->debug('request mark period as active', ['period' => $accompanyingPeriodId]);
|
||||
$this->messageBus->dispatch(new AccompanyingPeriodStepChangeRequestMessage($accompanyingPeriodId, 'mark_active'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
<?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\AccompanyingPeriod\Lifecycle;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Workflow\Registry;
|
||||
|
||||
/**
|
||||
* Change the step of an accompanying period
|
||||
*
|
||||
* This should be invoked through scripts (not in the in context of an http request, or an
|
||||
* action from a user).
|
||||
*/
|
||||
class AccompanyingPeriodStepChanger
|
||||
{
|
||||
private const LOG_PREFIX = '[AccompanyingPeriodStepChanger] ';
|
||||
|
||||
public function __construct(
|
||||
private EntityManagerInterface $entityManager,
|
||||
private LoggerInterface $logger,
|
||||
private Registry $workflowRegistry,
|
||||
) {
|
||||
}
|
||||
|
||||
public function __invoke(AccompanyingPeriod $period, string $transition, ?string $workflowName = null): void
|
||||
{
|
||||
$workflow = $this->workflowRegistry->get($period, $workflowName);
|
||||
|
||||
if (!$workflow->can($period, $transition)) {
|
||||
$this->logger->info(self::LOG_PREFIX . 'not able to apply the transition on period', [
|
||||
'period_id' => $period->getId(),
|
||||
'transition' => $transition
|
||||
]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$workflow->apply($period, $transition);
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
$this->logger->info(self::LOG_PREFIX . 'could apply a transition', [
|
||||
'period_id' => $period->getId(),
|
||||
'transition' => $transition
|
||||
]);
|
||||
}
|
||||
}
|
@@ -12,6 +12,7 @@ declare(strict_types=1);
|
||||
namespace Chill\PersonBundle;
|
||||
|
||||
use Chill\PersonBundle\DependencyInjection\CompilerPass\AccompanyingPeriodTimelineCompilerPass;
|
||||
use Chill\PersonBundle\Service\EntityInfo\AccompanyingPeriodInfoUnionQueryPartInterface;
|
||||
use Chill\PersonBundle\Widget\PersonListWidgetFactory;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
@@ -26,5 +27,7 @@ class ChillPersonBundle extends Bundle
|
||||
->addWidgetFactory(new PersonListWidgetFactory());
|
||||
|
||||
$container->addCompilerPass(new AccompanyingPeriodTimelineCompilerPass());
|
||||
$container->registerForAutoconfiguration(AccompanyingPeriodInfoUnionQueryPartInterface::class)
|
||||
->addTag('chill_person.accompanying_period_info_part');
|
||||
}
|
||||
}
|
||||
|
@@ -42,10 +42,18 @@ final class ImportSocialWorkMetadata extends Command
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$description = 'Imports a structured table containing social issues, social actions, objectives, results and evaluations.';
|
||||
$help = 'File to csv format, no headers, semi-colon as delimiter, datas sorted by alphabetical order, column after column.'. PHP_EOL
|
||||
. 'Columns are: social issues parent, social issues child, social actions parent, social actions child, goals, results, evaluations.'. PHP_EOL
|
||||
. PHP_EOL
|
||||
. 'See social_work_metadata.csv as example.'. PHP_EOL;
|
||||
|
||||
$this
|
||||
->setName('chill:person:import-socialwork')
|
||||
->addOption('filepath', 'f', InputOption::VALUE_REQUIRED, 'The file to import.')
|
||||
->addOption('language', 'l', InputOption::VALUE_OPTIONAL, 'The default language');
|
||||
->addOption('language', 'l', InputOption::VALUE_OPTIONAL, 'The default language')
|
||||
->setDescription($description)
|
||||
->setHelp($help);
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
|
@@ -169,9 +169,7 @@ final class AccompanyingCourseApiController extends ApiController
|
||||
$accompanyingPeriods = $person->getCurrentAccompanyingPeriods();
|
||||
$accompanyingPeriodsChecked = array_filter(
|
||||
$accompanyingPeriods,
|
||||
function (AccompanyingPeriod $period) {
|
||||
return $this->isGranted(AccompanyingPeriodVoter::SEE, $period);
|
||||
}
|
||||
fn (AccompanyingPeriod $period) => $this->isGranted(AccompanyingPeriodVoter::SEE, $period)
|
||||
);
|
||||
|
||||
return $this->json(array_values($accompanyingPeriodsChecked), Response::HTTP_OK, [], ['groups' => ['read']]);
|
||||
|
@@ -222,14 +222,10 @@ class AccompanyingPeriodController extends AbstractController
|
||||
$accompanyingPeriodsRaw = $this->accompanyingPeriodACLAwareRepository
|
||||
->findByPerson($person, AccompanyingPeriodVoter::SEE);
|
||||
|
||||
usort($accompanyingPeriodsRaw, static function ($a, $b) {
|
||||
return $b->getOpeningDate() > $a->getOpeningDate();
|
||||
});
|
||||
usort($accompanyingPeriodsRaw, static fn ($a, $b) => $b->getOpeningDate() > $a->getOpeningDate());
|
||||
|
||||
// filter visible or not visible
|
||||
$accompanyingPeriods = array_filter($accompanyingPeriodsRaw, function (AccompanyingPeriod $ap) {
|
||||
return $this->isGranted(AccompanyingPeriodVoter::SEE, $ap);
|
||||
});
|
||||
$accompanyingPeriods = array_filter($accompanyingPeriodsRaw, fn (AccompanyingPeriod $ap) => $this->isGranted(AccompanyingPeriodVoter::SEE, $ap));
|
||||
|
||||
return $this->render('@ChillPerson/AccompanyingPeriod/list.html.twig', [
|
||||
'accompanying_periods' => $accompanyingPeriods,
|
||||
@@ -331,9 +327,7 @@ class AccompanyingPeriodController extends AbstractController
|
||||
/** @var AccompanyingPeriod $period */
|
||||
$period = array_filter(
|
||||
$person->getAccompanyingPeriods(),
|
||||
static function (AccompanyingPeriod $p) use ($period_id) {
|
||||
return $p->getId() === ($period_id);
|
||||
}
|
||||
static fn (AccompanyingPeriod $p) => $p->getId() === ($period_id)
|
||||
)[0] ?? null;
|
||||
|
||||
if (null === $period) {
|
||||
|
@@ -105,12 +105,8 @@ class AccompanyingPeriodRegulationListController
|
||||
$builder
|
||||
->add('services', EntityType::class, [
|
||||
'class' => Scope::class,
|
||||
'query_builder' => static function (EntityRepository $er) {
|
||||
return $er->createQueryBuilder('s');
|
||||
},
|
||||
'choice_label' => function (Scope $s) {
|
||||
return $this->translatableStringHelper->localize($s->getName());
|
||||
},
|
||||
'query_builder' => static fn (EntityRepository $er) => $er->createQueryBuilder('s'),
|
||||
'choice_label' => fn (Scope $s) => $this->translatableStringHelper->localize($s->getName()),
|
||||
'multiple' => true,
|
||||
'label' => 'Service',
|
||||
'required' => false,
|
||||
@@ -123,9 +119,7 @@ class AccompanyingPeriodRegulationListController
|
||||
|
||||
return $qb;
|
||||
},
|
||||
'choice_label' => function (UserJob $j) {
|
||||
return $this->translatableStringHelper->localize($j->getLabel());
|
||||
},
|
||||
'choice_label' => fn (UserJob $j) => $this->translatableStringHelper->localize($j->getLabel()),
|
||||
'multiple' => true,
|
||||
'label' => 'Métier',
|
||||
'required' => false,
|
||||
@@ -147,9 +141,7 @@ class AccompanyingPeriodRegulationListController
|
||||
|
||||
return $qb;
|
||||
},
|
||||
'choice_label' => static function (Location $l) {
|
||||
return $l->getName();
|
||||
},
|
||||
'choice_label' => static fn (Location $l) => $l->getName(),
|
||||
'multiple' => true,
|
||||
'group_by' => function (Location $l) {
|
||||
if (null === $type = $l->getLocationType()) {
|
||||
|
@@ -164,9 +164,7 @@ class HouseholdCompositionController extends AbstractController
|
||||
$isEdit = $request->query->has('edit');
|
||||
|
||||
if ($isEdit) {
|
||||
$householdCompositions = $household->getCompositions()->filter(static function (HouseholdComposition $composition) use ($request) {
|
||||
return $composition->getId() === $request->query->getInt('edit');
|
||||
});
|
||||
$householdCompositions = $household->getCompositions()->filter(static fn (HouseholdComposition $composition) => $composition->getId() === $request->query->getInt('edit'));
|
||||
|
||||
if ($householdCompositions->count() !== 1) {
|
||||
throw new BadRequestHttpException('could not find the composition with this id associated to the household');
|
||||
|
@@ -81,9 +81,7 @@ class HouseholdController extends AbstractController
|
||||
}
|
||||
}
|
||||
|
||||
usort($accompanyingPeriods, static function ($a, $b) {
|
||||
return $b->getOpeningDate() <=> $a->getOpeningDate();
|
||||
});
|
||||
usort($accompanyingPeriods, static fn ($a, $b) => $b->getOpeningDate() <=> $a->getOpeningDate());
|
||||
|
||||
$oldMembers = $household->getNonCurrentMembers();
|
||||
$accompanyingPeriodsOld = [];
|
||||
|
@@ -108,14 +108,10 @@ class PersonApiController extends ApiController
|
||||
$addresses = $person
|
||||
->getAccompanyingPeriodParticipations()
|
||||
->filter(
|
||||
static function (AccompanyingPeriodParticipation $accompanyingPeriodParticipation): bool {
|
||||
return null !== $accompanyingPeriodParticipation->getAccompanyingPeriod()->getAddressLocation();
|
||||
}
|
||||
static fn (AccompanyingPeriodParticipation $accompanyingPeriodParticipation): bool => null !== $accompanyingPeriodParticipation->getAccompanyingPeriod()->getAddressLocation()
|
||||
)
|
||||
->map(
|
||||
static function (AccompanyingPeriodParticipation $accompanyingPeriodParticipation): ?Address {
|
||||
return $accompanyingPeriodParticipation->getAccompanyingPeriod()->getAddressLocation();
|
||||
}
|
||||
static fn (AccompanyingPeriodParticipation $accompanyingPeriodParticipation): ?Address => $accompanyingPeriodParticipation->getAccompanyingPeriod()->getAddressLocation()
|
||||
)
|
||||
->filter(
|
||||
// We remove potential null addresses.
|
||||
|
@@ -165,7 +165,7 @@ final class PersonController extends AbstractController
|
||||
$cFGroup = null;
|
||||
|
||||
$cFDefaultGroup = $this->em->getRepository(\Chill\CustomFieldsBundle\Entity\CustomFieldsDefaultGroup::class)
|
||||
->findOneByEntity('Chill\\PersonBundle\\Entity\\Person');
|
||||
->findOneByEntity(\Chill\PersonBundle\Entity\Person::class);
|
||||
|
||||
if ($cFDefaultGroup) {
|
||||
$cFGroup = $cFDefaultGroup->getCustomFieldsGroup();
|
||||
|
@@ -120,7 +120,7 @@ class ReassignAccompanyingPeriodController extends AbstractController
|
||||
$assignForm->handleRequest($request);
|
||||
|
||||
if ($assignForm->isSubmitted() && $assignForm->isValid()) {
|
||||
$assignPeriodIds = json_decode($assignForm->get('periods')->getData(), true);
|
||||
$assignPeriodIds = json_decode($assignForm->get('periods')->getData(), true, 512, JSON_THROW_ON_ERROR);
|
||||
$userTo = $assignForm->get('userTo')->getData();
|
||||
$userFrom = $assignForm->get('userFrom')->getData();
|
||||
|
||||
@@ -179,7 +179,7 @@ class ReassignAccompanyingPeriodController extends AbstractController
|
||||
{
|
||||
$defaultData = [
|
||||
'userFrom' => $userFrom,
|
||||
'periods' => json_encode($periodIds),
|
||||
'periods' => json_encode($periodIds, JSON_THROW_ON_ERROR),
|
||||
];
|
||||
|
||||
$builder = $this->formFactory->createNamedBuilder('reassign', FormType::class, $defaultData);
|
||||
|
@@ -44,9 +44,7 @@ class SocialWorkSocialActionApiController extends ApiController
|
||||
|
||||
$socialActions = $socialIssue->getRecursiveSocialActions()->toArray();
|
||||
|
||||
usort($socialActions, static function (SocialAction $sa, SocialAction $sb) {
|
||||
return $sa->getOrdering() <=> $sb->getOrdering();
|
||||
});
|
||||
usort($socialActions, static fn (SocialAction $sa, SocialAction $sb) => $sa->getOrdering() <=> $sb->getOrdering());
|
||||
|
||||
$pagination = $this->paginator->create(count($socialActions));
|
||||
// max one page
|
||||
|
@@ -115,9 +115,7 @@ class LoadCustomFields extends AbstractFixture implements
|
||||
|
||||
// get possible values for cfGroup
|
||||
$choices = array_map(
|
||||
static function ($a) {
|
||||
return $a['slug'];
|
||||
},
|
||||
static fn ($a) => $a['slug'],
|
||||
$this->customFieldChoice->getOptions()['choices']
|
||||
);
|
||||
// create faker
|
||||
@@ -125,12 +123,12 @@ class LoadCustomFields extends AbstractFixture implements
|
||||
// select a set of people and add data
|
||||
foreach ($personIds as $id) {
|
||||
// add info on 1 person on 2
|
||||
if (mt_rand(0, 1) === 1) {
|
||||
if (random_int(0, 1) === 1) {
|
||||
/** @var Person $person */
|
||||
$person = $manager->getRepository(Person::class)->find($id);
|
||||
$person->setCFData([
|
||||
'remarques' => $this->createCustomFieldText()
|
||||
->serialize($faker->text(mt_rand(150, 250)), $this->customFieldText),
|
||||
->serialize($faker->text(random_int(150, 250)), $this->customFieldText),
|
||||
'document-d-identite' => $this->createCustomFieldChoice()
|
||||
->serialize([$choices[array_rand($choices)]], $this->customFieldChoice),
|
||||
]);
|
||||
|
@@ -15,6 +15,7 @@ use Chill\MainBundle\DependencyInjection\MissingBundleException;
|
||||
use Chill\MainBundle\Security\Authorization\ChillExportVoter;
|
||||
use Chill\PersonBundle\Controller\HouseholdCompositionTypeApiController;
|
||||
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodCommentVoter;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodResourceVoter;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||
@@ -1006,22 +1007,46 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
||||
'property' => 'step',
|
||||
],
|
||||
'supports' => [
|
||||
'Chill\PersonBundle\Entity\AccompanyingPeriod',
|
||||
\Chill\PersonBundle\Entity\AccompanyingPeriod::class,
|
||||
],
|
||||
'initial_marking' => 'DRAFT',
|
||||
'places' => [
|
||||
'DRAFT',
|
||||
'CONFIRMED',
|
||||
'CLOSED',
|
||||
AccompanyingPeriod::STEP_DRAFT,
|
||||
AccompanyingPeriod::STEP_CONFIRMED,
|
||||
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT,
|
||||
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG,
|
||||
AccompanyingPeriod::STEP_CLOSED,
|
||||
],
|
||||
'transitions' => [
|
||||
'confirm' => [
|
||||
'from' => 'DRAFT',
|
||||
'to' => 'CONFIRMED',
|
||||
'from' => AccompanyingPeriod::STEP_DRAFT,
|
||||
'to' => AccompanyingPeriod::STEP_CONFIRMED,
|
||||
],
|
||||
'mark_inactive_short' => [
|
||||
'from' => AccompanyingPeriod::STEP_CONFIRMED,
|
||||
'to' => AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT,
|
||||
],
|
||||
'mark_inactive_long' => [
|
||||
'from' => [
|
||||
AccompanyingPeriod::STEP_CONFIRMED,
|
||||
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT
|
||||
],
|
||||
'to' => AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG,
|
||||
],
|
||||
'mark_active' => [
|
||||
'from' => [
|
||||
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG,
|
||||
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT,
|
||||
],
|
||||
'to' => AccompanyingPeriod::STEP_CONFIRMED
|
||||
],
|
||||
'close' => [
|
||||
'from' => 'CONFIRMED',
|
||||
'to' => 'CLOSED',
|
||||
'from' => [
|
||||
AccompanyingPeriod::STEP_CONFIRMED,
|
||||
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT,
|
||||
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG,
|
||||
],
|
||||
'to' => AccompanyingPeriod::STEP_CLOSED,
|
||||
],
|
||||
],
|
||||
],
|
||||
@@ -1043,7 +1068,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
||||
$container->prependExtensionConfig(
|
||||
'chill_custom_fields',
|
||||
['customizables_entities' => [
|
||||
['class' => 'Chill\PersonBundle\Entity\Person', 'name' => 'PersonEntity'],
|
||||
['class' => \Chill\PersonBundle\Entity\Person::class, 'name' => 'PersonEntity'],
|
||||
],
|
||||
]
|
||||
);
|
||||
|
@@ -30,7 +30,7 @@ class Configuration implements ConfigurationInterface
|
||||
public function getConfigTreeBuilder()
|
||||
{
|
||||
$treeBuilder = new TreeBuilder('cl_chill_person');
|
||||
$rootNode = $treeBuilder->getRootNode('cl_chill_person');
|
||||
$rootNode = $treeBuilder->getRootNode();
|
||||
|
||||
$rootNode
|
||||
->canBeDisabled()
|
||||
@@ -128,6 +128,15 @@ class Configuration implements ConfigurationInterface
|
||||
->info('Can we have more than one simultaneous accompanying period in the same time. Default false.')
|
||||
->defaultValue(false)
|
||||
->end()
|
||||
->arrayNode('accompanying_period_lifecycle_delays')
|
||||
->addDefaultsIfNotSet()
|
||||
->info('Delays before marking an accompanying period as inactive')
|
||||
->children()
|
||||
->booleanNode('mark_inactive')->defaultTrue()->end()
|
||||
->scalarNode('mark_inactive_short_after')->defaultValue('P6M')->end()
|
||||
->scalarNode('mark_inactive_long_after')->defaultValue('P2Y')->end()
|
||||
->end()
|
||||
->end() // end of 'accompanying_period_lifecycle_delays
|
||||
->end() // children of 'root', parent = root
|
||||
;
|
||||
|
||||
@@ -137,7 +146,7 @@ class Configuration implements ConfigurationInterface
|
||||
private function addFieldNode($key)
|
||||
{
|
||||
$tree = new TreeBuilder($key, 'enum');
|
||||
$node = $tree->getRootNode($key);
|
||||
$node = $tree->getRootNode();
|
||||
|
||||
switch ($key) {
|
||||
case 'accompanying_period':
|
||||
|
@@ -109,6 +109,24 @@ class AccompanyingPeriod implements
|
||||
*/
|
||||
public const STEP_CONFIRMED = 'CONFIRMED';
|
||||
|
||||
/**
|
||||
* Mark an accompanying period as confirmed, but inactive
|
||||
*
|
||||
* this means that the accompanying period **is**
|
||||
* confirmed, but no activity (Activity, AccompanyingPeriod, ...)
|
||||
* has been associated, or updated, within this accompanying period.
|
||||
*/
|
||||
public const STEP_CONFIRMED_INACTIVE_SHORT = 'CONFIRMED_INACTIVE_SHORT';
|
||||
|
||||
/**
|
||||
* Mark an accompanying period as confirmed, but inactive
|
||||
*
|
||||
* this means that the accompanying period **is**
|
||||
* confirmed, but no activity (Activity, AccompanyingPeriod, ...)
|
||||
* has been associated, or updated, within this accompanying period.
|
||||
*/
|
||||
public const STEP_CONFIRMED_INACTIVE_LONG = 'CONFIRMED_INACTIVE_LONG';
|
||||
|
||||
/**
|
||||
* Mark an accompanying period as "draft".
|
||||
*
|
||||
@@ -340,6 +358,7 @@ class AccompanyingPeriod implements
|
||||
/**
|
||||
* @ORM\Column(type="string", length=32, nullable=true)
|
||||
* @Groups({"read"})
|
||||
* @var AccompanyingPeriod::STEP_*
|
||||
*/
|
||||
private string $step = self::STEP_DRAFT;
|
||||
|
||||
@@ -712,11 +731,9 @@ class AccompanyingPeriod implements
|
||||
if ($this->getStep() === self::STEP_DRAFT) {
|
||||
return [[self::STEP_DRAFT]];
|
||||
}
|
||||
|
||||
if ($this->getStep() === self::STEP_CONFIRMED) {
|
||||
if (str_starts_with($this->getStep(), 'CONFIRM')) {
|
||||
return [[self::STEP_DRAFT, self::STEP_CONFIRMED]];
|
||||
}
|
||||
|
||||
if ($this->getStep() === self::STEP_CLOSED) {
|
||||
return [[self::STEP_DRAFT, self::STEP_CONFIRMED, self::STEP_CLOSED]];
|
||||
}
|
||||
@@ -828,9 +845,7 @@ class AccompanyingPeriod implements
|
||||
$collection = $this
|
||||
->getParticipationsContainsPerson($person)
|
||||
->filter(
|
||||
static function (AccompanyingPeriodParticipation $participation): bool {
|
||||
return null === $participation->getEndDate();
|
||||
}
|
||||
static fn (AccompanyingPeriodParticipation $participation): bool => null === $participation->getEndDate()
|
||||
);
|
||||
|
||||
return $collection->count() > 0 ? $collection->first() : null;
|
||||
@@ -844,9 +859,7 @@ class AccompanyingPeriod implements
|
||||
return $this
|
||||
->getParticipations()
|
||||
->filter(
|
||||
static function (AccompanyingPeriodParticipation $participation): bool {
|
||||
return null === $participation->getEndDate();
|
||||
}
|
||||
static fn (AccompanyingPeriodParticipation $participation): bool => null === $participation->getEndDate()
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,79 @@
|
||||
<?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\Entity\User;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* Informations about AccompanyingPeriod
|
||||
*
|
||||
* This entity allow access to some basic information about the AccompanyingPeriod. It is
|
||||
* populated from a SQL view, dynamically build from various sources.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* - get the user involved with an accompanying period
|
||||
*
|
||||
* @ORM\Entity()
|
||||
* @ORM\Table(name="view_chill_person_accompanying_period_info")
|
||||
*/
|
||||
class AccompanyingPeriodInfo
|
||||
{
|
||||
public function __construct(
|
||||
/**
|
||||
* @var AccompanyingPeriod
|
||||
* @ORM\ManyToOne(targetEntity=AccompanyingPeriod::class)
|
||||
*/
|
||||
public readonly AccompanyingPeriod $accompanyingPeriod,
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @ORM\Column(type="text")
|
||||
* @ORM\Id
|
||||
*/
|
||||
public readonly string $relatedEntity,
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @ORM\Column(type="integer")
|
||||
* @ORM\Id
|
||||
*/
|
||||
public readonly int $relatedEntityId,
|
||||
|
||||
/**
|
||||
* @var User
|
||||
* @ORM\ManyToOne(targetEntity=User::class)
|
||||
*/
|
||||
public readonly ?User $user,
|
||||
|
||||
/**
|
||||
* @var \DateTimeImmutable
|
||||
* @ORM\Column(type="datetime_immutable")
|
||||
*/
|
||||
public readonly \DateTimeImmutable $infoDate,
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @ORM\Column(type="json")
|
||||
*/
|
||||
public readonly array $metadata,
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @ORM\Column(type="text")
|
||||
*/
|
||||
public readonly string $discriminator,
|
||||
) {
|
||||
}
|
||||
}
|
@@ -44,20 +44,20 @@ class Comment implements TrackCreationInterface, TrackUpdateInterface
|
||||
* @Assert\NotBlank
|
||||
* @Assert\NotNull
|
||||
*/
|
||||
private ?string $content;
|
||||
private ?string $content = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="datetime")
|
||||
* @Groups({"read", "docgen:read"})
|
||||
*/
|
||||
private ?DateTimeInterface $createdAt;
|
||||
private ?DateTimeInterface $createdAt = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=User::class)
|
||||
* @ORM\JoinColumn(nullable=false)
|
||||
* @Groups({"read", "docgen:read"})
|
||||
*/
|
||||
private ?User $creator;
|
||||
private ?User $creator = null;
|
||||
|
||||
/**
|
||||
* @ORM\Id
|
||||
@@ -65,20 +65,20 @@ class Comment implements TrackCreationInterface, TrackUpdateInterface
|
||||
* @ORM\Column(type="integer")
|
||||
* @Groups({"read", "docgen:read"})
|
||||
*/
|
||||
private ?int $id;
|
||||
private ?int $id = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="datetime")
|
||||
* @Groups({"read"})
|
||||
*/
|
||||
private ?DateTimeInterface $updatedAt;
|
||||
private ?DateTimeInterface $updatedAt = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=User::class)
|
||||
* @ORM\JoinColumn(nullable=false)
|
||||
* @Groups({"read"})
|
||||
*/
|
||||
private ?User $updatedBy;
|
||||
private ?User $updatedBy = null;
|
||||
|
||||
public function getAccompanyingPeriod(): ?AccompanyingPeriod
|
||||
{
|
||||
|
@@ -200,13 +200,11 @@ class Household
|
||||
*/
|
||||
public function getCurrentAddress(?DateTime $at = null): ?Address
|
||||
{
|
||||
$at = null === $at ? new DateTime('today') : $at;
|
||||
$at ??= new DateTime('today');
|
||||
|
||||
$addrs = $this->getAddresses()->filter(static function (Address $a) use ($at) {
|
||||
return $a->getValidFrom() <= $at && (
|
||||
null === $a->getValidTo() || $a->getValidTo() > $at
|
||||
);
|
||||
});
|
||||
$addrs = $this->getAddresses()->filter(static fn (Address $a) => $a->getValidFrom() <= $at && (
|
||||
null === $a->getValidTo() || $a->getValidTo() > $at
|
||||
));
|
||||
|
||||
if ($addrs->count() > 0) {
|
||||
return $addrs->first();
|
||||
@@ -338,9 +336,7 @@ class Household
|
||||
public function getCurrentPersons(?DateTimeImmutable $now = null): ReadableCollection
|
||||
{
|
||||
return $this->getCurrentMembers($now)
|
||||
->map(static function (HouseholdMember $m) {
|
||||
return $m->getPerson();
|
||||
});
|
||||
->map(static fn (HouseholdMember $m) => $m->getPerson());
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
@@ -367,9 +363,7 @@ class Household
|
||||
$membership->getStartDate(),
|
||||
$membership->getEndDate()
|
||||
)->filter(
|
||||
static function (HouseholdMember $m) use ($membership) {
|
||||
return $m->getPerson() !== $membership->getPerson();
|
||||
}
|
||||
static fn (HouseholdMember $m) => $m->getPerson() !== $membership->getPerson()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -412,7 +406,7 @@ class Household
|
||||
{
|
||||
$criteria = new Criteria();
|
||||
$expr = Criteria::expr();
|
||||
$date = null === $now ? (new DateTimeImmutable('today')) : $now;
|
||||
$date = $now ?? new DateTimeImmutable('today');
|
||||
|
||||
$criteria
|
||||
->where(
|
||||
@@ -508,9 +502,7 @@ class Household
|
||||
|
||||
usort(
|
||||
$compositionOrdered,
|
||||
static function (HouseholdComposition $a, HouseholdComposition $b) {
|
||||
return $a->getStartDate() <=> $b->getStartDate();
|
||||
}
|
||||
static fn (HouseholdComposition $a, HouseholdComposition $b) => $a->getStartDate() <=> $b->getStartDate()
|
||||
);
|
||||
|
||||
$iterator = new ArrayIterator($compositionOrdered);
|
||||
@@ -634,7 +626,7 @@ class Household
|
||||
{
|
||||
$criteria = new Criteria();
|
||||
$expr = Criteria::expr();
|
||||
$date = null === $now ? (new DateTimeImmutable('today')) : $now;
|
||||
$date = $now ?? new DateTimeImmutable('today');
|
||||
|
||||
$criteria
|
||||
->where($expr->orX(
|
||||
|
@@ -142,7 +142,7 @@ class HouseholdMember
|
||||
|
||||
public function isCurrent(?DateTimeImmutable $at = null): bool
|
||||
{
|
||||
$at = null === $at ? new DateTimeImmutable('now') : $at;
|
||||
$at ??= new DateTimeImmutable('now');
|
||||
|
||||
return $this->getStartDate() < $at && (
|
||||
null === $this->getEndDate() || $this->getEndDate() > $at
|
||||
|
@@ -775,9 +775,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
): int {
|
||||
// TODO should be optimized to avoid loading accompanying period ?
|
||||
return $this->getAccompanyingPeriodInvolved($asParticipantOpen, $asRequestor)
|
||||
->filter(function (AccompanyingPeriod $p) {
|
||||
return $p->getStep() !== AccompanyingPeriod::STEP_DRAFT;
|
||||
})
|
||||
->filter(fn (AccompanyingPeriod $p) => $p->getStep() !== AccompanyingPeriod::STEP_DRAFT)
|
||||
->count();
|
||||
}
|
||||
|
||||
@@ -1087,7 +1085,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
{
|
||||
$criteria = new Criteria();
|
||||
$expr = Criteria::expr();
|
||||
$date = null === $at ? new DateTimeImmutable('today') : $at;
|
||||
$date = $at ?? new DateTimeImmutable('today');
|
||||
$datef = $date->format('Y-m-d');
|
||||
|
||||
if (
|
||||
@@ -1341,9 +1339,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
|
||||
return $this->getAccompanyingPeriodParticipations()
|
||||
->matching($criteria)
|
||||
->filter(static function (AccompanyingPeriodParticipation $app) {
|
||||
return AccompanyingPeriod::STEP_CLOSED !== $app->getAccompanyingPeriod()->getStep();
|
||||
});
|
||||
->filter(static fn (AccompanyingPeriodParticipation $app) => AccompanyingPeriod::STEP_CLOSED !== $app->getAccompanyingPeriod()->getStep());
|
||||
}
|
||||
|
||||
public function getOtherPhoneNumbers(): Collection
|
||||
|
@@ -50,7 +50,7 @@ class PersonCurrentAddress
|
||||
/**
|
||||
* @ORM\Column(name="valid_to", type="date_immutable")
|
||||
*/
|
||||
protected ?DateTimeImmutable $validTo;
|
||||
protected ?DateTimeImmutable $validTo = null;
|
||||
|
||||
public function getAddress(): Address
|
||||
{
|
||||
|
@@ -55,7 +55,7 @@ class PersonResource implements TrackCreationInterface, TrackUpdateInterface
|
||||
* @ORM\Column(type="integer")
|
||||
* @Groups({"read", "docgen:read"})
|
||||
*/
|
||||
private ?int $id;
|
||||
private ?int $id = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=PersonResourceKind::class, inversedBy="personResources")
|
||||
|
@@ -41,7 +41,7 @@ class PersonPhone
|
||||
* @ORM\Column(name="id", type="integer")
|
||||
* @ORM\GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
private ?int $id;
|
||||
private ?int $id = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(
|
||||
@@ -59,7 +59,7 @@ class PersonPhone
|
||||
/**
|
||||
* @ORM\Column(type="text", length=40, nullable=true)
|
||||
*/
|
||||
private ?string $type;
|
||||
private ?string $type = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
@@ -45,7 +45,7 @@ class Result
|
||||
/**
|
||||
* @ORM\Column(type="datetime", nullable=true)
|
||||
*/
|
||||
private ?DateTime $desactivationDate;
|
||||
private ?DateTime $desactivationDate = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToMany(targetEntity=Goal::class, mappedBy="results")
|
||||
|
@@ -128,9 +128,7 @@ final class GeographicalUnitStatAggregator implements AggregatorInterface
|
||||
'placeholder' => 'Select a geographical layer',
|
||||
'class' => GeographicalUnitLayer::class,
|
||||
'choices' => $this->geographicalUnitLayerRepository->findAllHavingUnits(),
|
||||
'choice_label' => function (GeographicalUnitLayer $item) {
|
||||
return $this->translatableStringHelper->localize($item->getName());
|
||||
},
|
||||
'choice_label' => fn (GeographicalUnitLayer $item) => $this->translatableStringHelper->localize($item->getName()),
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
]);
|
||||
|
@@ -86,13 +86,19 @@ final class StepAggregator implements AggregatorInterface
|
||||
return function ($value): string {
|
||||
switch ($value) {
|
||||
case AccompanyingPeriod::STEP_DRAFT:
|
||||
return $this->translator->trans('Draft');
|
||||
return $this->translator->trans('course.draft');
|
||||
|
||||
case AccompanyingPeriod::STEP_CONFIRMED:
|
||||
return $this->translator->trans('Confirmed');
|
||||
return $this->translator->trans('course.confirmed');
|
||||
|
||||
case AccompanyingPeriod::STEP_CLOSED:
|
||||
return $this->translator->trans('Closed');
|
||||
return $this->translator->trans('course.closed');
|
||||
|
||||
case AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT:
|
||||
return $this->translator->trans('course.inactive_short');
|
||||
|
||||
case AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG:
|
||||
return $this->translator->trans('course.inactive_long');
|
||||
|
||||
case '_header':
|
||||
return 'Step';
|
||||
|
@@ -147,9 +147,7 @@ final class CountryOfBirthAggregator implements AggregatorInterface, ExportEleme
|
||||
];
|
||||
}
|
||||
|
||||
return static function (string $value) use ($labels): string {
|
||||
return $labels[$value];
|
||||
};
|
||||
return static fn (string $value): string => $labels[$value];
|
||||
}
|
||||
|
||||
public function getQueryKeys($data)
|
||||
|
@@ -100,9 +100,7 @@ class GeographicalUnitAggregator implements AggregatorInterface
|
||||
'placeholder' => 'Select a geographical layer',
|
||||
'class' => GeographicalUnitLayer::class,
|
||||
'choices' => $this->geographicalUnitLayerRepository->findAllHavingUnits(),
|
||||
'choice_label' => function (GeographicalUnitLayer $item) {
|
||||
return $this->translatableStringHelper->localize($item->getName());
|
||||
},
|
||||
'choice_label' => fn (GeographicalUnitLayer $item) => $this->translatableStringHelper->localize($item->getName()),
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
]);
|
||||
|
@@ -141,9 +141,7 @@ final class NationalityAggregator implements AggregatorInterface, ExportElementV
|
||||
];
|
||||
}
|
||||
|
||||
return static function ($value) use ($labels): string {
|
||||
return $labels[$value];
|
||||
};
|
||||
return static fn ($value): string => $labels[$value];
|
||||
}
|
||||
|
||||
public function getQueryKeys($data)
|
||||
|
@@ -64,9 +64,7 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface
|
||||
$labels = array_combine($values, $values);
|
||||
$labels['_header'] = $this->getTitle();
|
||||
|
||||
return static function ($value) use ($labels) {
|
||||
return $labels[$value];
|
||||
};
|
||||
return static fn ($value) => $labels[$value];
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
@@ -91,9 +89,7 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = []): QueryBuilder
|
||||
{
|
||||
$centers = array_map(static function ($el) {
|
||||
return $el['center'];
|
||||
}, $acl);
|
||||
$centers = array_map(static fn ($el) => $el['center'], $acl);
|
||||
|
||||
$qb = $this->repository->createQueryBuilder('acp');
|
||||
|
||||
|
@@ -63,9 +63,7 @@ class CountAccompanyingPeriodWork implements ExportInterface, GroupedExportInter
|
||||
$labels = array_combine($values, $values);
|
||||
$labels['_header'] = $this->getTitle();
|
||||
|
||||
return static function ($value) use ($labels) {
|
||||
return $labels[$value];
|
||||
};
|
||||
return static fn ($value) => $labels[$value];
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
@@ -90,9 +88,7 @@ class CountAccompanyingPeriodWork implements ExportInterface, GroupedExportInter
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = []): QueryBuilder
|
||||
{
|
||||
$centers = array_map(static function ($el) {
|
||||
return $el['center'];
|
||||
}, $acl);
|
||||
$centers = array_map(static fn ($el) => $el['center'], $acl);
|
||||
|
||||
$qb = $this->em->createQueryBuilder();
|
||||
|
||||
|
@@ -62,9 +62,7 @@ class CountEvaluation implements ExportInterface, GroupedExportInterface
|
||||
$labels = array_combine($values, $values);
|
||||
$labels['_header'] = $this->getTitle();
|
||||
|
||||
return static function ($value) use ($labels) {
|
||||
return $labels[$value];
|
||||
};
|
||||
return static fn ($value) => $labels[$value];
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
@@ -89,9 +87,7 @@ class CountEvaluation implements ExportInterface, GroupedExportInterface
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||
{
|
||||
$centers = array_map(static function ($el) {
|
||||
return $el['center'];
|
||||
}, $acl);
|
||||
$centers = array_map(static fn ($el) => $el['center'], $acl);
|
||||
|
||||
$qb = $this->entityManager->createQueryBuilder();
|
||||
|
||||
|
@@ -113,9 +113,7 @@ class CountHousehold implements ExportInterface, GroupedExportInterface
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||
{
|
||||
$centers = array_map(static function ($el) {
|
||||
return $el['center'];
|
||||
}, $acl);
|
||||
$centers = array_map(static fn ($el) => $el['center'], $acl);
|
||||
|
||||
$qb = $this->entityManager->createQueryBuilder();
|
||||
|
||||
|
@@ -62,9 +62,7 @@ class CountPerson implements ExportInterface, GroupedExportInterface
|
||||
$labels = array_combine($values, $values);
|
||||
$labels['_header'] = $this->getTitle();
|
||||
|
||||
return static function ($value) use ($labels) {
|
||||
return $labels[$value];
|
||||
};
|
||||
return static fn ($value) => $labels[$value];
|
||||
}
|
||||
|
||||
public function getQueryKeys($data)
|
||||
@@ -94,9 +92,7 @@ class CountPerson implements ExportInterface, GroupedExportInterface
|
||||
*/
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||
{
|
||||
$centers = array_map(static function ($el) {
|
||||
return $el['center'];
|
||||
}, $acl);
|
||||
$centers = array_map(static fn ($el) => $el['center'], $acl);
|
||||
|
||||
$qb = $this->personRepository->createQueryBuilder('person');
|
||||
|
||||
|
@@ -64,9 +64,7 @@ class CountPersonWithAccompanyingCourse implements ExportInterface, GroupedExpor
|
||||
$labels = array_combine($values, $values);
|
||||
$labels['_header'] = $this->getTitle();
|
||||
|
||||
return static function ($value) use ($labels) {
|
||||
return $labels[$value];
|
||||
};
|
||||
return static fn ($value) => $labels[$value];
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
@@ -91,9 +89,7 @@ class CountPersonWithAccompanyingCourse implements ExportInterface, GroupedExpor
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||
{
|
||||
$centers = array_map(static function ($el) {
|
||||
return $el['center'];
|
||||
}, $acl);
|
||||
$centers = array_map(static fn ($el) => $el['center'], $acl);
|
||||
|
||||
$qb = $this->repository->createQueryBuilder('acp');
|
||||
|
||||
|
@@ -41,6 +41,7 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Query\Expr\Join;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use function strlen;
|
||||
|
||||
class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface
|
||||
@@ -100,6 +101,8 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface
|
||||
|
||||
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
private UserHelper $userHelper;
|
||||
|
||||
public function __construct(
|
||||
@@ -113,6 +116,7 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface
|
||||
SocialIssueRepository $socialIssueRepository,
|
||||
SocialIssueRender $socialIssueRender,
|
||||
TranslatableStringHelperInterface $translatableStringHelper,
|
||||
TranslatorInterface $translator,
|
||||
RollingDateConverterInterface $rollingDateConverter,
|
||||
UserHelper $userHelper
|
||||
) {
|
||||
@@ -126,6 +130,7 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface
|
||||
$this->thirdPartyRender = $thirdPartyRender;
|
||||
$this->thirdPartyRepository = $thirdPartyRepository;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
$this->translator = $translator;
|
||||
$this->rollingDateConverter = $rollingDateConverter;
|
||||
$this->userHelper = $userHelper;
|
||||
}
|
||||
@@ -182,7 +187,7 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->translatableStringHelper->localize(json_decode($value, true));
|
||||
return $this->translatableStringHelper->localize(json_decode($value, true, 512, JSON_THROW_ON_ERROR));
|
||||
};
|
||||
|
||||
case 'locationPersonName':
|
||||
@@ -226,7 +231,7 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface
|
||||
'|',
|
||||
array_map(
|
||||
fn ($s) => $this->translatableStringHelper->localize($s),
|
||||
json_decode($value, true)
|
||||
json_decode($value, true, 512, JSON_THROW_ON_ERROR)
|
||||
)
|
||||
);
|
||||
};
|
||||
@@ -245,11 +250,32 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface
|
||||
'|',
|
||||
array_map(
|
||||
fn ($s) => $this->socialIssueRender->renderString($this->socialIssueRepository->find($s), []),
|
||||
json_decode($value, true)
|
||||
json_decode($value, true, 512, JSON_THROW_ON_ERROR)
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
case 'step':
|
||||
return fn ($value) => match ($value) {
|
||||
'_header' => 'export.list.acp.step',
|
||||
null => '',
|
||||
AccompanyingPeriod::STEP_DRAFT => $this->translator->trans('course.draft'),
|
||||
AccompanyingPeriod::STEP_CONFIRMED => $this->translator->trans('course.confirmed'),
|
||||
AccompanyingPeriod::STEP_CLOSED => $this->translator->trans('course.closed'),
|
||||
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT => $this->translator->trans('course.inactive_short'),
|
||||
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG => $this->translator->trans('course.inactive_long'),
|
||||
default => $value,
|
||||
};
|
||||
|
||||
case 'intensity':
|
||||
return fn ($value) => match ($value) {
|
||||
'_header' => 'export.list.acp.intensity',
|
||||
null => '',
|
||||
AccompanyingPeriod::INTENSITY_OCCASIONAL => $this->translator->trans('occasional'),
|
||||
AccompanyingPeriod::INTENSITY_REGULAR => $this->translator->trans('regular'),
|
||||
default => $value,
|
||||
};
|
||||
|
||||
default:
|
||||
return static function ($value) use ($key) {
|
||||
if ('_header' === $value) {
|
||||
@@ -290,9 +316,7 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||
{
|
||||
$centers = array_map(static function ($el) {
|
||||
return $el['center'];
|
||||
}, $acl);
|
||||
$centers = array_map(static fn ($el) => $el['center'], $acl);
|
||||
|
||||
$qb = $this->entityManager->createQueryBuilder();
|
||||
|
||||
|
@@ -263,9 +263,7 @@ class ListAccompanyingPeriodWork implements ListInterface, GroupedExportInterfac
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||
{
|
||||
$centers = array_map(static function ($el) {
|
||||
return $el['center'];
|
||||
}, $acl);
|
||||
$centers = array_map(static fn ($el) => $el['center'], $acl);
|
||||
|
||||
$qb = $this->entityManager->createQueryBuilder();
|
||||
|
||||
|
@@ -241,9 +241,7 @@ class ListEvaluation implements ListInterface, GroupedExportInterface
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||
{
|
||||
$centers = array_map(static function ($el) {
|
||||
return $el['center'];
|
||||
}, $acl);
|
||||
$centers = array_map(static fn ($el) => $el['center'], $acl);
|
||||
|
||||
$qb = $this->entityManager->createQueryBuilder();
|
||||
|
||||
|
@@ -146,9 +146,7 @@ class ListHouseholdInPeriod implements ListInterface, GroupedExportInterface
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||
{
|
||||
$centers = array_map(static function ($el) {
|
||||
return $el['center'];
|
||||
}, $acl);
|
||||
$centers = array_map(static fn ($el) => $el['center'], $acl);
|
||||
|
||||
$qb = $this->entityManager->createQueryBuilder();
|
||||
|
||||
|
@@ -191,9 +191,7 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
|
||||
*/
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||
{
|
||||
$centers = array_map(static function ($el) {
|
||||
return $el['center'];
|
||||
}, $acl);
|
||||
$centers = array_map(static fn ($el) => $el['center'], $acl);
|
||||
|
||||
// throw an error if any fields are present
|
||||
if (!array_key_exists('fields', $data)) {
|
||||
@@ -334,7 +332,7 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
|
||||
|
||||
return $this->customFieldProvider
|
||||
->getCustomFieldByType($cf->getType())
|
||||
->render(json_decode($value, true), $cf, 'csv');
|
||||
->render(json_decode($value, true, 512, JSON_THROW_ON_ERROR), $cf, 'csv');
|
||||
};
|
||||
|
||||
if ($cfType instanceof CustomFieldChoice && $cfType->isMultiple($cf)) {
|
||||
@@ -344,7 +342,7 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
|
||||
if (null === $value) {
|
||||
return '';
|
||||
}
|
||||
$decoded = json_decode($value, true);
|
||||
$decoded = json_decode($value, true, 512, JSON_THROW_ON_ERROR);
|
||||
|
||||
if ('_header' === $value) {
|
||||
$label = $cfType->getChoices($cf)[$slugChoice];
|
||||
|
@@ -159,9 +159,7 @@ class ListPersonWithAccompanyingPeriod implements ExportElementValidatedInterfac
|
||||
*/
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||
{
|
||||
$centers = array_map(static function ($el) {
|
||||
return $el['center'];
|
||||
}, $acl);
|
||||
$centers = array_map(static fn ($el) => $el['center'], $acl);
|
||||
|
||||
// throw an error if any fields are present
|
||||
if (!array_key_exists('fields', $data)) {
|
||||
|
@@ -112,9 +112,7 @@ class StatAccompanyingCourseDuration implements ExportInterface, GroupedExportIn
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = []): QueryBuilder
|
||||
{
|
||||
$centers = array_map(static function ($el) {
|
||||
return $el['center'];
|
||||
}, $acl);
|
||||
$centers = array_map(static fn ($el) => $el['center'], $acl);
|
||||
|
||||
$qb = $this->repository->createQueryBuilder('acp');
|
||||
|
||||
|
@@ -59,9 +59,7 @@ class ClosingMotiveFilter implements FilterInterface
|
||||
{
|
||||
$builder->add('accepted_closingmotives', EntityType::class, [
|
||||
'class' => ClosingMotive::class,
|
||||
'choice_label' => function (ClosingMotive $cm) {
|
||||
return $this->translatableStringHelper->localize($cm->getName());
|
||||
},
|
||||
'choice_label' => fn (ClosingMotive $cm) => $this->translatableStringHelper->localize($cm->getName()),
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
]);
|
||||
|
@@ -61,11 +61,9 @@ class CreatorJobFilter implements FilterInterface
|
||||
$builder->add('creator_job', EntityType::class, [
|
||||
'class' => UserJob::class,
|
||||
'choices' => $this->userJobRepository->findAllActive(),
|
||||
'choice_label' => function (UserJob $j) {
|
||||
return $this->translatableStringHelper->localize(
|
||||
$j->getLabel()
|
||||
);
|
||||
},
|
||||
'choice_label' => fn (UserJob $j) => $this->translatableStringHelper->localize(
|
||||
$j->getLabel()
|
||||
),
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
'label' => 'Job',
|
||||
|
@@ -69,9 +69,7 @@ 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());
|
||||
},
|
||||
'choice_label' => fn (Evaluation $ev) => $this->translatableStringHelper->localize($ev->getTitle()),
|
||||
'multiple' => true,
|
||||
'expanded' => false,
|
||||
'attr' => ['class' => 'select2'],
|
||||
|
@@ -107,9 +107,7 @@ class GeographicalUnitStatFilter implements FilterInterface
|
||||
'placeholder' => 'Select a geographical unit',
|
||||
'choices' => $this->geographicalUnitRepository->findAll(),
|
||||
'choice_value' => static fn (SimpleGeographicalUnitDTO $item) => $item->id,
|
||||
'choice_label' => function (SimpleGeographicalUnitDTO $item) {
|
||||
return $this->translatableStringHelper->localize($this->geographicalUnitLayerRepository->find($item->layerId)->getName()) . ' > ' . $item->unitName;
|
||||
},
|
||||
'choice_label' => fn (SimpleGeographicalUnitDTO $item) => $this->translatableStringHelper->localize($this->geographicalUnitLayerRepository->find($item->layerId)->getName()) . ' > ' . $item->unitName,
|
||||
'attr' => [
|
||||
'class' => 'select2',
|
||||
],
|
||||
@@ -124,9 +122,7 @@ class GeographicalUnitStatFilter implements FilterInterface
|
||||
'%units' => implode(
|
||||
', ',
|
||||
array_map(
|
||||
function (SimpleGeographicalUnitDTO $item) {
|
||||
return $this->translatableStringHelper->localize($this->geographicalUnitLayerRepository->find($item->layerId)->getName()) . ' > ' . $item->unitName;
|
||||
},
|
||||
fn (SimpleGeographicalUnitDTO $item) => $this->translatableStringHelper->localize($this->geographicalUnitLayerRepository->find($item->layerId)->getName()) . ' > ' . $item->unitName,
|
||||
$data['units']
|
||||
)
|
||||
),
|
||||
|
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
|
||||
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\MainBundle\Form\Type\DateIntervalType;
|
||||
use Chill\MainBundle\Form\Type\PickRollingDateType;
|
||||
use Chill\MainBundle\Service\RollingDate\RollingDate;
|
||||
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodInfo;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
/**
|
||||
* Filter accompanying course which have a row in AccompanyingPeriodInfo within the given
|
||||
* interval
|
||||
*/
|
||||
final readonly class HavingAnAccompanyingPeriodInfoWithinDatesFilter implements FilterInterface
|
||||
{
|
||||
public function __construct(
|
||||
private RollingDateConverterInterface $rollingDateConverter,
|
||||
) {
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder): void
|
||||
{
|
||||
$builder
|
||||
->add('start_date', PickRollingDateType::class, [
|
||||
'label' => 'export.filter.course.having_info_within_interval.start_date',
|
||||
'data' => new RollingDate(RollingDate::T_TODAY),
|
||||
])
|
||||
->add('end_date', PickRollingDateType::class, [
|
||||
'label' => 'export.filter.course.having_info_within_interval.end_date',
|
||||
'data' => new RollingDate(RollingDate::T_TODAY),
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'export.filter.course.having_info_within_interval.title';
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string'): array
|
||||
{
|
||||
return [
|
||||
'export.filter.course.having_info_within_interval.Only course with events between %startDate% and %endDate%',
|
||||
[
|
||||
'%startDate%' => $this->rollingDateConverter->convert($data['start_date'])->format('d-m-Y'),
|
||||
'%endDate%' => $this->rollingDateConverter->convert($data['end_date'])->format('d-m-Y'),
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function addRole(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data): void
|
||||
{
|
||||
$ai = 'having_ai_within_interval_acc_info';
|
||||
$as = 'having_ai_within_interval_start_date';
|
||||
$ae = 'having_ai_within_interval_end_date';
|
||||
|
||||
$qb
|
||||
->andWhere(
|
||||
$qb->expr()->exists(
|
||||
'SELECT 1 FROM ' . AccompanyingPeriodInfo::class . " {$ai} WHERE {$ai}.infoDate BETWEEN :{$as} AND :{$ae} AND IDENTITY({$ai}.accompanyingPeriod) = acp.id"
|
||||
)
|
||||
)
|
||||
->setParameter($as, $this->rollingDateConverter->convert($data['start_date']), Types::DATETIME_IMMUTABLE)
|
||||
->setParameter($ae, $this->rollingDateConverter->convert($data['end_date']), Types::DATETIME_IMMUTABLE);
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::ACP_TYPE;
|
||||
}
|
||||
}
|
@@ -59,9 +59,7 @@ class OriginFilter implements FilterInterface
|
||||
{
|
||||
$builder->add('accepted_origins', EntityType::class, [
|
||||
'class' => Origin::class,
|
||||
'choice_label' => function (Origin $o) {
|
||||
return $this->translatableStringHelper->localize($o->getLabel());
|
||||
},
|
||||
'choice_label' => fn (Origin $o) => $this->translatableStringHelper->localize($o->getLabel()),
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
]);
|
||||
|
@@ -32,9 +32,11 @@ class StepFilter implements FilterInterface
|
||||
private const P = 'acp_step_filter_date';
|
||||
|
||||
private const STEPS = [
|
||||
'Draft' => AccompanyingPeriod::STEP_DRAFT,
|
||||
'Confirmed' => AccompanyingPeriod::STEP_CONFIRMED,
|
||||
'Closed' => AccompanyingPeriod::STEP_CLOSED,
|
||||
'course.draft' => AccompanyingPeriod::STEP_DRAFT,
|
||||
'course.confirmed' => AccompanyingPeriod::STEP_CONFIRMED,
|
||||
'course.closed' => AccompanyingPeriod::STEP_CLOSED,
|
||||
'course.inactive_short' => AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT,
|
||||
'course.inactive_long' => AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG,
|
||||
];
|
||||
|
||||
private RollingDateConverterInterface $rollingDateConverter;
|
||||
@@ -96,7 +98,7 @@ class StepFilter implements FilterInterface
|
||||
'data' => self::DEFAULT_CHOICE,
|
||||
])
|
||||
->add('calc_date', PickRollingDateType::class, [
|
||||
'label' => 'export.acp.filter.by_step.date_calc',
|
||||
'label' => 'export.filter.course.by_step.date_calc',
|
||||
'data' => new RollingDate(RollingDate::T_TODAY),
|
||||
]);
|
||||
}
|
||||
|
@@ -0,0 +1,88 @@
|
||||
<?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\Export\FilterInterface;
|
||||
use Chill\MainBundle\Form\Type\PickUserDynamicType;
|
||||
use Chill\MainBundle\Templating\Entity\UserRender;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
/**
|
||||
* Filter course where a user is "working" on it
|
||||
*
|
||||
* Makes use of AccompanyingPeriodInfo
|
||||
*/
|
||||
readonly class UserWorkingOnCourseFilter implements FilterInterface
|
||||
{
|
||||
private const AI_ALIAS = 'user_working_on_course_filter_acc_info';
|
||||
private const AI_USERS = 'user_working_on_course_filter_users';
|
||||
|
||||
public function __construct(
|
||||
private UserRender $userRender,
|
||||
) {
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder): void
|
||||
{
|
||||
$builder
|
||||
->add('users', PickUserDynamicType::class, [
|
||||
'multiple' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'export.filter.course.by_user_working.title';
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string'): array
|
||||
{
|
||||
return [
|
||||
'export.filter.course.by_user_working.Filtered by user working on course: only %users%', [
|
||||
'%users%' => implode(
|
||||
', ',
|
||||
array_map(
|
||||
fn (User $u) => $this->userRender->renderString($u, []),
|
||||
$data['users']
|
||||
)
|
||||
),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function addRole(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data): void
|
||||
{
|
||||
$qb
|
||||
->andWhere(
|
||||
$qb->expr()->exists(
|
||||
"SELECT 1 FROM " . AccompanyingPeriod\AccompanyingPeriodInfo::class . " " . self::AI_ALIAS . " " .
|
||||
"WHERE " . self::AI_ALIAS . ".user IN (:" . self::AI_USERS .") AND IDENTITY(" . self::AI_ALIAS . ".accompanyingPeriod) = acp.id"
|
||||
)
|
||||
)
|
||||
->setParameter(self::AI_USERS, $data['users'])
|
||||
;
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::ACP_TYPE;
|
||||
}
|
||||
}
|
@@ -59,9 +59,7 @@ final class EvaluationTypeFilter implements FilterInterface
|
||||
{
|
||||
$builder->add('accepted_evaluationtype', EntityType::class, [
|
||||
'class' => Evaluation::class,
|
||||
'choice_label' => function (Evaluation $ev): string {
|
||||
return $this->translatableStringHelper->localize($ev->getTitle());
|
||||
},
|
||||
'choice_label' => fn (Evaluation $ev): string => $this->translatableStringHelper->localize($ev->getTitle()),
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
]);
|
||||
|
@@ -78,11 +78,9 @@ class CompositionFilter implements FilterInterface
|
||||
$builder
|
||||
->add('accepted_composition', EntityType::class, [
|
||||
'class' => HouseholdCompositionType::class,
|
||||
'choice_label' => function (HouseholdCompositionType $type) {
|
||||
return $this->translatableStringHelper->localize(
|
||||
$type->getLabel()
|
||||
);
|
||||
},
|
||||
'choice_label' => fn (HouseholdCompositionType $type) => $this->translatableStringHelper->localize(
|
||||
$type->getLabel()
|
||||
),
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
])
|
||||
|
@@ -81,9 +81,7 @@ class AddressRefStatusFilter implements \Chill\MainBundle\Export\FilterInterface
|
||||
->add('ref_statuses', ChoiceType::class, [
|
||||
'label' => 'export.filter.person.by_address_ref_status.Status',
|
||||
'choices' => [Address::ADDR_REFERENCE_STATUS_TO_REVIEW, Address::ADDR_REFERENCE_STATUS_REVIEWED, Address::ADDR_REFERENCE_STATUS_MATCH],
|
||||
'choice_label' => function (string $item) {
|
||||
return 'export.filter.person.by_address_ref_status.'.$item;
|
||||
},
|
||||
'choice_label' => fn (string $item) => 'export.filter.person.by_address_ref_status.'.$item,
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
'data' => [Address::ADDR_REFERENCE_STATUS_TO_REVIEW]
|
||||
@@ -99,9 +97,7 @@ class AddressRefStatusFilter implements \Chill\MainBundle\Export\FilterInterface
|
||||
'%statuses%' => implode(
|
||||
', ',
|
||||
array_map(
|
||||
function (string $item) {
|
||||
return 'export.filter.person.by_address_ref_status.'.$item;
|
||||
},
|
||||
fn (string $item) => 'export.filter.person.by_address_ref_status.'.$item,
|
||||
$data['ref_statuses'] ?? RollingDate::T_TODAY
|
||||
)
|
||||
),
|
||||
|
@@ -42,8 +42,8 @@ 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'] : 150;
|
||||
$min = $data['min_age'] ?? 0;
|
||||
$max = $data['max_age'] ?? 150;
|
||||
$calc = $this->rollingDateConverter->convert($data['date_calc']);
|
||||
|
||||
$minDate = $calc->sub(new DateInterval('P' . $max . 'Y'));
|
||||
|
@@ -67,9 +67,7 @@ class GenderFilter implements
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('person_gender', array_filter(
|
||||
$data['accepted_genders'],
|
||||
static function ($el) {
|
||||
return 'null' !== $el;
|
||||
}
|
||||
static fn ($el) => 'null' !== $el
|
||||
));
|
||||
}
|
||||
|
||||
|
@@ -98,9 +98,7 @@ class GeographicalUnitFilter implements \Chill\MainBundle\Export\FilterInterface
|
||||
'placeholder' => 'Select a geographical unit',
|
||||
'choices' => $this->geographicalUnitRepository->findAll(),
|
||||
'choice_value' => static fn (SimpleGeographicalUnitDTO $item) => $item->id,
|
||||
'choice_label' => function (SimpleGeographicalUnitDTO $item) {
|
||||
return $this->translatableStringHelper->localize($this->geographicalUnitLayerRepository->find($item->layerId)->getName()) . ' > ' . $item->unitName;
|
||||
},
|
||||
'choice_label' => fn (SimpleGeographicalUnitDTO $item) => $this->translatableStringHelper->localize($this->geographicalUnitLayerRepository->find($item->layerId)->getName()) . ' > ' . $item->unitName,
|
||||
'attr' => [
|
||||
'class' => 'select2',
|
||||
],
|
||||
@@ -117,9 +115,7 @@ class GeographicalUnitFilter implements \Chill\MainBundle\Export\FilterInterface
|
||||
'%units%' => implode(
|
||||
', ',
|
||||
array_map(
|
||||
function (SimpleGeographicalUnitDTO $item) {
|
||||
return $this->translatableStringHelper->localize($this->geographicalUnitLayerRepository->find($item->layerId)->getName()) . ' > ' . $item->unitName;
|
||||
},
|
||||
fn (SimpleGeographicalUnitDTO $item) => $this->translatableStringHelper->localize($this->geographicalUnitLayerRepository->find($item->layerId)->getName()) . ' > ' . $item->unitName,
|
||||
$data['units']
|
||||
)
|
||||
),
|
||||
|
@@ -49,11 +49,9 @@ class MaritalStatusFilter implements FilterInterface
|
||||
{
|
||||
$builder->add('maritalStatus', EntityType::class, [
|
||||
'class' => MaritalStatus::class,
|
||||
'choice_label' => function (MaritalStatus $ms) {
|
||||
return $this->translatableStringHelper->localize(
|
||||
$ms->getName()
|
||||
);
|
||||
},
|
||||
'choice_label' => fn (MaritalStatus $ms) => $this->translatableStringHelper->localize(
|
||||
$ms->getName()
|
||||
),
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
]);
|
||||
|
@@ -72,9 +72,7 @@ class NationalityFilter implements
|
||||
{
|
||||
$countries = $data['nationalities'];
|
||||
|
||||
$names = array_map(function (Country $c) {
|
||||
return $this->translatableStringHelper->localize($c->getName());
|
||||
}, [$countries]);
|
||||
$names = array_map(fn (Country $c) => $this->translatableStringHelper->localize($c->getName()), [$countries]);
|
||||
|
||||
return [
|
||||
'Filtered by nationality : %nationalities%',
|
||||
|
@@ -100,9 +100,7 @@ class ResidentialAddressAtThirdpartyFilter implements FilterInterface
|
||||
$builder->add('thirdparty_cat', EntityType::class, [
|
||||
'class' => ThirdPartyCategory::class,
|
||||
'label' => 'Category',
|
||||
'choice_label' => function (ThirdPartyCategory $tpc) {
|
||||
return $this->translatableStringHelper->localize($tpc->getName());
|
||||
},
|
||||
'choice_label' => fn (ThirdPartyCategory $tpc) => $this->translatableStringHelper->localize($tpc->getName()),
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
]);
|
||||
|
@@ -69,11 +69,9 @@ class JobFilter implements FilterInterface
|
||||
{
|
||||
$builder->add('job', EntityType::class, [
|
||||
'class' => UserJob::class,
|
||||
'choice_label' => function (UserJob $j) {
|
||||
return $this->translatableStringHelper->localize(
|
||||
$j->getLabel()
|
||||
);
|
||||
},
|
||||
'choice_label' => fn (UserJob $j) => $this->translatableStringHelper->localize(
|
||||
$j->getLabel()
|
||||
),
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
]);
|
||||
|
@@ -69,11 +69,9 @@ class ScopeFilter implements FilterInterface
|
||||
{
|
||||
$builder->add('scope', EntityType::class, [
|
||||
'class' => Scope::class,
|
||||
'choice_label' => function (Scope $s) {
|
||||
return $this->translatableStringHelper->localize(
|
||||
$s->getName()
|
||||
);
|
||||
},
|
||||
'choice_label' => fn (Scope $s) => $this->translatableStringHelper->localize(
|
||||
$s->getName()
|
||||
),
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
]);
|
||||
|
@@ -136,7 +136,7 @@ class SocialWorkTypeFilter implements FilterInterface
|
||||
}
|
||||
|
||||
return ['Filtered actions by type, goals and results: %selected%', [
|
||||
'%selected%' => implode(', ', array_merge($actionTypes, $goals, $results)),
|
||||
'%selected%' => implode(', ', [...$actionTypes, ...$goals, ...$results]),
|
||||
]];
|
||||
}
|
||||
|
||||
|
@@ -39,7 +39,7 @@ class LabelPersonHelper
|
||||
return '';
|
||||
}
|
||||
|
||||
$decoded = json_decode($value);
|
||||
$decoded = json_decode($value, null, 512, JSON_THROW_ON_ERROR);
|
||||
|
||||
if (0 === count($decoded)) {
|
||||
return '';
|
||||
|
@@ -361,7 +361,7 @@ class ListPersonHelper
|
||||
return '';
|
||||
}
|
||||
|
||||
$ids = json_decode($value);
|
||||
$ids = json_decode($value, null, 512, JSON_THROW_ON_ERROR);
|
||||
|
||||
return
|
||||
implode(
|
||||
|
@@ -98,7 +98,7 @@ class AccompanyingPeriodType extends AbstractType
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => 'Chill\PersonBundle\Entity\AccompanyingPeriod',
|
||||
'data_class' => \Chill\PersonBundle\Entity\AccompanyingPeriod::class,
|
||||
]);
|
||||
|
||||
$resolver
|
||||
|
@@ -55,9 +55,7 @@ class PersonChoiceLoader implements ChoiceLoaderInterface
|
||||
{
|
||||
return new \Symfony\Component\Form\ChoiceList\ArrayChoiceList(
|
||||
$this->lazyLoadedPersons,
|
||||
static function (Person $p) use ($value) {
|
||||
return call_user_func($value, $p);
|
||||
}
|
||||
static fn (Person $p) => call_user_func($value, $p)
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -40,9 +40,7 @@ class HouseholdCompositionType extends AbstractType
|
||||
->add('householdCompositionType', EntityType::class, [
|
||||
'class' => \Chill\PersonBundle\Entity\Household\HouseholdCompositionType::class,
|
||||
'choices' => $types,
|
||||
'choice_label' => function (\Chill\PersonBundle\Entity\Household\HouseholdCompositionType $type) {
|
||||
return $this->translatableStringHelper->localize($type->getLabel());
|
||||
},
|
||||
'choice_label' => fn (\Chill\PersonBundle\Entity\Household\HouseholdCompositionType $type) => $this->translatableStringHelper->localize($type->getLabel()),
|
||||
'label' => 'household_composition.Household composition',
|
||||
])
|
||||
->add('startDate', ChillDateType::class, [
|
||||
|
@@ -118,12 +118,8 @@ class PersonType extends AbstractType
|
||||
]);
|
||||
|
||||
$builder->get('placeOfBirth')->addModelTransformer(new CallbackTransformer(
|
||||
static function ($string) {
|
||||
return strtoupper((string) $string);
|
||||
},
|
||||
static function ($string) {
|
||||
return strtoupper((string) $string);
|
||||
}
|
||||
static fn ($string) => strtoupper((string) $string),
|
||||
static fn ($string) => strtoupper((string) $string)
|
||||
));
|
||||
}
|
||||
|
||||
@@ -167,9 +163,7 @@ class PersonType extends AbstractType
|
||||
'allow_delete' => true,
|
||||
'by_reference' => false,
|
||||
'label' => false,
|
||||
'delete_empty' => static function (?PersonPhone $pp = null) {
|
||||
return null === $pp || $pp->isEmpty();
|
||||
},
|
||||
'delete_empty' => static fn (?PersonPhone $pp = null) => null === $pp || $pp->isEmpty(),
|
||||
'error_bubbling' => false,
|
||||
'empty_collection_explain' => 'No additional phone numbers',
|
||||
]);
|
||||
@@ -250,7 +244,7 @@ class PersonType extends AbstractType
|
||||
|
||||
$resolver->setAllowedTypes(
|
||||
'cFGroup',
|
||||
['null', 'Chill\CustomFieldsBundle\Entity\CustomFieldsGroup']
|
||||
['null', \Chill\CustomFieldsBundle\Entity\CustomFieldsGroup::class]
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -46,9 +46,7 @@ class GoalType extends AbstractType
|
||||
'class' => Result::class,
|
||||
'required' => false,
|
||||
'multiple' => true,
|
||||
'choice_label' => function (Result $r) {
|
||||
return $this->translatableStringHelper->localize($r->getTitle());
|
||||
},
|
||||
'choice_label' => fn (Result $r) => $this->translatableStringHelper->localize($r->getTitle()),
|
||||
'attr' => ['class' => 'select2 '],
|
||||
])
|
||||
->add('desactivationDate', ChillDateType::class, [
|
||||
|
@@ -50,16 +50,12 @@ class SocialActionType extends AbstractType
|
||||
->add('issue', EntityType::class, [
|
||||
'class' => SocialIssue::class,
|
||||
'label' => 'socialAction.socialIssue',
|
||||
'choice_label' => function (SocialIssue $issue) {
|
||||
return $this->translatableStringHelper->localize($issue->getTitle());
|
||||
},
|
||||
'choice_label' => fn (SocialIssue $issue) => $this->translatableStringHelper->localize($issue->getTitle()),
|
||||
])
|
||||
->add('parent', EntityType::class, [
|
||||
'class' => SocialAction::class,
|
||||
'required' => false,
|
||||
'choice_label' => function (SocialAction $issue) {
|
||||
return $this->translatableStringHelper->localize($issue->getTitle());
|
||||
},
|
||||
'choice_label' => fn (SocialAction $issue) => $this->translatableStringHelper->localize($issue->getTitle()),
|
||||
])
|
||||
->add('ordering', NumberType::class, [
|
||||
'required' => true,
|
||||
@@ -70,9 +66,7 @@ class SocialActionType extends AbstractType
|
||||
'required' => false,
|
||||
'multiple' => true,
|
||||
'attr' => ['class' => 'select2'],
|
||||
'choice_label' => function (Result $r) {
|
||||
return $this->translatableStringHelper->localize($r->getTitle());
|
||||
},
|
||||
'choice_label' => fn (Result $r) => $this->translatableStringHelper->localize($r->getTitle()),
|
||||
])
|
||||
|
||||
->add('goals', EntityType::class, [
|
||||
@@ -80,9 +74,7 @@ class SocialActionType extends AbstractType
|
||||
'required' => false,
|
||||
'multiple' => true,
|
||||
'attr' => ['class' => 'select2'],
|
||||
'choice_label' => function (Goal $g) {
|
||||
return $this->translatableStringHelper->localize($g->getTitle());
|
||||
},
|
||||
'choice_label' => fn (Goal $g) => $this->translatableStringHelper->localize($g->getTitle()),
|
||||
])
|
||||
|
||||
->add('evaluations', EntityType::class, [
|
||||
@@ -90,9 +82,7 @@ class SocialActionType extends AbstractType
|
||||
'required' => false,
|
||||
'multiple' => true,
|
||||
'attr' => ['class' => 'select2'],
|
||||
'choice_label' => function (Evaluation $e) {
|
||||
return $this->translatableStringHelper->localize($e->getTitle());
|
||||
},
|
||||
'choice_label' => fn (Evaluation $e) => $this->translatableStringHelper->localize($e->getTitle()),
|
||||
])
|
||||
|
||||
->add('defaultNotificationDelay', DateIntervalType::class, [
|
||||
|
@@ -60,18 +60,14 @@ class ClosingMotivePickerType extends AbstractType
|
||||
'class' => ClosingMotive::class,
|
||||
'empty_data' => null,
|
||||
'placeholder' => 'Choose a motive',
|
||||
'choice_label' => function (ClosingMotive $cm) {
|
||||
return $this->entityRenderExtension->renderString($cm);
|
||||
},
|
||||
'choice_label' => fn (ClosingMotive $cm) => $this->entityRenderExtension->renderString($cm),
|
||||
'only_leaf' => true,
|
||||
]);
|
||||
|
||||
$resolver
|
||||
->setAllowedTypes('only_leaf', 'bool')
|
||||
->setNormalizer('choices', function (Options $options) {
|
||||
return $this->repository
|
||||
->getActiveClosingMotive($options['only_leaf']);
|
||||
});
|
||||
->setNormalizer('choices', fn (Options $options) => $this->repository
|
||||
->getActiveClosingMotive($options['only_leaf']));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -113,15 +113,11 @@ class PickPersonType extends AbstractType
|
||||
// add the default options
|
||||
$resolver->setDefaults([
|
||||
'class' => Person::class,
|
||||
'choice_label' => static function (Person $p) {
|
||||
return $p->getFirstname() . ' ' . $p->getLastname();
|
||||
},
|
||||
'choice_label' => static fn (Person $p) => $p->getFirstname() . ' ' . $p->getLastname(),
|
||||
'placeholder' => 'Pick a person',
|
||||
'choice_attr' => static function (Person $p) {
|
||||
return [
|
||||
'data-center' => $p->getCenter()->getId(),
|
||||
];
|
||||
},
|
||||
'choice_attr' => static fn (Person $p) => [
|
||||
'data-center' => $p->getCenter()->getId(),
|
||||
],
|
||||
'attr' => ['class' => 'select2 '],
|
||||
'choice_loader' => function (Options $options) {
|
||||
$centers = $this->filterCentersfom($options);
|
||||
@@ -139,9 +135,7 @@ class PickPersonType extends AbstractType
|
||||
protected function filterCentersfom(Options $options)
|
||||
{
|
||||
if (null === $options['role']) {
|
||||
$centers = array_map(static function (GroupCenter $g) {
|
||||
return $g->getCenter();
|
||||
}, $this->user->getGroupCenters()->toArray());
|
||||
$centers = array_map(static fn (GroupCenter $g) => $g->getCenter(), $this->user->getGroupCenters()->toArray());
|
||||
} else {
|
||||
$centers = $this->authorizationHelper
|
||||
->getReachableCenters($this->user, $options['role']->getRole());
|
||||
@@ -164,9 +158,7 @@ class PickPersonType extends AbstractType
|
||||
|
||||
if (
|
||||
!in_array($c->getId(), array_map(
|
||||
static function (Center $c) {
|
||||
return $c->getId();
|
||||
},
|
||||
static fn (Center $c) => $c->getId(),
|
||||
$centers
|
||||
), true)
|
||||
) {
|
||||
|
@@ -38,9 +38,7 @@ class PickSocialActionType extends AbstractType
|
||||
->setDefaults([
|
||||
'class' => SocialAction::class,
|
||||
'choices' => $this->actionRepository->findAllActive(),
|
||||
'choice_label' => function (SocialAction $sa) {
|
||||
return $this->actionRender->renderString($sa, []);
|
||||
},
|
||||
'choice_label' => fn (SocialAction $sa) => $this->actionRender->renderString($sa, []),
|
||||
'placeholder' => 'Pick a social action',
|
||||
'required' => false,
|
||||
'attr' => ['class' => 'select2'],
|
||||
|
@@ -38,9 +38,7 @@ class PickSocialIssueType extends AbstractType
|
||||
->setDefaults([
|
||||
'class' => SocialIssue::class,
|
||||
'choices' => $this->issueRepository->findAllActive(),
|
||||
'choice_label' => function (SocialIssue $si) {
|
||||
return $this->issueRender->renderString($si, []);
|
||||
},
|
||||
'choice_label' => fn (SocialIssue $si) => $this->issueRender->renderString($si, []),
|
||||
'placeholder' => 'Pick a social issue',
|
||||
'required' => false,
|
||||
'attr' => ['class' => 'select2'],
|
||||
|
@@ -40,13 +40,13 @@ class Select2MaritalStatusType extends AbstractType
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$transformer = new ObjectToIdTransformer($this->em, 'Chill\PersonBundle\Entity\MaritalStatus');
|
||||
$transformer = new ObjectToIdTransformer($this->em, \Chill\PersonBundle\Entity\MaritalStatus::class);
|
||||
$builder->addModelTransformer($transformer);
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$maritalStatuses = $this->em->getRepository('Chill\PersonBundle\Entity\MaritalStatus')->findAll();
|
||||
$maritalStatuses = $this->em->getRepository(\Chill\PersonBundle\Entity\MaritalStatus::class)->findAll();
|
||||
$choices = [];
|
||||
|
||||
foreach ($maritalStatuses as $ms) {
|
||||
|
@@ -168,7 +168,7 @@ class MembersEditor
|
||||
$criteria->where(
|
||||
$expr->andX(
|
||||
$expr->lt('startDate', $date),
|
||||
$expr->isNull('endDate', $date)
|
||||
$expr->isNull('endDate')
|
||||
)
|
||||
);
|
||||
|
||||
|
@@ -76,9 +76,7 @@ class PrivacyEventSubscriber implements EventSubscriberInterface
|
||||
$involved = $this->getInvolved();
|
||||
$involved['period_id'] = $event->getPeriod()->getId();
|
||||
$involved['persons'] = $event->getPeriod()->getPersons()
|
||||
->map(static function (Person $p) {
|
||||
return $p->getId();
|
||||
})
|
||||
->map(static fn (Person $p) => $p->getId())
|
||||
->toArray();
|
||||
|
||||
$this->logger->notice(
|
||||
@@ -102,9 +100,7 @@ class PrivacyEventSubscriber implements EventSubscriberInterface
|
||||
|
||||
if ($event->hasPersons()) {
|
||||
$involved['persons'] = array_map(
|
||||
static function (Person $p) {
|
||||
return $p->getId();
|
||||
},
|
||||
static fn (Person $p) => $p->getId(),
|
||||
$event->getPersons()
|
||||
);
|
||||
}
|
||||
|
@@ -0,0 +1,93 @@
|
||||
<?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\AccompanyingPeriod;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodInfo;
|
||||
use DateInterval;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use LogicException;
|
||||
use Symfony\Component\Clock\ClockInterface;
|
||||
|
||||
readonly class AccompanyingPeriodInfoRepository implements AccompanyingPeriodInfoRepositoryInterface
|
||||
{
|
||||
private EntityRepository $entityRepository;
|
||||
|
||||
public function __construct(
|
||||
private ClockInterface $clock,
|
||||
private EntityManagerInterface $em,
|
||||
) {
|
||||
$this->entityRepository = $em->getRepository($this->getClassName());
|
||||
}
|
||||
|
||||
public function findAccompanyingPeriodIdInactiveAfter(DateInterval $interval, array $statuses = []): array
|
||||
{
|
||||
$query = $this->em->createQuery();
|
||||
$baseDql = 'SELECT DISTINCT IDENTITY(ai.accompanyingPeriod) FROM '.AccompanyingPeriodInfo::class.' ai JOIN ai.accompanyingPeriod a WHERE NOT EXISTS
|
||||
(SELECT 1 FROM ' . AccompanyingPeriodInfo::class . ' aiz WHERE aiz.infoDate > :after AND IDENTITY(aiz.accompanyingPeriod) = IDENTITY(ai.accompanyingPeriod))';
|
||||
|
||||
if ([] !== $statuses) {
|
||||
$dql = $baseDql . ' AND a.step IN (:statuses)';
|
||||
$query->setParameter('statuses', $statuses);
|
||||
} else {
|
||||
$dql = $baseDql;
|
||||
}
|
||||
|
||||
return $query->setDQL($dql)
|
||||
->setParameter('after', $this->clock->now()->sub($interval))
|
||||
->getSingleColumnResult();
|
||||
}
|
||||
|
||||
public function findAccompanyingPeriodIdActiveSince(DateInterval $interval, array $statuses = []): array
|
||||
{
|
||||
$query = $this->em->createQuery();
|
||||
$baseDql = 'SELECT DISTINCT IDENTITY(ai.accompanyingPeriod) FROM ' . AccompanyingPeriodInfo::class . ' ai
|
||||
JOIN ai.accompanyingPeriod a WHERE ai.infoDate > :after';
|
||||
|
||||
if ([] !== $statuses) {
|
||||
$dql = $baseDql . ' AND a.step IN (:statuses)';
|
||||
$query->setParameter('statuses', $statuses);
|
||||
} else {
|
||||
$dql = $baseDql;
|
||||
}
|
||||
|
||||
return $query->setDQL($dql)
|
||||
->setParameter('after', $this->clock->now()->sub($interval))
|
||||
->getSingleColumnResult();
|
||||
}
|
||||
|
||||
public function find($id): ?AccompanyingPeriodInfo
|
||||
{
|
||||
throw new LogicException("Calling an accompanying period info by his id does not make sense");
|
||||
}
|
||||
|
||||
public function findAll(): array
|
||||
{
|
||||
return $this->entityRepository->findAll();
|
||||
}
|
||||
|
||||
public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array
|
||||
{
|
||||
return $this->entityRepository->findBy($criteria, $orderBy, $limit, $offset);
|
||||
}
|
||||
|
||||
public function findOneBy(array $criteria): ?AccompanyingPeriodInfo
|
||||
{
|
||||
return $this->entityRepository->findOneBy($criteria);
|
||||
}
|
||||
|
||||
public function getClassName(): string
|
||||
{
|
||||
return AccompanyingPeriodInfo::class;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
<?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\AccompanyingPeriod;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodInfo;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
|
||||
/**
|
||||
* @template-extends ObjectRepository<AccompanyingPeriodInfo>
|
||||
*/
|
||||
interface AccompanyingPeriodInfoRepositoryInterface extends ObjectRepository
|
||||
{
|
||||
/**
|
||||
* Return a list of id for inactive accompanying periods
|
||||
*
|
||||
* @param \DateInterval $interval
|
||||
* @param list<AccompanyingPeriod::STEP_*> $statuses
|
||||
* @return list<int>
|
||||
*/
|
||||
public function findAccompanyingPeriodIdInactiveAfter(\DateInterval $interval, array $statuses = []): array;
|
||||
|
||||
/**
|
||||
* @param \DateInterval $interval
|
||||
* @param list<AccompanyingPeriod::STEP_*> $statuses
|
||||
* @return list<int>
|
||||
*/
|
||||
public function findAccompanyingPeriodIdActiveSince(\DateInterval $interval, array $statuses = []): array;
|
||||
}
|
@@ -322,9 +322,7 @@ final class PersonACLAwareRepository implements PersonACLAwareRepositoryInterfac
|
||||
),
|
||||
]
|
||||
),
|
||||
array_map(static function (Center $c) {
|
||||
return $c->getId();
|
||||
}, $authorizedCenters)
|
||||
array_map(static fn (Center $c) => $c->getId(), $authorizedCenters)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -44,7 +44,7 @@ class ResidentialAddressRepository extends ServiceEntityRepository
|
||||
|
||||
public function buildQueryFindCurrentResidentialAddresses(Person $person, ?DateTimeImmutable $at = null): QueryBuilder
|
||||
{
|
||||
$date = null === $at ? new DateTimeImmutable('today') : $at;
|
||||
$date = $at ?? new DateTimeImmutable('today');
|
||||
$qb = $this->createQueryBuilder('ra');
|
||||
|
||||
$dateFilter = $qb->expr()->andX(
|
||||
|
@@ -14,7 +14,7 @@
|
||||
<scopes></scopes>
|
||||
<referrer></referrer>
|
||||
<resources></resources>
|
||||
<start-date v-if="accompanyingCourse.step === 'CONFIRMED'"></start-date>
|
||||
<start-date v-if="accompanyingCourse.step.startsWith('CONFIRMED')"></start-date>
|
||||
<comment v-if="accompanyingCourse.step === 'DRAFT'"></comment>
|
||||
<confirm v-if="accompanyingCourse.step === 'DRAFT'"></confirm>
|
||||
|
||||
|
@@ -11,12 +11,22 @@
|
||||
{{ $t('course.step.draft') }}
|
||||
</span>
|
||||
</span>
|
||||
<span v-else-if="accompanyingCourse.step === 'CONFIRMED'" class="text-md-end">
|
||||
<span class="d-md-block mb-md-3">
|
||||
<span v-else-if="accompanyingCourse.step === 'CONFIRMED' || accompanyingCourse.step === 'CONFIRMED_INACTIVE_SHORT' || accompanyingCourse.step === 'CONFIRMED_INACTIVE_LONG'" class="text-md-end">
|
||||
<span v-if="accompanyingCourse.step === 'CONFIRMED'" class="d-md-block mb-md-3">
|
||||
<span class="badge bg-primary">
|
||||
{{ $t('course.step.active') }}
|
||||
</span>
|
||||
</span>
|
||||
<span v-else-if="accompanyingCourse.step === 'CONFIRMED_INACTIVE_SHORT'" class="d-md-block mb-md-3">
|
||||
<span class="badge bg-chill-yellow text-primary">
|
||||
{{ $t('course.step.inactive_short') }}
|
||||
</span>
|
||||
</span>
|
||||
<span v-else-if="accompanyingCourse.step === 'CONFIRMED_INACTIVE_LONG'" class="d-md-block mb-md-3">
|
||||
<span class="badge bg-chill-pink">
|
||||
{{ $t('course.step.inactive_long') }}
|
||||
</span>
|
||||
</span>
|
||||
<span class="d-md-block">
|
||||
<span class="d-md-block ms-3 ms-md-0">
|
||||
<i>{{ $t('course.open_at') }}{{ $d(accompanyingCourse.openingDate.datetime, 'text') }}</i>
|
||||
|
@@ -21,7 +21,9 @@ const appMessages = {
|
||||
step: {
|
||||
draft: "Brouillon",
|
||||
active: "En file active",
|
||||
closed: "Cloturé"
|
||||
closed: "Cloturé",
|
||||
inactive_short: "Hors file active",
|
||||
inactive_long: "Pré-archivé",
|
||||
},
|
||||
open_at: "ouvert le ",
|
||||
by: "par ",
|
||||
|
@@ -52,11 +52,13 @@
|
||||
{% endif %}
|
||||
|
||||
{% if acp.step == 'DRAFT' %}
|
||||
<span class="badge bg-secondary" style="font-size: 85%;" title="{{ 'course.draft'|trans }}">{{ 'course.draft'|trans }}</span>
|
||||
{% endif %}
|
||||
|
||||
{% if acp.step == 'CLOSED' %}
|
||||
<span class="badge bg-danger" style="font-size: 85%;" title="{{ 'course.closed'|trans }}">{{ 'course.closed'|trans }}</span>
|
||||
<span class="badge bg-secondary" style="font-size: 85%;" title="{{ 'course.draft'|trans|e('html_attr') }}">{{ 'course.draft'|trans }}</span>
|
||||
{% elseif acp.step == 'CLOSED' %}
|
||||
<span class="badge bg-danger" style="font-size: 85%;" title="{{ 'course.closed'|trans|e('html_attr') }}">{{ 'course.closed'|trans }}</span>
|
||||
{% elseif acp.step == 'CONFIRMED_INACTIVE_SHORT' %}
|
||||
<span class="badge bg-chill-yellow text-primary" style="font-size: 85%;" title="{{ 'course.inactive_short'|trans|e('html_attr') }}">{{ 'course.inactive_short'|trans }}</span>
|
||||
{% elseif acp.step == 'CONFIRMED_INACTIVE_LONG' %}
|
||||
<span class="badge bg-danger" style="font-size: 85%;" title="{{ 'course.inactive_long'|trans|e('html_attr') }}">{{ 'course.inactive_long'|trans }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -173,7 +173,7 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getAdvancedSearchTitle()
|
||||
public function getAdvancedSearchTitle(): string
|
||||
{
|
||||
return 'Search within persons';
|
||||
}
|
||||
|
@@ -97,9 +97,7 @@ class HouseholdVoter extends Voter implements ProvideRoleHierarchyInterface, Chi
|
||||
|
||||
private function checkAssociatedMembersRole(Household $household, string $attribute): bool
|
||||
{
|
||||
foreach ($household->getCurrentMembers()->map(static function (HouseholdMember $member) {
|
||||
return $member->getPerson();
|
||||
}) as $person) {
|
||||
foreach ($household->getCurrentMembers()->map(static fn (HouseholdMember $member) => $member->getPerson()) as $person) {
|
||||
if ($this->security->isGranted($attribute, $person)) {
|
||||
return true;
|
||||
}
|
||||
|
@@ -150,12 +150,8 @@ class AccompanyingPeriodDocGenNormalizer implements ContextAwareNormalizerInterf
|
||||
$this->closingMotiveRender->renderString($period->getClosingMotive(), []) : '',
|
||||
'ref' => $this->normalizer->normalize($period->getUser(), $format, $userContext),
|
||||
'hasRef' => $period->getUser() !== null,
|
||||
'socialIssuesText' => implode(', ', array_map(function (SocialIssue $s) {
|
||||
return $this->socialIssueRender->renderString($s, []);
|
||||
}, $period->getSocialIssues()->toArray())),
|
||||
'scopesText' => implode(', ', array_map(function (Scope $s) {
|
||||
return $this->translatableStringHelper->localize($s->getName());
|
||||
}, $scopes)),
|
||||
'socialIssuesText' => implode(', ', array_map(fn (SocialIssue $s) => $this->socialIssueRender->renderString($s, []), $period->getSocialIssues()->toArray())),
|
||||
'scopesText' => implode(', ', array_map(fn (Scope $s) => $this->translatableStringHelper->localize($s->getName()), $scopes)),
|
||||
'hasRequestor' => $period->getRequestor() !== null,
|
||||
'requestorKind' => $period->getRequestorKind(),
|
||||
'hasLocation' => $period->getLocation() !== null,
|
||||
|
@@ -48,9 +48,7 @@ class AccompanyingPeriodWorkEvaluationNormalizer implements ContextAwareNormaliz
|
||||
$initial = $this->normalizer->normalize($object, $format, array_merge(
|
||||
$context,
|
||||
[self::IGNORE_EVALUATION => spl_object_hash($object)],
|
||||
[AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => static function ($object, $format, $context) {
|
||||
return $object->getId();
|
||||
}]
|
||||
[AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => static fn ($object, $format, $context) => $object->getId()]
|
||||
));
|
||||
|
||||
// due to bug: https://api-platform.com/docs/core/serialization/#collection-relation
|
||||
|
@@ -94,9 +94,7 @@ class PersonDocGenNormalizer implements
|
||||
// we simplify the list of attributes for the embedded persons
|
||||
AbstractNormalizer::GROUPS => ['docgen:read'],
|
||||
// when a person reference the same person... take care of circular references
|
||||
AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => function ($object, $format, $context) {
|
||||
return $this->normalizer->normalize(null, $format, $context);
|
||||
},
|
||||
AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => fn ($object, $format, $context) => $this->normalizer->normalize(null, $format, $context),
|
||||
]);
|
||||
|
||||
if (null === $person) {
|
||||
@@ -117,9 +115,7 @@ class PersonDocGenNormalizer implements
|
||||
'altNames' => implode(
|
||||
', ',
|
||||
array_map(
|
||||
static function (PersonAltName $altName) {
|
||||
return $altName->getLabel();
|
||||
},
|
||||
static fn (PersonAltName $altName) => $altName->getLabel(),
|
||||
$person->getAltNames()->toArray()
|
||||
)
|
||||
),
|
||||
|
@@ -257,12 +257,10 @@ class PersonJsonNormalizer implements DenormalizerAwareInterface, NormalizerAwar
|
||||
{
|
||||
return $altNames
|
||||
->map(
|
||||
static function (PersonAltName $personAltName): array {
|
||||
return [
|
||||
'key' => $personAltName->getKey(),
|
||||
'label' => $personAltName->getLabel(),
|
||||
];
|
||||
}
|
||||
static fn (PersonAltName $personAltName): array => [
|
||||
'key' => $personAltName->getKey(),
|
||||
'label' => $personAltName->getLabel(),
|
||||
]
|
||||
)
|
||||
->toArray();
|
||||
}
|
||||
|
@@ -37,9 +37,7 @@ class SocialIssueNormalizer implements ContextAwareNormalizerInterface, Normaliz
|
||||
'type' => 'social_issue',
|
||||
'id' => $socialIssue->getId(),
|
||||
'parent_id' => $socialIssue->hasParent() ? $socialIssue->getParent()->getId() : null,
|
||||
'children_ids' => $socialIssue->getChildren()->map(static function (SocialIssue $si) {
|
||||
return $si->getId();
|
||||
}),
|
||||
'children_ids' => $socialIssue->getChildren()->map(static fn (SocialIssue $si) => $si->getId()),
|
||||
'title' => $socialIssue->getTitle(),
|
||||
'text' => $this->render->renderString($socialIssue, []),
|
||||
];
|
||||
|
@@ -34,7 +34,7 @@ class OldDraftAccompanyingPeriodRemover implements OldDraftAccompanyingPeriodRem
|
||||
|
||||
public function remove(DateInterval $interval): void
|
||||
{
|
||||
$this->logger->debug('[' . __CLASS__ . '] start to remove old periods', [
|
||||
$this->logger->debug('[' . self::class . '] start to remove old periods', [
|
||||
'interval' => $interval->format('%d days'),
|
||||
]);
|
||||
|
||||
@@ -96,7 +96,7 @@ class OldDraftAccompanyingPeriodRemover implements OldDraftAccompanyingPeriodRem
|
||||
];
|
||||
});
|
||||
|
||||
$this->logger->info('[' . __CLASS__ . '] periods removed', array_merge($results, [
|
||||
$this->logger->info('[' . self::class . '] periods removed', array_merge($results, [
|
||||
'interval' => $interval->format('%d days'),
|
||||
]));
|
||||
}
|
||||
|
@@ -143,14 +143,10 @@ class AccompanyingPeriodContext implements
|
||||
->add('category', EntityType::class, [
|
||||
'placeholder' => 'Choose a document category',
|
||||
'class' => DocumentCategory::class,
|
||||
'query_builder' => static function (EntityRepository $er) {
|
||||
return $er->createQueryBuilder('c')
|
||||
->where('c.documentClass = :docClass')
|
||||
->setParameter('docClass', AccompanyingCourseDocument::class);
|
||||
},
|
||||
'choice_label' => function ($entity = null) {
|
||||
return $entity ? $this->translatableStringHelper->localize($entity->getName()) : '';
|
||||
},
|
||||
'query_builder' => static fn (EntityRepository $er) => $er->createQueryBuilder('c')
|
||||
->where('c.documentClass = :docClass')
|
||||
->setParameter('docClass', AccompanyingCourseDocument::class),
|
||||
'choice_label' => fn ($entity = null) => $entity ? $this->translatableStringHelper->localize($entity->getName()) : '',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -160,9 +156,7 @@ class AccompanyingPeriodContext implements
|
||||
public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, mixed $entity): void
|
||||
{
|
||||
$options = $template->getOptions();
|
||||
$persons = new ArrayCollection($entity->getCurrentParticipations()->map(static function (AccompanyingPeriodParticipation $p) {
|
||||
return $p->getPerson();
|
||||
})->toArray());
|
||||
$persons = new ArrayCollection($entity->getCurrentParticipations()->map(static fn (AccompanyingPeriodParticipation $p) => $p->getPerson())->toArray());
|
||||
|
||||
foreach ($entity->getCurrentParticipations() as $p) {
|
||||
foreach ($p->getPerson()->getResources() as $r) {
|
||||
@@ -187,9 +181,7 @@ class AccompanyingPeriodContext implements
|
||||
$builder->add($key, EntityType::class, [
|
||||
'class' => Person::class,
|
||||
'choices' => $persons,
|
||||
'choice_label' => function (Person $p) {
|
||||
return $this->personRender->renderString($p, ['addAge' => true]);
|
||||
},
|
||||
'choice_label' => fn (Person $p) => $this->personRender->renderString($p, ['addAge' => true]),
|
||||
'multiple' => false,
|
||||
'expanded' => true,
|
||||
'required' => false,
|
||||
|
@@ -63,9 +63,7 @@ class AccompanyingPeriodWorkEvaluationContext implements
|
||||
$this->accompanyingPeriodWorkContext->adminFormReverseTransform($data),
|
||||
[
|
||||
'evaluations' => array_map(
|
||||
static function (Evaluation $e) {
|
||||
return $e->getId();
|
||||
},
|
||||
static fn (Evaluation $e) => $e->getId(),
|
||||
$data['evaluations']
|
||||
),
|
||||
]
|
||||
@@ -78,9 +76,7 @@ class AccompanyingPeriodWorkEvaluationContext implements
|
||||
$this->accompanyingPeriodWorkContext->adminFormTransform($data),
|
||||
[
|
||||
'evaluations' => array_map(
|
||||
function ($id) {
|
||||
return $this->evaluationRepository->find($id);
|
||||
},
|
||||
fn ($id) => $this->evaluationRepository->find($id),
|
||||
$data['evaluations'] ?? []
|
||||
),
|
||||
]
|
||||
@@ -97,9 +93,7 @@ class AccompanyingPeriodWorkEvaluationContext implements
|
||||
'class' => Evaluation::class,
|
||||
'label' => 'Linked evaluations',
|
||||
'choices' => $this->evaluationRepository->findAll(),
|
||||
'choice_label' => function (Evaluation $e) {
|
||||
return $this->translatableStringHelper->localize($e->getTitle());
|
||||
},
|
||||
'choice_label' => fn (Evaluation $e) => $this->translatableStringHelper->localize($e->getTitle()),
|
||||
'multiple' => true,
|
||||
'attr' => ['class' => 'select2'],
|
||||
]);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user