Project 'cooperatic/kohinos-tav' was moved to 'agplv3/kohinos-tav'. Please update any links and bookmarks that may still have the old path.
Commit 8fc7cd05 by Yvon Kerdoncuff

Merge branch '6035-6080-recurrence-gestion-duplication-et-terminaison' into…

Merge branch '6035-6080-recurrence-gestion-duplication-et-terminaison' into '5691-paiement-reccurent-payzen'

A TESTER : check for existing not ended and not expired recurring payment : warn…

See merge request cooperatic/kohinos-tav!80
parents 8ac275d6 a4ae2881
......@@ -128,6 +128,11 @@ class UserAdherentController extends FluxController
* Returns error message or null if no error.
*/
private function paiementCotisTavValidation($flux) {
//Look for existing recurring payment
if($reason = $this->tavCotisationsUtils->checkExistingRecurringPayment($flux)) {
return $reason;
}
// Look for existing cotisation
if ($this->tavCotisationsUtils->checkExistingCotisation($flux)) {
return "Cotisation déjà payée ce mois-ci.";
......
......@@ -2,6 +2,7 @@
namespace App\Entity;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
use Payum\Core\Model\Payment as BasePayment;
use Ramsey\Uuid\Doctrine\UuidGenerator;
......@@ -182,4 +183,56 @@ class Payment extends BasePayment
return $this;
}
/**
* Return null in case of error
* Returns true if payment is already ended or CB expired
* Returns false otherwise
*
* @param $reason
* @return bool|null
*/
public function isRecurringPaymentEndedOrExpired(&$reason)
{
if(!$this->details
|| !array_key_exists('vads_effective_creation_date',$this->details)
|| !array_key_exists('vads_expiry_year',$this->details)
|| !array_key_exists('vads_effective_creation_date',$this->details)
) {
$reason = "Attribut détails vide ou clés absentes.";
return null;
}
$firstDayOfCreationMonth = DateTime::createFromFormat(
'Ymd',substr($this->details['vads_effective_creation_date'],0,6) . "01"
);
if(!$firstDayOfCreationMonth) {
$reason = "Error parsing vads_effective_creation_date : " . $this->details['vads_effective_creation_date'];
return null;
}
$day = $this->getRecurrenceMonthDay() ? $this->getRecurrenceMonthDay() - 1 : 0; //if not set assume first day of month (not a big deal anyway)
$dateOfFirstOccurenceAfterInitialPayment = $firstDayOfCreationMonth->modify(
"+" . $day . " days next month"
);
$paymentEndDate = $this->getRecurrenceMonthsCount() ?
$dateOfFirstOccurenceAfterInitialPayment->modify(
"+" . ($this->getRecurrenceMonthsCount() - 1) . " months" //minus one because initial payment is not considered by payzen as the first occurence
)
: null; //assume no end date if recurrenceMonthsCount not set
//Now check expiry date
$paymentEndDateDueToExpiry = new DateTime();
$paymentEndDateDueToExpiry->setDate($this->details['vads_expiry_year'],$this->details['vads_expiry_month'],$day+1);
$now = new DateTime();
if($paymentEndDate && $paymentEndDate < $paymentEndDateDueToExpiry) {
//Compare now with payment end date
$reason = "Paiement récurrent en cours jusqu'à dernière échéance le " . $paymentEndDate->format('d/m/Y') . ".";
return $now >= $paymentEndDate;
} else {
//Compare now with expiry date
$reason = "Paiement récurrent en cours jusqu'à dernière échéance le " . $paymentEndDateDueToExpiry->format('d/m/Y') . " en raison de l'expiration du moyen de paiement.";
return $now >= $paymentEndDateDueToExpiry;
}
}
}
......@@ -32,7 +32,10 @@ class AchatMonnaieAdherentRecurrentFormType extends AchatMonnaieAdherentFormType
'constraints' => [
new GreaterThanOrEqual(['value' => 2, 'message' => "Le nombre d'échéances doit être au moins égal à 2."]),
],
'help' => "Une échéance par mois. Le premier paiement est inclus dans le nombre d'échéances.",
'help' => "Une échéance par mois.
Le premier paiement est inclus dans le nombre d'échéances.
Le nombre d'échéance réel pourra être diminué selon la date d'expiration du moyen de paiement utilisé.
Pour demander une interruption anticipée, merci de contacter la caisse.",
'attr' => ['autocomplete' => 'off']
])
->add('jourPrelevement', ChoiceType::class, [
......@@ -41,7 +44,8 @@ class AchatMonnaieAdherentRecurrentFormType extends AchatMonnaieAdherentFormType
'data' => $jourPrelevement,
'required' => true,
'mapped' => false,
'attr' => ['autocomplete' => 'off', 'readonly' => true]
'attr' => ['autocomplete' => 'off', 'readonly' => true],
'help' => "Pour simplifier le traitement de l'information, le jour de prélèvement est fixé au jour du premier paiement ou au plus tard le 28 du mois."
])
->remove('saveHelloAsso')
->remove('save')
......
......@@ -3,6 +3,7 @@
namespace App\Utils;
use App\Entity\Adherent;
use App\Entity\Payment;
use App\Entity\Siege;
use App\Entity\Flux;
use App\Entity\CotisationTavReversement;
......@@ -44,6 +45,23 @@ class TAVCotisationUtils
return count($existing) > 0;
}
public function checkExistingRecurringPayment(Flux $flux)
{
$recurringPayments = $this->em->getRepository(Payment::class)->findBy([
'isRecurrent' => true,
'clientEmail' => $flux->getDestinataire()->getUser()->getEmail(),
]);
$res = "";
foreach($recurringPayments as $p) {
$reason = "";
if($p->isRecurringPaymentEndedOrExpired($reason) !== true) {
$res .= ($reason . " ");
}
}
return $res;
}
/**
* First method to calculate allowance:
* according to a contribution rate defined in user's profile (ProfilDeCotisation).
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment