Merge remote-tracking branch 'origin/master' into cire16

This commit is contained in:
2022-12-22 10:22:58 +01:00
801 changed files with 39243 additions and 6591 deletions

View File

@@ -17,10 +17,11 @@ use Chill\ActivityBundle\Form\ActivityType;
use Chill\ActivityBundle\Repository\ActivityACLAwareRepositoryInterface;
use Chill\ActivityBundle\Repository\ActivityRepository;
use Chill\ActivityBundle\Repository\ActivityTypeCategoryRepository;
use Chill\ActivityBundle\Repository\ActivityTypeRepository;
use Chill\ActivityBundle\Repository\ActivityTypeRepositoryInterface;
use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
use Chill\MainBundle\Repository\LocationRepository;
use Chill\MainBundle\Repository\UserRepositoryInterface;
use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
@@ -41,7 +42,6 @@ use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Serializer\SerializerInterface;
use function array_key_exists;
@@ -55,7 +55,7 @@ final class ActivityController extends AbstractController
private ActivityTypeCategoryRepository $activityTypeCategoryRepository;
private ActivityTypeRepository $activityTypeRepository;
private ActivityTypeRepositoryInterface $activityTypeRepository;
private CenterResolverManagerInterface $centerResolver;
@@ -73,9 +73,11 @@ final class ActivityController extends AbstractController
private ThirdPartyRepository $thirdPartyRepository;
private UserRepositoryInterface $userRepository;
public function __construct(
ActivityACLAwareRepositoryInterface $activityACLAwareRepository,
ActivityTypeRepository $activityTypeRepository,
ActivityTypeRepositoryInterface $activityTypeRepository,
ActivityTypeCategoryRepository $activityTypeCategoryRepository,
PersonRepository $personRepository,
ThirdPartyRepository $thirdPartyRepository,
@@ -86,6 +88,7 @@ final class ActivityController extends AbstractController
EventDispatcherInterface $eventDispatcher,
LoggerInterface $logger,
SerializerInterface $serializer,
UserRepositoryInterface $userRepository,
CenterResolverManagerInterface $centerResolver
) {
$this->activityACLAwareRepository = $activityACLAwareRepository;
@@ -100,6 +103,7 @@ final class ActivityController extends AbstractController
$this->eventDispatcher = $eventDispatcher;
$this->logger = $logger;
$this->serializer = $serializer;
$this->userRepository = $userRepository;
$this->centerResolver = $centerResolver;
}
@@ -372,7 +376,7 @@ final class ActivityController extends AbstractController
if ($request->query->has('activityData')) {
$activityData = $request->query->get('activityData');
if (array_key_exists('durationTime', $activityData)) {
if (array_key_exists('durationTime', $activityData) && $activityType->getDurationTimeVisible() > 0) {
$durationTimeInMinutes = $activityData['durationTime'];
$hours = floor($durationTimeInMinutes / 60);
$minutes = $durationTimeInMinutes % 60;
@@ -391,26 +395,36 @@ final class ActivityController extends AbstractController
}
}
if (array_key_exists('personsId', $activityData)) {
if (array_key_exists('personsId', $activityData) && $activityType->getPersonsVisible() > 0) {
foreach ($activityData['personsId'] as $personId) {
$concernedPerson = $this->personRepository->find($personId);
$entity->addPerson($concernedPerson);
}
}
if (array_key_exists('professionalsId', $activityData)) {
if (array_key_exists('professionalsId', $activityData) && $activityType->getThirdPartiesVisible() > 0) {
foreach ($activityData['professionalsId'] as $professionalsId) {
$professional = $this->thirdPartyRepository->find($professionalsId);
$entity->addThirdParty($professional);
}
}
if (array_key_exists('location', $activityData)) {
if (array_key_exists('usersId', $activityData) && $activityType->getUsersVisible() > 0) {
foreach ($activityData['usersId'] as $userId) {
$user = $this->userRepository->find($userId);
if (null !== $user) {
$entity->addUser($user);
}
}
}
if (array_key_exists('location', $activityData) && $activityType->getLocationVisible() > 0) {
$location = $this->locationRepository->find($activityData['location']);
$entity->setLocation($location);
}
if (array_key_exists('comment', $activityData)) {
if (array_key_exists('comment', $activityData) && $activityType->getCommentVisible() > 0) {
$comment = new CommentEmbeddable();
$comment->setComment($activityData['comment']);
$comment->setUserId($this->getUser()->getid());

View File

@@ -13,6 +13,10 @@ namespace Chill\ActivityBundle\Entity;
use Chill\ActivityBundle\Validator\Constraints as ActivityValidator;
use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
use Chill\MainBundle\Doctrine\Model\TrackCreationTrait;
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
use Chill\MainBundle\Doctrine\Model\TrackUpdateTrait;
use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
use Chill\MainBundle\Entity\Embeddable\PrivateCommentEmbeddable;
@@ -55,8 +59,12 @@ use Symfony\Component\Validator\Constraints as Assert;
* getUserFunction="getUser",
* path="scope")
*/
class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterface, HasCentersInterface, HasScopesInterface
class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterface, HasCentersInterface, HasScopesInterface, TrackCreationInterface, TrackUpdateInterface
{
use TrackCreationTrait;
use TrackUpdateTrait;
public const SENTRECEIVED_RECEIVED = 'received';
public const SENTRECEIVED_SENT = 'sent';

View File

@@ -516,6 +516,11 @@ class ActivityType
return $this->userVisible;
}
public function hasCategory(): bool
{
return null !== $this->getCategory();
}
/**
* Is active
* return true if the type is active.

View File

@@ -0,0 +1,68 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators;
use Chill\ActivityBundle\Entity\Activity;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
class ByActivityNumberAggregator implements AggregatorInterface
{
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data): void
{
$qb
->addSelect('(SELECT COUNT(activity.id) FROM ' . Activity::class . ' activity WHERE activity.accompanyingPeriod = acp) AS activity_by_number_aggregator')
->addGroupBy('activity_by_number_aggregator');
}
public function applyOn(): string
{
return Declarations::ACP_TYPE;
}
public function buildForm(FormBuilderInterface $builder): void
{
// No form needed
}
public function getLabels($key, array $values, $data)
{
return static function ($value) {
if ('_header' === $value) {
return '';
}
if (null === $value) {
return '';
}
return $value;
};
}
public function getQueryKeys($data): array
{
return ['activity_by_number_aggregator'];
}
public function getTitle(): string
{
return 'Group acp by activity number';
}
}

View File

@@ -13,46 +13,34 @@ namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Repository\UserRepository;
use Chill\MainBundle\Repository\UserRepositoryInterface;
use Chill\MainBundle\Templating\Entity\UserRender;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use function in_array;
class ByUserAggregator implements AggregatorInterface
class ByCreatorAggregator implements AggregatorInterface
{
private UserRender $userRender;
private UserRepository $userRepository;
private UserRepositoryInterface $userRepository;
public function __construct(
UserRepository $userRepository,
UserRepositoryInterface $userRepository,
UserRender $userRender
) {
$this->userRepository = $userRepository;
$this->userRender = $userRender;
}
public function addRole()
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
if (!in_array('user', $qb->getAllAliases(), true)) {
$qb->join('activity.users', 'user');
}
$qb->addSelect('user.id AS users_aggregator');
$groupBy = $qb->getDQLPart('groupBy');
if (!empty($groupBy)) {
$qb->addGroupBy('users_aggregator');
} else {
$qb->groupBy('users_aggregator');
}
$qb->addSelect('IDENTITY(activity.createdBy) AS creator_aggregator');
$qb->addGroupBy('creator_aggregator');
}
public function applyOn(): string
@@ -69,7 +57,11 @@ class ByUserAggregator implements AggregatorInterface
{
return function ($value): string {
if ('_header' === $value) {
return 'Accepted users';
return 'Created by';
}
if (null === $value) {
return '';
}
$u = $this->userRepository->find($value);
@@ -80,11 +72,11 @@ class ByUserAggregator implements AggregatorInterface
public function getQueryKeys($data): array
{
return ['users_aggregator'];
return ['creator_aggregator'];
}
public function getTitle(): string
{
return 'Group activity by linked users';
return 'Group activity by creator';
}
}

View File

@@ -33,26 +33,19 @@ class BySocialActionAggregator implements AggregatorInterface
$this->actionRepository = $actionRepository;
}
public function addRole()
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
if (!in_array('socialaction', $qb->getAllAliases(), true)) {
$qb->join('activity.socialActions', 'socialaction');
if (!in_array('actsocialaction', $qb->getAllAliases(), true)) {
$qb->leftJoin('activity.socialActions', 'actsocialaction');
}
$qb->addSelect('socialaction.id AS socialaction_aggregator');
$groupBy = $qb->getDQLPart('groupBy');
if (!empty($groupBy)) {
$qb->addGroupBy('socialaction_aggregator');
} else {
$qb->groupBy('socialaction_aggregator');
}
$qb->addSelect('actsocialaction.id AS socialaction_aggregator');
$qb->addGroupBy('socialaction_aggregator');
}
public function applyOn(): string
@@ -72,6 +65,10 @@ class BySocialActionAggregator implements AggregatorInterface
return 'Social action';
}
if (null === $value) {
return '';
}
$sa = $this->actionRepository->find($value);
return $this->actionRender->renderString($sa, []);

View File

@@ -33,26 +33,19 @@ class BySocialIssueAggregator implements AggregatorInterface
$this->issueRender = $issueRender;
}
public function addRole()
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
if (!in_array('socialissue', $qb->getAllAliases(), true)) {
$qb->join('activity.socialIssues', 'socialissue');
if (!in_array('actsocialissue', $qb->getAllAliases(), true)) {
$qb->leftJoin('activity.socialIssues', 'actsocialissue');
}
$qb->addSelect('socialissue.id AS socialissue_aggregator');
$groupBy = $qb->getDQLPart('groupBy');
if (!empty($groupBy)) {
$qb->addGroupBy('socialissue_aggregator');
} else {
$qb->groupBy('socialissue_aggregator');
}
$qb->addSelect('actsocialissue.id AS socialissue_aggregator');
$qb->addGroupBy('socialissue_aggregator');
}
public function applyOn(): string
@@ -72,6 +65,10 @@ class BySocialIssueAggregator implements AggregatorInterface
return 'Social issues';
}
if (null === $value) {
return '';
}
$i = $this->issueRepository->find($value);
return $this->issueRender->renderString($i, []);

View File

@@ -33,26 +33,19 @@ class ByThirdpartyAggregator implements AggregatorInterface
$this->thirdPartyRender = $thirdPartyRender;
}
public function addRole()
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
if (!in_array('thirdparty', $qb->getAllAliases(), true)) {
$qb->join('activity.thirdParties', 'thirdparty');
if (!in_array('acttparty', $qb->getAllAliases(), true)) {
$qb->leftJoin('activity.thirdParties', 'acttparty');
}
$qb->addSelect('thirdparty.id AS thirdparty_aggregator');
$groupBy = $qb->getDQLPart('groupBy');
if (!empty($groupBy)) {
$qb->addGroupBy('thirdparty_aggregator');
} else {
$qb->groupBy('thirdparty_aggregator');
}
$qb->addSelect('acttparty.id AS thirdparty_aggregator');
$qb->addGroupBy('thirdparty_aggregator');
}
public function applyOn(): string
@@ -72,6 +65,10 @@ class ByThirdpartyAggregator implements AggregatorInterface
return 'Accepted thirdparty';
}
if (null === $value) {
return '';
}
$tp = $this->thirdPartyRepository->find($value);
return $this->thirdPartyRender->renderString($tp, []);

View File

@@ -19,7 +19,7 @@ use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use function in_array;
class UserScopeAggregator implements AggregatorInterface
class CreatorScopeAggregator implements AggregatorInterface
{
private ScopeRepository $scopeRepository;
@@ -33,26 +33,19 @@ class UserScopeAggregator implements AggregatorInterface
$this->translatableStringHelper = $translatableStringHelper;
}
public function addRole()
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
if (!in_array('user', $qb->getAllAliases(), true)) {
$qb->join('activity.user', 'user');
if (!in_array('actcreator', $qb->getAllAliases(), true)) {
$qb->leftJoin('activity.createdBy', 'actcreator');
}
$qb->addSelect('IDENTITY(user.mainScope) AS userscope_aggregator');
$groupBy = $qb->getDQLPart('groupBy');
if (!empty($groupBy)) {
$qb->addGroupBy('userscope_aggregator');
} else {
$qb->groupBy('userscope_aggregator');
}
$qb->addSelect('IDENTITY(actcreator.mainScope) AS creatorscope_aggregator');
$qb->addGroupBy('creatorscope_aggregator');
}
public function applyOn(): string
@@ -72,6 +65,10 @@ class UserScopeAggregator implements AggregatorInterface
return 'Scope';
}
if (null === $value) {
return '';
}
$s = $this->scopeRepository->find($value);
return $this->translatableStringHelper->localize(
@@ -82,11 +79,11 @@ class UserScopeAggregator implements AggregatorInterface
public function getQueryKeys($data): array
{
return ['userscope_aggregator'];
return ['creatorscope_aggregator'];
}
public function getTitle(): string
{
return 'Group activity by userscope';
return 'Group activity by creator scope';
}
}

View File

@@ -13,7 +13,6 @@ namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\AggregatorInterface;
use DateTime;
use Doctrine\ORM\QueryBuilder;
use RuntimeException;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
@@ -38,7 +37,7 @@ class DateAggregator implements AggregatorInterface
$this->translator = $translator;
}
public function addRole()
public function addRole(): ?string
{
return null;
}
@@ -49,41 +48,27 @@ class DateAggregator implements AggregatorInterface
switch ($data['frequency']) {
case 'month':
$fmt = 'MM';
$fmt = 'YYYY-MM';
break;
break;
case 'week':
$fmt = 'IW';
$fmt = 'YYYY-IW';
break;
break;
case 'year':
$fmt = 'YYYY'; $order = 'DESC';
break;
break; // order DESC does not works !
default:
throw new RuntimeException(sprintf("The frequency data '%s' is invalid.", $data['frequency']));
}
$qb->addSelect(sprintf("TO_CHAR(activity.date, '%s') AS date_aggregator", $fmt));
$groupBy = $qb->getDQLPart('groupBy');
if (!empty($groupBy)) {
$qb->addGroupBy('date_aggregator');
} else {
$qb->groupBy('date_aggregator');
}
$orderBy = $qb->getDQLPart('orderBy');
if (!empty($orderBy)) {
$qb->addOrderBy('date_aggregator', $order);
} else {
$qb->orderBy('date_aggregator', $order);
}
$qb->addGroupBy('date_aggregator');
$qb->addOrderBy('date_aggregator', $order);
}
public function applyOn(): string
@@ -109,16 +94,12 @@ break;
return 'by ' . $data['frequency'];
}
if (null === $value) {
return '';
}
switch ($data['frequency']) {
case 'month':
$month = DateTime::createFromFormat('!m', $value);
return sprintf(
'%02d (%s)',
$value,
$month->format('M')
);
case 'week':
//return $this->translator->trans('for week') .' '. $value ;

View File

@@ -33,26 +33,19 @@ class LocationTypeAggregator implements AggregatorInterface
$this->translatableStringHelper = $translatableStringHelper;
}
public function addRole()
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
if (!in_array('location', $qb->getAllAliases(), true)) {
$qb->join('activity.location', 'location');
if (!in_array('actloc', $qb->getAllAliases(), true)) {
$qb->leftJoin('activity.location', 'actloc');
}
$qb->addSelect('IDENTITY(location.locationType) AS locationtype_aggregator');
$groupBy = $qb->getDQLPart('groupBy');
if (!empty($groupBy)) {
$qb->addGroupBy('locationtype_aggregator');
} else {
$qb->groupBy('locationtype_aggregator');
}
$qb->addSelect('IDENTITY(actloc.locationType) AS locationtype_aggregator');
$qb->addGroupBy('locationtype_aggregator');
}
public function applyOn(): string
@@ -72,6 +65,10 @@ class LocationTypeAggregator implements AggregatorInterface
return 'Accepted locationtype';
}
if (null === $value) {
return '';
}
$lt = $this->locationTypeRepository->find($value);
return $this->translatableStringHelper->localize(

View File

@@ -12,53 +12,43 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Aggregator;
use Chill\ActivityBundle\Export\Declarations;
use Chill\ActivityBundle\Repository\ActivityTypeRepository;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\ActivityBundle\Repository\ActivityTypeRepositoryInterface;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Closure;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
use function in_array;
class ActivityTypeAggregator implements AggregatorInterface
{
public const KEY = 'activity_type_aggregator';
protected ActivityTypeRepository $activityTypeRepository;
protected ActivityTypeRepositoryInterface $activityTypeRepository;
protected TranslatableStringHelperInterface $translatableStringHelper;
public function __construct(
ActivityTypeRepository $activityTypeRepository,
ActivityTypeRepositoryInterface $activityTypeRepository,
TranslatableStringHelperInterface $translatableStringHelper
) {
$this->activityTypeRepository = $activityTypeRepository;
$this->translatableStringHelper = $translatableStringHelper;
}
public function addRole()
public function addRole(): ?string
{
return new Role(ActivityStatsVoter::STATS);
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
if (!in_array('type', $qb->getAllAliases(), true)) {
$qb->join('activity.activityType', 'type');
if (!in_array('acttype', $qb->getAllAliases(), true)) {
$qb->leftJoin('activity.activityType', 'acttype');
}
$qb->addSelect(sprintf('IDENTITY(activity.activityType) AS %s', self::KEY));
$groupby = $qb->getDQLPart('groupBy');
if (!empty($groupBy)) {
$qb->addGroupBy(self::KEY);
} else {
$qb->groupBy(self::KEY);
}
$qb->addGroupBy(self::KEY);
}
public function applyOn(): string
@@ -81,6 +71,10 @@ class ActivityTypeAggregator implements AggregatorInterface
return 'Activity type';
}
if (null === $value) {
return '';
}
$t = $this->activityTypeRepository->find($value);
return $this->translatableStringHelper->localize($t->getName());
@@ -96,23 +90,4 @@ class ActivityTypeAggregator implements AggregatorInterface
{
return 'Aggregate by activity type';
}
/**
* Check if a join between Activity and another alias.
*
* @param Join[] $joins
* @param string $alias the alias to search for
*
* @return bool
*/
private function checkJoinAlreadyDefined(array $joins, $alias)
{
foreach ($joins as $join) {
if ($join->getAlias() === $alias) {
return true;
}
}
return false;
}
}

View File

@@ -12,14 +12,12 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Aggregator;
use Chill\ActivityBundle\Export\Declarations;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Repository\UserRepository;
use Chill\MainBundle\Templating\Entity\UserRender;
use Closure;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
class ActivityUserAggregator implements AggregatorInterface
{
@@ -37,9 +35,9 @@ class ActivityUserAggregator implements AggregatorInterface
$this->userRender = $userRender;
}
public function addRole()
public function addRole(): ?string
{
return new Role(ActivityStatsVoter::STATS);
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
@@ -63,14 +61,15 @@ class ActivityUserAggregator implements AggregatorInterface
public function getLabels($key, $values, $data): Closure
{
// preload users at once
$this->userRepository->findBy(['id' => $values]);
return function ($value) {
if ('_header' === $value) {
return 'Activity user';
}
if (null === $value) {
return '';
}
$u = $this->userRepository->find($value);
return $this->userRender->renderString($u, []);

View File

@@ -0,0 +1,86 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Aggregator;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Repository\UserRepositoryInterface;
use Chill\MainBundle\Templating\Entity\UserRender;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use function in_array;
class ActivityUsersAggregator implements AggregatorInterface
{
private UserRender $userRender;
private UserRepositoryInterface $userRepository;
public function __construct(UserRepositoryInterface $userRepository, UserRender $userRender)
{
$this->userRepository = $userRepository;
$this->userRender = $userRender;
}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
if (!in_array('actusers', $qb->getAllAliases(), true)) {
$qb->leftJoin('activity.users', 'actusers');
}
$qb
->addSelect('actusers.id AS activity_users_aggregator')
->addGroupBy('activity_users_aggregator');
}
public function applyOn(): string
{
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
{
// nothing to add on the form
}
public function getLabels($key, array $values, $data)
{
return function ($value) {
if ('_header' === $value) {
return 'Activity users';
}
if (null === $value) {
return '';
}
$u = $this->userRepository->find($value);
return $this->userRender->renderString($u, []);
};
}
public function getQueryKeys($data)
{
return ['activity_users_aggregator'];
}
public function getTitle()
{
return 'Aggregate by activity users';
}
}

View File

@@ -0,0 +1,87 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Aggregator;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Repository\UserJobRepositoryInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use function in_array;
class ActivityUsersJobAggregator implements \Chill\MainBundle\Export\AggregatorInterface
{
private TranslatableStringHelperInterface $translatableStringHelper;
private UserJobRepositoryInterface $userJobRepository;
public function __construct(UserJobRepositoryInterface $userJobRepository, TranslatableStringHelperInterface $translatableStringHelper)
{
$this->userJobRepository = $userJobRepository;
$this->translatableStringHelper = $translatableStringHelper;
}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
if (!in_array('actusers', $qb->getAllAliases(), true)) {
$qb->leftJoin('activity.users', 'actusers');
}
$qb
->addSelect('IDENTITY(actusers.userJob) AS activity_users_job_aggregator')
->addGroupBy('activity_users_job_aggregator');
}
public function applyOn()
{
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
{
// nothing to add in the form
}
public function getLabels($key, array $values, $data)
{
return function ($value): string {
if ('_header' === $value) {
return 'Users \'s job';
}
if (null === $value) {
return '';
}
$j = $this->userJobRepository->find($value);
return $this->translatableStringHelper->localize(
$j->getLabel()
);
};
}
public function getQueryKeys($data): array
{
return ['activity_users_job_aggregator'];
}
public function getTitle()
{
return 'Aggregate by users job';
}
}

View File

@@ -0,0 +1,87 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Aggregator;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Repository\ScopeRepositoryInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use function in_array;
class ActivityUsersScopeAggregator implements \Chill\MainBundle\Export\AggregatorInterface
{
private ScopeRepositoryInterface $scopeRepository;
private TranslatableStringHelperInterface $translatableStringHelper;
public function __construct(ScopeRepositoryInterface $scopeRepository, TranslatableStringHelperInterface $translatableStringHelper)
{
$this->scopeRepository = $scopeRepository;
$this->translatableStringHelper = $translatableStringHelper;
}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
if (!in_array('actusers', $qb->getAllAliases(), true)) {
$qb->leftJoin('activity.users', 'actusers');
}
$qb
->addSelect('IDENTITY(actusers.mainScope) AS activity_users_main_scope_aggregator')
->addGroupBy('activity_users_main_scope_aggregator');
}
public function applyOn()
{
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
{
// nothing to add in the form
}
public function getLabels($key, array $values, $data)
{
return function ($value): string {
if ('_header' === $value) {
return 'Users \'s scope';
}
if (null === $value) {
return '';
}
$s = $this->scopeRepository->find($value);
return $this->translatableStringHelper->localize(
$s->getName()
);
};
}
public function getQueryKeys($data): array
{
return ['activity_users_main_scope_aggregator'];
}
public function getTitle()
{
return 'Aggregate by users scope';
}
}

View File

@@ -14,7 +14,6 @@ namespace Chill\ActivityBundle\Export\Aggregator\PersonAggregators;
use Chill\ActivityBundle\Export\Declarations;
use Chill\ActivityBundle\Repository\ActivityReasonCategoryRepository;
use Chill\ActivityBundle\Repository\ActivityReasonRepository;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
@@ -24,11 +23,10 @@ use Doctrine\ORM\QueryBuilder;
use RuntimeException;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use function array_key_exists;
use function count;
use function in_array;
class ActivityReasonAggregator implements AggregatorInterface, ExportElementValidatedInterface
{
@@ -48,19 +46,19 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali
$this->translatableStringHelper = $translatableStringHelper;
}
public function addRole()
public function addRole(): ?string
{
return new Role(ActivityStatsVoter::STATS);
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
// add select element
if ('reasons' === $data['level']) {
$elem = 'reasons.id';
$elem = 'actreasons.id';
$alias = 'activity_reasons_id';
} elseif ('categories' === $data['level']) {
$elem = 'category.id';
$elem = 'actreasoncat.id';
$alias = 'activity_categories_id';
} else {
throw new RuntimeException('The data provided are not recognized.');
@@ -69,29 +67,15 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali
$qb->addSelect($elem . ' as ' . $alias);
// make a jointure only if needed
$join = $qb->getDQLPart('join');
if (
(
array_key_exists('activity', $join)
&& !$this->checkJoinAlreadyDefined($join['activity'], 'reasons')
)
|| (!array_key_exists('activity', $join))
) {
$qb->add(
'join',
[
'activity' => new Join(Join::INNER_JOIN, 'activity.reasons', 'reasons'),
],
true
);
if (!in_array('actreasons', $qb->getAllAliases(), true)) {
$qb->innerJoin('activity.reasons', 'actreasons');
}
// join category if necessary
if ('activity_categories_id' === $alias) {
// add join only if needed
if (!$this->checkJoinAlreadyDefined($qb->getDQLPart('join')['activity'], 'category')) {
$qb->join('reasons.category', 'category');
if (!in_array('actreasoncat', $qb->getAllAliases(), true)) {
$qb->join('actreasons.category', 'actreasoncat');
}
}
@@ -195,23 +179,4 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali
->addViolation();
}
}
/**
* Check if a join between Activity and another alias.
*
* @param Join[] $joins
* @param string $alias the alias to search for
*
* @return bool
*/
private function checkJoinAlreadyDefined(array $joins, $alias)
{
foreach ($joins as $join) {
if ($join->getAlias() === $alias) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,83 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Aggregator;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\AggregatorInterface;
use Doctrine\ORM\QueryBuilder;
use LogicException;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class SentReceivedAggregator implements AggregatorInterface
{
private TranslatorInterface $translator;
public function __construct(TranslatorInterface $translator)
{
$this->translator = $translator;
}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data): void
{
$qb->addSelect('activity.sentReceived AS activity_sentreceived_aggregator')
->addGroupBy('activity_sentreceived_aggregator');
}
public function applyOn(): string
{
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder): void
{
// No form needed
}
public function getLabels($key, array $values, $data): callable
{
return function (?string $value): string {
if ('_header' === $value) {
return 'export.aggregator.activity.by_sent_received.Sent or received';
}
switch ($value) {
case null:
return '';
case 'sent':
return $this->translator->trans('export.aggregator.activity.by_sent_received.is sent');
case 'received':
return $this->translator->trans('export.aggregator.activity.by_sent_received.is received');
default:
throw new LogicException(sprintf('The value %s is not valid', $value));
}
};
}
public function getQueryKeys($data): array
{
return ['activity_sentreceived_aggregator'];
}
public function getTitle(): string
{
return 'export.aggregator.activity.by_sent_received.Group activity by sentreceived';
}
}

View File

@@ -17,11 +17,14 @@ use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Export\ExportInterface;
use Chill\MainBundle\Export\FormatterInterface;
use Chill\MainBundle\Export\GroupedExportInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
use Chill\PersonBundle\Entity\Person\PersonCenterHistory;
use Chill\PersonBundle\Export\Declarations as PersonDeclarations;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query;
use LogicException;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
class AvgActivityDuration implements ExportInterface, GroupedExportInterface
{
@@ -35,7 +38,6 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface
public function buildForm(FormBuilderInterface $builder)
{
// TODO: Implement buildForm() method.
}
public function getAllowedFormattersTypes(): array
@@ -67,9 +69,9 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface
return ['export_avg_activity_duration'];
}
public function getResult($qb, $data)
public function getResult($query, $data)
{
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
public function getTitle(): string
@@ -84,17 +86,34 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{
$qb = $this->repository->createQueryBuilder('activity')
->join('activity.accompanyingPeriod', 'acp');
$centers = array_map(static function ($el) {
return $el['center'];
}, $acl);
$qb->select('AVG(activity.durationTime) as export_avg_activity_duration');
$qb = $this->repository->createQueryBuilder('activity');
$qb
->join('activity.accompanyingPeriod', 'acp')
->select('AVG(activity.durationTime) as export_avg_activity_duration')
->andWhere($qb->expr()->isNotNull('activity.durationTime'));
$qb
->andWhere(
$qb->expr()->exists(
'SELECT 1 FROM ' . AccompanyingPeriodParticipation::class . ' acl_count_part
JOIN ' . PersonCenterHistory::class . ' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person)
WHERE acl_count_part.accompanyingPeriod = acp.id AND acl_count_person_history.center IN (:authorized_centers)
'
)
)
->setParameter('authorized_centers', $centers);
return $qb;
}
public function requiredRole(): Role
public function requiredRole(): string
{
return new Role(ActivityStatsVoter::STATS);
return ActivityStatsVoter::STATS;
}
public function supportsModifiers(): array
@@ -102,7 +121,7 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface
return [
Declarations::ACTIVITY,
Declarations::ACTIVITY_ACP,
//PersonDeclarations::ACP_TYPE,
PersonDeclarations::ACP_TYPE,
];
}
}

View File

@@ -17,11 +17,14 @@ use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Export\ExportInterface;
use Chill\MainBundle\Export\FormatterInterface;
use Chill\MainBundle\Export\GroupedExportInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
use Chill\PersonBundle\Entity\Person\PersonCenterHistory;
use Chill\PersonBundle\Export\Declarations as PersonDeclarations;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query;
use LogicException;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterface
{
@@ -67,9 +70,9 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac
return ['export_avg_activity_visit_duration'];
}
public function getResult($qb, $data)
public function getResult($query, $data)
{
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
public function getTitle(): string
@@ -84,17 +87,34 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{
$qb = $this->repository->createQueryBuilder('activity')
->join('activity.accompanyingPeriod', 'acp');
$centers = array_map(static function ($el) {
return $el['center'];
}, $acl);
$qb->select('AVG(activity.travelTime) as export_avg_activity_visit_duration');
$qb = $this->repository->createQueryBuilder('activity');
$qb
->join('activity.accompanyingPeriod', 'acp')
->select('AVG(activity.travelTime) as export_avg_activity_visit_duration')
->andWhere($qb->expr()->isNotNull('activity.travelTime'));
$qb
->andWhere(
$qb->expr()->exists(
'SELECT 1 FROM ' . AccompanyingPeriodParticipation::class . ' acl_count_part
JOIN ' . PersonCenterHistory::class . ' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person)
WHERE acl_count_part.accompanyingPeriod = acp.id AND acl_count_person_history.center IN (:authorized_centers)
'
)
)
->setParameter('authorized_centers', $centers);
return $qb;
}
public function requiredRole(): Role
public function requiredRole(): string
{
return new Role(ActivityStatsVoter::STATS);
return ActivityStatsVoter::STATS;
}
public function supportsModifiers(): array
@@ -102,7 +122,7 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac
return [
Declarations::ACTIVITY,
Declarations::ACTIVITY_ACP,
//PersonDeclarations::ACP_TYPE,
PersonDeclarations::ACP_TYPE,
];
}
}

View File

@@ -17,13 +17,14 @@ use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Export\ExportInterface;
use Chill\MainBundle\Export\FormatterInterface;
use Chill\MainBundle\Export\GroupedExportInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
use Chill\PersonBundle\Entity\Person\PersonCenterHistory;
use Chill\PersonBundle\Export\Declarations as PersonDeclarations;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query;
use LogicException;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
class CountActivity implements ExportInterface, GroupedExportInterface
{
@@ -68,9 +69,9 @@ class CountActivity implements ExportInterface, GroupedExportInterface
return ['export_count_activity'];
}
public function getResult($qb, $data)
public function getResult($query, $data)
{
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
public function getTitle(): string
@@ -85,17 +86,33 @@ class CountActivity implements ExportInterface, GroupedExportInterface
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{
$qb = $this->repository->createQueryBuilder('activity')
$centers = array_map(static function ($el) {
return $el['center'];
}, $acl);
$qb = $this->repository
->createQueryBuilder('activity')
->join('activity.accompanyingPeriod', 'acp');
$qb->select('COUNT(activity.id) as export_count_activity');
$qb
->andWhere(
$qb->expr()->exists(
'SELECT 1 FROM ' . AccompanyingPeriodParticipation::class . ' acl_count_part
JOIN ' . PersonCenterHistory::class . ' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person)
WHERE acl_count_part.accompanyingPeriod = acp.id AND acl_count_person_history.center IN (:authorized_centers)
'
)
)
->setParameter('authorized_centers', $centers);
$qb->select('COUNT(DISTINCT activity.id) as export_count_activity');
return $qb;
}
public function requiredRole(): Role
public function requiredRole(): string
{
return new Role(ActivityStatsVoter::STATS);
return ActivityStatsVoter::STATS;
}
public function supportsModifiers(): array
@@ -103,7 +120,7 @@ class CountActivity implements ExportInterface, GroupedExportInterface
return [
Declarations::ACTIVITY,
Declarations::ACTIVITY_ACP,
//PersonDeclarations::ACP_TYPE,
PersonDeclarations::ACP_TYPE,
];
}
}

View File

@@ -0,0 +1,165 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Export\LinkedToACP;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Export\ListActivityHelper;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Export\GroupedExportInterface;
use Chill\MainBundle\Export\Helper\TranslatableStringExportLabelHelper;
use Chill\MainBundle\Export\ListInterface;
use Chill\PersonBundle\Entity\Person\PersonCenterHistory;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\FormBuilderInterface;
class ListActivity implements ListInterface, GroupedExportInterface
{
private EntityManagerInterface $entityManager;
private ListActivityHelper $helper;
private TranslatableStringExportLabelHelper $translatableStringExportLabelHelper;
public function __construct(
ListActivityHelper $helper,
EntityManagerInterface $entityManager,
TranslatableStringExportLabelHelper $translatableStringExportLabelHelper
) {
$this->helper = $helper;
$this->entityManager = $entityManager;
$this->translatableStringExportLabelHelper = $translatableStringExportLabelHelper;
}
public function buildForm(FormBuilderInterface $builder)
{
$this->helper->buildForm($builder);
}
public function getAllowedFormattersTypes()
{
return $this->helper->getAllowedFormattersTypes();
}
public function getDescription()
{
return ListActivityHelper::MSG_KEY . 'List activities linked to an accompanying course';
}
public function getGroup(): string
{
return 'Exports of activities linked to an accompanying period';
}
public function getLabels($key, array $values, $data)
{
switch ($key) {
case 'acpId':
return static function ($value) {
if ('_header' === $value) {
return ListActivityHelper::MSG_KEY . 'accompanying course id';
}
return $value ?? '';
};
case 'scopesNames':
return $this->translatableStringExportLabelHelper->getLabelMulti($key, $values, ListActivityHelper::MSG_KEY . 'course circles');
default:
return $this->helper->getLabels($key, $values, $data);
}
}
public function getQueryKeys($data)
{
return
array_merge(
$this->helper->getQueryKeys($data),
[
'acpId',
'scopesNames',
]
);
}
public function getResult($query, $data)
{
return $this->helper->getResult($query, $data);
}
public function getTitle()
{
return ListActivityHelper::MSG_KEY . 'List activity linked to a course';
}
public function getType()
{
return $this->helper->getType();
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{
$centers = array_map(static function ($el) {
return $el['center'];
}, $acl);
$qb = $this->entityManager->createQueryBuilder();
$qb
->distinct()
->from(Activity::class, 'activity')
->join('activity.accompanyingPeriod', 'acp')
->leftJoin('acp.participations', 'acppart')
->leftJoin('acppart.person', 'person')
->andWhere('acppart.startDate != acppart.endDate OR acppart.endDate IS NULL')
->andWhere(
$qb->expr()->exists(
'SELECT 1
FROM ' . PersonCenterHistory::class . ' acl_count_person_history
WHERE acl_count_person_history.person = person
AND acl_count_person_history.center IN (:authorized_centers)
'
)
)
// some grouping are necessary
->addGroupBy('acp.id')
->addOrderBy('activity.date')
->addOrderBy('activity.id')
->setParameter('authorized_centers', $centers);
$this->helper->addSelect($qb);
// add select for this step
$qb
->addSelect('acp.id AS acpId')
->addSelect('(SELECT AGGREGATE(acpScope.name) FROM ' . Scope::class . ' acpScope WHERE acpScope MEMBER OF acp.scopes) AS scopesNames')
->addGroupBy('scopesNames');
return $qb;
}
public function requiredRole(): string
{
return ActivityStatsVoter::LISTS;
}
public function supportsModifiers()
{
return array_merge(
$this->helper->supportsModifiers(),
[
\Chill\PersonBundle\Export\Declarations::ACP_TYPE,
]
);
}
}

View File

@@ -17,11 +17,14 @@ use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Export\ExportInterface;
use Chill\MainBundle\Export\FormatterInterface;
use Chill\MainBundle\Export\GroupedExportInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
use Chill\PersonBundle\Entity\Person\PersonCenterHistory;
use Chill\PersonBundle\Export\Declarations as PersonDeclarations;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query;
use LogicException;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
class SumActivityDuration implements ExportInterface, GroupedExportInterface
{
@@ -67,9 +70,9 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface
return ['export_sum_activity_duration'];
}
public function getResult($qb, $data)
public function getResult($query, $data)
{
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
public function getTitle(): string
@@ -84,17 +87,34 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{
$qb = $this->repository->createQueryBuilder('activity')
$centers = array_map(static function ($el) {
return $el['center'];
}, $acl);
$qb = $this->repository
->createQueryBuilder('activity')
->join('activity.accompanyingPeriod', 'acp');
$qb->select('SUM(activity.durationTime) as export_sum_activity_duration');
$qb->select('SUM(activity.durationTime) as export_sum_activity_duration')
->andWhere($qb->expr()->isNotNull('activity.durationTime'));
$qb
->andWhere(
$qb->expr()->exists(
'SELECT 1 FROM ' . AccompanyingPeriodParticipation::class . ' acl_count_part
JOIN ' . PersonCenterHistory::class . ' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person)
WHERE acl_count_part.accompanyingPeriod = acp.id AND acl_count_person_history.center IN (:authorized_centers)
'
)
)
->setParameter('authorized_centers', $centers);
return $qb;
}
public function requiredRole(): Role
public function requiredRole(): string
{
return new Role(ActivityStatsVoter::STATS);
return ActivityStatsVoter::STATS;
}
public function supportsModifiers(): array
@@ -102,7 +122,7 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface
return [
Declarations::ACTIVITY,
Declarations::ACTIVITY_ACP,
//PersonDeclarations::ACP_TYPE,
PersonDeclarations::ACP_TYPE,
];
}
}

View File

@@ -17,11 +17,14 @@ use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Export\ExportInterface;
use Chill\MainBundle\Export\FormatterInterface;
use Chill\MainBundle\Export\GroupedExportInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
use Chill\PersonBundle\Entity\Person\PersonCenterHistory;
use Chill\PersonBundle\Export\Declarations as PersonDeclarations;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query;
use LogicException;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
class SumActivityVisitDuration implements ExportInterface, GroupedExportInterface
{
@@ -67,9 +70,9 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac
return ['export_sum_activity_visit_duration'];
}
public function getResult($qb, $data)
public function getResult($query, $data)
{
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
public function getTitle(): string
@@ -84,17 +87,34 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{
$qb = $this->repository->createQueryBuilder('activity')
$centers = array_map(static function ($el) {
return $el['center'];
}, $acl);
$qb = $this->repository
->createQueryBuilder('activity')
->join('activity.accompanyingPeriod', 'acp');
$qb->select('SUM(activity.travelTime) as export_sum_activity_visit_duration');
$qb->select('SUM(activity.travelTime) as export_sum_activity_visit_duration')
->andWhere($qb->expr()->isNotNull('activity.travelTime'));
$qb
->andWhere(
$qb->expr()->exists(
'SELECT 1 FROM ' . AccompanyingPeriodParticipation::class . ' acl_count_part
JOIN ' . PersonCenterHistory::class . ' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person)
WHERE acl_count_part.accompanyingPeriod = acp.id AND acl_count_person_history.center IN (:authorized_centers)
'
)
)
->setParameter('authorized_centers', $centers);
return $qb;
}
public function requiredRole(): Role
public function requiredRole(): string
{
return new Role(ActivityStatsVoter::STATS);
return ActivityStatsVoter::STATS;
}
public function supportsModifiers(): array
@@ -102,7 +122,7 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac
return [
Declarations::ACTIVITY,
Declarations::ACTIVITY_ACP,
//PersonDeclarations::ACP_TYPE,
PersonDeclarations::ACP_TYPE,
];
}
}

View File

@@ -21,7 +21,6 @@ use Chill\PersonBundle\Export\Declarations as PersonDeclarations;
use Doctrine\ORM\Query;
use LogicException;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
class CountActivity implements ExportInterface, GroupedExportInterface
{
@@ -66,9 +65,9 @@ class CountActivity implements ExportInterface, GroupedExportInterface
return ['export_count_activity'];
}
public function getResult($qb, $data)
public function getResult($query, $data)
{
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
public function getTitle()
@@ -85,21 +84,32 @@ class CountActivity implements ExportInterface, GroupedExportInterface
{
$centers = array_map(static fn ($el) => $el['center'], $acl);
$qb = $this->activityRepository->createQueryBuilder('activity')
->join('activity.person', 'person');
$qb = $this->activityRepository
->createQueryBuilder('activity')
->join('activity.person', 'person')
->join('person.centerHistory', 'centerHistory');
$qb->select('COUNT(activity.id) as export_count_activity');
$qb
->where($qb->expr()->in('person.center', ':centers'))
->where(
$qb->expr()->andX(
$qb->expr()->lte('centerHistory.startDate', 'activity.date'),
$qb->expr()->orX(
$qb->expr()->isNull('centerHistory.endDate'),
$qb->expr()->gt('centerHistory.endDate', 'activity.date')
)
)
)
->andWhere($qb->expr()->in('centerHistory.center', ':centers'))
->setParameter('centers', $centers);
return $qb;
}
public function requiredRole()
public function requiredRole(): string
{
return new Role(ActivityStatsVoter::STATS);
return ActivityStatsVoter::STATS;
}
public function supportsModifiers()
@@ -107,7 +117,7 @@ class CountActivity implements ExportInterface, GroupedExportInterface
return [
Declarations::ACTIVITY,
Declarations::ACTIVITY_PERSON,
//PersonDeclarations::PERSON_TYPE,
PersonDeclarations::PERSON_TYPE,
];
}
}

