mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Fixes for conflicts
This commit is contained in:
commit
46b4ccd7e8
@ -1 +1 @@
|
||||
5.5.64
|
||||
5.5.67
|
@ -175,8 +175,6 @@ class CheckData extends Command
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private function checkOauthSanity()
|
||||
|
@ -443,6 +443,8 @@ class CompanySettings extends BaseSettings
|
||||
|
||||
public $postmark_secret = '';
|
||||
|
||||
public $custom_sending_email = '';
|
||||
|
||||
public $mailgun_secret = '';
|
||||
|
||||
public $mailgun_domain = '';
|
||||
@ -459,7 +461,11 @@ class CompanySettings extends BaseSettings
|
||||
|
||||
public $show_shipping_address = false;
|
||||
|
||||
public $accept_client_input_quote_approval = false;
|
||||
|
||||
public static $casts = [
|
||||
'accept_client_input_quote_approval' => 'bool',
|
||||
'custom_sending_email' => 'string',
|
||||
'show_paid_stamp' => 'bool',
|
||||
'show_shipping_address' => 'bool',
|
||||
'company_logo_size' => 'string',
|
||||
|
@ -33,7 +33,6 @@ use PDOException;
|
||||
use Sentry\Laravel\Integration;
|
||||
use Sentry\State\Scope;
|
||||
use Symfony\Component\Console\Exception\CommandNotFoundException;
|
||||
use Symfony\Component\Debug\Exception\FatalThrowableError;
|
||||
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use League\Flysystem\UnableToCreateDirectory;
|
||||
@ -222,7 +221,7 @@ class Handler extends ExceptionHandler
|
||||
return response()->json(['message'=>'Too many requests'], 429);
|
||||
// } elseif ($exception instanceof FatalThrowableError && $request->expectsJson()) {
|
||||
// return response()->json(['message'=>'Fatal error'], 500); //@deprecated
|
||||
} elseif ($exception instanceof AuthorizationException) {
|
||||
} elseif ($exception instanceof AuthorizationException && $request->expectsJson()) {
|
||||
return response()->json(['message'=> $exception->getMessage()], 401);
|
||||
} elseif ($exception instanceof TokenMismatchException) {
|
||||
return redirect()
|
||||
|
33
app/Exceptions/Ninja/ClientPortalAuthorizationException.php
Normal file
33
app/Exceptions/Ninja/ClientPortalAuthorizationException.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Exceptions\Ninja;
|
||||
|
||||
use Exception;
|
||||
|
||||
class ClientPortalAuthorizationException extends Exception
|
||||
{
|
||||
public function report()
|
||||
{
|
||||
// ..
|
||||
}
|
||||
|
||||
public function render($request)
|
||||
{
|
||||
return view('errors.client-error', [
|
||||
'account' => auth()->guard('contact')->check() ? auth()->guard('contact')->user()->user->account : false,
|
||||
'company' => auth()->guard('contact')->check() ? auth()->guard('contact')->user()->company : false,
|
||||
'title' => ctrans('texts.error_title'),
|
||||
'message' => $this->getMessage(),
|
||||
'code' => $this->getCode(),
|
||||
]);
|
||||
}
|
||||
}
|
@ -26,10 +26,11 @@ class BankIntegrationFilters extends QueryFilters
|
||||
*/
|
||||
public function name(string $name = ''): Builder
|
||||
{
|
||||
if(strlen($name) >=1)
|
||||
return $this->builder->where('bank_account_name', 'like', '%'.$name.'%');
|
||||
if (strlen($name) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder;
|
||||
return $this->builder->where('bank_account_name', 'like', '%'.$name.'%');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,10 +91,14 @@ class BankIntegrationFilters extends QueryFilters
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort): Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
|
@ -27,10 +27,11 @@ class BankTransactionFilters extends QueryFilters
|
||||
*/
|
||||
public function name(string $name = ''): Builder
|
||||
{
|
||||
if(strlen($name) >=1)
|
||||
return $this->builder->where('bank_account_name', 'like', '%'.$name.'%');
|
||||
if (strlen($name) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder;
|
||||
return $this->builder->where('bank_account_name', 'like', '%'.$name.'%');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -40,7 +41,7 @@ class BankTransactionFilters extends QueryFilters
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
public function filter(string $filter = '') : Builder
|
||||
public function filter(string $filter = ''): Builder
|
||||
{
|
||||
if (strlen($filter) == 0) {
|
||||
return $this->builder;
|
||||
@ -66,7 +67,7 @@ class BankTransactionFilters extends QueryFilters
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function client_status(string $value = '') :Builder
|
||||
public function client_status(string $value = ''): Builder
|
||||
{
|
||||
if (strlen($value) == 0) {
|
||||
return $this->builder;
|
||||
@ -123,12 +124,13 @@ class BankTransactionFilters extends QueryFilters
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort) : Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if(!is_array($sort_col))
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
if($sort_col[0] == 'deposit')
|
||||
return $this->builder->where('base_type', 'CREDIT')->orderBy('amount', $sort_col[1]);
|
||||
|
@ -11,11 +11,7 @@
|
||||
|
||||
namespace App\Filters;
|
||||
|
||||
use App\Models\BankTransactionRule;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
/**
|
||||
* BankTransactionRuleilters.
|
||||
@ -30,10 +26,11 @@ class BankTransactionRuleFilters extends QueryFilters
|
||||
*/
|
||||
public function name(string $name = ''): Builder
|
||||
{
|
||||
if(strlen($name) >=1)
|
||||
return $this->builder->where('name', 'like', '%'.$name.'%');
|
||||
if (strlen($name) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder;
|
||||
return $this->builder->where('name', 'like', '%'.$name.'%');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -43,7 +40,7 @@ class BankTransactionRuleFilters extends QueryFilters
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
public function filter(string $filter = '') : Builder
|
||||
public function filter(string $filter = ''): Builder
|
||||
{
|
||||
if (strlen($filter) == 0) {
|
||||
return $this->builder;
|
||||
@ -61,26 +58,17 @@ class BankTransactionRuleFilters extends QueryFilters
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort) : Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base query.
|
||||
*
|
||||
* @param int company_id
|
||||
* @param User $user
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
public function baseQuery(int $company_id, User $user) : Builder
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the query by the users company ID.
|
||||
*
|
||||
|
@ -11,11 +11,7 @@
|
||||
|
||||
namespace App\Filters;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
/**
|
||||
* ClientFilters.
|
||||
@ -30,10 +26,11 @@ class ClientFilters extends QueryFilters
|
||||
*/
|
||||
public function name(string $name = ''): Builder
|
||||
{
|
||||
if(strlen($name) >=1)
|
||||
return $this->builder->where('name', 'like', '%'.$name.'%');
|
||||
if (strlen($name) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder;
|
||||
return $this->builder->where('name', 'like', '%'.$name.'%');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -42,8 +39,12 @@ class ClientFilters extends QueryFilters
|
||||
* @param string $balance
|
||||
* @return Builder
|
||||
*/
|
||||
public function balance(string $balance): Builder
|
||||
public function balance(string $balance = ''): Builder
|
||||
{
|
||||
if (strlen($balance) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
$parts = $this->split($balance);
|
||||
|
||||
return $this->builder->where('balance', $parts->operator, $parts->value);
|
||||
@ -55,27 +56,29 @@ class ClientFilters extends QueryFilters
|
||||
* @param string balance
|
||||
* @return Builder
|
||||
*/
|
||||
public function between_balance(string $balance): Builder
|
||||
public function between_balance(string $balance = ''): Builder
|
||||
{
|
||||
$parts = explode(':', $balance);
|
||||
|
||||
if (! is_array($parts)) {
|
||||
if (!is_array($parts) || count($parts) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->whereBetween('balance', [$parts[0], $parts[1]]);
|
||||
}
|
||||
|
||||
public function email(string $email = ''):Builder
|
||||
public function email(string $email = ''): Builder
|
||||
{
|
||||
return
|
||||
if (strlen($email) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
$this->builder->whereHas('contacts', function ($query) use ($email) {
|
||||
return $this->builder->whereHas('contacts', function ($query) use ($email) {
|
||||
$query->where('email', $email);
|
||||
});
|
||||
}
|
||||
|
||||
public function client_id(string $client_id = '') :Builder
|
||||
public function client_id(string $client_id = ''): Builder
|
||||
{
|
||||
if (strlen($client_id) == 0) {
|
||||
return $this->builder;
|
||||
@ -84,13 +87,21 @@ class ClientFilters extends QueryFilters
|
||||
return $this->builder->where('id', $this->decodePrimaryKey($client_id));
|
||||
}
|
||||
|
||||
public function id_number(string $id_number = ''):Builder
|
||||
public function id_number(string $id_number = ''): Builder
|
||||
{
|
||||
if (strlen($id_number) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->where('id_number', $id_number);
|
||||
}
|
||||
|
||||
public function number(string $number = ''):Builder
|
||||
public function number(string $number = ''): Builder
|
||||
{
|
||||
if (strlen($number) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->where('number', $number);
|
||||
}
|
||||
|
||||
@ -101,7 +112,7 @@ class ClientFilters extends QueryFilters
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
public function filter(string $filter = '') : Builder
|
||||
public function filter(string $filter = ''): Builder
|
||||
{
|
||||
if (strlen($filter) == 0) {
|
||||
return $this->builder;
|
||||
@ -128,10 +139,14 @@ class ClientFilters extends QueryFilters
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort) : Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
if($sort_col[0] == 'display_name')
|
||||
$sort_col[0] = 'name';
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
namespace App\Filters;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
/**
|
||||
@ -26,7 +25,7 @@ class CompanyGatewayFilters extends QueryFilters
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
public function filter(string $filter = '') : Builder
|
||||
public function filter(string $filter = ''): Builder
|
||||
{
|
||||
if (strlen($filter) == 0) {
|
||||
return $this->builder;
|
||||
@ -43,10 +42,14 @@ class CompanyGatewayFilters extends QueryFilters
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort) : Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ class CreditFilters extends QueryFilters
|
||||
* @param string credit_status The credit status as seen by the client
|
||||
* @return Builder
|
||||
*/
|
||||
public function credit_status(string $value = '') :Builder
|
||||
public function credit_status(string $value = ''): Builder
|
||||
{
|
||||
if (strlen($value) == 0) {
|
||||
return $this->builder;
|
||||
@ -66,7 +66,7 @@ class CreditFilters extends QueryFilters
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
public function filter(string $filter = '') : Builder
|
||||
public function filter(string $filter = ''): Builder
|
||||
{
|
||||
if (strlen($filter) == 0) {
|
||||
return $this->builder;
|
||||
@ -85,16 +85,29 @@ class CreditFilters extends QueryFilters
|
||||
});
|
||||
}
|
||||
|
||||
public function number(string $number = ''): Builder
|
||||
{
|
||||
if (strlen($number) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->where('number', $number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort) : Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
@ -123,7 +136,7 @@ class CreditFilters extends QueryFilters
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
private function contactViewFilter() : Builder
|
||||
private function contactViewFilter(): Builder
|
||||
{
|
||||
return $this->builder
|
||||
->whereCompanyId(auth()->guard('contact')->user()->company->id)
|
||||
|
@ -32,7 +32,7 @@ class DesignFilters extends QueryFilters
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->where(function ($query) use ($filter) {
|
||||
return $this->builder->where(function ($query) use ($filter) {
|
||||
$query->where('designs.name', 'like', '%'.$filter.'%');
|
||||
});
|
||||
}
|
||||
@ -44,14 +44,15 @@ class DesignFilters extends QueryFilters
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort): Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if(is_array($sort_col))
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder;
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -61,7 +62,6 @@ class DesignFilters extends QueryFilters
|
||||
*/
|
||||
public function entityFilter(): Builder
|
||||
{
|
||||
//return $this->builder->whereCompanyId(auth()->user()->company()->id);
|
||||
return $this->builder->where('company_id', auth()->user()->company()->id)->orWhere('company_id', null)->orderBy('id','asc');
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ class DocumentFilters extends QueryFilters
|
||||
* Overriding method as client_id does
|
||||
* not exist on this model, just pass
|
||||
* back the builder
|
||||
*
|
||||
* @param string $client_id The client hashed id.
|
||||
*
|
||||
* @return Builder
|
||||
@ -54,14 +55,15 @@ class DocumentFilters extends QueryFilters
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort = '') : Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if(is_array($sort_col))
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder;
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,7 +25,7 @@ class ExpenseCategoryFilters extends QueryFilters
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
public function filter(string $filter = '') : Builder
|
||||
public function filter(string $filter = ''): Builder
|
||||
{
|
||||
if (strlen($filter) == 0) {
|
||||
return $this->builder;
|
||||
@ -41,10 +41,14 @@ class ExpenseCategoryFilters extends QueryFilters
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort) : Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
if (is_array($sort_col) && in_array($sort_col[1], ['asc', 'desc']) && in_array($sort_col[0], ['name']))
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
|
||||
|
@ -25,7 +25,7 @@ class ExpenseFilters extends QueryFilters
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
public function filter(string $filter = '') : Builder
|
||||
public function filter(string $filter = ''): Builder
|
||||
{
|
||||
if (strlen($filter) == 0) {
|
||||
return $this->builder;
|
||||
@ -53,7 +53,7 @@ class ExpenseFilters extends QueryFilters
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function client_status(string $value = '') :Builder
|
||||
public function client_status(string $value = ''): Builder
|
||||
{
|
||||
if (strlen($value) == 0) {
|
||||
return $this->builder;
|
||||
@ -132,16 +132,29 @@ class ExpenseFilters extends QueryFilters
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
public function number(string $number = ''): Builder
|
||||
{
|
||||
if (strlen($number) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->where('number', $number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort) : Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
if (is_array($sort_col) && in_array($sort_col[1], ['asc', 'desc']) && in_array($sort_col[0], ['public_notes', 'date', 'id_number', 'custom_value1', 'custom_value2', 'custom_value3', 'custom_value4'])) {
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
@ -179,8 +179,7 @@ class InvoiceFilters extends QueryFilters
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
//catch invalid explode array count
|
||||
if (count($sort_col) == 1) {
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
@ -224,7 +223,7 @@ class InvoiceFilters extends QueryFilters
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
private function contactViewFilter() : Builder
|
||||
private function contactViewFilter(): Builder
|
||||
{
|
||||
return $this->builder
|
||||
->whereCompanyId(auth()->guard('contact')->user()->company->id)
|
||||
|
@ -62,25 +62,30 @@ class PaymentFilters extends QueryFilters
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
public function number(string $number = ''): Builder
|
||||
{
|
||||
if (strlen($number) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->where('number', $number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort): Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if(is_array($sort_col))
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function number(string $number = ''): Builder
|
||||
{
|
||||
return $this->builder->where('number', $number);
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,10 +42,14 @@ class PaymentTermFilters extends QueryFilters
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort): Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
|
@ -58,12 +58,13 @@ class ProductFilters extends QueryFilters
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort): Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if(!is_array($sort_col))
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ class ProjectFilters extends QueryFilters
|
||||
* @return Illuminate\Eloquent\Query\Builder
|
||||
* @deprecated
|
||||
*/
|
||||
public function filter(string $filter = '') :Builder
|
||||
public function filter(string $filter = ''): Builder
|
||||
{
|
||||
if (strlen($filter) == 0) {
|
||||
return $this->builder;
|
||||
@ -38,16 +38,29 @@ class ProjectFilters extends QueryFilters
|
||||
});
|
||||
}
|
||||
|
||||
public function number(string $number = ''): Builder
|
||||
{
|
||||
if (strlen($number) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->where('number', $number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Illuminate\Eloquent\Query\Builder
|
||||
*/
|
||||
public function sort(string $sort) :Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
if(is_array($sort_col))
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
@ -57,7 +70,7 @@ class ProjectFilters extends QueryFilters
|
||||
*
|
||||
* @return Illuminate\Eloquent\Query\Builder
|
||||
*/
|
||||
public function entityFilter() :Builder
|
||||
public function entityFilter(): Builder
|
||||
{
|
||||
return $this->builder->company();
|
||||
}
|
||||
|
@ -100,16 +100,29 @@ class PurchaseOrderFilters extends QueryFilters
|
||||
});
|
||||
}
|
||||
|
||||
public function number(string $number = ''): Builder
|
||||
{
|
||||
if (strlen($number) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->where('number', $number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort): Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
@ -136,7 +149,7 @@ class PurchaseOrderFilters extends QueryFilters
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
private function contactViewFilter() : Builder
|
||||
private function contactViewFilter(): Builder
|
||||
{
|
||||
return $this->builder
|
||||
->whereCompanyId(auth()->guard('contact')->user()->company->id)
|
||||
|
@ -136,7 +136,7 @@ abstract class QueryFilters
|
||||
* @param string filter
|
||||
* @return Builder
|
||||
*/
|
||||
public function status(string $filter = '') : Builder
|
||||
public function status(string $filter = ''): Builder
|
||||
{
|
||||
if (strlen($filter) == 0) {
|
||||
return $this->builder;
|
||||
@ -241,7 +241,7 @@ abstract class QueryFilters
|
||||
return $this->builder->where('is_deleted', $value);
|
||||
}
|
||||
|
||||
public function client_id(string $client_id = '') :Builder
|
||||
public function client_id(string $client_id = ''): Builder
|
||||
{
|
||||
if (strlen($client_id) == 0) {
|
||||
return $this->builder;
|
||||
@ -250,7 +250,7 @@ abstract class QueryFilters
|
||||
return $this->builder->where('client_id', $this->decodePrimaryKey($client_id));
|
||||
}
|
||||
|
||||
public function vendor_id(string $vendor_id = '') :Builder
|
||||
public function vendor_id(string $vendor_id = ''): Builder
|
||||
{
|
||||
if (strlen($vendor_id) == 0) {
|
||||
return $this->builder;
|
||||
|
@ -113,7 +113,11 @@ class QuoteFilters extends QueryFilters
|
||||
|
||||
public function number($number = ''): Builder
|
||||
{
|
||||
return $this->builder->where('number', 'like', '%'.$number.'%');
|
||||
if (strlen($number) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->where('number', $number);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -122,10 +126,14 @@ class QuoteFilters extends QueryFilters
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort): Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
if($sort_col[0] == 'valid_until')
|
||||
$sort_col[0] = 'due_date';
|
||||
|
||||
|
@ -40,16 +40,29 @@ class RecurringExpenseFilters extends QueryFilters
|
||||
});
|
||||
}
|
||||
|
||||
public function number(string $number = ''): Builder
|
||||
{
|
||||
if (strlen($number) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->where('number', $number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort): Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
|
@ -83,16 +83,29 @@ class RecurringInvoiceFilters extends QueryFilters
|
||||
|
||||
}
|
||||
|
||||
public function number(string $number = ''): Builder
|
||||
{
|
||||
if (strlen($number) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->where('number', $number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort): Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
|
@ -39,16 +39,29 @@ class RecurringQuoteFilters extends QueryFilters
|
||||
});
|
||||
}
|
||||
|
||||
public function number(string $number = ''): Builder
|
||||
{
|
||||
if (strlen($number) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->where('number', $number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function sort(string $sort): Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
|
@ -42,10 +42,14 @@ class SubscriptionFilters extends QueryFilters
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort): Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
|
@ -18,18 +18,30 @@ use Illuminate\Database\Eloquent\Builder;
|
||||
*/
|
||||
class SystemLogFilters extends QueryFilters
|
||||
{
|
||||
public function type_id(int $type_id) :Builder
|
||||
public function type_id(string $type_id = ''): Builder
|
||||
{
|
||||
if (strlen($type_id) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->where('type_id', $type_id);
|
||||
}
|
||||
|
||||
public function category_id(int $category_id) :Builder
|
||||
public function category_id(string $category_id = ''): Builder
|
||||
{
|
||||
if (strlen($category_id) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->where('category_id', $category_id);
|
||||
}
|
||||
|
||||
public function event_id(int $event_id) :Builder
|
||||
public function event_id(string $event_id = ''): Builder
|
||||
{
|
||||
if (strlen($event_id) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->where('event_id', $event_id);
|
||||
}
|
||||
|
||||
@ -40,7 +52,7 @@ class SystemLogFilters extends QueryFilters
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
public function filter(string $filter = '') : Builder
|
||||
public function filter(string $filter = ''): Builder
|
||||
{
|
||||
if (strlen($filter) == 0) {
|
||||
return $this->builder;
|
||||
@ -55,10 +67,14 @@ class SystemLogFilters extends QueryFilters
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort) : Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
|
@ -82,16 +82,29 @@ class TaskFilters extends QueryFilters
|
||||
return $this->builder->where('project_id', $this->decodePrimaryKey($project));
|
||||
}
|
||||
|
||||
public function number(string $number = ''): Builder
|
||||
{
|
||||
if (strlen($number) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->where('number', $number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort): Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
|
@ -42,10 +42,14 @@ class TaskStatusFilters extends QueryFilters
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort): Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ class TaxRateFilters extends QueryFilters
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
public function filter(string $filter = '') : Builder
|
||||
public function filter(string $filter = ''): Builder
|
||||
{
|
||||
if (strlen($filter) == 0) {
|
||||
return $this->builder;
|
||||
@ -42,10 +42,14 @@ class TaxRateFilters extends QueryFilters
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort): Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
|
@ -42,10 +42,14 @@ class TokenFilters extends QueryFilters
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort): Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
|
@ -46,10 +46,14 @@ class UserFilters extends QueryFilters
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort): Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
@ -76,8 +80,9 @@ class UserFilters extends QueryFilters
|
||||
public function with(string $value = ''): Builder
|
||||
{
|
||||
|
||||
if(strlen($value) == 0)
|
||||
if(strlen($value) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder
|
||||
->orWhere($this->with_property, $value)
|
||||
|
@ -46,16 +46,29 @@ class VendorFilters extends QueryFilters
|
||||
});
|
||||
}
|
||||
|
||||
public function number(string $number = ''): Builder
|
||||
{
|
||||
if (strlen($number) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->where('number', $number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort): Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
|
@ -42,10 +42,14 @@ class WebhookFilters extends QueryFilters
|
||||
* @param string sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort): Builder
|
||||
public function sort(string $sort = ''): Builder
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,6 @@ class GmailTransport extends AbstractTransport
|
||||
/* Need to slow down */
|
||||
if($e->getCode() == '429') {
|
||||
|
||||
sleep(rand(5,10));
|
||||
nlog("429 google - retrying ");
|
||||
$service->users_messages->send('me', $body, []);
|
||||
|
||||
|
@ -291,11 +291,11 @@ class LoginController extends BaseController
|
||||
return response()->json(['message' => 'User found, but not attached to any companies, please see your administrator'], 400);
|
||||
}
|
||||
|
||||
$cu->first()->account->companies->each(function ($company) use ($cu, $request) {
|
||||
if ($company->tokens()->where('is_system', true)->count() == 0) {
|
||||
(new CreateCompanyToken($company, $cu->first()->user, $request->server('HTTP_USER_AGENT')))->handle();
|
||||
}
|
||||
});
|
||||
// $cu->first()->account->companies->each(function ($company) use ($cu, $request) {
|
||||
// if ($company->tokens()->where('is_system', true)->count() == 0) {
|
||||
// (new CreateCompanyToken($company, $cu->first()->user, $request->server('HTTP_USER_AGENT')))->handle();
|
||||
// }
|
||||
// });
|
||||
|
||||
if ($request->has('current_company') && $request->input('current_company') == 'true') {
|
||||
$cu->where('company_id', $company_token->company_id);
|
||||
@ -480,13 +480,13 @@ class LoginController extends BaseController
|
||||
return $cu;
|
||||
}
|
||||
|
||||
if (auth()->user()->company_users()->count() != auth()->user()->tokens()->distinct('company_id')->count()) {
|
||||
auth()->user()->companies->each(function ($company) {
|
||||
if (!CompanyToken::where('user_id', auth()->user()->id)->where('company_id', $company->id)->exists()) {
|
||||
(new CreateCompanyToken($company, auth()->user(), 'Google_O_Auth'))->handle();
|
||||
}
|
||||
});
|
||||
}
|
||||
// if (auth()->user()->company_users()->count() != auth()->user()->tokens()->distinct('company_id')->count()) {
|
||||
// auth()->user()->companies->each(function ($company) {
|
||||
// if (!CompanyToken::where('user_id', auth()->user()->id)->where('company_id', $company->id)->exists()) {
|
||||
// (new CreateCompanyToken($company, auth()->user(), 'Google_O_Auth'))->handle();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
$truth->setCompanyToken(CompanyToken::where('user_id', auth()->user()->id)->where('company_id', $set_company->id)->first());
|
||||
|
||||
|
@ -267,7 +267,7 @@ class BaseController extends Controller
|
||||
|
||||
$updated_at = request()->has('updated_at') ? request()->input('updated_at') : 0;
|
||||
|
||||
if ($user->getCompany()->is_large && $updated_at == 0 && $this->complexPermissionsUser()) {
|
||||
if ($user->getCompany()->is_large && $updated_at == 0) {
|
||||
$updated_at = time();
|
||||
}
|
||||
|
||||
@ -633,7 +633,7 @@ class BaseController extends Controller
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
if ($user->getCompany()->is_large || $this->complexPermissionsUser()) {
|
||||
if ($user->getCompany()->is_large) {
|
||||
$this->manager->parseIncludes($this->mini_load);
|
||||
|
||||
return $this->miniLoadResponse($query);
|
||||
@ -859,7 +859,7 @@ class BaseController extends Controller
|
||||
'company.bank_transactions'=> function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at);
|
||||
|
||||
if (! $user->hasPermission('bank_transactions')) {
|
||||
if (! $user->hasPermission('bank_transaction')) {
|
||||
$query->where('bank_transactions.user_id', $user->id);
|
||||
}
|
||||
},
|
||||
|
@ -110,7 +110,6 @@ class EntityViewController extends Controller
|
||||
$key = $entity_type.'_id';
|
||||
|
||||
$invitation = $invitation_entity::where('key', $invitation_key)->firstOrFail();
|
||||
// $invitation = $invitation_entity::whereRaw('BINARY `key`= ?', [$invitation_key])->firstOrFail();
|
||||
|
||||
$contact = $invitation->contact;
|
||||
|
||||
@ -141,7 +140,7 @@ class EntityViewController extends Controller
|
||||
$query->where('is_deleted', 0);
|
||||
})
|
||||
->with('contact.client')
|
||||
->first();
|
||||
->firstOrFail();
|
||||
|
||||
$contact = $invitation->contact;
|
||||
$contact->password = Hash::make($request->password);
|
||||
|
@ -150,11 +150,17 @@ class PaymentController extends Controller
|
||||
|
||||
$invoices = Invoice::whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id')));
|
||||
|
||||
$invoices->each(function ($i){
|
||||
$i->is_proforma = false;
|
||||
$i->saveQuietly();
|
||||
});
|
||||
|
||||
event('eloquent.created: App\Models\Payment', $payment);
|
||||
|
||||
if($invoices->sum('balance') > 0){
|
||||
|
||||
$invoice = $invoices->first();
|
||||
$invoice->service()->touchPdf(true);
|
||||
|
||||
return redirect()->route('client.invoice.show', ['invoice' => $invoice->hashed_id, 'hash' => $request->input('hash')]);
|
||||
}
|
||||
|
@ -81,6 +81,7 @@ class QuoteController extends Controller
|
||||
public function bulk(ProcessQuotesInBulkRequest $request)
|
||||
{
|
||||
$transformed_ids = $this->transformKeys($request->quotes);
|
||||
nlog(request()->all());
|
||||
|
||||
if ($request->action == 'download') {
|
||||
return $this->downloadQuotes((array) $transformed_ids);
|
||||
@ -180,6 +181,14 @@ class QuoteController extends Controller
|
||||
|
||||
if ($process) {
|
||||
foreach ($quotes as $quote) {
|
||||
|
||||
|
||||
if(request()->has('user_input') && strlen(request()->input('user_input')) > 2) {
|
||||
|
||||
$quote->public_notes .= $quote->public_notes . "\n" . request()->input('user_input');
|
||||
$quote->saveQuietly();
|
||||
}
|
||||
|
||||
$quote->service()->approve(auth()->user())->save();
|
||||
|
||||
if (request()->has('signature') && ! is_null(request()->signature) && ! empty(request()->signature)) {
|
||||
|
@ -55,4 +55,9 @@ class SubscriptionPlanSwitchController extends Controller
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function not_availabe()
|
||||
{
|
||||
abort(404, 'ewwo');
|
||||
}
|
||||
}
|
||||
|
@ -494,7 +494,7 @@ class CompanyController extends BaseController
|
||||
$account->delete();
|
||||
|
||||
if (Ninja::isHosted()) {
|
||||
\Modules\Admin\Jobs\Account\NinjaDeletedAccount::dispatch($account_key, $request->all());
|
||||
\Modules\Admin\Jobs\Account\NinjaDeletedAccount::dispatch($account_key, $request->all(), auth()->user()->email);
|
||||
}
|
||||
|
||||
LightLogs::create(new AccountDeleted())
|
||||
|
@ -642,10 +642,57 @@ class CreditController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/api/v1/credit/{invitation_key}/download",
|
||||
* operationId="downloadCredit",
|
||||
* tags={"quotes"},
|
||||
* summary="Download a specific credit by invitation key",
|
||||
* description="Downloads a specific quote",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||
* @OA\Parameter(
|
||||
* name="invitation_key",
|
||||
* in="path",
|
||||
* description="The Credit Invitation Key",
|
||||
* example="D2J234DFA",
|
||||
* required=true,
|
||||
* @OA\Schema(
|
||||
* type="string",
|
||||
* format="string",
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="Returns the credit pdf",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
*
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
* @param $invitation_key
|
||||
* @return \Symfony\Component\HttpFoundation\BinaryFileResponse
|
||||
*/
|
||||
public function downloadPdf($invitation_key)
|
||||
{
|
||||
$invitation = $this->credit_repository->getInvitationByKey($invitation_key);
|
||||
|
||||
if (! $invitation) {
|
||||
return response()->json(['message' => 'no record found'], 400);
|
||||
}
|
||||
|
||||
$credit = $invitation->credit;
|
||||
|
||||
$file = $credit->service()->getCreditPdf($invitation);
|
||||
|
@ -277,6 +277,8 @@ class ExpenseController extends BaseController
|
||||
|
||||
event(new ExpenseWasUpdated($expense, $expense->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
event('eloquent.updated: App\Models\Expense', $expense);
|
||||
|
||||
return $this->itemResponse($expense->fresh());
|
||||
}
|
||||
|
||||
@ -369,6 +371,8 @@ class ExpenseController extends BaseController
|
||||
|
||||
event(new ExpenseWasCreated($expense, $expense->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
event('eloquent.created: App\Models\Expense', $expense);
|
||||
|
||||
return $this->itemResponse($expense);
|
||||
}
|
||||
|
||||
|
@ -422,16 +422,6 @@ class InvoiceController extends BaseController
|
||||
|
||||
event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
// $transaction = [
|
||||
// 'invoice' => $invoice->transaction_event(),
|
||||
// 'payment' => [],
|
||||
// 'client' => $invoice->client->transaction_event(),
|
||||
// 'credit' => [],
|
||||
// 'metadata' => [],
|
||||
// ];
|
||||
|
||||
// TransactionLog::dispatch(TransactionEvent::INVOICE_UPDATED, $transaction, $invoice->company->db);
|
||||
|
||||
return $this->itemResponse($invoice);
|
||||
}
|
||||
|
||||
|
@ -205,6 +205,8 @@ class PaymentController extends BaseController
|
||||
{
|
||||
$payment = $this->payment_repo->save($request->all(), PaymentFactory::create(auth()->user()->company()->id, auth()->user()->id));
|
||||
|
||||
event('eloquent.created: App\Models\Payment', $payment);
|
||||
|
||||
return $this->itemResponse($payment);
|
||||
}
|
||||
|
||||
@ -378,6 +380,8 @@ class PaymentController extends BaseController
|
||||
|
||||
event(new PaymentWasUpdated($payment, $payment->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
event('eloquent.updated: App\Models\Payment', $payment);
|
||||
|
||||
return $this->itemResponse($payment);
|
||||
}
|
||||
|
||||
|
@ -262,12 +262,14 @@ class ProjectController extends BaseController
|
||||
|
||||
$project->fill($request->all());
|
||||
$project->number = empty($project->number) ? $this->getNextProjectNumber($project) : $project->number;
|
||||
$project->save();
|
||||
$project->saveQuietly();
|
||||
|
||||
if ($request->has('documents')) {
|
||||
$this->saveDocuments($request->input('documents'), $project);
|
||||
}
|
||||
|
||||
event('eloquent.updated: App\Models\Project', $project);
|
||||
|
||||
return $this->itemResponse($project->fresh());
|
||||
}
|
||||
|
||||
@ -358,17 +360,19 @@ class ProjectController extends BaseController
|
||||
{
|
||||
$project = ProjectFactory::create(auth()->user()->company()->id, auth()->user()->id);
|
||||
$project->fill($request->all());
|
||||
$project->save();
|
||||
$project->saveQuietly();
|
||||
|
||||
if (empty($project->number)) {
|
||||
$project->number = $this->getNextProjectNumber($project);
|
||||
$project->save();
|
||||
$project->saveQuietly();
|
||||
}
|
||||
|
||||
if ($request->has('documents')) {
|
||||
$this->saveDocuments($request->input('documents'), $project);
|
||||
}
|
||||
|
||||
event('eloquent.created: App\Models\Project', $project);
|
||||
|
||||
return $this->itemResponse($project->fresh());
|
||||
}
|
||||
|
||||
|
@ -762,4 +762,74 @@ class PurchaseOrderController extends BaseController
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/api/v1/purchase_order/{invitation_key}/download",
|
||||
* operationId="downloadPurchaseOrder",
|
||||
* tags={"purchase_orders"},
|
||||
* summary="Download a specific purchase order by invitation key",
|
||||
* description="Downloads a specific purchase order",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||
* @OA\Parameter(
|
||||
* name="invitation_key",
|
||||
* in="path",
|
||||
* description="The Purchase Order Invitation Key",
|
||||
* example="D2J234DFA",
|
||||
* required=true,
|
||||
* @OA\Schema(
|
||||
* type="string",
|
||||
* format="string",
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="Returns the Purchase Order pdf",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
*
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
* @param $invitation_key
|
||||
* @return \Symfony\Component\HttpFoundation\BinaryFileResponse
|
||||
*/
|
||||
public function downloadPdf($invitation_key)
|
||||
{
|
||||
$invitation = $this->purchase_order_repository->getInvitationByKey($invitation_key);
|
||||
|
||||
if (! $invitation) {
|
||||
return response()->json(['message' => 'no record found'], 400);
|
||||
}
|
||||
|
||||
$purchase_order = $invitation->purchase_order;
|
||||
|
||||
$file = $purchase_order->service()->getPurchaseOrderPdf();
|
||||
|
||||
$headers = ['Content-Type' => 'application/pdf'];
|
||||
|
||||
if (request()->input('inline') == 'true') {
|
||||
$headers = array_merge($headers, ['Content-Disposition' => 'inline']);
|
||||
}
|
||||
|
||||
return response()->streamDownload(function () use ($file) {
|
||||
echo Storage::get($file);
|
||||
}, basename($file), $headers);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -779,9 +779,58 @@ class QuoteController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/api/v1/quote/{invitation_key}/download",
|
||||
* operationId="downloadQuote",
|
||||
* tags={"quotes"},
|
||||
* summary="Download a specific quote by invitation key",
|
||||
* description="Downloads a specific quote",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||
* @OA\Parameter(
|
||||
* name="invitation_key",
|
||||
* in="path",
|
||||
* description="The Quote Invitation Key",
|
||||
* example="D2J234DFA",
|
||||
* required=true,
|
||||
* @OA\Schema(
|
||||
* type="string",
|
||||
* format="string",
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="Returns the quote pdf",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
*
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
* @param $invitation_key
|
||||
* @return \Symfony\Component\HttpFoundation\BinaryFileResponse
|
||||
*/
|
||||
|
||||
public function downloadPdf($invitation_key)
|
||||
{
|
||||
$invitation = $this->quote_repo->getInvitationByKey($invitation_key);
|
||||
|
||||
if (! $invitation) {
|
||||
return response()->json(['message' => 'no record found'], 400);
|
||||
}
|
||||
|
||||
$contact = $invitation->contact;
|
||||
$quote = $invitation->quote;
|
||||
|
||||
|
@ -283,6 +283,8 @@ class TaskController extends BaseController
|
||||
|
||||
event(new TaskWasUpdated($task, $task->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
event('eloquent.updated: App\Models\Task', $task);
|
||||
|
||||
return $this->itemResponse($task->fresh());
|
||||
}
|
||||
|
||||
@ -376,6 +378,9 @@ class TaskController extends BaseController
|
||||
|
||||
event(new TaskWasCreated($task, $task->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
event('eloquent.created: App\Models\Task', $task);
|
||||
|
||||
|
||||
return $this->itemResponse($task);
|
||||
}
|
||||
|
||||
|
@ -276,6 +276,8 @@ class VendorController extends BaseController
|
||||
|
||||
event(new VendorWasUpdated($vendor, $vendor->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
event('eloquent.updated: App\Models\Vendor', $vendor);
|
||||
|
||||
return $this->itemResponse($vendor->fresh());
|
||||
}
|
||||
|
||||
@ -372,6 +374,8 @@ class VendorController extends BaseController
|
||||
|
||||
event(new VendorWasCreated($vendor, $vendor->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
event('eloquent.created: App\Models\Vendor', $vendor);
|
||||
|
||||
return $this->itemResponse($vendor);
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,7 @@ class InvoicesTable extends Component
|
||||
$query = Invoice::query()
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', false)
|
||||
->where('is_proforma', false)
|
||||
->with('client.gateway_tokens', 'client.contacts')
|
||||
->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc');
|
||||
|
||||
|
@ -15,12 +15,35 @@ namespace App\Http\Livewire;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\CompanyGateway;
|
||||
use App\Models\Invoice;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Str;
|
||||
use Livewire\Component;
|
||||
|
||||
class RequiredClientInfo extends Component
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $show_terms = false;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $invoice;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $terms_accepted = true;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $fields = [];
|
||||
|
||||
/**
|
||||
@ -28,6 +51,9 @@ class RequiredClientInfo extends Component
|
||||
*/
|
||||
public $contact;
|
||||
|
||||
/**
|
||||
* @var Client
|
||||
*/
|
||||
public $client;
|
||||
|
||||
/**
|
||||
@ -60,6 +86,11 @@ class RequiredClientInfo extends Component
|
||||
'client_shipping_postal_code' => 'shipping_postal_code',
|
||||
'client_shipping_country_id' => 'shipping_country_id',
|
||||
|
||||
'client_custom_value1' => 'custom_value1',
|
||||
'client_custom_value2' => 'custom_value2',
|
||||
'client_custom_value3' => 'custom_value3',
|
||||
'client_custom_value4' => 'custom_value4',
|
||||
|
||||
'contact_first_name' => 'first_name',
|
||||
'contact_last_name' => 'last_name',
|
||||
'contact_email' => 'email',
|
||||
@ -100,6 +131,10 @@ class RequiredClientInfo extends Component
|
||||
'client.name' => '',
|
||||
'client.website' => '',
|
||||
'client.phone' => '',
|
||||
'client.custom_value1' => '',
|
||||
'client.custom_value2' => '',
|
||||
'client.custom_value3' => '',
|
||||
'client.custom_value4' => '',
|
||||
];
|
||||
|
||||
public $show_form = false;
|
||||
@ -114,9 +149,28 @@ class RequiredClientInfo extends Component
|
||||
|
||||
$this->client = $this->contact->client;
|
||||
|
||||
count($this->fields) > 0
|
||||
if($this->company->settings->show_accept_invoice_terms && request()->query('hash'))
|
||||
{
|
||||
$this->show_terms = true;
|
||||
$this->terms_accepted = false;
|
||||
$this->show_form = true;
|
||||
|
||||
$hash = Cache::get(request()->input('hash'));
|
||||
|
||||
$this->invoice = Invoice::find($this->decodePrimaryKey($hash['invoice_id']));
|
||||
|
||||
}
|
||||
|
||||
count($this->fields) > 0 || $this->show_terms
|
||||
? $this->checkFields()
|
||||
: $this->show_form = false;
|
||||
|
||||
}
|
||||
|
||||
public function toggleTermsAccepted()
|
||||
{
|
||||
$this->terms_accepted = !$this->terms_accepted;
|
||||
|
||||
}
|
||||
|
||||
public function handleSubmit(array $data): bool
|
||||
@ -155,7 +209,7 @@ class RequiredClientInfo extends Component
|
||||
|
||||
private function updateClientDetails(array $data): bool
|
||||
{
|
||||
nlog($this->company->id);
|
||||
|
||||
$client = [];
|
||||
$contact = [];
|
||||
|
||||
@ -215,6 +269,7 @@ class RequiredClientInfo extends Component
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function showCopyBillingCheckbox(): bool
|
||||
|
@ -23,7 +23,7 @@ class ShowActivityRequest extends Request
|
||||
*/
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->isAdmin();
|
||||
// return auth()->user()->can('view', Activity::class);
|
||||
// return auth()->user()->isAdmin();
|
||||
return auth()->user()->can('view', Activity::class);
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Http\Requests\ClientPortal\Subscriptions;
|
||||
|
||||
use App\Models\Subscription;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Exceptions\Ninja\ClientPortalAuthorizationException;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ShowPlanSwitchRequest extends FormRequest
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
@ -31,4 +38,11 @@ class ShowPlanSwitchRequest extends FormRequest
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
protected function failedAuthorization()
|
||||
{
|
||||
|
||||
throw new ClientPortalAuthorizationException('Unable to change plans due to a restriction on this product.', 400);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -227,6 +227,8 @@ class BaseImport
|
||||
];
|
||||
|
||||
nlog("Ingest {$ex->getMessage()}");
|
||||
nlog($record);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -368,7 +370,7 @@ class BaseImport
|
||||
$payment_data['invoices'] = [
|
||||
[
|
||||
'invoice_id' => $invoice->id,
|
||||
'amount' => $payment_data['amount'] ?? null,
|
||||
'amount' => min($invoice->amount, $payment_data['amount']) ?? null,
|
||||
],
|
||||
];
|
||||
|
||||
|
@ -68,6 +68,11 @@ class BaseTransformer
|
||||
|
||||
}
|
||||
|
||||
public function getInvoiceTypeId($data, $field)
|
||||
{
|
||||
return isset($data[$field]) && $data[$field] ? (string)$data[$field] : '1';
|
||||
}
|
||||
|
||||
public function getNumber($data, $field)
|
||||
{
|
||||
return (isset($data->$field) && $data->$field) ? (int)$data->$field : 0;
|
||||
|
@ -222,9 +222,10 @@ class InvoiceTransformer extends BaseTransformer
|
||||
$record,
|
||||
'item.custom_value4'
|
||||
),
|
||||
'type_id' => '1', //$this->getInvoiceTypeId( $record, 'item.type_id' ),
|
||||
'type_id' => $this->getInvoiceTypeId( $record, 'item.type_id' ),
|
||||
];
|
||||
}
|
||||
|
||||
$transformed['line_items'] = $line_items;
|
||||
|
||||
return $transformed;
|
||||
|
@ -52,17 +52,6 @@ class VendorTransformer extends BaseTransformer
|
||||
'custom_value2' => $this->getString($data, 'vendor.custom_value2'),
|
||||
'custom_value3' => $this->getString($data, 'vendor.custom_value3'),
|
||||
'custom_value4' => $this->getString($data, 'vendor.custom_value4'),
|
||||
// 'vendor_contacts' => [
|
||||
// [
|
||||
// 'first_name' => $this->getString(
|
||||
// $data,
|
||||
// 'vendor.first_name'
|
||||
// ),
|
||||
// 'last_name' => $this->getString($data, 'vendor.last_name'),
|
||||
// 'email' => $this->getString($data, 'vendor.email'),
|
||||
// 'phone' => $this->getString($data, 'vendor.phone'),
|
||||
// ],
|
||||
// ],
|
||||
'contacts' => [
|
||||
[
|
||||
'first_name' => $this->getString(
|
||||
@ -70,7 +59,7 @@ class VendorTransformer extends BaseTransformer
|
||||
'contact.first_name'
|
||||
),
|
||||
'last_name' => $this->getString($data, 'contact.last_name'),
|
||||
'email' => $this->getString($data, 'contact.email'),
|
||||
'email' => strlen($this->getString($data, 'contact.email')) > 1 ? $this->getString($data, 'contact.email') : $this->getString($data, 'vendor.email'),
|
||||
'phone' => $this->getString($data, 'contact.phone'),
|
||||
'custom_value1' => $this->getString(
|
||||
$data,
|
||||
|
@ -115,6 +115,7 @@ class CreateAccount
|
||||
|
||||
$spafe62e = isset($this->request['token_name']) ? $this->request['token_name'] : request()->server('HTTP_USER_AGENT');
|
||||
$sp2d97e8 = (new CreateCompanyToken($sp035a66, $spaa9f78, $spafe62e))->handle();
|
||||
|
||||
if ($spaa9f78) {
|
||||
event(new AccountCreated($spaa9f78, $sp035a66, Ninja::eventVars()));
|
||||
}
|
||||
|
@ -160,9 +160,5 @@ class AdjustProductInventory implements ShouldQueue
|
||||
|
||||
});
|
||||
|
||||
// $nmo->to_user = $this->company->owner();
|
||||
|
||||
// NinjaMailerJob::dispatch($nmo);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ class NinjaMailerJob implements ShouldQueue
|
||||
|
||||
public function backoff()
|
||||
{
|
||||
return [30, 60, 180, 240];
|
||||
return [5, 10, 30, 240];
|
||||
}
|
||||
|
||||
public function handle()
|
||||
@ -176,19 +176,15 @@ class NinjaMailerJob implements ShouldQueue
|
||||
* this merges a text string with a json object
|
||||
* need to harvest the ->Message property using the following
|
||||
*/
|
||||
if($e instanceof ClientException)
|
||||
if(stripos($e->getMessage(), 'code 406') || stripos($e->getMessage(), 'code 300') || stripos($e->getMessage(), 'code 413'))
|
||||
{
|
||||
|
||||
$response = $e->getResponse();
|
||||
$message_body = json_decode($response->getBody()->getContents());
|
||||
$message = "Either Attachment too large, or recipient has been suppressed.";
|
||||
|
||||
if($message_body && property_exists($message_body, 'Message')){
|
||||
$message = $message_body->Message;
|
||||
}
|
||||
|
||||
/*Do not retry if this is a postmark specific issue such as invalid recipient. */
|
||||
$this->fail();
|
||||
$this->logMailError($e->getMessage(), $this->company->clients()->first());
|
||||
$this->cleanUpMailers();
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
@ -382,12 +378,14 @@ class NinjaMailerJob implements ShouldQueue
|
||||
return $this->setMailDriver();
|
||||
}
|
||||
|
||||
|
||||
$user = $this->resolveSendingUser();
|
||||
|
||||
$sending_email = (isset($this->nmo->settings->custom_sending_email) && stripos($this->nmo->settings->custom_sending_email, "@")) ? $this->nmo->settings->custom_sending_email : $user->email;
|
||||
$sending_user = (isset($this->nmo->settings->email_from_name) && strlen($this->nmo->settings->email_from_name) > 2) ? $this->nmo->settings->email_from_name : $user->name();
|
||||
|
||||
$this->nmo
|
||||
->mailable
|
||||
->from($user->email, $user->name());
|
||||
->from($sending_email, $sending_user);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -406,9 +404,12 @@ class NinjaMailerJob implements ShouldQueue
|
||||
|
||||
$user = $this->resolveSendingUser();
|
||||
|
||||
$sending_email = (isset($this->nmo->settings->custom_sending_email) && stripos($this->nmo->settings->custom_sending_email, "@")) ? $this->nmo->settings->custom_sending_email : $user->email;
|
||||
$sending_user = (isset($this->nmo->settings->email_from_name) && strlen($this->nmo->settings->email_from_name) > 2) ? $this->nmo->settings->email_from_name : $user->name();
|
||||
|
||||
$this->nmo
|
||||
->mailable
|
||||
->from($user->email, $user->name());
|
||||
->from($sending_email, $sending_user);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -445,7 +446,6 @@ class NinjaMailerJob implements ShouldQueue
|
||||
$message->getHeaders()->addTextHeader('gmailtoken', $token);
|
||||
});
|
||||
|
||||
sleep(rand(1,3));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -472,7 +472,6 @@ class NinjaMailerJob implements ShouldQueue
|
||||
|
||||
$google->getClient()->setAccessToken(json_encode($user->oauth_user_token));
|
||||
|
||||
sleep(rand(1,6));
|
||||
}
|
||||
catch(\Exception $e) {
|
||||
$this->logMailError('Gmail Token Invalid', $this->company->clients()->first());
|
||||
@ -649,8 +648,9 @@ class NinjaMailerJob implements ShouldQueue
|
||||
|
||||
public function failed($exception = null)
|
||||
{
|
||||
if($exception)
|
||||
nlog($exception->getMessage());
|
||||
|
||||
config(['queue.failed.driver' => null]);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -12,6 +12,7 @@
|
||||
namespace App\Jobs\Ninja;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Account;
|
||||
use App\Models\Client;
|
||||
use App\Models\Company;
|
||||
use Illuminate\Bus\Queueable;
|
||||
@ -43,7 +44,7 @@ class CompanySizeCheck implements ShouldQueue
|
||||
{
|
||||
if (! config('ninja.db.multi_db_enabled')) {
|
||||
|
||||
Company::where('is_large', false)->withCount(['invoices', 'clients', 'products'])->cursor()->each(function ($company) {
|
||||
Company::where('is_large', false)->withCount(['invoices', 'clients', 'products', 'quotes'])->cursor()->each(function ($company) {
|
||||
if ($company->invoices_count > 500 || $company->products_count > 500 || $company->clients_count > 500) {
|
||||
nlog("Marking company {$company->id} as large");
|
||||
|
||||
@ -62,6 +63,22 @@ class CompanySizeCheck implements ShouldQueue
|
||||
|
||||
});
|
||||
|
||||
/* Ensures lower permissioned users return the correct dataset and refresh responses */
|
||||
Account::whereHas('companies', function ($query){
|
||||
$query->where('is_large',0);
|
||||
})
|
||||
->whereHas('company_users', function ($query){
|
||||
|
||||
$query->where('is_admin', 0);
|
||||
|
||||
})
|
||||
->cursor()->each(function ($account){
|
||||
|
||||
$account->companies()->update(['is_large' => true]);
|
||||
|
||||
});
|
||||
|
||||
|
||||
} else {
|
||||
//multiDB environment, need to
|
||||
foreach (MultiDB::$dbs as $db) {
|
||||
@ -69,8 +86,8 @@ class CompanySizeCheck implements ShouldQueue
|
||||
|
||||
nlog("Company size check db {$db}");
|
||||
|
||||
Company::where('is_large', false)->withCount(['invoices', 'clients', 'products'])->cursor()->each(function ($company) {
|
||||
if ($company->invoices_count > 500 || $company->products_count > 500 || $company->clients_count > 500) {
|
||||
Company::where('is_large', false)->withCount(['invoices', 'clients', 'products', 'quotes'])->cursor()->each(function ($company) {
|
||||
if ($company->invoices_count > 500 || $company->products_count > 500 || $company->clients_count > 500 || $company->quotes_count > 500) {
|
||||
nlog("Marking company {$company->id} as large");
|
||||
|
||||
$company->account->companies()->update(['is_large' => true]);
|
||||
@ -88,6 +105,22 @@ class CompanySizeCheck implements ShouldQueue
|
||||
|
||||
});
|
||||
|
||||
Account::where('plan', 'enterprise')
|
||||
->whereDate('plan_expires', '>', now())
|
||||
->whereHas('companies', function ($query){
|
||||
$query->where('is_large',0);
|
||||
})
|
||||
->whereHas('company_users', function ($query){
|
||||
|
||||
$query->where('is_admin', 0);
|
||||
|
||||
})
|
||||
->cursor()->each(function ($account){
|
||||
|
||||
$account->companies()->update(['is_large' => true]);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ class UpdateOrCreateProduct implements ShouldQueue
|
||||
$product->company_id = $this->invoice->company_id;
|
||||
$product->project_id = $this->invoice->project_id;
|
||||
$product->vendor_id = $this->invoice->vendor_id;
|
||||
$product->save();
|
||||
$product->saveQuietly();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,11 @@ class ZipQuotes implements ShouldQueue
|
||||
$path = $this->quotes->first()->client->quote_filepath($invitation);
|
||||
|
||||
$this->quotes->each(function ($quote) {
|
||||
|
||||
$quote->service()->createInvitations();
|
||||
|
||||
(new CreateEntityPdf($quote->invitations()->first()))->handle();
|
||||
|
||||
});
|
||||
|
||||
try {
|
||||
|
@ -79,7 +79,6 @@ class CreateUser
|
||||
'is_locked' => 0,
|
||||
'permissions' => '',
|
||||
'notifications' => CompanySettings::notificationDefaults(),
|
||||
//'settings' => DefaultSettings::userSettings(),
|
||||
'settings' => null,
|
||||
]);
|
||||
|
||||
|
@ -99,6 +99,6 @@ class SystemLogger implements ShouldQueue
|
||||
|
||||
public function failed($e)
|
||||
{
|
||||
nlog($e->getMessage());
|
||||
config(['queue.failed.driver' => null]);
|
||||
}
|
||||
}
|
||||
|
@ -11,53 +11,34 @@
|
||||
|
||||
namespace App\Jobs\Util;
|
||||
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
use App\Jobs\Util\WebhookSingle;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Client as ClientModel;
|
||||
use App\Models\SystemLog;
|
||||
use App\Models\Company;
|
||||
use App\Models\Webhook;
|
||||
use App\Transformers\ArraySerializer;
|
||||
use App\Utils\Ninja;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\RequestOptions;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Resource\Item;
|
||||
|
||||
|
||||
class WebhookHandler implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
private $entity;
|
||||
|
||||
private $event_id;
|
||||
|
||||
private $company;
|
||||
|
||||
public $tries = 1; //number of retries
|
||||
|
||||
public $deleteWhenMissingModels = true;
|
||||
|
||||
private string $includes;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param $event_id
|
||||
* @param $entity
|
||||
*/
|
||||
public function __construct($event_id, $entity, $company, $includes = '')
|
||||
{
|
||||
$this->event_id = $event_id;
|
||||
$this->entity = $entity;
|
||||
$this->company = $company;
|
||||
$this->includes = $includes;
|
||||
}
|
||||
public function __construct(private int $event_id, private $entity, private Company $company, private string $includes = ''){}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
@ -74,12 +55,10 @@ class WebhookHandler implements ShouldQueue
|
||||
return true;
|
||||
}
|
||||
|
||||
$subscriptions = Webhook::where('company_id', $this->company->id)
|
||||
->where('event_id', $this->event_id)
|
||||
->cursor()
|
||||
->each(function ($subscription) {
|
||||
|
||||
// $this->process($subscription);
|
||||
Webhook::where('company_id', $this->company->id)
|
||||
->where('event_id', $this->event_id)
|
||||
->cursor()
|
||||
->each(function ($subscription) {
|
||||
|
||||
WebhookSingle::dispatch($subscription->id, $this->entity, $this->company->db, $this->includes);
|
||||
|
||||
@ -87,10 +66,8 @@ class WebhookHandler implements ShouldQueue
|
||||
|
||||
}
|
||||
|
||||
public function failed($exception)
|
||||
public function failed($exception = null)
|
||||
{
|
||||
|
||||
nlog(print_r($exception->getMessage(), 1));
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -15,11 +15,15 @@ use App\Jobs\Util\SystemLogger;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Client as ClientModel;
|
||||
use App\Models\Company;
|
||||
use App\Models\Product;
|
||||
use App\Models\SystemLog;
|
||||
use App\Models\Vendor;
|
||||
use App\Models\Webhook;
|
||||
use App\Transformers\ArraySerializer;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\BadResponseException;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use GuzzleHttp\Exception\ServerException;
|
||||
use GuzzleHttp\RequestOptions;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
@ -28,8 +32,6 @@ use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Resource\Item;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use GuzzleHttp\Exception\ServerException;
|
||||
|
||||
class WebhookSingle implements ShouldQueue
|
||||
{
|
||||
@ -79,8 +81,14 @@ class WebhookSingle implements ShouldQueue
|
||||
|
||||
$subscription = Webhook::with('company')->find($this->subscription_id);
|
||||
|
||||
if($subscription)
|
||||
nlog("firing event ID {$subscription->event_id}");
|
||||
|
||||
if(!$subscription){
|
||||
$this->fail();
|
||||
|
||||
nlog("failed to fire event, could not find webhook ID {$this->subscription_id}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -235,19 +243,27 @@ class WebhookSingle implements ShouldQueue
|
||||
}
|
||||
|
||||
private function resolveClient()
|
||||
{
|
||||
{ nlog(get_class($this->entity));
|
||||
|
||||
//make sure it isn't an instance of the Client Model
|
||||
if ((! $this->entity instanceof ClientModel) && $this->entity->client()->exists()) {
|
||||
if (!$this->entity instanceof \App\Models\Client &&
|
||||
!$this->entity instanceof \App\Models\Vendor &&
|
||||
!$this->entity instanceof \App\Models\Product &&
|
||||
!$this->entity instanceof \App\Models\PurchaseOrder &&
|
||||
$this->entity->client()->exists()) {
|
||||
|
||||
return $this->entity->client;
|
||||
|
||||
}
|
||||
|
||||
return $this->company->clients()->first();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function failed($exception)
|
||||
public function failed($exception = null)
|
||||
{
|
||||
|
||||
nlog(print_r($exception->getMessage(), 1));
|
||||
config(['queue.failed.driver' => null]);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -51,5 +51,6 @@ class RestoreClientActivity implements ShouldQueue
|
||||
$fields->activity_type_id = Activity::RESTORE_CLIENT;
|
||||
|
||||
$this->activity_repo->save($fields, $event->client, $event->event_vars);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -38,21 +38,18 @@ class CreateInvoicePdf implements ShouldQueue
|
||||
|
||||
if (isset($event->invoice)) {
|
||||
$event->invoice->invitations->each(function ($invitation) {
|
||||
// CreateEntityPdf::dispatch($invitation->load('invoice', 'contact.client.company'));
|
||||
(new CreateEntityPdf($invitation->load('invoice', 'contact.client.company')))->handle();
|
||||
});
|
||||
}
|
||||
|
||||
if (isset($event->quote)) {
|
||||
$event->quote->invitations->each(function ($invitation) {
|
||||
// CreateEntityPdf::dispatch($invitation->load('quote', 'contact.client.company'));
|
||||
(new CreateEntityPdf($invitation->load('quote', 'contact.client.company')))->handle();
|
||||
});
|
||||
}
|
||||
|
||||
if (isset($event->credit)) {
|
||||
$event->credit->invitations->each(function ($invitation) {
|
||||
// CreateEntityPdf::dispatch($invitation->load('credit', 'contact.client.company'));
|
||||
(new CreateEntityPdf($invitation->load('credit', 'contact.client.company')))->handle();
|
||||
|
||||
});
|
||||
|
@ -13,6 +13,8 @@ namespace App\Listeners\Subscription;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Account;
|
||||
use App\Models\Company;
|
||||
use App\Notifications\Ninja\RenewalFailureNotification;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Imdhemy\Purchases\Events\AppStore\DidRenew;
|
||||
|
||||
@ -38,10 +40,18 @@ class AppStoreRenewSubscription implements ShouldQueue
|
||||
|
||||
$inapp_transaction_id = $event->getSubscriptionId(); //$subscription_id
|
||||
|
||||
nlog("inapp upgrade processing for = {$inapp_transaction_id}");
|
||||
|
||||
MultiDB::findAndSetDbByInappTransactionId($inapp_transaction_id);
|
||||
|
||||
$account = Account::where('inapp_transaction_id', $inapp_transaction_id)->first();
|
||||
|
||||
if(!$account) {
|
||||
$ninja_company = Company::on('db-ninja-01')->find(config('ninja.ninja_default_company_id'));
|
||||
$ninja_company->notification(new RenewalFailureNotification("{$inapp_transaction_id}"))->ninja();
|
||||
return;
|
||||
}
|
||||
|
||||
if($account->plan_term == 'month')
|
||||
$account->plan_expires = now()->addMonth();
|
||||
elseif($account->plan_term == 'year')
|
||||
|
@ -27,6 +27,8 @@ class BaseEmailEngine implements EngineInterface
|
||||
|
||||
public $attachments = [];
|
||||
|
||||
public $attachment_links = [];
|
||||
|
||||
public $link;
|
||||
|
||||
public $text;
|
||||
@ -37,6 +39,8 @@ class BaseEmailEngine implements EngineInterface
|
||||
|
||||
public $text_footer;
|
||||
|
||||
public int $max_attachment_size = 3000000;
|
||||
|
||||
public function setFooter($footer)
|
||||
{
|
||||
$this->footer = $footer;
|
||||
@ -95,6 +99,14 @@ class BaseEmailEngine implements EngineInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setAttachmentLinks($links)
|
||||
{
|
||||
$this->attachment_links = array_merge($this->getAttachmentLinks(), $links);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function setViewLink($link)
|
||||
{
|
||||
$this->link = $link;
|
||||
@ -131,6 +143,11 @@ class BaseEmailEngine implements EngineInterface
|
||||
return $this->attachments;
|
||||
}
|
||||
|
||||
public function getAttachmentLinks()
|
||||
{
|
||||
return $this->attachment_links;
|
||||
}
|
||||
|
||||
public function getFooter()
|
||||
{
|
||||
return $this->footer;
|
||||
|
@ -18,6 +18,7 @@ use App\Utils\Ninja;
|
||||
use App\Utils\Number;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Lang;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
|
||||
class CreditEmailEngine extends BaseEmailEngine
|
||||
{
|
||||
@ -136,11 +137,19 @@ class CreditEmailEngine extends BaseEmailEngine
|
||||
|
||||
// Storage::url
|
||||
foreach ($this->credit->documents as $document) {
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, 'file' => base64_encode($document->getFile())]]);
|
||||
|
||||
if($document->size > $this->max_attachment_size)
|
||||
$this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
|
||||
else
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, 'file' => base64_encode($document->getFile())]]);
|
||||
}
|
||||
|
||||
foreach ($this->credit->company->documents as $document) {
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, 'file' => base64_encode($document->getFile())]]);
|
||||
|
||||
if($document->size > $this->max_attachment_size)
|
||||
$this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
|
||||
else
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, 'file' => base64_encode($document->getFile())]]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ use App\Utils\Number;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Lang;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
|
||||
class InvoiceEmailEngine extends BaseEmailEngine
|
||||
{
|
||||
@ -136,13 +137,22 @@ class InvoiceEmailEngine extends BaseEmailEngine
|
||||
//attach third party documents
|
||||
if ($this->client->getSetting('document_email_attachment') !== false && $this->invoice->company->account->hasFeature(Account::FEATURE_DOCUMENTS)) {
|
||||
|
||||
|
||||
// Storage::url
|
||||
foreach ($this->invoice->documents as $document) {
|
||||
$this->setAttachments([['file' => base64_encode($document->getFile()), 'path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, ]]);
|
||||
|
||||
if($document->size > $this->max_attachment_size)
|
||||
$this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
|
||||
else
|
||||
$this->setAttachments([['file' => base64_encode($document->getFile()), 'path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, ]]);
|
||||
}
|
||||
|
||||
foreach ($this->invoice->company->documents as $document) {
|
||||
$this->setAttachments([['file' => base64_encode($document->getFile()), 'path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, ]]);
|
||||
|
||||
if($document->size > $this->max_attachment_size)
|
||||
$this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
|
||||
else
|
||||
$this->setAttachments([['file' => base64_encode($document->getFile()), 'path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, ]]);
|
||||
}
|
||||
|
||||
$line_items = $this->invoice->line_items;
|
||||
@ -160,7 +170,12 @@ class InvoiceEmailEngine extends BaseEmailEngine
|
||||
->cursor()
|
||||
->each(function ($expense) {
|
||||
foreach ($expense->documents as $document) {
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, ]]);
|
||||
|
||||
if($document->size > $this->max_attachment_size)
|
||||
$this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
|
||||
else
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, ]]);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -176,7 +191,12 @@ class InvoiceEmailEngine extends BaseEmailEngine
|
||||
->cursor()
|
||||
->each(function ($task) {
|
||||
foreach ($task->documents as $document) {
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, ]]);
|
||||
|
||||
if($document->size > $this->max_attachment_size)
|
||||
$this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
|
||||
else
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, ]]);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ use App\Utils\Ninja;
|
||||
use App\Utils\Number;
|
||||
use App\Utils\Traits\MakesDates;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
|
||||
class PaymentEmailEngine extends BaseEmailEngine
|
||||
{
|
||||
@ -100,7 +101,11 @@ class PaymentEmailEngine extends BaseEmailEngine
|
||||
if ($this->client->getSetting('document_email_attachment') !== false)
|
||||
{
|
||||
foreach ($invoice->documents as $document) {
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, ]]);
|
||||
|
||||
if($document->size > $this->max_attachment_size)
|
||||
$this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
|
||||
else
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, ]]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@ use App\Utils\Traits\MakesHash;
|
||||
use App\Utils\VendorHtmlEngine;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Lang;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
|
||||
class PurchaseOrderEmailEngine extends BaseEmailEngine
|
||||
{
|
||||
@ -126,11 +127,6 @@ class PurchaseOrderEmailEngine extends BaseEmailEngine
|
||||
->setTextBody($text_body);
|
||||
|
||||
if ($this->vendor->getSetting('pdf_email_attachment') !== false && $this->purchase_order->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
|
||||
// if (Ninja::isHosted()) {
|
||||
// $this->setAttachments([$this->purchase_order->pdf_file_path($this->invitation, 'url', true)]);
|
||||
// } else {
|
||||
// $this->setAttachments([$this->purchase_order->pdf_file_path($this->invitation)]);
|
||||
// }
|
||||
|
||||
$pdf = (new CreatePurchaseOrderPdf($this->invitation))->rawPdf();
|
||||
|
||||
@ -143,13 +139,19 @@ class PurchaseOrderEmailEngine extends BaseEmailEngine
|
||||
|
||||
// Storage::url
|
||||
foreach ($this->purchase_order->documents as $document) {
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null]]);
|
||||
// $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, 'file' => base64_encode($document->getFile())]]);
|
||||
|
||||
if($document->size > $this->max_attachment_size)
|
||||
$this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
|
||||
else
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null]]);
|
||||
}
|
||||
|
||||
foreach ($this->purchase_order->company->documents as $document) {
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null]]);
|
||||
// $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, 'file' => base64_encode($document->getFile())]]);
|
||||
|
||||
if($document->size > $this->max_attachment_size)
|
||||
$this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
|
||||
else
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null]]);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ use App\Utils\Ninja;
|
||||
use App\Utils\Number;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Lang;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
|
||||
class QuoteEmailEngine extends BaseEmailEngine
|
||||
{
|
||||
@ -128,11 +129,19 @@ class QuoteEmailEngine extends BaseEmailEngine
|
||||
|
||||
// Storage::url
|
||||
foreach ($this->quote->documents as $document) {
|
||||
$this->setAttachments([['file' => base64_encode($document->getFile()), 'path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, ]]);
|
||||
|
||||
if($document->size > $this->max_attachment_size)
|
||||
$this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
|
||||
else
|
||||
$this->setAttachments([['file' => base64_encode($document->getFile()), 'path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, ]]);
|
||||
}
|
||||
|
||||
foreach ($this->quote->company->documents as $document) {
|
||||
$this->setAttachments([['file' => base64_encode($document->getFile()), 'path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, ]]);
|
||||
|
||||
if($document->size > $this->max_attachment_size)
|
||||
$this->setAttachmentLinks(["<a class='doc_links' href='" . URL::signedRoute('documents.public_download', ['document_hash' => $document->hash]) ."'>". $document->name ."</a>"]);
|
||||
else
|
||||
$this->setAttachments([['file' => base64_encode($document->getFile()), 'path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, ]]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,6 +116,7 @@ class TemplateEmail extends Mailable
|
||||
'company' => $company,
|
||||
'whitelabel' => $this->client->user->account->isPaid() ? true : false,
|
||||
'logo' => $this->company->present()->logo($settings),
|
||||
'links' => $this->build_email->getAttachmentLinks(),
|
||||
]);
|
||||
|
||||
foreach ($this->build_email->getAttachments() as $file) {
|
||||
|
@ -109,6 +109,7 @@ class VendorTemplateEmail extends Mailable
|
||||
'company' => $this->company,
|
||||
'whitelabel' => $this->vendor->user->account->isPaid() ? true : false,
|
||||
'logo' => $this->company->present()->logo($settings),
|
||||
'links' => $this->build_email->getAttachmentLinks(),
|
||||
]);
|
||||
|
||||
|
||||
|
@ -375,18 +375,4 @@ class Activity extends StaticModel
|
||||
return $this->belongsTo(Company::class);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return mixed
|
||||
// */
|
||||
// public function resolveRouteBinding($value, $field = null)
|
||||
// {
|
||||
// if (is_numeric($value)) {
|
||||
// throw new ModelNotFoundException("Record with value {$value} not found");
|
||||
// }
|
||||
|
||||
// return $this
|
||||
// //->withTrashed()
|
||||
// ->where('id', $this->decodePrimaryKey($value))->firstOrFail();
|
||||
// }
|
||||
|
||||
}
|
@ -70,16 +70,4 @@ class ClientGatewayToken extends BaseModel
|
||||
return $this->belongsTo(User::class)->withTrashed();
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Retrieve the model for a bound value.
|
||||
// *
|
||||
// * @param mixed $value
|
||||
// * @param null $field
|
||||
// * @return Model|null
|
||||
// */
|
||||
// public function resolveRouteBinding($value, $field = null)
|
||||
// {
|
||||
// return $this
|
||||
// ->where('id', $this->decodePrimaryKey($value))->firstOrFail();
|
||||
// }
|
||||
}
|
||||
|
@ -43,6 +43,10 @@ class CompanyGateway extends BaseModel
|
||||
'require_client_phone',
|
||||
'require_contact_name',
|
||||
'require_contact_email',
|
||||
'require_custom_value1',
|
||||
'require_custom_value2',
|
||||
'require_custom_value3',
|
||||
'require_custom_value4',
|
||||
'update_details',
|
||||
'config',
|
||||
'fees_and_limits',
|
||||
@ -412,12 +416,4 @@ class CompanyGateway extends BaseModel
|
||||
return route('payment_webhook', ['company_key' => $this->company->company_key, 'company_gateway_id' => $this->hashed_id]);
|
||||
}
|
||||
|
||||
// public function resolveRouteBinding($value, $field = null)
|
||||
// {
|
||||
|
||||
// return $this
|
||||
// ->where('id', $this->decodePrimaryKey($value))->withTrashed()->firstOrFail();
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
@ -249,18 +249,18 @@ class Credit extends BaseModel
|
||||
|
||||
if ($this->balance == 0) {
|
||||
$this->status_id = self::STATUS_APPLIED;
|
||||
$this->save();
|
||||
$this->saveQuietly();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->save();
|
||||
$this->saveQuietly();
|
||||
}
|
||||
|
||||
public function setStatus($status)
|
||||
{
|
||||
$this->status_id = $status;
|
||||
$this->save();
|
||||
$this->saveQuietly();
|
||||
}
|
||||
|
||||
public function pdf_file_path($invitation = null, string $type = 'path', bool $portal = false)
|
||||
@ -313,7 +313,7 @@ class Credit extends BaseModel
|
||||
$this->invitations->each(function ($invitation) {
|
||||
if (! isset($invitation->sent_date)) {
|
||||
$invitation->sent_date = Carbon::now();
|
||||
$invitation->save();
|
||||
$invitation->saveQuietly();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ class Currency extends StaticModel
|
||||
'updated_at' => 'timestamp',
|
||||
'created_at' => 'timestamp',
|
||||
'deleted_at' => 'timestamp',
|
||||
//'precision' => 'string',
|
||||
'precision' => 'integer',
|
||||
];
|
||||
}
|
||||
|
@ -14,14 +14,13 @@ namespace App\Models;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException as ModelNotFoundException;
|
||||
|
||||
class GroupSetting extends StaticModel
|
||||
{
|
||||
use MakesHash;
|
||||
use SoftDeletes;
|
||||
|
||||
//public $timestamps = false;
|
||||
|
||||
protected $casts = [
|
||||
'settings' => 'object',
|
||||
'updated_at' => 'timestamp',
|
||||
@ -65,4 +64,25 @@ class GroupSetting extends StaticModel
|
||||
return $this->morphMany(Document::class, 'documentable');
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the model for a bound value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param null $field
|
||||
* @return Model|null
|
||||
*/
|
||||
public function resolveRouteBinding($value, $field = null)
|
||||
{
|
||||
|
||||
if (is_numeric($value)) {
|
||||
throw new ModelNotFoundException("Record with value {$value} not found");
|
||||
}
|
||||
|
||||
return $this
|
||||
->withTrashed()
|
||||
->company()
|
||||
->where('id', $this->decodePrimaryKey($value))->firstOrFail();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,14 +292,6 @@ class Payment extends BaseModel
|
||||
return new PaymentService($this);
|
||||
}
|
||||
|
||||
|
||||
// public function resolveRouteBinding($value, $field = null)
|
||||
// {
|
||||
// return $this
|
||||
// ->withTrashed()
|
||||
// ->where('id', $this->decodePrimaryKey($value))->firstOrFail();
|
||||
// }
|
||||
|
||||
public function refund(array $data) :self
|
||||
{
|
||||
return $this->service()->refundPayment($data);
|
||||
|
@ -141,6 +141,10 @@ class PurchaseOrder extends BaseModel
|
||||
}
|
||||
}
|
||||
|
||||
public function getEntityType()
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
public function assigned_user()
|
||||
{
|
||||
@ -186,7 +190,7 @@ class PurchaseOrder extends BaseModel
|
||||
$this->invitations->each(function ($invitation) {
|
||||
if (! isset($invitation->sent_date)) {
|
||||
$invitation->sent_date = Carbon::now();
|
||||
$invitation->save();
|
||||
$invitation->saveQuietly();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ class Quote extends BaseModel
|
||||
$this->invitations->each(function ($invitation) {
|
||||
if (! isset($invitation->sent_date)) {
|
||||
$invitation->sent_date = Carbon::now();
|
||||
$invitation->save();
|
||||
$invitation->saveQuietly();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -57,8 +57,7 @@ class StaticModel extends Model
|
||||
}
|
||||
|
||||
return $this
|
||||
->withTrashed()
|
||||
->company()
|
||||
->where('id', $this->decodePrimaryKey($value))->firstOrFail();
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -367,22 +367,41 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
*/
|
||||
public function hasPermission($permission) : bool
|
||||
{
|
||||
$parts = explode('_', $permission);
|
||||
$all_permission = '____';
|
||||
|
||||
/**
|
||||
* We use the limit parameter here to ensure we don't split on permissions that have multiple underscores.
|
||||
*
|
||||
* For example view_recurring_invoice without the limit would split to view bank recurring invoice
|
||||
*
|
||||
* Using only part 0 and 1 would search for permission view_recurring / edit_recurring so this would
|
||||
* leak permissions for other recurring_* entities
|
||||
*
|
||||
* The solution here will split the word - consistently - into view _ {entity} and edit _ {entity}
|
||||
*
|
||||
*/
|
||||
$parts = explode('_', $permission, 2);
|
||||
$all_permission = '____';
|
||||
$edit_all = '____';
|
||||
$edit_entity = '____';
|
||||
|
||||
/* If we have multiple parts, then make sure we search for the _all permission */
|
||||
if (count($parts) > 1) {
|
||||
$all_permission = $parts[0].'_all';
|
||||
|
||||
/*If this is a view search, make sure we add in the edit_{entity} AND edit_all permission into the checks*/
|
||||
if($parts[0] == 'view') {
|
||||
$edit_all = 'edit_all';
|
||||
$edit_entity = "edit_{$parts[1]}";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $this->isOwner() ||
|
||||
$this->isAdmin() ||
|
||||
(stripos($this->token()->cu->permissions, $permission) !== false) ||
|
||||
(stripos($this->token()->cu->permissions, $all_permission) !== false) ||
|
||||
(stripos($this->token()->cu->permissions, $permission) !== false);
|
||||
|
||||
// return $this->isOwner() ||
|
||||
// $this->isAdmin() ||
|
||||
// (is_int(stripos($this->token()->cu->permissions, $all_permission))) ||
|
||||
// (is_int(stripos($this->token()->cu->permissions, $permission)));
|
||||
(stripos($this->token()->cu->permissions, $edit_all) !== false) ||
|
||||
(stripos($this->token()->cu->permissions, $edit_entity) !== false);
|
||||
|
||||
}
|
||||
|
||||
|
@ -145,7 +145,7 @@ class VendorContact extends Authenticatable implements HasLocalePreference
|
||||
{
|
||||
return $this
|
||||
->withTrashed()
|
||||
->company()
|
||||
// ->company()
|
||||
->where('id', $this->decodePrimaryKey($value))
|
||||
->firstOrFail();
|
||||
}
|
||||
|
@ -18,47 +18,47 @@ class Webhook extends BaseModel
|
||||
use SoftDeletes;
|
||||
use Filterable;
|
||||
|
||||
const EVENT_CREATE_CLIENT = 1;
|
||||
const EVENT_CREATE_CLIENT = 1; //tested
|
||||
|
||||
const EVENT_CREATE_INVOICE = 2;
|
||||
const EVENT_CREATE_INVOICE = 2; //tested
|
||||
|
||||
const EVENT_CREATE_QUOTE = 3;
|
||||
const EVENT_CREATE_QUOTE = 3; //tested
|
||||
|
||||
const EVENT_CREATE_PAYMENT = 4;
|
||||
const EVENT_CREATE_PAYMENT = 4; //tested
|
||||
|
||||
const EVENT_CREATE_VENDOR = 5;
|
||||
const EVENT_CREATE_VENDOR = 5; //tested
|
||||
|
||||
const EVENT_UPDATE_QUOTE = 6;
|
||||
const EVENT_UPDATE_QUOTE = 6; //tested
|
||||
|
||||
const EVENT_DELETE_QUOTE = 7;
|
||||
const EVENT_DELETE_QUOTE = 7; //tested
|
||||
|
||||
const EVENT_UPDATE_INVOICE = 8;
|
||||
const EVENT_UPDATE_INVOICE = 8; //tested
|
||||
|
||||
const EVENT_DELETE_INVOICE = 9;
|
||||
const EVENT_DELETE_INVOICE = 9; //tested
|
||||
|
||||
const EVENT_UPDATE_CLIENT = 10;
|
||||
const EVENT_UPDATE_CLIENT = 10; //tested
|
||||
|
||||
const EVENT_DELETE_CLIENT = 11;
|
||||
const EVENT_DELETE_CLIENT = 11; //tested
|
||||
|
||||
const EVENT_DELETE_PAYMENT = 12;
|
||||
const EVENT_DELETE_PAYMENT = 12; //tested
|
||||
|
||||
const EVENT_UPDATE_VENDOR = 13;
|
||||
const EVENT_UPDATE_VENDOR = 13; //tested
|
||||
|
||||
const EVENT_DELETE_VENDOR = 14;
|
||||
const EVENT_DELETE_VENDOR = 14; //tested
|
||||
|
||||
const EVENT_CREATE_EXPENSE = 15;
|
||||
const EVENT_CREATE_EXPENSE = 15; //tested
|
||||
|
||||
const EVENT_UPDATE_EXPENSE = 16;
|
||||
const EVENT_UPDATE_EXPENSE = 16; //tested
|
||||
|
||||
const EVENT_DELETE_EXPENSE = 17;
|
||||
const EVENT_DELETE_EXPENSE = 17; //tested
|
||||
|
||||
const EVENT_CREATE_TASK = 18;
|
||||
const EVENT_CREATE_TASK = 18; //tested
|
||||
|
||||
const EVENT_UPDATE_TASK = 19;
|
||||
const EVENT_UPDATE_TASK = 19; //tested
|
||||
|
||||
const EVENT_DELETE_TASK = 20;
|
||||
const EVENT_DELETE_TASK = 20; //tested
|
||||
|
||||
const EVENT_APPROVE_QUOTE = 21;
|
||||
const EVENT_APPROVE_QUOTE = 21; //tested
|
||||
|
||||
const EVENT_LATE_INVOICE = 22;
|
||||
|
||||
@ -66,22 +66,86 @@ class Webhook extends BaseModel
|
||||
|
||||
const EVENT_REMIND_INVOICE = 24;
|
||||
|
||||
const EVENT_PROJECT_CREATE = 25;
|
||||
const EVENT_PROJECT_CREATE = 25; //tested
|
||||
|
||||
const EVENT_PROJECT_UPDATE = 26;
|
||||
const EVENT_PROJECT_UPDATE = 26; //tested
|
||||
|
||||
const EVENT_CREATE_CREDIT = 27;
|
||||
const EVENT_CREATE_CREDIT = 27; //tested
|
||||
|
||||
const EVENT_UPDATE_CREDIT = 28;
|
||||
const EVENT_UPDATE_CREDIT = 28; //tested
|
||||
|
||||
const EVENT_DELETE_CREDIT = 29;
|
||||
const EVENT_DELETE_CREDIT = 29; //tested
|
||||
|
||||
const EVENT_PROJECT_DELETE = 30;
|
||||
const EVENT_PROJECT_DELETE = 30; //tested
|
||||
|
||||
const EVENT_UPDATE_PAYMENT = 31;
|
||||
const EVENT_UPDATE_PAYMENT = 31; //tested
|
||||
|
||||
const EVENT_ARCHIVE_PAYMENT = 32; //tested
|
||||
|
||||
const EVENT_ARCHIVE_INVOICE = 33; //tested
|
||||
|
||||
const EVENT_ARCHIVE_QUOTE = 34; //tested
|
||||
|
||||
const EVENT_ARCHIVE_CREDIT = 35; //tested
|
||||
|
||||
const EVENT_ARCHIVE_TASK = 36; //tested
|
||||
|
||||
const EVENT_ARCHIVE_CLIENT = 37; //tested
|
||||
|
||||
const EVENT_ARCHIVE_PROJECT = 38; //tested
|
||||
|
||||
const EVENT_ARCHIVE_EXPENSE = 39; //tested
|
||||
|
||||
const EVENT_RESTORE_PAYMENT = 40; //tested
|
||||
|
||||
const EVENT_RESTORE_INVOICE = 41; //tested
|
||||
|
||||
const EVENT_RESTORE_QUOTE = 42; ///tested
|
||||
|
||||
const EVENT_RESTORE_CREDIT = 43; //tested
|
||||
|
||||
const EVENT_RESTORE_TASK = 44; //tested
|
||||
|
||||
const EVENT_RESTORE_CLIENT = 45; //tested
|
||||
|
||||
const EVENT_RESTORE_PROJECT = 46; //tested
|
||||
|
||||
const EVENT_RESTORE_EXPENSE = 47; //tested
|
||||
|
||||
const EVENT_ARCHIVE_VENDOR = 48; //tested
|
||||
|
||||
const EVENT_RESTORE_VENDOR = 49; //tested
|
||||
|
||||
const EVENT_CREATE_PRODUCT = 50; //tested
|
||||
|
||||
const EVENT_UPDATE_PRODUCT = 51; //tested
|
||||
|
||||
const EVENT_DELETE_PRODUCT = 52; //tested
|
||||
|
||||
const EVENT_RESTORE_PRODUCT = 53; //tested
|
||||
|
||||
const EVENT_ARCHIVE_PRODUCT = 54; //tested
|
||||
|
||||
const EVENT_CREATE_PURCHASE_ORDER = 55; //tested
|
||||
|
||||
const EVENT_UPDATE_PURCHASE_ORDER = 56; //tested
|
||||
|
||||
const EVENT_DELETE_PURCHASE_ORDER = 57; //tested
|
||||
|
||||
const EVENT_RESTORE_PURCHASE_ORDER = 58; //tested
|
||||
|
||||
const EVENT_ARCHIVE_PURCHASE_ORDER = 59; //tested
|
||||
|
||||
public static $valid_events = [
|
||||
self::EVENT_CREATE_PURCHASE_ORDER,
|
||||
self::EVENT_UPDATE_PURCHASE_ORDER,
|
||||
self::EVENT_DELETE_PURCHASE_ORDER,
|
||||
self::EVENT_RESTORE_PURCHASE_ORDER,
|
||||
self::EVENT_ARCHIVE_PURCHASE_ORDER,
|
||||
self::EVENT_UPDATE_PRODUCT,
|
||||
self::EVENT_DELETE_PRODUCT,
|
||||
self::EVENT_RESTORE_PRODUCT,
|
||||
self::EVENT_ARCHIVE_PRODUCT,
|
||||
self::EVENT_CREATE_CLIENT,
|
||||
self::EVENT_CREATE_INVOICE,
|
||||
self::EVENT_CREATE_QUOTE,
|
||||
@ -112,7 +176,26 @@ class Webhook extends BaseModel
|
||||
self::EVENT_UPDATE_CREDIT,
|
||||
self::EVENT_DELETE_CREDIT,
|
||||
self::EVENT_PROJECT_DELETE,
|
||||
self::EVENT_UPDATE_PAYMENT
|
||||
self::EVENT_UPDATE_PAYMENT,
|
||||
self::EVENT_ARCHIVE_EXPENSE,
|
||||
self::EVENT_ARCHIVE_PROJECT,
|
||||
self::EVENT_ARCHIVE_CLIENT,
|
||||
self::EVENT_ARCHIVE_TASK,
|
||||
self::EVENT_ARCHIVE_CREDIT,
|
||||
self::EVENT_ARCHIVE_QUOTE,
|
||||
self::EVENT_ARCHIVE_INVOICE,
|
||||
self::EVENT_ARCHIVE_PAYMENT,
|
||||
self::EVENT_ARCHIVE_VENDOR,
|
||||
self::EVENT_RESTORE_EXPENSE,
|
||||
self::EVENT_RESTORE_PROJECT,
|
||||
self::EVENT_RESTORE_CLIENT,
|
||||
self::EVENT_RESTORE_TASK,
|
||||
self::EVENT_RESTORE_CREDIT,
|
||||
self::EVENT_RESTORE_QUOTE,
|
||||
self::EVENT_RESTORE_INVOICE,
|
||||
self::EVENT_RESTORE_PAYMENT,
|
||||
self::EVENT_RESTORE_VENDOR
|
||||
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
|
@ -30,13 +30,7 @@ class ClientAccountNotFound extends Notification
|
||||
* @return void
|
||||
*/
|
||||
|
||||
|
||||
protected string $account_key;
|
||||
|
||||
public function __construct(string $account_key)
|
||||
{
|
||||
$this->account_key = $account_key;
|
||||
}
|
||||
public function __construct(protected string $account_key, protected string $email){}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
@ -77,6 +71,7 @@ class ClientAccountNotFound extends Notification
|
||||
|
||||
$content = "Client not found, unable to remove account\n";
|
||||
$content .= "Account: {$this->account_key }\n";
|
||||
$content .= "Email: {$this->email}\n";
|
||||
|
||||
return (new SlackMessage)
|
||||
->success()
|
||||
|
@ -68,7 +68,7 @@ class RenewalFailureNotification extends Notification
|
||||
public function toSlack($notifiable)
|
||||
{
|
||||
$content = "Plan paid, account not updated\n";
|
||||
$content .= "Contact: {$this->notification_message}";
|
||||
$content .= "Contact/Inapp Purchase: {$this->notification_message}";
|
||||
|
||||
return (new SlackMessage)
|
||||
->success()
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace App\Observers;
|
||||
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\CreditInvitation;
|
||||
use App\Models\InvoiceInvitation;
|
||||
use App\Models\QuoteInvitation;
|
||||
use App\Models\RecurringInvoiceInvitation;
|
||||
@ -79,7 +80,12 @@ class ClientContactObserver
|
||||
|
||||
});
|
||||
|
||||
CreditInvitation::withTrashed()->where('client_contact_id', $client_contact_id)->cursor()->each(function ($invite){
|
||||
|
||||
if($invite->credits()->doesnthave('invitations'))
|
||||
$invite->credit->service()->createInvitations();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,9 +96,6 @@ class ClientContactObserver
|
||||
*/
|
||||
public function restored(ClientContact $clientContact)
|
||||
{
|
||||
// $clientContact->invoice_invitations()->restore();
|
||||
// $clientContact->quote_invitations()->restore();
|
||||
// $clientContact->credit_invitations()->restore();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -17,6 +17,8 @@ use App\Models\Webhook;
|
||||
|
||||
class ClientObserver
|
||||
{
|
||||
public $afterCommit = true;
|
||||
|
||||
/**
|
||||
* Handle the client "created" event.
|
||||
*
|
||||
@ -25,13 +27,13 @@ class ClientObserver
|
||||
*/
|
||||
public function created(Client $client)
|
||||
{
|
||||
$subscriptions = Webhook::where('company_id', $client->company->id)
|
||||
$subscriptions = Webhook::where('company_id', $client->company_id)
|
||||
->where('event_id', Webhook::EVENT_CREATE_CLIENT)
|
||||
->exists();
|
||||
|
||||
if ($subscriptions) {
|
||||
WebhookHandler::dispatch(Webhook::EVENT_CREATE_CLIENT, $client, $client->company)->delay(now()->addSeconds(2));
|
||||
}
|
||||
if ($subscriptions)
|
||||
WebhookHandler::dispatch(Webhook::EVENT_CREATE_CLIENT, $client, $client->company)->delay(0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -42,51 +44,44 @@ class ClientObserver
|
||||
*/
|
||||
public function updated(Client $client)
|
||||
{
|
||||
$subscriptions = Webhook::where('company_id', $client->company->id)
|
||||
->where('event_id', Webhook::EVENT_UPDATE_CLIENT)
|
||||
|
||||
$event = Webhook::EVENT_UPDATE_CLIENT;
|
||||
|
||||
if($client->getOriginal('deleted_at') && !$client->deleted_at)
|
||||
$event = Webhook::EVENT_RESTORE_CLIENT;
|
||||
|
||||
if($client->is_deleted)
|
||||
$event = Webhook::EVENT_DELETE_CLIENT;
|
||||
|
||||
|
||||
$subscriptions = Webhook::where('company_id', $client->company_id)
|
||||
->where('event_id', $event)
|
||||
->exists();
|
||||
|
||||
if ($subscriptions) {
|
||||
WebhookHandler::dispatch(Webhook::EVENT_UPDATE_CLIENT, $client, $client->company)->delay(now()->addSeconds(2));
|
||||
}
|
||||
if ($subscriptions)
|
||||
WebhookHandler::dispatch($event, $client, $client->company)->delay(0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the client "deleted" event.
|
||||
* Handle the client "archived" event.
|
||||
*
|
||||
* @param Client $client
|
||||
* @return void
|
||||
*/
|
||||
public function deleted(Client $client)
|
||||
{
|
||||
$subscriptions = Webhook::where('company_id', $client->company->id)
|
||||
->where('event_id', Webhook::EVENT_DELETE_CLIENT)
|
||||
if($client->is_deleted)
|
||||
return;
|
||||
|
||||
$subscriptions = Webhook::where('company_id', $client->company_id)
|
||||
->where('event_id', Webhook::EVENT_ARCHIVE_CLIENT)
|
||||
->exists();
|
||||
|
||||
if ($subscriptions) {
|
||||
WebhookHandler::dispatch(Webhook::EVENT_DELETE_CLIENT, $client, $client->company)->delay(now()->addSeconds(2));
|
||||
}
|
||||
if ($subscriptions)
|
||||
WebhookHandler::dispatch(Webhook::EVENT_ARCHIVE_CLIENT, $client, $client->company)->delay(0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the client "restored" event.
|
||||
*
|
||||
* @param Client $client
|
||||
* @return void
|
||||
*/
|
||||
public function restored(Client $client)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the client "force deleted" event.
|
||||
*
|
||||
* @param Client $client
|
||||
* @return void
|
||||
*/
|
||||
public function forceDeleted(Client $client)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,9 @@ use App\Models\Webhook;
|
||||
|
||||
class CreditObserver
|
||||
{
|
||||
|
||||
public $afterCommit = true;
|
||||
|
||||
/**
|
||||
* Handle the client "created" event.
|
||||
*
|
||||
@ -27,12 +30,12 @@ class CreditObserver
|
||||
*/
|
||||
public function created(Credit $credit)
|
||||
{
|
||||
$subscriptions = Webhook::where('company_id', $credit->company->id)
|
||||
$subscriptions = Webhook::where('company_id', $credit->company_id)
|
||||
->where('event_id', Webhook::EVENT_CREATE_CREDIT)
|
||||
->exists();
|
||||
|
||||
if ($subscriptions) {
|
||||
WebhookHandler::dispatch(Webhook::EVENT_CREATE_CREDIT, $credit, $credit->company)->delay(now()->addSeconds(2));
|
||||
WebhookHandler::dispatch(Webhook::EVENT_CREATE_CREDIT, $credit, $credit->company)->delay(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,13 +47,21 @@ class CreditObserver
|
||||
*/
|
||||
public function updated(Credit $credit)
|
||||
{
|
||||
$subscriptions = Webhook::where('company_id', $credit->company->id)
|
||||
->where('event_id', Webhook::EVENT_UPDATE_CREDIT)
|
||||
$event = Webhook::EVENT_UPDATE_CREDIT;
|
||||
|
||||
if($credit->getOriginal('deleted_at') && !$credit->deleted_at)
|
||||
$event = Webhook::EVENT_RESTORE_CREDIT;
|
||||
|
||||
if($credit->is_deleted)
|
||||
$event = Webhook::EVENT_DELETE_CREDIT;
|
||||
|
||||
$subscriptions = Webhook::where('company_id', $credit->company_id)
|
||||
->where('event_id', $event)
|
||||
->exists();
|
||||
|
||||
if ($subscriptions) {
|
||||
WebhookHandler::dispatch(Webhook::EVENT_UPDATE_CREDIT, $credit, $credit->company)->delay(now()->addSeconds(2));
|
||||
}
|
||||
if ($subscriptions)
|
||||
WebhookHandler::dispatch($event, $credit, $credit->company)->delay(0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -61,13 +72,16 @@ class CreditObserver
|
||||
*/
|
||||
public function deleted(Credit $credit)
|
||||
{
|
||||
$subscriptions = Webhook::where('company_id', $credit->company->id)
|
||||
->where('event_id', Webhook::EVENT_DELETE_CREDIT)
|
||||
if($credit->is_deleted)
|
||||
return;
|
||||
|
||||
$subscriptions = Webhook::where('company_id', $credit->company_id)
|
||||
->where('event_id', Webhook::EVENT_ARCHIVE_CREDIT)
|
||||
->exists();
|
||||
|
||||
if ($subscriptions) {
|
||||
WebhookHandler::dispatch(Webhook::EVENT_DELETE_CREDIT, $credit, $credit->company)->delay(now()->addSeconds(2));
|
||||
}
|
||||
if ($subscriptions)
|
||||
WebhookHandler::dispatch(Webhook::EVENT_ARCHIVE_CREDIT, $credit, $credit->company)->delay(0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -91,4 +105,10 @@ class CreditObserver
|
||||
{
|
||||
//
|
||||
}
|
||||
/**
|
||||
* Handle the client "archive" event.
|
||||
*
|
||||
* @param Credit $credit
|
||||
* @return void
|
||||
*/
|
||||
}
|
||||
|
@ -17,6 +17,8 @@ use App\Models\Webhook;
|
||||
|
||||
class ExpenseObserver
|
||||
{
|
||||
public $afterCommit = true;
|
||||
|
||||
/**
|
||||
* Handle the expense "created" event.
|
||||
*
|
||||
@ -25,13 +27,13 @@ class ExpenseObserver
|
||||
*/
|
||||
public function created(Expense $expense)
|
||||
{
|
||||
$subscriptions = Webhook::where('company_id', $expense->company->id)
|
||||
$subscriptions = Webhook::where('company_id', $expense->company_id)
|
||||
->where('event_id', Webhook::EVENT_CREATE_EXPENSE)
|
||||
->exists();
|
||||
|
||||
if ($subscriptions) {
|
||||
WebhookHandler::dispatch(Webhook::EVENT_CREATE_EXPENSE, $expense, $expense->company)->delay(now()->addSeconds(2));
|
||||
}
|
||||
if ($subscriptions)
|
||||
WebhookHandler::dispatch(Webhook::EVENT_CREATE_EXPENSE, $expense, $expense->company)->delay(0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -42,13 +44,22 @@ class ExpenseObserver
|
||||
*/
|
||||
public function updated(Expense $expense)
|
||||
{
|
||||
$subscriptions = Webhook::where('company_id', $expense->company->id)
|
||||
->where('event_id', Webhook::EVENT_UPDATE_EXPENSE)
|
||||
->exists();
|
||||
$event = Webhook::EVENT_UPDATE_EXPENSE;
|
||||
|
||||
if($expense->getOriginal('deleted_at') && !$expense->deleted_at)
|
||||
$event = Webhook::EVENT_RESTORE_EXPENSE;
|
||||
|
||||
if($expense->is_deleted)
|
||||
$event = Webhook::EVENT_DELETE_EXPENSE;
|
||||
|
||||
|
||||
$subscriptions = Webhook::where('company_id', $expense->company_id)
|
||||
->where('event_id', $event)
|
||||
->exists();
|
||||
|
||||
if ($subscriptions)
|
||||
WebhookHandler::dispatch($event, $expense, $expense->company)->delay(0);
|
||||
|
||||
if ($subscriptions) {
|
||||
WebhookHandler::dispatch(Webhook::EVENT_UPDATE_EXPENSE, $expense, $expense->company)->delay(now()->addSeconds(2));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -59,13 +70,16 @@ class ExpenseObserver
|
||||
*/
|
||||
public function deleted(Expense $expense)
|
||||
{
|
||||
$subscriptions = Webhook::where('company_id', $expense->company->id)
|
||||
->where('event_id', Webhook::EVENT_DELETE_EXPENSE)
|
||||
if($expense->is_deleted)
|
||||
return;
|
||||
|
||||
$subscriptions = Webhook::where('company_id', $expense->company_id)
|
||||
->where('event_id', Webhook::EVENT_ARCHIVE_EXPENSE)
|
||||
->exists();
|
||||
|
||||
if ($subscriptions) {
|
||||
WebhookHandler::dispatch(Webhook::EVENT_DELETE_EXPENSE, $expense, $expense->company)->delay(now()->addSeconds(2));
|
||||
}
|
||||
if ($subscriptions)
|
||||
WebhookHandler::dispatch(Webhook::EVENT_ARCHIVE_EXPENSE, $expense, $expense->company)->delay(0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,4 +103,10 @@ class ExpenseObserver
|
||||
{
|
||||
//
|
||||
}
|
||||
/**
|
||||
* Handle the expense "archive" event.
|
||||
*
|
||||
* @param Expense $expense
|
||||
* @return void
|
||||
*/
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user