diff --git a/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml b/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml index 35a4d6a22..2b4b6788a 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml +++ b/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml @@ -183,4 +183,5 @@ export: Group by aside activity type: Grouper les activités annexes par type d'activité Aside activity type: Type d'activité annexe - +# ROLES +CHILL_ASIDE_ACTIVITY_STATS: Statistiques pour les activités annexes diff --git a/src/Bundle/ChillBudgetBundle/translations/messages.fr.yml b/src/Bundle/ChillBudgetBundle/translations/messages.fr.yml index 5fd8fa6f6..8337dff87 100644 --- a/src/Bundle/ChillBudgetBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillBudgetBundle/translations/messages.fr.yml @@ -77,6 +77,13 @@ The balance: Différence entre ressources et charges Valid since %startDate% until %endDate%: Valide depuis le %startDate% jusqu'au %endDate% Valid since %startDate%: Valide depuis le %startDate% +# ROLES +Budget elements: Budget +CHILL_BUDGET_ELEMENT_CREATE: Créer une ressource/charge +CHILL_BUDGET_ELEMENT_DELETE: Supprimer une ressource/charge +CHILL_BUDGET_ELEMENT_SEE: Voir les ressources/charges +CHILL_BUDGET_ELEMENT_UPDATE: Modifier une ressource/charge + ## admin crud: diff --git a/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml b/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml index 4fbad1546..b658dbbee 100644 --- a/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml @@ -66,3 +66,11 @@ online_edit_document: Éditer en ligne workflow: Document deleted: Document supprimé + +# ROLES +accompanyingCourseDocument: Documents dans les parcours d'accompagnement +CHILL_ACCOMPANYING_COURSE_DOCUMENT_CREATE: Créer un document +CHILL_ACCOMPANYING_COURSE_DOCUMENT_DELETE: Supprimer un document +CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE: Voir les documents +CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE_DETAILS: Voir les détails d'un document +CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE: Modifier un document \ No newline at end of file diff --git a/src/Bundle/ChillMainBundle/Export/Helper/AggregateStringHelper.php b/src/Bundle/ChillMainBundle/Export/Helper/AggregateStringHelper.php new file mode 100644 index 000000000..6266ce86f --- /dev/null +++ b/src/Bundle/ChillMainBundle/Export/Helper/AggregateStringHelper.php @@ -0,0 +1,36 @@ + -
+
{{ form_widget(form.roll, { 'attr': { 'data-roll-picker': 'data-roll-picker'}}) }} {{ form_errors(form.roll) }}
-
+
{{ form_widget(form.fixedDate) }} {{ form_errors(form.fixedDate) }}
diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountSocialWorkActions.php b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php similarity index 97% rename from src/Bundle/ChillPersonBundle/Export/Export/CountSocialWorkActions.php rename to src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php index 0aaf526cc..40253ea0b 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountSocialWorkActions.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountAccompanyingPeriodWork.php @@ -24,7 +24,7 @@ use Doctrine\ORM\QueryBuilder; use LogicException; use Symfony\Component\Form\FormBuilderInterface; -class CountSocialWorkActions implements ExportInterface, GroupedExportInterface +class CountAccompanyingPeriodWork implements ExportInterface, GroupedExportInterface { protected EntityManagerInterface $em; diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php index 28ad94bd3..8c96906fc 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php @@ -19,7 +19,8 @@ use Chill\MainBundle\Export\Helper\DateTimeHelper; use Chill\MainBundle\Export\Helper\ExportAddressHelper; use Chill\MainBundle\Export\Helper\UserHelper; use Chill\MainBundle\Export\ListInterface; -use Chill\MainBundle\Form\Type\ChillDateType; +use Chill\MainBundle\Form\Type\PickRollingDateType; +use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation; @@ -87,6 +88,8 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface private PersonRepository $personRepository; + private RollingDateConverterInterface $rollingDateConverter; + private SocialIssueRender $socialIssueRender; private SocialIssueRepository $socialIssueRepository; @@ -110,6 +113,7 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface SocialIssueRepository $socialIssueRepository, SocialIssueRender $socialIssueRender, TranslatableStringHelperInterface $translatableStringHelper, + RollingDateConverterInterface $rollingDateConverter, UserHelper $userHelper ) { $this->addressHelper = $addressHelper; @@ -122,14 +126,14 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface $this->thirdPartyRender = $thirdPartyRender; $this->thirdPartyRepository = $thirdPartyRepository; $this->translatableStringHelper = $translatableStringHelper; + $this->rollingDateConverter = $rollingDateConverter; $this->userHelper = $userHelper; } public function buildForm(FormBuilderInterface $builder) { $builder - ->add('calc_date', ChillDateType::class, [ - 'input' => 'datetime_immutable', + ->add('calc_date', PickRollingDateType::class, [ 'label' => 'export.list.acp.Date of calculation for associated elements', 'help' => 'export.list.acp.The associated referree, localisation, and other elements will be valid at this date', 'required' => true, @@ -306,7 +310,7 @@ class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface ->setParameter('list_acp_step', AccompanyingPeriod::STEP_DRAFT) ->setParameter('authorized_centers', $centers); - $this->addSelectClauses($qb, $data['calc_date']); + $this->addSelectClauses($qb, $this->rollingDateConverter->convert($data['calc_date'])); return $qb; } diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWork.php b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWork.php new file mode 100644 index 000000000..d0c1863c3 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriodWork.php @@ -0,0 +1,396 @@ +entityManager = $entityManager; + $this->dateTimeHelper = $dateTimeHelper; + $this->userHelper = $userHelper; + $this->personHelper = $personHelper; + $this->thirdPartyHelper = $thirdPartyHelper; + $this->translatableStringExportLabelHelper = $translatableStringExportLabelHelper; + $this->socialIssueRender = $socialIssueRender; + $this->socialIssueRepository = $socialIssueRepository; + $this->socialActionRender = $socialActionRender; + $this->rollingDateConverter = $rollingDateConverter; + $this->aggregateStringHelper = $aggregateStringHelper; + $this->socialActionRepository = $socialActionRepository; + } + + public function buildForm(FormBuilderInterface $builder) + { + $builder + ->add('calc_date', PickRollingDateType::class, [ + 'label' => 'export.list.acpw.Date of calculation for associated elements', + 'help' => 'export.list.acpw.help_description', + 'required' => true, + 'data' => new RollingDate(RollingDate::T_TODAY), + ]); + } + + public function getAllowedFormattersTypes() + { + return [FormatterInterface::TYPE_LIST]; + } + + public function getDescription(): string + { + return 'export.list.acpw.List description'; + } + + public function getGroup(): string + { + return 'Exports of social work actions'; + } + + public function getLabels($key, array $values, $data) + { + switch ($key) { + case 'startDate': + case 'endDate': + case 'createdAt': + case 'updatedAt': + return $this->dateTimeHelper->getLabel('export.list.acpw.' . $key); + + case 'socialAction': + return function ($value) use ($key) { + if ('_header' === $value) { + return 'export.list.acpw.' . $key; + } + + if (null === $value) { + return ''; + } + + return $this->socialActionRender->renderString( + $this->socialActionRepository->find($value), + [] + ); + }; + + case 'socialIssue': + return function ($value) use ($key) { + if ('_header' === $value) { + return 'export.list.acpw.' . $key; + } + + if (null === $value) { + return ''; + } + + return $this->socialIssueRender->renderString( + $this->socialIssueRepository->find($value), + [] + ); + }; + + case 'createdBy': + case 'updatedBy': + case 'acp_user': + return $this->userHelper->getLabel($key, $values, 'export.list.acpw.' . $key); + + case 'referrers': + //$date = $this->rollDateConverter->convert($data['calc_date'])->format('d/m/Y'); + return $this->userHelper->getLabel($key, $values, 'export.list.acpw.' . $key); + + case 'personsName': + return $this->personHelper->getLabelMulti($key, $values, 'export.list.acpw.' . $key); + + case 'handlingThierParty': + return $this->thirdPartyHelper->getLabel($key, $values, 'export.list.acpw.' . $key); + + case 'thirdParties': + return $this->thirdPartyHelper->getLabelMulti($key, $values, 'export.list.acpw.' . $key); + + case 'personsId': + case 'goalsId': + case 'goalResultsId': + case 'resultsId': + case 'evaluationsId': + return $this->aggregateStringHelper->getLabelMulti($key, $values, 'export.list.acpw.' . $key); + + case 'goalsTitle': + case 'goalResultsTitle': + case 'resultsTitle': + case 'evaluationsTitle': + return $this->translatableStringExportLabelHelper->getLabelMulti($key, $values, 'export.list.acpw.' . $key); + + default: + return static function ($value) use ($key) { + if ('_header' === $value) { + return 'export.list.acpw.' . $key; + } + + if (null === $value) { + return ''; + } + + return $value; + }; + } + } + + public function getQueryKeys($data) + { + return self::FIELDS; + } + + public function getResult($query, $data) + { + return $query->getQuery()->getResult(AbstractQuery::HYDRATE_SCALAR); + } + + public function getTitle(): string + { + return 'export.list.acpw.List of accompanying period works'; + } + + public function getType(): string + { + return Declarations::SOCIAL_WORK_ACTION_TYPE; + } + + public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) + { + $centers = array_map(static function ($el) { + return $el['center']; + }, $acl); + + $qb = $this->entityManager->createQueryBuilder(); + + $qb + ->from(AccompanyingPeriodWork::class, 'acpw') + ->distinct() + ->select('acpw.id AS id') + ->join('acpw.accompanyingPeriod', 'acp') + ->join('acp.participations', 'acppart') + ->join('acppart.person', 'person') + // ignore participation which didn't last one day, at least + ->andWhere('acppart.startDate != acppart.endDate OR acppart.endDate IS NULL') + // get participants at the given date + ->andWhere('acppart.startDate <= :calc_date AND (acppart.endDate > :calc_date OR acppart.endDate IS NULL)') + ->andWhere( + $qb->expr()->exists( + 'SELECT 1 FROM ' . PersonCenterHistory::class . ' acl_count_person_history WHERE acl_count_person_history.person = person + AND acl_count_person_history.center IN (:authorized_centers) + ' + ) + ) + ->setParameter('authorized_centers', $centers) + ->setParameter('calc_date', $this->rollingDateConverter->convert($data['calc_date'])); + + $this->addSelectClauses($qb, $this->rollingDateConverter->convert($data['calc_date'])); + + return $qb; + } + + public function requiredRole(): string + { + return AccompanyingPeriodVoter::STATS; + } + + public function supportsModifiers(): array + { + return [ + Declarations::SOCIAL_WORK_ACTION_TYPE, + Declarations::ACP_TYPE, + Declarations::PERSON_TYPE, + ]; + } + + private function addSelectClauses(QueryBuilder $qb, DateTimeImmutable $calcDate): void + { + // add regular fields + foreach ([ + 'startDate', + 'endDate', + 'note', + 'createdAt', + 'updatedAt', + ] as $field) { + $qb->addSelect(sprintf('acpw.%s AS %s', $field, $field)); + } + + // those with identity + foreach ([ + 'createdBy', + 'updatedBy', + 'handlingThierParty', + ] as $field) { + $qb->addSelect(sprintf('IDENTITY(acpw.%s) AS %s', $field, $field)); + } + + // join socialaction + $qb + ->join('acpw.socialAction', 'sa') + ->addSelect('sa.id AS socialActionId') + ->addSelect('sa.id AS socialAction') + ->addSelect('IDENTITY(sa.issue) AS socialIssue'); + + // join acp + $qb + ->addSelect('acp.id AS acp_id') + ->addSelect('IDENTITY(acp.user) AS acp_user'); + + // persons + $qb + ->addSelect('(SELECT AGGREGATE(person_acpw_member.id) FROM ' . Person::class . ' person_acpw_member ' + . 'WHERE person_acpw_member MEMBER OF acpw.persons) AS personsId') + ->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 IDENTITY(history.user) FROM ' . UserHistory::class . ' history ' . + 'WHERE history.accompanyingPeriod = acp AND history.startDate <= :calcDate AND (history.endDate IS NULL OR history.endDate > :calcDate)) AS referrers'); + + // thirdparties + $qb + ->addSelect('(SELECT AGGREGATE(tp.id) FROM ' . ThirdParty::class . ' tp ' + . 'WHERE tp MEMBER OF acpw.thirdParties) AS thirdParties'); + + // goals + $qb + ->addSelect('(SELECT AGGREGATE(IDENTITY(goal.goal)) FROM ' . AccompanyingPeriodWorkGoal::class . ' goal ' + . 'WHERE goal MEMBER OF acpw.goals) AS goalsId') + ->addSelect('(SELECT AGGREGATE(g.title) FROM ' . AccompanyingPeriodWorkGoal::class . ' goal1 ' + . 'LEFT JOIN ' . Goal::class . ' g WITH goal1.goal = g.id WHERE goal1 MEMBER OF acpw.goals) AS goalsTitle'); + + // goals results + $qb + ->addSelect('(SELECT AGGREGATE(wr.id) FROM ' . Result::class . ' wr ' + . 'JOIN ' . AccompanyingPeriodWorkGoal::class . ' wg WITH wr MEMBER OF wg.results ' + . 'WHERE wg MEMBER OF acpw.goals) AS goalResultsId') + ->addSelect('(SELECT AGGREGATE(wr1.title) FROM ' . Result::class . ' wr1 ' + . 'JOIN ' . AccompanyingPeriodWorkGoal::class . ' wg1 WITH wr1 MEMBER OF wg1.results ' + . 'WHERE wg1 MEMBER OF acpw.goals) AS goalResultsTitle'); + + // results + $qb + ->addSelect('(SELECT AGGREGATE(result.id) FROM ' . Result::class . ' result ' + . 'WHERE result MEMBER OF acpw.results ) AS resultsId ') + ->addSelect('(SELECT AGGREGATE (result1.title) FROM ' . Result::class . ' result1 ' + . 'WHERE result1 MEMBER OF acpw.results ) AS resultsTitle '); + + // evaluations + $qb + ->addSelect('(SELECT AGGREGATE(IDENTITY(we.evaluation)) FROM ' . AccompanyingPeriodWorkEvaluation::class . ' we ' + . 'WHERE we MEMBER OF acpw.accompanyingPeriodWorkEvaluations ) AS evaluationsId ') + ->addSelect('(SELECT AGGREGATE(ev.title) FROM ' . AccompanyingPeriodWorkEvaluation::class . ' we1 ' + . 'LEFT JOIN ' . Evaluation::class . ' ev WITH we1.evaluation = ev.id ' + . 'WHERE we1 MEMBER OF acpw.accompanyingPeriodWorkEvaluations ) AS evaluationsTitle '); + + $qb->setParameter('calcDate', $calcDate); + } +} diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListEvaluation.php b/src/Bundle/ChillPersonBundle/Export/Export/ListEvaluation.php new file mode 100644 index 000000000..e7d1e5dfd --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListEvaluation.php @@ -0,0 +1,336 @@ +entityManager = $entityManager; + $this->socialIssueRender = $socialIssueRender; + $this->socialIssueRepository = $socialIssueRepository; + $this->socialActionRender = $socialActionRender; + $this->socialActionRepository = $socialActionRepository; + $this->userHelper = $userHelper; + $this->personHelper = $personHelper; + $this->dateTimeHelper = $dateTimeHelper; + $this->translatableStringExportLabelHelper = $translatableStringExportLabelHelper; + $this->aggregateStringHelper = $aggregateStringHelper; + $this->rollingDateConverter = $rollingDateConverter; + } + + public function buildForm(FormBuilderInterface $builder) + { + $builder + ->add('calc_date', PickRollingDateType::class, [ + 'label' => 'export.list.eval.Date of calculation for associated elements', + 'help' => 'export.list.eval.help_description', + 'required' => true, + 'data' => new RollingDate(RollingDate::T_TODAY), + ]); + } + + public function getAllowedFormattersTypes() + { + return [FormatterInterface::TYPE_LIST]; + } + + public function getDescription(): string + { + return 'export.list.eval.Generate a list of evaluations, filtered on different parameters'; + } + + public function getGroup(): string + { + return 'Exports of evaluations'; + } + + public function getLabels($key, array $values, $data) + { + switch ($key) { + case 'startDate': + case 'endDate': + case 'maxDate': + case 'acpw_startDate': + case 'acpw_endDate': + case 'createdAt': + case 'updatedAt': + return $this->dateTimeHelper->getLabel('export.list.eval.' . $key); + + case 'acpw_socialaction': + return function ($value) use ($key) { + if ('_header' === $value) { + return 'export.list.eval.' . $key; + } + + if (null === $value || '' === $value) { + return ''; + } + + return $this->socialActionRender->renderString( + $this->socialActionRepository->find($value), + [] + ); + }; + + case 'acpw_socialissue': + return function ($value) use ($key) { + if ('_header' === $value) { + return 'export.list.eval.' . $key; + } + + if (null === $value || '' === $value) { + return ''; + } + + return $this->socialIssueRender->renderString( + $this->socialIssueRepository->find($value), + [] + ); + }; + + case 'createdBy': + case 'updatedBy': + case 'acpw_acp_user': + return $this->userHelper->getLabel($key, $values, 'export.list.eval.' . $key); + + case 'acpw_referrers': + return $this->userHelper->getLabel($key, $values, 'export.list.eval.' . $key); + + case 'acpw_persons_id': + return $this->aggregateStringHelper->getLabelMulti($key, $values, 'export.list.eval.' . $key); + + case 'acpw_persons': + return $this->personHelper->getLabelMulti($key, $values, 'export.list.eval.' . $key); + + case 'eval_title': + return $this->translatableStringExportLabelHelper + ->getLabel($key, $values, 'export.list.eval.' . $key); + + default: + return static function ($value) use ($key) { + if ('_header' === $value) { + return 'export.list.eval.' . $key; + } + + if (null === $value) { + return ''; + } + + return $value; + }; + } + } + + public function getQueryKeys($data) + { + return self::FIELDS; + } + + public function getResult($query, $data) + { + return $query->getQuery()->getResult(AbstractQuery::HYDRATE_SCALAR); + } + + public function getTitle(): string + { + return 'export.list.eval.List of evaluations'; + } + + public function getType(): string + { + return Declarations::EVAL_TYPE; + } + + public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) + { + $centers = array_map(static function ($el) { + return $el['center']; + }, $acl); + + $qb = $this->entityManager->createQueryBuilder(); + + $qb + ->from(AccompanyingPeriodWorkEvaluation::class, 'workeval') + ->distinct() + ->select('workeval.id AS id') + ->join('workeval.accompanyingPeriodWork', 'acpw') + ->join('acpw.accompanyingPeriod', 'acp') + ->join('acp.participations', 'acppart') + ->join('acppart.person', 'person') + // ignore participation which didn't last one day, at least + ->andWhere('acppart.startDate != acppart.endDate OR acppart.endDate IS NULL') + // get participants at the given date + ->andWhere('acppart.startDate <= :calc_date AND (acppart.endDate > :calc_date OR acppart.endDate IS NULL)') + ->andWhere( + $qb->expr()->exists( + 'SELECT 1 FROM ' . PersonCenterHistory::class . ' acl_count_person_history WHERE acl_count_person_history.person = person + AND acl_count_person_history.center IN (:authorized_centers) + ' + ) + ) + ->setParameter('authorized_centers', $centers) + ->setParameter('calc_date', $this->rollingDateConverter->convert($data['calc_date'])); + + $this->addSelectClauses($qb, $this->rollingDateConverter->convert($data['calc_date'])); + + return $qb; + } + + public function requiredRole(): string + { + return AccompanyingPeriodVoter::STATS; + } + + public function supportsModifiers(): array + { + return [ + Declarations::EVAL_TYPE, + Declarations::SOCIAL_WORK_ACTION_TYPE, + Declarations::ACP_TYPE, + Declarations::PERSON_TYPE, + ]; + } + + private function addSelectClauses(QueryBuilder $qb, DateTimeImmutable $calc_date): void + { + // add the regular fields + foreach (['startDate', 'endDate', 'maxDate', 'warningInterval', 'comment', 'createdAt', 'updatedAt'] as $field) { + $qb->addSelect(sprintf('workeval.%s AS %s', $field, $field)); + } + + // those with identity + foreach (['createdBy', 'updatedBy'] as $field) { + $qb->addSelect(sprintf('IDENTITY(workeval.%s) AS %s', $field, $field)); + } + + foreach (['id', 'startDate', 'endDate', 'note'] as $field) { + $qb->addSelect(sprintf('acpw.%s AS %s', $field, 'acpw_' . $field)); + } + + // join socialaction + $qb + ->leftJoin('acpw.socialAction', 'sa') + ->addSelect('sa.id AS acpw_socialaction_id') + ->addSelect('sa.id AS acpw_socialaction') + ->addSelect('IDENTITY(sa.issue) AS acpw_socialissue'); + + // join acp + $qb + ->addSelect('acp.id AS acpw_acp_id') + ->addSelect('IDENTITY(acp.user) AS acpw_acp_user'); + + // referrers => at date XXXX + $qb + ->addSelect('(SELECT IDENTITY(history.user) FROM ' . UserHistory::class . ' history ' . + 'WHERE history.accompanyingPeriod = acp AND history.startDate <= :calc_date AND (history.endDate IS NULL OR history.endDate > :calc_date)) AS acpw_referrers'); + + // persons + $qb + ->addSelect('(SELECT AGGREGATE(person_acpw_member.id) FROM ' . Person::class . ' person_acpw_member ' + . 'WHERE person_acpw_member MEMBER OF acpw.persons) AS acpw_persons_id') + ->addSelect('(SELECT AGGREGATE(person1_acpw_member.id) FROM ' . Person::class . ' person1_acpw_member ' + . 'WHERE person1_acpw_member MEMBER OF acpw.persons) AS acpw_persons'); + + // join evaluation + $qb + ->leftJoin('workeval.evaluation', 'eval') + ->addSelect('eval.title AS eval_title'); + } +} diff --git a/src/Bundle/ChillPersonBundle/Export/Export/ListHouseholdInPeriod.php b/src/Bundle/ChillPersonBundle/Export/Export/ListHouseholdInPeriod.php new file mode 100644 index 000000000..fc72de77b --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Export/ListHouseholdInPeriod.php @@ -0,0 +1,251 @@ +addressHelper = $addressHelper; + $this->aggregateStringHelper = $aggregateStringHelper; + $this->entityManager = $entityManager; + $this->rollingDateConverter = $rollingDateConverter; + $this->translatableStringHelper = $translatableStringHelper; + } + + public function buildForm(FormBuilderInterface $builder) + { + $builder + ->add('calc_date', PickRollingDateType::class, [ + 'label' => 'export.list.household.Date of calculation for associated elements', + 'help' => 'export.list.household.help_description', + 'data' => new RollingDate(RollingDate::T_TODAY), + 'required' => true, + ]); + } + + public function getAllowedFormattersTypes() + { + return [FormatterInterface::TYPE_LIST]; + } + + public function getDescription(): string + { + return 'export.list.household.List description'; + } + + public function getGroup(): string + { + return 'Exports of households'; + } + + public function getLabels($key, array $values, $data) + { + if (substr($key, 0, strlen('address_fields')) === 'address_fields') { + return $this->addressHelper->getLabel($key, $values, $data, 'address_fields'); + } + + switch ($key) { + case 'membersId': + case 'membersName': + return $this->aggregateStringHelper->getLabelMulti($key, $values, 'export.list.household.' . $key); + + case 'compositionType': + //dump($values); + return $this->translatableStringHelper->getLabel($key, $values, 'export.list.household.' . $key); + + default: + return static function ($value) use ($key) { + if ('_header' === $value) { + return 'export.list.household.' . $key; + } + + return (string) $value; + }; + } + } + + public function getQueryKeys($data): array + { + return array_merge( + self::FIELDS, + $this->addressHelper->getKeys(ExportAddressHelper::F_ALL, 'address_fields') + ); + } + + public function getResult($query, $data) + { + return $query->getQuery()->getResult(AbstractQuery::HYDRATE_SCALAR); + } + + public function getTitle(): string + { + return 'export.list.household.List household associated with accompanying period title'; + } + + public function getType(): string + { + return Declarations::HOUSEHOLD_TYPE; + } + + public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) + { + $centers = array_map(static function ($el) { + return $el['center']; + }, $acl); + + $qb = $this->entityManager->createQueryBuilder(); + + $qb + ->from(Household::class, 'household') + ->distinct() + ->select('household.id AS id') + ->join('household.members', 'hmember') + ->join('hmember.person', 'person') + ->join('person.accompanyingPeriodParticipations', 'acppart') + ->join('acppart.accompanyingPeriod', 'acp') + ->andWhere('acppart.startDate != acppart.endDate OR acppart.endDate IS NULL') + ->andWhere( + $qb->expr()->exists( + 'SELECT 1 FROM ' . PersonCenterHistory::class . ' acl_count_person_history WHERE acl_count_person_history.person = person + AND acl_count_person_history.center IN (:authorized_centers) + ' + ) + ) + ->andWhere('hmember.startDate <= :count_household_at_date AND (hmember.endDate IS NULL OR hmember.endDate > :count_household_at_date)') + ->setParameter('authorized_centers', $centers) + ->setParameter('count_household_at_date', $this->rollingDateConverter->convert($data['calc_date'])); + + $this->addSelectClauses($qb, $this->rollingDateConverter->convert($data['calc_date'])); + + return $qb; + } + + public function requiredRole(): string + { + return HouseholdVoter::STATS; + } + + public function supportsModifiers(): array + { + return [ + Declarations::HOUSEHOLD_TYPE, + Declarations::ACP_TYPE, + Declarations::PERSON_TYPE, + ]; + } + + private function addSelectClauses(QueryBuilder $qb, DateTimeImmutable $calcDate): void + { + // members at date + $qb + ->addSelect('(SELECT COUNT(members0) FROM ' . HouseholdMember::class . ' members0 ' + . 'WHERE members0.startDate <= :calcDate AND (members0.endDate IS NULL OR members0.endDate > :calcDate) ' + . 'AND members0 MEMBER OF household.members) AS membersCount') + + ->addSelect('(SELECT AGGREGATE(IDENTITY(members1.person)) FROM ' . HouseholdMember::class . ' members1 ' + . 'WHERE members1.startDate <= :calcDate AND (members1.endDate IS NULL OR members1.endDate > :calcDate) ' + . 'AND members1 MEMBER OF household.members) AS membersId') + + ->addSelect("(SELECT AGGREGATE(CONCAT(person2.firstName, ' ', person2.lastName)) FROM " . HouseholdMember::class . ' members2 ' + . 'JOIN members2.person person2 ' + . 'WHERE members2.startDate <= :calcDate AND (members2.endDate IS NULL OR members2.endDate > :calcDate) ' + . 'AND members2 MEMBER OF household.members) AS membersName'); + + // composition at date + $qb + ->addSelect('(SELECT compo.numberOfChildren FROM ' . HouseholdComposition::class . ' compo ' + . 'WHERE compo.startDate <= :calcDate AND (compo.endDate IS NULL OR compo.endDate > :calcDate) ' + . 'AND compo MEMBER OF household.compositions) AS compositionNumberOfChildren') + + ->addSelect('(SELECT compo1.comment.comment FROM ' . HouseholdComposition::class . ' compo1 ' + . 'WHERE compo1.startDate <= :calcDate AND (compo1.endDate IS NULL OR compo1.endDate > :calcDate) ' + . 'AND compo1 MEMBER OF household.compositions) AS compositionComment') + + ->addSelect('( + SELECT type2.label + FROM ' . HouseholdComposition::class . ' compo2 + JOIN compo2.householdCompositionType type2 + WHERE compo2.startDate <= :calcDate AND (compo2.endDate IS NULL OR compo2.endDate > :calcDate) + AND compo2 MEMBER OF household.compositions + ) AS compositionType'); + + // address at date + $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') + ) + ) + ); + $this->addressHelper->addSelectClauses( + ExportAddressHelper::F_ALL, + $qb, + 'addresses', + 'address_fields' + ); + + // inject date parameter + $qb->setParameter('calcDate', $calcDate); + } +} diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodWorkEvaluationVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodWorkEvaluationVoter.php index 6f711f8b3..3861d5dd6 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodWorkEvaluationVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodWorkEvaluationVoter.php @@ -11,16 +11,25 @@ declare(strict_types=1); namespace Chill\PersonBundle\Security\Authorization; +use Chill\MainBundle\Security\Authorization\ChillVoterInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\Voter\Voter; use Symfony\Component\Security\Core\Security; use UnexpectedValueException; +use function in_array; -class AccompanyingPeriodWorkEvaluationVoter extends Voter +class AccompanyingPeriodWorkEvaluationVoter extends Voter implements ChillVoterInterface { + public const ALL = [ + self::SEE, + self::STATS, + ]; + public const SEE = 'CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_EVALUATION_SHOW'; + public const STATS = 'CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_EVALUATION_STATS'; + private Security $security; public function __construct(Security $security) @@ -31,7 +40,7 @@ class AccompanyingPeriodWorkEvaluationVoter extends Voter protected function supports($attribute, $subject) { return $subject instanceof AccompanyingPeriodWorkEvaluation - && self::SEE === $attribute; + && in_array($attribute, self::ALL, true); } /** @@ -41,6 +50,9 @@ class AccompanyingPeriodWorkEvaluationVoter extends Voter protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool { switch ($attribute) { + case self::STATS: + return $this->security->isGranted(AccompanyingPeriodWorkVoter::STATS, $subject); + case self::SEE: return $this->security->isGranted(AccompanyingPeriodWorkVoter::SEE, $subject->getAccompanyingPeriodWork()); diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodWorkVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodWorkVoter.php index 54872f877..84f31c202 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodWorkVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodWorkVoter.php @@ -11,8 +11,13 @@ declare(strict_types=1); namespace Chill\PersonBundle\Security\Authorization; +use Chill\MainBundle\Security\Authorization\ChillVoterInterface; +use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface; +use Chill\MainBundle\Security\Authorization\VoterHelperInterface; +use Chill\MainBundle\Security\ProvideRoleHierarchyInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork; +use Chill\PersonBundle\Entity\Person; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\Voter\Voter; use Symfony\Component\Security\Core\Security; @@ -20,8 +25,15 @@ use UnexpectedValueException; use function get_class; use function in_array; -class AccompanyingPeriodWorkVoter extends Voter +class AccompanyingPeriodWorkVoter extends Voter implements ProvideRoleHierarchyInterface, ChillVoterInterface { + public const ALL = [ + self::SEE, + self::CREATE, + self::UPDATE, + self::DELETE, + ]; + public const CREATE = 'CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_CREATE'; public const DELETE = 'CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_DELETE'; @@ -32,9 +44,39 @@ class AccompanyingPeriodWorkVoter extends Voter private Security $security; - public function __construct(Security $security) - { + private VoterHelperInterface $voterHelper; + + public function __construct( + Security $security, + VoterHelperFactoryInterface $voterHelperFactory + ) { $this->security = $security; + $this->voterHelper = $voterHelperFactory + ->generate(self::class) + ->addCheckFor(null, [self::CREATE]) + ->addCheckFor(AccompanyingPeriod::class, [self::ALL]) + ->addCheckFor(Person::class, [self::SEE, self::CREATE]) + ->build(); + } + + public function getRoles(): array + { + return [ + self::SEE, + self::CREATE, + self::UPDATE, + self::DELETE, + ]; + } + + public function getRolesWithHierarchy(): array + { + return ['Social actions' => $this->getRoles()]; + } + + public function getRolesWithoutScope(): array + { + return []; } protected function supports($attribute, $subject): bool @@ -86,9 +128,4 @@ class AccompanyingPeriodWorkVoter extends Voter throw new UnexpectedValueException(sprintf("attribute {$attribute} on instance %s is not supported", get_class($subject))); } - - private function getRoles(): array - { - return [self::SEE, self::CREATE, self::UPDATE, self::DELETE]; - } } diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/HouseholdVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/HouseholdVoter.php index 5d57cadcc..47a15db54 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/HouseholdVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/HouseholdVoter.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Security\Authorization; use Chill\MainBundle\Entity\Center; +use Chill\MainBundle\Security\Authorization\ChillVoterInterface; use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface; use Chill\MainBundle\Security\Authorization\VoterHelperInterface; use Chill\MainBundle\Security\ProvideRoleHierarchyInterface; @@ -23,7 +24,7 @@ use Symfony\Component\Security\Core\Security; use UnexpectedValueException; use function in_array; -class HouseholdVoter extends Voter implements ProvideRoleHierarchyInterface +class HouseholdVoter extends Voter implements ProvideRoleHierarchyInterface, ChillVoterInterface { public const EDIT = 'CHILL_PERSON_HOUSEHOLD_EDIT'; @@ -37,7 +38,9 @@ class HouseholdVoter extends Voter implements ProvideRoleHierarchyInterface public const STATS = 'CHILL_PERSON_HOUSEHOLD_STATS'; private const ALL = [ - self::EDIT, self::SEE, + self::SEE, + self::EDIT, + self::STATS, ]; private VoterHelperInterface $helper; @@ -60,7 +63,7 @@ class HouseholdVoter extends Voter implements ProvideRoleHierarchyInterface public function getRolesWithHierarchy(): array { - return ['Person' => $this->getRoles()]; + return ['Household' => $this->getRoles()]; } public function getRolesWithoutScope(): array diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Export/CountSocialWorkActionsTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Export/CountAccompanyingPeriodWorkTest.php similarity index 81% rename from src/Bundle/ChillPersonBundle/Tests/Export/Export/CountSocialWorkActionsTest.php rename to src/Bundle/ChillPersonBundle/Tests/Export/Export/CountAccompanyingPeriodWorkTest.php index 3ad0f7c1b..a16e04359 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Export/CountSocialWorkActionsTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Export/CountAccompanyingPeriodWorkTest.php @@ -13,15 +13,15 @@ namespace Export\Export; use Chill\MainBundle\Test\Export\AbstractExportTest; use Chill\PersonBundle\Export\Declarations; -use Chill\PersonBundle\Export\Export\CountSocialWorkActions; +use Chill\PersonBundle\Export\Export\CountAccompanyingPeriodWork; /** * @internal * @coversNothing */ -final class CountSocialWorkActionsTest extends AbstractExportTest +final class CountAccompanyingPeriodWorkTest extends AbstractExportTest { - private CountSocialWorkActions $export; + private CountAccompanyingPeriodWork $export; protected function setUp(): void { diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_evaluation.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_evaluation.yaml index f58b7112b..83b80d54e 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_evaluation.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_evaluation.yaml @@ -8,6 +8,12 @@ services: tags: - { name: chill.export, alias: count_evaluation } + Chill\PersonBundle\Export\Export\ListEvaluation: + autowire: true + autoconfigure: true + tags: + - { name: chill.export, alias: list_evaluation } + ## Filters chill.person.export.filter_evaluationtype: class: Chill\PersonBundle\Export\Filter\EvaluationFilters\EvaluationTypeFilter diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_household.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_household.yaml index 0b8c5f1ce..1a12c1bc8 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_household.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_household.yaml @@ -8,6 +8,12 @@ services: tags: - { name: chill.export, alias: count_household } + Chill\PersonBundle\Export\Export\ListHouseholdInPeriod: + autowire: true + autoconfigure: true + tags: + - { name: chill.export, alias: list_household_in_period } + ## Filters chill.person.export.filter_household_composition: class: Chill\PersonBundle\Export\Filter\HouseholdFilters\CompositionFilter diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml index 13c51762f..ecf0ec399 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml @@ -1,14 +1,19 @@ services: - chill.person.export.count_social_work_actions: - class: Chill\PersonBundle\Export\Export\CountSocialWorkActions + ## Indicators + Chill\PersonBundle\Export\Export\CountAccompanyingPeriodWork: autowire: true autoconfigure: true tags: - { name: chill.export, alias: count_social_work_actions } - ## FILTERS + Chill\PersonBundle\Export\Export\ListAccompanyingPeriodWork: + autowire: true + autoconfigure: true + tags: + - { name: chill.export, alias: list_social_work_actions } + ## FILTERS chill.person.export.filter_social_work_type: class: Chill\PersonBundle\Export\Filter\SocialWorkFilters\SocialWorkTypeFilter autowire: true diff --git a/src/Bundle/ChillPersonBundle/migrations/Version20230117152610.php b/src/Bundle/ChillPersonBundle/migrations/Version20230117152610.php new file mode 100644 index 000000000..81b61d2b5 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/migrations/Version20230117152610.php @@ -0,0 +1,52 @@ +addSql('ALTER TABLE country ALTER name TYPE JSON'); + $this->addSql('ALTER TABLE country ALTER name SET DEFAULT \'[]\'::json'); + $this->addSql('ALTER TABLE country ALTER name DROP NOT NULL'); + $this->addSql('COMMENT ON COLUMN country.name IS \'(DC2Type:simple_array)\''); + + $this->addSql('ALTER TABLE chill_person_household_composition_type ALTER label TYPE JSON'); + $this->addSql('ALTER TABLE chill_person_household_composition_type ALTER label SET DEFAULT \'[]\'::json'); + $this->addSql('ALTER TABLE chill_person_household_composition_type ALTER label DROP NOT NULL'); + $this->addSql('COMMENT ON COLUMN chill_person_household_composition_type.label IS \'(DC2Type:simple_array)\''); + } + + public function getDescription(): string + { + return 'convert json fields to jsonb'; + } + + public function up(Schema $schema): void + { + $this->addSql('ALTER TABLE chill_person_household_composition_type ALTER label TYPE JSONB'); + $this->addSql('ALTER TABLE chill_person_household_composition_type ALTER label SET DEFAULT \'[]\'::jsonb'); + $this->addSql('ALTER TABLE chill_person_household_composition_type ALTER label DROP NOT NULL'); + $this->addSql('COMMENT ON COLUMN chill_person_household_composition_type.label IS \'(DC2Type:json)\''); + + $this->addSql('ALTER TABLE country ALTER name TYPE JSONB'); + $this->addSql('ALTER TABLE country ALTER name SET DEFAULT \'[]\'::jsonb'); + $this->addSql('ALTER TABLE country ALTER name DROP NOT NULL'); + $this->addSql('COMMENT ON COLUMN country.name IS \'(DC2Type:json)\''); + } +} diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 5178a042c..55f1282cb 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -246,7 +246,6 @@ The accompanying course has been successfully removed.: La période d'accompagne Concerned scopes: Services concernés # person resource - person_resources_menu: "Personnes ressources" Person resources: "Ressources de la personne" Add a person resource: "Ajouter une ressource" @@ -259,8 +258,6 @@ There are no available resources: "Aucun ressource" no comment found: "Aucun commentaire" Select a type: "Choisissez un type" Select a person: "Choisissez une personne" -Select a thirdparty: "Choisissez un tiers" -Contact person: "Personne de contact" Kind: "Type" @@ -288,14 +285,11 @@ Residential addresses history: Historique des adresses de résidence Add a residential address: Ajouter une adresse de résidence Which kind of residential address would you create ?: Quel type d'adresse de résidence voulez-vous créer? The address of another person: L'adresse d'une autre personne -The address of a third party: L'adresse d'un tiers A new address: Une nouvelle adresse residential_address_person_explanation: L'adresse sera positionnée auprès d'une personne. Lorsque la personne déménage, l'adresse de résidence suivra également cette personne -residential_address_third_party_explanation: L'adresse sera associée à celle d'un tiers. residential_address_new_address_explanation: Créer une nouvelle adresse. L'adresse sera fixe. New residential address: Nouvelle adresse de résidence Host person: Choisir l'adresse d'une personne -Host third party: Choisir l'adresse d'un tiers The new residential address was created successfully: La nouvelle adresse de résidence a été créée Edit a residential address: Modifier l'addresse de résidence The residential address was updated successfully: L'adresse de résidence a été mise à jour @@ -313,13 +307,14 @@ Closing the accompanying period: Fermeture de la période d'accompagnement Opening the accompanying period: Ouverture d'une période d'accompagnement 'Timeline for %name%': 'Historique de %name%' -#roles +# ROLES CHILL_PERSON_SEE: Voir les personnes CHILL_PERSON_UPDATE: Modifier les personnes CHILL_PERSON_CREATE: Ajouter des personnes CHILL_PERSON_STATS: Statistiques sur les personnes CHILL_PERSON_LISTS: Liste des personnes CHILL_PERSON_DUPLICATE: Gérer les doublons de personnes + CHILL_PERSON_ACCOMPANYING_PERIOD_SEE: Vision simplifiée d'une période d'accompagnement CHILL_PERSON_ACCOMPANYING_PERIOD_CONFIDENTIAL: Voir et modifier les périodes d'accompagnement confidentielles CHILL_PERSON_ACCOMPANYING_PERIOD_DELETE: Supprimer une période d'accompagnement @@ -332,6 +327,18 @@ CHILL_PERSON_ACCOMPANYING_PERIOD_FULL: Voir les détails, créer, supprimer et m CHILL_PERSON_ACCOMPANYING_COURSE_REASSIGN_BULK: Réassigner les parcours en lot CHILL_PERSON_ACCOMPANYING_PERIOD_SEE_DETAILS: Voir les détails d'une période d'accompagnement CHILL_PERSON_ACCOMPANYING_PERIOD_STATS: Statistiques sur les parcours d'accompagnement + +CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_CREATE: Créer une action d'accompagnement +CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_DELETE: Supprimer une action d'accompagnement +CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_SEE: Voir les actions d'accompagnement +CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE: Modifier une action d'accompagnement +CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_STATS: Statistiques sur les actions d'accompagnement + +CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_EVALUATION_SHOW: Voir les évaluations +CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_EVALUATION_STATS: Statistiques sur les évaluations + +CHILL_PERSON_HOUSEHOLD_SEE: Voir les ménages +CHILL_PERSON_HOUSEHOLD_EDIT: Modifier les ménages CHILL_PERSON_HOUSEHOLD_STATS: Statistiques sur les ménages #period @@ -409,7 +416,6 @@ Maximum age: Âge maximum The minimum age should be less than the maximum age.: L'âge minimum doit être plus bas que l'âge maximum. Date during which residential address was valid: Date de validité -Filtered by person\'s who have a residential address located at a thirdparty of type %thirparty_type%: Uniquement les personnes qui ont une addresse de résidence chez un tiers de catégorie %thirdparty_type% Family composition: Composition familiale Family composition at this time: Composition familiale à cette date. @@ -518,7 +524,6 @@ Filter by requestor: Filtrer les parcours selon la présence du demandeur au sei Accepted choices: '' is person concerned: Le demandeur est une personne concernée is other person: Le demandeur est une personne, mais n'est pas concernée -is thirdparty: Le demandeur est un tiers no requestor: Le parcours ne comporte pas de demandeur "Filtered by requestor: only %choice%": "Filtré par présence du demandeur au sein des personnes concernées: uniquement si %choice%" Group by requestor: Grouper les parcours selon la nature du demandeur @@ -655,9 +660,6 @@ Aggregate by household position: Grouper les personnes par position dans le mén Household position in relation to this date: Position dans le ménage par rapport à cette date Household position: Position dans le ménage -Filter by person's who have a residential address located at a thirdparty of type: Filtrer les personnes qui ont une addresse de résidence chez un tiers de catégorie "xxx" -"Filtered by person's who have a residential address located at a thirdparty of type %thirdparty_type% and valid on %date_calc%": "Uniquement les personnes qui ont une addresse de résidence chez un tiers de catégorie %thirdparty_type% et valide sur la date %date_calc%" - Aggregate by age: Grouper les personnes par âge Calculate age in relation to this date: Calculer l'âge par rapport à cette date @@ -930,8 +932,6 @@ docgen: A context for accompanying period work evaluation: Contexte pour les évaluations dans les actions d'accompagnement Person basic: Personne (basique) A basic context for person: Contexte pour les personnes - Person with third party: Personne avec choix d'un tiers - A context for person with a third party (for sending mail): Un contexte d'une personne avec un tiers (pour envoyer un courrier à ce tiers, par exemple) Label for third party: Label à afficher aux utilisateurs Document title: Titre du document généré @@ -1106,16 +1106,80 @@ export: locationPersonId: Identifiant de l'usager auprès duquel le parcours est localisé acpaddress_fieldscountry: Pays de l'adresse isRequestorPerson: Le demandeur est-il un usager ? - isRequestorThirdParty: Le demandeur est-il un tiers ? requestorPersonId: Identifiant du demandeur personne - requestorThirdPartyId: Identifiant du tiers acprequestorPerson: Nom du demandeur personne - acprequestorThirdPaty: Nom du demandeur tiers scopes: Services socialIssues: Problématiques sociales - - - + eval: + List of evaluations: Liste des évaluations + Generate a list of evaluations, filtered on different parameters: Génère une liste des évaluations, filtrée sur différents paramètres. + Date of calculation for associated elements: Date de calcul des éléments associés + help_description: Les éléments associés, tel que le référent, l'adresse des usagers, etc. seront évalués à cette date + id: Identifiant de l'évaluation + startDate: Date de début + endDate: Date de fin + maxDate: Date d'échéance + warningInterval: Rappel + acpw_id: Identifiant de l'action + acpw_startDate: Début de l'action + acpw_endDate: Fin de l'action + acpw_socialaction_id: Identifiant de l'action + acpw_socialaction: Intitulé de l'action + acpw_socialissue: Problématique sociale + acpw_note: Commentaire de l'action + acpw_acp_id: Identifiant du parcours + acpw_acp_user: Référent du parcours + acpw_referrers: Agent traitant à la date spécifiée + acpw_persons_id: Identifiant des usagers + acpw_persons: Usagers de l'action + comment: Commentaire de l'évaluation + eval_title: Intitulé de l'évaluation + createdAt: Date de création + updatedAt: Date de modification + createdBy: Créé par + updatedBy: Modifié par + acpw: + List of accompanying period works: Liste des actions + List description: Génère une liste des actions d'accompagnement, filtrée sur différents paramètres. + help_description: L'agent traitant de l'action sera valide à cette date + id: Identifiant de l'action + startDate: Date de début + endDate: Date de fin + note: Commentaire de l'action + createdAt: Date de création + updatedAt: Date de modification + socialActionId: Identifiant de l'action + socialAction: Intitulé de l'action + socialIssue: Problématique sociale + createdBy: Créé par + updatedBy: Modifié par + acp_id: Identifiant du parcours + acp_user: Référent du parcours + referrers: Agents traitants + personsId: Identifiants des usagers + personsName: Usagers de l'action + goalsId: Identifiants des objectifs + goalsTitle: Objectifs + goalResultsId: Identifiants des résultats d'objectifs + goalResultsTitle: Résultats des objectifs + resultsId: Identifiants des Résultats + resultsTitle: Résultats + evaluationsId: Identifiants des évaluations + evaluationsTitle: Évaluations + household: + List household associated with accompanying period title: Liste des ménages impliqués dans un parcours + List description: Génère la liste des ménages, filtrée selon divers paramètres. + Date of calculation for associated elements: Date de calcul des éléments associés + help_description: Les éléments associés, comme l'adresse, les membres et la composition du ménage seront valides à cette date + id: Identifiant du ménage + address: Adresse du ménage + membersId: Identifiants des membres du ménage + membersName: Membres du ménage + membersCount: Nombre de membres + compositionNumberOfChildren: Nombre d'enfants dans la composition + compositionComment: Commentaire sur la composition + compositionType: Type de composition + acpaddress_fieldscountry: Pays # addressHelper effect social_action: and children: et dérivés diff --git a/src/Bundle/ChillTaskBundle/translations/messages.fr.yml b/src/Bundle/ChillTaskBundle/translations/messages.fr.yml index a2a57708f..8d1d2b39d 100644 --- a/src/Bundle/ChillTaskBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillTaskBundle/translations/messages.fr.yml @@ -116,3 +116,6 @@ CHILL_TASK_TASK_CREATE: Ajouter une tâche CHILL_TASK_TASK_DELETE: Supprimer une tâche CHILL_TASK_TASK_SHOW: Voir une tâche CHILL_TASK_TASK_UPDATE: Modifier une tâche +CHILL_TASK_TASK_CREATE_FOR_COURSE: Créer une tâche pour un parcours +CHILL_TASK_TASK_CREATE_FOR_PERSON: Créer une tâche pour une personne + diff --git a/src/Bundle/ChillThirdPartyBundle/Export/Helper/LabelThirdPartyHelper.php b/src/Bundle/ChillThirdPartyBundle/Export/Helper/LabelThirdPartyHelper.php index dc5f8ddc6..f87fe41b4 100644 --- a/src/Bundle/ChillThirdPartyBundle/Export/Helper/LabelThirdPartyHelper.php +++ b/src/Bundle/ChillThirdPartyBundle/Export/Helper/LabelThirdPartyHelper.php @@ -28,6 +28,21 @@ class LabelThirdPartyHelper $this->thirdPartyRepository = $thirdPartyRepository; } + public function getLabel(string $key, array $values, string $header): callable + { + return function ($value) use ($header) { + if ('_header' === $value) { + return $header; + } + + if (null === $value || null === $thirdParty = $this->thirdPartyRepository->find($value)) { + return ''; + } + + return $this->thirdPartyRender->renderString($thirdParty, []); + }; + } + public function getLabelMulti(string $key, array $values, string $header): callable { return function ($value) use ($header) { diff --git a/src/Bundle/ChillThirdPartyBundle/Security/Voter/ThirdPartyVoter.php b/src/Bundle/ChillThirdPartyBundle/Security/Voter/ThirdPartyVoter.php index 8c59ea799..e1dae28b9 100644 --- a/src/Bundle/ChillThirdPartyBundle/Security/Voter/ThirdPartyVoter.php +++ b/src/Bundle/ChillThirdPartyBundle/Security/Voter/ThirdPartyVoter.php @@ -54,7 +54,7 @@ class ThirdPartyVoter extends AbstractChillVoter implements ProvideRoleHierarchy public function getRolesWithHierarchy(): array { return [ - 'Third Party' => $this->getRoles(), + 'Third party' => $this->getRoles(), ]; } diff --git a/src/Bundle/ChillThirdPartyBundle/translations/messages.fr.yml b/src/Bundle/ChillThirdPartyBundle/translations/messages.fr.yml index 0ea68c8e8..94a10177b 100644 --- a/src/Bundle/ChillThirdPartyBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillThirdPartyBundle/translations/messages.fr.yml @@ -82,6 +82,15 @@ Third party category: Catégories de tiers Third party configuration: Gestion des tiers +# person resource +Select a thirdparty: "Choisissez un tiers" +Contact person: "Personne de contact" + +# Residential address +The address of a third party: L'adresse d'un tiers +residential_address_third_party_explanation: L'adresse sera associée à celle d'un tiers. +Host third party: Choisir l'adresse d'un tiers + # ROLES CHILL_3PARTY_3PARTY_CREATE: Ajouter un Tiers CHILL_3PARTY_3PARTY_SHOW: Voir un Tiers @@ -99,3 +108,25 @@ crud: title_new: Nouvelle catégorie de tiers title_edit: Modifier la catégorie de tiers +# docgen +docgen: + A context for person with a third party (for sending mail): Un contexte d'une personne avec un tiers (pour envoyer un courrier à ce tiers, par exemple) + Person with third party: Personne avec choix d'un tiers + +# exports +export: + list: + acp: + isRequestorThirdParty: Le demandeur est-il un tiers ? + requestorThirdPartyId: Identifiant du tiers + acprequestorThirdPaty: Nom du demandeur tiers + acpw: + handlingThierParty: Tiers traitant + thirdParties: Tiers intervenant + +# exports filters/aggregators +Filtered by person\'s who have a residential address located at a thirdparty of type %thirparty_type%: Uniquement les personnes qui ont une addresse de résidence chez un tiers de catégorie %thirdparty_type% +is thirdparty: Le demandeur est un tiers + +Filter by person's who have a residential address located at a thirdparty of type: Filtrer les personnes qui ont une addresse de résidence chez un tiers de catégorie "xxx" +"Filtered by person's who have a residential address located at a thirdparty of type %thirdparty_type% and valid on %date_calc%": "Uniquement les personnes qui ont une addresse de résidence chez un tiers de catégorie %thirdparty_type% et valide sur la date %date_calc%"