View File

@@ -26,7 +26,6 @@ use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Validator\Constraints\Callback;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
@@ -125,7 +124,7 @@ class ListActivity implements ListInterface, GroupedExportInterface
return 'attendee';
}
return $value ? 1 : 0;
return $value ? 'X' : '';
};
case 'list_reasons':
@@ -211,10 +210,20 @@ class ListActivity implements ListInterface, GroupedExportInterface
$qb
->from('ChillActivityBundle:Activity', 'activity')
->join('activity.person', 'person')
->join('person.center', 'center')
->andWhere('center IN (:authorized_centers)')
->setParameter('authorized_centers', $centers);
->join('activity.person', 'actperson')
->join('actperson.centerHistory', 'centerHistory');
$qb->where(
$qb->expr()->andX(
$qb->expr()->lte('centerHistory.startDate', 'activity.date'),
$qb->expr()->orX(
$qb->expr()->isNull('centerHistory.endDate'),
$qb->expr()->gt('centerHistory.endDate', 'activity.date')
)
)
)
->andWhere($qb->expr()->in('centerHistory.center', ':centers'))
->setParameter('centers', $centers);
foreach ($this->fields as $f) {
if (in_array($f, $data['fields'], true)) {
@@ -225,23 +234,23 @@ class ListActivity implements ListInterface, GroupedExportInterface
break;
case 'person_firstname':
$qb->addSelect('person.firstName AS person_firstname');
$qb->addSelect('actperson.firstName AS person_firstname');
break;
case 'person_lastname':
$qb->addSelect('person.lastName AS person_lastname');
$qb->addSelect('actperson.lastName AS person_lastname');
break;
case 'person_id':
$qb->addSelect('person.id AS person_id');
$qb->addSelect('actperson.id AS person_id');
break;
case 'user_username':
$qb->join('activity.user', 'user');
$qb->addSelect('user.username AS user_username');
$qb->join('activity.user', 'actuser');
$qb->addSelect('actuser.username AS user_username');
break;
@@ -252,7 +261,7 @@ class ListActivity implements ListInterface, GroupedExportInterface
break;
case 'type_name':
$qb->join('activity.type', 'type');
$qb->join('activity.activityType', 'type');
$qb->addSelect('type.name AS type_name');
break;
@@ -264,6 +273,11 @@ class ListActivity implements ListInterface, GroupedExportInterface
break;
case 'attendee':
$qb->addSelect('IDENTITY(activity.attendee) AS attendee');
break;
default:
$qb->addSelect(sprintf('activity.%s as %s', $f, $f));
@@ -275,9 +289,9 @@ class ListActivity implements ListInterface, GroupedExportInterface
return $qb;
}
public function requiredRole()
public function requiredRole(): string
{
return new Role(ActivityStatsVoter::LISTS);
return ActivityStatsVoter::LISTS;
}
public function supportsModifiers()

View File

@@ -22,7 +22,6 @@ use Chill\PersonBundle\Export\Declarations as PersonDeclarations;
use Doctrine\ORM\Query;
use LogicException;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
/**
* This export allow to compute stats on activity duration.
@@ -65,6 +64,8 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface
if (self::SUM === $this->action) {
return 'Sum activities linked to a person duration by various parameters.';
}
throw new LogicException('this action is not supported: ' . $this->action);
}
public function getGroup(): string
@@ -88,9 +89,9 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface
return ['export_stat_activity'];
}
public function getResult($qb, $data)
public function getResult($query, $data)
{
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
public function getTitle()
@@ -98,6 +99,8 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface
if (self::SUM === $this->action) {
return 'Sum activity linked to a person duration';
}
throw new LogicException('This action is not supported: ' . $this->action);
}
public function getType(): string
@@ -120,16 +123,29 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface
$select = 'SUM(activity.durationTime) AS export_stat_activity';
}
return $qb->select($select)
$qb->select($select)
->join('activity.person', 'person')
->join('person.center', 'center')
->where($qb->expr()->in('center', ':centers'))
->setParameter(':centers', $centers);
->join('person.centerHistory', 'centerHistory');
$qb
->where(
$qb->expr()->andX(
$qb->expr()->lte('centerHistory.startDate', 'activity.date'),
$qb->expr()->orX(
$qb->expr()->isNull('centerHistory.endDate'),
$qb->expr()->gt('centerHistory.endDate', 'activity.date')
)
)
)
->andWhere($qb->expr()->in('centerHistory.center', ':centers'))
->setParameter('centers', $centers);
return $qb;
}
public function requiredRole()
public function requiredRole(): string
{
return new Role(ActivityStatsVoter::STATS);
return ActivityStatsVoter::STATS;
}
public function supportsModifiers()

View File

@@ -0,0 +1,269 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Export;
use Chill\ActivityBundle\Export\Declarations;
use Chill\ActivityBundle\Repository\ActivityPresenceRepositoryInterface;
use Chill\ActivityBundle\Repository\ActivityTypeRepositoryInterface;
use Chill\MainBundle\Export\FormatterInterface;
use Chill\MainBundle\Export\Helper\DateTimeHelper;
use Chill\MainBundle\Export\Helper\TranslatableStringExportLabelHelper;
use Chill\MainBundle\Export\Helper\UserHelper;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Chill\PersonBundle\Export\Helper\LabelPersonHelper;
use Chill\ThirdPartyBundle\Export\Helper\LabelThirdPartyHelper;
use Doctrine\ORM\AbstractQuery;
use Doctrine\ORM\QueryBuilder;
use LogicException;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use const SORT_NUMERIC;
class ListActivityHelper
{
public const MSG_KEY = 'export.list.activity.';
private ActivityPresenceRepositoryInterface $activityPresenceRepository;
private ActivityTypeRepositoryInterface $activityTypeRepository;
private DateTimeHelper $dateTimeHelper;
private LabelPersonHelper $labelPersonHelper;
private LabelThirdPartyHelper $labelThirdPartyHelper;
private TranslatableStringHelperInterface $translatableStringHelper;
private TranslatableStringExportLabelHelper $translatableStringLabelHelper;
private TranslatorInterface $translator;
private UserHelper $userHelper;
public function __construct(
ActivityPresenceRepositoryInterface $activityPresenceRepository,
ActivityTypeRepositoryInterface $activityTypeRepository,
DateTimeHelper $dateTimeHelper,
LabelPersonHelper $labelPersonHelper,
LabelThirdPartyHelper $labelThirdPartyHelper,
TranslatorInterface $translator,
TranslatableStringHelperInterface $translatableStringHelper,
TranslatableStringExportLabelHelper $translatableStringLabelHelper,
UserHelper $userHelper
) {
$this->activityPresenceRepository = $activityPresenceRepository;
$this->activityTypeRepository = $activityTypeRepository;
$this->dateTimeHelper = $dateTimeHelper;
$this->labelPersonHelper = $labelPersonHelper;
$this->labelThirdPartyHelper = $labelThirdPartyHelper;
$this->translator = $translator;
$this->translatableStringHelper = $translatableStringHelper;
$this->translatableStringLabelHelper = $translatableStringLabelHelper;
$this->userHelper = $userHelper;
}
public function addSelect(QueryBuilder $qb): void
{
$qb
->addSelect('activity.id AS id')
->addSelect('activity.date')
->addSelect('IDENTITY(activity.activityType) AS typeName')
->leftJoin('activity.reasons', 'reasons')
->addSelect('AGGREGATE(reasons.name) AS listReasons')
->leftJoin('activity.persons', 'actPerson')
->addSelect('AGGREGATE(actPerson.id) AS personsIds')
->addSelect('AGGREGATE(actPerson.id) AS personsNames')
->leftJoin('activity.users', 'users_u')
->addSelect('AGGREGATE(users_u.id) AS usersIds')
->addSelect('AGGREGATE(users_u.id) AS usersNames')
->leftJoin('activity.thirdParties', 'thirdparty')
->addSelect('AGGREGATE(thirdparty.id) AS thirdPartiesIds')
->addSelect('AGGREGATE(thirdparty.id) AS thirdPartiesNames')
->addSelect('IDENTITY(activity.attendee) AS attendeeName')
->addSelect('activity.durationTime')
->addSelect('activity.travelTime')
->addSelect('activity.emergency')
->leftJoin('activity.location', 'location')
->addSelect('location.name AS locationName')
->addSelect('activity.sentReceived')
->addSelect('IDENTITY(activity.createdBy) AS createdBy')
->addSelect('activity.createdAt')
->addSelect('IDENTITY(activity.updatedBy) AS updatedBy')
->addSelect('activity.updatedAt')
->addGroupBy('activity.id')
->addGroupBy('location.id');
}
public function buildForm(FormBuilderInterface $builder)
{
}
public function getAllowedFormattersTypes()
{
return [FormatterInterface::TYPE_LIST];
}
public function getLabels($key, array $values, $data)
{
switch ($key) {
case 'createdAt':
case 'updatedAt':
return $this->dateTimeHelper->getLabel($key);
case 'createdBy':
case 'updatedBy':
return $this->userHelper->getLabel($key, $values, $key);
case 'date':
return $this->dateTimeHelper->getLabel(self::MSG_KEY . $key);
case 'attendeeName':
return function ($value) {
if ('_header' === $value) {
return 'Attendee';
}
if (null === $value || null === $presence = $this->activityPresenceRepository->find($value)) {
return '';
}
return $this->translatableStringHelper->localize($presence->getName());
};
case 'listReasons':
return $this->translatableStringLabelHelper->getLabelMulti($key, $values, 'Activity Reasons');
case 'typeName':
return function ($value) {
if ('_header' === $value) {
return 'Activity type';
}
if (null === $value || null === $type = $this->activityTypeRepository->find($value)) {
return '';
}
return $this->translatableStringHelper->localize($type->getName());
};
case 'usersNames':
return $this->userHelper->getLabelMulti($key, $values, self::MSG_KEY . 'users name');
case 'usersIds':
case 'thirdPartiesIds':
case 'personsIds':
return static function ($value) use ($key) {
if ('_header' === $value) {
switch ($key) {
case 'usersIds':
return self::MSG_KEY . 'users ids';
case 'thirdPartiesIds':
return self::MSG_KEY . 'third parties ids';
case 'personsIds':
return self::MSG_KEY . 'persons ids';
default:
throw new LogicException('key not supported');
}
}
$decoded = json_decode($value);
return implode(
'|',
array_unique(
array_filter($decoded, static fn (?int $id) => null !== $id),
SORT_NUMERIC
)
);
};
case 'personsNames':
return $this->labelPersonHelper->getLabelMulti($key, $values, self::MSG_KEY . 'persons name');
case 'thirdPartiesNames':
return $this->labelThirdPartyHelper->getLabelMulti($key, $values, self::MSG_KEY . 'thirds parties');
case 'sentReceived':
return function ($value) {
if ('_header' === $value) {
return self::MSG_KEY . 'sent received';
}
if (null === $value) {
return '';
}
return $this->translator->trans($value);
};
default:
return function ($value) use ($key) {
if ('_header' === $value) {
return self::MSG_KEY . $key;
}
if (null === $value) {
return '';
}
return $this->translator->trans($value);
};
}
}
public function getQueryKeys($data)
{
return [
'id',
'date',
'typeName',
'listReasons',
'attendeeName',
'durationTime',
'travelTime',
'emergency',
'locationName',
'sentReceived',
'personsIds',
'personsNames',
'usersIds',
'usersNames',
'thirdPartiesIds',
'thirdPartiesNames',
'createdBy',
'createdAt',
'updatedBy',
'updatedAt',
];
}
public function getResult($query, $data)
{
return $query->getQuery()->getResult(AbstractQuery::HYDRATE_SCALAR);
}
public function getType(): string
{
return Declarations::ACTIVITY;
}
public function supportsModifiers()
{
return [
Declarations::ACTIVITY,
];
}
}

View File

@@ -0,0 +1,95 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Entity\ActivityType;
use Chill\ActivityBundle\Repository\ActivityTypeRepositoryInterface;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use function in_array;
class ActivityTypeFilter implements FilterInterface
{
private ActivityTypeRepositoryInterface $activityTypeRepository;
private TranslatableStringHelperInterface $translatableStringHelper;
public function __construct(
ActivityTypeRepositoryInterface $activityTypeRepository,
TranslatableStringHelperInterface $translatableStringHelper
) {
$this->activityTypeRepository = $activityTypeRepository;
$this->translatableStringHelper = $translatableStringHelper;
}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
if (!in_array('activity', $qb->getAllAliases(), true)) {
$qb->join(Activity::class, 'activity', Expr\Join::WITH, 'activity.accompanyingPeriod = acp');
}
$clause = $qb->expr()->in('activity.activityType', ':selected_activity_types');
$qb->andWhere($clause);
$qb->setParameter('selected_activity_types', $data['types']);
}
public function applyOn()
{
return Declarations::ACP_TYPE;
}
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_activitytypes', EntityType::class, [
'class' => ActivityType::class,
'choices' => $this->activityTypeRepository->findAllActive(),
'choice_label' => function (ActivityType $aty) {
return
($aty->hasCategory() ? $this->translatableStringHelper->localize($aty->getCategory()->getName()) . ' > ' : '')
.
$this->translatableStringHelper->localize($aty->getName());
},
'multiple' => true,
'expanded' => true,
]);
}
public function describeAction($data, $format = 'string'): array
{
$types = [];
foreach ($data['accepted_activitytypes'] as $aty) {
$types[] = $this->translatableStringHelper->localize($aty->getName());
}
return ['Filtered by activity types: only %activitytypes%', [
'%activitytypes%' => implode(', ', $types),
]];
}
public function getTitle(): string
{
return 'Filter accompanying course by activity type';
}
}

View File

@@ -12,16 +12,13 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\PickUserDynamicType;
use Chill\MainBundle\Templating\Entity\UserRender;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use function in_array;
class ByUserFilter implements FilterInterface
class ByCreatorFilter implements FilterInterface
{
private UserRender $userRender;
@@ -30,29 +27,18 @@ class ByUserFilter implements FilterInterface
$this->userRender = $userRender;
}
public function addRole()
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
if (!in_array('user', $qb->getAllAliases(), true)) {
$qb->join('activity.users', 'user');
}
$clause = $qb->expr()->in('user.id', ':users');
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('users', $data['accepted_users']);
$qb
->andWhere(
$qb->expr()->in('activity.createdBy', ':users')
)
->setParameter('users', $data['accepted_users']);
}
public function applyOn(): string
@@ -62,13 +48,8 @@ class ByUserFilter implements FilterInterface
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_users', EntityType::class, [
'class' => User::class,
'choice_label' => function (User $u) {
return $this->userRender->renderString($u, []);
},
$builder->add('accepted_users', PickUserDynamicType::class, [
'multiple' => true,
'expanded' => true,
]);
}
@@ -80,13 +61,13 @@ class ByUserFilter implements FilterInterface
$users[] = $this->userRender->renderString($u, []);
}
return ['Filtered activity by linked users: only %users%', [
'%users%' => implode(', ou ', $users),
return ['Filtered activity by creator: only %users%', [
'%users%' => implode(', ', $users),
]];
}
public function getTitle(): string
{
return 'Filter activity by linked users';
return 'Filter activity by creator';
}
}

View File

@@ -14,10 +14,9 @@ namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\FilterInterface;
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
use Chill\PersonBundle\Form\Type\PickSocialActionType;
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use function in_array;
@@ -30,29 +29,24 @@ class BySocialActionFilter implements FilterInterface
$this->actionRender = $actionRender;
}
public function addRole()
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
if (!in_array('socialaction', $qb->getAllAliases(), true)) {
$qb->join('activity.socialActions', 'socialaction');
if (!in_array('actsocialaction', $qb->getAllAliases(), true)) {
$qb->join('activity.socialActions', 'actsocialaction');
}
$clause = $qb->expr()->in('socialaction.id', ':socialactions');
$clause = $qb->expr()->in('actsocialaction.id', ':socialactions');
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('socialactions', $data['accepted_socialactions']);
$qb->andWhere($clause)
->setParameter(
'socialactions',
SocialAction::getDescendantsWithThisForActions($data['accepted_socialactions'])
);
}
public function applyOn(): string
@@ -62,13 +56,8 @@ class BySocialActionFilter implements FilterInterface
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_socialactions', EntityType::class, [
'class' => SocialAction::class,
'choice_label' => function (SocialAction $sa) {
return $this->actionRender->renderString($sa, []);
},
$builder->add('accepted_socialactions', PickSocialActionType::class, [
'multiple' => true,
'expanded' => true,
]);
}
@@ -76,12 +65,14 @@ class BySocialActionFilter implements FilterInterface
{
$actions = [];
foreach ($data['accepted_socialactions'] as $sa) {
$actions[] = $this->actionRender->renderString($sa, []);
foreach ($data['accepted_socialactions'] as $action) {
$actions[] = $this->actionRender->renderString($action, [
'show_and_children' => true,
]);
}
return ['Filtered activity by linked socialaction: only %actions%', [
'%actions%' => implode(', ou ', $actions),
'%actions%' => implode(', ', $actions),
]];
}

View File

@@ -14,10 +14,9 @@ namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\FilterInterface;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Chill\PersonBundle\Form\Type\PickSocialIssueType;
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use function in_array;
@@ -30,29 +29,24 @@ class BySocialIssueFilter implements FilterInterface
$this->issueRender = $issueRender;
}
public function addRole()
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
if (!in_array('socialissue', $qb->getAllAliases(), true)) {
$qb->join('activity.socialIssues', 'socialissue');
if (!in_array('actsocialissue', $qb->getAllAliases(), true)) {
$qb->join('activity.socialIssues', 'actsocialissue');
}
$clause = $qb->expr()->in('socialissue.id', ':socialissues');
$clause = $qb->expr()->in('actsocialissue.id', ':socialissues');
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('socialissues', $data['accepted_socialissues']);
$qb->andWhere($clause)
->setParameter(
'socialissues',
SocialIssue::getDescendantsWithThisForIssues($data['accepted_socialissues'])
);
}
public function applyOn(): string
@@ -62,13 +56,8 @@ class BySocialIssueFilter implements FilterInterface
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_socialissues', EntityType::class, [
'class' => SocialIssue::class,
'choice_label' => function (SocialIssue $si) {
return $this->issueRender->renderString($si, []);
},
$builder->add('accepted_socialissues', PickSocialIssueType::class, [
'multiple' => true,
'expanded' => true,
]);
}
@@ -76,12 +65,14 @@ class BySocialIssueFilter implements FilterInterface
{
$issues = [];
foreach ($data['accepted_socialissues'] as $si) {
$issues[] = $this->issueRender->renderString($si, []);
foreach ($data['accepted_socialissues'] as $issue) {
$issues[] = $this->issueRender->renderString($issue, [
'show_and_children' => true,
]);
}
return ['Filtered activity by linked socialissue: only %issues%', [
'%issues%' => implode(', ou ', $issues),
'%issues%' => implode(', ', $issues),
]];
}

View File

@@ -35,7 +35,7 @@ class EmergencyFilter implements FilterInterface
$this->translator = $translator;
}
public function addRole()
public function addRole(): ?string
{
return null;
}
@@ -74,15 +74,13 @@ class EmergencyFilter implements FilterInterface
public function describeAction($data, $format = 'string'): array
{
foreach (self::CHOICES as $k => $v) {
if ($v === $data['accepted_emergency']) {
$choice = $k;
}
}
return ['Filtered activity by emergency: only %emergency%', [
'%emergency%' => $this->translator->trans($choice),
]];
return [
'Filtered by emergency: only %emergency%', [
'%emergency%' => $this->translator->trans(
$data['accepted_emergency'] ? 'is emergency' : 'is not emergency'
),
],
];
}
public function getTitle(): string

View File

@@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Entity\Activity;
use Chill\MainBundle\Export\FilterInterface;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
class HasNoActivityFilter implements FilterInterface
{
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$qb
->andWhere('
NOT EXISTS (
SELECT 1 FROM ' . Activity::class . ' activity
WHERE activity.accompanyingPeriod = acp
)
');
}
public function applyOn(): string
{
return Declarations::ACP_TYPE;
}
public function buildForm(FormBuilderInterface $builder)
{
//no form needed
}
public function describeAction($data, $format = 'string'): array
{
return ['Filtered acp which has no activities', []];
}
public function getTitle(): string
{
return 'Filter acp which has no activity';
}
}

View File

@@ -12,12 +12,11 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Entity\LocationType;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\PickLocationTypeType;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use function in_array;
@@ -30,19 +29,19 @@ class LocationTypeFilter implements FilterInterface
$this->translatableStringHelper = $translatableStringHelper;
}
public function addRole()
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
if (!in_array('location', $qb->getAllAliases(), true)) {
$qb->join('activity.location', 'location');
if (!in_array('actloc', $qb->getAllAliases(), true)) {
$qb->join('activity.location', 'actloc');
}
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->in('location.locationType', ':locationtype');
$clause = $qb->expr()->in('actloc.locationType', ':locationtype');
if ($where instanceof Andx) {
$where->add($clause);
@@ -61,13 +60,9 @@ class LocationTypeFilter implements FilterInterface
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_locationtype', EntityType::class, [
'class' => LocationType::class,
'choice_label' => function (LocationType $type) {
return $this->translatableStringHelper->localize($type->getTitle());
},
$builder->add('accepted_locationtype', PickLocationTypeType::class, [
'multiple' => true,
'expanded' => true,
//'label' => false,
]);
}
@@ -82,7 +77,7 @@ class LocationTypeFilter implements FilterInterface
}
return ['Filtered activity by locationtype: only %types%', [
'%types%' => implode(', ou ', $types),
'%types%' => implode(', ', $types),
]];
}

View File

@@ -36,7 +36,7 @@ class SentReceivedFilter implements FilterInterface
$this->translator = $translator;
}
public function addRole()
public function addRole(): ?string
{
return null;
}

View File

@@ -12,12 +12,11 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\PickUserDynamicType;
use Chill\MainBundle\Templating\Entity\UserRender;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
class UserFilter implements FilterInterface
@@ -29,7 +28,7 @@ class UserFilter implements FilterInterface
$this->userRender = $userRender;
}
public function addRole()
public function addRole(): ?string
{
return null;
}
@@ -57,13 +56,8 @@ class UserFilter implements FilterInterface
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_users', EntityType::class, [
'class' => User::class,
'choice_label' => function (User $u) {
return $this->userRender->renderString($u, []);
},
$builder->add('accepted_users', PickUserDynamicType::class, [
'multiple' => true,
'expanded' => true,
'label' => 'Creators',
]);
}
@@ -77,7 +71,7 @@ class UserFilter implements FilterInterface
}
return ['Filtered activity by user: only %users%', [
'%users%' => implode(', ou ', $users),
'%users%' => implode(', ', $users),
]];
}

View File

@@ -30,20 +30,20 @@ class UserScopeFilter implements FilterInterface
$this->translatableStringHelper = $translatableStringHelper;
}
public function addRole()
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
if (!in_array('user', $qb->getAllAliases(), true)) {
$qb->join('activity.user', 'user');
if (!in_array('actuser', $qb->getAllAliases(), true)) {
$qb->join('activity.user', 'actuser');
}
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->in('user.mainScope', ':userscope');
$clause = $qb->expr()->in('actuser.mainScope', ':userscope');
if ($where instanceof Andx) {
$where->add($clause);
@@ -85,7 +85,7 @@ class UserScopeFilter implements FilterInterface
}
return ['Filtered activity by userscope: only %scopes%', [
'%scopes%' => implode(', ou ', $scopes),
'%scopes%' => implode(', ', $scopes),
]];
}

View File

@@ -13,9 +13,10 @@ namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\MainBundle\Form\Type\Export\FilterType;
use DateTime;
use Chill\MainBundle\Form\Type\PickRollingDateType;
use Chill\MainBundle\Service\RollingDate\RollingDate;
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
@@ -28,12 +29,17 @@ class ActivityDateFilter implements FilterInterface
{
protected TranslatorInterface $translator;
public function __construct(TranslatorInterface $translator)
{
private RollingDateConverterInterface $rollingDateConverter;
public function __construct(
TranslatorInterface $translator,
RollingDateConverterInterface $rollingDateConverter
) {
$this->translator = $translator;
$this->rollingDateConverter = $rollingDateConverter;
}
public function addRole()
public function addRole(): ?string
{
return null;
}
@@ -54,8 +60,14 @@ class ActivityDateFilter implements FilterInterface
}
$qb->add('where', $where);
$qb->setParameter('date_from', $data['date_from']);
$qb->setParameter('date_to', $data['date_to']);
$qb->setParameter(
'date_from',
$this->rollingDateConverter->convert($data['date_from'])
);
$qb->setParameter(
'date_to',
$this->rollingDateConverter->convert($data['date_to'])
);
}
public function applyOn(): string
@@ -66,13 +78,13 @@ class ActivityDateFilter implements FilterInterface
public function buildForm(FormBuilderInterface $builder)
{
$builder
->add('date_from', ChillDateType::class, [
->add('date_from', PickRollingDateType::class, [
'label' => 'Activities after this date',
'data' => new DateTime(),
'data' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START),
])
->add('date_to', ChillDateType::class, [
->add('date_to', PickRollingDateType::class, [
'label' => 'Activities before this date',
'data' => new DateTime(),
'data' => new RollingDate(RollingDate::T_TODAY),
]);
$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
@@ -121,8 +133,8 @@ class ActivityDateFilter implements FilterInterface
return [
'Filtered by date of activity: only between %date_from% and %date_to%',
[
'%date_from%' => $data['date_from']->format('d-m-Y'),
'%date_to%' => $data['date_to']->format('d-m-Y'),
'%date_from%' => $this->rollingDateConverter->convert($data['date_from'])->format('d-m-Y'),
'%date_to%' => $this->rollingDateConverter->convert($data['date_to'])->format('d-m-Y'),
],
];
}

View File

@@ -13,52 +13,41 @@ namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Entity\ActivityType;
use Chill\ActivityBundle\Export\Declarations;
use Chill\ActivityBundle\Repository\ActivityTypeRepository;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\ActivityBundle\Repository\ActivityTypeRepositoryInterface;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use function count;
class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInterface
{
protected ActivityTypeRepository $activityTypeRepository;
protected ActivityTypeRepositoryInterface $activityTypeRepository;
protected TranslatableStringHelperInterface $translatableStringHelper;
public function __construct(
TranslatableStringHelperInterface $translatableStringHelper,
ActivityTypeRepository $activityTypeRepository
ActivityTypeRepositoryInterface $activityTypeRepository
) {
$this->translatableStringHelper = $translatableStringHelper;
$this->activityTypeRepository = $activityTypeRepository;
}
public function addRole()
public function addRole(): ?string
{
return new Role(ActivityStatsVoter::STATS);
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->in('activity.activityType', ':selected_activity_types');
if ($where instanceof Expr\Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->andWhere($clause);
$qb->setParameter('selected_activity_types', $data['types']);
}
@@ -70,11 +59,26 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('types', EntityType::class, [
'choices' => $this->activityTypeRepository->findAllActive(),
'class' => ActivityType::class,
'choice_label' => fn (ActivityType $type) => $this->translatableStringHelper->localize($type->getName()),
'group_by' => fn (ActivityType $type) => $this->translatableStringHelper->localize($type->getCategory()->getName()),
'choice_label' => function (ActivityType $aty) {
return
($aty->hasCategory() ? $this->translatableStringHelper->localize($aty->getCategory()->getName()) . ' > ' : '')
.
$this->translatableStringHelper->localize($aty->getName());
},
'group_by' => function (ActivityType $type) {
if (!$type->hasCategory()) {
return null;
}
return $this->translatableStringHelper->localize($type->getCategory()->getName());
},
'multiple' => true,
'expanded' => false,
'attr' => [
'class' => 'select2',
],
]);
}
@@ -87,7 +91,7 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter
);
return ['Filtered by activity type: only %list%', [
'%list%' => implode(', ou ', $reasonsNames),
'%list%' => implode(', ', $reasonsNames),
]];
}
@@ -104,23 +108,4 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter
->addViolation();
}
}
/**
* Check if a join between Activity and Reason is already defined.
*
* @param Join[] $joins
* @param mixed $alias
*
* @return bool
*/
private function checkJoinAlreadyDefined(array $joins, $alias)
{
foreach ($joins as $join) {
if ($join->getAlias() === $alias) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\PickUserDynamicType;
use Chill\MainBundle\Templating\Entity\UserRender;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
class ActivityUsersFilter implements FilterInterface
{
private UserRender $userRender;
public function __construct(UserRender $userRender)
{
$this->userRender = $userRender;
}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$orX = $qb->expr()->orX();
foreach ($data['accepted_users'] as $key => $user) {
$orX->add($qb->expr()->isMemberOf(':activity_users_filter_u' . $key, 'activity.users'));
$qb->setParameter('activity_users_filter_u' . $key, $user);
}
$qb->andWhere($orX);
}
public function applyOn()
{
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_users', PickUserDynamicType::class, [
'multiple' => true,
'label' => 'Users',
]);
}
public function describeAction($data, $format = 'string')
{
$users = [];
foreach ($data['accepted_users'] as $u) {
$users[] = $this->userRender->renderString($u, []);
}
return ['Filtered activity by users: only %users%', [
'%users%' => implode(', ', $users),
]];
}
public function getTitle(): string
{
return 'Filter activity by users';
}
}

