mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
Updates for subscription cron logic to utilize company timezone
This commit is contained in:
parent
dd28cb0372
commit
d353bfc52a
@ -39,62 +39,25 @@ class SubscriptionCron
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
nlog('Subscription Cron');
|
||||
|
||||
Auth::logout();
|
||||
|
||||
if (! config('ninja.db.multi_db_enabled')) {
|
||||
$invoices = Invoice::where('is_deleted', 0)
|
||||
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
|
||||
->where('balance', '>', 0)
|
||||
->where('is_proforma', 0)
|
||||
->whereDate('due_date', '<=', now()->addDay()->startOfDay())
|
||||
->whereNull('deleted_at')
|
||||
->whereNotNull('subscription_id')
|
||||
->cursor();
|
||||
|
||||
$invoices->each(function (Invoice $invoice) {
|
||||
$subscription = $invoice->subscription;
|
||||
nlog('Subscription Cron '. now()->toDateTimeString());
|
||||
|
||||
$body = [
|
||||
'context' => 'plan_expired',
|
||||
'client' => $invoice->client->hashed_id,
|
||||
'invoice' => $invoice->hashed_id,
|
||||
'subscription' => $subscription->hashed_id,
|
||||
];
|
||||
$this->timezoneAware();
|
||||
|
||||
$this->sendLoad($subscription, $body);
|
||||
//This will send the notification daily.
|
||||
//We'll need to handle this by performing some action on the invoice to either archive it or delete it?
|
||||
});
|
||||
|
||||
} else {
|
||||
//multiDB environment, need to
|
||||
foreach (MultiDB::$dbs as $db) {
|
||||
MultiDB::setDB($db);
|
||||
|
||||
$invoices = Invoice::where('is_deleted', 0)
|
||||
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
|
||||
->where('balance', '>', 0)
|
||||
->where('is_proforma', 0)
|
||||
->whereDate('due_date', '<=', now()->addDay()->startOfDay())
|
||||
->whereNull('deleted_at')
|
||||
->whereNotNull('subscription_id')
|
||||
->cursor();
|
||||
nlog('Subscription Cron for ' . $db . ' ' . now()->toDateTimeString());
|
||||
|
||||
$invoices->each(function (Invoice $invoice) {
|
||||
$subscription = $invoice->subscription;
|
||||
$this->timezoneAware();
|
||||
|
||||
$body = [
|
||||
'context' => 'plan_expired',
|
||||
'client' => $invoice->client->hashed_id,
|
||||
'invoice' => $invoice->hashed_id,
|
||||
'subscription' => $subscription->hashed_id,
|
||||
];
|
||||
|
||||
$this->sendLoad($subscription, $body);
|
||||
//This will send the notification daily.
|
||||
//We'll need to handle this by performing some action on the invoice to either archive it or delete it?
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -131,7 +94,7 @@ class SubscriptionCron
|
||||
->where('is_proforma', 0)
|
||||
->whereNotNull('subscription_id')
|
||||
->where('balance', '>', 0)
|
||||
->whereDate('due_date', '<=', now()->setTimezone($company->timezone()->name)->addDay()->startOfDay())
|
||||
->whereDate('due_date', '<=', now()->addDay()->startOfDay())
|
||||
->cursor()
|
||||
->each(function (Invoice $invoice) {
|
||||
|
||||
|
@ -12,13 +12,19 @@
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\User;
|
||||
use App\Models\Client;
|
||||
use App\Models\Company;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Product;
|
||||
use App\Models\RecurringInvoice;
|
||||
use Tests\MockAccountData;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Models\CompanyToken;
|
||||
use App\Models\Subscription;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\DataMapper\CompanySettings;
|
||||
use App\Factory\CompanyUserFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
@ -51,6 +57,250 @@ class SubscriptionApiTest extends TestCase
|
||||
Model::reguard();
|
||||
}
|
||||
|
||||
public function testSubscriptionCronLocalization()
|
||||
{
|
||||
|
||||
$settings = CompanySettings::defaults();
|
||||
$settings->timezone_id = '50'; //europe/vienna
|
||||
|
||||
$c2 = Company::factory()->create([
|
||||
'account_id' => $this->company->account_id,
|
||||
'settings' => $settings
|
||||
]);
|
||||
|
||||
$cu = CompanyUserFactory::create($this->user->id, $c2->id, $this->account->id);
|
||||
$cu->is_owner = true;
|
||||
$cu->is_admin = true;
|
||||
$cu->is_locked = true;
|
||||
$cu->permissions = '["view_client"]';
|
||||
$cu->save();
|
||||
|
||||
$different_company_token = \Illuminate\Support\Str::random(64);
|
||||
|
||||
$company_token = new CompanyToken();
|
||||
$company_token->user_id = $this->user->id;
|
||||
$company_token->company_id = $c2->id;
|
||||
$company_token->account_id = $c2->account_id;
|
||||
$company_token->name = 'test token';
|
||||
$company_token->token = $different_company_token;
|
||||
$company_token->is_system = true;
|
||||
$company_token->save();
|
||||
|
||||
|
||||
$s = Subscription::factory()->create([
|
||||
'company_id' => $c2->id,
|
||||
'user_id' => $this->user->id,
|
||||
]);
|
||||
|
||||
$client2 = Client::factory()->create([
|
||||
'company_id' => $c2->id,
|
||||
'user_id' => $this->user->id,
|
||||
]);
|
||||
|
||||
$i = Invoice::factory()->create([
|
||||
'company_id' => $c2->id,
|
||||
'user_id' => $this->user->id,
|
||||
'subscription_id' => $s->id,
|
||||
'due_date' => now()->startOfDay(),
|
||||
'client_id' => $client2->id,
|
||||
'status_id' => Invoice::STATUS_SENT
|
||||
]);
|
||||
|
||||
$settings = CompanySettings::defaults();
|
||||
$settings->timezone_id = '110'; //sydney/australia
|
||||
|
||||
$c = Company::factory()->create([
|
||||
'account_id' => $this->company->account_id,
|
||||
'settings' => $settings,
|
||||
]);
|
||||
|
||||
$cu = CompanyUserFactory::create($this->user->id, $c->id, $this->account->id);
|
||||
$cu->is_owner = true;
|
||||
$cu->is_admin = true;
|
||||
$cu->is_locked = true;
|
||||
$cu->permissions = '["view_client"]';
|
||||
$cu->save();
|
||||
|
||||
$different_company_token = \Illuminate\Support\Str::random(64);
|
||||
|
||||
$company_token = new CompanyToken();
|
||||
$company_token->user_id = $this->user->id;
|
||||
$company_token->company_id = $c->id;
|
||||
$company_token->account_id = $c->account_id;
|
||||
$company_token->name = 'test token';
|
||||
$company_token->token = $different_company_token;
|
||||
$company_token->is_system = true;
|
||||
$company_token->save();
|
||||
|
||||
$s1 = Subscription::factory()->create([
|
||||
'company_id' => $c->id,
|
||||
'user_id' => $this->user->id,
|
||||
]);
|
||||
|
||||
|
||||
$client = Client::factory()->create([
|
||||
'company_id' => $c2->id,
|
||||
'user_id' => $this->user->id,
|
||||
]);
|
||||
|
||||
$i = Invoice::factory()->create([
|
||||
'company_id' => $c->id,
|
||||
'user_id' => $this->user->id,
|
||||
'subscription_id' => $s1->id,
|
||||
'due_date' => now()->startOfDay(),
|
||||
'client_id' => $client->id,
|
||||
'status_id' => Invoice::STATUS_SENT
|
||||
]);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$company = Company::find($c->id); //sydney
|
||||
|
||||
$timezone_now = now()->setTimezone($company->timezone()->name);
|
||||
|
||||
$this->assertEquals('Australia/Sydney', $timezone_now->timezoneName);
|
||||
|
||||
$this->travelTo($timezone_now->copy()->startOfDay()->subHour());
|
||||
|
||||
$i = false;
|
||||
|
||||
//Capture companies within the window of 00:00 and 00:30
|
||||
if($timezone_now->gte($timezone_now->copy()->startOfDay()) && $timezone_now->lt($timezone_now->copy()->startOfDay()->addMinutes(30))) {
|
||||
|
||||
$i = Invoice::query()
|
||||
->where('company_id', $company->id)
|
||||
->whereNull('deleted_at')
|
||||
->where('is_deleted', 0)
|
||||
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
|
||||
->where('is_proforma', 0)
|
||||
->whereNotNull('subscription_id')
|
||||
->where('balance', '>', 0)
|
||||
->whereDate('due_date', '<=', now()->setTimezone($company->timezone()->name)->addDay()->startOfDay())
|
||||
->get();
|
||||
|
||||
}
|
||||
|
||||
$this->assertFalse($i);
|
||||
|
||||
$this->travelTo($timezone_now->copy()->startOfDay());
|
||||
|
||||
if(now()->gte($timezone_now->copy()->startOfDay()) && now()->lt($timezone_now->copy()->startOfDay()->addMinutes(30))) {
|
||||
|
||||
$i = Invoice::query()
|
||||
->where('company_id', $company->id)
|
||||
->whereNull('deleted_at')
|
||||
->where('is_deleted', 0)
|
||||
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
|
||||
->where('is_proforma', 0)
|
||||
->whereNotNull('subscription_id')
|
||||
->whereDate('due_date', '<=', now()->setTimezone($company->timezone()->name)->addDay()->startOfDay())
|
||||
->get();
|
||||
|
||||
}
|
||||
|
||||
$this->assertEquals(1, $i->count());
|
||||
|
||||
$i = false;
|
||||
|
||||
$this->travelTo($timezone_now->copy()->startOfDay()->addHours(2));
|
||||
|
||||
if($timezone_now->gte($timezone_now->copy()->startOfDay()) && $timezone_now->lt($timezone_now->copy()->startOfDay()->addMinutes(30))) {
|
||||
|
||||
$i = Invoice::query()
|
||||
->where('company_id', $company->id)
|
||||
->whereNull('deleted_at')
|
||||
->where('is_deleted', 0)
|
||||
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
|
||||
->where('is_proforma', 0)
|
||||
->whereNotNull('subscription_id')
|
||||
->where('balance', '>', 0)
|
||||
->whereDate('due_date', '<=', now()->setTimezone($company->timezone()->name)->addDay()->startOfDay())
|
||||
->get();
|
||||
|
||||
}
|
||||
|
||||
$this->assertFalse($i);
|
||||
|
||||
$count = Invoice::whereNotNull('subscription_id')->count();
|
||||
|
||||
$this->assertEquals(2, $count);
|
||||
|
||||
$this->travelBack();
|
||||
//////////////////////////////////////////// vienna //////////////////////////////////////////////////
|
||||
|
||||
$company = Company::find($c2->id); //vienna
|
||||
|
||||
$timezone_now = now()->setTimezone($company->timezone()->name);
|
||||
|
||||
$this->assertEquals('Europe/Vienna', $timezone_now->timezoneName);
|
||||
|
||||
$this->travelTo($timezone_now->copy()->startOfDay()->subHour());
|
||||
|
||||
$this->travelTo($timezone_now->copy()->startOfDay()->subHour());
|
||||
|
||||
$i = false;
|
||||
|
||||
//Capture companies within the window of 00:00 and 00:30
|
||||
if($timezone_now->gte($timezone_now->copy()->startOfDay()) && $timezone_now->lt($timezone_now->copy()->startOfDay()->addMinutes(30))) {
|
||||
|
||||
$i = Invoice::query()
|
||||
->where('company_id', $company->id)
|
||||
->whereNull('deleted_at')
|
||||
->where('is_deleted', 0)
|
||||
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
|
||||
->where('is_proforma', 0)
|
||||
->whereNotNull('subscription_id')
|
||||
->where('balance', '>', 0)
|
||||
->whereDate('due_date', '<=', now()->setTimezone($company->timezone()->name)->addDay()->startOfDay())
|
||||
->get();
|
||||
|
||||
}
|
||||
|
||||
$this->assertFalse($i);
|
||||
|
||||
$this->travelTo($timezone_now->copy()->startOfDay());
|
||||
|
||||
if(now()->gte($timezone_now->copy()->startOfDay()) && now()->lt($timezone_now->copy()->startOfDay()->addMinutes(30))) {
|
||||
|
||||
$i = Invoice::query()
|
||||
->where('company_id', $company->id)
|
||||
->whereNull('deleted_at')
|
||||
->where('is_deleted', 0)
|
||||
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
|
||||
->where('is_proforma', 0)
|
||||
->whereNotNull('subscription_id')
|
||||
->whereDate('due_date', '<=', now()->setTimezone($company->timezone()->name)->addDay()->startOfDay())
|
||||
->get();
|
||||
|
||||
}
|
||||
|
||||
$this->assertEquals(1, $i->count());
|
||||
|
||||
$i = false;
|
||||
|
||||
$this->travelTo($timezone_now->copy()->startOfDay()->addHours(2));
|
||||
|
||||
if($timezone_now->gte($timezone_now->copy()->startOfDay()) && $timezone_now->lt($timezone_now->copy()->startOfDay()->addMinutes(30))) {
|
||||
|
||||
$i = Invoice::query()
|
||||
->where('company_id', $company->id)
|
||||
->whereNull('deleted_at')
|
||||
->where('is_deleted', 0)
|
||||
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
|
||||
->where('is_proforma', 0)
|
||||
->whereNotNull('subscription_id')
|
||||
->where('balance', '>', 0)
|
||||
->whereDate('due_date', '<=', now()->setTimezone($company->timezone()->name)->addDay()->startOfDay())
|
||||
->get();
|
||||
|
||||
}
|
||||
|
||||
$this->assertFalse($i);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function testAssignInvoice()
|
||||
{
|
||||
$i = Invoice::factory()
|
||||
|
Loading…
x
Reference in New Issue
Block a user