diff --git a/app/Http/Controllers/MigrationController.php b/app/Http/Controllers/MigrationController.php index 57abd6fb4f45..0b04cc504ea5 100644 --- a/app/Http/Controllers/MigrationController.php +++ b/app/Http/Controllers/MigrationController.php @@ -304,6 +304,7 @@ class MigrationController extends BaseController App::forgetInstance('translator'); $t = app('translator'); $t->replace(Ninja::transformTranslations($user->account->companies()->first()->settings)); + App::setLocale($user->account->companies()->first()->getLocale()); if(!$existing_company && $company_count >=10) { diff --git a/app/Http/Controllers/PostMarkController.php b/app/Http/Controllers/PostMarkController.php index 60bb918e688a..5401808119a0 100644 --- a/app/Http/Controllers/PostMarkController.php +++ b/app/Http/Controllers/PostMarkController.php @@ -20,6 +20,8 @@ use App\Models\InvoiceInvitation; use App\Models\QuoteInvitation; use App\Models\RecurringInvoiceInvitation; use App\Models\SystemLog; +use App\Notifications\Ninja\EmailBounceNotification; +use App\Notifications\Ninja\EmailSpamNotification; use Illuminate\Http\Request; use Turbo124\Beacon\Facades\LightLogs; @@ -173,6 +175,10 @@ class PostMarkController extends BaseController LightLogs::create($bounce)->queue(); SystemLogger::dispatch($request->all(), SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_BOUNCED, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client, $this->invitation->company); + + if(config('ninja.notification.slack')) + $this->invitation->company->notification(new EmailBounceNotification($this->invitation->company->account))->ninja(); + } // { @@ -215,6 +221,10 @@ class PostMarkController extends BaseController LightLogs::create($spam)->queue(); SystemLogger::dispatch($request->all(), SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_SPAM_COMPLAINT, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client, $this->invitation->company); + + if(config('ninja.notification.slack')) + $this->invitation->company->notification(new EmailSpamNotification($this->invitation->company->account))->ninja(); + } private function discoverInvitation($message_id) diff --git a/app/Http/Controllers/TokenController.php b/app/Http/Controllers/TokenController.php index f095ca2070fe..aacdc145b84c 100644 --- a/app/Http/Controllers/TokenController.php +++ b/app/Http/Controllers/TokenController.php @@ -21,6 +21,7 @@ use App\Http\Requests\Token\StoreTokenRequest; use App\Http\Requests\Token\UpdateTokenRequest; use App\Models\CompanyToken; use App\Repositories\TokenRepository; +use App\Transformers\CompanyTokenHashedTransformer; use App\Transformers\CompanyTokenTransformer; use App\Utils\Traits\ChecksEntityStatus; use App\Utils\Traits\MakesHash; @@ -93,6 +94,8 @@ class TokenController extends BaseController */ public function index(TokenFilters $filters) { + $this->entity_transformer = CompanyTokenHashedTransformer::class; + $tokens = CompanyToken::filter($filters); return $this->listResponse($tokens); @@ -205,6 +208,8 @@ class TokenController extends BaseController */ public function edit(EditTokenRequest $request, CompanyToken $token) { + $this->entity_transformer = CompanyTokenHashedTransformer::class; + return $this->itemResponse($token); } @@ -265,6 +270,8 @@ class TokenController extends BaseController return $request->disallowUpdate(); } + $this->entity_transformer = CompanyTokenHashedTransformer::class; + $token = $this->token_repo->save($request->all(), $token); return $this->itemResponse($token->fresh()); @@ -419,6 +426,8 @@ class TokenController extends BaseController //may not need these destroy routes as we are using actions to 'archive/delete' $token->delete(); + $this->entity_transformer = CompanyTokenHashedTransformer::class; + return $this->itemResponse($token); } @@ -475,6 +484,9 @@ class TokenController extends BaseController */ public function bulk() { + + $this->entity_transformer = CompanyTokenHashedTransformer::class; + $action = request()->input('action'); $ids = request()->input('ids'); diff --git a/app/Jobs/Company/CompanyImport.php b/app/Jobs/Company/CompanyImport.php index 52fbdb5b949d..88ee380f3cfc 100644 --- a/app/Jobs/Company/CompanyImport.php +++ b/app/Jobs/Company/CompanyImport.php @@ -335,11 +335,12 @@ class CompanyImport implements ShouldQueue } } - if($this->company->account->isFreeHostedClient() && $client_count = count($this->getObject('clients', true)) > config('ninja.quotas.free.clients')){ + if($this->company->account->isFreeHostedClient() && (count($this->getObject('clients', true)) > config('ninja.quotas.free.clients')) ){ nlog("client quota busted"); $client_limit = config('ninja.quotas.free.clients'); + $client_count = count($this->getObject('clients', true)); $this->message = "You are attempting to import ({$client_count}) clients, your current plan allows a total of ({$client_limit})"; diff --git a/app/Jobs/RecurringInvoice/SendRecurring.php b/app/Jobs/RecurringInvoice/SendRecurring.php index 4d992607a054..8db0d968c122 100644 --- a/app/Jobs/RecurringInvoice/SendRecurring.php +++ b/app/Jobs/RecurringInvoice/SendRecurring.php @@ -135,7 +135,7 @@ class SendRecurring implements ShouldQueue if ($invitation->contact && !$invitation->contact->trashed() && strlen($invitation->contact->email) >=1 && $invoice->client->getSetting('auto_email_invoice')) { try{ - EmailEntity::dispatch($invitation, $invoice->company)->delay(now()->addSeconds(1)); + EmailEntity::dispatch($invitation, $invoice->company); } catch(\Exception $e) { nlog($e->getMessage()); diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index a6297b7034d0..7d2257c6b19a 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -101,6 +101,7 @@ class Invoice extends BaseModel 'updated_at' => 'timestamp', 'created_at' => 'timestamp', 'deleted_at' => 'timestamp', + 'is_deleted' => 'bool', ]; protected $with = []; diff --git a/app/Notifications/Ninja/EmailBounceNotification.php b/app/Notifications/Ninja/EmailBounceNotification.php new file mode 100644 index 000000000000..91ba5576150c --- /dev/null +++ b/app/Notifications/Ninja/EmailBounceNotification.php @@ -0,0 +1,88 @@ +account = $account; + } + + /** + * Get the notification's delivery channels. + * + * @param mixed $notifiable + * @return array + */ + public function via($notifiable) + { + return ['slack']; + } + + /** + * Get the mail representation of the notification. + * + * @param mixed $notifiable + * @return MailMessage + */ + public function toMail($notifiable) + { + } + + /** + * Get the array representation of the notification. + * + * @param mixed $notifiable + * @return array + */ + public function toArray($notifiable) + { + return [ + // + ]; + } + + public function toSlack($notifiable) + { + + $content = "Email bounce notification for Account {$this->account->key} \n"; + + $owner = $this->account->companies()->first()->owner(); + + $content .= "Owner {$owner->present()->name() } | {$owner->email}"; + + return (new SlackMessage) + ->success() + ->from(ctrans('texts.notification_bot')) + ->image('https://app.invoiceninja.com/favicon.png') + ->content($content); + } +} diff --git a/app/Notifications/Ninja/EmailSpamNotification.php b/app/Notifications/Ninja/EmailSpamNotification.php new file mode 100644 index 000000000000..2044a870a1bd --- /dev/null +++ b/app/Notifications/Ninja/EmailSpamNotification.php @@ -0,0 +1,88 @@ +account = $account; + } + + /** + * Get the notification's delivery channels. + * + * @param mixed $notifiable + * @return array + */ + public function via($notifiable) + { + return ['slack']; + } + + /** + * Get the mail representation of the notification. + * + * @param mixed $notifiable + * @return MailMessage + */ + public function toMail($notifiable) + { + } + + /** + * Get the array representation of the notification. + * + * @param mixed $notifiable + * @return array + */ + public function toArray($notifiable) + { + return [ + // + ]; + } + + public function toSlack($notifiable) + { + + $content = "Email SPAM notification for Account {$this->account->key} \n"; + + $owner = $this->account->companies()->first()->owner(); + + $content .= "Owner {$owner->present()->name() } | {$owner->email}"; + + return (new SlackMessage) + ->success() + ->from(ctrans('texts.notification_bot')) + ->image('https://app.invoiceninja.com/favicon.png') + ->content($content); + } +} diff --git a/app/Repositories/PaymentRepository.php b/app/Repositories/PaymentRepository.php index 4ea1e65340e3..a4a70c834cfe 100644 --- a/app/Repositories/PaymentRepository.php +++ b/app/Repositories/PaymentRepository.php @@ -47,9 +47,13 @@ class PaymentRepository extends BaseRepository { */ public function save(array $data, Payment $payment): ?Payment { - if ($payment->amount >= 0) { + // if ($payment->amount >= 0) { + // return $this->applyPayment($data, $payment); + // } + + return $this->applyPayment($data, $payment); - } + return $payment; } @@ -80,8 +84,8 @@ class PaymentRepository extends BaseRepository { $client->service()->updatePaidToDate($data['amount'])->save(); } - elseif($data['amount'] >0){ - + // elseif($data['amount'] >0){ + else{ //this fixes an edge case with unapplied payments $client->service()->updatePaidToDate($data['amount'])->save(); } diff --git a/app/Services/Invoice/AutoBillInvoice.php b/app/Services/Invoice/AutoBillInvoice.php index 2771c3409a2a..025e9dcec957 100644 --- a/app/Services/Invoice/AutoBillInvoice.php +++ b/app/Services/Invoice/AutoBillInvoice.php @@ -105,6 +105,7 @@ class AutoBillInvoice extends AbstractService $fee = 0; /* Build payment hash */ + $payment_hash = PaymentHash::create([ 'hash' => Str::random(64), 'data' => ['invoices' => [['invoice_id' => $this->invoice->hashed_id, 'amount' => $amount, 'invoice_number' => $this->invoice->number]]], @@ -123,7 +124,8 @@ class AutoBillInvoice extends AbstractService ->tokenBilling($gateway_token, $payment_hash); } catch(\Exception $e){ - nlog($e->getMessage()); + nlog("payment NOT captured for ". $this->invoice->number . " with error " . $e->getMessage()); + // nlog($e->getMessage()); } if($payment){ diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index 762ca47142bb..aeefce8f7cd6 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -4342,7 +4342,7 @@ $LANG = array( 'payment_type_instant_bank_pay' => 'Instant Bank Pay', 'payment_type_iDEAL' => 'iDEAL', 'payment_type_Przelewy24' => 'Przelewy24', - 'payment_type_Mollie Bank Transfer' => 'Bank Transfer', + 'payment_type_Mollie Bank Transfer' => 'Mollie Bank Transfer', 'payment_type_KBC/CBC' => 'KBC/CBC', 'payment_type_Instant Bank Pay' => 'Instant Bank Pay', 'payment_type_Hosted Page' => 'Hosted Page',