Merge pull request #8405 from turbo124/v5-develop

Fixes for recurring price increases/updates
This commit is contained in:
David Bomba 2023-03-30 07:59:52 +11:00 committed by GitHub
commit 6f9969fc07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 568 additions and 12 deletions

View File

@ -40,6 +40,8 @@ class UpdateRecurring implements ShouldQueue
{ {
MultiDB::setDb($this->company->db); MultiDB::setDb($this->company->db);
$this->user->setCompany($this->company);
RecurringInvoice::where('company_id', $this->company->id) RecurringInvoice::where('company_id', $this->company->id)
->whereIn('id', $this->ids) ->whereIn('id', $this->ids)
->chunk(100, function ($recurring_invoices) { ->chunk(100, function ($recurring_invoices) {

View File

@ -39,7 +39,6 @@ class PaymentNotification implements ShouldQueue
* Handle the event. * Handle the event.
* *
* @param object $event * @param object $event
* @return bool
*/ */
public function handle($event) public function handle($event)
{ {
@ -51,6 +50,15 @@ class PaymentNotification implements ShouldQueue
$payment = $event->payment; $payment = $event->payment;
/*Google Analytics Track Revenue*/
if (isset($payment->company->google_analytics_key)) {
$this->trackRevenue($event);
}
if($payment->is_manual)
return;
/*User notifications*/ /*User notifications*/
foreach ($payment->company->company_users as $company_user) { foreach ($payment->company->company_users as $company_user) {
$user = $company_user->user; $user = $company_user->user;
@ -80,10 +88,6 @@ class PaymentNotification implements ShouldQueue
} }
} }
/*Google Analytics Track Revenue*/
if (isset($payment->company->google_analytics_key)) {
$this->trackRevenue($event);
}
} }
private function trackRevenue($event) private function trackRevenue($event)

View File

@ -120,4 +120,11 @@ class AppServiceProvider extends ServiceProvider
Artisan::call('db:seed'); Artisan::call('db:seed');
}); });
} }
public function register(): void
{
if (Ninja::isHosted()) {
$this->app->register(\App\Providers\BroadcastServiceProvider::class);
}
}
} }

View File

@ -26,17 +26,19 @@ class UpdatePrice extends AbstractService
$line_items = $this->recurring_invoice->line_items; $line_items = $this->recurring_invoice->line_items;
foreach ($line_items as $key => $line_item) { foreach ($line_items as $key => $line_item) {
$product = Product::where('company_id', $this->recurring_invoice->company_id) $product = Product::where('company_id', $this->recurring_invoice->company_id)
->where('product_key', $line_item->product_key) ->where('product_key', $line_item->product_key)
->where('is_deleted', 0) ->where('is_deleted', 0)
->first(); ->first();
if ($product) { if ($product) {
$line_items[$key]->cost = $product->cost; $line_items[$key]->cost = floatval($product->cost);
} }
} }
$this->recurring_invoice->line_items = $line_items; $this->recurring_invoice->line_items = $line_items;
$this->recurring_invoice->calc()->getInvoice()->save(); $this->recurring_invoice->calc()->getInvoice()->save();
} }
} }

View File

@ -194,7 +194,7 @@ return [
*/ */
App\Providers\AppServiceProvider::class, App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class, App\Providers\AuthServiceProvider::class,
App\Providers\BroadcastServiceProvider::class, // App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class, App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class, App\Providers\RouteServiceProvider::class,
App\Providers\ComposerServiceProvider::class, App\Providers\ComposerServiceProvider::class,

View File

@ -5015,6 +5015,22 @@ $LANG = array(
'restored_payment_link' => 'Successfully restored payment link', 'restored_payment_link' => 'Successfully restored payment link',
'search_payment_link' => 'Search 1 Payment Link', 'search_payment_link' => 'Search 1 Payment Link',
'search_payment_links' => 'Search :count Payment Links', 'search_payment_links' => 'Search :count Payment Links',
'increase_prices' => 'Increase Prices',
'update_prices' => 'Update Prices',
'incresed_prices' => 'Successfully queued prices to be increased',
'updated_prices' => 'Successfully queued prices to be updated',
'api_token' => 'API Token',
'api_key' => 'API Key',
'endpoint' => 'Endpoint',
'not_billable' => 'Not Billable',
'allow_billable_task_items' => 'Allow Billable Task Items',
'allow_billable_task_items_help' => 'Enable configuring which task items are billed',
'show_task_item_description' => 'Show Task Item Description',
'show_task_item_description_help' => 'Enable specifying task item descriptions',
'email_record' => 'Email Record',
'invoice_product_columns' => 'Invoice Product Columns',
'quote_product_columns' => 'Quote Product Columns',
'vendors' => 'Vendors',
); );

