mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-08 07:54:30 -04:00
Fixes for reminders when calculating across negative GMT timezones.
This commit is contained in:
parent
702ec48261
commit
20088f10c4
@ -47,7 +47,7 @@ class UpdateReminder extends AbstractService
|
|||||||
|
|
||||||
if (is_null($this->invoice->reminder1_sent) &&
|
if (is_null($this->invoice->reminder1_sent) &&
|
||||||
$this->settings->schedule_reminder1 == 'after_invoice_date') {
|
$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())) {
|
if ($reminder_date->gt(now())) {
|
||||||
$date_collection->push($reminder_date);
|
$date_collection->push($reminder_date);
|
||||||
@ -58,7 +58,7 @@ class UpdateReminder extends AbstractService
|
|||||||
($this->invoice->partial_due_date || $this->invoice->due_date) &&
|
($this->invoice->partial_due_date || $this->invoice->due_date) &&
|
||||||
$this->settings->schedule_reminder1 == 'before_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;
|
$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')}");
|
// nlog("1. {$reminder_date->format('Y-m-d')}");
|
||||||
|
|
||||||
if ($reminder_date->gt(now())) {
|
if ($reminder_date->gt(now())) {
|
||||||
@ -71,7 +71,7 @@ class UpdateReminder extends AbstractService
|
|||||||
$this->settings->schedule_reminder1 == 'after_due_date') {
|
$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;
|
$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')}");
|
// nlog("2. {$reminder_date->format('Y-m-d')}");
|
||||||
|
|
||||||
if ($reminder_date->gt(now())) {
|
if ($reminder_date->gt(now())) {
|
||||||
@ -81,7 +81,7 @@ class UpdateReminder extends AbstractService
|
|||||||
|
|
||||||
if (is_null($this->invoice->reminder2_sent) &&
|
if (is_null($this->invoice->reminder2_sent) &&
|
||||||
$this->settings->schedule_reminder2 == 'after_invoice_date') {
|
$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())) {
|
if ($reminder_date->gt(now())) {
|
||||||
$date_collection->push($reminder_date);
|
$date_collection->push($reminder_date);
|
||||||
@ -93,7 +93,7 @@ class UpdateReminder extends AbstractService
|
|||||||
$this->settings->schedule_reminder2 == 'before_due_date') {
|
$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;
|
$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')}");
|
// nlog("3. {$reminder_date->format('Y-m-d')}");
|
||||||
|
|
||||||
if ($reminder_date->gt(now())) {
|
if ($reminder_date->gt(now())) {
|
||||||
@ -106,7 +106,7 @@ class UpdateReminder extends AbstractService
|
|||||||
$this->settings->schedule_reminder2 == 'after_due_date') {
|
$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;
|
$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')}");
|
// nlog("4. {$reminder_date->format('Y-m-d')}");
|
||||||
|
|
||||||
if ($reminder_date->gt(now())) {
|
if ($reminder_date->gt(now())) {
|
||||||
@ -116,7 +116,7 @@ class UpdateReminder extends AbstractService
|
|||||||
|
|
||||||
if (is_null($this->invoice->reminder3_sent) &&
|
if (is_null($this->invoice->reminder3_sent) &&
|
||||||
$this->settings->schedule_reminder3 == 'after_invoice_date') {
|
$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())) {
|
if ($reminder_date->gt(now())) {
|
||||||
$date_collection->push($reminder_date);
|
$date_collection->push($reminder_date);
|
||||||
@ -128,7 +128,7 @@ class UpdateReminder extends AbstractService
|
|||||||
$this->settings->schedule_reminder3 == 'before_due_date') {
|
$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;
|
$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')}");
|
// nlog("5. {$reminder_date->format('Y-m-d')}");
|
||||||
|
|
||||||
if ($reminder_date->gt(now())) {
|
if ($reminder_date->gt(now())) {
|
||||||
@ -141,7 +141,7 @@ class UpdateReminder extends AbstractService
|
|||||||
$this->settings->schedule_reminder3 == 'after_due_date') {
|
$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;
|
$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')}");
|
// nlog("6. {$reminder_date->format('Y-m-d')}");
|
||||||
|
|
||||||
if ($reminder_date->gt(now())) {
|
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->reminder1_sent || $this->settings->schedule_reminder1 == "" || !$this->settings->enable_reminder1) &&
|
||||||
($this->invoice->reminder2_sent || $this->settings->schedule_reminder2 == "" || !$this->settings->enable_reminder2) &&
|
($this->invoice->reminder2_sent || $this->settings->schedule_reminder2 == "" || !$this->settings->enable_reminder2) &&
|
||||||
($this->invoice->reminder3_sent || $this->settings->schedule_reminder3 == "" || !$this->settings->enable_reminder3)) {
|
($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 && $reminder_date->gt(now())) {
|
||||||
if ($reminder_date->gt(now())) {
|
|
||||||
$date_collection->push($reminder_date);
|
$date_collection->push($reminder_date);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ($date_collection->count() >= 1 && $date_collection->sort()->first()->gte(now())) {
|
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 {
|
} else {
|
||||||
$this->invoice->next_send_date = null;
|
$this->invoice->next_send_date = null;
|
||||||
}
|
}
|
||||||
|
@ -157,6 +157,80 @@ class ReminderTest extends TestCase
|
|||||||
'balance' => 10,
|
'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()
|
public function testDKRemindersNotSending()
|
||||||
@ -434,7 +508,7 @@ class ReminderTest extends TestCase
|
|||||||
$fee = collect($this->invoice->line_items)->where('cost', 102)->first();
|
$fee = collect($this->invoice->line_items)->where('cost', 102)->first();
|
||||||
|
|
||||||
$this->assertEquals(102, $fee->cost);
|
$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());
|
$this->travelTo(now()->addDay()->startOfDay()->addHour());
|
||||||
|
|
||||||
@ -446,7 +520,7 @@ class ReminderTest extends TestCase
|
|||||||
$fee = collect($this->invoice->line_items)->where('cost', 103)->first();
|
$fee = collect($this->invoice->line_items)->where('cost', 103)->first();
|
||||||
|
|
||||||
$this->assertEquals(103, $fee->cost);
|
$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();
|
$this->travelBack();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user