View File

@@ -14,21 +14,18 @@ namespace Chill\ActivityBundle\Export\Filter\PersonFilters;
use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\ActivityBundle\Export\Declarations;
use Chill\ActivityBundle\Repository\ActivityReasonRepository;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use function array_key_exists;
use function count;
use function in_array;
class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInterface
{
@@ -44,9 +41,9 @@ class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInt
$this->activityReasonRepository = $activityReasonRepository;
}
public function addRole()
public function addRole(): ?string
{
return new Role(ActivityStatsVoter::STATS);
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
@@ -54,20 +51,9 @@ class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInt
$where = $qb->getDQLPart('where');
$join = $qb->getDQLPart('join');
$clause = $qb->expr()->in('reasons', ':selected_activity_reasons');
//dump($join);
// add a join to reasons only if needed
if (
(
array_key_exists('activity', $join)
&& !$this->checkJoinAlreadyDefined($join['activity'], 'reasons')
)
|| (!array_key_exists('activity', $join))
) {
$qb->add(
'join',
['activity' => new Join(Join::INNER_JOIN, 'activity.reasons', 'reasons')],
true
);
if (!in_array('actreasons', $qb->getAllAliases(), true)) {
$qb->join('activity.reasons', 'actreasons');
}
if ($where instanceof Expr\Andx) {
@@ -125,21 +111,4 @@ class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInt
->addViolation();
}
}
/**
* Check if a join between Activity and Reason is already defined.
*
* @param Join[] $joins
* @param mixed $alias
*/
private function checkJoinAlreadyDefined(array $joins, $alias): bool
{
foreach ($joins as $join) {
if ($join->getAlias() === $alias) {
return true;
}
}
return false;
}
}

