Merge branch 'master' into 616_rapid-action

This commit is contained in:
2023-05-24 11:21:34 +02:00
2652 changed files with 82793 additions and 26335 deletions

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\AccompanyingPeriod\Events;
use Chill\MainBundle\Entity\Address;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\AccompanyingPeriod\Events;
use Chill\MainBundle\Entity\Notification;
@@ -62,6 +62,7 @@ class UserRefEventSubscriber implements EventSubscriberInterface
&& $period->getUser() !== $this->security->getUser()
&& null !== $period->getUser()
&& $period->getStep() !== AccompanyingPeriod::STEP_DRAFT
&& !$period->isPreventUserIsChangedNotification()
) {
$this->generateNotificationToUser($period);
}

View File

@@ -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)();
}
}

View File

@@ -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());
}
}

View File

@@ -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;
}
}

View File

@@ -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'));
}
}
}

View File

@@ -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
]);
}
}

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\AccompanyingPeriod\SocialIssueConsistency;
use Chill\PersonBundle\Entity\AccompanyingPeriod;

View File

@@ -1,19 +1,21 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\AccompanyingPeriod\SocialIssueConsistency;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PrePersistEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
/**
* This service listens for preUpdate and prePersist events on some entities
@@ -26,22 +28,22 @@ use Doctrine\ORM\Event\LifecycleEventArgs;
*/
final class AccompanyingPeriodSocialIssueConsistencyEntityListener
{
public function prePersist(AccompanyingPeriodLinkedWithSocialIssuesEntityInterface $entity, LifecycleEventArgs $eventArgs)
public function prePersist(AccompanyingPeriodLinkedWithSocialIssuesEntityInterface $entity, PrePersistEventArgs $eventArgs)
{
$this->ensureConsistencyEntity($entity);
}
public function prePersistAccompanyingPeriod(AccompanyingPeriod $period, LifecycleEventArgs $eventArgs)
public function prePersistAccompanyingPeriod(AccompanyingPeriod $period, PrePersistEventArgs $eventArgs)
{
$this->ensureConsistencyAccompanyingPeriod($period);
}
public function preUpdate(AccompanyingPeriodLinkedWithSocialIssuesEntityInterface $entity, LifecycleEventArgs $eventArgs)
public function preUpdate(AccompanyingPeriodLinkedWithSocialIssuesEntityInterface $entity, PreUpdateEventArgs $eventArgs)
{
$this->ensureConsistencyEntity($entity);
}
public function preUpdateAccompanyingPeriod(AccompanyingPeriod $period, LifecycleEventArgs $eventArgs)
public function preUpdateAccompanyingPeriod(AccompanyingPeriod $period, PreUpdateEventArgs $eventArgs)
{
$this->ensureConsistencyAccompanyingPeriod($period);
}

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\AccompanyingPeriod\Suggestion;
use Chill\MainBundle\Entity\User;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\AccompanyingPeriod\Suggestion;
use Chill\MainBundle\Entity\User;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Actions;
use Symfony\Component\EventDispatcher\Event;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Actions\Remove;
use Chill\PersonBundle\Actions\ActionEvent;
@@ -117,7 +117,7 @@ class PersonMove
$from->getId()
);
return $sqls ?? [];
return $sqls;
}
protected function createDeleteSQL(ClassMetadata $metadata, Person $from, $field): string

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\CRUD\Controller;
use Chill\MainBundle\CRUD\Controller\CRUDController;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\CRUD\Controller;
use BadMethodCallException;

View File

