Merge pull request #9051 from turbo124/v5-develop

Updates for readme
This commit is contained in:
David Bomba 2023-12-17 12:05:10 +11:00 committed by GitHub
commit 676207479c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 83 additions and 50 deletions

View File

@ -36,7 +36,8 @@ We offer a $30 per year white-label license to remove the Invoice Ninja branding
### Desktop Apps ### Desktop Apps
* [macOS](https://apps.apple.com/app/id1503970375?platform=mac) * [macOS](https://apps.apple.com/app/id1503970375?platform=mac)
* [Windows](https://microsoft.com/en-us/p/invoice-ninja/9n3f2bbcfdr6) * [Windows](https://microsoft.com/en-us/p/invoice-ninja/9n3f2bbcfdr6)
* [Linux](https://snapcraft.io/invoiceninja) * [Linux - Snap](https://snapcraft.io/invoiceninja)
* [Linux - Flatpak](https://flathub.org/apps/com.invoiceninja.InvoiceNinja)
### Installation Options ### Installation Options
* [Docker File](https://hub.docker.com/r/invoiceninja/invoiceninja/) * [Docker File](https://hub.docker.com/r/invoiceninja/invoiceninja/)

View File

@ -15,6 +15,23 @@ use Illuminate\Support\Facades\App;
class EmailTemplateDefaults class EmailTemplateDefaults
{ {
public array $templates = [
'email_template_invoice',
'email_template_quote',
'email_template_credit',
'email_template_payment',
'email_template_payment_partial',
'email_template_statement',
'email_template_reminder1',
'email_template_reminder2',
'email_template_reminder3',
'email_template_reminder_endless',
'email_template_custom1',
'email_template_custom2',
'email_template_custom3',
'email_template_purchase_order',
];
public static function getDefaultTemplate($template, $locale) public static function getDefaultTemplate($template, $locale)
{ {
App::setLocale($locale); App::setLocale($locale);

View File

@ -22,7 +22,10 @@ class BulkBankIntegrationRequest extends Request
*/ */
public function authorize() : bool public function authorize() : bool
{ {
return auth()->user()->isAdmin(); /** @var \App\Models\User $user */
$user = auth()->user();
return $user->isAdmin();
} }
public function rules() public function rules()

View File

@ -11,17 +11,37 @@
namespace App\Http\Requests\Email; namespace App\Http\Requests\Email;
use App\Http\Requests\Request;
use App\Utils\Ninja; use App\Utils\Ninja;
use App\Utils\Traits\MakesHash;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use App\Http\Requests\Request;
use App\Utils\Traits\MakesHash;
use Illuminate\Validation\Rule;
use Illuminate\Auth\Access\AuthorizationException;
class SendEmailRequest extends Request class SendEmailRequest extends Request
{ {
use MakesHash; use MakesHash;
private string $entity_plural = '';
private string $error_message = ''; private string $error_message = '';
public array $templates = [
'email_template_invoice',
'email_template_quote',
'email_template_credit',
'email_template_payment',
'email_template_payment_partial',
'email_template_statement',
'email_template_reminder1',
'email_template_reminder2',
'email_template_reminder3',
'email_template_reminder_endless',
'email_template_custom1',
'email_template_custom2',
'email_template_custom3',
'email_template_purchase_order',
];
/** /**
* Determine if the user is authorized to make this request. * Determine if the user is authorized to make this request.
* *
@ -39,14 +59,16 @@ class SendEmailRequest extends Request
*/ */
public function rules() public function rules()
{ {
/** @var \App\Models\User $user */
$user = auth()->user();
return [ return [
'template' => 'bail|required', 'template' => 'bail|required|in:'.implode(',', $this->templates),
'entity' => 'bail|required', 'entity' => 'bail|required|in:App\Models\Invoice,App\Models\Quote,App\Models\Credit,App\Models\RecurringInvoice,App\Models\PurchaseOrder,App\Models\Payment',
'entity_id' => 'bail|required', 'entity_id' => ['bail', 'required', Rule::exists($this->entity_plural, 'id')->where('company_id', $user->company()->id)],
'cc_email.*' => 'bail|sometimes|email', 'cc_email.*' => 'bail|sometimes|email',
]; ];
} }
public function prepareForValidation() public function prepareForValidation()
@ -70,6 +92,8 @@ class SendEmailRequest extends Request
$input['entity_id'] = $this->decodePrimaryKey($input['entity_id']); $input['entity_id'] = $this->decodePrimaryKey($input['entity_id']);
} }
$this->entity_plural = Str::plural($input['entity']) ?? '';
if (isset($input['entity'])) { if (isset($input['entity'])) {
$input['entity'] = "App\Models\\".ucfirst(Str::camel($input['entity'])); $input['entity'] = "App\Models\\".ucfirst(Str::camel($input['entity']));
} }

View File

@ -11,24 +11,25 @@
namespace App\Jobs\PostMark; namespace App\Jobs\PostMark;
use App\DataMapper\Analytics\Mail\EmailBounce; use App\Models\Company;
use App\DataMapper\Analytics\Mail\EmailSpam; use App\Models\SystemLog;
use App\Jobs\Util\SystemLogger;
use App\Libraries\MultiDB; use App\Libraries\MultiDB;
use Postmark\PostmarkClient;
use Illuminate\Bus\Queueable;
use App\Jobs\Util\SystemLogger;
use App\Models\QuoteInvitation;
use App\Models\CreditInvitation; use App\Models\CreditInvitation;
use App\Models\InvoiceInvitation; use App\Models\InvoiceInvitation;
use Illuminate\Queue\SerializesModels;
use Turbo124\Beacon\Facades\LightLogs;
use App\Models\PurchaseOrderInvitation; use App\Models\PurchaseOrderInvitation;
use App\Models\QuoteInvitation; use Illuminate\Queue\InteractsWithQueue;
use App\Models\RecurringInvoiceInvitation; use App\Models\RecurringInvoiceInvitation;
use App\Models\SystemLog;
use App\Notifications\Ninja\EmailSpamNotification;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue; use App\DataMapper\Analytics\Mail\EmailSpam;
use Illuminate\Queue\SerializesModels; use App\DataMapper\Analytics\Mail\EmailBounce;
use Postmark\PostmarkClient; use App\Notifications\Ninja\EmailSpamNotification;
use Turbo124\Beacon\Facades\LightLogs;
class ProcessPostmarkWebhook implements ShouldQueue class ProcessPostmarkWebhook implements ShouldQueue
{ {
@ -82,9 +83,14 @@ class ProcessPostmarkWebhook implements ShouldQueue
public function handle() public function handle()
{ {
MultiDB::findAndSetDbByCompanyKey($this->request['Tag']); MultiDB::findAndSetDbByCompanyKey($this->request['Tag']);
$company = Company::where('company_key', $this->request['Tag'])->first();
$this->invitation = $this->discoverInvitation($this->request['MessageID']); $this->invitation = $this->discoverInvitation($this->request['MessageID']);
if ($company && $this->request['RecordType'] == 'SpamComplaint' && config('ninja.notification.slack')) {
$company->notification(new EmailSpamNotification($company))->ninja();
}
if (!$this->invitation) { if (!$this->invitation) {
return; return;
} }
@ -305,20 +311,8 @@ class ProcessPostmarkWebhook implements ShouldQueue
if($sl) { if($sl) {
$this->updateSystemLog($sl, $data); $this->updateSystemLog($sl, $data);
if (config('ninja.notification.slack')) {
$this->invitation->company->notification(new EmailSpamNotification($this->invitation->company->account))->ninja();
} }
return;
}
(new SystemLogger($data, SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_SPAM_COMPLAINT, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client, $this->invitation->company))->handle();
if (config('ninja.notification.slack')) {
$this->invitation->company->notification(new EmailSpamNotification($this->invitation->company->account))->ninja();
}
} }
private function discoverInvitation($message_id) private function discoverInvitation($message_id)

View File

@ -11,6 +11,7 @@
namespace App\Notifications\Ninja; namespace App\Notifications\Ninja;
use App\Models\Company;
use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification; use Illuminate\Notifications\Notification;
@ -21,11 +22,8 @@ class EmailSpamNotification extends Notification
* *
* @return void * @return void
*/ */
protected $account; public function __construct(protected Company $company)
public function __construct($account)
{ {
$this->account = $account;
} }
/** /**
@ -63,9 +61,9 @@ class EmailSpamNotification extends Notification
public function toSlack($notifiable) public function toSlack($notifiable)
{ {
$content = "Email SPAM notification for Account {$this->account->key} \n"; $content = "Email SPAM notification for Company {$this->company->company_key} \n";
$owner = $this->account->companies()->first()->owner(); $owner = $this->company->owner();
$content .= "Owner {$owner->present()->name() } | {$owner->email}"; $content .= "Owner {$owner->present()->name() } | {$owner->email}";

View File

@ -1,11 +1,6 @@
@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.payment_type_credit_card'), 'card_title' => 'PayPal']) @extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.payment_type_credit_card'), 'card_title' => ''])
@section('gateway_head') @section('gateway_head')
<link
rel="stylesheet"
type="text/css"
href="https://www.paypalobjects.com/webstatic/en_US/developer/docs/css/cardfields.css"
/>
@endsection @endsection
@ -20,7 +15,7 @@
<div class="alert alert-failure mb-4" hidden id="errors"></div> <div class="alert alert-failure mb-4" hidden id="errors"></div>
<div id="paypal-button-container" class="paypal-button-container"></div> <div id="paypal-button-container" class="paypal-button-container"></div>
@endsection @endsection
@ -46,6 +41,9 @@
createOrder: function(data, actions) { createOrder: function(data, actions) {
return "{!! $order_id !!}" return "{!! $order_id !!}"
}, },
onCancel: function() {
window.location.href = "/client/invoices/";
},
onApprove: function(data, actions) { onApprove: function(data, actions) {
return actions.order.capture().then(function(details) { return actions.order.capture().then(function(details) {
@ -58,6 +56,9 @@
}, },
onError: function(err) { onError: function(err) {
console.log(err); console.log(err);
},
onClick: function (){
document.getElementById('paypal-button-container').hidden = true;
} }
}).render('#paypal-button-container').catch(function(err) { }).render('#paypal-button-container').catch(function(err) {

View File

@ -1,11 +1,6 @@
@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.payment_type_credit_card'), 'card_title' => 'PayPal']) @extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.payment_type_credit_card'), 'card_title' => 'PayPal'])
@section('gateway_head') @section('gateway_head')
<link
rel="stylesheet"
type="text/css"
href="https://www.paypalobjects.com/webstatic/en_US/developer/docs/css/cardfields.css"
/>
@endsection @endsection