mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-13 13:54:23 +00:00
Merge remote-tracking branch 'origin/111_exports_suite' into testing
This commit is contained in:
commit
5af492b2db
@ -11,10 +11,10 @@ AccompanyingPeriod::class,,,acp
|
|||||||
,User::class,acp.user,acpuser
|
,User::class,acp.user,acpuser
|
||||||
AccompanyingPeriodWork::class,,,acpw
|
AccompanyingPeriodWork::class,,,acpw
|
||||||
,AccompanyingPeriodWorkEvaluation::class,acpw.accompanyingPeriodWorkEvaluations,workeval
|
,AccompanyingPeriodWorkEvaluation::class,acpw.accompanyingPeriodWorkEvaluations,workeval
|
||||||
,Goal::class,acpw.goals,goal
|
|
||||||
,User::class,acpw.referrers,acpwuser
|
,User::class,acpw.referrers,acpwuser
|
||||||
,Result::class,acpw.results,acpwresult
|
|
||||||
,SocialAction::class,acpw.socialAction,acpwsocialaction
|
,SocialAction::class,acpw.socialAction,acpwsocialaction
|
||||||
|
,Goal::class,acpw.goals,goal
|
||||||
|
,Result::class,acpw.results,result
|
||||||
AccompanyingPeriodParticipation::class,,,acppart
|
AccompanyingPeriodParticipation::class,,,acppart
|
||||||
,Person::class,acppart.person,partperson
|
,Person::class,acppart.person,partperson
|
||||||
AccompanyingPeriodWorkEvaluation::class,,,workeval
|
AccompanyingPeriodWorkEvaluation::class,,,workeval
|
||||||
@ -23,17 +23,17 @@ Goal::class,,,goal
|
|||||||
,Result::class,goal.results,goalresult
|
,Result::class,goal.results,goalresult
|
||||||
Person::class,,,person
|
Person::class,,,person
|
||||||
,Center::class,person.center,center
|
,Center::class,person.center,center
|
||||||
,HouseholdMember::class,partperson.householdParticipations,member
|
,HouseholdMember::class,partperson.householdParticipations,householdmember
|
||||||
,MaritalStatus::class,person.maritalStatus,personmarital
|
,MaritalStatus::class,person.maritalStatus,personmarital
|
||||||
|
,VendeePerson::class,,vp
|
||||||
|
,VendeePersonMineur::class,,vpm
|
||||||
ResidentialAddress::class,,,resaddr
|
ResidentialAddress::class,,,resaddr
|
||||||
,Person::class,resaddr.person,resaddrperson
|
|
||||||
,Center::class,resaddrperson.center,resaddrcenter
|
|
||||||
,ThirdParty::class,resaddr.hostThirdParty,tparty
|
,ThirdParty::class,resaddr.hostThirdParty,tparty
|
||||||
ThirdParty::class,,,tparty
|
ThirdParty::class,,,tparty
|
||||||
,ThirdPartyCategory::class,tparty.categories,tpartycat
|
,ThirdPartyCategory::class,tparty.categories,tpartycat
|
||||||
HouseholdMember::class,,,member
|
HouseholdMember::class,,,householdmember
|
||||||
,Household::class,member.household,household
|
,Household::class,householdmember.household,household
|
||||||
,Person::class,member.person,memberperson
|
,Person::class,householdmember.person,memberperson
|
||||||
,,memberperson.center,membercenter
|
,,memberperson.center,membercenter
|
||||||
Household::class,,,household
|
Household::class,,,household
|
||||||
,HouseholdComposition::class,household.compositions,composition
|
,HouseholdComposition::class,household.compositions,composition
|
||||||
@ -58,11 +58,6 @@ Calendar::class,,,cal
|
|||||||
,Location::class,cal.location,calloc
|
,Location::class,cal.location,calloc
|
||||||
,User::class,cal.user,caluser
|
,User::class,cal.user,caluser
|
||||||
VendeePerson::class,,,vp
|
VendeePerson::class,,,vp
|
||||||
,Person::class,vp.person,vpperson
|
|
||||||
,Center::class,vpperson.center,vpcenter
|
|
||||||
,SituationProfessionelle::class,vp.situationProfessionelle,vpprof
|
,SituationProfessionelle::class,vp.situationProfessionelle,vpprof
|
||||||
,StatutLogement::class,vp.statutLogement,vplog
|
,StatutLogement::class,vp.statutLogement,vplog
|
||||||
,TempsDeTravail::class,vp.tempsDeTravail,vptt
|
,TempsDeTravail::class,vp.tempsDeTravail,vptt
|
||||||
VendeePersonMineur::class,,,vpm
|
|
||||||
,Person::class,vpm.person,vpmperson
|
|
||||||
,Center::class,vpmperson.center,vpmcenter
|
|
||||||
|
|
@ -5,72 +5,67 @@ Add condition with distinct alias on each export join clauses (Indicators + Filt
|
|||||||
|
|
||||||
These are alias conventions :
|
These are alias conventions :
|
||||||
|
|
||||||
| Entity | Join | Attribute | Alias |
|
| Entity | Join | Attribute | Alias |
|
||||||
| :--- | :--- |:-------------------------------------------|:----------------------------------|
|
|:----------------------------------------|:----------------------------------------|:-------------------------------------------|:----------------------------------|
|
||||||
| AccompanyingPeriod::class | | | acp |
|
| AccompanyingPeriod::class | | | acp |
|
||||||
| | AccompanyingPeriodWork::class | acp.works | acpw |
|
| | AccompanyingPeriodWork::class | acp.works | acpw |
|
||||||
| | AccompanyingPeriodParticipation::class | acp.participations | acppart |
|
| | AccompanyingPeriodParticipation::class | acp.participations | acppart |
|
||||||
| | Location::class | acp.administrativeLocation | acploc |
|
| | Location::class | acp.administrativeLocation | acploc |
|
||||||
| | ClosingMotive::class | acp.closingMotive | acpmotive |
|
| | ClosingMotive::class | acp.closingMotive | acpmotive |
|
||||||
| | UserJob::class | acp.job | acpjob |
|
| | UserJob::class | acp.job | acpjob |
|
||||||
| | Origin::class | acp.origin | acporigin |
|
| | Origin::class | acp.origin | acporigin |
|
||||||
| | Scope::class | acp.scopes | acpscope |
|
| | Scope::class | acp.scopes | acpscope |
|
||||||
| | SocialIssue::class | acp.socialIssues | acpsocialissue |
|
| | SocialIssue::class | acp.socialIssues | acpsocialissue |
|
||||||
| | User::class | acp.user | acpuser |
|
| | User::class | acp.user | acpuser |
|
||||||
| AccompanyingPeriodWork::class | | | acpw |
|
| AccompanyingPeriodWork::class | | | acpw |
|
||||||
| | AccompanyingPeriodWorkEvaluation::class | acpw.accompanyingPeriodWorkEvaluations | workeval |
|
| | AccompanyingPeriodWorkEvaluation::class | acpw.accompanyingPeriodWorkEvaluations | workeval |
|
||||||
| | Goal::class | acpw.goals | goal |
|
| | User::class | acpw.referrers | acpwuser |
|
||||||
| | User::class | acpw.referrers | acpwuser |
|
| | SocialAction::class | acpw.socialAction | acpwsocialaction |
|
||||||
| | Result::class | acpw.results | acpwresult |
|
| | Goal::class | acpw.goals | goal |
|
||||||
| | SocialAction::class | acpw.socialAction | acpwsocialaction |
|
| | Result::class | acpw.results | result |
|
||||||
| AccompanyingPeriodParticipation::class | | | acppart |
|
| AccompanyingPeriodParticipation::class | | | acppart |
|
||||||
| | Person::class | acppart.person | partperson |
|
| | Person::class | acppart.person | partperson |
|
||||||
| AccompanyingPeriodWorkEvaluation::class | | | workeval |
|
| AccompanyingPeriodWorkEvaluation::class | | | workeval |
|
||||||
| | Evaluation::class | workeval.evaluation | eval |
|
| | Evaluation::class | workeval.evaluation | eval |
|
||||||
| Goal::class | | | goal |
|
| Goal::class | | | goal |
|
||||||
| | Result::class | goal.results | goalresult |
|
| | Result::class | goal.results | goalresult |
|
||||||
| Person::class | | | person |
|
| Person::class | | | person |
|
||||||
| | Center::class | person.center | center |
|
| | Center::class | person.center | center |
|
||||||
| | HouseholdMember::class | partperson.householdParticipations | member |
|
| | HouseholdMember::class | partperson.householdParticipations | householdmember |
|
||||||
| | MaritalStatus::class | person.maritalStatus | personmarital |
|
| | MaritalStatus::class | person.maritalStatus | personmarital |
|
||||||
| ResidentialAddress::class | | | resaddr |
|
| | VendeePerson::class | | vp |
|
||||||
| | Person::class | resaddr.person | resaddrperson |
|
| | VendeePersonMineur::class | | vpm |
|
||||||
| | Center::class | resaddrperson.center | resaddrcenter |
|
| ResidentialAddress::class | | | resaddr |
|
||||||
| | ThirdParty::class | resaddr.hostThirdParty | tparty |
|
| | ThirdParty::class | resaddr.hostThirdParty | tparty |
|
||||||
| ThirdParty::class | | | tparty |
|
| ThirdParty::class | | | tparty |
|
||||||
| | ThirdPartyCategory::class | tparty.categories | tpartycat |
|
| | ThirdPartyCategory::class | tparty.categories | tpartycat |
|
||||||
| HouseholdMember::class | | | member |
|
| HouseholdMember::class | | | householdmember |
|
||||||
| | Household::class | member.household | household |
|
| | Household::class | householdmember.household | household |
|
||||||
| | Person::class | member.person | memberperson |
|
| | Person::class | householdmember.person | memberperson |
|
||||||
| | | memberperson.center | membercenter |
|
| | | memberperson.center | membercenter |
|
||||||
| Household::class | | | household |
|
| Household::class | | | household |
|
||||||
| | HouseholdComposition::class | household.compositions | composition |
|
| | HouseholdComposition::class | household.compositions | composition |
|
||||||
| Activity::class | | | activity |
|
| Activity::class | | | activity |
|
||||||
| | Person::class | activity.person | actperson |
|
| | Person::class | activity.person | actperson |
|
||||||
| | AccompanyingPeriod::class | activity.accompanyingPeriod | actacp |
|
| | AccompanyingPeriod::class | activity.accompanyingPeriod | actacp |
|
||||||
| | Person::class | activity\_person\_having\_activity.person | person\_person\_having\_activity |
|
| | Person::class | activity\_person\_having\_activity.person | person\_person\_having\_activity |
|
||||||
| | ActivityReason::class | activity\_person\_having\_activity.reasons | reasons\_person\_having\_activity |
|
| | ActivityReason::class | activity\_person\_having\_activity.reasons | reasons\_person\_having\_activity |
|
||||||
| | ActivityType::class | activity.activityType | acttype |
|
| | ActivityType::class | activity.activityType | acttype |
|
||||||
| | Location::class | activity.location | actloc |
|
| | Location::class | activity.location | actloc |
|
||||||
| | SocialAction::class | activity.socialActions | actsocialaction |
|
| | SocialAction::class | activity.socialActions | actsocialaction |
|
||||||
| | SocialIssue::class | activity.socialIssues | actsocialssue |
|
| | SocialIssue::class | activity.socialIssues | actsocialssue |
|
||||||
| | ThirdParty::class | activity.thirdParties | acttparty |
|
| | ThirdParty::class | activity.thirdParties | acttparty |
|
||||||
| | User::class | activity.user | actuser |
|
| | User::class | activity.user | actuser |
|
||||||
| | User::class | activity.users | actusers |
|
| | User::class | activity.users | actusers |
|
||||||
| | ActivityReason::class | activity.reasons | actreasons |
|
| | ActivityReason::class | activity.reasons | actreasons |
|
||||||
| | Center::class | actperson.center | actcenter |
|
| | Center::class | actperson.center | actcenter |
|
||||||
| ActivityReason::class | | | actreasons |
|
| ActivityReason::class | | | actreasons |
|
||||||
| | ActivityReasonCategory::class | actreason.category | actreasoncat |
|
| | ActivityReasonCategory::class | actreason.category | actreasoncat |
|
||||||
| Calendar::class | | | cal |
|
| Calendar::class | | | cal |
|
||||||
| | CancelReason::class | cal.cancelReason | calcancel |
|
| | CancelReason::class | cal.cancelReason | calcancel |
|
||||||
| | Location::class | cal.location | calloc |
|
| | Location::class | cal.location | calloc |
|
||||||
| | User::class | cal.user | caluser |
|
| | User::class | cal.user | caluser |
|
||||||
| VendeePerson::class | | | vp |
|
| VendeePerson::class | | | vp |
|
||||||
| | Person::class | vp.person | vpperson |
|
| | SituationProfessionelle::class | vp.situationProfessionelle | vpprof |
|
||||||
| | Center::class | vpperson.center | vpcenter |
|
| | StatutLogement::class | vp.statutLogement | vplog |
|
||||||
| | SituationProfessionelle::class | vp.situationProfessionelle | vpprof |
|
| | TempsDeTravail::class | vp.tempsDeTravail | vptt |
|
||||||
| | StatutLogement::class | vp.statutLogement | vplog |
|
|
||||||
| | TempsDeTravail::class | vp.tempsDeTravail | vptt |
|
|
||||||
| VendeePersonMineur::class | | | vpm |
|
|
||||||
| | Person::class | vpm.person | vpmperson |
|
|
||||||
| | Center::class | vpmperson.center | vpmcenter |
|
|
||||||
|
@ -101,7 +101,7 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface
|
|||||||
return [
|
return [
|
||||||
Declarations::ACTIVITY,
|
Declarations::ACTIVITY,
|
||||||
Declarations::ACTIVITY_ACP,
|
Declarations::ACTIVITY_ACP,
|
||||||
//PersonDeclarations::ACP_TYPE,
|
PersonDeclarations::ACP_TYPE,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac
|
|||||||
return [
|
return [
|
||||||
Declarations::ACTIVITY,
|
Declarations::ACTIVITY,
|
||||||
Declarations::ACTIVITY_ACP,
|
Declarations::ACTIVITY_ACP,
|
||||||
//PersonDeclarations::ACP_TYPE,
|
PersonDeclarations::ACP_TYPE,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ class CountActivity implements ExportInterface, GroupedExportInterface
|
|||||||
return [
|
return [
|
||||||
Declarations::ACTIVITY,
|
Declarations::ACTIVITY,
|
||||||
Declarations::ACTIVITY_ACP,
|
Declarations::ACTIVITY_ACP,
|
||||||
//PersonDeclarations::ACP_TYPE,
|
PersonDeclarations::ACP_TYPE,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface
|
|||||||
return [
|
return [
|
||||||
Declarations::ACTIVITY,
|
Declarations::ACTIVITY,
|
||||||
Declarations::ACTIVITY_ACP,
|
Declarations::ACTIVITY_ACP,
|
||||||
//PersonDeclarations::ACP_TYPE,
|
PersonDeclarations::ACP_TYPE,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac
|
|||||||
return [
|
return [
|
||||||
Declarations::ACTIVITY,
|
Declarations::ACTIVITY,
|
||||||
Declarations::ACTIVITY_ACP,
|
Declarations::ACTIVITY_ACP,
|
||||||
//PersonDeclarations::ACP_TYPE,
|
PersonDeclarations::ACP_TYPE,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ class CountActivity implements ExportInterface, GroupedExportInterface
|
|||||||
return [
|
return [
|
||||||
Declarations::ACTIVITY,
|
Declarations::ACTIVITY,
|
||||||
Declarations::ACTIVITY_PERSON,
|
Declarations::ACTIVITY_PERSON,
|
||||||
//PersonDeclarations::PERSON_TYPE,
|
PersonDeclarations::PERSON_TYPE,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,13 +9,14 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
|
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
|
||||||
|
|
||||||
use Chill\ActivityBundle\Entity\Activity;
|
use Chill\ActivityBundle\Entity\Activity;
|
||||||
use Chill\ActivityBundle\Entity\ActivityType;
|
use Chill\ActivityBundle\Entity\ActivityType;
|
||||||
use Chill\MainBundle\Export\FilterInterface;
|
use Chill\MainBundle\Export\FilterInterface;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
use Chill\PersonBundle\Export\Declarations;
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
|
use Doctrine\ORM\Query\Expr;
|
||||||
use Doctrine\ORM\Query\Expr\Andx;
|
use Doctrine\ORM\Query\Expr\Andx;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
@ -40,14 +41,8 @@ class ActivityTypeFilter implements FilterInterface
|
|||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data)
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
{
|
{
|
||||||
// One2many between activity and accompanyingperiod is not reversed !
|
if (!in_array('activity', $qb->getAllAliases(), true)) {
|
||||||
// we replace indicator 'from' clause by 'act', and put 'acp' in a join
|
$qb->join(Activity::class, 'activity', Expr\Join::WITH, 'activity.accompanyingPeriod = acp');
|
||||||
|
|
||||||
$qb->resetDQLPart('from');
|
|
||||||
$qb->from(Activity::class, 'activity');
|
|
||||||
|
|
||||||
if (!in_array('actacp', $qb->getAllAliases(), true)) {
|
|
||||||
$qb->join('activity.accompanyingPeriod', 'actacp');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_array('acttype', $qb->getAllAliases(), true)) {
|
if (!in_array('acttype', $qb->getAllAliases(), true)) {
|
@ -197,7 +197,7 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt
|
|||||||
|
|
||||||
public function getTitle()
|
public function getTitle()
|
||||||
{
|
{
|
||||||
return 'Filtered by person having an activity in a period';
|
return 'Filter by person having an activity in a period';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validateForm($data, ExecutionContextInterface $context)
|
public function validateForm($data, ExecutionContextInterface $context)
|
||||||
|
@ -13,10 +13,10 @@ namespace Chill\ActivityBundle\Security\Authorization;
|
|||||||
|
|
||||||
use Chill\MainBundle\Entity\Center;
|
use Chill\MainBundle\Entity\Center;
|
||||||
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
|
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
|
||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface;
|
||||||
|
use Chill\MainBundle\Security\Authorization\VoterHelperInterface;
|
||||||
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
|
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
use function in_array;
|
|
||||||
|
|
||||||
class ActivityStatsVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface
|
class ActivityStatsVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface
|
||||||
{
|
{
|
||||||
@ -24,14 +24,14 @@ class ActivityStatsVoter extends AbstractChillVoter implements ProvideRoleHierar
|
|||||||
|
|
||||||
public const STATS = 'CHILL_ACTIVITY_STATS';
|
public const STATS = 'CHILL_ACTIVITY_STATS';
|
||||||
|
|
||||||
/**
|
protected VoterHelperInterface $helper;
|
||||||
* @var AuthorizationHelper
|
|
||||||
*/
|
|
||||||
protected $helper;
|
|
||||||
|
|
||||||
public function __construct(AuthorizationHelper $helper)
|
public function __construct(VoterHelperFactoryInterface $voterHelperFactory)
|
||||||
{
|
{
|
||||||
$this->helper = $helper;
|
$this->helper = $voterHelperFactory
|
||||||
|
->generate(self::class)
|
||||||
|
->addCheckFor(Center::class, [self::STATS, self::LISTS])
|
||||||
|
->build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRoles(): array
|
public function getRoles(): array
|
||||||
@ -49,30 +49,14 @@ class ActivityStatsVoter extends AbstractChillVoter implements ProvideRoleHierar
|
|||||||
return $this->getAttributes();
|
return $this->getAttributes();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getSupportedClasses()
|
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
|
||||||
{
|
{
|
||||||
return [Center::class];
|
return $this->helper->voteOnAttribute($attribute, $subject, $token);
|
||||||
}
|
|
||||||
|
|
||||||
protected function isGranted($attribute, $object, $user = null)
|
|
||||||
{
|
|
||||||
if (!$user instanceof \Symfony\Component\Security\Core\User\UserInterface) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->helper->userHasAccess($user, $object, $attribute);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function supports($attribute, $subject)
|
protected function supports($attribute, $subject)
|
||||||
{
|
{
|
||||||
if (
|
return $this->helper->supports($attribute, $subject);
|
||||||
$subject instanceof Center
|
|
||||||
&& in_array($attribute, $this->getAttributes(), true)
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getAttributes()
|
private function getAttributes()
|
||||||
|
@ -67,6 +67,11 @@ services:
|
|||||||
name: chill.export_filter
|
name: chill.export_filter
|
||||||
alias: 'activity_person_having_ac_bw_date_filter'
|
alias: 'activity_person_having_ac_bw_date_filter'
|
||||||
|
|
||||||
|
chill.person.export.filter_activitytype:
|
||||||
|
class: Chill\ActivityBundle\Export\Filter\ACPFilters\ActivityTypeFilter
|
||||||
|
tags:
|
||||||
|
- { name: chill.export_filter, alias: accompanyingcourse_activitytype_filter }
|
||||||
|
|
||||||
chill.activity.export.locationtype_filter:
|
chill.activity.export.locationtype_filter:
|
||||||
class: Chill\ActivityBundle\Export\Filter\ACPFilters\LocationTypeFilter
|
class: Chill\ActivityBundle\Export\Filter\ACPFilters\LocationTypeFilter
|
||||||
tags:
|
tags:
|
||||||
|
@ -23,6 +23,7 @@ use Symfony\Component\Form\Extension\Core\Type\FormType;
|
|||||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||||
use Symfony\Component\Form\FormFactoryInterface;
|
use Symfony\Component\Form\FormFactoryInterface;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
@ -142,10 +143,8 @@ class ExportController extends AbstractController
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the list of available exports.
|
* Render the list of available exports.
|
||||||
*
|
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
|
||||||
*/
|
*/
|
||||||
public function indexAction(Request $request)
|
public function indexAction(): Response
|
||||||
{
|
{
|
||||||
$exportManager = $this->exportManager;
|
$exportManager = $this->exportManager;
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ namespace Chill\MainBundle\Export;
|
|||||||
use Chill\MainBundle\Form\Type\Export\ExportType;
|
use Chill\MainBundle\Form\Type\Export\ExportType;
|
||||||
use Chill\MainBundle\Form\Type\Export\PickCenterType;
|
use Chill\MainBundle\Form\Type\Export\PickCenterType;
|
||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||||
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Generator;
|
use Generator;
|
||||||
@ -42,52 +43,38 @@ class ExportManager
|
|||||||
/**
|
/**
|
||||||
* The collected aggregators, injected by DI.
|
* The collected aggregators, injected by DI.
|
||||||
*
|
*
|
||||||
* @var AggregatorInterface[]
|
* @var array|AggregatorInterface[]
|
||||||
*/
|
*/
|
||||||
private $aggregators = [];
|
private array $aggregators = [];
|
||||||
|
|
||||||
/**
|
private AuthorizationCheckerInterface $authorizationChecker;
|
||||||
* @var AuthorizationChecker
|
|
||||||
*/
|
|
||||||
private $authorizationChecker;
|
|
||||||
|
|
||||||
/**
|
private AuthorizationHelperInterface $authorizationHelper;
|
||||||
* @var AuthorizationHelper
|
|
||||||
*/
|
|
||||||
private $authorizationHelper;
|
|
||||||
|
|
||||||
/**
|
private EntityManagerInterface $em;
|
||||||
* @var EntityManagerInterface
|
|
||||||
*/
|
|
||||||
private $em;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collected Exports, injected by DI.
|
* Collected Exports, injected by DI.
|
||||||
*
|
*
|
||||||
* @var ExportInterface[]
|
* @var array|ExportInterface[]
|
||||||
*/
|
*/
|
||||||
private $exports = [];
|
private array $exports = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The collected filters, injected by DI.
|
* The collected filters, injected by DI.
|
||||||
*
|
*
|
||||||
* @var FilterInterface[]
|
* @var array|FilterInterface[]
|
||||||
*/
|
*/
|
||||||
private $filters = [];
|
private array $filters = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collected Formatters, injected by DI.
|
* Collected Formatters, injected by DI.
|
||||||
*
|
*
|
||||||
* @var FormatterInterface[]
|
* @var array|FormatterInterface[]
|
||||||
*/
|
*/
|
||||||
private $formatters = [];
|
private array $formatters = [];
|
||||||
|
|
||||||
/**
|
private LoggerInterface $logger;
|
||||||
* a logger.
|
|
||||||
*
|
|
||||||
* @var LoggerInterface
|
|
||||||
*/
|
|
||||||
private $logger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Symfony\Component\Security\Core\User\UserInterface
|
* @var \Symfony\Component\Security\Core\User\UserInterface
|
||||||
@ -98,7 +85,7 @@ class ExportManager
|
|||||||
LoggerInterface $logger,
|
LoggerInterface $logger,
|
||||||
EntityManagerInterface $em,
|
EntityManagerInterface $em,
|
||||||
AuthorizationCheckerInterface $authorizationChecker,
|
AuthorizationCheckerInterface $authorizationChecker,
|
||||||
AuthorizationHelper $authorizationHelper,
|
AuthorizationHelperInterface $authorizationHelper,
|
||||||
TokenStorageInterface $tokenStorage
|
TokenStorageInterface $tokenStorage
|
||||||
) {
|
) {
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
@ -547,19 +534,16 @@ class ExportManager
|
|||||||
. 'an ExportInterface.');
|
. 'an ExportInterface.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null === $centers) {
|
if (null === $centers || [] === $centers) {
|
||||||
$centers = $this->authorizationHelper->getReachableCenters(
|
// we want to try if at least one center is reachable
|
||||||
|
return [] !== $this->authorizationHelper->getReachableCenters(
|
||||||
$this->user,
|
$this->user,
|
||||||
$role
|
$role
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($centers) === 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($centers as $center) {
|
foreach ($centers as $center) {
|
||||||
if ($this->authorizationChecker->isGranted($role, $center) === false) {
|
if (false === $this->authorizationChecker->isGranted($role, $center)) {
|
||||||
//debugging
|
//debugging
|
||||||
$this->logger->debug('user has no access to element', [
|
$this->logger->debug('user has no access to element', [
|
||||||
'method' => __METHOD__,
|
'method' => __METHOD__,
|
||||||
@ -568,10 +552,6 @@ class ExportManager
|
|||||||
'role' => $role,
|
'role' => $role,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
///// Bypasse les autorisations qui empêche d'afficher les nouveaux exports
|
|
||||||
return true;
|
|
||||||
///// TODO supprimer le return true
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -230,7 +230,8 @@ class SpreadSheetFormatter implements FormatterInterface
|
|||||||
$worksheet->fromArray(
|
$worksheet->fromArray(
|
||||||
$sortedResults,
|
$sortedResults,
|
||||||
null,
|
null,
|
||||||
'A' . $line
|
'A' . $line,
|
||||||
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
return $line + count($sortedResults) + 1;
|
return $line + count($sortedResults) + 1;
|
||||||
|
@ -15,6 +15,7 @@ use Chill\MainBundle\Center\GroupingCenterInterface;
|
|||||||
use Chill\MainBundle\Entity\Center;
|
use Chill\MainBundle\Entity\Center;
|
||||||
use Chill\MainBundle\Export\ExportManager;
|
use Chill\MainBundle\Export\ExportManager;
|
||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||||
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
@ -24,6 +25,7 @@ use Symfony\Component\Form\FormBuilderInterface;
|
|||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||||
|
|
||||||
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
use function array_intersect;
|
use function array_intersect;
|
||||||
use function array_key_exists;
|
use function array_key_exists;
|
||||||
use function array_merge;
|
use function array_merge;
|
||||||
@ -38,30 +40,24 @@ class PickCenterType extends AbstractType
|
|||||||
{
|
{
|
||||||
public const CENTERS_IDENTIFIERS = 'c';
|
public const CENTERS_IDENTIFIERS = 'c';
|
||||||
|
|
||||||
/**
|
protected AuthorizationHelperInterface $authorizationHelper;
|
||||||
* @var AuthorizationHelper
|
|
||||||
*/
|
protected ExportManager $exportManager;
|
||||||
protected $authorizationHelper;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var ExportManager
|
* @var array|GroupingCenterInterface[]
|
||||||
*/
|
*/
|
||||||
protected $exportManager;
|
protected array $groupingCenters = [];
|
||||||
|
|
||||||
/**
|
|
||||||
* @var GroupingCenterInterface[]
|
|
||||||
*/
|
|
||||||
protected $groupingCenters = [];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Symfony\Component\Security\Core\User\UserInterface
|
* @var \Symfony\Component\Security\Core\User\UserInterface
|
||||||
*/
|
*/
|
||||||
protected $user;
|
protected UserInterface $user;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
TokenStorageInterface $tokenStorage,
|
TokenStorageInterface $tokenStorage,
|
||||||
ExportManager $exportManager,
|
ExportManager $exportManager,
|
||||||
AuthorizationHelper $authorizationHelper
|
AuthorizationHelperInterface $authorizationHelper
|
||||||
) {
|
) {
|
||||||
$this->exportManager = $exportManager;
|
$this->exportManager = $exportManager;
|
||||||
$this->user = $tokenStorage->getToken()->getUser();
|
$this->user = $tokenStorage->getToken()->getUser();
|
||||||
@ -78,22 +74,12 @@ class PickCenterType extends AbstractType
|
|||||||
$export = $this->exportManager->getExport($options['export_alias']);
|
$export = $this->exportManager->getExport($options['export_alias']);
|
||||||
$centers = $this->authorizationHelper->getReachableCenters(
|
$centers = $this->authorizationHelper->getReachableCenters(
|
||||||
$this->user,
|
$this->user,
|
||||||
(string) $export->requiredRole()
|
$export->requiredRole()
|
||||||
);
|
);
|
||||||
|
|
||||||
$builder->add(self::CENTERS_IDENTIFIERS, EntityType::class, [
|
$builder->add(self::CENTERS_IDENTIFIERS, EntityType::class, [
|
||||||
'class' => Center::class,
|
'class' => Center::class,
|
||||||
'query_builder' => static function (EntityRepository $er) use ($centers) {
|
'choices' => $centers,
|
||||||
$qb = $er->createQueryBuilder('c');
|
|
||||||
$ids = array_map(
|
|
||||||
static function (Center $el) {
|
|
||||||
return $el->getId();
|
|
||||||
},
|
|
||||||
$centers
|
|
||||||
);
|
|
||||||
|
|
||||||
return $qb->where($qb->expr()->in('c.id', $ids));
|
|
||||||
},
|
|
||||||
'multiple' => true,
|
'multiple' => true,
|
||||||
'expanded' => true,
|
'expanded' => true,
|
||||||
'choice_label' => static function (Center $c) {
|
'choice_label' => static function (Center $c) {
|
||||||
|
@ -16,7 +16,7 @@ use Doctrine\ORM\EntityManagerInterface;
|
|||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
use Doctrine\Persistence\ObjectRepository;
|
use Doctrine\Persistence\ObjectRepository;
|
||||||
|
|
||||||
final class CenterRepository implements ObjectRepository
|
final class CenterRepository implements CenterRepositoryInterface
|
||||||
{
|
{
|
||||||
private EntityRepository $repository;
|
private EntityRepository $repository;
|
||||||
|
|
||||||
@ -30,6 +30,11 @@ final class CenterRepository implements ObjectRepository
|
|||||||
return $this->repository->find($id, $lockMode, $lockVersion);
|
return $this->repository->find($id, $lockMode, $lockVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function findActive(): array
|
||||||
|
{
|
||||||
|
return $this->findAll();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Center[]
|
* @return Center[]
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Chill\MainBundle\Repository;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Center;
|
||||||
|
use Doctrine\Persistence\ObjectRepository;
|
||||||
|
|
||||||
|
interface CenterRepositoryInterface extends ObjectRepository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Return all active centers
|
||||||
|
*
|
||||||
|
* Note: this is a teaser: active will comes later on center entity
|
||||||
|
*
|
||||||
|
* @return Center[]
|
||||||
|
*/
|
||||||
|
public function findActive(): array;
|
||||||
|
}
|
@ -517,3 +517,9 @@ div.popover {
|
|||||||
div.v-toast {
|
div.v-toast {
|
||||||
z-index: 10000!important;
|
z-index: 10000!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.grouped {
|
||||||
|
padding: 1em;
|
||||||
|
border: 1px solid black;
|
||||||
|
margin-bottom: 2em;
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
<h6>
|
||||||
|
<a href="{{ path('chill_main_export_index') }}" title="{{ 'Back to the list'|trans }}">
|
||||||
|
<i class="fa fa-folder-open-o fa-fw"></i>
|
||||||
|
</a>
|
||||||
|
{{ export_group|trans }}
|
||||||
|
</h6>
|
@ -36,10 +36,7 @@ window.addEventListener("DOMContentLoaded", function(e) {
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
|
|
||||||
<h6>
|
{{ include('@ChillMain/Export/_breadcrumb.html.twig') }}
|
||||||
<i class="fa fa-folder-open-o fa-fw"></i>
|
|
||||||
{{ export_group|trans }}
|
|
||||||
</h6>
|
|
||||||
|
|
||||||
<h1>{{ export.title|trans }}</h1>
|
<h1>{{ export.title|trans }}</h1>
|
||||||
<h2>{{ "Download export"|trans }}</h2>
|
<h2>{{ "Download export"|trans }}</h2>
|
||||||
|
@ -22,15 +22,15 @@
|
|||||||
|
|
||||||
{% block js %}
|
{% block js %}
|
||||||
{{ encore_entry_script_tags('page_export') }}
|
{{ encore_entry_script_tags('page_export') }}
|
||||||
|
{% if export_alias == 'count_social_work_actions' %}
|
||||||
|
{{ encore_entry_script_tags('vue_export_action_goal_result') }}
|
||||||
|
{% endif %}
|
||||||
{% endblock js %}
|
{% endblock js %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
|
|
||||||
<h6>
|
{{ include('@ChillMain/Export/_breadcrumb.html.twig') }}
|
||||||
<i class="fa fa-folder-open-o fa-fw"></i>
|
|
||||||
{{ export_group|trans }}
|
|
||||||
</h6>
|
|
||||||
|
|
||||||
<h1>{{ export.title|trans }}</h1>
|
<h1>{{ export.title|trans }}</h1>
|
||||||
|
|
||||||
|
@ -22,11 +22,8 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
|
|
||||||
<h6>
|
{{ include('@ChillMain/Export/_breadcrumb.html.twig') }}
|
||||||
<i class="fa fa-folder-open-o fa-fw"></i>
|
|
||||||
{{ export_group|trans }}
|
|
||||||
</h6>
|
|
||||||
|
|
||||||
<h1>{{ export.title|trans }}</h1>
|
<h1>{{ export.title|trans }}</h1>
|
||||||
|
|
||||||
|
@ -23,10 +23,7 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
|
|
||||||
<h6>
|
{{ include('@ChillMain/Export/_breadcrumb.html.twig') }}
|
||||||
<i class="fa fa-folder-open-o fa-fw"></i>
|
|
||||||
{{ export_group|trans }}
|
|
||||||
</h6>
|
|
||||||
|
|
||||||
<h1>{{ export.title|trans }}</h1>
|
<h1>{{ export.title|trans }}</h1>
|
||||||
|
|
||||||
@ -36,19 +33,21 @@
|
|||||||
<section class="formatter mb-4">
|
<section class="formatter mb-4">
|
||||||
<h2>{{ 'Formatter'| trans }}</h2>
|
<h2>{{ 'Formatter'| trans }}</h2>
|
||||||
|
|
||||||
<div>
|
|
||||||
{% if form.children.formatter.children|length == 0 %}
|
{% if form.children.formatter.children|length == 0 %}
|
||||||
<p>
|
<p>
|
||||||
<span class="chill-no-data-statement">{{ "No options availables. Your report is fully configured."|trans }}</span>
|
<span class="chill-no-data-statement">{{ "No options availables. Your report is fully configured."|trans }}</span>
|
||||||
</p>
|
</p>
|
||||||
{{ form_widget(form.children.formatter) }}
|
{{ form_widget(form.children.formatter) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{# we always have to render children, to mark as rendered #}
|
<div class="container py-4">
|
||||||
{% for input in form.children.formatter.children %}
|
{# we always have to render children, to mark as rendered #}
|
||||||
{{ form_row(input) }}
|
{% for input in form.children.formatter.children %}
|
||||||
{% endfor %}
|
<div class="row">
|
||||||
|
{{ form_row(input) }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
|
@ -19,24 +19,23 @@ class ChillExportVoter extends Voter
|
|||||||
{
|
{
|
||||||
public const EXPORT = 'chill_export';
|
public const EXPORT = 'chill_export';
|
||||||
|
|
||||||
protected AuthorizationHelperInterface $authorizationHelper;
|
private VoterHelperInterface $helper;
|
||||||
|
|
||||||
public function __construct(AuthorizationHelperInterface $authorizationHelper)
|
public function __construct(VoterHelperFactoryInterface $voterHelperFactory)
|
||||||
{
|
{
|
||||||
$this->authorizationHelper = $authorizationHelper;
|
$this->helper = $voterHelperFactory
|
||||||
|
->generate(self::class)
|
||||||
|
->addCheckFor(null, [self::EXPORT])
|
||||||
|
->build();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function supports($attribute, $subject): bool
|
protected function supports($attribute, $subject): bool
|
||||||
{
|
{
|
||||||
return self::EXPORT === $attribute;
|
return $this->helper->supports($attribute, $subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
|
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
|
||||||
{
|
{
|
||||||
if (!$token->getUser() instanceof User) {
|
return $this->helper->voteOnAttribute($attribute, $subject, $token);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [] !== $this->authorizationHelper->getReachableCenters($token->getUser(), $attribute);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ namespace Chill\MainBundle\Test;
|
|||||||
* and use tearDownTrait after usage.
|
* and use tearDownTrait after usage.
|
||||||
*
|
*
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
|
* @deprecated use @class{Prophecy\PhpUnit\ProphecyTrait} instead
|
||||||
*/
|
*/
|
||||||
trait ProphecyTrait
|
trait ProphecyTrait
|
||||||
{
|
{
|
||||||
|
@ -89,12 +89,8 @@ services:
|
|||||||
- { name: validator.constraint_validator, alias: 'role_scope_scope_presence' }
|
- { name: validator.constraint_validator, alias: 'role_scope_scope_presence' }
|
||||||
|
|
||||||
Chill\MainBundle\Export\ExportManager:
|
Chill\MainBundle\Export\ExportManager:
|
||||||
arguments:
|
autoconfigure: true
|
||||||
- "@logger"
|
autowire: true
|
||||||
- "@doctrine.orm.entity_manager"
|
|
||||||
- "@security.authorization_checker"
|
|
||||||
- "@chill.main.security.authorization.helper"
|
|
||||||
- "@security.token_storage"
|
|
||||||
|
|
||||||
Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface: '@Chill\MainBundle\Security\Resolver\CenterResolverDispatcher'
|
Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface: '@Chill\MainBundle\Security\Resolver\CenterResolverDispatcher'
|
||||||
|
|
||||||
|
@ -81,12 +81,8 @@ services:
|
|||||||
|
|
||||||
chill.main.form.pick_centers_type:
|
chill.main.form.pick_centers_type:
|
||||||
class: Chill\MainBundle\Form\Type\Export\PickCenterType
|
class: Chill\MainBundle\Form\Type\Export\PickCenterType
|
||||||
arguments:
|
autowire: true
|
||||||
- "@security.token_storage"
|
autoconfigure: true
|
||||||
- '@Chill\MainBundle\Export\ExportManager'
|
|
||||||
- "@chill.main.security.authorization.helper"
|
|
||||||
tags:
|
|
||||||
- { name: form.type }
|
|
||||||
|
|
||||||
chill.main.form.formatter_type:
|
chill.main.form.formatter_type:
|
||||||
class: Chill\MainBundle\Form\Type\Export\FormatterType
|
class: Chill\MainBundle\Form\Type\Export\FormatterType
|
||||||
|
@ -45,7 +45,7 @@ final class OriginAggregator implements AggregatorInterface
|
|||||||
$qb->join('acp.origin', 'acporigin');
|
$qb->join('acp.origin', 'acporigin');
|
||||||
}
|
}
|
||||||
|
|
||||||
$qb->addSelect('o.id AS origin_aggregator');
|
$qb->addSelect('acporigin.id AS origin_aggregator');
|
||||||
|
|
||||||
$groupby = $qb->getDQLPart('groupBy');
|
$groupby = $qb->getDQLPart('groupBy');
|
||||||
|
|
||||||
|
@ -16,8 +16,10 @@ use Chill\MainBundle\Export\ExportElementValidatedInterface;
|
|||||||
use Chill\MainBundle\Form\Type\ChillDateType;
|
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
use Chill\PersonBundle\Entity\Household\HouseholdMember;
|
use Chill\PersonBundle\Entity\Household\HouseholdMember;
|
||||||
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
use Chill\PersonBundle\Repository\Household\PositionRepository;
|
use Chill\PersonBundle\Repository\Household\PositionRepository;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
|
use Doctrine\ORM\Query\Expr;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||||
@ -31,8 +33,11 @@ final class HouseholdPositionAggregator implements AggregatorInterface, ExportEl
|
|||||||
|
|
||||||
private TranslatorInterface $translator;
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
public function __construct(TranslatorInterface $translator, TranslatableStringHelper $translatableStringHelper, PositionRepository $positionRepository)
|
public function __construct(
|
||||||
{
|
TranslatorInterface $translator,
|
||||||
|
TranslatableStringHelper $translatableStringHelper,
|
||||||
|
PositionRepository $positionRepository
|
||||||
|
) {
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
$this->positionRepository = $positionRepository;
|
$this->positionRepository = $positionRepository;
|
||||||
$this->translatableStringHelper = $translatableStringHelper;
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
@ -45,28 +50,25 @@ final class HouseholdPositionAggregator implements AggregatorInterface, ExportEl
|
|||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data)
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
{
|
{
|
||||||
$qb->resetDQLPart('from');
|
if (!in_array('householdmember', $qb->getAllAliases(), true)) {
|
||||||
$qb->from(HouseholdMember::class, 'member');
|
$qb->join(HouseholdMember::class, 'householdmember', Expr\Join::WITH, 'householdmember.person = person');
|
||||||
|
|
||||||
if (!in_array('memberperson', $qb->getAllAliases(), true)) {
|
|
||||||
$qb->join('member.person', 'memberperson');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_array('membercenter', $qb->getAllAliases(), true)) {
|
if (!in_array('center', $qb->getAllAliases(), true)) {
|
||||||
$qb->join('memberperson.center', 'membercenter');
|
$qb->join('person.center', 'center');
|
||||||
}
|
}
|
||||||
|
|
||||||
$qb->andWhere($qb->expr()->andX(
|
$qb->andWhere($qb->expr()->andX(
|
||||||
$qb->expr()->lte('member.startDate', ':date'),
|
$qb->expr()->lte('householdmember.startDate', ':date'),
|
||||||
$qb->expr()->orX(
|
$qb->expr()->orX(
|
||||||
$qb->expr()->isNull('member.endDate'),
|
$qb->expr()->isNull('householdmember.endDate'),
|
||||||
$qb->expr()->gte('member.endDate', ':date')
|
$qb->expr()->gte('householdmember.endDate', ':date')
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
|
|
||||||
$qb->setParameter('date', $data['date_position']);
|
$qb->setParameter('date', $data['date_position']);
|
||||||
|
|
||||||
$qb->addSelect('IDENTITY(member.position) AS household_position_aggregator');
|
$qb->addSelect('IDENTITY(householdmember.position) AS household_position_aggregator');
|
||||||
|
|
||||||
$groupBy = $qb->getDQLPart('groupBy');
|
$groupBy = $qb->getDQLPart('groupBy');
|
||||||
|
|
||||||
@ -79,7 +81,7 @@ final class HouseholdPositionAggregator implements AggregatorInterface, ExportEl
|
|||||||
|
|
||||||
public function applyOn()
|
public function applyOn()
|
||||||
{
|
{
|
||||||
return 'person';
|
return Declarations::PERSON_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
|
@ -29,6 +29,7 @@ final class ActionTypeAggregator implements AggregatorInterface
|
|||||||
SocialActionRender $actionRender
|
SocialActionRender $actionRender
|
||||||
) {
|
) {
|
||||||
$this->socialActionRepository = $socialActionRepository;
|
$this->socialActionRepository = $socialActionRepository;
|
||||||
|
$this->actionRender = $actionRender;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addRole(): ?string
|
public function addRole(): ?string
|
||||||
|
@ -41,7 +41,7 @@ final class GoalAggregator implements AggregatorInterface
|
|||||||
$qb->join('acpw.goals', 'goal');
|
$qb->join('acpw.goals', 'goal');
|
||||||
}
|
}
|
||||||
|
|
||||||
$qb->addSelect('goal.id as goal_aggregator');
|
$qb->addSelect('IDENTITY(goal.goal) as goal_aggregator');
|
||||||
|
|
||||||
$groupBy = $qb->getDQLPart('groupBy');
|
$groupBy = $qb->getDQLPart('groupBy');
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ final class GoalAggregator implements AggregatorInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn()
|
public function applyOn(): string
|
||||||
{
|
{
|
||||||
return Declarations::SOCIAL_WORK_ACTION_TYPE;
|
return Declarations::SOCIAL_WORK_ACTION_TYPE;
|
||||||
}
|
}
|
||||||
@ -70,17 +70,19 @@ final class GoalAggregator implements AggregatorInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
$g = $this->goalRepository->find($value);
|
$g = $this->goalRepository->find($value);
|
||||||
|
|
||||||
return $this->translatableStringHelper->localize($g->getTitle());
|
return $this->translatableStringHelper->localize(
|
||||||
|
$g->getTitle()
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getQueryKeys($data)
|
public function getQueryKeys($data): array
|
||||||
{
|
{
|
||||||
return ['goal_aggregator'];
|
return ['goal_aggregator'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTitle()
|
public function getTitle(): string
|
||||||
{
|
{
|
||||||
return 'Group social work actions by goal';
|
return 'Group social work actions by goal';
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,138 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Export\AggregatorInterface;
|
||||||
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
|
use Chill\PersonBundle\Repository\SocialWork\GoalRepository;
|
||||||
|
use Chill\PersonBundle\Repository\SocialWork\ResultRepository;
|
||||||
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
|
||||||
|
class GoalResultAggregator implements AggregatorInterface
|
||||||
|
{
|
||||||
|
private ResultRepository $resultRepository;
|
||||||
|
|
||||||
|
private GoalRepository $goalRepository;
|
||||||
|
|
||||||
|
private TranslatableStringHelper $translatableStringHelper;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
ResultRepository $resultRepository,
|
||||||
|
GoalRepository $goalRepository,
|
||||||
|
TranslatableStringHelper $translatableStringHelper
|
||||||
|
) {
|
||||||
|
$this->resultRepository = $resultRepository;
|
||||||
|
$this->goalRepository = $goalRepository;
|
||||||
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getLabels($key, array $values, $data)
|
||||||
|
{
|
||||||
|
return function ($value) use ($key): string {
|
||||||
|
switch ($key) {
|
||||||
|
case 'goal_aggregator':
|
||||||
|
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return 'Goal Type';
|
||||||
|
}
|
||||||
|
|
||||||
|
$g = $this->goalRepository->find($value);
|
||||||
|
|
||||||
|
return $this->translatableStringHelper->localize(
|
||||||
|
$g->getTitle()
|
||||||
|
);
|
||||||
|
|
||||||
|
case 'result_aggregator':
|
||||||
|
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return 'Result Type';
|
||||||
|
}
|
||||||
|
|
||||||
|
$r = $this->resultRepository->find($value);
|
||||||
|
|
||||||
|
return $this->translatableStringHelper->localize(
|
||||||
|
$r->getTitle()
|
||||||
|
);
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new \LogicException();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getQueryKeys($data): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'goal_aggregator',
|
||||||
|
'result_aggregator'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
|
{
|
||||||
|
// no form
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getTitle(): string
|
||||||
|
{
|
||||||
|
return 'Group social work actions by goal and result';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function addRole(): ?string
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
|
{
|
||||||
|
if (!in_array('goal', $qb->getAllAliases(), true)) {
|
||||||
|
$qb->join('acpw.goals', 'goal');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array('goalresult', $qb->getAllAliases(), true)) {
|
||||||
|
$qb->join('goal.results', 'goalresult');
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb->addSelect('IDENTITY(goal.goal) as goal_aggregator');
|
||||||
|
$qb->addSelect('goalresult.id as result_aggregator');
|
||||||
|
|
||||||
|
$groupBy = $qb->getDQLPart('groupBy');
|
||||||
|
|
||||||
|
if (!empty($groupBy)) {
|
||||||
|
$qb->addGroupBy('goal_aggregator');
|
||||||
|
} else {
|
||||||
|
$qb->groupBy('goal_aggregator');
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb->addGroupBy('result_aggregator');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function applyOn(): string
|
||||||
|
{
|
||||||
|
return Declarations::SOCIAL_WORK_ACTION_TYPE;
|
||||||
|
}
|
||||||
|
}
|
@ -37,19 +37,11 @@ final class ResultAggregator implements AggregatorInterface
|
|||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data)
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
{
|
{
|
||||||
if (!in_array('acpwresult', $qb->getAllAliases(), true)) {
|
if (!in_array('result', $qb->getAllAliases(), true)) {
|
||||||
$qb->join('acpw.results', 'acpwresult');
|
$qb->join('acpw.results', 'result');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_array('goal', $qb->getAllAliases(), true)) {
|
$qb->addSelect('result.id as result_aggregator');
|
||||||
$qb->join('acpw.goals', 'goal');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!in_array('goalresult', $qb->getAllAliases(), true)) {
|
|
||||||
$qb->join('goal.results', 'goalresult');
|
|
||||||
}
|
|
||||||
|
|
||||||
$qb->addSelect('acpwresult.id, IDENTITY(goal.results) as result_aggregator');
|
|
||||||
|
|
||||||
$groupBy = $qb->getDQLPart('groupBy');
|
$groupBy = $qb->getDQLPart('groupBy');
|
||||||
|
|
||||||
@ -60,7 +52,7 @@ final class ResultAggregator implements AggregatorInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn()
|
public function applyOn(): string
|
||||||
{
|
{
|
||||||
return Declarations::SOCIAL_WORK_ACTION_TYPE;
|
return Declarations::SOCIAL_WORK_ACTION_TYPE;
|
||||||
}
|
}
|
||||||
@ -77,18 +69,20 @@ final class ResultAggregator implements AggregatorInterface
|
|||||||
return 'Result Type';
|
return 'Result Type';
|
||||||
}
|
}
|
||||||
|
|
||||||
$g = $this->resultRepository->find($value);
|
$r = $this->resultRepository->find($value);
|
||||||
|
|
||||||
return $this->translatableStringHelper->localize($g->getTitle());
|
return $this->translatableStringHelper->localize(
|
||||||
|
$r->getTitle()
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getQueryKeys($data)
|
public function getQueryKeys($data): array
|
||||||
{
|
{
|
||||||
return ['result_aggregator'];
|
return ['result_aggregator'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTitle()
|
public function getTitle(): string
|
||||||
{
|
{
|
||||||
return 'Group social work actions by result';
|
return 'Group social work actions by result';
|
||||||
}
|
}
|
||||||
|
@ -112,8 +112,8 @@ class CountEvaluation implements ExportInterface, GroupedExportInterface
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
Declarations::EVAL_TYPE,
|
Declarations::EVAL_TYPE,
|
||||||
//Declarations::ACP_TYPE,
|
Declarations::SOCIAL_WORK_ACTION_TYPE,
|
||||||
//Declarations::SOCIAL_WORK_ACTION_TYPE,
|
Declarations::ACP_TYPE,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ class CountHousehold implements ExportInterface, GroupedExportInterface
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
Declarations::HOUSEHOLD_TYPE,
|
Declarations::HOUSEHOLD_TYPE,
|
||||||
//Declarations::ACP_TYPE
|
Declarations::ACP_TYPE,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,8 +111,8 @@ class CountPersonWithAccompanyingCourse implements ExportInterface, GroupedExpor
|
|||||||
public function supportsModifiers(): array
|
public function supportsModifiers(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
Declarations::ACP_TYPE,
|
|
||||||
Declarations::PERSON_TYPE,
|
Declarations::PERSON_TYPE,
|
||||||
|
Declarations::ACP_TYPE,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,6 +110,7 @@ class CountSocialWorkActions implements ExportInterface, GroupedExportInterface
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
Declarations::SOCIAL_WORK_ACTION_TYPE,
|
Declarations::SOCIAL_WORK_ACTION_TYPE,
|
||||||
|
Declarations::ACP_TYPE,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,6 +108,6 @@ class DeadOrAliveFilter implements FilterInterface
|
|||||||
|
|
||||||
public function getTitle()
|
public function getTitle()
|
||||||
{
|
{
|
||||||
return 'Filtered by person\'s that are alive or have deceased at a certain date';
|
return "Filter by person's that are alive or have deceased at a certain date";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,15 +39,12 @@ class ResidentialAddressAtThirdpartyFilter implements FilterInterface
|
|||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data)
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
{
|
{
|
||||||
$qb->resetDQLPart('from');
|
if (!in_array('resaddr', $qb->getAllAliases(), true)) {
|
||||||
$qb->from(ResidentialAddress::class, 'resaddr');
|
$qb->join(ResidentialAddress::class, 'resaddr', Expr\Join::WITH, 'resaddr.person = person');
|
||||||
|
|
||||||
if (!in_array('resaddrperson', $qb->getAllAliases(), true)) {
|
|
||||||
$qb->join('resaddr.person', 'resaddrperson');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_array('resaddrcenter', $qb->getAllAliases(), true)) {
|
if (!in_array('center', $qb->getAllAliases(), true)) {
|
||||||
$qb->join('resaddrperson.center', 'resaddrcenter');
|
$qb->join('person.center', 'center');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_array('tparty', $qb->getAllAliases(), true)) {
|
if (!in_array('tparty', $qb->getAllAliases(), true)) {
|
||||||
@ -109,6 +106,6 @@ class ResidentialAddressAtThirdpartyFilter implements FilterInterface
|
|||||||
|
|
||||||
public function getTitle()
|
public function getTitle()
|
||||||
{
|
{
|
||||||
return 'Filtered by person\'s who have a residential address located at a thirdparty of type';
|
return "Filter by person's who have a residential address located at a thirdparty of type";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Export\Filter\PersonFilters;
|
|||||||
use Chill\MainBundle\Export\FilterInterface;
|
use Chill\MainBundle\Export\FilterInterface;
|
||||||
use Chill\PersonBundle\Entity\Person\ResidentialAddress;
|
use Chill\PersonBundle\Entity\Person\ResidentialAddress;
|
||||||
use Chill\PersonBundle\Export\Declarations;
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
|
use Doctrine\ORM\Query\Expr;
|
||||||
use Doctrine\ORM\Query\Expr\Andx;
|
use Doctrine\ORM\Query\Expr\Andx;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
|
||||||
@ -26,15 +27,12 @@ class ResidentialAddressAtUserFilter implements FilterInterface
|
|||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data)
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
{
|
{
|
||||||
$qb->resetDQLPart('from');
|
if (!in_array('resaddr', $qb->getAllAliases(), true)) {
|
||||||
$qb->from(ResidentialAddress::class, 'resaddr');
|
$qb->join(ResidentialAddress::class, 'resaddr', Expr\Join::WITH, 'resaddr.person = person');
|
||||||
|
|
||||||
if (!in_array('resaddrperson', $qb->getAllAliases(), true)) {
|
|
||||||
$qb->join('resaddr.person', 'resaddrperson');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_array('resaddrcenter', $qb->getAllAliases(), true)) {
|
if (!in_array('center', $qb->getAllAliases(), true)) {
|
||||||
$qb->join('resaddrperson.center', 'resaddrcenter');
|
$qb->join('person.center', 'center');
|
||||||
}
|
}
|
||||||
|
|
||||||
$where = $qb->getDQLPart('where');
|
$where = $qb->getDQLPart('where');
|
||||||
@ -61,11 +59,11 @@ class ResidentialAddressAtUserFilter implements FilterInterface
|
|||||||
|
|
||||||
public function describeAction($data, $format = 'string')
|
public function describeAction($data, $format = 'string')
|
||||||
{
|
{
|
||||||
return ['Filtered by person\'s who have a residential address located at another user'];
|
return ["Filtered by person's who have a residential address located at another user"];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTitle()
|
public function getTitle()
|
||||||
{
|
{
|
||||||
return 'Filtered by person\'s who have a residential address located at another user';
|
return "Filter by person's who have a residential address located at another user";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,35 +13,119 @@ namespace Chill\PersonBundle\Export\Filter\SocialWorkFilters;
|
|||||||
|
|
||||||
use Chill\MainBundle\Export\FilterInterface;
|
use Chill\MainBundle\Export\FilterInterface;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
use Chill\PersonBundle\Entity\SocialWork\Goal;
|
|
||||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||||
|
use Chill\PersonBundle\Entity\SocialWork\Goal;
|
||||||
|
use Chill\PersonBundle\Entity\SocialWork\Result;
|
||||||
use Chill\PersonBundle\Export\Declarations;
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
|
|
||||||
use Doctrine\ORM\Query\Expr\Andx;
|
use Doctrine\ORM\Query\Expr\Andx;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
use Symfony\Component\Form\CallbackTransformer;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\Form\FormEvent;
|
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
|
||||||
use Symfony\Component\Form\FormEvents;
|
|
||||||
use Symfony\Component\Form\FormInterface;
|
|
||||||
|
|
||||||
class SocialWorkTypeFilter implements FilterInterface
|
class SocialWorkTypeFilter implements FilterInterface
|
||||||
{
|
{
|
||||||
private SocialActionRender $socialActionRender;
|
private SocialActionRender $socialActionRender;
|
||||||
|
|
||||||
private SocialActionRepository $socialActionRepository;
|
|
||||||
|
|
||||||
private TranslatableStringHelper $translatableStringHelper;
|
private TranslatableStringHelper $translatableStringHelper;
|
||||||
|
|
||||||
public function __construct(
|
private EntityManagerInterface $em;
|
||||||
|
|
||||||
|
public function __construct
|
||||||
|
(
|
||||||
SocialActionRender $socialActionRender,
|
SocialActionRender $socialActionRender,
|
||||||
TranslatableStringHelper $translatableStringHelper,
|
TranslatableStringHelper $translatableStringHelper,
|
||||||
SocialActionRepository $socialActionRepository
|
EntityManagerInterface $em
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
$this->socialActionRender = $socialActionRender;
|
$this->socialActionRender = $socialActionRender;
|
||||||
$this->translatableStringHelper = $translatableStringHelper;
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
$this->socialActionRepository = $socialActionRepository;
|
$this->em = $em;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
|
{
|
||||||
|
$builder
|
||||||
|
->add('actionType', HiddenType::class)
|
||||||
|
->get('actionType')
|
||||||
|
->addModelTransformer(
|
||||||
|
$this->iterableToIdTransformer(SocialAction::class)
|
||||||
|
)
|
||||||
|
;
|
||||||
|
$builder
|
||||||
|
->add('goal', HiddenType::class)
|
||||||
|
->get('goal')
|
||||||
|
->addModelTransformer(
|
||||||
|
$this->iterableToIdTransformer(Goal::class)
|
||||||
|
)
|
||||||
|
;
|
||||||
|
$builder
|
||||||
|
->add('result', HiddenType::class)
|
||||||
|
->get('result')
|
||||||
|
->addModelTransformer(
|
||||||
|
$this->iterableToIdTransformer(Result::class)
|
||||||
|
)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function iterableToIdTransformer(string $entity): CallbackTransformer
|
||||||
|
{
|
||||||
|
return new CallbackTransformer(
|
||||||
|
static function (?iterable $asIterable): string {
|
||||||
|
if (null === $asIterable) { return ''; }
|
||||||
|
$ids = [];
|
||||||
|
foreach ($asIterable as $value) {
|
||||||
|
$ids[] = $value->getId();
|
||||||
|
}
|
||||||
|
return implode(',', $ids);
|
||||||
|
},
|
||||||
|
function (?string $asString) use ($entity): array {
|
||||||
|
if (null === $asString) { return []; }
|
||||||
|
return array_map(
|
||||||
|
fn (string $id)
|
||||||
|
=> $this->em
|
||||||
|
->getRepository($entity)
|
||||||
|
->findOneBy(['id' => (int) $id]),
|
||||||
|
explode(',', $asString)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle(): string
|
||||||
|
{
|
||||||
|
return 'Filter by type of action, goals and results';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function describeAction($data, $format = 'string'): array
|
||||||
|
{
|
||||||
|
$actionTypes = [];
|
||||||
|
$goals = [];
|
||||||
|
$results = [];
|
||||||
|
|
||||||
|
foreach ($data['actionType'] as $at) {
|
||||||
|
$actionTypes[] = $this->translatableStringHelper->localize(
|
||||||
|
$at->getTitle()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($data['goal'] as $g) {
|
||||||
|
$goals[] = $this->translatableStringHelper->localize(
|
||||||
|
$g->getTitle()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($data['result'] as $r) {
|
||||||
|
$results[] = $this->translatableStringHelper->localize(
|
||||||
|
$r->getTitle()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ['Filtered actions by type, goals and results: %selected%', [
|
||||||
|
'%selected%' => implode(', ', array_merge($actionTypes, $goals, $results))
|
||||||
|
]];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addRole(): ?string
|
public function addRole(): ?string
|
||||||
@ -52,93 +136,48 @@ class SocialWorkTypeFilter implements FilterInterface
|
|||||||
public function alterQuery(QueryBuilder $qb, $data)
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
{
|
{
|
||||||
$where = $qb->getDQLPart('where');
|
$where = $qb->getDQLPart('where');
|
||||||
$clause = $qb->expr()->in('r', ':referrers');
|
|
||||||
|
|
||||||
if ($where instanceof Andx) {
|
if (count($data['actionType']) > 0) {
|
||||||
$where->add($clause);
|
$clause = $qb->expr()->in('acpw.socialAction', ':actionType');
|
||||||
} else {
|
|
||||||
$where = $qb->expr()->andX($clause);
|
if ($where instanceof Andx) {
|
||||||
|
$where->add($clause);
|
||||||
|
} else {
|
||||||
|
$where = $qb->expr()->andX($clause);
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb->setParameter('actionType', $data['actionType']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($data['goal']) > 0) {
|
||||||
|
if (!in_array('goal', $qb->getAllAliases(), true)) {
|
||||||
|
$qb->join('acpw.goals', 'goal');
|
||||||
|
}
|
||||||
|
|
||||||
|
$where->add(
|
||||||
|
$qb->expr()->in('goal.id', ':goals')
|
||||||
|
);
|
||||||
|
|
||||||
|
$qb->setParameter('goals', $data['goal']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($data['result']) > 0) {
|
||||||
|
if (!in_array('result', $qb->getAllAliases(), true)) {
|
||||||
|
$qb->join('acpw.results', 'result');
|
||||||
|
}
|
||||||
|
|
||||||
|
$where->add(
|
||||||
|
$qb->expr()->in('result.id', ':results')
|
||||||
|
);
|
||||||
|
|
||||||
|
$qb->setParameter('results', $data['result']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$qb->add('where', $where);
|
$qb->add('where', $where);
|
||||||
$qb->setParameter('referrers', $data['referrers']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
{
|
{
|
||||||
return Declarations::SOCIAL_WORK_ACTION_TYPE;
|
return Declarations::SOCIAL_WORK_ACTION_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
|
||||||
{
|
|
||||||
$socialActions = $this->socialActionRepository->findAll();
|
|
||||||
|
|
||||||
$builder->add('actionType', ChoiceType::class, [
|
|
||||||
'choices' => $socialActions,
|
|
||||||
'choice_label' => function (SocialAction $sa) {
|
|
||||||
return $this->socialActionRender->renderString($sa, []);
|
|
||||||
},
|
|
||||||
'multiple' => true,
|
|
||||||
'expanded' => true,
|
|
||||||
]);
|
|
||||||
|
|
||||||
/*
|
|
||||||
$refreshGoals = function (FormInterface $form, SocialAction $actionType = null) {
|
|
||||||
|
|
||||||
$goals = null === $actionType ? [] : $actionType->getGoals();
|
|
||||||
|
|
||||||
$form->add('goal', ChoiceType::class, [
|
|
||||||
'placeholder' => '',
|
|
||||||
'choices' => $goals,
|
|
||||||
'choice_label' => function (Goal $g) {
|
|
||||||
return $this->translatableStringHelper->localize($g->getTitle());
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
};
|
|
||||||
|
|
||||||
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($refreshGoals) {
|
|
||||||
$data = $event->getData();
|
|
||||||
dump($data);
|
|
||||||
|
|
||||||
$refreshGoals($event->getForm(), $data);
|
|
||||||
});
|
|
||||||
|
|
||||||
$builder->get('actionType')->addEventListener(
|
|
||||||
FormEvents::POST_SUBMIT,
|
|
||||||
function (FormEvent $event) use ($refreshGoals) {
|
|
||||||
$actionType = $event->getForm()->getData();
|
|
||||||
dump($actionType);
|
|
||||||
$refreshGoals($event->getForm()->getParent(), $actionType);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
public function describeAction($data, $format = 'string'): array
|
|
||||||
{
|
|
||||||
$actionTypes = [];
|
|
||||||
$objectives = [];
|
|
||||||
$results = [];
|
|
||||||
|
|
||||||
foreach ($data['actionType'] as $at) {
|
|
||||||
$actionTypes[] = $at->getTitle();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($data['objectives'] as $o) {
|
|
||||||
$objectives[] = $o->getTitle();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($data['results'] as $r) {
|
|
||||||
$results[] = $r->getTitle();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ['Filtered by referrers: only %actionTypes%', [
|
|
||||||
'%actionTypes%' => implode(', ou ', $actionTypes),
|
|
||||||
]];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTitle(): string
|
|
||||||
{
|
|
||||||
return 'Filter by type of action, objectives and results';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,381 @@
|
|||||||
|
<template>
|
||||||
|
<teleport to="#export_filters_social_work_type_filter_form">
|
||||||
|
|
||||||
|
<fieldset class="mb-3" id="actionType">
|
||||||
|
<div class="row">
|
||||||
|
<legend class="col-sm-4 col-form-label">{{ $t('action.label')}}</legend>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
|
||||||
|
<VueMultiselect
|
||||||
|
v-model="action"
|
||||||
|
:options="actions.options"
|
||||||
|
@select="selectAction"
|
||||||
|
@remove="unselectAction"
|
||||||
|
:multiple="true"
|
||||||
|
:close-on-select="false"
|
||||||
|
:placeholder="$t('action.placeholder')"
|
||||||
|
label="text"
|
||||||
|
track-by="id"
|
||||||
|
:searchable="true"
|
||||||
|
></VueMultiselect>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset class="mb-3" id="goal">
|
||||||
|
<div class="row">
|
||||||
|
<legend class="col-sm-4 col-form-label">{{ $t('goal.label')}}</legend>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
|
||||||
|
<VueMultiselect
|
||||||
|
v-model="goal"
|
||||||
|
:options="goals.options"
|
||||||
|
@select="selectGoal"
|
||||||
|
@remove="unselectGoal"
|
||||||
|
:multiple="true"
|
||||||
|
:close-on-select="false"
|
||||||
|
:placeholder="$t('goal.placeholder')"
|
||||||
|
label="title"
|
||||||
|
:custom-label="transTitle"
|
||||||
|
track-by="id"
|
||||||
|
:searchable="true"
|
||||||
|
></VueMultiselect>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset class="mb-3" id="result">
|
||||||
|
<div class="row">
|
||||||
|
<legend class="col-sm-4 col-form-label">{{ $t('result.label')}}</legend>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
|
||||||
|
<VueMultiselect
|
||||||
|
v-model="result"
|
||||||
|
:options="results.options"
|
||||||
|
@select="selectResult"
|
||||||
|
@remove="unselectResult"
|
||||||
|
:multiple="true"
|
||||||
|
:close-on-select="false"
|
||||||
|
:placeholder="$t('result.placeholder')"
|
||||||
|
label="title"
|
||||||
|
:custom-label="transTitle"
|
||||||
|
track-by="id"
|
||||||
|
:searchable="true"
|
||||||
|
></VueMultiselect>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
</teleport>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import VueMultiselect from 'vue-multiselect';
|
||||||
|
import { getSocialActions, getGoalByAction, getResultByAction, getResultByGoal } from './api';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "App",
|
||||||
|
components: {
|
||||||
|
VueMultiselect
|
||||||
|
},
|
||||||
|
i18n: {
|
||||||
|
messages: {
|
||||||
|
fr: {
|
||||||
|
action: {
|
||||||
|
label: 'Types d\'actions',
|
||||||
|
placeholder: 'Choisissez une ou plusieurs actions',
|
||||||
|
},
|
||||||
|
goal: {
|
||||||
|
label: 'Objectifs',
|
||||||
|
placeholder: 'Choisissez un ou plusieurs objectifs',
|
||||||
|
},
|
||||||
|
result: {
|
||||||
|
label: 'Résultats',
|
||||||
|
placeholder: 'Choisissez un ou plusieurs résultats',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
actions: {
|
||||||
|
options: [], // array with multiselect options
|
||||||
|
value: [], // array with selected values
|
||||||
|
hiddenField: document.getElementById(
|
||||||
|
'export_filters_social_work_type_filter_form_actionType'),
|
||||||
|
},
|
||||||
|
goals: {
|
||||||
|
options: [],
|
||||||
|
value: [],
|
||||||
|
hiddenField: document.getElementById(
|
||||||
|
'export_filters_social_work_type_filter_form_goal'),
|
||||||
|
},
|
||||||
|
results: {
|
||||||
|
options: [],
|
||||||
|
value: [],
|
||||||
|
hiddenField: document.getElementById(
|
||||||
|
'export_filters_social_work_type_filter_form_result'),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
action: {
|
||||||
|
get() {
|
||||||
|
return this.actions.value;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.actions.value = value;
|
||||||
|
this.rebuildHiddenFieldValues('actions');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
goal: {
|
||||||
|
get() {
|
||||||
|
return this.goals.value;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.goals.value = value;
|
||||||
|
this.rebuildHiddenFieldValues('goals');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
result: {
|
||||||
|
get() {
|
||||||
|
return this.results.value;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.results.value = value;
|
||||||
|
this.rebuildHiddenFieldValues('results');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getSocialActionsList();
|
||||||
|
|
||||||
|
this.actions.hiddenField.value = '';
|
||||||
|
this.goals.hiddenField.value = '';
|
||||||
|
this.results.hiddenField.value = '';
|
||||||
|
|
||||||
|
//console.log(this.actions.hiddenField, this.goals.hiddenField, this.results.hiddenField);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getSocialActionsList() {
|
||||||
|
this.actions.options = await getSocialActions();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select/unselect in Action Multiselect
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
selectAction(value) {
|
||||||
|
//console.log('----'); console.log('select action', value.id);
|
||||||
|
let children = this.getChildrensFromParent(value);
|
||||||
|
this.addSelectedElement('actions', children);
|
||||||
|
|
||||||
|
let parentAndChildren = [...[value], ...children];
|
||||||
|
parentAndChildren.forEach(elem => {
|
||||||
|
getGoalByAction(elem.id).then(response => new Promise((resolve, reject) => {
|
||||||
|
this.addElementInData('goals', response.results);
|
||||||
|
resolve();
|
||||||
|
})).catch;
|
||||||
|
getResultByAction(elem.id).then(response => new Promise((resolve, reject) => {
|
||||||
|
this.addElementInData('results', response.results);
|
||||||
|
resolve();
|
||||||
|
})).catch;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
unselectAction(value) {
|
||||||
|
//console.log('----'); console.log('unselect action', value.id);
|
||||||
|
getGoalByAction(value.id).then(response => new Promise((resolve, reject) => {
|
||||||
|
[ this.goals.options, this.goals.value ] = this.removeElementInData('goals', response.results);
|
||||||
|
resolve();
|
||||||
|
})).catch;
|
||||||
|
getResultByAction(value.id).then(response => new Promise((resolve, reject) => {
|
||||||
|
[ this.results.options, this.results.value ] = this.removeElementInData('results', response.results);
|
||||||
|
resolve();
|
||||||
|
})).catch;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select/unselect in Goal Multiselect
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
selectGoal(value) {
|
||||||
|
//console.log('----'); console.log('select goal', value.id);
|
||||||
|
getResultByGoal(value.id).then(response => new Promise((resolve, reject) => {
|
||||||
|
this.addElementInData('results', response.results);
|
||||||
|
resolve();
|
||||||
|
})).catch;
|
||||||
|
},
|
||||||
|
|
||||||
|
unselectGoal(value) {
|
||||||
|
//console.log('----'); console.log('unselect goal', value.id);
|
||||||
|
getResultByGoal(value.id).then(response => new Promise((resolve, reject) => {
|
||||||
|
[ this.results.options, this.results.value ] = this.removeElementInData('results', response.results);
|
||||||
|
resolve();
|
||||||
|
})).catch;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select/unselect in Result Multiselect
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
selectResult(value) {
|
||||||
|
//console.log('----'); console.log('select result', value.id);
|
||||||
|
},
|
||||||
|
|
||||||
|
unselectResult(value) {
|
||||||
|
//console.log('----'); console.log('unselect result', value.id);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Choose parent action will involve retaining the "children" actions.
|
||||||
|
* @param value
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
getChildrensFromParent(value) {
|
||||||
|
if (null === value.parent) {
|
||||||
|
let excludeParent = this.actions.options.filter(o => o.parent !== null);
|
||||||
|
let children = excludeParent.filter(o => o.parent.id === value.id);
|
||||||
|
//console.log("get childrens", children.map(e => e.id));
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add response elements in data target
|
||||||
|
* @param target string -> 'actions', 'goals' or 'results'
|
||||||
|
* @param response array of objects with fetch results
|
||||||
|
*/
|
||||||
|
addElementInData(target, response) {
|
||||||
|
let data = this[target];
|
||||||
|
let dump = [];
|
||||||
|
response.forEach(elem => {
|
||||||
|
let found = data.options.some(e => e.id === elem.id);
|
||||||
|
if (!found) {
|
||||||
|
data.options.push(elem);
|
||||||
|
dump.push(elem.id);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (dump.length > 0) {
|
||||||
|
//console.log('push ' + dump.length + ' elems in', target, dump);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove response elements from data target
|
||||||
|
* @param target string -> 'actions', 'goals' or 'results'
|
||||||
|
* @param response array of objects with fetch results
|
||||||
|
* @returns data.<target>.options
|
||||||
|
*/
|
||||||
|
removeElementInData(target, response) {
|
||||||
|
let data = this[target];
|
||||||
|
let dump = [];
|
||||||
|
response.forEach(elem => {
|
||||||
|
let found = data.options.some(e => e.id === elem.id);
|
||||||
|
if (found) {
|
||||||
|
data.options = data.options.filter(e => e.id !== elem.id);
|
||||||
|
dump.push(elem.id);
|
||||||
|
|
||||||
|
this.removeSelectedElement(target, elem);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (dump.length > 0) {
|
||||||
|
//console.log('remove ' + dump.length + ' elems from ' + target + ' options', dump);
|
||||||
|
}
|
||||||
|
return [ data.options, data.value ];
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param target
|
||||||
|
* @param elements
|
||||||
|
*/
|
||||||
|
addSelectedElement(target, elements) {
|
||||||
|
let data = this[target];
|
||||||
|
let dump = [];
|
||||||
|
elements.forEach(elem => {
|
||||||
|
let selected = data.value.some(e => e.id === elem.id);
|
||||||
|
if (!selected) {
|
||||||
|
|
||||||
|
data.value.push(elem);
|
||||||
|
dump.push(elem.id);
|
||||||
|
|
||||||
|
// add in hiddenField
|
||||||
|
this.rebuildHiddenFieldValues(target);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (dump.length > 0) {
|
||||||
|
//console.log('add ' + dump.length + ' selected elems in', target, dump);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove element from selected and from hiddenField
|
||||||
|
* @param target
|
||||||
|
* @param elem
|
||||||
|
*/
|
||||||
|
removeSelectedElement(target, elem) {
|
||||||
|
let data = this[target];
|
||||||
|
let selected = data.value.some(e => e.id === elem.id);
|
||||||
|
if (selected) {
|
||||||
|
|
||||||
|
// remove from selected
|
||||||
|
data.value = data.value.filter(e => e.id !== elem.id);
|
||||||
|
//console.log('remove ' + elem.id + ' from selected ' + target);
|
||||||
|
|
||||||
|
// remove from hiddenField
|
||||||
|
this.rebuildHiddenFieldValues(target);
|
||||||
|
|
||||||
|
// in any cases, remove should be recursive
|
||||||
|
this.unselectToNextField(target, elem);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When unselect Action, it could remove elements in goals multiselect.
|
||||||
|
* In that case, we have to unselect Goal to remove elements in results too.
|
||||||
|
* @param target
|
||||||
|
* @param elem
|
||||||
|
*/
|
||||||
|
unselectToNextField(target, elem) {
|
||||||
|
if (target === 'goals') {
|
||||||
|
//console.log('!!!! target is goal: unselect goal', elem.id);
|
||||||
|
this.unselectGoal(elem);
|
||||||
|
//console.log('!!!! done');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rebuild values serie (string) in target HiddenField
|
||||||
|
* @param target
|
||||||
|
*/
|
||||||
|
rebuildHiddenFieldValues(target) {
|
||||||
|
let data = this[target];
|
||||||
|
//console.log('rebuild hiddenFields ' + target + ' values :');
|
||||||
|
data.hiddenField.value = ''; // reset
|
||||||
|
data.value.forEach(elem => {
|
||||||
|
data.hiddenField.value = this.addIdToValue(data.hiddenField.value, elem.id);
|
||||||
|
})
|
||||||
|
//console.log(data.hiddenField);
|
||||||
|
},
|
||||||
|
|
||||||
|
addIdToValue(string, id) {
|
||||||
|
let array = string ? string.split(',') : [];
|
||||||
|
array.push(id.toString());
|
||||||
|
let str = array.join();
|
||||||
|
return str;
|
||||||
|
},
|
||||||
|
|
||||||
|
transTitle ({ title }) {
|
||||||
|
return title.fr //TODO multilang
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
@ -0,0 +1,41 @@
|
|||||||
|
import { fetchResults } from 'ChillMainAssets/lib/api/apiMethods';
|
||||||
|
|
||||||
|
const getSocialActions = () => fetchResults(
|
||||||
|
'/api/1.0/person/social/social-action.json', {
|
||||||
|
item_per_page: 200
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const getGoalByAction = (id) => {
|
||||||
|
let url = `/api/1.0/person/social-work/goal/by-social-action/${id}.json`;
|
||||||
|
return fetch(url)
|
||||||
|
.then(response => {
|
||||||
|
if (response.ok) { return response.json(); }
|
||||||
|
throw Error('Error with request resource response');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getResultByAction = (id) => {
|
||||||
|
let url = `/api/1.0/person/social-work/result/by-social-action/${id}.json`;
|
||||||
|
return fetch(url)
|
||||||
|
.then(response => {
|
||||||
|
if (response.ok) { return response.json(); }
|
||||||
|
throw Error('Error with request resource response');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getResultByGoal = (id) => {
|
||||||
|
let url = `/api/1.0/person/social-work/result/by-goal/${id}.json`;
|
||||||
|
return fetch(url)
|
||||||
|
.then(response => {
|
||||||
|
if (response.ok) { return response.json(); }
|
||||||
|
throw Error('Error with request resource response');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
getSocialActions,
|
||||||
|
getGoalByAction,
|
||||||
|
getResultByAction,
|
||||||
|
getResultByGoal,
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
import { createApp } from "vue";
|
||||||
|
import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n';
|
||||||
|
import App from './App.vue';
|
||||||
|
|
||||||
|
const i18n = _createI18n({});
|
||||||
|
|
||||||
|
const app = createApp({
|
||||||
|
template: `<app></app>`,
|
||||||
|
})
|
||||||
|
.use(i18n)
|
||||||
|
.component('app', App)
|
||||||
|
.mount('#export_export')
|
||||||
|
;
|
@ -11,6 +11,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\PersonBundle\Security\Authorization;
|
namespace Chill\PersonBundle\Security\Authorization;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Center;
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
|
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
|
||||||
use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface;
|
use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface;
|
||||||
@ -119,6 +120,7 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH
|
|||||||
->addCheckFor(null, [self::CREATE, self::REASSIGN_BULK])
|
->addCheckFor(null, [self::CREATE, self::REASSIGN_BULK])
|
||||||
->addCheckFor(AccompanyingPeriod::class, [self::TOGGLE_CONFIDENTIAL, ...self::ALL])
|
->addCheckFor(AccompanyingPeriod::class, [self::TOGGLE_CONFIDENTIAL, ...self::ALL])
|
||||||
->addCheckFor(Person::class, [self::SEE, self::CREATE])
|
->addCheckFor(Person::class, [self::SEE, self::CREATE])
|
||||||
|
->addCheckFor(Center::class, [self::STATS])
|
||||||
->build();
|
->build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,10 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\PersonBundle\Security\Authorization;
|
namespace Chill\PersonBundle\Security\Authorization;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Center;
|
||||||
|
use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface;
|
||||||
|
use Chill\MainBundle\Security\Authorization\VoterHelperInterface;
|
||||||
|
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
|
||||||
use Chill\PersonBundle\Entity\Household\Household;
|
use Chill\PersonBundle\Entity\Household\Household;
|
||||||
use Chill\PersonBundle\Entity\Household\HouseholdMember;
|
use Chill\PersonBundle\Entity\Household\HouseholdMember;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
@ -19,7 +23,7 @@ use Symfony\Component\Security\Core\Security;
|
|||||||
use UnexpectedValueException;
|
use UnexpectedValueException;
|
||||||
use function in_array;
|
use function in_array;
|
||||||
|
|
||||||
class HouseholdVoter extends Voter
|
class HouseholdVoter extends Voter implements ProvideRoleHierarchyInterface
|
||||||
{
|
{
|
||||||
public const EDIT = 'CHILL_PERSON_HOUSEHOLD_EDIT';
|
public const EDIT = 'CHILL_PERSON_HOUSEHOLD_EDIT';
|
||||||
|
|
||||||
@ -36,17 +40,40 @@ class HouseholdVoter extends Voter
|
|||||||
self::EDIT, self::SEE,
|
self::EDIT, self::SEE,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
private VoterHelperInterface $helper;
|
||||||
|
|
||||||
private Security $security;
|
private Security $security;
|
||||||
|
|
||||||
public function __construct(Security $security)
|
public function __construct(Security $security, VoterHelperFactoryInterface $voterHelperFactory)
|
||||||
{
|
{
|
||||||
$this->security = $security;
|
$this->security = $security;
|
||||||
|
$this->helper = $voterHelperFactory
|
||||||
|
->generate(self::class)
|
||||||
|
->addCheckFor(Center::class, [self::STATS])
|
||||||
|
->build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRolesWithHierarchy(): array
|
||||||
|
{
|
||||||
|
return [ 'Person' => $this->getRoles() ];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRoles(): array
|
||||||
|
{
|
||||||
|
return [self::STATS];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRolesWithoutScope(): array
|
||||||
|
{
|
||||||
|
return $this->getRoles();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function supports($attribute, $subject)
|
protected function supports($attribute, $subject)
|
||||||
{
|
{
|
||||||
return $subject instanceof Household
|
return ($subject instanceof Household
|
||||||
&& in_array($attribute, self::ALL, true);
|
&& in_array($attribute, self::ALL, true))
|
||||||
|
|| $this->helper->supports($attribute, $subject)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
|
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
|
||||||
@ -58,6 +85,9 @@ class HouseholdVoter extends Voter
|
|||||||
case self::EDIT:
|
case self::EDIT:
|
||||||
return $this->checkAssociatedMembersRole($subject, PersonVoter::UPDATE);
|
return $this->checkAssociatedMembersRole($subject, PersonVoter::UPDATE);
|
||||||
|
|
||||||
|
case self::STATS:
|
||||||
|
return $this->voteOnAttribute($attribute, $subject, $token);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new UnexpectedValueException('attribute not supported');
|
throw new UnexpectedValueException('attribute not supported');
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ module.exports = function(encore, entries)
|
|||||||
encore.addEntry('vue_accourse_work_create', __dirname + '/Resources/public/vuejs/AccompanyingCourseWorkCreate/index.js');
|
encore.addEntry('vue_accourse_work_create', __dirname + '/Resources/public/vuejs/AccompanyingCourseWorkCreate/index.js');
|
||||||
encore.addEntry('vue_accourse_work_edit', __dirname + '/Resources/public/vuejs/AccompanyingCourseWorkEdit/index.js');
|
encore.addEntry('vue_accourse_work_edit', __dirname + '/Resources/public/vuejs/AccompanyingCourseWorkEdit/index.js');
|
||||||
encore.addEntry('vue_visgraph', __dirname + '/Resources/public/vuejs/VisGraph/index.js');
|
encore.addEntry('vue_visgraph', __dirname + '/Resources/public/vuejs/VisGraph/index.js');
|
||||||
|
encore.addEntry('vue_export_action_goal_result', __dirname + '/Resources/public/vuejs/ExportFormActionGoalResult/index.js');
|
||||||
|
|
||||||
encore.addEntry('mod_set_referrer', __dirname + '/Resources/public/mod/AccompanyingPeriod/setReferrer.js');
|
encore.addEntry('mod_set_referrer', __dirname + '/Resources/public/mod/AccompanyingPeriod/setReferrer.js');
|
||||||
|
|
||||||
|
@ -65,13 +65,6 @@ services:
|
|||||||
tags:
|
tags:
|
||||||
- { name: chill.export_filter, alias: accompanyingcourse_evaluation_filter }
|
- { name: chill.export_filter, alias: accompanyingcourse_evaluation_filter }
|
||||||
|
|
||||||
chill.person.export.filter_activitytype:
|
|
||||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\ActivityTypeFilter
|
|
||||||
autowire: true
|
|
||||||
autoconfigure: true
|
|
||||||
tags:
|
|
||||||
- { name: chill.export_filter, alias: accompanyingcourse_activitytype_filter }
|
|
||||||
|
|
||||||
chill.person.export.filter_origin:
|
chill.person.export.filter_origin:
|
||||||
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\OriginFilter
|
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\OriginFilter
|
||||||
autowire: true
|
autowire: true
|
||||||
|
@ -79,3 +79,10 @@ services:
|
|||||||
autoconfigure: true
|
autoconfigure: true
|
||||||
tags:
|
tags:
|
||||||
- { name: chill.export_aggregator, alias: social_work_actions_result_aggregator }
|
- { name: chill.export_aggregator, alias: social_work_actions_result_aggregator }
|
||||||
|
|
||||||
|
chill.person.export.aggregator_goalresult:
|
||||||
|
class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\GoalResultAggregator
|
||||||
|
autowire: true
|
||||||
|
autoconfigure: true
|
||||||
|
tags:
|
||||||
|
- { name: chill.export_aggregator, alias: social_work_actions_goal_result_aggregator }
|
||||||
|
@ -86,8 +86,8 @@ Civility: Civilité
|
|||||||
choose civility: --
|
choose civility: --
|
||||||
All genders: tous les genres
|
All genders: tous les genres
|
||||||
Any person selected: Aucune personne sélectionnée
|
Any person selected: Aucune personne sélectionnée
|
||||||
Create a household and add an address: Ajouter une adresse pour un usager non suivi et seul dans un ménage
|
Create a household and add an address: Ajouter une adresse pour une personne non suivie et seule dans un ménage
|
||||||
A new household will be created. The person will be member of this household.: Un nouveau ménage va être créé. L'usager sera membre de ce ménage.
|
A new household will be created. The person will be member of this household.: Un nouveau ménage va être créé. La personne sera membre de ce ménage.
|
||||||
Comment on the gender: Commentaire sur le genre
|
Comment on the gender: Commentaire sur le genre
|
||||||
|
|
||||||
# dédoublonnage
|
# dédoublonnage
|
||||||
@ -127,8 +127,8 @@ address_country_code: Code pays
|
|||||||
|
|
||||||
'Alreay existing person': 'Dossiers déjà encodés'
|
'Alreay existing person': 'Dossiers déjà encodés'
|
||||||
'Add the person': 'Ajouter la personne'
|
'Add the person': 'Ajouter la personne'
|
||||||
'Add the person and create an accompanying period': "Créer l'usager ET créer une période d'accompagnement"
|
'Add the person and create an accompanying period': "Créer la personne ET créer une période d'accompagnement"
|
||||||
'Add the person and create a household': "Créer l'usager ET créer un ménage"
|
'Add the person and create a household': "Créer la personne ET créer un ménage"
|
||||||
Show person: Voir le dossier de la personne
|
Show person: Voir le dossier de la personne
|
||||||
'Confirm the creation': 'Confirmer la création'
|
'Confirm the creation': 'Confirmer la création'
|
||||||
'You will create this person': 'Vous allez créer le dossier suivant'
|
'You will create this person': 'Vous allez créer le dossier suivant'
|
||||||
@ -200,7 +200,7 @@ Participants: Personnes impliquées
|
|||||||
Create an accompanying course: Créer un parcours
|
Create an accompanying course: Créer un parcours
|
||||||
Accompanying courses of users: Parcours des utilisateurs
|
Accompanying courses of users: Parcours des utilisateurs
|
||||||
This accompanying course is still a draft: Ce parcours est encore à l'état brouillon.
|
This accompanying course is still a draft: Ce parcours est encore à l'état brouillon.
|
||||||
Associated peoples: Usagers concernés
|
Associated peoples: Personnes concernées
|
||||||
Resources: Interlocuteurs privilégiés
|
Resources: Interlocuteurs privilégiés
|
||||||
Any requestor to this accompanying course: Aucun demandeur pour ce parcours
|
Any requestor to this accompanying course: Aucun demandeur pour ce parcours
|
||||||
Social action: Action d'accompagnement
|
Social action: Action d'accompagnement
|
||||||
@ -217,7 +217,7 @@ See this period: Voir cette période
|
|||||||
Requestor: Demandeur
|
Requestor: Demandeur
|
||||||
No requestor: Pas de demandeur
|
No requestor: Pas de demandeur
|
||||||
No resources: "Pas d'interlocuteurs privilégiés"
|
No resources: "Pas d'interlocuteurs privilégiés"
|
||||||
Persons associated: Usagers concernés
|
Persons associated: Personnes concernés
|
||||||
Referrer: Référent
|
Referrer: Référent
|
||||||
Referrers: Agents traitants
|
Referrers: Agents traitants
|
||||||
Some peoples does not belong to any household currently. Add them to an household soon: Certaines personnes n'appartiennent à aucun ménage actuellement. Renseignez leur ménage dès que possible.
|
Some peoples does not belong to any household currently. Add them to an household soon: Certaines personnes n'appartiennent à aucun ménage actuellement. Renseignez leur ménage dès que possible.
|
||||||
@ -244,7 +244,7 @@ List of resources: "Liste des ressources"
|
|||||||
There are no available resources: "Aucun ressource"
|
There are no available resources: "Aucun ressource"
|
||||||
no comment found: "Aucun commentaire"
|
no comment found: "Aucun commentaire"
|
||||||
Select a type: "Choisissez un type"
|
Select a type: "Choisissez un type"
|
||||||
Select a person: "Choisissez un usager"
|
Select a person: "Choisissez une personne"
|
||||||
Select a thirdparty: "Choisissez un tiers"
|
Select a thirdparty: "Choisissez un tiers"
|
||||||
Contact person: "Personne de contact"
|
Contact person: "Personne de contact"
|
||||||
Kind: "Type"
|
Kind: "Type"
|
||||||
@ -276,11 +276,11 @@ Which kind of residential address would you create ?: Quel type d'adresse de ré
|
|||||||
The address of another person: L'adresse d'une autre personne
|
The address of another person: L'adresse d'une autre personne
|
||||||
The address of a third party: L'adresse d'un tiers
|
The address of a third party: L'adresse d'un tiers
|
||||||
A new address: Une nouvelle adresse
|
A new address: Une nouvelle adresse
|
||||||
residential_address_person_explanation: L'adresse sera positionnée auprès d'un usager. Lorsque l'usager déménage, l'adresse de résidence suivra également cet usager
|
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_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.
|
residential_address_new_address_explanation: Créer une nouvelle adresse. L'adresse sera fixe.
|
||||||
New residential address: Nouvelle adresse de résidence
|
New residential address: Nouvelle adresse de résidence
|
||||||
Host person: Choisir l'adresse d'un usager
|
Host person: Choisir l'adresse d'une personne
|
||||||
Host third party: Choisir l'adresse d'un tiers
|
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
|
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
|
Edit a residential address: Modifier l'addresse de résidence
|
||||||
@ -318,6 +318,7 @@ 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_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_SEE_DETAILS: Voir les détails d'une période d'accompagnement
|
||||||
CHILL_PERSON_ACCOMPANYING_PERIOD_STATS: Statistiques sur les parcours d'accompagnement
|
CHILL_PERSON_ACCOMPANYING_PERIOD_STATS: Statistiques sur les parcours d'accompagnement
|
||||||
|
CHILL_PERSON_HOUSEHOLD_STATS: Statistiques sur les ménages
|
||||||
|
|
||||||
#period
|
#period
|
||||||
Period closed!: Période clôturée!
|
Period closed!: Période clôturée!
|
||||||
@ -330,16 +331,16 @@ Accompanyied people: Personnes accompagnées
|
|||||||
|
|
||||||
## exports
|
## exports
|
||||||
Exports of persons: Exports des personnes
|
Exports of persons: Exports des personnes
|
||||||
Count people by various parameters.: Compte le nombre d'usagers en fonction de différents filtres.
|
Count people by various parameters.: Compte le nombre de personnes en fonction de différents filtres.
|
||||||
Count people: Nombre d'usagers
|
Count people: Nombre de personnes
|
||||||
List peoples: Liste des personnes
|
List peoples: Liste des personnes
|
||||||
Create a list of people according to various filters.: Crée une liste des personnes selon différents filtres.
|
Create a list of people according to various filters.: Crée une liste des personnes selon différents filtres.
|
||||||
Fields to include in export: Champs à inclure dans l'export
|
Fields to include in export: Champs à inclure dans l'export
|
||||||
Address valid at this date: Addresse valide à cette date
|
Address valid at this date: Addresse valide à cette date
|
||||||
List duplicates: Liste des doublons
|
List duplicates: Liste des doublons
|
||||||
Create a list of duplicate people: Créer la liste des personnes détectées comme doublons.
|
Create a list of duplicate people: Créer la liste des personnes détectées comme doublons.
|
||||||
Count people participating in an accompanying course by various parameters.: Nombre d'usagers concernées par un parcours
|
Count people participating in an accompanying course by various parameters.: Nombre de personnes concernées par un parcours
|
||||||
Count people participating in an accompanying course: Nombre d'usagers concernés par un parcours
|
Count people participating in an accompanying course: Nombre de personnes concernés par un parcours
|
||||||
|
|
||||||
Exports of accompanying courses: Exports des parcours d'accompagnement
|
Exports of accompanying courses: Exports des parcours d'accompagnement
|
||||||
Count accompanying courses: Nombre de parcours
|
Count accompanying courses: Nombre de parcours
|
||||||
@ -362,72 +363,77 @@ Count households: Nombre de ménages
|
|||||||
Count household by various parameters.: Compte le nombre de ménages impliqués dans un parcours selon différents filtres.
|
Count household by various parameters.: Compte le nombre de ménages impliqués dans un parcours selon différents filtres.
|
||||||
|
|
||||||
## persons filters
|
## persons filters
|
||||||
Filter by person gender: Filtrer par genre de la personne
|
Filter by person gender: Filtrer les personnes par genre
|
||||||
Accepted genders: Genres acceptés
|
Accepted genders: Genres acceptés
|
||||||
'Filtering by genders: only %genders%': 'Filtré par genre: seulement %genders%'
|
'Filtering by genders: only %genders%': 'Filtré par genre: seulement %genders%'
|
||||||
|
|
||||||
Filter by person's nationality: Filtrer par nationalité
|
Filter by person's nationality: Filtrer les personnes par nationalité
|
||||||
Nationalities: Nationalités
|
Nationalities: Nationalités
|
||||||
Choose countries: Choisir les nationalités
|
Choose countries: Choisir les nationalités
|
||||||
'Filtered by nationality : %nationalities%': 'Filtré par nationalité : seulement %nationalities%'
|
'Filtered by nationality : %nationalities%': 'Filtré par nationalité : seulement %nationalities%'
|
||||||
|
|
||||||
Filter by person's birthdate: Filtrer par date de naissance de la personne
|
Filter by person's birthdate: Filtrer les personnes par date de naissance
|
||||||
Born after this date: Nés après cette date
|
Born after this date: Nés après cette date
|
||||||
Born before this date: Nés avant cette date
|
Born before this date: Nés avant cette date
|
||||||
This field should not be empty: Ce champ ne peut pas être vide
|
This field should not be empty: Ce champ ne peut pas être vide
|
||||||
This date should be after the date given in "born after" field: Cette date doit être après la date donnée du le champ "nés après le"
|
This date should be after the date given in "born after" field: Cette date doit être après la date donnée du le champ "nés après le"
|
||||||
"Filtered by person's birthdate: between %date_from% and %date_to%": "Filtré par date de naissance de la personne: uniquement nés entre le %date_from% et %date_to%"
|
"Filtered by person's birthdate: between %date_from% and %date_to%": "Filtré par date de naissance de la personne: uniquement nés entre le %date_from% et %date_to%"
|
||||||
|
|
||||||
Filter by person's deathdate: Filtrer par date de décès de la personne
|
Filter by person's deathdate: Filtrer les personnes par date de décès
|
||||||
"Filtered by person's deathdate: between %date_from% and %date_to%": "Filtré par date de naissance de la personne: uniquement nés entre le %date_from% et %date_to%"
|
"Filtered by person's deathdate: between %date_from% and %date_to%": "Filtré par date de naissance de la personne: uniquement nés entre le %date_from% et %date_to%"
|
||||||
Death after this date: Décédé après cette date
|
Death after this date: Décédé après cette date
|
||||||
Deathdate before: Décédé avant cette date
|
Deathdate before: Décédé avant cette date
|
||||||
|
|
||||||
Alive: Vivant
|
Alive: Vivant
|
||||||
Deceased: Décédé
|
Deceased: Décédé
|
||||||
Filter in relation to this date: Filtrer par rapport à cette date
|
Filter in relation to this date: Filtrer par rapport à cette date
|
||||||
"Filtered by a state of %deadOrAlive% at this date %date_calc%": Filtré par personnes qui sont %deadOrAlive% à cette date %date_calc%
|
"Filtered by a state of %deadOrAlive% at this date %date_calc%": Filtré par personnes qui sont %deadOrAlive% à cette date %date_calc%
|
||||||
|
|
||||||
Filter by person's age: Filtrer par âge de la personne
|
Filter by person's age: Filtrer les personnes par age
|
||||||
"Filtered by person's age: between %min_age% and %max_age%": "Filtré par âge de la personne entre %min_age% et %max_age%"
|
"Filtered by person's age: between %min_age% and %max_age%": "Filtré par âge de la personne entre %min_age% et %max_age%"
|
||||||
Minimum age: Âge minimum
|
Minimum age: Âge minimum
|
||||||
Maximum age: Âge maximum
|
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.
|
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é
|
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 usagers qui ont une addresse de résidence chez un tiers de catégorie %thirdparty_type%
|
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: Composition familiale
|
||||||
Family composition at this time: Composition familiale à cette date.
|
Family composition at this time: Composition familiale à cette date.
|
||||||
|
|
||||||
|
Filter by person's marital status: Filtrer les personnes par état matrimonial
|
||||||
Filtered by person's marital status: Filtré par état matrimonial
|
Filtered by person's marital status: Filtré par état matrimonial
|
||||||
Filter by person's marital status: Filtrer par état matrimonial
|
|
||||||
Marital status at this time: État matrimonial par rapport à cette date
|
Marital status at this time: État matrimonial par rapport à cette date
|
||||||
|
|
||||||
Filter by entrusted child status: Filtrer les usagers qui sont "enfant confié"
|
Filter by entrusted child status: Filtrer les personnes "enfant confié"
|
||||||
Filtered by entrusted child status: Uniquement les usagers qui sont "enfant confié"
|
Filtered by entrusted child status: Uniquement les personnes qui sont "enfant confié"
|
||||||
|
|
||||||
Filter by nomadic status: Filtrer les usagers qui sont "gens de voyage"
|
Filter by nomadic status: Filtrer les personnes "gens du voyage"
|
||||||
Filtered by nomadic status: Uniquement les usagers qui sont "gens de voyage"
|
Filtered by nomadic status: Uniquement les personnes qui sont "gens du voyage"
|
||||||
|
|
||||||
Filtered by person's who have a residential address located at another user: Uniquement les usagers qui ont une addresse de résidence chez un autre usager
|
"Filter by person's who have a residential address located at another user": Filtrer les personnes qui ont une addresse de résidence chez une autre personne
|
||||||
|
"Filtered by person's who have a residential address located at another user": Uniquement les personnes qui ont une addresse de résidence chez une autre personne
|
||||||
|
|
||||||
Filtered by person's that are alive or have deceased at a certain date: Filtrer par usagers qui sont décédé ou vivant à une certaine date
|
Filter by person's that are alive or have deceased at a certain date: Filtrer les personnes qui sont décédées ou vivantes à une certaine date
|
||||||
|
Filtered by person's that are alive or have deceased at a certain date: Uniquement les personnes qui sont décédées ou vivantes à une certaine date
|
||||||
|
|
||||||
"Filter by accompanying period: active period": "Filtrer par période d'accompagnement: en file active"
|
"Filter by accompanying period: active period": "Filtrer les personnes par période d'accompagnement: en file active"
|
||||||
Having an accompanying period opened after this date: Ayant une période d'accompagnement ouverte après cette date
|
Having an accompanying period opened after this date: Ayant une période d'accompagnement ouverte après cette date
|
||||||
Having an accompanying period ending before this date, or still opened at this date: Ayant une période d'accompagnement fermée après cette date, ou toujours ouverte à cette date
|
Having an accompanying period ending before this date, or still opened at this date: Ayant une période d'accompagnement fermée après cette date, ou toujours ouverte à cette date
|
||||||
"Filtered by accompanying period: persons having an accompanying period opened after the %date_from% and closed before the %date_to% (or still opened at the %date_to%)": "Filtré par période d'accompagnement: personnes ayant une période d'accompagnement ouverte après le %date_from%, et cloturée le %date_to% (ou toujours ouverte le %date_to%)"
|
"Filtered by accompanying period: persons having an accompanying period opened after the %date_from% and closed before the %date_to% (or still opened at the %date_to%)": "Filtré par période d'accompagnement: personnes ayant une période d'accompagnement ouverte après le %date_from%, et cloturée le %date_to% (ou toujours ouverte le %date_to%)"
|
||||||
|
|
||||||
"Filter by accompanying period: starting between two dates": "Filtrer par période d'accompagnement: début de la période entre deux dates"
|
"Filter by accompanying period: starting between two dates": "Filtrer les personnes par période d'accompagnement: début de la période entre deux dates"
|
||||||
"Having an accompanying period opened before this date": "Ayant une période d'accompagnement ouverte avant cette date"
|
"Having an accompanying period opened before this date": "Ayant une période d'accompagnement ouverte avant cette date"
|
||||||
"Filtered by accompanying period: persons having an accompanying period opened between the %date_from% and %date_to%": "Filtrer par période d'accompagnement: ayant une période ouverte entre le %date_from% et le %date_to%"
|
"Filtered by accompanying period: persons having an accompanying period opened between the %date_from% and %date_to%": "Filtrer par période d'accompagnement: ayant une période ouverte entre le %date_from% et le %date_to%"
|
||||||
|
|
||||||
"Filter by accompanying period: closed between two dates": "Filtrer par période d'accompagnement: période fermée entre deux dates"
|
"Filter by accompanying period: closed between two dates": "Filtrer les personnes par période d'accompagnement: période fermée entre deux dates"
|
||||||
Having an accompanying period closed after this date: Ayant une période d'accompagnement fermée après cette date
|
Having an accompanying period closed after this date: Ayant une période d'accompagnement fermée après cette date
|
||||||
"Having an accompanying period closed before this date": "Ayant une période d'accompagnement fermée avant cette date"
|
"Having an accompanying period closed before this date": "Ayant une période d'accompagnement fermée avant cette date"
|
||||||
"Filtered by accompanying period: persons having an accompanying period closed between the %date_from% and %date_to%": "Filtrer par période d'accompagnement: ayant une période fermée entre le %date_from% et le %date_to%"
|
"Filtered by accompanying period: persons having an accompanying period closed between the %date_from% and %date_to%": "Filtrer par période d'accompagnement: ayant une période fermée entre le %date_from% et le %date_to%"
|
||||||
|
|
||||||
|
Filter by person having an activity in a period: Filtrer les personnes ayant eu une échange pendant la période donnée
|
||||||
|
Filtered by person having an activity between %date_from% and %date_to% with reasons %reasons_name%: Uniquement les personnes associées à une échange entre %date_from% et %date_to% avec les sujets %reasons_name%
|
||||||
|
|
||||||
|
|
||||||
## accompanying course filters/aggr
|
## accompanying course filters/aggr
|
||||||
Filter by user scope: Filtrer les parcours par service du référent
|
Filter by user scope: Filtrer les parcours par service du référent
|
||||||
"Filtered by user main scope: only %scope%": "Filtré par service du référent: uniquement %scope%"
|
"Filtered by user main scope: only %scope%": "Filtré par service du référent: uniquement %scope%"
|
||||||
@ -456,7 +462,9 @@ Filter by socialaction: Filtrer les parcours par action d'accompagnement
|
|||||||
Accepted socialactions: Actions d'accompagnement
|
Accepted socialactions: Actions d'accompagnement
|
||||||
"Filtered by socialactions: only %socialactions%": "Filtré par action d'accompagnement: uniquement %socialactions%"
|
"Filtered by socialactions: only %socialactions%": "Filtré par action d'accompagnement: uniquement %socialactions%"
|
||||||
Group by social action: Grouper les parcours par action d'accompagnement
|
Group by social action: Grouper les parcours par action d'accompagnement
|
||||||
Filter by type of action, objectives and results: "Filtrer par type d'action, objectif et résultat"
|
|
||||||
|
Filter by type of action, goals and results: "Filtrer les actions par type, objectif et résultat"
|
||||||
|
'Filtered actions by type, goals and results: %selected%': "Actions filtrées par: %selected%"
|
||||||
|
|
||||||
Filter by evaluation: Filtrer les parcours par évaluation
|
Filter by evaluation: Filtrer les parcours par évaluation
|
||||||
Accepted evaluations: Évaluations
|
Accepted evaluations: Évaluations
|
||||||
@ -484,13 +492,13 @@ Administrative location: Localisation administrative
|
|||||||
"Filtered by administratives locations: only %locations%": "Filtré par localisation administrative: uniquement %locations%"
|
"Filtered by administratives locations: only %locations%": "Filtré par localisation administrative: uniquement %locations%"
|
||||||
Group by administrative location: Grouper les parcours par localisation administrative
|
Group by administrative location: Grouper les parcours par localisation administrative
|
||||||
|
|
||||||
Filter by requestor: Filtrer les parcours selon la présence du demandeur au sein des usagers concernés
|
Filter by requestor: Filtrer les parcours selon la présence du demandeur au sein des personnes concernées
|
||||||
Accepted choices: ''
|
Accepted choices: ''
|
||||||
is person concerned: Le demandeur est un usager concerné
|
is person concerned: Le demandeur est une personne concernée
|
||||||
is other person: Le demandeur est un usager, mais n'est pas concerné
|
is other person: Le demandeur est une personne, mais n'est pas concernée
|
||||||
is thirdparty: Le demandeur est un tiers
|
is thirdparty: Le demandeur est un tiers
|
||||||
no requestor: Le parcours ne comporte pas de demandeur
|
no requestor: Le parcours ne comporte pas de demandeur
|
||||||
"Filtered by requestor: only %choice%": "Filtré par présence du demandeur au sein des usagers concernés: uniquement si %choice%"
|
"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
|
Group by requestor: Grouper les parcours selon la nature du demandeur
|
||||||
|
|
||||||
Filter by confidential: Filtrer les parcours par confidentialité
|
Filter by confidential: Filtrer les parcours par confidentialité
|
||||||
@ -553,6 +561,10 @@ Group by treating agent: Grouper les actions par agent traitant
|
|||||||
Group social work actions by action type: Grouper les actions par type
|
Group social work actions by action type: Grouper les actions par type
|
||||||
Group social work actions by goal: Grouper les actions par objectif
|
Group social work actions by goal: Grouper les actions par objectif
|
||||||
Group social work actions by result: Grouper les actions par résultat
|
Group social work actions by result: Grouper les actions par résultat
|
||||||
|
Group social work actions by goal and result: Grouper les actions par objectif et résultat
|
||||||
|
Goal Type: Objectif
|
||||||
|
Result Type: Résultat
|
||||||
|
Goal and result Type: Objectif et résultat
|
||||||
|
|
||||||
## evaluations filters/aggr
|
## evaluations filters/aggr
|
||||||
Filter by evaluation type: Filtrer les évaluations par type
|
Filter by evaluation type: Filtrer les évaluations par type
|
||||||
@ -576,7 +588,7 @@ Group by composition: Grouper les ménages par composition familiale
|
|||||||
Group by number of children: Grouper les ménages par nombre d'enfants
|
Group by number of children: Grouper les ménages par nombre d'enfants
|
||||||
|
|
||||||
## persons aggregators
|
## persons aggregators
|
||||||
Group by duration: Grouper par durée du parcours
|
Group by duration: Grouper les parcours par durée
|
||||||
Rounded month duration: Durée en mois (arrondie)
|
Rounded month duration: Durée en mois (arrondie)
|
||||||
current duration: en cours
|
current duration: en cours
|
||||||
duration 0 month: 0 mois (<15 jours)
|
duration 0 month: 0 mois (<15 jours)
|
||||||
@ -589,13 +601,15 @@ Group by country: Grouper par pays
|
|||||||
Group people by gender: Grouper les personnes par genre
|
Group people by gender: Grouper les personnes par genre
|
||||||
Group people by their professional situation: Grouper les personnes par situation professionelle
|
Group people by their professional situation: Grouper les personnes par situation professionelle
|
||||||
Group people by marital status: Grouper les personnes par état matrimonial
|
Group people by marital status: Grouper les personnes par état matrimonial
|
||||||
Aggregate by household position: Grouper par position dans le ménage
|
|
||||||
|
Aggregate by household position: Grouper les personnes par position dans le ménage
|
||||||
Household position in relation to this date: Position dans le ménage par rapport à cette date
|
Household position in relation to this date: Position dans le ménage par rapport à cette date
|
||||||
Household position: Position dans le ménage
|
Household position: Position dans le ménage
|
||||||
Filtered by person's who have a residential address located at a thirdparty of type: Uniquement les usagers 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 usagers 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 par âge
|
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
|
Calculate age in relation to this date: Calculer l'âge par rapport à cette date
|
||||||
|
|
||||||
Group people by country of birth: Grouper les personnes par pays de naissance
|
Group people by country of birth: Grouper les personnes par pays de naissance
|
||||||
@ -763,7 +777,7 @@ This course is located at a temporarily address. You should locate this course t
|
|||||||
Accompanying course location: Localisation du parcours
|
Accompanying course location: Localisation du parcours
|
||||||
This course is located by: Localisé auprès de
|
This course is located by: Localisé auprès de
|
||||||
This course has a temporarily location: Localisation temporaire
|
This course has a temporarily location: Localisation temporaire
|
||||||
Choose a person to locate by: Localiser auprès d'un usager concerné
|
Choose a person to locate by: Localiser auprès d'une personne concernée
|
||||||
Associate at least one member with an household, and set an address to this household: Associez au moins un membre du parcours à un ménage, et indiquez une adresse à ce ménage.
|
Associate at least one member with an household, and set an address to this household: Associez au moins un membre du parcours à un ménage, et indiquez une adresse à ce ménage.
|
||||||
Locate by: Localiser auprès de
|
Locate by: Localiser auprès de
|
||||||
fix it: Compléter
|
fix it: Compléter
|
||||||
@ -848,7 +862,7 @@ Person addresses: Adresses de résidence
|
|||||||
Household addresses: Adresses de domicile
|
Household addresses: Adresses de domicile
|
||||||
Insert an address: Insérer une adresse
|
Insert an address: Insérer une adresse
|
||||||
see social issues: Voir les problématiques sociales
|
see social issues: Voir les problématiques sociales
|
||||||
see persons associated: Voir les usagers concernés
|
see persons associated: Voir les personnes concernées
|
||||||
|
|
||||||
docgen:
|
docgen:
|
||||||
Accompanying Period basic: "Parcours d'accompagnement (basique)"
|
Accompanying Period basic: "Parcours d'accompagnement (basique)"
|
||||||
@ -869,10 +883,10 @@ docgen:
|
|||||||
period_notification:
|
period_notification:
|
||||||
period_designated_subject: Vous êtes référent d'un parcours d'accompagnement
|
period_designated_subject: Vous êtes référent d'un parcours d'accompagnement
|
||||||
You are designated to a new period: Vous avez été désigné référent d'un parcours d'accompagnement.
|
You are designated to a new period: Vous avez été désigné référent d'un parcours d'accompagnement.
|
||||||
Persons are: Les usagers concernés sont les suivants
|
Persons are: Les personnes concernées sont les suivantes
|
||||||
Social issues are: Les problématiques sociales renseignées sont les suivantes
|
Social issues are: Les problématiques sociales renseignées sont les suivantes
|
||||||
See it online: Visualisez le parcours en ligne
|
See it online: Visualisez le parcours en ligne
|
||||||
Person locating period has moved: L'usager qui localise un parcours a déménagé
|
Person locating period has moved: La personne qui localise un parcours a déménagé
|
||||||
|
|
||||||
You are getting a notification for a period which does not exists any more: Cette notification ne correspond pas à une période d'accompagnement valide.
|
You are getting a notification for a period which does not exists any more: Cette notification ne correspond pas à une période d'accompagnement valide.
|
||||||
You are getting a notification for a period you are not allowed to see: La notification fait référence à une période d'accompagnement à laquelle vous n'avez pas accès.
|
You are getting a notification for a period you are not allowed to see: La notification fait référence à une période d'accompagnement à laquelle vous n'avez pas accès.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user