mirror of
				https://gitlab.com/Chill-Projet/chill-bundles.git
				synced 2025-11-03 18:58:24 +00:00 
			
		
		
		
	Merge remote-tracking branch 'origin/master' into change_interlocuteurs_display
This commit is contained in:
		@@ -77,6 +77,7 @@ and this project adheres to
 | 
			
		||||
* [parcours] Create document buttons made sticky (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/532)
 | 
			
		||||
* [person] Trailing guillemet removed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/530)
 | 
			
		||||
* [notification] Display of social action within workflow notification set to display block (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/537)
 | 
			
		||||
* [onthefly] trim trailing whitespace in email of person and thirdparty (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/542)
 | 
			
		||||
* [parcours] Display of interlocuteurs changed to flex-table in parcours edit page to prevent cut-off of information (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/535)
 | 
			
		||||
 | 
			
		||||
## Test releases
 | 
			
		||||
 
 | 
			
		||||
@@ -460,8 +460,3 @@ parameters:
 | 
			
		||||
			count: 1
 | 
			
		||||
			path: src/Bundle/ChillThirdPartyBundle/Search/ThirdPartySearch.php
 | 
			
		||||
 | 
			
		||||
		-
 | 
			
		||||
			message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
 | 
			
		||||
			count: 1
 | 
			
		||||
			path: src/Bundle/ChillThirdPartyBundle/Templating/Entity/ThirdPartyRender.php
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@ use function count;
 | 
			
		||||
/**
 | 
			
		||||
 * Helps to find a summary of the budget: the sum of resources and charges.
 | 
			
		||||
 */
 | 
			
		||||
class SummaryBudget
 | 
			
		||||
