Fixes for reminders when calculating across negative GMT timezones.

This commit is contained in:
David Bomba 2024-09-23 06:33:30 +10:00
parent 702ec48261
commit 20088f10c4
2 changed files with 89 additions and 17 deletions

View File

@ -47,7 +47,7 @@ class UpdateReminder extends AbstractService
if (is_null($this->invoice->reminder1_sent) &&
$this->settings->schedule_reminder1 == 'after_invoice_date') {
$reminder_date = Carbon::parse($this->invoice->date)->startOfDay()->addDays((int)$this->settings->num_days_reminder1);
$reminder_date = Carbon::parse($this->invoice->date)->startOfDay()->addDays((int)$this->settings->num_days_reminder1)->addSeconds($offset);
if ($reminder_date->gt(now())) {
$date_collection->push($reminder_date);
@ -58,7 +58,7 @@ class UpdateReminder extends AbstractService
($this->invoice->partial_due_date || $this->invoice->due_date) &&
$this->settings->schedule_reminder1 == 'before_due_date') {
$partial_or_due_date = ($this->invoice->partial > 0 && isset($this->invoice->partial_due_date)) ? $this->invoice->partial_due_date : $this->invoice->due_date;
$reminder_date = Carbon::parse($partial_or_due_date)->startOfDay()->subDays((int)$this->settings->num_days_reminder1);
$reminder_date = Carbon::parse($partial_or_due_date)->startOfDay()->subDays((int)$this->settings->num_days_reminder1)->addSeconds($offset);
// nlog("1. {$reminder_date->format('Y-m-d')}");
if ($reminder_date->gt(now())) {
@ -71,7 +71,7 @@ class UpdateReminder extends AbstractService
$this->settings->schedule_reminder1 == 'after_due_date') {
$partial_or_due_date = ($this->invoice->partial > 0 && isset($this->invoice->partial_due_date)) ? $this->invoice->partial_due_date : $this->invoice->due_date;
$reminder_date = Carbon::parse($partial_or_due_date)->startOfDay()->addDays((int)$this->settings->num_days_reminder1);
$reminder_date = Carbon::parse($partial_or_due_date)->startOfDay()->addDays((int)$this->settings->num_days_reminder1)->addSeconds($offset);
// nlog("2. {$reminder_date->format('Y-m-d')}");
if ($reminder_date->gt(now())) {
@ -81,7 +81,7 @@ class UpdateReminder extends AbstractService
if (is_null($this->invoice->reminder2_sent) &&
$this->settings->schedule_reminder2 == 'after_invoice_date') {
$reminder_date = Carbon::parse($this->invoice->date)->startOfDay()->addDays((int)$this->settings->num_days_reminder2);
$reminder_date = Carbon::parse($this->invoice->date)->startOfDay()->addDays((int)$this->settings->num_days_reminder2)->addSeconds($offset);
if ($reminder_date->gt(now())) {
$date_collection->push($reminder_date);
@ -93,7 +93,7 @@ class UpdateReminder extends AbstractService
$this->settings->schedule_reminder2 == 'before_due_date') {
$partial_or_due_date = ($this->invoice->partial > 0 && isset($this->invoice->partial_due_date)) ? $this->invoice->partial_due_date : $this->invoice->due_date;
$reminder_date = Carbon::parse($partial_or_due_date)->startOfDay()->subDays((int)$this->settings->num_days_reminder2);
$reminder_date = Carbon::parse($partial_or_due_date)->startOfDay()->subDays((int)$this->settings->num_days_reminder2)->addSeconds($offset);
// nlog("3. {$reminder_date->format('Y-m-d')}");
if ($reminder_date->gt(now())) {
@ -106,7 +106,7 @@ class UpdateReminder extends AbstractService
$this->settings->schedule_reminder2 == 'after_due_date') {
$partial_or_due_date = ($this->invoice->partial > 0 && isset($this->invoice->partial_due_date)) ? $this->invoice->partial_due_date : $this->invoice->due_date;
$reminder_date = Carbon::parse($partial_or_due_date)->startOfDay()->addDays((int)$this->settings->num_days_reminder2);
$reminder_date = Carbon::parse($partial_or_due_date)->startOfDay()->addDays((int)$this->settings->num_days_reminder2)->addSeconds($offset);
// nlog("4. {$reminder_date->format('Y-m-d')}");
if ($reminder_date->gt(now())) {
@ -116,7 +116,7 @@ class UpdateReminder extends AbstractService
if (is_null($this->invoice->reminder3_sent) &&
$this->settings->schedule_reminder3 == 'after_invoice_date') {
$reminder_date = Carbon::parse($this->invoice->date)->startOfDay()->addDays((int)$this->settings->num_days_reminder3);
$reminder_date = Carbon::parse($this->invoice->date)->startOfDay()->addDays((int)$this->settings->num_days_reminder3)->addSeconds($offset);
if ($reminder_date->gt(now())) {
$date_collection->push($reminder_date);
@ -128,7 +128,7 @@ class UpdateReminder extends AbstractService
$this->settings->schedule_reminder3 == 'before_due_date') {
$partial_or_due_date = ($this->invoice->partial > 0 && isset($this->invoice->partial_due_date)) ? $this->invoice->partial_due_date : $this->invoice->due_date;
$reminder_date = Carbon::parse($partial_or_due_date)->startOfDay()->subDays((int)$this->settings->num_days_reminder3);
$reminder_date = Carbon::parse($partial_or_due_date)->startOfDay()->subDays((int)$this->settings->num_days_reminder3)->addSeconds($offset);
// nlog("5. {$reminder_date->format('Y-m-d')}");
if ($reminder_date->gt(now())) {
@ -141,7 +141,7 @@ class UpdateReminder extends AbstractService
$this->settings->schedule_reminder3 == 'after_due_date') {
$partial_or_due_date = ($this->invoice->partial > 0 && isset($this->invoice->partial_due_date)) ? $this->invoice->partial_due_date : $this->invoice->due_date;
$reminder_date = Carbon::parse($partial_or_due_date)->startOfDay()->addDays((int)$this->settings->num_days_reminder3);
$reminder_date = Carbon::parse($partial_or_due_date)->startOfDay()->addDays((int)$this->settings->num_days_reminder3)->addSeconds($offset);
// nlog("6. {$reminder_date->format('Y-m-d')}");
if ($reminder_date->gt(now())) {
@ -154,17 +154,15 @@ class UpdateReminder extends AbstractService
($this->invoice->reminder1_sent || $this->settings->schedule_reminder1 == "" || !$this->settings->enable_reminder1) &&
($this->invoice->reminder2_sent || $this->settings->schedule_reminder2 == "" || !$this->settings->enable_reminder2) &&
($this->invoice->reminder3_sent || $this->settings->schedule_reminder3 == "" || !$this->settings->enable_reminder3)) {
$reminder_date = $this->addTimeInterval($this->invoice->last_sent_date, (int) $this->settings->endless_reminder_frequency_id);
$reminder_date = $this->addTimeInterval($this->invoice->last_sent_date, (int) $this->settings->endless_reminder_frequency_id)->addSeconds($offset);
if ($reminder_date) {
if ($reminder_date->gt(now())) {
$date_collection->push($reminder_date);
}
if ($reminder_date && $reminder_date->gt(now())) {
$date_collection->push($reminder_date);
}
}
if ($date_collection->count() >= 1 && $date_collection->sort()->first()->gte(now())) {
$this->invoice->next_send_date = $date_collection->sort()->first()->addSeconds($offset);
$this->invoice->next_send_date = $date_collection->sort()->first();
} else {
$this->invoice->next_send_date = null;
}

View File

@ -157,6 +157,80 @@ class ReminderTest extends TestCase
'balance' => 10,
]);
}
public function testReminderScheduleNy()
{
$settings = CompanySettings::defaults();
$settings->timezone_id = '15';
$settings->entity_send_time = 6;
$settings->payment_terms = '14';
$settings->send_reminders = true;
$settings->enable_reminder1 = true;
$settings->enable_reminder2 = false;
$settings->enable_reminder3 = false;
$settings->enable_reminder_endless = true;
$settings->schedule_reminder1 = 'after_invoice_date';
$settings->schedule_reminder2 = '';
$settings->schedule_reminder3 = '';
$settings->num_days_reminder1 = 1;
$settings->num_days_reminder2 = 0;
$settings->num_days_reminder3 = 0;
$settings->endless_reminder_frequency_id = '1';
$this->buildData($settings);
$this->travelTo(Carbon::parse('2024-09-20')->startOfDay()->addHours(1));
$invoice = Invoice::factory()->create([
'company_id' => $this->company->id,
'user_id' => $this->user->id,
'client_id' => $this->client->id,
'amount' => 10,
'balance' => 10,
'date' => '2024-09-19',
'number' => 'JJJ1-11-2024',
'due_date' => '2024-09-19',
'status_id' => 2,
'last_sent_date' => '19-09-2024',
]);
$this->assertEquals(1, $invoice->company->settings->num_days_reminder1);
$invoice->service()->setReminder($settings)->save();
$this->assertEquals(10, $invoice->balance);
$this->assertEquals('2024-09-20', $invoice->next_send_date->format('Y-m-d'));
$x = false;
do {
$this->travelTo(now()->addHour());
(new ReminderJob())->handle();
$invoice = $invoice->fresh();
$x = (bool)$invoice->reminder1_sent;
} while ($x === false);
$this->assertNotNull($invoice->reminder_last_sent);
$this->assertEquals(now()->addDays(1), $invoice->next_send_date);
$x = 0;
do {
$this->travelTo(now()->addHour());
(new ReminderJob())->handle();
$invoice = $invoice->fresh();
$x++;
} while ($x < 24);
$this->assertEquals(now()->addDays(1), $invoice->next_send_date);
}
public function testDKRemindersNotSending()
@ -434,7 +508,7 @@ class ReminderTest extends TestCase
$fee = collect($this->invoice->line_items)->where('cost', 102)->first();
$this->assertEquals(102, $fee->cost);
$this->assertEquals('Fee added '.now()->format('d/M/Y'), $fee->notes);
$this->assertEquals('Late fee added on '.now()->format('d/M/Y'), $fee->notes);
$this->travelTo(now()->addDay()->startOfDay()->addHour());
@ -446,7 +520,7 @@ class ReminderTest extends TestCase
$fee = collect($this->invoice->line_items)->where('cost', 103)->first();
$this->assertEquals(103, $fee->cost);
$this->assertEquals('Fee added '.now()->format('d/M/Y'), $fee->notes);
$this->assertEquals('Late fee added on '.now()->format('d/M/Y'), $fee->notes);
$this->travelBack();