From 0a4464fc235c72b090c42a836ad7d75774a2413a Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 26 May 2020 20:22:50 +1000 Subject: [PATCH] Payment Failure Notifications (#3755) * Type Change for Payment Terms * Fixes for payment terms casting * Working on payment failure notifications * Working on payment failure notifications --- app/DataMapper/CompanySettings.php | 9 ++- app/Jobs/Mail/PaymentFailureMailer.php | 37 +++++++--- app/PaymentDrivers/StripePaymentDriver.php | 4 ++ .../Traits/Notifications/UserNotifies.php | 17 +++++ .../2014_10_13_000000_create_users_table.php | 68 +++++++++++++++---- 5 files changed, 109 insertions(+), 26 deletions(-) diff --git a/app/DataMapper/CompanySettings.php b/app/DataMapper/CompanySettings.php index 9874ffc8a6..babe17df19 100644 --- a/app/DataMapper/CompanySettings.php +++ b/app/DataMapper/CompanySettings.php @@ -29,8 +29,8 @@ class CompanySettings extends BaseSettings public $enable_client_portal_tasks = false; public $enable_client_portal_password = false; - public $enable_client_portal = true;//implemented - public $enable_client_portal_dashboard = true;//implemented + public $enable_client_portal = true; //implemented + public $enable_client_portal_dashboard = true; //implemented public $signature_on_pdf = false; public $document_email_attachment = false; public $send_portal_password = false; @@ -55,7 +55,7 @@ class CompanySettings extends BaseSettings public $default_task_rate = 0; - public $payment_terms = "-1"; + public $payment_terms = ""; public $send_reminders = false; public $custom_message_dashboard = ''; @@ -231,7 +231,10 @@ class CompanySettings extends BaseSettings public $portal_custom_footer = ''; public $portal_custom_js = ''; + public $client_can_register = false; + public static $casts = [ + 'client_can_register' => 'bool', 'portal_design_id' => 'string', 'late_fee_endless_percent' => 'float', 'late_fee_endless_amount' => 'float', diff --git a/app/Jobs/Mail/PaymentFailureMailer.php b/app/Jobs/Mail/PaymentFailureMailer.php index fa823279d5..3a98c50143 100644 --- a/app/Jobs/Mail/PaymentFailureMailer.php +++ b/app/Jobs/Mail/PaymentFailureMailer.php @@ -12,6 +12,7 @@ use App\Mail\Admin\PaymentFailureObject; use App\Models\SystemLog; use App\Models\User; use App\Providers\MailServiceProvider; +use App\Utils\Traits\Notifications\UserNotifies; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; @@ -22,7 +23,7 @@ use Illuminate\Support\Facades\Mail; class PaymentFailureMailer extends BaseMailerJob implements ShouldQueue { - use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, UserNotifies; public $client; @@ -62,17 +63,31 @@ class PaymentFailureMailer extends BaseMailerJob implements ShouldQueue //if we need to set an email driver do it now $this->setMailDriver($this->client->getSetting('email_sending_method')); - $mail_obj = (new PaymentFailureObject($this->client, $this->message, $this->amount, $this->company))->build(); - $mail_obj->from = [$this->company->owner()->email, $this->company->owner()->present()->name()]; - - //send email - Mail::to($this->user->email) - ->send(new EntityNotificationMailer($mail_obj)); + //iterate through company_users + $this->company->company_users->each(function ($company_user){ - //catch errors - if (count(Mail::failures()) > 0) { - $this->logMailError(Mail::failures()); - } + //determine if this user has the right permissions + $methods = $this->findCompanyUserNotificationType($company_user, ['payment_failure']); + + //if mail is a method type -fire mail!! + if (($key = array_search('mail', $methods)) !== false) { + unset($methods[$key]); + + $mail_obj = (new PaymentFailureObject($this->client, $this->message, $this->amount, $this->company))->build(); + $mail_obj->from = [$this->company->owner()->email, $this->company->owner()->present()->name()]; + + //send email + Mail::to($company_user->user->email) + ->send(new EntityNotificationMailer($mail_obj)); + + //catch errors + if (count(Mail::failures()) > 0) { + $this->logMailError(Mail::failures()); + } + + } + + }); } diff --git a/app/PaymentDrivers/StripePaymentDriver.php b/app/PaymentDrivers/StripePaymentDriver.php index 4353cdf2fa..f53f34e115 100644 --- a/app/PaymentDrivers/StripePaymentDriver.php +++ b/app/PaymentDrivers/StripePaymentDriver.php @@ -13,6 +13,7 @@ namespace App\PaymentDrivers; use App\Events\Payment\PaymentWasCreated; use App\Factory\PaymentFactory; +use App\Jobs\Mail\PaymentFailureMailer; use App\Jobs\Util\SystemLogger; use App\Models\ClientGatewayToken; use App\Models\GatewayType; @@ -364,6 +365,9 @@ class StripePaymentDriver extends BasePaymentDriver return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]); } else { + + PaymentFailureMailer::dispatch($this->client, $server_response->cancellation_reason, $this->client->company, $server_response->amount); + /*Fail and log*/ SystemLogger::dispatch( [ diff --git a/app/Utils/Traits/Notifications/UserNotifies.php b/app/Utils/Traits/Notifications/UserNotifies.php index 264cf6357e..a7d4addf2c 100644 --- a/app/Utils/Traits/Notifications/UserNotifies.php +++ b/app/Utils/Traits/Notifications/UserNotifies.php @@ -61,6 +61,23 @@ trait UserNotifies return $notifiable_methods; } + public function findCompanyUserNotificationType($company_user, $required_permissions) :array + { + if ($this->migrationRunning($company_user)) { + return []; + } + + $notifiable_methods = []; + $notifications = $company_user->notifications; + + if (count(array_intersect($required_permissions, $notifications->email)) >=1 || count(array_intersect($required_permissions, "all_user_notifications")) >=1 || count(array_intersect($required_permissions, "all_notifications")) >=1) { + array_push($notifiable_methods, 'mail'); + } + + return $notifiable_methods; + + } + private function migrationRunning($company_user) { return $company_user->is_migrating; diff --git a/database/migrations/2014_10_13_000000_create_users_table.php b/database/migrations/2014_10_13_000000_create_users_table.php index a4e3aa9b53..00556724d1 100644 --- a/database/migrations/2014_10_13_000000_create_users_table.php +++ b/database/migrations/2014_10_13_000000_create_users_table.php @@ -212,7 +212,7 @@ class CreateUsersTable extends Migration // $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); $table->unique(['company_id', 'user_id']); - $table->index(['account_id', 'company_id']); + $table->index(['account_id', 'company_id','deleted_at']); }); Schema::create('documents', function (Blueprint $table) { @@ -297,6 +297,7 @@ class CreateUsersTable extends Migration $table->string('name')->nullable(); $table->timestamps(6); $table->softDeletes('deleted_at', 6); + $table->index(['company_id', 'deleted_at']); $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade'); $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade')->onUpdate('cascade'); @@ -351,6 +352,7 @@ class CreateUsersTable extends Migration $table->timestamps(6); $table->softDeletes('deleted_at', 6); + $table->index(['company_id', 'deleted_at']); $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade'); $table->foreign('industry_id')->references('id')->on('industries'); @@ -392,6 +394,7 @@ class CreateUsersTable extends Migration $table->rememberToken(); $table->timestamps(6); $table->softDeletes('deleted_at', 6); + $table->index(['company_id', 'deleted_at']); $table->foreign('client_id')->references('id')->on('clients')->onDelete('cascade')->onUpdate('cascade'); //$table->unique(['company_id', 'email']); @@ -417,6 +420,7 @@ class CreateUsersTable extends Migration $table->timestamps(6); $table->softDeletes('deleted_at', 6); + $table->index(['company_id', 'deleted_at']); $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade'); @@ -496,6 +500,7 @@ class CreateUsersTable extends Migration $t->timestamps(6); $t->softDeletes('deleted_at', 6); + $t->index(['company_id', 'deleted_at']); $t->unique(['company_id', 'number']); }); @@ -571,6 +576,7 @@ class CreateUsersTable extends Migration $t->timestamps(6); $t->softDeletes('deleted_at', 6); + $t->index(['company_id', 'deleted_at']); $t->unique(['company_id', 'number']); }); @@ -601,7 +607,7 @@ class CreateUsersTable extends Migration $t->timestamps(6); $t->softDeletes('deleted_at', 6); - $t->index(['deleted_at', 'credit_id']); + $t->index(['deleted_at', 'credit_id','company_id']); $t->unique(['client_contact_id', 'credit_id']); }); @@ -661,13 +667,15 @@ class CreateUsersTable extends Migration $t->datetime('last_sent_date')->nullable(); $t->datetime('next_send_date')->nullable(); $t->unsignedInteger('remaining_cycles')->nullable(); + $t->timestamps(6); + $t->softDeletes('deleted_at', 6); + $t->index(['company_id', 'deleted_at']); $t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade')->onUpdate('cascade'); $t->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade'); $t->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade'); - $t->timestamps(6); - $t->softDeletes('deleted_at', 6); + }); Schema::create('recurring_quotes', function ($t) { @@ -724,13 +732,15 @@ class CreateUsersTable extends Migration $t->datetime('last_sent_date')->nullable(); $t->datetime('next_send_date')->nullable(); $t->unsignedInteger('remaining_cycles')->nullable(); + $t->timestamps(6); + $t->softDeletes('deleted_at', 6); + $t->index(['company_id', 'deleted_at']); $t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade')->onUpdate('cascade'); $t->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade'); $t->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade'); - $t->timestamps(6); - $t->softDeletes('deleted_at', 6); + }); Schema::create('quotes', function ($t) { @@ -807,6 +817,7 @@ class CreateUsersTable extends Migration $t->timestamps(6); $t->softDeletes('deleted_at', 6); + $t->index(['company_id', 'deleted_at']); $t->unique(['company_id', 'number']); }); @@ -836,7 +847,7 @@ class CreateUsersTable extends Migration $t->timestamps(6); $t->softDeletes('deleted_at', 6); - $t->index(['deleted_at', 'invoice_id']); + $t->index(['deleted_at', 'invoice_id', 'company_id']); $t->unique(['client_contact_id', 'invoice_id']); }); @@ -867,7 +878,8 @@ class CreateUsersTable extends Migration $t->timestamps(6); $t->softDeletes('deleted_at', 6); - $t->index(['deleted_at', 'quote_id']); + + $t->index(['deleted_at', 'quote_id','company_id']); $t->unique(['client_contact_id', 'quote_id']); }); @@ -881,6 +893,8 @@ class CreateUsersTable extends Migration $t->string('name', 100); $t->decimal('rate', 13, 3)->default(0); + $t->index(['company_id', 'deleted_at']); + $t->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade'); $t->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade'); }); @@ -910,15 +924,17 @@ class CreateUsersTable extends Migration $t->decimal('tax_rate2', 13, 3)->default(0); $t->string('tax_name3')->nullable(); $t->decimal('tax_rate3', 13, 3)->default(0); + $t->softDeletes('deleted_at', 6); + $t->timestamps(6); $t->boolean('is_deleted')->default(false); + $t->index(['company_id', 'deleted_at']); + $t->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade'); $t->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade'); - $t->timestamps(6); - $t->softDeletes('deleted_at', 6); }); @@ -951,6 +967,8 @@ class CreateUsersTable extends Migration $t->unsignedInteger('currency_id'); $t->unsignedInteger('exchange_currency_id'); + $t->index(['company_id', 'deleted_at']); + $t->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade'); $t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade')->onUpdate('cascade'); $t->foreign('client_contact_id')->references('id')->on('client_contacts')->onDelete('cascade')->onUpdate('cascade'); @@ -998,6 +1016,8 @@ class CreateUsersTable extends Migration $table->timestamps(6); $table->softDeletes('deleted_at', 6); + $table->index(['company_id', 'deleted_at']); + $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade'); $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade'); $table->foreign('bank_id')->references('id')->on('banks'); @@ -1017,6 +1037,8 @@ class CreateUsersTable extends Migration $table->timestamps(6); $table->softDeletes('deleted_at', 6); + $table->index(['company_id', 'deleted_at']); + $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade'); $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade'); $table->foreign('bank_company_id')->references('id')->on('bank_companies')->onDelete('cascade')->onUpdate('cascade'); @@ -1032,6 +1054,8 @@ class CreateUsersTable extends Migration $table->timestamps(6); $table->softDeletes('deleted_at', 6); + $table->index(['company_id', 'deleted_at']); + $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade'); $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade'); }); @@ -1059,6 +1083,7 @@ class CreateUsersTable extends Migration $table->text('notes'); $table->timestamps(6); + $table->index(['vendor_id', 'company_id']); $table->index(['project_id', 'company_id']); $table->index(['user_id', 'company_id']); @@ -1123,8 +1148,10 @@ class CreateUsersTable extends Migration $table->boolean('is_default')->default(0); $table->text('meta')->nullable(); $table->softDeletes('deleted_at', 6); - $table->timestamps(6); + + $table->index(['company_id', 'deleted_at']); + $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade'); $table->foreign('client_id')->references('id')->on('clients')->onDelete('cascade')->onUpdate('cascade'); }); @@ -1138,6 +1165,8 @@ class CreateUsersTable extends Migration $table->softDeletes('deleted_at', 6); $table->timestamps(6); + $table->index(['company_id', 'deleted_at']); + $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade'); }); @@ -1199,7 +1228,8 @@ class CreateUsersTable extends Migration $table->string('custom_value3')->nullable(); $table->string('custom_value4')->nullable(); - + $table->index(['company_id', 'deleted_at']); + $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade'); $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade'); $table->foreign('country_id')->references('id')->on('countries'); @@ -1225,6 +1255,8 @@ class CreateUsersTable extends Migration $table->string('custom_value3')->nullable(); $table->string('custom_value4')->nullable(); + $table->index(['company_id', 'deleted_at']); + $table->foreign('vendor_id')->references('id')->on('vendors')->onDelete('cascade')->onUpdate('cascade'); $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade'); $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade'); @@ -1237,6 +1269,9 @@ class CreateUsersTable extends Migration $table->timestamps(6); $table->softDeletes(); $table->string('name')->nullable(); + + $table->index(['company_id', 'deleted_at']); + }); Schema::create('expenses', function (Blueprint $table) { @@ -1280,6 +1315,8 @@ class CreateUsersTable extends Migration $table->string('custom_value3')->nullable(); $table->string('custom_value4')->nullable(); + $table->index(['company_id', 'deleted_at']); + // Relations $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade'); $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade'); @@ -1308,6 +1345,8 @@ class CreateUsersTable extends Migration $t->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade'); $t->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade'); + $t->index(['company_id', 'deleted_at']); + $t->unique(['company_id', 'name']); }); @@ -1336,6 +1375,8 @@ class CreateUsersTable extends Migration $table->boolean('is_running')->default(false); $table->text('time_log')->nullable(); + $table->index(['company_id', 'deleted_at']); + $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade'); $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade'); $table->foreign('invoice_id')->references('id')->on('invoices')->onDelete('cascade')->onUpdate('cascade'); @@ -1354,6 +1395,9 @@ class CreateUsersTable extends Migration $table->boolean('is_deleted')->default(false); $table->timestamps(6); $table->softDeletes('deleted_at', 6); + + $table->index(['company_id', 'deleted_at']); + $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade'); }); }