Export: split export about person on accompanying period work: one with the

people associated with the work, another one with the people associated with the
  accompanying period
This commit is contained in:
2023-11-10 18:01:13 +01:00
parent 0d741ab886
commit 2cc5fa06ae
11 changed files with 691 additions and 24 deletions

View File

@@ -25,7 +25,7 @@ use Doctrine\ORM\QueryBuilder;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Form\FormBuilderInterface;
class CountAccompanyingPeriodWork implements ExportInterface, GroupedExportInterface
class CountAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriod implements ExportInterface, GroupedExportInterface
{
private readonly bool $filterStatsByCenters;
@@ -53,7 +53,7 @@ class CountAccompanyingPeriodWork implements ExportInterface, GroupedExportInter
public function getDescription(): string
{
return 'Count social work actions by various parameters';
return 'export.export.count_accompanying_period_work_associate_person.description';
}
public function getGroup(): string
@@ -68,7 +68,7 @@ class CountAccompanyingPeriodWork implements ExportInterface, GroupedExportInter
}
$labels = array_combine($values, $values);
$labels['_header'] = $this->getTitle();
$labels['_header'] = 'export.export.count_accompanying_period_work_associate_person.header';
return static fn ($value) => $labels[$value];
}
@@ -85,7 +85,7 @@ class CountAccompanyingPeriodWork implements ExportInterface, GroupedExportInter
public function getTitle(): string
{
return 'Count social work actions';
return 'export.export.count_accompanying_period_work_associate_person.title';
}
public function getType(): string

View File

@@ -0,0 +1,139 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Export\Export;
use Chill\MainBundle\Export\AccompanyingCourseExportHelper;
use Chill\MainBundle\Export\ExportInterface;
use Chill\MainBundle\Export\FormatterInterface;
use Chill\MainBundle\Export\GroupedExportInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person\PersonCenterHistory;
use Chill\PersonBundle\Export\Declarations;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Form\FormBuilderInterface;
class CountAccompanyingPeriodWorkAssociatePersonOnWork implements ExportInterface, GroupedExportInterface
{
private readonly bool $filterStatsByCenters;
public function __construct(
protected EntityManagerInterface $em,
ParameterBagInterface $parameterBag,
) {
$this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
}
public function buildForm(FormBuilderInterface $builder): void
{
// No form necessary?
}
public function getFormDefaultData(): array
{
return [];
}
public function getAllowedFormattersTypes(): array
{
return [FormatterInterface::TYPE_TABULAR];
}
public function getDescription(): string
{
return 'export.export.count_accompanying_period_work_associate_work.description';
}
public function getGroup(): string
{
return 'Exports of social work actions';
}
public function getLabels($key, array $values, $data)
{
if ('export_result' !== $key) {
throw new \LogicException("the key {$key} is not used by this export");
}
$labels = array_combine($values, $values);
$labels['_header'] = 'export.export.count_accompanying_period_work_associate_work.header';
return static fn ($value) => $labels[$value];
}
public function getQueryKeys($data): array
{
return ['export_result'];
}
public function getResult($query, $data)
{
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
public function getTitle(): string
{
return 'export.export.count_accompanying_period_work_associate_work.title';
}
public function getType(): string
{
return Declarations::SOCIAL_WORK_ACTION_TYPE;
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = []): QueryBuilder
{
$centers = array_map(static fn ($el) => $el['center'], $acl);
$qb = $this->em->createQueryBuilder();
$qb
->from(AccompanyingPeriod\AccompanyingPeriodWork::class, 'acpw')
->join('acpw.accompanyingPeriod', 'acp')
->join('acpw.persons', 'person');
if ($this->filterStatsByCenters) {
$qb
->andWhere(
$qb->expr()->exists(
'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person
AND acl_count_person_history.center IN (:authorized_centers)
'
)
)
->setParameter('authorized_centers', $centers);
}
$qb->select('COUNT(DISTINCT acpw.id) as export_result');
AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb);
return $qb;
}
public function requiredRole(): string
{
return AccompanyingPeriodVoter::STATS;
}
public function supportsModifiers(): array
{
return [
Declarations::SOCIAL_WORK_ACTION_TYPE,
Declarations::ACP_TYPE,
Declarations::PERSON_TYPE,
];
}
}

