Merge pull request #8150 from turbo124/preview

Preview
This commit is contained in:
David Bomba 2023-01-14 17:07:07 +11:00 committed by GitHub
commit f5a40f8da2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 79259 additions and 79252 deletions

View File

@ -1 +1 @@
5.5.54 5.5.55

View File

@ -56,7 +56,7 @@ class ReactBuilder extends Command
$directoryIterator = new \RecursiveDirectoryIterator(public_path('react'), \RecursiveDirectoryIterator::SKIP_DOTS); $directoryIterator = new \RecursiveDirectoryIterator(public_path('react'), \RecursiveDirectoryIterator::SKIP_DOTS);
foreach (new \RecursiveIteratorIterator($directoryIterator) as $file) { foreach (new \RecursiveIteratorIterator($directoryIterator) as $file) {
if (str_contains($file->getFileName(), '.js')) { if (str_contains($file->getFileName(), '.js') && !strpos($file->getFileName(), '.json')) {
if (str_contains($file->getFileName(), 'index.')) { if (str_contains($file->getFileName(), 'index.')) {
$includes .= '<script type="module" crossorigin src="/react/'.$file->getFileName().'"></script>'."\n"; $includes .= '<script type="module" crossorigin src="/react/'.$file->getFileName().'"></script>'."\n";
} else { } else {

View File

@ -54,8 +54,9 @@ class BulkInvoiceJob implements ShouldQueue
* @return void * @return void
*/ */
public function handle() public function handle()
{ { //only the reminder should mark the reminder sent field
$this->invoice->service()->touchReminder($this->reminder_template)->markSent()->save(); // $this->invoice->service()->touchReminder($this->reminder_template)->markSent()->save();
$this->invoice->service()->markSent()->save();
$this->invoice->invitations->load('contact.client.country', 'invoice.client.country', 'invoice.company')->each(function ($invitation) { $this->invoice->invitations->load('contact.client.country', 'invoice.client.country', 'invoice.company')->each(function ($invitation) {
EmailEntity::dispatch($invitation, $this->invoice->company, $this->reminder_template)->delay(now()->addSeconds(5)); EmailEntity::dispatch($invitation, $this->invoice->company, $this->reminder_template)->delay(now()->addSeconds(5));

View File

@ -181,6 +181,11 @@ class ClientContact extends Authenticatable implements HasLocalePreference
return $this->hasMany(InvoiceInvitation::class); return $this->hasMany(InvoiceInvitation::class);
} }
public function recurring_invoice_invitations()
{
return $this->hasMany(RecurringInvoiceInvitation::class);
}
public function quote_invitations() public function quote_invitations()
{ {
return $this->hasMany(QuoteInvitation::class); return $this->hasMany(QuoteInvitation::class);

View File

@ -48,6 +48,7 @@ class ClientContactObserver
$clientContact->invoice_invitations()->delete(); $clientContact->invoice_invitations()->delete();
$clientContact->quote_invitations()->delete(); $clientContact->quote_invitations()->delete();
$clientContact->credit_invitations()->delete(); $clientContact->credit_invitations()->delete();
$clientContact->recurring_invoice_invitations()->delete();
} }
/** /**
@ -58,9 +59,9 @@ class ClientContactObserver
*/ */
public function restored(ClientContact $clientContact) public function restored(ClientContact $clientContact)
{ {
$clientContact->invoice_invitations()->restore(); // $clientContact->invoice_invitations()->restore();
$clientContact->quote_invitations()->restore(); // $clientContact->quote_invitations()->restore();
$clientContact->credit_invitations()->restore(); // $clientContact->credit_invitations()->restore();
} }
/** /**

View File

@ -225,6 +225,7 @@ use App\Listeners\User\UpdateUserLastLogin;
use App\Listeners\User\UpdatedUserActivity; use App\Listeners\User\UpdatedUserActivity;
use App\Models\Account; use App\Models\Account;
use App\Models\Client; use App\Models\Client;
use App\Models\ClientContact;
use App\Models\Company; use App\Models\Company;
use App\Models\CompanyGateway; use App\Models\CompanyGateway;
use App\Models\CompanyToken; use App\Models\CompanyToken;
@ -241,6 +242,7 @@ use App\Models\Subscription;
use App\Models\Task; use App\Models\Task;
use App\Models\User; use App\Models\User;
use App\Observers\AccountObserver; use App\Observers\AccountObserver;
use App\Observers\ClientContactObserver;
use App\Observers\ClientObserver; use App\Observers\ClientObserver;
use App\Observers\CompanyGatewayObserver; use App\Observers\CompanyGatewayObserver;
use App\Observers\CompanyObserver; use App\Observers\CompanyObserver;
@ -633,6 +635,7 @@ class EventServiceProvider extends ServiceProvider
Account::observe(AccountObserver::class); Account::observe(AccountObserver::class);
Subscription::observe(SubscriptionObserver::class); Subscription::observe(SubscriptionObserver::class);
Client::observe(ClientObserver::class); Client::observe(ClientObserver::class);
ClientContact::observe(ClientContactObserver::class);
Company::observe(CompanyObserver::class); Company::observe(CompanyObserver::class);
CompanyGateway::observe(CompanyGatewayObserver::class); CompanyGateway::observe(CompanyGatewayObserver::class);
CompanyToken::observe(CompanyTokenObserver::class); CompanyToken::observe(CompanyTokenObserver::class);

View File

@ -257,7 +257,8 @@ class PaymentRepository extends BaseRepository {
$payment = $payment->service()->deletePayment(); $payment = $payment->service()->deletePayment();
event(new PaymentWasDeleted($payment, $payment->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null))); if($payment)
event(new PaymentWasDeleted($payment, $payment->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
return $payment; return $payment;

View File

@ -37,7 +37,7 @@ class ClientService
$this->client->balance += $amount; $this->client->balance += $amount;
$this->client->save(); $this->client->save();
}, 2); }, 1);
} }
catch (\Throwable $throwable) { catch (\Throwable $throwable) {
nlog("DB ERROR " . $throwable->getMessage()); nlog("DB ERROR " . $throwable->getMessage());
@ -58,7 +58,7 @@ class ClientService
$this->client->paid_to_date += $paid_to_date; $this->client->paid_to_date += $paid_to_date;
$this->client->save(); $this->client->save();
}, 2); }, 1);
} }
catch (\Throwable $throwable) { catch (\Throwable $throwable) {
nlog("DB ERROR " . $throwable->getMessage()); nlog("DB ERROR " . $throwable->getMessage());
@ -79,7 +79,7 @@ class ClientService
$this->client->paid_to_date += $amount; $this->client->paid_to_date += $amount;
$this->client->save(); $this->client->save();
}, 2); }, 1);
return $this; return $this;
} }

View File

@ -25,6 +25,7 @@ use App\Models\Payment;
use App\Models\PaymentHash; use App\Models\PaymentHash;
use App\Models\SystemLog; use App\Models\SystemLog;
use App\Services\Subscription\SubscriptionService; use App\Services\Subscription\SubscriptionService;
use App\Utils\Ninja;
use App\Utils\Number; use App\Utils\Number;
use App\Utils\Traits\MakesDates; use App\Utils\Traits\MakesDates;
use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesHash;
@ -195,13 +196,14 @@ class InstantPayment
$credit_totals = $first_invoice->client->getSetting('use_credits_payment') == 'always' ? $first_invoice->client->service()->getCreditBalance() : 0; $credit_totals = $first_invoice->client->getSetting('use_credits_payment') == 'always' ? $first_invoice->client->service()->getCreditBalance() : 0;
$starting_invoice_amount = $first_invoice->balance; $starting_invoice_amount = $first_invoice->balance;
/* Schedule a job to check the gateway fees for this invoice*/
if(Ninja::isHosted())
CheckGatewayFee::dispatch($first_invoice->id, $client->company->db)->delay(600);
if ($gateway) { if ($gateway) {
$first_invoice->service()->addGatewayFee($gateway, $payment_method_id, $invoice_totals)->save(); $first_invoice->service()->addGatewayFee($gateway, $payment_method_id, $invoice_totals)->save();
} }
/* Schedule a job to check the gateway fees for this invoice*/
CheckGatewayFee::dispatch($first_invoice->id, $client->company->db)->delay(600);
/** /**
* Gateway fee is calculated * Gateway fee is calculated
* by adding it as a line item, and then subtract * by adding it as a line item, and then subtract

View File

@ -38,22 +38,21 @@ class DeletePayment
\DB::connection(config('database.default'))->transaction(function () { \DB::connection(config('database.default'))->transaction(function () {
if ($this->payment->is_deleted) {
return $this->payment;
}
$this->payment = Payment::withTrashed()->where('id', $this->payment->id)->lockForUpdate()->first(); $this->payment = Payment::withTrashed()->where('id', $this->payment->id)->lockForUpdate()->first();
$this->setStatus(Payment::STATUS_CANCELLED) //sets status of payment if (!$this->payment->is_deleted) {
->updateCreditables() //return the credits first
->adjustInvoices() $this->setStatus(Payment::STATUS_CANCELLED) //sets status of payment
->deletePaymentables() ->updateCreditables() //return the credits first
->cleanupPayment() ->adjustInvoices()
->save(); ->deletePaymentables()
->cleanupPayment()
->save();
}
}, 2); }, 1);
return $this->payment; return $this->payment;

View File

@ -14,8 +14,8 @@ return [
'require_https' => env('REQUIRE_HTTPS', true), 'require_https' => env('REQUIRE_HTTPS', true),
'app_url' => rtrim(env('APP_URL', ''), '/'), 'app_url' => rtrim(env('APP_URL', ''), '/'),
'app_domain' => env('APP_DOMAIN', 'invoicing.co'), 'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
'app_version' => '5.5.54', 'app_version' => '5.5.55',
'app_tag' => '5.5.54', 'app_tag' => '5.5.55',
'minimum_client_version' => '5.0.16', 'minimum_client_version' => '5.0.16',
'terms_version' => '1.0.1', 'terms_version' => '1.0.1',
'api_secret' => env('API_SECRET', ''), 'api_secret' => env('API_SECRET', ''),

View File

@ -10,12 +10,12 @@ const RESOURCES = {
"icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35", "icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35",
"icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed", "icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed",
"version.json": "43e72e92e1557ca9db0b6a8ef41236ef", "version.json": "43e72e92e1557ca9db0b6a8ef41236ef",
"main.dart.js": "ecdb40eb2ef34a3c1dd83b20ba310466", "main.dart.js": "cd104c4e8a2ea6cf387c4a33bbdd1378",
"canvaskit/canvaskit.js": "2bc454a691c631b07a9307ac4ca47797", "canvaskit/canvaskit.js": "2bc454a691c631b07a9307ac4ca47797",
"canvaskit/profiling/canvaskit.js": "38164e5a72bdad0faa4ce740c9b8e564", "canvaskit/profiling/canvaskit.js": "38164e5a72bdad0faa4ce740c9b8e564",
"canvaskit/profiling/canvaskit.wasm": "95a45378b69e77af5ed2bc72b2209b94", "canvaskit/profiling/canvaskit.wasm": "95a45378b69e77af5ed2bc72b2209b94",
"canvaskit/canvaskit.wasm": "bf50631470eb967688cca13ee181af62", "canvaskit/canvaskit.wasm": "bf50631470eb967688cca13ee181af62",
"/": "6cd8c3a7362a881cbf233dccce721f09", "/": "2e1433054772c16bc5262ec08e7095f3",
"assets/AssetManifest.json": "759f9ef9973f7e26c2a51450b55bb9fa", "assets/AssetManifest.json": "759f9ef9973f7e26c2a51450b55bb9fa",
"assets/packages/intl_phone_field/assets/flags/pf.png": "1ae72c24380d087cbe2d0cd6c3b58821", "assets/packages/intl_phone_field/assets/flags/pf.png": "1ae72c24380d087cbe2d0cd6c3b58821",
"assets/packages/intl_phone_field/assets/flags/fi.png": "3ccd69a842e55183415b7ea2c04b15c8", "assets/packages/intl_phone_field/assets/flags/fi.png": "3ccd69a842e55183415b7ea2c04b15c8",

79637
public/main.dart.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

78101
public/main.foss.dart.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,148 +0,0 @@
<?php
namespace Tests\Feature\Scheduler;
use App\Export\CSV\ClientExport;
use App\Models\Scheduler;
use App\Utils\Traits\MakesHash;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutEvents;
use Illuminate\Routing\Middleware\ThrottleRequests;
use Illuminate\Support\Facades\Session;
use Illuminate\Validation\ValidationException;
use Tests\MockUnitData;
use Tests\TestCase;
class SchedulerTest extends TestCase
{
use MakesHash;
use MockUnitData;
use WithoutEvents;
// use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
Session::start();
$this->faker = \Faker\Factory::create();
Model::reguard();
$this->makeTestData();
$this->withoutMiddleware(
ThrottleRequests::class
);
// $this->withoutExceptionHandling();
}
public function testSchedulerCantBeCreatedWithWrongData()
{
$data = [
'repeat_every' => Scheduler::DAILY,
'job' => Scheduler::CREATE_CLIENT_REPORT,
'date_key' => '123',
'report_keys' => ['test'],
'date_range' => 'all',
// 'start_from' => '2022-01-01'
];
$response = false;
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/task_scheduler/', $data);
$response->assertSessionHasErrors();
}
public function testSchedulerCanBeUpdated()
{
$response = $this->createScheduler();
$arr = $response->json();
$id = $arr['data']['id'];
$scheduler = Scheduler::find($this->decodePrimaryKey($id));
$updateData = [
'start_from' => 1655934741,
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->put('/api/v1/task_scheduler/'.$this->encodePrimaryKey($scheduler->id), $updateData);
$responseData = $response->json();
$this->assertEquals($updateData['start_from'], $responseData['data']['start_from']);
}
public function testSchedulerCanBeSeen()
{
$response = $this->createScheduler();
$arr = $response->json();
$id = $arr['data']['id'];
$scheduler = Scheduler::find($this->decodePrimaryKey($id));
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get('/api/v1/task_scheduler/'.$this->encodePrimaryKey($scheduler->id));
$arr = $response->json();
$this->assertEquals('create_client_report', $arr['data']['action_name']);
}
public function testSchedulerJobCanBeUpdated()
{
$response = $this->createScheduler();
$arr = $response->json();
$id = $arr['data']['id'];
$scheduler = Scheduler::find($this->decodePrimaryKey($id));
$this->assertSame('create_client_report', $scheduler->action_name);
$updateData = [
'job' => Scheduler::CREATE_CREDIT_REPORT,
'date_range' => 'all',
'report_keys' => ['test1'],
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->put('/api/v1/task_scheduler/'.$this->encodePrimaryKey($scheduler->id), $updateData);
$updatedSchedulerJob = Scheduler::first()->action_name;
$arr = $response->json();
$this->assertSame('create_credit_report', $arr['data']['action_name']);
}
public function createScheduler()
{
$data = [
'repeat_every' => Scheduler::DAILY,
'job' => Scheduler::CREATE_CLIENT_REPORT,
'date_key' => '123',
'report_keys' => ['test'],
'date_range' => 'all',
'start_from' => '2022-01-01',
];
return $response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/task_scheduler/', $data);
}
}