class SummaryBudget implements SummaryBudgetInterface
 | 
			
		||||
{
 | 
			
		||||
    private const QUERY_CHARGE_BY_HOUSEHOLD = 'select SUM(amount) AS sum, type FROM chill_budget.charge WHERE (person_id IN (_ids_) OR household_id = ?) AND NOW() BETWEEN startdate AND COALESCE(enddate, \'infinity\'::timestamp) GROUP BY type';
 | 
			
		||||
 | 
			
		||||
@@ -52,26 +52,6 @@ class SummaryBudget
 | 
			
		||||
        $this->translatableStringHelper = $translatableStringHelper;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getEmptyChargeArray(): array
 | 
			
		||||
    {
 | 
			
		||||
        $keys = $this->configRepository->getChargesKeys();
 | 
			
		||||
        $labels = $this->chargeLabels;
 | 
			
		||||
 | 
			
		||||
        return array_combine($keys, array_map(function ($i) use ($labels) {
 | 
			
		||||
            return ['sum' => 0.0, 'label' => $this->translatableStringHelper->localize($labels[$i])];
 | 
			
		||||
        }, $keys));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getEmptyResourceArray(): array
 | 
			
		||||
    {
 | 
			
		||||
        $keys = $this->configRepository->getResourcesKeys();
 | 
			
		||||
        $labels = $this->resourcesLabels;
 | 
			
		||||
 | 
			
		||||
        return array_combine($keys, array_map(function ($i) use ($labels) {
 | 
			
		||||
            return ['sum' => 0.0, 'label' => $this->translatableStringHelper->localize($labels[$i])];
 | 
			
		||||
        }, $keys));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getSummaryForHousehold(?Household $household): array
 | 
			
		||||
    {
 | 
			
		||||
        if (null === $household) {
 | 
			
		||||
@@ -101,8 +81,15 @@ class SummaryBudget
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getSummaryForPerson(Person $person): array
 | 
			
		||||
    public function getSummaryForPerson(?Person $person): array
 | 
			
		||||
    {
 | 
			
		||||
        if (null === $person) {
 | 
			
		||||
            return [
 | 
			
		||||
                'resources' => $this->getEmptyResourceArray(),
 | 
			
		||||
                'charges' => $this->getEmptyChargeArray(),
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $rsm = $this->buildRsm();
 | 
			
		||||
 | 
			
		||||
        $resources = $this->em->createNativeQuery(self::QUERY_RESOURCE_BY_PERSON, $rsm)
 | 
			
		||||
@@ -128,6 +115,26 @@ class SummaryBudget
 | 
			
		||||
        return $rsm;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function getEmptyChargeArray(): array
 | 
			
		||||
    {
 | 
			
		||||
        $keys = $this->configRepository->getChargesKeys();
 | 
			
		||||
        $labels = $this->chargeLabels;
 | 
			
		||||
 | 
			
		||||
        return array_combine($keys, array_map(function ($i) use ($labels) {
 | 
			
		||||
            return ['sum' => 0.0, 'label' => $this->translatableStringHelper->localize($labels[$i])];
 | 
			
		||||
        }, $keys));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function getEmptyResourceArray(): array
 | 
			
		||||
    {
 | 
			
		||||
        $keys = $this->configRepository->getResourcesKeys();
 | 
			
		||||
        $labels = $this->resourcesLabels;
 | 
			
		||||
 | 
			
		||||
        return array_combine($keys, array_map(function ($i) use ($labels) {
 | 
			
		||||
            return ['sum' => 0.0, 'label' => $this->translatableStringHelper->localize($labels[$i])];
 | 
			
		||||
        }, $keys));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function rowToArray(array $rows, string $kind): array
 | 
			
		||||
    {
 | 
			
		||||
        switch ($kind) {
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,25 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Chill\BudgetBundle\Service\Summary;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\Household\Household;
 | 
			
		||||
use Chill\PersonBundle\Entity\Person;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Helps to find a summary of the budget: the sum of resources and charges.
 | 
			
		||||
 */
 | 
			
		||||
interface SummaryBudgetInterface
 | 
			
		||||
{
 | 
			
		||||
    public function getSummaryForHousehold(?Household $household): array;
 | 
			
		||||
 | 
			
		||||
    public function getSummaryForPerson(?Person $person): array;
 | 
			
		||||
}
 | 
			
		||||
@@ -33,11 +33,11 @@ class ApiController extends AbstractCRUDController
 | 
			
		||||
     * Base method for handling api action.
 | 
			
		||||
     *
 | 
			
		||||
     * @param mixed $id
 | 
			
		||||
     * @param mixed $_format
 | 
			
		||||
     * @param string $_format
 | 
			
		||||
     *
 | 
			
		||||
     * @return void
 | 
			
		||||
     */
 | 
			
		||||
    public function entityApi(Request $request, $id, $_format): Response
 | 
			
		||||
    public function entityApi(Request $request, $id, ?string $_format = 'json'): Response
 | 
			
		||||
    {
 | 
			
		||||
        switch ($request->getMethod()) {
 | 
			
		||||
            case Request::METHOD_GET:
 | 
			
		||||
 
 | 
			
		||||
@@ -45,7 +45,7 @@ class SearchUserApiProvider implements SearchApiInterface
 | 
			
		||||
        $query
 | 
			
		||||
            ->setSelectKey('user')
 | 
			
		||||
            ->setSelectJsonbMetadata("jsonb_build_object('id', u.id)")
 | 
			
		||||
            ->setSelectPertinence('GREATEST(SIMILARITY(LOWER(UNACCENT(?)), u.label),
 | 
			
		||||
            ->setSelectPertinence('3 + GREATEST(SIMILARITY(LOWER(UNACCENT(?)), u.label),
 | 
			
		||||
                SIMILARITY(LOWER(UNACCENT(?)), u.usernamecanonical))', [$pattern, $pattern])
 | 
			
		||||
            ->setFromClause('users AS u')
 | 
			
		||||
            ->setWhereClauses('
 | 
			
		||||
 
 | 
			
		||||
@@ -44,13 +44,21 @@ class DateNormalizer implements ContextAwareNormalizerInterface, DenormalizerInt
 | 
			
		||||
 | 
			
		||||
        switch ($type) {
 | 
			
		||||
            case DateTime::class:
 | 
			
		||||
                return DateTime::createFromFormat(DateTimeInterface::ISO8601, $data['datetime']);
 | 
			
		||||
                $result = DateTime::createFromFormat(DateTimeInterface::ISO8601, $data['datetime']);
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case DateTimeInterface::class:
 | 
			
		||||
            case DateTimeImmutable::class:
 | 
			
		||||
                return DateTimeImmutable::createFromFormat(DateTimeInterface::ISO8601, $data['datetime']);
 | 
			
		||||
                $result = DateTimeImmutable::createFromFormat(DateTimeInterface::ISO8601, $data['datetime']);
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (false === $result) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $result;
 | 
			
		||||
 | 
			
		||||
        throw new UnexpectedValueException();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,7 @@ class PhonenumberNormalizer implements ContextAwareNormalizerInterface, Denormal
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param mixed $data
 | 
			
		||||
     * @param string|null $data
 | 
			
		||||
     * @param mixed $type
 | 
			
		||||
     * @param null|mixed $format
 | 
			
		||||
     *
 | 
			
		||||
@@ -40,7 +40,7 @@ class PhonenumberNormalizer implements ContextAwareNormalizerInterface, Denormal
 | 
			
		||||
     */
 | 
			
		||||
    public function denormalize($data, $type, $format = null, array $context = [])
 | 
			
		||||
    {
 | 
			
		||||
        if ('' === trim($data)) {
 | 
			
		||||
        if ('' === trim((string) $data)) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -514,6 +514,8 @@ class Household
 | 
			
		||||
 | 
			
		||||
            if ($iterator->valid()) {
 | 
			
		||||
                $current->setValidTo($iterator->current()->getValidFrom());
 | 
			
		||||
            } else {
 | 
			
		||||
                $current->setValidTo(null);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -276,25 +276,21 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
 | 
			
		||||
    /**
 | 
			
		||||
     * The person's first name.
 | 
			
		||||
     *
 | 
			
		||||
     * @var string
 | 
			
		||||
     *
 | 
			
		||||
     * @ORM\Column(type="string", length=255)
 | 
			
		||||
     * @Assert\NotBlank(message="The firstname cannot be empty")
 | 
			
		||||
     * @Assert\Length(
 | 
			
		||||
     *     max=255,
 | 
			
		||||
     * )
 | 
			
		||||
     */
 | 
			
		||||
    private $firstName;
 | 
			
		||||
    private string $firstName = '';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * fullname canonical. Read-only field, which is calculated by
 | 
			
		||||
     * the database.
 | 
			
		||||
     *
 | 
			
		||||
     * @var string
 | 
			
		||||
     *
 | 
			
		||||
     * @ORM\Column(type="text", nullable=true)
 | 
			
		||||
     */
 | 
			
		||||
    private $fullnameCanonical;
 | 
			
		||||
    private string $fullnameCanonical = '';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The person's gender.
 | 
			
		||||
@@ -328,6 +324,8 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
 | 
			
		||||
     *     targetEntity=HouseholdMember::class,
 | 
			
		||||
     *     mappedBy="person"
 | 
			
		||||
     * )
 | 
			
		||||
     *
 | 
			
		||||
     * @var Collection|HouseholdMember[]
 | 
			
		||||
     */
 | 
			
		||||
    private Collection $householdParticipations;
 | 
			
		||||
 | 
			
		||||
@@ -343,15 +341,13 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
 | 
			
		||||
    /**
 | 
			
		||||
     * The person's last name.
 | 
			
		||||
     *
 | 
			
		||||
     * @var string
 | 
			
		||||
     *
 | 
			
		||||
     * @ORM\Column(type="string", length=255)
 | 
			
		||||
     * @Assert\NotBlank(message="The lastname cannot be empty")
 | 
			
		||||
     * @Assert\Length(
 | 
			
		||||
     *     max=255,
 | 
			
		||||
     * )
 | 
			
		||||
     */
 | 
			
		||||
    private $lastName;
 | 
			
		||||
    private string $lastName = '';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The marital status of the person.
 | 
			
		||||
@@ -1117,6 +1113,9 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
 | 
			
		||||
        return $this->householdAddresses;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return Collection|HouseholdMember[]
 | 
			
		||||
     */
 | 
			
		||||
    public function getHouseholdParticipations(): Collection
 | 
			
		||||
    {
 | 
			
		||||
        return $this->householdParticipations;
 | 
			
		||||
@@ -1126,6 +1125,8 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
 | 
			
		||||
     * Get participation where the person does not share the household.
 | 
			
		||||
     *
 | 
			
		||||
     * Order by startDate, desc
 | 
			
		||||
     *
 | 
			
		||||
     * @return HouseholdMember[]
 | 
			
		||||
     */
 | 
			
		||||
    public function getHouseholdParticipationsNotShareHousehold(): Collection
 | 
			
		||||
    {
 | 
			
		||||
@@ -1146,6 +1147,8 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
 | 
			
		||||
     * Get participation where the person does share the household.
 | 
			
		||||
     *
 | 
			
		||||
     * Order by startDate, desc
 | 
			
		||||
     *
 | 
			
		||||
     * @return Collection|HouseholdMember[]
 | 
			
		||||
     */
 | 
			
		||||
    public function getHouseholdParticipationsShareHousehold(): Collection
 | 
			
		||||
    {
 | 
			
		||||
@@ -1565,18 +1568,14 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
 | 
			
		||||
 | 
			
		||||
    public function setEmail(?string $email): self
 | 
			
		||||
    {
 | 
			
		||||
        if (null === $email) {
 | 
			
		||||
            $email = '';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->email = $email;
 | 
			
		||||
        $this->email = trim((string) $email);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function setFirstName(string $firstName): self
 | 
			
		||||
    public function setFirstName(?string $firstName): self
 | 
			
		||||
    {
 | 
			
		||||
        $this->firstName = $firstName;
 | 
			
		||||
        $this->firstName = (string) $firstName;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
@@ -1602,9 +1601,9 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function setLastName(string $lastName): self
 | 
			
		||||
    public function setLastName(?string $lastName): self
 | 
			
		||||
    {
 | 
			
		||||
        $this->lastName = $lastName;
 | 
			
		||||
        $this->lastName = (string) $lastName;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -29,8 +29,12 @@ use Symfony\Contracts\Translation\TranslatorInterface;
 | 
			
		||||
 | 
			
		||||
final class PersonResourceType extends AbstractType
 | 
			
		||||
{
 | 
			
		||||
    private PersonRenderInterface $personRender;
 | 
			
		||||
 | 
			
		||||
    private ResourceKindRender $resourceKindRender;
 | 
			
		||||
 | 
			
		||||
    private ThirdPartyRender $thirdPartyRender;
 | 
			
		||||
 | 
			
		||||
    private TranslatorInterface $translator;
 | 
			
		||||
 | 
			
		||||
    public function __construct(ResourceKindRender $resourceKindRender, PersonRenderInterface $personRender, ThirdPartyRender $thirdPartyRender, TranslatorInterface $translator)
 | 
			
		||||
 
 | 
			
		||||
@@ -61,8 +61,6 @@ class MembersEditor
 | 
			
		||||
            throw new LogicException('You must define a household first');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $event = new PersonAddressMoveEvent($person);
 | 
			
		||||
 | 
			
		||||
        $membership = (new HouseholdMember())
 | 
			
		||||
            ->setStartDate($date)
 | 
			
		||||
            ->setPerson($person)
 | 
			
		||||
@@ -70,9 +68,15 @@ class MembersEditor
 | 
			
		||||
            ->setHolder($holder)
 | 
			
		||||
            ->setComment($comment);
 | 
			
		||||
        $this->household->addMember($membership);
 | 
			
		||||
        $event->setNextMembership($membership);
 | 
			
		||||
 | 
			
		||||
        if ($position->getShareHousehold()) {
 | 
			
		||||
            // launch event only if moving to a "share household" position,
 | 
			
		||||
            // and if the destination household is different than the previous one
 | 
			
		||||
            $event = new PersonAddressMoveEvent($person);
 | 
			
		||||
            $event->setNextMembership($membership);
 | 
			
		||||
 | 
			
		||||
            $counter = 0;
 | 
			
		||||
 | 
			
		||||
            foreach ($person->getHouseholdParticipationsShareHousehold() as $participation) {
 | 
			
		||||
                if ($participation === $membership) {
 | 
			
		||||
                    continue;
 | 
			
		||||
@@ -82,14 +86,25 @@ class MembersEditor
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                ++$counter;
 | 
			
		||||
 | 
			
		||||
                if ($participation->getEndDate() === null || $participation->getEndDate() > $date) {
 | 
			
		||||
                    $event->setPreviousMembership($participation);
 | 
			
		||||
                    $participation->setEndDate($date);
 | 
			
		||||
                    $this->membershipsAffected[] = $participation;
 | 
			
		||||
                    $this->oldMembershipsHashes[] = spl_object_hash($participation);
 | 
			
		||||
 | 
			
		||||
                    if ($participation->getHousehold() !== $this->household) {
 | 
			
		||||
                        $event->setPreviousMembership($participation);
 | 
			
		||||
                        $this->events[] = $event;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // send also the event if there was no participation before
 | 
			
		||||
            if (0 === $counter) {
 | 
			
		||||
                $this->events[] = $event;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            foreach ($person->getHouseholdParticipationsNotShareHousehold() as $participation) {
 | 
			
		||||
                if ($participation->getHousehold() === $this->household
 | 
			
		||||
                    && $participation->getEndDate() === null || $participation->getEndDate() > $membership->getStartDate()
 | 
			
		||||
@@ -98,11 +113,30 @@ class MembersEditor
 | 
			
		||||
                    $participation->setEndDate($membership->getStartDate());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            // if a members is moved to the same household than the one he belongs to,
 | 
			
		||||
            // we should make it leave the household
 | 
			
		||||
            if ($person->getCurrentHousehold($date) === $this->household) {
 | 
			
		||||
                $this->leaveMovement($date, $person);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // if there are multiple belongings not sharing household, close the others
 | 
			
		||||
            foreach ($person->getHouseholdParticipationsNotShareHousehold() as $participation) {
 | 
			
		||||
                if ($participation === $membership) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if ($participation->getHousehold() === $this->household
 | 
			
		||||
                    && ($participation->getEndDate() === null || $participation->getEndDate() > $membership->getStartDate())
 | 
			
		||||
                    && $participation->getStartDate() <= $membership->getStartDate()
 | 
			
		||||
                ) {
 | 
			
		||||
                    $participation->setEndDate($membership->getStartDate());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->membershipsAffected[] = $membership;
 | 
			
		||||
        $this->persistables[] = $membership;
 | 
			
		||||
        $this->events[] = $event;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -88,7 +88,7 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface
 | 
			
		||||
            ->setExtras([
 | 
			
		||||
                'order' => 99999,
 | 
			
		||||
            ]);
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
        $menu->addChild($this->translator->trans('Person duplicate'), [
 | 
			
		||||
            'route' => 'chill_person_duplicate_view',
 | 
			
		||||
            'routeParameters' => [
 | 
			
		||||
@@ -98,7 +98,7 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface
 | 
			
		||||
            ->setExtras([
 | 
			
		||||
                'order' => 99999,
 | 
			
		||||
            ]);
 | 
			
		||||
 | 
			
		||||
         */
 | 
			
		||||
        if (
 | 
			
		||||
            'visible' === $this->showAccompanyingPeriod
 | 
			
		||||
            && $this->security->isGranted(AccompanyingPeriodVoter::SEE, $parameters['person'])
 | 
			
		||||
 
 | 
			
		||||
@@ -133,8 +133,8 @@ final class PersonACLAwareRepository implements PersonACLAwareRepositoryInterfac
 | 
			
		||||
 | 
			
		||||
        $pertinence = [];
 | 
			
		||||
        $pertinenceArgs = [];
 | 
			
		||||
        $orWhereSearchClause = [];
 | 
			
		||||
        $orWhereSearchClauseArgs = [];
 | 
			
		||||
        $andWhereSearchClause = [];
 | 
			
		||||
        $andWhereSearchClauseArgs = [];
 | 
			
		||||
 | 
			
		||||
        if ('' !== $default) {
 | 
			
		||||
            foreach (explode(' ', $default) as $str) {
 | 
			
		||||
@@ -145,15 +145,15 @@ final class PersonACLAwareRepository implements PersonACLAwareRepositoryInterfac
 | 
			
		||||
                    '(starts_with(LOWER(UNACCENT(lastname)), UNACCENT(LOWER(?))))::int';
 | 
			
		||||
                array_push($pertinenceArgs, $str, $str, $str, $str);
 | 
			
		||||
 | 
			
		||||
                $orWhereSearchClause[] =
 | 
			
		||||
                $andWhereSearchClause[] =
 | 
			
		||||
                    '(LOWER(UNACCENT(?)) <<% person.fullnamecanonical OR ' .
 | 
			
		||||
                    "person.fullnamecanonical LIKE '%' || LOWER(UNACCENT(?)) || '%' )";
 | 
			
		||||
                array_push($orWhereSearchClauseArgs, $str, $str);
 | 
			
		||||
                array_push($andWhereSearchClauseArgs, $str, $str);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $query->andWhereClause(
 | 
			
		||||
                implode(' OR ', $orWhereSearchClause),
 | 
			
		||||
                $orWhereSearchClauseArgs
 | 
			
		||||
                implode(' AND ', $andWhereSearchClause),
 | 
			
		||||
                $andWhereSearchClauseArgs
 | 
			
		||||
            );
 | 
			
		||||
        } else {
 | 
			
		||||
            $pertinence = ['1'];
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Serializer\Normalizer;
 | 
			
		||||
 | 
			
		||||
use Chill\BudgetBundle\Service\Summary\SummaryBudget;
 | 
			
		||||
use Chill\BudgetBundle\Service\Summary\SummaryBudgetInterface;
 | 
			
		||||
use Chill\DocGeneratorBundle\Serializer\Helper\NormalizeNullValueHelper;
 | 
			
		||||
use Chill\MainBundle\Entity\Address;
 | 
			
		||||
use Chill\MainBundle\Entity\Civility;
 | 
			
		||||
@@ -45,7 +45,7 @@ class PersonDocGenNormalizer implements
 | 
			
		||||
 | 
			
		||||
    private RelationshipRepository $relationshipRepository;
 | 
			
		||||
 | 
			
		||||
    private SummaryBudget $summaryBudget;
 | 
			
		||||
    private SummaryBudgetInterface $summaryBudget;
 | 
			
		||||
 | 
			
		||||
    private TranslatableStringHelper $translatableStringHelper;
 | 
			
		||||
 | 
			
		||||
@@ -56,7 +56,7 @@ class PersonDocGenNormalizer implements
 | 
			
		||||
        RelationshipRepository $relationshipRepository,
 | 
			
		||||
        TranslatorInterface $translator,
 | 
			
		||||
        TranslatableStringHelper $translatableStringHelper,
 | 
			
		||||
        SummaryBudget $summaryBudget
 | 
			
		||||
        SummaryBudgetInterface $summaryBudget
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->personRender = $personRender;
 | 
			
		||||
        $this->relationshipRepository = $relationshipRepository;
 | 
			
		||||
@@ -214,6 +214,14 @@ class PersonDocGenNormalizer implements
 | 
			
		||||
            $data['relations'] = [];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($context['docgen:person:with-budget'] ?? false) {
 | 
			
		||||
            $data['budget']['person'] = $this->summaryBudget->getSummaryForPerson(null);
 | 
			
		||||
 | 
			
		||||
            if ($context['docgen:person:with-household'] ?? false) {
 | 
			
		||||
                $data['budget']['household'] = $this->summaryBudget->getSummaryForHousehold(null);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $data;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -208,8 +208,8 @@ class PersonJsonNormalizer implements DenormalizerAwareInterface, NormalizerAwar
 | 
			
		||||
            'birthdate' => $this->normalizer->normalize($person->getBirthdate(), $format, $context),
 | 
			
		||||
            'deathdate' => $this->normalizer->normalize($person->getDeathdate(), $format, $context),
 | 
			
		||||
            'age' => $this->normalizer->normalize($person->getAge(), $format, $context),
 | 
			
		||||
            'phonenumber' => $this->normalizer->normalize($person->getPhonenumber()),
 | 
			
		||||
            'mobilenumber' => $this->normalizer->normalize($person->getMobilenumber()),
 | 
			
		||||
            'phonenumber' => $this->normalizer->normalize($person->getPhonenumber(), $format, $context),
 | 
			
		||||
            'mobilenumber' => $this->normalizer->normalize($person->getMobilenumber(), $format, $context),
 | 
			
		||||
            'email' => $person->getEmail(),
 | 
			
		||||
            'gender' => $person->getGender(),
 | 
			
		||||
        ];
 | 
			
		||||
 
 | 
			
		||||
@@ -65,7 +65,7 @@ final class HouseholdApiControllerTest extends WebTestCase
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $reference = $em->createQueryBuilder()->select('ar')->from(AddressReference::class, 'ar')
 | 
			
		||||
            ->setFirstResult(random_int(0, $nbReference))
 | 
			
		||||
            ->setFirstResult(random_int(0, $nbReference - 1))
 | 
			
		||||
            ->setMaxResults(1)
 | 
			
		||||
            ->getQuery()->getSingleResult();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -75,6 +75,7 @@ final class HouseholdTest extends TestCase
 | 
			
		||||
 | 
			
		||||
        $lastAddress = new Address();
 | 
			
		||||
        $lastAddress->setValidFrom($yesterday = new DateTime('yesterday'));
 | 
			
		||||
        $lastAddress->setValidTo(new DateTime('tomorrow'));
 | 
			
		||||
        $household->addAddress($lastAddress);
 | 
			
		||||
 | 
			
		||||
        $this->assertNull($lastAddress->getValidTo());
 | 
			
		||||
@@ -82,6 +83,7 @@ final class HouseholdTest extends TestCase
 | 
			
		||||
 | 
			
		||||
        $previousAddress = new Address();
 | 
			
		||||
        $previousAddress->setValidFrom($oneMonthAgo = new DateTime('1 month ago'));
 | 
			
		||||
        $previousAddress->setValidTo(new DateTime('now'));
 | 
			
		||||
        $household->addAddress($previousAddress);
 | 
			
		||||
 | 
			
		||||
        $addresses = $household->getAddressesOrdered();
 | 
			
		||||
@@ -95,6 +97,7 @@ final class HouseholdTest extends TestCase
 | 
			
		||||
 | 
			
		||||
        $futureAddress = new Address();
 | 
			
		||||
        $futureAddress->setValidFrom($tomorrow = new DateTime('tomorrow'));
 | 
			
		||||
        $futureAddress->setValidTo(new DateTime('2150-01-01'));
 | 
			
		||||
        $household->addAddress($futureAddress);
 | 
			
		||||
 | 
			
		||||
        $addresses = $household->getAddressesOrdered();
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ declare(strict_types=1);
 | 
			
		||||
namespace Chill\PersonBundle\Tests\Household;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\Household\Household;
 | 
			
		||||
use Chill\PersonBundle\Entity\Household\HouseholdMember;
 | 
			
		||||
use Chill\PersonBundle\Entity\Household\Position;
 | 
			
		||||
use Chill\PersonBundle\Entity\Person;
 | 
			
		||||
use Chill\PersonBundle\Event\Person\PersonAddressMoveEvent;
 | 
			
		||||
@@ -39,6 +40,122 @@ final class MembersEditorTest extends TestCase
 | 
			
		||||
        $this->factory = $this->buildMembersEditorFactory();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testAddingParticipationNotSharingHouseholdCloseTheOldOnes()
 | 
			
		||||
    {
 | 
			
		||||
        $person = new Person();
 | 
			
		||||
        $position = (new Position())->setShareHousehold(false);
 | 
			
		||||
        $household = new Household();
 | 
			
		||||
 | 
			
		||||
        // set a first time the person in position
 | 
			
		||||
        $factory = $this->buildMembersEditorFactory();
 | 
			
		||||
        $editor = $factory->createEditor($household);
 | 
			
		||||
 | 
			
		||||
        $editor->addMovement($aMonthAgo = new DateTimeImmutable('1 month ago'), $person, $position);
 | 
			
		||||
 | 
			
		||||
        // set a second time the person in position
 | 
			
		||||
        $factory = $this->buildMembersEditorFactory();
 | 
			
		||||
        $editor = $factory->createEditor($household);
 | 
			
		||||
 | 
			
		||||
        $editor->addMovement($yesterday = new DateTimeImmutable('yesterday'), $person, $position);
 | 
			
		||||
 | 
			
		||||
        $this->assertCount(2, $person->getHouseholdParticipationsNotShareHousehold());
 | 
			
		||||
 | 
			
		||||
        $startDates = [];
 | 
			
		||||
        $endDates = [];
 | 
			
		||||
 | 
			
		||||
        foreach ($person->getHouseholdParticipationsNotShareHousehold() as $participation) {
 | 
			
		||||
            $startDates[] = $participation->getStartDate();
 | 
			
		||||
            $endDates[] = $participation->getEndDate();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->assertContains($aMonthAgo, $startDates);
 | 
			
		||||
        $this->assertContains($yesterday, $startDates);
 | 
			
		||||
        $this->assertContains($yesterday, $endDates);
 | 
			
		||||
        $this->assertContains(null, $endDates);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * We test here a move for a person:.
 | 
			
		||||
     *
 | 
			
		||||
     * * which was in a position "sharing household"
 | 
			
		||||
     * * which move to the another household, in a position "not sharing household"
 | 
			
		||||
     *
 | 
			
		||||
     * The person should stays in the two households
 | 
			
		||||
     */
 | 
			
		||||
    public function testMoveFromSharingHouseholdToNotSharingHousehouldInDifferentHousehold()
 | 
			
		||||
    {
 | 
			
		||||
        $person = new Person();
 | 
			
		||||
        $household = new Household();
 | 
			
		||||
        $positionSharing = (new Position())->setShareHousehold(true);
 | 
			
		||||
        $positionNotSharing = (new Position())->setShareHousehold(false);
 | 
			
		||||
        $factory = $this->buildMembersEditorFactory();
 | 
			
		||||
        $editor = $factory->createEditor($household);
 | 
			
		||||
 | 
			
		||||
        // we add the member to the household
 | 
			
		||||
        $editor->addMovement(new DateTimeImmutable('1 month ago'), $person, $positionSharing);
 | 
			
		||||
 | 
			
		||||
        // double check that the person is in the household
 | 
			
		||||
        $this->assertContains($person, $household->getCurrentPersons());
 | 
			
		||||
 | 
			
		||||
        // we do the move to the position not sharing household
 | 
			
		||||
        $editor = $factory->createEditor($household2 = new Household());
 | 
			
		||||
        $editor->addMovement(new DateTimeImmutable('yesterday'), $person, $positionNotSharing);
 | 
			
		||||
 | 
			
		||||
        $sharings = $household->getCurrentMembers()->filter(static function (HouseholdMember $m) {
 | 
			
		||||
            return $m->getShareHousehold();
 | 
			
		||||
        });
 | 
			
		||||
        $notSharing = $household2->getCurrentMembers()->filter(static function (HouseholdMember $m) {
 | 
			
		||||
            return !$m->getShareHousehold();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $this->assertCount(1, $notSharing);
 | 
			
		||||
        $this->assertCount(1, $sharings);
 | 
			
		||||
 | 
			
		||||
        $getPerson = static function (HouseholdMember $m) { return $m->getPerson(); };
 | 
			
		||||
 | 
			
		||||
        $this->assertContains($person, $notSharing->map($getPerson));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * We test here a move for a person:.
 | 
			
		||||
     *
 | 
			
		||||
     * * which was in a position "sharing household"
 | 
			
		||||
     * * which move to the same household, in a position "not sharing household"
 | 
			
		||||
     */
 | 
			
		||||
    public function testMoveFromSharingHouseholdToNotSharingHousehouldInSamehousehold()
 | 
			
		||||
    {
 | 
			
		||||
        $person = new Person();
 | 
			
		||||
        $household = new Household();
 | 
			
		||||
        $positionSharing = (new Position())->setShareHousehold(true);
 | 
			
		||||
        $positionNotSharing = (new Position())->setShareHousehold(false);
 | 
			
		||||
        $factory = $this->buildMembersEditorFactory();
 | 
			
		||||
        $editor = $factory->createEditor($household);
 | 
			
		||||
 | 
			
		||||
        // we add the member to the household
 | 
			
		||||
        $editor->addMovement(new DateTimeImmutable('1 month ago'), $person, $positionSharing);
 | 
			
		||||
 | 
			
		||||
        // double check that the person is in the household
 | 
			
		||||
        $this->assertContains($person, $household->getCurrentPersons());
 | 
			
		||||
 | 
			
		||||
        // we do the move to the position not sharing household
 | 
			
		||||
        $editor = $factory->createEditor($household);
 | 
			
		||||
        $editor->addMovement(new DateTimeImmutable('yesterday'), $person, $positionNotSharing);
 | 
			
		||||
 | 
			
		||||
        $sharings = $household->getCurrentMembers()->filter(static function (HouseholdMember $m) {
 | 
			
		||||
            return $m->getShareHousehold();
 | 
			
		||||
        });
 | 
			
		||||
        $notSharing = $household->getCurrentMembers()->filter(static function (HouseholdMember $m) {
 | 
			
		||||
            return !$m->getShareHousehold();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $this->assertCount(1, $notSharing);
 | 
			
		||||
        $this->assertCount(0, $sharings);
 | 
			
		||||
 | 
			
		||||
        $getPerson = static function (HouseholdMember $m) { return $m->getPerson(); };
 | 
			
		||||
 | 
			
		||||
        $this->assertContains($person, $notSharing->map($getPerson));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testMovePersonWithoutSharedHousehold()
 | 
			
		||||
    {
 | 
			
		||||
        $person = new Person();
 | 
			
		||||
@@ -126,7 +243,7 @@ final class MembersEditorTest extends TestCase
 | 
			
		||||
        $this->assertEquals($date, $membership1->getEndDate());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testPostMove()
 | 
			
		||||
    public function testPostMoveToAPositionNotSharingHousehold()
 | 
			
		||||
    {
 | 
			
		||||
        $person = new Person();
 | 
			
		||||
        $position = (new Position())
 | 
			
		||||
@@ -134,6 +251,86 @@ final class MembersEditorTest extends TestCase
 | 
			
		||||
        $household1 = new Household();
 | 
			
		||||
        $household2 = new Household();
 | 
			
		||||
        $eventDispatcher = $this->prophesize(EventDispatcherInterface::class);
 | 
			
		||||
        $eventDispatcher
 | 
			
		||||
            ->dispatch(Argument::type(PersonAddressMoveEvent::class))
 | 
			
		||||
            ->shouldNotBeCalled();
 | 
			
		||||
        $factory = $this->buildMembersEditorFactory(
 | 
			
		||||
            $eventDispatcher->reveal(),
 | 
			
		||||
            null
 | 
			
		||||
        );
 | 
			
		||||
        $editor = $factory->createEditor($household1);
 | 
			
		||||
 | 
			
		||||
        $editor->addMovement(new DateTimeImmutable('now'), $person, $position);
 | 
			
		||||
 | 
			
		||||
        $editor->postMove();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testPostMoveToAPositionSharingHouseholdAndSameHousehold()
 | 
			
		||||
    {
 | 
			
		||||
        $person = new Person();
 | 
			
		||||
        $position = (new Position())
 | 
			
		||||
            ->setShareHousehold(true);
 | 
			
		||||
        $position2 = (new Position())
 | 
			
		||||
            ->setShareHousehold(true);
 | 
			
		||||
        $household1 = new Household();
 | 
			
		||||
 | 
			
		||||
        // set into the first household
 | 
			
		||||
        $editor = $this->buildMembersEditorFactory()
 | 
			
		||||
            ->createEditor($household1);
 | 
			
		||||
        $editor->addMovement(new DateTimeImmutable('1 year ago'), $person, $position);
 | 
			
		||||
 | 
			
		||||
        // prepare for next move
 | 
			
		||||
        $eventDispatcher = $this->prophesize(EventDispatcherInterface::class);
 | 
			
		||||
        $eventDispatcher
 | 
			
		||||
            ->dispatch(Argument::type(PersonAddressMoveEvent::class))
 | 
			
		||||
            ->shouldNotBeCalled();
 | 
			
		||||
        $factory = $this->buildMembersEditorFactory(
 | 
			
		||||
            $eventDispatcher->reveal(),
 | 
			
		||||
            null
 | 
			
		||||
        );
 | 
			
		||||
        $editor = $factory->createEditor($household1);
 | 
			
		||||
 | 
			
		||||
        $editor->addMovement(new DateTimeImmutable('now'), $person, $position2);
 | 
			
		||||
 | 
			
		||||
        $editor->postMove();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testPostMoveToAPositionSharingHouseholdFromDifferentHousehold()
 | 
			
		||||
    {
 | 
			
		||||
        $person = new Person();
 | 
			
		||||
        $position = (new Position())
 | 
			
		||||
            ->setShareHousehold(true);
 | 
			
		||||
        $household1 = new Household();
 | 
			
		||||
        $household2 = new Household();
 | 
			
		||||
 | 
			
		||||
        // set into the first household
 | 
			
		||||
        $editor = $this->buildMembersEditorFactory()
 | 
			
		||||
            ->createEditor($household1);
 | 
			
		||||
        $editor->addMovement(new DateTimeImmutable('1 year ago'), $person, $position);
 | 
			
		||||
 | 
			
		||||
        // perform now the movement
 | 
			
		||||
        $eventDispatcher = $this->prophesize(EventDispatcherInterface::class);
 | 
			
		||||
        $eventDispatcher
 | 
			
		||||
            ->dispatch(Argument::type(PersonAddressMoveEvent::class))
 | 
			
		||||
            ->shouldBeCalled();
 | 
			
		||||
        $factory = $this->buildMembersEditorFactory(
 | 
			
		||||
            $eventDispatcher->reveal(),
 | 
			
		||||
            null
 | 
			
		||||
        );
 | 
			
		||||
        $editor = $factory->createEditor($household2);
 | 
			
		||||
 | 
			
		||||
        $editor->addMovement(new DateTimeImmutable('now'), $person, $position);
 | 
			
		||||
 | 
			
		||||
        $editor->postMove();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testPostMoveToAPositionSharingHouseholdFromNoHousehold()
 | 
			
		||||
    {
 | 
			
		||||
        $person = new Person();
 | 
			
		||||
        $position = (new Position())
 | 
			
		||||
            ->setShareHousehold(true);
 | 
			
		||||
        $household1 = new Household();
 | 
			
		||||
        $eventDispatcher = $this->prophesize(EventDispatcherInterface::class);
 | 
			
		||||
        $eventDispatcher
 | 
			
		||||
            ->dispatch(Argument::type(PersonAddressMoveEvent::class))
 | 
			
		||||
            ->shouldBeCalled();
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Serializer\Normalizer;
 | 
			
		||||
 | 
			
		||||
use Chill\BudgetBundle\Service\Summary\SummaryBudgetInterface;
 | 
			
		||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
 | 
			
		||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
 | 
			
		||||
use Chill\PersonBundle\Entity\Household\Household;
 | 
			
		||||
@@ -72,6 +73,17 @@ final class PersonDocGenNormalizerTest extends KernelTestCase
 | 
			
		||||
        $this->normalizer = self::$container->get(NormalizerInterface::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function dataGeneratorNormalizationNullOrNotNullHaveSameKeys(): iterable
 | 
			
		||||
    {
 | 
			
		||||
        yield [['docgen:expects' => Person::class, 'groups' => ['docgen:read']]];
 | 
			
		||||
 | 
			
		||||
        yield [['docgen:expects' => Person::class, 'groups' => ['docgen:read'], 'docgen:person:with-household' => true]];
 | 
			
		||||
 | 
			
		||||
        yield [['docgen:expects' => Person::class, 'groups' => ['docgen:read'], 'docgen:person:with-relations' => true]];
 | 
			
		||||
 | 
			
		||||
        yield [['docgen:expects' => Person::class, 'groups' => ['docgen:read'], 'docgen:person:with-budget' => true]];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function generateData()
 | 
			
		||||
    {
 | 
			
		||||
        $person = new Person();
 | 
			
		||||
@@ -90,12 +102,16 @@ final class PersonDocGenNormalizerTest extends KernelTestCase
 | 
			
		||||
        yield [null, self::BLANK, 'normalization for a null person'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testNormalizationNullOrNotNullHaveSameKeys()
 | 
			
		||||
    /**
 | 
			
		||||
     * @dataProvider dataGeneratorNormalizationNullOrNotNullHaveSameKeys
 | 
			
		||||
     *
 | 
			
		||||
     * @param mixed $context
 | 
			
		||||
     */
 | 
			
		||||
    public function testNormalizationNullOrNotNullHaveSameKeys($context)
 | 
			
		||||
    {
 | 
			
		||||
        $this->markTestSkipped();
 | 
			
		||||
        $period = new Person();
 | 
			
		||||
        $notNullData = $this->buildPersonNormalizer()->normalize($period, 'docgen', ['docgen:expects' => Person::class]);
 | 
			
		||||
        $nullData = $this->buildPersonNormalizer()->normalize(null, 'docgen', ['docgen:expects' => Person::class]);
 | 
			
		||||
        $notNullData = $this->buildPersonNormalizer()->normalize($period, 'docgen', $context);
 | 
			
		||||
        $nullData = $this->buildPersonNormalizer()->normalize(null, 'docgen', $context);
 | 
			
		||||
 | 
			
		||||
        $this->assertEqualsCanonicalizing(
 | 
			
		||||
            array_keys($notNullData),
 | 
			
		||||
@@ -131,7 +147,6 @@ final class PersonDocGenNormalizerTest extends KernelTestCase
 | 
			
		||||
 | 
			
		||||
    public function testNormalizePersonWithHousehold()
 | 
			
		||||
    {
 | 
			
		||||
        $this->markTestSkipped();
 | 
			
		||||
        $household = new Household();
 | 
			
		||||
        $person = new Person();
 | 
			
		||||
        $person
 | 
			
		||||
@@ -172,7 +187,6 @@ final class PersonDocGenNormalizerTest extends KernelTestCase
 | 
			
		||||
 | 
			
		||||
    public function testNormalizePersonWithRelationships()
 | 
			
		||||
    {
 | 
			
		||||
        $this->markTestSkipped();
 | 
			
		||||
        $person = (new Person())->setFirstName('Renaud')->setLastName('megane');
 | 
			
		||||
        $father = (new Person())->setFirstName('Clément')->setLastName('megane');
 | 
			
		||||
        $mother = (new Person())->setFirstName('Mireille')->setLastName('Mathieu');
 | 
			
		||||
@@ -235,13 +249,25 @@ final class PersonDocGenNormalizerTest extends KernelTestCase
 | 
			
		||||
        ?RelationshipRepository $relationshipRepository = null,
 | 
			
		||||
        ?TranslatorInterface $translator = null,
 | 
			
		||||
        ?TranslatableStringHelper $translatableStringHelper = null,
 | 
			
		||||
        ?NormalizerInterface $normalizer = null
 | 
			
		||||
        ?NormalizerInterface $normalizer = null,
 | 
			
		||||
        ?SummaryBudgetInterface $summaryBudget = null
 | 
			
		||||
    ): PersonDocGenNormalizer {
 | 
			
		||||
        if (null === $summaryBudget) {
 | 
			
		||||
            $summaryBudget = $this->prophesize(SummaryBudgetInterface::class);
 | 
			
		||||
            $summaryBudget->getSummaryForHousehold(Argument::any())->willReturn(
 | 
			
		||||
                ['resources' => [], 'charges' => []]
 | 
			
		||||
            );
 | 
			
		||||
            $summaryBudget->getSummaryForPerson(Argument::any())->willReturn(
 | 
			
		||||
                ['resources' => [], 'charges' => []]
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $personDocGenNormalizer = new PersonDocGenNormalizer(
 | 
			
		||||
            $personRender ?? self::$container->get(PersonRender::class),
 | 
			
		||||
            $relationshipRepository ?? self::$container->get(RelationshipRepository::class),
 | 
			
		||||
            $translator ?? self::$container->get(TranslatorInterface::class),
 | 
			
		||||
            $translatableStringHelper ?? self::$container->get(TranslatableStringHelperInterface::class)
 | 
			
		||||
            $translatableStringHelper ?? self::$container->get(TranslatableStringHelperInterface::class),
 | 
			
		||||
            $summaryBudget->reveal(),
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        if (null === $normalizer) {
 | 
			
		||||
@@ -259,13 +285,31 @@ final class PersonDocGenNormalizerTest extends KernelTestCase
 | 
			
		||||
        ?PersonRender $personRender = null,
 | 
			
		||||
        ?RelationshipRepository $relationshipRepository = null,
 | 
			
		||||
        ?TranslatorInterface $translator = null,
 | 
			
		||||
        ?TranslatableStringHelper $translatableStringHelper = null
 | 
			
		||||
        ?TranslatableStringHelper $translatableStringHelper = null,
 | 
			
		||||
        ?SummaryBudgetInterface $summaryBudget = null
 | 
			
		||||
    ): PersonDocGenNormalizer {
 | 
			
		||||
        if (null === $relationshipRepository) {
 | 
			
		||||
            $relationshipRepository = $this->prophesize(RelationshipRepository::class);
 | 
			
		||||
            $relationshipRepository->findByPerson(Argument::type(Person::class))->willReturn([]);
 | 
			
		||||
            $relationshipRepository = $relationshipRepository->reveal();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (null === $summaryBudget) {
 | 
			
		||||
            $summaryBudget = $this->prophesize(SummaryBudgetInterface::class);
 | 
			
		||||
            $summaryBudget->getSummaryForHousehold(Argument::any())->willReturn(
 | 
			
		||||
                ['resources' => [], 'charges' => []]
 | 
			
		||||
            );
 | 
			
		||||
            $summaryBudget->getSummaryForPerson(Argument::any())->willReturn(
 | 
			
		||||
                ['resources' => [], 'charges' => []]
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $normalizer = new PersonDocGenNormalizer(
 | 
			
		||||
            $personRender ?? self::$container->get(PersonRender::class),
 | 
			
		||||
            $relationshipRepository ?? self::$container->get(RelationshipRepository::class),
 | 
			
		||||
            $relationshipRepository,
 | 
			
		||||
            $translator ?? self::$container->get(TranslatorInterface::class),
 | 
			
		||||
            $translatableStringHelper ?? self::$container->get(TranslatableStringHelperInterface::class)
 | 
			
		||||
            $translatableStringHelper ?? self::$container->get(TranslatableStringHelperInterface::class),
 | 
			
		||||
            $summaryBudget->reveal()
 | 
			
		||||
        );
 | 
			
		||||
        $normalizerManager = $this->prophesize(NormalizerInterface::class);
 | 
			
		||||
        $normalizerManager->supportsNormalization(Argument::any(), 'docgen', Argument::any())->willReturn(true);
 | 
			
		||||
 
 | 
			
		||||
@@ -762,7 +762,7 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
     */
 | 
			
		||||
    public function setEmail($email = null)
 | 
			
		||||
    {
 | 
			
		||||
        $this->email = $email;
 | 
			
		||||
        $this->email = trim((string) $email);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,12 @@ final class ThirdPartyACLAwareRepository implements ThirdPartyACLAwareRepository
 | 
			
		||||
    {
 | 
			
		||||
        $qb = $this->thirdPartyRepository->createQueryBuilder('tp');
 | 
			
		||||
 | 
			
		||||
        $qb->leftJoin('tp.parent', 'parent')
 | 
			
		||||
            ->andWhere($qb->expr()->andX(
 | 
			
		||||
                'tp.active = \'TRUE\'',
 | 
			
		||||
                $qb->expr()->orX($qb->expr()->isNull('parent'), 'parent.active = \'TRUE\'')
 | 
			
		||||
            ));
 | 
			
		||||
 | 
			
		||||
        if (null !== $filterString) {
 | 
			
		||||
            $qb->andWhere($qb->expr()->like('tp.canonicalized', 'LOWER(UNACCENT(:filterString))'))
 | 
			
		||||
                ->setParameter('filterString', '%' . $filterString . '%');
 | 
			
		||||
 
 | 
			
		||||
@@ -109,14 +109,15 @@ class ThirdPartyApiSearch implements SearchApiInterface
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $query
 | 
			
		||||
            ->setSelectPertinence(implode(' + ', $pertinence), array_merge(
 | 
			
		||||
            ->setSelectPertinence(implode(' + ', $pertinence) . ' + 1', array_merge(
 | 
			
		||||
                [],
 | 
			
		||||
                ...$pertinenceArgs
 | 
			
		||||
            ))
 | 
			
		||||
            ->andWhereClause(implode(' OR ', $wheres), array_merge(
 | 
			
		||||
                [],
 | 
			
		||||
                ...$whereArgs
 | 
			
		||||
            ));
 | 
			
		||||
            ->andWhereClause(implode(' AND ', $wheres)
 | 
			
		||||
                . ' AND tparty.active IS TRUE and (parent.active IS TRUE OR parent IS NULL)', array_merge(
 | 
			
		||||
                    [],
 | 
			
		||||
                    ...$whereArgs
 | 
			
		||||
                ));
 | 
			
		||||
 | 
			
		||||
        return $query;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -63,7 +63,7 @@ class ThirdPartyNormalizer implements NormalizerAwareInterface, NormalizerInterf
 | 
			
		||||
            }, $thirdParty->getTypesAndCategories()),
 | 
			
		||||
            'profession' => $this->normalizer->normalize($thirdParty->getProfession(), $format, $context),
 | 
			
		||||
            'address' => $this->normalizer->normalize($thirdParty->getAddress(), $format, ['address_rendering' => 'short']),
 | 
			
		||||
            'telephone' => $this->normalizer->normalize($thirdParty->getTelephone()),
 | 
			
		||||
            'telephone' => $this->normalizer->normalize($thirdParty->getTelephone(), $format, $context),
 | 
			
		||||
            'email' => $thirdParty->getEmail(),
 | 
			
		||||
            'isChild' => $thirdParty->isChild(),
 | 
			
		||||
            'parent' => $this->normalizer->normalize($thirdParty->getParent(), $format, $context),
 | 
			
		||||
 
 | 
			
		||||
@@ -71,13 +71,13 @@ class ThirdPartyRender extends AbstractChillEntityRender
 | 
			
		||||
            $civility = '';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!empty($entity->getAcronym())) {
 | 
			
		||||
        if ('' !== (string) $entity->getAcronym()) {
 | 
			
		||||
            $acronym = ' (' . $entity->getAcronym() . ')';
 | 
			
		||||
        } else {
 | 
			
		||||
            $acronym = '';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $firstname = empty($entity->getFirstname()) ? '' : $entity->getFirstname();
 | 
			
		||||
        $firstname = ('' === $entity->getFirstname()) ? '' : $entity->getFirstname();
 | 
			
		||||
 | 
			
		||||
        return $civility . $firstname . ' ' . $entity->getName() . $acronym;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user