diff --git a/galette/lib/Galette/Repository/Reminders.php b/galette/lib/Galette/Repository/Reminders.php index 30ec555251..4b786df95a 100644 --- a/galette/lib/Galette/Repository/Reminders.php +++ b/galette/lib/Galette/Repository/Reminders.php @@ -90,6 +90,28 @@ public function __construct($selected = null) */ private function loadToRemind(Db $zdb, $type, $nomail = false) { + global $preferences; + + $limit_now = new \DateTime(); + $limit_now->sub(new \DateInterval('P1D')); + $limit_now->setTime(23, 59, 59); + if ($preferences->pref_beg_membership != '') { + //case beginning of membership + list($j, $m) = explode('/', $preferences->pref_beg_membership); + $limit_date = new \DateTime($limit_now->format('Y') . '-' . $m . '-' . $j); + while ($limit_now <= $limit_date) { + $limit_date->sub(new \DateInterval('P1Y')); + } + } elseif ($preferences->pref_membership_ext != '') { + //case membership extension + $limit_date = clone $limit_now; + $limit_date->sub(new \DateInterval('P' . $preferences->pref_membership_ext . 'M')); + } else { + throw new \RuntimeException( + 'Unable to define end date; none of pref_beg_membership nor pref_membership_ext are defined!' + ); + } + $this->toremind = array(); $select = $zdb->select(Members::TABLE, 'a'); $select->columns([Members::PK, 'date_echeance']); @@ -145,6 +167,15 @@ private function loadToRemind(Db $zdb, $type, $nomail = false) $results = $zdb->execute($select); foreach ($results as $r) { + if ($r->last_reminder !== null && $r->last_reminder != '') { + $last_reminder = new \DateTime($r->last_reminder); + if ($limit_date >= $last_reminder) { + //last reminder has been sent too long ago, must be ignored + $r->reminder_type = $type; + $r->last_reminder = ''; + } + } + if ($r->reminder_type < $type) { //sent impending, but is now late. reset last remind. $r->reminder_type = $type; @@ -167,8 +198,7 @@ private function loadToRemind(Db $zdb, $type, $nomail = false) if ($r->last_reminder === null || $r->last_reminder == '') { $date_checked = true; } else { - $last_reminder = new \DateTime($r->last_reminder); - if ($now >= $second && $second > $last_reminder) { + if ($now >= $second && $last_reminder >= $limit_date && $second > $last_reminder) { $date_checked = true; } } @@ -185,7 +215,7 @@ private function loadToRemind(Db $zdb, $type, $nomail = false) $date_checked = true; } else { $last_reminder = new \DateTime($r->last_reminder); - if ($now >= $second && $second > $last_reminder) { + if ($now >= $second && $last_reminder >= $limit_date && $second > $last_reminder) { $date_checked = true; } } diff --git a/tests/Galette/Repository/tests/units/Reminders.php b/tests/Galette/Repository/tests/units/Reminders.php index acf3e6bce3..66fe318af6 100644 --- a/tests/Galette/Repository/tests/units/Reminders.php +++ b/tests/Galette/Repository/tests/units/Reminders.php @@ -451,4 +451,166 @@ public function testGetList() $this->assertCount(1, $lreminders->getList($this->zdb)); $this->assertCount(0, $ireminders->getList($this->zdb)); } + + /** + * Test getList with reminders from previous period already present + * + * @return void + */ + public function testGetListNextYear() + { + //impendings + $ireminders = new \Galette\Repository\Reminders([\Galette\Entity\Reminder::IMPENDING]); + $this->assertSame([], $ireminders->getList($this->zdb)); + + //lates + $lreminders = new \Galette\Repository\Reminders([\Galette\Entity\Reminder::LATE]); + $this->assertSame([], $lreminders->getList($this->zdb)); + + //all + $reminders = new \Galette\Repository\Reminders(); + $this->assertSame([], $reminders->getList($this->zdb)); + + //create member + $this->getMemberTwo(); + $id = $this->adh->id; + + //create a contribution, just before being a close to be expired contribution + $now = new \DateTime(); + + //add a first close to be expired contribution reminder - last year + $send = new \DateTime(); + $send->sub(new \DateInterval('P30D'))->sub(new \DateInterval('P1Y')); + $data = array( + 'reminder_type' => \Galette\Entity\Reminder::IMPENDING, + 'reminder_dest' => $id, + 'reminder_date' => $send->format('Y-m-d'), + 'reminder_success' => true, + 'reminder_nomail' => ($this->zdb->isPostgres() ? 'false' : 0) + ); + + $insert = $this->zdb->insert(\Galette\Entity\Reminder::TABLE); + $insert->values($data); + + $add = $this->zdb->execute($insert); + $this->assertGreaterThan(0, $add->count()); + + //add a second close to be expired contribution reminder, yesterday - last year + $send = new \DateTime(); + $send->sub(new \DateInterval('P1D'))->sub(new \DateInterval('P1Y')); + $data = array( + 'reminder_type' => \Galette\Entity\Reminder::IMPENDING, + 'reminder_dest' => $id, + 'reminder_date' => $send->format('Y-m-d'), + 'reminder_success' => true, + 'reminder_nomail' => ($this->zdb->isPostgres() ? 'false' : 0) + ); + + $insert = $this->zdb->insert(\Galette\Entity\Reminder::TABLE); + $insert->values($data); + + $add = $this->zdb->execute($insert); + $this->assertGreaterThan(0, $add->count()); + + //add a sent late reminder, as it should have been + $send = clone $now; + $send->sub(new \DateInterval('P5D'))->sub(new \DateInterval('P1Y')); + $data = array( + 'reminder_type' => \Galette\Entity\Reminder::LATE, + 'reminder_dest' => $id, + 'reminder_date' => $send->format('Y-m-d'), + 'reminder_success' => true, + 'reminder_nomail' => ($this->zdb->isPostgres() ? 'false' : 0) + ); + + $insert = $this->zdb->insert(\Galette\Entity\Reminder::TABLE); + $insert->values($data); + + $add = $this->zdb->execute($insert); + $this->assertGreaterThan(0, $add->count()); + + //create a close to be expired contribution + $due_date = clone $now; + $due_date->add(new \DateInterval('P30D')); + $begin_date = clone $due_date; + $begin_date->add(new \DateInterval('P1D')); + $begin_date->sub(new \DateInterval('P1Y')); + + $this->cleanContributions(); + $this->createContrib([ + 'id_adh' => $id, + 'id_type_cotis' => 3, + 'montant_cotis' => '111', + 'type_paiement_cotis' => '6', + 'info_cotis' => 'FAKER' . $this->seed, + 'date_fin_cotis' => $due_date->format('Y-m-d'), + 'date_enreg' => $begin_date->format('Y-m-d'), + 'date_debut_cotis' => $begin_date->format('Y-m-d') + ]); + + $adh = $this->adh; + $this->assertTrue($adh->load($id)); + + //member is up-to-date, and close to be expired, one impending reminder to send + $this->assertTrue($this->adh->isUp2Date()); + $this->assertCount(1, $reminders->getList($this->zdb)); + $this->assertCount(0, $lreminders->getList($this->zdb)); + $this->assertCount(1, $ireminders->getList($this->zdb)); + + //create an expired contribution, late by 30 days + $due_date = clone $now; + $due_date->sub(new \DateInterval('P30D')); + $begin_date = clone $due_date; + $begin_date->add(new \DateInterval('P1D')); + $begin_date->sub(new \DateInterval('P1Y')); + + $this->cleanContributions(); + $this->createContrib([ + 'id_adh' => $id, + 'id_type_cotis' => 3, + 'montant_cotis' => '111', + 'type_paiement_cotis' => '6', + 'info_cotis' => 'FAKER' . $this->seed, + 'date_fin_cotis' => $due_date->format('Y-m-d'), + 'date_enreg' => $begin_date->format('Y-m-d'), + 'date_debut_cotis' => $begin_date->format('Y-m-d') + ]); + + $adh = $this->adh; + $this->assertTrue($adh->load($id)); + + //member is late, one late reminder to send + $this->assertFalse($this->adh->isUp2Date()); + $this->assertCount(1, $reminders->getList($this->zdb)); + $this->assertCount(1, $lreminders->getList($this->zdb)); + $this->assertCount(0, $ireminders->getList($this->zdb)); + + //create an expired contribution, 60 days ago + $due_date = clone $now; + $due_date->sub(new \DateInterval('P60D')); + $begin_date = clone $due_date; + $begin_date->add(new \DateInterval('P1D')); + $begin_date->sub(new \DateInterval('P1Y')); + + $this->cleanContributions(); + $this->createContrib([ + 'id_adh' => $id, + 'id_type_cotis' => 3, + 'montant_cotis' => '111', + 'type_paiement_cotis' => '6', + 'info_cotis' => 'FAKER' . $this->seed, + 'date_fin_cotis' => $due_date->format('Y-m-d'), + 'date_enreg' => $begin_date->format('Y-m-d'), + 'date_debut_cotis' => $begin_date->format('Y-m-d') + ]); + + $adh = $this->adh; + $this->assertTrue($adh->load($id)); + + //member has been late for two months, one late reminder to send + $this->assertFalse($this->adh->isUp2Date()); + $this->assertCount(1, $reminders->getList($this->zdb)); + $this->assertCount(1, $lreminders->getList($this->zdb)); + $this->assertCount(0, $ireminders->getList($this->zdb)); + } }