mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-17 00:22:51 +01:00
commit
a340ce8e8c
@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased (daily channel)](https://github.com/invoiceninja/invoiceninja/tree/v5-develop)
|
||||
- Add Cache-control: no-cache to prevent overaggressive caching of assets
|
||||
- Improved labelling in the settings (client portal)
|
||||
- Client portal: Multiple accounts access improvements (#5703)
|
||||
- Client portal: "Credits" updates (#5734)
|
||||
- Client portal: Make sidebar white color, in order to make logo displaying more simple. (#5753)
|
||||
|
||||
## [v5.1.56-release](https://github.com/invoiceninja/invoiceninja/releases/tag/v5.1.56-release)
|
||||
## Fixed:
|
||||
|
@ -1 +1 @@
|
||||
5.1.62
|
||||
5.1.63
|
@ -105,6 +105,9 @@ class CreateAccount extends Command
|
||||
'password' => Hash::make($password),
|
||||
'confirmation_code' => $this->createDbHash(config('database.default')),
|
||||
'email_verified_at' => now(),
|
||||
'first_name' => 'New',
|
||||
'last_name' => 'User',
|
||||
'phone' => '',
|
||||
]);
|
||||
|
||||
$company_token = new CompanyToken;
|
||||
|
@ -105,6 +105,8 @@ class CreateSingleAccount extends Command
|
||||
'account_id' => $account->id,
|
||||
'slack_webhook_url' => config('ninja.notification.slack'),
|
||||
'default_password_timeout' => 30*60000,
|
||||
'portal_mode' => 'domain',
|
||||
'portal_domain' => 'http://ninja.test:8000',
|
||||
]);
|
||||
|
||||
$account->default_company_id = $company->id;
|
||||
|
@ -128,7 +128,7 @@ class DemoMode extends Command
|
||||
{
|
||||
$faker = \Faker\Factory::create();
|
||||
|
||||
$this->count = 50;
|
||||
$this->count = 25;
|
||||
|
||||
$this->info('Creating Small Account and Company');
|
||||
|
||||
@ -486,7 +486,7 @@ class DemoMode extends Command
|
||||
if (rand(0, 1)) {
|
||||
$invoice->assigned_user_id = $assigned_user_id;
|
||||
}
|
||||
|
||||
$invoice->number = $this->getNextRecurringInvoiceNumber($client);
|
||||
$invoice->save();
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ namespace App\Exceptions;
|
||||
use App\Exceptions\FilePermissionsFailure;
|
||||
use App\Exceptions\InternalPDFFailure;
|
||||
use App\Exceptions\PhantomPDFFailure;
|
||||
use App\Utils\Ninja;
|
||||
use Exception;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
@ -75,7 +76,28 @@ class Handler extends ExceptionHandler
|
||||
return;
|
||||
}
|
||||
|
||||
if (app()->bound('sentry') && $this->shouldReport($exception)) {
|
||||
if(Ninja::isHosted()){
|
||||
|
||||
app('sentry')->configureScope(function (Scope $scope): void {
|
||||
|
||||
if(auth()->guard('contact') && auth()->guard('contact')->user())
|
||||
$key = auth()->guard('contact')->user()->company->account->key;
|
||||
elseif (auth()->guard('user') && auth()->guard('user')->user())
|
||||
$key = auth()->user()->account->key;
|
||||
else
|
||||
$key = 'Anonymous';
|
||||
|
||||
$scope->setUser([
|
||||
'id' => 'Hosted_User',
|
||||
'email' => 'hosted@invoiceninja.com',
|
||||
'name' => $key,
|
||||
]);
|
||||
});
|
||||
|
||||
app('sentry')->captureException($exception);
|
||||
|
||||
}
|
||||
elseif (app()->bound('sentry') && $this->shouldReport($exception)) {
|
||||
app('sentry')->configureScope(function (Scope $scope): void {
|
||||
if (auth()->guard('contact') && auth()->guard('contact')->user() && auth()->guard('contact')->user()->company->account->report_errors) {
|
||||
$scope->setUser([
|
||||
|
10
app/Exceptions/NonExistingBackupFile.php
Normal file
10
app/Exceptions/NonExistingBackupFile.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class NonExistingBackupFile extends Exception
|
||||
{
|
||||
// ..
|
||||
}
|
@ -33,9 +33,6 @@ class ClientFactory
|
||||
$client->client_hash = Str::random(40);
|
||||
$client->settings = ClientSettings::defaults();
|
||||
|
||||
// $client_contact = ClientContactFactory::create($company_id, $user_id);
|
||||
// $client->contacts->add($client_contact);
|
||||
|
||||
return $client;
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ class CompanyGatewayFactory
|
||||
$company_gateway = new CompanyGateway;
|
||||
$company_gateway->company_id = $company_id;
|
||||
$company_gateway->user_id = $user_id;
|
||||
$company_gateway->require_billing_address = false;
|
||||
$company_gateway->require_shipping_address = false;
|
||||
// $company_gateway->fees_and_limits = new FeesAndLimits;
|
||||
|
||||
return $company_gateway;
|
||||
|
@ -37,10 +37,10 @@ class CreditFactory
|
||||
$credit->tax_rate1 = 0;
|
||||
$credit->tax_name2 = '';
|
||||
$credit->tax_rate2 = 0;
|
||||
$credit->custom_value1 = 0;
|
||||
$credit->custom_value2 = 0;
|
||||
$credit->custom_value3 = 0;
|
||||
$credit->custom_value4 = 0;
|
||||
$credit->custom_value1 = '';
|
||||
$credit->custom_value2 = '';
|
||||
$credit->custom_value3 = '';
|
||||
$credit->custom_value4 = '';
|
||||
$credit->amount = 0;
|
||||
$credit->balance = 0;
|
||||
$credit->partial = 0;
|
||||
|
@ -38,10 +38,10 @@ class InvoiceFactory
|
||||
$invoice->tax_rate2 = 0;
|
||||
$invoice->tax_name3 = '';
|
||||
$invoice->tax_rate3 = 0;
|
||||
$invoice->custom_value1 = 0;
|
||||
$invoice->custom_value2 = 0;
|
||||
$invoice->custom_value3 = 0;
|
||||
$invoice->custom_value4 = 0;
|
||||
$invoice->custom_value1 = '';
|
||||
$invoice->custom_value2 = '';
|
||||
$invoice->custom_value3 = '';
|
||||
$invoice->custom_value4 = '';
|
||||
$invoice->amount = 0;
|
||||
$invoice->balance = 0;
|
||||
$invoice->paid_to_date = 0;
|
||||
|
@ -36,10 +36,10 @@ class RecurringInvoiceFactory
|
||||
$invoice->tax_rate1 = 0;
|
||||
$invoice->tax_name2 = '';
|
||||
$invoice->tax_rate2 = 0;
|
||||
$invoice->custom_value1 = 0;
|
||||
$invoice->custom_value2 = 0;
|
||||
$invoice->custom_value3 = 0;
|
||||
$invoice->custom_value4 = 0;
|
||||
$invoice->custom_value1 = '';
|
||||
$invoice->custom_value2 = '';
|
||||
$invoice->custom_value3 = '';
|
||||
$invoice->custom_value4 = '';
|
||||
$invoice->amount = 0;
|
||||
$invoice->balance = 0;
|
||||
$invoice->partial = 0;
|
||||
|
@ -35,10 +35,10 @@ class RecurringQuoteFactory
|
||||
$quote->tax_rate1 = 0;
|
||||
$quote->tax_name2 = '';
|
||||
$quote->tax_rate2 = 0;
|
||||
$quote->custom_value1 = 0;
|
||||
$quote->custom_value2 = 0;
|
||||
$quote->custom_value3 = 0;
|
||||
$quote->custom_value4 = 0;
|
||||
$quote->custom_value1 = '';
|
||||
$quote->custom_value2 = '';
|
||||
$quote->custom_value3 = '';
|
||||
$quote->custom_value4 = '';
|
||||
$quote->amount = 0;
|
||||
$quote->balance = 0;
|
||||
$quote->partial = 0;
|
||||
|
@ -169,4 +169,27 @@ abstract class QueryFilters
|
||||
|
||||
return $this->builder->where('created_at', '>=', $created_at);
|
||||
}
|
||||
|
||||
public function is_deleted($value)
|
||||
{
|
||||
|
||||
return $this->builder->where('is_deleted', $value);
|
||||
|
||||
}
|
||||
|
||||
public function filter_deleted_clients($value)
|
||||
{
|
||||
|
||||
if($value == 'true'){
|
||||
|
||||
return $this->builder->whereHas('client', function (Builder $query) {
|
||||
|
||||
$query->where('is_deleted', 0);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return $this->builder;
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ function isActive($page, bool $boolean = false)
|
||||
}
|
||||
|
||||
if ($page == $current_page) {
|
||||
return 'bg-primary-darken';
|
||||
return 'bg-gray-200';
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -72,7 +72,7 @@ class ContactForgotPasswordController extends Controller
|
||||
{
|
||||
//MultiDB::userFindAndSetDb($request->input('email'));
|
||||
|
||||
$user = MultiDB::hasContact(['email' => $request->input('email')]);
|
||||
$user = MultiDB::hasContact($request->input('email'));
|
||||
|
||||
$this->validateEmail($request);
|
||||
|
||||
@ -84,6 +84,10 @@ class ContactForgotPasswordController extends Controller
|
||||
);
|
||||
|
||||
if ($request->ajax()) {
|
||||
|
||||
if($response == Password::RESET_THROTTLED)
|
||||
return response()->json(['message' => ctrans('passwords.throttled'), 'status' => false], 429);
|
||||
|
||||
return $response == Password::RESET_LINK_SENT
|
||||
? response()->json(['message' => 'Reset link sent to your email.', 'status' => true], 201)
|
||||
: response()->json(['message' => 'Email not found', 'status' => false], 401);
|
||||
|
@ -104,9 +104,9 @@ class ForgotPasswordController extends Controller
|
||||
*/
|
||||
public function sendResetLinkEmail(Request $request)
|
||||
{
|
||||
//MultiDB::userFindAndSetDb($request->input('email'));
|
||||
// MultiDB::userFindAndSetDb($request->input('email'));
|
||||
|
||||
$user = MultiDB::hasUser(['email' => $request->input('email')]);
|
||||
// $user = MultiDB::hasUser(['email' => $request->input('email')]);
|
||||
|
||||
$this->validateEmail($request);
|
||||
|
||||
@ -115,9 +115,13 @@ class ForgotPasswordController extends Controller
|
||||
// need to show to the user. Finally, we'll send out a proper response.
|
||||
$response = $this->broker()->sendResetLink(
|
||||
$this->credentials($request)
|
||||
);
|
||||
);
|
||||
|
||||
if ($request->ajax()) {
|
||||
|
||||
if($response == Password::RESET_THROTTLED)
|
||||
return response()->json(['message' => ctrans('passwords.throttled'), 'status' => false], 429);
|
||||
|
||||
return $response == Password::RESET_LINK_SENT
|
||||
? response()->json(['message' => 'Reset link sent to your email.', 'status' => true], 201)
|
||||
: response()->json(['message' => 'Email not found', 'status' => false], 401);
|
||||
|
@ -23,6 +23,7 @@ use App\Libraries\MultiDB;
|
||||
use App\Libraries\OAuth\OAuth;
|
||||
use App\Libraries\OAuth\Providers\Google;
|
||||
use App\Models\Client;
|
||||
use App\Models\Company;
|
||||
use App\Models\CompanyToken;
|
||||
use App\Models\CompanyUser;
|
||||
use App\Models\SystemLog;
|
||||
@ -209,7 +210,7 @@ class LoginController extends BaseController
|
||||
else
|
||||
$timeout = $timeout/1000;
|
||||
|
||||
Cache::put($user->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
Cache::put($user->hashed_id.'_'.$user->account_id.'_logged_in', Str::random(64), $timeout);
|
||||
|
||||
$cu = CompanyUser::query()
|
||||
->where('user_id', auth()->user()->id);
|
||||
@ -236,11 +237,12 @@ class LoginController extends BaseController
|
||||
->batch();
|
||||
|
||||
SystemLogger::dispatch(
|
||||
request()->getClientIp(),
|
||||
json_encode(['ip' => request()->getClientIp()]),
|
||||
SystemLog::CATEGORY_SECURITY,
|
||||
SystemLog::EVENT_USER,
|
||||
SystemLog::TYPE_LOGIN_FAILURE,
|
||||
Client::first(),
|
||||
null,
|
||||
Company::first(),
|
||||
);
|
||||
|
||||
$this->incrementLoginAttempts($request);
|
||||
@ -366,8 +368,7 @@ class LoginController extends BaseController
|
||||
else
|
||||
$timeout = $timeout/1000;
|
||||
|
||||
|
||||
Cache::put($existing_user->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
Cache::put($existing_user->hashed_id.'_'.$existing_user->account_id.'_logged_in', Str::random(64), $timeout);
|
||||
|
||||
$cu = CompanyUser::query()
|
||||
->where('user_id', auth()->user()->id);
|
||||
@ -416,8 +417,7 @@ class LoginController extends BaseController
|
||||
else
|
||||
$timeout = $timeout/1000;
|
||||
|
||||
|
||||
Cache::put(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
Cache::put(auth()->user()->hashed_id.'_'.auth()->user()->account_id.'_logged_in', Str::random(64), $timeout);
|
||||
|
||||
$cu = CompanyUser::whereUserId(auth()->user()->id);
|
||||
|
||||
|
@ -189,10 +189,7 @@ class BaseController extends Controller
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
if ($user->getCompany()->is_large)
|
||||
$this->manager->parseIncludes($this->mini_load);
|
||||
else
|
||||
$this->manager->parseIncludes($this->first_load);
|
||||
$this->manager->parseIncludes($this->first_load);
|
||||
|
||||
$this->serializer = request()->input('serializer') ?: EntityTransformer::API_SERIALIZER_ARRAY;
|
||||
|
||||
@ -366,13 +363,92 @@ class BaseController extends Controller
|
||||
return $this->response($this->manager->createData($resource)->toArray());
|
||||
}
|
||||
|
||||
protected function miniLoadResponse($query)
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
|
||||
$this->serializer = request()->input('serializer') ?: EntityTransformer::API_SERIALIZER_ARRAY;
|
||||
|
||||
if ($this->serializer === EntityTransformer::API_SERIALIZER_JSON) {
|
||||
$this->manager->setSerializer(new JsonApiSerializer());
|
||||
} else {
|
||||
$this->manager->setSerializer(new ArraySerializer());
|
||||
}
|
||||
|
||||
$transformer = new $this->entity_transformer($this->serializer);
|
||||
$created_at = request()->has('created_at') ? request()->input('created_at') : 0;
|
||||
|
||||
$created_at = date('Y-m-d H:i:s', $created_at);
|
||||
|
||||
$query->with(
|
||||
[
|
||||
'company' => function ($query) use ($created_at, $user) {
|
||||
$query->whereNotNull('created_at')->with('documents');
|
||||
},
|
||||
'company.designs'=> function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at)->with('company');
|
||||
|
||||
if(!$user->isAdmin())
|
||||
$query->where('designs.user_id', $user->id);
|
||||
},
|
||||
'company.documents'=> function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at);
|
||||
},
|
||||
'company.groups' => function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at);
|
||||
|
||||
if(!$user->isAdmin())
|
||||
$query->where('group_settings.user_id', $user->id);
|
||||
},
|
||||
'company.payment_terms'=> function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at);
|
||||
|
||||
if(!$user->isAdmin())
|
||||
$query->where('payment_terms.user_id', $user->id);
|
||||
|
||||
},
|
||||
'company.tax_rates' => function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at);
|
||||
|
||||
if(!$user->isAdmin())
|
||||
$query->where('tax_rates.user_id', $user->id);
|
||||
|
||||
},
|
||||
'company.activities'=> function ($query) use($user) {
|
||||
|
||||
if(!$user->isAdmin())
|
||||
$query->where('activities.user_id', $user->id);
|
||||
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
if ($query instanceof Builder) {
|
||||
$limit = request()->input('per_page', 20);
|
||||
|
||||
$paginator = $query->paginate($limit);
|
||||
$query = $paginator->getCollection();
|
||||
$resource = new Collection($query, $transformer, $this->entity_type);
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
} else {
|
||||
$resource = new Collection($query, $transformer, $this->entity_type);
|
||||
}
|
||||
|
||||
return $this->response($this->manager->createData($resource)->toArray());
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected function timeConstrainedResponse($query)
|
||||
{
|
||||
|
||||
$user = auth()->user();
|
||||
|
||||
if ($user->getCompany()->is_large)
|
||||
if ($user->getCompany()->is_large){
|
||||
$this->manager->parseIncludes($this->mini_load);
|
||||
return $this->miniLoadResponse($query);
|
||||
}
|
||||
else
|
||||
$this->manager->parseIncludes($this->first_load);
|
||||
|
||||
|
@ -24,12 +24,12 @@ class ContactHashLoginController extends Controller
|
||||
*/
|
||||
public function login(string $contact_key)
|
||||
{
|
||||
return redirect('/client/login');
|
||||
return redirect('/client/invoices');
|
||||
}
|
||||
|
||||
public function magicLink(string $magic_link)
|
||||
{
|
||||
return redirect('/client/login');
|
||||
return redirect('/client/invoices');
|
||||
}
|
||||
|
||||
public function errorPage()
|
||||
|
@ -22,8 +22,15 @@ class CreditController extends Controller
|
||||
|
||||
public function show(ShowCreditRequest $request, Credit $credit)
|
||||
{
|
||||
return $this->render('credits.show', [
|
||||
'credit' => $credit,
|
||||
]);
|
||||
set_time_limit(0);
|
||||
|
||||
$data = ['credit' => $credit];
|
||||
|
||||
|
||||
if ($request->query('mode') === 'fullscreen') {
|
||||
return render('credits.show-fullscreen', $data);
|
||||
}
|
||||
|
||||
return $this->render('credits.show', $data);
|
||||
}
|
||||
}
|
||||
|
@ -164,10 +164,10 @@ class InvoiceController extends Controller
|
||||
|
||||
//if only 1 pdf, output to buffer for download
|
||||
if ($invoices->count() == 1) {
|
||||
return response()->streamDownload(function () use ($invoices) {
|
||||
echo file_get_contents($invoices->first()->pdf_file_path());
|
||||
}, basename($invoices->first()->pdf_file_path()), ['Cache-Control:' => 'no-cache']);
|
||||
//return response()->download(TempFile::path($invoices->first()->pdf_file_path()), basename($invoices->first()->pdf_file_path()));
|
||||
|
||||
$file = $invoices->first()->pdf_file_path();
|
||||
return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);;
|
||||
|
||||
}
|
||||
|
||||
// enable output of HTTP headers
|
||||
|
@ -290,7 +290,8 @@ class PaymentController extends Controller
|
||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||
SystemLog::EVENT_GATEWAY_ERROR,
|
||||
SystemLog::TYPE_FAILURE,
|
||||
auth('contact')->user()->client
|
||||
auth('contact')->user()->client,
|
||||
auth('contact')->user()->client->company
|
||||
);
|
||||
|
||||
throw new PaymentFailed($e->getMessage());
|
||||
|
@ -76,10 +76,9 @@ class QuoteController extends Controller
|
||||
}
|
||||
|
||||
if ($quotes->count() == 1) {
|
||||
return response()->streamDownload(function () use ($quotes) {
|
||||
echo file_get_contents($quotes->first()->pdf_file_path());
|
||||
}, basename($quotes->first()->pdf_file_path()), ['Cache-Control:' => 'no-cache']);
|
||||
//return response()->download(TempFile::path($invoices->first()->pdf_file_path()), basename($quotes->first()->pdf_file_path()));
|
||||
|
||||
$file = $quotes->first()->pdf_file_path();
|
||||
return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
||||
}
|
||||
|
||||
// enable output of HTTP headers
|
||||
|
34
app/Http/Controllers/ClientPortal/TaskController.php
Normal file
34
app/Http/Controllers/ClientPortal/TaskController.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers\ClientPortal;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\ClientPortal\Tasks\ShowTasksRequest;
|
||||
|
||||
class TaskController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show the tasks in the client portal.
|
||||
*
|
||||
* @param ShowTasksRequest $request
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*/
|
||||
public function index(ShowTasksRequest $request)
|
||||
{
|
||||
\Carbon\Carbon::setLocale(
|
||||
auth('contact')->user()->preferredLocale()
|
||||
);
|
||||
|
||||
return render('tasks.index');
|
||||
}
|
||||
}
|
@ -114,7 +114,7 @@ class ConnectedAccountController extends BaseController
|
||||
auth()->user()->save();
|
||||
|
||||
$timeout = auth()->user()->company()->default_password_timeout;
|
||||
Cache::put(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
Cache::put(auth()->user()->hashed_id.'_'.auth()->user()->account_id.'_logged_in', Str::random(64), $timeout);
|
||||
|
||||
return $this->itemResponse(auth()->user());
|
||||
|
||||
@ -160,6 +160,9 @@ class ConnectedAccountController extends BaseController
|
||||
'email_verified_at' =>now()
|
||||
];
|
||||
|
||||
if(auth()->user()->email != $google->harvestEmail($user))
|
||||
return response()->json(['message' => 'Primary Email differs to OAuth email. Emails must match.'], 400);
|
||||
|
||||
auth()->user()->update($connected_account);
|
||||
auth()->user()->email_verified_at = now();
|
||||
auth()->user()->save();
|
||||
|
@ -535,11 +535,9 @@ class CreditController extends BaseController
|
||||
return $this->itemResponse($credit);
|
||||
}
|
||||
break;
|
||||
case 'download':
|
||||
return response()->streamDownload(function () use ($credit) {
|
||||
echo file_get_contents($credit->pdf_file_path());
|
||||
}, basename($credit->pdf_file_path()), ['Cache-Control:' => 'no-cache']);
|
||||
//return response()->download(TempFile::path($credit->pdf_file_path()), basename($credit->pdf_file_path()));
|
||||
case 'download':
|
||||
$file = $credit->pdf_file_path();
|
||||
return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
||||
break;
|
||||
case 'archive':
|
||||
$this->credit_repository->archive($credit);
|
||||
@ -589,7 +587,7 @@ class CreditController extends BaseController
|
||||
|
||||
$file_path = $credit->service()->getCreditPdf($invitation);
|
||||
|
||||
return response()->download($file_path, basename($file_path), ['Cache-Control:' => 'no-cache']);
|
||||
return response()->download($file_path, basename($file_path), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
64
app/Http/Controllers/ExportController.php
Normal file
64
app/Http/Controllers/ExportController.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\Export\StoreExportRequest;
|
||||
use App\Jobs\Company\CompanyExport;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Http\Response;
|
||||
|
||||
class ExportController extends BaseController
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Post(
|
||||
* path="/api/v1/export",
|
||||
* operationId="getExport",
|
||||
* tags={"export"},
|
||||
* summary="Export data from the system",
|
||||
* description="Export data from the system",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="success",
|
||||
* @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"),
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function index(StoreExportRequest $request)
|
||||
{
|
||||
|
||||
CompanyExport::dispatch(auth()->user()->getCompany(), auth()->user());
|
||||
|
||||
return response()->json(['message' => 'Processing'], 200);
|
||||
|
||||
}
|
||||
}
|
@ -671,10 +671,10 @@ class InvoiceController extends BaseController
|
||||
}
|
||||
break;
|
||||
case 'download':
|
||||
return response()->streamDownload(function () use ($invoice) {
|
||||
echo file_get_contents($invoice->pdf_file_path());
|
||||
}, basename($invoice->pdf_file_path()), ['Cache-Control:' => 'no-cache']);
|
||||
//return response()->download(TempFile::path($invoice->pdf_file_path()), basename($invoice->pdf_file_path()));
|
||||
|
||||
$file = $invoice->pdf_file_path();
|
||||
return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
||||
|
||||
break;
|
||||
case 'restore':
|
||||
$this->invoice_repo->restore($invoice);
|
||||
@ -793,9 +793,10 @@ class InvoiceController extends BaseController
|
||||
$contact = $invitation->contact;
|
||||
$invoice = $invitation->invoice;
|
||||
|
||||
$file_path = $invoice->service()->getInvoicePdf($contact);
|
||||
$file = $invoice->service()->getInvoicePdf($contact);
|
||||
|
||||
return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);;
|
||||
|
||||
return response()->download($file_path, basename($file_path), ['Cache-Control:' => 'no-cache']);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -844,13 +845,10 @@ class InvoiceController extends BaseController
|
||||
*/
|
||||
public function deliveryNote(ShowInvoiceRequest $request, Invoice $invoice)
|
||||
{
|
||||
$file_path = $invoice->service()->getInvoiceDeliveryNote($invoice, $invoice->invitations->first()->contact);
|
||||
$file = $invoice->service()->getInvoiceDeliveryNote($invoice, $invoice->invitations->first()->contact);
|
||||
|
||||
try {
|
||||
$file = public_path("storage/{$file_path}");
|
||||
|
||||
|
||||
return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache']);
|
||||
return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
||||
} catch (\Exception $e) {
|
||||
return response(['message' => 'Oops, something went wrong. Make sure you have symlink to storage/ in public/ directory.'], 500);
|
||||
}
|
||||
|
@ -107,6 +107,12 @@ class LicenseController extends BaseController
|
||||
'errors' => new stdClass,
|
||||
];
|
||||
|
||||
$account->plan_term = Account::PLAN_TERM_YEARLY;
|
||||
$account->plan_paid = null;
|
||||
$account->plan_expires = null;
|
||||
$account->plan = Account::PLAN_FREE;
|
||||
$account->save();
|
||||
|
||||
return response()->json($error, 400);
|
||||
} else {
|
||||
$account = auth()->user()->company()->account;
|
||||
|
@ -25,7 +25,6 @@ class OneTimeTokenController extends BaseController
|
||||
{
|
||||
|
||||
private $contexts = [
|
||||
'stripe_connect' => 'https://connect.stripe.com/oauth/authorize?response_type=code&client_id=ca_J2Fh2tZfMlaaItUfbUwBBx4JPss8jCz9&scope=read_write'
|
||||
];
|
||||
|
||||
public function __construct()
|
||||
|
@ -21,13 +21,18 @@ class PaymentWebhookController extends Controller
|
||||
public function __invoke(PaymentWebhookRequest $request, string $company_key, string $company_gateway_id)
|
||||
{
|
||||
|
||||
MultiDB::findAndSetDbByCompanyKey($company_key);
|
||||
// MultiDB::findAndSetDbByCompanyKey($company_key);
|
||||
|
||||
$payment = $request->getPayment();
|
||||
|
||||
if(!$payment)
|
||||
return response()->json(['message' => 'Payment record not found.'], 400);
|
||||
|
||||
$client = is_null($payment) ? $request->getClient() : $payment->client;
|
||||
|
||||
// $contact= $client->primary_contact()->first();
|
||||
// Auth::guard('contact')->login($contact, true);
|
||||
if(!$client)
|
||||
return response()->json(['message' => 'Client record not found.'], 400);
|
||||
|
||||
|
||||
return $request->getCompanyGateway()
|
||||
->driver($client)
|
||||
|
@ -125,7 +125,13 @@ class PostMarkController extends BaseController
|
||||
$this->invitation->email_status = 'delivered';
|
||||
$this->invitation->save();
|
||||
|
||||
SystemLogger::dispatch($request->all(), SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_DELIVERY, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client);
|
||||
SystemLogger::dispatch($request->all(),
|
||||
SystemLog::CATEGORY_MAIL,
|
||||
SystemLog::EVENT_MAIL_DELIVERY,
|
||||
SystemLog::TYPE_WEBHOOK_RESPONSE,
|
||||
$this->invitation->contact->client,
|
||||
$this->invitation->company
|
||||
);
|
||||
}
|
||||
|
||||
// {
|
||||
@ -167,7 +173,7 @@ class PostMarkController extends BaseController
|
||||
|
||||
LightLogs::create($bounce)->batch();
|
||||
|
||||
SystemLogger::dispatch($request->all(), SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_BOUNCED, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client);
|
||||
SystemLogger::dispatch($request->all(), SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_BOUNCED, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client, $this->invitation->company);
|
||||
}
|
||||
|
||||
// {
|
||||
@ -209,7 +215,7 @@ class PostMarkController extends BaseController
|
||||
|
||||
LightLogs::create($bounce)->batch();
|
||||
|
||||
SystemLogger::dispatch($request->all(), SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_SPAM_COMPLAINT, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client);
|
||||
SystemLogger::dispatch($request->all(), SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_SPAM_COMPLAINT, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client, $this->invitation->company);
|
||||
}
|
||||
|
||||
private function discoverInvitation($message_id)
|
||||
|
@ -675,10 +675,10 @@ class QuoteController extends BaseController
|
||||
// code...
|
||||
break;
|
||||
case 'download':
|
||||
return response()->streamDownload(function () use ($quote) {
|
||||
echo file_get_contents($quote->pdf_file_path());
|
||||
}, basename($quote->pdf_file_path()), ['Cache-Control:' => 'no-cache']);
|
||||
//return response()->download(TempFile::path($quote->pdf_file_path()), basename($quote->pdf_file_path()));
|
||||
|
||||
$file = $quote->pdf_file_path();
|
||||
return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
||||
|
||||
break;
|
||||
case 'restore':
|
||||
$this->quote_repo->restore($quote);
|
||||
@ -730,7 +730,7 @@ class QuoteController extends BaseController
|
||||
|
||||
$file_path = $quote->service()->getQuotePdf($contact);
|
||||
|
||||
return response()->download($file_path, basename($file_path), ['Cache-Control:' => 'no-cache']);
|
||||
return response()->download($file_path, basename($file_path), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -497,7 +497,7 @@ class RecurringInvoiceController extends BaseController
|
||||
|
||||
$file_path = $recurring_invoice->service()->getInvoicePdf($contact);
|
||||
|
||||
return response()->download($file_path, basename($file_path), ['Cache-Control:' => 'no-cache']);
|
||||
return response()->download($file_path, basename($file_path), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -275,7 +275,9 @@ class SetupController extends Controller
|
||||
|
||||
public function update()
|
||||
{
|
||||
|
||||
// if(Ninja::isHosted())
|
||||
// return redirect('/');
|
||||
|
||||
// if( Ninja::isNinja() || !request()->has('secret') || (request()->input('secret') != config('ninja.update_secret')) )
|
||||
if(!request()->has('secret') || (request()->input('secret') != config('ninja.update_secret')) )
|
||||
return redirect('/');
|
||||
@ -290,6 +292,11 @@ class SetupController extends Controller
|
||||
unlink ($cacheServices);
|
||||
}
|
||||
|
||||
$cacheRoute = base_path('bootstrap/cache/routes-v7.php');
|
||||
if (file_exists($cacheRoute)) {
|
||||
unlink ($cacheRoute);
|
||||
}
|
||||
|
||||
Artisan::call('clear-compiled');
|
||||
Artisan::call('route:clear');
|
||||
Artisan::call('view:clear');
|
||||
|
@ -17,8 +17,11 @@ use App\Factory\CompanyGatewayFactory;
|
||||
use App\Http\Requests\StripeConnect\InitializeStripeConnectRequest;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Client;
|
||||
use App\Models\Company;
|
||||
use App\Models\CompanyGateway;
|
||||
use App\Models\GatewayType;
|
||||
use App\PaymentDrivers\Stripe\Connect\Account;
|
||||
use Illuminate\Http\Request;
|
||||
use Stripe\Exception\ApiErrorException;
|
||||
|
||||
class StripeConnectController extends BaseController
|
||||
@ -38,6 +41,8 @@ class StripeConnectController extends BaseController
|
||||
|
||||
MultiDB::findAndSetDbByCompanyKey($request->getTokenContent()['company_key']);
|
||||
|
||||
$company = Company::where('company_key', $request->getTokenContent()['company_key'])->first();
|
||||
|
||||
$company_gateway = CompanyGateway::query()
|
||||
->where('gateway_key', 'd14dd26a47cecc30fdd65700bfb67b34')
|
||||
->where('company_id', $request->getCompany()->id)
|
||||
@ -45,53 +50,84 @@ class StripeConnectController extends BaseController
|
||||
|
||||
if ($company_gateway) {
|
||||
|
||||
$config = decrypt($company_gateway->config);
|
||||
$config = $company_gateway->getConfig();
|
||||
|
||||
if(property_exists($config, 'account_id'))
|
||||
return render('gateways.stripe.connect.existing');
|
||||
|
||||
}
|
||||
else
|
||||
$company_gateway = CompanyGatewayFactory::create($request->getCompany()->id, $request->getContact()->id);
|
||||
return view('auth.connect.existing');
|
||||
|
||||
/* Set Credit Card To Enabled */
|
||||
$gateway_types = $company_gateway->driver(new Client)->gatewayTypes();
|
||||
$fees_and_limits = new \stdClass;
|
||||
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits;
|
||||
|
||||
$company_gateway->gateway_key = 'd14dd26a47cecc30fdd65700bfb67b34';
|
||||
$company_gateway->fees_and_limits = $fees_and_limits;
|
||||
$company_gateway->save();
|
||||
|
||||
/* Link account if existing account exists */
|
||||
if($account_id = $this->checkAccountAlreadyLinkToEmail($company_gateway, $request->getContact()->email)) {
|
||||
|
||||
$config = json_decode(decrypt($company_gateway->config));
|
||||
|
||||
$config->account_id = $account_id;
|
||||
$company_gateway->config = encrypt(json_encode($config));
|
||||
$company_gateway->save();
|
||||
|
||||
return render('gateways.stripe.connect.existing');
|
||||
}
|
||||
|
||||
$data = [
|
||||
'type' => 'standard',
|
||||
'email' => $request->getContact()->email,
|
||||
'country' => $request->getCompany()->country()->iso_3166_2,
|
||||
];
|
||||
$stripe_client_id = config('ninja.ninja_stripe_client_id');
|
||||
$redirect_uri = 'https://invoicing.co/stripe/completed';
|
||||
$endpoint = "https://connect.stripe.com/oauth/authorize?response_type=code&client_id={$stripe_client_id}&redirect_uri={$redirect_uri}&scope=read_write&state={$token}";
|
||||
|
||||
$account = Account::create($data);
|
||||
$link = Account::link($account->id, $token);
|
||||
$company_gateway->config = encrypt(json_encode(['account_id' => $account->id]));
|
||||
$company_gateway->save();
|
||||
// if($email = $request->getContact()->email)
|
||||
// $endpoint .= "&stripe_user[email]={$email}";
|
||||
|
||||
return redirect($link['url']);
|
||||
// $company_name = str_replace(" ", "_", $company->present()->name());
|
||||
// $endpoint .= "&stripe_user[business_name]={$company_name}";
|
||||
|
||||
return redirect($endpoint);
|
||||
}
|
||||
|
||||
public function completed()
|
||||
public function completed(InitializeStripeConnectRequest $request)
|
||||
{
|
||||
return render('gateways.stripe.connect.completed');
|
||||
|
||||
\Stripe\Stripe::setApiKey(config('ninja.ninja_stripe_key'));
|
||||
|
||||
try {
|
||||
$response = \Stripe\OAuth::token([
|
||||
'grant_type' => 'authorization_code',
|
||||
'code' => $request->input('code'),
|
||||
]);
|
||||
|
||||
}catch(\Exception $e)
|
||||
{
|
||||
|
||||
nlog($e->getMessage());
|
||||
|
||||
}
|
||||
|
||||
// nlog($response);
|
||||
|
||||
$company = Company::where('company_key', $request->getTokenContent()['company_key'])->first();
|
||||
|
||||
$company_gateway = CompanyGatewayFactory::create($company->id, $company->owner()->id);
|
||||
$fees_and_limits = new \stdClass;
|
||||
$fees_and_limits->{GatewayType::CREDIT_CARD} = new FeesAndLimits;
|
||||
$company_gateway->gateway_key = 'd14dd26a47cecc30fdd65700bfb67b34';
|
||||
$company_gateway->fees_and_limits = $fees_and_limits;
|
||||
$company_gateway->setConfig([]);
|
||||
// $company_gateway->save();
|
||||
|
||||
$payload = [
|
||||
'account_id' => $response->stripe_user_id,
|
||||
"token_type" => 'bearer',
|
||||
"stripe_publishable_key" => $response->stripe_publishable_key,
|
||||
"scope" => $response->scope,
|
||||
"livemode" => $response->livemode,
|
||||
"stripe_user_id" => $response->stripe_user_id,
|
||||
"refresh_token" => $response->refresh_token,
|
||||
"access_token" => $response->access_token
|
||||
];
|
||||
|
||||
/* Link account if existing account exists */
|
||||
// if($account_id = $this->checkAccountAlreadyLinkToEmail($company_gateway, $request->getContact()->email)) {
|
||||
|
||||
// $payload['account_id'] = $account_id;
|
||||
// $payload['stripe_user_id'] = $account_id;
|
||||
// $company_gateway->setConfig($payload);
|
||||
// $company_gateway->save();
|
||||
|
||||
// return view('auth.connect.existing');
|
||||
|
||||
// }
|
||||
|
||||
$company_gateway->setConfig($payload);
|
||||
$company_gateway->save();
|
||||
|
||||
//response here
|
||||
return view('auth.connect.completed');
|
||||
}
|
||||
|
||||
|
||||
@ -111,4 +147,22 @@ class StripeConnectController extends BaseController
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*********************************
|
||||
* Stripe OAuth
|
||||
*/
|
||||
|
||||
// public function initialize(InitializeStripeConnectRequest $request, string $token)
|
||||
// {
|
||||
|
||||
// $stripe_key = config('ninja.ninja_stripe_key');
|
||||
|
||||
// $endpoint = "https://connect.stripe.com/oauth/authorize?response_type=code&client_id={$stripe_key}&scope=read_write";
|
||||
|
||||
// return redirect($endpoint);
|
||||
|
||||
// }
|
||||
}
|
||||
|
52
app/Http/Controllers/StripeController.php
Normal file
52
app/Http/Controllers/StripeController.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Jobs\Util\ImportStripeCustomers;
|
||||
use App\Jobs\Util\StripeUpdatePaymentMethods;
|
||||
|
||||
class StripeController extends BaseController
|
||||
{
|
||||
|
||||
public function update()
|
||||
{
|
||||
if(auth()->user()->isAdmin())
|
||||
{
|
||||
|
||||
StripeUpdatePaymentMethods::dispatch(auth()->user()->company());
|
||||
|
||||
return response()->json(['message' => 'Processing'], 200);
|
||||
|
||||
}
|
||||
|
||||
|
||||
return response()->json(['message' => 'Unauthorized'], 403);
|
||||
}
|
||||
|
||||
public function import()
|
||||
{
|
||||
|
||||
if(auth()->user()->isAdmin())
|
||||
{
|
||||
|
||||
ImportStripeCustomers::dispatch(auth()->user()->company());
|
||||
|
||||
return response()->json(['message' => 'Processing'], 200);
|
||||
|
||||
}
|
||||
|
||||
|
||||
return response()->json(['message' => 'Unauthorized'], 403);
|
||||
}
|
||||
|
||||
}
|
@ -41,7 +41,7 @@ class SubdomainController extends BaseController
|
||||
public function index()
|
||||
{
|
||||
|
||||
if(in_array(request()->input('subdomain'), $this->protected) || MultiDB::findAndSetDbByDomain(request()->input('subdomain')))
|
||||
if(in_array(request()->input('subdomain'), $this->protected) || MultiDB::findAndSetDbByDomain(['subdomain' => request()->input('subdomain')]))
|
||||
return response()->json(['message' => 'Domain not available'] , 401);
|
||||
|
||||
return response()->json(['message' => 'Domain available'], 200);
|
||||
|
@ -63,9 +63,11 @@ class UserController extends BaseController
|
||||
*/
|
||||
public function __construct(UserRepository $user_repo)
|
||||
{
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$this->user_repo = $user_repo;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -376,7 +378,6 @@ class UserController extends BaseController
|
||||
*/
|
||||
public function update(UpdateUserRequest $request, User $user)
|
||||
{
|
||||
|
||||
$old_company_user = $user->company_user;
|
||||
$old_user = json_encode($user);
|
||||
$old_user_email = $user->getOriginal('email');
|
||||
|
@ -110,7 +110,6 @@ class Kernel extends HttpKernel
|
||||
ShareErrorsFromSession::class,
|
||||
VerifyCsrfToken::class,
|
||||
SubstituteBindings::class,
|
||||
//\App\Http\Middleware\StartupCheck::class,
|
||||
QueryLogging::class,
|
||||
],
|
||||
'shop' => [
|
||||
@ -160,4 +159,28 @@ class Kernel extends HttpKernel
|
||||
'check_client_existence' => CheckClientExistence::class,
|
||||
'user_verified' => UserVerified::class,
|
||||
];
|
||||
|
||||
|
||||
protected $middlewarePriority = [
|
||||
SetDomainNameDb::class,
|
||||
SetDb::class,
|
||||
SetWebDb::class,
|
||||
UrlSetDb::class,
|
||||
ContactSetDb::class,
|
||||
SetEmailDb::class,
|
||||
SetInviteDb::class,
|
||||
SetDbByCompanyKey::class,
|
||||
TokenAuth::class,
|
||||
ContactTokenAuth::class,
|
||||
ContactKeyLogin::class,
|
||||
Authenticate::class,
|
||||
ShopTokenAuth::class,
|
||||
ContactRegister::class,
|
||||
PhantomSecret::class,
|
||||
CheckClientExistence::class,
|
||||
ClientPortalEnabled::class,
|
||||
PasswordProtection::class,
|
||||
Locale::class,
|
||||
SubstituteBindings::class,
|
||||
];
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ class NameWebsiteLogo extends Component
|
||||
public $profile;
|
||||
|
||||
public $name;
|
||||
public $vat_number;
|
||||
public $website;
|
||||
public $phone;
|
||||
|
||||
@ -16,6 +17,7 @@ class NameWebsiteLogo extends Component
|
||||
|
||||
public $rules = [
|
||||
'name' => ['sometimes', 'min:3'],
|
||||
'vat_number' => ['sometimes'],
|
||||
'website' => ['sometimes'],
|
||||
'phone' => ['sometimes', 'string', 'max:255'],
|
||||
];
|
||||
@ -25,6 +27,7 @@ class NameWebsiteLogo extends Component
|
||||
$this->fill([
|
||||
'profile' => auth()->user('contact')->client,
|
||||
'name' => auth()->user('contact')->client->present()->name,
|
||||
'vat_number' => auth()->user('contact')->client->present()->vat_number,
|
||||
'website' => auth()->user('contact')->client->present()->website,
|
||||
'phone' => auth()->user('contact')->client->present()->phone,
|
||||
'saved' => ctrans('texts.save'),
|
||||
@ -41,6 +44,7 @@ class NameWebsiteLogo extends Component
|
||||
$data = $this->validate($this->rules);
|
||||
|
||||
$this->profile->name = $data['name'];
|
||||
$this->profile->vat_number = $data['vat_number'];
|
||||
$this->profile->website = $data['website'];
|
||||
$this->profile->phone = $data['phone'];
|
||||
|
||||
|
39
app/Http/Livewire/TasksTable.php
Normal file
39
app/Http/Livewire/TasksTable.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Models\Task;
|
||||
use App\Utils\Traits\WithSorting;
|
||||
use Livewire\Component;
|
||||
use Livewire\WithPagination;
|
||||
|
||||
class TasksTable extends Component
|
||||
{
|
||||
use WithSorting;
|
||||
use WithPagination;
|
||||
|
||||
public $per_page = 10;
|
||||
|
||||
public function render()
|
||||
{
|
||||
$query = Task::query()
|
||||
->where('client_id', auth('contact')->user()->client->id)
|
||||
->whereNotNull('invoice_id')
|
||||
->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc')
|
||||
->paginate($this->per_page);
|
||||
|
||||
return render('components.livewire.tasks-table', [
|
||||
'tasks' => $query,
|
||||
]);
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Utils\Ninja;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use stdClass;
|
||||
@ -26,7 +27,7 @@ class ApiSecretCheck
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if (! config('ninja.api_secret')) {
|
||||
if (! config('ninja.api_secret') || Ninja::isHosted()) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ class CheckClientExistence
|
||||
$multiple_contacts = ClientContact::query()
|
||||
->where('email', auth('contact')->user()->email)
|
||||
->whereNotNull('email')
|
||||
->where('email', '<>', '')
|
||||
->whereNull('deleted_at')
|
||||
->distinct('company_id')
|
||||
->distinct('email')
|
||||
@ -38,6 +39,9 @@ class CheckClientExistence
|
||||
->whereHas('client', function ($query) {
|
||||
return $query->whereNull('deleted_at');
|
||||
})
|
||||
->whereHas('client.company', function ($query){
|
||||
return $query->where('account_id', auth('contact')->user()->client->company->account->id);
|
||||
})
|
||||
->get();
|
||||
|
||||
if (count($multiple_contacts) == 0) {
|
||||
|
@ -42,7 +42,7 @@ class ContactKeyLogin
|
||||
if (MultiDB::findAndSetDbByContactKey($request->segment(3))) {
|
||||
|
||||
if($client_contact = ClientContact::where('contact_key', $request->segment(3))->first()){
|
||||
auth()->guard('contact')->login($client_contact, true);
|
||||
Auth::guard('contact')->login($client_contact, true);
|
||||
return redirect()->to('client/dashboard');
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ class PasswordProtection
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
|
||||
|
||||
$error = [
|
||||
'message' => 'Invalid Password',
|
||||
'errors' => new stdClass,
|
||||
@ -44,9 +44,9 @@ class PasswordProtection
|
||||
else
|
||||
$timeout = $timeout/1000;
|
||||
|
||||
if (Cache::get(auth()->user()->hashed_id.'_logged_in')) {
|
||||
if (Cache::get(auth()->user()->hashed_id.'_'.auth()->user()->account_id.'_logged_in')) {
|
||||
|
||||
Cache::put(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
Cache::put(auth()->user()->hashed_id.'_'.auth()->user()->account_id.'_logged_in', Str::random(64), $timeout);
|
||||
|
||||
return $next($request);
|
||||
|
||||
@ -68,12 +68,13 @@ class PasswordProtection
|
||||
//If OAuth and user also has a password set - check both
|
||||
if ($existing_user = MultiDB::hasUser($query) && auth()->user()->has_password && Hash::check(auth()->user()->password, $request->header('X-API-PASSWORD'))) {
|
||||
|
||||
Cache::put(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
Cache::put(auth()->user()->hashed_id.'_'.auth()->user()->account_id.'_logged_in', Str::random(64), $timeout);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
elseif($existing_user = MultiDB::hasUser($query) && !auth()->user()->has_password){
|
||||
|
||||
Cache::put(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
Cache::put(auth()->user()->hashed_id.'_'.auth()->user()->account_id.'_logged_in', Str::random(64), $timeout);
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@ -83,7 +84,7 @@ class PasswordProtection
|
||||
|
||||
}elseif ($request->header('X-API-PASSWORD') && Hash::check($request->header('X-API-PASSWORD'), auth()->user()->password)) {
|
||||
|
||||
Cache::put(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
Cache::put(auth()->user()->hashed_id.'_'.auth()->user()->account_id.'_logged_in', Str::random(64), $timeout);
|
||||
|
||||
return $next($request);
|
||||
|
||||
|
@ -34,14 +34,16 @@ class RedirectIfAuthenticated
|
||||
}
|
||||
break;
|
||||
case 'user':
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect()->route('dashboard.index');
|
||||
}
|
||||
Auth::logout();
|
||||
// if (Auth::guard($guard)->check()) {
|
||||
// return redirect()->route('dashboard.index');
|
||||
// }
|
||||
break;
|
||||
default:
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect('/');
|
||||
}
|
||||
Auth::logout();
|
||||
// if (Auth::guard($guard)->check()) {
|
||||
// return redirect('/');
|
||||
// }
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@ class SetDb
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
|
||||
$error = [
|
||||
'message' => 'Invalid Token',
|
||||
'errors' => new stdClass,
|
||||
|
@ -34,13 +34,50 @@ class SetDomainNameDb
|
||||
/*
|
||||
* Use the host name to set the active DB
|
||||
**/
|
||||
if ($request->getSchemeAndHttpHost() && config('ninja.db.multi_db_enabled') && ! MultiDB::findAndSetDbByDomain($request->getSchemeAndHttpHost())) {
|
||||
if (request()->json) {
|
||||
return response()->json($error, 403);
|
||||
} else {
|
||||
abort(404);
|
||||
|
||||
if(!config('ninja.db.multi_db_enabled'))
|
||||
return $next($request);
|
||||
|
||||
|
||||
if (strpos($request->getHost(), 'invoicing.co') !== false)
|
||||
{
|
||||
$subdomain = explode('.', $request->getHost())[0];
|
||||
|
||||
$query = [
|
||||
'subdomain' => $subdomain,
|
||||
'portal_mode' => 'subdomain',
|
||||
];
|
||||
|
||||
if(!MultiDB::findAndSetDbByDomain($query)){
|
||||
if ($request->json) {
|
||||
return response()->json($error, 403);
|
||||
} else {
|
||||
MultiDB::setDb('db-ninja-01');
|
||||
nlog("I could not set the DB - defaulting to DB1");
|
||||
//abort(400, 'Domain not found');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
$query = [
|
||||
'portal_domain' => $request->getSchemeAndHttpHost(),
|
||||
'portal_mode' => 'domain',
|
||||
];
|
||||
|
||||
if(!MultiDB::findAndSetDbByDomain($query)){
|
||||
if ($request->json) {
|
||||
return response()->json($error, 403);
|
||||
} else {
|
||||
MultiDB::setDb('db-ninja-01');
|
||||
nlog("I could not set the DB - defaulting to DB1");
|
||||
//abort(400, 'Domain not found');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@ -34,15 +34,10 @@ class SetEmailDb
|
||||
|
||||
if ($request->input('email') && config('ninja.db.multi_db_enabled')) {
|
||||
|
||||
|
||||
if (! MultiDB::userFindAndSetDb($request->input('email')))
|
||||
return response()->json($error, 400);
|
||||
|
||||
|
||||
}
|
||||
// else {
|
||||
// return response()->json($error, 403);
|
||||
// }
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ class SetInviteDb
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$error = [
|
||||
'message' => 'Invalid URL',
|
||||
'message' => 'I could not find the database for this object.',
|
||||
'errors' => new stdClass,
|
||||
];
|
||||
/*
|
||||
@ -46,7 +46,7 @@ class SetInviteDb
|
||||
if (request()->json) {
|
||||
return response()->json($error, 403);
|
||||
} else {
|
||||
abort(404);
|
||||
abort(404,'I could not find the database for this object.');
|
||||
}
|
||||
}
|
||||
|
||||
|
30
app/Http/Requests/ClientPortal/Tasks/ShowTasksRequest.php
Normal file
30
app/Http/Requests/ClientPortal/Tasks/ShowTasksRequest.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\ClientPortal\Tasks;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ShowTasksRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return (bool)auth()->user('contact')->client->getSetting('enable_client_portal_tasks');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
@ -14,8 +14,10 @@ namespace App\Http\Requests\Company;
|
||||
use App\DataMapper\CompanySettings;
|
||||
use App\Http\Requests\Request;
|
||||
use App\Http\ValidationRules\Company\ValidCompanyQuantity;
|
||||
use App\Http\ValidationRules\Company\ValidSubdomain;
|
||||
use App\Http\ValidationRules\ValidSettingsRule;
|
||||
use App\Models\Company;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
class StoreCompanyRequest extends Request
|
||||
@ -45,7 +47,13 @@ class StoreCompanyRequest extends Request
|
||||
if (isset($input['portal_mode']) && ($input['portal_mode'] == 'domain' || $input['portal_mode'] == 'iframe')) {
|
||||
$rules['portal_domain'] = 'sometimes|url';
|
||||
} else {
|
||||
$rules['subdomain'] = 'nullable|alpha_num';
|
||||
|
||||
if(Ninja::isHosted()){
|
||||
$rules['subdomain'] = ['nullable', 'alpha_num', new ValidSubdomain($this->all())];
|
||||
}
|
||||
else
|
||||
$rules['subdomain'] = 'nullable|alpha_num';
|
||||
|
||||
}
|
||||
|
||||
return $rules;
|
||||
@ -55,8 +63,9 @@ class StoreCompanyRequest extends Request
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if(array_key_exists('portal_domain', $input) && strlen($input['portal_domain']) > 1)
|
||||
$input['portal_domain'] = str_replace("http:", "https:", $input['portal_domain']);
|
||||
//https not sure i should be forcing this.
|
||||
// if(array_key_exists('portal_domain', $input) && strlen($input['portal_domain']) > 1)
|
||||
// $input['portal_domain'] = str_replace("http:", "https:", $input['portal_domain']);
|
||||
|
||||
if (array_key_exists('google_analytics_url', $input)) {
|
||||
$input['google_analytics_key'] = $input['google_analytics_url'];
|
||||
|
@ -13,7 +13,9 @@ namespace App\Http\Requests\Company;
|
||||
|
||||
use App\DataMapper\CompanySettings;
|
||||
use App\Http\Requests\Request;
|
||||
use App\Http\ValidationRules\Company\ValidSubdomain;
|
||||
use App\Http\ValidationRules\ValidSettingsRule;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
class UpdateCompanyRequest extends Request
|
||||
@ -46,7 +48,12 @@ class UpdateCompanyRequest extends Request
|
||||
if (isset($input['portal_mode']) && ($input['portal_mode'] == 'domain' || $input['portal_mode'] == 'iframe')) {
|
||||
$rules['portal_domain'] = 'sometimes|url';
|
||||
} else {
|
||||
$rules['subdomain'] = 'nullable|alpha_num';
|
||||
|
||||
if(Ninja::isHosted()){
|
||||
$rules['subdomain'] = ['nullable', 'alpha_num', new ValidSubdomain($this->all())];
|
||||
}
|
||||
else
|
||||
$rules['subdomain'] = 'nullable|alpha_num';
|
||||
}
|
||||
|
||||
// if($this->company->account->isPaidHostedClient()) {
|
||||
@ -60,8 +67,8 @@ class UpdateCompanyRequest extends Request
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if(array_key_exists('portal_domain', $input) && strlen($input['portal_domain']) > 1)
|
||||
$input['portal_domain'] = str_replace("http:", "https:", $input['portal_domain']);
|
||||
// if(array_key_exists('portal_domain', $input) && strlen($input['portal_domain']) > 1)
|
||||
// $input['portal_domain'] = str_replace("http:", "https:", $input['portal_domain']);
|
||||
|
||||
if (array_key_exists('settings', $input)) {
|
||||
$input['settings'] = $this->filterSaveableSettings($input['settings']);
|
||||
|
39
app/Http/Requests/Export/StoreExportRequest.php
Normal file
39
app/Http/Requests/Export/StoreExportRequest.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
|
||||
namespace App\Http\Requests\Export;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class StoreExportRequest extends Request
|
||||
{
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->user()->isAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@ class PaymentWebhookRequest extends Request
|
||||
|
||||
public function authorize()
|
||||
{
|
||||
MultiDB::findAndSetDbByCompanyKey($this->getCompany()->company_key);
|
||||
MultiDB::findAndSetDbByCompanyKey($this->company_key);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -45,7 +45,7 @@ class PaymentWebhookRequest extends Request
|
||||
* @param mixed $id
|
||||
* @return null|\App\Models\CompanyGateway
|
||||
*/
|
||||
public function getCompanyGateway(): ?CompanyGateway
|
||||
public function getCompanyGateway()
|
||||
{
|
||||
return CompanyGateway::findOrFail($this->decodePrimaryKey($this->company_gateway_id));
|
||||
}
|
||||
@ -56,13 +56,13 @@ class PaymentWebhookRequest extends Request
|
||||
* @param string $hash
|
||||
* @return null|\App\Models\PaymentHash
|
||||
*/
|
||||
public function getPaymentHash(): ?PaymentHash
|
||||
public function getPaymentHash()
|
||||
{
|
||||
if ($this->query('hash')) {
|
||||
return PaymentHash::where('hash', $this->query('hash'))->firstOrFail();
|
||||
}
|
||||
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -94,7 +94,7 @@ class PaymentWebhookRequest extends Request
|
||||
|
||||
// If none of previously done logics is correct, we'll just display
|
||||
// not found page.
|
||||
abort(404);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -102,11 +102,14 @@ class PaymentWebhookRequest extends Request
|
||||
*
|
||||
* @return null|\App\Models\Client
|
||||
*/
|
||||
public function getClient(): ?Client
|
||||
public function getClient()
|
||||
{
|
||||
$hash = $this->getPaymentHash();
|
||||
|
||||
return Client::find($hash->data->client_id)->firstOrFail();
|
||||
if($hash)
|
||||
return Client::find($hash->data->client_id)->firstOrFail();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -49,6 +49,9 @@ class InitializeStripeConnectRequest extends FormRequest
|
||||
*/
|
||||
public function getTokenContent()
|
||||
{
|
||||
if($this->state)
|
||||
$this->token = $this->state;
|
||||
|
||||
$data = Cache::get($this->token);
|
||||
|
||||
return $data;
|
||||
|
@ -15,6 +15,7 @@ use App\Http\Requests\Request;
|
||||
use App\Http\ValidationRules\ValidVendorGroupSettingsRule;
|
||||
use App\Models\Vendor;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class StoreVendorRequest extends Request
|
||||
{
|
||||
@ -39,6 +40,9 @@ class StoreVendorRequest extends Request
|
||||
//$rules['settings'] = new ValidVendorGroupSettingsRule();
|
||||
$rules['contacts.*.email'] = 'nullable|distinct';
|
||||
|
||||
if (isset($this->number)) {
|
||||
$rules['number'] = Rule::unique('vendors')->where('company_id', auth()->user()->company()->id);
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
50
app/Http/ValidationRules/Company/ValidSubdomain.php
Normal file
50
app/Http/ValidationRules/Company/ValidSubdomain.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\ValidationRules\Company;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
|
||||
/**
|
||||
* Class ValidCompanyQuantity.
|
||||
*/
|
||||
class ValidSubdomain implements Rule
|
||||
{
|
||||
/**
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
private $input;
|
||||
|
||||
public function __construct($input)
|
||||
{
|
||||
$this->input = $input;
|
||||
}
|
||||
|
||||
public function passes($attribute, $value)
|
||||
{
|
||||
if(empty($input['subdomain']))
|
||||
return true;
|
||||
|
||||
return MultiDB::checkDomainAvailable($input['subdomain']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function message()
|
||||
{
|
||||
return ctrans('texts.subdomain_taken');
|
||||
}
|
||||
}
|
@ -82,9 +82,7 @@ class PortalComposer
|
||||
$data[] = ['title' => ctrans('texts.subscriptions'), 'url' => 'client.subscriptions.index', 'icon' => 'calendar'];
|
||||
|
||||
if (auth()->user('contact')->client->getSetting('enable_client_portal_tasks')) {
|
||||
$data[] = ['title' => ctrans('texts.tasks'), 'url' => 'client.dashboard', 'icon' => 'clock'];
|
||||
|
||||
// TODO: Update when 'tasks' module is available in client portal.
|
||||
$data[] = ['title' => ctrans('texts.tasks'), 'url' => 'client.tasks.index', 'icon' => 'clock'];
|
||||
}
|
||||
|
||||
return $data;
|
||||
|
467
app/Jobs/Company/CompanyExport.php
Normal file
467
app/Jobs/Company/CompanyExport.php
Normal file
@ -0,0 +1,467 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Jobs\Company;
|
||||
|
||||
use App\Jobs\Mail\NinjaMailerJob;
|
||||
use App\Jobs\Mail\NinjaMailerObject;
|
||||
use App\Jobs\Util\UnlinkFile;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Mail\DownloadBackup;
|
||||
use App\Mail\DownloadInvoices;
|
||||
use App\Models\Company;
|
||||
use App\Models\CreditInvitation;
|
||||
use App\Models\InvoiceInvitation;
|
||||
use App\Models\QuoteInvitation;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Models\RecurringInvoiceInvitation;
|
||||
use App\Models\User;
|
||||
use App\Models\VendorContact;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use ZipStream\Option\Archive;
|
||||
use ZipStream\ZipStream;
|
||||
|
||||
class CompanyExport implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, MakesHash;
|
||||
|
||||
public $company;
|
||||
|
||||
private $export_format;
|
||||
|
||||
private $export_data = [];
|
||||
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param Company $company
|
||||
* @param User $user
|
||||
* @param string $custom_token_name
|
||||
*/
|
||||
public function __construct(Company $company, User $user, $export_format = 'json')
|
||||
{
|
||||
$this->company = $company;
|
||||
$this->user = $user;
|
||||
$this->export_format = $export_format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return CompanyToken|null
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
MultiDB::setDb($this->company->db);
|
||||
|
||||
$this->company = Company::where('company_key', $this->company->company_key)->first();
|
||||
|
||||
set_time_limit(0);
|
||||
|
||||
$this->export_data['app_version'] = config('ninja.app_version');
|
||||
|
||||
$this->export_data['activities'] = $this->company->all_activities->map(function ($activity){
|
||||
|
||||
$activity = $this->transformArrayOfKeys($activity, [
|
||||
'user_id',
|
||||
'company_id',
|
||||
'client_id',
|
||||
'client_contact_id',
|
||||
'account_id',
|
||||
'project_id',
|
||||
'vendor_id',
|
||||
'payment_id',
|
||||
'invoice_id',
|
||||
'credit_id',
|
||||
'invitation_id',
|
||||
'task_id',
|
||||
'expense_id',
|
||||
'token_id',
|
||||
'quote_id',
|
||||
'subscription_id',
|
||||
'recurring_invoice_id'
|
||||
]);
|
||||
|
||||
return $activity;
|
||||
|
||||
})->makeHidden(['id'])->toArray();
|
||||
|
||||
$this->export_data['backups'] = $this->company->all_activities()->with('backup')->cursor()->map(function ($activity){
|
||||
|
||||
$backup = $activity->backup;
|
||||
|
||||
if(!$backup)
|
||||
return;
|
||||
|
||||
$backup->activity_id = $this->encodePrimaryKey($backup->activity_id);
|
||||
|
||||
return $backup;
|
||||
|
||||
})->toArray();
|
||||
|
||||
$this->export_data['users'] = $this->company->users()->withTrashed()->cursor()->map(function ($user){
|
||||
|
||||
$user->account_id = $this->encodePrimaryKey($user->account_id);
|
||||
$user->id = $this->encodePrimaryKey($user->id);
|
||||
|
||||
return $user;
|
||||
|
||||
})->toArray();
|
||||
|
||||
|
||||
$this->export_data['client_contacts'] = $this->company->client_contacts->map(function ($client_contact){
|
||||
|
||||
$client_contact = $this->transformArrayOfKeys($client_contact, ['id', 'company_id', 'user_id',' client_id']);
|
||||
|
||||
return $client_contact;
|
||||
|
||||
})->toArray();
|
||||
|
||||
|
||||
$this->export_data['client_gateway_tokens'] = $this->company->client_gateway_tokens->map(function ($client_gateway_token){
|
||||
|
||||
$client_gateway_token = $this->transformArrayOfKeys($client_gateway_token, ['id', 'company_id', 'client_id']);
|
||||
|
||||
return $client_gateway_token;
|
||||
|
||||
})->toArray();
|
||||
|
||||
|
||||
$this->export_data['clients'] = $this->company->clients->map(function ($client){
|
||||
|
||||
$client = $this->transformArrayOfKeys($client, ['id', 'company_id', 'user_id',' assigned_user_id', 'group_settings_id']);
|
||||
|
||||
return $client;
|
||||
|
||||
})->toArray();
|
||||
|
||||
$this->export_data['company'] = $this->company->toArray();
|
||||
|
||||
$this->export_data['company_gateways'] = $this->company->company_gateways->map(function ($company_gateway){
|
||||
|
||||
$company_gateway = $this->transformArrayOfKeys($company_gateway, ['company_id', 'user_id']);
|
||||
$company_gateway->config = decrypt($company_gateway->config);
|
||||
|
||||
return $company_gateway;
|
||||
|
||||
})->toArray();
|
||||
|
||||
$this->export_data['company_tokens'] = $this->company->tokens->map(function ($token){
|
||||
|
||||
$token = $this->transformArrayOfKeys($token, ['company_id', 'account_id', 'user_id']);
|
||||
|
||||
return $token;
|
||||
|
||||
})->toArray();
|
||||
|
||||
$this->export_data['company_ledger'] = $this->company->ledger->map(function ($ledger){
|
||||
|
||||
$ledger = $this->transformArrayOfKeys($ledger, ['activity_id', 'client_id', 'company_id', 'account_id', 'user_id','company_ledgerable_id']);
|
||||
|
||||
return $ledger;
|
||||
|
||||
})->toArray();
|
||||
|
||||
$this->export_data['company_users'] = $this->company->company_users->map(function ($company_user){
|
||||
|
||||
$company_user = $this->transformArrayOfKeys($company_user, ['company_id', 'account_id', 'user_id']);
|
||||
|
||||
return $company_user;
|
||||
|
||||
})->toArray();
|
||||
|
||||
$this->export_data['credits'] = $this->company->credits->map(function ($credit){
|
||||
|
||||
$credit = $this->transformBasicEntities($credit);
|
||||
$credit = $this->transformArrayOfKeys($credit, ['recurring_id','client_id', 'vendor_id', 'project_id', 'design_id', 'subscription_id','invoice_id']);
|
||||
|
||||
return $credit;
|
||||
|
||||
})->toArray();
|
||||
|
||||
|
||||
$this->export_data['credit_invitations'] = CreditInvitation::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($credit){
|
||||
|
||||
$credit = $this->transformArrayOfKeys($credit, ['company_id', 'user_id', 'client_contact_id', 'recurring_invoice_id']);
|
||||
|
||||
return $credit;
|
||||
|
||||
})->toArray();
|
||||
|
||||
$this->export_data['designs'] = $this->company->user_designs->makeHidden(['id'])->toArray();
|
||||
|
||||
$this->export_data['documents'] = $this->company->documents->map(function ($document){
|
||||
|
||||
$document = $this->transformArrayOfKeys($document, ['user_id', 'assigned_user_id', 'company_id', 'project_id', 'vendor_id']);
|
||||
|
||||
return $document;
|
||||
|
||||
})->toArray();
|
||||
|
||||
$this->export_data['expense_categories'] = $this->company->expenses->map(function ($expense_category){
|
||||
|
||||
$expense_category = $this->transformArrayOfKeys($expense_category, ['user_id', 'company_id']);
|
||||
|
||||
return $expense_category;
|
||||
|
||||
})->toArray();
|
||||
|
||||
|
||||
$this->export_data['expenses'] = $this->company->expenses->map(function ($expense){
|
||||
|
||||
$expense = $this->transformBasicEntities($expense);
|
||||
$expense = $this->transformArrayOfKeys($expense, ['vendor_id', 'invoice_id', 'client_id', 'category_id', 'recurring_expense_id','project_id']);
|
||||
|
||||
return $expense;
|
||||
|
||||
})->toArray();
|
||||
|
||||
$this->export_data['group_settings'] = $this->company->group_settings->map(function ($gs){
|
||||
|
||||
$gs = $this->transformArrayOfKeys($gs, ['user_id', 'company_id']);
|
||||
|
||||
return $gs;
|
||||
|
||||
})->toArray();
|
||||
|
||||
|
||||
$this->export_data['invoices'] = $this->company->invoices->map(function ($invoice){
|
||||
|
||||
$invoice = $this->transformBasicEntities($invoice);
|
||||
$invoice = $this->transformArrayOfKeys($invoice, ['recurring_id','client_id', 'vendor_id', 'project_id', 'design_id', 'subscription_id']);
|
||||
|
||||
return $invoice;
|
||||
|
||||
})->toArray();
|
||||
|
||||
|
||||
$this->export_data['invoice_invitations'] = InvoiceInvitation::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($invoice){
|
||||
|
||||
$invoice = $this->transformArrayOfKeys($invoice, ['company_id', 'user_id', 'client_contact_id', 'recurring_invoice_id']);
|
||||
|
||||
return $invoice;
|
||||
|
||||
})->toArray();
|
||||
|
||||
$this->export_data['payment_terms'] = $this->company->user_payment_terms->map(function ($term){
|
||||
|
||||
$term = $this->transformArrayOfKeys($term, ['user_id', 'company_id']);
|
||||
|
||||
return $term;
|
||||
|
||||
})->makeHidden(['id'])->toArray();
|
||||
|
||||
$this->export_data['paymentables'] = $this->company->payments()->with('paymentables')->cursor()->map(function ($paymentable){
|
||||
|
||||
$paymentable = $this->transformArrayOfKeys($paymentable, ['payment_id','paymentable_id']);
|
||||
|
||||
return $paymentable;
|
||||
|
||||
})->toArray();
|
||||
|
||||
$this->export_data['payments'] = $this->company->payments->map(function ($payment){
|
||||
|
||||
$payment = $this->transformBasicEntities($payment);
|
||||
$payment = $this->transformArrayOfKeys($payment, ['client_id','project_id', 'vendor_id', 'client_contact_id', 'invitation_id', 'company_gateway_id']);
|
||||
|
||||
return $payment;
|
||||
|
||||
})->toArray();
|
||||
|
||||
|
||||
$this->export_data['projects'] = $this->company->projects->map(function ($project){
|
||||
|
||||
$project = $this->transformBasicEntities($project);
|
||||
$project = $this->transformArrayOfKeys($project, ['client_id']);
|
||||
|
||||
return $project;
|
||||
|
||||
})->toArray();
|
||||
|
||||
$this->export_data['quotes'] = $this->company->quotes->map(function ($quote){
|
||||
|
||||
$quote = $this->transformBasicEntities($quote);
|
||||
$quote = $this->transformArrayOfKeys($quote, ['invoice_id','recurring_id','client_id', 'vendor_id', 'project_id', 'design_id', 'subscription_id']);
|
||||
|
||||
return $quote;
|
||||
|
||||
})->toArray();
|
||||
|
||||
|
||||
$this->export_data['quote_invitations'] = QuoteInvitation::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($quote){
|
||||
|
||||
$quote = $this->transformArrayOfKeys($quote, ['company_id', 'user_id', 'client_contact_id', 'recurring_invoice_id']);
|
||||
|
||||
return $quote;
|
||||
|
||||
})->toArray();
|
||||
|
||||
|
||||
$this->export_data['recurring_invoices'] = $this->company->recurring_invoices->map(function ($ri){
|
||||
|
||||
$ri = $this->transformBasicEntities($ri);
|
||||
$ri = $this->transformArrayOfKeys($ri, ['client_id', 'vendor_id', 'project_id', 'design_id', 'subscription_id']);
|
||||
return $ri;
|
||||
|
||||
})->toArray();
|
||||
|
||||
|
||||
$this->export_data['recurring_invoice_invitations'] = RecurringInvoiceInvitation::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($ri){
|
||||
|
||||
$ri = $this->transformArrayOfKeys($ri, ['company_id', 'user_id', 'client_contact_id', 'recurring_invoice_id']);
|
||||
|
||||
return $ri;
|
||||
|
||||
})->toArray();
|
||||
|
||||
$this->export_data['subscriptions'] = $this->company->subscriptions->map(function ($subscription){
|
||||
|
||||
$subscription = $this->transformBasicEntities($subscription);
|
||||
$subscription->group_id = $this->encodePrimaryKey($subscription->group_id);
|
||||
|
||||
return $subscription;
|
||||
|
||||
})->toArray();
|
||||
|
||||
|
||||
$this->export_data['system_logs'] = $this->company->system_logs->map(function ($log){
|
||||
|
||||
$log->client_id = $this->encodePrimaryKey($log->client_id);
|
||||
$log->company_id = $this->encodePrimaryKey($log->company_id);
|
||||
|
||||
return $log;
|
||||
|
||||
})->makeHidden(['id'])->toArray();
|
||||
|
||||
$this->export_data['tasks'] = $this->company->tasks->map(function ($task){
|
||||
|
||||
$task = $this->transformBasicEntities($task);
|
||||
$task = $this->transformArrayOfKeys($task, ['client_id', 'invoice_id', 'project_id', 'status_id']);
|
||||
|
||||
return $task;
|
||||
|
||||
})->toArray();
|
||||
|
||||
$this->export_data['task_statuses'] = $this->company->task_statuses->map(function ($status){
|
||||
|
||||
$status->id = $this->encodePrimaryKey($status->id);
|
||||
$status->user_id = $this->encodePrimaryKey($status->user_id);
|
||||
$status->company_id = $this->encodePrimaryKey($status->company_id);
|
||||
|
||||
return $status;
|
||||
|
||||
})->toArray();
|
||||
|
||||
$this->export_data['tax_rates'] = $this->company->tax_rates->map(function ($rate){
|
||||
|
||||
$rate->company_id = $this->encodePrimaryKey($rate->company_id);
|
||||
$rate->user_id = $this->encodePrimaryKey($rate->user_id);
|
||||
|
||||
return $rate;
|
||||
|
||||
})->makeHidden(['id'])->toArray();
|
||||
|
||||
$this->export_data['vendors'] = $this->company->vendors->map(function ($vendor){
|
||||
|
||||
return $this->transformBasicEntities($vendor);
|
||||
|
||||
})->toArray();
|
||||
|
||||
|
||||
$this->export_data['vendor_contacts'] = VendorContact::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($vendor){
|
||||
|
||||
$vendor = $this->transformBasicEntities($vendor);
|
||||
$vendor->vendor_id = $this->encodePrimaryKey($vendor->vendor_id);
|
||||
|
||||
return $vendor;
|
||||
|
||||
})->toArray();
|
||||
|
||||
$this->export_data['webhooks'] = $this->company->webhooks->map(function ($hook){
|
||||
|
||||
$hook->user_id = $this->encodePrimaryKey($hook->user_id);
|
||||
$hook->company_id = $this->encodePrimaryKey($hook->company_id);
|
||||
|
||||
return $hook;
|
||||
|
||||
})->makeHidden(['id'])->toArray();
|
||||
|
||||
//write to tmp and email to owner();
|
||||
|
||||
$this->zipAndSend();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function transformBasicEntities($model)
|
||||
{
|
||||
|
||||
return $this->transformArrayOfKeys($model, ['id', 'user_id', 'assigned_user_id', 'company_id']);
|
||||
|
||||
}
|
||||
|
||||
private function transformArrayOfKeys($model, $keys)
|
||||
{
|
||||
|
||||
foreach($keys as $key){
|
||||
$model->{$key} = $this->encodePrimaryKey($model->{$key});
|
||||
}
|
||||
|
||||
return $model;
|
||||
|
||||
}
|
||||
|
||||
private function zipAndSend()
|
||||
{
|
||||
|
||||
$tempStream = fopen('php://memory', 'w+');
|
||||
|
||||
$options = new Archive();
|
||||
$options->setOutputStream($tempStream);
|
||||
|
||||
$file_name = date('Y-m-d').'_'.str_replace(' ', '_', $this->company->present()->name() . '_' . $this->company->company_key .'.zip');
|
||||
|
||||
$zip = new ZipStream($file_name, $options);
|
||||
|
||||
$fp = tmpfile();
|
||||
fwrite($fp, json_encode($this->export_data));
|
||||
rewind($fp);
|
||||
$zip->addFileFromStream('backup.json', $fp);
|
||||
|
||||
$zip->finish();
|
||||
|
||||
$path = 'backups/';
|
||||
|
||||
Storage::disk(config('filesystems.default'))->put($path.$file_name, $tempStream);
|
||||
|
||||
fclose($tempStream);
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new DownloadBackup(Storage::disk(config('filesystems.default'))->url($path.$file_name), $this->company);
|
||||
$nmo->to_user = $this->user;
|
||||
$nmo->company = $this->company;
|
||||
$nmo->settings = $this->company->settings;
|
||||
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
|
||||
UnlinkFile::dispatch(config('filesystems.default'), $path.$file_name)->delay(now()->addHours(1));
|
||||
}
|
||||
|
||||
}
|
199
app/Jobs/Company/CompanyImport.php
Normal file
199
app/Jobs/Company/CompanyImport.php
Normal file
@ -0,0 +1,199 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Jobs\Company;
|
||||
|
||||
use App\Exceptions\NonExistingMigrationFile;
|
||||
use App\Jobs\Mail\NinjaMailerJob;
|
||||
use App\Jobs\Mail\NinjaMailerObject;
|
||||
use App\Jobs\Util\UnlinkFile;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Mail\DownloadBackup;
|
||||
use App\Mail\DownloadInvoices;
|
||||
use App\Models\Company;
|
||||
use App\Models\CreditInvitation;
|
||||
use App\Models\InvoiceInvitation;
|
||||
use App\Models\QuoteInvitation;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Models\RecurringInvoiceInvitation;
|
||||
use App\Models\User;
|
||||
use App\Models\VendorContact;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use ZipArchive;
|
||||
use ZipStream\Option\Archive;
|
||||
use ZipStream\ZipStream;
|
||||
|
||||
class CompanyImport implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, MakesHash;
|
||||
|
||||
protected $current_app_version;
|
||||
|
||||
public $company;
|
||||
|
||||
private $account;
|
||||
|
||||
public $file_path;
|
||||
|
||||
private $backup_file;
|
||||
|
||||
public $import_company;
|
||||
|
||||
public $ids = [];
|
||||
|
||||
private $options = '';
|
||||
|
||||
private $importables = [
|
||||
'company',
|
||||
'users',
|
||||
// 'payment_terms',
|
||||
// 'tax_rates',
|
||||
// 'clients',
|
||||
// 'company_gateways',
|
||||
// 'client_gateway_tokens',
|
||||
// 'vendors',
|
||||
// 'projects',
|
||||
// 'products',
|
||||
// 'credits',
|
||||
// 'invoices',
|
||||
// 'recurring_invoices',
|
||||
// 'quotes',
|
||||
// 'payments',
|
||||
// 'expense_categories',
|
||||
// 'task_statuses',
|
||||
// 'expenses',
|
||||
// 'tasks',
|
||||
// 'documents',
|
||||
];
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param Company $company
|
||||
* @param User $user
|
||||
* @param string $custom_token_name
|
||||
*/
|
||||
public function __construct(Company $company, string $file_path, array $options)
|
||||
{
|
||||
$this->company = $company;
|
||||
$this->file_path = $file_path;
|
||||
$this->options = $options;
|
||||
$this->current_app_version = config('ninja.app_version');
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
MultiDB::setDb($this->company->db);
|
||||
|
||||
$this->company =Company::where('company_key', $this->company->company_key)->firstOrFail();
|
||||
$this->account = $this->company->account;
|
||||
|
||||
$this->unzipFile()
|
||||
->preFlightChecks();
|
||||
|
||||
foreach($this->importables as $import){
|
||||
|
||||
$method = Str::ucfirst(Str::camel($import));
|
||||
|
||||
$this->{$method}();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//check if this is a complete company import OR if it is selective
|
||||
/*
|
||||
Company and settings only
|
||||
Data
|
||||
*/
|
||||
|
||||
private function preFlightChecks()
|
||||
{
|
||||
//check the file version and perform any necessary adjustments to the file in order to proceed - needed when we change schema
|
||||
|
||||
if($this->current_app_version != $this->backup_file->app_version)
|
||||
{
|
||||
//perform some magic here
|
||||
}
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function unzipFile()
|
||||
{
|
||||
$zip = new ZipArchive();
|
||||
$archive = $zip->open(public_path("storage/backups/{$this->file_path}"));
|
||||
$filename = pathinfo($this->filepath, PATHINFO_FILENAME);
|
||||
$zip->extractTo(public_path("storage/backups/{$filename}"));
|
||||
$zip->close();
|
||||
$file_location = public_path("storage/backups/$filename/backup.json");
|
||||
|
||||
if (! file_exists($file_location)) {
|
||||
throw new NonExistingMigrationFile('Backup file does not exist, or it is corrupted.');
|
||||
}
|
||||
|
||||
$this->backup_file = json_decode(file_get_contents($file_location));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function importCompany()
|
||||
{
|
||||
|
||||
//$this->import_company = ..
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function importUsers()
|
||||
{
|
||||
User::unguard();
|
||||
|
||||
foreach ($this->backup_file->users as $user)
|
||||
{
|
||||
|
||||
$new_user = User::firstOrNew(
|
||||
['email' => $user->email],
|
||||
(array)$user,
|
||||
);
|
||||
|
||||
$new_user->account_id = $this->account->id;
|
||||
$new_user->save(['timestamps' => false]);
|
||||
|
||||
$this->ids['users']["{$user->id}"] = $new_user->id;
|
||||
}
|
||||
|
||||
Expense::reguard();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function transformId(string$resource, string $old): int
|
||||
{
|
||||
if (! array_key_exists($resource, $this->ids)) {
|
||||
throw new \Exception("Resource {$resource} not available.");
|
||||
}
|
||||
|
||||
if (! array_key_exists("{$old}", $this->ids[$resource])) {
|
||||
throw new \Exception("Missing resource key: {$old}");
|
||||
}
|
||||
|
||||
return $this->ids[$resource]["{$old}"];
|
||||
}
|
||||
}
|
@ -64,7 +64,7 @@ class CreateEntityPdf implements ShouldQueue
|
||||
*
|
||||
* @param $invitation
|
||||
*/
|
||||
public function __construct($invitation)
|
||||
public function __construct($invitation, $disk = 'public')
|
||||
{
|
||||
$this->invitation = $invitation;
|
||||
|
||||
@ -86,7 +86,9 @@ class CreateEntityPdf implements ShouldQueue
|
||||
|
||||
$this->contact = $invitation->contact;
|
||||
|
||||
$this->disk = $disk ?? config('filesystems.default');
|
||||
$this->disk = $disk;
|
||||
|
||||
// $this->disk = $disk ?? config('filesystems.default');
|
||||
}
|
||||
|
||||
public function handle()
|
||||
@ -192,12 +194,12 @@ class CreateEntityPdf implements ShouldQueue
|
||||
try{
|
||||
|
||||
Storage::disk($this->disk)->put($file_path, $pdf);
|
||||
|
||||
|
||||
}
|
||||
catch(\Exception $e)
|
||||
{
|
||||
|
||||
throw new FilePermissionsFailure('Could not write the PDF, permission issues!');
|
||||
throw new FilePermissionsFailure($e->getMessage());
|
||||
|
||||
}
|
||||
}
|
||||
@ -209,8 +211,5 @@ class CreateEntityPdf implements ShouldQueue
|
||||
{
|
||||
|
||||
}
|
||||
// public function failed(\Exception $exception)
|
||||
// {
|
||||
// nlog("help!");
|
||||
// }
|
||||
|
||||
}
|
||||
|
@ -96,8 +96,8 @@ class CSVImport implements ShouldQueue {
|
||||
MultiDB::setDb( $this->company->db );
|
||||
|
||||
Auth::login( $this->company->owner(), true );
|
||||
|
||||
$this->company->owner()->setCompany( $this->company );
|
||||
|
||||
auth()->user()->setCompany($this->company);
|
||||
|
||||
$this->buildMaps();
|
||||
|
||||
|
@ -83,23 +83,24 @@ class ZipInvoices implements ShouldQueue
|
||||
$zip = new ZipStream($file_name, $options);
|
||||
|
||||
foreach ($this->invoices as $invoice) {
|
||||
$zip->addFileFromPath(basename($invoice->pdf_file_path()), TempFile::path($invoice->pdf_file_path()));
|
||||
//$zip->addFileFromPath(basename($invoice->pdf_file_path()), TempFile::path($invoice->pdf_file_path()));
|
||||
$zip->addFileFromPath(basename($invoice->pdf_file_path()), $invoice->pdf_file_path());
|
||||
}
|
||||
|
||||
$zip->finish();
|
||||
|
||||
Storage::disk(config('filesystems.default'))->put($path.$file_name, $tempStream);
|
||||
Storage::disk('public')->put($path.$file_name, $tempStream);
|
||||
|
||||
fclose($tempStream);
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new DownloadInvoices(Storage::disk(config('filesystems.default'))->url($path.$file_name), $this->company);
|
||||
$nmo->mailable = new DownloadInvoices(Storage::disk('public')->url($path.$file_name), $this->company);
|
||||
$nmo->to_user = $this->user;
|
||||
$nmo->settings = $this->settings;
|
||||
$nmo->company = $this->company;
|
||||
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
|
||||
UnlinkFile::dispatch(config('filesystems.default'), $path.$file_name)->delay(now()->addHours(1));
|
||||
UnlinkFile::dispatch('public', $path.$file_name)->delay(now()->addHours(1));
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ use App\Libraries\Google\Google;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Mail\TemplateEmail;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Company;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
use App\Models\SystemLog;
|
||||
@ -54,7 +55,11 @@ class NinjaMailerJob implements ShouldQueue
|
||||
|
||||
public $nmo;
|
||||
|
||||
public function __construct(NinjaMailerObject $nmo)
|
||||
public $override;
|
||||
|
||||
public $company;
|
||||
|
||||
public function __construct(NinjaMailerObject $nmo, bool $override = false)
|
||||
{
|
||||
|
||||
$this->nmo = $nmo;
|
||||
@ -64,12 +69,15 @@ class NinjaMailerJob implements ShouldQueue
|
||||
public function handle()
|
||||
{
|
||||
/*If we are migrating data we don't want to fire any emails*/
|
||||
if ($this->nmo->company->is_disabled)
|
||||
if ($this->nmo->company->is_disabled && !$this->override)
|
||||
return true;
|
||||
|
||||
/*Set the correct database*/
|
||||
MultiDB::setDb($this->nmo->company->db);
|
||||
|
||||
/* Serializing models from other jobs wipes the primary key */
|
||||
$this->company = Company::where('company_key', $this->nmo->company->company_key)->first();
|
||||
|
||||
/* Set the email driver */
|
||||
$this->setMailDriver();
|
||||
|
||||
@ -83,6 +91,10 @@ class NinjaMailerJob implements ShouldQueue
|
||||
$this->nmo->mailable->replyTo($this->nmo->settings->reply_to_email, $reply_to_name);
|
||||
|
||||
}
|
||||
else {
|
||||
$this->nmo->mailable->replyTo($this->company->owner()->email, $this->company->owner()->present()->name());
|
||||
}
|
||||
|
||||
|
||||
if (strlen($this->nmo->settings->bcc_email) > 1) {
|
||||
nlog('bcc list available');
|
||||
@ -104,10 +116,12 @@ class NinjaMailerJob implements ShouldQueue
|
||||
} catch (\Exception $e) {
|
||||
|
||||
nlog("error failed with {$e->getMessage()}");
|
||||
// nlog($e);
|
||||
|
||||
if($this->nmo->entity)
|
||||
$this->entityEmailFailed($e->getMessage());
|
||||
|
||||
if(Ninja::isHosted())
|
||||
app('sentry')->captureException($e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,7 +183,15 @@ class NinjaMailerJob implements ShouldQueue
|
||||
nlog("Sending via {$user->name()}");
|
||||
|
||||
$google = (new Google())->init();
|
||||
$google->getClient()->setAccessToken(json_encode($user->oauth_user_token));
|
||||
|
||||
try{
|
||||
$google->getClient()->setAccessToken(json_encode($user->oauth_user_token));
|
||||
}
|
||||
catch(\Exception $e) {
|
||||
$this->logMailError('Gmail Token Invalid', $this->company->clients()->first());
|
||||
$this->nmo->settings->email_sending_method = 'default';
|
||||
return $this->setMailDriver();
|
||||
}
|
||||
|
||||
if ($google->getClient()->isAccessTokenExpired()) {
|
||||
$google->refreshToken($user);
|
||||
@ -202,7 +224,8 @@ class NinjaMailerJob implements ShouldQueue
|
||||
SystemLog::CATEGORY_MAIL,
|
||||
SystemLog::EVENT_MAIL_SEND,
|
||||
SystemLog::TYPE_FAILURE,
|
||||
$recipient_object
|
||||
$recipient_object,
|
||||
$this->nmo->company
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -55,9 +55,6 @@ class UserEmailChanged implements ShouldQueue
|
||||
public function handle()
|
||||
{
|
||||
nlog("notifying user of email change");
|
||||
|
||||
if ($this->company->is_disabled)
|
||||
return true;
|
||||
|
||||
//Set DB
|
||||
MultiDB::setDb($this->company->db);
|
||||
@ -78,7 +75,7 @@ class UserEmailChanged implements ShouldQueue
|
||||
$nmo->company = $this->company;
|
||||
$nmo->to_user = $this->old_user;
|
||||
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
NinjaMailerJob::dispatch($nmo, true);
|
||||
|
||||
// $nmo->to_user = $this->new_user;
|
||||
// NinjaMailerJob::dispatch($nmo);
|
||||
|
@ -17,6 +17,7 @@ use App\Exceptions\MigrationValidatorFailed;
|
||||
use App\Exceptions\ProcessingMigrationArchiveFailed;
|
||||
use App\Exceptions\ResourceDependencyMissing;
|
||||
use App\Exceptions\ResourceNotAvailableForMigration;
|
||||
use App\Factory\ClientContactFactory;
|
||||
use App\Factory\ClientFactory;
|
||||
use App\Factory\CompanyLedgerFactory;
|
||||
use App\Factory\CreditFactory;
|
||||
@ -209,6 +210,9 @@ class Import implements ShouldQueue
|
||||
$this->{$method}($data[$import]);
|
||||
}
|
||||
|
||||
if(Ninja::isHosted())
|
||||
$this->processNinjaTokens($data['ninja_tokens']);
|
||||
|
||||
$this->setInitialCompanyLedgerBalances();
|
||||
|
||||
// $this->fixClientBalances();
|
||||
@ -1261,7 +1265,7 @@ class Import implements ShouldQueue
|
||||
$modified['fees_and_limits'] = $this->cleanFeesAndLimits($modified['fees_and_limits']);
|
||||
}
|
||||
|
||||
if(Ninja::isHosted() && $modified['gateway_key'] == 'd14dd26a37cecc30fdd65700bfb55b23'){
|
||||
else if(Ninja::isHosted() && $modified['gateway_key'] == 'd14dd26a37cecc30fdd65700bfb55b23'){
|
||||
$modified['gateway_key'] = 'd14dd26a47cecc30fdd65700bfb67b34';
|
||||
$modified['fees_and_limits'] = [];
|
||||
}
|
||||
@ -1293,6 +1297,8 @@ class Import implements ShouldQueue
|
||||
|
||||
$modified['company_id'] = $this->company->id;
|
||||
$modified['client_id'] = $this->transformId('clients', $resource['client_id']);
|
||||
$modified['company_gateway_id'] = $this->transformId('company_gateways', $resource['company_gateway_id']);
|
||||
|
||||
//$modified['user_id'] = $this->processUserId($resource);
|
||||
|
||||
$cgt = ClientGatewayToken::Create($modified);
|
||||
@ -1612,6 +1618,9 @@ class Import implements ShouldQueue
|
||||
->batch();
|
||||
|
||||
info(print_r($exception->getMessage(), 1));
|
||||
|
||||
if(Ninja::isHosted())
|
||||
app('sentry')->captureException($exception);
|
||||
}
|
||||
|
||||
|
||||
@ -1636,6 +1645,64 @@ class Import implements ShouldQueue
|
||||
return $response->getBody();
|
||||
}
|
||||
|
||||
private function buildNewUserPlan()
|
||||
{
|
||||
$local_company = Company::find($this->company->id);
|
||||
$owner = $local_company->owner();
|
||||
|
||||
$ninja_company = Company::on('db-ninja-01')->find(config('ninja.ninja_default_company_id'));
|
||||
|
||||
/* If we already have a record of this user - move along. */
|
||||
if($client_contact = ClientContact::on('db-ninja-01')->where(['email' => $owner->email, 'company_id' => $ninja_company->id])->exists())
|
||||
return $client_contact->client;
|
||||
|
||||
$ninja_client = ClientFactory::create($ninja_company->id, $ninja_company->owner()->id);
|
||||
$ninja_client->setConnection('db-ninja-01');
|
||||
$ninja_client->name = $owner->present()->name();
|
||||
$ninja_client->address1 = $local_company->settings->address1;
|
||||
$ninja_client->address2 = $local_company->settings->address2;
|
||||
$ninja_client->city = $local_company->settings->city;
|
||||
$ninja_client->postal_code = $local_company->settings->postal_code;
|
||||
$ninja_client->state = $local_company->settings->state;
|
||||
$ninja_client->country_id = $local_company->settings->country_id;
|
||||
|
||||
$ninja_client->save();
|
||||
|
||||
$ninja_client_contact = ClientContactFactory::create($ninja_company->id, $ninja_company->owner()->id);
|
||||
$ninja_client_contact->setConnection('db-ninja-01');
|
||||
$ninja_client_contact->first_name = $owner->first_name;
|
||||
$ninja_client_contact->last_name = $owner->last_name;
|
||||
$ninja_client_contact->client_id = $ninja_client->id;
|
||||
$ninja_client_contact->email = $owner->email;
|
||||
$ninja_client_contact->phone = $owner->phone;
|
||||
$ninja_client_contact->save();
|
||||
|
||||
|
||||
return $ninja_client;
|
||||
}
|
||||
|
||||
private function processNinjaTokens(array $data)
|
||||
{
|
||||
if(count($data) == 0)
|
||||
$ninja_client = $this->buildNewUserPlan();
|
||||
|
||||
foreach($data as $token)
|
||||
{
|
||||
//get invoiceninja company_id
|
||||
$ninja_company = Company::on('db-ninja-01')->where('id', config('ninja.ninja_default_company_id'))->first();
|
||||
|
||||
$token['company_id'] = $ninja_client->company_id;
|
||||
$token['client_id'] = $ninja_client->id;
|
||||
$token['user_id'] = $ninja_client->user_id;
|
||||
$token['company_gateway_id'] = config('ninja.ninja_default_company_gateway_id');
|
||||
//todo
|
||||
|
||||
ClientGatewayToken::unguard();
|
||||
$cgt = ClientGatewayToken::Create($token);
|
||||
ClientGatewayToken::reguard();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* In V4 we use negative invoices (credits) and add then into the client balance. In V5, these sit off ledger and are applied later.
|
||||
This next section will check for credit balances and reduce the client balance so that the V5 balances are correct
|
||||
|
68
app/Jobs/Util/ImportStripeCustomers.php
Normal file
68
app/Jobs/Util/ImportStripeCustomers.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
namespace App\Jobs\Util;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Client;
|
||||
use App\Models\CompanyGateway;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
|
||||
class ImportStripeCustomers implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public $company;
|
||||
|
||||
private $stripe_keys = ['d14dd26a47cecc30fdd65700bfb67b34', 'd14dd26a37cecc30fdd65700bfb55b23'];
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param $event_id
|
||||
* @param $entity
|
||||
*/
|
||||
public function __construct($company)
|
||||
{
|
||||
$this->company = $company;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
MultiDB::setDb($this->company->db);
|
||||
|
||||
$cgs = CompanyGateway::where('company_id', $this->company->id)
|
||||
->whereIn('gateway_key', $this->stripe_keys)
|
||||
->get();
|
||||
|
||||
$cgs->each(function ($company_gateway){
|
||||
|
||||
$company_gateway->driver(new Client)->importCustomers();
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public function failed($exception)
|
||||
{
|
||||
nlog("Stripe import customer methods exception");
|
||||
nlog($exception->getMessage());
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@
|
||||
namespace App\Jobs\Util;
|
||||
|
||||
use App\Events\Invoice\InvoiceWasEmailed;
|
||||
use App\Jobs\Entity\EmailEntity;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Invoice;
|
||||
use App\Utils\Ninja;
|
||||
|
@ -139,7 +139,7 @@ class StartMigration implements ShouldQueue
|
||||
$this->company->update_products = $update_product_flag;
|
||||
$this->company->save();
|
||||
|
||||
Mail::to($this->user)->send(new MigrationFailed($e, $e->getMessage()));
|
||||
Mail::to($this->user->email, $this->user->name())->send(new MigrationFailed($e, $e->getMessage()));
|
||||
|
||||
if (app()->environment() !== 'production') {
|
||||
info($e->getMessage());
|
||||
|
68
app/Jobs/Util/StripeUpdatePaymentMethods.php
Normal file
68
app/Jobs/Util/StripeUpdatePaymentMethods.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
namespace App\Jobs\Util;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Client;
|
||||
use App\Models\CompanyGateway;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
|
||||
class StripeUpdatePaymentMethods implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public $company;
|
||||
|
||||
private $stripe_keys = ['d14dd26a47cecc30fdd65700bfb67b34', 'd14dd26a37cecc30fdd65700bfb55b23'];
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param $event_id
|
||||
* @param $entity
|
||||
*/
|
||||
public function __construct($company)
|
||||
{
|
||||
$this->company = $company;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
MultiDB::setDb($this->company->db);
|
||||
|
||||
$cgs = CompanyGateway::where('company_id', $this->company->id)
|
||||
->whereIn('gateway_key', $this->stripe_keys)
|
||||
->get();
|
||||
|
||||
$cgs->each(function ($company_gateway){
|
||||
|
||||
$company_gateway->driver(new Client)->updateAllPaymentMethods();
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public function failed($exception)
|
||||
{
|
||||
nlog("Stripe update payment methods exception");
|
||||
nlog($exception->getMessage());
|
||||
}
|
||||
}
|
@ -11,7 +11,9 @@
|
||||
|
||||
namespace App\Jobs\Util;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Client;
|
||||
use App\Models\Company;
|
||||
use App\Models\SystemLog;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
@ -33,24 +35,32 @@ class SystemLogger implements ShouldQueue
|
||||
|
||||
protected $client;
|
||||
|
||||
public function __construct($log, $category_id, $event_id, $type_id, ?Client $client)
|
||||
protected $company;
|
||||
|
||||
public function __construct($log, $category_id, $event_id, $type_id, ?Client $client, Company $company)
|
||||
{
|
||||
$this->log = $log;
|
||||
$this->category_id = $category_id;
|
||||
$this->event_id = $event_id;
|
||||
$this->type_id = $type_id;
|
||||
$this->client = $client;
|
||||
$this->company = $company;
|
||||
}
|
||||
|
||||
public function handle() :void
|
||||
{
|
||||
if(!$this->client)
|
||||
if(!$this->company)
|
||||
return;
|
||||
|
||||
|
||||
MultiDB::setDb($this->company->db);
|
||||
|
||||
$client_id = $this->client ? $this->client->id : null;
|
||||
$user_id = $this->client ? $this->client->user_id : $this->company->owner()->id;
|
||||
|
||||
$sl = [
|
||||
'client_id' => $this->client->id,
|
||||
'company_id' => $this->client->company->id,
|
||||
'user_id' => $this->client->user_id,
|
||||
'client_id' => $client_id,
|
||||
'company_id' => $this->company->id,
|
||||
'user_id' => $user_id,
|
||||
'log' => $this->log,
|
||||
'category_id' => $this->category_id,
|
||||
'event_id' => $this->event_id,
|
||||
|
@ -39,8 +39,6 @@ class UnlinkFile implements ShouldQueue
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
// nlog("deleting");
|
||||
// nlog($this->file_path);
|
||||
Storage::disk($this->disk)->delete($this->file_path);
|
||||
}
|
||||
}
|
||||
|
@ -123,6 +123,7 @@ class WebhookHandler implements ShouldQueue
|
||||
SystemLog::EVENT_WEBHOOK_RESPONSE,
|
||||
SystemLog::TYPE_WEBHOOK_RESPONSE,
|
||||
$this->company->clients->first(),
|
||||
$this->company
|
||||
);
|
||||
|
||||
}
|
||||
@ -136,6 +137,7 @@ class WebhookHandler implements ShouldQueue
|
||||
SystemLog::EVENT_WEBHOOK_RESPONSE,
|
||||
SystemLog::TYPE_WEBHOOK_RESPONSE,
|
||||
$this->company->clients->first(),
|
||||
$this->company,
|
||||
);
|
||||
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ class MultiDB
|
||||
return Company::whereSubdomain($subdomain)->get()->count() == 0;
|
||||
}
|
||||
|
||||
|
||||
//multi-db active
|
||||
foreach (self::$dbs as $db) {
|
||||
if (Company::on($db)->whereSubdomain($subdomain)->get()->count() >= 1) {
|
||||
@ -63,7 +64,7 @@ class MultiDB
|
||||
}
|
||||
}
|
||||
|
||||
self::setDefaultDatabase();
|
||||
//self::setDefaultDatabase();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -129,13 +130,12 @@ class MultiDB
|
||||
}
|
||||
|
||||
foreach (self::$dbs as $db) {
|
||||
|
||||
self::setDB($db);
|
||||
|
||||
$user = User::where($data)->withTrashed()->first();
|
||||
|
||||
if ($user) {
|
||||
if ($user = User::where($data)->withTrashed()->first())
|
||||
return $user;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
self::setDefaultDatabase();
|
||||
@ -147,18 +147,18 @@ class MultiDB
|
||||
* @param array $data
|
||||
* @return User|null
|
||||
*/
|
||||
public static function hasContact(array $data) : ?ClientContact
|
||||
public static function hasContact(string $email) : ?ClientContact
|
||||
{
|
||||
if (! config('ninja.db.multi_db_enabled')) {
|
||||
return ClientContact::where($data)->withTrashed()->first();
|
||||
return ClientContact::where('email', $email)->withTrashed()->first();
|
||||
}
|
||||
|
||||
foreach (self::$dbs as $db) {
|
||||
self::setDB($db);
|
||||
|
||||
$user = ClientContacts::where($data)->withTrashed()->first();
|
||||
|
||||
$user = ClientContact::on($db)->where('email', $email)->withTrashed()->first();
|
||||
|
||||
if ($user) {
|
||||
self::setDB($db);
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
@ -189,12 +189,15 @@ class MultiDB
|
||||
//multi-db active
|
||||
foreach (self::$dbs as $db) {
|
||||
|
||||
if (User::on($db)->where(['email' => $email])->count() >= 1)
|
||||
if (User::on($db)->where('email', $email)->count() >= 1){
|
||||
nlog("setting db {$db}");
|
||||
self::setDb($db);
|
||||
return true;
|
||||
|
||||
}
|
||||
self::setDefaultDatabase();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
self::setDefaultDatabase();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -203,7 +206,6 @@ class MultiDB
|
||||
foreach (self::$dbs as $db) {
|
||||
if ($ct = CompanyToken::on($db)->whereRaw('BINARY `token`= ?', [$token])->first()) {
|
||||
self::setDb($ct->company->db);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -252,14 +254,14 @@ class MultiDB
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function findAndSetDbByDomain($subdomain) :bool
|
||||
public static function findAndSetDbByDomain($query_array) :bool
|
||||
{
|
||||
|
||||
if (! config('ninja.db.multi_db_enabled'))
|
||||
return (Company::whereSubdomain($subdomain)->exists() === true);
|
||||
return (Company::where($query_array)->exists() === true);
|
||||
|
||||
foreach (self::$dbs as $db) {
|
||||
if ($company = Company::on($db)->whereSubdomain($subdomain)->first()) {
|
||||
if ($company = Company::on($db)->where($query_array)->first()) {
|
||||
self::setDb($company->db);
|
||||
return true;
|
||||
}
|
||||
|
@ -43,6 +43,9 @@ class InvoiceEmailFailedActivity implements ShouldQueue
|
||||
|
||||
MultiDB::setDb($event->company->db);
|
||||
|
||||
if(strpos($event->message, 'shared/public') !== false)
|
||||
$event->message = "Unable to open attachment file for reading";
|
||||
|
||||
$fields = new stdClass;
|
||||
|
||||
$fields->invoice_id = $event->invitation->invoice->id;
|
||||
|
@ -67,12 +67,15 @@ class UpdateUserLastLogin implements ShouldQueue
|
||||
$user->save();
|
||||
}
|
||||
|
||||
$arr = json_encode(['ip' => $ip]);
|
||||
|
||||
SystemLogger::dispatch(
|
||||
$ip,
|
||||
$arr,
|
||||
SystemLog::CATEGORY_SECURITY,
|
||||
SystemLog::EVENT_USER,
|
||||
SystemLog::TYPE_LOGIN_SUCCESS,
|
||||
$event->company->clients()->first(),
|
||||
null,
|
||||
$event->company,
|
||||
);
|
||||
|
||||
}
|
||||
|
@ -27,8 +27,6 @@ class ContactPasswordlessLogin extends Mailable
|
||||
*/
|
||||
public $email;
|
||||
|
||||
public $url = 'https://google.com';
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
@ -49,6 +47,8 @@ class ContactPasswordlessLogin extends Mailable
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this->view('email.billing.passwordless-login');
|
||||
return $this
|
||||
->subject(ctrans('texts.account_passwordless_login'))
|
||||
->view('email.billing.passwordless-login');
|
||||
}
|
||||
}
|
||||
|
53
app/Mail/DownloadBackup.php
Normal file
53
app/Mail/DownloadBackup.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Models\Company;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class DownloadBackup extends Mailable
|
||||
{
|
||||
|
||||
public $file_path;
|
||||
|
||||
public $company;
|
||||
|
||||
public function __construct($file_path, Company $company)
|
||||
{
|
||||
$this->file_path = $file_path;
|
||||
|
||||
$this->company = $company;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
$company = Company::where('company_key', $this->company->company_key)->first();
|
||||
|
||||
return $this->from(config('mail.from.address'), config('mail.from.name'))
|
||||
->subject(ctrans('texts.download_backup_subject', ['company' => $company->present()->name()]))
|
||||
->markdown(
|
||||
'email.admin.download_files',
|
||||
[
|
||||
'url' => $this->file_path,
|
||||
'logo' => $company->present()->logo,
|
||||
'whitelabel' => $company->account->isPaid() ? true : false,
|
||||
'settings' => $company->settings,
|
||||
'greeting' => $company->present()->name(),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
@ -95,9 +95,12 @@ class CreditEmailEngine extends BaseEmailEngine
|
||||
->setInvitation($this->invitation);
|
||||
|
||||
if ($this->client->getSetting('pdf_email_attachment') !== false && $this->credit->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
|
||||
$this->setAttachments([$this->credit->pdf_file_path()]);
|
||||
|
||||
// $this->setAttachments(['path' => $this->credit->pdf_file_path(), 'name' => basename($this->credit->pdf_file_path())]);
|
||||
if(Ninja::isHosted())
|
||||
$this->setAttachments([$this->credit->pdf_file_path(null, 'url', true)]);
|
||||
else
|
||||
$this->setAttachments([$this->credit->pdf_file_path()]);
|
||||
|
||||
}
|
||||
|
||||
//attach third party documents
|
||||
|
@ -106,7 +106,12 @@ class InvoiceEmailEngine extends BaseEmailEngine
|
||||
->setInvitation($this->invitation);
|
||||
|
||||
if ($this->client->getSetting('pdf_email_attachment') !== false && $this->invoice->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
|
||||
$this->setAttachments([$this->invoice->pdf_file_path()]);
|
||||
|
||||
if(Ninja::isHosted())
|
||||
$this->setAttachments([$this->invoice->pdf_file_path(null, 'url', true)]);
|
||||
else
|
||||
$this->setAttachments([$this->invoice->pdf_file_path()]);
|
||||
|
||||
// $this->setAttachments(['path' => $this->invoice->pdf_file_path(), 'name' => basename($this->invoice->pdf_file_path())]);
|
||||
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace App\Mail\Engine;
|
||||
|
||||
use App\DataMapper\EmailTemplateDefaults;
|
||||
use App\Models\Account;
|
||||
use App\Utils\Helpers;
|
||||
use App\Utils\Number;
|
||||
use App\Utils\Traits\MakesDates;
|
||||
@ -72,6 +73,16 @@ class PaymentEmailEngine extends BaseEmailEngine
|
||||
->setViewLink('')
|
||||
->setViewText('');
|
||||
|
||||
if ($this->client->getSetting('pdf_email_attachment') !== false && $this->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
|
||||
|
||||
$this->payment->invoices->each(function ($invoice){
|
||||
|
||||
$this->setAttachments([$invoice->pdf_file_path()]);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -97,8 +97,11 @@ class QuoteEmailEngine extends BaseEmailEngine
|
||||
|
||||
|
||||
if ($this->client->getSetting('pdf_email_attachment') !== false && $this->quote->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
|
||||
$this->setAttachments([$this->quote->pdf_file_path()]);
|
||||
//$this->setAttachments(['path' => $this->quote->pdf_file_path(), 'name' => basename($this->quote->pdf_file_path())]);
|
||||
|
||||
if(Ninja::isHosted())
|
||||
$this->setAttachments([$this->quote->pdf_file_path(null, 'url', true)]);
|
||||
else
|
||||
$this->setAttachments([$this->quote->pdf_file_path()]);
|
||||
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@ class TemplateEmail extends Mailable
|
||||
});
|
||||
|
||||
//conditionally attach files
|
||||
if ($settings->pdf_email_attachment !== false && ! empty($this->build_email->getAttachments())) {
|
||||
// if ($settings->pdf_email_attachment !== false && ! empty($this->build_email->getAttachments())) {
|
||||
|
||||
//hosted | plan check here
|
||||
foreach ($this->build_email->getAttachments() as $file) {
|
||||
@ -118,7 +118,7 @@ class TemplateEmail extends Mailable
|
||||
$this->attach($file['path'], ['as' => $file['name'], 'mime' => $file['mime']]);
|
||||
|
||||
}
|
||||
}
|
||||
// }
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -13,12 +13,14 @@ namespace App\Models;
|
||||
|
||||
use App\DataMapper\ClientSettings;
|
||||
use App\DataMapper\CompanySettings;
|
||||
use App\Jobs\Entity\CreateEntityPdf;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Utils\Traits\UserSessionAttributes;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException as ModelNotFoundException;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
|
||||
/**
|
||||
@ -199,4 +201,5 @@ class BaseModel extends Model
|
||||
|
||||
return $formatted_number;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Presenters\CompanyPresenter;
|
||||
use App\Models\User;
|
||||
use App\Services\Notification\NotificationService;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Traits\CompanySettingsSaver;
|
||||
@ -20,8 +21,8 @@ use App\Utils\Traits\ThrottlesEmail;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Laracasts\Presenter\PresentableTrait;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Laracasts\Presenter\PresentableTrait;
|
||||
|
||||
class Company extends BaseModel
|
||||
{
|
||||
@ -150,6 +151,11 @@ class Company extends BaseModel
|
||||
return $this->belongsTo(Account::class);
|
||||
}
|
||||
|
||||
public function client_contacts()
|
||||
{
|
||||
return $this->hasMany(ClientContact::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function users()
|
||||
{
|
||||
return $this->hasManyThrough(User::class, CompanyUser::class, 'company_id', 'id', 'id', 'user_id');
|
||||
@ -203,6 +209,12 @@ class Company extends BaseModel
|
||||
return $this->hasMany(Vendor::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function all_activities()
|
||||
{
|
||||
return $this->hasMany(Activity::class);
|
||||
}
|
||||
|
||||
|
||||
public function activities()
|
||||
{
|
||||
return $this->hasMany(Activity::class)->orderBy('id', 'DESC')->take(300);
|
||||
@ -301,11 +313,21 @@ class Company extends BaseModel
|
||||
return $this->hasMany(Design::class)->whereCompanyId($this->id)->orWhere('company_id', null);
|
||||
}
|
||||
|
||||
public function user_designs()
|
||||
{
|
||||
return $this->hasMany(Design::class);
|
||||
}
|
||||
|
||||
public function payment_terms()
|
||||
{
|
||||
return $this->hasMany(PaymentTerm::class)->whereCompanyId($this->id)->orWhere('company_id', null);
|
||||
}
|
||||
|
||||
public function user_payment_terms()
|
||||
{
|
||||
return $this->hasMany(PaymentTerm::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo
|
||||
*/
|
||||
@ -411,9 +433,7 @@ class Company extends BaseModel
|
||||
|
||||
public function owner()
|
||||
{
|
||||
$c = $this->company_users->where('is_owner', true)->first();
|
||||
|
||||
return User::find($c->user_id);
|
||||
return $this->company_users->where('is_owner', true)->first()->user;
|
||||
}
|
||||
|
||||
public function resolveRouteBinding($value, $field = null)
|
||||
@ -423,12 +443,12 @@ class Company extends BaseModel
|
||||
|
||||
public function domain()
|
||||
{
|
||||
if (Ninja::isNinja()) {
|
||||
if (Ninja::isHosted()) {
|
||||
|
||||
if($this->portal_mode == 'domain')
|
||||
return $this->portal_domain;
|
||||
|
||||
return "https://{$this->subdomain}" . config('ninja.app_domain');
|
||||
return "https://{$this->subdomain}." . config('ninja.app_domain');
|
||||
}
|
||||
|
||||
return config('ninja.app_url');
|
||||
|
@ -309,14 +309,14 @@ class CompanyGateway extends BaseModel
|
||||
$fees_and_limits = $this->getFeesAndLimits($gateway_type_id);
|
||||
|
||||
if (! $fees_and_limits) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
$fee = 0;
|
||||
|
||||
if ($fees_and_limits->fee_amount) {
|
||||
$fee += $fees_and_limits->fee_amount;
|
||||
// info("fee after adding fee amount = {$fee}");
|
||||
nlog("fee after adding fee amount = {$fee}");
|
||||
}
|
||||
|
||||
if ($fees_and_limits->fee_percent) {
|
||||
@ -325,7 +325,7 @@ class CompanyGateway extends BaseModel
|
||||
} else {
|
||||
$fee += round(($amount * $fees_and_limits->fee_percent / 100), 2);
|
||||
}
|
||||
// info("fee after adding fee percent = {$fee}");
|
||||
nlog("fee after adding fee percent = {$fee}");
|
||||
}
|
||||
|
||||
/* Cap fee if we have to here. */
|
||||
@ -334,6 +334,7 @@ class CompanyGateway extends BaseModel
|
||||
}
|
||||
|
||||
$pre_tax_fee = $fee;
|
||||
nlog("fee after adding fee percent = {$fee}");
|
||||
|
||||
/**/
|
||||
if ($include_taxes) {
|
||||
@ -352,6 +353,7 @@ class CompanyGateway extends BaseModel
|
||||
// info("fee after adding fee tax 3 = {$fee}");
|
||||
}
|
||||
}
|
||||
nlog("fee after adding fee percent = {$fee}");
|
||||
|
||||
return $fee;
|
||||
}
|
||||
|
@ -251,23 +251,37 @@ class Credit extends BaseModel
|
||||
$this->save();
|
||||
}
|
||||
|
||||
public function pdf_file_path($invitation = null)
|
||||
public function pdf_file_path($invitation = null, string $type = 'path', bool $portal = false)
|
||||
{
|
||||
$storage_path = Storage::url($this->client->credit_filepath().$this->numberFormatter().'.pdf');
|
||||
|
||||
if (Storage::exists($this->client->credit_filepath().$this->numberFormatter().'.pdf')) {
|
||||
return $storage_path;
|
||||
}
|
||||
|
||||
if (! $invitation) {
|
||||
event(new CreditWasUpdated($this, $this->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
CreateEntityPdf::dispatchNow($this->invitations->first());
|
||||
} else {
|
||||
event(new CreditWasUpdated($this, $this->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
CreateEntityPdf::dispatchNow($invitation);
|
||||
|
||||
if($this->invitations()->exists())
|
||||
$invitation = $this->invitations()->first();
|
||||
else{
|
||||
$this->service()->createInvitations();
|
||||
$invitation = $this->invitations()->first();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $storage_path;
|
||||
if(!$invitation)
|
||||
throw new \Exception('Hard fail, could not create an invitation - is there a valid contact?');
|
||||
|
||||
$file_path = $this->client->credit_filepath().$this->numberFormatter().'.pdf';
|
||||
|
||||
if(Ninja::isHosted() && $portal && Storage::disk(config('filesystems.default'))->exists($file_path)){
|
||||
return Storage::disk(config('filesystems.default'))->{$type}($file_path);
|
||||
}
|
||||
elseif(Ninja::isHosted() && $portal){
|
||||
$file_path = CreateEntityPdf::dispatchNow($invitation,config('filesystems.default'));
|
||||
return Storage::disk(config('filesystems.default'))->{$type}($file_path);
|
||||
}
|
||||
|
||||
if(Storage::disk('public')->exists($file_path))
|
||||
return Storage::disk('public')->{$type}($file_path);
|
||||
|
||||
$file_path = CreateEntityPdf::dispatchNow($invitation);
|
||||
return Storage::disk('public')->{$type}($file_path);
|
||||
}
|
||||
|
||||
public function markInvitationsSent()
|
||||
|
@ -96,4 +96,9 @@ class Expense extends BaseModel
|
||||
{
|
||||
return $this->belongsTo(Vendor::class);
|
||||
}
|
||||
|
||||
public function client()
|
||||
{
|
||||
return $this->belongsTo(Client::class);
|
||||
}
|
||||
}
|
||||
|
@ -392,7 +392,7 @@ class Invoice extends BaseModel
|
||||
return $invoice_calc->build();
|
||||
}
|
||||
|
||||
public function pdf_file_path($invitation = null, string $type = 'url')
|
||||
public function pdf_file_path($invitation = null, string $type = 'path', bool $portal = false)
|
||||
{
|
||||
if (! $invitation) {
|
||||
|
||||
@ -408,19 +408,23 @@ class Invoice extends BaseModel
|
||||
if(!$invitation)
|
||||
throw new \Exception('Hard fail, could not create an invitation - is there a valid contact?');
|
||||
|
||||
$storage_path = Storage::$type($this->client->invoice_filepath().$this->numberFormatter().'.pdf');
|
||||
$file_path = $this->client->invoice_filepath().$this->numberFormatter().'.pdf';
|
||||
|
||||
if (! Storage::exists($this->client->invoice_filepath().$this->numberFormatter().'.pdf')) {
|
||||
event(new InvoiceWasUpdated($this, $this->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
CreateEntityPdf::dispatchNow($invitation);
|
||||
if(Ninja::isHosted() && $portal && Storage::disk(config('filesystems.default'))->exists($file_path)){
|
||||
return Storage::disk(config('filesystems.default'))->{$type}($file_path);
|
||||
}
|
||||
elseif(Ninja::isHosted() && $portal){
|
||||
$file_path = CreateEntityPdf::dispatchNow($invitation,config('filesystems.default'));
|
||||
return Storage::disk(config('filesystems.default'))->{$type}($file_path);
|
||||
}
|
||||
|
||||
if(Storage::disk('public')->exists($file_path))
|
||||
return Storage::disk('public')->{$type}($file_path);
|
||||
|
||||
return $storage_path;
|
||||
$file_path = CreateEntityPdf::dispatchNow($invitation);
|
||||
return Storage::disk('public')->{$type}($file_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates Invites to SENT.
|
||||
*/
|
||||
public function markInvitationsSent()
|
||||
{
|
||||
$this->invitations->each(function ($invitation) {
|
||||
|
@ -207,26 +207,39 @@ class Quote extends BaseModel
|
||||
}
|
||||
|
||||
|
||||
public function pdf_file_path($invitation = null, string $type = 'url')
|
||||
public function pdf_file_path($invitation = null, string $type = 'path', bool $portal = false)
|
||||
{
|
||||
if (! $invitation) {
|
||||
$invitation = $this->invitations->first();
|
||||
|
||||
if($this->invitations()->exists())
|
||||
$invitation = $this->invitations()->first();
|
||||
else{
|
||||
$this->service()->createInvitations();
|
||||
$invitation = $this->invitations()->first();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$storage_path = Storage::$type($this->client->quote_filepath().$this->numberFormatter().'.pdf');
|
||||
if(!$invitation)
|
||||
throw new \Exception('Hard fail, could not create an invitation - is there a valid contact?');
|
||||
|
||||
nlog($storage_path);
|
||||
$file_path = $this->client->quote_filepath().$this->numberFormatter().'.pdf';
|
||||
|
||||
if (! Storage::exists($this->client->quote_filepath().$this->numberFormatter().'.pdf')) {
|
||||
event(new QuoteWasUpdated($this, $this->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
CreateEntityPdf::dispatchNow($invitation);
|
||||
if(Ninja::isHosted() && $portal && Storage::disk(config('filesystems.default'))->exists($file_path)){
|
||||
return Storage::disk(config('filesystems.default'))->{$type}($file_path);
|
||||
}
|
||||
elseif(Ninja::isHosted() && $portal){
|
||||
$file_path = CreateEntityPdf::dispatchNow($invitation,config('filesystems.default'));
|
||||
return Storage::disk(config('filesystems.default'))->{$type}($file_path);
|
||||
}
|
||||
|
||||
if(Storage::disk('public')->exists($file_path))
|
||||
return Storage::disk('public')->{$type}($file_path);
|
||||
|
||||
return $storage_path;
|
||||
$file_path = CreateEntityPdf::dispatchNow($invitation);
|
||||
return Storage::disk('public')->{$type}($file_path);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param int $status
|
||||
* @return string
|
||||
|
@ -159,7 +159,7 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
*/
|
||||
public function setCompany($company)
|
||||
{
|
||||
config(['ninja.company_id' => $company->id]);
|
||||
// config(['ninja.company_id' => $company->id]);
|
||||
|
||||
$this->company = $company;
|
||||
}
|
||||
@ -169,16 +169,29 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
*/
|
||||
public function getCompany()
|
||||
{
|
||||
if ($this->company) {
|
||||
return $this->company;
|
||||
}
|
||||
|
||||
if (request()->header('X-API-TOKEN')) {
|
||||
$company_token = CompanyToken::whereRaw('BINARY `token`= ?', [request()->header('X-API-TOKEN')])->first();
|
||||
$company_token = CompanyToken::with(['company'])->whereRaw('BINARY `token`= ?', [request()->header('X-API-TOKEN')])->first();
|
||||
|
||||
return $company_token->company;
|
||||
}
|
||||
elseif ($this->company){
|
||||
|
||||
return Company::find(config('ninja.company_id'));
|
||||
return $this->company;
|
||||
|
||||
}
|
||||
|
||||
// return false;
|
||||
throw new \Exception('No Company Found');
|
||||
//return Company::find(config('ninja.company_id'));
|
||||
}
|
||||
|
||||
public function companyIsSet()
|
||||
{
|
||||
if($this->company)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -136,7 +136,7 @@ class AuthorizeCreditCard
|
||||
|
||||
PaymentFailureMailer::dispatch($this->authorize->client, $response->getTransactionResponse()->getTransId(), $this->authorize->client->company, $amount);
|
||||
|
||||
SystemLogger::dispatch($logger_message, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_AUTHORIZE, $this->authorize->client);
|
||||
SystemLogger::dispatch($logger_message, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_AUTHORIZE, $this->authorize->client, $this->authorize->client->company);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -192,7 +192,8 @@ class AuthorizeCreditCard
|
||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||
SystemLog::EVENT_GATEWAY_SUCCESS,
|
||||
SystemLog::TYPE_AUTHORIZE,
|
||||
$this->authorize->client
|
||||
$this->authorize->client,
|
||||
$this->authorize->client->company,
|
||||
);
|
||||
|
||||
return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
|
||||
|
@ -86,7 +86,7 @@ class RefundTransaction
|
||||
'amount' => $amount,
|
||||
];
|
||||
|
||||
SystemLogger::dispatch($data, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_SUCCESS, SystemLog::TYPE_AUTHORIZE, $this->authorize->client);
|
||||
SystemLogger::dispatch($data, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_SUCCESS, SystemLog::TYPE_AUTHORIZE, $this->authorize->client, $this->authorize->client->company);
|
||||
|
||||
|
||||
return $data;
|
||||
@ -105,7 +105,7 @@ class RefundTransaction
|
||||
'amount' => $amount,
|
||||
];
|
||||
|
||||
SystemLogger::dispatch($data, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_AUTHORIZE, $this->authorize->client);
|
||||
SystemLogger::dispatch($data, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_AUTHORIZE, $this->authorize->client, $this->authorize->client->company);
|
||||
|
||||
return $data;
|
||||
}
|
||||
@ -125,7 +125,7 @@ class RefundTransaction
|
||||
'amount' => $amount,
|
||||
];
|
||||
|
||||
SystemLogger::dispatch($data, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_AUTHORIZE, $this->authorize->client);
|
||||
SystemLogger::dispatch($data, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_AUTHORIZE, $this->authorize->client, $this->authorize->client->company);
|
||||
|
||||
return $data;
|
||||
|
||||
@ -141,7 +141,7 @@ class RefundTransaction
|
||||
'amount' => $amount,
|
||||
];
|
||||
|
||||
SystemLogger::dispatch($data, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_AUTHORIZE, $this->authorize->client);
|
||||
SystemLogger::dispatch($data, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_AUTHORIZE, $this->authorize->client, $this->authorize->client->company);
|
||||
|
||||
return $data;
|
||||
}
|
||||
@ -158,7 +158,7 @@ class RefundTransaction
|
||||
'amount' => $amount,
|
||||
];
|
||||
|
||||
SystemLogger::dispatch($data, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_AUTHORIZE, $this->authorize->client);
|
||||
SystemLogger::dispatch($data, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_AUTHORIZE, $this->authorize->client, $this->authorize->client->company);
|
||||
|
||||
return $data;
|
||||
}
|
||||
@ -173,7 +173,7 @@ class RefundTransaction
|
||||
'amount' => $amount,
|
||||
];
|
||||
|
||||
SystemLogger::dispatch($data, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_AUTHORIZE, $this->authorize->client);
|
||||
SystemLogger::dispatch($data, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_AUTHORIZE, $this->authorize->client, $this->authorize->client->company);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -394,6 +394,7 @@ class BaseDriver extends AbstractPaymentDriver
|
||||
SystemLog::EVENT_GATEWAY_ERROR,
|
||||
$gateway::SYSTEM_LOG_TYPE,
|
||||
$gateway->client,
|
||||
$gateway->client->company,
|
||||
);
|
||||
|
||||
throw new PaymentFailed($error, $e->getCode());
|
||||
@ -527,6 +528,7 @@ class BaseDriver extends AbstractPaymentDriver
|
||||
SystemLog::EVENT_GATEWAY_SUCCESS,
|
||||
$gateway_const,
|
||||
$this->client,
|
||||
$this->client->company,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -149,7 +149,8 @@ class CreditCard
|
||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||
SystemLog::EVENT_GATEWAY_SUCCESS,
|
||||
SystemLog::TYPE_BRAINTREE,
|
||||
$this->braintree->client
|
||||
$this->braintree->client,
|
||||
$this->braintree->client->company,
|
||||
);
|
||||
|
||||
return redirect()->route('client.payments.show', ['payment' => $this->braintree->encodePrimaryKey($payment->id)]);
|
||||
@ -179,7 +180,8 @@ class CreditCard
|
||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||
SystemLog::EVENT_GATEWAY_FAILURE,
|
||||
SystemLog::TYPE_BRAINTREE,
|
||||
$this->braintree->client
|
||||
$this->braintree->client,
|
||||
$this->braintree->client->company,
|
||||
);
|
||||
|
||||
throw new PaymentFailed($response->transaction->additionalProcessorResponse, $response->transaction->processorResponseCode);
|
||||
|
@ -76,7 +76,8 @@ trait Utilities
|
||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||
SystemLog::EVENT_GATEWAY_SUCCESS,
|
||||
SystemLog::TYPE_CHECKOUT,
|
||||
$this->getParent()->client
|
||||
$this->getParent()->client,
|
||||
$this->getParent()->client->company
|
||||
);
|
||||
|
||||
return redirect()->route('client.payments.show', ['payment' => $this->getParent()->encodePrimaryKey($payment->id)]);
|
||||
@ -101,7 +102,8 @@ trait Utilities
|
||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||
SystemLog::EVENT_GATEWAY_FAILURE,
|
||||
SystemLog::TYPE_CHECKOUT,
|
||||
$this->getParent()->client
|
||||
$this->getParent()->client,
|
||||
$this->getParent()->client->company,
|
||||
);
|
||||
|
||||
if ($throw_exception) {
|
||||
|
@ -282,7 +282,7 @@ class CheckoutComPaymentDriver extends BaseDriver
|
||||
'message' => $message,
|
||||
];
|
||||
|
||||
SystemLogger::dispatch($data, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_CHECKOUT, $this->client);
|
||||
SystemLogger::dispatch($data, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_CHECKOUT, $this->client, $this->client->company);
|
||||
}
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user