View File

@ -56,6 +56,8 @@ class RecurringInvoiceTest extends TestCase
$this->makeTestData(); $this->makeTestData();
} }
public function testBulkIncreasePriceWithJob() public function testBulkIncreasePriceWithJob()
{ {
@ -561,4 +563,5 @@ class RecurringInvoiceTest extends TestCase
$this->assertEquals(null, $invoice->subscription_id); $this->assertEquals(null, $invoice->subscription_id);
} }
} }

View File

@ -11,12 +11,21 @@
namespace Tests\Unit; namespace Tests\Unit;
use App\Factory\RecurringInvoiceFactory;
use App\Models\RecurringInvoice;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Carbon;
use Tests\MockAccountData;
use Tests\TestCase; use Tests\TestCase;
use App\Models\User;
use App\Models\Client;
use App\Models\Account;
use App\Models\Company;
use Tests\MockAccountData;
use App\Models\ClientContact;
use Illuminate\Support\Carbon;
use App\Utils\Traits\MakesHash;
use App\Models\RecurringInvoice;
use App\DataMapper\CompanySettings;
use App\DataMapper\DefaultSettings;
use App\Factory\RecurringInvoiceFactory;
use App\Factory\InvoiceToRecurringInvoiceFactory;
use Illuminate\Foundation\Testing\DatabaseTransactions;
/** /**
* @test * @test
@ -24,6 +33,7 @@ use Tests\TestCase;
*/ */
class RecurringDatesTest extends TestCase class RecurringDatesTest extends TestCase
{ {
use MakesHash;
use MockAccountData; use MockAccountData;
use DatabaseTransactions; use DatabaseTransactions;
@ -34,6 +44,518 @@ class RecurringDatesTest extends TestCase
$this->makeTestData(); $this->makeTestData();
} }
public function testDailyFrequencyCalc6()
{
$this->travelTo(now()->subHours(8));
$account = Account::factory()->create();
$settings = CompanySettings::defaults();
$settings->entity_send_time = '1';
$settings->timezone_id = '113';
$company = Company::factory()->create([
'account_id' => $account->id,
'settings' => $settings,
]);
$account->default_company_id = $company->id;
$account->save();
$user = User::factory()->create([
'account_id' => $account->id,
'confirmation_code' => $this->createDbHash(config('database.default')),
'email' => 'whiz@gmail.com',
]);
$userPermissions = collect([
'view_invoice',
'view_client',
'edit_client',
'edit_invoice',
'create_invoice',
'create_client',
]);
$userSettings = DefaultSettings::userSettings();
$user->companies()->attach($company->id, [
'account_id' => $account->id,
'is_owner' => 1,
'is_admin' => 1,
'notifications' => CompanySettings::notificationDefaults(),
'permissions' => $userPermissions->toJson(),
'settings' => json_encode($userSettings),
'is_locked' => 0,
]);
$client = Client::factory()->create(['user_id' => $user->id, 'company_id' => $company->id]);
ClientContact::factory()->create([
'user_id' => $user->id,
'client_id' => $client->id,
'company_id' => $company->id,
'is_primary' => 1,
]);
$recurring_invoice = RecurringInvoice::factory()->create([
'user_id' => $user->id,
'company_id' => $company->id,
'client_id' => $client->id,
'frequency_id' => RecurringInvoice::FREQUENCY_DAILY,
'next_send_date' => now()->format('Y-m-d'),
'next_send_date_client' => now()->format('Y-m-d'),
'date' => now()->format('Y-m-d'),
'remaining_cycles' => -1,
'status_id' => 1,
]);
$recurring_invoice->service()->start()->save();
$this->assertEquals('1', $client->getSetting('entity_send_time'));
$this->assertEquals('113', $client->getSetting('timezone_id'));
$this->assertEquals(now()->format('Y-m-d'), Carbon::parse($recurring_invoice->next_send_date)->format('Y-m-d'));
$this->assertEquals(now()->format('Y-m-d'), Carbon::parse($recurring_invoice->next_send_date_client)->format('Y-m-d'));
$recurring_invoice->next_send_date = $recurring_invoice->nextSendDate();
$recurring_invoice->next_send_date_client = $recurring_invoice->nextSendDateClient();
$recurring_invoice->save();
$this->assertEquals(now()->startOfDay()->addDay()->addSeconds($client->timezone_offset()), Carbon::parse($recurring_invoice->next_send_date));
$this->assertEquals(now()->addDay()->format('Y-m-d'), Carbon::parse($recurring_invoice->next_send_date_client)->format('Y-m-d'));
$recurring_invoice->next_send_date = $recurring_invoice->nextSendDate();
$recurring_invoice->next_send_date_client = $recurring_invoice->nextSendDateClient();
$recurring_invoice->save();
$this->assertEquals(now()->startOfDay()->addDays(2)->addSeconds($client->timezone_offset()), Carbon::parse($recurring_invoice->next_send_date));
$this->assertEquals(now()->addDays(2)->format('Y-m-d'), Carbon::parse($recurring_invoice->next_send_date_client)->format('Y-m-d'));
$this->travelBack();
}
public function testDailyFrequencyCalc5()
{
$account = Account::factory()->create();
$settings = CompanySettings::defaults();
$settings->entity_send_time = '23';
$settings->timezone_id = '113';
$company = Company::factory()->create([
'account_id' => $account->id,
'settings' => $settings,
]);
$account->default_company_id = $company->id;
$account->save();
$user = User::factory()->create([
'account_id' => $account->id,
'confirmation_code' => $this->createDbHash(config('database.default')),
'email' => 'whiz@gmail.com',
]);
$userPermissions = collect([
'view_invoice',
'view_client',
'edit_client',
'edit_invoice',
'create_invoice',
'create_client',
]);
$userSettings = DefaultSettings::userSettings();
$user->companies()->attach($company->id, [
'account_id' => $account->id,
'is_owner' => 1,
'is_admin' => 1,
'notifications' => CompanySettings::notificationDefaults(),
'permissions' => $userPermissions->toJson(),
'settings' => json_encode($userSettings),
'is_locked' => 0,
]);
$client = Client::factory()->create(['user_id' => $user->id, 'company_id' => $company->id]);
ClientContact::factory()->create([
'user_id' => $user->id,
'client_id' => $client->id,
'company_id' => $company->id,
'is_primary' => 1,
]);
$recurring_invoice = RecurringInvoice::factory()->create([
'user_id' => $user->id,
'company_id' => $company->id,
'client_id' => $client->id,
'frequency_id' => RecurringInvoice::FREQUENCY_DAILY,
'next_send_date' => now()->format('Y-m-d'),
'next_send_date_client' => now()->format('Y-m-d'),
'date' => now()->format('Y-m-d'),
'remaining_cycles' => -1,
'status_id' => 1,
]);
$recurring_invoice->service()->start()->save();
$this->assertEquals('23', $client->getSetting('entity_send_time'));
$this->assertEquals('113', $client->getSetting('timezone_id'));
$this->assertEquals(now()->format('Y-m-d'), Carbon::parse($recurring_invoice->next_send_date)->format('Y-m-d'));
$this->assertEquals(now()->format('Y-m-d'), Carbon::parse($recurring_invoice->next_send_date_client)->format('Y-m-d'));
$recurring_invoice->next_send_date = $recurring_invoice->nextSendDate();
$recurring_invoice->next_send_date_client = $recurring_invoice->nextSendDateClient();
$recurring_invoice->save();
$this->assertEquals(now()->startOfDay()->addDay()->addSeconds($client->timezone_offset()), Carbon::parse($recurring_invoice->next_send_date));
$this->assertEquals(now()->addDay()->format('Y-m-d'), Carbon::parse($recurring_invoice->next_send_date_client)->format('Y-m-d'));
}
public function testDailyFrequencyCalc4()
{
$account = Account::factory()->create();
$settings = CompanySettings::defaults();
$settings->entity_send_time = '6';
$settings->timezone_id = '1';
$company = Company::factory()->create([
'account_id' => $account->id,
'settings' => $settings,
]);
$account->default_company_id = $company->id;
$account->save();
$user = User::factory()->create([
'account_id' => $account->id,
'confirmation_code' => $this->createDbHash(config('database.default')),
'email' => 'whiz@gmail.com',
]);
$userPermissions = collect([
'view_invoice',
'view_client',
'edit_client',
'edit_invoice',
'create_invoice',
'create_client',
]);
$userSettings = DefaultSettings::userSettings();
$user->companies()->attach($company->id, [
'account_id' => $account->id,
'is_owner' => 1,
'is_admin' => 1,
'notifications' => CompanySettings::notificationDefaults(),
'permissions' => $userPermissions->toJson(),
'settings' => json_encode($userSettings),
'is_locked' => 0,
]);
$client = Client::factory()->create(['user_id' => $user->id, 'company_id' => $company->id]);
ClientContact::factory()->create([
'user_id' => $user->id,
'client_id' => $client->id,
'company_id' => $company->id,
'is_primary' => 1,
]);
$recurring_invoice = RecurringInvoice::factory()->create([
'user_id' => $user->id,
'company_id' => $company->id,
'client_id' => $client->id,
'frequency_id' => RecurringInvoice::FREQUENCY_DAILY,
'next_send_date' => now()->format('Y-m-d'),
'next_send_date_client' => now()->format('Y-m-d'),
'date' => now()->format('Y-m-d'),
'remaining_cycles' => -1,
'status_id' => 1,
]);
$recurring_invoice->service()->start()->save();
$this->assertEquals('6', $client->getSetting('entity_send_time'));
$this->assertEquals('1', $client->getSetting('timezone_id'));
$this->assertEquals(now()->format('Y-m-d'), Carbon::parse($recurring_invoice->next_send_date)->format('Y-m-d'));
$this->assertEquals(now()->format('Y-m-d'), Carbon::parse($recurring_invoice->next_send_date_client)->format('Y-m-d'));
$recurring_invoice->next_send_date = $recurring_invoice->nextSendDate();
$recurring_invoice->next_send_date_client = $recurring_invoice->nextSendDateClient();
$recurring_invoice->save();
$this->assertEquals(now()->startOfDay()->addDay()->addSeconds($client->timezone_offset()), Carbon::parse($recurring_invoice->next_send_date));
$this->assertEquals(now()->addDay()->format('Y-m-d'), Carbon::parse($recurring_invoice->next_send_date_client)->format('Y-m-d'));
}
public function testDailyFrequencyCalc3()
{
$account = Account::factory()->create();
$settings = CompanySettings::defaults();
$settings->entity_send_time = '1';
$settings->timezone_id = '1';
$company = Company::factory()->create([
'account_id' => $account->id,
'settings' => $settings,
]);
$account->default_company_id = $company->id;
$account->save();
$user = User::factory()->create([
'account_id' => $account->id,
'confirmation_code' => $this->createDbHash(config('database.default')),
'email' => 'whiz@gmail.com',
]);
$userPermissions = collect([
'view_invoice',
'view_client',
'edit_client',
'edit_invoice',
'create_invoice',
'create_client',
]);
$userSettings = DefaultSettings::userSettings();
$user->companies()->attach($company->id, [
'account_id' => $account->id,
'is_owner' => 1,
'is_admin' => 1,
'notifications' => CompanySettings::notificationDefaults(),
'permissions' => $userPermissions->toJson(),
'settings' => json_encode($userSettings),
'is_locked' => 0,
]);
$client = Client::factory()->create(['user_id' => $user->id, 'company_id' => $company->id]);
ClientContact::factory()->create([
'user_id' => $user->id,
'client_id' => $client->id,
'company_id' => $company->id,
'is_primary' => 1,
]);
$this->assertEquals('1', $client->getSetting('entity_send_time'));
$this->assertEquals('1', $client->getSetting('timezone_id'));
$recurring_invoice = RecurringInvoice::factory()->create([
'user_id' => $user->id,
'company_id' => $company->id,
'client_id' => $client->id,
'frequency_id' => RecurringInvoice::FREQUENCY_DAILY,
'next_send_date' => now()->format('Y-m-d'),
'next_send_date_client' => now()->format('Y-m-d'),
'date' => now()->format('Y-m-d'),
'remaining_cycles' => -1,
'status_id' => 1,
]);
$recurring_invoice->service()->start()->save();
$this->assertEquals(now()->format('Y-m-d'), Carbon::parse($recurring_invoice->next_send_date)->format('Y-m-d'));
$this->assertEquals(now()->format('Y-m-d'), Carbon::parse($recurring_invoice->next_send_date_client)->format('Y-m-d'));
$recurring_invoice->next_send_date = $recurring_invoice->nextSendDate();
$recurring_invoice->next_send_date_client = $recurring_invoice->nextSendDateClient();
$recurring_invoice->save();
$this->assertEquals(now()->startOfDay()->addDay()->addSeconds($client->timezone_offset()), Carbon::parse($recurring_invoice->next_send_date));
$this->assertEquals(now()->addDay()->format('Y-m-d'), Carbon::parse($recurring_invoice->next_send_date_client)->format('Y-m-d'));
}
public function testDailyFrequencyCalc2()
{
$account = Account::factory()->create();
$settings = CompanySettings::defaults();
$settings->entity_send_time = '23';
$settings->timezone_id = '113';
$company = Company::factory()->create([
'account_id' => $account->id,
'settings' => $settings,
]);
$account->default_company_id = $company->id;
$account->save();
$user = User::factory()->create([
'account_id' => $account->id,
'confirmation_code' => $this->createDbHash(config('database.default')),
'email' => 'whiz@gmail.com',
]);
$userPermissions = collect([
'view_invoice',
'view_client',
'edit_client',
'edit_invoice',
'create_invoice',
'create_client',
]);
$userSettings = DefaultSettings::userSettings();
$user->companies()->attach($company->id, [
'account_id' => $account->id,
'is_owner' => 1,
'is_admin' => 1,
'notifications' => CompanySettings::notificationDefaults(),
'permissions' => $userPermissions->toJson(),
'settings' => json_encode($userSettings),
'is_locked' => 0,
]);
$client = Client::factory()->create(['user_id' => $user->id, 'company_id' => $company->id]);
ClientContact::factory()->create([
'user_id' => $user->id,
'client_id' => $client->id,
'company_id' => $company->id,
'is_primary' => 1,
]);
$this->assertEquals('23', $client->getSetting('entity_send_time'));
$this->assertEquals('113', $client->getSetting('timezone_id'));
$recurring_invoice = RecurringInvoice::factory()->create([
'user_id' => $user->id,
'company_id' => $company->id,
'client_id' => $client->id,
'frequency_id' => RecurringInvoice::FREQUENCY_DAILY,
'next_send_date' => now()->format('Y-m-d'),
'next_send_date_client' => now()->format('Y-m-d'),
'date' => now()->format('Y-m-d'),
'remaining_cycles' => -1,
'status_id' => 1,
]);
$recurring_invoice->service()->start()->save();
$this->assertEquals(now()->format('Y-m-d'), Carbon::parse($recurring_invoice->next_send_date)->format('Y-m-d'));
$this->assertEquals(now()->format('Y-m-d'), Carbon::parse($recurring_invoice->next_send_date_client)->format('Y-m-d'));
$recurring_invoice->next_send_date = $recurring_invoice->nextSendDate();
$recurring_invoice->next_send_date_client = $recurring_invoice->nextSendDateClient();
$recurring_invoice->save();
$this->assertEquals(now()->startOfDay()->addDay()->addSeconds($client->timezone_offset()), Carbon::parse($recurring_invoice->next_send_date));
$this->assertEquals(now()->addDay()->format('Y-m-d'), Carbon::parse($recurring_invoice->next_send_date_client)->format('Y-m-d'));
}
public function testDailyFrequencyCalc()
{
$account = Account::factory()->create();
$settings = CompanySettings::defaults();
$settings->entity_send_time = '1';
$settings->timezone_id = '113';
$company = Company::factory()->create([
'account_id' => $account->id,
'settings' => $settings,
]);
$account->default_company_id = $company->id;
$account->save();
$user = User::factory()->create([
'account_id' => $account->id,
'confirmation_code' => $this->createDbHash(config('database.default')),
'email' => 'whiz@gmail.com',
]);
$userPermissions = collect([
'view_invoice',
'view_client',
'edit_client',
'edit_invoice',
'create_invoice',
'create_client',
]);
$userSettings = DefaultSettings::userSettings();
$user->companies()->attach($company->id, [
'account_id' => $account->id,
'is_owner' => 1,
'is_admin' => 1,
'notifications' => CompanySettings::notificationDefaults(),
'permissions' => $userPermissions->toJson(),
'settings' => json_encode($userSettings),
'is_locked' => 0,
]);
$client = Client::factory()->create(['user_id' => $user->id, 'company_id' => $company->id]);
ClientContact::factory()->create([
'user_id' => $user->id,
'client_id' => $client->id,
'company_id' => $company->id,
'is_primary' => 1,
]);
$this->assertEquals('1', $client->getSetting('entity_send_time'));
$this->assertEquals('113', $client->getSetting('timezone_id'));
$recurring_invoice = RecurringInvoice::factory()->create([
'user_id' => $user->id,
'company_id' => $company->id,
'client_id' => $client->id,
'frequency_id' => RecurringInvoice::FREQUENCY_DAILY,
'next_send_date' => now()->format('Y-m-d'),
'next_send_date_client' => now()->format('Y-m-d'),
'date' => now()->format('Y-m-d'),
'remaining_cycles' => -1,
'status_id' => 1,
]);
$recurring_invoice->service()->start()->save();
$this->assertEquals(now()->format('Y-m-d'), Carbon::parse($recurring_invoice->next_send_date)->format('Y-m-d'));
$this->assertEquals(now()->format('Y-m-d'), Carbon::parse($recurring_invoice->next_send_date_client)->format('Y-m-d'));
$recurring_invoice->next_send_date = $recurring_invoice->nextSendDate();
$recurring_invoice->next_send_date_client = $recurring_invoice->nextSendDateClient();
$recurring_invoice->save();
$this->assertEquals(now()->startOfDay()->addDay()->addSeconds($client->timezone_offset()), Carbon::parse($recurring_invoice->next_send_date));
$this->assertEquals(now()->addDay()->format('Y-m-d'), Carbon::parse($recurring_invoice->next_send_date_client)->format('Y-m-d'));
}
public function testRecurringDatesDraftInvoice() public function testRecurringDatesDraftInvoice()
{ {
$recurring_invoice = RecurringInvoiceFactory::create($this->company->id, $this->user->id); $recurring_invoice = RecurringInvoiceFactory::create($this->company->id, $this->user->id);