View File

@@ -11,6 +11,7 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter\PersonFilters;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\ActivityBundle\Repository\ActivityReasonRepository;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
@@ -52,17 +53,17 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt
$this->translator = $translator;
}
public function addRole()
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
// create a query for activity
// create a subquery for activity
$sqb = $qb->getEntityManager()->createQueryBuilder();
$sqb->select('person_person_having_activity.id')
->from('ChillActivityBundle:Activity', 'activity_person_having_activity')
->from(Activity::class, 'activity_person_having_activity')
->join('activity_person_having_activity.person', 'person_person_having_activity');
// add clause between date
@@ -197,7 +198,7 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt
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)

View File

@@ -0,0 +1,81 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Entity\UserJob;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
class UsersJobFilter implements FilterInterface
{
private TranslatableStringHelperInterface $translatableStringHelper;
public function __construct(TranslatableStringHelperInterface $translatableStringHelper)
{
$this->translatableStringHelper = $translatableStringHelper;
}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$qb
->andWhere(
$qb->expr()->exists(
'SELECT 1 FROM ' . Activity::class . ' activity_users_job_filter_act
JOIN activity_users_job_filter_act.users users WHERE users.userJob IN (:activity_users_job_filter_jobs) AND activity_users_job_filter_act = activity '
)
)
->setParameter('activity_users_job_filter_jobs', $data['jobs']);
}
public function applyOn()
{
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('jobs', EntityType::class, [
'class' => UserJob::class,
'choice_label' => fn (UserJob $j) => $this->translatableStringHelper->localize($j->getLabel()),
'multiple' => true,
'expanded' => true,
]);
}
public function describeAction($data, $format = 'string')
{
return ['export.filter.activity.by_usersjob.Filtered activity by users job: only %jobs%', [
'%jobs%' => implode(
', ',
array_map(
fn (UserJob $job) => $this->translatableStringHelper->localize($job->getLabel()),
$data['jobs']->toArray()
)
),
]];
}
public function getTitle()
{
return 'export.filter.activity.by_usersjob.Filter by users job';
}
}

