diff --git a/src/Adherent/Tag/TagGenerator/AdherentStatusTagGenerator.php b/src/Adherent/Tag/TagGenerator/AdherentStatusTagGenerator.php index 25102eba11e..9a5515c27d6 100644 --- a/src/Adherent/Tag/TagGenerator/AdherentStatusTagGenerator.php +++ b/src/Adherent/Tag/TagGenerator/AdherentStatusTagGenerator.php @@ -5,12 +5,15 @@ use App\Adherent\Tag\TagEnum; use App\Entity\Adherent; use App\Membership\MembershipSourceEnum; +use App\Repository\Contribution\PaymentRepository; use App\Repository\DonationRepository; class AdherentStatusTagGenerator extends AbstractTagGenerator { - public function __construct(private readonly DonationRepository $donationRepository) - { + public function __construct( + private readonly DonationRepository $donationRepository, + private readonly PaymentRepository $paymentRepository, + ) { } public static function getDefaultPriority(): int @@ -20,46 +23,81 @@ public static function getDefaultPriority(): int public function generate(Adherent $adherent, array $previousTags): array { - if (MembershipSourceEnum::LEGISLATIVE === $adherent->getSource()) { - return [TagEnum::SYMPATHISANT_ENSEMBLE2024]; - } - - if ($adherent->isBesoinDEuropeUser()) { - return [TagEnum::SYMPATHISANT_BESOIN_D_EUROPE]; - } - - if (\in_array($adherent->getSource(), [MembershipSourceEnum::AVECVOUS, MembershipSourceEnum::JEMENGAGE])) { - return [TagEnum::SYMPATHISANT_COMPTE_AVECVOUS_JEMENGAGE]; + if ($adherent->isOtherPartyMembership()) { + return [TagEnum::SYMPATHISANT_AUTRE_PARTI]; } - $mainTag = null; - - if (\count($adherent->getConfirmedPayments())) { - $mainTag = \sprintf(TagEnum::ADHERENT_YEAR_ELU_TAG_PATTERN, date('Y')); - } $countCotisationByYear = $this->donationRepository->countCotisationByYearForAdherent($adherent); if ($countTotalCotisation = \count($countCotisationByYear)) { + $currentYear = date('Y'); $lastYear = key($countCotisationByYear); - if ($lastYear == date('Y')) { + if ($lastYear == $currentYear) { if (1 === $countTotalCotisation) { - $mainTag = \sprintf(TagEnum::ADHERENT_YEAR_PRIMO_TAG_PATTERN, $lastYear); - } else { - $mainTag = \sprintf(TagEnum::ADHERENT_YEAR_RECOTISATION_TAG_PATTERN, $lastYear); + return [sprintf(TagEnum::ADHERENT_YEAR_PRIMO_TAG_PATTERN, $currentYear)]; } - } elseif (null === $mainTag) { - $mainTag = \sprintf(TagEnum::ADHERENT_YEAR_TAG_PATTERN, $lastYear); + + return [sprintf(TagEnum::ADHERENT_YEAR_RECOTISATION_TAG_PATTERN, $currentYear)]; + } + + if ( + \count($adherent->getConfirmedPayments()) + || $adherent->hasRecentContribution() + ) { + return [sprintf(TagEnum::ADHERENT_YEAR_ELU_TAG_PATTERN, date('Y'))]; } + + $totalContributionPaymentsByYear = $this->paymentRepository->getTotalPaymentByYearForAdherent($adherent); + + if (!empty($totalContributionPaymentsByYear)) { + if ( + array_key_exists($currentYear, $totalContributionPaymentsByYear) + && $totalContributionPaymentsByYear[$currentYear] > 30 + && ( + !$adherent->findElectedRepresentativeMandates(true) + || $adherent->exemptFromCotisation + ) + ) { + return [sprintf(TagEnum::ADHERENT_YEAR_ELU_TAG_PATTERN, $currentYear)]; + } + } + + $allYears = array_unique(array_merge( + $countCotisationByYear, + $totalContributionPaymentsByYear + )); + unset($allYears[$currentYear]); + + foreach ($allYears as $year) { + if (array_key_exists($year, $countCotisationByYear)) { + return [\sprintf(TagEnum::ADHERENT_YEAR_TAG_PATTERN, $lastYear)]; + } + + if ( + array_key_exists($year, $totalContributionPaymentsByYear) + && $totalContributionPaymentsByYear[$year] > 30 + && ( + !$adherent->findElectedRepresentativeMandates(true) + || $adherent->exemptFromCotisation + ) + ) { + return [sprintf(TagEnum::ADHERENT_YEAR_ELU_TAG_PATTERN, $currentYear)]; + } + } + } + + if (\in_array($adherent->getSource(), [MembershipSourceEnum::AVECVOUS, MembershipSourceEnum::JEMENGAGE])) { + return [TagEnum::SYMPATHISANT_COMPTE_AVECVOUS_JEMENGAGE]; } - if ($mainTag) { - return [$mainTag]; + if ($adherent->isBesoinDEuropeUser()) { + return [TagEnum::SYMPATHISANT_BESOIN_D_EUROPE]; } - if ($adherent->isOtherPartyMembership()) { - return [TagEnum::SYMPATHISANT_AUTRE_PARTI]; + if (MembershipSourceEnum::LEGISLATIVE === $adherent->getSource()) { + return [TagEnum::SYMPATHISANT_ENSEMBLE2024]; } if (!$adherent->isV2() && $adherent->getActivatedAt() && $adherent->getActivatedAt() < new \DateTime('2022-09-17')) { diff --git a/src/Entity/Adherent.php b/src/Entity/Adherent.php index 3707f73cc0e..f018cf67139 100644 --- a/src/Entity/Adherent.php +++ b/src/Entity/Adherent.php @@ -2387,6 +2387,13 @@ public function removeContribution(Contribution $contribution): void $this->contributions->removeElement($contribution); } + public function hasRecentContribution(): bool + { + $date = new \DateTime('-21 days 00:00'); + + return $this->contributedAt && $this->contributedAt >= $date; + } + #[Groups(['adherent_elect_read'])] public function getContributionAmount(): ?int { diff --git a/src/Repository/Contribution/PaymentRepository.php b/src/Repository/Contribution/PaymentRepository.php index 08de5c28d00..19514701186 100644 --- a/src/Repository/Contribution/PaymentRepository.php +++ b/src/Repository/Contribution/PaymentRepository.php @@ -2,6 +2,7 @@ namespace App\Repository\Contribution; +use App\Entity\Adherent; use App\Entity\Contribution\Payment; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; @@ -28,4 +29,26 @@ public function save(Payment $payment): void $this->_em->persist($payment); $this->_em->flush(); } + + public function getTotalPaymentByYearForAdherent(Adherent $adherent): array + { + return array_column($this->createQueryBuilder('payment') + ->select('YEAR(payment.date) AS year') + ->addSelect('SUM(payment.amount) AS total') + ->where('payment.adherent = :adherent') + ->andWhere('donation.status IN (:status)') + ->setParameters([ + 'adherent' => $adherent, + 'status' => [ + 'paid_out', + 'confirmed', + 'cheque_cashed', + ], + ]) + ->groupBy('year') + ->orderBy('year', 'DESC') + ->getQuery() + ->getResult(), 'total', 'year' + ); + } }