mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-29 10:05:03 +00:00
Merge branch 'refs/heads/master' into ticket-app-master
# Conflicts: # composer.json # config/bundles.php # config/packages/doctrine_migrations_chill.yaml # package.json # src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadUserGroup.php # src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php # src/Bundle/ChillMainBundle/Entity/UserGroup.php # src/Bundle/ChillMainBundle/Resources/public/chill/js/date.ts # src/Bundle/ChillMainBundle/Resources/public/lib/download-report/download-report.js # src/Bundle/ChillMainBundle/Resources/public/module/ckeditor5/editor_config.ts # src/Bundle/ChillMainBundle/Resources/public/module/ckeditor5/index.ts # src/Bundle/ChillMainBundle/Resources/public/page/export/download-export.js # src/Bundle/ChillMainBundle/Resources/public/types.ts # src/Bundle/ChillMainBundle/Resources/views/Dev/dev.assets.html.twig # src/Bundle/ChillMainBundle/Templating/Entity/UserGroupRender.php # src/Bundle/ChillMainBundle/chill.api.specs.yaml # src/Bundle/ChillMainBundle/chill.webpack.config.js # src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Comment.vue # src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/PersonsAssociated.vue # src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Resources.vue # src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Resources/WriteComment.vue # src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue # src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue # src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/components/Household.vue # src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/components/MemberDetails.vue # src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/components/PersonComment.vue # src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/AddPersons.vue # src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/Entity/PersonRenderBox.vue # src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/Entity/PersonText.vue # src/Bundle/ChillPersonBundle/Resources/public/vuejs/_js/i18n.ts # tests/app/config/bootstrap.php
This commit is contained in:
@@ -26,7 +26,7 @@ readonly class AccompanyingPeriodStepChangeCronjob implements CronJobInterface
|
||||
{
|
||||
$now = $this->clock->now();
|
||||
|
||||
if (null !== $cronJobExecution && $now->sub(new \DateInterval('P1D')) < $cronJobExecution->getLastStart()) {
|
||||
if (null !== $cronJobExecution && $now->sub(new \DateInterval('PT23H45M')) < $cronJobExecution->getLastStart()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -51,7 +51,7 @@ class ActionEvent extends \Symfony\Contracts\EventDispatcher\Event
|
||||
/**
|
||||
* an array of key value data to describe the movement.
|
||||
*/
|
||||
protected $metadata = []
|
||||
protected $metadata = [],
|
||||
) {}
|
||||
|
||||
/**
|
||||
|
@@ -32,7 +32,7 @@ class PersonMove
|
||||
public function __construct(
|
||||
private readonly EntityManagerInterface $em,
|
||||
private readonly PersonMoveManager $personMoveManager,
|
||||
private readonly EventDispatcherInterface $eventDispatcher
|
||||
private readonly EventDispatcherInterface $eventDispatcher,
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -201,7 +201,7 @@ class PersonMove
|
||||
private function getDeleteEntities(): array
|
||||
{
|
||||
return [
|
||||
AccompanyingPeriod\AccompanyingPeriodWork::class,
|
||||
// AccompanyingPeriod\AccompanyingPeriodWork::class,
|
||||
Relationship::class,
|
||||
];
|
||||
}
|
||||
@@ -216,7 +216,7 @@ class PersonMove
|
||||
}
|
||||
|
||||
/**
|
||||
* get the full table name with schema if it does exists.
|
||||
* get the full table name with schema if it exists.
|
||||
*/
|
||||
private function getTableName(ClassMetadata $metadata): string
|
||||
{
|
||||
|
@@ -23,7 +23,16 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
*/
|
||||
class EntityPersonCRUDController extends CRUDController
|
||||
{
|
||||
public function __construct(private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry) {}
|
||||
public function __construct(protected readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry) {}
|
||||
|
||||
protected function generateTemplateParameter(string $action, mixed $entity, Request $request, array $defaultTemplateParameters = [])
|
||||
{
|
||||
$templateParameters = parent::generateTemplateParameter($action, $entity, $request, $defaultTemplateParameters);
|
||||
|
||||
$templateParameters['person'] = $this->getPerson($request);
|
||||
|
||||
return $templateParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the base method to add a filtering step to a person.
|
||||
@@ -66,25 +75,6 @@ class EntityPersonCRUDController extends CRUDController
|
||||
return $qb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function generateTemplateParameter(string $action, $entity, Request $request, array $defaultTemplateParameters = []): array
|
||||
{
|
||||
$person = $this->getPerson($request);
|
||||
|
||||
if (null === $person) {
|
||||
throw new \Exception('the `person_id` parameter is not set in the query. You should set it or override the current method to allow another behaviour: '.__METHOD__);
|
||||
}
|
||||
|
||||
return parent::generateTemplateParameter(
|
||||
$action,
|
||||
$entity,
|
||||
$request,
|
||||
\array_merge(['person' => $person], $defaultTemplateParameters)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the person from the request.
|
||||
*
|
||||
|
@@ -28,7 +28,7 @@ final class ChillPersonMoveCommand extends Command
|
||||
public function __construct(
|
||||
private readonly PersonMove $mover,
|
||||
private readonly EntityManagerInterface $em,
|
||||
private readonly LoggerInterface $chillLogger
|
||||
private readonly LoggerInterface $chillLogger,
|
||||
) {
|
||||
parent::__construct('chill:person:move');
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@ final class ImportSocialWorkMetadata extends Command
|
||||
protected EntityManagerInterface $em;
|
||||
|
||||
public function __construct(
|
||||
protected SocialWorkMetadataInterface $importer
|
||||
protected SocialWorkMetadataInterface $importer,
|
||||
) {
|
||||
parent::__construct('chill:person:import-socialwork');
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@ class ConfigPersonAltNamesHelper
|
||||
/**
|
||||
* the raw config, directly from the container parameter.
|
||||
*/
|
||||
private $config
|
||||
private $config,
|
||||
) {}
|
||||
|
||||
/**
|
||||
|
@@ -25,7 +25,7 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
||||
use Chill\PersonBundle\Privacy\AccompanyingPeriodPrivacyEvent;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepository;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriodRepository;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
@@ -46,7 +46,7 @@ use Symfony\Component\Workflow\Registry;
|
||||
|
||||
final class AccompanyingCourseApiController extends ApiController
|
||||
{
|
||||
public function __construct(private readonly AccompanyingPeriodRepository $accompanyingPeriodRepository, private readonly AccompanyingPeriodACLAwareRepository $accompanyingPeriodACLAwareRepository, private readonly EventDispatcherInterface $eventDispatcher, private readonly ReferralsSuggestionInterface $referralAvailable, private readonly Registry $registry, private readonly ValidatorInterface $validator, private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry) {}
|
||||
public function __construct(private readonly AccompanyingPeriodRepository $accompanyingPeriodRepository, private readonly EventDispatcherInterface $eventDispatcher, private readonly ReferralsSuggestionInterface $referralAvailable, private readonly Registry $registry, private readonly ValidatorInterface $validator, private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry, private readonly AccompanyingPeriodWorkRepository $accompanyingPeriodWorkRepository) {}
|
||||
|
||||
public function commentApi($id, Request $request, string $_format): Response
|
||||
{
|
||||
@@ -305,6 +305,20 @@ final class AccompanyingCourseApiController extends ApiController
|
||||
return $this->json($accompanyingCourse->getIntensity(), Response::HTTP_OK, [], ['groups' => ['read']]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ParamConverter("accompanyingPeriod", options={"id": "id"})
|
||||
*/
|
||||
#[Route(path: '/api/1.0/person/accompanying-course/{id}/works.json', name: 'chill_api_person_accompanying_period_works')]
|
||||
public function worksByAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): JsonResponse
|
||||
{
|
||||
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $accompanyingPeriod);
|
||||
|
||||
$works = $this->accompanyingPeriodWorkRepository->findBy(['accompanyingPeriod' => $accompanyingPeriod]);
|
||||
dump($works);
|
||||
|
||||
return $this->json($works, Response::HTTP_OK, [], ['groups' => ['read']]);
|
||||
}
|
||||
|
||||
public function workApi($id, Request $request, string $_format): Response
|
||||
{
|
||||
return $this->addRemoveSomething(
|
||||
|
@@ -109,11 +109,10 @@ final class AccompanyingCourseController extends \Symfony\Bundle\FrameworkBundle
|
||||
'accompanying_period_id' => $accompanyingCourse->getId(),
|
||||
'person_id' => $person_id,
|
||||
]))
|
||||
->setMethod('DELETE')
|
||||
->add('submit', SubmitType::class, ['label' => 'Delete'])
|
||||
->getForm();
|
||||
|
||||
if (Request::METHOD_DELETE === $request->getMethod()) {
|
||||
if (Request::METHOD_POST === $request->getMethod()) {
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isValid()) {
|
||||
@@ -205,20 +204,24 @@ final class AccompanyingCourseController extends \Symfony\Bundle\FrameworkBundle
|
||||
['date' => 'DESC', 'id' => 'DESC'],
|
||||
);
|
||||
|
||||
$activities = \array_slice($activities, 0, 3);
|
||||
|
||||
$works = $this->workRepository->findByAccompanyingPeriod(
|
||||
$accompanyingCourse,
|
||||
['startDate' => 'DESC', 'endDate' => 'DESC'],
|
||||
3
|
||||
);
|
||||
|
||||
$counters = [
|
||||
'activities' => count($activities),
|
||||
'openWorks' => count($accompanyingCourse->getOpenWorks()),
|
||||
'works' => count($works),
|
||||
];
|
||||
|
||||
return $this->render('@ChillPerson/AccompanyingCourse/index.html.twig', [
|
||||
'accompanyingCourse' => $accompanyingCourse,
|
||||
'withoutHousehold' => $withoutHousehold,
|
||||
'participationsByHousehold' => $accompanyingCourse->actualParticipationsByHousehold(),
|
||||
'works' => $works,
|
||||
'activities' => $activities,
|
||||
'works' => \array_slice($works, 0, 3),
|
||||
'activities' => \array_slice($activities, 0, 3),
|
||||
'counters' => $counters,
|
||||
]);
|
||||
}
|
||||
|
||||
|
@@ -11,7 +11,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Controller;
|
||||
|
||||
use Chill\DocStoreBundle\Serializer\Normalizer\StoredObjectNormalizer;
|
||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||
use Chill\MainBundle\Templating\Listing\FilterOrderHelper;
|
||||
use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactoryInterface;
|
||||
@@ -41,7 +40,7 @@ final class AccompanyingCourseWorkController extends AbstractController
|
||||
private readonly LoggerInterface $chillLogger,
|
||||
private readonly TranslatableStringHelperInterface $translatableStringHelper,
|
||||
private readonly FilterOrderHelperFactoryInterface $filterOrderHelperFactory,
|
||||
private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry
|
||||
private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry,
|
||||
) {}
|
||||
|
||||
#[Route(path: '{_locale}/person/accompanying-period/{id}/work/new', name: 'chill_person_accompanying_period_work_new', methods: ['GET'])]
|
||||
@@ -80,10 +79,10 @@ final class AccompanyingCourseWorkController extends AbstractController
|
||||
|
||||
$form = $this->createDeleteForm($work->getId());
|
||||
|
||||
if (Request::METHOD_DELETE === $request->getMethod()) {
|
||||
if (Request::METHOD_POST === $request->getMethod()) {
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isValid()) {
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$this->chillLogger->notice('An accompanying period work has been removed', [
|
||||
'by_user' => $this->getUser()->getUsername(),
|
||||
'work_id' => $work->getId(),
|
||||
@@ -116,7 +115,7 @@ final class AccompanyingCourseWorkController extends AbstractController
|
||||
{
|
||||
$this->denyAccessUnlessGranted(AccompanyingPeriodWorkVoter::UPDATE, $work);
|
||||
|
||||
$json = $this->serializer->normalize($work, 'json', ['groups' => ['read', StoredObjectNormalizer::ADD_DAV_EDIT_LINK_CONTEXT]]);
|
||||
$json = $this->serializer->normalize($work, 'json', ['groups' => ['read']]);
|
||||
|
||||
return $this->render('@ChillPerson/AccompanyingCourseWork/edit.html.twig', [
|
||||
'accompanyingCourse' => $work->getAccompanyingPeriod(),
|
||||
@@ -179,7 +178,6 @@ final class AccompanyingCourseWorkController extends AbstractController
|
||||
|
||||
return $this->createFormBuilder()
|
||||
->setAction($this->generateUrl('chill_person_accompanying_period_work_delete', $params))
|
||||
->setMethod('DELETE')
|
||||
->add('submit', SubmitType::class, ['label' => 'Delete'])
|
||||
->getForm();
|
||||
}
|
||||
|
@@ -39,7 +39,7 @@ class AccompanyingPeriodController extends AbstractController
|
||||
private readonly EventDispatcherInterface $eventDispatcher,
|
||||
private readonly ValidatorInterface $validator,
|
||||
private readonly TranslatorInterface $translator,
|
||||
private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry
|
||||
private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry,
|
||||
) {}
|
||||
|
||||
/**
|
||||
|
@@ -0,0 +1,81 @@
|
||||
<?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\Routing\ChillUrlGeneratorInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkVoter;
|
||||
use Chill\PersonBundle\Service\AccompanyingPeriodWorkEvaluationDocument\AccompanyingPeriodWorkEvaluationDocumentDuplicator;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
|
||||
class AccompanyingPeriodWorkEvaluationDocumentDuplicateController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly AccompanyingPeriodWorkEvaluationDocumentDuplicator $duplicator,
|
||||
private readonly Security $security,
|
||||
private readonly SerializerInterface $serializer,
|
||||
private readonly EntityManagerInterface $entityManager,
|
||||
private readonly ChillUrlGeneratorInterface $urlGenerator,
|
||||
) {}
|
||||
|
||||
#[Route('/api/1.0/person/accompanying-course-work-evaluation-document/{id}/duplicate', methods: ['POST'])]
|
||||
public function duplicateApi(AccompanyingPeriodWorkEvaluationDocument $document): Response
|
||||
{
|
||||
$work = $document->getAccompanyingPeriodWorkEvaluation()->getAccompanyingPeriodWork();
|
||||
|
||||
if (!$this->security->isGranted(AccompanyingPeriodWorkVoter::UPDATE, $work)) {
|
||||
throw new AccessDeniedHttpException('not allowed to edit this accompanying period work');
|
||||
}
|
||||
|
||||
$duplicatedDocument = $this->duplicator->duplicate($document);
|
||||
|
||||
$this->entityManager->persist($duplicatedDocument);
|
||||
$this->entityManager->persist($duplicatedDocument->getStoredObject());
|
||||
$this->entityManager->flush();
|
||||
|
||||
return new JsonResponse(
|
||||
$this->serializer->serialize($duplicatedDocument, 'json', [AbstractNormalizer::GROUPS => ['read']]),
|
||||
json: true
|
||||
);
|
||||
}
|
||||
|
||||
#[Route('/{_locale}/person/accompanying-course-work-evaluation-document/{id}/duplicate', name: 'chill_person_accompanying_period_work_evaluation_document_duplicate', methods: ['POST'])]
|
||||
public function duplicate(AccompanyingPeriodWorkEvaluationDocument $document): Response
|
||||
{
|
||||
$work = $document->getAccompanyingPeriodWorkEvaluation()->getAccompanyingPeriodWork();
|
||||
|
||||
if (!$this->security->isGranted(AccompanyingPeriodWorkVoter::UPDATE, $work)) {
|
||||
throw new AccessDeniedHttpException('not allowed to edit this accompanying period work');
|
||||
}
|
||||
|
||||
$duplicatedDocument = $this->duplicator->duplicate($document);
|
||||
|
||||
$this->entityManager->persist($duplicatedDocument);
|
||||
$this->entityManager->persist($duplicatedDocument->getStoredObject());
|
||||
$this->entityManager->flush();
|
||||
|
||||
return new RedirectResponse(
|
||||
$this->urlGenerator->forwardReturnPath(
|
||||
'chill_person_accompanying_period_work_edit',
|
||||
['id' => $work->getId(), 'doc_id' => $duplicatedDocument->getId()]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@@ -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 AdministrativeStatusController extends CRUDController
|
||||
{
|
||||
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator)
|
||||
{
|
||||
$query->addOrderBy('e.order', 'ASC');
|
||||
|
||||
return parent::orderQuery($action, $query, $request, $paginator);
|
||||
}
|
||||
}
|
@@ -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 EmploymentStatusController extends CRUDController
|
||||
{
|
||||
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator)
|
||||
{
|
||||
$query->addOrderBy('e.order', 'ASC');
|
||||
|
||||
return parent::orderQuery($action, $query, $request, $paginator);
|
||||
}
|
||||
}
|
@@ -43,7 +43,7 @@ class HouseholdCompositionController extends AbstractController
|
||||
private readonly EntityManagerInterface $entityManager,
|
||||
private readonly TranslatorInterface $translator,
|
||||
private readonly \Twig\Environment $engine,
|
||||
private readonly UrlGeneratorInterface $urlGenerator
|
||||
private readonly UrlGeneratorInterface $urlGenerator,
|
||||
) {}
|
||||
|
||||
#[Route(path: '/{_locale}/person/household/{household_id}/composition/{composition_id}/delete', name: 'chill_person_household_composition_delete')]
|
||||
@@ -63,11 +63,10 @@ class HouseholdCompositionController extends AbstractController
|
||||
'composition_id' => $composition_id,
|
||||
'household_id' => $household_id,
|
||||
]))
|
||||
->setMethod('DELETE')
|
||||
->add('submit', SubmitType::class, ['label' => 'Delete'])
|
||||
->getForm();
|
||||
|
||||
if (Request::METHOD_DELETE === $request->getMethod()) {
|
||||
if (Request::METHOD_POST === $request->getMethod()) {
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isValid()) {
|
||||
|
@@ -33,9 +33,12 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use Symfony\Component\Serializer\Exception;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
|
||||
class HouseholdMemberController extends ApiController
|
||||
{
|
||||
private array $household_fields_visibility;
|
||||
|
||||
public function __construct(
|
||||
private readonly UrlGeneratorInterface $generator,
|
||||
private readonly TranslatorInterface $translator,
|
||||
@@ -45,7 +48,10 @@ class HouseholdMemberController extends ApiController
|
||||
private readonly Security $security,
|
||||
private readonly PositionRepository $positionRepository,
|
||||
private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry,
|
||||
) {}
|
||||
protected ParameterBagInterface $parameterBag,
|
||||
) {
|
||||
$this->household_fields_visibility = $parameterBag->get('chill_person.household_fields');
|
||||
}
|
||||
|
||||
#[Route(path: '/{_locale}/person/household/member/{id}/edit', name: 'chill_person_household_member_edit')]
|
||||
public function editMembership(Request $request, HouseholdMember $member): Response
|
||||
@@ -144,6 +150,7 @@ class HouseholdMemberController extends ApiController
|
||||
'allowHouseholdCreate' => $allowHouseholdCreate ?? true,
|
||||
'allowHouseholdSearch' => $allowHouseholdSearch ?? true,
|
||||
'allowLeaveWithoutHousehold' => $allowLeaveWithoutHousehold ?? $request->query->has('allow_leave_without_household'),
|
||||
'displayDependents' => ('visible' == $this->household_fields_visibility['number_of_dependents']) ? true : false,
|
||||
];
|
||||
|
||||
// context
|
||||
|
@@ -31,7 +31,7 @@ class PersonApiController extends ApiController
|
||||
public function __construct(
|
||||
private readonly AuthorizedCenterOnPersonCreationInterface $authorizedCenterOnPersonCreation,
|
||||
private readonly ConfigPersonAltNamesHelper $configPersonAltNameHelper,
|
||||
ParameterBagInterface $parameterBag
|
||||
ParameterBagInterface $parameterBag,
|
||||
) {
|
||||
$this->showCenters = $parameterBag->get('chill_main')['acl']['form_show_centers'];
|
||||
}
|
||||
|
@@ -29,6 +29,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use function count;
|
||||
|
||||
class PersonDuplicateController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController
|
||||
@@ -40,6 +41,7 @@ class PersonDuplicateController extends \Symfony\Bundle\FrameworkBundle\Controll
|
||||
private readonly EventDispatcherInterface $eventDispatcher,
|
||||
private readonly Security $security,
|
||||
private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry,
|
||||
private readonly TranslatorInterface $translator,
|
||||
) {}
|
||||
|
||||
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/person/{person1_id}/duplicate/{person2_id}/confirm', name: 'chill_person_duplicate_confirm')]
|
||||
@@ -125,7 +127,14 @@ class PersonDuplicateController extends \Symfony\Bundle\FrameworkBundle\Controll
|
||||
$person2 = $form->get('person')->getData();
|
||||
|
||||
if (null === $person2) {
|
||||
throw $this->createNotFoundException("Person with id {$person2->getId}() not".' found on this server');
|
||||
throw $this->createNotFoundException('Person not found on this server');
|
||||
}
|
||||
|
||||
// Validation: Ensure person1 is not the same as person2
|
||||
if ($person->getId() === $person2->getId()) {
|
||||
$this->addFlash('error', $this->translator->trans('Person1 cannot be the same as Person2'));
|
||||
|
||||
return $this->redirectToRoute('chill_person_duplicate_view', ['person_id' => $person2->getId()]);
|
||||
}
|
||||
|
||||
$direction = $form->get('direction')->getData();
|
||||
|
@@ -44,14 +44,13 @@ final class PersonResourceController extends AbstractController
|
||||
'resource_id' => $resource_id,
|
||||
'person_id' => $person_id,
|
||||
]))
|
||||
->setMethod('DELETE')
|
||||
->add('submit', SubmitType::class, ['label' => 'Delete'])
|
||||
->getForm();
|
||||
|
||||
if (Request::METHOD_DELETE === $request->getMethod()) {
|
||||
if (Request::METHOD_POST === $request->getMethod()) {
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isValid()) {
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$this->em->remove($resource);
|
||||
$this->em->flush();
|
||||
|
||||
|
@@ -0,0 +1,60 @@
|
||||
<?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\Repository\Workflow\EntityWorkflowStepSignatureACLAwareRepository;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowManager;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class PersonSignatureController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly EntityWorkflowStepSignatureACLAwareRepository $signatureRepository,
|
||||
private readonly EntityWorkflowManager $entityWorkflowManager,
|
||||
) {}
|
||||
|
||||
#[Route(path: '/{_locale}/signatures/by-person/{id}', name: 'chill_person_signature_list')]
|
||||
public function listSignatures(Person $person): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(PersonVoter::SEE, $person);
|
||||
|
||||
$signatures = $this->signatureRepository->findByPersonAndPendingState($person);
|
||||
$signatureData = [];
|
||||
|
||||
foreach ($signatures as $signature) {
|
||||
$entityWorkflow = $signature->getStep()->getEntityWorkflow();
|
||||
$handler = $this->entityWorkflowManager->getHandler($entityWorkflow);
|
||||
|
||||
$workflow = [
|
||||
'handler_template' => $handler->getTemplate($entityWorkflow),
|
||||
'handler_template_data' => $handler->getTemplateData($entityWorkflow),
|
||||
'entity_workflow' => $entityWorkflow,
|
||||
];
|
||||
|
||||
$storedObject = $this->entityWorkflowManager->getAssociatedStoredObject($entityWorkflow);
|
||||
$signatureData[] = [
|
||||
'signature' => $signature,
|
||||
'document' => $storedObject,
|
||||
'workflow' => $workflow,
|
||||
];
|
||||
}
|
||||
|
||||
return $this->render('@ChillPerson/Person/signature_list.html.twig', [
|
||||
'signatures' => $signatureData,
|
||||
'person' => $person,
|
||||
]);
|
||||
}
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
<?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\PersonBundle\Repository\SocialWork\SocialActionRepository;
|
||||
use Chill\PersonBundle\Service\SocialWork\SocialActionCSVExportService;
|
||||
use League\Csv\CannotInsertRecord;
|
||||
use League\Csv\Exception;
|
||||
use League\Csv\UnavailableStream;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
class SocialActionCSVExportController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly SocialActionRepository $socialActionRepository,
|
||||
private readonly Security $security,
|
||||
private readonly SocialActionCSVExportService $socialActionCSVExportService,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @throws UnavailableStream
|
||||
* @throws CannotInsertRecord
|
||||
* @throws Exception
|
||||
*/
|
||||
#[Route(path: '/{_locale}/admin/social-work/social-action/export/list.{_format}', name: 'chill_person_social_action_export_list', requirements: ['_format' => 'csv'])]
|
||||
public function socialActionList(Request $request, string $_format = 'csv'): StreamedResponse
|
||||
{
|
||||
if (!$this->security->isGranted('ROLE_ADMIN')) {
|
||||
throw new AccessDeniedHttpException('Only ROLE_ADMIN can export this list');
|
||||
}
|
||||
|
||||
$actions = $this->socialActionRepository->findAllOrdered();
|
||||
|
||||
$csv = $this->socialActionCSVExportService->generateCsv($actions);
|
||||
|
||||
return new StreamedResponse(
|
||||
function () use ($csv) {
|
||||
foreach ($csv->chunk(1024) as $chunk) {
|
||||
echo $chunk;
|
||||
flush();
|
||||
}
|
||||
},
|
||||
Response::HTTP_OK,
|
||||
[
|
||||
'Content-Encoding' => 'none',
|
||||
'Content-Type' => 'text/csv; charset=UTF-8',
|
||||
'Content-Disposition' => 'attachment; filename=results.csv',
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
<?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\PersonBundle\Repository\SocialWork\SocialIssueRepository;
|
||||
use Chill\PersonBundle\Service\SocialWork\SocialIssueCSVExportService;
|
||||
use League\Csv\CannotInsertRecord;
|
||||
use League\Csv\Exception;
|
||||
use League\Csv\UnavailableStream;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
class SocialIssueCSVExportController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly SocialIssueRepository $socialIssueRepository,
|
||||
private readonly Security $security,
|
||||
private readonly SocialIssueCSVExportService $socialIssueCSVExportService,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @throws UnavailableStream
|
||||
* @throws CannotInsertRecord
|
||||
* @throws Exception
|
||||
*/
|
||||
#[Route(path: '/{_locale}/admin/social-work/social-issue/export/list.{_format}', name: 'chill_person_social_issue_export_list', requirements: ['_format' => 'csv'])]
|
||||
public function socialIssueList(Request $request, string $_format = 'csv'): StreamedResponse
|
||||
{
|
||||
if (!$this->security->isGranted('ROLE_ADMIN')) {
|
||||
throw new AccessDeniedHttpException('Only ROLE_ADMIN can export this list');
|
||||
}
|
||||
|
||||
$socialIssues = $this->socialIssueRepository->findAllOrdered();
|
||||
|
||||
$csv = $this->socialIssueCSVExportService->generateCsv($socialIssues);
|
||||
|
||||
return new StreamedResponse(
|
||||
function () use ($csv) {
|
||||
foreach ($csv->chunk(1024) as $chunk) {
|
||||
echo $chunk;
|
||||
flush();
|
||||
}
|
||||
},
|
||||
Response::HTTP_OK,
|
||||
[
|
||||
'Content-Encoding' => 'none',
|
||||
'Content-Type' => 'text/csv; charset=UTF-8',
|
||||
'Content-Disposition' => 'attachment; users.csv',
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
@@ -11,46 +11,97 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Controller;
|
||||
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||
use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactoryInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepository;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriodRepository;
|
||||
use Doctrine\ORM\NonUniqueResultException;
|
||||
use Doctrine\ORM\NoResultException;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class UserAccompanyingPeriodController extends AbstractController
|
||||
{
|
||||
public function __construct(private readonly AccompanyingPeriodRepository $accompanyingPeriodRepository, private readonly PaginatorFactory $paginatorFactory) {}
|
||||
public function __construct(
|
||||
private readonly AccompanyingPeriodRepository $accompanyingPeriodRepository,
|
||||
private readonly PaginatorFactory $paginatorFactory,
|
||||
private readonly AccompanyingPeriodACLAwareRepository $accompanyingPeriodACLAwareRepository,
|
||||
private readonly FilterOrderHelperFactoryInterface $filterOrderHelperFactory,
|
||||
private readonly TranslatorInterface $translator,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @throws NonUniqueResultException
|
||||
* @throws NoResultException
|
||||
*/
|
||||
#[Route(path: '/{_locale}/person/accompanying-periods/my', name: 'chill_person_accompanying_period_user')]
|
||||
public function listAction(Request $request): Response
|
||||
{
|
||||
$active = $request->query->getBoolean('active', true);
|
||||
$steps = match ($active) {
|
||||
true => [
|
||||
$filter = (int) $request->query->get('filter', 2);
|
||||
$user = $this->getUser();
|
||||
|
||||
if (!$user instanceof User) {
|
||||
throw new \LogicException('Expected an instance of Chill\MainBundle\Entity\User.');
|
||||
}
|
||||
|
||||
$activeTab = match ($filter) {
|
||||
2 => 'referrer',
|
||||
4 => 'referrer_to_works',
|
||||
6 => 'both',
|
||||
8 => 'intervening',
|
||||
default => 'referrer',
|
||||
};
|
||||
|
||||
$statusAndDateFilter = $this->buildStatusAndDateFilter($filter);
|
||||
|
||||
$status = $statusAndDateFilter->getCheckboxData('statusFilter');
|
||||
$from = null;
|
||||
$to = null;
|
||||
|
||||
if ('intervening' === $activeTab) {
|
||||
$interventionBetweenDates = $statusAndDateFilter->getDateRangeData('interventionBetweenDates');
|
||||
$from = $interventionBetweenDates['from'];
|
||||
$to = $interventionBetweenDates['to'];
|
||||
}
|
||||
|
||||
$steps = [];
|
||||
|
||||
if (in_array('is_open', $status, true)) {
|
||||
$steps[] = [
|
||||
...$steps,
|
||||
AccompanyingPeriod::STEP_CONFIRMED,
|
||||
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG,
|
||||
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT,
|
||||
],
|
||||
false => [
|
||||
AccompanyingPeriod::STEP_CLOSED,
|
||||
]
|
||||
};
|
||||
];
|
||||
}
|
||||
|
||||
$total = $this->accompanyingPeriodRepository->countBy(['user' => $this->getUser(), 'step' => $steps]);
|
||||
$pagination = $this->paginatorFactory->create($total);
|
||||
$accompanyingPeriods = $this->accompanyingPeriodRepository->findBy(
|
||||
['user' => $this->getUser(), 'step' => $steps],
|
||||
['openingDate' => 'DESC'],
|
||||
$pagination->getItemsPerPage(),
|
||||
$pagination->getCurrentPageFirstItemNumber()
|
||||
if (in_array('is_closed', $status, true)) {
|
||||
$steps[] = AccompanyingPeriod::STEP_CLOSED;
|
||||
}
|
||||
|
||||
$total = $this->accompanyingPeriodACLAwareRepository->countByUserAssociation($user, $steps, $from, $to, $filter);
|
||||
$paginator = $this->paginatorFactory->create($total);
|
||||
$accompanyingPeriods = $this->accompanyingPeriodACLAwareRepository->findByUserAssociation(
|
||||
$user,
|
||||
$steps,
|
||||
$from,
|
||||
$to,
|
||||
$filter,
|
||||
$paginator->getCurrentPageFirstItemNumber(),
|
||||
$paginator->getItemsPerPage(),
|
||||
);
|
||||
|
||||
return $this->render('@ChillPerson/AccompanyingPeriod/user_periods_list.html.twig', [
|
||||
'accompanyingPeriods' => $accompanyingPeriods,
|
||||
'pagination' => $pagination,
|
||||
'active' => $active,
|
||||
'pagination' => $paginator,
|
||||
'activeTab' => $activeTab,
|
||||
'filter' => $filter,
|
||||
'statusFilter' => $statusAndDateFilter,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -71,4 +122,29 @@ class UserAccompanyingPeriodController extends AbstractController
|
||||
'pagination' => $pagination,
|
||||
]);
|
||||
}
|
||||
|
||||
public function buildStatusAndDateFilter(int $filter)
|
||||
{
|
||||
$filterBuilder = $this->filterOrderHelperFactory
|
||||
->create(self::class)
|
||||
->addCheckbox(
|
||||
'statusFilter',
|
||||
['is_open', 'is_closed'],
|
||||
['is_open'],
|
||||
array_map(
|
||||
static fn (string $s) => 'my_parcours_filters.'.$s,
|
||||
['is_open', 'is_closed']
|
||||
)
|
||||
);
|
||||
|
||||
if (8 === $filter) {
|
||||
$filterBuilder->addDateRange(
|
||||
'interventionBetweenDates',
|
||||
$this->translator->trans('Since'),
|
||||
new \DateTimeImmutable('-6 months'),
|
||||
);
|
||||
}
|
||||
|
||||
return $filterBuilder->build();
|
||||
}
|
||||
}
|
||||
|
@@ -48,12 +48,12 @@ class LoadAccompanyingPeriodClosingMotive extends AbstractFixture implements Ord
|
||||
|
||||
public static $references = [];
|
||||
|
||||
public function getOrder()
|
||||
public function getOrder(): int
|
||||
{
|
||||
return 9500;
|
||||
}
|
||||
|
||||
public function load(ObjectManager $manager)
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
foreach (static::$closingMotives as $ref => $new) {
|
||||
$motive = new ClosingMotive();
|
||||
|
@@ -38,7 +38,7 @@ class LoadAccompanyingPeriodNotifications extends AbstractFixture implements Dep
|
||||
],
|
||||
];
|
||||
|
||||
public function getDependencies()
|
||||
public function getDependencies(): array
|
||||
{
|
||||
return [
|
||||
LoadPeople::class,
|
||||
|
@@ -27,12 +27,12 @@ class LoadAccompanyingPeriodOrigin extends AbstractFixture implements OrderedFix
|
||||
|
||||
private array $phoneCall = ['en' => 'phone call', 'fr' => 'appel téléphonique'];
|
||||
|
||||
public function getOrder()
|
||||
public function getOrder(): int
|
||||
{
|
||||
return 9000;
|
||||
}
|
||||
|
||||
public function load(ObjectManager $manager)
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
$o = new Origin();
|
||||
$o->setLabel($this->phoneCall);
|
||||
|
@@ -11,6 +11,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\DataFixtures\ORM;
|
||||
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
|
||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||
@@ -28,14 +29,14 @@ class LoadAccompanyingPeriodWork extends \Doctrine\Bundle\FixturesBundle\Fixture
|
||||
|
||||
public function __construct(private readonly AccompanyingPeriodRepository $periodRepository, private readonly EvaluationRepository $evaluationRepository) {}
|
||||
|
||||
public function getDependencies()
|
||||
public function getDependencies(): array
|
||||
{
|
||||
return [
|
||||
LoadPeople::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function load(ObjectManager $manager)
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
// load all the period which are confirmed
|
||||
$periods = $this->periodRepository
|
||||
@@ -64,9 +65,9 @@ class LoadAccompanyingPeriodWork extends \Doctrine\Bundle\FixturesBundle\Fixture
|
||||
->setStartDate(new \DateTimeImmutable('today'))
|
||||
->addPerson($period->getPersons()->first())
|
||||
->setCreatedAt(new \DateTimeImmutable())
|
||||
->setCreatedBy($this->getReference('center a_social'))
|
||||
->setCreatedBy($this->getReference('center a_social', User::class))
|
||||
->setUpdatedAt(new \DateTimeImmutable())
|
||||
->setUpdatedBy($this->getReference('center a_social'));
|
||||
->setUpdatedBy($this->getReference('center a_social', User::class));
|
||||
$manager->persist($work);
|
||||
|
||||
if ($action->getEvaluations()->count() > 0) {
|
||||
@@ -91,9 +92,9 @@ class LoadAccompanyingPeriodWork extends \Doctrine\Bundle\FixturesBundle\Fixture
|
||||
->setStartDate(new \DateTimeImmutable('today'))
|
||||
->addPerson($period->getPersons()->first())
|
||||
->setCreatedAt(new \DateTimeImmutable())
|
||||
->setCreatedBy($this->getReference('center a_social'))
|
||||
->setCreatedBy($this->getReference('center a_social', User::class))
|
||||
->setUpdatedAt(new \DateTimeImmutable())
|
||||
->setUpdatedBy($this->getReference('center a_social'));
|
||||
->setUpdatedBy($this->getReference('center a_social', User::class));
|
||||
$manager->persist($work);
|
||||
$ev = new AccompanyingPeriod\AccompanyingPeriodWorkEvaluation();
|
||||
$ev->setAccompanyingPeriodWork($work)
|
||||
|
@@ -0,0 +1,43 @@
|
||||
<?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\DataFixtures\ORM;
|
||||
|
||||
use Chill\PersonBundle\Entity\AdministrativeStatus;
|
||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||
use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
|
||||
class LoadAdministrativeStatus extends Fixture implements FixtureGroupInterface
|
||||
{
|
||||
public static function getGroups(): array
|
||||
{
|
||||
return ['administrative_status'];
|
||||
}
|
||||
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
$status = [
|
||||
['name' => ['fr' => 'situation administrative régulière']],
|
||||
['name' => ['fr' => 'sans papier']],
|
||||
['name' => ['fr' => 'séjour provisoire']],
|
||||
];
|
||||
|
||||
foreach ($status as $val) {
|
||||
$administrativeStatus = (new AdministrativeStatus())
|
||||
->setName($val['name'])
|
||||
->setActive(true);
|
||||
$manager->persist($administrativeStatus);
|
||||
}
|
||||
|
||||
$manager->flush();
|
||||
}
|
||||
}
|
@@ -40,12 +40,12 @@ class LoadCustomFields extends AbstractFixture implements OrderedFixtureInterfac
|
||||
) {}
|
||||
|
||||
// put your code here
|
||||
public function getOrder()
|
||||
public function getOrder(): int
|
||||
{
|
||||
return 10003;
|
||||
}
|
||||
|
||||
public function load(ObjectManager $manager)
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
$this->loadFields($manager);
|
||||
$this->loadData($manager);
|
||||
|
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\DataFixtures\ORM;
|
||||
|
||||
use Chill\PersonBundle\Entity\EmploymentStatus;
|
||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||
use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
|
||||
class LoadEmploymentStatus extends Fixture implements FixtureGroupInterface
|
||||
{
|
||||
public static function getGroups(): array
|
||||
{
|
||||
return ['employment_status'];
|
||||
}
|
||||
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
$status = [
|
||||
['name' => ['fr' => 'Salarié·e']],
|
||||
['name' => ['fr' => 'Indépendant·e']],
|
||||
['name' => ['fr' => 'Chômeur·euse']],
|
||||
['name' => ['fr' => 'Bénéficiaire du CPAS']],
|
||||
['name' => ['fr' => 'Pensionsé·e']],
|
||||
];
|
||||
|
||||
foreach ($status as $val) {
|
||||
$employmentStatus = (new EmploymentStatus())
|
||||
->setName($val['name'])
|
||||
->setActive(true);
|
||||
$manager->persist($employmentStatus);
|
||||
}
|
||||
|
||||
$manager->flush();
|
||||
}
|
||||
}
|
@@ -16,6 +16,7 @@ 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\Household\Position;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Entity\Person\PersonCenterHistory;
|
||||
use Chill\PersonBundle\Household\MembersEditorFactory;
|
||||
@@ -38,7 +39,7 @@ class LoadHousehold extends Fixture implements DependentFixtureInterface
|
||||
$this->loader = new NativeLoader();
|
||||
}
|
||||
|
||||
public function getDependencies()
|
||||
public function getDependencies(): array
|
||||
{
|
||||
return [
|
||||
LoadPeople::class,
|
||||
@@ -46,7 +47,7 @@ class LoadHousehold extends Fixture implements DependentFixtureInterface
|
||||
];
|
||||
}
|
||||
|
||||
public function load(ObjectManager $manager)
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
// generate two times the participation. This will lead to
|
||||
// some movement in participation (same people in two differents
|
||||
@@ -127,7 +128,7 @@ class LoadHousehold extends Fixture implements DependentFixtureInterface
|
||||
|
||||
foreach ($this->getRandomPersons(1, 3) as $person) {
|
||||
$date = $startDate->add(new \DateInterval('P'.\random_int(1, 200).'W'));
|
||||
$position = $this->getReference(LoadHouseholdPosition::ADULT);
|
||||
$position = $this->getReference(LoadHouseholdPosition::ADULT, Position::class);
|
||||
|
||||
$movement->addMovement($date, $person, $position, 0 === $k, 'self generated');
|
||||
++$k;
|
||||
@@ -136,7 +137,7 @@ class LoadHousehold extends Fixture implements DependentFixtureInterface
|
||||
// load children
|
||||
foreach ($this->getRandomPersons(0, 3) as $person) {
|
||||
$date = $startDate->add(new \DateInterval('P'.\random_int(1, 200).'W'));
|
||||
$position = $this->getReference(LoadHouseholdPosition::CHILD);
|
||||
$position = $this->getReference(LoadHouseholdPosition::CHILD, Position::class);
|
||||
|
||||
$movement->addMovement($date, $person, $position, 0 === $k, 'self generated');
|
||||
++$k;
|
||||
@@ -145,7 +146,7 @@ class LoadHousehold extends Fixture implements DependentFixtureInterface
|
||||
// load children out
|
||||
foreach ($this->getRandomPersons(0, 2) as $person) {
|
||||
$date = $startDate->add(new \DateInterval('P'.\random_int(1, 200).'W'));
|
||||
$position = $this->getReference(LoadHouseholdPosition::CHILD_OUT);
|
||||
$position = $this->getReference(LoadHouseholdPosition::CHILD_OUT, Position::class);
|
||||
|
||||
$movement->addMovement($date, $person, $position, 0 === $k, 'self generated');
|
||||
++$k;
|
||||
@@ -161,7 +162,7 @@ class LoadHousehold extends Fixture implements DependentFixtureInterface
|
||||
{
|
||||
$ref = LoadPostalCodes::$refs[\array_rand(LoadPostalCodes::$refs)];
|
||||
|
||||
return $this->getReference($ref);
|
||||
return $this->getReference($ref, PostalCode::class);
|
||||
}
|
||||
|
||||
private function getRandomPersons(int $min, int $max): array
|
||||
|
@@ -34,7 +34,7 @@ class LoadHouseholdCompositionType extends AbstractFixture implements FixtureGro
|
||||
return ['composition-type'];
|
||||
}
|
||||
|
||||
public function load(ObjectManager $manager)
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
foreach (self::TYPES as $type) {
|
||||
$manager->persist(
|
||||
|
@@ -29,7 +29,7 @@ class LoadHouseholdPosition extends Fixture
|
||||
['Enfant hors ménage', false, false, 3.0, self::CHILD_OUT],
|
||||
];
|
||||
|
||||
public function load(ObjectManager $manager)
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
foreach (
|
||||
self::POSITIONS_DATA as [$name, $share, $allowHolder,
|
||||
|
@@ -31,12 +31,12 @@ class LoadMaritalStatus extends AbstractFixture implements OrderedFixtureInterfa
|
||||
['id' => 'unknown', 'name' => ['en' => 'unknown', 'fr' => 'indéterminé']],
|
||||
];
|
||||
|
||||
public function getOrder()
|
||||
public function getOrder(): int
|
||||
{
|
||||
return 9999;
|
||||
}
|
||||
|
||||
public function load(ObjectManager $manager)
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
echo "loading maritalStatuses... \n";
|
||||
|
||||
|
@@ -15,11 +15,14 @@ use Chill\MainBundle\DataFixtures\ORM\LoadPostalCodes;
|
||||
use Chill\MainBundle\Entity\Address;
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Entity\Country;
|
||||
use Chill\MainBundle\Entity\Gender;
|
||||
use Chill\MainBundle\Entity\GenderEnum;
|
||||
use Chill\MainBundle\Entity\PostalCode;
|
||||
use Chill\MainBundle\Entity\Scope;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Repository\CenterRepository;
|
||||
use Chill\MainBundle\Repository\CountryRepository;
|
||||
use Chill\MainBundle\Repository\GenderRepository;
|
||||
use Chill\MainBundle\Repository\ScopeRepository;
|
||||
use Chill\MainBundle\Repository\UserRepository;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
@@ -77,12 +80,15 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
||||
*/
|
||||
protected array $cacheUsers = [];
|
||||
|
||||
/**
|
||||
* @var array|Gender[]
|
||||
*/
|
||||
protected array $cacheGenders = [];
|
||||
|
||||
protected Generator $faker;
|
||||
|
||||
protected NativeLoader $loader;
|
||||
|
||||
private array $genders = [Person::MALE_GENDER, Person::FEMALE_GENDER, Person::BOTH_GENDER];
|
||||
|
||||
private array $peoples = [
|
||||
[
|
||||
'lastName' => 'Depardieu',
|
||||
@@ -90,7 +96,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
||||
'birthdate' => '1948-12-27',
|
||||
'placeOfBirth' => 'Châteauroux',
|
||||
'nationality' => 'RU',
|
||||
'gender' => Person::MALE_GENDER,
|
||||
'gender' => GenderEnum::MALE,
|
||||
'center' => 'Center A',
|
||||
'accompanyingPeriods' => [
|
||||
[
|
||||
@@ -119,7 +125,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
||||
'maritalStatus' => 'ms_divorce',
|
||||
],
|
||||
[
|
||||
// to have a person with same birthdate of Gérard Depardieu
|
||||
// to have a person with same birthdate as Gérard Depardieu
|
||||
'lastName' => 'Van Snick',
|
||||
'firstName' => 'Bart',
|
||||
'birthdate' => '1948-12-27',
|
||||
@@ -131,7 +137,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
||||
'lastName' => 'Depardieu',
|
||||
'firstName' => 'Charline',
|
||||
'birthdate' => '1970-10-15',
|
||||
'gender' => Person::FEMALE_GENDER,
|
||||
'gender' => GenderEnum::FEMALE,
|
||||
'center' => 'Center A',
|
||||
'maritalStatus' => 'ms_legalco',
|
||||
],
|
||||
@@ -227,14 +233,15 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
||||
protected CountryRepository $countryRepository,
|
||||
protected MaritalStatusRepository $maritalStatusRepository,
|
||||
protected ScopeRepository $scopeRepository,
|
||||
protected UserRepository $userRepository
|
||||
protected UserRepository $userRepository,
|
||||
protected GenderRepository $genderRepository,
|
||||
) {
|
||||
$this->faker = Factory::create('fr_FR');
|
||||
$this->faker->addProvider($this);
|
||||
$this->loader = new NativeLoader($this->faker);
|
||||
}
|
||||
|
||||
public function getOrder()
|
||||
public function getOrder(): int
|
||||
{
|
||||
return 10000;
|
||||
}
|
||||
@@ -272,9 +279,17 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
||||
/**
|
||||
* @internal This method is public and called by faker as a custom generator
|
||||
*/
|
||||
public function getRandomGender(): string
|
||||
public function getRandomGender(int $nullPercentage = 50): ?Gender
|
||||
{
|
||||
return $this->genders[array_rand($this->genders)];
|
||||
if (0 === \count($this->cacheGenders)) {
|
||||
$this->cacheGenders = $this->genderRepository->findByActiveOrdered();
|
||||
}
|
||||
|
||||
if (\random_int(0, 100) > $nullPercentage) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->cacheGenders[array_rand($this->cacheGenders)];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -295,7 +310,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
||||
return $this->cacheMaritalStatuses[array_rand($this->cacheMaritalStatuses)];
|
||||
}
|
||||
|
||||
public function load(ObjectManager $manager)
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
$this->loadExpectedPeople($manager);
|
||||
$this->loadRandPeople($manager);
|
||||
@@ -343,8 +358,8 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
||||
|
||||
if (\random_int(0, 10) > 3) {
|
||||
// always add social scope:
|
||||
$accompanyingPeriod->addScope($this->getReference('scope_social'));
|
||||
$origin = $this->getReference(LoadAccompanyingPeriodOrigin::ACCOMPANYING_PERIOD_ORIGIN);
|
||||
$accompanyingPeriod->addScope($this->getReference('scope_social', Scope::class));
|
||||
$origin = $this->getReference(LoadAccompanyingPeriodOrigin::ACCOMPANYING_PERIOD_ORIGIN, AccompanyingPeriod\Origin::class);
|
||||
$accompanyingPeriod->setOrigin($origin);
|
||||
$accompanyingPeriod->setIntensity('regular');
|
||||
$accompanyingPeriod->setAddressLocation($this->createAddress());
|
||||
@@ -457,7 +472,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
||||
{
|
||||
$ref = LoadPostalCodes::$refs[array_rand(LoadPostalCodes::$refs)];
|
||||
|
||||
return $this->getReference($ref);
|
||||
return $this->getReference($ref, PostalCode::class);
|
||||
}
|
||||
|
||||
private function getRandomSocialIssue(): SocialIssue
|
||||
|
@@ -12,7 +12,9 @@ declare(strict_types=1);
|
||||
namespace Chill\PersonBundle\DataFixtures\ORM;
|
||||
|
||||
use Chill\MainBundle\DataFixtures\ORM\LoadPermissionsGroup;
|
||||
use Chill\MainBundle\Entity\PermissionsGroup;
|
||||
use Chill\MainBundle\Entity\RoleScope;
|
||||
use Chill\MainBundle\Entity\Scope;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||
use Doctrine\Common\DataFixtures\AbstractFixture;
|
||||
@@ -25,16 +27,16 @@ use Doctrine\Persistence\ObjectManager;
|
||||
*/
|
||||
class LoadPersonACL extends AbstractFixture implements OrderedFixtureInterface
|
||||
{
|
||||
public function getOrder()
|
||||
public function getOrder(): int
|
||||
{
|
||||
return 9600;
|
||||
}
|
||||
|
||||
public function load(ObjectManager $manager)
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
foreach (LoadPermissionsGroup::$refs as $permissionsGroupRef) {
|
||||
$permissionsGroup = $this->getReference($permissionsGroupRef);
|
||||
$scopeSocial = $this->getReference('scope_social');
|
||||
$permissionsGroup = $this->getReference($permissionsGroupRef, PermissionsGroup::class);
|
||||
$scopeSocial = $this->getReference('scope_social', Scope::class);
|
||||
|
||||
// create permission group
|
||||
switch ($permissionsGroup->getName()) {
|
||||
|
@@ -35,7 +35,7 @@ class LoadRelations extends Fixture implements FixtureGroupInterface
|
||||
return ['person_relations'];
|
||||
}
|
||||
|
||||
public function load(ObjectManager $manager)
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
foreach (self::RELATIONS as $key => $value) {
|
||||
echo 'Creating a new relation type: relation'.$value['title']['fr'].'reverse relation: '.$value['reverseTitle']['fr']."\n";
|
||||
|
@@ -14,6 +14,7 @@ namespace Chill\PersonBundle\DataFixtures\ORM;
|
||||
use Chill\MainBundle\DataFixtures\ORM\LoadUsers;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\PersonBundle\DataFixtures\Helper\PersonRandomHelper;
|
||||
use Chill\PersonBundle\Entity\Relationships\Relation;
|
||||
use Chill\PersonBundle\Entity\Relationships\Relationship;
|
||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
|
||||
@@ -46,7 +47,7 @@ class LoadRelationships extends Fixture implements DependentFixtureInterface
|
||||
->setFromPerson($this->getRandomPerson($this->em))
|
||||
->setToPerson($this->getRandomPerson($this->em))
|
||||
->setRelation($this->getReference(LoadRelations::RELATION_KEY.
|
||||
random_int(0, \count(LoadRelations::RELATIONS) - 1)))
|
||||
random_int(0, \count(LoadRelations::RELATIONS) - 1), Relation::class))
|
||||
->setReverse((bool) random_int(0, 1))
|
||||
->setCreatedBy($user)
|
||||
->setUpdatedBy($user)
|
||||
@@ -74,6 +75,6 @@ class LoadRelationships extends Fixture implements DependentFixtureInterface
|
||||
{
|
||||
$userRef = array_rand(LoadUsers::$refs);
|
||||
|
||||
return $this->getReference($userRef);
|
||||
return $this->getReference($userRef, User::class);
|
||||
}
|
||||
}
|
||||
|
@@ -21,12 +21,12 @@ class LoadSocialWorkMetadata extends Fixture implements OrderedFixtureInterface
|
||||
{
|
||||
public function __construct(private readonly SocialWorkMetadata $importer) {}
|
||||
|
||||
public function getOrder()
|
||||
public function getOrder(): int
|
||||
{
|
||||
return 9500;
|
||||
}
|
||||
|
||||
public function load(ObjectManager $manager)
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
try {
|
||||
$csv = Reader::createFromPath(__DIR__.'/data/social_work_metadata.csv');
|
||||
|
@@ -15,10 +15,16 @@ use Chill\MainBundle\DependencyInjection\MissingBundleException;
|
||||
use Chill\MainBundle\Security\Authorization\ChillExportVoter;
|
||||
use Chill\PersonBundle\Controller\AccompanyingPeriodCommentApiController;
|
||||
use Chill\PersonBundle\Controller\AccompanyingPeriodResourceApiController;
|
||||
use Chill\PersonBundle\Controller\AdministrativeStatusController;
|
||||
use Chill\PersonBundle\Controller\EmploymentStatusController;
|
||||
use Chill\PersonBundle\Controller\HouseholdCompositionTypeApiController;
|
||||
use Chill\PersonBundle\Controller\RelationApiController;
|
||||
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\AdministrativeStatus;
|
||||
use Chill\PersonBundle\Entity\EmploymentStatus;
|
||||
use Chill\PersonBundle\Form\AdministrativeStatusType;
|
||||
use Chill\PersonBundle\Form\EmploymentStatusType;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodCommentVoter;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodResourceVoter;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||
@@ -54,6 +60,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
||||
|
||||
$this->handlePersonFieldsParameters($container, $config['person_fields']);
|
||||
$this->handleAccompanyingPeriodsFieldsParameters($container, $config['accompanying_periods_fields']);
|
||||
$this->handleHouseholdFieldsParameters($container, $config['household_fields']);
|
||||
|
||||
$container->setParameter(
|
||||
'chill_person.allow_multiple_simultaneous_accompanying_periods',
|
||||
@@ -129,6 +136,9 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
||||
'chill_accompanying_periods' => [
|
||||
'fields' => $config['accompanying_periods_fields'],
|
||||
],
|
||||
'chill_household' => [
|
||||
'fields' => $config['household_fields'],
|
||||
],
|
||||
],
|
||||
'form_themes' => ['@ChillPerson/Export/ListPersonFormFields.html.twig'],
|
||||
];
|
||||
@@ -192,6 +202,50 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'class' => AdministrativeStatus::class,
|
||||
'name' => 'administrative_status',
|
||||
'base_path' => '/admin/administrative',
|
||||
'base_role' => 'ROLE_ADMIN',
|
||||
'form_class' => AdministrativeStatusType::class,
|
||||
'controller' => AdministrativeStatusController::class,
|
||||
'actions' => [
|
||||
'index' => [
|
||||
'role' => 'ROLE_ADMIN',
|
||||
'template' => '@ChillPerson/AdministrativeStatus/index.html.twig',
|
||||
],
|
||||
'new' => [
|
||||
'role' => 'ROLE_ADMIN',
|
||||
'template' => '@ChillPerson/AdministrativeStatus/new.html.twig',
|
||||
],
|
||||
'edit' => [
|
||||
'role' => 'ROLE_ADMIN',
|
||||
'template' => '@ChillPerson/AdministrativeStatus/edit.html.twig',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'class' => EmploymentStatus::class,
|
||||
'name' => 'employment_status',
|
||||
'base_path' => '/admin/employment',
|
||||
'base_role' => 'ROLE_ADMIN',
|
||||
'form_class' => EmploymentStatusType::class,
|
||||
'controller' => EmploymentStatusController::class,
|
||||
'actions' => [
|
||||
'index' => [
|
||||
'role' => 'ROLE_ADMIN',
|
||||
'template' => '@ChillPerson/EmploymentStatus/index.html.twig',
|
||||
],
|
||||
'new' => [
|
||||
'role' => 'ROLE_ADMIN',
|
||||
'template' => '@ChillPerson/EmploymentStatus/new.html.twig',
|
||||
],
|
||||
'edit' => [
|
||||
'role' => 'ROLE_ADMIN',
|
||||
'template' => '@ChillPerson/EmploymentStatus/edit.html.twig',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'class' => \Chill\PersonBundle\Entity\MaritalStatus::class,
|
||||
'name' => 'person_marital-status',
|
||||
@@ -1092,6 +1146,23 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
||||
}
|
||||
}
|
||||
|
||||
private function handleHouseholdFieldsParameters(ContainerBuilder $container, $config)
|
||||
{
|
||||
$container->setParameter('chill_person.household_fields', $config);
|
||||
|
||||
foreach ($config as $key => $value) {
|
||||
switch ($key) {
|
||||
case 'enabled':
|
||||
break;
|
||||
|
||||
default:
|
||||
$container->setParameter('chill_person.household_fields.'.$key, $value);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function handlePersonFieldsParameters(ContainerBuilder $container, $config)
|
||||
{
|
||||
if (\array_key_exists('enabled', $config)) {
|
||||
|
@@ -83,8 +83,11 @@ class Configuration implements ConfigurationInterface
|
||||
->append($this->addFieldNode('accompanying_period'))
|
||||
->append($this->addFieldNode('memo'))
|
||||
->append($this->addFieldNode('number_of_children'))
|
||||
->append($this->addFieldNode('number_of_dependents', 'hidden'))
|
||||
->append($this->addFieldNode('acceptEmail'))
|
||||
->append($this->addFieldNode('deathdate'))
|
||||
->append($this->addFieldNode('employment_status', 'hidden'))
|
||||
->append($this->addFieldNode('administrative_status', 'hidden'))
|
||||
->arrayNode('alt_names')
|
||||
->defaultValue([])
|
||||
->arrayPrototype()
|
||||
@@ -107,6 +110,12 @@ class Configuration implements ConfigurationInterface
|
||||
->end()
|
||||
->end() // children for 'person_fields', parent = array 'person_fields'
|
||||
->end() // person_fields, parent = children of root
|
||||
->arrayNode('household_fields')
|
||||
->canBeDisabled()
|
||||
->children()
|
||||
->append($this->addFieldNode('number_of_dependents', 'hidden'))
|
||||
->end()
|
||||
->end()
|
||||
->arrayNode('accompanying_periods_fields')
|
||||
->canBeDisabled()
|
||||
->children()
|
||||
@@ -141,7 +150,7 @@ class Configuration implements ConfigurationInterface
|
||||
return $treeBuilder;
|
||||
}
|
||||
|
||||
private function addFieldNode($key)
|
||||
private function addFieldNode(string $key, string $defaultVisibility = 'visible')
|
||||
{
|
||||
$tree = new TreeBuilder($key, 'enum');
|
||||
$node = $tree->getRootNode();
|
||||
@@ -153,7 +162,7 @@ class Configuration implements ConfigurationInterface
|
||||
|
||||
$node
|
||||
->values(['hidden', 'visible'])
|
||||
->defaultValue('visible')
|
||||
->defaultValue($defaultVisibility)
|
||||
->info($info)
|
||||
->end();
|
||||
|
||||
|
@@ -135,14 +135,14 @@ class AccompanyingPeriod implements
|
||||
private ?Location $administrativeLocation = null;
|
||||
|
||||
/**
|
||||
* @var Collection&Selectable<int, Calendar>
|
||||
* @var Collection<int, Calendar>&Selectable
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: Calendar::class, mappedBy: 'accompanyingPeriod')]
|
||||
#[ORM\OneToMany(mappedBy: 'accompanyingPeriod', targetEntity: Calendar::class)]
|
||||
private Collection&Selectable $calendars;
|
||||
|
||||
#[Groups(['read', 'write', 'docgen:read'])]
|
||||
#[Assert\NotBlank(groups: [AccompanyingPeriod::STEP_CLOSED])]
|
||||
#[Assert\GreaterThanOrEqual(propertyPath: 'openingDate', groups: [AccompanyingPeriod::STEP_CLOSED], message: 'The closing date must be later than the date of creation')]
|
||||
#[Assert\GreaterThanOrEqual(propertyPath: 'openingDate', message: 'The closing date must be later than the date of creation', groups: [AccompanyingPeriod::STEP_CLOSED])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATE_MUTABLE, nullable: true)]
|
||||
private ?\DateTime $closingDate = null;
|
||||
|
||||
@@ -153,10 +153,10 @@ class AccompanyingPeriod implements
|
||||
private ?ClosingMotive $closingMotive = null;
|
||||
|
||||
/**
|
||||
* @var Collection<Comment>
|
||||
* @var Collection<int, Comment>
|
||||
*/
|
||||
#[Assert\NotBlank(groups: [AccompanyingPeriod::STEP_DRAFT])]
|
||||
#[ORM\OneToMany(targetEntity: Comment::class, mappedBy: 'accompanyingPeriod', cascade: ['persist', 'remove'], orphanRemoval: true)]
|
||||
#[ORM\OneToMany(mappedBy: 'accompanyingPeriod', targetEntity: Comment::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
|
||||
#[ORM\OrderBy(['createdAt' => Criteria::DESC, 'id' => 'DESC'])]
|
||||
private Collection $comments;
|
||||
|
||||
@@ -194,9 +194,9 @@ class AccompanyingPeriod implements
|
||||
private ?UserJob $job = null;
|
||||
|
||||
/**
|
||||
* @var Collection<AccompanyingPeriodLocationHistory>
|
||||
* @var Collection<int, AccompanyingPeriodLocationHistory>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: AccompanyingPeriodLocationHistory::class, mappedBy: 'period', cascade: ['persist', 'remove'], orphanRemoval: true)]
|
||||
#[ORM\OneToMany(mappedBy: 'period', targetEntity: AccompanyingPeriodLocationHistory::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
|
||||
private Collection $locationHistories;
|
||||
|
||||
#[Groups(['read', 'write', 'docgen:read'])]
|
||||
@@ -212,10 +212,10 @@ class AccompanyingPeriod implements
|
||||
private ?Origin $origin = null;
|
||||
|
||||
/**
|
||||
* @var Collection<AccompanyingPeriodParticipation>
|
||||
* @var Collection<int, AccompanyingPeriodParticipation>
|
||||
*/
|
||||
#[Groups(['read', 'docgen:read'])]
|
||||
#[ORM\OneToMany(targetEntity: AccompanyingPeriodParticipation::class, mappedBy: 'accompanyingPeriod', orphanRemoval: true, cascade: ['persist', 'refresh', 'remove', 'merge', 'detach'])]
|
||||
#[ORM\OneToMany(mappedBy: 'accompanyingPeriod', targetEntity: AccompanyingPeriodParticipation::class, cascade: ['persist', 'refresh', 'remove', 'merge', 'detach'], orphanRemoval: true)]
|
||||
#[ParticipationOverlap(groups: [AccompanyingPeriod::STEP_DRAFT, AccompanyingPeriod::STEP_CONFIRMED])]
|
||||
private Collection $participations;
|
||||
|
||||
@@ -246,7 +246,7 @@ class AccompanyingPeriod implements
|
||||
private ?ThirdParty $requestorThirdParty = null;
|
||||
|
||||
/**
|
||||
* @var Collection<resource>
|
||||
* @var Collection<int, AccompanyingPeriod\Resource>
|
||||
*/
|
||||
#[Groups(['read', 'docgen:read'])]
|
||||
#[ORM\OneToMany(targetEntity: AccompanyingPeriod\Resource::class, mappedBy: 'accompanyingPeriod', cascade: ['persist', 'remove'], orphanRemoval: true)]
|
||||
@@ -254,7 +254,7 @@ class AccompanyingPeriod implements
|
||||
private Collection $resources;
|
||||
|
||||
/**
|
||||
* @var Collection<Scope>
|
||||
* @var Collection<int, Scope>
|
||||
*/
|
||||
#[Groups(['read', 'docgen:read'])]
|
||||
#[Assert\Count(min: 1, groups: [AccompanyingPeriod::STEP_CONFIRMED], minMessage: 'A course must be associated to at least one scope')]
|
||||
@@ -263,7 +263,7 @@ class AccompanyingPeriod implements
|
||||
private Collection $scopes;
|
||||
|
||||
/**
|
||||
* @var Collection<SocialIssue>
|
||||
* @var Collection<int, SocialIssue>
|
||||
*/
|
||||
#[Groups(['read', 'docgen:read'])]
|
||||
#[Assert\Count(min: 1, groups: [AccompanyingPeriod::STEP_CONFIRMED], minMessage: 'A course must contains at least one social issue')]
|
||||
@@ -279,9 +279,9 @@ class AccompanyingPeriod implements
|
||||
private ?string $step = self::STEP_DRAFT;
|
||||
|
||||
/**
|
||||
* @var Collection<AccompanyingPeriodStepHistory>
|
||||
* @var Collection<int, AccompanyingPeriodStepHistory>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: AccompanyingPeriodStepHistory::class, mappedBy: 'period', cascade: ['persist', 'remove'], orphanRemoval: true)]
|
||||
#[ORM\OneToMany(mappedBy: 'period', targetEntity: AccompanyingPeriodStepHistory::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
|
||||
private Collection $stepHistories;
|
||||
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATETIME_MUTABLE, nullable: true, options: ['default' => null])]
|
||||
@@ -296,7 +296,7 @@ class AccompanyingPeriod implements
|
||||
private ?User $user = null;
|
||||
|
||||
/**
|
||||
* @var Collection<UserHistory>
|
||||
* @var Collection<int, UserHistory>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: UserHistory::class, mappedBy: 'accompanyingPeriod', orphanRemoval: true, cascade: ['persist', 'remove'])]
|
||||
private Collection $userHistories;
|
||||
@@ -311,10 +311,10 @@ class AccompanyingPeriod implements
|
||||
private ?User $userPrevious = null;
|
||||
|
||||
/**
|
||||
* @var Collection<AccompanyingPeriodWork>
|
||||
* @var Collection<int, AccompanyingPeriodWork>
|
||||
*/
|
||||
#[Assert\Valid(traverse: true)]
|
||||
#[ORM\OneToMany(targetEntity: AccompanyingPeriodWork::class, mappedBy: 'accompanyingPeriod')]
|
||||
#[ORM\OneToMany(mappedBy: 'accompanyingPeriod', targetEntity: AccompanyingPeriodWork::class)]
|
||||
private Collection $works;
|
||||
|
||||
/**
|
||||
@@ -427,7 +427,7 @@ class AccompanyingPeriod implements
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addResource(Resource $resource): self
|
||||
public function addResource(AccompanyingPeriod\Resource $resource): self
|
||||
{
|
||||
$resource->setAccompanyingPeriod($this);
|
||||
$this->resources[] = $resource;
|
||||
@@ -511,6 +511,14 @@ class AccompanyingPeriod implements
|
||||
return $this->getParticipationsContainsPerson($person)->count() > 0;
|
||||
}
|
||||
|
||||
public function getOpenWorks(): Collection
|
||||
{
|
||||
return $this->getWorks()->filter(
|
||||
static fn (AccompanyingPeriodWork $work): bool => null === $work->getEndDate()
|
||||
or $work->getEndDate() > new \DateTimeImmutable('today')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a new participation for a person.
|
||||
*/
|
||||
@@ -592,7 +600,7 @@ class AccompanyingPeriod implements
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ReadableCollection<(int|string), Comment>
|
||||
* @return ReadableCollection<int, Comment>
|
||||
*/
|
||||
#[Groups(['read'])]
|
||||
public function getComments(): ReadableCollection
|
||||
@@ -707,19 +715,24 @@ class AccompanyingPeriod implements
|
||||
public function getNextCalendarsForPerson(Person $person, $limit = 5): ReadableCollection
|
||||
{
|
||||
$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)
|
||||
);
|
||||
$criteria = Criteria::create();
|
||||
$expr = Criteria::expr();
|
||||
|
||||
$criteria
|
||||
->where(
|
||||
$expr->gte('startDate', $today),
|
||||
)
|
||||
->orderBy(['startDate' => 'ASC']);
|
||||
|
||||
$criteriaByPerson = Criteria::create();
|
||||
$criteriaByPerson
|
||||
->where(
|
||||
$expr->memberOf('persons', $person)
|
||||
)
|
||||
->setMaxResults($limit);
|
||||
|
||||
return $this->calendars->matching($criteria)->matching($criteriaByPerson);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -796,7 +809,7 @@ class AccompanyingPeriod implements
|
||||
/**
|
||||
* Get a list of all persons which are participating to this course.
|
||||
*
|
||||
* @psalm-return Collection<(int|string), Person|null>
|
||||
* @psalm-return Collection<int, Person|null>
|
||||
*/
|
||||
public function getPersons(): Collection
|
||||
{
|
||||
@@ -892,6 +905,9 @@ class AccompanyingPeriod implements
|
||||
return $this->requestorThirdParty;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, AccompanyingPeriod\Resource>
|
||||
*/
|
||||
public function getResources(): Collection
|
||||
{
|
||||
return $this->resources;
|
||||
@@ -1332,6 +1348,16 @@ class AccompanyingPeriod implements
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUserHistories(): ReadableCollection
|
||||
{
|
||||
return $this->userHistories;
|
||||
}
|
||||
|
||||
public function getCurrentUserHistory(): ?UserHistory
|
||||
{
|
||||
return $this->getUserHistories()->findFirst(fn (int $key, UserHistory $userHistory) => null === $userHistory->getEndDate());
|
||||
}
|
||||
|
||||
private function addStepHistory(AccompanyingPeriodStepHistory $stepHistory, array $context = []): self
|
||||
{
|
||||
if (!$this->stepHistories->contains($stepHistory)) {
|
||||
|
@@ -40,12 +40,13 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
|
||||
private ?AccompanyingPeriod $accompanyingPeriod = null;
|
||||
|
||||
/**
|
||||
* @var Collection<AccompanyingPeriodWorkEvaluation>
|
||||
* @var Collection<int, AccompanyingPeriodWorkEvaluation>
|
||||
*
|
||||
* @internal /!\ the serialization for write evaluations is handled in `AccompanyingPeriodWorkDenormalizer`
|
||||
* @internal the serialization for write evaluations is handled in `accompanyingperiodworkdenormalizer`
|
||||
* @internal the serialization for context docgen:read is handled in `accompanyingperiodworknormalizer`
|
||||
*/
|
||||
#[Serializer\Groups(['read', 'docgen:read'])]
|
||||
#[ORM\OneToMany(targetEntity: AccompanyingPeriodWorkEvaluation::class, mappedBy: 'accompanyingPeriodWork', cascade: ['remove', 'persist'], orphanRemoval: true)]
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\OneToMany(mappedBy: 'accompanyingPeriodWork', targetEntity: AccompanyingPeriodWorkEvaluation::class, cascade: ['remove', 'persist'], orphanRemoval: true)]
|
||||
#[ORM\OrderBy(['startDate' => \Doctrine\Common\Collections\Criteria::DESC, 'id' => 'DESC'])]
|
||||
private Collection $accompanyingPeriodWorkEvaluations;
|
||||
|
||||
@@ -72,10 +73,10 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
|
||||
private ?\DateTimeImmutable $endDate = null;
|
||||
|
||||
/**
|
||||
* @var Collection<AccompanyingPeriodWorkGoal>
|
||||
* @var Collection<int, AccompanyingPeriodWorkGoal>
|
||||
*/
|
||||
#[Serializer\Groups(['read', 'docgen:read', 'accompanying_period_work:edit'])]
|
||||
#[ORM\OneToMany(targetEntity: AccompanyingPeriodWorkGoal::class, mappedBy: 'accompanyingPeriodWork', cascade: ['persist'], orphanRemoval: true)]
|
||||
#[ORM\OneToMany(mappedBy: 'accompanyingPeriodWork', targetEntity: AccompanyingPeriodWorkGoal::class, cascade: ['persist'], orphanRemoval: true)]
|
||||
private Collection $goals;
|
||||
|
||||
#[Serializer\Groups(['read', 'docgen:read', 'accompanying_period_work:edit'])]
|
||||
@@ -93,7 +94,7 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
|
||||
private string $note = '';
|
||||
|
||||
/**
|
||||
* @var Collection<Person>
|
||||
* @var Collection<int, Person>
|
||||
*/
|
||||
#[Serializer\Groups(['read', 'docgen:read', 'read:accompanyingPeriodWork:light', 'accompanying_period_work:edit', 'accompanying_period_work:create'])]
|
||||
#[ORM\ManyToMany(targetEntity: Person::class)]
|
||||
@@ -111,7 +112,7 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
|
||||
private Collection $referrersHistory;
|
||||
|
||||
/**
|
||||
* @var Collection<Result>
|
||||
* @var Collection<int, Result>
|
||||
*/
|
||||
#[Serializer\Groups(['read', 'docgen:read', 'accompanying_period_work:edit'])]
|
||||
#[ORM\ManyToMany(targetEntity: Result::class, inversedBy: 'accompanyingPeriodWorks')]
|
||||
@@ -128,7 +129,7 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
|
||||
private ?\DateTimeImmutable $startDate = null;
|
||||
|
||||
/**
|
||||
* @var Collection<ThirdParty>
|
||||
* @var Collection<int, ThirdParty>
|
||||
*/
|
||||
#[Serializer\Groups(['read', 'docgen:read', 'accompanying_period_work:edit'])]
|
||||
#[ORM\ManyToMany(targetEntity: ThirdParty::class)]
|
||||
@@ -289,20 +290,40 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ReadableCollection<int, User>
|
||||
* Retrieves a collection of current referrers.
|
||||
*
|
||||
* This method filters the referrer history to get only those entries
|
||||
* where the end date is null, maps them to their associated users,
|
||||
* and returns them as a new ReadableCollection.
|
||||
*
|
||||
* @return ReadableCollection<int, User> collection of active referrers
|
||||
*/
|
||||
#[Serializer\Groups(['read', 'docgen:read', 'read:accompanyingPeriodWork:light', 'accompanying_period_work:edit', 'accompanying_period_work:create'])]
|
||||
#[Serializer\Groups(['accompanying_period_work:edit'])]
|
||||
public function getReferrers(): ReadableCollection
|
||||
{
|
||||
$users = $this->referrersHistory
|
||||
->filter(fn (AccompanyingPeriodWorkReferrerHistory $h) => null === $h->getEndDate())
|
||||
->map(fn (AccompanyingPeriodWorkReferrerHistory $h) => $h->getUser())
|
||||
->getValues()
|
||||
;
|
||||
->getValues();
|
||||
|
||||
return new ArrayCollection(array_values($users));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ReadableCollection<int, AccompanyingPeriodWorkReferrerHistory>
|
||||
*/
|
||||
public function getReferrersHistoryCurrent(): ReadableCollection
|
||||
{
|
||||
return new ArrayCollection(
|
||||
$this->getReferrersHistory()
|
||||
->filter(fn (AccompanyingPeriodWorkReferrerHistory $h) => null === $h->getEndDate())
|
||||
->getValues()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, AccompanyingPeriodWorkReferrerHistory>
|
||||
*/
|
||||
public function getReferrersHistory(): Collection
|
||||
{
|
||||
return $this->referrersHistory;
|
||||
@@ -470,9 +491,9 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setCreatedBy(?User $createdBy): self
|
||||
public function setCreatedBy(?User $user): self
|
||||
{
|
||||
$this->createdBy = $createdBy;
|
||||
$this->createdBy = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -514,14 +535,14 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
|
||||
|
||||
public function setStartDate(\DateTimeInterface $startDate): self
|
||||
{
|
||||
$this->startDate = $startDate;
|
||||
$this->startDate = $startDate instanceof \DateTime ? \DateTimeImmutable::createFromMutable($startDate) : $startDate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setUpdatedAt(\DateTimeInterface $datetime): TrackUpdateInterface
|
||||
{
|
||||
$this->updatedAt = $datetime;
|
||||
$this->updatedAt = $datetime instanceof \DateTime ? \DateTimeImmutable::createFromMutable($datetime) : $datetime;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@@ -47,10 +47,10 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU
|
||||
*
|
||||
* @see{Chill\PersonBundle\Serializer\Normalizer\AccompanyingPeriodWorkEvaluationDenormalizer}
|
||||
*
|
||||
* @var Collection<AccompanyingPeriodWorkEvaluationDocument>
|
||||
* @var Collection<int, AccompanyingPeriodWorkEvaluationDocument>
|
||||
*/
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\OneToMany(targetEntity: AccompanyingPeriodWorkEvaluationDocument::class, mappedBy: 'accompanyingPeriodWorkEvaluation', cascade: ['remove', 'persist'], orphanRemoval: true)]
|
||||
#[ORM\OneToMany(mappedBy: 'accompanyingPeriodWorkEvaluation', targetEntity: AccompanyingPeriodWorkEvaluationDocument::class, cascade: ['remove', 'persist'], orphanRemoval: true)]
|
||||
#[ORM\OrderBy(['createdAt' => \Doctrine\Common\Collections\Criteria::DESC, 'id' => 'DESC'])]
|
||||
private Collection $documents;
|
||||
|
||||
|
@@ -60,9 +60,10 @@ class AccompanyingPeriodWorkEvaluationDocument implements \Chill\MainBundle\Doct
|
||||
#[ORM\ManyToOne(targetEntity: DocGeneratorTemplate::class)]
|
||||
private ?DocGeneratorTemplate $template = null;
|
||||
|
||||
#[Serializer\Groups(['read', 'write', 'accompanying_period_work_evaluation:create'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::TEXT, nullable: false, options: ['default' => ''])]
|
||||
private ?string $title = '';
|
||||
/**
|
||||
* Store the title only if the storedObject is not yet associated with the instance.
|
||||
*/
|
||||
private string $proxyTitle = '';
|
||||
|
||||
public function getAccompanyingPeriodWorkEvaluation(): ?AccompanyingPeriodWorkEvaluation
|
||||
{
|
||||
@@ -89,9 +90,10 @@ class AccompanyingPeriodWorkEvaluationDocument implements \Chill\MainBundle\Doct
|
||||
return $this->template;
|
||||
}
|
||||
|
||||
#[Serializer\Groups(['read'])]
|
||||
public function getTitle(): ?string
|
||||
{
|
||||
return $this->title;
|
||||
return (string) $this->getStoredObject()?->getTitle();
|
||||
}
|
||||
|
||||
public function setAccompanyingPeriodWorkEvaluation(?AccompanyingPeriodWorkEvaluation $accompanyingPeriodWorkEvaluation): AccompanyingPeriodWorkEvaluationDocument
|
||||
@@ -125,6 +127,10 @@ class AccompanyingPeriodWorkEvaluationDocument implements \Chill\MainBundle\Doct
|
||||
{
|
||||
$this->storedObject = $storedObject;
|
||||
|
||||
if ('' !== $this->proxyTitle) {
|
||||
$this->storedObject->setTitle($this->proxyTitle);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -135,9 +141,14 @@ class AccompanyingPeriodWorkEvaluationDocument implements \Chill\MainBundle\Doct
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setTitle(?string $title): AccompanyingPeriodWorkEvaluationDocument
|
||||
#[Serializer\Groups(['write', 'accompanying_period_work_evaluation:create'])]
|
||||
public function setTitle(?string $proxyTitle): AccompanyingPeriodWorkEvaluationDocument
|
||||
{
|
||||
$this->title = $title;
|
||||
if (null !== $this->storedObject) {
|
||||
$this->storedObject->setTitle((string) $proxyTitle);
|
||||
} else {
|
||||
$this->proxyTitle = (string) $proxyTitle;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@@ -41,7 +41,7 @@ class AccompanyingPeriodWorkGoal
|
||||
private string $note = '';
|
||||
|
||||
/**
|
||||
* @var Collection<Result>
|
||||
* @var Collection<int, Result>
|
||||
*/
|
||||
#[Serializer\Groups(['accompanying_period_work:edit', 'read', 'docgen:read'])]
|
||||
#[ORM\ManyToMany(targetEntity: Result::class, inversedBy: 'accompanyingPeriodWorkGoals')]
|
||||
|
@@ -45,7 +45,7 @@ class AccompanyingPeriodWorkReferrerHistory implements TrackCreationInterface, T
|
||||
* @var \DateTimeImmutable
|
||||
*/
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATE_IMMUTABLE, nullable: false)]
|
||||
private \DateTimeImmutable $startDate
|
||||
private \DateTimeImmutable $startDate,
|
||||
) {}
|
||||
|
||||
public function getId(): ?int
|
||||
|
@@ -29,9 +29,9 @@ class ClosingMotive
|
||||
/**
|
||||
* Child Accompanying periods.
|
||||
*
|
||||
* @var Collection<ClosingMotive>
|
||||
* @var Collection<int, ClosingMotive>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: ClosingMotive::class, mappedBy: 'parent')]
|
||||
#[ORM\OneToMany(mappedBy: 'parent', targetEntity: ClosingMotive::class)]
|
||||
private Collection $children;
|
||||
|
||||
#[Serializer\Groups(['docgen:read'])]
|
||||
@@ -45,7 +45,7 @@ class ClosingMotive
|
||||
#[Serializer\Context(['is-translatable' => true], groups: ['docgen:read'])]
|
||||
private array $name = [];
|
||||
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::FLOAT)]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::FLOAT, options: ['default' => 0.0])]
|
||||
private float $ordering = 0.0;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: ClosingMotive::class, inversedBy: 'children')]
|
||||
@@ -182,11 +182,9 @@ class ClosingMotive
|
||||
/**
|
||||
* Set name.
|
||||
*
|
||||
* @param array $name
|
||||
*
|
||||
* @return ClosingMotive
|
||||
*/
|
||||
public function setName($name)
|
||||
public function setName(array $name)
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
|
@@ -132,6 +132,11 @@ class Comment implements TrackCreationInterface, TrackUpdateInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCreatedBy(): ?User
|
||||
{
|
||||
return $this->getCreator();
|
||||
}
|
||||
|
||||
public function setUpdatedAt(\DateTimeInterface $updatedAt): self
|
||||
{
|
||||
$this->updatedAt = $updatedAt;
|
||||
|
@@ -39,7 +39,7 @@ class UserHistory implements TrackCreationInterface
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private User $user,
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATETIME_IMMUTABLE, nullable: false, options: ['default' => 'now()'])]
|
||||
private \DateTimeImmutable $startDate = new \DateTimeImmutable('now')
|
||||
private \DateTimeImmutable $startDate = new \DateTimeImmutable('now'),
|
||||
) {}
|
||||
|
||||
public function getAccompanyingPeriod(): AccompanyingPeriod
|
||||
|
@@ -42,7 +42,7 @@ class AccompanyingPeriodParticipation
|
||||
#[ORM\JoinColumn(name: 'accompanyingperiod_id', referencedColumnName: 'id', nullable: false)]
|
||||
private ?AccompanyingPeriod $accompanyingPeriod,
|
||||
#[Groups(['read', 'docgen:read'])] #[ORM\ManyToOne(targetEntity: Person::class, inversedBy: 'accompanyingPeriodParticipations')] #[ORM\JoinColumn(name: 'person_id', referencedColumnName: 'id', nullable: false)]
|
||||
private ?Person $person
|
||||
private ?Person $person,
|
||||
) {
|
||||
$this->startDate = new \DateTime('now');
|
||||
$person->getAccompanyingPeriodParticipations()->add($this);
|
||||
|
81
src/Bundle/ChillPersonBundle/Entity/AdministrativeStatus.php
Normal file
81
src/Bundle/ChillPersonBundle/Entity/AdministrativeStatus.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?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;
|
||||
|
||||
use Chill\PersonBundle\Repository\AdministrativeStatusRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
|
||||
#[Serializer\DiscriminatorMap(typeProperty: 'type', mapping: ['chill_person_administrative_status' => AdministrativeStatus::class])]
|
||||
#[ORM\Entity(repositoryClass: AdministrativeStatusRepository::class)]
|
||||
#[ORM\Table(name: 'chill_person_administrative_status')]
|
||||
class AdministrativeStatus
|
||||
{
|
||||
#[Serializer\Groups(['read', 'docgen:read'])]
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER)]
|
||||
private ?int $id = null;
|
||||
|
||||
#[Serializer\Groups(['read', 'docgen:read'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON)]
|
||||
#[Serializer\Context(['is-translatable' => true], groups: ['docgen:read'])]
|
||||
private array $name = [];
|
||||
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::BOOLEAN)]
|
||||
private bool $active = true;
|
||||
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::FLOAT, name: 'ordering', nullable: true, options: ['default' => '0.0'])]
|
||||
private float $order = 0;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getActive(): ?bool
|
||||
{
|
||||
return $this->active;
|
||||
}
|
||||
|
||||
public function getName(): ?array
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getOrder(): ?float
|
||||
{
|
||||
return $this->order;
|
||||
}
|
||||
|
||||
public function setActive(bool $active): self
|
||||
{
|
||||
$this->active = $active;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setName(array $name): self
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setOrder(float $order): self
|
||||
{
|
||||
$this->order = $order;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
81
src/Bundle/ChillPersonBundle/Entity/EmploymentStatus.php
Normal file
81
src/Bundle/ChillPersonBundle/Entity/EmploymentStatus.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?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;
|
||||
|
||||
use Chill\PersonBundle\Repository\EmploymentStatusRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
|
||||
#[Serializer\DiscriminatorMap(typeProperty: 'type', mapping: ['chill_person_employment_status' => EmploymentStatus::class])]
|
||||
#[ORM\Entity(repositoryClass: EmploymentStatusRepository::class)]
|
||||
#[ORM\Table(name: 'chill_person_employment_status')]
|
||||
class EmploymentStatus
|
||||
{
|
||||
#[Serializer\Groups(['read', 'docgen:read'])]
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER)]
|
||||
private ?int $id = null;
|
||||
|
||||
#[Serializer\Groups(['read', 'docgen:read'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON)]
|
||||
#[Serializer\Context(['is-translatable' => true], groups: ['docgen:read'])]
|
||||
private array $name = [];
|
||||
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::BOOLEAN)]
|
||||
private bool $active = true;
|
||||
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::FLOAT, name: 'ordering', nullable: true, options: ['default' => '0.0'])]
|
||||
private float $order = 0;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getActive(): ?bool
|
||||
{
|
||||
return $this->active;
|
||||
}
|
||||
|
||||
public function getName(): ?array
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getOrder(): ?float
|
||||
{
|
||||
return $this->order;
|
||||
}
|
||||
|
||||
public function setActive(bool $active): self
|
||||
{
|
||||
$this->active = $active;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setName(array $name): self
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setOrder(float $order): self
|
||||
{
|
||||
$this->order = $order;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -21,6 +21,7 @@ use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\Common\Collections\ReadableCollection;
|
||||
use Doctrine\Common\Collections\Selectable;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
@@ -35,7 +36,7 @@ class Household implements HasCentersInterface
|
||||
/**
|
||||
* Addresses.
|
||||
*
|
||||
* @var Collection<Address>
|
||||
* @var Collection<int, Address>
|
||||
*/
|
||||
#[Serializer\Groups(['write'])]
|
||||
#[ORM\ManyToMany(targetEntity: Address::class, cascade: ['persist', 'remove', 'merge', 'detach'])]
|
||||
@@ -47,33 +48,33 @@ class Household implements HasCentersInterface
|
||||
private CommentEmbeddable $commentMembers;
|
||||
|
||||
/**
|
||||
* @var Collection&Selectable<int, HouseholdComposition>
|
||||
* @var Collection<int, HouseholdComposition>&Selectable
|
||||
*/
|
||||
#[Assert\Valid(traverse: true, groups: ['household_composition'])]
|
||||
#[ORM\OneToMany(targetEntity: HouseholdComposition::class, mappedBy: 'household', orphanRemoval: true, cascade: ['persist'])]
|
||||
#[Assert\Valid(groups: ['household_composition'], traverse: true)]
|
||||
#[ORM\OneToMany(mappedBy: 'household', targetEntity: HouseholdComposition::class, cascade: ['persist'], orphanRemoval: true)]
|
||||
#[ORM\OrderBy(['startDate' => Criteria::DESC])]
|
||||
private Collection&Selectable $compositions;
|
||||
|
||||
#[Serializer\Groups(['read', 'docgen:read'])]
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER)]
|
||||
#[ORM\Column(type: Types::INTEGER)]
|
||||
private ?int $id = null;
|
||||
|
||||
/**
|
||||
* @var Collection<HouseholdMember>
|
||||
* @var Collection<int, HouseholdMember>
|
||||
*/
|
||||
#[Serializer\Groups(['read', 'docgen:read'])]
|
||||
#[ORM\OneToMany(targetEntity: HouseholdMember::class, mappedBy: 'household')]
|
||||
#[ORM\OneToMany(mappedBy: 'household', targetEntity: HouseholdMember::class)]
|
||||
private Collection $members;
|
||||
|
||||
#[Serializer\Groups(['docgen:read'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::BOOLEAN, name: 'waiting_for_birth', options: ['default' => false])]
|
||||
#[ORM\Column(name: 'waiting_for_birth', type: Types::BOOLEAN, options: ['default' => false])]
|
||||
#[Assert\Type('boolean', groups: ['household_metadata'])]
|
||||
private bool $waitingForBirth = false;
|
||||
|
||||
#[Serializer\Groups(['docgen:read'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATE_IMMUTABLE, name: 'waiting_for_birth_date', nullable: true, options: ['default' => null])]
|
||||
#[ORM\Column(type: Types::DATE_IMMUTABLE, name: 'waiting_for_birth_date', nullable: true, options: ['default' => null])]
|
||||
#[Assert\Expression('this.getWaitingForBirth() == false or value != null', message: 'The waiting for birth date must be set', groups: ['household_metadata'])]
|
||||
private ?\DateTimeImmutable $waitingForBirthDate = null;
|
||||
|
||||
|
@@ -58,6 +58,16 @@ class HouseholdComposition implements TrackCreationInterface, TrackUpdateInterfa
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER, nullable: true, options: ['default' => null])]
|
||||
private ?int $numberOfChildren = null;
|
||||
|
||||
#[Assert\GreaterThanOrEqual(0, groups: ['Default', 'household_composition'])]
|
||||
#[Serializer\Groups(['docgen:read'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER, nullable: true, options: ['default' => null])]
|
||||
private ?int $numberOfDependents = null;
|
||||
|
||||
#[Assert\GreaterThanOrEqual(0, groups: ['Default', 'household_composition'])]
|
||||
#[Serializer\Groups(['docgen:read'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER, nullable: true, options: ['default' => null])]
|
||||
private ?int $numberOfDependentsWithDisabilities = null;
|
||||
|
||||
#[Assert\NotNull(groups: ['Default', 'household_composition'])]
|
||||
#[Serializer\Groups(['docgen:read'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATE_IMMUTABLE, nullable: false)]
|
||||
@@ -98,6 +108,16 @@ class HouseholdComposition implements TrackCreationInterface, TrackUpdateInterfa
|
||||
return $this->numberOfChildren;
|
||||
}
|
||||
|
||||
public function getNumberOfDependents(): ?int
|
||||
{
|
||||
return $this->numberOfDependents;
|
||||
}
|
||||
|
||||
public function getNumberOfDependentsWithDisabilities(): ?int
|
||||
{
|
||||
return $this->numberOfDependentsWithDisabilities;
|
||||
}
|
||||
|
||||
public function getStartDate(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->startDate;
|
||||
@@ -142,6 +162,20 @@ class HouseholdComposition implements TrackCreationInterface, TrackUpdateInterfa
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setNumberOfDependents(?int $numberOfDependents): HouseholdComposition
|
||||
{
|
||||
$this->numberOfDependents = $numberOfDependents;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setNumberOfDependentsWithDisabilities(?int $numberOfDependentsWithDisabilities): HouseholdComposition
|
||||
{
|
||||
$this->numberOfDependentsWithDisabilities = $numberOfDependentsWithDisabilities;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setStartDate(?\DateTimeImmutable $startDate): HouseholdComposition
|
||||
{
|
||||
$this->startDate = $startDate;
|
||||
|
@@ -29,7 +29,7 @@ class HouseholdCompositionType
|
||||
private ?int $id = null;
|
||||
|
||||
#[Serializer\Groups(['read', 'docgen:read'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON)]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON, options: ['default' => '{}', 'jsonb' => true])]
|
||||
#[Serializer\Context(['is-translatable' => true], groups: ['docgen:read'])]
|
||||
private array $label = [];
|
||||
|
||||
|
@@ -22,7 +22,7 @@ use Doctrine\ORM\Mapping as ORM;
|
||||
class MaritalStatus
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 7)]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 15)]
|
||||
private ?string $id;
|
||||
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON)]
|
||||
|
@@ -21,9 +21,12 @@ use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Entity\Civility;
|
||||
use Chill\MainBundle\Entity\Country;
|
||||
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
|
||||
use Chill\MainBundle\Entity\Gender;
|
||||
use Chill\MainBundle\Entity\HasCenterInterface;
|
||||
use Chill\MainBundle\Entity\Language;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflowSignatureStateEnum;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflowStepSignature;
|
||||
use Chill\MainBundle\Validation\Constraint\PhonenumberConstraint;
|
||||
use Chill\PersonBundle\Entity\Household\Household;
|
||||
use Chill\PersonBundle\Entity\Household\HouseholdMember;
|
||||
@@ -39,6 +42,8 @@ use DateTime;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\Common\Collections\ReadableCollection;
|
||||
use Doctrine\Common\Collections\Selectable;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use libphonenumber\PhoneNumber;
|
||||
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
|
||||
@@ -58,19 +63,11 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
#[HouseholdMembershipSequential(groups: ['household_memberships'])]
|
||||
class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateInterface, \Stringable
|
||||
{
|
||||
final public const BOTH_GENDER = 'both';
|
||||
|
||||
// have days in commun
|
||||
final public const ERROR_ADDIND_PERIOD_AFTER_AN_OPEN_PERIOD = 2; // where there exist
|
||||
|
||||
final public const ERROR_PERIODS_ARE_COLLAPSING = 1; // when two different periods
|
||||
|
||||
final public const FEMALE_GENDER = 'woman';
|
||||
|
||||
final public const MALE_GENDER = 'man';
|
||||
|
||||
final public const NO_INFORMATION = 'unknown';
|
||||
|
||||
/**
|
||||
* Accept receiving email.
|
||||
*/
|
||||
@@ -86,7 +83,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
/**
|
||||
* The person's accompanying periods (when the person was accompanied by the center).
|
||||
*
|
||||
* @var Collection<AccompanyingPeriodParticipation>
|
||||
* @var Collection<int, AccompanyingPeriodParticipation>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: AccompanyingPeriodParticipation::class, mappedBy: 'person', cascade: ['persist', 'remove', 'merge', 'detach'])]
|
||||
#[ORM\OrderBy(['startDate' => Criteria::DESC])]
|
||||
@@ -95,7 +92,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
/**
|
||||
* The accompanying period requested by the Person.
|
||||
*
|
||||
* @var Collection<AccompanyingPeriod>
|
||||
* @var Collection<int, AccompanyingPeriod>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: AccompanyingPeriod::class, mappedBy: 'requestorPerson')]
|
||||
private Collection $accompanyingPeriodRequested;
|
||||
@@ -103,7 +100,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
/**
|
||||
* Addresses.
|
||||
*
|
||||
* @var Collection<Address>
|
||||
* @var Collection<int, Address>
|
||||
*/
|
||||
#[ORM\ManyToMany(targetEntity: Address::class, cascade: ['persist', 'remove', 'merge', 'detach'])]
|
||||
#[ORM\JoinTable(name: 'chill_person_persons_to_addresses')]
|
||||
@@ -111,7 +108,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
private Collection $addresses;
|
||||
|
||||
/**
|
||||
* @var Collection<PersonAltName>
|
||||
* @var Collection<int, PersonAltName>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: PersonAltName::class, mappedBy: 'person', cascade: ['persist', 'remove', 'merge', 'detach'], orphanRemoval: true)]
|
||||
private Collection $altNames;
|
||||
@@ -124,13 +121,13 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
private ?\DateTime $birthdate = null;
|
||||
|
||||
/**
|
||||
* @var Collection<Charge>
|
||||
* @var Collection<int, Charge>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: Charge::class, mappedBy: 'person')]
|
||||
private Collection $budgetCharges;
|
||||
|
||||
/**
|
||||
* @var Collection<resource>
|
||||
* @var Collection<int, \Chill\BudgetBundle\Entity\Resource>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: Resource::class, mappedBy: 'person')]
|
||||
private Collection $budgetResources;
|
||||
@@ -149,14 +146,14 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
#[ORM\ManyToOne(targetEntity: Center::class)]
|
||||
private ?Center $center = null;
|
||||
|
||||
#[ORM\OneToOne(targetEntity: PersonCenterCurrent::class, mappedBy: 'person')]
|
||||
#[ORM\OneToOne(mappedBy: 'person', targetEntity: PersonCenterCurrent::class)]
|
||||
private ?PersonCenterCurrent $centerCurrent = null;
|
||||
|
||||
/**
|
||||
* @var Collection<PersonCenterHistory>
|
||||
* @var Collection<int, PersonCenterHistory>&Selectable
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: PersonCenterHistory::class, mappedBy: 'person', cascade: ['persist', 'remove'])]
|
||||
private Collection $centerHistory;
|
||||
#[ORM\OneToMany(mappedBy: 'person', targetEntity: PersonCenterHistory::class, cascade: ['persist', 'remove'])]
|
||||
private Collection&Selectable $centerHistory;
|
||||
|
||||
/**
|
||||
* Array where customfield's data are stored.
|
||||
@@ -212,7 +209,6 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
/**
|
||||
* The person's deathdate.
|
||||
*/
|
||||
#[Assert\Date]
|
||||
#[Assert\GreaterThanOrEqual(propertyPath: 'birthdate')]
|
||||
#[Assert\LessThanOrEqual('today')]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATE_IMMUTABLE, nullable: true)]
|
||||
@@ -241,11 +237,11 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
private ?string $fullnameCanonical = '';
|
||||
|
||||
/**
|
||||
* The person's gender.
|
||||
* NEW column : The person's gender.
|
||||
*/
|
||||
#[Assert\NotNull(message: 'The gender must be set')]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 9, nullable: true)]
|
||||
private ?string $gender = null;
|
||||
#[ORM\ManyToOne(targetEntity: Gender::class)]
|
||||
private ?Gender $gender = null;
|
||||
|
||||
/**
|
||||
* Comment on gender.
|
||||
@@ -256,13 +252,13 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
/**
|
||||
* Read-only field, computed by the database.
|
||||
*
|
||||
* @var Collection<PersonHouseholdAddress>
|
||||
* @var Collection<int, PersonHouseholdAddress>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: PersonHouseholdAddress::class, mappedBy: 'person')]
|
||||
private Collection $householdAddresses;
|
||||
|
||||
/**
|
||||
* @var Collection<HouseholdMember>
|
||||
* @var Collection<int, HouseholdMember>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: HouseholdMember::class, mappedBy: 'person')]
|
||||
private Collection $householdParticipations;
|
||||
@@ -299,7 +295,6 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
/**
|
||||
* The date of the last marital status change of the person.
|
||||
*/
|
||||
#[Assert\Date]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATE_MUTABLE, nullable: true)]
|
||||
private ?\DateTime $maritalStatusDate = null;
|
||||
|
||||
@@ -309,6 +304,13 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::TEXT)]
|
||||
private string $memo = '';
|
||||
|
||||
/**
|
||||
* The person's administrative status.
|
||||
*/
|
||||
#[ORM\ManyToOne(targetEntity: AdministrativeStatus::class)]
|
||||
#[ORM\JoinColumn(nullable: true)]
|
||||
private ?AdministrativeStatus $administrativeStatus = null;
|
||||
|
||||
/**
|
||||
* The person's mobile phone number.
|
||||
*/
|
||||
@@ -316,6 +318,13 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
#[PhonenumberConstraint(type: 'mobile')]
|
||||
private ?PhoneNumber $mobilenumber = null;
|
||||
|
||||
/**
|
||||
* The person's professional status.
|
||||
*/
|
||||
#[ORM\ManyToOne(targetEntity: EmploymentStatus::class)]
|
||||
#[ORM\JoinColumn(nullable: true)]
|
||||
private ?EmploymentStatus $employmentStatus = null;
|
||||
|
||||
/**
|
||||
* The person's nationality.
|
||||
*/
|
||||
@@ -330,14 +339,14 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
private ?int $numberOfChildren = null;
|
||||
|
||||
/**
|
||||
* @var Collection<PersonPhone>
|
||||
* @var Collection<int, PersonPhone>
|
||||
*/
|
||||
#[Assert\Valid(traverse: true)]
|
||||
#[ORM\OneToMany(targetEntity: PersonPhone::class, mappedBy: 'person', cascade: ['persist', 'remove', 'merge', 'detach'], orphanRemoval: true)]
|
||||
private Collection $otherPhoneNumbers;
|
||||
|
||||
/**
|
||||
* @var Collection<AccompanyingPeriod>
|
||||
* @var Collection<int, AccompanyingPeriod>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: AccompanyingPeriod::class, mappedBy: 'personLocation')]
|
||||
private Collection $periodLocatedOn;
|
||||
@@ -361,7 +370,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::BOOLEAN)]
|
||||
private bool $proxyAccompanyingPeriodOpenState = false; // TO-DELETE ?
|
||||
/**
|
||||
* @var Collection<PersonResource>
|
||||
* @var Collection<int, PersonResource>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: PersonResource::class, mappedBy: 'personOwner')]
|
||||
private Collection $resources;
|
||||
@@ -381,6 +390,12 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
#[ORM\ManyToOne(targetEntity: User::class)]
|
||||
private ?User $updatedBy = null;
|
||||
|
||||
/**
|
||||
* @var Collection<int, EntityWorkflowStepSignature>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: EntityWorkflowStepSignature::class, mappedBy: 'personSigner', orphanRemoval: true)]
|
||||
private Collection $signatures;
|
||||
|
||||
/**
|
||||
* Person constructor.
|
||||
*/
|
||||
@@ -402,6 +417,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
$this->budgetCharges = new ArrayCollection();
|
||||
$this->resources = new ArrayCollection();
|
||||
$this->centerHistory = new ArrayCollection();
|
||||
$this->signatures = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
@@ -473,6 +489,35 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addSignature(EntityWorkflowStepSignature $signature): self
|
||||
{
|
||||
if (!$this->signatures->contains($signature)) {
|
||||
$this->signatures->add($signature);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeSignature(EntityWorkflowStepSignature $signature): self
|
||||
{
|
||||
$this->signatures->removeElement($signature);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ReadableCollection<int, EntityWorkflowStepSignature>
|
||||
*/
|
||||
public function getSignatures(): ReadableCollection
|
||||
{
|
||||
return $this->signatures;
|
||||
}
|
||||
|
||||
public function getSignaturesPending(): ReadableCollection
|
||||
{
|
||||
return $this->signatures->filter(fn (EntityWorkflowStepSignature $signature) => EntityWorkflowSignatureStateEnum::PENDING === $signature->getState());
|
||||
}
|
||||
|
||||
/**
|
||||
* Function used for validation that check if the accompanying periods of
|
||||
* the person are not collapsing (i.e. have not shared days) or having
|
||||
@@ -593,7 +638,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
*/
|
||||
public function getAccompanyingPeriodInvolved(
|
||||
bool $asParticipantOpen = true,
|
||||
bool $asRequestor = true
|
||||
bool $asRequestor = true,
|
||||
): Collection {
|
||||
$result = new ArrayCollection();
|
||||
|
||||
@@ -620,7 +665,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
|
||||
public function countAccompanyingPeriodInvolved(
|
||||
bool $asParticipantOpen = true,
|
||||
bool $asRequestor = true
|
||||
bool $asRequestor = true,
|
||||
): int {
|
||||
// TODO should be optimized to avoid loading accompanying period ?
|
||||
return $this->getAccompanyingPeriodInvolved($asParticipantOpen, $asRequestor)
|
||||
@@ -739,6 +784,11 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
return $this->addresses;
|
||||
}
|
||||
|
||||
public function getAdministrativeStatus(): ?AdministrativeStatus
|
||||
{
|
||||
return $this->administrativeStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the age of a person, calculated at the date 'now'.
|
||||
*
|
||||
@@ -1002,7 +1052,12 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
return $this->fullnameCanonical;
|
||||
}
|
||||
|
||||
public function getGender(): ?string
|
||||
public function getEmploymentStatus(): ?EmploymentStatus
|
||||
{
|
||||
return $this->employmentStatus;
|
||||
}
|
||||
|
||||
public function getGender(): ?Gender
|
||||
{
|
||||
return $this->gender;
|
||||
}
|
||||
@@ -1012,24 +1067,6 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
return $this->genderComment;
|
||||
}
|
||||
|
||||
/**
|
||||
* return gender as a Numeric form.
|
||||
* This is used for translations.
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @deprecated Keep for legacy. Used in Chill 1.5 for feminize before icu translations
|
||||
*/
|
||||
public function getGenderNumeric()
|
||||
{
|
||||
return match ($this->getGender()) {
|
||||
self::FEMALE_GENDER => 1,
|
||||
self::MALE_GENDER => 0,
|
||||
self::BOTH_GENDER => 2,
|
||||
default => -1,
|
||||
};
|
||||
}
|
||||
|
||||
public function getHouseholdAddresses(): Collection
|
||||
{
|
||||
return $this->householdAddresses;
|
||||
@@ -1395,6 +1432,13 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setAdministrativeStatus(?AdministrativeStatus $administrativeStatus): self
|
||||
{
|
||||
$this->administrativeStatus = $administrativeStatus;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setAcceptSMS(bool $acceptSMS): self
|
||||
{
|
||||
$this->acceptSMS = $acceptSMS;
|
||||
@@ -1409,10 +1453,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $birthdate
|
||||
*/
|
||||
public function setBirthdate($birthdate): self
|
||||
public function setBirthdate(?\DateTime $birthdate): self
|
||||
{
|
||||
$this->birthdate = $birthdate;
|
||||
|
||||
@@ -1443,7 +1484,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setCenterHistory(Collection $centerHistory): Person
|
||||
public function setCenterHistory(Collection&Selectable $centerHistory): Person
|
||||
{
|
||||
$this->centerHistory = $centerHistory;
|
||||
|
||||
@@ -1527,20 +1568,27 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setFullnameCanonical($fullnameCanonical): self
|
||||
public function setFullnameCanonical(?string $fullnameCanonical): self
|
||||
{
|
||||
$this->fullnameCanonical = $fullnameCanonical;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setGender(?string $gender): self
|
||||
public function setGender(?Gender $gender): self
|
||||
{
|
||||
$this->gender = $gender;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setEmploymentStatus(?EmploymentStatus $employmentStatus): self
|
||||
{
|
||||
$this->employmentStatus = $employmentStatus;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setGenderComment(CommentEmbeddable $genderComment): self
|
||||
{
|
||||
$this->genderComment = $genderComment;
|
||||
@@ -1636,7 +1684,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
}
|
||||
|
||||
/**
|
||||
* @param (\Doctrine\Common\Collections\Collection<int, Language>) $spokenLanguages
|
||||
* @param (Collection<int, Language>) $spokenLanguages
|
||||
*/
|
||||
public function setSpokenLanguages(Collection $spokenLanguages): self
|
||||
{
|
||||
|
@@ -0,0 +1,198 @@
|
||||
<?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\Person;
|
||||
|
||||
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\MainBundle\Entity\Embeddable\CommentEmbeddable;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Annotation\Groups;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
#[ORM\MappedSuperclass]
|
||||
class AbstractPersonResource implements TrackCreationInterface, TrackUpdateInterface
|
||||
{
|
||||
use TrackCreationTrait;
|
||||
|
||||
use TrackUpdateTrait;
|
||||
|
||||
#[ORM\Embedded(class: CommentEmbeddable::class, columnPrefix: 'comment_')]
|
||||
#[Groups(['read', 'docgen:read'])]
|
||||
private CommentEmbeddable $comment;
|
||||
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
|
||||
#[Groups(['read', 'docgen:read'])]
|
||||
private ?string $freeText = null;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: PersonResourceKind::class, inversedBy: 'personResources')]
|
||||
#[ORM\JoinColumn(nullable: true)]
|
||||
#[Groups(['read', 'docgen:read'])]
|
||||
private ?PersonResourceKind $kind = null;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: Person::class)]
|
||||
#[ORM\JoinColumn(nullable: true)]
|
||||
#[Groups(['read', 'docgen:read'])]
|
||||
private ?Person $person = null;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: Person::class, inversedBy: 'resources')]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
#[Groups(['read'])]
|
||||
private ?Person $personOwner = null;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: ThirdParty::class, inversedBy: 'personResources')]
|
||||
#[ORM\JoinColumn(nullable: true)]
|
||||
#[Groups(['read', 'docgen:read'])]
|
||||
private ?ThirdParty $thirdParty = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->comment = new CommentEmbeddable();
|
||||
}
|
||||
|
||||
public function getComment(): CommentEmbeddable
|
||||
{
|
||||
return $this->comment;
|
||||
}
|
||||
|
||||
public function getFreeText(): ?string
|
||||
{
|
||||
return $this->freeText;
|
||||
}
|
||||
|
||||
public function getKind(): ?PersonResourceKind
|
||||
{
|
||||
return $this->kind;
|
||||
}
|
||||
|
||||
public function getPerson(): ?Person
|
||||
{
|
||||
return $this->person;
|
||||
}
|
||||
|
||||
public function getPersonOwner(): ?Person
|
||||
{
|
||||
return $this->personOwner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Groups({"read", "docgen:read"})
|
||||
*/
|
||||
public function getResourceKind(): string
|
||||
{
|
||||
if ($this->getPerson() instanceof Person) {
|
||||
return 'person';
|
||||
}
|
||||
|
||||
if ($this->getThirdParty() instanceof ThirdParty) {
|
||||
return 'thirdparty';
|
||||
}
|
||||
|
||||
if (null !== $this->getFreeText()) {
|
||||
return 'freetext';
|
||||
}
|
||||
|
||||
return 'none';
|
||||
}
|
||||
|
||||
public function getThirdParty(): ?ThirdParty
|
||||
{
|
||||
return $this->thirdParty;
|
||||
}
|
||||
|
||||
public function setComment(?CommentEmbeddable $comment): self
|
||||
{
|
||||
if (null === $comment) {
|
||||
$this->comment->setComment('');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->comment = $comment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setFreeText(?string $freeText): self
|
||||
{
|
||||
$this->freeText = $freeText;
|
||||
|
||||
if ('' !== $freeText && null !== $freeText) {
|
||||
$this->setPerson(null);
|
||||
$this->setThirdParty(null);
|
||||
}
|
||||
|
||||
if ('' === $freeText) {
|
||||
$this->freeText = null;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setKind(?PersonResourceKind $kind): self
|
||||
{
|
||||
$this->kind = $kind;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setPerson(?Person $person): self
|
||||
{
|
||||
$this->person = $person;
|
||||
|
||||
if (null !== $person) {
|
||||
$this->setFreeText('');
|
||||
$this->setThirdParty(null);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setPersonOwner(?Person $personOwner): self
|
||||
{
|
||||
$this->personOwner = $personOwner;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setThirdParty(?ThirdParty $thirdParty): self
|
||||
{
|
||||
$this->thirdParty = $thirdParty;
|
||||
|
||||
if (null !== $thirdParty) {
|
||||
$this->setFreeText('');
|
||||
$this->setPerson(null);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Assert\Callback
|
||||
*/
|
||||
public function validate(ExecutionContextInterface $context, mixed $payload): void
|
||||
{
|
||||
if (null === $this->person && null === $this->thirdParty && (null === $this->freeText || '' === $this->freeText)) {
|
||||
$context->buildViolation('You must associate at least one entity')
|
||||
->addViolation();
|
||||
}
|
||||
|
||||
if (null !== $this->person && $this->person === $this->personOwner) {
|
||||
$context->buildViolation('You cannot associate a resource with the same person')
|
||||
->addViolation();
|
||||
}
|
||||
}
|
||||
}
|
@@ -44,7 +44,7 @@ class PersonCenterHistory implements TrackCreationInterface, TrackUpdateInterfac
|
||||
#[ORM\ManyToOne(targetEntity: Center::class)]
|
||||
private ?Center $center = null,
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATE_IMMUTABLE, nullable: false)]
|
||||
private ?\DateTimeImmutable $startDate = null
|
||||
private ?\DateTimeImmutable $startDate = null,
|
||||
) {}
|
||||
|
||||
public function getCenter(): ?Center
|
||||
|
@@ -12,206 +12,24 @@ declare(strict_types=1);
|
||||
namespace Chill\PersonBundle\Entity\Person;
|
||||
|
||||
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\MainBundle\Entity\Embeddable\CommentEmbeddable;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
use Symfony\Component\Serializer\Annotation\Groups;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
|
||||
#[Serializer\DiscriminatorMap(typeProperty: 'type', mapping: ['personResource' => PersonResource::class])]
|
||||
#[ORM\Entity]
|
||||
#[ORM\Table(name: 'chill_person_resource')]
|
||||
class PersonResource implements TrackCreationInterface, TrackUpdateInterface
|
||||
class PersonResource extends AbstractPersonResource implements TrackCreationInterface, TrackUpdateInterface
|
||||
{
|
||||
use TrackCreationTrait;
|
||||
|
||||
use TrackUpdateTrait;
|
||||
|
||||
#[Groups(['read', 'docgen:read'])]
|
||||
#[ORM\Embedded(class: CommentEmbeddable::class, columnPrefix: 'comment_')]
|
||||
private CommentEmbeddable $comment;
|
||||
|
||||
#[Groups(['read', 'docgen:read'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
|
||||
private ?string $freeText = null;
|
||||
|
||||
#[Groups(['read', 'docgen:read'])]
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER)]
|
||||
private ?int $id = null;
|
||||
|
||||
#[Groups(['read', 'docgen:read'])]
|
||||
#[ORM\ManyToOne(targetEntity: PersonResourceKind::class, inversedBy: 'personResources')]
|
||||
#[ORM\JoinColumn(nullable: true)]
|
||||
private ?PersonResourceKind $kind = null;
|
||||
|
||||
/**
|
||||
* The person which host the owner of this resource.
|
||||
*/
|
||||
#[Groups(['read', 'docgen:read'])]
|
||||
#[ORM\ManyToOne(targetEntity: Person::class)]
|
||||
#[ORM\JoinColumn(nullable: true)]
|
||||
private ?Person $person = null;
|
||||
|
||||
/**
|
||||
* The person linked with this resource.
|
||||
*/
|
||||
#[Groups(['read'])]
|
||||
#[ORM\ManyToOne(targetEntity: Person::class, inversedBy: 'resources')]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private ?Person $personOwner = null;
|
||||
|
||||
#[Groups(['read', 'docgen:read'])]
|
||||
#[ORM\ManyToOne(targetEntity: ThirdParty::class, inversedBy: 'personResources')]
|
||||
#[ORM\JoinColumn(nullable: true)]
|
||||
private ?ThirdParty $thirdParty = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->comment = new CommentEmbeddable();
|
||||
}
|
||||
|
||||
public function getComment(): CommentEmbeddable
|
||||
{
|
||||
return $this->comment;
|
||||
}
|
||||
|
||||
public function getFreeText(): ?string
|
||||
{
|
||||
return $this->freeText;
|
||||
}
|
||||
|
||||
/**
|
||||
* GETTERS.
|
||||
*/
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getKind(): ?PersonResourceKind
|
||||
{
|
||||
return $this->kind;
|
||||
}
|
||||
|
||||
public function getPerson(): ?Person
|
||||
{
|
||||
return $this->person;
|
||||
}
|
||||
|
||||
public function getPersonOwner(): ?Person
|
||||
{
|
||||
return $this->personOwner;
|
||||
}
|
||||
|
||||
#[Groups(['read', 'docgen:read'])]
|
||||
public function getResourceKind(): string
|
||||
{
|
||||
if ($this->getPerson() instanceof Person) {
|
||||
return 'person';
|
||||
}
|
||||
|
||||
if ($this->getThirdParty() instanceof ThirdParty) {
|
||||
return 'thirdparty';
|
||||
}
|
||||
|
||||
if (null !== $this->getFreeText()) {
|
||||
return 'freetext';
|
||||
}
|
||||
|
||||
return 'none';
|
||||
}
|
||||
|
||||
public function getThirdParty(): ?ThirdParty
|
||||
{
|
||||
return $this->thirdParty;
|
||||
}
|
||||
|
||||
public function setComment(?CommentEmbeddable $comment): self
|
||||
{
|
||||
if (null === $comment) {
|
||||
$this->comment->setComment('');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->comment = $comment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setFreeText(?string $freeText): self
|
||||
{
|
||||
$this->freeText = $freeText;
|
||||
|
||||
if ('' !== $freeText && null !== $freeText) {
|
||||
$this->setPerson(null);
|
||||
$this->setThirdParty(null);
|
||||
}
|
||||
|
||||
if ('' === $freeText) {
|
||||
$this->freeText = null;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setKind(?PersonResourceKind $kind): self
|
||||
{
|
||||
$this->kind = $kind;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setPerson(?Person $person): self
|
||||
{
|
||||
$this->person = $person;
|
||||
|
||||
if (null !== $person) {
|
||||
$this->setFreeText('');
|
||||
$this->setThirdParty(null);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setPersonOwner(?Person $personOwner): self
|
||||
{
|
||||
$this->personOwner = $personOwner;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setThirdParty(?ThirdParty $thirdParty): self
|
||||
{
|
||||
$this->thirdParty = $thirdParty;
|
||||
|
||||
if (null !== $thirdParty) {
|
||||
$this->setFreeText('');
|
||||
$this->setPerson(null);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Assert\Callback]
|
||||
public function validate(ExecutionContextInterface $context, mixed $payload)
|
||||
{
|
||||
if (null === $this->person && null === $this->thirdParty && (null === $this->freeText || '' === $this->freeText)) {
|
||||
$context->buildViolation('You must associate at least one entity')
|
||||
->addViolation();
|
||||
}
|
||||
|
||||
if (null !== $this->person && $this->person === $this->personOwner) {
|
||||
$context->buildViolation('You cannot associate a resource with the same person')
|
||||
->addViolation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -76,7 +76,7 @@ class PersonNotDuplicate
|
||||
$this->date = $date;
|
||||
}
|
||||
|
||||
public function setId($id)
|
||||
public function setId(?int $id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
@@ -20,7 +20,6 @@ use libphonenumber\PhoneNumber;
|
||||
#[ORM\Entity]
|
||||
#[ORM\Table(name: 'chill_person_phone')]
|
||||
#[ORM\Index(name: 'phonenumber', columns: ['phonenumber'])]
|
||||
#[ORM\Index(name: 'phonenumber', columns: ['phonenumber'])]
|
||||
class PersonPhone
|
||||
{
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATETIME_MUTABLE, nullable: false)]
|
||||
@@ -37,7 +36,12 @@ class PersonPhone
|
||||
#[ORM\ManyToOne(targetEntity: Person::class, inversedBy: 'otherPhoneNumbers')]
|
||||
private Person $person;
|
||||
|
||||
#[ORM\Column(type: 'phone_number', nullable: false)]
|
||||
/**
|
||||
* The phonenumber.
|
||||
*
|
||||
* This phonenumber is nullable: this allow user to store some notes instead of a phonenumber
|
||||
*/
|
||||
#[ORM\Column(type: 'phone_number', nullable: true)]
|
||||
private ?PhoneNumber $phonenumber = null;
|
||||
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::TEXT, length: 40, nullable: true)]
|
||||
|
@@ -27,7 +27,7 @@ class Relation
|
||||
private ?int $id = null;
|
||||
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::BOOLEAN, nullable: true)]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::BOOLEAN, options: ['default' => true])]
|
||||
private bool $isActive = true;
|
||||
|
||||
#[Serializer\Groups(['read'])]
|
||||
|
@@ -39,7 +39,7 @@ class Evaluation
|
||||
private ?\DateInterval $notificationDelay = null;
|
||||
|
||||
/**
|
||||
* @var Collection<SocialAction>
|
||||
* @var Collection<int, SocialAction>
|
||||
*/
|
||||
#[ORM\ManyToMany(targetEntity: SocialAction::class, mappedBy: 'evaluations')]
|
||||
private Collection $socialActions;
|
||||
|
@@ -31,14 +31,14 @@ class Goal
|
||||
private ?int $id = null;
|
||||
|
||||
/**
|
||||
* @var Collection<Result>
|
||||
* @var Collection<int, Result>
|
||||
*/
|
||||
#[ORM\ManyToMany(targetEntity: Result::class, inversedBy: 'goals')]
|
||||
#[ORM\JoinTable(name: 'chill_person_social_work_goal_result')]
|
||||
private Collection $results;
|
||||
|
||||
/**
|
||||
* @var Collection<SocialAction>
|
||||
* @var Collection<int, SocialAction>
|
||||
*/
|
||||
#[ORM\ManyToMany(targetEntity: SocialAction::class, mappedBy: 'goals')]
|
||||
private Collection $socialActions;
|
||||
|
@@ -24,13 +24,13 @@ use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
class Result
|
||||
{
|
||||
/**
|
||||
* @var Collection<AccompanyingPeriodWorkGoal>
|
||||
* @var Collection<int, AccompanyingPeriodWorkGoal>
|
||||
*/
|
||||
#[ORM\ManyToMany(targetEntity: AccompanyingPeriodWorkGoal::class, mappedBy: 'results')]
|
||||
private Collection $accompanyingPeriodWorkGoals;
|
||||
|
||||
/**
|
||||
* @var Collection<AccompanyingPeriodWork>
|
||||
* @var Collection<int, AccompanyingPeriodWork>
|
||||
*/
|
||||
#[ORM\ManyToMany(targetEntity: AccompanyingPeriodWork::class, mappedBy: 'results')]
|
||||
private Collection $accompanyingPeriodWorks;
|
||||
@@ -39,7 +39,7 @@ class Result
|
||||
private ?\DateTime $desactivationDate = null;
|
||||
|
||||
/**
|
||||
* @var Collection<Goal>
|
||||
* @var Collection<int, Goal>
|
||||
*/
|
||||
#[ORM\ManyToMany(targetEntity: Goal::class, mappedBy: 'results')]
|
||||
private Collection $goals;
|
||||
@@ -51,7 +51,7 @@ class Result
|
||||
private ?int $id = null;
|
||||
|
||||
/**
|
||||
* @var Collection<SocialAction>
|
||||
* @var Collection<int, SocialAction>
|
||||
*/
|
||||
#[ORM\ManyToMany(targetEntity: SocialAction::class, mappedBy: 'results')]
|
||||
private Collection $socialActions;
|
||||
|
@@ -23,9 +23,9 @@ use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
class SocialAction
|
||||
{
|
||||
/**
|
||||
* @var Collection<SocialAction>
|
||||
* @var Collection<int, SocialAction>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: SocialAction::class, mappedBy: 'parent')]
|
||||
#[ORM\OneToMany(mappedBy: 'parent', targetEntity: SocialAction::class)]
|
||||
private Collection $children;
|
||||
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATEINTERVAL, nullable: true)]
|
||||
@@ -35,14 +35,14 @@ class SocialAction
|
||||
private ?\DateTimeInterface $desactivationDate = null;
|
||||
|
||||
/**
|
||||
* @var Collection<Evaluation>
|
||||
* @var Collection<int, Evaluation>
|
||||
*/
|
||||
#[ORM\ManyToMany(targetEntity: Evaluation::class, inversedBy: 'socialActions')]
|
||||
#[ORM\JoinTable(name: 'chill_person_social_work_evaluation_action')]
|
||||
private Collection $evaluations;
|
||||
|
||||
/**
|
||||
* @var Collection<Goal>
|
||||
* @var Collection<int, Goal>
|
||||
*/
|
||||
#[ORM\ManyToMany(targetEntity: Goal::class, inversedBy: 'socialActions')]
|
||||
#[ORM\JoinTable(name: 'chill_person_social_action_goal')]
|
||||
@@ -63,7 +63,7 @@ class SocialAction
|
||||
private ?SocialAction $parent = null;
|
||||
|
||||
/**
|
||||
* @var Collection<Result>
|
||||
* @var Collection<int, Result>
|
||||
*/
|
||||
#[ORM\ManyToMany(targetEntity: Result::class, inversedBy: 'socialActions')]
|
||||
#[ORM\JoinTable(name: 'chill_person_social_action_result')]
|
||||
@@ -403,7 +403,7 @@ class SocialAction
|
||||
|
||||
return match ($actions instanceof ReadableCollection) {
|
||||
true => $actions->filter($filterFn),
|
||||
false => array_filter($actions, $filterFn)
|
||||
false => array_filter($actions, $filterFn),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -13,6 +13,7 @@ namespace Chill\PersonBundle\Entity\SocialWork;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
|
||||
use Symfony\Component\Serializer\Annotation\Groups;
|
||||
@@ -23,33 +24,33 @@ use Symfony\Component\Serializer\Annotation\Groups;
|
||||
class SocialIssue
|
||||
{
|
||||
/**
|
||||
* @var Collection<SocialIssue>
|
||||
* @var Collection<int, SocialIssue>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: SocialIssue::class, mappedBy: 'parent')]
|
||||
#[ORM\OneToMany(mappedBy: 'parent', targetEntity: SocialIssue::class)]
|
||||
private Collection $children;
|
||||
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATETIME_MUTABLE, nullable: true)]
|
||||
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
|
||||
private ?\DateTimeInterface $desactivationDate = null;
|
||||
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER)]
|
||||
#[ORM\Column(type: Types::INTEGER)]
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::FLOAT, name: 'ordering', options: ['default' => '0.0'])]
|
||||
#[ORM\Column(name: 'ordering', type: Types::FLOAT, options: ['default' => '0.0'])]
|
||||
private float $ordering = 0.0;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: SocialIssue::class, inversedBy: 'children')]
|
||||
private ?SocialIssue $parent = null;
|
||||
|
||||
/**
|
||||
* @var Collection<SocialAction>
|
||||
* @var Collection<int, SocialAction>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: SocialAction::class, mappedBy: 'issue')]
|
||||
#[ORM\OneToMany(mappedBy: 'issue', targetEntity: SocialAction::class)]
|
||||
private Collection $socialActions;
|
||||
|
||||
#[Groups(['read'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON)]
|
||||
#[ORM\Column(type: Types::JSON)]
|
||||
private array $title = [];
|
||||
|
||||
public function __construct()
|
||||
|
@@ -26,7 +26,7 @@ class CreatorJobAggregator implements AggregatorInterface
|
||||
|
||||
public function __construct(
|
||||
private readonly UserJobRepository $jobRepository,
|
||||
private readonly TranslatableStringHelper $translatableStringHelper
|
||||
private readonly TranslatableStringHelper $translatableStringHelper,
|
||||
) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
|
@@ -20,13 +20,13 @@ use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
final class OriginAggregator implements AggregatorInterface
|
||||
final readonly class OriginAggregator implements AggregatorInterface
|
||||
{
|
||||
private readonly EntityRepository $repository;
|
||||
private EntityRepository $repository;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
private readonly TranslatableStringHelper $translatableStringHelper
|
||||
private TranslatableStringHelper $translatableStringHelper,
|
||||
) {
|
||||
$this->repository = $em->getRepository(Origin::class);
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@ declare(strict_types=1);
|
||||
namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
|
||||
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\MainBundle\Export\DataTransformerInterface;
|
||||
use Chill\MainBundle\Form\Type\PickRollingDateType;
|
||||
use Chill\MainBundle\Repository\UserRepository;
|
||||
use Chill\MainBundle\Service\RollingDate\RollingDate;
|
||||
@@ -21,13 +22,17 @@ use Chill\PersonBundle\Export\Declarations;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
final readonly class ReferrerAggregator implements AggregatorInterface
|
||||
final readonly class ReferrerAggregator implements AggregatorInterface, DataTransformerInterface
|
||||
{
|
||||
private const A = 'acp_ref_agg_uhistory';
|
||||
|
||||
private const P = 'acp_ref_agg_date';
|
||||
|
||||
public function __construct(private UserRepository $userRepository, private UserRender $userRender, private RollingDateConverterInterface $rollingDateConverter) {}
|
||||
public function __construct(
|
||||
private UserRepository $userRepository,
|
||||
private UserRender $userRender,
|
||||
private RollingDateConverterInterface $rollingDateConverter,
|
||||
) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
{
|
||||
@@ -44,18 +49,16 @@ final readonly class ReferrerAggregator implements AggregatorInterface
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull(self::A),
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->lte(self::A.'.startDate', ':'.self::P),
|
||||
$qb->expr()->lt(self::A.'.startDate', ':'.self::P.'_end_date'),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull(self::A.'.endDate'),
|
||||
$qb->expr()->gt(self::A.'.endDate', ':'.self::P)
|
||||
$qb->expr()->gte(self::A.'.endDate', ':'.self::P.'_start_date')
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
->setParameter(
|
||||
self::P,
|
||||
$this->rollingDateConverter->convert($data['date_calc'])
|
||||
);
|
||||
->setParameter(':'.self::P.'_end_date', $this->rollingDateConverter->convert($data['end_date']))
|
||||
->setParameter(':'.self::P.'_start_date', $this->rollingDateConverter->convert($data['end_date']));
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
@@ -66,15 +69,37 @@ final readonly class ReferrerAggregator implements AggregatorInterface
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder
|
||||
->add('date_calc', PickRollingDateType::class, [
|
||||
'label' => 'export.aggregator.course.by_referrer.Computation date for referrer',
|
||||
->add('start_date', PickRollingDateType::class, [
|
||||
'label' => 'export.aggregator.course.by_referrer.Referrer after',
|
||||
'required' => true,
|
||||
])
|
||||
->add('end_date', PickRollingDateType::class, [
|
||||
'label' => 'export.aggregator.course.by_referrer.Until',
|
||||
'required' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getFormDefaultData(): array
|
||||
{
|
||||
return ['date_calc' => new RollingDate(RollingDate::T_TODAY)];
|
||||
return [
|
||||
'start_date' => new RollingDate(RollingDate::T_YEAR_CURRENT_START),
|
||||
'end_date' => new RollingDate(RollingDate::T_TODAY),
|
||||
];
|
||||
}
|
||||
|
||||
public function transformData(?array $before): array
|
||||
{
|
||||
$default = $this->getFormDefaultData();
|
||||
$data = [];
|
||||
|
||||
if (null === $before) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$data['start_date'] = $before['date_calc'] ?? $before['start_date'] ?? $default['start_date'];
|
||||
$data['end_date'] = $before['date_calc'] ?? $before['end_date'] ?? $default['end_date'];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
|
@@ -13,20 +13,25 @@ namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
|
||||
|
||||
use Chill\MainBundle\Entity\User\UserScopeHistory;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\MainBundle\Export\DataTransformerInterface;
|
||||
use Chill\MainBundle\Form\Type\PickRollingDateType;
|
||||
use Chill\MainBundle\Repository\ScopeRepositoryInterface;
|
||||
use Chill\MainBundle\Service\RollingDate\RollingDate;
|
||||
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Doctrine\ORM\Query\Expr\Join;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
readonly class ReferrerScopeAggregator implements AggregatorInterface
|
||||
readonly class ReferrerScopeAggregator implements AggregatorInterface, DataTransformerInterface
|
||||
{
|
||||
private const PREFIX = 'acp_agg_referrer_scope';
|
||||
|
||||
public function __construct(
|
||||
private ScopeRepositoryInterface $scopeRepository,
|
||||
private TranslatableStringHelperInterface $translatableStringHelper,
|
||||
private RollingDateConverterInterface $rollingDateConverter,
|
||||
) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
@@ -45,13 +50,9 @@ readonly class ReferrerScopeAggregator implements AggregatorInterface
|
||||
Join::WITH,
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->eq("{$p}_userHistory.accompanyingPeriod", 'acp.id'),
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->gte('COALESCE(acp.closingDate, CURRENT_TIMESTAMP())', "{$p}_userHistory.startDate"),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull("{$p}_userHistory.endDate"),
|
||||
$qb->expr()->lt('COALESCE(acp.closingDate, CURRENT_TIMESTAMP())', "{$p}_userHistory.endDate")
|
||||
)
|
||||
)
|
||||
// check that the user is referrer when the accompanying period is opened
|
||||
"OVERLAPSI (acp.openingDate, acp.closingDate), ({$p}_userHistory.startDate, {$p}_userHistory.endDate) = TRUE",
|
||||
"OVERLAPSI (:{$p}_startDate, :{$p}_endDate), ({$p}_userHistory.startDate, {$p}_userHistory.endDate) = TRUE"
|
||||
)
|
||||
)
|
||||
->leftJoin(
|
||||
@@ -59,16 +60,13 @@ readonly class ReferrerScopeAggregator implements AggregatorInterface
|
||||
"{$p}_scopeHistory",
|
||||
Join::WITH,
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->eq("{$p}_scopeHistory.user", "{$p}_userHistory.user"),
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->lte("{$p}_scopeHistory.startDate", "{$p}_userHistory.startDate"),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull("{$p}_scopeHistory.endDate"),
|
||||
$qb->expr()->gt("{$p}_scopeHistory.endDate", "{$p}_userHistory.startDate")
|
||||
)
|
||||
)
|
||||
"{$p}_scopeHistory.user = {$p}_userHistory.user",
|
||||
"OVERLAPSI ({$p}_scopeHistory.startDate, {$p}_scopeHistory.endDate), ({$p}_userHistory.startDate, {$p}_userHistory.endDate) = TRUE",
|
||||
"OVERLAPSI (:{$p}_startDate, :{$p}_endDate), ({$p}_userHistory.startDate, {$p}_userHistory.endDate) = TRUE"
|
||||
)
|
||||
)
|
||||
->setParameter("{$p}_startDate", $this->rollingDateConverter->convert($data['start_date']))
|
||||
->setParameter("{$p}_endDate", $this->rollingDateConverter->convert($data['end_date']))
|
||||
->addSelect("IDENTITY({$p}_scopeHistory.scope) AS {$p}_select")
|
||||
->addGroupBy("{$p}_select");
|
||||
}
|
||||
@@ -78,11 +76,36 @@ readonly class ReferrerScopeAggregator implements AggregatorInterface
|
||||
return Declarations::ACP_TYPE;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder) {}
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder
|
||||
->add('start_date', PickRollingDateType::class, [
|
||||
'label' => 'export.aggregator.course.by_referrer_scope.Referrer and scope after',
|
||||
'required' => true,
|
||||
])
|
||||
->add('end_date', PickRollingDateType::class, [
|
||||
'label' => 'export.aggregator.course.by_referrer_scope.Until',
|
||||
'required' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getFormDefaultData(): array
|
||||
{
|
||||
return [];
|
||||
return [
|
||||
'start_date' => new RollingDate(RollingDate::T_YEAR_CURRENT_START),
|
||||
'end_date' => new RollingDate(RollingDate::T_TODAY),
|
||||
];
|
||||
}
|
||||
|
||||
public function transformData(?array $before): array
|
||||
{
|
||||
$default = $this->getFormDefaultData();
|
||||
$data = [];
|
||||
|
||||
$data['start_date'] = $before['start_date'] ?? new RollingDate(RollingDate::T_FIXED_DATE, new \DateTimeImmutable('1970-01-01'));
|
||||
$data['end_date'] = $before['end_date'] ?? $default['end_date'];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
|
@@ -13,20 +13,25 @@ namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
|
||||
|
||||
use Chill\MainBundle\Entity\User\UserJobHistory;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\MainBundle\Export\DataTransformerInterface;
|
||||
use Chill\MainBundle\Form\Type\PickRollingDateType;
|
||||
use Chill\MainBundle\Repository\UserJobRepository;
|
||||
use Chill\MainBundle\Service\RollingDate\RollingDate;
|
||||
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Doctrine\ORM\Query\Expr\Join;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
final readonly class UserJobAggregator implements AggregatorInterface
|
||||
final readonly class UserJobAggregator implements AggregatorInterface, DataTransformerInterface
|
||||
{
|
||||
private const PREFIX = 'acp_agg_user_job';
|
||||
|
||||
public function __construct(
|
||||
private UserJobRepository $jobRepository,
|
||||
private TranslatableStringHelper $translatableStringHelper
|
||||
private TranslatableStringHelper $translatableStringHelper,
|
||||
private RollingDateConverterInterface $rollingDateConverter,
|
||||
) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
@@ -45,13 +50,9 @@ final readonly class UserJobAggregator implements AggregatorInterface
|
||||
Join::WITH,
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->eq("{$p}_userHistory.accompanyingPeriod", 'acp.id'),
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->gte('COALESCE(acp.closingDate, CURRENT_TIMESTAMP())', "{$p}_userHistory.startDate"),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull("{$p}_userHistory.endDate"),
|
||||
$qb->expr()->lt('COALESCE(acp.closingDate, CURRENT_TIMESTAMP())', "{$p}_userHistory.endDate")
|
||||
)
|
||||
)
|
||||
// check that the user is referrer when the accompanying period is opened
|
||||
"OVERLAPSI (acp.openingDate, acp.closingDate), ({$p}_userHistory.startDate, {$p}_userHistory.endDate) = TRUE",
|
||||
"OVERLAPSI (:{$p}_startDate, :{$p}_endDate), ({$p}_userHistory.startDate, {$p}_userHistory.endDate) = TRUE"
|
||||
)
|
||||
)
|
||||
->leftJoin(
|
||||
@@ -59,16 +60,13 @@ final readonly class UserJobAggregator implements AggregatorInterface
|
||||
"{$p}_jobHistory",
|
||||
Join::WITH,
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->eq("{$p}_jobHistory.user", "{$p}_userHistory.user"),
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->lte("{$p}_jobHistory.startDate", "{$p}_userHistory.startDate"),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull("{$p}_jobHistory.endDate"),
|
||||
$qb->expr()->gt("{$p}_jobHistory.endDate", "{$p}_userHistory.startDate")
|
||||
)
|
||||
)
|
||||
"{$p}_jobHistory.user = {$p}_userHistory.user",
|
||||
"OVERLAPSI ({$p}_jobHistory.startDate, {$p}_jobHistory.endDate), ({$p}_userHistory.startDate, {$p}_userHistory.endDate) = TRUE",
|
||||
"OVERLAPSI (:{$p}_startDate, :{$p}_endDate), ({$p}_jobHistory.startDate, {$p}_jobHistory.endDate) = TRUE"
|
||||
)
|
||||
)
|
||||
->setParameter("{$p}_startDate", $this->rollingDateConverter->convert($data['start_date']))
|
||||
->setParameter("{$p}_endDate", $this->rollingDateConverter->convert($data['end_date']))
|
||||
->addSelect("IDENTITY({$p}_jobHistory.job) AS {$p}_select")
|
||||
->addGroupBy("{$p}_select");
|
||||
}
|
||||
@@ -78,11 +76,36 @@ final readonly class UserJobAggregator implements AggregatorInterface
|
||||
return Declarations::ACP_TYPE;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder) {}
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder
|
||||
->add('start_date', PickRollingDateType::class, [
|
||||
'label' => 'export.aggregator.course.by_referrer_job.Referrer and job after',
|
||||
'required' => true,
|
||||
])
|
||||
->add('end_date', PickRollingDateType::class, [
|
||||
'label' => 'export.aggregator.course.by_referrer_job.Until',
|
||||
'required' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getFormDefaultData(): array
|
||||
{
|
||||
return [];
|
||||
return [
|
||||
'start_date' => new RollingDate(RollingDate::T_YEAR_CURRENT_START),
|
||||
'end_date' => new RollingDate(RollingDate::T_TODAY),
|
||||
];
|
||||
}
|
||||
|
||||
public function transformData(?array $before): array
|
||||
{
|
||||
$default = $this->getFormDefaultData();
|
||||
$data = [];
|
||||
|
||||
$data['start_date'] = $before['start_date'] ?? new RollingDate(RollingDate::T_FIXED_DATE, new \DateTimeImmutable('1970-01-01'));
|
||||
$data['end_date'] = $before['end_date'] ?? $default['end_date'];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
|
@@ -26,7 +26,7 @@ final readonly class ByStepAggregator implements AggregatorInterface
|
||||
private const KEY = 'acpstephistory_step_agg';
|
||||
|
||||
public function __construct(
|
||||
private TranslatorInterface $translator
|
||||
private TranslatorInterface $translator,
|
||||
) {}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
|
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Export\Aggregator\PersonAggregators;
|
||||
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Chill\PersonBundle\Repository\AdministrativeStatusRepository;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
final readonly class AdministrativeStatusAggregator implements AggregatorInterface
|
||||
{
|
||||
public function __construct(private AdministrativeStatusRepository $administrativeStatusRepository, private TranslatableStringHelper $translatableStringHelper) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$qb->leftJoin('person.administrativeStatus', 'admin_status');
|
||||
$qb->addSelect('admin_status.id as administrative_status_aggregator');
|
||||
|
||||
$qb->addGroupBy('administrative_status_aggregator');
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
{
|
||||
return Declarations::PERSON_TYPE;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder) {}
|
||||
|
||||
public function getFormDefaultData(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
return function ($value): string {
|
||||
if ('_header' === $value) {
|
||||
return 'Administrative status';
|
||||
}
|
||||
|
||||
if (null === $value || '' === $value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$g = $this->administrativeStatusRepository->find($value);
|
||||
|
||||
return $this->translatableStringHelper->localize($g->getName());
|
||||
};
|
||||
}
|
||||
|
||||
public function getQueryKeys($data)
|
||||
{
|
||||
return ['administrative_status_aggregator'];
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return 'Group people by administrative status';
|
||||
}
|
||||
}
|
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Export\Aggregator\PersonAggregators;
|
||||
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Chill\PersonBundle\Repository\EmploymentStatusRepository;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
final readonly class EmploymentStatusAggregator implements AggregatorInterface
|
||||
{
|
||||
public function __construct(private EmploymentStatusRepository $employmentStatusRepository, private TranslatableStringHelper $translatableStringHelper) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$qb->leftJoin('person.employmentStatus', 'es');
|
||||
$qb->addSelect('es.id as employment_status_aggregator');
|
||||
|
||||
$qb->addGroupBy('employment_status_aggregator');
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
{
|
||||
return Declarations::PERSON_TYPE;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder) {}
|
||||
|
||||
public function getFormDefaultData(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
return function ($value): string {
|
||||
if ('_header' === $value) {
|
||||
return 'Employment status';
|
||||
}
|
||||
|
||||
if (null === $value || '' === $value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$g = $this->employmentStatusRepository->find($value);
|
||||
|
||||
return $this->translatableStringHelper->localize($g->getName());
|
||||
};
|
||||
}
|
||||
|
||||
public function getQueryKeys($data)
|
||||
{
|
||||
return ['employment_status_aggregator'];
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return 'Group people by employment status';
|
||||
}
|
||||
}
|
@@ -12,7 +12,8 @@ declare(strict_types=1);
|
||||
namespace Chill\PersonBundle\Export\Aggregator\PersonAggregators;
|
||||
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\MainBundle\Repository\GenderRepository;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
@@ -20,7 +21,7 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
final readonly class GenderAggregator implements AggregatorInterface
|
||||
{
|
||||
public function __construct(private TranslatorInterface $translator) {}
|
||||
public function __construct(private TranslatorInterface $translator, private TranslatableStringHelperInterface $translatableStringHelper, private GenderRepository $repository) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
{
|
||||
@@ -29,7 +30,8 @@ final readonly class GenderAggregator implements AggregatorInterface
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$qb->addSelect('person.gender as gender');
|
||||
$qb->leftJoin('person.gender', 'g');
|
||||
$qb->addSelect('g.id as gender');
|
||||
|
||||
$qb->addGroupBy('gender');
|
||||
}
|
||||
@@ -48,30 +50,20 @@ final readonly class GenderAggregator implements AggregatorInterface
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
return function ($value) {
|
||||
switch ($value) {
|
||||
case Person::FEMALE_GENDER:
|
||||
return $this->translator->trans('woman');
|
||||
|
||||
case Person::MALE_GENDER:
|
||||
return $this->translator->trans('man');
|
||||
|
||||
case Person::BOTH_GENDER:
|
||||
return $this->translator->trans('both');
|
||||
|
||||
case Person::NO_INFORMATION:
|
||||
return $this->translator->trans('unknown');
|
||||
|
||||
case null:
|
||||
case '':
|
||||
return $this->translator->trans('Not given');
|
||||
|
||||
case '_header':
|
||||
return $this->translator->trans('Gender');
|
||||
|
||||
default:
|
||||
throw new \LogicException(sprintf('The value %s is not valid', $value));
|
||||
return function (int|string|null $value) {
|
||||
if (null === $value || '' === $value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ('_header' === $value) {
|
||||
return $this->translator->trans('Gender');
|
||||
}
|
||||
|
||||
if (null === $gender = $this->repository->find((int) $value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return (string) $this->translatableStringHelper->localize($gender->getLabel());
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -24,7 +24,7 @@ class CreatorAggregator implements AggregatorInterface
|
||||
|
||||
public function __construct(
|
||||
private readonly UserRepository $userRepository,
|
||||
private readonly UserRender $userRender
|
||||
private readonly UserRender $userRender,
|
||||
) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
|
@@ -26,7 +26,7 @@ class CreatorJobAggregator implements AggregatorInterface
|
||||
|
||||
public function __construct(
|
||||
private readonly UserJobRepository $jobRepository,
|
||||
private readonly TranslatableStringHelper $translatableStringHelper
|
||||
private readonly TranslatableStringHelper $translatableStringHelper,
|
||||
) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
|
@@ -26,7 +26,7 @@ class CreatorScopeAggregator implements AggregatorInterface
|
||||
|
||||
public function __construct(
|
||||
private readonly ScopeRepository $scopeRepository,
|
||||
private readonly TranslatableStringHelper $translatableStringHelper
|
||||
private readonly TranslatableStringHelper $translatableStringHelper,
|
||||
) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
|
@@ -27,7 +27,7 @@ final readonly class JobAggregator implements AggregatorInterface
|
||||
|
||||
public function __construct(
|
||||
private UserJobRepository $jobRepository,
|
||||
private TranslatableStringHelper $translatableStringHelper
|
||||
private TranslatableStringHelper $translatableStringHelper,
|
||||
) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
|
@@ -28,7 +28,7 @@ final readonly class ReferrerAggregator implements AggregatorInterface
|
||||
public function __construct(
|
||||
private UserRepository $userRepository,
|
||||
private UserRender $userRender,
|
||||
private RollingDateConverterInterface $rollingDateConverter
|
||||
private RollingDateConverterInterface $rollingDateConverter,
|
||||
) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
|
@@ -27,7 +27,7 @@ final readonly class ScopeAggregator implements AggregatorInterface
|
||||
|
||||
public function __construct(
|
||||
private ScopeRepository $scopeRepository,
|
||||
private TranslatableStringHelper $translatableStringHelper
|
||||
private TranslatableStringHelper $translatableStringHelper,
|
||||
) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
|
@@ -29,7 +29,7 @@ class AvgDurationAPWorkPersonAssociatedOnAccompanyingPeriod implements ExportInt
|
||||
|
||||
public function __construct(
|
||||
ParameterBagInterface $parameterBag,
|
||||
private readonly AccompanyingPeriodWorkRepository $accompanyingPeriodWorkRepository
|
||||
private readonly AccompanyingPeriodWorkRepository $accompanyingPeriodWorkRepository,
|
||||
) {
|
||||
$this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
|
||||
}
|
||||
|
@@ -29,7 +29,7 @@ class AvgDurationAPWorkPersonAssociatedOnWork implements ExportInterface, Groupe
|
||||
|
||||
public function __construct(
|
||||
ParameterBagInterface $parameterBag,
|
||||
private readonly AccompanyingPeriodWorkRepository $accompanyingPeriodWorkRepository
|
||||
private readonly AccompanyingPeriodWorkRepository $accompanyingPeriodWorkRepository,
|
||||
) {
|
||||
$this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
|
||||
}
|
||||
|
@@ -54,7 +54,6 @@ final readonly class ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeri
|
||||
'socialAction',
|
||||
'socialIssue',
|
||||
'acp_id',
|
||||
'acp_user',
|
||||
'startDate',
|
||||
'endDate',
|
||||
'goalsId',
|
||||
@@ -70,8 +69,8 @@ final readonly class ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeri
|
||||
'personsName',
|
||||
'thirdParties',
|
||||
'handlingThierParty',
|
||||
// 'acpwReferrers',
|
||||
'referrers',
|
||||
'acpwReferrers',
|
||||
'referrer',
|
||||
'createdAt',
|
||||
'createdBy',
|
||||
'updatedAt',
|
||||
@@ -156,9 +155,9 @@ final readonly class ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeri
|
||||
[]
|
||||
);
|
||||
},
|
||||
'createdBy', 'updatedBy', 'acp_user' => $this->userHelper->getLabel($key, $values, 'export.list.acpw.'.$key),
|
||||
'referrers' => $this->userHelper->getLabel($key, $values, 'export.list.acpw.'.$key),
|
||||
// 'acpwReferrers' => $this->userHelper->getLabelMulti($key, $values, 'export.list.acpw.' . $key),
|
||||
'createdBy', 'updatedBy' => $this->userHelper->getLabel($key, $values, 'export.list.acpw.'.$key),
|
||||
'referrer' => $this->userHelper->getLabel($key, $values, 'export.list.acpw.'.$key),
|
||||
'acpwReferrers' => $this->userHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key),
|
||||
'personsName' => $this->personHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key),
|
||||
'handlingThierParty' => $this->thirdPartyHelper->getLabel($key, $values, 'export.list.acpw.'.$key),
|
||||
'thirdParties' => $this->thirdPartyHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key),
|
||||
@@ -272,8 +271,7 @@ final readonly class ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeri
|
||||
|
||||
// join acp
|
||||
$qb
|
||||
->addSelect('acp.id AS acp_id')
|
||||
->addSelect('IDENTITY(acp.user) AS acp_user');
|
||||
->addSelect('acp.id AS acp_id');
|
||||
|
||||
// persons
|
||||
$qb
|
||||
@@ -282,21 +280,18 @@ final readonly class ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeri
|
||||
->addSelect('(SELECT AGGREGATE(person1_acpw_member.id) FROM '.Person::class.' person1_acpw_member '
|
||||
.'WHERE person1_acpw_member MEMBER OF acpw.persons) AS personsName');
|
||||
|
||||
// referrers => at date XXXX
|
||||
$qb
|
||||
->addSelect('(SELECT JSON_BUILD_OBJECT(\'uid\', IDENTITY(history.user), \'d\', history.startDate) FROM '.UserHistory::class.' history '.
|
||||
'WHERE history.accompanyingPeriod = acp AND history.startDate <= :calcDate AND (history.endDate IS NULL OR history.endDate > :calcDate)) AS referrers');
|
||||
|
||||
/*
|
||||
// acpwReferrers at date XXX
|
||||
// referrer => at date XXXX
|
||||
$qb
|
||||
->addSelect('(
|
||||
SELECT IDENTITY(acpw_ref_history.accompanyingPeriodWork) AS acpw_ref_history_id,
|
||||
JSON_BUILD_OBJECT(\'uid\', IDENTITY(acpw_ref_history.user), \'d\', acpw_ref_history.startDate)
|
||||
FROM ' . AccompanyingPeriodWorkReferrerHistory::class . ' acpw_ref_history ' .
|
||||
'WHERE acpw_ref_history.accompanyingPeriodWork = acpw AND acpw_ref_history.startDate <= :calcDate AND (acpw_ref_history.endDate IS NULL or acpw_ref_history.endDate > :calcDate) GROUP BY acpw_ref_history_id) AS acpwReferrers'
|
||||
);
|
||||
*/
|
||||
SELECT JSON_BUILD_OBJECT(\'uid\', IDENTITY(history.user), \'d\', history.startDate) FROM '.UserHistory::class.' history '.
|
||||
'WHERE history.accompanyingPeriod = acp AND history.startDate <= :calcDate AND (history.endDate IS NULL OR history.endDate > :calcDate)) AS referrer');
|
||||
|
||||
// acpwReferrer at date XXX
|
||||
$qb->addSelect('(SELECT AGGREGATE(IDENTITY(acpwrh.user)) FROM '.AccompanyingPeriodWorkReferrerHistory::class.' acpwrh
|
||||
WHERE acpwrh.accompanyingPeriodWork = acpw
|
||||
AND acpwrh.startDate <= :calcDate AND (acpwrh.endDate IS NULL or acpwrh.endDate > :calcDate)
|
||||
) AS acpwReferrers');
|
||||
$qb->setParameter('calcDate', $calcDate);
|
||||
|
||||
// thirdparties
|
||||
$qb
|
||||
|
@@ -54,7 +54,6 @@ final readonly class ListAccompanyingPeriodWorkAssociatePersonOnWork implements
|
||||
'socialAction',
|
||||
'socialIssue',
|
||||
'acp_id',
|
||||
'acp_user',
|
||||
'startDate',
|
||||
'endDate',
|
||||
'goalsId',
|
||||
@@ -70,8 +69,8 @@ final readonly class ListAccompanyingPeriodWorkAssociatePersonOnWork implements
|
||||
'personsName',
|
||||
'thirdParties',
|
||||
'handlingThierParty',
|
||||
// 'acpwReferrers',
|
||||
'referrers',
|
||||
'acpwReferrers',
|
||||
'referrer',
|
||||
'createdAt',
|
||||
'createdBy',
|
||||
'updatedAt',
|
||||
@@ -156,9 +155,9 @@ final readonly class ListAccompanyingPeriodWorkAssociatePersonOnWork implements
|
||||
[]
|
||||
);
|
||||
},
|
||||
'createdBy', 'updatedBy', 'acp_user' => $this->userHelper->getLabel($key, $values, 'export.list.acpw.'.$key),
|
||||
'referrers' => $this->userHelper->getLabel($key, $values, 'export.list.acpw.'.$key),
|
||||
// 'acpwReferrers' => $this->userHelper->getLabelMulti($key, $values, 'export.list.acpw.' . $key),
|
||||
'createdBy', 'updatedBy' => $this->userHelper->getLabel($key, $values, 'export.list.acpw.'.$key),
|
||||
'referrer' => $this->userHelper->getLabel($key, $values, 'export.list.acpw.'.$key),
|
||||
'acpwReferrers' => $this->userHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key),
|
||||
'personsName' => $this->personHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key),
|
||||
'handlingThierParty' => $this->thirdPartyHelper->getLabel($key, $values, 'export.list.acpw.'.$key),
|
||||
'thirdParties' => $this->thirdPartyHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key),
|
||||
@@ -267,8 +266,7 @@ final readonly class ListAccompanyingPeriodWorkAssociatePersonOnWork implements
|
||||
|
||||
// join acp
|
||||
$qb
|
||||
->addSelect('acp.id AS acp_id')
|
||||
->addSelect('IDENTITY(acp.user) AS acp_user');
|
||||
->addSelect('acp.id AS acp_id');
|
||||
|
||||
// persons
|
||||
$qb
|
||||
@@ -277,21 +275,17 @@ final readonly class ListAccompanyingPeriodWorkAssociatePersonOnWork implements
|
||||
->addSelect('(SELECT AGGREGATE(person1_acpw_member.id) FROM '.Person::class.' person1_acpw_member '
|
||||
.'WHERE person1_acpw_member MEMBER OF acpw.persons) AS personsName');
|
||||
|
||||
// referrers => at date XXXX
|
||||
// referrer => at date XXXX
|
||||
$qb
|
||||
->addSelect('(SELECT JSON_BUILD_OBJECT(\'uid\', IDENTITY(history.user), \'d\', history.startDate) FROM '.UserHistory::class.' history '.
|
||||
'WHERE history.accompanyingPeriod = acp AND history.startDate <= :calcDate AND (history.endDate IS NULL OR history.endDate > :calcDate)) AS referrers');
|
||||
'WHERE history.accompanyingPeriod = acp AND history.startDate <= :calcDate AND (history.endDate IS NULL OR history.endDate > :calcDate)) AS referrer');
|
||||
|
||||
/*
|
||||
// acpwReferrers at date XXX
|
||||
$qb
|
||||
->addSelect('(
|
||||
SELECT IDENTITY(acpw_ref_history.accompanyingPeriodWork) AS acpw_ref_history_id,
|
||||
JSON_BUILD_OBJECT(\'uid\', IDENTITY(acpw_ref_history.user), \'d\', acpw_ref_history.startDate)
|
||||
FROM ' . AccompanyingPeriodWorkReferrerHistory::class . ' acpw_ref_history ' .
|
||||
'WHERE acpw_ref_history.accompanyingPeriodWork = acpw AND acpw_ref_history.startDate <= :calcDate AND (acpw_ref_history.endDate IS NULL or acpw_ref_history.endDate > :calcDate) GROUP BY acpw_ref_history_id) AS acpwReferrers'
|
||||
);
|
||||
*/
|
||||
$qb->addSelect('(SELECT AGGREGATE(IDENTITY(acpwrh.user)) FROM '.AccompanyingPeriodWorkReferrerHistory::class.' acpwrh
|
||||
WHERE acpwrh.accompanyingPeriodWork = acpw
|
||||
AND acpwrh.startDate <= :calcDate AND (acpwrh.endDate IS NULL or acpwrh.endDate > :calcDate)
|
||||
) AS acpwReferrers');
|
||||
$qb->setParameter('calcDate', $calcDate);
|
||||
|
||||
// thirdparties
|
||||
$qb
|
||||
|
@@ -219,11 +219,14 @@ class ListHouseholdInPeriod implements ListInterface, GroupedExportInterface
|
||||
$qb
|
||||
->leftJoin('household.addresses', 'addresses')
|
||||
->andWhere(
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->lte('addresses.validFrom', ':calcDate'),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull('addresses.validTo'),
|
||||
$qb->expr()->gt('addresses.validTo', ':calcDate')
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull('addresses'), // Include households without any address
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->lte('addresses.validFrom', ':calcDate'),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull('addresses.validTo'),
|
||||
$qb->expr()->gt('addresses.validTo', ':calcDate')
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
@@ -23,10 +23,8 @@ use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Chill\PersonBundle\Export\Helper\ListPersonHelper;
|
||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Query;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
@@ -41,7 +39,7 @@ class ListPerson implements ListInterface, GroupedExportInterface
|
||||
public function __construct(
|
||||
private readonly CustomFieldProvider $customFieldProvider,
|
||||
private readonly ListPersonHelper $listPersonHelper,
|
||||
private readonly EntityManagerInterface $entityManager,
|
||||
protected readonly EntityManagerInterface $entityManager,
|
||||
private readonly TranslatableStringHelper $translatableStringHelper,
|
||||
ParameterBagInterface $parameterBag,
|
||||
) {
|
||||
|
@@ -51,7 +51,7 @@ class ListPersonDuplicate implements DirectExportInterface, ExportElementValidat
|
||||
EntityManagerInterface $em,
|
||||
private readonly TranslatorInterface $translator,
|
||||
private readonly UrlGeneratorInterface $router,
|
||||
$routeParameters
|
||||
$routeParameters,
|
||||
) {
|
||||
$this->entityManager = $em;
|
||||
$this->baseUrl = $routeParameters['scheme'].
|
||||
|
@@ -28,7 +28,7 @@ class CreatorJobFilter implements FilterInterface
|
||||
|
||||
public function __construct(
|
||||
private readonly TranslatableStringHelper $translatableStringHelper,
|
||||
private readonly UserJobRepositoryInterface $userJobRepository
|
||||
private readonly UserJobRepositoryInterface $userJobRepository,
|
||||
) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
|
@@ -37,7 +37,7 @@ class GeographicalUnitStatFilter implements FilterInterface
|
||||
private readonly GeographicalUnitRepositoryInterface $geographicalUnitRepository,
|
||||
private readonly GeographicalUnitLayerRepositoryInterface $geographicalUnitLayerRepository,
|
||||
private readonly TranslatableStringHelperInterface $translatableStringHelper,
|
||||
private readonly RollingDateConverterInterface $rollingDateConverter
|
||||
private readonly RollingDateConverterInterface $rollingDateConverter,
|
||||
) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
|
@@ -41,7 +41,7 @@ final readonly class ReferrerFilterBetweenDates implements FilterInterface
|
||||
|
||||
public function __construct(
|
||||
private RollingDateConverterInterface $rollingDateConverter,
|
||||
private UserRender $userRender
|
||||
private UserRender $userRender,
|
||||
) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
|
@@ -30,7 +30,7 @@ final readonly class SocialActionFilter implements FilterInterface
|
||||
public function __construct(
|
||||
private SocialActionRender $actionRender,
|
||||
private RollingDateConverterInterface $rollingDateConverter,
|
||||
private TranslatorInterface $translator
|
||||
private TranslatorInterface $translator,
|
||||
) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
|
@@ -30,7 +30,7 @@ class SocialIssueFilter implements FilterInterface
|
||||
|
||||
public function __construct(
|
||||
TranslatorInterface $translator,
|
||||
private readonly SocialIssueRender $socialIssueRender
|
||||
private readonly SocialIssueRender $socialIssueRender,
|
||||
) {
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
@@ -13,23 +13,28 @@ namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
|
||||
|
||||
use Chill\MainBundle\Entity\User\UserJobHistory;
|
||||
use Chill\MainBundle\Entity\UserJob;
|
||||
use Chill\MainBundle\Export\DataTransformerInterface;
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\MainBundle\Form\Type\PickRollingDateType;
|
||||
use Chill\MainBundle\Repository\UserJobRepositoryInterface;
|
||||
use Chill\MainBundle\Service\RollingDate\RollingDate;
|
||||
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\UserHistory;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Query\Expr\Join;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class UserJobFilter implements FilterInterface
|
||||
final readonly class UserJobFilter implements FilterInterface, DataTransformerInterface
|
||||
{
|
||||
private const PREFIX = 'acp_filter_user_job';
|
||||
|
||||
public function __construct(
|
||||
private readonly TranslatableStringHelper $translatableStringHelper,
|
||||
private readonly UserJobRepositoryInterface $userJobRepository,
|
||||
private TranslatableStringHelper $translatableStringHelper,
|
||||
private UserJobRepositoryInterface $userJobRepository,
|
||||
private RollingDateConverterInterface $rollingDateConverter,
|
||||
) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
@@ -41,42 +46,31 @@ class UserJobFilter implements FilterInterface
|
||||
{
|
||||
$p = self::PREFIX;
|
||||
|
||||
$qb
|
||||
->leftJoin(
|
||||
'acp.userHistories',
|
||||
"{$p}_userHistory",
|
||||
Join::WITH,
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->eq("{$p}_userHistory.accompanyingPeriod", 'acp.id'),
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->gte('COALESCE(acp.closingDate, CURRENT_TIMESTAMP())', "{$p}_userHistory.startDate"),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull("{$p}_userHistory.endDate"),
|
||||
$qb->expr()->lt('COALESCE(acp.closingDate, CURRENT_TIMESTAMP())', "{$p}_userHistory.endDate")
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
->leftJoin(
|
||||
UserJobHistory::class,
|
||||
"{$p}_jobHistory",
|
||||
Join::WITH,
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->eq("{$p}_jobHistory.user", "{$p}_userHistory.user"),
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->lte("{$p}_jobHistory.startDate", "{$p}_userHistory.startDate"),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull("{$p}_jobHistory".'.endDate'),
|
||||
$qb->expr()->gt("{$p}_jobHistory.endDate", "{$p}_userHistory.startDate")
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
->andWhere($qb->expr()->in("{$p}_jobHistory.job", ":{$p}_job"))
|
||||
->setParameter(
|
||||
"{$p}_job",
|
||||
$data['jobs'],
|
||||
$qb->andWhere(
|
||||
$qb->expr()->exists(
|
||||
sprintf(
|
||||
<<<DQL
|
||||
SELECT 1
|
||||
FROM %s {$p}_userHistory
|
||||
JOIN %s {$p}_userJobHistory
|
||||
WITH
|
||||
{$p}_userHistory.user = {$p}_userJobHistory.user
|
||||
AND OVERLAPSI({$p}_userHistory.startDate, {$p}_userHistory.endDate),({$p}_userJobHistory.startDate, {$p}_userJobHistory.endDate) = TRUE
|
||||
WHERE {$p}_userHistory.accompanyingPeriod = acp
|
||||
AND {$p}_userHistory.startDate <= :{$p}_endDate
|
||||
AND ({$p}_userHistory.endDate IS NULL OR {$p}_userHistory.endDate > :{$p}_startDate)
|
||||
AND {$p}_userJobHistory.startDate <= :{$p}_endDate
|
||||
AND ({$p}_userJobHistory.endDate IS NULL OR {$p}_userJobHistory.endDate > :{$p}_startDate)
|
||||
AND {$p}_userJobHistory.job IN (:{$p}_jobs)
|
||||
DQL,
|
||||
UserHistory::class,
|
||||
UserJobHistory::class,
|
||||
),
|
||||
)
|
||||
)
|
||||
->setParameter("{$p}_jobs", $data['jobs'])
|
||||
->setParameter("{$p}_startDate", $this->rollingDateConverter->convert($data['start_date']))
|
||||
->setParameter("{$p}_endDate", $this->rollingDateConverter->convert($data['end_date']))
|
||||
;
|
||||
}
|
||||
|
||||
@@ -95,20 +89,29 @@ class UserJobFilter implements FilterInterface
|
||||
'expanded' => true,
|
||||
'choice_label' => fn (UserJob $job) => $this->translatableStringHelper->localize($job->getLabel()),
|
||||
'label' => 'Job',
|
||||
]);
|
||||
])
|
||||
->add('start_date', PickRollingDateType::class, [
|
||||
'label' => 'export.filter.course.by_user_job.Start from',
|
||||
])
|
||||
->add('end_date', PickRollingDateType::class, [
|
||||
'label' => 'export.filter.course.by_user_job.Until',
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string')
|
||||
{
|
||||
return [
|
||||
'export.filter.course.by_user_job.Filtered by user job: only %job%', [
|
||||
'%job%' => implode(
|
||||
'exports.filter.course.by_user_job.Filtered by user job: only job', [
|
||||
'job' => implode(
|
||||
', ',
|
||||
array_map(
|
||||
fn (UserJob $job) => $this->translatableStringHelper->localize($job->getLabel()),
|
||||
$data['jobs'] instanceof Collection ? $data['jobs']->toArray() : $data['jobs']
|
||||
)
|
||||
),
|
||||
'startDate' => $this->rollingDateConverter->convert($data['start_date']),
|
||||
'endDate' => $this->rollingDateConverter->convert($data['end_date']),
|
||||
],
|
||||
];
|
||||
}
|
||||
@@ -117,9 +120,30 @@ class UserJobFilter implements FilterInterface
|
||||
{
|
||||
return [
|
||||
'jobs' => [],
|
||||
'start_date' => new RollingDate(RollingDate::T_YEAR_CURRENT_START),
|
||||
'end_date' => new RollingDate(RollingDate::T_TODAY),
|
||||
];
|
||||
}
|
||||
|
||||
public function transformData(?array $before): array
|
||||
{
|
||||
$default = $this->getFormDefaultData();
|
||||
|
||||
if (null === $before) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
if (!array_key_exists('start_date', $before) || null === $before['start_date']) {
|
||||
$before['start_date'] = $default['start_date'];
|
||||
}
|
||||
|
||||
if (!array_key_exists('end_date', $before) || null === $before['end_date']) {
|
||||
$before['end_date'] = $default['end_date'];
|
||||
}
|
||||
|
||||
return $before;
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'export.filter.course.by_user_job.Filter by user job';
|
||||
|
@@ -13,23 +13,28 @@ namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
|
||||
|
||||
use Chill\MainBundle\Entity\Scope;
|
||||
use Chill\MainBundle\Entity\User\UserScopeHistory;
|
||||
use Chill\MainBundle\Export\DataTransformerInterface;
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\MainBundle\Form\Type\PickRollingDateType;
|
||||
use Chill\MainBundle\Repository\ScopeRepositoryInterface;
|
||||
use Chill\MainBundle\Service\RollingDate\RollingDate;
|
||||
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\UserHistory;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Query\Expr\Join;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class UserScopeFilter implements FilterInterface
|
||||
final readonly class UserScopeFilter implements FilterInterface, DataTransformerInterface
|
||||
{
|
||||
private const PREFIX = 'acp_filter_main_scope';
|
||||
|
||||
public function __construct(
|
||||
private readonly ScopeRepositoryInterface $scopeRepository,
|
||||
private readonly TranslatableStringHelper $translatableStringHelper,
|
||||
private ScopeRepositoryInterface $scopeRepository,
|
||||
private TranslatableStringHelper $translatableStringHelper,
|
||||
private RollingDateConverterInterface $rollingDateConverter,
|
||||
) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
@@ -37,47 +42,35 @@ class UserScopeFilter implements FilterInterface
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
public function alterQuery(QueryBuilder $qb, $data): void
|
||||
{
|
||||
$p = self::PREFIX;
|
||||
|
||||
$qb
|
||||
->join(
|
||||
'acp.userHistories',
|
||||
"{$p}_userHistory",
|
||||
Join::WITH,
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->eq("{$p}_userHistory.accompanyingPeriod", 'acp.id'),
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->gte('COALESCE(acp.closingDate, CURRENT_TIMESTAMP())', "{$p}_userHistory.startDate"),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull("{$p}_userHistory.endDate"),
|
||||
$qb->expr()->lt('COALESCE(acp.closingDate, CURRENT_TIMESTAMP())', "{$p}_userHistory.endDate")
|
||||
)
|
||||
)
|
||||
)
|
||||
$qb->andWhere(
|
||||
$qb->expr()->exists(
|
||||
sprintf(
|
||||
<<<DQL
|
||||
SELECT 1
|
||||
FROM %s {$p}_userHistory
|
||||
JOIN %s {$p}_userScopeHistory
|
||||
WITH
|
||||
{$p}_userHistory.user = {$p}_userScopeHistory.user
|
||||
AND OVERLAPSI({$p}_userHistory.startDate, {$p}_userHistory.endDate),({$p}_userScopeHistory.startDate, {$p}_userScopeHistory.endDate) = TRUE
|
||||
WHERE {$p}_userHistory.accompanyingPeriod = acp
|
||||
AND {$p}_userHistory.startDate <= :{$p}_endDate
|
||||
AND ({$p}_userHistory.endDate IS NULL OR {$p}_userHistory.endDate > :{$p}_startDate)
|
||||
AND {$p}_userScopeHistory.startDate <= :{$p}_endDate
|
||||
AND ({$p}_userScopeHistory.endDate IS NULL OR {$p}_userScopeHistory.endDate > :{$p}_startDate)
|
||||
AND {$p}_userScopeHistory.scope IN (:{$p}_scopes)
|
||||
DQL,
|
||||
UserHistory::class,
|
||||
UserScopeHistory::class,
|
||||
),
|
||||
)
|
||||
->join(
|
||||
UserScopeHistory::class,
|
||||
"{$p}_scopeHistory",
|
||||
Join::WITH,
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->eq("{$p}_scopeHistory.user", "{$p}_userHistory.user"),
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->lte("{$p}_scopeHistory.startDate", "{$p}_userHistory.startDate"),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull("{$p}_scopeHistory.endDate"),
|
||||
$qb->expr()->gt("{$p}_scopeHistory.endDate", "{$p}_userHistory.startDate")
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
->andWhere($qb->expr()->in("{$p}_scopeHistory.scope", ":{$p}_scopes"))
|
||||
->setParameter(
|
||||
"{$p}_scopes",
|
||||
$data['scopes'],
|
||||
)
|
||||
;
|
||||
)
|
||||
->setParameter("{$p}_scopes", $data['scopes'])
|
||||
->setParameter("{$p}_startDate", $this->rollingDateConverter->convert($data['start_date']))
|
||||
->setParameter("{$p}_endDate", $this->rollingDateConverter->convert($data['end_date']));
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
@@ -94,20 +87,28 @@ class UserScopeFilter implements FilterInterface
|
||||
'choice_label' => fn (Scope $s) => $this->translatableStringHelper->localize($s->getName()),
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
])
|
||||
->add('start_date', PickRollingDateType::class, [
|
||||
'label' => 'export.filter.course.by_user_scope.Start from',
|
||||
])
|
||||
->add('end_date', PickRollingDateType::class, [
|
||||
'label' => 'export.filter.course.by_user_scope.Until',
|
||||
]);
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string')
|
||||
{
|
||||
return [
|
||||
'export.filter.course.by_user_scope.Filtered by user main scope: only %scope%', [
|
||||
'%scope%' => implode(
|
||||
'exports.filter.course.by_user_scope.Filtered by user main scope: only scopes', [
|
||||
'scopes' => implode(
|
||||
', ',
|
||||
array_map(
|
||||
fn (Scope $s) => $this->translatableStringHelper->localize($s->getName()),
|
||||
$data['scopes'] instanceof Collection ? $data['scopes']->toArray() : $data['scopes']
|
||||
)
|
||||
),
|
||||
'startDate' => $this->rollingDateConverter->convert($data['start_date']),
|
||||
'endDate' => $this->rollingDateConverter->convert($data['end_date']),
|
||||
],
|
||||
];
|
||||
}
|
||||
@@ -116,9 +117,30 @@ class UserScopeFilter implements FilterInterface
|
||||
{
|
||||
return [
|
||||
'scopes' => [],
|
||||
'start_date' => new RollingDate(RollingDate::T_YEAR_CURRENT_START),
|
||||
'end_date' => new RollingDate(RollingDate::T_TODAY),
|
||||
];
|
||||
}
|
||||
|
||||
public function transformData(?array $before): array
|
||||
{
|
||||
$default = $this->getFormDefaultData();
|
||||
|
||||
if (null === $before) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
if (!array_key_exists('start_date', $before) || null === $before['start_date']) {
|
||||
$before['start_date'] = $default['start_date'];
|
||||
}
|
||||
|
||||
if (!array_key_exists('end_date', $before) || null === $before['end_date']) {
|
||||
$before['end_date'] = $default['end_date'];
|
||||
}
|
||||
|
||||
return $before;
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'export.filter.course.by_user_scope.Filter by user scope';
|
||||
|
@@ -32,7 +32,7 @@ use Symfony\Component\Form\FormBuilderInterface;
|
||||
final readonly class ByDateFilter implements FilterInterface
|
||||
{
|
||||
public function __construct(
|
||||
private RollingDateConverterInterface $rollingDateConverter
|
||||
private RollingDateConverterInterface $rollingDateConverter,
|
||||
) {}
|
||||
|
||||
public function getTitle()
|
||||
|
@@ -27,7 +27,7 @@ readonly class CompositionFilter implements FilterInterface
|
||||
{
|
||||
public function __construct(
|
||||
private TranslatableStringHelper $translatableStringHelper,
|
||||
private RollingDateConverterInterface $rollingDateConverter
|
||||
private RollingDateConverterInterface $rollingDateConverter,
|
||||
) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user