mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-13 13:54:23 +00:00
merge conflict fixed
This commit is contained in:
commit
3059935305
@ -5,69 +5,70 @@ Add condition with distinct alias on each export join clauses (Indicators + Filt
|
|||||||
|
|
||||||
These are alias conventions :
|
These are alias conventions :
|
||||||
|
|
||||||
| Entity | Join | Attribute | Alias |
|
| Entity | Join | Attribute | Alias |
|
||||||
|:----------------------------------------|:----------------------------------------|:-------------------------------------------|:----------------------------------|
|
|:----------------------------------------|:----------------------------------------|:-------------------------------------------|:---------------------------------------|
|
||||||
| AccompanyingPeriod::class | | | acp |
|
| AccompanyingPeriod::class | | | acp |
|
||||||
| | AccompanyingPeriodWork::class | acp.works | acpw |
|
| | AccompanyingPeriodWork::class | acp.works | acpw |
|
||||||
| | AccompanyingPeriodParticipation::class | acp.participations | acppart |
|
| | AccompanyingPeriodParticipation::class | acp.participations | acppart |
|
||||||
| | Location::class | acp.administrativeLocation | acploc |
|
| | Location::class | acp.administrativeLocation | acploc |
|
||||||
| | ClosingMotive::class | acp.closingMotive | acpmotive |
|
| | ClosingMotive::class | acp.closingMotive | acpmotive |
|
||||||
| | UserJob::class | acp.job | acpjob |
|
| | UserJob::class | acp.job | acpjob |
|
||||||
| | Origin::class | acp.origin | acporigin |
|
| | Origin::class | acp.origin | acporigin |
|
||||||
| | Scope::class | acp.scopes | acpscope |
|
| | Scope::class | acp.scopes | acpscope |
|
||||||
| | SocialIssue::class | acp.socialIssues | acpsocialissue |
|
| | SocialIssue::class | acp.socialIssues | acpsocialissue |
|
||||||
| | User::class | acp.user | acpuser |
|
| | User::class | acp.user | acpuser |
|
||||||
| | AccompanyingPeriopStepHistory::class | acp.stepHistories | acpstephistories |
|
| | 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 |
|
||||||
| | SocialAction::class | acpw.socialAction | acpwsocialaction |
|
| | SocialAction::class | acpw.socialAction | acpwsocialaction |
|
||||||
| | Goal::class | acpw.goals | goal |
|
| | Goal::class | acpw.goals | goal |
|
||||||
| | Result::class | acpw.results | result |
|
| | Result::class | acpw.results | result |
|
||||||
| AccompanyingPeriodParticipation::class | | | acppart |
|
| AccompanyingPeriodParticipation::class | | | acppart |
|
||||||
| | Person::class | acppart.person | partperson |
|
| | Person::class | acppart.person | partperson |
|
||||||
| AccompanyingPeriodWorkEvaluation::class | | | workeval |
|
| AccompanyingPeriodWorkEvaluation::class | | | workeval |
|
||||||
| | Evaluation::class | workeval.evaluation | eval |
|
| | Evaluation::class | workeval.evaluation | eval |
|
||||||
| Goal::class | | | goal |
|
| Goal::class | | | goal |
|
||||||
| | Result::class | goal.results | goalresult |
|
| | Result::class | goal.results | goalresult |
|
||||||
| Person::class | | | person |
|
| Person::class | | | person |
|
||||||
| | Center::class | person.center | center |
|
| | Center::class | person.center | center |
|
||||||
| | HouseholdMember::class | partperson.householdParticipations | householdmember |
|
| | HouseholdMember::class | partperson.householdParticipations | householdmember |
|
||||||
| | MaritalStatus::class | person.maritalStatus | personmarital |
|
| | MaritalStatus::class | person.maritalStatus | personmarital |
|
||||||
| | VendeePerson::class | | vp |
|
| | VendeePerson::class | | vp |
|
||||||
| | VendeePersonMineur::class | | vpm |
|
| | VendeePersonMineur::class | | vpm |
|
||||||
| ResidentialAddress::class | | | resaddr |
|
| | CurrentPersonAddress::class | person.currentPersonAddress | currentPersonAddress (on a given date) |
|
||||||
| | ThirdParty::class | resaddr.hostThirdParty | tparty |
|
| ResidentialAddress::class | | | resaddr |
|
||||||
| ThirdParty::class | | | tparty |
|
| | ThirdParty::class | resaddr.hostThirdParty | tparty |
|
||||||
| | ThirdPartyCategory::class | tparty.categories | tpartycat |
|
| ThirdParty::class | | | tparty |
|
||||||
| HouseholdMember::class | | | householdmember |
|
| | ThirdPartyCategory::class | tparty.categories | tpartycat |
|
||||||
| | Household::class | householdmember.household | household |
|
| HouseholdMember::class | | | householdmember |
|
||||||
| | Person::class | householdmember.person | memberperson |
|
| | Household::class | householdmember.household | household |
|
||||||
| | | memberperson.center | membercenter |
|
| | Person::class | householdmember.person | memberperson |
|
||||||
| Household::class | | | household |
|
| | | memberperson.center | membercenter |
|
||||||
| | HouseholdComposition::class | household.compositions | composition |
|
| Household::class | | | household |
|
||||||
| Activity::class | | | activity |
|
| | HouseholdComposition::class | household.compositions | composition |
|
||||||
| | Person::class | activity.person | actperson |
|
| Activity::class | | | activity |
|
||||||
| | AccompanyingPeriod::class | activity.accompanyingPeriod | acp |
|
| | Person::class | activity.person | actperson |
|
||||||
| | Person::class | activity\_person\_having\_activity.person | person\_person\_having\_activity |
|
| | AccompanyingPeriod::class | activity.accompanyingPeriod | acp |
|
||||||
| | ActivityReason::class | activity\_person\_having\_activity.reasons | reasons\_person\_having\_activity |
|
| | Person::class | activity\_person\_having\_activity.person | person\_person\_having\_activity |
|
||||||
| | ActivityType::class | activity.activityType | acttype |
|
| | ActivityReason::class | activity\_person\_having\_activity.reasons | reasons\_person\_having\_activity |
|
||||||
| | Location::class | activity.location | actloc |
|
| | ActivityType::class | activity.activityType | acttype |
|
||||||
| | SocialAction::class | activity.socialActions | actsocialaction |
|
| | Location::class | activity.location | actloc |
|
||||||
| | SocialIssue::class | activity.socialIssues | actsocialssue |
|
| | SocialAction::class | activity.socialActions | actsocialaction |
|
||||||
| | ThirdParty::class | activity.thirdParties | acttparty |
|
| | SocialIssue::class | activity.socialIssues | actsocialssue |
|
||||||
| | User::class | activity.user | actuser |
|
| | ThirdParty::class | activity.thirdParties | acttparty |
|
||||||
| | User::class | activity.users | actusers |
|
| | User::class | activity.user | actuser |
|
||||||
| | ActivityReason::class | activity.reasons | actreasons |
|
| | User::class | activity.users | actusers |
|
||||||
| | Center::class | actperson.center | actcenter |
|
| | ActivityReason::class | activity.reasons | actreasons |
|
||||||
| | Person::class | activity.createdBy | actcreator |
|
| | Center::class | actperson.center | actcenter |
|
||||||
| ActivityReason::class | | | actreasons |
|
| | Person::class | activity.createdBy | actcreator |
|
||||||
| | ActivityReasonCategory::class | actreason.category | actreasoncat |
|
| ActivityReason::class | | | actreasons |
|
||||||
| Calendar::class | | | cal |
|
| | ActivityReasonCategory::class | actreason.category | actreasoncat |
|
||||||
| | CancelReason::class | cal.cancelReason | calcancel |
|
| Calendar::class | | | cal |
|
||||||
| | Location::class | cal.location | calloc |
|
| | CancelReason::class | cal.cancelReason | calcancel |
|
||||||
| | User::class | cal.user | caluser |
|
| | Location::class | cal.location | calloc |
|
||||||
| VendeePerson::class | | | vp |
|
| | User::class | cal.user | caluser |
|
||||||
| | SituationProfessionelle::class | vp.situationProfessionelle | vpprof |
|
| VendeePerson::class | | | vp |
|
||||||
| | StatutLogement::class | vp.statutLogement | vplog |
|
| | SituationProfessionelle::class | vp.situationProfessionelle | vpprof |
|
||||||
| | TempsDeTravail::class | vp.tempsDeTravail | vptt |
|
| | StatutLogement::class | vp.statutLogement | vplog |
|
||||||
|
| | TempsDeTravail::class | vp.tempsDeTravail | vptt |
|
||||||
|
@ -5,11 +5,6 @@ parameters:
|
|||||||
count: 1
|
count: 1
|
||||||
path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php
|
path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Access to an undefined property Chill\\\\PersonBundle\\\\Entity\\\\Household\\\\PersonHouseholdAddress\\:\\:\\$relation\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Entity/Household/PersonHouseholdAddress.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Access to an undefined property Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\:\\:\\$work\\.$#"
|
message: "#^Access to an undefined property Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\:\\:\\$work\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
@ -30,11 +25,6 @@ parameters:
|
|||||||
count: 1
|
count: 1
|
||||||
path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/MembersEditorNormalizer.php
|
path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/MembersEditorNormalizer.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Undefined variable\\: \\$choiceSlug$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Export/ListPerson.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Undefined variable\\: \\$choiceSlug$#"
|
message: "#^Undefined variable\\: \\$choiceSlug$#"
|
||||||
count: 1
|
count: 1
|
||||||
|
@ -10,16 +10,6 @@ parameters:
|
|||||||
count: 1
|
count: 1
|
||||||
path: src/Bundle/ChillActivityBundle/Entity/ActivityReasonCategory.php
|
path: src/Bundle/ChillActivityBundle/Entity/ActivityReasonCategory.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Method Chill\\\\ActivityBundle\\\\Export\\\\Export\\\\StatActivityDuration\\:\\:getDescription\\(\\) should return string but return statement is missing\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillActivityBundle/Export/Export/StatActivityDuration.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Method Chill\\\\ActivityBundle\\\\Export\\\\Export\\\\StatActivityDuration\\:\\:getTitle\\(\\) should return string but return statement is missing\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillActivityBundle/Export/Export/StatActivityDuration.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
|
||||||
@ -330,21 +320,6 @@ parameters:
|
|||||||
count: 6
|
count: 6
|
||||||
path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
|
path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Aggregator/CountryOfBirthAggregator.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Aggregator/NationalityAggregator.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
|
||||||
count: 2
|
|
||||||
path: src/Bundle/ChillPersonBundle/Export/Export/ListPerson.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
|
||||||
|
@ -34,6 +34,8 @@ use Chill\MainBundle\Doctrine\DQL\Replace;
|
|||||||
use Chill\MainBundle\Doctrine\DQL\Similarity;
|
use Chill\MainBundle\Doctrine\DQL\Similarity;
|
||||||
use Chill\MainBundle\Doctrine\DQL\STContains;
|
use Chill\MainBundle\Doctrine\DQL\STContains;
|
||||||
use Chill\MainBundle\Doctrine\DQL\StrictWordSimilarityOPS;
|
use Chill\MainBundle\Doctrine\DQL\StrictWordSimilarityOPS;
|
||||||
|
use Chill\MainBundle\Doctrine\DQL\STX;
|
||||||
|
use Chill\MainBundle\Doctrine\DQL\STY;
|
||||||
use Chill\MainBundle\Doctrine\DQL\ToChar;
|
use Chill\MainBundle\Doctrine\DQL\ToChar;
|
||||||
use Chill\MainBundle\Doctrine\DQL\Unaccent;
|
use Chill\MainBundle\Doctrine\DQL\Unaccent;
|
||||||
use Chill\MainBundle\Doctrine\ORM\Hydration\FlatHierarchyEntityHydrator;
|
use Chill\MainBundle\Doctrine\ORM\Hydration\FlatHierarchyEntityHydrator;
|
||||||
@ -242,6 +244,8 @@ class ChillMainExtension extends Extension implements
|
|||||||
'STRICT_WORD_SIMILARITY_OPS' => StrictWordSimilarityOPS::class,
|
'STRICT_WORD_SIMILARITY_OPS' => StrictWordSimilarityOPS::class,
|
||||||
'ST_CONTAINS' => STContains::class,
|
'ST_CONTAINS' => STContains::class,
|
||||||
'JSONB_ARRAY_LENGTH' => JsonbArrayLength::class,
|
'JSONB_ARRAY_LENGTH' => JsonbArrayLength::class,
|
||||||
|
'ST_X' => STX::class,
|
||||||
|
'ST_Y' => STY::class,
|
||||||
],
|
],
|
||||||
'datetime_functions' => [
|
'datetime_functions' => [
|
||||||
'EXTRACT' => Extract::class,
|
'EXTRACT' => Extract::class,
|
||||||
|
37
src/Bundle/ChillMainBundle/Doctrine/DQL/STX.php
Normal file
37
src/Bundle/ChillMainBundle/Doctrine/DQL/STX.php
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?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 STX extends FunctionNode
|
||||||
|
{
|
||||||
|
private $field;
|
||||||
|
|
||||||
|
public function getSql(SqlWalker $sqlWalker)
|
||||||
|
{
|
||||||
|
return sprintf('ST_X(%s)', $this->field->dispatch($sqlWalker));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parse(Parser $parser)
|
||||||
|
{
|
||||||
|
$parser->match(Lexer::T_IDENTIFIER);
|
||||||
|
$parser->match(Lexer::T_OPEN_PARENTHESIS);
|
||||||
|
|
||||||
|
$this->field = $parser->ArithmeticExpression();
|
||||||
|
|
||||||
|
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
|
||||||
|
}
|
||||||
|
}
|
37
src/Bundle/ChillMainBundle/Doctrine/DQL/STY.php
Normal file
37
src/Bundle/ChillMainBundle/Doctrine/DQL/STY.php
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?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 STY extends FunctionNode
|
||||||
|
{
|
||||||
|
private $field;
|
||||||
|
|
||||||
|
public function getSql(SqlWalker $sqlWalker)
|
||||||
|
{
|
||||||
|
return sprintf('ST_Y(%s)', $this->field->dispatch($sqlWalker));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parse(Parser $parser)
|
||||||
|
{
|
||||||
|
$parser->match(Lexer::T_IDENTIFIER);
|
||||||
|
$parser->match(Lexer::T_OPEN_PARENTHESIS);
|
||||||
|
|
||||||
|
$this->field = $parser->ArithmeticExpression();
|
||||||
|
|
||||||
|
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
|
||||||
|
}
|
||||||
|
}
|
@ -20,11 +20,12 @@ use PhpOffice\PhpSpreadsheet\Shared\Date;
|
|||||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
||||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||||
|
use RuntimeException;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
|
||||||
|
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
use function array_key_exists;
|
use function array_key_exists;
|
||||||
use function array_keys;
|
use function array_keys;
|
||||||
use function array_map;
|
use function array_map;
|
||||||
@ -80,7 +81,7 @@ class SpreadsheetListFormatter implements FormatterInterface
|
|||||||
*
|
*
|
||||||
* @uses appendAggregatorForm
|
* @uses appendAggregatorForm
|
||||||
*
|
*
|
||||||
* @param type $exportAlias
|
* @param string $exportAlias
|
||||||
*/
|
*/
|
||||||
public function buildForm(
|
public function buildForm(
|
||||||
FormBuilderInterface $builder,
|
FormBuilderInterface $builder,
|
||||||
@ -144,8 +145,6 @@ class SpreadsheetListFormatter implements FormatterInterface
|
|||||||
$i = 1;
|
$i = 1;
|
||||||
|
|
||||||
foreach ($result as $row) {
|
foreach ($result as $row) {
|
||||||
$line = [];
|
|
||||||
|
|
||||||
if (true === $this->formatterData['numerotation']) {
|
if (true === $this->formatterData['numerotation']) {
|
||||||
$worksheet->setCellValue('A' . ($i + 1), (string) $i);
|
$worksheet->setCellValue('A' . ($i + 1), (string) $i);
|
||||||
}
|
}
|
||||||
@ -155,13 +154,22 @@ class SpreadsheetListFormatter implements FormatterInterface
|
|||||||
foreach ($row as $key => $value) {
|
foreach ($row as $key => $value) {
|
||||||
$row = $a . ($i + 1);
|
$row = $a . ($i + 1);
|
||||||
|
|
||||||
if ($value instanceof DateTimeInterface) {
|
$formattedValue = $this->getLabel($key, $value);
|
||||||
$worksheet->setCellValue($row, Date::PHPToExcel($value));
|
|
||||||
$worksheet->getStyle($row)
|
if ($formattedValue instanceof DateTimeInterface) {
|
||||||
->getNumberFormat()
|
$worksheet->setCellValue($row, Date::PHPToExcel($formattedValue));
|
||||||
->setFormatCode(NumberFormat::FORMAT_DATE_DDMMYYYY);
|
|
||||||
|
if ($formattedValue->format('His') === '000000') {
|
||||||
|
$worksheet->getStyle($row)
|
||||||
|
->getNumberFormat()
|
||||||
|
->setFormatCode(NumberFormat::FORMAT_DATE_DDMMYYYY);
|
||||||
|
} else {
|
||||||
|
$worksheet->getStyle($row)
|
||||||
|
->getNumberFormat()
|
||||||
|
->setFormatCode(NumberFormat::FORMAT_DATE_DATETIME);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$worksheet->setCellValue($row, $this->getLabel($key, $value));
|
$worksheet->setCellValue($row, $formattedValue);
|
||||||
}
|
}
|
||||||
++$a;
|
++$a;
|
||||||
}
|
}
|
||||||
@ -259,6 +267,10 @@ class SpreadsheetListFormatter implements FormatterInterface
|
|||||||
foreach ($keys as $key) {
|
foreach ($keys as $key) {
|
||||||
// get an array with all values for this key if possible
|
// get an array with all values for this key if possible
|
||||||
$values = array_map(static function ($v) use ($key) {
|
$values = array_map(static function ($v) use ($key) {
|
||||||
|
if (!array_key_exists($key, $v)) {
|
||||||
|
throw new RuntimeException(sprintf('This key does not exists: %s. Available keys are %s', $key, implode(', ', array_keys($v))));
|
||||||
|
}
|
||||||
|
|
||||||
return $v[$key];
|
return $v[$key];
|
||||||
}, $this->result);
|
}, $this->result);
|
||||||
// store the label in the labelsCache property
|
// store the label in the labelsCache property
|
||||||
|
60
src/Bundle/ChillMainBundle/Export/Helper/DateTimeHelper.php
Normal file
60
src/Bundle/ChillMainBundle/Export/Helper/DateTimeHelper.php
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<?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\Export\Helper;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
use Exception;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
|
class DateTimeHelper
|
||||||
|
{
|
||||||
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
|
public function __construct(TranslatorInterface $translator)
|
||||||
|
{
|
||||||
|
$this->translator = $translator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLabel($header): callable
|
||||||
|
{
|
||||||
|
return function ($value) use ($header) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return $this->translator->trans($header);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// warning: won't work with DateTimeImmutable as we reset time a few lines later
|
||||||
|
$date = DateTime::createFromFormat('Y-m-d', $value);
|
||||||
|
$hasTime = false;
|
||||||
|
|
||||||
|
if (false === $date) {
|
||||||
|
$date = DateTime::createFromFormat('Y-m-d H:i:s', $value);
|
||||||
|
$hasTime = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that the creation could occurs.
|
||||||
|
if (false === $date) {
|
||||||
|
throw new Exception(sprintf('The value %s could '
|
||||||
|
. 'not be converted to %s', $value, DateTime::class));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$hasTime) {
|
||||||
|
$date->setTime(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $date;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
274
src/Bundle/ChillMainBundle/Export/Helper/ExportAddressHelper.php
Normal file
274
src/Bundle/ChillMainBundle/Export/Helper/ExportAddressHelper.php
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
<?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\Export\Helper;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Repository\AddressRepository;
|
||||||
|
use Chill\MainBundle\Templating\Entity\AddressRender;
|
||||||
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use LogicException;
|
||||||
|
use Symfony\Component\PropertyAccess\PropertyAccess;
|
||||||
|
use Symfony\Component\PropertyAccess\PropertyAccessor;
|
||||||
|
use function in_array;
|
||||||
|
use function strlen;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helps to load addresses and format them in list.
|
||||||
|
*/
|
||||||
|
class ExportAddressHelper
|
||||||
|
{
|
||||||
|
public const F_ALL =
|
||||||
|
self::F_ATTRIBUTES | self::F_BUILDING | self::F_COUNTRY |
|
||||||
|
self::F_GEOM | self::F_POSTAL_CODE | self::F_STREET;
|
||||||
|
|
||||||
|
public const F_AS_STRING = 0b00010000;
|
||||||
|
|
||||||
|
public const F_ATTRIBUTES = 0b01000000;
|
||||||
|
|
||||||
|
public const F_BUILDING = 0b00001000;
|
||||||
|
|
||||||
|
public const F_COUNTRY = 0b00000001;
|
||||||
|
|
||||||
|
public const F_GEOM = 0b00100000;
|
||||||
|
|
||||||
|
public const F_POSTAL_CODE = 0b00000010;
|
||||||
|
|
||||||
|
public const F_STREET = 0b00000100;
|
||||||
|
|
||||||
|
private const ALL = [
|
||||||
|
'country' => self::F_COUNTRY,
|
||||||
|
'postal_code' => self::F_POSTAL_CODE,
|
||||||
|
'street' => self::F_STREET,
|
||||||
|
'building' => self::F_BUILDING,
|
||||||
|
'string' => self::F_AS_STRING,
|
||||||
|
'geom' => self::F_GEOM,
|
||||||
|
'attributes' => self::F_ATTRIBUTES,
|
||||||
|
];
|
||||||
|
|
||||||
|
private const COLUMN_MAPPING = [
|
||||||
|
'country' => ['country'],
|
||||||
|
'postal_code' => ['postcode_code', 'postcode_name'],
|
||||||
|
'street' => ['street', 'streetNumber'],
|
||||||
|
'building' => ['buildingName', 'corridor', 'distribution', 'extra', 'flat', 'floor', 'steps'],
|
||||||
|
'string' => ['_as_string'],
|
||||||
|
'attributes' => ['isNoAddress', 'confidential', 'id'],
|
||||||
|
'geom' => ['_lat', '_lon'],
|
||||||
|
];
|
||||||
|
|
||||||
|
private AddressRender $addressRender;
|
||||||
|
|
||||||
|
private AddressRepository $addressRepository;
|
||||||
|
|
||||||
|
private PropertyAccessor $propertyAccess;
|
||||||
|
|
||||||
|
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
AddressRepository $addressRepository,
|
||||||
|
TranslatableStringHelperInterface $translatableStringHelper,
|
||||||
|
AddressRender $addressRender
|
||||||
|
) {
|
||||||
|
$this->addressRepository = $addressRepository;
|
||||||
|
$this->propertyAccess = PropertyAccess::createPropertyAccessor();
|
||||||
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
|
$this->addressRender = $addressRender;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addSelectClauses(int $params, QueryBuilder $queryBuilder, $entityName = 'address', $prefix = 'add')
|
||||||
|
{
|
||||||
|
foreach (self::ALL as $key => $bitmask) {
|
||||||
|
if (($params & $bitmask) === $bitmask) {
|
||||||
|
foreach (self::COLUMN_MAPPING[$key] as $field) {
|
||||||
|
switch ($field) {
|
||||||
|
case 'id':
|
||||||
|
case '_as_string':
|
||||||
|
$queryBuilder->addSelect(sprintf('%s.id AS %s%s', $entityName, $prefix, $field));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'street':
|
||||||
|
case 'streetNumber':
|
||||||
|
case 'floor':
|
||||||
|
case 'corridor':
|
||||||
|
case 'steps':
|
||||||
|
case 'buildingName':
|
||||||
|
case 'flat':
|
||||||
|
case 'distribution':
|
||||||
|
case 'extra':
|
||||||
|
$queryBuilder->addSelect(sprintf('%s.%s AS %s%s', $entityName, $field, $prefix, $field));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'country':
|
||||||
|
case 'postcode_name':
|
||||||
|
case 'postcode_code':
|
||||||
|
$postCodeAlias = sprintf('%spostcode_t', $prefix);
|
||||||
|
|
||||||
|
if (!in_array($postCodeAlias, $queryBuilder->getAllAliases(), true)) {
|
||||||
|
$queryBuilder->leftJoin($entityName . '.postcode', $postCodeAlias);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('postcode_name' === $field) {
|
||||||
|
$queryBuilder->addSelect(sprintf('%s.%s AS %s%s', $postCodeAlias, 'name', $prefix, $field));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('postcode_code' === $field) {
|
||||||
|
$queryBuilder->addSelect(sprintf('%s.%s AS %s%s', $postCodeAlias, 'code', $prefix, $field));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$countryAlias = sprintf('%scountry_t', $prefix);
|
||||||
|
|
||||||
|
if (!in_array($countryAlias, $queryBuilder->getAllAliases(), true)) {
|
||||||
|
$queryBuilder->leftJoin(sprintf('%s.country', $postCodeAlias), $countryAlias);
|
||||||
|
}
|
||||||
|
|
||||||
|
$queryBuilder->addSelect(sprintf('%s.%s AS %s%s', $countryAlias, 'name', $prefix, $field));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'isNoAddress':
|
||||||
|
case 'confidential':
|
||||||
|
$queryBuilder->addSelect(sprintf('CASE WHEN %s.%s = \'TRUE\' THEN 1 ELSE 0 END AS %s%s', $entityName, $field, $prefix, $field));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '_lat':
|
||||||
|
$queryBuilder->addSelect(sprintf('ST_Y(%s.point) AS %s%s', $entityName, $prefix, $field));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '_lon':
|
||||||
|
$queryBuilder->addSelect(sprintf('ST_X(%s.point) AS %s%s', $entityName, $prefix, $field));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new LogicException('This key is not supported: ' . $key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param self::F_* $params
|
||||||
|
*
|
||||||
|
* @return array|string[]
|
||||||
|
*/
|
||||||
|
public function getKeys(int $params, string $prefix = ''): array
|
||||||
|
{
|
||||||
|
$prefixes = [];
|
||||||
|
|
||||||
|
foreach (self::ALL as $key => $bitmask) {
|
||||||
|
if (($params & $bitmask) === $bitmask) {
|
||||||
|
$prefixes = array_merge(
|
||||||
|
$prefixes,
|
||||||
|
array_map(
|
||||||
|
static function ($item) use ($prefix) { return $prefix . $item; },
|
||||||
|
self::COLUMN_MAPPING[$key]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $prefixes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLabel($key, array $values, $data, string $prefix = '', string $translationPrefix = 'export.address_helper.'): callable
|
||||||
|
{
|
||||||
|
$sanitizedKey = substr($key, strlen($prefix));
|
||||||
|
|
||||||
|
switch ($sanitizedKey) {
|
||||||
|
case 'id':
|
||||||
|
case 'street':
|
||||||
|
case 'streetNumber':
|
||||||
|
case 'buildingName':
|
||||||
|
case 'corridor':
|
||||||
|
case 'distribution':
|
||||||
|
case 'extra':
|
||||||
|
case 'flat':
|
||||||
|
case 'floor':
|
||||||
|
case '_lat':
|
||||||
|
case '_lon':
|
||||||
|
case 'postcode_code':
|
||||||
|
case 'postcode_name':
|
||||||
|
return static function ($value) use ($sanitizedKey, $translationPrefix) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return $translationPrefix . $sanitizedKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'country':
|
||||||
|
return function ($value) use ($key) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return 'export.list.acp' . $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->translatableStringHelper->localize(json_decode($value, true));
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'isNoAddress':
|
||||||
|
case 'confidential':
|
||||||
|
return static function ($value) use ($sanitizedKey, $translationPrefix) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return $translationPrefix . $sanitizedKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($value) {
|
||||||
|
case null:
|
||||||
|
return '';
|
||||||
|
|
||||||
|
case true:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case false:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new LogicException('this value is not supported for ' . $sanitizedKey . ': ' . $value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
case '_as_string':
|
||||||
|
return function ($value) use ($sanitizedKey, $translationPrefix) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return $translationPrefix . $sanitizedKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$address = $this->addressRepository->find($value);
|
||||||
|
|
||||||
|
return $this->addressRender->renderString($address, []);
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new LogicException('this key is not supported: ' . $sanitizedKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
src/Bundle/ChillMainBundle/Export/Helper/UserHelper.php
Normal file
43
src/Bundle/ChillMainBundle/Export/Helper/UserHelper.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?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\Export\Helper;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Repository\UserRepositoryInterface;
|
||||||
|
use Chill\MainBundle\Templating\Entity\UserRender;
|
||||||
|
|
||||||
|
class UserHelper
|
||||||
|
{
|
||||||
|
private UserRender $userRender;
|
||||||
|
|
||||||
|
private UserRepositoryInterface $userRepository;
|
||||||
|
|
||||||
|
public function __construct(UserRender $userRender, UserRepositoryInterface $userRepository)
|
||||||
|
{
|
||||||
|
$this->userRender = $userRender;
|
||||||
|
$this->userRepository = $userRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLabel($key, array $values, string $header): callable
|
||||||
|
{
|
||||||
|
return function ($value) use ($header) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return $header;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value || null === $user = $this->userRepository->find($value)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->userRender->renderString($user, []);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -12,19 +12,40 @@ declare(strict_types=1);
|
|||||||
namespace Chill\MainBundle\Repository;
|
namespace Chill\MainBundle\Repository;
|
||||||
|
|
||||||
use Chill\MainBundle\Entity\Civility;
|
use Chill\MainBundle\Entity\Civility;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
|
||||||
/**
|
class CivilityRepository implements CivilityRepositoryInterface
|
||||||
* @method Civility|null find($id, $lockMode = null, $lockVersion = null)
|
|
||||||
* @method Civility|null findOneBy(array $criteria, array $orderBy = null)
|
|
||||||
* @method Civility[] findAll()
|
|
||||||
* @method Civility[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
|
||||||
*/
|
|
||||||
class CivilityRepository extends ServiceEntityRepository
|
|
||||||
{
|
{
|
||||||
public function __construct(ManagerRegistry $registry)
|
private EntityRepository $repository;
|
||||||
|
|
||||||
|
public function __construct(EntityManagerInterface $entityManager)
|
||||||
{
|
{
|
||||||
parent::__construct($registry, Civility::class);
|
$this->repository = $entityManager->getRepository($this->getClassName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function find($id): ?Civility
|
||||||
|
{
|
||||||
|
return $this->repository->find($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findAll(): array
|
||||||
|
{
|
||||||
|
return $this->repository->findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array
|
||||||
|
{
|
||||||
|
return $this->repository->findBy($criteria, $orderBy, $limit, $offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findOneBy(array $criteria): ?Civility
|
||||||
|
{
|
||||||
|
return $this->repository->findOneBy($criteria);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getClassName(): string
|
||||||
|
{
|
||||||
|
return Civility::class;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
<?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\Civility;
|
||||||
|
use Doctrine\Persistence\ObjectRepository;
|
||||||
|
|
||||||
|
interface CivilityRepositoryInterface extends ObjectRepository
|
||||||
|
{
|
||||||
|
public function find($id): ?Civility;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|Civility[]
|
||||||
|
*/
|
||||||
|
public function findAll(): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|Civility[]
|
||||||
|
*/
|
||||||
|
public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array;
|
||||||
|
|
||||||
|
public function findOneBy(array $criteria): ?Civility;
|
||||||
|
|
||||||
|
public function getClassName(): string;
|
||||||
|
}
|
@ -14,15 +14,14 @@ namespace Chill\MainBundle\Repository;
|
|||||||
use Chill\MainBundle\Entity\Language;
|
use Chill\MainBundle\Entity\Language;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
use Doctrine\Persistence\ObjectRepository;
|
|
||||||
|
|
||||||
final class LanguageRepository implements ObjectRepository
|
final class LanguageRepository implements LanguageRepositoryInterface
|
||||||
{
|
{
|
||||||
private EntityRepository $repository;
|
private EntityRepository $repository;
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $entityManager)
|
public function __construct(EntityManagerInterface $entityManager)
|
||||||
{
|
{
|
||||||
$this->repository = $entityManager->getRepository(Language::class);
|
$this->repository = $entityManager->getRepository($this->getClassName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function find($id, $lockMode = null, $lockVersion = null): ?Language
|
public function find($id, $lockMode = null, $lockVersion = null): ?Language
|
||||||
@ -54,7 +53,7 @@ final class LanguageRepository implements ObjectRepository
|
|||||||
return $this->repository->findOneBy($criteria, $orderBy);
|
return $this->repository->findOneBy($criteria, $orderBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getClassName()
|
public function getClassName(): string
|
||||||
{
|
{
|
||||||
return Language::class;
|
return Language::class;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
<?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\Language;
|
||||||
|
use Doctrine\Persistence\ObjectRepository;
|
||||||
|
|
||||||
|
interface LanguageRepositoryInterface extends ObjectRepository
|
||||||
|
{
|
||||||
|
public function find($id, $lockMode = null, $lockVersion = null): ?Language;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Language[]
|
||||||
|
*/
|
||||||
|
public function findAll(): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed|null $limit
|
||||||
|
* @param mixed|null $offset
|
||||||
|
*
|
||||||
|
* @return Language[]
|
||||||
|
*/
|
||||||
|
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array;
|
||||||
|
|
||||||
|
public function findOneBy(array $criteria, ?array $orderBy = null): ?Language;
|
||||||
|
|
||||||
|
public function getClassName(): string;
|
||||||
|
}
|
@ -680,10 +680,12 @@ final class ExportManagerTest extends KernelTestCase
|
|||||||
|
|
||||||
return new ExportManager(
|
return new ExportManager(
|
||||||
$logger ?? self::$container->get('logger'),
|
$logger ?? self::$container->get('logger'),
|
||||||
$em ?? self::$container->get('doctrine.orm.entity_manager'),
|
|
||||||
$authorizationChecker ?? self::$container->get('security.authorization_checker'),
|
$authorizationChecker ?? self::$container->get('security.authorization_checker'),
|
||||||
$authorizationHelper ?? self::$container->get('chill.main.security.authorization.helper'),
|
$authorizationHelper ?? self::$container->get('chill.main.security.authorization.helper'),
|
||||||
$tokenStorage
|
$tokenStorage,
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,9 @@ services:
|
|||||||
autowire: true
|
autowire: true
|
||||||
autoconfigure: true
|
autoconfigure: true
|
||||||
|
|
||||||
|
Chill\MainBundle\Export\Helper\:
|
||||||
|
resource: '../../Export/Helper'
|
||||||
|
|
||||||
chill.main.export_element_validator:
|
chill.main.export_element_validator:
|
||||||
class: Chill\MainBundle\Validator\Constraints\Export\ExportElementConstraintValidator
|
class: Chill\MainBundle\Validator\Constraints\Export\ExportElementConstraintValidator
|
||||||
tags:
|
tags:
|
||||||
|
@ -39,6 +39,8 @@ Last updated by: Dernière mise à jour par
|
|||||||
on: "le "
|
on: "le "
|
||||||
Last updated on: Dernière mise à jour le
|
Last updated on: Dernière mise à jour le
|
||||||
by_user: "par "
|
by_user: "par "
|
||||||
|
lifecycleUpdate: Evenements de création et mise à jour
|
||||||
|
address_fields: Données liées à l'adresse
|
||||||
|
|
||||||
Edit: Modifier
|
Edit: Modifier
|
||||||
Update: Mettre à jour
|
Update: Mettre à jour
|
||||||
@ -57,6 +59,7 @@ Until: Jusqu'au
|
|||||||
#elements used in software
|
#elements used in software
|
||||||
centers: centres
|
centers: centres
|
||||||
Centers: Centres
|
Centers: Centres
|
||||||
|
center: centre
|
||||||
comment: commentaire
|
comment: commentaire
|
||||||
Comment: Commentaire
|
Comment: Commentaire
|
||||||
Pinned comment: Commentaire épinglé
|
Pinned comment: Commentaire épinglé
|
||||||
@ -79,17 +82,17 @@ Postal code: Code postal
|
|||||||
Valid from: Valide à partir du
|
Valid from: Valide à partir du
|
||||||
Choose a postal code: Choisir un code postal
|
Choose a postal code: Choisir un code postal
|
||||||
address:
|
address:
|
||||||
address_homeless: L'adresse est-elle celle d'un domicile fixe ?
|
address_homeless: L'adresse est-elle celle d'un domicile fixe ?
|
||||||
real address: Adresse d'un domicile
|
real address: Adresse d'un domicile
|
||||||
consider homeless: Cette adresse est incomplète
|
consider homeless: Cette adresse est incomplète
|
||||||
address more:
|
address more:
|
||||||
floor: ét
|
floor: ét
|
||||||
corridor: coul
|
corridor: coul
|
||||||
steps: esc
|
steps: esc
|
||||||
flat: appart
|
flat: appart
|
||||||
buildingName: résidence
|
buildingName: résidence
|
||||||
extra: ""
|
extra: ""
|
||||||
distribution: cedex
|
distribution: cedex
|
||||||
Create a new address: Créer une nouvelle adresse
|
Create a new address: Créer une nouvelle adresse
|
||||||
Create an address: Créer une adresse
|
Create an address: Créer une adresse
|
||||||
Update address: Modifier l'adresse
|
Update address: Modifier l'adresse
|
||||||
@ -125,7 +128,7 @@ Location and location type: Localisations et types de localisation
|
|||||||
Back to the admin: Menu d'administration
|
Back to the admin: Menu d'administration
|
||||||
"Administration interface": Interface d'administration
|
"Administration interface": Interface d'administration
|
||||||
Welcome to the admin section !: >
|
Welcome to the admin section !: >
|
||||||
Bienvenue dans l'interface d'administration !
|
Bienvenue dans l'interface d'administration !
|
||||||
|
|
||||||
#permissions
|
#permissions
|
||||||
Permissions Menu: Gestion des droits
|
Permissions Menu: Gestion des droits
|
||||||
@ -236,6 +239,7 @@ Default for: Type de localisation par défaut pour
|
|||||||
none: aucun
|
none: aucun
|
||||||
person: usager
|
person: usager
|
||||||
thirdparty: tiers
|
thirdparty: tiers
|
||||||
|
civility: civilité
|
||||||
|
|
||||||
#admin section for civility
|
#admin section for civility
|
||||||
abbreviation: abbréviation
|
abbreviation: abbréviation
|
||||||
@ -334,69 +338,69 @@ Impersonate: Incarner l'utilisateur
|
|||||||
Impersonate mode: Mode fantôme
|
Impersonate mode: Mode fantôme
|
||||||
|
|
||||||
crud:
|
crud:
|
||||||
# general items
|
# general items
|
||||||
new:
|
new:
|
||||||
button_action_form: Créer
|
button_action_form: Créer
|
||||||
link_edit: Modifier
|
link_edit: Modifier
|
||||||
save_and_close: Créer & fermer
|
save_and_close: Créer & fermer
|
||||||
save_and_show: Créer & voir
|
save_and_show: Créer & voir
|
||||||
save_and_new: Créer & nouveau
|
save_and_new: Créer & nouveau
|
||||||
success: Les données ont été créées
|
success: Les données ont été créées
|
||||||
edit:
|
edit:
|
||||||
button_action_form: Enregistrer
|
button_action_form: Enregistrer
|
||||||
back_to_view: Voir
|
back_to_view: Voir
|
||||||
save_and_close: Enregistrer & fermer
|
save_and_close: Enregistrer & fermer
|
||||||
save_and_show: Enregistrer & voir
|
save_and_show: Enregistrer & voir
|
||||||
success: Les données ont été modifiées
|
success: Les données ont été modifiées
|
||||||
delete:
|
delete:
|
||||||
success: Les données ont été supprimées
|
success: Les données ont été supprimées
|
||||||
link_to_form: Supprimer
|
link_to_form: Supprimer
|
||||||
default:
|
default:
|
||||||
success: Les données ont été enregistrées
|
success: Les données ont été enregistrées
|
||||||
view:
|
view:
|
||||||
link_duplicate: Dupliquer
|
link_duplicate: Dupliquer
|
||||||
admin_user:
|
admin_user:
|
||||||
index:
|
index:
|
||||||
title: Utilisateurs
|
title: Utilisateurs
|
||||||
add_new: Créer
|
add_new: Créer
|
||||||
title_edit: Modifier un utilisateur
|
title_edit: Modifier un utilisateur
|
||||||
title_new: Créer un utilisateur
|
title_new: Créer un utilisateur
|
||||||
admin_user_job:
|
admin_user_job:
|
||||||
index:
|
index:
|
||||||
title: Métiers
|
title: Métiers
|
||||||
add_new: Créer
|
add_new: Créer
|
||||||
title_new: Nouveau métier
|
title_new: Nouveau métier
|
||||||
title_edit: Modifier un métier
|
title_edit: Modifier un métier
|
||||||
main_location_type:
|
main_location_type:
|
||||||
index:
|
index:
|
||||||
title: Liste des types de localisations
|
title: Liste des types de localisations
|
||||||
add_new: Ajouter un type de localisation
|
add_new: Ajouter un type de localisation
|
||||||
title_new: Nouveau type de localisation
|
title_new: Nouveau type de localisation
|
||||||
title_edit: Modifier un type de localisation
|
title_edit: Modifier un type de localisation
|
||||||
main_location:
|
main_location:
|
||||||
index:
|
index:
|
||||||
title: Liste des localisations
|
title: Liste des localisations
|
||||||
add_new: Ajouter une localisation
|
add_new: Ajouter une localisation
|
||||||
title_new: Nouvelle localisation
|
title_new: Nouvelle localisation
|
||||||
title_edit: Modifier une localisation
|
title_edit: Modifier une localisation
|
||||||
main_language:
|
main_language:
|
||||||
index:
|
index:
|
||||||
title: Liste des langues
|
title: Liste des langues
|
||||||
add_new: Ajouter une langue
|
add_new: Ajouter une langue
|
||||||
title_new: Nouvelle langue
|
title_new: Nouvelle langue
|
||||||
title_edit: Modifier une langue
|
title_edit: Modifier une langue
|
||||||
main_country:
|
main_country:
|
||||||
index:
|
index:
|
||||||
title: Liste des pays
|
title: Liste des pays
|
||||||
add_new: Ajouter un pays
|
add_new: Ajouter un pays
|
||||||
title_new: Nouveau pays
|
title_new: Nouveau pays
|
||||||
title_edit: Modifier un pays
|
title_edit: Modifier un pays
|
||||||
main_civility:
|
main_civility:
|
||||||
index:
|
index:
|
||||||
title: Liste des civilités
|
title: Liste des civilités
|
||||||
add_new: Ajouter une civilité
|
add_new: Ajouter une civilité
|
||||||
title_new: Nouvelle civilité
|
title_new: Nouvelle civilité
|
||||||
title_edit: Modifier une civilité
|
title_edit: Modifier une civilité
|
||||||
|
|
||||||
No entities: Aucun élément
|
No entities: Aucun élément
|
||||||
|
|
||||||
@ -515,3 +519,22 @@ notification:
|
|||||||
Remove an email: Supprimer l'adresse email
|
Remove an email: Supprimer l'adresse email
|
||||||
Email with access link: Adresse email ayant reçu un lien d'accès
|
Email with access link: Adresse email ayant reçu un lien d'accès
|
||||||
|
|
||||||
|
export:
|
||||||
|
address_helper:
|
||||||
|
id: Identifiant de l'adresse
|
||||||
|
street: Voie
|
||||||
|
streetNumber: Numéro de voie
|
||||||
|
buildingName: Résidence
|
||||||
|
corridor: Couloir
|
||||||
|
distribution: Distribution
|
||||||
|
extra: Extra
|
||||||
|
flat: Appartement
|
||||||
|
floor: Étage
|
||||||
|
postcode_code: Code postal
|
||||||
|
postcode_name: Libellé du code postal
|
||||||
|
country: Pays
|
||||||
|
_as_string: Adresse formattée
|
||||||
|
confidential: Adresse confidentielle ?
|
||||||
|
isNoAddress: Adresse incomplète ?
|
||||||
|
_lat: Latitude
|
||||||
|
_lon: Longitude
|
||||||
|
@ -84,7 +84,7 @@ class PersonHouseholdAddress
|
|||||||
|
|
||||||
public function getHousehold(): ?Household
|
public function getHousehold(): ?Household
|
||||||
{
|
{
|
||||||
return $this->relation;
|
return $this->household;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPerson(): ?Person
|
public function getPerson(): ?Person
|
||||||
|
@ -1760,7 +1760,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param type $spokenLanguages
|
* @param Collection $spokenLanguages
|
||||||
*/
|
*/
|
||||||
public function setSpokenLanguages($spokenLanguages): self
|
public function setSpokenLanguages($spokenLanguages): self
|
||||||
{
|
{
|
||||||
|
@ -38,7 +38,7 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface
|
|||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder): void
|
public function buildForm(FormBuilderInterface $builder): void
|
||||||
{
|
{
|
||||||
// TODO: Implement buildForm() method.
|
// Nothing to add here
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAllowedFormattersTypes(): array
|
public function getAllowedFormattersTypes(): array
|
||||||
|
@ -0,0 +1,416 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Export\Export;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Address;
|
||||||
|
use Chill\MainBundle\Entity\Scope;
|
||||||
|
use Chill\MainBundle\Export\FormatterInterface;
|
||||||
|
use Chill\MainBundle\Export\GroupedExportInterface;
|
||||||
|
use Chill\MainBundle\Export\Helper\DateTimeHelper;
|
||||||
|
use Chill\MainBundle\Export\Helper\ExportAddressHelper;
|
||||||
|
use Chill\MainBundle\Export\Helper\UserHelper;
|
||||||
|
use Chill\MainBundle\Export\ListInterface;
|
||||||
|
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||||
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
|
||||||
|
use Chill\PersonBundle\Entity\Household\PersonHouseholdAddress;
|
||||||
|
use Chill\PersonBundle\Entity\Person\PersonCenterHistory;
|
||||||
|
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
||||||
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
|
use Chill\PersonBundle\Repository\PersonRepository;
|
||||||
|
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
|
||||||
|
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||||
|
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
|
||||||
|
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
|
||||||
|
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
|
||||||
|
use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender;
|
||||||
|
use DateTimeImmutable;
|
||||||
|
use Doctrine\ORM\AbstractQuery;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Doctrine\ORM\Query\Expr\Join;
|
||||||
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use function strlen;
|
||||||
|
|
||||||
|
class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface
|
||||||
|
{
|
||||||
|
private const FIELDS = [
|
||||||
|
'id',
|
||||||
|
'step',
|
||||||
|
'stepSince',
|
||||||
|
'openingDate',
|
||||||
|
'closingDate',
|
||||||
|
'referrer',
|
||||||
|
'referrerSince',
|
||||||
|
'administrativeLocation',
|
||||||
|
'locationIsPerson',
|
||||||
|
'locationIsTemp',
|
||||||
|
'locationPersonName',
|
||||||
|
'locationPersonId',
|
||||||
|
'origin',
|
||||||
|
'closingMotive',
|
||||||
|
'confidential',
|
||||||
|
'emergency',
|
||||||
|
'intensity',
|
||||||
|
'job',
|
||||||
|
'isRequestorPerson',
|
||||||
|
'isRequestorThirdParty',
|
||||||
|
'requestorPerson',
|
||||||
|
'requestorPersonId',
|
||||||
|
'requestorThirdParty',
|
||||||
|
'requestorThirdPartyId',
|
||||||
|
'scopes',
|
||||||
|
'socialIssues',
|
||||||
|
'createdAt',
|
||||||
|
'createdBy',
|
||||||
|
'updatedAt',
|
||||||
|
'updatedBy',
|
||||||
|
];
|
||||||
|
|
||||||
|
private ExportAddressHelper $addressHelper;
|
||||||
|
|
||||||
|
private DateTimeHelper $dateTimeHelper;
|
||||||
|
|
||||||
|
private EntityManagerInterface $entityManager;
|
||||||
|
|
||||||
|
private PersonRenderInterface $personRender;
|
||||||
|
|
||||||
|
private PersonRepository $personRepository;
|
||||||
|
|
||||||
|
private SocialIssueRender $socialIssueRender;
|
||||||
|
|
||||||
|
private SocialIssueRepository $socialIssueRepository;
|
||||||
|
|
||||||
|
private ThirdPartyRender $thirdPartyRender;
|
||||||
|
|
||||||
|
private ThirdPartyRepository $thirdPartyRepository;
|
||||||
|
|
||||||
|
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||||
|
|
||||||
|
private UserHelper $userHelper;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
ExportAddressHelper $addressHelper,
|
||||||
|
DateTimeHelper $dateTimeHelper,
|
||||||
|
EntityManagerInterface $entityManager,
|
||||||
|
PersonRenderInterface $personRender,
|
||||||
|
PersonRepository $personRepository,
|
||||||
|
ThirdPartyRepository $thirdPartyRepository,
|
||||||
|
ThirdPartyRender $thirdPartyRender,
|
||||||
|
SocialIssueRepository $socialIssueRepository,
|
||||||
|
SocialIssueRender $socialIssueRender,
|
||||||
|
TranslatableStringHelperInterface $translatableStringHelper,
|
||||||
|
UserHelper $userHelper
|
||||||
|
) {
|
||||||
|
$this->addressHelper = $addressHelper;
|
||||||
|
$this->dateTimeHelper = $dateTimeHelper;
|
||||||
|
$this->entityManager = $entityManager;
|
||||||
|
$this->personRender = $personRender;
|
||||||
|
$this->personRepository = $personRepository;
|
||||||
|
$this->socialIssueRender = $socialIssueRender;
|
||||||
|
$this->socialIssueRepository = $socialIssueRepository;
|
||||||
|
$this->thirdPartyRender = $thirdPartyRender;
|
||||||
|
$this->thirdPartyRepository = $thirdPartyRepository;
|
||||||
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
|
$this->userHelper = $userHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
|
{
|
||||||
|
$builder
|
||||||
|
->add('calc_date', ChillDateType::class, [
|
||||||
|
'input' => 'datetime_immutable',
|
||||||
|
'label' => 'export.list.acp.Date of calculation for associated elements',
|
||||||
|
'help' => 'export.list.acp.The associated referree, localisation, and other elements will be valid at this date',
|
||||||
|
'required' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAllowedFormattersTypes()
|
||||||
|
{
|
||||||
|
return [FormatterInterface::TYPE_LIST];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescription()
|
||||||
|
{
|
||||||
|
return 'export.list.acp.Generate a list of accompanying periods, filtered on different parameters.';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getGroup(): string
|
||||||
|
{
|
||||||
|
return 'Exports of accompanying courses';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLabels($key, array $values, $data)
|
||||||
|
{
|
||||||
|
if (substr($key, 0, strlen('address_fields')) === 'address_fields') {
|
||||||
|
return $this->addressHelper->getLabel($key, $values, $data, 'address_fields');
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($key) {
|
||||||
|
case 'stepSince':
|
||||||
|
case 'openingDate':
|
||||||
|
case 'closingDate':
|
||||||
|
case 'referrerSince':
|
||||||
|
case 'createdAt':
|
||||||
|
case 'updatedAt':
|
||||||
|
return $this->dateTimeHelper->getLabel('export.list.acp.' . $key);
|
||||||
|
|
||||||
|
case 'origin':
|
||||||
|
case 'closingMotive':
|
||||||
|
case 'job':
|
||||||
|
return function ($value) use ($key) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return 'export.list.acp.' . $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->translatableStringHelper->localize(json_decode($value, true));
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'locationPersonName':
|
||||||
|
case 'requestorPerson':
|
||||||
|
return function ($value) use ($key) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return 'export.list.acp.' . $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value || null === $person = $this->personRepository->find($value)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->personRender->renderString($person, []);
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'requestorThirdParty':
|
||||||
|
return function ($value) use ($key) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return 'export.list.acp.' . $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value || null === $thirdparty = $this->thirdPartyRepository->find($value)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->thirdPartyRender->renderString($thirdparty, []);
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'scopes':
|
||||||
|
return function ($value) use ($key) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return 'export.list.acp.' . $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode(
|
||||||
|
'|',
|
||||||
|
array_map(
|
||||||
|
fn ($s) => $this->translatableStringHelper->localize($s),
|
||||||
|
json_decode($value, true)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'socialIssues':
|
||||||
|
return function ($value) use ($key) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return 'export.list.acp.' . $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode(
|
||||||
|
'|',
|
||||||
|
array_map(
|
||||||
|
fn ($s) => $this->socialIssueRender->renderString($this->socialIssueRepository->find($s), []),
|
||||||
|
json_decode($value, true)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
return static function ($value) use ($key) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return 'export.list.acp.' . $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQueryKeys($data)
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
self::FIELDS,
|
||||||
|
$this->addressHelper->getKeys(ExportAddressHelper::F_ALL, 'address_fields')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getResult($query, $data)
|
||||||
|
{
|
||||||
|
return $query->getQuery()->getResult(AbstractQuery::HYDRATE_SCALAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle()
|
||||||
|
{
|
||||||
|
return 'export.list.acp.List of accompanying periods';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getType()
|
||||||
|
{
|
||||||
|
return Declarations::PERSON_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||||
|
{
|
||||||
|
$centers = array_map(static function ($el) {
|
||||||
|
return $el['center'];
|
||||||
|
}, $acl);
|
||||||
|
|
||||||
|
$qb = $this->entityManager->createQueryBuilder();
|
||||||
|
|
||||||
|
$qb
|
||||||
|
->from(AccompanyingPeriod::class, 'acp')
|
||||||
|
->andWhere('acp.step != :list_acp_step')
|
||||||
|
->andWhere(
|
||||||
|
$qb->expr()->exists(
|
||||||
|
'SELECT 1 FROM ' . AccompanyingPeriodParticipation::class . ' acl_count_part
|
||||||
|
JOIN ' . PersonCenterHistory::class . ' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person)
|
||||||
|
WHERE acl_count_part.accompanyingPeriod = acp.id AND acl_count_person_history.center IN (:authorized_centers)
|
||||||
|
'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
->setParameter('list_acp_step', AccompanyingPeriod::STEP_DRAFT)
|
||||||
|
->setParameter('authorized_centers', $centers);
|
||||||
|
|
||||||
|
$this->addSelectClauses($qb, $data['calc_date']);
|
||||||
|
|
||||||
|
return $qb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function requiredRole(): string
|
||||||
|
{
|
||||||
|
return PersonVoter::LISTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supportsModifiers()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Declarations::ACP_TYPE,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addSelectClauses(QueryBuilder $qb, DateTimeImmutable $calcDate): void
|
||||||
|
{
|
||||||
|
// add the regular fields
|
||||||
|
foreach (['id', 'openingDate', 'closingDate', 'confidential', 'emergency', 'intensity', 'createdAt', 'updatedAt'] as $field) {
|
||||||
|
$qb->addSelect(sprintf('acp.%s AS %s', $field, $field));
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the field which are simple association
|
||||||
|
foreach (['origin' => 'label', 'closingMotive' => 'name', 'job' => 'label', 'createdBy' => 'label', 'updatedBy' => 'label', 'administrativeLocation' => 'name'] as $entity => $field) {
|
||||||
|
$qb
|
||||||
|
->leftJoin(sprintf('acp.%s', $entity), "{$entity}_t")
|
||||||
|
->addSelect(sprintf('%s_t.%s AS %s', $entity, $field, $entity));
|
||||||
|
}
|
||||||
|
|
||||||
|
// step at date
|
||||||
|
$qb
|
||||||
|
->addSelect('stepHistory.step AS step')
|
||||||
|
->addSelect('stepHistory.startDate AS stepSince')
|
||||||
|
->leftJoin('acp.stepHistories', 'stepHistory')
|
||||||
|
->andWhere(
|
||||||
|
$qb->expr()->andX(
|
||||||
|
$qb->expr()->lte('stepHistory.startDate', ':calcDate'),
|
||||||
|
$qb->expr()->orX($qb->expr()->isNull('stepHistory.endDate'), $qb->expr()->gt('stepHistory.endDate', ':calcDate'))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// referree at date
|
||||||
|
$qb
|
||||||
|
->addSelect('referrer_t.label AS referrer')
|
||||||
|
->addSelect('userHistory.startDate AS referrerSince')
|
||||||
|
->leftJoin('acp.userHistories', 'userHistory')
|
||||||
|
->leftJoin('userHistory.user', 'referrer_t')
|
||||||
|
->andWhere(
|
||||||
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->isNull('userHistory'),
|
||||||
|
$qb->expr()->andX(
|
||||||
|
$qb->expr()->lte('userHistory.startDate', ':calcDate'),
|
||||||
|
$qb->expr()->orX($qb->expr()->isNull('userHistory.endDate'), $qb->expr()->gt('userHistory.endDate', ':calcDate'))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// location of the acp
|
||||||
|
$qb
|
||||||
|
->addSelect('CASE WHEN locationHistory.personLocation IS NOT NULL THEN 1 ELSE 0 END AS locationIsPerson')
|
||||||
|
->addSelect('CASE WHEN locationHistory.personLocation IS NOT NULL THEN 0 ELSE 1 END AS locationIsTemp')
|
||||||
|
->addSelect('IDENTITY(locationHistory.personLocation) AS locationPersonName')
|
||||||
|
->addSelect('IDENTITY(locationHistory.personLocation) AS locationPersonId')
|
||||||
|
->leftJoin('acp.locationHistories', 'locationHistory')
|
||||||
|
->andWhere(
|
||||||
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->isNull('locationHistory'),
|
||||||
|
$qb->expr()->andX(
|
||||||
|
$qb->expr()->lte('locationHistory.startDate', ':calcDate'),
|
||||||
|
$qb->expr()->orX($qb->expr()->isNull('locationHistory.endDate'), $qb->expr()->gt('locationHistory.endDate', ':calcDate'))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
->leftJoin(PersonHouseholdAddress::class, 'personAddress', Join::WITH, 'locationHistory.personLocation = personAddress.person')
|
||||||
|
->andWhere(
|
||||||
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->isNull('personAddress'),
|
||||||
|
$qb->expr()->andX(
|
||||||
|
$qb->expr()->lte('personAddress.validFrom', ':calcDate'),
|
||||||
|
$qb->expr()->orX($qb->expr()->isNull('personAddress.validTo'), $qb->expr()->gt('personAddress.validTo', ':calcDate'))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
->leftJoin(Address::class, 'acp_address', Join::WITH, 'COALESCE(IDENTITY(locationHistory.addressLocation), IDENTITY(personAddress.address)) = acp_address.id');
|
||||||
|
|
||||||
|
$this->addressHelper->addSelectClauses(ExportAddressHelper::F_ALL, $qb, 'acp_address', 'address_fields');
|
||||||
|
|
||||||
|
// requestor
|
||||||
|
$qb
|
||||||
|
->addSelect('CASE WHEN acp.requestorPerson IS NULL THEN 1 ELSE 0 END AS isRequestorPerson')
|
||||||
|
->addSelect('CASE WHEN acp.requestorPerson IS NULL THEN 0 ELSE 1 END AS isRequestorThirdParty')
|
||||||
|
->addSelect('IDENTITY(acp.requestorPerson) AS requestorPersonId')
|
||||||
|
->addSelect('IDENTITY(acp.requestorThirdParty) AS requestorThirdPartyId')
|
||||||
|
->addSelect('IDENTITY(acp.requestorPerson) AS requestorPerson')
|
||||||
|
->addSelect('IDENTITY(acp.requestorThirdParty) AS requestorThirdParty');
|
||||||
|
|
||||||
|
$qb
|
||||||
|
// scopes
|
||||||
|
->addSelect('(SELECT AGGREGATE(scope.name) FROM ' . Scope::class . ' scope WHERE scope MEMBER OF acp.scopes) AS scopes')
|
||||||
|
// social issues
|
||||||
|
->addSelect('(SELECT AGGREGATE(socialIssue.id) FROM ' . SocialIssue::class . ' socialIssue WHERE socialIssue MEMBER OF acp.socialIssues) AS socialIssues');
|
||||||
|
|
||||||
|
// add parameter
|
||||||
|
$qb->setParameter('calcDate', $calcDate);
|
||||||
|
}
|
||||||
|
}
|
@ -17,21 +17,22 @@ use Chill\CustomFieldsBundle\Service\CustomFieldProvider;
|
|||||||
use Chill\MainBundle\Export\ExportElementValidatedInterface;
|
use Chill\MainBundle\Export\ExportElementValidatedInterface;
|
||||||
use Chill\MainBundle\Export\FormatterInterface;
|
use Chill\MainBundle\Export\FormatterInterface;
|
||||||
use Chill\MainBundle\Export\GroupedExportInterface;
|
use Chill\MainBundle\Export\GroupedExportInterface;
|
||||||
|
use Chill\MainBundle\Export\Helper\ExportAddressHelper;
|
||||||
use Chill\MainBundle\Export\ListInterface;
|
use Chill\MainBundle\Export\ListInterface;
|
||||||
|
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Chill\PersonBundle\Export\Declarations;
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
|
use Chill\PersonBundle\Export\Helper\ListPersonHelper;
|
||||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||||
use DateTime;
|
use DateTimeImmutable;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\Query;
|
use Doctrine\ORM\Query;
|
||||||
use Exception;
|
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\DateType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\Validator\Constraints\Callback;
|
use Symfony\Component\Validator\Constraints\Callback;
|
||||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
|
||||||
|
|
||||||
use function addcslashes;
|
use function addcslashes;
|
||||||
use function array_key_exists;
|
use function array_key_exists;
|
||||||
@ -39,7 +40,7 @@ use function array_keys;
|
|||||||
use function array_merge;
|
use function array_merge;
|
||||||
use function count;
|
use function count;
|
||||||
use function in_array;
|
use function in_array;
|
||||||
use function strtolower;
|
use function strlen;
|
||||||
use function uniqid;
|
use function uniqid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,40 +48,35 @@ use function uniqid;
|
|||||||
*/
|
*/
|
||||||
class ListPerson implements ExportElementValidatedInterface, ListInterface, GroupedExportInterface
|
class ListPerson implements ExportElementValidatedInterface, ListInterface, GroupedExportInterface
|
||||||
{
|
{
|
||||||
protected CustomFieldProvider $customFieldProvider;
|
private ExportAddressHelper $addressHelper;
|
||||||
|
|
||||||
protected EntityManagerInterface $entityManager;
|
private CustomFieldProvider $customFieldProvider;
|
||||||
|
|
||||||
protected array $fields = [
|
private EntityManagerInterface $entityManager;
|
||||||
'id', 'firstName', 'lastName', 'birthdate',
|
|
||||||
'placeOfBirth', 'gender', 'memo', 'email', 'phonenumber',
|
|
||||||
'mobilenumber', 'contactInfo', 'countryOfBirth', 'nationality',
|
|
||||||
'address_street_address_1', 'address_street_address_2',
|
|
||||||
'address_valid_from', 'address_postcode_label', 'address_postcode_code',
|
|
||||||
'address_country_name', 'address_country_code', 'address_isnoaddress',
|
|
||||||
];
|
|
||||||
|
|
||||||
protected TranslatableStringHelper $translatableStringHelper;
|
private ListPersonHelper $listPersonHelper;
|
||||||
|
|
||||||
protected TranslatorInterface $translator;
|
|
||||||
|
|
||||||
private $slugs = [];
|
private $slugs = [];
|
||||||
|
|
||||||
|
private TranslatableStringHelper $translatableStringHelper;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
ExportAddressHelper $addressHelper,
|
||||||
|
CustomFieldProvider $customFieldProvider,
|
||||||
|
ListPersonHelper $listPersonHelper,
|
||||||
EntityManagerInterface $em,
|
EntityManagerInterface $em,
|
||||||
TranslatorInterface $translator,
|
TranslatableStringHelper $translatableStringHelper
|
||||||
TranslatableStringHelper $translatableStringHelper,
|
|
||||||
CustomFieldProvider $customFieldProvider
|
|
||||||
) {
|
) {
|
||||||
$this->entityManager = $em;
|
$this->addressHelper = $addressHelper;
|
||||||
$this->translator = $translator;
|
|
||||||
$this->translatableStringHelper = $translatableStringHelper;
|
|
||||||
$this->customFieldProvider = $customFieldProvider;
|
$this->customFieldProvider = $customFieldProvider;
|
||||||
|
$this->listPersonHelper = $listPersonHelper;
|
||||||
|
$this->entityManager = $em;
|
||||||
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
{
|
{
|
||||||
$choices = array_combine($this->fields, $this->fields);
|
$choices = array_combine(ListPersonHelper::FIELDS, ListPersonHelper::FIELDS);
|
||||||
|
|
||||||
foreach ($this->getCustomFields() as $cf) {
|
foreach ($this->getCustomFields() as $cf) {
|
||||||
$choices[$this->translatableStringHelper->localize($cf->getName())]
|
$choices[$this->translatableStringHelper->localize($cf->getName())]
|
||||||
@ -96,7 +92,7 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
|
|||||||
'label' => 'Fields to include in export',
|
'label' => 'Fields to include in export',
|
||||||
'choice_attr' => static function (string $val): array {
|
'choice_attr' => static function (string $val): array {
|
||||||
// add a 'data-display-target' for address fields
|
// add a 'data-display-target' for address fields
|
||||||
if (substr($val, 0, 8) === 'address_') {
|
if (substr($val, 0, 7) === 'address' || 'center' === $val || 'household' === $val) {
|
||||||
return ['data-display-target' => 'address_date'];
|
return ['data-display-target' => 'address_date'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,17 +107,15 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
])],
|
])],
|
||||||
|
'data' => array_values($choices),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// add a date field for addresses
|
// add a date field for addresses
|
||||||
$builder->add('address_date', DateType::class, [
|
$builder->add('address_date', ChillDateType::class, [
|
||||||
'label' => 'Address valid at this date',
|
'label' => 'Data valid at this date',
|
||||||
'data' => new DateTime(),
|
'help' => 'Data regarding center, addresses, and so on will be computed at this date',
|
||||||
'attr' => ['class' => 'datepicker'],
|
'data' => new DateTimeImmutable(),
|
||||||
'widget' => 'single_text',
|
'input' => 'datetime_immutable',
|
||||||
'format' => 'dd-MM-yyyy',
|
|
||||||
'required' => false,
|
|
||||||
'block_name' => 'list_export_form_address_date',
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,113 +136,35 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
|
|||||||
|
|
||||||
public function getLabels($key, array $values, $data)
|
public function getLabels($key, array $values, $data)
|
||||||
{
|
{
|
||||||
switch ($key) {
|
if (in_array($key, $this->listPersonHelper->getAllPossibleFields(), true)) {
|
||||||
case 'birthdate':
|
return $this->listPersonHelper->getLabels($key, $values, $data);
|
||||||
// for birthdate, we have to transform the string into a date
|
|
||||||
// to format the date correctly.
|
|
||||||
return static function ($value) {
|
|
||||||
if ('_header' === $value) {
|
|
||||||
return 'birthdate';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($value)) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
$date = DateTime::createFromFormat('Y-m-d', $value);
|
|
||||||
// check that the creation could occurs.
|
|
||||||
if (false === $date) {
|
|
||||||
throw new Exception(sprintf('The value %s could '
|
|
||||||
. 'not be converted to %s', $value, DateTime::class));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $date->format('d-m-Y');
|
|
||||||
};
|
|
||||||
|
|
||||||
case 'gender':
|
|
||||||
// for gender, we have to translate men/women statement
|
|
||||||
return function ($value) {
|
|
||||||
if ('_header' === $value) {
|
|
||||||
return 'gender';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->translator->trans($value);
|
|
||||||
};
|
|
||||||
|
|
||||||
case 'countryOfBirth':
|
|
||||||
case 'nationality':
|
|
||||||
$countryRepository = $this->entityManager
|
|
||||||
->getRepository(\Chill\MainBundle\Entity\Country::class);
|
|
||||||
|
|
||||||
// load all countries in a single query
|
|
||||||
$countryRepository->findBy(['countryCode' => $values]);
|
|
||||||
|
|
||||||
return function ($value) use ($key, $countryRepository) {
|
|
||||||
if ('_header' === $value) {
|
|
||||||
return strtolower($key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null === $value) {
|
|
||||||
return $this->translator->trans('no data');
|
|
||||||
}
|
|
||||||
|
|
||||||
$country = $countryRepository->find($value);
|
|
||||||
|
|
||||||
return $this->translatableStringHelper->localize(
|
|
||||||
$country->getName()
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
case 'address_country_name':
|
|
||||||
return function ($value) use ($key) {
|
|
||||||
if ('_header' === $value) {
|
|
||||||
return strtolower($key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null === $value) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->translatableStringHelper->localize(json_decode($value, true));
|
|
||||||
};
|
|
||||||
|
|
||||||
case 'address_isnoaddress':
|
|
||||||
return static function (?string $value): string {
|
|
||||||
if ('_header' === $value) {
|
|
||||||
return 'address.address_homeless';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null !== $value) {
|
|
||||||
return 'X';
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
};
|
|
||||||
|
|
||||||
default:
|
|
||||||
// for fields which are associated with person
|
|
||||||
if (in_array($key, $this->fields, true)) {
|
|
||||||
return static function ($value) use ($key) {
|
|
||||||
if ('_header' === $value) {
|
|
||||||
return strtolower($key);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $value;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->getLabelForCustomField($key, $values, $data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $this->getLabelForCustomField($key, $values, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getQueryKeys($data)
|
public function getQueryKeys($data)
|
||||||
{
|
{
|
||||||
$fields = [];
|
$fields = [];
|
||||||
|
|
||||||
foreach ($data['fields'] as $key) {
|
foreach (ListPersonHelper::FIELDS as $key) {
|
||||||
if (in_array($key, $this->fields, true)) {
|
if (!in_array($key, $data['fields'], true)) {
|
||||||
$fields[] = $key;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (substr($key, 0, strlen('address_fields')) === 'address_fields') {
|
||||||
|
$fields = array_merge($fields, $this->addressHelper->getKeys(ExportAddressHelper::F_ALL, 'address_fields'));
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('lifecycleUpdate' === $key) {
|
||||||
|
$fields = array_merge($fields, ['createdAt', 'createdBy', 'updatedAt', 'updatedBy']);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fields[] = $key;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the key from slugs and return
|
// add the key from slugs and return
|
||||||
@ -270,6 +186,9 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
|
|||||||
return Declarations::PERSON_TYPE;
|
return Declarations::PERSON_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* param array{fields: string[], address_date: DateTimeImmutable} $data.
|
||||||
|
*/
|
||||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||||
{
|
{
|
||||||
$centers = array_map(static function ($el) {
|
$centers = array_map(static function ($el) {
|
||||||
@ -284,40 +203,24 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
|
|||||||
|
|
||||||
$qb = $this->entityManager->createQueryBuilder();
|
$qb = $this->entityManager->createQueryBuilder();
|
||||||
|
|
||||||
foreach ($this->fields as $f) {
|
$qb
|
||||||
if (in_array($f, $data['fields'], true)) {
|
->from(Person::class, 'person')
|
||||||
switch ($f) {
|
->andWhere(
|
||||||
case 'countryOfBirth':
|
$qb->expr()->exists(
|
||||||
case 'nationality':
|
'SELECT 1 FROM ' . Person\PersonCenterHistory::class . ' pch WHERE pch.person = person.id AND pch.center IN (:authorized_centers)'
|
||||||
$qb->addSelect(sprintf('IDENTITY(person.%s) as %s', $f, $f));
|
)
|
||||||
|
)
|
||||||
|
->setParameter('authorized_centers', $centers);
|
||||||
|
|
||||||
break;
|
$fields = $data['fields'];
|
||||||
|
|
||||||
case 'address_street_address_1':
|
$this->listPersonHelper->addSelect($qb, $fields, $data['address_date']);
|
||||||
case 'address_street_address_2':
|
|
||||||
case 'address_valid_from':
|
|
||||||
case 'address_postcode_label':
|
|
||||||
case 'address_postcode_code':
|
|
||||||
case 'address_country_name':
|
|
||||||
case 'address_country_code':
|
|
||||||
case 'address_isnoaddress':
|
|
||||||
$qb->addSelect(sprintf(
|
|
||||||
'GET_PERSON_ADDRESS_%s(person.id, :address_date) AS %s',
|
|
||||||
// get the part after address_
|
|
||||||
strtoupper(substr($f, 8)),
|
|
||||||
$f
|
|
||||||
));
|
|
||||||
$qb->setParameter('address_date', $data['address_date']);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
$qb->addSelect(sprintf('person.%s as %s', $f, $f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($this->getCustomFields() as $cf) {
|
foreach ($this->getCustomFields() as $cf) {
|
||||||
|
if (!in_array($cf->getSlug(), $fields, true)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$cfType = $this->customFieldProvider->getCustomFieldByType($cf->getType());
|
$cfType = $this->customFieldProvider->getCustomFieldByType($cf->getType());
|
||||||
|
|
||||||
if ($cfType instanceof CustomFieldChoice && $cfType->isMultiple($cf)) {
|
if ($cfType instanceof CustomFieldChoice && $cfType->isMultiple($cf)) {
|
||||||
@ -345,12 +248,6 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$qb
|
|
||||||
->from('ChillPersonBundle:Person', 'person')
|
|
||||||
->join('person.center', 'center')
|
|
||||||
->andWhere('center IN (:authorized_centers)')
|
|
||||||
->setParameter('authorized_centers', $centers);
|
|
||||||
|
|
||||||
return $qb;
|
return $qb;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,14 +265,14 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
|
|||||||
{
|
{
|
||||||
// get the field starting with address_
|
// get the field starting with address_
|
||||||
$addressFields = array_filter(
|
$addressFields = array_filter(
|
||||||
$this->fields,
|
ListPersonHelper::FIELDS,
|
||||||
static fn (string $el): bool => substr($el, 0, 8) === 'address_'
|
static fn (string $el): bool => substr($el, 0, 8) === 'address_'
|
||||||
);
|
);
|
||||||
|
|
||||||
// check if there is one field starting with address in data
|
// check if there is one field starting with address in data
|
||||||
if (count(array_intersect($data['fields'], $addressFields)) > 0) {
|
if (count(array_intersect($data['fields'], $addressFields)) > 0) {
|
||||||
// if a field address is checked, the date must not be empty
|
// if a field address is checked, the date must not be empty
|
||||||
if (empty($data['address_date'])) {
|
if (!$data['address_date'] instanceof DateTimeImmutable) {
|
||||||
$context
|
$context
|
||||||
->buildViolation('You must set this date if an address is checked')
|
->buildViolation('You must set this date if an address is checked')
|
||||||
->atPath('address_date')
|
->atPath('address_date')
|
||||||
@ -456,7 +353,7 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
|
|||||||
. ' | ' . $label;
|
. ' | ' . $label;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('_other' === $slugChoice && $cfType->isChecked($cf, $choiceSlug, $decoded)) {
|
if ('_other' === $slugChoice && $cfType->isChecked($cf, $slugChoice, $decoded)) {
|
||||||
return $cfType->extractOtherValue($cf, $decoded);
|
return $cfType->extractOtherValue($cf, $decoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,220 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Export\Export;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Export\ExportElementValidatedInterface;
|
||||||
|
use Chill\MainBundle\Export\FormatterInterface;
|
||||||
|
use Chill\MainBundle\Export\GroupedExportInterface;
|
||||||
|
use Chill\MainBundle\Export\Helper\ExportAddressHelper;
|
||||||
|
use Chill\MainBundle\Export\ListInterface;
|
||||||
|
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use Chill\PersonBundle\Entity\Person\PersonCenterHistory;
|
||||||
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
|
use Chill\PersonBundle\Export\Helper\ListPersonHelper;
|
||||||
|
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||||
|
use DateTimeImmutable;
|
||||||
|
use Doctrine\ORM\AbstractQuery;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\Validator\Constraints\Callback;
|
||||||
|
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||||
|
use function array_key_exists;
|
||||||
|
use function count;
|
||||||
|
use function in_array;
|
||||||
|
use function strlen;
|
||||||
|
|
||||||
|
class ListPersonWithAccompanyingPeriod implements ExportElementValidatedInterface, ListInterface, GroupedExportInterface
|
||||||
|
{
|
||||||
|
private ExportAddressHelper $addressHelper;
|
||||||
|
|
||||||
|
private EntityManagerInterface $entityManager;
|
||||||
|
|
||||||
|
private ListPersonHelper $listPersonHelper;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
ExportAddressHelper $addressHelper,
|
||||||
|
ListPersonHelper $listPersonHelper,
|
||||||
|
EntityManagerInterface $em
|
||||||
|
) {
|
||||||
|
$this->addressHelper = $addressHelper;
|
||||||
|
$this->listPersonHelper = $listPersonHelper;
|
||||||
|
$this->entityManager = $em;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
|
{
|
||||||
|
$choices = array_combine(ListPersonHelper::FIELDS, ListPersonHelper::FIELDS);
|
||||||
|
|
||||||
|
// Add a checkbox to select fields
|
||||||
|
$builder->add('fields', ChoiceType::class, [
|
||||||
|
'multiple' => true,
|
||||||
|
'expanded' => true,
|
||||||
|
'choices' => $choices,
|
||||||
|
'label' => 'Fields to include in export',
|
||||||
|
'choice_attr' => static function (string $val): array {
|
||||||
|
// add a 'data-display-target' for address fields
|
||||||
|
if (substr($val, 0, 7) === 'address' || 'center' === $val || 'household' === $val) {
|
||||||
|
return ['data-display-target' => 'address_date'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
'constraints' => [new Callback([
|
||||||
|
'callback' => static function ($selected, ExecutionContextInterface $context) {
|
||||||
|
if (count($selected) === 0) {
|
||||||
|
$context->buildViolation('You must select at least one element')
|
||||||
|
->atPath('fields')
|
||||||
|
->addViolation();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
])],
|
||||||
|
'data' => array_values($choices),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// add a date field for addresses
|
||||||
|
$builder->add('address_date', ChillDateType::class, [
|
||||||
|
'label' => 'Data valid at this date',
|
||||||
|
'help' => 'Data regarding center, addresses, and so on will be computed at this date',
|
||||||
|
'data' => new DateTimeImmutable(),
|
||||||
|
'input' => 'datetime_immutable',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAllowedFormattersTypes()
|
||||||
|
{
|
||||||
|
return [FormatterInterface::TYPE_LIST];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescription()
|
||||||
|
{
|
||||||
|
return 'export.list.person_with_acp.Create a list of people having an accompaying periods, according to various filters.';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getGroup(): string
|
||||||
|
{
|
||||||
|
return 'Exports of persons';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLabels($key, array $values, $data)
|
||||||
|
{
|
||||||
|
return $this->listPersonHelper->getLabels($key, $values, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQueryKeys($data)
|
||||||
|
{
|
||||||
|
$fields = [];
|
||||||
|
|
||||||
|
foreach (ListPersonHelper::FIELDS as $key) {
|
||||||
|
if (!in_array($key, $data['fields'], true)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (substr($key, 0, strlen('address_fields')) === 'address_fields') {
|
||||||
|
$fields = array_merge($fields, $this->addressHelper->getKeys(ExportAddressHelper::F_ALL, 'address_fields'));
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('lifecycleUpdate' === $key) {
|
||||||
|
$fields = array_merge($fields, ['createdAt', 'createdBy', 'updatedAt', 'updatedBy']);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fields[] = $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getResult($query, $data)
|
||||||
|
{
|
||||||
|
return $query->getQuery()->getResult(AbstractQuery::HYDRATE_SCALAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle()
|
||||||
|
{
|
||||||
|
return 'export.list.person_with_acp.List peoples having an accompanying period';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getType()
|
||||||
|
{
|
||||||
|
return Declarations::PERSON_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* param array{fields: string[], address_date: DateTimeImmutable} $data.
|
||||||
|
*/
|
||||||
|
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||||
|
{
|
||||||
|
$centers = array_map(static function ($el) {
|
||||||
|
return $el['center'];
|
||||||
|
}, $acl);
|
||||||
|
|
||||||
|
// throw an error if any fields are present
|
||||||
|
if (!array_key_exists('fields', $data)) {
|
||||||
|
throw new \Doctrine\DBAL\Exception\InvalidArgumentException('any fields '
|
||||||
|
. 'have been checked');
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb = $this->entityManager->createQueryBuilder();
|
||||||
|
|
||||||
|
$qb->from(Person::class, 'person')
|
||||||
|
->join('person.accompanyingPeriodParticipations', 'acppart')
|
||||||
|
->join('acppart.accompanyingPeriod', 'acp')
|
||||||
|
->andWhere($qb->expr()->neq('acp.step', "'" . AccompanyingPeriod::STEP_DRAFT . "'"))
|
||||||
|
->andWhere(
|
||||||
|
$qb->expr()->exists(
|
||||||
|
'SELECT 1 FROM ' . PersonCenterHistory::class . ' pch WHERE pch.person = person.id AND pch.center IN (:authorized_centers)'
|
||||||
|
)
|
||||||
|
)->setParameter('authorized_centers', $centers);
|
||||||
|
|
||||||
|
$fields = $data['fields'];
|
||||||
|
|
||||||
|
$this->listPersonHelper->addSelect($qb, $fields, $data['address_date']);
|
||||||
|
|
||||||
|
return $qb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function requiredRole(): string
|
||||||
|
{
|
||||||
|
return PersonVoter::LISTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supportsModifiers()
|
||||||
|
{
|
||||||
|
return [Declarations::PERSON_TYPE, Declarations::PERSON_IMPLIED_IN, Declarations::ACP_TYPE];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validateForm($data, ExecutionContextInterface $context)
|
||||||
|
{
|
||||||
|
// get the field starting with address_
|
||||||
|
$addressFields = array_filter(
|
||||||
|
ListPersonHelper::FIELDS,
|
||||||
|
static fn (string $el): bool => substr($el, 0, 8) === 'address_'
|
||||||
|
);
|
||||||
|
|
||||||
|
// check if there is one field starting with address in data
|
||||||
|
if (count(array_intersect($data['fields'], $addressFields)) > 0) {
|
||||||
|
// if a field address is checked, the date must not be empty
|
||||||
|
if (!$data['address_date'] instanceof DateTimeImmutable) {
|
||||||
|
$context
|
||||||
|
->buildViolation('You must set this date if an address is checked')
|
||||||
|
->atPath('address_date')
|
||||||
|
->addViolation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,6 @@ declare(strict_types=1);
|
|||||||
namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
|
namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
|
||||||
|
|
||||||
use Chill\MainBundle\Export\FilterInterface;
|
use Chill\MainBundle\Export\FilterInterface;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
|
||||||
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
||||||
use Chill\PersonBundle\Export\Declarations;
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
use Chill\PersonBundle\Form\Type\PickSocialIssueType;
|
use Chill\PersonBundle\Form\Type\PickSocialIssueType;
|
||||||
@ -31,15 +30,11 @@ class SocialIssueFilter implements FilterInterface
|
|||||||
|
|
||||||
private SocialIssueRender $socialIssueRender;
|
private SocialIssueRender $socialIssueRender;
|
||||||
|
|
||||||
private TranslatableStringHelper $translatableStringHelper;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
TranslatorInterface $translator,
|
TranslatorInterface $translator,
|
||||||
TranslatableStringHelper $translatableStringHelper,
|
|
||||||
SocialIssueRender $socialIssueRender
|
SocialIssueRender $socialIssueRender
|
||||||
) {
|
) {
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
$this->translatableStringHelper = $translatableStringHelper;
|
|
||||||
$this->socialIssueRender = $socialIssueRender;
|
$this->socialIssueRender = $socialIssueRender;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +54,7 @@ class SocialIssueFilter implements FilterInterface
|
|||||||
$qb->andWhere($clause)
|
$qb->andWhere($clause)
|
||||||
->setParameter(
|
->setParameter(
|
||||||
'socialissues',
|
'socialissues',
|
||||||
SocialIssue::getDescendantsWithThisForIssues($data['accepted_socialissues'])
|
SocialIssue::getDescendantsWithThisForIssues($data['accepted_socialissues']->toArray())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
441
src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php
Normal file
441
src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php
Normal file
@ -0,0 +1,441 @@
|
|||||||
|
<?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\Helper;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Export\Helper\ExportAddressHelper;
|
||||||
|
use Chill\MainBundle\Repository\CenterRepositoryInterface;
|
||||||
|
use Chill\MainBundle\Repository\CivilityRepositoryInterface;
|
||||||
|
use Chill\MainBundle\Repository\CountryRepository;
|
||||||
|
use Chill\MainBundle\Repository\LanguageRepositoryInterface;
|
||||||
|
use Chill\MainBundle\Repository\UserRepositoryInterface;
|
||||||
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use Chill\PersonBundle\Repository\MaritalStatusRepositoryInterface;
|
||||||
|
use DateTime;
|
||||||
|
use DateTimeImmutable;
|
||||||
|
use Doctrine\ORM\Query;
|
||||||
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use Exception;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||||
|
use RuntimeException;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
use function in_array;
|
||||||
|
use function strlen;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for list person: provide:.
|
||||||
|
*
|
||||||
|
* * the labels;
|
||||||
|
* * add select statement in query
|
||||||
|
*
|
||||||
|
* for some fields
|
||||||
|
*/
|
||||||
|
class ListPersonHelper
|
||||||
|
{
|
||||||
|
public const FIELDS = [
|
||||||
|
'id',
|
||||||
|
'civility',
|
||||||
|
'firstName',
|
||||||
|
'lastName',
|
||||||
|
'birthdate',
|
||||||
|
'center',
|
||||||
|
'deathdate',
|
||||||
|
'placeOfBirth',
|
||||||
|
'gender',
|
||||||
|
'genderComment',
|
||||||
|
'maritalStatus',
|
||||||
|
'maritalStatusComment',
|
||||||
|
'maritalStatusDate',
|
||||||
|
'memo',
|
||||||
|
'email',
|
||||||
|
'phonenumber',
|
||||||
|
'mobilenumber',
|
||||||
|
'numberOfChildren',
|
||||||
|
'contactInfo',
|
||||||
|
'countryOfBirth',
|
||||||
|
'nationality',
|
||||||
|
// add full addresses
|
||||||
|
'address_fields',
|
||||||
|
// add a list of spoken languages
|
||||||
|
'spokenLanguages',
|
||||||
|
// add household id
|
||||||
|
'household_id',
|
||||||
|
// add created at, created by, updated at, and updated by
|
||||||
|
'lifecycleUpdate',
|
||||||
|
];
|
||||||
|
|
||||||
|
private ExportAddressHelper $addressHelper;
|
||||||
|
|
||||||
|
private CenterRepositoryInterface $centerRepository;
|
||||||
|
|
||||||
|
private CivilityRepositoryInterface $civilityRepository;
|
||||||
|
|
||||||
|
private CountryRepository $countryRepository;
|
||||||
|
|
||||||
|
private LanguageRepositoryInterface $languageRepository;
|
||||||
|
|
||||||
|
private MaritalStatusRepositoryInterface $maritalStatusRepository;
|
||||||
|
|
||||||
|
private TranslatableStringHelper $translatableStringHelper;
|
||||||
|
|
||||||
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
|
private UserRepositoryInterface $userRepository;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
ExportAddressHelper $addressHelper,
|
||||||
|
CenterRepositoryInterface $centerRepository,
|
||||||
|
CivilityRepositoryInterface $civilityRepository,
|
||||||
|
CountryRepository $countryRepository,
|
||||||
|
LanguageRepositoryInterface $languageRepository,
|
||||||
|
MaritalStatusRepositoryInterface $maritalStatusRepository,
|
||||||
|
TranslatableStringHelper $translatableStringHelper,
|
||||||
|
TranslatorInterface $translator,
|
||||||
|
UserRepositoryInterface $userRepository
|
||||||
|
) {
|
||||||
|
$this->addressHelper = $addressHelper;
|
||||||
|
$this->centerRepository = $centerRepository;
|
||||||
|
$this->civilityRepository = $civilityRepository;
|
||||||
|
$this->countryRepository = $countryRepository;
|
||||||
|
$this->languageRepository = $languageRepository;
|
||||||
|
$this->maritalStatusRepository = $maritalStatusRepository;
|
||||||
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
|
$this->translator = $translator;
|
||||||
|
$this->userRepository = $userRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array|value-of<self::FIELDS>[] $fields
|
||||||
|
*/
|
||||||
|
public function addSelect(QueryBuilder $qb, array $fields, DateTimeImmutable $computedDate): void
|
||||||
|
{
|
||||||
|
foreach (ListPersonHelper::FIELDS as $f) {
|
||||||
|
if (!in_array($f, $fields, true)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($f) {
|
||||||
|
case 'countryOfBirth':
|
||||||
|
case 'nationality':
|
||||||
|
$qb->addSelect(sprintf('IDENTITY(person.%s) as %s', $f, $f));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'address_fields':
|
||||||
|
$this->addCurrentAddressAt($qb, $computedDate);
|
||||||
|
$qb->leftJoin('personHouseholdAddress.address', 'personAddress');
|
||||||
|
$this->addressHelper->addSelectClauses(ExportAddressHelper::F_ALL, $qb, 'personAddress', 'address_fields');
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'spokenLanguages':
|
||||||
|
$qb
|
||||||
|
->leftJoin('person.spokenLanguages', 'spokenLanguage')
|
||||||
|
->addSelect('AGGREGATE(spokenLanguage.id) AS spokenLanguages')
|
||||||
|
->addGroupBy('person');
|
||||||
|
|
||||||
|
if (in_array('center', $fields, true)) {
|
||||||
|
$qb->addGroupBy('center');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array('address_fields', $fields, true)) {
|
||||||
|
$qb
|
||||||
|
->addGroupBy('address_fieldsid')
|
||||||
|
->addGroupBy('address_fieldscountry_t.id')
|
||||||
|
->addGroupBy('address_fieldspostcode_t.id');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array('household_id', $fields, true)) {
|
||||||
|
$qb->addGroupBy('household_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'household_id':
|
||||||
|
$qb
|
||||||
|
->addSelect('IDENTITY(personHouseholdAddress.household) AS household_id');
|
||||||
|
|
||||||
|
$this->addCurrentAddressAt($qb, $computedDate);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'center':
|
||||||
|
$qb
|
||||||
|
->addSelect('IDENTITY(centerHistory.center) AS center')
|
||||||
|
->leftJoin('person.centerHistory', 'centerHistory')
|
||||||
|
->andWhere(
|
||||||
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->isNull('centerHistory'),
|
||||||
|
$qb->expr()->andX(
|
||||||
|
$qb->expr()->lte('centerHistory.startDate', ':address_date'),
|
||||||
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->isNull('centerHistory.endDate'),
|
||||||
|
$qb->expr()->gte('centerHistory.endDate', ':address_date')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
->setParameter('address_date', $computedDate);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'lifecycleUpdate':
|
||||||
|
$qb
|
||||||
|
->addSelect('person.createdAt AS createdAt')
|
||||||
|
->addSelect('IDENTITY(person.createdBy) AS createdBy')
|
||||||
|
->addSelect('person.updatedAt AS updatedAt')
|
||||||
|
->addSelect('IDENTITY(person.updatedBy) AS updatedBy');
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'genderComment':
|
||||||
|
$qb->addSelect('person.genderComment.comment AS genderComment');
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'maritalStatus':
|
||||||
|
$qb->addSelect('IDENTITY(person.maritalStatus) AS maritalStatus');
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'maritalStatusComment':
|
||||||
|
$qb->addSelect('person.maritalStatusComment.comment AS maritalStatusComment');
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'civility':
|
||||||
|
$qb->addSelect('IDENTITY(person.civility) AS civility');
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
$qb->addSelect(sprintf('person.%s as %s', $f, $f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|string[]
|
||||||
|
*/
|
||||||
|
public function getAllPossibleFields(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
self::FIELDS,
|
||||||
|
['createdAt', 'createdBy', 'updatedAt', 'updatedBy'],
|
||||||
|
$this->addressHelper->getKeys(ExportAddressHelper::F_ALL, 'address_fields')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLabels($key, array $values, $data): callable
|
||||||
|
{
|
||||||
|
if (substr($key, 0, strlen('address_fields')) === 'address_fields') {
|
||||||
|
return $this->addressHelper->getLabel($key, $values, $data, 'address_fields');
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($key) {
|
||||||
|
case 'center':
|
||||||
|
return function ($value) use ($key) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return $this->translator->trans($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value || null === $center = $this->centerRepository->find($value)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $center->getName();
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'birthdate':
|
||||||
|
case 'deathdate':
|
||||||
|
case 'maritalStatusDate':
|
||||||
|
case 'createdAt':
|
||||||
|
case 'updatedAt':
|
||||||
|
// for birthdate, we have to transform the string into a date
|
||||||
|
// to format the date correctly.
|
||||||
|
return function ($value) use ($key) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return $this->translator->trans($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// warning: won't work with DateTimeImmutable as we reset time a few lines later
|
||||||
|
$date = DateTime::createFromFormat('Y-m-d', $value);
|
||||||
|
$hasTime = false;
|
||||||
|
|
||||||
|
if (false === $date) {
|
||||||
|
$date = DateTime::createFromFormat('Y-m-d H:i:s', $value);
|
||||||
|
$hasTime = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that the creation could occurs.
|
||||||
|
if (false === $date) {
|
||||||
|
throw new Exception(sprintf('The value %s could '
|
||||||
|
. 'not be converted to %s', $value, DateTime::class));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$hasTime) {
|
||||||
|
$date->setTime(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $date;
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'createdBy':
|
||||||
|
case 'updatedBy':
|
||||||
|
return function ($value) use ($key) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return $this->translator->trans($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->userRepository->find($value)->getLabel();
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'civility':
|
||||||
|
return function ($value) use ($key) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return $this->translator->trans($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$civility = $this->civilityRepository->find($value);
|
||||||
|
|
||||||
|
if (null === $civility) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->translatableStringHelper->localize($civility->getName());
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'gender':
|
||||||
|
// for gender, we have to translate men/women statement
|
||||||
|
return function ($value) use ($key) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return $this->translator->trans($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->translator->trans($value);
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'maritalStatus':
|
||||||
|
return function ($value) use ($key) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return $this->translator->trans($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$maritalStatus = $this->maritalStatusRepository->find($value);
|
||||||
|
|
||||||
|
return $this->translatableStringHelper->localize($maritalStatus->getName());
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'spokenLanguages':
|
||||||
|
return function ($value) use ($key) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return $this->translator->trans($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$ids = json_decode($value);
|
||||||
|
|
||||||
|
return
|
||||||
|
implode(
|
||||||
|
'|',
|
||||||
|
array_map(function ($id) {
|
||||||
|
if (null === $id) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$lang = $this->languageRepository->find($id);
|
||||||
|
|
||||||
|
if (null === $lang) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->translatableStringHelper->localize($lang->getName());
|
||||||
|
}, $ids)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'countryOfBirth':
|
||||||
|
case 'nationality':
|
||||||
|
return function ($value) use ($key) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return $this->translator->trans($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$country = $this->countryRepository->find($value);
|
||||||
|
|
||||||
|
return $this->translatableStringHelper->localize(
|
||||||
|
$country->getName()
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (!in_array($key, self::getAllPossibleFields(), true)) {
|
||||||
|
throw new RuntimeException("this key is not supported by this helper: {$key}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// for fields which are associated with person
|
||||||
|
return function ($value) use ($key) {
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return $this->translator->trans($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addCurrentAddressAt(QueryBuilder $qb, DateTimeImmutable $date): void
|
||||||
|
{
|
||||||
|
if (!(in_array('personHouseholdAddress', $qb->getAllAliases(), true))) {
|
||||||
|
$qb
|
||||||
|
->leftJoin('person.householdAddresses', 'personHouseholdAddress')
|
||||||
|
->andWhere(
|
||||||
|
$qb->expr()->orX(
|
||||||
|
// no address at this time
|
||||||
|
$qb->expr()->isNull('personHouseholdAddress'),
|
||||||
|
// there is one address...
|
||||||
|
$qb->expr()->andX(
|
||||||
|
$qb->expr()->lte('personHouseholdAddress.validFrom', ':address_date'),
|
||||||
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->isNull('personHouseholdAddress.validTo'),
|
||||||
|
$qb->expr()->gt('personHouseholdAddress.validTo', ':address_date')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
->setParameter('address_date', $date);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -14,9 +14,8 @@ namespace Chill\PersonBundle\Repository;
|
|||||||
use Chill\PersonBundle\Entity\MaritalStatus;
|
use Chill\PersonBundle\Entity\MaritalStatus;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
use Doctrine\Persistence\ObjectRepository;
|
|
||||||
|
|
||||||
class MaritalStatusRepository implements ObjectRepository
|
class MaritalStatusRepository implements MaritalStatusRepositoryInterface
|
||||||
{
|
{
|
||||||
private EntityRepository $repository;
|
private EntityRepository $repository;
|
||||||
|
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
<?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\Repository;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Entity\MaritalStatus;
|
||||||
|
|
||||||
|
interface MaritalStatusRepositoryInterface
|
||||||
|
{
|
||||||
|
public function find($id): ?MaritalStatus;
|
||||||
|
|
||||||
|
public function findAll(): array;
|
||||||
|
|
||||||
|
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array;
|
||||||
|
|
||||||
|
public function findOneBy(array $criteria): ?MaritalStatus;
|
||||||
|
|
||||||
|
public function getClassName(): string;
|
||||||
|
}
|
@ -15,13 +15,24 @@ services:
|
|||||||
tags:
|
tags:
|
||||||
- { name: chill.export, alias: count_person_with_accompanying_course }
|
- { name: chill.export, alias: count_person_with_accompanying_course }
|
||||||
|
|
||||||
chill.person.export.list_person:
|
Chill\PersonBundle\Export\Export\ListPerson:
|
||||||
class: Chill\PersonBundle\Export\Export\ListPerson
|
|
||||||
autowire: true
|
autowire: true
|
||||||
autoconfigure: true
|
autoconfigure: true
|
||||||
tags:
|
tags:
|
||||||
- { name: chill.export, alias: list_person }
|
- { name: chill.export, alias: list_person }
|
||||||
|
|
||||||
|
Chill\PersonBundle\Export\Export\ListPersonWithAccompanyingPeriod:
|
||||||
|
autowire: true
|
||||||
|
autoconfigure: true
|
||||||
|
tags:
|
||||||
|
- { name: chill.export, alias: list_person_with_acp }
|
||||||
|
|
||||||
|
Chill\PersonBundle\Export\Export\ListAccompanyingPeriod:
|
||||||
|
autowire: true
|
||||||
|
autoconfigure: true
|
||||||
|
tags:
|
||||||
|
- { name: chill.export, alias: list_acp }
|
||||||
|
|
||||||
chill.person.export.list_person.duplicate:
|
chill.person.export.list_person.duplicate:
|
||||||
class: Chill\PersonBundle\Export\Export\ListPersonDuplicate
|
class: Chill\PersonBundle\Export\Export\ListPersonDuplicate
|
||||||
arguments:
|
arguments:
|
||||||
|
@ -89,6 +89,16 @@ Any person selected: Aucune personne sélectionnée
|
|||||||
Create a household and add an address: Ajouter une adresse pour une personne non suivie et seule dans un ménage
|
Create a household and add an address: Ajouter une adresse pour une personne non suivie et seule dans un ménage
|
||||||
A new household will be created. The person will be member of this household.: Un nouveau ménage va être créé. La personne sera membre de ce ménage.
|
A new household will be created. The person will be member of this household.: Un nouveau ménage va être créé. La personne sera membre de ce ménage.
|
||||||
Comment on the gender: Commentaire sur le genre
|
Comment on the gender: Commentaire sur le genre
|
||||||
|
genderComment: Commentaire sur le genre
|
||||||
|
maritalStatus: État civil
|
||||||
|
maritalStatusComment: Commentaire sur l'état civil
|
||||||
|
maritalStatusDate: Date de l'état civil
|
||||||
|
memo: Commentaire
|
||||||
|
numberOfChildren: Nombre d'enfants
|
||||||
|
contactInfo: Commentaire des contacts
|
||||||
|
spokenLanguages: Langues parlées
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# dédoublonnage
|
# dédoublonnage
|
||||||
Old person: Doublon
|
Old person: Doublon
|
||||||
@ -339,6 +349,8 @@ List peoples: Liste des personnes
|
|||||||
Create a list of people according to various filters.: Crée une liste des personnes selon différents filtres.
|
Create a list of people according to various filters.: Crée une liste des personnes selon différents filtres.
|
||||||
Fields to include in export: Champs à inclure dans l'export
|
Fields to include in export: Champs à inclure dans l'export
|
||||||
Address valid at this date: Addresse valide à cette date
|
Address valid at this date: Addresse valide à cette date
|
||||||
|
Data valid at this date: Données valides à cette date
|
||||||
|
Data regarding center, addresses, and so on will be computed at this date: Les données concernant le centre, l'adresse, le ménage, sera calculé à cette date.
|
||||||
List duplicates: Liste des doublons
|
List duplicates: Liste des doublons
|
||||||
Create a list of duplicate people: Créer la liste des personnes détectées comme doublons.
|
Create a list of duplicate people: Créer la liste des personnes détectées comme doublons.
|
||||||
Count people participating in an accompanying course: Nombre de personnes concernées par un parcours
|
Count people participating in an accompanying course: Nombre de personnes concernées par un parcours
|
||||||
@ -748,6 +760,7 @@ socialAction:
|
|||||||
defaultNotificationDelay: Délai de notification par défaut
|
defaultNotificationDelay: Délai de notification par défaut
|
||||||
socialIssue: Problématique sociale
|
socialIssue: Problématique sociale
|
||||||
|
|
||||||
|
household_id: Identifiant du ménage
|
||||||
household:
|
household:
|
||||||
allowHolder: Peut être titulaire
|
allowHolder: Peut être titulaire
|
||||||
shareHousehold: Membre du ménage
|
shareHousehold: Membre du ménage
|
||||||
@ -1006,6 +1019,49 @@ export:
|
|||||||
Computation date for referrer: Date à laquelle le référent était actif
|
Computation date for referrer: Date à laquelle le référent était actif
|
||||||
by_referrer:
|
by_referrer:
|
||||||
Computation date for referrer: Date à laquelle le référent était actif
|
Computation date for referrer: Date à laquelle le référent était actif
|
||||||
|
list:
|
||||||
|
person_with_acp:
|
||||||
|
List peoples having an accompanying period: Liste des personnes ayant un parcours d'accompagnement
|
||||||
|
Create a list of people having an accompaying periods, according to various filters.: Génère une liste des personnes ayant un parcours d'accompagnement, selon différents critères liés au parcours ou à l'usager
|
||||||
|
acp:
|
||||||
|
List of accompanying periods: Liste de périodes d'accompagnements
|
||||||
|
Generate a list of accompanying periods, filtered on different parameters.: Génère une liste des périodes d'accompagnement, filtrée sur différents paramètres.
|
||||||
|
Date of calculation for associated elements: Date de calcul des éléments associés
|
||||||
|
The associated referree, localisation, and other elements will be valid at this date: Les éléments associés, comme la localisation, le référent et d'autres éléments seront valides à cette date
|
||||||
|
id: Identifiant du parcours
|
||||||
|
openingDate: Date d'ouverture du parcours
|
||||||
|
closingDate: Date de fermeture du parcours
|
||||||
|
confidential: Confidentiel
|
||||||
|
emergency: Urgent
|
||||||
|
intensity: Intensité
|
||||||
|
createdAt: Créé le
|
||||||
|
updatedAt: Dernière mise à jour le
|
||||||
|
acpOrigin: Origine du parcours
|
||||||
|
acpClosingMotive: Motif de fermeture
|
||||||
|
acpJob: Métier du parcours
|
||||||
|
createdBy: Créé par
|
||||||
|
updatedBy: Dernière modification par
|
||||||
|
administrativeLocation: Location administrative
|
||||||
|
step: Etape
|
||||||
|
stepSince: Dernière modification de l'étape
|
||||||
|
referrer: Référent
|
||||||
|
referrerSince: Référent depuis le
|
||||||
|
locationIsPerson: Parcours localisé auprès d'un usager concerné
|
||||||
|
locationIsTemp: Parcours avec une localisation temporaire
|
||||||
|
acpLocationPersonName: Usager auprès duquel le parcours est localisé
|
||||||
|
locationPersonId: Identifiant de l'usager auprès duquel le parcours est localisé
|
||||||
|
acpaddress_fieldscountry: Pays de l'adresse
|
||||||
|
isRequestorPerson: Le demandeur est-il un usager ?
|
||||||
|
isRequestorThirdParty: Le demandeur est-il un tiers ?
|
||||||
|
requestorPersonId: Identifiant du demandeur personne
|
||||||
|
requestorThirdPartyId: Identifiant du tiers
|
||||||
|
acprequestorPerson: Nom du demandeur personne
|
||||||
|
acprequestorThirdPaty: Nom du demandeur tiers
|
||||||
|
scopes: Services
|
||||||
|
socialIssues: Problématiques sociales
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
social_action:
|
social_action:
|
||||||
and children: et dérivés
|
and children: et dérivés
|
||||||
|
Loading…
x
Reference in New Issue
Block a user