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

Email quota exceeded emails

This commit is contained in:
= 2021-08-07 20:56:42 +10:00
parent 9b3763a203
commit e6ccb9bde7
7 changed files with 112 additions and 27 deletions

View File

@ -69,7 +69,7 @@ class Kernel extends ConsoleKernel
/* Run hosted specific jobs */
if (Ninja::isHosted()) {
$schedule->job(new AdjustEmailQuota)->daily()->withoutOverlapping();
$schedule->job(new AdjustEmailQuota)->dailyAt('23:00')->withoutOverlapping();
$schedule->job(new SendFailedEmails)->daily()->withoutOverlapping();
$schedule->command('ninja:check-data --database=db-ninja-02')->daily()->withoutOverlapping();

View File

@ -72,9 +72,6 @@ class NinjaMailerJob implements ShouldQueue
public function handle()
{
if($this->preFlightChecksFail())
return;
/*Set the correct database*/
MultiDB::setDb($this->nmo->company->db);
@ -82,6 +79,9 @@ class NinjaMailerJob implements ShouldQueue
/* Serializing models from other jobs wipes the primary key */
$this->company = Company::where('company_key', $this->nmo->company->company_key)->first();
if($this->preFlightChecksFail())
return;
/* Set the email driver */
$this->setMailDriver();

View File

@ -13,26 +13,18 @@ namespace App\Jobs\Ninja;
use App\Libraries\MultiDB;
use App\Models\Account;
use App\Utils\Ninja;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Cache;
class AdjustEmailQuota implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
const FREE_PLAN_DAILY_QUOTA = 10;
const PRO_PLAN_DAILY_QUOTA = 50;
const ENTERPRISE_PLAN_DAILY_QUOTA = 200;
const FREE_PLAN_DAILY_CAP = 20;
const PRO_PLAN_DAILY_CAP = 100;
const ENTERPRISE_PLAN_DAILY_CAP = 300;
const DAILY_MULTIPLIER = 1.1;
/**
* Create a new job instance.
*
@ -50,22 +42,27 @@ class AdjustEmailQuota implements ShouldQueue
*/
public function handle()
{
if (! config('ninja.db.multi_db_enabled')) {
$this->adjust();
} else {
//multiDB environment, need to
foreach (MultiDB::$dbs as $db) {
MultiDB::setDB($db);
if(!Ninja::isHosted())
return;
//multiDB environment, need to
foreach (MultiDB::$dbs as $db) {
MultiDB::setDB($db);
$this->adjust();
$this->adjust();
}
}
}
public function adjust()
{
foreach (Account::cursor() as $account) {
//@TODO once we add in the two columns daily_emails_quota daily_emails_sent_
}
Account::query()->cursor()->each(function ($account){
Cache::forget($account->key);
Cache::forget("throttle_notified:{$account->key}");
});
}
}

View File

@ -0,0 +1,60 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
*/
namespace App\Mail\Ninja;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class EmailQuotaExceeded extends Mailable
{
public $company;
public $settings;
public $logo;
public $title;
public $body;
public $whitelabel;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct($company)
{
$this->company = $company;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
$this->settings = $this->company->settings;
$this->logo = $this->company->present()->logo();
$this->title = ctrans('texts.email_quota_exceeded_subject');
$this->body = ctrans('texts.email_quota_exceeded_body', ['quota' => $this->company->account->getDailyEmailLimit()]);
$this->whitelabel = $this->company->account->isPaid();
return $this->from(config('mail.from.address'), config('mail.from.name'))
->subject(ctrans('texts.email_quota_exceeded_subject'))
->view('email.admin.email_quota_exceeded');
}
}

View File

@ -11,14 +11,16 @@
namespace App\Models;
use App\Jobs\Mail\NinjaMailerJob;
use App\Jobs\Mail\NinjaMailerObject;
use App\Models\Presenters\AccountPresenter;
use App\Utils\Ninja;
use App\Utils\Traits\MakesHash;
use Carbon\Carbon;
use DateTime;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Laracasts\Presenter\PresentableTrait;
use Illuminate\Support\Facades\Cache;
use Laracasts\Presenter\PresentableTrait;
class Account extends BaseModel
{
@ -357,7 +359,24 @@ class Account extends BaseModel
if(is_null(Cache::get($this->key)))
return false;
return Cache::get($this->key) > $this->getDailyEmailLimit();
if(Cache::get($this->key) > $this->getDailyEmailLimit()) {
if(is_null(Cache::get("throttle_notified:{$this->key}"))) {
$nmo = new NinjaMailerObject;
$nmo->mailable = new MaxCompanies($account->companies()->first());
$nmo->company = $account->companies()->first();
$nmo->settings = $account->companies()->first()->settings;
$nmo->to_user = $account->companies()->first()->owner();
NinjaMailerJob::dispatch($nmo);
Cache::put("throttle_notified:{$this->key}", true, 60 * 24);
}
return true;
}
return false;
}
}

View File

@ -4289,6 +4289,8 @@ $LANG = array(
'back_to' => 'Back to :url',
'stripe_connect_migration_title' => 'Connect your Stripe Account',
'stripe_connect_migration_desc' => 'Invoice Ninja v5 uses Stripe Connect to link your Stripe account to Invoice Ninja. This provides an additional layer of security for your account. Now that you data has migrated, you will need to Authorize Stripe to accept payments in v5.<br><br>To do this, navigate to Settings > Online Payments > Configure Gateways. Click on Stripe Connect and then under Settings click Setup Gateway. This will take you to Stripe to authorize Invoice Ninja and on your return your account will be successfully linked!',
'email_quota_exceeded_subject' => 'Account email quota exceeded.',
'email_quota_exceeded_body' => 'In a 24 hour period you have sent :quota emails. <br> We have paused your outbound emails.<br><br> Your email quota will reset at 23:00 UTC.',
);
return $LANG;

View File

@ -0,0 +1,7 @@
@component('email.template.admin', ['logo' => $logo, 'settings' => $settings])
<div class="center">
<h1>{!! $title !!}</h1>
<p>{!! $body !!}</p>
</div>
@endcomponent