1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-09-20 08:21:34 +02:00

Payment Failure Notifications (#3755)

* Type Change for Payment Terms

* Fixes for payment terms casting

* Working on payment failure notifications

* Working on payment failure notifications
This commit is contained in:
David Bomba 2020-05-26 20:22:50 +10:00 committed by GitHub
parent e038c624bf
commit 0a4464fc23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 109 additions and 26 deletions

View File

@ -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',

View File

@ -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());
}
}
});
}

View File

@ -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(
[

View File

@ -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;

View File

@ -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');
});
}