View File

@@ -0,0 +1,88 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Repository\ScopeRepositoryInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
class UsersScopeFilter implements FilterInterface
{
private ScopeRepositoryInterface $scopeRepository;
private TranslatableStringHelperInterface $translatableStringHelper;
public function __construct(
ScopeRepositoryInterface $scopeRepository,
TranslatableStringHelperInterface $translatableStringHelper
) {
$this->scopeRepository = $scopeRepository;
$this->translatableStringHelper = $translatableStringHelper;
}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$qb
->andWhere(
$qb->expr()->exists(
'SELECT 1 FROM ' . Activity::class . ' activity_users_scope_filter_act
JOIN activity_users_scope_filter_act.users users WHERE users.mainScope IN (:activity_users_scope_filter_scopes) AND activity_users_scope_filter_act = activity '
)
)
->setParameter('activity_users_scope_filter_scopes', $data['scopes']);
}
public function applyOn()
{
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('scopes', EntityType::class, [
'class' => Scope::class,
'choices' => $this->scopeRepository->findAllActive(),
'choice_label' => fn (Scope $s) => $this->translatableStringHelper->localize($s->getName()),
'multiple' => true,
'expanded' => true,
]);
}
public function describeAction($data, $format = 'string')
{
return ['export.filter.activity.by_usersscope.Filtered activity by users scope: only %scopes%', [
'%scopes%' => implode(
', ',
array_map(
fn (Scope $s) => $this->translatableStringHelper->localize($s->getName()),
$data['scopes']->toArray()
)
),
]];
}
public function getTitle()
{
return 'export.filter.activity.by_usersscope.Filter by users scope';
}
}

View File

