From ebb03e945ba40fe9f8458895ea1f98d2d3b7c85f Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 31 Jul 2022 15:56:57 +1000 Subject: [PATCH 01/26] Minor fixes for routes --- routes/api.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/routes/api.php b/routes/api.php index 7ee9da841403..db70b3de13d1 100644 --- a/routes/api.php +++ b/routes/api.php @@ -332,11 +332,11 @@ Route::group(['middleware' => ['throttle:300,1', 'api_db', 'token_auth', 'locale }); -Route::match(['get', 'post'], 'payment_webhook/{company_key}/{company_gateway_id}', [PaymentWebhookController::class]) +Route::match(['get', 'post'], 'payment_webhook/{company_key}/{company_gateway_id}', PaymentWebhookController::class) ->middleware(['throttle:1000,1','guest']) ->name('payment_webhook'); -Route::match(['get', 'post'], 'payment_notification_webhook/{company_key}/{company_gateway_id}/{client}', [PaymentNotificationWebhookController::class]) +Route::match(['get', 'post'], 'payment_notification_webhook/{company_key}/{company_gateway_id}/{client}', PaymentNotificationWebhookController::class) ->middleware(['throttle:1000,1', 'guest']) ->name('payment_notification_webhook'); From 48c36d000468296928066a236e2fac36b4339f57 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 31 Jul 2022 19:11:32 +1000 Subject: [PATCH 02/26] Fixes for mailers --- app/Helpers/Mail/GmailTransport.php | 4 +- app/Helpers/Mail/Office365MailTransport.php | 4 +- app/Http/Controllers/ImportController.php | 3 +- app/Http/Middleware/QueryLogging.php | 10 +-- app/Jobs/Import/CSVIngest.php | 14 +--- app/Jobs/Mail/NinjaMailerJob.php | 4 +- app/Mail/TemplateEmail.php | 2 + app/Mail/VendorTemplateEmail.php | 2 + app/Services/Credit/SendEmail.php | 5 +- app/Services/Invoice/InvoiceService.php | 6 +- config/logging.php | 2 +- config/services.php | 85 ++++++++++----------- routes/api.php | 8 +- routes/client.php | 2 +- 14 files changed, 73 insertions(+), 78 deletions(-) diff --git a/app/Helpers/Mail/GmailTransport.php b/app/Helpers/Mail/GmailTransport.php index b88c124aa88b..4117e710fdbe 100644 --- a/app/Helpers/Mail/GmailTransport.php +++ b/app/Helpers/Mail/GmailTransport.php @@ -34,8 +34,8 @@ class GmailTransport extends AbstractTransport nlog("in Do Send"); $message = MessageConverter::toEmail($message->getOriginalMessage()); - $token = $message->getHeaders()->get('GmailToken')->getValue(); - $message->getHeaders()->remove('GmailToken'); + $token = $message->getHeaders()->get('gmailtoken')->getValue(); + $message->getHeaders()->remove('gmailtoken'); $client = new Client(); $client->setClientId(config('ninja.auth.google.client_id')); diff --git a/app/Helpers/Mail/Office365MailTransport.php b/app/Helpers/Mail/Office365MailTransport.php index f50f3d8e0043..a4fa9d5e790f 100644 --- a/app/Helpers/Mail/Office365MailTransport.php +++ b/app/Helpers/Mail/Office365MailTransport.php @@ -33,8 +33,8 @@ class Office365MailTransport extends AbstractTransport $symfony_message = MessageConverter::toEmail($message->getOriginalMessage()); $graph = new Graph(); - $token = $symfony_message->getHeaders()->get('GmailToken')->getValue(); - $symfony_message->getHeaders()->remove('GmailToken'); + $token = $symfony_message->getHeaders()->get('gmailtoken')->getValue(); + $symfony_message->getHeaders()->remove('gmailtoken'); $graph->setAccessToken($token); diff --git a/app/Http/Controllers/ImportController.php b/app/Http/Controllers/ImportController.php index 6447ae292375..f7ec7670d2a9 100644 --- a/app/Http/Controllers/ImportController.php +++ b/app/Http/Controllers/ImportController.php @@ -105,7 +105,7 @@ class ImportController extends Controller public function import(ImportRequest $request) { $data = $request->all(); -nlog($data); + if (empty($data['hash'])) { // Create a reference $data['hash'] = $hash = Str::random(32); @@ -113,7 +113,6 @@ nlog($data); /** @var UploadedFile $file */ foreach ($request->files->get('files') as $entityType => $file) { $contents = file_get_contents($file->getPathname()); - // Store the csv in cache with an expiry of 10 minutes Cache::put($hash.'-'.$entityType, base64_encode($contents), 600); } diff --git a/app/Http/Middleware/QueryLogging.php b/app/Http/Middleware/QueryLogging.php index ee85701612a3..0bf364225054 100644 --- a/app/Http/Middleware/QueryLogging.php +++ b/app/Http/Middleware/QueryLogging.php @@ -35,9 +35,9 @@ class QueryLogging { // Enable query logging for development - if (! Ninja::isHosted() || ! config('beacon.enabled')) { - return $next($request); - } + // if (! Ninja::isHosted() || ! config('beacon.enabled')) { + // return $next($request); + // } $timeStart = microtime(true); DB::enableQueryLog(); @@ -50,8 +50,8 @@ class QueryLogging $timeEnd = microtime(true); $time = $timeEnd - $timeStart; - nlog("Query count = {$count}"); - nlog($queries); + // nlog("Query count = {$count}"); + // nlog($queries); if ($count > 175) { nlog("Query count = {$count}"); diff --git a/app/Jobs/Import/CSVIngest.php b/app/Jobs/Import/CSVIngest.php index 05fea37a0e72..5313050be057 100644 --- a/app/Jobs/Import/CSVIngest.php +++ b/app/Jobs/Import/CSVIngest.php @@ -72,7 +72,7 @@ class CSVIngest implements ShouldQueue set_time_limit(0); - $engine = $this->bootEngine($this->import_type); + $engine = $this->bootEngine(); foreach (['client', 'product', 'invoice', 'payment', 'vendor', 'expense'] as $entity) { $engine->import($entity); @@ -106,29 +106,23 @@ class CSVIngest implements ShouldQueue } } - private function bootEngine(string $import_type) + private function bootEngine() { - switch ($import_type) { + switch ($this->import_type) { case 'csv': return new Csv($this->request, $this->company); - break; case 'waveaccounting': return new Wave($this->request, $this->company); - break; case 'invoicely': return new Invoicely($this->request, $this->company); - break; case 'invoice2go': return new Invoice2Go($this->request, $this->company); - break; case 'zoho': return new Zoho($this->request, $this->company); - break; case 'freshbooks': return new Freshbooks($this->request, $this->company); - break; default: - // code... + nlog("could not return provider"); break; } } diff --git a/app/Jobs/Mail/NinjaMailerJob.php b/app/Jobs/Mail/NinjaMailerJob.php index c99631e84d28..e3e3d47f12bd 100644 --- a/app/Jobs/Mail/NinjaMailerJob.php +++ b/app/Jobs/Mail/NinjaMailerJob.php @@ -228,7 +228,7 @@ class NinjaMailerJob implements ShouldQueue $this->nmo ->mailable ->from($user->email, $user->name()) - ->withSwiftMessage(function ($message) use($token) { + ->withSymfonyMessage(function ($message) use($token) { $message->getHeaders()->addTextHeader('GmailToken', $token); }); @@ -298,7 +298,7 @@ class NinjaMailerJob implements ShouldQueue $this->nmo ->mailable ->from($user->email, $user->name()) - ->withSwiftMessage(function ($message) use($token) { + ->withSymfonyMessage(function ($message) use($token) { $message->getHeaders()->addTextHeader('GmailToken', $token); }); diff --git a/app/Mail/TemplateEmail.php b/app/Mail/TemplateEmail.php index 5ad58d4f98ec..4b1c1c2acbc3 100644 --- a/app/Mail/TemplateEmail.php +++ b/app/Mail/TemplateEmail.php @@ -134,6 +134,8 @@ class TemplateEmail extends Mailable elseif($this->invitation->credit) $path = $this->client->credit_filepath($this->invitation).$this->invitation->credit->numberFormatter().'.pdf'; + sleep(1); + if($path && !Storage::disk(config('filesystems.default'))->exists($path)){ sleep(2); diff --git a/app/Mail/VendorTemplateEmail.php b/app/Mail/VendorTemplateEmail.php index 02992de1d5c9..0fab3bcc9e58 100644 --- a/app/Mail/VendorTemplateEmail.php +++ b/app/Mail/VendorTemplateEmail.php @@ -127,6 +127,8 @@ class VendorTemplateEmail extends Mailable if($this->invitation->purchase_order) $path = $this->vendor->purchase_order_filepath($this->invitation).$this->invitation->purchase_order->numberFormatter().'.pdf'; + sleep(1); + if($path && !Storage::disk(config('filesystems.default'))->exists($path)){ sleep(2); diff --git a/app/Services/Credit/SendEmail.php b/app/Services/Credit/SendEmail.php index e7e6c48fe558..f7c2d5835745 100644 --- a/app/Services/Credit/SendEmail.php +++ b/app/Services/Credit/SendEmail.php @@ -45,10 +45,7 @@ class SendEmail $this->credit->invitations->each(function ($invitation) { if (! $invitation->contact->trashed() && $invitation->contact->email) { - - // $email_builder = (new CreditEmail())->build($invitation, $this->reminder_template); - // EmailCredit::dispatchNow($email_builder, $invitation, $invitation->company); - EmailEntity::dispatchSync($invitation, $invitation->company, $this->reminder_template); + EmailEntity::dispatch($invitation, $invitation->company, $this->reminder_template); } }); diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index bf880d2c875f..2af53ce6b08a 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -421,7 +421,8 @@ class InvoiceService try { if ($force) { $this->invoice->invitations->each(function ($invitation) { - CreateEntityPdf::dispatchSync($invitation); + // CreateEntityPdf::dispatchSync($invitation); + (new CreateEntityPdf($invitation))->handle(); }); return $this; @@ -560,7 +561,8 @@ class InvoiceService public function adjustInventory($old_invoice = []) { if ($this->invoice->company->track_inventory) { - AdjustProductInventory::dispatchSync($this->invoice->company, $this->invoice, $old_invoice); + (new AdjustProductInventory($this->invoice->company, $this->invoice, $old_invoice))->handle(); + // AdjustProductInventory::dispatchSync($this->invoice->company, $this->invoice, $old_invoice); } return $this; diff --git a/config/logging.php b/config/logging.php index e7eb0331b9cd..5be233cfdc7f 100644 --- a/config/logging.php +++ b/config/logging.php @@ -124,7 +124,6 @@ return [ 'emergency' => [ 'path' => storage_path('logs/laravel.log'), ], - ], 'gelf' => [ 'driver' => 'custom', @@ -188,5 +187,6 @@ return [ 'extra_prefix' => null, ], +] ]; diff --git a/config/services.php b/config/services.php index b9b4c24c5a7b..aec15f6fc8d7 100644 --- a/config/services.php +++ b/config/services.php @@ -44,57 +44,56 @@ return [ 'ses' => [ 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('SES_REGION', 'us-east-1'), + ], + 'sparkpost' => [ + 'secret' => env('SPARKPOST_SECRET'), + ], - 'sparkpost' => [ - 'secret' => env('SPARKPOST_SECRET'), - ], + 'gmail' => [ + 'token' => '', + ], - 'gmail' => [ - 'token' => '', - ], + 'stripe' => [ + 'model' => App\Models\User::class, + 'key' => env('STRIPE_KEY'), + 'secret' => env('STRIPE_SECRET'), + ], - 'stripe' => [ - 'model' => App\Models\User::class, - 'key' => env('STRIPE_KEY'), - 'secret' => env('STRIPE_SECRET'), - ], + 'github' => [ + 'client_id' => env('GITHUB_CLIENT_ID'), + 'client_secret' => env('GITHUB_CLIENT_SECRET'), + 'redirect' => env('GITHUB_OAUTH_REDIRECT'), + ], - 'github' => [ - 'client_id' => env('GITHUB_CLIENT_ID'), - 'client_secret' => env('GITHUB_CLIENT_SECRET'), - 'redirect' => env('GITHUB_OAUTH_REDIRECT'), - ], + 'google' => [ + 'client_id' => env('GOOGLE_CLIENT_ID'), + 'client_secret' => env('GOOGLE_CLIENT_SECRET'), + 'redirect' => env('GOOGLE_OAUTH_REDIRECT'), + ], - 'google' => [ - 'client_id' => env('GOOGLE_CLIENT_ID'), - 'client_secret' => env('GOOGLE_CLIENT_SECRET'), - 'redirect' => env('GOOGLE_OAUTH_REDIRECT'), - ], + 'facebook' => [ + 'client_id' => env('FACEBOOK_CLIENT_ID'), + 'client_secret' => env('FACEBOOK_CLIENT_SECRET'), + 'redirect' => env('FACEBOOK_OAUTH_REDIRECT'), + ], - 'facebook' => [ - 'client_id' => env('FACEBOOK_CLIENT_ID'), - 'client_secret' => env('FACEBOOK_CLIENT_SECRET'), - 'redirect' => env('FACEBOOK_OAUTH_REDIRECT'), - ], + 'linkedin' => [ + 'client_id' => env('LINKEDIN_CLIENT_ID'), + 'client_secret' => env('LINKEDIN_CLIENT_SECRET'), + 'redirect' => env('LINKEDIN_OAUTH_REDIRECT'), + ], - 'linkedin' => [ - 'client_id' => env('LINKEDIN_CLIENT_ID'), - 'client_secret' => env('LINKEDIN_CLIENT_SECRET'), - 'redirect' => env('LINKEDIN_OAUTH_REDIRECT'), - ], + 'twitter' => [ + 'client_id' => env('TWITTER_CLIENT_ID'), + 'client_secret' => env('TWITTER_CLIENT_SECRET'), + 'redirect' => env('TWITTER_OAUTH_REDIRECT'), + ], - 'twitter' => [ - 'client_id' => env('TWITTER_CLIENT_ID'), - 'client_secret' => env('TWITTER_CLIENT_SECRET'), - 'redirect' => env('TWITTER_OAUTH_REDIRECT'), - ], - - 'bitbucket' => [ - 'client_id' => env('BITBUCKET_CLIENT_ID'), - 'client_secret' => env('BITBUCKET_CLIENT_SECRET'), - 'redirect' => env('BITBUCKET_OAUTH_REDIRECT'), - ], - 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'bitbucket' => [ + 'client_id' => env('BITBUCKET_CLIENT_ID'), + 'client_secret' => env('BITBUCKET_CLIENT_SECRET'), + 'redirect' => env('BITBUCKET_OAUTH_REDIRECT'), ], ]; diff --git a/routes/api.php b/routes/api.php index db70b3de13d1..f5150ec20004 100644 --- a/routes/api.php +++ b/routes/api.php @@ -259,7 +259,7 @@ Route::group(['middleware' => ['throttle:300,1', 'api_db', 'token_auth', 'locale Route::resource('task_scheduler', TaskSchedulerController::class)->except('edit')->parameters(['task_scheduler' => 'scheduler']); Route::get('scheduler', [SchedulerController::class, 'index']); - Route::post('support/messages/send', [SendingController::class]); + Route::post('support/messages/send', SendingController::class); Route::post('self-update', [SelfUpdateController::class, 'update'])->middleware('password_protected'); Route::post('self-update/check_version', [SelfUpdateController::class, 'checkVersion']); @@ -287,7 +287,7 @@ Route::group(['middleware' => ['throttle:300,1', 'api_db', 'token_auth', 'locale Route::post('settings/disable_two_factor', [TwoFactorController::class, 'disableTwoFactor']); - Route::post('verify', [TwilioController::class, 'generate'])->name('verify.generate')->middleware('throttle:5,1'); + Route::post('verify', [TwilioController::class, 'generate'])->name('verify.generate')->middleware('throttle:100,1'); Route::post('verify/confirm', [TwilioController::class, 'confirm'])->name('verify.confirm'); Route::resource('vendors', VendorController::class); // name = (vendors. index / create / show / update / destroy / edit @@ -333,11 +333,11 @@ Route::group(['middleware' => ['throttle:300,1', 'api_db', 'token_auth', 'locale }); Route::match(['get', 'post'], 'payment_webhook/{company_key}/{company_gateway_id}', PaymentWebhookController::class) - ->middleware(['throttle:1000,1','guest']) + ->middleware('throttle:1000,1') ->name('payment_webhook'); Route::match(['get', 'post'], 'payment_notification_webhook/{company_key}/{company_gateway_id}/{client}', PaymentNotificationWebhookController::class) - ->middleware(['throttle:1000,1', 'guest']) + ->middleware('throttle:1000,1') ->name('payment_notification_webhook'); Route::post('api/v1/postmark_webhook', [PostMarkController::class, 'webhook'])->middleware('throttle:1000,1'); diff --git a/routes/client.php b/routes/client.php index 0da85644fd30..574d451de408 100644 --- a/routes/client.php +++ b/routes/client.php @@ -90,7 +90,7 @@ Route::group(['middleware' => ['auth:contact', 'locale', 'domain_db','check_clie Route::get('credits/{credit_invitation}', [App\Http\Controllers\ClientPortal\CreditController::class,'show'])->name('credits.show_invitation'); - Route::get('client/switch_company/{contact}', [App\Http\Controllers\ClientPortal\SwitchCompanyController::class])->name('switch_company'); + Route::get('client/switch_company/{contact}', App\Http\Controllers\ClientPortal\SwitchCompanyController::class)->name('switch_company'); Route::post('documents/download_multiple', [App\Http\Controllers\ClientPortal\DocumentController::class, 'downloadMultiple'])->name('documents.download_multiple'); Route::get('documents/{document}/download', [App\Http\Controllers\ClientPortal\DocumentController::class, 'download'])->name('documents.download'); From 57e1eb7a8e885029d5c5b46fc8317415467e663b Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 31 Jul 2022 19:20:18 +1000 Subject: [PATCH 03/26] Inject delay into Send Recurring invoices to allow PDFs to catch up --- app/Jobs/RecurringInvoice/SendRecurring.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Jobs/RecurringInvoice/SendRecurring.php b/app/Jobs/RecurringInvoice/SendRecurring.php index 5f22baf98080..d3a6b5c38fa1 100644 --- a/app/Jobs/RecurringInvoice/SendRecurring.php +++ b/app/Jobs/RecurringInvoice/SendRecurring.php @@ -135,7 +135,7 @@ class SendRecurring implements ShouldQueue $invoice->invitations->each(function ($invitation) use ($invoice) { if ($invitation->contact && ! $invitation->contact->trashed() && strlen($invitation->contact->email) >= 1 && $invoice->client->getSetting('auto_email_invoice')) { try { - EmailEntity::dispatch($invitation, $invoice->company); + EmailEntity::dispatch($invitation, $invoice->company)->delay(10); } catch (\Exception $e) { nlog($e->getMessage()); } From 05559feeb2f028c60dd81de52634bdd1ff492eac Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 31 Jul 2022 20:02:21 +1000 Subject: [PATCH 04/26] Fixes for routes --- app/Listeners/Mail/MailSentListener.php | 6 +++--- routes/client.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Listeners/Mail/MailSentListener.php b/app/Listeners/Mail/MailSentListener.php index c92300bda234..865459f48cd2 100644 --- a/app/Listeners/Mail/MailSentListener.php +++ b/app/Listeners/Mail/MailSentListener.php @@ -36,13 +36,13 @@ class MailSentListener implements ShouldQueue public function handle(MessageSent $event) { if (property_exists($event->message, 'invitation') && $event->message->invitation) { - MultiDB::setDb($event->message->invitation->company->db); + MultiDB::setDb($event->sent->invitation->company->db); if ($event->message->getHeaders()->get('x-pm-message-id')) { - $postmark_id = $event->message->getHeaders()->get('x-pm-message-id')->getValue(); + $postmark_id = $event->sent->getHeaders()->get('x-pm-message-id')->getValue(); // nlog($postmark_id); - $invitation = $event->message->invitation; + $invitation = $event->sent->invitation; $invitation->message_id = $postmark_id; $invitation->save(); } diff --git a/routes/client.php b/routes/client.php index 574d451de408..806ed1079533 100644 --- a/routes/client.php +++ b/routes/client.php @@ -105,7 +105,7 @@ Route::group(['middleware' => ['auth:contact', 'locale', 'domain_db','check_clie Route::get('statement', [App\Http\Controllers\ClientPortal\StatementController::class, 'index'])->name('statement'); Route::get('statement/raw', [App\Http\Controllers\ClientPortal\StatementController::class, 'raw'])->name('statement.raw'); - Route::post('upload', [App\Http\Controllers\ClientPortal\UploadController::class])->name('upload.store'); + Route::post('upload', App\Http\Controllers\ClientPortal\UploadController::class)->name('upload.store'); Route::get('logout', [ContactLoginController::class, 'logout'])->name('logout'); }); From 2ec8e2150697628ef5b8052329b6c1fd30472e72 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 31 Jul 2022 20:43:43 +1000 Subject: [PATCH 05/26] Fixes for mail sent listener --- app/Listeners/Mail/MailSentListener.php | 22 ++++++++++++---------- app/Providers/EventServiceProvider.php | 6 +++--- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/app/Listeners/Mail/MailSentListener.php b/app/Listeners/Mail/MailSentListener.php index 865459f48cd2..7d52131bb551 100644 --- a/app/Listeners/Mail/MailSentListener.php +++ b/app/Listeners/Mail/MailSentListener.php @@ -35,17 +35,19 @@ class MailSentListener implements ShouldQueue */ public function handle(MessageSent $event) { - if (property_exists($event->message, 'invitation') && $event->message->invitation) { - MultiDB::setDb($event->sent->invitation->company->db); + nlog("mail listener"); + nlog($event); + // if (property_exists($event->message, 'invitation') && $event->message->invitation) { + // MultiDB::setDb($event->sent->invitation->company->db); - if ($event->message->getHeaders()->get('x-pm-message-id')) { - $postmark_id = $event->sent->getHeaders()->get('x-pm-message-id')->getValue(); + // if ($event->message->getHeaders()->get('x-pm-message-id')) { + // $postmark_id = $event->sent->getHeaders()->get('x-pm-message-id')->getValue(); - // nlog($postmark_id); - $invitation = $event->sent->invitation; - $invitation->message_id = $postmark_id; - $invitation->save(); - } - } + // // nlog($postmark_id); + // $invitation = $event->sent->invitation; + // $invitation->message_id = $postmark_id; + // $invitation->save(); + // } + // } } } diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 53bb69bbb4ca..495ebf41aadd 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -271,9 +271,9 @@ class EventServiceProvider extends ServiceProvider ], MessageSending::class => [ ], - MessageSent::class => [ - MailSentListener::class, - ], + // MessageSent::class => [ + // MailSentListener::class, + // ], UserWasCreated::class => [ CreatedUserActivity::class, SendVerificationNotification::class, From a9b35220819aef0f4ea6c53152c21af150379474 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 31 Jul 2022 21:51:35 +1000 Subject: [PATCH 06/26] Fixes for using dispatchSync() --- app/Jobs/Mail/NinjaMailerJob.php | 4 ++-- app/Jobs/Util/StartMigration.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Jobs/Mail/NinjaMailerJob.php b/app/Jobs/Mail/NinjaMailerJob.php index e3e3d47f12bd..2d87ba119dec 100644 --- a/app/Jobs/Mail/NinjaMailerJob.php +++ b/app/Jobs/Mail/NinjaMailerJob.php @@ -229,7 +229,7 @@ class NinjaMailerJob implements ShouldQueue ->mailable ->from($user->email, $user->name()) ->withSymfonyMessage(function ($message) use($token) { - $message->getHeaders()->addTextHeader('GmailToken', $token); + $message->getHeaders()->addTextHeader('gmailtoken', $token); }); sleep(rand(1,3)); @@ -299,7 +299,7 @@ class NinjaMailerJob implements ShouldQueue ->mailable ->from($user->email, $user->name()) ->withSymfonyMessage(function ($message) use($token) { - $message->getHeaders()->addTextHeader('GmailToken', $token); + $message->getHeaders()->addTextHeader('gmailtoken', $token); }); } diff --git a/app/Jobs/Util/StartMigration.php b/app/Jobs/Util/StartMigration.php index 27ad98cdaaa8..6592f3cf9980 100644 --- a/app/Jobs/Util/StartMigration.php +++ b/app/Jobs/Util/StartMigration.php @@ -116,7 +116,7 @@ class StartMigration implements ShouldQueue throw new NonExistingMigrationFile('Migration file does not exist, or it is corrupted.'); } - Import::dispatchSync($file, $this->company, $this->user); + (new Import($file, $this->company, $this->user))->handle(); Storage::deleteDirectory(public_path("storage/migrations/{$filename}")); From 4de240c3ab30b537e195233928309996eaed5941 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 31 Jul 2022 22:23:50 +1000 Subject: [PATCH 07/26] Remove storage checks --- app/Utils/Traits/Uploadable.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Utils/Traits/Uploadable.php b/app/Utils/Traits/Uploadable.php index 3284c5ce3069..1f29bc84280f 100644 --- a/app/Utils/Traits/Uploadable.php +++ b/app/Utils/Traits/Uploadable.php @@ -22,9 +22,9 @@ trait Uploadable { public function removeLogo($company) { - if (Storage::exists($company->settings->company_logo)) { - UnlinkFile::dispatchSync(config('filesystems.default'), $company->settings->company_logo); - } + //if (Storage::disk(config('filesystems.default'))->exists($company->settings->company_logo)) { + (new UnlinkFile(config('filesystems.default'), $company->settings->company_logo))->handle(); + //} } public function uploadLogo($file, $company, $entity) From b38b0e4517e805cc26408d2952854b93fb73c33d Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 31 Jul 2022 22:33:00 +1000 Subject: [PATCH 08/26] Add tags to mailables --- app/Mail/TemplateEmail.php | 3 ++- app/Mail/VendorTemplateEmail.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/Mail/TemplateEmail.php b/app/Mail/TemplateEmail.php index 4b1c1c2acbc3..e04374edd1f9 100644 --- a/app/Mail/TemplateEmail.php +++ b/app/Mail/TemplateEmail.php @@ -119,7 +119,8 @@ class TemplateEmail extends Mailable ->withSymfonyMessage(function ($message) use ($company) { $message->getHeaders()->addTextHeader('Tag', $company->company_key); $message->invitation = $this->invitation; - }); + }) + ->tag($company->company_key); /*In the hosted platform we need to slow things down a little for Storage to catch up.*/ diff --git a/app/Mail/VendorTemplateEmail.php b/app/Mail/VendorTemplateEmail.php index 0fab3bcc9e58..447114621ce0 100644 --- a/app/Mail/VendorTemplateEmail.php +++ b/app/Mail/VendorTemplateEmail.php @@ -113,7 +113,8 @@ class VendorTemplateEmail extends Mailable ->withSymfonyMessage(function ($message) { $message->getHeaders()->addTextHeader('Tag', $this->company->company_key); $message->invitation = $this->invitation; - }); + }) + ->tag($this->company->company_key); /*In the hosted platform we need to slow things down a little for Storage to catch up.*/ // if (Ninja::isHosted()) { From 2ac46b7392d3cad725f4bec2c341a5cc951d471f Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 1 Aug 2022 04:53:39 +1000 Subject: [PATCH 09/26] Minor fixes --- app/Http/Controllers/ClientPortal/InvitationController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/ClientPortal/InvitationController.php b/app/Http/Controllers/ClientPortal/InvitationController.php index 7b9e08a59401..790a75af08f1 100644 --- a/app/Http/Controllers/ClientPortal/InvitationController.php +++ b/app/Http/Controllers/ClientPortal/InvitationController.php @@ -84,7 +84,7 @@ class InvitationController extends Controller ->with($entity) ->where('key', $invitation_key) ->with('contact.client') - ->first(); + ->firstOrFail(); if($invitation->{$entity}->is_deleted) return $this->render('generic.not_available', ['account' => $invitation->company->account, 'company' => $invitation->company]); From d7f01907fadd0b078e6f7ad658d703bfcdc4f869 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 1 Aug 2022 06:20:38 +1000 Subject: [PATCH 10/26] Fixes for template emails --- app/Mail/TemplateEmail.php | 2 +- app/Mail/VendorTemplateEmail.php | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/app/Mail/TemplateEmail.php b/app/Mail/TemplateEmail.php index e04374edd1f9..4ec31fd6ccdd 100644 --- a/app/Mail/TemplateEmail.php +++ b/app/Mail/TemplateEmail.php @@ -124,7 +124,7 @@ class TemplateEmail extends Mailable /*In the hosted platform we need to slow things down a little for Storage to catch up.*/ - if(Ninja::isHosted()){ + if(Ninja::isHosted() && $this->invitation){ $path = false; diff --git a/app/Mail/VendorTemplateEmail.php b/app/Mail/VendorTemplateEmail.php index 447114621ce0..5a9f7e6d2545 100644 --- a/app/Mail/VendorTemplateEmail.php +++ b/app/Mail/VendorTemplateEmail.php @@ -116,12 +116,7 @@ class VendorTemplateEmail extends Mailable }) ->tag($this->company->company_key); - /*In the hosted platform we need to slow things down a little for Storage to catch up.*/ - // if (Ninja::isHosted()) { - // sleep(1); - // } - - if(Ninja::isHosted()){ + if(Ninja::isHosted() && $this->invitation){ $path = false; From f4551245a9feb573f48fb2d5abe79b066f9d491f Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 1 Aug 2022 06:26:04 +1000 Subject: [PATCH 11/26] Fixes for payments js --- public/js/clients/invoices/payment.js | 2 +- public/mix-manifest.json | 2 +- resources/js/clients/invoices/payment.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/public/js/clients/invoices/payment.js b/public/js/clients/invoices/payment.js index a4c3e61899b3..f86a412730c4 100755 --- a/public/js/clients/invoices/payment.js +++ b/public/js/clients/invoices/payment.js @@ -1,2 +1,2 @@ /*! For license information please see payment.js.LICENSE.txt */ -(()=>{function e(e,t){for(var n=0;n{function e(e,t){for(var n=0;n Date: Mon, 1 Aug 2022 07:02:08 +1000 Subject: [PATCH 12/26] Add tag to all outbound emails --- app/Jobs/Mail/NinjaMailerJob.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/Jobs/Mail/NinjaMailerJob.php b/app/Jobs/Mail/NinjaMailerJob.php index 2d87ba119dec..13f06281e112 100644 --- a/app/Jobs/Mail/NinjaMailerJob.php +++ b/app/Jobs/Mail/NinjaMailerJob.php @@ -100,6 +100,8 @@ class NinjaMailerJob implements ShouldQueue $this->nmo->mailable->replyTo($this->company->owner()->email, $this->company->owner()->present()->name()); } + $this->nmo->mailable->tag($this->company->company_key); + //send email try { nlog("trying to send to {$this->nmo->to_user->email} ". now()->toDateTimeString()); @@ -143,7 +145,7 @@ class NinjaMailerJob implements ShouldQueue $this->entityEmailFailed($message); /* Don't send postmark failures to Sentry */ - if(Ninja::isHosted() && (!$e instanceof ClientException)) + if(Ninja::isHosted() && (!$e instanceof ClientException || !$e instanceof \Symfony\Component\Mailer\Exception\HttpTransportException)) app('sentry')->captureException($e); } } From 7ac4786bff0c1b659a87a6b2faeb5d444c898470 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 1 Aug 2022 07:30:04 +1000 Subject: [PATCH 13/26] Refactor to remove dispatchSync from code path --- app/Console/Commands/RecurringCommand.php | 2 +- app/Http/Controllers/Auth/LoginController.php | 4 ++-- app/Http/Controllers/CompanyController.php | 4 ++-- app/Http/Controllers/SetupController.php | 6 +++--- app/Jobs/Account/CreateAccount.php | 4 ++-- app/Jobs/Cron/RecurringInvoicesCron.php | 4 ++-- app/Jobs/Entity/EmailEntity.php | 2 +- app/Jobs/Invoice/ZipInvoices.php | 2 +- app/Jobs/Mail/NinjaMailerJob.php | 6 +++--- app/Jobs/Ninja/CheckDbStatus.php | 4 ++-- app/Jobs/Ninja/SendReminders.php | 2 +- app/Jobs/PurchaseOrder/PurchaseOrderEmail.php | 2 +- app/Jobs/PurchaseOrder/ZipPurchaseOrders.php | 2 +- app/Jobs/Quote/ZipQuotes.php | 2 +- app/Listeners/Quote/ReachWorkflowSettings.php | 2 +- app/Mail/VendorTemplateEmail.php | 2 +- app/Models/CreditInvitation.php | 4 ++-- app/Models/QuoteInvitation.php | 2 +- app/Services/Credit/CreditService.php | 4 ++-- app/Services/Invoice/InvoiceService.php | 2 -- app/Services/Invoice/SendEmail.php | 2 +- app/Services/Payment/SendEmail.php | 5 +---- app/Services/Quote/QuoteService.php | 4 ++-- 23 files changed, 34 insertions(+), 39 deletions(-) diff --git a/app/Console/Commands/RecurringCommand.php b/app/Console/Commands/RecurringCommand.php index 628a09b8f548..2bc62d79dee5 100644 --- a/app/Console/Commands/RecurringCommand.php +++ b/app/Console/Commands/RecurringCommand.php @@ -47,6 +47,6 @@ class RecurringCommand extends Command */ public function handle() { - RecurringInvoicesCron::dispatchSync(); + (new RecurringInvoicesCron())->handle(); } } diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 9167e8528a2a..9f702bbe3174 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -294,7 +294,7 @@ class LoginController extends BaseController $cu->first()->account->companies->each(function ($company) use ($cu, $request) { if ($company->tokens()->where('is_system', true)->count() == 0) { - CreateCompanyToken::dispatchSync($company, $cu->first()->user, $request->server('HTTP_USER_AGENT')); + (new CreateCompanyToken($company, $cu->first()->user, $request->server('HTTP_USER_AGENT')))->handle(); } }); @@ -474,7 +474,7 @@ class LoginController extends BaseController if (auth()->user()->company_users()->count() != auth()->user()->tokens()->distinct('company_id')->count()) { auth()->user()->companies->each(function ($company) { if (!CompanyToken::where('user_id', auth()->user()->id)->where('company_id', $company->id)->exists()) { - CreateCompanyToken::dispatchSync($company, auth()->user(), 'Google_O_Auth'); + (new CreateCompanyToken($company, auth()->user(), 'Google_O_Auth'))->handle(); } }); } diff --git a/app/Http/Controllers/CompanyController.php b/app/Http/Controllers/CompanyController.php index 5317a46babdf..86fc01c732c7 100644 --- a/app/Http/Controllers/CompanyController.php +++ b/app/Http/Controllers/CompanyController.php @@ -212,8 +212,8 @@ class CompanyController extends BaseController $this->forced_includes = ['company_user']; $company = (new CreateCompany($request->all(), auth()->user()->company()->account))->handle(); - CreateCompanyPaymentTerms::dispatchSync($company, auth()->user()); - CreateCompanyTaskStatuses::dispatchSync($company, auth()->user()); + (new CreateCompanyPaymentTerms($company, auth()->user()))->handle(); + (new CreateCompanyTaskStatuses($company, auth()->user()))->handle(); $company = $this->company_repo->save($request->all(), $company); diff --git a/app/Http/Controllers/SetupController.php b/app/Http/Controllers/SetupController.php index 36493d48f11b..c9ef036af7b7 100644 --- a/app/Http/Controllers/SetupController.php +++ b/app/Http/Controllers/SetupController.php @@ -145,10 +145,10 @@ class SetupController extends Controller /* Create the first account. */ if (Account::count() == 0) { - CreateAccount::dispatchSync($request->all(), $request->getClientIp()); + (new CreateAccount($request->all(), $request->getClientIp()))->handle(); } - VersionCheck::dispatchSync(); + (new VersionCheck())->handle(); $this->buildCache(true); @@ -316,7 +316,7 @@ class SetupController extends Controller $this->buildCache(true); - SchedulerCheck::dispatchSync(); + (new SchedulerCheck())->handle(); return redirect('/'); } diff --git a/app/Jobs/Account/CreateAccount.php b/app/Jobs/Account/CreateAccount.php index 2690d627fb93..9ab7f99cd79f 100644 --- a/app/Jobs/Account/CreateAccount.php +++ b/app/Jobs/Account/CreateAccount.php @@ -97,8 +97,8 @@ class CreateAccount $spaa9f78 = (new CreateUser($this->request, $sp794f3f, $sp035a66, true))->handle(); - CreateCompanyPaymentTerms::dispatchSync($sp035a66, $spaa9f78); - CreateCompanyTaskStatuses::dispatchSync($sp035a66, $spaa9f78); + (new CreateCompanyPaymentTerms($sp035a66, $spaa9f78))->handle(); + (new CreateCompanyTaskStatuses($sp035a66, $spaa9f78))->handle(); if ($spaa9f78) { auth()->login($spaa9f78, false); diff --git a/app/Jobs/Cron/RecurringInvoicesCron.php b/app/Jobs/Cron/RecurringInvoicesCron.php index 5584f5c18628..0923675072f0 100644 --- a/app/Jobs/Cron/RecurringInvoicesCron.php +++ b/app/Jobs/Cron/RecurringInvoicesCron.php @@ -74,7 +74,7 @@ class RecurringInvoicesCron } try { - SendRecurring::dispatchSync($recurring_invoice, $recurring_invoice->company->db); + (new SendRecurring($recurring_invoice, $recurring_invoice->company->db))->handle(); } catch (\Exception $e) { nlog("Unable to sending recurring invoice {$recurring_invoice->id} ".$e->getMessage()); } @@ -114,7 +114,7 @@ class RecurringInvoicesCron } try { - SendRecurring::dispatchSync($recurring_invoice, $recurring_invoice->company->db); + (new SendRecurring($recurring_invoice, $recurring_invoice->company->db))->handle(); } catch (\Exception $e) { nlog("Unable to sending recurring invoice {$recurring_invoice->id} ".$e->getMessage()); } diff --git a/app/Jobs/Entity/EmailEntity.php b/app/Jobs/Entity/EmailEntity.php index cc3cd03ba33a..ce76748a6f6e 100644 --- a/app/Jobs/Entity/EmailEntity.php +++ b/app/Jobs/Entity/EmailEntity.php @@ -126,7 +126,7 @@ class EmailEntity implements ShouldQueue $nmo->reminder_template = $this->reminder_template; $nmo->entity = $this->entity; - NinjaMailerJob::dispatchSync($nmo); + (new NinjaMailerJob($nmo))->handle(); } private function resolveEntityString() :string diff --git a/app/Jobs/Invoice/ZipInvoices.php b/app/Jobs/Invoice/ZipInvoices.php index e3ba20013408..b0b8410b0136 100644 --- a/app/Jobs/Invoice/ZipInvoices.php +++ b/app/Jobs/Invoice/ZipInvoices.php @@ -80,7 +80,7 @@ class ZipInvoices implements ShouldQueue $path = $this->invoices->first()->client->invoice_filepath($invitation); $this->invoices->each(function ($invoice) { - CreateEntityPdf::dispatchSync($invoice->invitations()->first()); + (new CreateEntityPdf($invoice->invitations()->first()))->handle(); }); try { diff --git a/app/Jobs/Mail/NinjaMailerJob.php b/app/Jobs/Mail/NinjaMailerJob.php index 13f06281e112..598156ce711a 100644 --- a/app/Jobs/Mail/NinjaMailerJob.php +++ b/app/Jobs/Mail/NinjaMailerJob.php @@ -101,7 +101,7 @@ class NinjaMailerJob implements ShouldQueue } $this->nmo->mailable->tag($this->company->company_key); - + //send email try { nlog("trying to send to {$this->nmo->to_user->email} ". now()->toDateTimeString()); @@ -117,7 +117,7 @@ class NinjaMailerJob implements ShouldQueue /* Count the amount of emails sent across all the users accounts */ Cache::increment($this->company->account->key); - } catch (\Exception $e) { + } catch (\Exception | \RuntimeException $e) { nlog("error failed with {$e->getMessage()}"); @@ -145,7 +145,7 @@ class NinjaMailerJob implements ShouldQueue $this->entityEmailFailed($message); /* Don't send postmark failures to Sentry */ - if(Ninja::isHosted() && (!$e instanceof ClientException || !$e instanceof \Symfony\Component\Mailer\Exception\HttpTransportException)) + if(Ninja::isHosted() && (!$e instanceof ClientException)) app('sentry')->captureException($e); } } diff --git a/app/Jobs/Ninja/CheckDbStatus.php b/app/Jobs/Ninja/CheckDbStatus.php index 8c782fd5ee57..1fb53b1a123d 100644 --- a/app/Jobs/Ninja/CheckDbStatus.php +++ b/app/Jobs/Ninja/CheckDbStatus.php @@ -39,7 +39,7 @@ class CheckDbStatus implements ShouldQueue */ public function handle() { - DbStatus::dispatchSync('db-ninja-01', 'db.status.db-ninja-01'); - DbStatus::dispatchSync('db-ninja-02', 'db.status.db-ninja-02'); + (new DbStatus('db-ninja-01', 'db.status.db-ninja-01'))->handle(); + (new DbStatus('db-ninja-02', 'db.status.db-ninja-02'))->handle(); } } diff --git a/app/Jobs/Ninja/SendReminders.php b/app/Jobs/Ninja/SendReminders.php index d84c04b3631b..f2d520aac270 100644 --- a/app/Jobs/Ninja/SendReminders.php +++ b/app/Jobs/Ninja/SendReminders.php @@ -214,7 +214,7 @@ class SendReminders implements ShouldQueue if ($this->checkSendSetting($invoice, $template) && $invoice->company->account->hasFeature(Account::FEATURE_EMAIL_TEMPLATES_REMINDERS)) { nlog('firing email'); - EmailEntity::dispatchSync($invitation, $invitation->company, $template); + EmailEntity::dispatch($invitation, $invitation->company, $template)->delay(10); } }); diff --git a/app/Jobs/PurchaseOrder/PurchaseOrderEmail.php b/app/Jobs/PurchaseOrder/PurchaseOrderEmail.php index c49154a09208..aeccc61a723c 100644 --- a/app/Jobs/PurchaseOrder/PurchaseOrderEmail.php +++ b/app/Jobs/PurchaseOrder/PurchaseOrderEmail.php @@ -89,7 +89,7 @@ class PurchaseOrderEmail implements ShouldQueue $nmo->reminder_template = 'purchase_order'; $nmo->entity = $invitation->purchase_order; - NinjaMailerJob::dispatchSync($nmo); + NinjaMailerJob::dispatch($nmo)->delay(5); }); if ($this->purchase_order->invitations->count() >= 1) { diff --git a/app/Jobs/PurchaseOrder/ZipPurchaseOrders.php b/app/Jobs/PurchaseOrder/ZipPurchaseOrders.php index a440e2c1ccb9..73b1f9d399a1 100644 --- a/app/Jobs/PurchaseOrder/ZipPurchaseOrders.php +++ b/app/Jobs/PurchaseOrder/ZipPurchaseOrders.php @@ -82,7 +82,7 @@ class ZipPurchaseOrders implements ShouldQueue $path = $this->purchase_orders->first()->vendor->purchase_order_filepath($invitation); $this->purchase_orders->each(function ($purchase_order) { - CreatePurchaseOrderPdf::dispatchSync($purchase_order->invitations()->first()); + (new CreatePurchaseOrderPdf($purchase_order->invitations()->first()))->handle(); }); try { diff --git a/app/Jobs/Quote/ZipQuotes.php b/app/Jobs/Quote/ZipQuotes.php index c8cf24ed1e8d..a4f9d85883c5 100644 --- a/app/Jobs/Quote/ZipQuotes.php +++ b/app/Jobs/Quote/ZipQuotes.php @@ -80,7 +80,7 @@ class ZipQuotes implements ShouldQueue $path = $this->quotes->first()->client->quote_filepath($invitation); $this->quotes->each(function ($quote) { - CreateEntityPdf::dispatchSync($quote->invitations()->first()); + (new CreateEntityPdf($quote->invitations()->first()))->handle(); }); try { diff --git a/app/Listeners/Quote/ReachWorkflowSettings.php b/app/Listeners/Quote/ReachWorkflowSettings.php index 8d4733fdb83f..16bca41c36c5 100644 --- a/app/Listeners/Quote/ReachWorkflowSettings.php +++ b/app/Listeners/Quote/ReachWorkflowSettings.php @@ -27,6 +27,6 @@ class ReachWorkflowSettings { MultiDB::setDb($event->company->db); - QuoteWorkflowSettings::dispatchSync($event->quote); + (new QuoteWorkflowSettings($event->quote))->handle(); } } diff --git a/app/Mail/VendorTemplateEmail.php b/app/Mail/VendorTemplateEmail.php index 5a9f7e6d2545..94ff1319376d 100644 --- a/app/Mail/VendorTemplateEmail.php +++ b/app/Mail/VendorTemplateEmail.php @@ -130,7 +130,7 @@ class VendorTemplateEmail extends Mailable sleep(2); if(!Storage::disk(config('filesystems.default'))->exists($path)) { - CreatePurchaseOrderPdf::dispatchSync($this->invitation); + (new CreatePurchaseOrderPdf($this->invitation))->handle(); sleep(2); } diff --git a/app/Models/CreditInvitation.php b/app/Models/CreditInvitation.php index ba32dd04f9aa..bcb3daa1d4b8 100644 --- a/app/Models/CreditInvitation.php +++ b/app/Models/CreditInvitation.php @@ -129,8 +129,8 @@ class CreditInvitation extends BaseModel $storage_path = Storage::url($this->credit->client->quote_filepath($this).$this->credit->numberFormatter().'.pdf'); if (! Storage::exists($this->credit->client->credit_filepath($this).$this->credit->numberFormatter().'.pdf')) { - event(new CreditWasUpdated($this, $this->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null))); - CreateEntityPdf::dispatchSync($this); + event(new CreditWasUpdated($this->credit, $this->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null))); + (new CreateEntityPdf($this))->handle(); } return $storage_path; diff --git a/app/Models/QuoteInvitation.php b/app/Models/QuoteInvitation.php index bb6fce43867a..7c2378ea2580 100644 --- a/app/Models/QuoteInvitation.php +++ b/app/Models/QuoteInvitation.php @@ -134,7 +134,7 @@ class QuoteInvitation extends BaseModel if (! Storage::exists($this->quote->client->quote_filepath($this).$this->quote->numberFormatter().'.pdf')) { event(new QuoteWasUpdated($this->quote, $this->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null))); - CreateEntityPdf::dispatchSync($this); + (new CreateEntityPdf($this))->handle(); } return $storage_path; diff --git a/app/Services/Credit/CreditService.php b/app/Services/Credit/CreditService.php index ec43ceed2403..eeac8f404766 100644 --- a/app/Services/Credit/CreditService.php +++ b/app/Services/Credit/CreditService.php @@ -196,7 +196,7 @@ class CreditService try { if ($force) { $this->credit->invitations->each(function ($invitation) { - CreateEntityPdf::dispatchSync($invitation); + (new CreateEntityPdf($invitation))->handle(); }); return $this; @@ -243,7 +243,7 @@ class CreditService public function deletePdf() { $this->credit->invitations->each(function ($invitation) { - UnlinkFile::dispatchSync(config('filesystems.default'), $this->credit->client->credit_filepath($invitation).$this->credit->numberFormatter().'.pdf'); + (new UnlinkFile(config('filesystems.default'), $this->credit->client->credit_filepath($invitation).$this->credit->numberFormatter().'.pdf'))->handle(); }); return $this; diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index 2af53ce6b08a..c20594a03e3a 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -421,7 +421,6 @@ class InvoiceService try { if ($force) { $this->invoice->invitations->each(function ($invitation) { - // CreateEntityPdf::dispatchSync($invitation); (new CreateEntityPdf($invitation))->handle(); }); @@ -562,7 +561,6 @@ class InvoiceService { if ($this->invoice->company->track_inventory) { (new AdjustProductInventory($this->invoice->company, $this->invoice, $old_invoice))->handle(); - // AdjustProductInventory::dispatchSync($this->invoice->company, $this->invoice, $old_invoice); } return $this; diff --git a/app/Services/Invoice/SendEmail.php b/app/Services/Invoice/SendEmail.php index 10a35479c460..55f9c534fad8 100644 --- a/app/Services/Invoice/SendEmail.php +++ b/app/Services/Invoice/SendEmail.php @@ -45,7 +45,7 @@ class SendEmail extends AbstractService $this->invoice->invitations->each(function ($invitation) { if (! $invitation->contact->trashed() && $invitation->contact->email) { - EmailEntity::dispatchSync($invitation, $invitation->company, $this->reminder_template); + EmailEntity::dispatch($invitation, $invitation->company, $this->reminder_template)->delay(10); } }); } diff --git a/app/Services/Payment/SendEmail.php b/app/Services/Payment/SendEmail.php index 87ff586edcdf..598fd92f3dd9 100644 --- a/app/Services/Payment/SendEmail.php +++ b/app/Services/Payment/SendEmail.php @@ -36,10 +36,7 @@ class SendEmail $this->payment->client->contacts->each(function ($contact) { if ($contact->email) { - // dispatchSync always returns 0, in this case we can handle it without returning false; - return EmailPayment::dispatchSync($this->payment, $this->payment->company, $contact); - // return false; - //11-01-2021 only send payment receipt to the first contact + EmailPayment::dispatch($this->payment, $this->payment->company, $contact); } }); } diff --git a/app/Services/Quote/QuoteService.php b/app/Services/Quote/QuoteService.php index 62414cec3377..8a8174c3ea4c 100644 --- a/app/Services/Quote/QuoteService.php +++ b/app/Services/Quote/QuoteService.php @@ -136,7 +136,7 @@ class QuoteService try { if ($force) { $this->quote->invitations->each(function ($invitation) { - CreateEntityPdf::dispatchSync($invitation); + (new CreateEntityPdf($invitation))->handle(); }); return $this; @@ -225,7 +225,7 @@ class QuoteService public function deletePdf() { $this->quote->invitations->each(function ($invitation) { - UnlinkFile::dispatchSync(config('filesystems.default'), $this->quote->client->quote_filepath($invitation).$this->quote->numberFormatter().'.pdf'); + (new UnlinkFile(config('filesystems.default'), $this->quote->client->quote_filepath($invitation).$this->quote->numberFormatter().'.pdf'))->handle(); }); return $this; From 4634662136dc00c0c5011776114bfcbc9959582a Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 1 Aug 2022 07:46:45 +1000 Subject: [PATCH 14/26] Fixes for query logging --- app/Http/Middleware/QueryLogging.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Http/Middleware/QueryLogging.php b/app/Http/Middleware/QueryLogging.php index 0bf364225054..1ee27c815676 100644 --- a/app/Http/Middleware/QueryLogging.php +++ b/app/Http/Middleware/QueryLogging.php @@ -35,9 +35,9 @@ class QueryLogging { // Enable query logging for development - // if (! Ninja::isHosted() || ! config('beacon.enabled')) { - // return $next($request); - // } + if (! Ninja::isHosted() || ! config('beacon.enabled')) { + return $next($request); + } $timeStart = microtime(true); DB::enableQueryLog(); From 87396cd626e3cfb3ae990044b09d1aa4ab75d70c Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 1 Aug 2022 08:02:04 +1000 Subject: [PATCH 15/26] Fixes for expense date imports --- .../Transformer/Csv/ExpenseTransformer.php | 2 +- tests/Feature/Import/expenses.csv | 370 +++++++++--------- 2 files changed, 186 insertions(+), 186 deletions(-) diff --git a/app/Import/Transformer/Csv/ExpenseTransformer.php b/app/Import/Transformer/Csv/ExpenseTransformer.php index 226b6d17f590..c8198db0d4bb 100644 --- a/app/Import/Transformer/Csv/ExpenseTransformer.php +++ b/app/Import/Transformer/Csv/ExpenseTransformer.php @@ -42,7 +42,7 @@ class ExpenseTransformer extends BaseTransformer 'client_id' => isset($data['expense.client']) ? $this->getClientId($data['expense.client']) : null, - 'date' => $clientId, + 'date' => $this->getString($data, 'expense.date'), 'public_notes' => $this->getString($data, 'expense.public_notes'), 'private_notes' => $this->getString($data, 'expense.private_notes'), 'category_id' => isset($data['expense.category']) diff --git a/tests/Feature/Import/expenses.csv b/tests/Feature/Import/expenses.csv index af05d055eb48..0ddec395d1de 100644 --- a/tests/Feature/Import/expenses.csv +++ b/tests/Feature/Import/expenses.csv @@ -1,185 +1,185 @@ -"Invoice Ninja v4.5.23 - December 17, 2020 7:01 am","","","" -"","","","" -"Expenses","","","" -"Client","Project","Notes","Amount" -"David Bomba","officiis","Sed minima soluta saepe quae laboriosam placeat. Sequi laboriosam architecto et aut. Ut hic repellat veniam eligendi.","3.94" -"David Bomba","maxime","Distinctio consectetur provident nisi autem ipsum animi.","1.11" -"David Bomba","atque","Fugiat illo iste esse laudantium est. Recusandae et ullam optio soluta. Est est nulla doloribus adipisci.","9.779999999999999" -"David Bomba","itaque","Placeat aliquam et est quasi illo aut inventore. Expedita asperiores cupiditate accusantium. Eos esse dolorem tenetur illo totam.","3.5" -"David Bomba","et","Est quia soluta asperiores dolor ipsum illum sapiente.","3.98" -"David Bomba","velit","Quia consequatur magnam impedit dignissimos. Ut vel sapiente nemo quia laborum. Consectetur occaecati quia sunt eum. Dignissimos labore molestiae laudantium impedit temporibus blanditiis porro maxime. Dolorem quia alias ducimus fugiat. Aut vel officia voluptatem et quia.","1.83" -"David Bomba","corporis","Vel temporibus qui et ex a. Pariatur minima ipsa quasi non dolorum laboriosam laboriosam. Dolor soluta ut nostrum veniam. Porro alias eos quibusdam. Maiores aut eos similique.","9.59" -"David Bomba","expedita","Mollitia aperiam modi velit sit necessitatibus dolor quibusdam sit. Autem molestiae neque neque doloribus nulla.","8.859999999999999" -"David Bomba","ea","Deleniti exercitationem rem et nihil. Ea qui autem fuga repudiandae accusamus qui et et. Quia accusamus molestiae dolor.","5.37" -"David Bomba","ducimus","Ut nobis sint et error ducimus minus suscipit. Ipsum inventore cumque et magni minima explicabo. Corporis earum nihil at facilis ut voluptates aut. Blanditiis reiciendis aut dolor et. Est rerum magni in qui velit. Dolore nihil nostrum quisquam in ut.","8.960000000000001" -"David Bomba","in","Non laudantium adipisci eos porro. Quia aspernatur cum soluta eaque blanditiis fugit alias. Quam nobis dolorem repellendus ut alias dolor cumque. Laboriosam laboriosam et debitis autem autem.","3.14" -"David Bomba","ut","Fuga quam reprehenderit adipisci nesciunt ratione omnis. Dolore dicta quasi excepturi rerum. Alias voluptatem voluptatem vel harum iste id. Nihil est velit quo soluta delectus.","4.6" -"David Bomba","adipisci","Itaque iure necessitatibus vel doloribus omnis. Possimus atque tempora quo ut.","6.64" -"David Bomba","quidem","Sit maiores quia quos facilis earum ducimus. Numquam dolores quo numquam.","7.47" -"David Bomba","optio","Qui minus dicta culpa aperiam id natus quaerat. Facilis cupiditate consequuntur quisquam soluta in.","3.03" -"David Bomba","temporibus","Tempora eligendi nisi dolore non tenetur. Officiis autem aspernatur et optio. Omnis dolore placeat et nihil et.","7.54" -"David Bomba","repellendus","Voluptates hic dolorum aspernatur vitae. Adipisci dicta ut sapiente commodi quia explicabo.","2.14" -"David Bomba","dolorum","Quo vitae atque aut vel et dolorem eaque alias. Quod tempore illum placeat ipsum aspernatur. Incidunt qui ea dolorem et. Optio qui deserunt beatae sed perferendis. Esse rerum et magnam eum soluta. Consequatur rem sed ut repellendus exercitationem. Dolores error omnis quia qui qui.","5.9" -"David Bomba","non","Et cumque odio nam voluptatum nam molestias.","2.62" -"David Bomba","quam","Nostrum in eos voluptatem.","8.630000000000001" -"David Bomba","harum","Vero deleniti vel cumque cumque cupiditate nihil. Est non blanditiis consequatur commodi similique cumque ipsa sapiente. Dolor eum fugiat distinctio nihil aut. Sequi qui cum architecto quia ullam rerum ad. Quo et magnam perferendis rerum voluptatem. Maiores atque ipsa nihil.","7.64" -"David Bomba","quasi","Et labore doloremque incidunt atque illo repudiandae. Officiis necessitatibus est quo. Veniam eum qui aut est est.","5.79" -"David Bomba","sed","Illo nihil aut iste sed. In ea rerum atque iure. Et maiores qui odit inventore cum at. Possimus doloribus dicta excepturi quisquam asperiores qui.","2.56" -"David Bomba","numquam","Ex temporibus alias voluptatem qui.","6.21" -"David Bomba","quis","Aut nobis qui quia. Laboriosam id optio aut. Voluptatem doloremque doloremque odit sint iure sint adipisci. Ut fugiat perspiciatis adipisci earum quasi et.","9.74" -"David Bomba","laboriosam","Temporibus quisquam eligendi harum. Quis est architecto suscipit. Saepe aut et quis. Dolorem nisi recusandae laborum nulla aut dolorem. Provident consectetur maxime minima sint. Et non consequatur possimus officia non sunt incidunt. Odit quia sit quia consequatur ipsam.","5.59" -"David Bomba","voluptas","Numquam quasi eos harum laborum illo. Sit distinctio totam dolores deleniti veritatis voluptas inventore. Pariatur dicta saepe id id quod ratione ea.","5.86" -"David Bomba","unde","Similique autem maiores et repellat natus eius unde sequi.","8.81" -"David Bomba","autem","Sit eveniet reiciendis aut rerum est omnis sunt sed.","3.42" -"David Bomba","sequi","Nesciunt sequi modi inventore delectus aut sit fuga. Modi et quibusdam et laborum.","9.51" -"David Bomba","deserunt","Similique hic voluptate velit. Fuga est est qui fugit eligendi consequatur omnis. Nihil alias adipisci quisquam ut explicabo facere.","2.16" -"David Bomba","id","Facere vero amet fugit et voluptatem nisi repellendus. Excepturi sit earum in pariatur consequatur aut. Molestiae et explicabo voluptas tempore voluptates eos.","9.83" -"David Bomba","nesciunt","Perspiciatis id iste vel enim alias fugit itaque. Facilis quae aut quos nam est nemo suscipit impedit. Debitis ut commodi iure magni. Optio voluptatum inventore tempora incidunt aut deserunt corporis animi.","6.12" -"David Bomba","error","Quisquam ut dolor quo. Hic ex quos neque omnis officiis cumque. Et quae qui autem. Pariatur amet iure labore fugiat error quo.","2.03" -"David Bomba","iste","Ad qui adipisci in et quos eveniet. Sapiente voluptatum sint error ex in. Minima voluptatem commodi ea aut laborum.","5.13" -"David Bomba","laudantium","Quo inventore est mollitia fugiat. Veniam sit fugit dolorem.","7.91" -"David Bomba","minima","Nulla laborum totam adipisci esse explicabo. Eaque dolor facere nesciunt voluptatem ratione. Nesciunt dignissimos cum voluptas quidem repudiandae aut sed. Repellat voluptatem veniam culpa eum.","8.25" -"David Bomba","aliquid","Consequuntur sint laboriosam adipisci consequatur quam a fuga. Delectus sequi tempore molestias dolorem fugiat molestiae ex. Quisquam eaque eum iure ut nisi odit quia. Id iusto ipsa nihil harum hic voluptatum beatae sed. Eum quam omnis in cumque.","9.92" -"David Bomba","iusto","Laboriosam quia eum error quam repellendus.","6.02" -"David Bomba","nemo","Deleniti asperiores doloribus consequuntur magni. Earum aspernatur et vitae veniam molestiae magni. Quaerat error ea dignissimos qui labore error velit.","9.9" -"David Bomba","minus","Voluptatum explicabo amet quidem quia autem aut temporibus. Dolorem sed aut totam et minus ut consequatur tenetur. Et rerum quia autem neque sed neque.","8.26" -"David Bomba","quos","Suscipit praesentium animi ut sunt. Tempore adipisci maiores sed atque id libero consectetur porro. Itaque consequuntur perspiciatis officiis sit. Itaque magni velit laborum rerum qui reiciendis ut. Provident tempore fuga hic quae aut.","6.52" -"David Bomba","vel","Eum aliquam officia ea beatae fugit qui ut laboriosam.","8.34" -"David Bomba","fuga","Vel ut deserunt consequatur voluptatum quis nam. Reiciendis possimus quisquam fugiat numquam.","4.12" -"David Bomba","nostrum","Non ducimus non rem. Est qui odit est nam. Ab voluptatum nihil itaque explicabo hic.","7.07" -"David Bomba","hic","Non modi voluptatum blanditiis et.","4.29" -"David Bomba","rerum","Enim omnis ut dolore ex velit sit. Ab et dolor qui iste. Odit quia et et debitis eligendi illo. Rerum rem corrupti dolor est est ea illum.","7.08" -"David Bomba","corrupti","Ut vitae accusantium ratione in suscipit. Distinctio unde est expedita omnis. Sequi non sit ut modi nostrum libero nesciunt beatae. Qui dolorem optio reprehenderit eum.","8.970000000000001" -"David Bomba","maiores","Aut accusantium neque nam aut quas inventore. Qui laboriosam quam commodi aut suscipit et. Nam aut iusto aut facilis vitae dolores eum. Culpa magni deserunt qui rerum aut.","2.41" -"David Bomba","totam","Totam eos molestiae totam vero fuga sint. Nisi minima et veritatis fugiat. Quo earum ut eius odit.","3.41" -"David Bomba","eligendi","Voluptates amet voluptatem placeat aliquam non non saepe. Provident quaerat laudantium debitis. Quasi sed maxime deserunt laboriosam reiciendis tempore.","8.33" -"David Bomba","architecto","Placeat qui qui doloribus architecto distinctio.","3.3" -"David Bomba","qui","Quibusdam repellat quo tenetur ipsum. Et labore itaque totam sequi quia. Quo in beatae ipsa quia est. Totam architecto placeat hic qui recusandae tempora reiciendis.","2.49" -"David Bomba","deleniti","Ut illo vero accusantium ex dolor id. Hic in nobis est dolorem consequatur qui ratione.","6.07" -"David Bomba","aspernatur","Non voluptatem et deserunt molestiae consectetur. Fuga autem et nisi qui quisquam veniam modi sunt. Recusandae maiores qui facere ut expedita laudantium maxime consequuntur. Qui id quibusdam neque et accusantium.","5.05" -"David Bomba","sit","Quaerat consequatur debitis aut quidem magnam. Illum dolore numquam voluptates cum amet corporis sit.","5.82" -"David Bomba","doloremque","Est non ut libero. Aut qui qui qui maiores. Impedit est optio saepe dignissimos odio. Qui nisi doloremque eius mollitia sint repellat possimus at. Possimus et sit odio quis.","4.08" -"David Bomba","quaerat","Error est eum in pariatur. Aspernatur recusandae ex quasi molestiae. Quos sed excepturi placeat non.","8.380000000000001" -"David Bomba","pariatur","Laboriosam aliquam et eos consequatur ab quis.","4.52" -"David Bomba","facilis","Vero officia necessitatibus adipisci in culpa. Soluta et voluptas magni tenetur ut aut. Et ducimus qui non dolores eum.","9.49" -"David Bomba","aut","Excepturi sit ipsum ipsam corrupti. Quod ab voluptatem explicabo ex. Dolores fugit maiores nemo. Natus sit eligendi quia voluptas deleniti qui. Omnis perferendis consequatur aut quos architecto in.","7.73" -"David Bomba","molestiae","Quam et ex provident magni.","3.26" -"David Bomba","inventore","Placeat enim ipsa perspiciatis dolorem quasi impedit quas exercitationem. Consequatur aut architecto laborum suscipit. Voluptas veritatis voluptas corrupti ex earum laudantium. Ad aliquid est autem a molestias enim dolores dignissimos.","4.82" -"David Bomba","enim","Qui quo sed et quos possimus error. Recusandae at illum ipsum natus. In esse et sit debitis quo ut tempore. Et vel eos officiis provident perferendis.","3.98" -"David Bomba","consectetur","Quas voluptas facere beatae sequi quos et magni. Pariatur harum aspernatur qui consequatur quae. Rem voluptatem dolorem voluptatem voluptas quas rerum.","6.81" -"David Bomba","distinctio","Placeat libero quis id sed praesentium. Ea sed magnam et aliquam.","2.17" -"David Bomba","praesentium","Non itaque consectetur repellendus cupiditate vel expedita. Ipsa rerum harum voluptatem magnam voluptatem. Est reiciendis inventore repellat ut vitae minus in.","8.41" -"David Bomba","eius","Corporis consequatur aut maiores. Praesentium in voluptates consequatur et accusamus. Fuga itaque aliquid consequuntur consequatur.","2.69" -"David Bomba","ipsum","Iste sit beatae consequuntur omnis praesentium iste nulla. Totam odio neque quia excepturi optio sit. Dolores quis unde repellat et maxime.","2.13" -"David Bomba","veniam","Illum nisi maiores aspernatur ut ut voluptatum.","4.8" -"David Bomba","quae","Voluptatem perspiciatis atque laborum qui recusandae non dicta qui. Qui esse nesciunt corporis architecto.","3.35" -"David Bomba","tenetur","Neque dolores ad ut. Sit sed nemo est sed ut. Alias est est officiis pariatur autem.","8.619999999999999" -"David Bomba","aliquam","Aut minus eveniet architecto doloribus esse sint amet. Dignissimos qui enim et fuga sapiente quaerat.","5.03" -"David Bomba","porro","Iure maxime aperiam ipsa id doloremque ad pariatur quia. Aut maiores ipsa est dolor quidem ad quisquam. Excepturi dolor dolores molestiae explicabo dolorem. Sapiente nobis mollitia reprehenderit voluptatem culpa vel sapiente corrupti.","7.42" -"David Bomba","repudiandae","Molestias ut ullam ipsa accusantium. Nobis aut sint cupiditate a ullam. Aut velit nemo modi voluptate.","2.03" -"David Bomba","voluptatem","Maxime non nobis quae omnis molestiae sed dolor dolorem.","3.69" -"David Bomba","ipsa","Voluptas commodi expedita doloribus ut. Minima ullam repudiandae doloribus repellat aut ut. Officia odio labore laboriosam dolor et. Quia dolorem suscipit possimus omnis quidem nam commodi.","1.28" -"David Bomba","nam","Et odio provident eos eveniet nisi ut est enim. Earum inventore tempora doloribus officia sit et esse facere. Quia iusto suscipit et occaecati. Voluptatum commodi placeat tempora saepe facilis exercitationem. Quae esse id et est iste.","7.57" -"David Bomba","voluptates","Sed corrupti dolore culpa consectetur id voluptatem fugiat. Ex impedit sit eum facere reprehenderit ut.","4.91" -"David Bomba","odio","Maxime sed fuga id. Architecto ut nisi et ullam reiciendis voluptatem. Odit excepturi qui cupiditate.","4.54" -"David Bomba","dolorem","Ratione et iure similique est exercitationem a laboriosam.","5.59" -"David Bomba","ipsam","Iure iste sapiente molestias culpa distinctio qui. Ut aut qui similique maxime vel qui. Et aspernatur corporis omnis. Aliquid asperiores veniam harum veritatis fugit quas quia omnis.","7.86" -"David Bomba","consequatur","Consequatur officia perferendis placeat quis. Nihil consectetur et voluptatibus. Modi sint modi modi possimus velit.","1.92" -"David Bomba","quia","Et eaque doloribus accusantium eos. Optio maxime fuga voluptate et. Consequatur atque modi eos dolorem. Quae assumenda repudiandae corporis. Suscipit quo quia ipsa itaque. Animi adipisci voluptas ut.","5.78" -"David Bomba","recusandae","Labore voluptas vero ut. Facere unde iure neque unde dolor. Non quis provident et porro.","1.69" -"David Bomba","reiciendis","Aut nulla autem porro.","4.38" -"David Bomba","beatae","Qui est quaerat quas velit accusamus minima. Ut aspernatur ut minima architecto. Nobis vero nisi suscipit voluptatum necessitatibus aut autem. Sunt ut atque enim aut quisquam laborum. Voluptatibus et laborum voluptatibus ex et nam voluptatem.","2.35" -"David Bomba","dolor","Sed impedit rerum quibusdam sed est laudantium praesentium. Voluptatem eligendi commodi vel magnam.","4.56" -"David Bomba","nihil","Et voluptatem possimus provident eaque ipsum. Recusandae rerum maiores quasi illum eum accusantium quae sunt.","5.15" -"David Bomba","impedit","Laborum dolores qui expedita eum ut. Distinctio explicabo laudantium quasi eligendi magnam necessitatibus placeat.","7.55" -"David Bomba","est","Consequatur suscipit qui aut rerum iste tempore illo. Assumenda temporibus illo aliquam quis rerum. Et officiis rerum culpa facilis ex.","8.68" -"David Bomba","dolores","Veritatis eius consequatur doloremque voluptates debitis. Voluptate asperiores rerum officiis.","2.88" -"David Bomba","reprehenderit","Expedita dolor nam inventore aliquam est architecto. Ut at itaque eius maiores est est soluta.","3.68" -"David Bomba","mollitia","Similique sint voluptatem excepturi laboriosam. Quam fuga recusandae totam id molestiae similique deserunt nesciunt. Ullam earum iusto reprehenderit qui.","7.78" -"David Bomba","cumque","Ut illum quis qui enim. Repudiandae earum incidunt natus eius qui. Qui unde a doloribus qui aliquid.","2.94" -"David Bomba","incidunt","Autem quos voluptas architecto sed cumque distinctio. Incidunt illo iste delectus molestias. Molestias nisi quis velit.","5.14" -"David Bomba","quo","Dolorem nobis dolorem quidem veritatis facilis sunt rerum exercitationem.","5.26" -"David Bomba","voluptatibus","Voluptatem voluptas vel explicabo placeat at eos ea. Laudantium est numquam repudiandae quia autem unde praesentium.","5.62" -"David Bomba","natus","Laudantium ut ut voluptas quam et et. Voluptatem aspernatur accusamus ut aliquid laborum et iure praesentium. Dolor voluptatem mollitia possimus beatae et ratione omnis. Consequatur possimus enim velit hic.","8.02" -"David Bomba","vero","Et similique omnis ea dolorem. Atque assumenda ratione hic. Doloremque reprehenderit sed voluptatem nemo.","6.14" -"David Bomba","provident","Consectetur animi ad est vel voluptatem velit. Repellat et sunt et provident. Sequi deserunt dignissimos nobis et et nam id. Voluptas et quia odit vero molestiae nulla odio id.","9.5" -"David Bomba","tempora","Laudantium distinctio et voluptate ex sint. Aut adipisci et consequatur at consequatur numquam. Ipsa aliquam totam placeat eveniet. Eligendi sint molestiae reiciendis rerum quam.","5.66" -"David Bomba","blanditiis","Odio perspiciatis nobis nulla odit omnis facere voluptates. Eos consequatur cupiditate facere sunt pariatur tempora. Reiciendis maiores odio sit quo cumque quidem qui. Hic et qui asperiores ut.","1.05" -"David Bomba","officia","Dolor fuga natus et laborum. Qui laborum cum et est laboriosam. Molestiae repudiandae in aut magni. Sint impedit vel ut ut velit ullam.","1.98" -"David Bomba","exercitationem","Et recusandae dolore eos optio sapiente. Dolores vitae libero aut sit.","7.85" -"David Bomba","illo","Earum corrupti occaecati dolores voluptatibus ab fugit. Dolorem assumenda ipsa tempore sed at dolor occaecati. Qui itaque quia modi est ea et.","8.6" -"David Bomba","eaque","Distinctio impedit incidunt labore est assumenda. Ut sed quasi odit vel rem dolor voluptate.","8.68" -"David Bomba","eveniet","Molestiae id dicta quod placeat consequatur asperiores dolorem. Sequi numquam qui ut libero dolore impedit aut. Eum temporibus non nesciunt.","3.89" -"David Bomba","debitis","Magnam eum qui facilis sed. Voluptas ab nostrum et nihil maiores. Sunt ratione nemo ipsum rem repudiandae voluptas.","6.53" -"David Bomba","culpa","A omnis consequatur quae. Vero et quas cum facilis.","4.65" -"David Bomba","sapiente","Autem vel pariatur odit quod et dicta veritatis. Sed nulla debitis reiciendis. Aut tenetur nostrum optio sit repellendus aut et.","1.2" -"David Bomba","delectus","Nobis dolorem iusto qui eos est recusandae velit. Qui voluptas veritatis aut occaecati quia. Accusantium earum debitis sed aut non.","9.859999999999999" -"David Bomba","dignissimos","Est dolorem odio perferendis officiis dignissimos quidem eveniet. Qui earum eos possimus laudantium qui et excepturi. Sed vel rem asperiores eum ut rerum deserunt et. Nam at et id commodi. Magnam reiciendis sapiente hic commodi et a illum sed. Magnam eos veniam iure delectus similique.","8.85" -"David Bomba","quisquam","At perspiciatis vero laborum itaque non. Facere nesciunt blanditiis consequuntur in. Consequuntur voluptatem ipsa culpa sed. Modi error vel dolorem.","7.12" -"David Bomba","sunt","Commodi excepturi aut quam sed impedit molestiae. Quis a iure vel quia error hic unde. In dolore quisquam nihil adipisci perspiciatis. Enim eveniet sed magni voluptate id molestiae sit non. Ut et molestiae sint et voluptas aperiam nobis.","8.109999999999999" -"David Bomba","necessitatibus","Autem illo sit quasi voluptatem enim. Aperiam recusandae eveniet enim consequatur. Et eius pariatur quas ipsa ex inventore. Sunt aliquam ut numquam in autem inventore eligendi molestiae.","2.71" -"David Bomba","cupiditate","Esse nulla illum sunt aliquid. Temporibus eum earum ea recusandae est distinctio. Placeat quae culpa et placeat animi et aut.","4.52" -"David Bomba","aperiam","Sit fuga sit itaque esse cum.","5.78" -"David Bomba","assumenda","Eius et eum vitae adipisci deserunt omnis commodi.","3.36" -"David Bomba","laborum","Tempora sint vel maxime et iusto eos. Consequatur aut aut autem ea est animi fugit. Qui sint ducimus ipsum et.","2.25" -"David Bomba","perferendis","Optio mollitia aperiam laudantium fuga et. Sed qui ad delectus aperiam inventore sit nisi eos.","8.470000000000001" -"David Bomba","a","Minima est et sed. Voluptatibus et quia recusandae.","1.16" -"David Bomba","dolore","Odit illum ut quia commodi natus. Veniam nemo qui quis optio. Repellat at est distinctio magnam.","9.539999999999999" -"David Bomba","placeat","Est culpa sit nemo dolores sunt eligendi ut suscipit. Voluptas qui maxime molestiae saepe sint ipsam. Delectus tempora iure sed sit.","5.9" -"David Bomba","cum","Autem voluptatem dolores qui dicta. Delectus ex aut rem quibusdam odit provident et.","6.92" -"David Bomba","dicta","Nemo fuga fugiat molestiae odio. Ullam rerum sed assumenda.","6.94" -"David Bomba","ex","Et accusamus ullam explicabo voluptatem eligendi neque. Veritatis quia suscipit aut sunt ipsa autem recusandae vel. Est et voluptas sint dolor velit eius incidunt rem.","8.609999999999999" -"David Bomba","rem","Corrupti a voluptatibus culpa aut autem omnis.","5.09" -"David Bomba","commodi","Quas asperiores expedita soluta porro ea id. Voluptatem dolorum magni aut ut in saepe. Eos et dignissimos error fugit hic.","4.59" -"David Bomba","voluptate","Beatae perspiciatis ipsam occaecati recusandae rerum optio. Magnam repudiandae soluta a qui velit voluptatem. Quaerat et expedita a cupiditate rem.","1.22" -"David Bomba","eum","Qui voluptatem ducimus aperiam odit et recusandae dolore.","4.28" -"David Bomba","quas","Delectus perferendis eum nihil. Accusamus temporibus rerum quia. Iure aut placeat illum praesentium totam ea voluptas ipsa. Maiores sapiente ut labore tempore.","3.86" -"David Bomba","magni","Eaque fugit excepturi ad. Dolores molestias natus fuga corrupti. Quo natus tempore voluptas magnam velit.","7.1" -"David Bomba","fugit","Omnis suscipit quis aut laudantium. Velit voluptas totam sequi. Architecto iste quia natus. Quas totam modi quod provident.","5.86" -"David Bomba","neque","Maiores itaque iure vel aut. Totam dolorum est quisquam officia nostrum. Aut in alias praesentium aliquid.","3.91" -"David Bomba","molestias","Cupiditate ut cupiditate voluptates accusantium iste veritatis ut molestias.","2.1" -"David Bomba","saepe","Dicta sequi laborum ex quos pariatur. Consequatur et culpa minima quo qui laboriosam. Nam nulla et quis fugit doloremque sunt nemo. Fugit quae totam quos distinctio ea in.","2.35" -"David Bomba","similique","Magni velit veniam eos sed ut repellendus. Sint dolorem quaerat quidem porro nobis. Maiores amet molestias consequatur sit.","9.01" -"David Bomba","earum","Iusto illo reiciendis vitae dolorem accusamus et. Qui aut quia consequatur facilis. Dolores aut ut optio aperiam qui officia. Cupiditate voluptatem quia odit et aut. Aut unde maxime dicta dignissimos quas. Dolorum aperiam quod est culpa. Blanditiis rerum perferendis aut.","6.46" -"David Bomba","ullam","Et illo voluptatum doloribus. Voluptatem sed dolores fugiat libero consequatur quas et. Vero quos consequuntur id quibusdam sequi blanditiis.","9.27" -"David Bomba","eos","Aperiam facilis sed non quo repudiandae dolores. Vero cumque dolorum et porro laborum exercitationem. Fugiat doloribus corporis soluta mollitia vel. Veniam velit dolore voluptas quam.","8.08" -"David Bomba","facere","Qui delectus quidem et qui. Fuga a omnis atque veniam. Repellat et saepe neque sed rerum quam.","6.34" -"David Bomba","quod","Architecto velit nam veniam ratione. Qui velit doloribus aut. Distinctio laudantium est consequatur consequatur molestiae. Cum et accusamus esse dolore quam.","1.07" -"David Bomba","nobis","Quasi omnis quidem qui sint et repellat facilis veritatis. Quam inventore soluta earum sit illum et. Eos delectus tempore odio ut laboriosam culpa.","2.56" -"David Bomba","perspiciatis","Quam deserunt temporibus laboriosam ea consequatur explicabo omnis. Exercitationem atque autem ut. Sit dolorum eius ut dolorem odit dolorem debitis.","1.67" -"David Bomba","animi","Quia ea atque id quia. Et odio laboriosam delectus dolorem. Fugiat ipsa porro accusantium.","7.91" -"David Bomba","nulla","Minus sit nobis rerum reiciendis. Consectetur modi non qui quisquam omnis culpa. Ut commodi tempora sit iste.","7.29" -"David Bomba","quibusdam","Et et nihil rerum aut vitae. Aut optio optio unde voluptatem. Perspiciatis aut placeat explicabo et ducimus.","7.9" -"David Bomba","excepturi","Quis repudiandae ratione impedit repellat doloremque est. Accusamus minus cupiditate velit. Aliquam explicabo magnam eaque velit quibusdam et quisquam. Eos maxime consequatur voluptatem quis doloremque quibusdam.","3.4" -"David Bomba","veritatis","Ut reprehenderit aut aut non quam cupiditate numquam.","6.15" -"David Bomba","omnis","Iusto eum aspernatur temporibus ratione voluptatem ducimus. Repellat rem sed aut cupiditate. Et quasi voluptatibus cumque cupiditate. Velit quidem praesentium quasi est sed est.","9.869999999999999" -"David Bomba","voluptatum","Ipsum cupiditate aut officia praesentium aut architecto. Eos omnis ratione sed quam. Sed corporis aut quia dicta autem.","5.64" -"David Bomba","sint","Libero sed dolore suscipit repellat ut libero.","5.69" -"David Bomba","odit","Nesciunt esse explicabo expedita facere repellat nulla. Eligendi iusto quos in culpa. Amet commodi et odit nostrum. Quaerat excepturi non rerum officiis autem ut.","1.37" -"David Bomba","ad","Vel enim sit sed doloribus sit sed. In veritatis sunt autem et aliquid aspernatur. Fugiat deleniti et porro repellat maiores ea.","4.55" -"David Bomba","asperiores","Cum veniam ipsam suscipit eos totam quae. Eaque ducimus odit ut molestiae aut esse.","1.9" -"David Bomba","accusamus","Aliquam alias laborum numquam asperiores. Ut praesentium repellendus ut nostrum. Cumque ut est et nam qui esse hic.","3.8" -"David Bomba","explicabo","Vero eaque quasi officiis modi nihil ad dolor. Sequi facilis assumenda possimus vel fugit inventore voluptatem.","2.21" -"David Bomba","consequuntur","Reprehenderit et aut rerum quos iusto rerum. A delectus eveniet quia expedita.","3.72" -"David Bomba","repellat","Consequatur quis at ut nesciunt quibusdam dicta ut provident. Aperiam dicta dolores id sed non ex sunt.","7.56" -"David Bomba","esse","Aut harum cupiditate quos nihil quis. Cupiditate non non est nesciunt consequatur. Provident est quis porro consequatur et. Illo placeat et quisquam sit nisi veniam commodi.","5.03" -"David Bomba","doloribus","Provident molestias libero dolores sit voluptate quis architecto.","9.91" -"David Bomba","magnam","Voluptas dicta occaecati adipisci autem sunt libero tenetur est. Voluptas quia recusandae est et enim est. Labore fugit vitae qui cumque aut. Illo aperiam aliquid deserunt beatae. Voluptatem tempora tenetur dignissimos et autem qui minus voluptatem.","1.53" -"David Bomba","suscipit","Ullam amet consequuntur itaque. Cupiditate odio facere quis est fuga architecto. Aut placeat quae ut itaque. Voluptatem omnis architecto ipsum qui. Blanditiis nostrum iusto quo nesciunt voluptate. Ut expedita unde ex illum ut dignissimos.","4.43" -"David Bomba","iure","Quo autem voluptas reiciendis temporibus.","4.27" -"David Bomba","modi","Adipisci dolor vel non officia nisi veritatis. Est quo voluptas doloribus quis est sunt. Ducimus minus quia quia est eos maiores earum. Ut placeat iste tempore occaecati.","1.04" -"David Bomba","labore","Doloremque distinctio aperiam voluptas rerum quidem sed.","1.95" -"David Bomba","soluta","Dolore sint similique eos. Harum est ipsa aut voluptas esse culpa. Voluptas voluptatem cumque et aut et quasi tempora.","1.67" -"David Bomba","accusantium","Eos quo voluptatem odit temporibus aut. Reprehenderit sit ducimus expedita nostrum incidunt ut voluptates.","8.619999999999999" -"David Bomba","vitae","Enim error dolorem cupiditate voluptate quasi numquam quis. Porro ducimus eos maiores facere.","5.28" -"David Bomba","possimus","Et tempore at sit est repellendus aut illo eum. Ratione aperiam aliquam veritatis rerum est cupiditate. Fuga sit recusandae officiis.","9.279999999999999" -"David Bomba","nisi","Animi modi ut perspiciatis temporibus quo. Est officia qui numquam perspiciatis. Provident ut nostrum enim accusantium veniam saepe. Vero est minus aut aliquam.","8.67" -"David Bomba","ratione","Nemo at quo est velit.","5.6" -"David Bomba","illum","Odio illo veritatis dolorem omnis ad. Magni officia est officia voluptate voluptas dolor. Est dolores et tempora corporis est at ullam. Illum amet ipsa quia et omnis esse quaerat. Fugiat unde magni quod saepe. Incidunt assumenda neque voluptatem.","6.01" -"David Bomba","libero","Reiciendis voluptatem sed vitae sapiente pariatur alias. Voluptates velit libero voluptatum minima aperiam. Magnam natus consequatur voluptatem molestiae iure cum qui. Nisi tempore aperiam porro.","9.16" -"David Bomba","alias","A fugiat id aliquam officia. Eum eum tempore rerum officiis modi sit. Non impedit incidunt et commodi quia harum nesciunt.","1.92" -"David Bomba","occaecati","Aspernatur aut temporibus voluptas. Cumque sint sint voluptatibus.","5.95" -"David Bomba","1","100","100" -"David Bomba","ab","Sed perferendis modi velit minima placeat reprehenderit. Voluptatum ullam vel officia quia et esse quaerat. Sit aperiam minus dolor. Quasi earum temporibus est aspernatur.","6.86" -"David Bomba","amet","Nihil consequatur et deserunt nihil et.","7.82" -"David Bomba",":MONTH","hey there :MONTH+1 and :YEAR+1","0" +"Invoice Ninja v4.5.23 - December 17, 2020 7:01 am",,,, +,,,, +Expenses,,,, +Client,Project,Notes,Amount,Date +David Bomba,officiis,Sed minima soluta saepe quae laboriosam placeat. Sequi laboriosam architecto et aut. Ut hic repellat veniam eligendi.,3.94,2022-01-01 +David Bomba,maxime,Distinctio consectetur provident nisi autem ipsum animi.,1.11,2022-01-01 +David Bomba,atque,Fugiat illo iste esse laudantium est. Recusandae et ullam optio soluta. Est est nulla doloribus adipisci.,9.78,2022-01-02 +David Bomba,itaque,Placeat aliquam et est quasi illo aut inventore. Expedita asperiores cupiditate accusantium. Eos esse dolorem tenetur illo totam.,3.5,2022-01-03 +David Bomba,et,Est quia soluta asperiores dolor ipsum illum sapiente.,3.98,2022-01-04 +David Bomba,velit,Quia consequatur magnam impedit dignissimos. Ut vel sapiente nemo quia laborum. Consectetur occaecati quia sunt eum. Dignissimos labore molestiae laudantium impedit temporibus blanditiis porro maxime. Dolorem quia alias ducimus fugiat. Aut vel officia voluptatem et quia.,1.83,2022-01-05 +David Bomba,corporis,Vel temporibus qui et ex a. Pariatur minima ipsa quasi non dolorum laboriosam laboriosam. Dolor soluta ut nostrum veniam. Porro alias eos quibusdam. Maiores aut eos similique.,9.59,2022-01-06 +David Bomba,expedita,Mollitia aperiam modi velit sit necessitatibus dolor quibusdam sit. Autem molestiae neque neque doloribus nulla.,8.86,2022-01-07 +David Bomba,ea,Deleniti exercitationem rem et nihil. Ea qui autem fuga repudiandae accusamus qui et et. Quia accusamus molestiae dolor.,5.37,2022-01-08 +David Bomba,ducimus,Ut nobis sint et error ducimus minus suscipit. Ipsum inventore cumque et magni minima explicabo. Corporis earum nihil at facilis ut voluptates aut. Blanditiis reiciendis aut dolor et. Est rerum magni in qui velit. Dolore nihil nostrum quisquam in ut.,8.96,2022-01-09 +David Bomba,in,Non laudantium adipisci eos porro. Quia aspernatur cum soluta eaque blanditiis fugit alias. Quam nobis dolorem repellendus ut alias dolor cumque. Laboriosam laboriosam et debitis autem autem.,3.14,2022-01-10 +David Bomba,ut,Fuga quam reprehenderit adipisci nesciunt ratione omnis. Dolore dicta quasi excepturi rerum. Alias voluptatem voluptatem vel harum iste id. Nihil est velit quo soluta delectus.,4.6,2022-01-11 +David Bomba,adipisci,Itaque iure necessitatibus vel doloribus omnis. Possimus atque tempora quo ut.,6.64,2022-01-12 +David Bomba,quidem,Sit maiores quia quos facilis earum ducimus. Numquam dolores quo numquam.,7.47,2022-01-13 +David Bomba,optio,Qui minus dicta culpa aperiam id natus quaerat. Facilis cupiditate consequuntur quisquam soluta in.,3.03,2022-01-14 +David Bomba,temporibus,Tempora eligendi nisi dolore non tenetur. Officiis autem aspernatur et optio. Omnis dolore placeat et nihil et.,7.54,2022-01-15 +David Bomba,repellendus,Voluptates hic dolorum aspernatur vitae. Adipisci dicta ut sapiente commodi quia explicabo.,2.14,2022-01-16 +David Bomba,dolorum,Quo vitae atque aut vel et dolorem eaque alias. Quod tempore illum placeat ipsum aspernatur. Incidunt qui ea dolorem et. Optio qui deserunt beatae sed perferendis. Esse rerum et magnam eum soluta. Consequatur rem sed ut repellendus exercitationem. Dolores error omnis quia qui qui.,5.9,2022-01-17 +David Bomba,non,Et cumque odio nam voluptatum nam molestias.,2.62,2022-01-18 +David Bomba,quam,Nostrum in eos voluptatem.,8.63,2022-01-19 +David Bomba,harum,Vero deleniti vel cumque cumque cupiditate nihil. Est non blanditiis consequatur commodi similique cumque ipsa sapiente. Dolor eum fugiat distinctio nihil aut. Sequi qui cum architecto quia ullam rerum ad. Quo et magnam perferendis rerum voluptatem. Maiores atque ipsa nihil.,7.64,2022-01-20 +David Bomba,quasi,Et labore doloremque incidunt atque illo repudiandae. Officiis necessitatibus est quo. Veniam eum qui aut est est.,5.79,2022-01-21 +David Bomba,sed,Illo nihil aut iste sed. In ea rerum atque iure. Et maiores qui odit inventore cum at. Possimus doloribus dicta excepturi quisquam asperiores qui.,2.56,2022-01-22 +David Bomba,numquam,Ex temporibus alias voluptatem qui.,6.21,2022-01-23 +David Bomba,quis,Aut nobis qui quia. Laboriosam id optio aut. Voluptatem doloremque doloremque odit sint iure sint adipisci. Ut fugiat perspiciatis adipisci earum quasi et.,9.74,2022-01-24 +David Bomba,laboriosam,Temporibus quisquam eligendi harum. Quis est architecto suscipit. Saepe aut et quis. Dolorem nisi recusandae laborum nulla aut dolorem. Provident consectetur maxime minima sint. Et non consequatur possimus officia non sunt incidunt. Odit quia sit quia consequatur ipsam.,5.59,2022-01-25 +David Bomba,voluptas,Numquam quasi eos harum laborum illo. Sit distinctio totam dolores deleniti veritatis voluptas inventore. Pariatur dicta saepe id id quod ratione ea.,5.86,2022-01-26 +David Bomba,unde,Similique autem maiores et repellat natus eius unde sequi.,8.81,2022-01-27 +David Bomba,autem,Sit eveniet reiciendis aut rerum est omnis sunt sed.,3.42,2022-01-28 +David Bomba,sequi,Nesciunt sequi modi inventore delectus aut sit fuga. Modi et quibusdam et laborum.,9.51,2022-01-29 +David Bomba,deserunt,Similique hic voluptate velit. Fuga est est qui fugit eligendi consequatur omnis. Nihil alias adipisci quisquam ut explicabo facere.,2.16,2022-01-30 +David Bomba,id,Facere vero amet fugit et voluptatem nisi repellendus. Excepturi sit earum in pariatur consequatur aut. Molestiae et explicabo voluptas tempore voluptates eos.,9.83,2022-01-31 +David Bomba,nesciunt,Perspiciatis id iste vel enim alias fugit itaque. Facilis quae aut quos nam est nemo suscipit impedit. Debitis ut commodi iure magni. Optio voluptatum inventore tempora incidunt aut deserunt corporis animi.,6.12,2022-02-01 +David Bomba,error,Quisquam ut dolor quo. Hic ex quos neque omnis officiis cumque. Et quae qui autem. Pariatur amet iure labore fugiat error quo.,2.03,2022-02-02 +David Bomba,iste,Ad qui adipisci in et quos eveniet. Sapiente voluptatum sint error ex in. Minima voluptatem commodi ea aut laborum.,5.13,2022-02-03 +David Bomba,laudantium,Quo inventore est mollitia fugiat. Veniam sit fugit dolorem.,7.91,2022-02-04 +David Bomba,minima,Nulla laborum totam adipisci esse explicabo. Eaque dolor facere nesciunt voluptatem ratione. Nesciunt dignissimos cum voluptas quidem repudiandae aut sed. Repellat voluptatem veniam culpa eum.,8.25,2022-02-05 +David Bomba,aliquid,Consequuntur sint laboriosam adipisci consequatur quam a fuga. Delectus sequi tempore molestias dolorem fugiat molestiae ex. Quisquam eaque eum iure ut nisi odit quia. Id iusto ipsa nihil harum hic voluptatum beatae sed. Eum quam omnis in cumque.,9.92,2022-02-06 +David Bomba,iusto,Laboriosam quia eum error quam repellendus.,6.02,2022-02-07 +David Bomba,nemo,Deleniti asperiores doloribus consequuntur magni. Earum aspernatur et vitae veniam molestiae magni. Quaerat error ea dignissimos qui labore error velit.,9.9,2022-02-08 +David Bomba,minus,Voluptatum explicabo amet quidem quia autem aut temporibus. Dolorem sed aut totam et minus ut consequatur tenetur. Et rerum quia autem neque sed neque.,8.26,2022-02-09 +David Bomba,quos,Suscipit praesentium animi ut sunt. Tempore adipisci maiores sed atque id libero consectetur porro. Itaque consequuntur perspiciatis officiis sit. Itaque magni velit laborum rerum qui reiciendis ut. Provident tempore fuga hic quae aut.,6.52,2022-02-10 +David Bomba,vel,Eum aliquam officia ea beatae fugit qui ut laboriosam.,8.34,2022-02-11 +David Bomba,fuga,Vel ut deserunt consequatur voluptatum quis nam. Reiciendis possimus quisquam fugiat numquam.,4.12,2022-02-12 +David Bomba,nostrum,Non ducimus non rem. Est qui odit est nam. Ab voluptatum nihil itaque explicabo hic.,7.07,2022-02-13 +David Bomba,hic,Non modi voluptatum blanditiis et.,4.29,2022-02-14 +David Bomba,rerum,Enim omnis ut dolore ex velit sit. Ab et dolor qui iste. Odit quia et et debitis eligendi illo. Rerum rem corrupti dolor est est ea illum.,7.08,2022-02-15 +David Bomba,corrupti,Ut vitae accusantium ratione in suscipit. Distinctio unde est expedita omnis. Sequi non sit ut modi nostrum libero nesciunt beatae. Qui dolorem optio reprehenderit eum.,8.97,2022-02-16 +David Bomba,maiores,Aut accusantium neque nam aut quas inventore. Qui laboriosam quam commodi aut suscipit et. Nam aut iusto aut facilis vitae dolores eum. Culpa magni deserunt qui rerum aut.,2.41,2022-02-17 +David Bomba,totam,Totam eos molestiae totam vero fuga sint. Nisi minima et veritatis fugiat. Quo earum ut eius odit.,3.41,2022-02-18 +David Bomba,eligendi,Voluptates amet voluptatem placeat aliquam non non saepe. Provident quaerat laudantium debitis. Quasi sed maxime deserunt laboriosam reiciendis tempore.,8.33,2022-02-19 +David Bomba,architecto,Placeat qui qui doloribus architecto distinctio.,3.3,2022-02-20 +David Bomba,qui,Quibusdam repellat quo tenetur ipsum. Et labore itaque totam sequi quia. Quo in beatae ipsa quia est. Totam architecto placeat hic qui recusandae tempora reiciendis.,2.49,2022-02-21 +David Bomba,deleniti,Ut illo vero accusantium ex dolor id. Hic in nobis est dolorem consequatur qui ratione.,6.07,2022-02-22 +David Bomba,aspernatur,Non voluptatem et deserunt molestiae consectetur. Fuga autem et nisi qui quisquam veniam modi sunt. Recusandae maiores qui facere ut expedita laudantium maxime consequuntur. Qui id quibusdam neque et accusantium.,5.05,2022-02-23 +David Bomba,sit,Quaerat consequatur debitis aut quidem magnam. Illum dolore numquam voluptates cum amet corporis sit.,5.82,2022-02-24 +David Bomba,doloremque,Est non ut libero. Aut qui qui qui maiores. Impedit est optio saepe dignissimos odio. Qui nisi doloremque eius mollitia sint repellat possimus at. Possimus et sit odio quis.,4.08,2022-02-25 +David Bomba,quaerat,Error est eum in pariatur. Aspernatur recusandae ex quasi molestiae. Quos sed excepturi placeat non.,8.38,2022-02-26 +David Bomba,pariatur,Laboriosam aliquam et eos consequatur ab quis.,4.52,2022-02-27 +David Bomba,facilis,Vero officia necessitatibus adipisci in culpa. Soluta et voluptas magni tenetur ut aut. Et ducimus qui non dolores eum.,9.49,2022-02-28 +David Bomba,aut,Excepturi sit ipsum ipsam corrupti. Quod ab voluptatem explicabo ex. Dolores fugit maiores nemo. Natus sit eligendi quia voluptas deleniti qui. Omnis perferendis consequatur aut quos architecto in.,7.73,2022-03-01 +David Bomba,molestiae,Quam et ex provident magni.,3.26,2022-03-02 +David Bomba,inventore,Placeat enim ipsa perspiciatis dolorem quasi impedit quas exercitationem. Consequatur aut architecto laborum suscipit. Voluptas veritatis voluptas corrupti ex earum laudantium. Ad aliquid est autem a molestias enim dolores dignissimos.,4.82,2022-03-03 +David Bomba,enim,Qui quo sed et quos possimus error. Recusandae at illum ipsum natus. In esse et sit debitis quo ut tempore. Et vel eos officiis provident perferendis.,3.98,2022-03-04 +David Bomba,consectetur,Quas voluptas facere beatae sequi quos et magni. Pariatur harum aspernatur qui consequatur quae. Rem voluptatem dolorem voluptatem voluptas quas rerum.,6.81,2022-03-05 +David Bomba,distinctio,Placeat libero quis id sed praesentium. Ea sed magnam et aliquam.,2.17,2022-03-06 +David Bomba,praesentium,Non itaque consectetur repellendus cupiditate vel expedita. Ipsa rerum harum voluptatem magnam voluptatem. Est reiciendis inventore repellat ut vitae minus in.,8.41,2022-03-07 +David Bomba,eius,Corporis consequatur aut maiores. Praesentium in voluptates consequatur et accusamus. Fuga itaque aliquid consequuntur consequatur.,2.69,2022-03-08 +David Bomba,ipsum,Iste sit beatae consequuntur omnis praesentium iste nulla. Totam odio neque quia excepturi optio sit. Dolores quis unde repellat et maxime.,2.13,2022-03-09 +David Bomba,veniam,Illum nisi maiores aspernatur ut ut voluptatum.,4.8,2022-03-10 +David Bomba,quae,Voluptatem perspiciatis atque laborum qui recusandae non dicta qui. Qui esse nesciunt corporis architecto.,3.35,2022-03-11 +David Bomba,tenetur,Neque dolores ad ut. Sit sed nemo est sed ut. Alias est est officiis pariatur autem.,8.62,2022-03-12 +David Bomba,aliquam,Aut minus eveniet architecto doloribus esse sint amet. Dignissimos qui enim et fuga sapiente quaerat.,5.03,2022-03-13 +David Bomba,porro,Iure maxime aperiam ipsa id doloremque ad pariatur quia. Aut maiores ipsa est dolor quidem ad quisquam. Excepturi dolor dolores molestiae explicabo dolorem. Sapiente nobis mollitia reprehenderit voluptatem culpa vel sapiente corrupti.,7.42,2022-03-14 +David Bomba,repudiandae,Molestias ut ullam ipsa accusantium. Nobis aut sint cupiditate a ullam. Aut velit nemo modi voluptate.,2.03,2022-03-15 +David Bomba,voluptatem,Maxime non nobis quae omnis molestiae sed dolor dolorem.,3.69,2022-03-16 +David Bomba,ipsa,Voluptas commodi expedita doloribus ut. Minima ullam repudiandae doloribus repellat aut ut. Officia odio labore laboriosam dolor et. Quia dolorem suscipit possimus omnis quidem nam commodi.,1.28,2022-03-17 +David Bomba,nam,Et odio provident eos eveniet nisi ut est enim. Earum inventore tempora doloribus officia sit et esse facere. Quia iusto suscipit et occaecati. Voluptatum commodi placeat tempora saepe facilis exercitationem. Quae esse id et est iste.,7.57,2022-03-18 +David Bomba,voluptates,Sed corrupti dolore culpa consectetur id voluptatem fugiat. Ex impedit sit eum facere reprehenderit ut.,4.91,2022-03-19 +David Bomba,odio,Maxime sed fuga id. Architecto ut nisi et ullam reiciendis voluptatem. Odit excepturi qui cupiditate.,4.54,2022-03-20 +David Bomba,dolorem,Ratione et iure similique est exercitationem a laboriosam.,5.59,2022-03-21 +David Bomba,ipsam,Iure iste sapiente molestias culpa distinctio qui. Ut aut qui similique maxime vel qui. Et aspernatur corporis omnis. Aliquid asperiores veniam harum veritatis fugit quas quia omnis.,7.86,2022-03-22 +David Bomba,consequatur,Consequatur officia perferendis placeat quis. Nihil consectetur et voluptatibus. Modi sint modi modi possimus velit.,1.92,2022-03-23 +David Bomba,quia,Et eaque doloribus accusantium eos. Optio maxime fuga voluptate et. Consequatur atque modi eos dolorem. Quae assumenda repudiandae corporis. Suscipit quo quia ipsa itaque. Animi adipisci voluptas ut.,5.78,2022-03-24 +David Bomba,recusandae,Labore voluptas vero ut. Facere unde iure neque unde dolor. Non quis provident et porro.,1.69,2022-03-25 +David Bomba,reiciendis,Aut nulla autem porro.,4.38,2022-03-26 +David Bomba,beatae,Qui est quaerat quas velit accusamus minima. Ut aspernatur ut minima architecto. Nobis vero nisi suscipit voluptatum necessitatibus aut autem. Sunt ut atque enim aut quisquam laborum. Voluptatibus et laborum voluptatibus ex et nam voluptatem.,2.35,2022-03-27 +David Bomba,dolor,Sed impedit rerum quibusdam sed est laudantium praesentium. Voluptatem eligendi commodi vel magnam.,4.56,2022-03-28 +David Bomba,nihil,Et voluptatem possimus provident eaque ipsum. Recusandae rerum maiores quasi illum eum accusantium quae sunt.,5.15,2022-03-29 +David Bomba,impedit,Laborum dolores qui expedita eum ut. Distinctio explicabo laudantium quasi eligendi magnam necessitatibus placeat.,7.55,2022-03-30 +David Bomba,est,Consequatur suscipit qui aut rerum iste tempore illo. Assumenda temporibus illo aliquam quis rerum. Et officiis rerum culpa facilis ex.,8.68,2022-03-31 +David Bomba,dolores,Veritatis eius consequatur doloremque voluptates debitis. Voluptate asperiores rerum officiis.,2.88,2022-04-01 +David Bomba,reprehenderit,Expedita dolor nam inventore aliquam est architecto. Ut at itaque eius maiores est est soluta.,3.68,2022-04-02 +David Bomba,mollitia,Similique sint voluptatem excepturi laboriosam. Quam fuga recusandae totam id molestiae similique deserunt nesciunt. Ullam earum iusto reprehenderit qui.,7.78,2022-04-03 +David Bomba,cumque,Ut illum quis qui enim. Repudiandae earum incidunt natus eius qui. Qui unde a doloribus qui aliquid.,2.94,2022-04-04 +David Bomba,incidunt,Autem quos voluptas architecto sed cumque distinctio. Incidunt illo iste delectus molestias. Molestias nisi quis velit.,5.14,2022-04-05 +David Bomba,quo,Dolorem nobis dolorem quidem veritatis facilis sunt rerum exercitationem.,5.26,2022-04-06 +David Bomba,voluptatibus,Voluptatem voluptas vel explicabo placeat at eos ea. Laudantium est numquam repudiandae quia autem unde praesentium.,5.62,2022-04-07 +David Bomba,natus,Laudantium ut ut voluptas quam et et. Voluptatem aspernatur accusamus ut aliquid laborum et iure praesentium. Dolor voluptatem mollitia possimus beatae et ratione omnis. Consequatur possimus enim velit hic.,8.02,2022-04-08 +David Bomba,vero,Et similique omnis ea dolorem. Atque assumenda ratione hic. Doloremque reprehenderit sed voluptatem nemo.,6.14,2022-04-09 +David Bomba,provident,Consectetur animi ad est vel voluptatem velit. Repellat et sunt et provident. Sequi deserunt dignissimos nobis et et nam id. Voluptas et quia odit vero molestiae nulla odio id.,9.5,2022-04-10 +David Bomba,tempora,Laudantium distinctio et voluptate ex sint. Aut adipisci et consequatur at consequatur numquam. Ipsa aliquam totam placeat eveniet. Eligendi sint molestiae reiciendis rerum quam.,5.66,2022-04-11 +David Bomba,blanditiis,Odio perspiciatis nobis nulla odit omnis facere voluptates. Eos consequatur cupiditate facere sunt pariatur tempora. Reiciendis maiores odio sit quo cumque quidem qui. Hic et qui asperiores ut.,1.05,2022-04-12 +David Bomba,officia,Dolor fuga natus et laborum. Qui laborum cum et est laboriosam. Molestiae repudiandae in aut magni. Sint impedit vel ut ut velit ullam.,1.98,2022-04-13 +David Bomba,exercitationem,Et recusandae dolore eos optio sapiente. Dolores vitae libero aut sit.,7.85,2022-04-14 +David Bomba,illo,Earum corrupti occaecati dolores voluptatibus ab fugit. Dolorem assumenda ipsa tempore sed at dolor occaecati. Qui itaque quia modi est ea et.,8.6,2022-04-15 +David Bomba,eaque,Distinctio impedit incidunt labore est assumenda. Ut sed quasi odit vel rem dolor voluptate.,8.68,2022-04-16 +David Bomba,eveniet,Molestiae id dicta quod placeat consequatur asperiores dolorem. Sequi numquam qui ut libero dolore impedit aut. Eum temporibus non nesciunt.,3.89,2022-04-17 +David Bomba,debitis,Magnam eum qui facilis sed. Voluptas ab nostrum et nihil maiores. Sunt ratione nemo ipsum rem repudiandae voluptas.,6.53,2022-04-18 +David Bomba,culpa,A omnis consequatur quae. Vero et quas cum facilis.,4.65,2022-04-19 +David Bomba,sapiente,Autem vel pariatur odit quod et dicta veritatis. Sed nulla debitis reiciendis. Aut tenetur nostrum optio sit repellendus aut et.,1.2,2022-04-20 +David Bomba,delectus,Nobis dolorem iusto qui eos est recusandae velit. Qui voluptas veritatis aut occaecati quia. Accusantium earum debitis sed aut non.,9.86,2022-04-21 +David Bomba,dignissimos,Est dolorem odio perferendis officiis dignissimos quidem eveniet. Qui earum eos possimus laudantium qui et excepturi. Sed vel rem asperiores eum ut rerum deserunt et. Nam at et id commodi. Magnam reiciendis sapiente hic commodi et a illum sed. Magnam eos veniam iure delectus similique.,8.85,2022-04-22 +David Bomba,quisquam,At perspiciatis vero laborum itaque non. Facere nesciunt blanditiis consequuntur in. Consequuntur voluptatem ipsa culpa sed. Modi error vel dolorem.,7.12,2022-04-23 +David Bomba,sunt,Commodi excepturi aut quam sed impedit molestiae. Quis a iure vel quia error hic unde. In dolore quisquam nihil adipisci perspiciatis. Enim eveniet sed magni voluptate id molestiae sit non. Ut et molestiae sint et voluptas aperiam nobis.,8.11,2022-04-24 +David Bomba,necessitatibus,Autem illo sit quasi voluptatem enim. Aperiam recusandae eveniet enim consequatur. Et eius pariatur quas ipsa ex inventore. Sunt aliquam ut numquam in autem inventore eligendi molestiae.,2.71,2022-04-25 +David Bomba,cupiditate,Esse nulla illum sunt aliquid. Temporibus eum earum ea recusandae est distinctio. Placeat quae culpa et placeat animi et aut.,4.52,2022-04-26 +David Bomba,aperiam,Sit fuga sit itaque esse cum.,5.78,2022-04-27 +David Bomba,assumenda,Eius et eum vitae adipisci deserunt omnis commodi.,3.36,2022-04-28 +David Bomba,laborum,Tempora sint vel maxime et iusto eos. Consequatur aut aut autem ea est animi fugit. Qui sint ducimus ipsum et.,2.25,2022-04-29 +David Bomba,perferendis,Optio mollitia aperiam laudantium fuga et. Sed qui ad delectus aperiam inventore sit nisi eos.,8.47,2022-04-30 +David Bomba,a,Minima est et sed. Voluptatibus et quia recusandae.,1.16,2022-05-01 +David Bomba,dolore,Odit illum ut quia commodi natus. Veniam nemo qui quis optio. Repellat at est distinctio magnam.,9.54,2022-05-02 +David Bomba,placeat,Est culpa sit nemo dolores sunt eligendi ut suscipit. Voluptas qui maxime molestiae saepe sint ipsam. Delectus tempora iure sed sit.,5.9,2022-05-03 +David Bomba,cum,Autem voluptatem dolores qui dicta. Delectus ex aut rem quibusdam odit provident et.,6.92,2022-05-04 +David Bomba,dicta,Nemo fuga fugiat molestiae odio. Ullam rerum sed assumenda.,6.94,2022-05-05 +David Bomba,ex,Et accusamus ullam explicabo voluptatem eligendi neque. Veritatis quia suscipit aut sunt ipsa autem recusandae vel. Est et voluptas sint dolor velit eius incidunt rem.,8.61,2022-05-06 +David Bomba,rem,Corrupti a voluptatibus culpa aut autem omnis.,5.09,2022-05-07 +David Bomba,commodi,Quas asperiores expedita soluta porro ea id. Voluptatem dolorum magni aut ut in saepe. Eos et dignissimos error fugit hic.,4.59,2022-05-08 +David Bomba,voluptate,Beatae perspiciatis ipsam occaecati recusandae rerum optio. Magnam repudiandae soluta a qui velit voluptatem. Quaerat et expedita a cupiditate rem.,1.22,2022-05-09 +David Bomba,eum,Qui voluptatem ducimus aperiam odit et recusandae dolore.,4.28,2022-05-10 +David Bomba,quas,Delectus perferendis eum nihil. Accusamus temporibus rerum quia. Iure aut placeat illum praesentium totam ea voluptas ipsa. Maiores sapiente ut labore tempore.,3.86,2022-05-11 +David Bomba,magni,Eaque fugit excepturi ad. Dolores molestias natus fuga corrupti. Quo natus tempore voluptas magnam velit.,7.1,2022-05-12 +David Bomba,fugit,Omnis suscipit quis aut laudantium. Velit voluptas totam sequi. Architecto iste quia natus. Quas totam modi quod provident.,5.86,2022-05-13 +David Bomba,neque,Maiores itaque iure vel aut. Totam dolorum est quisquam officia nostrum. Aut in alias praesentium aliquid.,3.91,2022-05-14 +David Bomba,molestias,Cupiditate ut cupiditate voluptates accusantium iste veritatis ut molestias.,2.1,2022-05-15 +David Bomba,saepe,Dicta sequi laborum ex quos pariatur. Consequatur et culpa minima quo qui laboriosam. Nam nulla et quis fugit doloremque sunt nemo. Fugit quae totam quos distinctio ea in.,2.35,2022-05-16 +David Bomba,similique,Magni velit veniam eos sed ut repellendus. Sint dolorem quaerat quidem porro nobis. Maiores amet molestias consequatur sit.,9.01,2022-05-17 +David Bomba,earum,Iusto illo reiciendis vitae dolorem accusamus et. Qui aut quia consequatur facilis. Dolores aut ut optio aperiam qui officia. Cupiditate voluptatem quia odit et aut. Aut unde maxime dicta dignissimos quas. Dolorum aperiam quod est culpa. Blanditiis rerum perferendis aut.,6.46,2022-05-18 +David Bomba,ullam,Et illo voluptatum doloribus. Voluptatem sed dolores fugiat libero consequatur quas et. Vero quos consequuntur id quibusdam sequi blanditiis.,9.27,2022-05-19 +David Bomba,eos,Aperiam facilis sed non quo repudiandae dolores. Vero cumque dolorum et porro laborum exercitationem. Fugiat doloribus corporis soluta mollitia vel. Veniam velit dolore voluptas quam.,8.08,2022-05-20 +David Bomba,facere,Qui delectus quidem et qui. Fuga a omnis atque veniam. Repellat et saepe neque sed rerum quam.,6.34,2022-05-21 +David Bomba,quod,Architecto velit nam veniam ratione. Qui velit doloribus aut. Distinctio laudantium est consequatur consequatur molestiae. Cum et accusamus esse dolore quam.,1.07,2022-05-22 +David Bomba,nobis,Quasi omnis quidem qui sint et repellat facilis veritatis. Quam inventore soluta earum sit illum et. Eos delectus tempore odio ut laboriosam culpa.,2.56,2022-05-23 +David Bomba,perspiciatis,Quam deserunt temporibus laboriosam ea consequatur explicabo omnis. Exercitationem atque autem ut. Sit dolorum eius ut dolorem odit dolorem debitis.,1.67,2022-05-24 +David Bomba,animi,Quia ea atque id quia. Et odio laboriosam delectus dolorem. Fugiat ipsa porro accusantium.,7.91,2022-05-25 +David Bomba,nulla,Minus sit nobis rerum reiciendis. Consectetur modi non qui quisquam omnis culpa. Ut commodi tempora sit iste.,7.29,2022-05-26 +David Bomba,quibusdam,Et et nihil rerum aut vitae. Aut optio optio unde voluptatem. Perspiciatis aut placeat explicabo et ducimus.,7.9,2022-05-27 +David Bomba,excepturi,Quis repudiandae ratione impedit repellat doloremque est. Accusamus minus cupiditate velit. Aliquam explicabo magnam eaque velit quibusdam et quisquam. Eos maxime consequatur voluptatem quis doloremque quibusdam.,3.4,2022-05-28 +David Bomba,veritatis,Ut reprehenderit aut aut non quam cupiditate numquam.,6.15,2022-05-29 +David Bomba,omnis,Iusto eum aspernatur temporibus ratione voluptatem ducimus. Repellat rem sed aut cupiditate. Et quasi voluptatibus cumque cupiditate. Velit quidem praesentium quasi est sed est.,9.87,2022-05-30 +David Bomba,voluptatum,Ipsum cupiditate aut officia praesentium aut architecto. Eos omnis ratione sed quam. Sed corporis aut quia dicta autem.,5.64,2022-05-31 +David Bomba,sint,Libero sed dolore suscipit repellat ut libero.,5.69,2022-06-01 +David Bomba,odit,Nesciunt esse explicabo expedita facere repellat nulla. Eligendi iusto quos in culpa. Amet commodi et odit nostrum. Quaerat excepturi non rerum officiis autem ut.,1.37,2022-06-02 +David Bomba,ad,Vel enim sit sed doloribus sit sed. In veritatis sunt autem et aliquid aspernatur. Fugiat deleniti et porro repellat maiores ea.,4.55,2022-06-03 +David Bomba,asperiores,Cum veniam ipsam suscipit eos totam quae. Eaque ducimus odit ut molestiae aut esse.,1.9,2022-06-04 +David Bomba,accusamus,Aliquam alias laborum numquam asperiores. Ut praesentium repellendus ut nostrum. Cumque ut est et nam qui esse hic.,3.8,2022-06-05 +David Bomba,explicabo,Vero eaque quasi officiis modi nihil ad dolor. Sequi facilis assumenda possimus vel fugit inventore voluptatem.,2.21,2022-06-06 +David Bomba,consequuntur,Reprehenderit et aut rerum quos iusto rerum. A delectus eveniet quia expedita.,3.72,2022-06-07 +David Bomba,repellat,Consequatur quis at ut nesciunt quibusdam dicta ut provident. Aperiam dicta dolores id sed non ex sunt.,7.56,2022-06-08 +David Bomba,esse,Aut harum cupiditate quos nihil quis. Cupiditate non non est nesciunt consequatur. Provident est quis porro consequatur et. Illo placeat et quisquam sit nisi veniam commodi.,5.03,2022-06-09 +David Bomba,doloribus,Provident molestias libero dolores sit voluptate quis architecto.,9.91,2022-06-10 +David Bomba,magnam,Voluptas dicta occaecati adipisci autem sunt libero tenetur est. Voluptas quia recusandae est et enim est. Labore fugit vitae qui cumque aut. Illo aperiam aliquid deserunt beatae. Voluptatem tempora tenetur dignissimos et autem qui minus voluptatem.,1.53,2022-06-11 +David Bomba,suscipit,Ullam amet consequuntur itaque. Cupiditate odio facere quis est fuga architecto. Aut placeat quae ut itaque. Voluptatem omnis architecto ipsum qui. Blanditiis nostrum iusto quo nesciunt voluptate. Ut expedita unde ex illum ut dignissimos.,4.43,2022-06-12 +David Bomba,iure,Quo autem voluptas reiciendis temporibus.,4.27,2022-06-13 +David Bomba,modi,Adipisci dolor vel non officia nisi veritatis. Est quo voluptas doloribus quis est sunt. Ducimus minus quia quia est eos maiores earum. Ut placeat iste tempore occaecati.,1.04,2022-06-14 +David Bomba,labore,Doloremque distinctio aperiam voluptas rerum quidem sed.,1.95,2022-06-15 +David Bomba,soluta,Dolore sint similique eos. Harum est ipsa aut voluptas esse culpa. Voluptas voluptatem cumque et aut et quasi tempora.,1.67,2022-06-16 +David Bomba,accusantium,Eos quo voluptatem odit temporibus aut. Reprehenderit sit ducimus expedita nostrum incidunt ut voluptates.,8.62,2022-06-17 +David Bomba,vitae,Enim error dolorem cupiditate voluptate quasi numquam quis. Porro ducimus eos maiores facere.,5.28,2022-06-18 +David Bomba,possimus,Et tempore at sit est repellendus aut illo eum. Ratione aperiam aliquam veritatis rerum est cupiditate. Fuga sit recusandae officiis.,9.28,2022-06-19 +David Bomba,nisi,Animi modi ut perspiciatis temporibus quo. Est officia qui numquam perspiciatis. Provident ut nostrum enim accusantium veniam saepe. Vero est minus aut aliquam.,8.67,2022-06-20 +David Bomba,ratione,Nemo at quo est velit.,5.6,2022-06-21 +David Bomba,illum,Odio illo veritatis dolorem omnis ad. Magni officia est officia voluptate voluptas dolor. Est dolores et tempora corporis est at ullam. Illum amet ipsa quia et omnis esse quaerat. Fugiat unde magni quod saepe. Incidunt assumenda neque voluptatem.,6.01,2022-06-22 +David Bomba,libero,Reiciendis voluptatem sed vitae sapiente pariatur alias. Voluptates velit libero voluptatum minima aperiam. Magnam natus consequatur voluptatem molestiae iure cum qui. Nisi tempore aperiam porro.,9.16,2022-06-23 +David Bomba,alias,A fugiat id aliquam officia. Eum eum tempore rerum officiis modi sit. Non impedit incidunt et commodi quia harum nesciunt.,1.92,2022-06-24 +David Bomba,occaecati,Aspernatur aut temporibus voluptas. Cumque sint sint voluptatibus.,5.95,2022-06-25 +David Bomba,1,100,100,2022-06-26 +David Bomba,ab,Sed perferendis modi velit minima placeat reprehenderit. Voluptatum ullam vel officia quia et esse quaerat. Sit aperiam minus dolor. Quasi earum temporibus est aspernatur.,6.86,2022-06-27 +David Bomba,amet,Nihil consequatur et deserunt nihil et.,7.82,2022-06-28 +David Bomba,:MONTH,hey there :MONTH+1 and :YEAR+1,0,2022-06-29 From 8ac4aa56a0ce01887f49f4c707271c9c45ccb45e Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 1 Aug 2022 10:39:47 +1000 Subject: [PATCH 16/26] Limit logging --- app/Jobs/Cron/RecurringInvoicesCron.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/Jobs/Cron/RecurringInvoicesCron.php b/app/Jobs/Cron/RecurringInvoicesCron.php index 0923675072f0..83e8cf880242 100644 --- a/app/Jobs/Cron/RecurringInvoicesCron.php +++ b/app/Jobs/Cron/RecurringInvoicesCron.php @@ -62,8 +62,7 @@ class RecurringInvoicesCron nlog(now()->format('Y-m-d').' Sending Recurring Invoices. Count = '.$recurring_invoices->count()); $recurring_invoices->each(function ($recurring_invoice, $key) { - nlog('Current date = '.now()->format('Y-m-d').' Recurring date = '.$recurring_invoice->next_send_date); - + // nlog('Current date = '.now()->format('Y-m-d').' Recurring date = '.$recurring_invoice->next_send_date); nlog("Trying to send {$recurring_invoice->number}"); /* Special check if we should generate another invoice is the previous one is yet to be paid */ @@ -103,7 +102,7 @@ class RecurringInvoicesCron nlog(now()->format('Y-m-d').' Sending Recurring Invoices. Count = '.$recurring_invoices->count()); $recurring_invoices->each(function ($recurring_invoice, $key) { - nlog('Current date = '.now()->format('Y-m-d').' Recurring date = '.$recurring_invoice->next_send_date.' Recurring #id = '.$recurring_invoice->id); + // nlog('Current date = '.now()->format('Y-m-d').' Recurring date = '.$recurring_invoice->next_send_date.' Recurring #id = '.$recurring_invoice->id); nlog("Trying to send {$recurring_invoice->number}"); From 524fad7bf4f25e4fa2db8e9e90ba5edaf1b9ee43 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 1 Aug 2022 11:28:19 +1000 Subject: [PATCH 17/26] Refactor for recurring invoices --- app/Jobs/Cron/CompanyRecurringCron.php | 70 ++++++++++++++++++++ app/Jobs/Cron/SendCompanyRecurring.php | 91 ++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 app/Jobs/Cron/CompanyRecurringCron.php create mode 100644 app/Jobs/Cron/SendCompanyRecurring.php diff --git a/app/Jobs/Cron/CompanyRecurringCron.php b/app/Jobs/Cron/CompanyRecurringCron.php new file mode 100644 index 000000000000..5e0a1d765c19 --- /dev/null +++ b/app/Jobs/Cron/CompanyRecurringCron.php @@ -0,0 +1,70 @@ +whereHas('recurring_invoices', function ($query){ + $query->where('next_send_date', '<=', now()->toDateTimeString()) + ->whereNotNull('next_send_date') + ->whereNull('deleted_at') + ->where('is_deleted', false) + ->where('status_id', RecurringInvoice::STATUS_ACTIVE) + ->where('remaining_cycles', '!=', '0') + ->whereHas('client', function ($query) { + $query->where('is_deleted', 0) + ->where('deleted_at', null); + }); + }) + ->cursor()->each(function ($company){ + + SendCompanyRecurring::dispatch($company->id, $company->db); + + }); + } + } +} diff --git a/app/Jobs/Cron/SendCompanyRecurring.php b/app/Jobs/Cron/SendCompanyRecurring.php new file mode 100644 index 000000000000..fc2fe63a01b2 --- /dev/null +++ b/app/Jobs/Cron/SendCompanyRecurring.php @@ -0,0 +1,91 @@ +company_id = $company_id; + + $this->db = $db; + + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() : void + { + + MultiDB::setDB($this->db); + + $recurring_invoices = Company::where('id', $this->company_id) + ->where('is_disabled', 0) + ->whereHas('recurring_invoices', function ($query){ + $query->where('next_send_date', '<=', now()->toDateTimeString()) + ->whereNotNull('next_send_date') + ->whereNull('deleted_at') + ->where('is_deleted', false) + ->where('status_id', RecurringInvoice::STATUS_ACTIVE) + ->where('remaining_cycles', '!=', '0') + ->whereHas('client', function ($query) { + $query->where('is_deleted', 0) + ->where('deleted_at', null); + }); + }) + ->cursor()->each(function ($recurring_invoice){ + + nlog("Trying to send {$recurring_invoice->number}"); + + if ($recurring_invoice->company->stop_on_unpaid_recurring) { + if ($recurring_invoice->invoices()->whereIn('status_id', [2, 3])->where('is_deleted', 0)->where('balance', '>', 0)->exists()) { + return; + } + } + + try { + (new SendRecurring($recurring_invoice, $recurring_invoice->company->db))->handle(); + } catch (\Exception $e) { + nlog("Unable to sending recurring invoice {$recurring_invoice->id} ".$e->getMessage()); + } + + }); + + } +} From e63d99c2d14511c07fb6340dad4bc213348746d8 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 1 Aug 2022 12:50:55 +1000 Subject: [PATCH 18/26] Performance improvements for recurring invoices --- app/Jobs/Cron/RecurringInvoicesCron.php | 1 - app/Jobs/RecurringInvoice/SendRecurring.php | 37 +++++++++++++-------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/app/Jobs/Cron/RecurringInvoicesCron.php b/app/Jobs/Cron/RecurringInvoicesCron.php index 83e8cf880242..330efe77dde9 100644 --- a/app/Jobs/Cron/RecurringInvoicesCron.php +++ b/app/Jobs/Cron/RecurringInvoicesCron.php @@ -102,7 +102,6 @@ class RecurringInvoicesCron nlog(now()->format('Y-m-d').' Sending Recurring Invoices. Count = '.$recurring_invoices->count()); $recurring_invoices->each(function ($recurring_invoice, $key) { - // nlog('Current date = '.now()->format('Y-m-d').' Recurring date = '.$recurring_invoice->next_send_date.' Recurring #id = '.$recurring_invoice->id); nlog("Trying to send {$recurring_invoice->number}"); diff --git a/app/Jobs/RecurringInvoice/SendRecurring.php b/app/Jobs/RecurringInvoice/SendRecurring.php index d3a6b5c38fa1..c67b28fd6e3f 100644 --- a/app/Jobs/RecurringInvoice/SendRecurring.php +++ b/app/Jobs/RecurringInvoice/SendRecurring.php @@ -15,6 +15,7 @@ use App\DataMapper\Analytics\SendRecurringFailure; use App\Events\Invoice\InvoiceWasEmailed; use App\Factory\InvoiceInvitationFactory; use App\Factory\RecurringInvoiceToInvoiceFactory; +use App\Jobs\Cron\AutoBill; use App\Jobs\Entity\EmailEntity; use App\Models\Invoice; use App\Models\RecurringInvoice; @@ -107,21 +108,12 @@ class SendRecurring implements ShouldQueue $this->recurring_invoice->setCompleted(); } - nlog('next send date = '.$this->recurring_invoice->next_send_date); - nlog('remaining cycles = '.$this->recurring_invoice->remaining_cycles); - nlog('last send date = '.$this->recurring_invoice->last_sent_date); + // nlog('next send date = '.$this->recurring_invoice->next_send_date); + // nlog('remaining cycles = '.$this->recurring_invoice->remaining_cycles); + // nlog('last send date = '.$this->recurring_invoice->last_sent_date); $this->recurring_invoice->save(); - /* - - if ($this->recurring_invoice->company->pause_recurring_until_paid){ - $this->recurring_invoice->service() - ->stop(); - } - - */ - event('eloquent.created: App\Models\Invoice', $invoice); if ($invoice->client->getSetting('auto_email_invoice')) { @@ -147,11 +139,14 @@ class SendRecurring implements ShouldQueue if ($invoice->client->getSetting('auto_bill_date') == 'on_send_date' && $invoice->auto_bill_enabled) { nlog("attempting to autobill {$invoice->number}"); - $invoice->service()->autoBill(); + // $invoice->service()->autoBill(); + AutoBill::dispatch($invoice, $this->db)->delay(20); + } elseif ($invoice->client->getSetting('auto_bill_date') == 'on_due_date' && $invoice->auto_bill_enabled) { if ($invoice->due_date && Carbon::parse($invoice->due_date)->startOfDay()->lte(now()->startOfDay())) { nlog("attempting to autobill {$invoice->number}"); - $invoice->service()->autoBill(); + // $invoice->service()->autoBill(); + AutoBill::dispatch($invoice, $this->db)->delay(20); } } } @@ -188,3 +183,17 @@ class SendRecurring implements ShouldQueue nlog(print_r($exception->getMessage(), 1)); } } + + +/** + * + * 1/8/2022 + * + * Improvements here include moving the emailentity and autobilling into the queue. + * + * Further improvements could using the CompanyRecurringCron.php stub which divides + * the recurring invoices into companies and spins them off into their own queue to + * improve parallel processing. + * + * Need to be careful we do not overload redis and OOM. +*/ \ No newline at end of file From ad7889b76925ea62f328ba0f961b6ced893d5127 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 1 Aug 2022 17:17:06 +1000 Subject: [PATCH 19/26] Clean up for spam notifications --- app/Notifications/Ninja/SpamNotification.php | 22 ++++++++++--------- .../Notification/NotificationService.php | 1 - 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/app/Notifications/Ninja/SpamNotification.php b/app/Notifications/Ninja/SpamNotification.php index 061c720e3865..9c85bb1565dc 100644 --- a/app/Notifications/Ninja/SpamNotification.php +++ b/app/Notifications/Ninja/SpamNotification.php @@ -29,7 +29,7 @@ class SpamNotification extends Notification * @return void */ - protected array $spam_list; + public array $spam_list; public function __construct($spam_list) { @@ -74,43 +74,45 @@ class SpamNotification extends Notification { $content = ''; - foreach($this->spam_list as $spam_list) - { + // foreach($this->spam_lists as $spam_list) + // { - if(array_key_exists('companies', $spam_list)) + if(array_key_exists('companies', $this->spam_list)) { $content .= " Companies \n"; - foreach($spam_list['companies'] as $company) + foreach($this->spam_list['companies'] as $company) { $content .= "{$company['name']} - c_key={$company['company_key']} - a_key={$company['account_key']} - {$company['owner']} \n"; } } - if(array_key_exists('templates', $spam_list)) + if(array_key_exists('templates', $this->spam_list)) { $content .= " Templates \n"; - foreach($spam_list['templates'] as $company) + foreach($this->spam_list['templates'] as $company) { $content .= "{$company['name']} - c_key={$company['company_key']} - a_key={$company['account_key']} - {$company['owner']} \n"; } } - if(array_key_exists('users', $spam_list)) + if(array_key_exists('users', $this->spam_list)) { $content .= ' Users \n'; - foreach($spam_list['users'] as $user) + foreach($this->spam_list['users'] as $user) { $content .= "{$user['email']} - a_key={$user['account_key']} - created={$user['created']} \n"; } } - } + // } + + return (new SlackMessage) ->success() diff --git a/app/Services/Notification/NotificationService.php b/app/Services/Notification/NotificationService.php index 63022d21c326..c4d44b620ead 100644 --- a/app/Services/Notification/NotificationService.php +++ b/app/Services/Notification/NotificationService.php @@ -70,7 +70,6 @@ class NotificationService extends AbstractService public function ninja() { Notification::route('slack', config('ninja.notification.slack')) - ->route('mail', config('ninja.notification.mail')) ->notify($this->notification); } } From 1e3b1c08da411c304b960384833f98c58ffcac7e Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 1 Aug 2022 17:43:26 +1000 Subject: [PATCH 20/26] Remove dispatchSync --- app/Console/Commands/CreateAccount.php | 6 +++--- app/Console/Commands/DemoMode.php | 8 ++++---- app/Console/Commands/HostedUsers.php | 4 ++-- app/Console/Commands/SendTestEmails.php | 2 +- app/Jobs/Credit/ZipCredits.php | 2 +- app/Mail/TemplateEmail.php | 2 +- app/Models/InvoiceInvitation.php | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/app/Console/Commands/CreateAccount.php b/app/Console/Commands/CreateAccount.php index 90613083d2cb..c0eaed16bc59 100644 --- a/app/Console/Commands/CreateAccount.php +++ b/app/Console/Commands/CreateAccount.php @@ -131,9 +131,9 @@ class CreateAccount extends Command 'settings' => null, ]); - CreateCompanyPaymentTerms::dispatchSync($company, $user); - CreateCompanyTaskStatuses::dispatchSync($company, $user); - VersionCheck::dispatchSync(); + (new CreateCompanyPaymentTerms($company, $user))->handle(); + (new CreateCompanyTaskStatuses($company, $user))->handle(); + (new VersionCheck())->handle(); } private function warmCache() diff --git a/app/Console/Commands/DemoMode.php b/app/Console/Commands/DemoMode.php index 38fb577a1b38..8a5864a6440a 100644 --- a/app/Console/Commands/DemoMode.php +++ b/app/Console/Commands/DemoMode.php @@ -112,9 +112,9 @@ class DemoMode extends Command $this->info('Seeding Random Data'); $this->createSmallAccount(); - VersionCheck::dispatchSync(); + (new VersionCheck())->handle(); - CompanySizeCheck::dispatchSync(); + (new CompanySizeCheck())->handle(); } private function createSmallAccount() @@ -164,8 +164,8 @@ class DemoMode extends Command ]); } - CreateCompanyPaymentTerms::dispatchSync($company, $user); - CreateCompanyTaskStatuses::dispatchSync($company, $user); + (new CreateCompanyPaymentTerms($company, $user))->handle(); + (new CreateCompanyTaskStatuses($company, $user))->handle(); $company_token = new CompanyToken; $company_token->user_id = $user->id; diff --git a/app/Console/Commands/HostedUsers.php b/app/Console/Commands/HostedUsers.php index ec076dc86b26..63a1b94e7e35 100644 --- a/app/Console/Commands/HostedUsers.php +++ b/app/Console/Commands/HostedUsers.php @@ -43,13 +43,13 @@ class HostedUsers extends Command { Company::on('db-ninja-01')->each(function ($company) { if (Ninja::isHosted()) { - \Modules\Admin\Jobs\Account\NinjaUser::dispatchSync([], $company); + (new \Modules\Admin\Jobs\Account\NinjaUser([], $company))->handle(); } }); Company::on('db-ninja-02')->each(function ($company) { if (Ninja::isHosted()) { - \Modules\Admin\Jobs\Account\NinjaUser::dispatchSync([], $company); + (new \Modules\Admin\Jobs\Account\NinjaUser([], $company))->handle(); } }); } diff --git a/app/Console/Commands/SendTestEmails.php b/app/Console/Commands/SendTestEmails.php index 924fb7256608..aa10cd582234 100644 --- a/app/Console/Commands/SendTestEmails.php +++ b/app/Console/Commands/SendTestEmails.php @@ -96,6 +96,6 @@ class SendTestEmails extends Command $nmo->settings = $user->account->companies()->first()->settings; $nmo->to_user = $user; - NinjaMailerJob::dispatchSync($nmo); + (new NinjaMailerJob($nmo))->handle(); } } diff --git a/app/Jobs/Credit/ZipCredits.php b/app/Jobs/Credit/ZipCredits.php index ec851529a57b..0071338e0e6b 100644 --- a/app/Jobs/Credit/ZipCredits.php +++ b/app/Jobs/Credit/ZipCredits.php @@ -80,7 +80,7 @@ class ZipCredits implements ShouldQueue $path = $this->credits->first()->client->quote_filepath($invitation); $this->credits->each(function ($credit) { - CreateEntityPdf::dispatchSync($credit->invitations()->first()); + (new CreateEntityPdf($credit->invitations()->first()))->handle(); }); try { diff --git a/app/Mail/TemplateEmail.php b/app/Mail/TemplateEmail.php index 4ec31fd6ccdd..941cbc8a9637 100644 --- a/app/Mail/TemplateEmail.php +++ b/app/Mail/TemplateEmail.php @@ -142,7 +142,7 @@ class TemplateEmail extends Mailable sleep(2); if(!Storage::disk(config('filesystems.default'))->exists($path)) { - CreateEntityPdf::dispatchSync($this->invitation); + (new CreateEntityPdf($this->invitation))->handle(); sleep(2); } diff --git a/app/Models/InvoiceInvitation.php b/app/Models/InvoiceInvitation.php index 34da795f342b..c724f417ebc7 100644 --- a/app/Models/InvoiceInvitation.php +++ b/app/Models/InvoiceInvitation.php @@ -112,7 +112,7 @@ class InvoiceInvitation extends BaseModel if (! Storage::exists($this->invoice->client->invoice_filepath($this).$this->invoice->numberFormatter().'.pdf')) { event(new InvoiceWasUpdated($this->invoice, $this->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null))); - CreateEntityPdf::dispatchSync($this); + (new CreateEntityPdf($this))->handle(); } return $storage_path; From 85edd8ace6ffe115188a694216556a0c602e5cd8 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 2 Aug 2022 07:39:50 +1000 Subject: [PATCH 21/26] Minor fixes for expense transformer --- app/Import/Transformer/Csv/ExpenseTransformer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Import/Transformer/Csv/ExpenseTransformer.php b/app/Import/Transformer/Csv/ExpenseTransformer.php index c8198db0d4bb..2e5cb032dc9a 100644 --- a/app/Import/Transformer/Csv/ExpenseTransformer.php +++ b/app/Import/Transformer/Csv/ExpenseTransformer.php @@ -42,7 +42,7 @@ class ExpenseTransformer extends BaseTransformer 'client_id' => isset($data['expense.client']) ? $this->getClientId($data['expense.client']) : null, - 'date' => $this->getString($data, 'expense.date'), + 'date' => strlen($this->getString($data, 'expense.date') > 1) ? date('Y-m-d', strtotime($this->getString($data, 'expense.date'))) : now()->format('Y-m-d'), 'public_notes' => $this->getString($data, 'expense.public_notes'), 'private_notes' => $this->getString($data, 'expense.private_notes'), 'category_id' => isset($data['expense.category']) From 412a4a131516e6a9b04481076d69573453aab4b9 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 2 Aug 2022 17:04:33 +1000 Subject: [PATCH 22/26] return early when model is missing --- app/Jobs/Ledger/ClientLedgerBalanceUpdate.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/Jobs/Ledger/ClientLedgerBalanceUpdate.php b/app/Jobs/Ledger/ClientLedgerBalanceUpdate.php index 3a9d054a56a8..36055d693da4 100644 --- a/app/Jobs/Ledger/ClientLedgerBalanceUpdate.php +++ b/app/Jobs/Ledger/ClientLedgerBalanceUpdate.php @@ -31,6 +31,8 @@ class ClientLedgerBalanceUpdate implements ShouldQueue public $client; + public $deleteWhenMissingModels = true; + public function __construct(Company $company, Client $client) { $this->company = $company; From 76225919e2ad28964ff94f1a13611b095fd74a2b Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 2 Aug 2022 17:28:24 +1000 Subject: [PATCH 23/26] catch for no email provided in braintree paypal integration --- .../portal/ninja2020/gateways/braintree/paypal/pay.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/portal/ninja2020/gateways/braintree/paypal/pay.blade.php b/resources/views/portal/ninja2020/gateways/braintree/paypal/pay.blade.php index 33ae3e5ad163..cb967a2e6f5e 100644 --- a/resources/views/portal/ninja2020/gateways/braintree/paypal/pay.blade.php +++ b/resources/views/portal/ninja2020/gateways/braintree/paypal/pay.blade.php @@ -39,7 +39,7 @@ data-token="{{ $token->token }}" name="payment-type" class="form-radio cursor-pointer toggle-payment-with-token"/> - {{ $token->meta?->email }} + {{ property_exists($token->meta, 'email') ? $token->meta?->email : 'no email provided'}} @endforeach @endisset From 7594397d2a85d42ef5005cab155dc25aa82214ff Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 2 Aug 2022 19:38:11 +1000 Subject: [PATCH 24/26] Force required fields for paytrace --- app/PaymentDrivers/PayTrace/CreditCard.php | 4 +++- app/PaymentDrivers/PaytracePaymentDriver.php | 12 +++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/PaymentDrivers/PayTrace/CreditCard.php b/app/PaymentDrivers/PayTrace/CreditCard.php index 9839f9b505c6..403ca22ed6fe 100644 --- a/app/PaymentDrivers/PayTrace/CreditCard.php +++ b/app/PaymentDrivers/PayTrace/CreditCard.php @@ -148,13 +148,15 @@ class CreditCard private function buildBillingAddress() { - return [ + $data = [ 'name' => $this->paytrace->client->present()->name(), 'street_address' => $this->paytrace->client->address1, 'city' => $this->paytrace->client->city, 'state' => $this->paytrace->client->state, 'zip' => $this->paytrace->client->postal_code, ]; + + nlog($data); } public function paymentView($data) diff --git a/app/PaymentDrivers/PaytracePaymentDriver.php b/app/PaymentDrivers/PaytracePaymentDriver.php index f96d7a9b1297..f3b3a325d75f 100644 --- a/app/PaymentDrivers/PaytracePaymentDriver.php +++ b/app/PaymentDrivers/PaytracePaymentDriver.php @@ -191,21 +191,23 @@ class PaytracePaymentDriver extends BaseDriver $fields[] = ['name' => 'client_phone', 'label' => ctrans('texts.client_phone'), 'type' => 'tel', 'validation' => 'required']; } - if ($this->company_gateway->require_billing_address) { $fields[] = ['name' => 'client_address_line_1', 'label' => ctrans('texts.address1'), 'type' => 'text', 'validation' => 'required']; + + if ($this->company_gateway->require_billing_address) { $fields[] = ['name' => 'client_city', 'label' => ctrans('texts.city'), 'type' => 'text', 'validation' => 'required']; $fields[] = ['name' => 'client_state', 'label' => ctrans('texts.state'), 'type' => 'text', 'validation' => 'required']; $fields[] = ['name' => 'client_country_id', 'label' => ctrans('texts.country'), 'type' => 'text', 'validation' => 'required']; } - if ($this->company_gateway->require_postal_code) { + // if ($this->company_gateway->require_postal_code) { $fields[] = ['name' => 'client_postal_code', 'label' => ctrans('texts.postal_code'), 'type' => 'text', 'validation' => 'required']; - } + $fields[] = ['name' => 'client_shipping_city', 'label' => ctrans('texts.shipping_city'), 'type' => 'text', 'validation' => 'required']; + $fields[] = ['name' => 'client_shipping_state', 'label' => ctrans('texts.shipping_state'), 'type' => 'text', 'validation' => 'required']; + + // } if ($this->company_gateway->require_shipping_address) { $fields[] = ['name' => 'client_shipping_address_line_1', 'label' => ctrans('texts.shipping_address1'), 'type' => 'text', 'validation' => 'required']; - $fields[] = ['name' => 'client_shipping_city', 'label' => ctrans('texts.shipping_city'), 'type' => 'text', 'validation' => 'required']; - $fields[] = ['name' => 'client_shipping_state', 'label' => ctrans('texts.shipping_state'), 'type' => 'text', 'validation' => 'required']; $fields[] = ['name' => 'client_shipping_postal_code', 'label' => ctrans('texts.shipping_postal_code'), 'type' => 'text', 'validation' => 'required']; $fields[] = ['name' => 'client_shipping_country_id', 'label' => ctrans('texts.shipping_country'), 'type' => 'text', 'validation' => 'required']; } From 6ca955164e7245017e0350a5ae63a80121428efd Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 3 Aug 2022 12:35:38 +1000 Subject: [PATCH 25/26] fixes for bccs --- app/Helpers/Mail/GmailTransport.php | 22 ++++++++++- app/Helpers/Mail/Office365MailTransport.php | 42 ++++++++++++++------- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/app/Helpers/Mail/GmailTransport.php b/app/Helpers/Mail/GmailTransport.php index 4117e710fdbe..6e36804720b4 100644 --- a/app/Helpers/Mail/GmailTransport.php +++ b/app/Helpers/Mail/GmailTransport.php @@ -31,7 +31,7 @@ class GmailTransport extends AbstractTransport protected function doSend(SentMessage $message): void { - nlog("in Do Send"); + nlog("In Do Send"); $message = MessageConverter::toEmail($message->getOriginalMessage()); $token = $message->getHeaders()->get('gmailtoken')->getValue(); @@ -45,7 +45,25 @@ class GmailTransport extends AbstractTransport $service = new Gmail($client); $body = new Message(); - $body->setRaw($this->base64_encode($message->toString())); + + $bccs = $message->getHeaders()->get('Bcc'); + + $bcc_list = ''; + + if($bccs) + { + $bcc_list = 'Bcc: '; + + foreach($bccs->getAddresses() as $address){ + + $bcc_list .= $address->getAddress() .','; + + } + + $bcc_list = rtrim($bcc_list, ",") . "\r\n"; + } + + $body->setRaw($this->base64_encode($bcc_list.$message->toString())); $service->users_messages->send('me', $body, []); diff --git a/app/Helpers/Mail/Office365MailTransport.php b/app/Helpers/Mail/Office365MailTransport.php index a4fa9d5e790f..e396e8f42531 100644 --- a/app/Helpers/Mail/Office365MailTransport.php +++ b/app/Helpers/Mail/Office365MailTransport.php @@ -16,7 +16,6 @@ use Microsoft\Graph\Graph; use Microsoft\Graph\Model\UploadSession; use Symfony\Component\Mailer\SentMessage; use Symfony\Component\Mailer\Transport\AbstractTransport; -use Symfony\Component\Mime\Email; use Symfony\Component\Mime\MessageConverter; class Office365MailTransport extends AbstractTransport @@ -38,20 +37,35 @@ class Office365MailTransport extends AbstractTransport $graph->setAccessToken($token); - try { - $graphMessage = $graph->createRequest('POST', '/users/'.$symfony_message->getFrom()[0]->getAddress().'/sendmail') - ->attachBody(base64_encode($message->toString())) - ->addHeaders(['Content-Type' => 'text/plain']) - ->setReturnType(\Microsoft\Graph\Model\Message::class) - ->execute(); - } catch (\Exception $e) { - sleep(5); - $graphMessage = $graph->createRequest('POST', '/users/'.$symfony_message->getFrom()[0]->getAddress().'/sendmail') - ->attachBody(base64_encode($message->toString())) - ->addHeaders(['Content-Type' => 'text/plain']) - ->setReturnType(\Microsoft\Graph\Model\Message::class) - ->execute(); + $bccs = $symfony_message->getHeaders()->get('Bcc'); + + $bcc_list = ''; + + if($bccs) + { + + foreach($bccs->getAddresses() as $address){ + + $bcc_list .= 'Bcc: "'.$address->getAddress().'" <'.$address->getAddress().'>\r\n'; + } + + } + + try { + $graphMessage = $graph->createRequest('POST', '/users/'.$symfony_message->getFrom()[0]->getAddress().'/sendmail') + ->attachBody(base64_encode($bcc_list.$message->toString())) + ->addHeaders(['Content-Type' => 'text/plain']) + ->setReturnType(\Microsoft\Graph\Model\Message::class) + ->execute(); + } catch (\Exception $e) { + sleep(5); + $graphMessage = $graph->createRequest('POST', '/users/'.$symfony_message->getFrom()[0]->getAddress().'/sendmail') + ->attachBody(base64_encode($bcc_list.$message->toString())) + ->addHeaders(['Content-Type' => 'text/plain']) + ->setReturnType(\Microsoft\Graph\Model\Message::class) + ->execute(); + } } From 63c7a3f4c8a60dced793b29e70e3372d6025c9f2 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 3 Aug 2022 12:44:55 +1000 Subject: [PATCH 26/26] v5.5.6 --- VERSION.txt | 2 +- config/ninja.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index 393072c7a6ec..29fe95d7a39b 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -5.5.5 \ No newline at end of file +5.5.6 \ No newline at end of file diff --git a/config/ninja.php b/config/ninja.php index 47f42c4872f4..a10ffce554fe 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -14,8 +14,8 @@ return [ 'require_https' => env('REQUIRE_HTTPS', true), 'app_url' => rtrim(env('APP_URL', ''), '/'), 'app_domain' => env('APP_DOMAIN', 'invoicing.co'), - 'app_version' => '5.5.5', - 'app_tag' => '5.5.5', + 'app_version' => '5.5.6', + 'app_tag' => '5.5.6', 'minimum_client_version' => '5.0.16', 'terms_version' => '1.0.1', 'api_secret' => env('API_SECRET', ''),