View File

@@ -47,7 +47,7 @@ use Doctrine\ORM\QueryBuilder;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Form\FormBuilderInterface;
class ListAccompanyingPeriodWork implements ListInterface, GroupedExportInterface
class ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriod implements ListInterface, GroupedExportInterface
{
private const FIELDS = [
'id',
@@ -121,7 +121,7 @@ class ListAccompanyingPeriodWork implements ListInterface, GroupedExportInterfac
public function getDescription(): string
{
return 'export.list.acpw.List description';
return 'export.list.acpw_associate_period.List description';
}
public function getGroup(): string
@@ -190,12 +190,12 @@ class ListAccompanyingPeriodWork implements ListInterface, GroupedExportInterfac
public function getResult($query, $data)
{
return dump($query->getQuery()->getResult(AbstractQuery::HYDRATE_SCALAR));
return $query->getQuery()->getResult(AbstractQuery::HYDRATE_SCALAR);
}
public function getTitle(): string
{
return 'export.list.acpw.List of accompanying period works';
return 'export.list.acpw_associate_period.List of accompanying period works';
}
public function getType(): string

View File

@@ -0,0 +1,348 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Export\Export;
use Chill\MainBundle\Export\AccompanyingCourseExportHelper;
use Chill\MainBundle\Export\FormatterInterface;
use Chill\MainBundle\Export\GroupedExportInterface;
use Chill\MainBundle\Export\Helper\AggregateStringHelper;
use Chill\MainBundle\Export\Helper\DateTimeHelper;
use Chill\MainBundle\Export\Helper\TranslatableStringExportLabelHelper;
use Chill\MainBundle\Export\Helper\UserHelper;
use Chill\MainBundle\Export\ListInterface;
use Chill\MainBundle\Form\Type\PickRollingDateType;
use Chill\MainBundle\Service\RollingDate\RollingDate;
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkGoal;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkReferrerHistory;
use Chill\PersonBundle\Entity\AccompanyingPeriod\UserHistory;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\Person\PersonCenterHistory;
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
use Chill\PersonBundle\Entity\SocialWork\Goal;
use Chill\PersonBundle\Entity\SocialWork\Result;
use Chill\PersonBundle\Export\Declarations;
use Chill\PersonBundle\Export\Helper\LabelPersonHelper;
use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository;
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Chill\ThirdPartyBundle\Export\Helper\LabelThirdPartyHelper;
use Doctrine\ORM\AbstractQuery;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Form\FormBuilderInterface;
class ListAccompanyingPeriodWorkAssociatePersonOnWork implements ListInterface, GroupedExportInterface
{
private const FIELDS = [
'id',
'socialActionId',
'socialAction',
'socialIssue',
'acp_id',
'acp_user',
'startDate',
'endDate',
'goalsId',
'goalsTitle',
'goalResultsId',
'goalResultsTitle',
'resultsId',
'resultsTitle',
'evaluationsId',
'evaluationsTitle',
'note',
'personsId',
'personsName',
'thirdParties',
'handlingThierParty',
// 'acpwReferrers',
'referrers',
'createdAt',
'createdBy',
'updatedAt',
'updatedBy',
];
private readonly bool $filterStatsByCenters;
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly DateTimeHelper $dateTimeHelper,
private readonly UserHelper $userHelper,
private readonly LabelPersonHelper $personHelper,
private readonly LabelThirdPartyHelper $thirdPartyHelper,
private readonly TranslatableStringExportLabelHelper $translatableStringExportLabelHelper,
private readonly SocialIssueRender $socialIssueRender,
private readonly SocialIssueRepository $socialIssueRepository,
private readonly SocialActionRender $socialActionRender,
private readonly RollingDateConverterInterface $rollingDateConverter,
private readonly AggregateStringHelper $aggregateStringHelper,
private readonly SocialActionRepository $socialActionRepository,
ParameterBagInterface $parameterBag,
) {
$this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
}
public function buildForm(FormBuilderInterface $builder)
{
$builder
->add('calc_date', PickRollingDateType::class, [
'label' => 'export.list.acpw.Date of calculation for associated elements',
'help' => 'export.list.acpw.help_description',
'required' => true,
]);
}
public function getFormDefaultData(): array
{
return ['calc_date' => new RollingDate(RollingDate::T_TODAY)];
}
public function getAllowedFormattersTypes()
{
return [FormatterInterface::TYPE_LIST];
}
public function getDescription(): string
{
return 'export.list.acpw_associate_work.List description';
}
public function getGroup(): string
{
return 'Exports of social work actions';
}
public function getLabels($key, array $values, $data)
{
return match ($key) {
'startDate', 'endDate', 'createdAt', 'updatedAt' => $this->dateTimeHelper->getLabel('export.list.acpw.'.$key),
'socialAction' => function ($value) use ($key) {
if ('_header' === $value) {
return 'export.list.acpw.'.$key;
}
if (null === $value) {
return '';
}
return $this->socialActionRender->renderString(
$this->socialActionRepository->find($value),
[]
);
},
'socialIssue' => function ($value) use ($key) {
if ('_header' === $value) {
return 'export.list.acpw.'.$key;
}
if (null === $value) {
return '';
}
return $this->socialIssueRender->renderString(
$this->socialIssueRepository->find($value),
[]
);
},
'createdBy', 'updatedBy', 'acp_user' => $this->userHelper->getLabel($key, $values, 'export.list.acpw.'.$key),
'referrers' => $this->userHelper->getLabel($key, $values, 'export.list.acpw.'.$key),
// 'acpwReferrers' => $this->userHelper->getLabelMulti($key, $values, 'export.list.acpw.' . $key),
'personsName' => $this->personHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key),
'handlingThierParty' => $this->thirdPartyHelper->getLabel($key, $values, 'export.list.acpw.'.$key),
'thirdParties' => $this->thirdPartyHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key),
'personsId', 'goalsId', 'goalResultsId', 'resultsId', 'evaluationsId' => $this->aggregateStringHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key),
'goalsTitle', 'goalResultsTitle', 'resultsTitle', 'evaluationsTitle' => $this->translatableStringExportLabelHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key),
default => static function ($value) use ($key) {
if ('_header' === $value) {
return 'export.list.acpw.'.$key;
}
if (null === $value) {
return '';
}
return $value;
},
};
}
public function getQueryKeys($data)
{
return self::FIELDS;
}
public function getResult($query, $data)
{
return $query->getQuery()->getResult(AbstractQuery::HYDRATE_SCALAR);
}
public function getTitle(): string
{
return 'export.list.acpw_associate_work.List of accompanying period works';
}
public function getType(): string
{
return Declarations::SOCIAL_WORK_ACTION_TYPE;
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{
$centers = array_map(static fn ($el) => $el['center'], $acl);
$qb = $this->entityManager->createQueryBuilder();
$qb
->from(AccompanyingPeriodWork::class, 'acpw')
->distinct()
->select('acpw.id AS id')
->join('acpw.accompanyingPeriod', 'acp')
->join('acpw.persons', 'person')
;
if ($this->filterStatsByCenters) {
$qb
->andWhere(
$qb->expr()->exists(
'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person
AND acl_count_person_history.center IN (:authorized_centers)
'
)
)
->setParameter('authorized_centers', $centers);
}
AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb);
$this->addSelectClauses($qb, $this->rollingDateConverter->convert($data['calc_date']));
return $qb;
}
public function requiredRole(): string
{
return AccompanyingPeriodVoter::STATS;
}
public function supportsModifiers(): array
{
return [
Declarations::SOCIAL_WORK_ACTION_TYPE,
Declarations::ACP_TYPE,
Declarations::PERSON_TYPE,
];
}
private function addSelectClauses(QueryBuilder $qb, \DateTimeImmutable $calcDate): void
{
// add regular fields
foreach ([
'startDate',
'endDate',
'note',
'createdAt',
'updatedAt',
] as $field) {
$qb->addSelect(sprintf('acpw.%s AS %s', $field, $field));
}
// those with identity
foreach ([
'createdBy',
'updatedBy',
'handlingThierParty',
] as $field) {
$qb->addSelect(sprintf('IDENTITY(acpw.%s) AS %s', $field, $field));
}
// join socialaction
$qb
->join('acpw.socialAction', 'sa')
->addSelect('sa.id AS socialActionId')
->addSelect('sa.id AS socialAction')
->addSelect('IDENTITY(sa.issue) AS socialIssue');
// join acp
$qb
->addSelect('acp.id AS acp_id')
->addSelect('IDENTITY(acp.user) AS acp_user');
// persons
$qb
->addSelect('(SELECT AGGREGATE(person_acpw_member.id) FROM '.Person::class.' person_acpw_member '
.'WHERE person_acpw_member MEMBER OF acpw.persons) AS personsId')
->addSelect('(SELECT AGGREGATE(person1_acpw_member.id) FROM '.Person::class.' person1_acpw_member '
.'WHERE person1_acpw_member MEMBER OF acpw.persons) AS personsName');
// referrers => at date XXXX
$qb
->addSelect('(SELECT JSON_BUILD_OBJECT(\'uid\', IDENTITY(history.user), \'d\', history.startDate) FROM '.UserHistory::class.' history '.
'WHERE history.accompanyingPeriod = acp AND history.startDate <= :calcDate AND (history.endDate IS NULL OR history.endDate > :calcDate)) AS referrers');
/*
// acpwReferrers at date XXX
$qb
->addSelect('(
SELECT IDENTITY(acpw_ref_history.accompanyingPeriodWork) AS acpw_ref_history_id,
JSON_BUILD_OBJECT(\'uid\', IDENTITY(acpw_ref_history.user), \'d\', acpw_ref_history.startDate)
FROM ' . AccompanyingPeriodWorkReferrerHistory::class . ' acpw_ref_history ' .
'WHERE acpw_ref_history.accompanyingPeriodWork = acpw AND acpw_ref_history.startDate <= :calcDate AND (acpw_ref_history.endDate IS NULL or acpw_ref_history.endDate > :calcDate) GROUP BY acpw_ref_history_id) AS acpwReferrers'
);
*/
// thirdparties
$qb
->addSelect('(SELECT AGGREGATE(tp.id) FROM '.ThirdParty::class.' tp '
.'WHERE tp MEMBER OF acpw.thirdParties) AS thirdParties');
// goals
$qb
->addSelect('(SELECT AGGREGATE(IDENTITY(goal.goal)) FROM '.AccompanyingPeriodWorkGoal::class.' goal '
.'WHERE goal MEMBER OF acpw.goals) AS goalsId')
->addSelect('(SELECT AGGREGATE(g.title) FROM '.AccompanyingPeriodWorkGoal::class.' goal1 '
.'LEFT JOIN '.Goal::class.' g WITH goal1.goal = g.id WHERE goal1 MEMBER OF acpw.goals) AS goalsTitle');
// goals results
$qb
->addSelect('(SELECT AGGREGATE(wr.id) FROM '.Result::class.' wr '
.'JOIN '.AccompanyingPeriodWorkGoal::class.' wg WITH wr MEMBER OF wg.results '
.'WHERE wg MEMBER OF acpw.goals) AS goalResultsId')
->addSelect('(SELECT AGGREGATE(wr1.title) FROM '.Result::class.' wr1 '
.'JOIN '.AccompanyingPeriodWorkGoal::class.' wg1 WITH wr1 MEMBER OF wg1.results '
.'WHERE wg1 MEMBER OF acpw.goals) AS goalResultsTitle');
// results
$qb
->addSelect('(SELECT AGGREGATE(result.id) FROM '.Result::class.' result '
.'WHERE result MEMBER OF acpw.results ) AS resultsId ')
->addSelect('(SELECT AGGREGATE (result1.title) FROM '.Result::class.' result1 '
.'WHERE result1 MEMBER OF acpw.results ) AS resultsTitle ');
// evaluations
$qb
->addSelect('(SELECT AGGREGATE(IDENTITY(we.evaluation)) FROM '.AccompanyingPeriodWorkEvaluation::class.' we '
.'WHERE we MEMBER OF acpw.accompanyingPeriodWorkEvaluations ) AS evaluationsId ')
->addSelect('(SELECT AGGREGATE(ev.title) FROM '.AccompanyingPeriodWorkEvaluation::class.' we1 '
.'LEFT JOIN '.Evaluation::class.' ev WITH we1.evaluation = ev.id '
.'WHERE we1 MEMBER OF acpw.accompanyingPeriodWorkEvaluations ) AS evaluationsTitle ');
$qb->setParameter('calcDate', $calcDate);
}
}