@@ -1,17 +1,18 @@
<?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.
*/
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');
}
}

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Command;
use Chill\PersonBundle\Actions\Remove\PersonMove;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Command;
use Chill\PersonBundle\Service\Import\ChillImporter;
@@ -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)

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Command;
use Chill\PersonBundle\Service\AccompanyingPeriod\OldDraftAccompanyingPeriodRemoverInterface;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Config;
/**

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;
@@ -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']]);

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\PersonBundle\Entity\AccompanyingPeriod;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\ActivityBundle\Entity\Activity;
@@ -177,7 +177,7 @@ class AccompanyingCourseController extends Controller
*/
public function editAction(AccompanyingPeriod $accompanyingCourse): Response
{
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $accompanyingCourse);
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::EDIT, $accompanyingCourse);
return $this->render('@ChillPerson/AccompanyingCourse/edit.html.twig', [
'accompanyingCourse' => $accompanyingCourse,
@@ -215,7 +215,7 @@ class AccompanyingCourseController extends Controller
// get persons without household
$withoutHousehold = [];
foreach ($accompanyingCourse->getParticipations() as $p) {
foreach ($accompanyingCourse->getCurrentParticipations() as $p) {
if (false === $p->getPerson()->isSharingHousehold()) {
$withoutHousehold[] = $p->getPerson();
}

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\Pagination\PaginatorFactory;
@@ -178,6 +178,27 @@ class AccompanyingCourseWorkController extends AbstractController
]);
}
/**
* @Route(
* "{_locale}/person/accompanying-period/work/{id}/show",
* name="chill_person_accompanying_period_work_show",
* methods={"GET"}
* )
*/
public function showWork(AccompanyingPeriodWork $work): Response
{
if (null === $work) {
throw $this->createNotFoundException('Unable to find Work entity.');
}
$this->denyAccessUnlessGranted(AccompanyingPeriodWorkVoter::SEE, $work);
return $this->render('@ChillPerson/AccompanyingCourseWork/show.html.twig', [
'accompanyingCourse' => $work->getAccompanyingPeriod(),
'work' => $work,
]);
}
private function createDeleteForm(int $id): Form
{
$params = [];

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
@@ -70,10 +70,10 @@ class AccompanyingPeriodController extends AbstractController
if ($person->isOpen() === false) {
$this->get('session')->getFlashBag()
->add('error', $this->get('translator')
->trans(
'Beware period is closed',
['%name%' => $person->__toString()]
));
->trans(
'Beware period is closed',
['%name%' => $person->__toString()]
));
return $this->redirect(
$this->generateUrl('chill_person_accompanying_period_list', [
@@ -99,9 +99,9 @@ class AccompanyingPeriodController extends AbstractController
if (count($errors) === 0) {
$this->get('session')->getFlashBag()
->add('success', $this->get('translator')
->trans('An accompanying period has been closed.', [
'%name%' => $person->__toString(),
]));
->trans('An accompanying period has been closed.', [
'%name%' => $person->__toString(),
]));
$this->getDoctrine()->getManager()->flush();
@@ -113,7 +113,7 @@ class AccompanyingPeriodController extends AbstractController
}
$this->get('session')->getFlashBag()
->add('error', $this->get('translator')
->trans('Error! Period not closed!'));
->trans('Error! Period not closed!'));
foreach ($errors as $error) {
$this->get('session')->getFlashBag()
@@ -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,
@@ -251,10 +247,10 @@ class AccompanyingPeriodController extends AbstractController
if ($person->isOpen()) {
$this->get('session')->getFlashBag()
->add('error', $this->get('translator')
->trans(
'Error! Period %name% is not closed ; it can be open',
['%name%' => $person->__toString()]
));
->trans(
'Error! Period %name% is not closed ; it can be open',
['%name%' => $person->__toString()]
));
return $this->redirect(
$this->generateUrl('chill_person_accompanying_period_list', [
@@ -285,10 +281,10 @@ class AccompanyingPeriodController extends AbstractController
if (count($errors) <= 0) {
$this->get('session')->getFlashBag()
->add('success', $this->get('translator')
->trans(
'An accompanying period has been opened.',
['%name%' => $person->__toString()]
));
->trans(
'An accompanying period has been opened.',
['%name%' => $person->__toString()]
));
$this->getDoctrine()->getManager()->flush();
@@ -300,7 +296,7 @@ class AccompanyingPeriodController extends AbstractController
}
$this->get('session')->getFlashBag()
->add('error', $this->get('translator')
->trans('Period not opened'));
->trans('Period not opened'));
foreach ($errors as $error) {
$this->get('session')->getFlashBag()
@@ -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) {

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\Entity\Location;
@@ -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()) {

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\CRUDController;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\Pagination\PaginatorFactory;
@@ -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');

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;

View File

@@ -0,0 +1,26 @@
<?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\Controller;
use Chill\MainBundle\CRUD\Controller\CRUDController;
use Chill\MainBundle\Pagination\PaginatorInterface;
use Symfony\Component\HttpFoundation\Request;
class HouseholdCompositionTypeController extends CRUDController
{
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator)
{
$query->addOrderBy('e.id', 'ASC');
return parent::orderQuery($action, $query, $request, $paginator);
}
}

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\Entity\Address;
@@ -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 = [];

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\CRUDController;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\CRUDController;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\CRUDController;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\Entity\Address;

View File

@@ -1,24 +1,25 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Chill\PersonBundle\Security\AuthorizedCenterOnPersonCreationInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
@@ -26,16 +27,37 @@ use function in_array;
class PersonApiController extends ApiController
{
private AuthorizationHelper $authorizationHelper;
private AuthorizedCenterOnPersonCreationInterface $authorizedCenterOnPersonCreation;
private ConfigPersonAltNamesHelper $configPersonAltNameHelper;
private bool $showCenters;
public function __construct(
AuthorizationHelper $authorizationHelper,
ConfigPersonAltNamesHelper $configPersonAltNameHelper
AuthorizedCenterOnPersonCreationInterface $authorizedCenterOnPersonCreation,
ConfigPersonAltNamesHelper $configPersonAltNameHelper,
ParameterBagInterface $parameterBag
) {
$this->authorizationHelper = $authorizationHelper;
$this->authorizedCenterOnPersonCreation = $authorizedCenterOnPersonCreation;
$this->configPersonAltNameHelper = $configPersonAltNameHelper;
$this->showCenters = $parameterBag->get('chill_main')['acl']['form_show_centers'];
}
/**
* @Route("/api/1.0/person/creation/authorized-centers",
* name="chill_person_person_creation_authorized_centers"
* )
*/
public function authorizedCentersForCreation(): Response
{
$centers = $this->authorizedCenterOnPersonCreation->getCenters();
return $this->json(
['showCenters' => $this->showCenters, 'centers' => $centers],
Response::HTTP_OK,
[],
['gropus' => ['read']]
);
}
/**
@@ -86,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.

View File

@@ -1,16 +1,18 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
use Chill\PersonBundle\Entity\Household\Household;
use Chill\PersonBundle\Entity\Household\HouseholdMember;
@@ -20,6 +22,7 @@ use Chill\PersonBundle\Form\PersonType;
use Chill\PersonBundle\Privacy\PrivacyEvent;
use Chill\PersonBundle\Repository\PersonRepository;
use Chill\PersonBundle\Search\SimilarPersonMatcher;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use DateTimeImmutable;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
@@ -44,6 +47,8 @@ use function is_array;
final class PersonController extends AbstractController
{
private AuthorizationHelperInterface $authorizationHelper;
/**
* @var ConfigPersonAltNamesHelper
*/
@@ -85,6 +90,7 @@ final class PersonController extends AbstractController
private $validator;
public function __construct(
AuthorizationHelperInterface $authorizationHelper,
SimilarPersonMatcher $similarPersonMatcher,
TranslatorInterface $translator,
EventDispatcherInterface $eventDispatcher,
@@ -93,8 +99,8 @@ final class PersonController extends AbstractController
LoggerInterface $logger,
ValidatorInterface $validator,
EntityManagerInterface $em,
Security $security
) {
$this->authorizationHelper = $authorizationHelper;
$this->similarPersonMatcher = $similarPersonMatcher;
$this->translator = $translator;
$this->eventDispatcher = $eventDispatcher;
@@ -103,7 +109,6 @@ final class PersonController extends AbstractController
$this->logger = $logger;
$this->validator = $validator;
$this->em = $em;
$this->security = $security;
}
public function editAction($person_id, Request $request)
@@ -160,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();
@@ -204,22 +209,15 @@ final class PersonController extends AbstractController
*
* The next post compare the data with previous one and, if yes, show a
* review page if there are "alternate persons".
*
* @return Response|\Symfony\Component\HttpFoundation\RedirectResponse
*/
public function newAction(Request $request)
public function newAction(Request $request): Response
{
$person = new Person();
if (
1 === count($this->security->getUser()
->getGroupCenters())
) {
$person->setCenter(
$this->security->getUser()
->getGroupCenters()[0]
->getCenter()
);
$authorizedCenters =$this->authorizationHelper->getReachableCenters($this->getUser(), PersonVoter::CREATE);
if (1 === count($authorizedCenters)) {
$person->setCenter($authorizedCenters[0]);
}
$form = $this->createForm(CreationPersonType::class, $person)

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\ActivityBundle\Entity\Activity;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\PersonBundle\Entity\Person\PersonResource;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\CRUDController;

View File

@@ -1,17 +1,19 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\Entity\PostalCode;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Form\Type\PickPostalCodeType;
use Chill\MainBundle\Form\Type\PickUserDynamicType;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Repository\UserRepository;
@@ -92,12 +94,15 @@ class ReassignAccompanyingPeriodController extends AbstractController
$form->handleRequest($request);
$userFrom = $form['user']->getData();
$postalCodes = $form['postal_code']->getData() instanceof PostalCode ? [$form['postal_code']->getData()] : [];
$total = $this->accompanyingPeriodACLAwareRepository->countByUserOpenedAccompanyingPeriod($userFrom);
$paginator = $this->paginatorFactory->create($total);
$paginator->setItemsPerPage(50);
$periods = $this->accompanyingPeriodACLAwareRepository
->findByUserOpenedAccompanyingPeriod(
->findByUserAndPostalCodesOpenedAccompanyingPeriod(
$userFrom,
$postalCodes,
['openingDate' => 'ASC'],
$paginator->getItemsPerPage(),
$paginator->getCurrentPageFirstItemNumber()
@@ -115,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();
@@ -123,7 +128,7 @@ class ReassignAccompanyingPeriodController extends AbstractController
$period = $this->courseRepository->find($periodId);
if ($period->getUser() === $userFrom) {
$period->setUser($userTo);
$period->setUser($userTo, true);
}
}
@@ -148,7 +153,9 @@ class ReassignAccompanyingPeriodController extends AbstractController
{
$data = [
'user' => null,
'postal_code' => null,
];
$builder = $this->formFactory->createBuilder(FormType::class, $data, [
'method' => 'get', 'csrf_protection' => false, ]);
@@ -158,16 +165,21 @@ class ReassignAccompanyingPeriodController extends AbstractController
'label' => 'reassign.Current user',
'required' => false,
'help' => 'reassign.Choose a user and click on "Filter" to apply',
])
->add('postal_code', PickPostalCodeType::class, [
'label' => 'reassign.Filter by postal code',
'required' => false,
'help' => 'reassign.Filter course which are located inside a postal code',
]);
return $builder->getForm();
}
private function buildReassignForm(array $periodIds, ?User $userFrom): FormInterface
private function buildReassignForm(array $periodIds, ?User $userFrom = null): FormInterface
{
$defaultData = [
'userFrom' => $userFrom,
'periods' => json_encode($periodIds),
'periods' => json_encode($periodIds, JSON_THROW_ON_ERROR),
];
$builder = $this->formFactory->createNamedBuilder('reassign', FormType::class, $defaultData);

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\CRUDController;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\PersonBundle\Entity\Person;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller\SocialWork;
use Chill\MainBundle\CRUD\Controller\CRUDController;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller\SocialWork;
use Chill\MainBundle\CRUD\Controller\CRUDController;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller\SocialWork;
use Chill\MainBundle\CRUD\Controller\CRUDController;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller\SocialWork;
use Chill\MainBundle\CRUD\Controller\CRUDController;

View File

@@ -1,22 +1,37 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller\SocialWork;
use Chill\MainBundle\CRUD\Controller\CRUDController;
use Chill\MainBundle\Pagination\PaginatorInterface;
use LogicException;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
class SocialIssueController extends CRUDController
{
protected function createFormFor(string $action, $entity, ?string $formClass = null, array $formOptions = []): FormInterface
{
if ('new' === $action) {
return parent::createFormFor($action, $entity, $formClass, ['step' => 'create']);
}
if ('edit' === $action) {
return parent::createFormFor($action, $entity, $formClass, ['step' => 'edit']);
}
throw new LogicException('action is not supported: ' . $action);
}
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator)
{
$query->addOrderBy('e.ordering', 'ASC');

View File

@@ -1,18 +1,19 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Serializer\Model\Collection;
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@@ -39,9 +40,11 @@ class SocialWorkEvaluationApiController extends AbstractController
*/
public function listEvaluationBySocialAction(SocialAction $action): Response
{
$pagination = $this->paginatorFactory->create($action->getEvaluations()->count());
$evaluations = $action->getEvaluations()->filter(static fn (Evaluation $eval) => $eval->isActive());
$evaluations = $action->getEvaluations()->slice(
$pagination = $this->paginatorFactory->create($evaluations->count());
$evaluations = $evaluations->slice(
$pagination->getCurrentPageFirstItemNumber(),
$pagination->getItemsPerPage()
);

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;

View File

@@ -1,19 +1,20 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Serializer\Model\Collection;
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
@@ -41,7 +42,10 @@ class SocialWorkSocialActionApiController extends ApiController
throw $this->createNotFoundException('socialIssue not found');
}
$socialActions = $socialIssue->getRecursiveSocialActions();
$socialActions = $socialIssue->getRecursiveSocialActions()->toArray();
usort($socialActions, static fn (SocialAction $sa, SocialAction $sb) => $sa->getOrdering() <=> $sb->getOrdering());
$pagination = $this->paginator->create(count($socialActions));
// max one page
$pagination->setItemsPerPage(count($socialActions));

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\Pagination\PaginatorFactory;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\Pagination\PaginatorFactory;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\DataFixtures\Helper;
use Chill\PersonBundle\Entity\Person;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\DataFixtures\Helper;
use Chill\PersonBundle\Entity\Person;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\MainBundle\DataFixtures\ORM\LoadAbstractNotificationsTrait;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Origin;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\PersonBundle\Entity\AccompanyingPeriod;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\CustomFieldsBundle\CustomFields\CustomFieldChoice;
@@ -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),
]);

View File

@@ -1,21 +1,23 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\MainBundle\DataFixtures\ORM\LoadCenters;
use Chill\MainBundle\DataFixtures\ORM\LoadPostalCodes;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Entity\PostalCode;
use Chill\PersonBundle\Entity\Household\Household;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\Person\PersonCenterHistory;
use Chill\PersonBundle\Household\MembersEditorFactory;
use DateInterval;
use DateTime;
@@ -192,14 +194,20 @@ class LoadHousehold extends Fixture implements DependentFixtureInterface
private function preparePersonIds()
{
$centers = LoadCenters::$centers;
// @TODO: Remove this and make this service stateless
$this->personIds = $this->em
->createQuery(
'SELECT p.id FROM ' . Person::class . ' p ' .
'JOIN p.center c ' .
'WHERE c.name = :center '
'WHERE EXISTS( ' .
'SELECT 1 FROM ' . PersonCenterHistory::class . ' pch ' .
'JOIN pch.center c ' .
'WHERE pch.person = p.id ' .
'AND c.name IN (:authorized_centers)' .
')'
)
->setParameter('center', 'Center A')
->setParameter('authorized_centers', $centers)
->getScalarResult();
shuffle($this->personIds);

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\PersonBundle\Entity\Household\HouseholdCompositionType;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\PersonBundle\Entity\Household\Position;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\PersonBundle\Entity\MaritalStatus;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\MainBundle\DataFixtures\ORM\LoadPostalCodes;
@@ -407,6 +407,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
private function createExpectedPerson($default): Person
{
/** @var Person $person */
$person = $this->loader->loadData([
Person::class => [
'person' => [
@@ -439,10 +440,15 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
break;
case 'countryOfBirth':
$country = $this->countryRepository
->findOneBy(['countryCode' => $value]);
$person->setCountryOfBirth($country);
break;
case 'nationality':
$country = $this->countryRepository
->findOneBy(['countryCode' => $value]);
$person->{'set' . ucfirst($key)}($country);
$person->setNationality($country);
break;
@@ -484,42 +490,6 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
return $this->getReference($ref);
}
/**
* Create a random address.
*
* @return Address
*/
private function getRandomAddress()
{
return (new Address())
->setStreetAddress1($this->faker->streetAddress)
->setStreetAddress2(
mt_rand(0, 9) > 5 ? $this->faker->streetAddress : ''
)
->setPoint(
mt_rand(0, 9) > 5 ? $this->getRandomPoint() : null
)
->setPostcode($this->getReference(
LoadPostalCodes::$refs[array_rand(LoadPostalCodes::$refs)]
))
->setValidFrom($this->faker->dateTimeBetween('-5 years'));
}
/**
* Create a random point.
*
* @return Point
*/
private function getRandomPoint()
{
$lonBrussels = 4.35243;
$latBrussels = 50.84676;
$lon = $lonBrussels + 0.01 * mt_rand(-5, 5);
$lat = $latBrussels + 0.01 * mt_rand(-5, 5);
return Point::fromLonLat($lon, $lat);
}
private function getRandomSocialIssue(): SocialIssue
{
if (0 === count($this->cacheSocialIssues)) {

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\MainBundle\DataFixtures\ORM\LoadPermissionsGroup;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\PersonBundle\Entity\Relationships\Relation;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\MainBundle\DataFixtures\ORM\LoadUsers;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\PersonBundle\Service\Import\SocialWorkMetadata;

View File

@@ -1,20 +1,21 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\DependencyInjection;
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;
@@ -75,7 +76,6 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../config'));
$loader->load('services.yaml');
$loader->load('services/widgets.yaml');
$loader->load('services/exports.yaml');
$loader->load('services/fixtures.yaml');
$loader->load('services/controller.yaml');
$loader->load('services/search.yaml');
@@ -95,9 +95,15 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
$loader->load('services/doctrineEventListener.yaml');
$loader->load('services/accompanyingPeriodConsistency.yaml');
$loader->load('services/exports_person.yaml');
if ($container->getParameter('chill_person.accompanying_period') !== 'hidden') {
$loader->load('services/exports_accompanying_period.yaml');
$loader->load('services/exports_accompanying_course.yaml');
$loader->load('services/exports_social_actions.yaml');
$loader->load('services/exports_evaluation.yaml');
}
$loader->load('services/exports_household.yaml');
}
/**
@@ -227,6 +233,27 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
],
],
],
[
'class' => \Chill\PersonBundle\Entity\Household\HouseholdCompositionType::class,
'name' => 'person_household_composition_type',
'base_path' => '/admin/person/household/composition-type',
'form_class' => \Chill\PersonBundle\Form\HouseholdCompositionTypeType::class,
'controller' => \Chill\PersonBundle\Controller\HouseholdCompositionTypeController::class,
'actions' => [
'index' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/HouseholdCompositionType/index.html.twig',
],
'new' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/HouseholdCompositionType/new.html.twig',
],
'edit' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/HouseholdCompositionType/edit.html.twig',
],
],
],
[
'class' => \Chill\PersonBundle\Entity\Relationships\Relation::class,
'name' => 'person_relation',
@@ -918,10 +945,8 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
/**
* Add a widget "add a person" on the homepage, automatically.
*
* @param \Chill\PersonBundle\DependencyInjection\containerBuilder $container
*/
protected function prependHomepageWidget(containerBuilder $container)
protected function prependHomepageWidget(ContainerBuilder $container)
{
$container->prependExtensionConfig('chill_main', [
'widgets' => [
@@ -982,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,
],
],
],
@@ -1019,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'],
],
]
);

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\DependencyInjection\CompilerPass;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\DependencyInjection;
use DateInterval;
@@ -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,8 +128,17 @@ 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
;
;
return $treeBuilder;
}
@@ -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':

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Doctrine\DQL;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Entity;
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
@@ -22,6 +22,7 @@ use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Entity\UserJob;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodLocationHistory;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodStepHistory;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
@@ -41,6 +42,7 @@ use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\ReadableCollection;
use Doctrine\ORM\Mapping as ORM;
use Iterator;
use LogicException;
@@ -52,7 +54,7 @@ use Symfony\Component\Validator\GroupSequenceProviderInterface;
use UnexpectedValueException;
use function in_array;
use function array_key_exists;
use const SORT_REGULAR;
/**
@@ -107,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".
*
@@ -129,6 +149,11 @@ class AccompanyingPeriod implements
*/
private ?Location $administrativeLocation = null;
/**
* @ORM\OneToMany(targetEntity="Chill\CalendarBundle\Entity\Calendar", mappedBy="accompanyingPeriod")
*/
private Collection $calendars;
/**
* @var DateTime
*
@@ -265,6 +290,8 @@ class AccompanyingPeriod implements
*/
private ?Comment $pinnedComment = null;
private bool $preventUserIsChangedNotification = false;
/**
* @ORM\Column(type="text")
* @Groups({"read", "write"})
@@ -331,9 +358,16 @@ class AccompanyingPeriod implements
/**
* @ORM\Column(type="string", length=32, nullable=true)
* @Groups({"read"})
* @var AccompanyingPeriod::STEP_*
*/
private string $step = self::STEP_DRAFT;
/**
* @ORM\OneToMany(targetEntity=AccompanyingPeriodStepHistory::class,
* mappedBy="period", cascade={"persist", "remove"}, orphanRemoval=true)
*/
private Collection $stepHistories;
/**
* @ORM\Column(type="datetime", nullable=true, options={"default": NULL})
*/
@@ -388,7 +422,7 @@ class AccompanyingPeriod implements
*/
public function __construct(?DateTime $dateOpening = null)
{
$this->setOpeningDate($dateOpening ?? new DateTime('now'));
$this->calendars = new ArrayCollection(); // TODO we cannot add a dependency between AccompanyingPeriod and calendars
$this->participations = new ArrayCollection();
$this->scopes = new ArrayCollection();
$this->socialIssues = new ArrayCollection();
@@ -397,6 +431,8 @@ class AccompanyingPeriod implements
$this->resources = new ArrayCollection();
$this->userHistories = new ArrayCollection();
$this->locationHistories = new ArrayCollection();
$this->stepHistories = new ArrayCollection();
$this->setOpeningDate($dateOpening ?? new DateTime('now'));
}
/**
@@ -599,9 +635,9 @@ class AccompanyingPeriod implements
/**
* Get a list of person which have an adresse available for a valid location.
*
* @return Collection|Person[]
* @return ReadableCollection<(int|string), Person>
*/
public function getAvailablePersonLocation(): Collection
public function getAvailablePersonLocation(): ReadableCollection
{
return $this->getOpenParticipations()
->filter(
@@ -612,6 +648,11 @@ class AccompanyingPeriod implements
);
}
public function getCalendars(): Collection
{
return $this->calendars;
}
public function getCenter(): ?Center
{
if ($this->getPersons()->count() === 0) {
@@ -623,16 +664,18 @@ class AccompanyingPeriod implements
public function getCenters(): ?iterable
{
$centers = [];
foreach ($this->getPersons() as $person) {
if (
!in_array($person->getCenter(), $centers ?? [], true)
&& null !== $person->getCenter()
null !== $person->getCenter()
&& !array_key_exists(spl_object_hash($person->getCenter()), $centers)
) {
$centers[] = $person->getCenter();
$centers[spl_object_hash($person->getCenter())] = $person->getCenter();
}
}
return $centers ?? null;
return array_values($centers);
}
/**
@@ -652,8 +695,9 @@ class AccompanyingPeriod implements
/**
* @Groups({"read"})
* @return ReadableCollection<(int|string), Comment>
*/
public function getComments(): Collection
public function getComments(): ReadableCollection
{
$pinnedComment = $this->pinnedComment;
@@ -677,7 +721,7 @@ class AccompanyingPeriod implements
/**
* @Groups({"docgen:read"})
*/
public function getCurrentParticipations(): Collection
public function getCurrentParticipations(): ReadableCollection
{
return $this->getOpenParticipations();
}
@@ -687,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]];
}
@@ -765,6 +807,24 @@ class AccompanyingPeriod implements
return 'none';
}
public function getNextCalendarsForPerson(Person $person, $limit = 5): Collection
{
$today = new DateTimeImmutable('today');
$criteria = Criteria::create()
->where(Criteria::expr()->gte('startDate', $today))
//->andWhere(Criteria::expr()->memberOf('persons', $person))
->orderBy(['startDate' => 'DESC'])
->setMaxResults($limit * 2);
return $this->calendars->matching($criteria)
->matching(
// due to a bug, filter two times
Criteria::create()
->where(Criteria::expr()->memberOf('persons', $person))
->setMaxResults($limit)
);
}
/**
* Get openingDate.
*
@@ -785,22 +845,21 @@ 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;
}
public function getOpenParticipations(): Collection
/**
* @return ReadableCollection<(int|string), AccompanyingPeriodParticipation>
*/
public function getOpenParticipations(): ReadableCollection
{
return $this
->getParticipations()
->filter(
static function (AccompanyingPeriodParticipation $participation): bool {
return null === $participation->getEndDate();
}
static fn (AccompanyingPeriodParticipation $participation): bool => null === $participation->getEndDate()
);
}
@@ -819,8 +878,9 @@ class AccompanyingPeriod implements
/**
* Get the participation containing a person.
* @return ReadableCollection<(int|string), AccompanyingPeriodParticipation>
*/
public function getParticipationsContainsPerson(Person $person): Collection
public function getParticipationsContainsPerson(Person $person): ReadableCollection
{
return $this
->getParticipations()
@@ -840,7 +900,7 @@ class AccompanyingPeriod implements
/**
* Get a list of all persons which are participating to this course.
*
* @psalm-return Collection<int, Person>
* @psalm-return Collection<(int|string), Person|null>
*/
public function getPersons(): Collection
{
@@ -964,6 +1024,11 @@ class AccompanyingPeriod implements
return $this->step;
}
public function getStepHistories(): Collection
{
return $this->stepHistories;
}
public function getUser(): ?User
{
return $this->user;
@@ -1048,6 +1113,11 @@ class AccompanyingPeriod implements
return false;
}
public function isPreventUserIsChangedNotification(): bool
{
return $this->preventUserIsChangedNotification;
}
public function isRequestorAnonymous(): bool
{
return $this->requestorAnonymous;
@@ -1104,7 +1174,7 @@ class AccompanyingPeriod implements
public function removeWork(AccompanyingPeriodWork $work): self
{
$this->work->removeElement($work);
$this->works->removeElement($work);
$work->setAccompanyingPeriod(null);
return $this;
@@ -1227,7 +1297,11 @@ class AccompanyingPeriod implements
*/
public function setOpeningDate($openingDate)
{
$this->openingDate = $openingDate;
if ($this->openingDate !== $openingDate) {
$this->openingDate = $openingDate;
$this->ensureStepContinuity();
}
return $this;
}
@@ -1326,6 +1400,14 @@ class AccompanyingPeriod implements
$this->bootPeriod();
}
if (self::STEP_DRAFT !== $this->step && $previous !== $step) {
// we create a new history
$history = new AccompanyingPeriodStepHistory();
$history->setStep($this->step)->setStartDate(new DateTimeImmutable('now'));
$this->addStepHistory($history);
}
return $this;
}
@@ -1343,11 +1425,12 @@ class AccompanyingPeriod implements
return $this;
}
public function setUser(?User $user): self
public function setUser(?User $user, bool $preventNotification = false): self
{
if ($this->user !== $user) {
$this->userPrevious = $this->user;
$this->userIsChanged = true;
$this->preventUserIsChangedNotification = $preventNotification;
foreach ($this->userHistories as $history) {
if (null === $history->getEndDate()) {
@@ -1365,6 +1448,17 @@ class AccompanyingPeriod implements
return $this;
}
private function addStepHistory(AccompanyingPeriodStepHistory $stepHistory): self
{
if (!$this->stepHistories->contains($stepHistory)) {
$this->stepHistories[] = $stepHistory;
$stepHistory->setPeriod($this);
$this->ensureStepContinuity();
}
return $this;
}
private function bootPeriod(): void
{
// first location history
@@ -1376,6 +1470,43 @@ class AccompanyingPeriod implements
$this->addLocationHistory($locationHistory);
}
private function ensureStepContinuity(): void
{
// ensure continuity of histories
$criteria = new Criteria();
$criteria->orderBy(['startDate' => Criteria::ASC, 'id' => Criteria::ASC]);
/** @var Iterator $steps */
$steps = $this->getStepHistories()->matching($criteria)->getIterator();
$steps->rewind();
// we set the start date of the first step as the opening date, only if it is
// not greater than the end date
/** @var AccompanyingPeriodStepHistory $current */
$current = $steps->current();
if (null === $current) {
return;
}
if ($this->getOpeningDate()->format('Y-m-d') !== $current->getStartDate()->format('Y-m-d')
&& ($this->getOpeningDate() <= $current->getEndDate() || null === $current->getEndDate())) {
$current->setStartDate(DateTimeImmutable::createFromMutable($this->getOpeningDate()));
}
// then we set all the end date to the start date of the next one
do {
/** @var AccompanyingPeriodStepHistory $current */
$current = $steps->current();
$steps->next();
if ($steps->valid()) {
$next = $steps->current();
$current->setEndDate($next->getStartDate());
}
} while ($steps->valid());
}
private function setRequestorPerson(?Person $requestorPerson = null): self
{
$this->requestorPerson = $requestorPerson;

View File

@@ -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,
) {
}
}

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;

View File

@@ -0,0 +1,115 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
use Chill\MainBundle\Doctrine\Model\TrackCreationTrait;
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
use Chill\MainBundle\Doctrine\Model\TrackUpdateTrait;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
use DateTimeImmutable;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table("chill_person_accompanying_period_step_history")
*/
class AccompanyingPeriodStepHistory implements TrackCreationInterface, TrackUpdateInterface
{
use TrackCreationTrait;
use TrackUpdateTrait;
/**
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
*/
private ?DateTimeImmutable $endDate = null;
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private ?int $id = null;
/**
* @ORM\ManyToOne(targetEntity=AccompanyingPeriod::class)
*/
private AccompanyingPeriod $period;
/**
* @ORM\Column(type="date_immutable")
*/
private ?DateTimeImmutable $startDate = null;
/**
* @ORM\Column(type="text", nullable=false)
*/
private string $step;
public function getEndDate(): ?DateTimeImmutable
{
return $this->endDate;
}
public function getId(): ?int
{
return $this->id;
}
public function getPeriod(): AccompanyingPeriod
{
return $this->period;
}
public function getStartDate(): ?DateTimeImmutable
{
return $this->startDate;
}
public function getStep(): string
{
return $this->step;
}
public function setEndDate(?DateTimeImmutable $endDate): self
{
$this->endDate = $endDate;
return $this;
}
/**
* @internal use AccompanyingPeriod::addLocationHistory
*/
public function setPeriod(AccompanyingPeriod $period): self
{
$this->period = $period;
return $this;
}
public function setStartDate(?DateTimeImmutable $startDate): self
{
$this->startDate = $startDate;
return $this;
}
public function setStep(string $step): AccompanyingPeriodStepHistory
{
$this->step = $step;
return $this;
}
}

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
@@ -94,8 +94,8 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
* @Serializer\Groups({"accompanying_period_work:create"})
* @Serializer\Groups({"accompanying_period_work:edit"})
* @Serializer\Groups({"read", "docgen:read", "read:accompanyingPeriodWork:light"})
* @Assert\GreaterThan(propertyPath="startDate",
* message="accompanying_course_work.The endDate should be greater than the start date"
* @Assert\GreaterThanOrEqual(propertyPath="startDate",
* message="accompanying_course_work.The endDate should be greater or equal than the start date"
* )
*/
private ?DateTimeImmutable $endDate = null;

View File

@@ -1,14 +1,14 @@
<?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.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
@@ -160,6 +160,14 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU
*/
private ?DateInterval $warningInterval = null;
/**
* @ORM\Column(type="integer", nullable=true)
* @Serializer\Groups({"read", "docgen:read"})
* @Serializer\Groups({"write"})
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
*/
private ?int $timeSpent = null;
public function __construct()
{
$this->documents = new ArrayCollection();
@@ -265,6 +273,11 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU
return $this->warningInterval;
}
public function getTimeSpent(): ?int
{
return $this->timeSpent;
}
public function removeDocument(AccompanyingPeriodWorkEvaluationDocument $document): self
{
$this->documents->removeElement($document);
@@ -322,6 +335,13 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU
return $this;
}
public function setTimeSpent(?int $timeSpent): self
{
$this->timeSpent = $timeSpent;
return $this;
}
public function setEvaluation(?Evaluation $evaluation): AccompanyingPeriodWorkEvaluation
{
if (

Some files were not shown because too many files have changed in this diff Show More