@@ -12,48 +12,33 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Form\Type;
use Chill\ActivityBundle\Entity\ActivityType;
use Chill\ActivityBundle\Repository\ActivityTypeRepository;
use Chill\ActivityBundle\Repository\ActivityTypeRepositoryInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class TranslatableActivityType extends AbstractType
{
protected ActivityTypeRepository $activityTypeRepository;
protected ActivityTypeRepositoryInterface $activityTypeRepository;
protected TranslatableStringHelperInterface $translatableStringHelper;
public function __construct(
TranslatableStringHelperInterface $helper,
ActivityTypeRepository $activityTypeRepository
ActivityTypeRepositoryInterface $activityTypeRepository
) {
$this->translatableStringHelper = $helper;
$this->activityTypeRepository = $activityTypeRepository;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
/** @var QueryBuilder $qb */
$qb = $options['query_builder'];
if (true === $options['active_only']) {
$qb->where($qb->expr()->eq('at.active', ':active'));
$qb->setParameter('active', true, Types::BOOLEAN);
}
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
[
'class' => ActivityType::class,
'active_only' => true,
'query_builder' => $this->activityTypeRepository
->createQueryBuilder('at'),
'choices' => $this->activityTypeRepository->findAllActive(),
'choice_label' => function (ActivityType $type) {
return $this->translatableStringHelper->localize($type->getName());
},

View File

@@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Repository;
use Chill\ActivityBundle\Entity\ActivityPresence;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
class ActivityPresenceRepository implements ActivityPresenceRepositoryInterface
{
private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
$this->repository = $entityManager->getRepository($this->getClassName());
}
public function find($id): ?ActivityPresence
{
return $this->repository->find($id);
}
public function findAll(): array
{
return $this->repository->findAll();
}
public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array
{
return $this->findBy($criteria, $orderBy, $limit, $offset);
}
public function findOneBy(array $criteria): ?ActivityPresence
{
return $this->findOneBy($criteria);
}
public function getClassName(): string
{
return ActivityPresence::class;
}
}

View File

@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Repository;
use Chill\ActivityBundle\Entity\ActivityPresence;
interface ActivityPresenceRepositoryInterface
{
public function find($id): ?ActivityPresence;
/**
* @return array|ActivityPresence[]
*/
public function findAll(): array;
/**
* @return array|ActivityPresence[]
*/
public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array;
public function findOneBy(array $criteria): ?ActivityPresence;
public function getClassName(): string;
}

View File

@@ -12,19 +12,54 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Repository;
use Chill\ActivityBundle\Entity\ActivityType;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
/**
* @method ActivityType|null find($id, $lockMode = null, $lockVersion = null)
* @method ActivityType|null findOneBy(array $criteria, array $orderBy = null)
* @method ActivityType[] findAll()
* @method ActivityType[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class ActivityTypeRepository extends ServiceEntityRepository
final class ActivityTypeRepository implements ActivityTypeRepositoryInterface
{
public function __construct(ManagerRegistry $registry)
private EntityRepository $repository;
public function __construct(EntityManagerInterface $em)
{
parent::__construct($registry, ActivityType::class);
$this->repository = $em->getRepository(ActivityType::class);
}
public function find($id): ?ActivityType
{
return $this->repository->find($id);
}
/**
* @return array|ActivityType[]
*/
public function findAll(): array
{
return $this->repository->findAll();
}
/**
* @return array|ActivityType[]
*/
public function findAllActive(): array
{
return $this->findBy(['active' => true]);
}
/**
* @return array|ActivityType[]
*/
public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array
{
return $this->repository->findBy($criteria, $orderBy, $limit, $offset);
}
public function findOneBy(array $criteria): ?ActivityType
{
return $this->repository->findOneBy($criteria);
}
public function getClassName(): string
{
return ActivityType::class;
}
}

View File

@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Repository;
use Chill\ActivityBundle\Entity\ActivityType;
use Doctrine\Persistence\ObjectRepository;
interface ActivityTypeRepositoryInterface extends ObjectRepository
{
/**
* @return array|ActivityType[]
*/
public function findAllActive(): array;
}

View File

@@ -17,7 +17,7 @@ const getLocations = () => fetchResults('/api/1.0/main/location.json');
const getLocationTypes = () => fetchResults('/api/1.0/main/location-type.json');
const getUserCurrentLocation =
const getUserCurrentLocation =
() => fetch('/api/1.0/main/user-current-location.json')
.then(response => {
if (response.ok) { return response.json(); }
@@ -35,6 +35,13 @@ const getLocationTypeByDefaultFor = (entity) => {
);
};
/**
* Post a location
*
* **NOTE**: also in use for Calendar
* @param body
* @returns {Promise<T>}
*/
const postLocation = (body) => {
const url = `/api/1.0/main/location.json`;
return fetch(url, {

View File

@@ -58,7 +58,7 @@ const makeAccompanyingPeriodLocation = (locationType, store) => {
export default function prepareLocations(store) {
// find the locations
// find the locations
let allLocations = getLocations().then(
(results) => {
store.commit('addAvailableLocationGroup', {
@@ -114,7 +114,7 @@ export default function prepareLocations(store) {
if (window.default_location_id) {
for (let group of store.state.availableLocations) {
let location = group.locations.find((l) => l.id === window.default_location_id);
if (location !== undefined & store.state.activity.location === null) {
if (location !== undefined && store.state.activity.location === null) {
store.dispatch('updateLocation', location);
break;
}

View File

@@ -1,3 +1,14 @@
{#
WARNING: this file is in use in both ActivityBundle and CalendarBundle.
Take care when editing this file.
Maybe should we think about abstracting this file a bit more ? Moving it to PersonBundle ?
#}
{% if context == 'calendar_accompanyingCourse' %}
{% import "@ChillCalendar/_invite.html.twig" as invite %}
{% endif %}
{% macro href(pathname, key, value) %}
{% set parms = { (key): value } %}
{{ path(pathname, parms) }}
@@ -18,7 +29,7 @@
{% endmacro %}
{% set blocks = [] %}
{% if entity.activityType.personsVisible %}
{% if context == 'calendar_accompanyingCourse' or context == 'calendar_person' or entity.activityType.personsVisible %}
{% if context == 'person' %}
{% set blocks = blocks|merge([{
'title': 'Others persons'|trans,
@@ -43,7 +54,7 @@
}]) %}
{% endif %}
{% endif %}
{% if entity.activityType.thirdPartiesVisible %}
{% if context == 'calendar_accompanyingCourse' or context == 'calendar_person' or entity.activityType.thirdPartiesVisible %}
{% set blocks = blocks|merge([{
'title': 'Third parties'|trans,
'items': entity.thirdParties,
@@ -52,7 +63,7 @@
'key' : 'id',
}]) %}
{% endif %}
{% if entity.activityType.usersVisible %}
{% if context == 'calendar_accompanyingCourse' or context == 'calendar_person' or entity.activityType.usersVisible %}
{% set blocks = blocks|merge([{
'title': 'Users concerned'|trans,
'items': entity.users,
@@ -132,6 +143,12 @@
{% if bloc.type == 'user' %}
<span class="badge-user">
{{ item|chill_entity_render_box({'render': 'raw', 'addAltNames': false }) }}
{%- if context == 'calendar_accompanyingCourse' or context == 'calendar_person' %}
{% set invite = entity.inviteForUser(item) %}
{% if invite is not null %}
{{ invite.invite_span(invite) }}
{% endif %}
{%- endif -%}
</span>
{% else %}
{{ _self.insert_onthefly(bloc.type, item) }}

View File

@@ -13,10 +13,10 @@ namespace Chill\ActivityBundle\Security\Authorization;
use Chill\MainBundle\Entity\Center;
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 function in_array;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
class ActivityStatsVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface
{
@@ -24,14 +24,14 @@ class ActivityStatsVoter extends AbstractChillVoter implements ProvideRoleHierar
public const STATS = 'CHILL_ACTIVITY_STATS';
/**
* @var AuthorizationHelper
*/
protected $helper;
protected VoterHelperInterface $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
@@ -49,30 +49,14 @@ class ActivityStatsVoter extends AbstractChillVoter implements ProvideRoleHierar
return $this->getAttributes();
}
protected function getSupportedClasses()
{
return [Center::class];
}
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)
{
if (
$subject instanceof Center
&& in_array($attribute, $this->getAttributes(), true)
) {
return true;
}
return $this->helper->supports($attribute, $subject);
}
return false;
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
return $this->helper->voteOnAttribute($attribute, $subject, $token);
}
private function getAttributes()

View File

@@ -369,8 +369,12 @@ final class ActivityControllerTest extends WebTestCase
$center
);
$reachableScopesId = array_intersect(
array_map(static function ($s) { return $s->getId(); }, $reachableScopesDelete),
array_map(static function ($s) { return $s->getId(); }, $reachableScopesUpdate)
array_map(static function ($s) {
return $s->getId();
}, $reachableScopesDelete),
array_map(static function ($s) {
return $s->getId();
}, $reachableScopesUpdate)
);
if (count($reachableScopesId) === 0) {

View File

@@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Aggregator\ACPAggregators;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Aggregator\ACPAggregators\BySocialActionAggregator;
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
use Doctrine\ORM\EntityManagerInterface;
/**
* @internal
* @coversNothing
*/
final class BySocialActionAggregatorTest extends AbstractAggregatorTest
{
private BySocialActionAggregator $aggregator;
protected function setUp(): void
{
self::bootKernel();
$this->aggregator = self::$container->get('chill.activity.export.bysocialaction_aggregator');
}
public function getAggregator()
{
return $this->aggregator;
}
public function getFormData(): array
{
return [
[],
];
}
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from(Activity::class, 'activity')
->join('activity.accompanyingPeriod', 'acp')
->join('activity.socialActions', 'actsocialaction'),
];
}
}

View File

@@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Aggregator\ACPAggregators;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Aggregator\ACPAggregators\BySocialIssueAggregator;
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
use Doctrine\ORM\EntityManagerInterface;
/**
* @internal
* @coversNothing
*/
final class BySocialIssueAggregatorTest extends AbstractAggregatorTest
{
private BySocialIssueAggregator $aggregator;
protected function setUp(): void
{
self::bootKernel();
$this->aggregator = self::$container->get('chill.activity.export.bysocialissue_aggregator');
}
public function getAggregator()
{
return $this->aggregator;
}
public function getFormData(): array
{
return [
[],
];
}
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from(Activity::class, 'activity')
->join('activity.accompanyingPeriod', 'acp')
->join('activity.socialIssues', 'actsocialissue'),
];
}
}

View File

@@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Aggregator\ACPAggregators;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Aggregator\ACPAggregators\ByThirdpartyAggregator;
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
use Doctrine\ORM\EntityManagerInterface;
/**
* @internal
* @coversNothing
*/
final class ByThirdpartyAggregatorTest extends AbstractAggregatorTest
{
private ByThirdpartyAggregator $aggregator;
protected function setUp(): void
{
self::bootKernel();
$this->aggregator = self::$container->get('chill.activity.export.bythirdparty_aggregator');
}
public function getAggregator()
{
return $this->aggregator;
}
public function getFormData(): array
{
return [
[],
];
}
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from(Activity::class, 'activity')
->join('activity.accompanyingPeriod', 'acp')
->join('activity.thirdParties', 'acttparty'),
];
}
}

View File

@@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Aggregator\ACPAggregators;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Aggregator\ACPAggregators\ByCreatorAggregator;
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
use Doctrine\ORM\EntityManagerInterface;
/**
* @internal
* @coversNothing
*/
final class ByUserAggregatorTest extends AbstractAggregatorTest
{
private ByCreatorAggregator $aggregator;
protected function setUp(): void
{
self::bootKernel();
$this->aggregator = self::$container->get('chill.activity.export.byuser_aggregator');
}
public function getAggregator()
{
return $this->aggregator;
}
public function getFormData(): array
{
return [
[],
];
}
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from(Activity::class, 'activity')
->join('activity.accompanyingPeriod', 'acp')
->join('activity.users', 'actusers'),
];
}
}

View File

@@ -0,0 +1,69 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Aggregator\ACPAggregators;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Aggregator\ACPAggregators\DateAggregator;
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
use Doctrine\ORM\EntityManagerInterface;
/**
* @internal
* @coversNothing
*/
final class DateAggregatorTest extends AbstractAggregatorTest
{
private DateAggregator $aggregator;
protected function setUp(): void
{
self::bootKernel();
$this->aggregator = self::$container->get('chill.activity.export.date_aggregator');
}
public function getAggregator()
{
return $this->aggregator;
}
public function getFormData(): array
{
return [
[
'frequency' => 'month',
],
[
'frequency' => 'week',
],
[
'frequency' => 'year',
],
];
}
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from(Activity::class, 'activity')
->join('activity.accompanyingPeriod', 'acp'),
];
}
}

View File

@@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Aggregator\ACPAggregators;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Aggregator\ACPAggregators\LocationTypeAggregator;
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
use Doctrine\ORM\EntityManagerInterface;
/**
* @internal
* @coversNothing
*/
final class LocationTypeAggregatorTest extends AbstractAggregatorTest
{
private LocationTypeAggregator $aggregator;
protected function setUp(): void
{
self::bootKernel();
$this->aggregator = self::$container->get('chill.activity.export.locationtype_aggregator');
}
public function getAggregator()
{
return $this->aggregator;
}
public function getFormData(): array
{
return [
[],
];
}
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from(Activity::class, 'activity')
->join('activity.accompanyingPeriod', 'acp')
->join('activity.location', 'actloc'),
];
}
}

View File

@@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Aggregator\ACPAggregators;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Aggregator\ACPAggregators\CreatorScopeAggregator;
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
use Doctrine\ORM\EntityManagerInterface;
/**
* @internal
* @coversNothing
*/
final class UserScopeAggregatorTest extends AbstractAggregatorTest
{
private CreatorScopeAggregator $aggregator;
protected function setUp(): void
{
self::bootKernel();
$this->aggregator = self::$container->get('chill.activity.export.userscope_aggregator');
}
public function getAggregator()
{
return $this->aggregator;
}
public function getFormData(): array
{
return [
[],
];
}
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from(Activity::class, 'activity')
->join('activity.accompanyingPeriod', 'acp')
->join('activity.user', 'actuser'),
];
}
}

View File

@@ -11,7 +11,10 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Tests\Export\Aggregator;
use Chill\ActivityBundle\Export\Aggregator\ActivityTypeAggregator;
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
use Doctrine\ORM\EntityManagerInterface;
use Prophecy\PhpUnit\ProphecyTrait;
/**
* Add tests for ActivityTypeAggregator.
@@ -21,26 +24,22 @@ use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
*/
final class ActivityTypeAggregatorTest extends AbstractAggregatorTest
{
/**
* @var \Chill\ActivityBundle\Export\Aggregator\ActivityReasonAggregator
*/
private $aggregator;
use ProphecyTrait;
private ActivityTypeAggregator $aggregator;
protected function setUp(): void
{
self::bootKernel();
$container = self::$kernel->getContainer();
$this->aggregator = self::$container->get('chill.activity.export.type_aggregator');
$this->aggregator = $container->get('chill.activity.export.type_aggregator');
$request = $this->prophesize()
->willExtend(\Symfony\Component\HttpFoundation\Request::class);
// add a fake request with a default locale (used in translatable string)
$prophet = new \Prophecy\Prophet();
$request = $prophet->prophesize();
$request->willExtend(\Symfony\Component\HttpFoundation\Request::class);
$request->getLocale()->willReturn('fr');
$container->get('request_stack')
self::$container->get('request_stack')
->push($request->reveal());
}
@@ -62,8 +61,7 @@ final class ActivityTypeAggregatorTest extends AbstractAggregatorTest
self::bootKernel();
}
$em = self::$kernel->getContainer()
->get('doctrine.orm.entity_manager');
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
@@ -72,12 +70,7 @@ final class ActivityTypeAggregatorTest extends AbstractAggregatorTest
$em->createQueryBuilder()
->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity')
->join('activity.reasons', 'reasons'),
$em->createQueryBuilder()
->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity')
->join('activity.reasons', 'reasons')
->join('reasons.category', 'category'),
->join('activity.activityType', 'acttype'),
];
}
}

View File

@@ -11,7 +11,10 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Tests\Export\Aggregator;
use Chill\ActivityBundle\Export\Aggregator\ActivityUserAggregator;
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
use Doctrine\ORM\EntityManagerInterface;
use Prophecy\PhpUnit\ProphecyTrait;
/**
* Add tests for ActivityUsernAggregator.
@@ -21,26 +24,22 @@ use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
*/
final class ActivityUserAggregatorTest extends AbstractAggregatorTest
{
/**
* @var \Chill\ActivityBundle\Export\Aggregator\ActivityUserAggregator
*/
private $aggregator;
use ProphecyTrait;
private ActivityUserAggregator $aggregator;
protected function setUp(): void
{
self::bootKernel();
$container = self::$kernel->getContainer();
$this->aggregator = self::$container->get('chill.activity.export.user_aggregator');
$this->aggregator = $container->get('chill.activity.export.user_aggregator');
$request = $this->prophesize()
->willExtend(\Symfony\Component\HttpFoundation\Request::class);
// add a fake request with a default locale (used in translatable string)
$prophet = new \Prophecy\Prophet();
$request = $prophet->prophesize();
$request->willExtend(\Symfony\Component\HttpFoundation\Request::class);
$request->getLocale()->willReturn('fr');
$container->get('request_stack')
self::$container->get('request_stack')
->push($request->reveal());
}
@@ -49,35 +48,25 @@ final class ActivityUserAggregatorTest extends AbstractAggregatorTest
return $this->aggregator;
}
public function getFormData()
public function getFormData(): array
{
return [
[],
];
}
public function getQueryBuilders()
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$kernel->getContainer()
->get('doctrine.orm.entity_manager');
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity'),
$em->createQueryBuilder()
->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity')
->join('activity.reasons', 'reasons'),
$em->createQueryBuilder()
->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity')
->join('activity.reasons', 'reasons')
->join('reasons.category', 'category'),
];
}
}

View File

@@ -9,38 +9,35 @@ declare(strict_types=1);
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Aggregator;
namespace Chill\ActivityBundle\Tests\Export\Aggregator\PersonAggregators;
use Chill\ActivityBundle\Export\Aggregator\PersonAggregators\ActivityReasonAggregator;
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
use Doctrine\ORM\EntityManagerInterface;
use Prophecy\PhpUnit\ProphecyTrait;
/**
* Add tests for ActivityReasonAggregator.
*
* @internal
* @coversNothing
*/
final class ActivityReasonAggregatorTest extends AbstractAggregatorTest
{
/**
* @var \Chill\ActivityBundle\Export\Aggregator\ActivityReasonAggregator
*/
private $aggregator;
use ProphecyTrait;
private ActivityReasonAggregator $aggregator;
protected function setUp(): void
{
self::bootKernel();
$container = self::$kernel->getContainer();
$this->aggregator = self::$container->get('chill.activity.export.reason_aggregator');
$this->aggregator = $container->get('chill.activity.export.reason_aggregator');
$request = $this->prophesize()
->willExtend(\Symfony\Component\HttpFoundation\Request::class);
// add a fake request with a default locale (used in translatable string)
$prophet = new \Prophecy\Prophet();
$request = $prophet->prophesize();
$request->willExtend(\Symfony\Component\HttpFoundation\Request::class);
$request->getLocale()->willReturn('fr');
$container->get('request_stack')
self::$container->get('request_stack')
->push($request->reveal());
}
@@ -49,7 +46,7 @@ final class ActivityReasonAggregatorTest extends AbstractAggregatorTest
return $this->aggregator;
}
public function getFormData()
public function getFormData(): array
{
return [
['level' => 'reasons'],
@@ -57,14 +54,13 @@ final class ActivityReasonAggregatorTest extends AbstractAggregatorTest
];
}
public function getQueryBuilders()
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$kernel->getContainer()
->get('doctrine.orm.entity_manager');
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
@@ -73,12 +69,12 @@ final class ActivityReasonAggregatorTest extends AbstractAggregatorTest
$em->createQueryBuilder()
->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity')
->join('activity.reasons', 'reasons'),
->join('activity.reasons', 'actreasons'),
$em->createQueryBuilder()
->select('count(activity.id)')
->from('ChillActivityBundle:Activity', 'activity')
->join('activity.reasons', 'reasons')
->join('reasons.category', 'category'),
->join('activity.reasons', 'actreasons')
->join('actreasons.category', 'actreasoncat'),
];
}
}

View File

@@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Export\LinkedToACP;
use Chill\ActivityBundle\Export\Export\LinkedToACP\AvgActivityDuration;
use Chill\MainBundle\Test\Export\AbstractExportTest;
/**
* @internal
* @coversNothing
*/
final class AvgActivityDurationTest extends AbstractExportTest
{
private AvgActivityDuration $export;
protected function setUp(): void
{
self::bootKernel();
$this->export = self::$container->get('chill.activity.export.avg_activity_duration_linked_to_acp');
}
public function getExport()
{
return $this->export;
}
public function getFormData(): array
{
return [
[],
];
}
public function getModifiersCombination(): array
{
return [
['activity'],
['activity', 'accompanying_period'],
];
}
}

View File

@@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Export\LinkedToACP;
use Chill\ActivityBundle\Export\Export\LinkedToACP\AvgActivityVisitDuration;
use Chill\MainBundle\Test\Export\AbstractExportTest;
/**
* @internal
* @coversNothing
*/
final class AvgActivityVisitDurationTest extends AbstractExportTest
{
private AvgActivityVisitDuration $export;
protected function setUp(): void
{
self::bootKernel();
$this->export = self::$container->get('chill.activity.export.avg_activity_visit_duration_linked_to_acp');
}
public function getExport()
{
return $this->export;
}
public function getFormData(): array
{
return [
[],
];
}
public function getModifiersCombination(): array
{
return [
['activity'],
['activity', 'accompanying_period'],
];
}
}

View File

@@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Export\LinkedToACP;
use Chill\ActivityBundle\Export\Export\LinkedToACP\CountActivity;
use Chill\MainBundle\Test\Export\AbstractExportTest;
/**
* @internal
* @coversNothing
*/
final class CountActivityTest extends AbstractExportTest
{
private CountActivity $export;
protected function setUp(): void
{
self::bootKernel();
$this->export = self::$container->get('chill.activity.export.count_activity_linked_to_acp');
}
public function getExport()
{
return $this->export;
}
public function getFormData(): array
{
return [
[],
];
}
public function getModifiersCombination(): array
{
return [
['activity'],
['activity', 'accompanying_period'],
];
}
}

View File

@@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Export\LinkedToACP;
use Chill\ActivityBundle\Export\Export\LinkedToACP\SumActivityDuration;
use Chill\MainBundle\Test\Export\AbstractExportTest;
/**
* @internal
* @coversNothing
*/
final class SumActivityDurationTest extends AbstractExportTest
{
private SumActivityDuration $export;
protected function setUp(): void
{
self::bootKernel();
$this->export = self::$container->get('chill.activity.export.sum_activity_duration_linked_to_acp');
}
public function getExport()
{
return $this->export;
}
public function getFormData(): array
{
return [
[],
];
}
public function getModifiersCombination(): array
{
return [
['activity'],
['activity', 'accompanying_period'],
];
}
}

View File

@@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Export\LinkedToACP;
use Chill\ActivityBundle\Export\Export\LinkedToACP\SumActivityVisitDuration;
use Chill\MainBundle\Test\Export\AbstractExportTest;
/**
* @internal
* @coversNothing
*/
final class SumActivityVisitDurationTest extends AbstractExportTest
{
private SumActivityVisitDuration $export;
protected function setUp(): void
{
self::bootKernel();
$this->export = self::$container->get('chill.activity.export.sum_activity_visit_duration_linked_to_acp');
}
public function getExport()
{
return $this->export;
}
public function getFormData(): array
{
return [
[],
];
}
public function getModifiersCombination(): array
{
return [
['activity'],
['activity', 'accompanying_period'],
];
}
}

