mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-28 04:56:13 +00:00
Merge branch '111_exports_suite' into calendar/finalization
This commit is contained in:
commit
aae1fbf7e6
@ -37,6 +37,9 @@ and this project adheres to
|
|||||||
* [social_action]: only show active objectives (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/625)
|
* [social_action]: only show active objectives (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/625)
|
||||||
* [household]: Reposition and cut button for enfant hors menage have been deleted (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/620)
|
* [household]: Reposition and cut button for enfant hors menage have been deleted (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/620)
|
||||||
* [admin]: Add crud for composition type in admin (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/611)
|
* [admin]: Add crud for composition type in admin (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/611)
|
||||||
|
* [social_action]: only show active objectives (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/625)
|
||||||
|
|
||||||
|
## Test releases
|
||||||
|
|
||||||
### 2022-05-30
|
### 2022-05-30
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
|||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\Query;
|
use Doctrine\ORM\Query;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\Security\Core\Role\Role;
|
|
||||||
|
|
||||||
class CountPerson implements ExportInterface
|
class CountPerson implements ExportInterface
|
||||||
{
|
{
|
||||||
@ -73,9 +72,9 @@ class CountPerson implements ExportInterface
|
|||||||
return ['export_result'];
|
return ['export_result'];
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
public function getTitle()
|
||||||
@ -106,9 +105,9 @@ class CountPerson implements ExportInterface
|
|||||||
return $qb;
|
return $qb;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function requiredRole()
|
public function requiredRole(): string
|
||||||
{
|
{
|
||||||
return new Role(PersonVoter::STATS);
|
return PersonVoter::STATS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function supportsModifiers()
|
public function supportsModifiers()
|
||||||
|
@ -265,7 +265,7 @@ Tests reside inside the installed bundles. You must `cd` into that directory, do
|
|||||||
|
|
||||||
**Note**: some bundle require the fixture to be executed. See the dedicated _how-tos_.
|
**Note**: some bundle require the fixture to be executed. See the dedicated _how-tos_.
|
||||||
|
|
||||||
Exemple, for running test inside `main` bundle:
|
Exemple, for running unit test inside `main` bundle:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
@ -280,6 +280,30 @@ Exemple, for running test inside `main` bundle:
|
|||||||
# run tests
|
# run tests
|
||||||
bin/phpunit src/Bundle/path/to/your/test
|
bin/phpunit src/Bundle/path/to/your/test
|
||||||
|
|
||||||
|
Or for running tests to check code style and php conventions with csfixer and phpstan:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# run code style fixer
|
||||||
|
bin/grumphp run --tasks=phpcsfixer
|
||||||
|
# run phpstan
|
||||||
|
bin/grumphp run --tasks=phpstan
|
||||||
|
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
To avoid phpstan block your commits:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
git commit -n ...
|
||||||
|
|
||||||
|
To avoid phpstan block your commits permanently:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
./bin/grumphp git:deinit
|
||||||
|
|
||||||
How to run webpack interactively
|
How to run webpack interactively
|
||||||
================================
|
================================
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ These are alias conventions :
|
|||||||
| | Scope::class | acp.scopes | acpscope |
|
| | Scope::class | acp.scopes | acpscope |
|
||||||
| | SocialIssue::class | acp.socialIssues | acpsocialissue |
|
| | SocialIssue::class | acp.socialIssues | acpsocialissue |
|
||||||
| | User::class | acp.user | acpuser |
|
| | User::class | acp.user | acpuser |
|
||||||
|
| | AccompanyingPeriopStepHistory::class | acp.stepHistories | acpstephistories |
|
||||||
| AccompanyingPeriodWork::class | | | acpw |
|
| AccompanyingPeriodWork::class | | | acpw |
|
||||||
| | AccompanyingPeriodWorkEvaluation::class | acpw.accompanyingPeriodWorkEvaluations | workeval |
|
| | AccompanyingPeriodWorkEvaluation::class | acpw.accompanyingPeriodWorkEvaluations | workeval |
|
||||||
| | User::class | acpw.referrers | acpwuser |
|
| | User::class | acpw.referrers | acpwuser |
|
||||||
@ -59,6 +60,7 @@ These are alias conventions :
|
|||||||
| | User::class | activity.users | actusers |
|
| | User::class | activity.users | actusers |
|
||||||
| | ActivityReason::class | activity.reasons | actreasons |
|
| | ActivityReason::class | activity.reasons | actreasons |
|
||||||
| | Center::class | actperson.center | actcenter |
|
| | Center::class | actperson.center | actcenter |
|
||||||
|
| | Person::class | activity.createdBy | actcreator |
|
||||||
| ActivityReason::class | | | actreasons |
|
| ActivityReason::class | | | actreasons |
|
||||||
| | ActivityReasonCategory::class | actreason.category | actreasoncat |
|
| | ActivityReasonCategory::class | actreason.category | actreasoncat |
|
||||||
| Calendar::class | | | cal |
|
| Calendar::class | | | cal |
|
||||||
|
@ -23,150 +23,6 @@ parameters:
|
|||||||
count: 1
|
count: 1
|
||||||
path: src/Bundle/ChillActivityBundle/Entity/ActivityReasonCategory.php
|
path: src/Bundle/ChillActivityBundle/Entity/ActivityReasonCategory.php
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityReasonAggregator.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\ActivityBundle\\\\Export\\\\Aggregator\\\\ActivityReasonAggregator\\:\\:addRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityReasonAggregator.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\ActivityBundle\\\\Export\\\\Aggregator\\\\ActivityTypeAggregator\\:\\:addRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\ActivityBundle\\\\Export\\\\Aggregator\\\\ActivityUserAggregator\\:\\:addRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillActivityBundle/Export/Export/CountActivity.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\ActivityBundle\\\\Export\\\\Export\\\\CountActivity\\:\\:requiredRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillActivityBundle/Export/Export/CountActivity.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillActivityBundle/Export/Export/ListActivity.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\ActivityBundle\\\\Export\\\\Export\\\\ListActivity\\:\\:requiredRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillActivityBundle/Export/Export/ListActivity.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillActivityBundle/Export/Export/StatActivityDuration.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\ActivityBundle\\\\Export\\\\Export\\\\StatActivityDuration\\:\\:requiredRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillActivityBundle/Export/Export/StatActivityDuration.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\ActivityBundle\\\\Export\\\\Filter\\\\ActivityDateFilter\\:\\:addRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillActivityBundle/Export/Filter/ActivityDateFilter.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillActivityBundle/Export/Filter/ActivityReasonFilter.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\ActivityBundle\\\\Export\\\\Filter\\\\ActivityReasonFilter\\:\\:addRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillActivityBundle/Export/Filter/ActivityReasonFilter.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\ActivityBundle\\\\Export\\\\Filter\\\\ActivityTypeFilter\\:\\:addRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\ActivityBundle\\\\Export\\\\Filter\\\\PersonHavingActivityBetweenDateFilter\\:\\:addRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillActivityBundle/Export/Filter/PersonHavingActivityBetweenDateFilter.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: """
|
message: """
|
||||||
#^Fetching class constant class of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
#^Fetching class constant class of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
||||||
@ -359,31 +215,6 @@ parameters:
|
|||||||
count: 1
|
count: 1
|
||||||
path: src/Bundle/ChillMainBundle/Entity/User.php
|
path: src/Bundle/ChillMainBundle/Entity/User.php
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\MainBundle\\\\Export\\\\DirectExportInterface\\:\\:requiredRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillMainBundle/Export/DirectExportInterface.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\MainBundle\\\\Export\\\\ExportInterface\\:\\:requiredRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillMainBundle/Export/ExportInterface.php
|
|
||||||
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\MainBundle\\\\Export\\\\ModifierInterface\\:\\:addRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillMainBundle/Export/ModifierInterface.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: """
|
message: """
|
||||||
#^Class Chill\\\\MainBundle\\\\Form\\\\Event\\\\CustomizeFormEvent extends deprecated class Symfony\\\\Component\\\\EventDispatcher\\\\Event\\:
|
#^Class Chill\\\\MainBundle\\\\Form\\\\Event\\\\CustomizeFormEvent extends deprecated class Symfony\\\\Component\\\\EventDispatcher\\\\Event\\:
|
||||||
@ -543,142 +374,6 @@ parameters:
|
|||||||
count: 2
|
count: 2
|
||||||
path: src/Bundle/ChillPersonBundle/Entity/Person.php
|
path: src/Bundle/ChillPersonBundle/Entity/Person.php
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\PersonBundle\\\\Export\\\\Aggregator\\\\AgeAggregator\\:\\:addRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Aggregator/AgeAggregator.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\PersonBundle\\\\Export\\\\Aggregator\\\\CountryOfBirthAggregator\\:\\:addRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Aggregator/CountryOfBirthAggregator.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\PersonBundle\\\\Export\\\\Aggregator\\\\GenderAggregator\\:\\:addRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Aggregator/GenderAggregator.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\PersonBundle\\\\Export\\\\Aggregator\\\\NationalityAggregator\\:\\:addRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Aggregator/NationalityAggregator.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Export/CountPerson.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\PersonBundle\\\\Export\\\\Export\\\\CountPerson\\:\\:requiredRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Export/CountPerson.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Export/ListPerson.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\PersonBundle\\\\Export\\\\Export\\\\ListPerson\\:\\:requiredRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Export/ListPerson.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Call to deprecated method execute\\(\\) of class Doctrine\\\\DBAL\\\\Statement\\:
|
|
||||||
Statement\\:\\:execute\\(\\) is deprecated, use Statement\\:\\:executeQuery\\(\\) or executeStatement\\(\\) instead$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Export/ListPersonDuplicate.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Export/ListPersonDuplicate.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\PersonBundle\\\\Export\\\\Export\\\\ListPersonDuplicate\\:\\:requiredRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Export/ListPersonDuplicate.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\PersonBundle\\\\Export\\\\Filter\\\\AccompanyingPeriodClosingFilter\\:\\:addRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingPeriodClosingFilter.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\PersonBundle\\\\Export\\\\Filter\\\\AccompanyingPeriodFilter\\:\\:addRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingPeriodFilter.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\PersonBundle\\\\Export\\\\Filter\\\\AccompanyingPeriodOpeningFilter\\:\\:addRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingPeriodOpeningFilter.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\PersonBundle\\\\Export\\\\Filter\\\\BirthdateFilter\\:\\:addRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Filter/BirthdateFilter.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\PersonBundle\\\\Export\\\\Filter\\\\GenderFilter\\:\\:addRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Filter/GenderFilter.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\PersonBundle\\\\Export\\\\Filter\\\\NationalityFilter\\:\\:addRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Filter/NationalityFilter.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: """
|
message: """
|
||||||
#^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
#^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
||||||
@ -740,29 +435,6 @@ parameters:
|
|||||||
count: 3
|
count: 3
|
||||||
path: src/Bundle/ChillReportBundle/Controller/ReportController.php
|
path: src/Bundle/ChillReportBundle/Controller/ReportController.php
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillReportBundle/Export/Export/ReportList.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\ReportBundle\\\\Export\\\\Export\\\\ReportList\\:\\:requiredRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillReportBundle/Export/Export/ReportList.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Return type of method Chill\\\\ReportBundle\\\\Export\\\\Filter\\\\ReportDateFilter\\:\\:addRole\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
|
||||||
since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillReportBundle/Export/Filter/ReportDateFilter.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: """
|
message: """
|
||||||
@ -845,14 +517,6 @@ parameters:
|
|||||||
count: 1
|
count: 1
|
||||||
path: src/Bundle/ChillTaskBundle/Form/SingleTaskType.php
|
path: src/Bundle/ChillTaskBundle/Form/SingleTaskType.php
|
||||||
|
|
||||||
-
|
|
||||||
message: """
|
|
||||||
#^Parameter \\$centerResolverDispatcher of method Chill\\\\TaskBundle\\\\Repository\\\\SingleTaskAclAwareRepository\\:\\:__construct\\(\\) has typehint with deprecated interface Chill\\\\MainBundle\\\\Security\\\\Resolver\\\\CenterResolverDispatcherInterface\\:
|
|
||||||
Use CenterResolverManager and its interface CenterResolverManagerInterface$#
|
|
||||||
"""
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: """
|
message: """
|
||||||
#^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
#^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
|
||||||
|
@ -245,11 +245,6 @@ parameters:
|
|||||||
count: 1
|
count: 1
|
||||||
path: src/Bundle/ChillMainBundle/Entity/User.php
|
path: src/Bundle/ChillMainBundle/Entity/User.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in a ternary operator condition, mixed given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillMainBundle/Export/Formatter/SpreadsheetListFormatter.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
|
@ -13,6 +13,10 @@ namespace Chill\ActivityBundle\Entity;
|
|||||||
|
|
||||||
use Chill\ActivityBundle\Validator\Constraints as ActivityValidator;
|
use Chill\ActivityBundle\Validator\Constraints as ActivityValidator;
|
||||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
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\Center;
|
||||||
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
|
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
|
||||||
use Chill\MainBundle\Entity\Embeddable\PrivateCommentEmbeddable;
|
use Chill\MainBundle\Entity\Embeddable\PrivateCommentEmbeddable;
|
||||||
@ -55,8 +59,12 @@ use Symfony\Component\Validator\Constraints as Assert;
|
|||||||
* getUserFunction="getUser",
|
* getUserFunction="getUser",
|
||||||
* path="scope")
|
* 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_RECEIVED = 'received';
|
||||||
|
|
||||||
public const SENTRECEIVED_SENT = 'sent';
|
public const SENTRECEIVED_SENT = 'sent';
|
||||||
|
@ -13,20 +13,19 @@ namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators;
|
|||||||
|
|
||||||
use Chill\ActivityBundle\Export\Declarations;
|
use Chill\ActivityBundle\Export\Declarations;
|
||||||
use Chill\MainBundle\Export\AggregatorInterface;
|
use Chill\MainBundle\Export\AggregatorInterface;
|
||||||
use Chill\MainBundle\Repository\UserRepository;
|
use Chill\MainBundle\Repository\UserRepositoryInterface;
|
||||||
use Chill\MainBundle\Templating\Entity\UserRender;
|
use Chill\MainBundle\Templating\Entity\UserRender;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use function in_array;
|
|
||||||
|
|
||||||
class ByUserAggregator implements AggregatorInterface
|
class ByCreatorAggregator implements AggregatorInterface
|
||||||
{
|
{
|
||||||
private UserRender $userRender;
|
private UserRender $userRender;
|
||||||
|
|
||||||
private UserRepository $userRepository;
|
private UserRepositoryInterface $userRepository;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
UserRepository $userRepository,
|
UserRepositoryInterface $userRepository,
|
||||||
UserRender $userRender
|
UserRender $userRender
|
||||||
) {
|
) {
|
||||||
$this->userRepository = $userRepository;
|
$this->userRepository = $userRepository;
|
||||||
@ -40,12 +39,8 @@ class ByUserAggregator implements AggregatorInterface
|
|||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data)
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
{
|
{
|
||||||
if (!in_array('actusers', $qb->getAllAliases(), true)) {
|
$qb->addSelect('IDENTITY(activity.createdBy) AS creator_aggregator');
|
||||||
$qb->leftJoin('activity.users', 'actusers');
|
$qb->addGroupBy('creator_aggregator');
|
||||||
}
|
|
||||||
|
|
||||||
$qb->addSelect('actusers.id AS users_aggregator');
|
|
||||||
$qb->addGroupBy('users_aggregator');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
@ -62,7 +57,7 @@ class ByUserAggregator implements AggregatorInterface
|
|||||||
{
|
{
|
||||||
return function ($value): string {
|
return function ($value): string {
|
||||||
if ('_header' === $value) {
|
if ('_header' === $value) {
|
||||||
return 'Accepted users';
|
return 'Created by';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null === $value) {
|
if (null === $value) {
|
||||||
@ -77,11 +72,11 @@ class ByUserAggregator implements AggregatorInterface
|
|||||||
|
|
||||||
public function getQueryKeys($data): array
|
public function getQueryKeys($data): array
|
||||||
{
|
{
|
||||||
return ['users_aggregator'];
|
return ['creator_aggregator'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTitle(): string
|
public function getTitle(): string
|
||||||
{
|
{
|
||||||
return 'Group activity by linked users';
|
return 'Group activity by creator';
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -19,7 +19,7 @@ use Doctrine\ORM\QueryBuilder;
|
|||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use function in_array;
|
use function in_array;
|
||||||
|
|
||||||
class UserScopeAggregator implements AggregatorInterface
|
class CreatorScopeAggregator implements AggregatorInterface
|
||||||
{
|
{
|
||||||
private ScopeRepository $scopeRepository;
|
private ScopeRepository $scopeRepository;
|
||||||
|
|
||||||
@ -40,12 +40,12 @@ class UserScopeAggregator implements AggregatorInterface
|
|||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data)
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
{
|
{
|
||||||
if (!in_array('actuser', $qb->getAllAliases(), true)) {
|
if (!in_array('actcreator', $qb->getAllAliases(), true)) {
|
||||||
$qb->leftJoin('activity.user', 'actuser');
|
$qb->leftJoin('activity.createdBy', 'actcreator');
|
||||||
}
|
}
|
||||||
|
|
||||||
$qb->addSelect('IDENTITY(actuser.mainScope) AS userscope_aggregator');
|
$qb->addSelect('IDENTITY(actcreator.mainScope) AS creatorscope_aggregator');
|
||||||
$qb->addGroupBy('userscope_aggregator');
|
$qb->addGroupBy('creatorscope_aggregator');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
@ -79,11 +79,11 @@ class UserScopeAggregator implements AggregatorInterface
|
|||||||
|
|
||||||
public function getQueryKeys($data): array
|
public function getQueryKeys($data): array
|
||||||
{
|
{
|
||||||
return ['userscope_aggregator'];
|
return ['creatorscope_aggregator'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTitle(): string
|
public function getTitle(): string
|
||||||
{
|
{
|
||||||
return 'Group activity by userscope';
|
return 'Group activity by creator scope';
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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';
|
||||||
|
}
|
||||||
|
}
|
@ -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';
|
||||||
|
}
|
||||||
|
}
|
@ -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';
|
||||||
|
}
|
||||||
|
}
|
@ -69,9 +69,9 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface
|
|||||||
return ['export_avg_activity_duration'];
|
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
|
public function getTitle(): string
|
||||||
|
@ -70,9 +70,9 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac
|
|||||||
return ['export_avg_activity_visit_duration'];
|
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
|
public function getTitle(): string
|
||||||
|
@ -69,9 +69,9 @@ class CountActivity implements ExportInterface, GroupedExportInterface
|
|||||||
return ['export_count_activity'];
|
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
|
public function getTitle(): string
|
||||||
|
@ -70,9 +70,9 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface
|
|||||||
return ['export_sum_activity_duration'];
|
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
|
public function getTitle(): string
|
||||||
|
@ -70,9 +70,9 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac
|
|||||||
return ['export_sum_activity_visit_duration'];
|
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
|
public function getTitle(): string
|
||||||
|
@ -65,9 +65,9 @@ class CountActivity implements ExportInterface, GroupedExportInterface
|
|||||||
return ['export_count_activity'];
|
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()
|
public function getTitle()
|
||||||
|
@ -64,6 +64,8 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface
|
|||||||
if (self::SUM === $this->action) {
|
if (self::SUM === $this->action) {
|
||||||
return 'Sum activities linked to a person duration by various parameters.';
|
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
|
public function getGroup(): string
|
||||||
@ -87,9 +89,9 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface
|
|||||||
return ['export_stat_activity'];
|
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()
|
public function getTitle()
|
||||||
@ -97,6 +99,8 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface
|
|||||||
if (self::SUM === $this->action) {
|
if (self::SUM === $this->action) {
|
||||||
return 'Sum activity linked to a person duration';
|
return 'Sum activity linked to a person duration';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new LogicException('This action is not supported: ' . $this->action);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getType(): string
|
public function getType(): string
|
||||||
|
@ -12,16 +12,13 @@ declare(strict_types=1);
|
|||||||
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
|
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
|
||||||
|
|
||||||
use Chill\ActivityBundle\Export\Declarations;
|
use Chill\ActivityBundle\Export\Declarations;
|
||||||
use Chill\MainBundle\Entity\User;
|
|
||||||
use Chill\MainBundle\Export\FilterInterface;
|
use Chill\MainBundle\Export\FilterInterface;
|
||||||
|
use Chill\MainBundle\Form\Type\PickUserDynamicType;
|
||||||
use Chill\MainBundle\Templating\Entity\UserRender;
|
use Chill\MainBundle\Templating\Entity\UserRender;
|
||||||
use Doctrine\ORM\Query\Expr\Andx;
|
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use function in_array;
|
|
||||||
|
|
||||||
class ByUserFilter implements FilterInterface
|
class ByCreatorFilter implements FilterInterface
|
||||||
{
|
{
|
||||||
private UserRender $userRender;
|
private UserRender $userRender;
|
||||||
|
|
||||||
@ -37,22 +34,11 @@ class ByUserFilter implements FilterInterface
|
|||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data)
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
{
|
{
|
||||||
$where = $qb->getDQLPart('where');
|
$qb
|
||||||
|
->andWhere(
|
||||||
if (!in_array('actusers', $qb->getAllAliases(), true)) {
|
$qb->expr()->in('activity.createdBy', ':users')
|
||||||
$qb->join('activity.users', 'actusers');
|
)
|
||||||
}
|
->setParameter('users', $data['accepted_users']);
|
||||||
|
|
||||||
$clause = $qb->expr()->in('actusers.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']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
@ -62,13 +48,8 @@ class ByUserFilter implements FilterInterface
|
|||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
{
|
{
|
||||||
$builder->add('accepted_users', EntityType::class, [
|
$builder->add('accepted_users', PickUserDynamicType::class, [
|
||||||
'class' => User::class,
|
|
||||||
'choice_label' => function (User $u) {
|
|
||||||
return $this->userRender->renderString($u, []);
|
|
||||||
},
|
|
||||||
'multiple' => true,
|
'multiple' => true,
|
||||||
'expanded' => true,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,13 +61,13 @@ class ByUserFilter implements FilterInterface
|
|||||||
$users[] = $this->userRender->renderString($u, []);
|
$users[] = $this->userRender->renderString($u, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ['Filtered activity by linked users: only %users%', [
|
return ['Filtered activity by creator: only %users%', [
|
||||||
'%users%' => implode(', ou ', $users),
|
'%users%' => implode(', ', $users),
|
||||||
]];
|
]];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTitle(): string
|
public function getTitle(): string
|
||||||
{
|
{
|
||||||
return 'Filter activity by linked users';
|
return 'Filter activity by creator';
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,10 +14,9 @@ namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
|
|||||||
use Chill\ActivityBundle\Export\Declarations;
|
use Chill\ActivityBundle\Export\Declarations;
|
||||||
use Chill\MainBundle\Export\FilterInterface;
|
use Chill\MainBundle\Export\FilterInterface;
|
||||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||||
|
use Chill\PersonBundle\Form\Type\PickSocialActionType;
|
||||||
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
|
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
|
||||||
use Doctrine\ORM\Query\Expr\Andx;
|
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use function in_array;
|
use function in_array;
|
||||||
|
|
||||||
@ -37,22 +36,17 @@ class BySocialActionFilter implements FilterInterface
|
|||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data)
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
{
|
{
|
||||||
$where = $qb->getDQLPart('where');
|
|
||||||
|
|
||||||
if (!in_array('actsocialaction', $qb->getAllAliases(), true)) {
|
if (!in_array('actsocialaction', $qb->getAllAliases(), true)) {
|
||||||
$qb->join('activity.socialActions', 'actsocialaction');
|
$qb->join('activity.socialActions', 'actsocialaction');
|
||||||
}
|
}
|
||||||
|
|
||||||
$clause = $qb->expr()->in('actsocialaction.id', ':socialactions');
|
$clause = $qb->expr()->in('actsocialaction.id', ':socialactions');
|
||||||
|
|
||||||
if ($where instanceof Andx) {
|
$qb->andWhere($clause)
|
||||||
$where->add($clause);
|
->setParameter(
|
||||||
} else {
|
'socialactions',
|
||||||
$where = $qb->expr()->andX($clause);
|
SocialAction::getDescendantsWithThisForActions($data['accepted_socialactions'])
|
||||||
}
|
);
|
||||||
|
|
||||||
$qb->add('where', $where);
|
|
||||||
$qb->setParameter('socialactions', $data['accepted_socialactions']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
@ -62,13 +56,8 @@ class BySocialActionFilter implements FilterInterface
|
|||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
{
|
{
|
||||||
$builder->add('accepted_socialactions', EntityType::class, [
|
$builder->add('accepted_socialactions', PickSocialActionType::class, [
|
||||||
'class' => SocialAction::class,
|
|
||||||
'choice_label' => function (SocialAction $sa) {
|
|
||||||
return $this->actionRender->renderString($sa, []);
|
|
||||||
},
|
|
||||||
'multiple' => true,
|
'multiple' => true,
|
||||||
'expanded' => true,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,12 +65,14 @@ class BySocialActionFilter implements FilterInterface
|
|||||||
{
|
{
|
||||||
$actions = [];
|
$actions = [];
|
||||||
|
|
||||||
foreach ($data['accepted_socialactions'] as $sa) {
|
foreach ($data['accepted_socialactions'] as $action) {
|
||||||
$actions[] = $this->actionRender->renderString($sa, []);
|
$actions[] = $this->actionRender->renderString($action, [
|
||||||
|
'show_and_children' => true,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ['Filtered activity by linked socialaction: only %actions%', [
|
return ['Filtered activity by linked socialaction: only %actions%', [
|
||||||
'%actions%' => implode(', ou ', $actions),
|
'%actions%' => implode(', ', $actions),
|
||||||
]];
|
]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,10 +14,9 @@ namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
|
|||||||
use Chill\ActivityBundle\Export\Declarations;
|
use Chill\ActivityBundle\Export\Declarations;
|
||||||
use Chill\MainBundle\Export\FilterInterface;
|
use Chill\MainBundle\Export\FilterInterface;
|
||||||
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
||||||
|
use Chill\PersonBundle\Form\Type\PickSocialIssueType;
|
||||||
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
|
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
|
||||||
use Doctrine\ORM\Query\Expr\Andx;
|
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use function in_array;
|
use function in_array;
|
||||||
|
|
||||||
@ -37,22 +36,17 @@ class BySocialIssueFilter implements FilterInterface
|
|||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data)
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
{
|
{
|
||||||
$where = $qb->getDQLPart('where');
|
|
||||||
|
|
||||||
if (!in_array('actsocialissue', $qb->getAllAliases(), true)) {
|
if (!in_array('actsocialissue', $qb->getAllAliases(), true)) {
|
||||||
$qb->join('activity.socialIssues', 'actsocialissue');
|
$qb->join('activity.socialIssues', 'actsocialissue');
|
||||||
}
|
}
|
||||||
|
|
||||||
$clause = $qb->expr()->in('actsocialissue.id', ':socialissues');
|
$clause = $qb->expr()->in('actsocialissue.id', ':socialissues');
|
||||||
|
|
||||||
if ($where instanceof Andx) {
|
$qb->andWhere($clause)
|
||||||
$where->add($clause);
|
->setParameter(
|
||||||
} else {
|
'socialissues',
|
||||||
$where = $qb->expr()->andX($clause);
|
SocialIssue::getDescendantsWithThisForIssues($data['accepted_socialissues'])
|
||||||
}
|
);
|
||||||
|
|
||||||
$qb->add('where', $where);
|
|
||||||
$qb->setParameter('socialissues', $data['accepted_socialissues']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
@ -62,13 +56,8 @@ class BySocialIssueFilter implements FilterInterface
|
|||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
{
|
{
|
||||||
$builder->add('accepted_socialissues', EntityType::class, [
|
$builder->add('accepted_socialissues', PickSocialIssueType::class, [
|
||||||
'class' => SocialIssue::class,
|
|
||||||
'choice_label' => function (SocialIssue $si) {
|
|
||||||
return $this->issueRender->renderString($si, []);
|
|
||||||
},
|
|
||||||
'multiple' => true,
|
'multiple' => true,
|
||||||
'expanded' => true,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,12 +65,14 @@ class BySocialIssueFilter implements FilterInterface
|
|||||||
{
|
{
|
||||||
$issues = [];
|
$issues = [];
|
||||||
|
|
||||||
foreach ($data['accepted_socialissues'] as $si) {
|
foreach ($data['accepted_socialissues'] as $issue) {
|
||||||
$issues[] = $this->issueRender->renderString($si, []);
|
$issues[] = $this->issueRender->renderString($issue, [
|
||||||
|
'show_and_children' => true,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ['Filtered activity by linked socialissue: only %issues%', [
|
return ['Filtered activity by linked socialissue: only %issues%', [
|
||||||
'%issues%' => implode(', ou ', $issues),
|
'%issues%' => implode(', ', $issues),
|
||||||
]];
|
]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,15 +74,13 @@ class EmergencyFilter implements FilterInterface
|
|||||||
|
|
||||||
public function describeAction($data, $format = 'string'): array
|
public function describeAction($data, $format = 'string'): array
|
||||||
{
|
{
|
||||||
foreach (self::CHOICES as $k => $v) {
|
return [
|
||||||
if ($v === $data['accepted_emergency']) {
|
'Filtered by emergency: only %emergency%', [
|
||||||
$choice = $k;
|
'%emergency%' => $this->translator->trans(
|
||||||
}
|
$data['accepted_emergency'] ? 'is emergency' : 'is not emergency'
|
||||||
}
|
),
|
||||||
|
],
|
||||||
return ['Filtered activity by emergency: only %emergency%', [
|
];
|
||||||
'%emergency%' => $this->translator->trans($choice),
|
|
||||||
]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTitle(): string
|
public function getTitle(): string
|
||||||
|
@ -12,12 +12,11 @@ declare(strict_types=1);
|
|||||||
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
|
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
|
||||||
|
|
||||||
use Chill\ActivityBundle\Export\Declarations;
|
use Chill\ActivityBundle\Export\Declarations;
|
||||||
use Chill\MainBundle\Entity\LocationType;
|
|
||||||
use Chill\MainBundle\Export\FilterInterface;
|
use Chill\MainBundle\Export\FilterInterface;
|
||||||
|
use Chill\MainBundle\Form\Type\PickLocationTypeType;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
use Doctrine\ORM\Query\Expr\Andx;
|
use Doctrine\ORM\Query\Expr\Andx;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use function in_array;
|
use function in_array;
|
||||||
|
|
||||||
@ -61,13 +60,9 @@ class LocationTypeFilter implements FilterInterface
|
|||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
{
|
{
|
||||||
$builder->add('accepted_locationtype', EntityType::class, [
|
$builder->add('accepted_locationtype', PickLocationTypeType::class, [
|
||||||
'class' => LocationType::class,
|
|
||||||
'choice_label' => function (LocationType $type) {
|
|
||||||
return $this->translatableStringHelper->localize($type->getTitle());
|
|
||||||
},
|
|
||||||
'multiple' => true,
|
'multiple' => true,
|
||||||
'expanded' => true,
|
//'label' => false,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +77,7 @@ class LocationTypeFilter implements FilterInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ['Filtered activity by locationtype: only %types%', [
|
return ['Filtered activity by locationtype: only %types%', [
|
||||||
'%types%' => implode(', ou ', $types),
|
'%types%' => implode(', ', $types),
|
||||||
]];
|
]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,12 +12,11 @@ declare(strict_types=1);
|
|||||||
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
|
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
|
||||||
|
|
||||||
use Chill\ActivityBundle\Export\Declarations;
|
use Chill\ActivityBundle\Export\Declarations;
|
||||||
use Chill\MainBundle\Entity\User;
|
|
||||||
use Chill\MainBundle\Export\FilterInterface;
|
use Chill\MainBundle\Export\FilterInterface;
|
||||||
|
use Chill\MainBundle\Form\Type\PickUserDynamicType;
|
||||||
use Chill\MainBundle\Templating\Entity\UserRender;
|
use Chill\MainBundle\Templating\Entity\UserRender;
|
||||||
use Doctrine\ORM\Query\Expr\Andx;
|
use Doctrine\ORM\Query\Expr\Andx;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
|
||||||
class UserFilter implements FilterInterface
|
class UserFilter implements FilterInterface
|
||||||
@ -57,13 +56,8 @@ class UserFilter implements FilterInterface
|
|||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
{
|
{
|
||||||
$builder->add('accepted_users', EntityType::class, [
|
$builder->add('accepted_users', PickUserDynamicType::class, [
|
||||||
'class' => User::class,
|
|
||||||
'choice_label' => function (User $u) {
|
|
||||||
return $this->userRender->renderString($u, []);
|
|
||||||
},
|
|
||||||
'multiple' => true,
|
'multiple' => true,
|
||||||
'expanded' => true,
|
|
||||||
'label' => 'Creators',
|
'label' => 'Creators',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -77,7 +71,7 @@ class UserFilter implements FilterInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ['Filtered activity by user: only %users%', [
|
return ['Filtered activity by user: only %users%', [
|
||||||
'%users%' => implode(', ou ', $users),
|
'%users%' => implode(', ', $users),
|
||||||
]];
|
]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ class UserScopeFilter implements FilterInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ['Filtered activity by userscope: only %scopes%', [
|
return ['Filtered activity by userscope: only %scopes%', [
|
||||||
'%scopes%' => implode(', ou ', $scopes),
|
'%scopes%' => implode(', ', $scopes),
|
||||||
]];
|
]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter
|
|||||||
);
|
);
|
||||||
|
|
||||||
return ['Filtered by activity type: only %list%', [
|
return ['Filtered by activity type: only %list%', [
|
||||||
'%list%' => implode(', ou ', $reasonsNames),
|
'%list%' => implode(', ', $reasonsNames),
|
||||||
]];
|
]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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';
|
||||||
|
}
|
||||||
|
}
|
@ -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';
|
||||||
|
}
|
||||||
|
}
|
@ -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';
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@ declare(strict_types=1);
|
|||||||
namespace Chill\ActivityBundle\Tests\Export\Aggregator\ACPAggregators;
|
namespace Chill\ActivityBundle\Tests\Export\Aggregator\ACPAggregators;
|
||||||
|
|
||||||
use Chill\ActivityBundle\Entity\Activity;
|
use Chill\ActivityBundle\Entity\Activity;
|
||||||
use Chill\ActivityBundle\Export\Aggregator\ACPAggregators\ByUserAggregator;
|
use Chill\ActivityBundle\Export\Aggregator\ACPAggregators\ByCreatorAggregator;
|
||||||
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
|
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ use Doctrine\ORM\EntityManagerInterface;
|
|||||||
*/
|
*/
|
||||||
final class ByUserAggregatorTest extends AbstractAggregatorTest
|
final class ByUserAggregatorTest extends AbstractAggregatorTest
|
||||||
{
|
{
|
||||||
private ByUserAggregator $aggregator;
|
private ByCreatorAggregator $aggregator;
|
||||||
|
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
|
@ -12,7 +12,7 @@ declare(strict_types=1);
|
|||||||
namespace Chill\ActivityBundle\Tests\Export\Aggregator\ACPAggregators;
|
namespace Chill\ActivityBundle\Tests\Export\Aggregator\ACPAggregators;
|
||||||
|
|
||||||
use Chill\ActivityBundle\Entity\Activity;
|
use Chill\ActivityBundle\Entity\Activity;
|
||||||
use Chill\ActivityBundle\Export\Aggregator\ACPAggregators\UserScopeAggregator;
|
use Chill\ActivityBundle\Export\Aggregator\ACPAggregators\CreatorScopeAggregator;
|
||||||
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
|
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ use Doctrine\ORM\EntityManagerInterface;
|
|||||||
*/
|
*/
|
||||||
final class UserScopeAggregatorTest extends AbstractAggregatorTest
|
final class UserScopeAggregatorTest extends AbstractAggregatorTest
|
||||||
{
|
{
|
||||||
private UserScopeAggregator $aggregator;
|
private CreatorScopeAggregator $aggregator;
|
||||||
|
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
|
@ -12,7 +12,7 @@ declare(strict_types=1);
|
|||||||
namespace Chill\ActivityBundle\Tests\Export\Filter\ACPFilters;
|
namespace Chill\ActivityBundle\Tests\Export\Filter\ACPFilters;
|
||||||
|
|
||||||
use Chill\ActivityBundle\Entity\Activity;
|
use Chill\ActivityBundle\Entity\Activity;
|
||||||
use Chill\ActivityBundle\Export\Filter\ACPFilters\ByUserFilter;
|
use Chill\ActivityBundle\Export\Filter\ACPFilters\ByCreatorFilter;
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\MainBundle\Test\Export\AbstractFilterTest;
|
use Chill\MainBundle\Test\Export\AbstractFilterTest;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
@ -23,7 +23,7 @@ use Doctrine\ORM\EntityManagerInterface;
|
|||||||
*/
|
*/
|
||||||
final class ByUserFilterTest extends AbstractFilterTest
|
final class ByUserFilterTest extends AbstractFilterTest
|
||||||
{
|
{
|
||||||
private ByUserFilter $filter;
|
private ByCreatorFilter $filter;
|
||||||
|
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
|
@ -4,18 +4,15 @@ services:
|
|||||||
autoconfigure: true
|
autoconfigure: true
|
||||||
|
|
||||||
## Indicators
|
## Indicators
|
||||||
chill.activity.export.count_activity_linked_to_person:
|
Chill\ActivityBundle\Export\Export\LinkedToPerson\CountActivity:
|
||||||
class: Chill\ActivityBundle\Export\Export\LinkedToPerson\CountActivity
|
|
||||||
tags:
|
tags:
|
||||||
- { name: chill.export, alias: 'count_activity_linked_to_person' }
|
- { name: chill.export, alias: 'count_activity_linked_to_person' }
|
||||||
|
|
||||||
chill.activity.export.sum_activity_duration_linked_to_person:
|
Chill\ActivityBundle\Export\Export\LinkedToPerson\StatActivityDuration:
|
||||||
class: Chill\ActivityBundle\Export\Export\LinkedToPerson\StatActivityDuration
|
|
||||||
tags:
|
tags:
|
||||||
- { name: chill.export, alias: 'sum_activity_duration_linked_to_person' }
|
- { name: chill.export, alias: 'sum_activity_duration_linked_to_person' }
|
||||||
|
|
||||||
chill.activity.export.list_activity_linked_to_person:
|
Chill\ActivityBundle\Export\Export\LinkedToPerson\ListActivity:
|
||||||
class: Chill\ActivityBundle\Export\Export\LinkedToPerson\ListActivity
|
|
||||||
tags:
|
tags:
|
||||||
- { name: chill.export, alias: 'list_activity_linked_to_person' }
|
- { name: chill.export, alias: 'list_activity_linked_to_person' }
|
||||||
|
|
||||||
@ -55,6 +52,10 @@ services:
|
|||||||
tags:
|
tags:
|
||||||
- { name: chill.export_filter, alias: 'activity_date_filter' }
|
- { 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:
|
chill.activity.export.reason_filter:
|
||||||
class: Chill\ActivityBundle\Export\Filter\PersonFilters\ActivityReasonFilter
|
class: Chill\ActivityBundle\Export\Filter\PersonFilters\ActivityReasonFilter
|
||||||
tags:
|
tags:
|
||||||
@ -77,10 +78,9 @@ services:
|
|||||||
tags:
|
tags:
|
||||||
- { name: chill.export_filter, alias: 'activity_locationtype_filter' }
|
- { name: chill.export_filter, alias: 'activity_locationtype_filter' }
|
||||||
|
|
||||||
chill.activity.export.byuser_filter: # TMS (M2M)
|
Chill\ActivityBundle\Export\Filter\ACPFilters\ByCreatorFilter:
|
||||||
class: Chill\ActivityBundle\Export\Filter\ACPFilters\ByUserFilter
|
|
||||||
tags:
|
tags:
|
||||||
- { name: chill.export_filter, alias: 'activity_byuser_filter' }
|
- { name: chill.export_filter, alias: 'activity_bycreator_filter' }
|
||||||
|
|
||||||
chill.activity.export.emergency_filter:
|
chill.activity.export.emergency_filter:
|
||||||
class: Chill\ActivityBundle\Export\Filter\ACPFilters\EmergencyFilter
|
class: Chill\ActivityBundle\Export\Filter\ACPFilters\EmergencyFilter
|
||||||
@ -112,9 +112,16 @@ services:
|
|||||||
tags:
|
tags:
|
||||||
- { name: chill.export_filter, alias: 'activity_userscope_filter' }
|
- { 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' }
|
||||||
|
|
||||||
## Aggregators
|
## Aggregators
|
||||||
chill.activity.export.reason_aggregator:
|
Chill\ActivityBundle\Export\Aggregator\PersonAggregators\ActivityReasonAggregator:
|
||||||
class: Chill\ActivityBundle\Export\Aggregator\PersonAggregators\ActivityReasonAggregator
|
|
||||||
tags:
|
tags:
|
||||||
- { name: chill.export_aggregator, alias: activity_reason_aggregator }
|
- { name: chill.export_aggregator, alias: activity_reason_aggregator }
|
||||||
|
|
||||||
@ -138,10 +145,9 @@ services:
|
|||||||
tags:
|
tags:
|
||||||
- { name: chill.export_aggregator, alias: activity_date_aggregator }
|
- { name: chill.export_aggregator, alias: activity_date_aggregator }
|
||||||
|
|
||||||
chill.activity.export.byuser_aggregator:
|
Chill\ActivityBundle\Export\Aggregator\ACPAggregators\ByCreatorAggregator:
|
||||||
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\ByUserAggregator
|
|
||||||
tags:
|
tags:
|
||||||
- { name: chill.export_aggregator, alias: activity_byuser_aggregator }
|
- { name: chill.export_aggregator, alias: activity_by_creator_aggregator }
|
||||||
|
|
||||||
chill.activity.export.bythirdparty_aggregator:
|
chill.activity.export.bythirdparty_aggregator:
|
||||||
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\ByThirdpartyAggregator
|
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\ByThirdpartyAggregator
|
||||||
@ -158,7 +164,18 @@ services:
|
|||||||
tags:
|
tags:
|
||||||
- { name: chill.export_aggregator, alias: activity_bysocialissue_aggregator }
|
- { name: chill.export_aggregator, alias: activity_bysocialissue_aggregator }
|
||||||
|
|
||||||
chill.activity.export.userscope_aggregator:
|
Chill\ActivityBundle\Export\Aggregator\ACPAggregators\CreatorScopeAggregator:
|
||||||
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\UserScopeAggregator
|
|
||||||
tags:
|
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 }
|
||||||
|
@ -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"');
|
||||||
|
}
|
||||||
|
}
|
@ -252,8 +252,6 @@ Filter by activity type: Filtrer les activités par type
|
|||||||
Filter activity by locationtype: Filtrer les activités par type de localisation
|
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%"
|
'Filtered activity by locationtype: only %types%': "Filtré par type de localisation: uniquement %types%"
|
||||||
Accepted locationtype: Types de localisation
|
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)
|
Accepted users: TMS(s)
|
||||||
Filter activity by emergency: Filtrer les activités par urgence
|
Filter activity by emergency: Filtrer les activités par urgence
|
||||||
'Filtered activity by emergency: only %emergency%': "Filtré par urgence: uniquement si %emergency%"
|
'Filtered activity by emergency: only %emergency%': "Filtré par urgence: uniquement si %emergency%"
|
||||||
@ -269,7 +267,11 @@ Filter activity by linked socialaction: Filtrer les activités par action liée
|
|||||||
Filter activity by linked socialissue: Filtrer les activités par problématique liée
|
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%"
|
'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
|
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
|
Creators: Créateurs
|
||||||
Filter activity by userscope: Filtrer les activités par service du créateur
|
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%"
|
'Filtered activity by userscope: only %scopes%': "Filtré par service du créateur: uniquement %scopes%"
|
||||||
@ -282,9 +284,14 @@ By reason: Par sujet
|
|||||||
By category of reason: Par catégorie de sujet
|
By category of reason: Par catégorie de sujet
|
||||||
Reason's level: Niveau du sujet
|
Reason's level: Niveau du sujet
|
||||||
Group by reasons: Sujet d'activité
|
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 type: Grouper les activités par type
|
||||||
Aggregate by activity reason: Grouper les activités par sujet
|
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 locationtype: Grouper les activités par type de localisation
|
||||||
Group activity by date: Grouper les activités par date
|
Group activity by date: Grouper les activités par date
|
||||||
@ -294,7 +301,8 @@ by week: Par semaine
|
|||||||
for week: Semaine
|
for week: Semaine
|
||||||
by year: Par année
|
by year: Par année
|
||||||
in year: En
|
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é
|
Group activity by linked thirdparties: Grouper les activités par tiers impliqué
|
||||||
Accepted thirdparty: Tiers impliqué
|
Accepted thirdparty: Tiers impliqué
|
||||||
Group activity by linked socialaction: Grouper les activités par action liée
|
Group activity by linked socialaction: Grouper les activités par action liée
|
||||||
@ -314,3 +322,13 @@ docgen:
|
|||||||
A basic context for activity: Contexte pour les échanges
|
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: 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.
|
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.
|
||||||
|
|
||||||
|
export:
|
||||||
|
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%'
|
||||||
|
@ -46,14 +46,7 @@ final class AgentAggregator implements AggregatorInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
$qb->addSelect('caluser.id AS agent_aggregator');
|
$qb->addSelect('caluser.id AS agent_aggregator');
|
||||||
|
|
||||||
$groupBy = $qb->getDQLPart('groupBy');
|
|
||||||
|
|
||||||
if (!empty($groupBy)) {
|
|
||||||
$qb->addGroupBy('agent_aggregator');
|
$qb->addGroupBy('agent_aggregator');
|
||||||
} else {
|
|
||||||
$qb->groupBy('agent_aggregator');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
|
@ -47,14 +47,7 @@ class CancelReasonAggregator implements AggregatorInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
$qb->addSelect('IDENTITY(cal.cancelReason) as cancel_reason_aggregator');
|
$qb->addSelect('IDENTITY(cal.cancelReason) as cancel_reason_aggregator');
|
||||||
|
|
||||||
$groupBy = $qb->getDQLPart('groupBy');
|
|
||||||
|
|
||||||
if (!empty($groupBy)) {
|
|
||||||
$qb->addGroupBy('cancel_reason_aggregator');
|
$qb->addGroupBy('cancel_reason_aggregator');
|
||||||
} else {
|
|
||||||
$qb->groupBy('cancel_reason_aggregator');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
|
@ -46,14 +46,7 @@ final class JobAggregator implements AggregatorInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
$qb->addSelect('IDENTITY(caluser.userJob) as job_aggregator');
|
$qb->addSelect('IDENTITY(caluser.userJob) as job_aggregator');
|
||||||
|
|
||||||
$groupBy = $qb->getDQLPart('groupBy');
|
|
||||||
|
|
||||||
if (!empty($groupBy)) {
|
|
||||||
$qb->addGroupBy('job_aggregator');
|
$qb->addGroupBy('job_aggregator');
|
||||||
} else {
|
|
||||||
$qb->groupBy('job_aggregator');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
|
@ -40,14 +40,7 @@ final class LocationAggregator implements AggregatorInterface
|
|||||||
$qb->join('cal.location', 'calloc');
|
$qb->join('cal.location', 'calloc');
|
||||||
}
|
}
|
||||||
$qb->addSelect('IDENTITY(cal.location) as location_aggregator');
|
$qb->addSelect('IDENTITY(cal.location) as location_aggregator');
|
||||||
|
|
||||||
$groupBy = $qb->getDQLPart('groupBy');
|
|
||||||
|
|
||||||
if (!empty($groupBy)) {
|
|
||||||
$qb->addGroupBy('location_aggregator');
|
$qb->addGroupBy('location_aggregator');
|
||||||
} else {
|
|
||||||
$qb->groupBy('location_aggregator');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
|
@ -46,14 +46,7 @@ final class LocationTypeAggregator implements AggregatorInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
$qb->addSelect('IDENTITY(calloc.locationType) as location_type_aggregator');
|
$qb->addSelect('IDENTITY(calloc.locationType) as location_type_aggregator');
|
||||||
|
|
||||||
$groupBy = $qb->getDQLPart('groupBy');
|
|
||||||
|
|
||||||
if (!empty($groupBy)) {
|
|
||||||
$qb->addGroupBy('location_type_aggregator');
|
$qb->addGroupBy('location_type_aggregator');
|
||||||
} else {
|
|
||||||
$qb->groupBy('location_type_aggregator');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
|
@ -28,13 +28,7 @@ class MonthYearAggregator implements AggregatorInterface
|
|||||||
{
|
{
|
||||||
$qb->addSelect("to_char(cal.startDate, 'MM-YYYY') AS month_year_aggregator");
|
$qb->addSelect("to_char(cal.startDate, 'MM-YYYY') AS month_year_aggregator");
|
||||||
// $qb->addSelect("extract(month from age(cal.startDate, cal.endDate)) AS month_aggregator");
|
// $qb->addSelect("extract(month from age(cal.startDate, cal.endDate)) AS month_aggregator");
|
||||||
$groupBy = $qb->getDQLPart('groupBy');
|
|
||||||
|
|
||||||
if (!empty($groupBy)) {
|
|
||||||
$qb->addGroupBy('month_year_aggregator');
|
$qb->addGroupBy('month_year_aggregator');
|
||||||
} else {
|
|
||||||
$qb->groupBy('month_year_aggregator');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
@ -54,10 +48,7 @@ class MonthYearAggregator implements AggregatorInterface
|
|||||||
return 'by month and year';
|
return 'by month and year';
|
||||||
}
|
}
|
||||||
|
|
||||||
$month = (int) substr($value, 0, 2);
|
return $value;
|
||||||
$year = (int) substr($value, 3, 4);
|
|
||||||
|
|
||||||
return strftime('%B %G', mktime(0, 0, 0, $month, 1, $year));
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,14 +46,7 @@ final class ScopeAggregator implements AggregatorInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
$qb->addSelect('IDENTITY(caluser.mainScope) as scope_aggregator');
|
$qb->addSelect('IDENTITY(caluser.mainScope) as scope_aggregator');
|
||||||
|
|
||||||
$groupBy = $qb->getDQLPart('groupBy');
|
|
||||||
|
|
||||||
if (!empty($groupBy)) {
|
|
||||||
$qb->addGroupBy('scope_aggregator');
|
$qb->addGroupBy('scope_aggregator');
|
||||||
} else {
|
|
||||||
$qb->groupBy('scope_aggregator');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
|
@ -71,9 +71,9 @@ class CountCalendars implements ExportInterface, GroupedExportInterface
|
|||||||
return ['export_result'];
|
return ['export_result'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getResult($qb, $data)
|
public function getResult($query, $data)
|
||||||
{
|
{
|
||||||
return $qb->getQuery()->getResult(AbstractQuery::HYDRATE_SCALAR);
|
return $query->getQuery()->getResult(AbstractQuery::HYDRATE_SCALAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTitle(): string
|
public function getTitle(): string
|
||||||
|
@ -71,9 +71,9 @@ class StatCalendarAvgDuration implements ExportInterface, GroupedExportInterface
|
|||||||
return ['export_result'];
|
return ['export_result'];
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
public function getTitle(): string
|
||||||
|
@ -71,9 +71,9 @@ class StatCalendarSumDuration implements ExportInterface, GroupedExportInterface
|
|||||||
return ['export_result'];
|
return ['export_result'];
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
public function getTitle(): string
|
||||||
|
@ -76,7 +76,7 @@ class AgentFilter implements FilterInterface
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
'Filtered by agent: only %agents%', [
|
'Filtered by agent: only %agents%', [
|
||||||
'%agents' => implode(', ou ', $users),
|
'%agents' => implode(', ', $users),
|
||||||
], ];
|
], ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ class JobFilter implements FilterInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ['Filtered by agent job: only %jobs%', [
|
return ['Filtered by agent job: only %jobs%', [
|
||||||
'%jobs%' => implode(', ou ', $userJobs),
|
'%jobs%' => implode(', ', $userJobs),
|
||||||
]];
|
]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ class ScopeFilter implements FilterInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ['Filtered by agent scope: only %scopes%', [
|
return ['Filtered by agent scope: only %scopes%', [
|
||||||
'%scopes%' => implode(', ou ', $scopes),
|
'%scopes%' => implode(', ', $scopes),
|
||||||
]];
|
]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,9 @@ class BaseContextData
|
|||||||
$data['createdAt'] = $this->normalizer->normalize(new DateTimeImmutable(), 'docgen', [
|
$data['createdAt'] = $this->normalizer->normalize(new DateTimeImmutable(), 'docgen', [
|
||||||
'docgen:expects' => DateTimeImmutable::class, 'groups' => ['docgen:read'],
|
'docgen:expects' => DateTimeImmutable::class, 'groups' => ['docgen:read'],
|
||||||
]);
|
]);
|
||||||
|
$data['createdAtDate'] = $this->normalizer->normalize(new DateTimeImmutable('today'), 'docgen', [
|
||||||
|
'docgen:expects' => DateTimeImmutable::class, 'groups' => ['docgen:read'],
|
||||||
|
]);
|
||||||
$data['location'] = $this->normalizer->normalize(
|
$data['location'] = $this->normalizer->normalize(
|
||||||
$user instanceof User ? $user->getCurrentLocation() : null,
|
$user instanceof User ? $user->getCurrentLocation() : null,
|
||||||
'docgen',
|
'docgen',
|
||||||
|
@ -34,7 +34,7 @@ class AccompanyingCourseDocument extends Document implements HasScopesInterface
|
|||||||
|
|
||||||
public function getScopes(): iterable
|
public function getScopes(): iterable
|
||||||
{
|
{
|
||||||
if (null !== $this->course) {
|
if (null === $this->course) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|||||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||||
use Symfony\Component\Form\FormFactoryInterface;
|
use Symfony\Component\Form\FormFactoryInterface;
|
||||||
|
use Symfony\Component\Form\FormInterface;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||||
@ -191,18 +192,12 @@ class ExportController extends AbstractController
|
|||||||
case 'export':
|
case 'export':
|
||||||
return $this->exportFormStep($request, $export, $alias);
|
return $this->exportFormStep($request, $export, $alias);
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'formatter':
|
case 'formatter':
|
||||||
return $this->formatterFormStep($request, $export, $alias);
|
return $this->formatterFormStep($request, $export, $alias);
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'generate':
|
case 'generate':
|
||||||
return $this->forwardToGenerate($request, $export, $alias);
|
return $this->forwardToGenerate($request, $export, $alias);
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw $this->createNotFoundException("The given step '{$step}' is invalid");
|
throw $this->createNotFoundException("The given step '{$step}' is invalid");
|
||||||
}
|
}
|
||||||
@ -214,10 +209,8 @@ class ExportController extends AbstractController
|
|||||||
* @param string $alias
|
* @param string $alias
|
||||||
* @param array $data the data from previous step. Required for steps 'formatter' and 'generate_formatter'
|
* @param array $data the data from previous step. Required for steps 'formatter' and 'generate_formatter'
|
||||||
* @param mixed $step
|
* @param mixed $step
|
||||||
*
|
|
||||||
* @return \Symfony\Component\Form\Form
|
|
||||||
*/
|
*/
|
||||||
protected function createCreateFormExport($alias, $step, $data = [])
|
protected function createCreateFormExport($alias, $step, $data = []): FormInterface
|
||||||
{
|
{
|
||||||
/** @var \Chill\MainBundle\Export\ExportManager $exportManager */
|
/** @var \Chill\MainBundle\Export\ExportManager $exportManager */
|
||||||
$exportManager = $this->exportManager;
|
$exportManager = $this->exportManager;
|
||||||
@ -475,8 +468,6 @@ class ExportController extends AbstractController
|
|||||||
* @param \Chill\MainBundle\Export\DirectExportInterface|\Chill\MainBundle\Export\ExportInterface $export
|
* @param \Chill\MainBundle\Export\DirectExportInterface|\Chill\MainBundle\Export\ExportInterface $export
|
||||||
* @param string $alias
|
* @param string $alias
|
||||||
*
|
*
|
||||||
* @throws type
|
|
||||||
*
|
|
||||||
* @return Response
|
* @return Response
|
||||||
*/
|
*/
|
||||||
protected function selectCentersStep(Request $request, $export, $alias)
|
protected function selectCentersStep(Request $request, $export, $alias)
|
||||||
@ -543,6 +534,8 @@ class ExportController extends AbstractController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,6 +22,7 @@ use Chill\MainBundle\Controller\UserController;
|
|||||||
use Chill\MainBundle\Controller\UserJobApiController;
|
use Chill\MainBundle\Controller\UserJobApiController;
|
||||||
use Chill\MainBundle\Controller\UserJobController;
|
use Chill\MainBundle\Controller\UserJobController;
|
||||||
use Chill\MainBundle\DependencyInjection\Widget\Factory\WidgetFactoryInterface;
|
use Chill\MainBundle\DependencyInjection\Widget\Factory\WidgetFactoryInterface;
|
||||||
|
use Chill\MainBundle\Doctrine\DQL\Age;
|
||||||
use Chill\MainBundle\Doctrine\DQL\Extract;
|
use Chill\MainBundle\Doctrine\DQL\Extract;
|
||||||
use Chill\MainBundle\Doctrine\DQL\GetJsonFieldByKey;
|
use Chill\MainBundle\Doctrine\DQL\GetJsonFieldByKey;
|
||||||
use Chill\MainBundle\Doctrine\DQL\JsonAggregate;
|
use Chill\MainBundle\Doctrine\DQL\JsonAggregate;
|
||||||
@ -248,6 +249,7 @@ class ChillMainExtension extends Extension implements
|
|||||||
'datetime_functions' => [
|
'datetime_functions' => [
|
||||||
'EXTRACT' => Extract::class,
|
'EXTRACT' => Extract::class,
|
||||||
'TO_CHAR' => ToChar::class,
|
'TO_CHAR' => ToChar::class,
|
||||||
|
'AGE' => Age::class,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'hydrators' => [
|
'hydrators' => [
|
||||||
|
@ -11,6 +11,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\MainBundle\DependencyInjection\CompilerPass;
|
namespace Chill\MainBundle\DependencyInjection\CompilerPass;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Export\ExportManager;
|
||||||
use LogicException;
|
use LogicException;
|
||||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
@ -30,53 +31,19 @@ class ExportsCompilerPass implements CompilerPassInterface
|
|||||||
{
|
{
|
||||||
public function process(ContainerBuilder $container)
|
public function process(ContainerBuilder $container)
|
||||||
{
|
{
|
||||||
if (!$container->has('Chill\MainBundle\Export\ExportManager')) {
|
if (!$container->has(ExportManager::class)) {
|
||||||
throw new LogicException('service Chill\MainBundle\Export\ExportManager '
|
throw new LogicException('service ' . ExportManager::class . ' '
|
||||||
. 'is not defined. It is required by ExportsCompilerPass');
|
. 'is not defined. It is required by ExportsCompilerPass');
|
||||||
}
|
}
|
||||||
|
|
||||||
$chillManagerDefinition = $container->findDefinition(
|
$chillManagerDefinition = $container->findDefinition(
|
||||||
'Chill\MainBundle\Export\ExportManager'
|
ExportManager::class
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->compileExports($chillManagerDefinition, $container);
|
|
||||||
$this->compileFilters($chillManagerDefinition, $container);
|
|
||||||
$this->compileAggregators($chillManagerDefinition, $container);
|
|
||||||
$this->compileFormatters($chillManagerDefinition, $container);
|
$this->compileFormatters($chillManagerDefinition, $container);
|
||||||
$this->compileExportElementsProvider($chillManagerDefinition, $container);
|
$this->compileExportElementsProvider($chillManagerDefinition, $container);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function compileAggregators(
|
|
||||||
Definition $chillManagerDefinition,
|
|
||||||
ContainerBuilder $container
|
|
||||||
) {
|
|
||||||
$taggedServices = $container->findTaggedServiceIds(
|
|
||||||
'chill.export_aggregator'
|
|
||||||
);
|
|
||||||
|
|
||||||
$knownAliases = [];
|
|
||||||
|
|
||||||
foreach ($taggedServices as $id => $tagAttributes) {
|
|
||||||
foreach ($tagAttributes as $attributes) {
|
|
||||||
if (!isset($attributes['alias'])) {
|
|
||||||
throw new LogicException("the 'alias' attribute is missing in your " .
|
|
||||||
"service '{$id}' definition");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (array_search($attributes['alias'], $knownAliases, true)) {
|
|
||||||
throw new LogicException('There is already a chill.export_aggregator service with alias '
|
|
||||||
. $attributes['alias'] . '. Choose another alias.');
|
|
||||||
}
|
|
||||||
$knownAliases[] = $attributes['alias'];
|
|
||||||
|
|
||||||
$chillManagerDefinition->addMethodCall(
|
|
||||||
'addAggregator',
|
|
||||||
[new Reference($id), $attributes['alias']]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function compileExportElementsProvider(
|
private function compileExportElementsProvider(
|
||||||
Definition $chillManagerDefinition,
|
Definition $chillManagerDefinition,
|
||||||
ContainerBuilder $container
|
ContainerBuilder $container
|
||||||
@ -108,68 +75,6 @@ class ExportsCompilerPass implements CompilerPassInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function compileExports(
|
|
||||||
Definition $chillManagerDefinition,
|
|
||||||
ContainerBuilder $container
|
|
||||||
) {
|
|
||||||
$taggedServices = $container->findTaggedServiceIds(
|
|
||||||
'chill.export'
|
|
||||||
);
|
|
||||||
|
|
||||||
$knownAliases = [];
|
|
||||||
|
|
||||||
foreach ($taggedServices as $id => $tagAttributes) {
|
|
||||||
foreach ($tagAttributes as $attributes) {
|
|
||||||
if (!isset($attributes['alias'])) {
|
|
||||||
throw new LogicException("the 'alias' attribute is missing in your " .
|
|
||||||
"service '{$id}' definition");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (array_search($attributes['alias'], $knownAliases, true)) {
|
|
||||||
throw new LogicException('There is already a chill.export service with alias '
|
|
||||||
. $attributes['alias'] . '. Choose another alias.');
|
|
||||||
}
|
|
||||||
$knownAliases[] = $attributes['alias'];
|
|
||||||
|
|
||||||
$chillManagerDefinition->addMethodCall(
|
|
||||||
'addExport',
|
|
||||||
[new Reference($id), $attributes['alias']]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function compileFilters(
|
|
||||||
Definition $chillManagerDefinition,
|
|
||||||
ContainerBuilder $container
|
|
||||||
) {
|
|
||||||
$taggedServices = $container->findTaggedServiceIds(
|
|
||||||
'chill.export_filter'
|
|
||||||
);
|
|
||||||
|
|
||||||
$knownAliases = [];
|
|
||||||
|
|
||||||
foreach ($taggedServices as $id => $tagAttributes) {
|
|
||||||
foreach ($tagAttributes as $attributes) {
|
|
||||||
if (!isset($attributes['alias'])) {
|
|
||||||
throw new LogicException("the 'alias' attribute is missing in your " .
|
|
||||||
"service '{$id}' definition");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (array_search($attributes['alias'], $knownAliases, true)) {
|
|
||||||
throw new LogicException('There is already a chill.export_filter service with alias '
|
|
||||||
. $attributes['alias'] . '. Choose another alias.');
|
|
||||||
}
|
|
||||||
$knownAliases[] = $attributes['alias'];
|
|
||||||
|
|
||||||
$chillManagerDefinition->addMethodCall(
|
|
||||||
'addFilter',
|
|
||||||
[new Reference($id), $attributes['alias']]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function compileFormatters(
|
private function compileFormatters(
|
||||||
Definition $chillManagerDefinition,
|
Definition $chillManagerDefinition,
|
||||||
ContainerBuilder $container
|
ContainerBuilder $container
|
||||||
|
54
src/Bundle/ChillMainBundle/Doctrine/DQL/Age.php
Normal file
54
src/Bundle/ChillMainBundle/Doctrine/DQL/Age.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?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\MainBundle\Doctrine\DQL;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
|
||||||
|
use Doctrine\ORM\Query\Lexer;
|
||||||
|
use Doctrine\ORM\Query\Parser;
|
||||||
|
use Doctrine\ORM\Query\SqlWalker;
|
||||||
|
|
||||||
|
class Age extends FunctionNode
|
||||||
|
{
|
||||||
|
private $value1;
|
||||||
|
|
||||||
|
private $value2;
|
||||||
|
|
||||||
|
public function getSql(SqlWalker $sqlWalker)
|
||||||
|
{
|
||||||
|
if (null !== $this->value2) {
|
||||||
|
return sprintf(
|
||||||
|
'AGE(%s, %s)',
|
||||||
|
$this->value1->dispatch($sqlWalker),
|
||||||
|
$this->value2->dispatch($sqlWalker)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
'AGE(%s)',
|
||||||
|
$this->value1->dispatch($sqlWalker),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parse(Parser $parser)
|
||||||
|
{
|
||||||
|
$parser->match(Lexer::T_IDENTIFIER);
|
||||||
|
$parser->match(Lexer::T_OPEN_PARENTHESIS);
|
||||||
|
|
||||||
|
$this->value1 = $parser->SimpleArithmeticExpression();
|
||||||
|
|
||||||
|
$parser->match(Lexer::T_COMMA);
|
||||||
|
|
||||||
|
$this->value2 = $parser->SimpleArithmeticExpression();
|
||||||
|
|
||||||
|
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
|
||||||
|
}
|
||||||
|
}
|
@ -27,7 +27,7 @@ class JsonbExistsInArray extends FunctionNode
|
|||||||
return sprintf(
|
return sprintf(
|
||||||
'%s ?? %s',
|
'%s ?? %s',
|
||||||
$this->expr1->dispatch($sqlWalker),
|
$this->expr1->dispatch($sqlWalker),
|
||||||
$sqlWalker->walkInputParameter($this->expr2)
|
$this->expr2->dispatch($sqlWalker)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ use Doctrine\DBAL\Types\ConversionException;
|
|||||||
use Doctrine\DBAL\Types\DateIntervalType;
|
use Doctrine\DBAL\Types\DateIntervalType;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
|
||||||
|
use LogicException;
|
||||||
use function count;
|
use function count;
|
||||||
use function current;
|
use function current;
|
||||||
use function preg_match;
|
use function preg_match;
|
||||||
@ -40,7 +41,7 @@ class NativeDateIntervalType extends DateIntervalType
|
|||||||
return $value->format(self::FORMAT);
|
return $value->format(self::FORMAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'DateInterval']);
|
throw ConversionException::conversionFailedInvalidType($value, 'string', ['null', 'DateInterval']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function convertToPHPValue($value, AbstractPlatform $platform)
|
public function convertToPHPValue($value, AbstractPlatform $platform)
|
||||||
@ -80,7 +81,7 @@ class NativeDateIntervalType extends DateIntervalType
|
|||||||
|
|
||||||
protected function createConversionException($value, $exception = null)
|
protected function createConversionException($value, $exception = null)
|
||||||
{
|
{
|
||||||
return ConversionException::conversionFailedFormat($value, $this->getName(), 'xx year xx mons xx days 01:02:03', $exception);
|
return ConversionException::conversionFailedFormat($value, 'string', 'xx year xx mons xx days 01:02:03', $exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function convertEntry(&$strings)
|
private function convertEntry(&$strings)
|
||||||
@ -125,5 +126,7 @@ class NativeDateIntervalType extends DateIntervalType
|
|||||||
|
|
||||||
return $intervalSpec;
|
return $intervalSpec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new LogicException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,11 @@ use Symfony\Component\Serializer\Annotation\Groups;
|
|||||||
*/
|
*/
|
||||||
class Scope
|
class Scope
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="boolean", nullable=false, options={"default": true})
|
||||||
|
*/
|
||||||
|
private bool $active = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Id
|
* @ORM\Id
|
||||||
* @ORM\Column(name="id", type="integer")
|
* @ORM\Column(name="id", type="integer")
|
||||||
@ -88,6 +93,18 @@ class Scope
|
|||||||
return $this->roleScopes;
|
return $this->roleScopes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isActive(): bool
|
||||||
|
{
|
||||||
|
return $this->active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setActive(bool $active): Scope
|
||||||
|
{
|
||||||
|
$this->active = $active;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $name
|
* @param $name
|
||||||
*
|
*
|
||||||
|
@ -11,28 +11,22 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\MainBundle\Export;
|
namespace Chill\MainBundle\Export;
|
||||||
|
|
||||||
use Symfony\Component\Security\Core\Role\Role;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
interface DirectExportInterface extends ExportElementInterface
|
interface DirectExportInterface extends ExportElementInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Generate the export.
|
* Generate the export.
|
||||||
*
|
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
|
||||||
*/
|
*/
|
||||||
public function generate(array $acl, array $data = []);
|
public function generate(array $acl, array $data = []): Response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get a description, which will be used in UI (and translated).
|
* get a description, which will be used in UI (and translated).
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getDescription();
|
public function getDescription(): string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* authorized role.
|
* authorized role.
|
||||||
*
|
|
||||||
* @return \Symfony\Component\Security\Core\Role\Role
|
|
||||||
*/
|
*/
|
||||||
public function requiredRole();
|
public function requiredRole(): string;
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,8 @@ namespace Chill\MainBundle\Export;
|
|||||||
use Chill\MainBundle\Form\Type\Export\ExportType;
|
use Chill\MainBundle\Form\Type\Export\ExportType;
|
||||||
use Chill\MainBundle\Form\Type\Export\PickCenterType;
|
use Chill\MainBundle\Form\Type\Export\PickCenterType;
|
||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Generator;
|
use Generator;
|
||||||
use InvalidArgumentException;
|
|
||||||
use LogicException;
|
use LogicException;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
@ -50,8 +48,6 @@ class ExportManager
|
|||||||
|
|
||||||
private AuthorizationHelperInterface $authorizationHelper;
|
private AuthorizationHelperInterface $authorizationHelper;
|
||||||
|
|
||||||
private EntityManagerInterface $em;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collected Exports, injected by DI.
|
* Collected Exports, injected by DI.
|
||||||
*
|
*
|
||||||
@ -82,16 +78,28 @@ class ExportManager
|
|||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
LoggerInterface $logger,
|
LoggerInterface $logger,
|
||||||
EntityManagerInterface $em,
|
|
||||||
AuthorizationCheckerInterface $authorizationChecker,
|
AuthorizationCheckerInterface $authorizationChecker,
|
||||||
AuthorizationHelperInterface $authorizationHelper,
|
AuthorizationHelperInterface $authorizationHelper,
|
||||||
TokenStorageInterface $tokenStorage
|
TokenStorageInterface $tokenStorage,
|
||||||
|
iterable $exports,
|
||||||
|
iterable $aggregators,
|
||||||
|
iterable $filters
|
||||||
|
//iterable $formatters,
|
||||||
|
//iterable $exportElementProvider
|
||||||
) {
|
) {
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
$this->em = $em;
|
|
||||||
$this->authorizationChecker = $authorizationChecker;
|
$this->authorizationChecker = $authorizationChecker;
|
||||||
$this->authorizationHelper = $authorizationHelper;
|
$this->authorizationHelper = $authorizationHelper;
|
||||||
$this->user = $tokenStorage->getToken()->getUser();
|
$this->user = $tokenStorage->getToken()->getUser();
|
||||||
|
$this->exports = iterator_to_array($exports);
|
||||||
|
$this->aggregators = iterator_to_array($aggregators);
|
||||||
|
$this->filters = iterator_to_array($filters);
|
||||||
|
// NOTE: PHP crashes on the next line (exit error code 11). This is desactivated until further investigation
|
||||||
|
//$this->formatters = iterator_to_array($formatters);
|
||||||
|
|
||||||
|
//foreach ($exportElementProvider as $prefix => $provider) {
|
||||||
|
// $this->addExportElementsProvider($provider, $prefix);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -141,52 +149,17 @@ class ExportManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* add an aggregator.
|
|
||||||
*
|
|
||||||
* @internal used by DI
|
|
||||||
*
|
|
||||||
* @param string $alias
|
|
||||||
*/
|
|
||||||
public function addAggregator(AggregatorInterface $aggregator, $alias)
|
|
||||||
{
|
|
||||||
$this->aggregators[$alias] = $aggregator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* add an export.
|
|
||||||
*
|
|
||||||
* @internal used by DI
|
|
||||||
*
|
|
||||||
* @param DirectExportInterface|ExportInterface $export
|
|
||||||
* @param type $alias
|
|
||||||
*/
|
|
||||||
public function addExport($export, $alias)
|
|
||||||
{
|
|
||||||
if ($export instanceof ExportInterface || $export instanceof DirectExportInterface) {
|
|
||||||
$this->exports[$alias] = $export;
|
|
||||||
} else {
|
|
||||||
throw new InvalidArgumentException(sprintf(
|
|
||||||
'The export with alias %s '
|
|
||||||
. 'does not implements %s or %s.',
|
|
||||||
$alias,
|
|
||||||
ExportInterface::class,
|
|
||||||
DirectExportInterface::class
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addExportElementsProvider(ExportElementsProviderInterface $provider, $prefix)
|
public function addExportElementsProvider(ExportElementsProviderInterface $provider, $prefix)
|
||||||
{
|
{
|
||||||
foreach ($provider->getExportElements() as $suffix => $element) {
|
foreach ($provider->getExportElements() as $suffix => $element) {
|
||||||
$alias = $prefix . '_' . $suffix;
|
$alias = $prefix . '_' . $suffix;
|
||||||
|
|
||||||
if ($element instanceof ExportInterface) {
|
if ($element instanceof ExportInterface) {
|
||||||
$this->addExport($element, $alias);
|
$this->exports[$alias] = $element;
|
||||||
} elseif ($element instanceof FilterInterface) {
|
} elseif ($element instanceof FilterInterface) {
|
||||||
$this->addFilter($element, $alias);
|
$this->filters[$alias] = $element;
|
||||||
} elseif ($element instanceof AggregatorInterface) {
|
} elseif ($element instanceof AggregatorInterface) {
|
||||||
$this->addAggregator($element, $alias);
|
$this->aggregators[$alias] = $element;
|
||||||
} elseif ($element instanceof FormatterInterface) {
|
} elseif ($element instanceof FormatterInterface) {
|
||||||
$this->addFormatter($element, $alias);
|
$this->addFormatter($element, $alias);
|
||||||
} else {
|
} else {
|
||||||
@ -196,24 +169,12 @@ class ExportManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* add a Filter.
|
|
||||||
*
|
|
||||||
* @internal Normally used by the dependency injection
|
|
||||||
*
|
|
||||||
* @param string $alias
|
|
||||||
*/
|
|
||||||
public function addFilter(FilterInterface $filter, $alias)
|
|
||||||
{
|
|
||||||
$this->filters[$alias] = $filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add a formatter.
|
* add a formatter.
|
||||||
*
|
*
|
||||||
* @internal used by DI
|
* @internal used by DI
|
||||||
*
|
*
|
||||||
* @param type $alias
|
* @param string $alias
|
||||||
*/
|
*/
|
||||||
public function addFormatter(FormatterInterface $formatter, $alias)
|
public function addFormatter(FormatterInterface $formatter, $alias)
|
||||||
{
|
{
|
||||||
@ -231,7 +192,6 @@ class ExportManager
|
|||||||
public function generate($exportAlias, array $pickedCentersData, array $data, array $formatterData)
|
public function generate($exportAlias, array $pickedCentersData, array $data, array $formatterData)
|
||||||
{
|
{
|
||||||
$export = $this->getExport($exportAlias);
|
$export = $this->getExport($exportAlias);
|
||||||
//$qb = $this->em->createQueryBuilder();
|
|
||||||
$centers = $this->getPickedCenters($pickedCentersData);
|
$centers = $this->getPickedCenters($pickedCentersData);
|
||||||
|
|
||||||
if ($export instanceof DirectExportInterface) {
|
if ($export instanceof DirectExportInterface) {
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
<?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\MainBundle\Form\Type;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\LocationType;
|
||||||
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
class PickLocationTypeType extends AbstractType
|
||||||
|
{
|
||||||
|
private TranslatableStringHelper $translatableStringHelper;
|
||||||
|
|
||||||
|
public function __construct(TranslatableStringHelper $translatableStringHelper)
|
||||||
|
{
|
||||||
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver
|
||||||
|
->setDefaults([
|
||||||
|
'class' => LocationType::class,
|
||||||
|
'choice_label' => function (LocationType $type) {
|
||||||
|
return $this->translatableStringHelper->localize($type->getTitle());
|
||||||
|
},
|
||||||
|
'placeholder' => 'Pick a location type',
|
||||||
|
'required' => false,
|
||||||
|
'attr' => ['class' => 'select2'],
|
||||||
|
'label' => 'Location type',
|
||||||
|
'multiple' => false,
|
||||||
|
])
|
||||||
|
->setAllowedTypes('multiple', ['bool']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParent(): string
|
||||||
|
{
|
||||||
|
return EntityType::class;
|
||||||
|
}
|
||||||
|
}
|
@ -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\MainBundle\Form\Type;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Location;
|
||||||
|
use Chill\MainBundle\Repository\LocationRepository;
|
||||||
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
class PickUserLocationType extends AbstractType
|
||||||
|
{
|
||||||
|
private LocationRepository $locationRepository;
|
||||||
|
|
||||||
|
private TranslatableStringHelper $translatableStringHelper;
|
||||||
|
|
||||||
|
public function __construct(TranslatableStringHelper $translatableStringHelper, LocationRepository $locationRepository)
|
||||||
|
{
|
||||||
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
|
$this->locationRepository = $locationRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver
|
||||||
|
->setDefaults([
|
||||||
|
'class' => Location::class,
|
||||||
|
'choices' => $this->locationRepository->findByPublicLocations(),
|
||||||
|
'choice_label' => function (Location $entity) {
|
||||||
|
return $entity->getName() ?
|
||||||
|
$entity->getName() . ' (' . $this->translatableStringHelper->localize($entity->getLocationType()->getTitle()) . ')' :
|
||||||
|
$this->translatableStringHelper->localize($entity->getLocationType()->getTitle());
|
||||||
|
},
|
||||||
|
'placeholder' => 'Pick a location',
|
||||||
|
'required' => false,
|
||||||
|
'attr' => ['class' => 'select2'],
|
||||||
|
'label' => 'Current location',
|
||||||
|
'multiple' => false,
|
||||||
|
])
|
||||||
|
->setAllowedTypes('multiple', ['bool']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParent(): string
|
||||||
|
{
|
||||||
|
return EntityType::class;
|
||||||
|
}
|
||||||
|
}
|
@ -15,9 +15,9 @@ use Chill\MainBundle\Entity\Center;
|
|||||||
use Chill\MainBundle\Entity\Scope;
|
use Chill\MainBundle\Entity\Scope;
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\MainBundle\Form\DataMapper\ScopePickerDataMapper;
|
use Chill\MainBundle\Form\DataMapper\ScopePickerDataMapper;
|
||||||
use Chill\MainBundle\Repository\ScopeRepository;
|
|
||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
|
use RuntimeException;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||||
@ -26,11 +26,9 @@ use Symfony\Component\Form\FormInterface;
|
|||||||
use Symfony\Component\Form\FormView;
|
use Symfony\Component\Form\FormView;
|
||||||
use Symfony\Component\OptionsResolver\Options;
|
use Symfony\Component\OptionsResolver\Options;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
|
||||||
use Symfony\Component\Security\Core\Role\Role;
|
use Symfony\Component\Security\Core\Role\Role;
|
||||||
use Symfony\Component\Security\Core\Security;
|
|
||||||
|
|
||||||
use function array_map;
|
use Symfony\Component\Security\Core\Security;
|
||||||
use function count;
|
use function count;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,47 +42,37 @@ use function count;
|
|||||||
*/
|
*/
|
||||||
class ScopePickerType extends AbstractType
|
class ScopePickerType extends AbstractType
|
||||||
{
|
{
|
||||||
protected AuthorizationHelperInterface $authorizationHelper;
|
private AuthorizationHelperInterface $authorizationHelper;
|
||||||
|
|
||||||
/**
|
private Security $security;
|
||||||
* @var ScopeRepository
|
|
||||||
*/
|
|
||||||
protected $scopeRepository;
|
|
||||||
|
|
||||||
protected Security $security;
|
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var TokenStorageInterface
|
|
||||||
*/
|
|
||||||
protected $tokenStorage;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var TranslatableStringHelper
|
|
||||||
*/
|
|
||||||
protected $translatableStringHelper;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
AuthorizationHelperInterface $authorizationHelper,
|
AuthorizationHelperInterface $authorizationHelper,
|
||||||
TokenStorageInterface $tokenStorage,
|
|
||||||
ScopeRepository $scopeRepository,
|
|
||||||
Security $security,
|
Security $security,
|
||||||
TranslatableStringHelper $translatableStringHelper
|
TranslatableStringHelperInterface $translatableStringHelper
|
||||||
) {
|
) {
|
||||||
$this->authorizationHelper = $authorizationHelper;
|
$this->authorizationHelper = $authorizationHelper;
|
||||||
$this->tokenStorage = $tokenStorage;
|
|
||||||
$this->scopeRepository = $scopeRepository;
|
|
||||||
$this->security = $security;
|
$this->security = $security;
|
||||||
$this->translatableStringHelper = $translatableStringHelper;
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
{
|
{
|
||||||
$items = $this->authorizationHelper->getReachableScopes(
|
$items = array_filter(
|
||||||
|
$this->authorizationHelper->getReachableScopes(
|
||||||
$this->security->getUser(),
|
$this->security->getUser(),
|
||||||
$options['role'] instanceof Role ? $options['role']->getRole() : $options['role'],
|
$options['role'] instanceof Role ? $options['role']->getRole() : $options['role'],
|
||||||
$options['center']
|
$options['center']
|
||||||
|
),
|
||||||
|
static function (Scope $s) { return $s->isActive(); }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (0 === count($items)) {
|
||||||
|
throw new RuntimeException('no scopes are reachable. This form should not be shown to user');
|
||||||
|
}
|
||||||
|
|
||||||
if (1 !== count($items)) {
|
if (1 !== count($items)) {
|
||||||
$builder->add('scope', EntityType::class, [
|
$builder->add('scope', EntityType::class, [
|
||||||
'class' => Scope::class,
|
'class' => Scope::class,
|
||||||
@ -123,35 +111,4 @@ class ScopePickerType extends AbstractType
|
|||||||
->setRequired('role')
|
->setRequired('role')
|
||||||
->setAllowedTypes('role', ['string', Role::class]);
|
->setAllowedTypes('role', ['string', Role::class]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array|Center|Center[] $center
|
|
||||||
* @param string $role
|
|
||||||
*
|
|
||||||
* @return \Doctrine\ORM\QueryBuilder
|
|
||||||
*/
|
|
||||||
protected function buildAccessibleScopeQuery($center, $role)
|
|
||||||
{
|
|
||||||
$roles = $this->authorizationHelper->getParentRoles($role);
|
|
||||||
$roles[] = $role;
|
|
||||||
$centers = $center instanceof Center ? [$center] : $center;
|
|
||||||
|
|
||||||
$qb = $this->scopeRepository->createQueryBuilder('s');
|
|
||||||
$qb
|
|
||||||
// jointure to center
|
|
||||||
->join('s.roleScopes', 'rs')
|
|
||||||
->join('rs.permissionsGroups', 'pg')
|
|
||||||
->join('pg.groupCenters', 'gc')
|
|
||||||
// add center constraint
|
|
||||||
->where($qb->expr()->in('IDENTITY(gc.center)', ':centers'))
|
|
||||||
->setParameter('centers', array_map(static fn (Center $c) => $c->getId(), $centers))
|
|
||||||
// role constraints
|
|
||||||
->andWhere($qb->expr()->in('rs.role', ':roles'))
|
|
||||||
->setParameter('roles', $roles)
|
|
||||||
// user contraint
|
|
||||||
->andWhere(':user MEMBER OF gc.users')
|
|
||||||
->setParameter('user', $this->tokenStorage->getToken()->getUser());
|
|
||||||
|
|
||||||
return $qb;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -11,39 +11,14 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\MainBundle\Form;
|
namespace Chill\MainBundle\Form;
|
||||||
|
|
||||||
use Chill\MainBundle\Entity\Location;
|
use Chill\MainBundle\Form\Type\PickUserLocationType;
|
||||||
use Chill\MainBundle\Repository\LocationRepository;
|
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
|
||||||
class UserCurrentLocationType extends AbstractType
|
class UserCurrentLocationType extends AbstractType
|
||||||
{
|
{
|
||||||
private LocationRepository $locationRepository;
|
|
||||||
|
|
||||||
private TranslatableStringHelper $translatableStringHelper;
|
|
||||||
|
|
||||||
public function __construct(TranslatableStringHelper $translatableStringHelper, LocationRepository $locationRepository)
|
|
||||||
{
|
|
||||||
$this->translatableStringHelper = $translatableStringHelper;
|
|
||||||
$this->locationRepository = $locationRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
{
|
{
|
||||||
$builder
|
$builder->add('currentLocation', PickUserLocationType::class);
|
||||||
->add('currentLocation', EntityType::class, [
|
|
||||||
'class' => Location::class,
|
|
||||||
'choices' => $this->locationRepository->findByPublicLocations(),
|
|
||||||
'choice_label' => function (Location $entity) {
|
|
||||||
return $entity->getName() ?
|
|
||||||
$entity->getName() . ' (' . $this->translatableStringHelper->localize($entity->getLocationType()->getTitle()) . ')' :
|
|
||||||
$this->translatableStringHelper->localize($entity->getLocationType()->getTitle());
|
|
||||||
},
|
|
||||||
'placeholder' => 'Pick a location',
|
|
||||||
'required' => false,
|
|
||||||
'attr' => ['class' => 'select2'],
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,15 @@ final class ScopeRepository implements ScopeRepositoryInterface
|
|||||||
return $this->repository->findAll();
|
return $this->repository->findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function findAllActive(): array
|
||||||
|
{
|
||||||
|
$qb = $this->repository->createQueryBuilder('s');
|
||||||
|
|
||||||
|
$qb->where('s.active = \'TRUE\'');
|
||||||
|
|
||||||
|
return $qb->getQuery()->getResult();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed|null $limit
|
* @param mixed|null $limit
|
||||||
* @param mixed|null $offset
|
* @param mixed|null $offset
|
||||||
|
@ -22,10 +22,15 @@ interface ScopeRepositoryInterface extends ObjectRepository
|
|||||||
public function find($id, $lockMode = null, $lockVersion = null): ?Scope;
|
public function find($id, $lockMode = null, $lockVersion = null): ?Scope;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Scope[]
|
* @return array|Scope[]
|
||||||
*/
|
*/
|
||||||
public function findAll(): array;
|
public function findAll(): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|Scope[]
|
||||||
|
*/
|
||||||
|
public function findAllActive(): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param null|mixed $limit
|
* @param null|mixed $limit
|
||||||
* @param null|mixed $offset
|
* @param null|mixed $offset
|
||||||
|
@ -14,9 +14,8 @@ namespace Chill\MainBundle\Repository;
|
|||||||
use Chill\MainBundle\Entity\UserJob;
|
use Chill\MainBundle\Entity\UserJob;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
use Doctrine\Persistence\ObjectRepository;
|
|
||||||
|
|
||||||
class UserJobRepository implements ObjectRepository
|
class UserJobRepository implements UserJobRepositoryInterface
|
||||||
{
|
{
|
||||||
private EntityRepository $repository;
|
private EntityRepository $repository;
|
||||||
|
|
||||||
@ -38,6 +37,11 @@ class UserJobRepository implements ObjectRepository
|
|||||||
return $this->repository->findAll();
|
return $this->repository->findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function findAllActive(): array
|
||||||
|
{
|
||||||
|
return $this->repository->findBy(['active' => true]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed|null $limit
|
* @param mixed|null $limit
|
||||||
* @param mixed|null $offset
|
* @param mixed|null $offset
|
||||||
@ -49,12 +53,12 @@ class UserJobRepository implements ObjectRepository
|
|||||||
return $this->repository->findBy($criteria, $orderBy, $limit, $offset);
|
return $this->repository->findBy($criteria, $orderBy, $limit, $offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function findOneBy(array $criteria)
|
public function findOneBy(array $criteria): ?UserJob
|
||||||
{
|
{
|
||||||
return $this->repository->findOneBy($criteria);
|
return $this->repository->findOneBy($criteria);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getClassName()
|
public function getClassName(): string
|
||||||
{
|
{
|
||||||
return UserJob::class;
|
return UserJob::class;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
<?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\MainBundle\Repository;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\UserJob;
|
||||||
|
use Doctrine\Persistence\ObjectRepository;
|
||||||
|
|
||||||
|
interface UserJobRepositoryInterface extends ObjectRepository
|
||||||
|
{
|
||||||
|
public function find($id): ?UserJob;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|UserJob[]
|
||||||
|
*/
|
||||||
|
public function findAll(): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|UserJob[]
|
||||||
|
*/
|
||||||
|
public function findAllActive(): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed|null $limit
|
||||||
|
* @param mixed|null $offset
|
||||||
|
*
|
||||||
|
* @return array|object[]|UserJob[]
|
||||||
|
*/
|
||||||
|
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null);
|
||||||
|
|
||||||
|
public function findOneBy(array $criteria): ?UserJob;
|
||||||
|
|
||||||
|
public function getClassName(): string;
|
||||||
|
}
|
@ -1,12 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -119,7 +119,3 @@ document.addEventListener('DOMContentLoaded', function(e) {
|
|||||||
loadDynamicPicker(document)
|
loadDynamicPicker(document)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,7 +20,12 @@
|
|||||||
|
|
||||||
{% block title %}{{ export.title|trans }}{% endblock %}
|
{% block title %}{{ export.title|trans }}{% endblock %}
|
||||||
|
|
||||||
|
{% block css %}
|
||||||
|
{{ encore_entry_link_tags('mod_pickentity_type') }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block js %}
|
{% block js %}
|
||||||
|
{{ encore_entry_script_tags('mod_pickentity_type') }}
|
||||||
{{ encore_entry_script_tags('page_export') }}
|
{{ encore_entry_script_tags('page_export') }}
|
||||||
{% if export_alias == 'count_social_work_actions' %}
|
{% if export_alias == 'count_social_work_actions' %}
|
||||||
{{ encore_entry_script_tags('vue_export_action_goal_result') }}
|
{{ encore_entry_script_tags('vue_export_action_goal_result') }}
|
||||||
|
@ -29,6 +29,18 @@ use function is_string;
|
|||||||
*/
|
*/
|
||||||
abstract class AbstractAggregatorTest extends KernelTestCase
|
abstract class AbstractAggregatorTest extends KernelTestCase
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* provide data for `testAliasDidNotDisappears`.
|
||||||
|
*/
|
||||||
|
public function dataProviderAliasDidNotDisappears()
|
||||||
|
{
|
||||||
|
foreach ($this->getQueryBuilders() as $qb) {
|
||||||
|
foreach ($this->getFormData() as $data) {
|
||||||
|
yield [clone $qb, $data];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* provide data for `testAlterQuery`.
|
* provide data for `testAlterQuery`.
|
||||||
*/
|
*/
|
||||||
@ -95,6 +107,28 @@ abstract class AbstractAggregatorTest extends KernelTestCase
|
|||||||
*/
|
*/
|
||||||
abstract public function getQueryBuilders();
|
abstract public function getQueryBuilders();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare aliases array before and after that aggregator alter query.
|
||||||
|
*
|
||||||
|
* @dataProvider dataProviderAliasDidNotDisappears
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testAliasDidNotDisappears(QueryBuilder $qb, array $data)
|
||||||
|
{
|
||||||
|
$aliases = $qb->getAllAliases();
|
||||||
|
|
||||||
|
$this->getAggregator()->alterQuery($qb, $data);
|
||||||
|
|
||||||
|
$alteredQuery = $qb->getAllAliases();
|
||||||
|
|
||||||
|
$this->assertGreaterThanOrEqual(count($aliases), count($alteredQuery));
|
||||||
|
|
||||||
|
foreach ($aliases as $alias) {
|
||||||
|
$this->assertContains($alias, $alteredQuery);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* test the alteration of query by the filter.
|
* test the alteration of query by the filter.
|
||||||
*
|
*
|
||||||
|
@ -40,6 +40,18 @@ abstract class AbstractFilterTest extends KernelTestCase
|
|||||||
$this->prophet = $this->getProphet();
|
$this->prophet = $this->getProphet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* provide data for `testAliasDidNotDisappears`.
|
||||||
|
*/
|
||||||
|
public function dataProviderAliasDidNotDisappears()
|
||||||
|
{
|
||||||
|
foreach ($this->getQueryBuilders() as $qb) {
|
||||||
|
foreach ($this->getFormData() as $data) {
|
||||||
|
yield [clone $qb, $data];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function dataProviderAlterQuery()
|
public function dataProviderAlterQuery()
|
||||||
{
|
{
|
||||||
foreach ($this->getQueryBuilders() as $qb) {
|
foreach ($this->getQueryBuilders() as $qb) {
|
||||||
@ -87,6 +99,28 @@ abstract class AbstractFilterTest extends KernelTestCase
|
|||||||
*/
|
*/
|
||||||
abstract public function getQueryBuilders();
|
abstract public function getQueryBuilders();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare aliases array before and after that filter alter query.
|
||||||
|
*
|
||||||
|
* @dataProvider dataProviderAliasDidNotDisappears
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testAliasDidNotDisappears(QueryBuilder $qb, array $data)
|
||||||
|
{
|
||||||
|
$aliases = $qb->getAllAliases();
|
||||||
|
|
||||||
|
$this->getFilter()->alterQuery($qb, $data);
|
||||||
|
|
||||||
|
$alteredQuery = $qb->getAllAliases();
|
||||||
|
|
||||||
|
$this->assertGreaterThanOrEqual(count($aliases), count($alteredQuery));
|
||||||
|
|
||||||
|
foreach ($aliases as $alias) {
|
||||||
|
$this->assertContains($alias, $alteredQuery);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* test the alteration of query by the filter.
|
* test the alteration of query by the filter.
|
||||||
*
|
*
|
||||||
|
79
src/Bundle/ChillMainBundle/Tests/Doctrine/DQL/AgeTest.php
Normal file
79
src/Bundle/ChillMainBundle/Tests/Doctrine/DQL/AgeTest.php
Normal 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\MainBundle\Tests\Doctrine\DQL;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Address;
|
||||||
|
use DateTimeImmutable;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
|
final class AgeTest extends KernelTestCase
|
||||||
|
{
|
||||||
|
private EntityManagerInterface $entityManager;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
self::bootKernel();
|
||||||
|
|
||||||
|
$this->entityManager = self::$container->get(EntityManagerInterface::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generateQueries(): iterable
|
||||||
|
{
|
||||||
|
yield [
|
||||||
|
'SELECT AGE(a.validFrom, a.validTo) FROM ' . Address::class . ' a',
|
||||||
|
[],
|
||||||
|
];
|
||||||
|
|
||||||
|
yield [
|
||||||
|
'SELECT AGE(:date0, :date1) FROM ' . Address::class . ' a',
|
||||||
|
[
|
||||||
|
'date0' => new DateTimeImmutable('now'),
|
||||||
|
'date1' => new DateTimeImmutable('2020-01-01'),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
yield [
|
||||||
|
'SELECT AGE(a.validFrom, :date1) FROM ' . Address::class . ' a',
|
||||||
|
[
|
||||||
|
'date1' => new DateTimeImmutable('now'),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
yield [
|
||||||
|
'SELECT AGE(:date0, a.validFrom) FROM ' . Address::class . ' a',
|
||||||
|
[
|
||||||
|
'date0' => new DateTimeImmutable('now'),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider generateQueries
|
||||||
|
*/
|
||||||
|
public function testWorking(string $dql, array $args)
|
||||||
|
{
|
||||||
|
$dql = $this->entityManager->createQuery($dql)->setMaxResults(3);
|
||||||
|
|
||||||
|
foreach ($args as $key => $value) {
|
||||||
|
$dql->setParameter($key, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
$results = $dql->getResult();
|
||||||
|
|
||||||
|
$this->assertIsArray($results);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
<?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 Doctrine\DQL;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
|
final class JsonbExistsInArrayTest extends KernelTestCase
|
||||||
|
{
|
||||||
|
private EntityManagerInterface $em;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
self::bootKernel();
|
||||||
|
$this->em = self::$container->get(EntityManagerInterface::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDQLFunctionWorks()
|
||||||
|
{
|
||||||
|
$result = $this->em
|
||||||
|
->createQuery('SELECT JSONB_EXISTS_IN_ARRAY(u.attributes, :param) FROM ' . User::class . ' u')
|
||||||
|
->setParameter('param', 'fr')
|
||||||
|
->getResult();
|
||||||
|
|
||||||
|
$this->assertIsArray($result);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,127 @@
|
|||||||
|
<?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 Form\Type;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Center;
|
||||||
|
use Chill\MainBundle\Entity\Scope;
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
|
use Chill\MainBundle\Form\Type\ScopePickerType;
|
||||||
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
||||||
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
use Prophecy\Argument;
|
||||||
|
use Prophecy\PhpUnit\ProphecyTrait;
|
||||||
|
use Symfony\Bridge\Doctrine\Form\DoctrineOrmExtension;
|
||||||
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
|
use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
|
use Symfony\Component\Form\PreloadedExtension;
|
||||||
|
use Symfony\Component\Form\Test\TypeTestCase;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
|
final class ScopePickerTypeTest extends TypeTestCase
|
||||||
|
{
|
||||||
|
use ProphecyTrait;
|
||||||
|
|
||||||
|
public function testBuildOneScopeIsSuccessful()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create(ScopePickerType::class, null, [
|
||||||
|
'center' => new Center(),
|
||||||
|
'role' => 'ONE_SCOPE',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$view = $form->createView();
|
||||||
|
|
||||||
|
$this->assertContains('hidden', $view['scope']->vars['block_prefixes']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBuildThreeScopesIsSuccessful()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create(ScopePickerType::class, null, [
|
||||||
|
'center' => new Center(),
|
||||||
|
'role' => 'THREE_SCOPE',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$view = $form->createView();
|
||||||
|
|
||||||
|
$this->assertContains('entity', $view['scope']->vars['block_prefixes']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBuildTwoScopesIsSuccessful()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create(ScopePickerType::class, null, [
|
||||||
|
'center' => new Center(),
|
||||||
|
'role' => 'TWO_SCOPE',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$view = $form->createView();
|
||||||
|
|
||||||
|
$this->assertContains('entity', $view['scope']->vars['block_prefixes']);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getExtensions()
|
||||||
|
{
|
||||||
|
$user = new User();
|
||||||
|
$role1Scope = 'ONE_SCOPE';
|
||||||
|
$role2Scope = 'TWO_SCOPE';
|
||||||
|
$role3Scope = 'THREE_SCOPE';
|
||||||
|
$scopeA = (new Scope())->setName(['fr' => 'scope a']);
|
||||||
|
$scopeB = (new Scope())->setName(['fr' => 'scope b']);
|
||||||
|
$scopeC = (new Scope())->setName(['fr' => 'scope b'])->setActive(false);
|
||||||
|
|
||||||
|
$authorizationHelper = $this->prophesize(AuthorizationHelperInterface::class);
|
||||||
|
$authorizationHelper->getReachableScopes($user, $role1Scope, Argument::any())
|
||||||
|
->willReturn([$scopeA]);
|
||||||
|
$authorizationHelper->getReachableScopes($user, $role2Scope, Argument::any())
|
||||||
|
->willReturn([$scopeA, $scopeB]);
|
||||||
|
$authorizationHelper->getReachableScopes($user, $role3Scope, Argument::any())
|
||||||
|
->willReturn([$scopeA, $scopeB, $scopeC]);
|
||||||
|
|
||||||
|
$security = $this->prophesize(Security::class);
|
||||||
|
$security->getUser()->willReturn($user);
|
||||||
|
|
||||||
|
$translatableStringHelper = $this->prophesize(TranslatableStringHelperInterface::class);
|
||||||
|
$translatableStringHelper->localize(Argument::type('array'))->will(
|
||||||
|
static function ($args) { return $args[0]['fr']; }
|
||||||
|
);
|
||||||
|
|
||||||
|
$type = new ScopePickerType(
|
||||||
|
$authorizationHelper->reveal(),
|
||||||
|
$security->reveal(),
|
||||||
|
$translatableStringHelper->reveal()
|
||||||
|
);
|
||||||
|
|
||||||
|
// add the mocks for creating EntityType
|
||||||
|
$entityManager = DoctrineTestHelper::createTestEntityManager();
|
||||||
|
$em = $this->prophesize(EntityManagerInterface::class);
|
||||||
|
$em->getClassMetadata(Scope::class)->willReturn($entityManager->getClassMetadata(Scope::class));
|
||||||
|
$em->contains(Argument::type(Scope::class))->willReturn(true);
|
||||||
|
$em->initializeObject(Argument::type(Scope::class))->will(static fn ($o) => $o);
|
||||||
|
$emRevealed = $em->reveal();
|
||||||
|
$managerRegistry = $this->prophesize(ManagerRegistry::class);
|
||||||
|
$managerRegistry->getManager(Argument::any())->willReturn($emRevealed);
|
||||||
|
$managerRegistry->getManagerForClass(Scope::class)->willReturn($emRevealed);
|
||||||
|
|
||||||
|
$entityType = $this->prophesize(EntityType::class);
|
||||||
|
$entityType->getParent()->willReturn(ChoiceType::class);
|
||||||
|
|
||||||
|
return [
|
||||||
|
new PreloadedExtension([$type], []),
|
||||||
|
new DoctrineOrmExtension($managerRegistry->reveal()),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -91,6 +91,14 @@ services:
|
|||||||
Chill\MainBundle\Export\ExportManager:
|
Chill\MainBundle\Export\ExportManager:
|
||||||
autoconfigure: true
|
autoconfigure: true
|
||||||
autowire: true
|
autowire: true
|
||||||
|
arguments:
|
||||||
|
$exports: !tagged_iterator { tag: chill.export, index_by: alias }
|
||||||
|
$aggregators: !tagged_iterator { tag: chill.export_aggregator, index_by: alias }
|
||||||
|
$filters: !tagged_iterator { tag: chill.export_filter, index_by: alias }
|
||||||
|
# for an unknown reason, iterator_to_array($formatter) cause a segmentation fault error (php-fpm code 11). removed temporarily
|
||||||
|
# $formatters: !tagged_iterator { tag: chill.export_formatter, index_by: alias }
|
||||||
|
# remove until we can properly test it
|
||||||
|
# $exportElementProvider: !tagged_iterator { tag: chill.export_elements_provider, index_by: prefix }
|
||||||
|
|
||||||
Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface: '@Chill\MainBundle\Security\Resolver\CenterResolverDispatcher'
|
Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface: '@Chill\MainBundle\Security\Resolver\CenterResolverDispatcher'
|
||||||
|
|
||||||
|
@ -122,8 +122,6 @@ services:
|
|||||||
|
|
||||||
Chill\MainBundle\Form\Type\PickAddressType: ~
|
Chill\MainBundle\Form\Type\PickAddressType: ~
|
||||||
|
|
||||||
Chill\MainBundle\Form\DataTransform\AddressToIdDataTransformer: ~
|
|
||||||
|
|
||||||
Chill\MainBundle\Form\DataTransform\AddressToIdDataTransformer:
|
Chill\MainBundle\Form\DataTransform\AddressToIdDataTransformer:
|
||||||
autoconfigure: true
|
autoconfigure: true
|
||||||
autowire: true
|
autowire: true
|
||||||
@ -132,10 +130,6 @@ services:
|
|||||||
autowire: true
|
autowire: true
|
||||||
autoconfigure: true
|
autoconfigure: true
|
||||||
|
|
||||||
Chill\MainBundle\Form\UserCurrentLocationType:
|
|
||||||
autowire: true
|
|
||||||
autoconfigure: true
|
|
||||||
|
|
||||||
Chill\MainBundle\Form\Type\LocationFormType: ~
|
Chill\MainBundle\Form\Type\LocationFormType: ~
|
||||||
|
|
||||||
Chill\MainBundle\Form\WorkflowStepType: ~
|
Chill\MainBundle\Form\WorkflowStepType: ~
|
||||||
|
@ -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\Migrations\Main;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
final class Version20221010142417 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('ALTER TABLE scopes DROP active');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'Allow a scope to be desactivated';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('ALTER TABLE scopes ADD active BOOLEAN DEFAULT true NOT NULL');
|
||||||
|
}
|
||||||
|
}
|
@ -189,6 +189,7 @@ Main scope: Cercle
|
|||||||
Main center: Centre
|
Main center: Centre
|
||||||
user job: Métier de l'utilisateur
|
user job: Métier de l'utilisateur
|
||||||
Job: Métier
|
Job: Métier
|
||||||
|
Jobs: Métiers
|
||||||
Choose a main center: Choisir un centre
|
Choose a main center: Choisir un centre
|
||||||
Choose a main scope: Choisir un cercle
|
Choose a main scope: Choisir un cercle
|
||||||
choose a job: Choisir un métier
|
choose a job: Choisir un métier
|
||||||
@ -227,6 +228,7 @@ never: jamais
|
|||||||
Create a new location: Créer une nouvelle localisation
|
Create a new location: Créer une nouvelle localisation
|
||||||
Location list: Liste des localisations
|
Location list: Liste des localisations
|
||||||
Location type: Type de localisation
|
Location type: Type de localisation
|
||||||
|
Pick a location type: Choisir un type de localisation
|
||||||
Phonenumber1: Numéro de téléphone
|
Phonenumber1: Numéro de téléphone
|
||||||
Phonenumber2: Autre numéro de téléphone
|
Phonenumber2: Autre numéro de téléphone
|
||||||
Location configuration: Configuration des localisations
|
Location configuration: Configuration des localisations
|
||||||
|
@ -13,6 +13,7 @@ namespace Chill\PersonBundle\Controller;
|
|||||||
|
|
||||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||||
use Chill\MainBundle\Serializer\Model\Collection;
|
use Chill\MainBundle\Serializer\Model\Collection;
|
||||||
|
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
|
||||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
@ -39,9 +40,11 @@ class SocialWorkEvaluationApiController extends AbstractController
|
|||||||
*/
|
*/
|
||||||
public function listEvaluationBySocialAction(SocialAction $action): Response
|
public function listEvaluationBySocialAction(SocialAction $action): Response
|
||||||
{
|
{
|
||||||
$pagination = $this->paginatorFactory->create($action->getEvaluations()->count());
|
$evaluations = $action->getEvaluations()->filter(static fn (Evaluation $eval) => $eval->isActive());
|
||||||
|
|
||||||
$evaluations = $action->getEvaluations()->slice(
|
$pagination = $this->paginatorFactory->create($evaluations->count());
|
||||||
|
|
||||||
|
$evaluations = $evaluations->slice(
|
||||||
$pagination->getCurrentPageFirstItemNumber(),
|
$pagination->getCurrentPageFirstItemNumber(),
|
||||||
$pagination->getItemsPerPage()
|
$pagination->getItemsPerPage()
|
||||||
);
|
);
|
||||||
|
@ -22,6 +22,7 @@ use Chill\MainBundle\Entity\Scope;
|
|||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\MainBundle\Entity\UserJob;
|
use Chill\MainBundle\Entity\UserJob;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodLocationHistory;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodLocationHistory;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodStepHistory;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
|
||||||
@ -341,6 +342,12 @@ class AccompanyingPeriod implements
|
|||||||
*/
|
*/
|
||||||
private string $step = self::STEP_DRAFT;
|
private string $step = self::STEP_DRAFT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\OneToMany(targetEntity=AccompanyingPeriodStepHistory::class,
|
||||||
|
* mappedBy="period", cascade={"persist", "remove"}, orphanRemoval=true)
|
||||||
|
*/
|
||||||
|
private Collection $stepHistories;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="datetime", nullable=true, options={"default": NULL})
|
* @ORM\Column(type="datetime", nullable=true, options={"default": NULL})
|
||||||
*/
|
*/
|
||||||
@ -395,8 +402,7 @@ class AccompanyingPeriod implements
|
|||||||
*/
|
*/
|
||||||
public function __construct(?DateTime $dateOpening = null)
|
public function __construct(?DateTime $dateOpening = null)
|
||||||
{
|
{
|
||||||
$this->setOpeningDate($dateOpening ?? new DateTime('now'));
|
$this->calendars = new ArrayCollection(); // TODO we cannot add a dependency between AccompanyingPeriod and calendars
|
||||||
$this->calendars = new ArrayCollection();
|
|
||||||
$this->participations = new ArrayCollection();
|
$this->participations = new ArrayCollection();
|
||||||
$this->scopes = new ArrayCollection();
|
$this->scopes = new ArrayCollection();
|
||||||
$this->socialIssues = new ArrayCollection();
|
$this->socialIssues = new ArrayCollection();
|
||||||
@ -405,6 +411,8 @@ class AccompanyingPeriod implements
|
|||||||
$this->resources = new ArrayCollection();
|
$this->resources = new ArrayCollection();
|
||||||
$this->userHistories = new ArrayCollection();
|
$this->userHistories = new ArrayCollection();
|
||||||
$this->locationHistories = new ArrayCollection();
|
$this->locationHistories = new ArrayCollection();
|
||||||
|
$this->stepHistories = new ArrayCollection();
|
||||||
|
$this->setOpeningDate($dateOpening ?? new DateTime('now'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -995,6 +1003,11 @@ class AccompanyingPeriod implements
|
|||||||
return $this->step;
|
return $this->step;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getStepHistories(): Collection
|
||||||
|
{
|
||||||
|
return $this->stepHistories;
|
||||||
|
}
|
||||||
|
|
||||||
public function getUser(): ?User
|
public function getUser(): ?User
|
||||||
{
|
{
|
||||||
return $this->user;
|
return $this->user;
|
||||||
@ -1263,8 +1276,12 @@ class AccompanyingPeriod implements
|
|||||||
*/
|
*/
|
||||||
public function setOpeningDate($openingDate)
|
public function setOpeningDate($openingDate)
|
||||||
{
|
{
|
||||||
|
if ($this->openingDate !== $openingDate) {
|
||||||
$this->openingDate = $openingDate;
|
$this->openingDate = $openingDate;
|
||||||
|
|
||||||
|
$this->ensureStepContinuity();
|
||||||
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1362,6 +1379,14 @@ class AccompanyingPeriod implements
|
|||||||
$this->bootPeriod();
|
$this->bootPeriod();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self::STEP_DRAFT !== $this->step && $previous !== $step) {
|
||||||
|
// we create a new history
|
||||||
|
$history = new AccompanyingPeriodStepHistory();
|
||||||
|
$history->setStep($this->step)->setStartDate(new DateTimeImmutable('now'));
|
||||||
|
|
||||||
|
$this->addStepHistory($history);
|
||||||
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1402,6 +1427,17 @@ class AccompanyingPeriod implements
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function addStepHistory(AccompanyingPeriodStepHistory $stepHistory): self
|
||||||
|
{
|
||||||
|
if (!$this->stepHistories->contains($stepHistory)) {
|
||||||
|
$this->stepHistories[] = $stepHistory;
|
||||||
|
$stepHistory->setPeriod($this);
|
||||||
|
$this->ensureStepContinuity();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
private function bootPeriod(): void
|
private function bootPeriod(): void
|
||||||
{
|
{
|
||||||
// first location history
|
// first location history
|
||||||
@ -1413,6 +1449,43 @@ class AccompanyingPeriod implements
|
|||||||
$this->addLocationHistory($locationHistory);
|
$this->addLocationHistory($locationHistory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function ensureStepContinuity(): void
|
||||||
|
{
|
||||||
|
// ensure continuity of histories
|
||||||
|
$criteria = new Criteria();
|
||||||
|
$criteria->orderBy(['startDate' => Criteria::ASC, 'id' => Criteria::ASC]);
|
||||||
|
|
||||||
|
/** @var Iterator $steps */
|
||||||
|
$steps = $this->getStepHistories()->matching($criteria)->getIterator();
|
||||||
|
$steps->rewind();
|
||||||
|
|
||||||
|
// we set the start date of the first step as the opening date, only if it is
|
||||||
|
// not greater than the end date
|
||||||
|
/** @var AccompanyingPeriodStepHistory $current */
|
||||||
|
$current = $steps->current();
|
||||||
|
|
||||||
|
if (null === $current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->getOpeningDate()->format('Y-m-d') !== $current->getStartDate()->format('Y-m-d')
|
||||||
|
&& ($this->getOpeningDate() <= $current->getEndDate() || null === $current->getEndDate())) {
|
||||||
|
$current->setStartDate(DateTimeImmutable::createFromMutable($this->getOpeningDate()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// then we set all the end date to the start date of the next one
|
||||||
|
do {
|
||||||
|
/** @var AccompanyingPeriodStepHistory $current */
|
||||||
|
$current = $steps->current();
|
||||||
|
$steps->next();
|
||||||
|
|
||||||
|
if ($steps->valid()) {
|
||||||
|
$next = $steps->current();
|
||||||
|
$current->setEndDate($next->getStartDate());
|
||||||
|
}
|
||||||
|
} while ($steps->valid());
|
||||||
|
}
|
||||||
|
|
||||||
private function setRequestorPerson(?Person $requestorPerson = null): self
|
private function setRequestorPerson(?Person $requestorPerson = null): self
|
||||||
{
|
{
|
||||||
$this->requestorPerson = $requestorPerson;
|
$this->requestorPerson = $requestorPerson;
|
||||||
|
@ -0,0 +1,115 @@
|
|||||||
|
<?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\Entity\AccompanyingPeriod;
|
||||||
|
|
||||||
|
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\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use DateTimeImmutable;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Entity
|
||||||
|
* @ORM\Table("chill_person_accompanying_period_step_history")
|
||||||
|
*/
|
||||||
|
class AccompanyingPeriodStepHistory implements TrackCreationInterface, TrackUpdateInterface
|
||||||
|
{
|
||||||
|
use TrackCreationTrait;
|
||||||
|
|
||||||
|
use TrackUpdateTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
|
||||||
|
*/
|
||||||
|
private ?DateTimeImmutable $endDate = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Id
|
||||||
|
* @ORM\GeneratedValue
|
||||||
|
* @ORM\Column(type="integer")
|
||||||
|
*/
|
||||||
|
private ?int $id = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToOne(targetEntity=AccompanyingPeriod::class)
|
||||||
|
*/
|
||||||
|
private AccompanyingPeriod $period;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="date_immutable")
|
||||||
|
*/
|
||||||
|
private ?DateTimeImmutable $startDate = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="text", nullable=false)
|
||||||
|
*/
|
||||||
|
private string $step;
|
||||||
|
|
||||||
|
public function getEndDate(): ?DateTimeImmutable
|
||||||
|
{
|
||||||
|
return $this->endDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPeriod(): AccompanyingPeriod
|
||||||
|
{
|
||||||
|
return $this->period;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getStartDate(): ?DateTimeImmutable
|
||||||
|
{
|
||||||
|
return $this->startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getStep(): string
|
||||||
|
{
|
||||||
|
return $this->step;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setEndDate(?DateTimeImmutable $endDate): self
|
||||||
|
{
|
||||||
|
$this->endDate = $endDate;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal use AccompanyingPeriod::addLocationHistory
|
||||||
|
*/
|
||||||
|
public function setPeriod(AccompanyingPeriod $period): self
|
||||||
|
{
|
||||||
|
$this->period = $period;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setStartDate(?DateTimeImmutable $startDate): self
|
||||||
|
{
|
||||||
|
$this->startDate = $startDate;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setStep(string $step): AccompanyingPeriodStepHistory
|
||||||
|
{
|
||||||
|
$this->step = $step;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
@ -36,7 +36,7 @@ class Comment implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
* inversedBy="comments")
|
* inversedBy="comments")
|
||||||
* @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
|
* @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
|
||||||
*/
|
*/
|
||||||
private ?AccompanyingPeriod $accompanyingPeriod;
|
private ?AccompanyingPeriod $accompanyingPeriod = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="text")
|
* @ORM\Column(type="text")
|
||||||
|
@ -1488,7 +1488,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
|||||||
$participation = $this->participationsContainAccompanyingPeriod($accompanyingPeriod);
|
$participation = $this->participationsContainAccompanyingPeriod($accompanyingPeriod);
|
||||||
|
|
||||||
if (!null === $participation) {
|
if (!null === $participation) {
|
||||||
$participation->setEndDate(DateTimeImmutable::class);
|
$participation->setEndDate(new DateTime());
|
||||||
$this->accompanyingPeriodParticipations->removeElement($participation);
|
$this->accompanyingPeriodParticipations->removeElement($participation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1569,8 +1569,6 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
|||||||
*/
|
*/
|
||||||
public function setCenter(Center $center): self
|
public function setCenter(Center $center): self
|
||||||
{
|
{
|
||||||
$this->center = $center;
|
|
||||||
|
|
||||||
$modification = new DateTimeImmutable('now');
|
$modification = new DateTimeImmutable('now');
|
||||||
|
|
||||||
foreach ($this->centerHistory as $centerHistory) {
|
foreach ($this->centerHistory as $centerHistory) {
|
||||||
|
@ -26,6 +26,11 @@ use Symfony\Component\Serializer\Annotation as Serializer;
|
|||||||
*/
|
*/
|
||||||
class Evaluation
|
class Evaluation
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="boolean", nullable=false, options={"default": true})
|
||||||
|
*/
|
||||||
|
private bool $active = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="dateinterval", nullable=true, options={"default": null})
|
* @ORM\Column(type="dateinterval", nullable=true, options={"default": null})
|
||||||
* @Serializer\Groups({"read"})
|
* @Serializer\Groups({"read"})
|
||||||
@ -114,6 +119,11 @@ class Evaluation
|
|||||||
return $this->url;
|
return $this->url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isActive(): bool
|
||||||
|
{
|
||||||
|
return $this->active;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return $this
|
* @return $this
|
||||||
*
|
*
|
||||||
@ -128,6 +138,13 @@ class Evaluation
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setActive(bool $active): Evaluation
|
||||||
|
{
|
||||||
|
$this->active = $active;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function setDelay(?DateInterval $delay): self
|
public function setDelay(?DateInterval $delay): self
|
||||||
{
|
{
|
||||||
$this->delay = $delay;
|
$this->delay = $delay;
|
||||||
|
@ -228,6 +228,22 @@ class SocialAction
|
|||||||
return $descendants;
|
return $descendants;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection|SocialAction[] $socialActions
|
||||||
|
*/
|
||||||
|
public static function getDescendantsWithThisForActions($socialActions): Collection
|
||||||
|
{
|
||||||
|
$unique = [];
|
||||||
|
|
||||||
|
foreach ($socialActions as $action) {
|
||||||
|
foreach ($action->getDescendantsWithThis() as $child) {
|
||||||
|
$unique[spl_object_hash($child)] = $child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ArrayCollection(array_values($unique));
|
||||||
|
}
|
||||||
|
|
||||||
public function getEvaluations(): Collection
|
public function getEvaluations(): Collection
|
||||||
{
|
{
|
||||||
return $this->evaluations;
|
return $this->evaluations;
|
||||||
@ -274,6 +290,11 @@ class SocialAction
|
|||||||
return $this->title;
|
return $this->title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function hasChildren(): bool
|
||||||
|
{
|
||||||
|
return 0 < $this->getChildren()->count();
|
||||||
|
}
|
||||||
|
|
||||||
public function hasParent(): bool
|
public function hasParent(): bool
|
||||||
{
|
{
|
||||||
return $this->getParent() instanceof self;
|
return $this->getParent() instanceof self;
|
||||||
@ -369,6 +390,8 @@ class SocialAction
|
|||||||
{
|
{
|
||||||
$this->parent = $parent;
|
$this->parent = $parent;
|
||||||
|
|
||||||
|
$parent->addChild($this);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,11 +71,17 @@ class SocialIssue
|
|||||||
$this->socialActions = new ArrayCollection();
|
$this->socialActions = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal use @see{SocialIssue::setParent} instead
|
||||||
|
*
|
||||||
|
* @param SocialIssue $child
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
public function addChild(self $child): self
|
public function addChild(self $child): self
|
||||||
{
|
{
|
||||||
if (!$this->children->contains($child)) {
|
if (!$this->children->contains($child)) {
|
||||||
$this->children[] = $child;
|
$this->children[] = $child;
|
||||||
$child->setParent($this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
@ -215,6 +221,22 @@ class SocialIssue
|
|||||||
return $descendants;
|
return $descendants;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array|SocialIssue[] $socialIssues
|
||||||
|
*/
|
||||||
|
public static function getDescendantsWithThisForIssues(array $socialIssues): Collection
|
||||||
|
{
|
||||||
|
$unique = [];
|
||||||
|
|
||||||
|
foreach ($socialIssues as $issue) {
|
||||||
|
foreach ($issue->getDescendantsWithThis() as $child) {
|
||||||
|
$unique[spl_object_hash($child)] = $child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ArrayCollection(array_values($unique));
|
||||||
|
}
|
||||||
|
|
||||||
public function getId(): ?int
|
public function getId(): ?int
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
@ -262,6 +284,11 @@ class SocialIssue
|
|||||||
return $this->title;
|
return $this->title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function hasChildren(): bool
|
||||||
|
{
|
||||||
|
return 0 < $this->getChildren()->count();
|
||||||
|
}
|
||||||
|
|
||||||
public function hasParent(): bool
|
public function hasParent(): bool
|
||||||
{
|
{
|
||||||
return null !== $this->parent;
|
return null !== $this->parent;
|
||||||
@ -329,6 +356,8 @@ class SocialIssue
|
|||||||
{
|
{
|
||||||
$this->parent = $parent;
|
$this->parent = $parent;
|
||||||
|
|
||||||
|
$parent->addChild($this);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,131 @@
|
|||||||
|
<?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\Aggregator\AccompanyingCourseAggregators;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Export\AggregatorInterface;
|
||||||
|
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||||
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
|
use Chill\PersonBundle\Entity\Household\HouseholdComposition;
|
||||||
|
use Chill\PersonBundle\Entity\Household\HouseholdMember;
|
||||||
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
|
use Chill\PersonBundle\Repository\Household\HouseholdCompositionTypeRepositoryInterface;
|
||||||
|
use Doctrine\ORM\Query\Expr\Join;
|
||||||
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use function in_array;
|
||||||
|
|
||||||
|
class ByHouseholdCompositionAggregator implements AggregatorInterface
|
||||||
|
{
|
||||||
|
private const PREFIX = 'acp_by_household_compo_agg';
|
||||||
|
|
||||||
|
private HouseholdCompositionTypeRepositoryInterface $householdCompositionTypeRepository;
|
||||||
|
|
||||||
|
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||||
|
|
||||||
|
public function __construct(HouseholdCompositionTypeRepositoryInterface $householdCompositionTypeRepository, TranslatableStringHelperInterface $translatableStringHelper)
|
||||||
|
{
|
||||||
|
$this->householdCompositionTypeRepository = $householdCompositionTypeRepository;
|
||||||
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addRole(): ?string
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
|
{
|
||||||
|
$p = self::PREFIX;
|
||||||
|
|
||||||
|
if (!in_array('acppart', $qb->getAllAliases(), true)) {
|
||||||
|
$qb->leftJoin('acp.participations', 'acppart');
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb
|
||||||
|
->leftJoin(
|
||||||
|
HouseholdMember::class,
|
||||||
|
"{$p}_hm",
|
||||||
|
Join::WITH,
|
||||||
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->isNull("{$p}_hm"),
|
||||||
|
$qb->expr()->andX(
|
||||||
|
$qb->expr()->lte("{$p}_hm.startDate", ":{$p}_date"),
|
||||||
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->isNull("{$p}_hm.endDate"),
|
||||||
|
$qb->expr()->gt("{$p}_hm.endDate", ":{$p}_date")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
->leftJoin(
|
||||||
|
HouseholdComposition::class,
|
||||||
|
"{$p}_compo",
|
||||||
|
Join::WITH,
|
||||||
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->isNull("{$p}_compo"),
|
||||||
|
$qb->expr()->andX(
|
||||||
|
$qb->expr()->lte("{$p}_compo.startDate", ":{$p}_date"),
|
||||||
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->isNull("{$p}_compo.endDate"),
|
||||||
|
$qb->expr()->gt("{$p}_compo.endDate", ":{$p}_date")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
->addSelect("IDENTITY({$p}_compo.householdCompositionType) AS {$p}_select")
|
||||||
|
->setParameter("{$p}_date", $data['date_calc'])
|
||||||
|
->addGroupBy("{$p}_select");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function applyOn()
|
||||||
|
{
|
||||||
|
return Declarations::ACP_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
|
{
|
||||||
|
$builder->add('date_calc', ChillDateType::class, [
|
||||||
|
'label' => 'export.aggregator.course.by_household_composition.Calc date',
|
||||||
|
'input_format' => 'datetime_immutable',
|
||||||
|
'data' => new \DateTimeImmutable('now'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLabels($key, array $values, $data)
|
||||||
|
{
|
||||||
|
return function ($value) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return 'export.aggregator.course.by_household_composition.Household composition';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $o = $this->householdCompositionTypeRepository->find($value)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->translatableStringHelper->localize($o->getLabel());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQueryKeys($data)
|
||||||
|
{
|
||||||
|
return [self::PREFIX . '_select'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle()
|
||||||
|
{
|
||||||
|
return 'export.aggregator.course.by_household_composition.Group course by household composition';
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
|
|||||||
use Chill\MainBundle\Export\AggregatorInterface;
|
use Chill\MainBundle\Export\AggregatorInterface;
|
||||||
use Chill\PersonBundle\Export\Declarations;
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use LogicException;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
@ -65,8 +66,6 @@ class ConfidentialAggregator implements AggregatorInterface
|
|||||||
default:
|
default:
|
||||||
throw new LogicException(sprintf('The value %s is not valid', $value));
|
throw new LogicException(sprintf('The value %s is not valid', $value));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $value;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,12 +13,21 @@ namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
|
|||||||
|
|
||||||
use Chill\MainBundle\Export\AggregatorInterface;
|
use Chill\MainBundle\Export\AggregatorInterface;
|
||||||
use Chill\PersonBundle\Export\Declarations;
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
|
use DateTimeImmutable;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use LogicException;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
final class DurationAggregator implements AggregatorInterface
|
final class DurationAggregator implements AggregatorInterface
|
||||||
{
|
{
|
||||||
|
private const CHOICES = [
|
||||||
|
'month',
|
||||||
|
'week',
|
||||||
|
'day',
|
||||||
|
];
|
||||||
|
|
||||||
private TranslatorInterface $translator;
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
public function __construct(TranslatorInterface $translator)
|
public function __construct(TranslatorInterface $translator)
|
||||||
@ -33,19 +42,31 @@ final class DurationAggregator implements AggregatorInterface
|
|||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data)
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
{
|
{
|
||||||
$qb->addSelect(
|
switch ($data['precision']) {
|
||||||
'
|
case 'day':
|
||||||
(acp.closingDate - acp.openingDate +15) *12/365
|
$qb->addSelect('(COALESCE(acp.closingDate, :now) - acp.openingDate) AS duration_aggregator');
|
||||||
AS duration_aggregator'
|
|
||||||
);
|
|
||||||
|
|
||||||
// TODO Pour avoir un interval plus précis (nécessaire ?):
|
break;
|
||||||
// adapter la fonction extract pour pouvoir l'utiliser avec des intervals: extract(month from interval)
|
|
||||||
// et ajouter une fonction custom qui calcule plus précisément les intervals, comme doctrineum/date-interval
|
|
||||||
// https://packagist.org/packages/doctrineum/date-interval#3.1.0 (mais composer fait un conflit de dépendance)
|
|
||||||
|
|
||||||
$qb->addGroupBy('duration_aggregator');
|
case 'week':
|
||||||
$qb->addOrderBy('duration_aggregator');
|
$qb->addSelect('(COALESCE(acp.closingDate, :now) - acp.openingDate) / 7 AS duration_aggregator');
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'month':
|
||||||
|
$qb->addSelect('(EXTRACT (MONTH FROM AGE(COALESCE(acp.closingDate, :now), acp.openingDate)) * 12 +
|
||||||
|
EXTRACT (MONTH FROM AGE(COALESCE(acp.closingDate, :now), acp.openingDate))) AS duration_aggregator');
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new LogicException('precision not supported: ' . $data['precision']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb
|
||||||
|
->setParameter('now', new DateTimeImmutable('now'))
|
||||||
|
->addGroupBy('duration_aggregator')
|
||||||
|
->addOrderBy('duration_aggregator');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
@ -55,25 +76,27 @@ final class DurationAggregator implements AggregatorInterface
|
|||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
{
|
{
|
||||||
// no form
|
$builder->add('precision', ChoiceType::class, [
|
||||||
|
'choices' => array_combine(self::CHOICES, self::CHOICES),
|
||||||
|
'label' => 'export.aggregator.course.duration.Precision',
|
||||||
|
'choice_label' => static fn (string $c) => 'export.aggregator.course.duration.' . $c,
|
||||||
|
'multiple' => false,
|
||||||
|
'expanded' => true,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLabels($key, array $values, $data)
|
public function getLabels($key, array $values, $data)
|
||||||
{
|
{
|
||||||
return function ($value): ?string {
|
return static function ($value) use ($data) {
|
||||||
if ('_header' === $value) {
|
if ('_header' === $value) {
|
||||||
return 'Rounded month duration';
|
return 'export.aggregator.course.duration.' . $data['precision'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null === $value) {
|
if (null === $value) {
|
||||||
return $this->translator->trans('current duration'); // when closingDate is null
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 === $value) {
|
return $value;
|
||||||
return $this->translator->trans('duration 0 month');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $value . $this->translator->trans(' months');
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
|
|||||||
use Chill\MainBundle\Export\AggregatorInterface;
|
use Chill\MainBundle\Export\AggregatorInterface;
|
||||||
use Chill\PersonBundle\Export\Declarations;
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use LogicException;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
@ -65,8 +66,6 @@ class EmergencyAggregator implements AggregatorInterface
|
|||||||
default:
|
default:
|
||||||
throw new LogicException(sprintf('The value %s is not valid', $value));
|
throw new LogicException(sprintf('The value %s is not valid', $value));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $value;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
|
|||||||
use Chill\MainBundle\Export\AggregatorInterface;
|
use Chill\MainBundle\Export\AggregatorInterface;
|
||||||
use Chill\PersonBundle\Export\Declarations;
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use LogicException;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
|
@ -12,15 +12,20 @@ declare(strict_types=1);
|
|||||||
namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
|
namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
|
||||||
|
|
||||||
use Chill\MainBundle\Export\AggregatorInterface;
|
use Chill\MainBundle\Export\AggregatorInterface;
|
||||||
|
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||||
use Chill\MainBundle\Repository\UserRepository;
|
use Chill\MainBundle\Repository\UserRepository;
|
||||||
use Chill\MainBundle\Templating\Entity\UserRender;
|
use Chill\MainBundle\Templating\Entity\UserRender;
|
||||||
use Chill\PersonBundle\Export\Declarations;
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
|
use DateTimeImmutable;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use function in_array;
|
|
||||||
|
|
||||||
final class ReferrerAggregator implements AggregatorInterface
|
final class ReferrerAggregator implements AggregatorInterface
|
||||||
{
|
{
|
||||||
|
private const A = 'acp_ref_agg_uhistory';
|
||||||
|
|
||||||
|
private const P = 'acp_ref_agg_date';
|
||||||
|
|
||||||
private UserRender $userRender;
|
private UserRender $userRender;
|
||||||
|
|
||||||
private UserRepository $userRepository;
|
private UserRepository $userRepository;
|
||||||
@ -40,12 +45,23 @@ final class ReferrerAggregator implements AggregatorInterface
|
|||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data)
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
{
|
{
|
||||||
if (!in_array('acpuser', $qb->getAllAliases(), true)) {
|
$qb
|
||||||
$qb->leftJoin('acp.user', 'acpuser');
|
->addSelect('IDENTITY(' . self::A . '.user) AS referrer_aggregator')
|
||||||
}
|
->addGroupBy('referrer_aggregator')
|
||||||
|
->leftJoin('acp.userHistories', self::A)
|
||||||
$qb->addSelect('acpuser.id AS referrer_aggregator');
|
->andWhere(
|
||||||
$qb->addGroupBy('referrer_aggregator');
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->isNull(self::A),
|
||||||
|
$qb->expr()->andX(
|
||||||
|
$qb->expr()->lte(self::A . '.startDate', ':' . self::P),
|
||||||
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->isNull(self::A . '.endDate'),
|
||||||
|
$qb->expr()->gt(self::A . '.endDate', ':' . self::P)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
->setParameter(self::P, $data['date_calc']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
@ -55,7 +71,13 @@ final class ReferrerAggregator implements AggregatorInterface
|
|||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
{
|
{
|
||||||
// no form
|
$builder
|
||||||
|
->add('date_calc', ChillDateType::class, [
|
||||||
|
'input' => 'datetime_immutable',
|
||||||
|
'data' => new DateTimeImmutable('now'),
|
||||||
|
'label' => 'export.aggregator.course.by_referrer.Computation date for referrer',
|
||||||
|
'required' => true,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLabels($key, array $values, $data)
|
public function getLabels($key, array $values, $data)
|
||||||
|
@ -12,19 +12,21 @@ declare(strict_types=1);
|
|||||||
namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
|
namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
|
||||||
|
|
||||||
use Chill\MainBundle\Export\AggregatorInterface;
|
use Chill\MainBundle\Export\AggregatorInterface;
|
||||||
//use Chill\MainBundle\Export\FilterInterface;
|
|
||||||
use Chill\MainBundle\Form\Type\ChillDateType;
|
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
use Chill\PersonBundle\Export\Declarations;
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use Doctrine\DBAL\Types\Types;
|
|
||||||
use Doctrine\ORM\Query\Expr\Andx;
|
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
use function in_array;
|
||||||
|
|
||||||
final class StepAggregator implements AggregatorInterface //, FilterInterface
|
final class StepAggregator implements AggregatorInterface
|
||||||
{
|
{
|
||||||
|
private const A = 'acpstephistories';
|
||||||
|
|
||||||
|
private const P = 'acp_step_agg_date';
|
||||||
|
|
||||||
private TranslatorInterface $translator;
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
@ -40,30 +42,26 @@ final class StepAggregator implements AggregatorInterface //, FilterInterface
|
|||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data)
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
{
|
{
|
||||||
$qb->addSelect('acp.step AS step_aggregator');
|
if (!in_array(self::A, $qb->getAllAliases(), true)) {
|
||||||
$qb->addGroupBy('step_aggregator');
|
$qb->leftJoin('acp.stepHistories', self::A);
|
||||||
|
|
||||||
/*
|
|
||||||
// add date in where clause
|
|
||||||
$where = $qb->getDQLPart('where');
|
|
||||||
|
|
||||||
$clause = $qb->expr()->andX(
|
|
||||||
$qb->expr()->lte('acp.openingDate', ':ondate'),
|
|
||||||
$qb->expr()->orX(
|
|
||||||
$qb->expr()->gt('acp.closingDate', ':ondate'),
|
|
||||||
$qb->expr()->isNull('acp.closingDate')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($where instanceof Andx) {
|
|
||||||
$where->add($clause);
|
|
||||||
} else {
|
|
||||||
$where = $qb->expr()->andX($clause);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$qb->add('where', $where);
|
$qb
|
||||||
$qb->setParameter('ondate', $data['on_date'], Types::DATE_MUTABLE);
|
->addSelect(self::A . '.step AS step_aggregator')
|
||||||
*/
|
->andWhere(
|
||||||
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->isNull(self::A . '.step'),
|
||||||
|
$qb->expr()->andX(
|
||||||
|
$qb->expr()->lte(self::A . '.startDate', ':' . self::P),
|
||||||
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->isNull(self::A . '.endDate'),
|
||||||
|
$qb->expr()->lt(self::A . '.endDate', ':' . self::P)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
->setParameter(self::P, $data['on_date'])
|
||||||
|
->addGroupBy('step_aggregator');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
@ -94,8 +92,11 @@ final class StepAggregator implements AggregatorInterface //, FilterInterface
|
|||||||
case '_header':
|
case '_header':
|
||||||
return 'Step';
|
return 'Step';
|
||||||
|
|
||||||
|
case null:
|
||||||
|
return '';
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new LogicException(sprintf('The value %s is not valid', $value));
|
return $value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
|||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
use function in_array;
|
||||||
|
|
||||||
final class CountryOfBirthAggregator implements AggregatorInterface, ExportElementValidatedInterface
|
final class CountryOfBirthAggregator implements AggregatorInterface, ExportElementValidatedInterface
|
||||||
{
|
{
|
||||||
@ -83,16 +84,12 @@ final class CountryOfBirthAggregator implements AggregatorInterface, ExportEleme
|
|||||||
. ' is not known.');
|
. ' is not known.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!in_array('countryOfBirth', $qb->getAllAliases(), true)) {
|
||||||
$qb->leftJoin('person.countryOfBirth', 'countryOfBirth');
|
$qb->leftJoin('person.countryOfBirth', 'countryOfBirth');
|
||||||
|
}
|
||||||
|
|
||||||
// add group by
|
// add group by
|
||||||
$groupBy = $qb->getDQLPart('groupBy');
|
|
||||||
|
|
||||||
if (!empty($groupBy)) {
|
|
||||||
$qb->addGroupBy('country_of_birth_aggregator');
|
$qb->addGroupBy('country_of_birth_aggregator');
|
||||||
} else {
|
|
||||||
$qb->groupBy('country_of_birth_aggregator');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn()
|
public function applyOn()
|
||||||
|
@ -70,14 +70,7 @@ final class HouseholdPositionAggregator implements AggregatorInterface, ExportEl
|
|||||||
$qb->setParameter('date', $data['date_position']);
|
$qb->setParameter('date', $data['date_position']);
|
||||||
|
|
||||||
$qb->addSelect('IDENTITY(householdmember.position) AS household_position_aggregator');
|
$qb->addSelect('IDENTITY(householdmember.position) AS household_position_aggregator');
|
||||||
|
|
||||||
$groupBy = $qb->getDQLPart('groupBy');
|
|
||||||
|
|
||||||
if (!empty($groupBy)) {
|
|
||||||
$qb->addGroupBy('household_position_aggregator');
|
$qb->addGroupBy('household_position_aggregator');
|
||||||
} else {
|
|
||||||
$qb->groupBy('household_position_aggregator');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn()
|
public function applyOn()
|
||||||
|
@ -43,14 +43,7 @@ final class MaritalStatusAggregator implements AggregatorInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
$qb->addSelect('personmarital.id as marital_status_aggregator');
|
$qb->addSelect('personmarital.id as marital_status_aggregator');
|
||||||
|
|
||||||
$groupBy = $qb->getDQLPart('groupBy');
|
|
||||||
|
|
||||||
if (!empty($groupBy)) {
|
|
||||||
$qb->addGroupBy('marital_status_aggregator');
|
$qb->addGroupBy('marital_status_aggregator');
|
||||||
} else {
|
|
||||||
$qb->groupBy('marital_status_aggregator');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn()
|
public function applyOn()
|
||||||
|
@ -83,15 +83,7 @@ final class NationalityAggregator implements AggregatorInterface, ExportElementV
|
|||||||
}
|
}
|
||||||
|
|
||||||
$qb->leftJoin('person.nationality', 'nationality');
|
$qb->leftJoin('person.nationality', 'nationality');
|
||||||
|
|
||||||
// add group by
|
|
||||||
$groupBy = $qb->getDQLPart('groupBy');
|
|
||||||
|
|
||||||
if (!empty($groupBy)) {
|
|
||||||
$qb->addGroupBy('nationality_aggregator');
|
$qb->addGroupBy('nationality_aggregator');
|
||||||
} else {
|
|
||||||
$qb->groupBy('nationality_aggregator');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn()
|
public function applyOn()
|
||||||
|
@ -75,9 +75,9 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface
|
|||||||
return ['export_result'];
|
return ['export_result'];
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
public function getTitle(): string
|
||||||
@ -99,6 +99,7 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface
|
|||||||
$qb = $this->repository->createQueryBuilder('acp');
|
$qb = $this->repository->createQueryBuilder('acp');
|
||||||
|
|
||||||
$qb
|
$qb
|
||||||
|
->andWhere('acp.step != :count_acp_step')
|
||||||
->andWhere(
|
->andWhere(
|
||||||
$qb->expr()->exists(
|
$qb->expr()->exists(
|
||||||
'SELECT 1 FROM ' . AccompanyingPeriodParticipation::class . ' acl_count_part
|
'SELECT 1 FROM ' . AccompanyingPeriodParticipation::class . ' acl_count_part
|
||||||
@ -107,6 +108,7 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface
|
|||||||
'
|
'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
->setParameter('count_acp_step', AccompanyingPeriod::STEP_DRAFT)
|
||||||
->setParameter('authorized_centers', $centers);
|
->setParameter('authorized_centers', $centers);
|
||||||
|
|
||||||
$qb->select('COUNT(DISTINCT acp.id) AS export_result');
|
$qb->select('COUNT(DISTINCT acp.id) AS export_result');
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user