mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-07 17:44:29 -04:00
commit
676207479c
@ -36,7 +36,8 @@ We offer a $30 per year white-label license to remove the Invoice Ninja branding
|
||||
### Desktop Apps
|
||||
* [macOS](https://apps.apple.com/app/id1503970375?platform=mac)
|
||||
* [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
|
||||
* [Docker File](https://hub.docker.com/r/invoiceninja/invoiceninja/)
|
||||
|
@ -15,6 +15,23 @@ use Illuminate\Support\Facades\App;
|
||||
|
||||
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)
|
||||
{
|
||||
App::setLocale($locale);
|
||||
|
@ -22,7 +22,10 @@ class BulkBankIntegrationRequest extends Request
|
||||
*/
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->isAdmin();
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return $user->isAdmin();
|
||||
}
|
||||
|
||||
public function rules()
|
||||
|
@ -11,17 +11,37 @@
|
||||
|
||||
namespace App\Http\Requests\Email;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
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
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
private string $entity_plural = '';
|
||||
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.
|
||||
*
|
||||
@ -39,14 +59,16 @@ class SendEmailRequest extends Request
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return [
|
||||
'template' => 'bail|required',
|
||||
'entity' => 'bail|required',
|
||||
'entity_id' => 'bail|required',
|
||||
'template' => 'bail|required|in:'.implode(',', $this->templates),
|
||||
'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', Rule::exists($this->entity_plural, 'id')->where('company_id', $user->company()->id)],
|
||||
'cc_email.*' => 'bail|sometimes|email',
|
||||
];
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function prepareForValidation()
|
||||
@ -70,6 +92,8 @@ class SendEmailRequest extends Request
|
||||
$input['entity_id'] = $this->decodePrimaryKey($input['entity_id']);
|
||||
}
|
||||
|
||||
$this->entity_plural = Str::plural($input['entity']) ?? '';
|
||||
|
||||
if (isset($input['entity'])) {
|
||||
$input['entity'] = "App\Models\\".ucfirst(Str::camel($input['entity']));
|
||||
}
|
||||
|
@ -11,24 +11,25 @@
|
||||
|
||||
namespace App\Jobs\PostMark;
|
||||
|
||||
use App\DataMapper\Analytics\Mail\EmailBounce;
|
||||
use App\DataMapper\Analytics\Mail\EmailSpam;
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
use App\Models\Company;
|
||||
use App\Models\SystemLog;
|
||||
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\InvoiceInvitation;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Turbo124\Beacon\Facades\LightLogs;
|
||||
use App\Models\PurchaseOrderInvitation;
|
||||
use App\Models\QuoteInvitation;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use App\Models\RecurringInvoiceInvitation;
|
||||
use App\Models\SystemLog;
|
||||
use App\Notifications\Ninja\EmailSpamNotification;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Postmark\PostmarkClient;
|
||||
use Turbo124\Beacon\Facades\LightLogs;
|
||||
use App\DataMapper\Analytics\Mail\EmailSpam;
|
||||
use App\DataMapper\Analytics\Mail\EmailBounce;
|
||||
use App\Notifications\Ninja\EmailSpamNotification;
|
||||
|
||||
class ProcessPostmarkWebhook implements ShouldQueue
|
||||
{
|
||||
@ -82,9 +83,14 @@ class ProcessPostmarkWebhook implements ShouldQueue
|
||||
public function handle()
|
||||
{
|
||||
MultiDB::findAndSetDbByCompanyKey($this->request['Tag']);
|
||||
$company = Company::where('company_key', $this->request['Tag'])->first();
|
||||
|
||||
$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) {
|
||||
return;
|
||||
}
|
||||
@ -305,20 +311,8 @@ class ProcessPostmarkWebhook implements ShouldQueue
|
||||
|
||||
if($sl) {
|
||||
$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)
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace App\Notifications\Ninja;
|
||||
|
||||
use App\Models\Company;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
@ -21,11 +22,8 @@ class EmailSpamNotification extends Notification
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected $account;
|
||||
|
||||
public function __construct($account)
|
||||
public function __construct(protected Company $company)
|
||||
{
|
||||
$this->account = $account;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,9 +61,9 @@ class EmailSpamNotification extends Notification
|
||||
|
||||
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}";
|
||||
|
||||
|
@ -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')
|
||||
<link
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
href="https://www.paypalobjects.com/webstatic/en_US/developer/docs/css/cardfields.css"
|
||||
/>
|
||||
|
||||
@endsection
|
||||
|
||||
@ -20,7 +15,7 @@
|
||||
|
||||
<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
|
||||
|
||||
@ -46,6 +41,9 @@
|
||||
createOrder: function(data, actions) {
|
||||
return "{!! $order_id !!}"
|
||||
},
|
||||
onCancel: function() {
|
||||
window.location.href = "/client/invoices/";
|
||||
},
|
||||
onApprove: function(data, actions) {
|
||||
|
||||
return actions.order.capture().then(function(details) {
|
||||
@ -58,6 +56,9 @@
|
||||
},
|
||||
onError: function(err) {
|
||||
console.log(err);
|
||||
},
|
||||
onClick: function (){
|
||||
document.getElementById('paypal-button-container').hidden = true;
|
||||
}
|
||||
|
||||
}).render('#paypal-button-container').catch(function(err) {
|
||||
|
@ -1,11 +1,6 @@
|
||||
@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.payment_type_credit_card'), 'card_title' => 'PayPal'])
|
||||
|
||||
@section('gateway_head')
|
||||
<link
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
href="https://www.paypalobjects.com/webstatic/en_US/developer/docs/css/cardfields.css"
|
||||
/>
|
||||
|
||||
@endsection
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user