mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
add docgen context for a list of activities in a course
This commit is contained in:
parent
4257a918f3
commit
bb65909bfa
@ -12,13 +12,21 @@ declare(strict_types=1);
|
||||
namespace Chill\ActivityBundle\Repository;
|
||||
|
||||
use Chill\ActivityBundle\Entity\Activity;
|
||||
use Chill\ActivityBundle\Entity\ActivityPresence;
|
||||
use Chill\ActivityBundle\Entity\ActivityType;
|
||||
use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
|
||||
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
|
||||
use Chill\MainBundle\Entity\Location;
|
||||
use Chill\MainBundle\Entity\LocationType;
|
||||
use Chill\MainBundle\Entity\Scope;
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||
use Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\AbstractQuery;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Query\ResultSetMappingBuilder;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
@ -72,6 +80,87 @@ final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInte
|
||||
->findByAccompanyingPeriod($period, $scopes, true, $limit, $start, $orderBy);
|
||||
}
|
||||
|
||||
public function findByAccompanyingPeriodSimplified(AccompanyingPeriod $period, ?int $limit = 1000): array
|
||||
{
|
||||
$rsm = new ResultSetMappingBuilder($this->em);
|
||||
|
||||
$sql = "
|
||||
SELECT
|
||||
a.id AS activity_id,
|
||||
date,
|
||||
CASE WHEN durationtime IS NOT NULL THEN (EXTRACT(EPOCH from durationtime) / 60)::int ELSE 0 END AS durationtimeminute,
|
||||
attendee_id,
|
||||
comment_comment,
|
||||
emergency,
|
||||
sentreceived,
|
||||
CASE WHEN traveltime IS NOT NULL THEN (EXTRACT(EPOCH from traveltime) / 60)::int ELSE 0 END AS traveltimeminute,
|
||||
t.id AS type_id, t.name as type_name,
|
||||
p.id AS presence_id, p.name AS presence_name,
|
||||
location.id AS location_id, location.address_id, location.name AS location_name, location.phonenumber1, location.phonenumber2, location.email,
|
||||
location.locationtype_id, locationtype.title AS locationtype_title,
|
||||
users.userids AS userids,
|
||||
thirdparties.thirdpartyids,
|
||||
persons.personids,
|
||||
actions.socialactionids,
|
||||
issues.socialissueids
|
||||
|
||||
FROM activity a
|
||||
LEFT JOIN chill_main_location location ON a.location_id = location.id
|
||||
LEFT JOIN chill_main_location_type locationtype ON location.locationtype_id = locationtype.id
|
||||
LEFT JOIN activitytpresence p ON a.attendee_id = p.id
|
||||
LEFT JOIN activitytype t ON a.type_id = t.id
|
||||
LEFT JOIN LATERAL (SELECT jsonb_agg(user_id) userids, activity_id FROM activity_user AS au WHERE a.id = au.activity_id GROUP BY activity_id) AS users ON TRUE
|
||||
LEFT JOIN LATERAL (SELECT jsonb_agg(thirdparty_id) thirdpartyids, activity_id FROM activity_thirdparty AS au WHERE a.id = au.activity_id GROUP BY activity_id) AS thirdparties ON TRUE
|
||||
LEFT JOIN LATERAL (SELECT jsonb_agg(person_id) personids, activity_id FROM activity_person AS au WHERE a.id = au.activity_id GROUP BY activity_id) AS persons ON TRUE
|
||||
LEFT JOIN LATERAL (SELECT jsonb_agg(socialaction_id) socialactionids, activity_id FROM postgres.public.chill_activity_activity_chill_person_socialaction AS au WHERE a.id = au.activity_id GROUP BY activity_id) AS actions ON TRUE
|
||||
LEFT JOIN LATERAL (SELECT jsonb_agg(socialissue_id) socialissueids, activity_id FROM postgres.public.chill_activity_activity_chill_person_socialissue AS au WHERE a.id = au.activity_id GROUP BY activity_id) AS issues ON TRUE
|
||||
|
||||
WHERE accompanyingperiod_id = ?
|
||||
ORDER BY a.date DESC, a.id DESC
|
||||
LIMIT ?
|
||||
";
|
||||
|
||||
$rsm
|
||||
->addEntityResult(Activity::class, 'a')
|
||||
->addFieldResult('a', 'activity_id', 'id')
|
||||
->addFieldResult('a', 'date', 'date')
|
||||
->addFieldResult('a', 'comment', 'comment')
|
||||
->addFieldResult('a', 'sentreceived', 'sentReceived')
|
||||
->addFieldResult('a', 'emergency', 'emergency')
|
||||
->addJoinedEntityResult(Location::class, 'location', 'a', 'location')
|
||||
->addFieldResult('location', 'location_id', 'id')
|
||||
->addFieldResult('location', 'location_name', 'name')
|
||||
->addFieldResult('location', 'phonenumber1', 'phonenumber1')
|
||||
->addFieldResult('location', 'phonenumber2', 'phonenumber2')
|
||||
->addFieldResult('location', 'email', 'email')
|
||||
->addJoinedEntityResult(LocationType::class,'locationType', 'location', 'locationType' )
|
||||
->addFieldResult('locationType', 'locationtype_id', 'id')
|
||||
->addFieldResult('locationType', 'locationtype_title', 'title')
|
||||
->addJoinedEntityResult(ActivityType::class, 'activityType', 'a', 'activityType')
|
||||
->addFieldResult('activityType', 'type_id', 'id')
|
||||
->addFieldResult('activityType', 'type_name', 'name')
|
||||
->addJoinedEntityResult(ActivityPresence::class, 'activityPresence', 'a', 'attendee')
|
||||
->addFieldResult('activityPresence', 'presence_id', 'id')
|
||||
->addFieldResult('activityPresence', 'presence_name', 'name')
|
||||
|
||||
// results which cannot be mapped into entity
|
||||
->addScalarResult('comment_comment', 'comment', Types::TEXT)
|
||||
->addScalarResult('userids', 'userIds', Types::JSON)
|
||||
->addScalarResult('thirdpartyids', 'thirdPartyIds', Types::JSON)
|
||||
->addScalarResult('personids', 'personIds', Types::JSON)
|
||||
->addScalarResult('socialactionids', 'socialActionIds', Types::JSON)
|
||||
->addScalarResult('socialissueids', 'socialIssueIds', Types::JSON)
|
||||
->addScalarResult('durationtimeminute', 'durationTimeMinute', Types::INTEGER)
|
||||
->addScalarResult('traveltimeminute', 'travelTimeMinute', Types::INTEGER)
|
||||
;
|
||||
|
||||
$nq = $this->em->createNativeQuery($sql, $rsm);
|
||||
|
||||
$nq->setParameter(0, $period->getId())->setParameter(1, $limit);
|
||||
|
||||
return $nq->getResult(AbstractQuery::HYDRATE_ARRAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $orderBy
|
||||
*
|
||||
|
@ -21,6 +21,19 @@ interface ActivityACLAwareRepositoryInterface
|
||||
*/
|
||||
public function findByAccompanyingPeriod(AccompanyingPeriod $period, string $role, ?int $start = 0, ?int $limit = 1000, ?array $orderBy = []): array;
|
||||
|
||||
/**
|
||||
* Return a list of activities, simplified as array (not object).
|
||||
*
|
||||
* The aim of this method is to get a long list of activities and keep performance.
|
||||
*
|
||||
* @param AccompanyingPeriod $period
|
||||
* @param string $role
|
||||
* @param int|null $limit
|
||||
* @param array|null $orderBy
|
||||
* @return array an array of array, each item representing an activity
|
||||
*/
|
||||
public function findByAccompanyingPeriodSimplified(AccompanyingPeriod $period, ?int $limit = 1000): array;
|
||||
|
||||
/**
|
||||
* @return Activity[]|array
|
||||
*/
|
||||
|
@ -0,0 +1,276 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\ActivityBundle\Service\DocGenerator;
|
||||
|
||||
use Chill\ActivityBundle\Entity\ActivityPresence;
|
||||
use Chill\ActivityBundle\Entity\ActivityType;
|
||||
use Chill\ActivityBundle\Repository\ActivityACLAwareRepositoryInterface;
|
||||
use Chill\DocGeneratorBundle\Context\DocGeneratorContextWithAdminFormInterface;
|
||||
use Chill\DocGeneratorBundle\Context\DocGeneratorContextWithPublicFormInterface;
|
||||
use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate;
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\MainBundle\Entity\Location;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Repository\UserRepository;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
||||
use Chill\PersonBundle\Repository\PersonRepository;
|
||||
use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository;
|
||||
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
|
||||
use Chill\PersonBundle\Service\DocGenerator\AccompanyingPeriodContext;
|
||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
|
||||
use libphonenumber\PhoneNumber;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
|
||||
class ListActivitiesByAccompanyingPeriodContext implements
|
||||
DocGeneratorContextWithAdminFormInterface,
|
||||
DocGeneratorContextWithPublicFormInterface
|
||||
{
|
||||
private AccompanyingPeriodContext $accompanyingPeriodContext;
|
||||
|
||||
private ActivityACLAwareRepositoryInterface $activityACLAwareRepository;
|
||||
|
||||
private NormalizerInterface $normalizer;
|
||||
|
||||
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||
|
||||
private PersonRepository $personRepository;
|
||||
|
||||
private SocialActionRepository $socialActionRepository;
|
||||
|
||||
private SocialIssueRepository $socialIssueRepository;
|
||||
|
||||
private UserRepository $userRepository;
|
||||
|
||||
private ThirdPartyRepository $thirdPartyRepository;
|
||||
|
||||
public function __construct(
|
||||
AccompanyingPeriodContext $accompanyingPeriodContext,
|
||||
ActivityACLAwareRepositoryInterface $activityACLAwareRepository,
|
||||
NormalizerInterface $normalizer,
|
||||
PersonRepository $personRepository,
|
||||
SocialActionRepository $socialActionRepository,
|
||||
SocialIssueRepository $socialIssueRepository,
|
||||
ThirdPartyRepository $thirdPartyRepository,
|
||||
TranslatableStringHelperInterface $translatableStringHelper,
|
||||
UserRepository $userRepository
|
||||
) {
|
||||
$this->accompanyingPeriodContext = $accompanyingPeriodContext;
|
||||
$this->activityACLAwareRepository = $activityACLAwareRepository;
|
||||
$this->normalizer = $normalizer;
|
||||
$this->personRepository = $personRepository;
|
||||
$this->socialActionRepository = $socialActionRepository;
|
||||
$this->socialIssueRepository = $socialIssueRepository;
|
||||
$this->thirdPartyRepository = $thirdPartyRepository;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
$this->userRepository = $userRepository;
|
||||
}
|
||||
|
||||
public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array
|
||||
{
|
||||
$data = $this->accompanyingPeriodContext->getData($template, $entity, $contextGenerationData);
|
||||
|
||||
$data['activities'] = $this->getActivitiesSimplified($entity);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function getActivitiesSimplified(AccompanyingPeriod $period)
|
||||
{
|
||||
$activities =
|
||||
$this->activityACLAwareRepository->findByAccompanyingPeriodSimplified($period);
|
||||
$results = [];
|
||||
|
||||
foreach ($activities as $row) {
|
||||
$activity = $row[0];
|
||||
|
||||
$activity['date'] = $this->normalizer->normalize($activity['date'], 'docgen', [
|
||||
AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => \DateTime::class
|
||||
]);
|
||||
|
||||
if (null === $activity['location']) {
|
||||
$activity['location'] = $this->normalizer->normalize(null, 'docgen', [
|
||||
AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => Location::class
|
||||
]);
|
||||
$activity['location']['type'] = 'location';
|
||||
} else {
|
||||
$activity['location']['isNull'] = false;
|
||||
$activity['location']['type'] = 'location';
|
||||
foreach (['1', '2'] as $key) {
|
||||
$activity['location']['phonenumber'.$key] = $this->normalizer->normalize(
|
||||
$activity['location']['phonenumber'.$key],
|
||||
'docgen',
|
||||
[AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => PhoneNumber::class]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_numeric($activity['location']['locationType']['id'])) {
|
||||
$activity['location']['locationType']['title'] = $this->translatableStringHelper->localize(
|
||||
$activity['location']['locationType']['title']
|
||||
);
|
||||
$activity['location']['locationType']['isNull'] = false;
|
||||
$activity['location']['locationType']['type'] = 'locationType';
|
||||
}
|
||||
|
||||
if (null !== $activity['activityType']) {
|
||||
$activity['activityType']['name'] = $this->translatableStringHelper->localize(
|
||||
$activity['activityType']['name']
|
||||
);
|
||||
$activity['activityType']['isNull'] = false;
|
||||
$activity['activityType']['type'] = 'activityType';
|
||||
} else {
|
||||
$activity['activityType'] = $this->normalizer->normalize(null, 'docgen', [
|
||||
AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => ActivityType::class
|
||||
]);
|
||||
}
|
||||
|
||||
if (null !== $activity['attendee']) {
|
||||
$activity['attendee']['name'] = $this->translatableStringHelper->localize(
|
||||
$activity['attendee']['name']
|
||||
);
|
||||
$activity['attendee']['isNull'] = false;
|
||||
$activity['attendee']['type'] = 'activityPresence';
|
||||
} else {
|
||||
$activity['attendee'] = $this->normalizer->normalize(null, 'docgen', [
|
||||
AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => ActivityPresence::class
|
||||
]);
|
||||
}
|
||||
|
||||
$activity['comment'] = (string) $row['comment'];
|
||||
$activity['travelTimeMinute'] = $row['travelTimeMinute'];
|
||||
$activity['durationTimeMinute'] = $row['durationTimeMinute'];
|
||||
|
||||
if (null !== $row['userIds']) {
|
||||
foreach ($row['userIds'] as $id) {
|
||||
$activity['users'][] = $this->normalizer->normalize(
|
||||
$this->userRepository->find($id),
|
||||
'docgen',
|
||||
[AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => User::class]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$activity['users'] = [];
|
||||
}
|
||||
|
||||
if (null !== $row['personIds']) {
|
||||
foreach ($row['personIds'] as $id) {
|
||||
$activity['persons'][] = $this->normalizer->normalize(
|
||||
$this->personRepository->find($id),
|
||||
'docgen',
|
||||
[AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => Person::class]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$activity['persons'] = [];
|
||||
}
|
||||
|
||||
if (null !== $row['thirdPartyIds']) {
|
||||
foreach ($row['thirdPartyIds'] as $id) {
|
||||
$activity['thirdParties'][] = $this->normalizer->normalize(
|
||||
$this->thirdPartyRepository->find($id),
|
||||
'docgen',
|
||||
[AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => ThirdParty::class]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$activity['thirdParties'] = [];
|
||||
}
|
||||
|
||||
if (null !== $row['socialActionIds']) {
|
||||
foreach ($row['socialActionIds'] as $id) {
|
||||
$activity['socialActions'][] = $this->normalizer->normalize(
|
||||
$this->socialActionRepository->find($id),
|
||||
'docgen',
|
||||
[AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => SocialAction::class]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$activity['socialActions'] = [];
|
||||
}
|
||||
|
||||
if (null !== $row['socialIssueIds']) {
|
||||
foreach ($row['socialIssueIds'] as $id) {
|
||||
$activity['socialIssues'][] = $this->normalizer->normalize(
|
||||
$this->socialIssueRepository->find($id),
|
||||
'docgen',
|
||||
[AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => SocialIssue::class]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$activity['socialIssues'] = [];
|
||||
}
|
||||
|
||||
$results[] = $activity;
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'docgen.Accompanying period with a list of activities description';
|
||||
}
|
||||
|
||||
public function getEntityClass(): string
|
||||
{
|
||||
return AccompanyingPeriod::class;
|
||||
}
|
||||
|
||||
public static function getKey(): string
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return 'docgen.Accompanying period with a list of activities';
|
||||
}
|
||||
|
||||
public function storeGenerated(DocGeneratorTemplate $template, StoredObject $storedObject, object $entity, array $contextGenerationData): void
|
||||
{
|
||||
$this->accompanyingPeriodContext->storeGenerated($template, $storedObject, $entity, $contextGenerationData);
|
||||
}
|
||||
|
||||
public function adminFormReverseTransform(array $data): array
|
||||
{
|
||||
return $this->accompanyingPeriodContext->adminFormReverseTransform($data);
|
||||
}
|
||||
|
||||
public function adminFormTransform(array $data): array
|
||||
{
|
||||
return $this->accompanyingPeriodContext->adminFormTransform($data);
|
||||
}
|
||||
|
||||
public function buildAdminForm(FormBuilderInterface $builder): void
|
||||
{
|
||||
$this->accompanyingPeriodContext->buildAdminForm($builder);
|
||||
}
|
||||
|
||||
public function hasAdminForm(): bool
|
||||
{
|
||||
return $this->accompanyingPeriodContext->hasAdminForm();
|
||||
}
|
||||
|
||||
public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void
|
||||
{
|
||||
$this->accompanyingPeriodContext->buildPublicForm($builder, $template, $entity);
|
||||
}
|
||||
|
||||
public function getFormData(DocGeneratorTemplate $template, $entity): array
|
||||
{
|
||||
return $this->accompanyingPeriodContext->getFormData($template, $entity);
|
||||
}
|
||||
|
||||
public function hasPublicForm(DocGeneratorTemplate $template, $entity): bool
|
||||
{
|
||||
return $this->accompanyingPeriodContext->hasPublicForm($template, $entity);
|
||||
}
|
||||
|
||||
}
|
@ -232,3 +232,5 @@ This is the minimal activity data: Activité n°
|
||||
docgen:
|
||||
Activity basic: Echange
|
||||
A basic context for activity: Contexte pour les échanges
|
||||
Accompanying period with a list of activities: Parcours d'accompagnement avec liste des échanges
|
||||
Accompanying period with a list of activities description: Ce contexte reprend les informations du parcours, et tous les échanges pour un parcours. Les échanges ne sont pas filtrés.
|
||||
|
Loading…
x
Reference in New Issue
Block a user