View File

@@ -9,8 +9,9 @@ declare(strict_types=1);
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Export;
namespace Chill\ActivityBundle\Tests\Export\Export\LinkedToPerson;
use Chill\ActivityBundle\Export\Export\LinkedToPerson\CountActivity;
use Chill\MainBundle\Test\Export\AbstractExportTest;
/**
@@ -19,19 +20,13 @@ use Chill\MainBundle\Test\Export\AbstractExportTest;
*/
final class CountActivityTest extends AbstractExportTest
{
/**
* @var
*/
private $export;
private CountActivity $export;
protected function setUp(): void
{
self::bootKernel();
/** @var \Symfony\Component\DependencyInjection\ContainerInterface $container */
$container = self::$kernel->getContainer();
$this->export = $container->get('chill.activity.export.count_activity');
$this->export = self::$container->get('chill.activity.export.count_activity_linked_to_person');
}
public function getExport()
@@ -39,14 +34,14 @@ final class CountActivityTest extends AbstractExportTest
return $this->export;
}
public function getFormData()
public function getFormData(): array
{
return [
[],
];
}
public function getModifiersCombination()
public function getModifiersCombination(): array
{
return [
['activity'],

View File

@@ -9,9 +9,11 @@ declare(strict_types=1);
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Export;
namespace Chill\ActivityBundle\Tests\Export\Export\LinkedToPerson;
use Chill\ActivityBundle\Export\Export\LinkedToPerson\ListActivity;
use Chill\MainBundle\Test\Export\AbstractExportTest;
use Prophecy\PhpUnit\ProphecyTrait;
/**
* @internal
@@ -19,27 +21,22 @@ use Chill\MainBundle\Test\Export\AbstractExportTest;
*/
final class ListActivityTest extends AbstractExportTest
{
/**
* @var \Chill\ActivityBundle\Export\Export\ListActivity
*/
private $export;
use ProphecyTrait;
private ListActivity $export;
protected function setUp(): void
{
self::bootKernel();
/** @var \Symfony\Component\DependencyInjection\ContainerInterface $container */
$container = self::$kernel->getContainer();
$this->export = self::$container->get('chill.activity.export.list_activity_linked_to_person');
$this->export = $container->get('chill.activity.export.list_activity');
$request = $this->prophesize()
->willExtend(\Symfony\Component\HttpFoundation\Request::class);
// add a fake request with a default locale (used in translatable string)
$prophet = new \Prophecy\Prophet();
$request = $prophet->prophesize();
$request->willExtend(\Symfony\Component\HttpFoundation\Request::class);
$request->getLocale()->willReturn('fr');
$container->get('request_stack')
self::$container->get('request_stack')
->push($request->reveal());
}

View File

@@ -9,8 +9,9 @@ declare(strict_types=1);
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Export;
namespace Chill\ActivityBundle\Tests\Export\Export\LinkedToPerson;
use Chill\ActivityBundle\Export\Export\LinkedToPerson\StatActivityDuration;
use Chill\MainBundle\Test\Export\AbstractExportTest;
/**
@@ -19,21 +20,15 @@ use Chill\MainBundle\Test\Export\AbstractExportTest;
* @internal
* @coversNothing
*/
final class StatActivityDurationSumTest extends AbstractExportTest
final class StatActivityDurationTest extends AbstractExportTest
{
/**
* @var \Chill\ActivityBundle\Export\Export\StatActivityDuration
*/
private $export;
private StatActivityDuration $export;
protected function setUp(): void
{
self::bootKernel();
/** @var \Symfony\Component\DependencyInjection\ContainerInterface $container */
$container = self::$kernel->getContainer();
$this->export = $container->get('chill.activity.export.sum_activity_duration');
$this->export = self::$container->get('chill.activity.export.sum_activity_duration_linked_to_person');
}
public function getExport()
@@ -41,14 +36,14 @@ final class StatActivityDurationSumTest extends AbstractExportTest
return $this->export;
}
public function getFormData()
public function getFormData(): array
{
return [
[],
];
}
public function getModifiersCombination()
public function getModifiersCombination(): array
{
return [
['activity'],

View File

@@ -0,0 +1,79 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Entity\ActivityType;
use Chill\ActivityBundle\Export\Filter\ACPFilters\ActivityTypeFilter;
use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query\Expr;
/**
* @internal
* @coversNothing
*/
final class ActivityTypeFilterTest extends AbstractFilterTest
{
private ActivityTypeFilter $filter;
protected function setUp(): void
{
self::bootKernel();
$this->filter = self::$container->get('chill.activity.export.filter_activitytype');
}
public function getFilter()
{
return $this->filter;
}
public function getFormData(): array
{
$em = self::$container->get(EntityManagerInterface::class);
$array = $em->createQueryBuilder()
->from(ActivityType::class, 'at')
->select('at')
->getQuery()
->getResult();
$data = [];
foreach ($array as $a) {
$data[] = [
'accepted_activitytypes' => $a,
];
}
return $data;
}
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from(AccompanyingPeriod::class, 'acp')
->join(Activity::class, 'activity', Expr\Join::WITH, 'activity.accompanyingPeriod = acp')
->join('activity.activityType', 'acttype'),
];
}
}

View File

@@ -0,0 +1,76 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Filter\ACPFilters\BySocialActionFilter;
use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
use Doctrine\ORM\EntityManagerInterface;
/**
* @internal
* @coversNothing
*/
final class BySocialActionFilterTest extends AbstractFilterTest
{
private BySocialActionFilter $filter;
protected function setUp(): void
{
self::bootKernel();
$this->filter = self::$container->get('chill.activity.export.bysocialaction_filter');
}
public function getFilter()
{
return $this->filter;
}
public function getFormData(): array
{
$em = self::$container->get(EntityManagerInterface::class);
$array = $em->createQueryBuilder()
->from(SocialAction::class, 'sa')
->select('sa')
->getQuery()
->getResult();
$data = [];
foreach ($array as $a) {
$data[] = [
'accepted_socialactions' => $a,
];
}
return $data;
}
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from(Activity::class, 'activity')
->join('activity.socialActions', 'actsocialaction'),
];
}
}

View File

@@ -0,0 +1,76 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Filter\ACPFilters\BySocialIssueFilter;
use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Doctrine\ORM\EntityManagerInterface;
/**
* @internal
* @coversNothing
*/
final class BySocialIssueFilterTest extends AbstractFilterTest
{
private BySocialIssueFilter $filter;
protected function setUp(): void
{
self::bootKernel();
$this->filter = self::$container->get('chill.activity.export.bysocialissue_filter');
}
public function getFilter()
{
return $this->filter;
}
public function getFormData(): array
{
$em = self::$container->get(EntityManagerInterface::class);
$array = $em->createQueryBuilder()
->from(SocialIssue::class, 'si')
->select('si')
->getQuery()
->getResult();
$data = [];
foreach ($array as $a) {
$data[] = [
'accepted_socialissues' => $a,
];
}
return $data;
}
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from(Activity::class, 'activity')
->join('activity.socialIssues', 'actsocialissue'),
];
}
}

View File

@@ -0,0 +1,76 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Filter\ACPFilters\ByCreatorFilter;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Doctrine\ORM\EntityManagerInterface;
/**
* @internal
* @coversNothing
*/
final class ByUserFilterTest extends AbstractFilterTest
{
private ByCreatorFilter $filter;
protected function setUp(): void
{
self::bootKernel();
$this->filter = self::$container->get('chill.activity.export.byuser_filter');
}
public function getFilter()
{
return $this->filter;
}
public function getFormData(): array
{
$em = self::$container->get(EntityManagerInterface::class);
$array = $em->createQueryBuilder()
->from(User::class, 'u')
->select('u')
->getQuery()
->getResult();
$data = [];
foreach ($array as $a) {
$data[] = [
'accepted_users' => $a,
];
}
return $data;
}
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from(Activity::class, 'activity')
->join('activity.users', 'actusers'),
];
}
}

View File

@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Filter\ACPFilters\EmergencyFilter;
use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Doctrine\ORM\EntityManagerInterface;
/**
* @internal
* @coversNothing
*/
final class EmergencyFilterTest extends AbstractFilterTest
{
private EmergencyFilter $filter;
protected function setUp(): void
{
self::bootKernel();
$this->filter = self::$container->get('chill.activity.export.emergency_filter');
}
public function getFilter()
{
return $this->filter;
}
public function getFormData(): array
{
return [
['accepted_emergency' => true],
['accepted_emergency' => false],
];
}
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from(Activity::class, 'activity'),
];
}
}

View File

@@ -0,0 +1,76 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Filter\ACPFilters\LocationTypeFilter;
use Chill\MainBundle\Entity\LocationType;
use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Doctrine\ORM\EntityManagerInterface;
/**
* @internal
* @coversNothing
*/
final class LocationTypeFilterTest extends AbstractFilterTest
{
private LocationTypeFilter $filter;
protected function setUp(): void
{
self::bootKernel();
$this->filter = self::$container->get('chill.activity.export.locationtype_filter');
}
public function getFilter()
{
return $this->filter;
}
public function getFormData(): array
{
$em = self::$container->get(EntityManagerInterface::class);
$array = $em->createQueryBuilder()
->from(LocationType::class, 'lt')
->select('lt')
->getQuery()
->getResult();
$data = [];
foreach ($array as $a) {
$data[] = [
'accepted_locationtype' => $a,
];
}
return $data;
}
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from(Activity::class, 'activity')
->join('activity.location', 'actloc'),
];
}
}

View File

@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Filter\ACPFilters\SentReceivedFilter;
use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Doctrine\ORM\EntityManagerInterface;
/**
* @internal
* @coversNothing
*/
final class SentReceivedFilterTest extends AbstractFilterTest
{
private SentReceivedFilter $filter;
protected function setUp(): void
{
self::bootKernel();
$this->filter = self::$container->get('chill.activity.export.sentreceived_filter');
}
public function getFilter()
{
return $this->filter;
}
public function getFormData(): array
{
return [
['accepted_sentreceived' => Activity::SENTRECEIVED_SENT],
['accepted_sentreceived' => Activity::SENTRECEIVED_RECEIVED],
];
}
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from(Activity::class, 'activity'),
];
}
}

View File

@@ -0,0 +1,75 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Filter\ACPFilters\UserFilter;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Doctrine\ORM\EntityManagerInterface;
/**
* @internal
* @coversNothing
*/
final class UserFilterTest extends AbstractFilterTest
{
private UserFilter $filter;
protected function setUp(): void
{
self::bootKernel();
$this->filter = self::$container->get('chill.activity.export.user_filter');
}
public function getFilter()
{
return $this->filter;
}
public function getFormData(): array
{
$em = self::$container->get(EntityManagerInterface::class);
$array = $em->createQueryBuilder()
->from(User::class, 'u')
->select('u')
->getQuery()
->getResult();
$data = [];
foreach ($array as $a) {
$data[] = [
'accepted_users' => $a,
];
}
return $data;
}
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from(Activity::class, 'activity'),
];
}
}

View File

@@ -0,0 +1,76 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Filter\ACPFilters\UserScopeFilter;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Doctrine\ORM\EntityManagerInterface;
/**
* @internal
* @coversNothing
*/
final class UserScopeFilterTest extends AbstractFilterTest
{
private UserScopeFilter $filter;
protected function setUp(): void
{
self::bootKernel();
$this->filter = self::$container->get('chill.activity.export.userscope_filter');
}
public function getFilter()
{
return $this->filter;
}
public function getFormData(): array
{
$em = self::$container->get(EntityManagerInterface::class);
$array = $em->createQueryBuilder()
->from(Scope::class, 's')
->select('s')
->getQuery()
->getResult();
$data = [];
foreach ($array as $a) {
$data[] = [
'accepted_userscope' => $a,
];
}
return $data;
}
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from(Activity::class, 'activity')
->join('activity.user', 'actuser'),
];
}
}

View File

@@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Filter;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Filter\ActivityDateFilter;
use Chill\MainBundle\Test\Export\AbstractFilterTest;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
/**
* @internal
* @coversNothing
*/
final class ActivityDateFilterTest extends AbstractFilterTest
{
private ActivityDateFilter $filter;
protected function setUp(): void
{
self::bootKernel();
$this->filter = self::$container->get('chill.activity.export.date_filter');
}
public function getFilter()
{
return $this->filter;
}
public function getFormData(): array
{
return [
[
'date_from' => DateTime::createFromFormat('Y-m-d', '2020-01-01'),
'date_to' => DateTime::createFromFormat('Y-m-d', '2021-01-01'),
],
];
}
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from(Activity::class, 'activity'),
];
}
}

View File

@@ -11,8 +11,10 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Tests\Export\Filter;
use Chill\ActivityBundle\Export\Filter\PersonFilters\ActivityReasonFilter;
use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Doctrine\Common\Collections\ArrayCollection;
use Prophecy\PhpUnit\ProphecyTrait;
/**
* @internal
@@ -20,26 +22,22 @@ use Doctrine\Common\Collections\ArrayCollection;
*/
final class ActivityReasonFilterTest extends AbstractFilterTest
{
/**
* @var \Chill\PersonBundle\Export\Filter\GenderFilter
*/
private $filter;
use ProphecyTrait;
private ActivityReasonFilter $filter;
protected function setUp(): void
{
self::bootKernel();
$container = self::$kernel->getContainer();
$this->filter = self::$container->get('chill.activity.export.reason_filter');
$this->filter = $container->get('chill.activity.export.reason_filter');
$request = $this->prophesize()
->willExtend(\Symfony\Component\HttpFoundation\Request::class);
// add a fake request with a default locale (used in translatable string)
$prophet = new \Prophecy\Prophet();
$request = $prophet->prophesize();
$request->willExtend(\Symfony\Component\HttpFoundation\Request::class);
$request->getLocale()->willReturn('fr');
$container->get('request_stack')
self::$container->get('request_stack')
->push($request->reveal());
}

View File

@@ -0,0 +1,75 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Filter;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Entity\ActivityType;
use Chill\ActivityBundle\Export\Filter\ActivityTypeFilter;
use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Doctrine\ORM\EntityManagerInterface;
/**
* @internal
* @coversNothing
*/
final class ActivityTypeFilterTest extends AbstractFilterTest
{
private ActivityTypeFilter $filter;
protected function setUp(): void
{
self::bootKernel();
$this->filter = self::$container->get('chill.activity.export.type_filter');
}
public function getFilter()
{
return $this->filter;
}
public function getFormData(): array
{
$em = self::$container->get(EntityManagerInterface::class);
$array = $em->createQueryBuilder()
->from(ActivityType::class, 'at')
->select('at')
->getQuery()
->getResult();
$data = [];
foreach ($array as $a) {
$data[] = [
'types' => $a,
];
}
return $data;
}
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from(Activity::class, 'activity'),
];
}
}

View File

@@ -0,0 +1,76 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Filter\PersonFilters;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\ActivityBundle\Export\Filter\PersonFilters\ActivityReasonFilter;
use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Doctrine\ORM\EntityManagerInterface;
/**
* @internal
* @coversNothing
*/
final class ActivityReasonFilterTest extends AbstractFilterTest
{
private ActivityReasonFilter $filter;
protected function setUp(): void
{
self::bootKernel();
$this->filter = self::$container->get('chill.activity.export.reason_filter');
}
public function getFilter()
{
return $this->filter;
}
public function getFormData(): array
{
$em = self::$container->get(EntityManagerInterface::class);
$array = $em->createQueryBuilder()
->from(ActivityReason::class, 'ar')
->select('ar')
->getQuery()
->getResult();
$data = [];
foreach ($array as $a) {
$data[] = [
'reasons' => $a,
];
}
return $data;
}
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from(Activity::class, 'activity')
->join('activity.reasons', 'actreasons'),
];
}
}

View File

@@ -0,0 +1,78 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Tests\Export\Filter\PersonFilters;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\ActivityBundle\Export\Filter\PersonFilters\PersonHavingActivityBetweenDateFilter;
use Chill\MainBundle\Test\Export\AbstractFilterTest;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
/**
* @internal
* @coversNothing
*/
final class PersonHavingActivityBetweenDateFilterTest extends AbstractFilterTest
{
private PersonHavingActivityBetweenDateFilter $filter;
protected function setUp(): void
{
self::bootKernel();
$this->filter = self::$container->get('chill.activity.export.person_having_an_activity_between_date_filter');
}
public function getFilter()
{
return $this->filter;
}
public function getFormData(): array
{
$em = self::$container->get(EntityManagerInterface::class);
$array = $em->createQueryBuilder()
->from(ActivityReason::class, 'ar')
->select('ar')
->getQuery()
->getResult();
$data = [];
foreach ($array as $a) {
$data[] = [
'date_from' => DateTime::createFromFormat('Y-m-d', '2021-07-01'),
'date_to' => DateTime::createFromFormat('Y-m-d', '2022-07-01'),
'reasons' => $a,
];
}
return $data;
}
public function getQueryBuilders(): array
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(activity.id)')
->from(Activity::class, 'activity'),
];
}
}

View File

@@ -11,6 +11,7 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Tests\Export\Filter;
use Chill\ActivityBundle\Export\Filter\PersonFilters\PersonHavingActivityBetweenDateFilter;
use Chill\MainBundle\Test\Export\AbstractFilterTest;
use DateTime;
use function array_slice;
@@ -21,27 +22,20 @@ use function array_slice;
*/
final class PersonHavingActivityBetweenDateFilterTest extends AbstractFilterTest
{
/**
* @var \Chill\PersonBundle\Export\Filter\PersonHavingActivityBetweenDateFilter
*/
private $filter;
private PersonHavingActivityBetweenDateFilter $filter;
protected function setUp(): void
{
self::bootKernel();
$container = self::$kernel->getContainer();
$this->filter = self::$container->get('chill.activity.export.person_having_an_activity_between_date_filter');
$this->filter = $container->get('chill.activity.export.'
. 'person_having_an_activity_between_date_filter');
$request = $this->prophesize()
->willExtend(\Symfony\Component\HttpFoundation\Request::class);
// add a fake request with a default locale (used in translatable string)
$prophet = new \Prophecy\Prophet();
$request = $prophet->prophesize();
$request->willExtend(\Symfony\Component\HttpFoundation\Request::class);
$request->getLocale()->willReturn('fr');
$container->get('request_stack')
self::$container->get('request_stack')
->push($request->reveal());
}

View File

@@ -188,7 +188,9 @@ final class ActivityTypeTest extends KernelTestCase
// map all the values in an array
$values = array_map(
static function ($choice) { return $choice->value; },
static function ($choice) {
return $choice->value;
},
$view['activity']['durationTime']->vars['choices']
);

View File

@@ -4,18 +4,15 @@ services:
autoconfigure: true
## Indicators
chill.activity.export.count_activity_linked_to_person:
class: Chill\ActivityBundle\Export\Export\LinkedToPerson\CountActivity
Chill\ActivityBundle\Export\Export\LinkedToPerson\CountActivity:
tags:
- { name: chill.export, alias: 'count_activity_linked_to_person' }
chill.activity.export.sum_activity_duration_linked_to_person:
class: Chill\ActivityBundle\Export\Export\LinkedToPerson\StatActivityDuration
Chill\ActivityBundle\Export\Export\LinkedToPerson\StatActivityDuration:
tags:
- { name: chill.export, alias: 'sum_activity_duration_linked_to_person' }
chill.activity.export.list_activity_linked_to_person:
class: Chill\ActivityBundle\Export\Export\LinkedToPerson\ListActivity
Chill\ActivityBundle\Export\Export\LinkedToPerson\ListActivity:
tags:
- { name: chill.export, alias: 'list_activity_linked_to_person' }
@@ -44,6 +41,12 @@ services:
tags:
- { name: chill.export, alias: 'avg_activity_visit_duration_linked_to_acp' }
Chill\ActivityBundle\Export\Export\LinkedToACP\ListActivity:
tags:
- { name: chill.export, alias: 'list_activity_acp'}
Chill\ActivityBundle\Export\Export\ListActivityHelper: ~
## Filters
chill.activity.export.type_filter:
class: Chill\ActivityBundle\Export\Filter\ActivityTypeFilter
@@ -55,6 +58,10 @@ services:
tags:
- { name: chill.export_filter, alias: 'activity_date_filter' }
Chill\ActivityBundle\Export\Filter\ActivityUsersFilter:
tags:
- { name: chill.export_filter, alias: 'activity_users_filter' }
chill.activity.export.reason_filter:
class: Chill\ActivityBundle\Export\Filter\PersonFilters\ActivityReasonFilter
tags:
@@ -67,15 +74,19 @@ services:
name: chill.export_filter
alias: 'activity_person_having_ac_bw_date_filter'
chill.activity.export.filter_activitytype:
class: Chill\ActivityBundle\Export\Filter\ACPFilters\ActivityTypeFilter
tags:
- { name: chill.export_filter, alias: 'accompanyingcourse_activitytype_filter' }
chill.activity.export.locationtype_filter:
class: Chill\ActivityBundle\Export\Filter\ACPFilters\LocationTypeFilter
tags:
- { name: chill.export_filter, alias: 'activity_locationtype_filter' }
chill.activity.export.byuser_filter: # TMS (M2M)
class: Chill\ActivityBundle\Export\Filter\ACPFilters\ByUserFilter
Chill\ActivityBundle\Export\Filter\ACPFilters\ByCreatorFilter:
tags:
- { name: chill.export_filter, alias: 'activity_byuser_filter' }
- { name: chill.export_filter, alias: 'activity_bycreator_filter' }
chill.activity.export.emergency_filter:
class: Chill\ActivityBundle\Export\Filter\ACPFilters\EmergencyFilter
@@ -107,16 +118,26 @@ services:
tags:
- { name: chill.export_filter, alias: 'activity_userscope_filter' }
Chill\ActivityBundle\Export\Filter\UsersJobFilter:
tags:
- { name: chill.export_filter, alias: 'activity_usersjob_filter' }
Chill\ActivityBundle\Export\Filter\UsersScopeFilter:
tags:
- { name: chill.export_filter, alias: 'activity_usersscope_filter' }
Chill\ActivityBundle\Export\Filter\ACPFilters\HasNoActivityFilter:
tags:
- { name: chill.export_filter, alias: 'accompanyingcourse_has_no_activity_filter' }
## Aggregators
chill.activity.export.reason_aggregator:
class: Chill\ActivityBundle\Export\Aggregator\PersonAggregators\ActivityReasonAggregator
Chill\ActivityBundle\Export\Aggregator\PersonAggregators\ActivityReasonAggregator:
tags:
- { name: chill.export_aggregator, alias: activity_reason_aggregator }
chill.activity.export.type_aggregator:
class: Chill\ActivityBundle\Export\Aggregator\ActivityTypeAggregator
Chill\ActivityBundle\Export\Aggregator\ActivityTypeAggregator:
tags:
- { name: chill.export_aggregator, alias: activity_type_aggregator }
- { name: chill.export_aggregator, alias: activity_common_type_aggregator }
chill.activity.export.user_aggregator:
class: Chill\ActivityBundle\Export\Aggregator\ActivityUserAggregator
@@ -133,10 +154,9 @@ services:
tags:
- { name: chill.export_aggregator, alias: activity_date_aggregator }
chill.activity.export.byuser_aggregator:
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\ByUserAggregator
Chill\ActivityBundle\Export\Aggregator\ACPAggregators\ByCreatorAggregator:
tags:
- { name: chill.export_aggregator, alias: activity_byuser_aggregator }
- { name: chill.export_aggregator, alias: activity_by_creator_aggregator }
chill.activity.export.bythirdparty_aggregator:
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\ByThirdpartyAggregator
@@ -153,7 +173,26 @@ services:
tags:
- { name: chill.export_aggregator, alias: activity_bysocialissue_aggregator }
chill.activity.export.userscope_aggregator:
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\UserScopeAggregator
Chill\ActivityBundle\Export\Aggregator\ACPAggregators\CreatorScopeAggregator:
tags:
- { name: chill.export_aggregator, alias: activity_userscope_aggregator }
- { name: chill.export_aggregator, alias: activity_creator_scope_aggregator }
Chill\ActivityBundle\Export\Aggregator\ActivityUsersAggregator:
tags:
- { name: chill.export_aggregator, alias: activity_users_aggregator }
Chill\ActivityBundle\Export\Aggregator\ActivityUsersScopeAggregator:
tags:
- { name: chill.export_aggregator, alias: activity_users_scope_aggregator }
Chill\ActivityBundle\Export\Aggregator\ActivityUsersJobAggregator:
tags:
- { name: chill.export_aggregator, alias: activity_users_job_aggregator }
Chill\ActivityBundle\Export\Aggregator\ACPAggregators\ByActivityNumberAggregator:
tags:
- { name: chill.export_aggregator, alias: accompanyingcourse_by_activity_number_aggregator }
Chill\ActivityBundle\Export\Aggregator\SentReceivedAggregator:
tags:
- { name: chill.export_aggregator, alias: activity_sentreceived_aggregator }

View File

@@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\Migrations\Activity;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20221014130554 extends AbstractMigration
{
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE activity DROP updatedAt');
$this->addSql('ALTER TABLE activity DROP createdAt');
$this->addSql('ALTER TABLE activity DROP updatedBy_id');
$this->addSql('ALTER TABLE activity DROP createdBy_id');
// rename some indexes on activity
$this->addSql('ALTER INDEX idx_ac74095a217bbb47 RENAME TO idx_55026b0c217bbb47');
$this->addSql('ALTER INDEX idx_ac74095a682b5931 RENAME TO idx_55026b0c682b5931');
$this->addSql('ALTER INDEX idx_ac74095aa76ed395 RENAME TO idx_55026b0ca76ed395');
$this->addSql('ALTER INDEX idx_ac74095ac54c8c93 RENAME TO idx_55026b0cc54c8c93');
}
public function getDescription(): string
{
return 'Track update and create on activity';
}
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE activity ADD updatedAt TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL');
$this->addSql('ALTER TABLE activity ADD createdAt TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL');
$this->addSql('ALTER TABLE activity ADD updatedBy_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE activity ADD createdBy_id INT DEFAULT NULL');
$this->addSql('COMMENT ON COLUMN activity.updatedAt IS \'(DC2Type:datetime_immutable)\'');
$this->addSql('COMMENT ON COLUMN activity.createdAt IS \'(DC2Type:datetime_immutable)\'');
$this->addSql('ALTER TABLE activity ADD CONSTRAINT FK_AC74095A65FF1AEC FOREIGN KEY (updatedBy_id) REFERENCES users (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE activity ADD CONSTRAINT FK_AC74095A3174800F FOREIGN KEY (createdBy_id) REFERENCES users (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE INDEX IDX_AC74095A65FF1AEC ON activity (updatedBy_id)');
$this->addSql('CREATE INDEX IDX_AC74095A3174800F ON activity (createdBy_id)');
// rename some indexes on activity
$this->addSql('ALTER INDEX idx_55026b0cc54c8c93 RENAME TO IDX_AC74095AC54C8C93');
$this->addSql('ALTER INDEX idx_55026b0c217bbb47 RENAME TO IDX_AC74095A217BBB47');
$this->addSql('ALTER INDEX idx_55026b0c682b5931 RENAME TO IDX_AC74095A682B5931');
$this->addSql('ALTER INDEX idx_55026b0ca76ed395 RENAME TO IDX_AC74095AA76ED395');
$this->addSql('UPDATE activity SET updatedBy_id=user_id, createdBy_id=user_id, createdAt="date", updatedAt="date"');
}
}

View File

@@ -45,6 +45,8 @@ by: 'Par '
location: Lieu
Reasons: Sujets
Private comment: Commentaire privé
sent: Envoyé
received: Reçu
#forms
@@ -119,15 +121,15 @@ Activity Presences: Presences aux activités
# Crud
crud:
activity_type:
title_new: Nouveau type d'activité
title_edit: Edition d'un type d'activité
activity_type_category:
title_new: Nouvelle catégorie de type d'activité
title_edit: Edition d'une catégorie de type d'activité
activity_presence:
title_new: Nouvelle Présence aux activités
title_edit: Edition d'une Présence aux activités
activity_type:
title_new: Nouveau type d'activité
title_edit: Edition d'un type d'activité
activity_type_category:
title_new: Nouvelle catégorie de type d'activité
title_edit: Edition d'une catégorie de type d'activité
activity_presence:
title_new: Nouvelle Présence aux activités
title_edit: Edition d'une Présence aux activités
# activity reason admin
ActivityReason list: Liste des sujets
@@ -252,8 +254,6 @@ Filter by activity type: Filtrer les activités par type
Filter activity by locationtype: Filtrer les activités par type de localisation
'Filtered activity by locationtype: only %types%': "Filtré par type de localisation: uniquement %types%"
Accepted locationtype: Types de localisation
Filter activity by linked users: Filtrer les activités par TMS
'Filtered activity by linked users: only %users%': "Filtré par TMS: uniquement %users%"
Accepted users: TMS(s)
Filter activity by emergency: Filtrer les activités par urgence
'Filtered activity by emergency: only %emergency%': "Filtré par urgence: uniquement si %emergency%"
@@ -262,18 +262,24 @@ activity is not emergency: l'activité n'est pas urgente
Filter activity by sentreceived: Filtrer les activités par envoyé/reçu
'Filtered activity by sentreceived: only %sentreceived%': "Filtré par envoyé/reçu: uniquement %sentreceived%"
Accepted sentreceived: ''
is sent: envoyé
is received: reçu
Filter activity by linked socialaction: Filtrer les activités par action liée
'Filtered activity by linked socialaction: only %actions%': "Filtré par action liée: uniquement %actions%"
Filter activity by linked socialissue: Filtrer les activités par problématique liée
'Filtered activity by linked socialissue: only %issues%': "Filtré par problématique liée: uniquement %issues%"
Filter activity by user: Filtrer les activités par créateur
'Filtered activity by user: only %users%': "Filtré par créateur: uniquement %users%"
Filter activity by users: Filtrer les activités par utilisateur participant
Filter activity by creator: Filtrer les activités par créateur de l'échange
'Filtered activity by user: only %users%': "Filtré par référent: uniquement %users%"
'Filtered activity by users: only %users%': "Filtré par utilisateurs participants: uniquement %users%"
'Filtered activity by creator: only %users%': "Filtré par créateur: uniquement %users%"
Creators: Créateurs
Filter activity by userscope: Filtrer les activités par service du créateur
'Filtered activity by userscope: only %scopes%': "Filtré par service du créateur: uniquement %scopes%"
Accepted userscope: Services
Filter acp which has no activity: Filtrer les parcours qui nont pas dactivité
Filtered acp which has no activities: Filtrer les parcours sans activité associée
Group acp by activity number: Grouper les parcours par nombre dactivité
#aggregators
Activity type: Type d'activité
@@ -282,9 +288,14 @@ By reason: Par sujet
By category of reason: Par catégorie de sujet
Reason's level: Niveau du sujet
Group by reasons: Sujet d'activité
Aggregate by activity user: Grouper les activités par utilisateur
Aggregate by activity user: Grouper les activités par référent
Aggregate by activity users: Grouper les activités par utilisateurs participants
Aggregate by activity type: Grouper les activités par type
Aggregate by activity reason: Grouper les activités par sujet
Aggregate by users scope: Grouper les activités par service principal de l'utilisateur
Users 's scope: Service principal des utilisateurs participants à l'activité
Aggregate by users job: Grouper les activités par métier des utilisateurs participants
Users 's job: Métier des utilisateurs participants à l'activité
Group activity by locationtype: Grouper les activités par type de localisation
Group activity by date: Grouper les activités par date
@@ -294,7 +305,8 @@ by week: Par semaine
for week: Semaine
by year: Par année
in year: En
Group activity by linked users: Grouper les activités par TMS impliqué
Group activity by creator: Grouper les activités par créateur de l'échange
Group activity by creator scope: Grouper les activités par service du créateur de l'échange
Group activity by linked thirdparties: Grouper les activités par tiers impliqué
Accepted thirdparty: Tiers impliqué
Group activity by linked socialaction: Grouper les activités par action liée
@@ -314,3 +326,41 @@ docgen:
A basic context for activity: Contexte pour les activités
Accompanying period with a list of activities: Parcours d'accompagnement avec liste des activités
Accompanying period with a list of activities description: Ce contexte reprend les informations du parcours, et tous les activités pour un parcours. Les activités ne sont pas filtrés.
export:
list:
activity:
users name: Nom des utilisateurs
users ids: Identifiant des utilisateurs
third parties ids: Identifiant des tiers
persons ids: Identifiant des personnes
persons name: Nom des personnes
thirds parties: Tiers
date: Date de l'activité
locationName: Localisation
sent received: Envoyé ou reçu
emergency: Urgence
accompanying course id: Identifiant du parcours
course circles: Cercles du parcours
travelTime: Durée de déplacement
durationTime: Durée
id: Identifiant
List activities linked to an accompanying course: Liste les activités liées à un parcours en fonction de différents filtres.
List activity linked to a course: Liste des activités liées à un parcours
filter:
activity:
by_usersjob:
Filter by users job: Filtrer les activités par métier d'au moins un utilisateur participant
'Filtered activity by users job: only %jobs%': 'Filtré par métier d''au moins un utilisateur participant: seulement %jobs%'
by_usersscope:
Filter by users scope: Filtrer les activités par services d'au moins un utilisateur participant
'Filtered activity by users scope: only %scopes%': 'Filtré par service d''au moins un utilisateur participant: seulement %scopes%'
aggregator:
activity:
by_sent_received:
Sent or received: Envoyé ou reçu
is sent: envoyé
is received: reçu
Group activity by sentreceived: Grouper les activités par envoyé / reçu