mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Merge pull request #5945 from turbo124/v5-develop
MultiDB fixes for livewire
This commit is contained in:
commit
df04fa0f62
@ -12,6 +12,7 @@
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Credit;
|
||||
use App\Utils\Traits\WithSorting;
|
||||
use Livewire\Component;
|
||||
@ -24,6 +25,13 @@ class CreditsTable extends Component
|
||||
|
||||
public $per_page = 10;
|
||||
|
||||
public $company;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
MultiDB::setDb($this->company->db);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
$query = Credit::query()
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Client;
|
||||
use App\Utils\Traits\WithSorting;
|
||||
use Livewire\Component;
|
||||
@ -25,8 +26,13 @@ class DocumentsTable extends Component
|
||||
|
||||
public $per_page = 10;
|
||||
|
||||
public $company;
|
||||
|
||||
public function mount($client)
|
||||
{
|
||||
|
||||
MultiDB::setDb($this->company->db);
|
||||
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Invoice;
|
||||
use App\Utils\Traits\WithSorting;
|
||||
use Carbon\Carbon;
|
||||
@ -26,8 +27,12 @@ class InvoicesTable extends Component
|
||||
|
||||
public $status = [];
|
||||
|
||||
public $company;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
MultiDB::setDb($this->company->db);
|
||||
|
||||
$this->sort_asc = false;
|
||||
|
||||
$this->sort_field = 'date';
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use Livewire\Component;
|
||||
|
||||
class PayNowDropdown extends Component
|
||||
@ -20,8 +21,12 @@ class PayNowDropdown extends Component
|
||||
|
||||
public $methods;
|
||||
|
||||
public $company;
|
||||
|
||||
public function mount(int $total)
|
||||
{
|
||||
MultiDB::setDb($this->company->db);
|
||||
|
||||
$this->total = $total;
|
||||
|
||||
$this->methods = auth()->user()->client->service()->getPaymentMethods($total);
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\ClientGatewayToken;
|
||||
use App\Utils\Traits\WithSorting;
|
||||
use Livewire\Component;
|
||||
@ -16,10 +17,16 @@ class PaymentMethodsTable extends Component
|
||||
use WithSorting;
|
||||
|
||||
public $per_page = 10;
|
||||
|
||||
public $client;
|
||||
|
||||
public $company;
|
||||
|
||||
public function mount($client)
|
||||
{
|
||||
|
||||
MultiDB::setDb($this->company->db);
|
||||
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Payment;
|
||||
use App\Utils\Traits\WithSorting;
|
||||
use Livewire\Component;
|
||||
@ -23,11 +24,17 @@ class PaymentsTable extends Component
|
||||
use WithPagination;
|
||||
|
||||
public $per_page = 10;
|
||||
|
||||
public $user;
|
||||
|
||||
public $company;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
MultiDB::setDb($this->company->db);
|
||||
|
||||
$this->user = auth()->user();
|
||||
|
||||
}
|
||||
|
||||
public function render()
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Quote;
|
||||
use App\Utils\Traits\WithSorting;
|
||||
use Livewire\Component;
|
||||
@ -23,8 +24,17 @@ class QuotesTable extends Component
|
||||
use WithPagination;
|
||||
|
||||
public $per_page = 10;
|
||||
|
||||
public $status = [];
|
||||
|
||||
public $company;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
MultiDB::setDb($this->company->db);
|
||||
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
$query = Quote::query()
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\RecurringInvoice;
|
||||
use Livewire\Component;
|
||||
|
||||
@ -22,6 +23,18 @@ class RecurringInvoiceCancellation extends Component
|
||||
*/
|
||||
public $invoice;
|
||||
|
||||
public $company;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
MultiDB::setDb($this->company->db);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return render('components.livewire.recurring-invoice-cancellation');
|
||||
}
|
||||
|
||||
public function processCancellation()
|
||||
{
|
||||
if ($this->invoice->subscription) {
|
||||
@ -31,8 +44,5 @@ class RecurringInvoiceCancellation extends Component
|
||||
return redirect()->route('client.recurring_invoices.request_cancellation', ['recurring_invoice' => $this->invoice->hashed_id]);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return render('components.livewire.recurring-invoice-cancellation');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\ClientContact;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Str;
|
||||
@ -65,7 +66,12 @@ class RequiredClientInfo extends Component
|
||||
|
||||
public $show_form = false;
|
||||
|
||||
public function mount() {}
|
||||
public $company;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
MultiDB::setDb($this->company->db);
|
||||
}
|
||||
|
||||
public function handleSubmit(array $data): bool
|
||||
{
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Subscription;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
@ -71,8 +72,12 @@ class SubscriptionPlanSwitch extends Component
|
||||
*/
|
||||
public $hash;
|
||||
|
||||
public $company;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
MultiDB::setDb($this->company->db);
|
||||
|
||||
$this->total = $this->amount;
|
||||
|
||||
$this->methods = $this->contact->client->service()->getPaymentMethods($this->amount);
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Utils\Traits\WithSorting;
|
||||
use Livewire\Component;
|
||||
@ -24,6 +25,13 @@ class SubscriptionRecurringInvoicesTable extends Component
|
||||
|
||||
public $per_page = 10;
|
||||
|
||||
public $company;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
MultiDB::setDb($this->company->db);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
$query = RecurringInvoice::query()
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Task;
|
||||
use App\Utils\Traits\WithSorting;
|
||||
use Livewire\Component;
|
||||
@ -24,6 +25,13 @@ class TasksTable extends Component
|
||||
|
||||
public $per_page = 10;
|
||||
|
||||
public $company;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
MultiDB::setDb($this->company->db);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
$query = Task::query()
|
||||
|
@ -19,6 +19,7 @@ use App\Jobs\Util\UnlinkFile;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Mail\DownloadBackup;
|
||||
use App\Mail\DownloadInvoices;
|
||||
use App\Mail\Import\CompanyImportFailure;
|
||||
use App\Models\Activity;
|
||||
use App\Models\Backup;
|
||||
use App\Models\Client;
|
||||
@ -88,6 +89,8 @@ class CompanyImport implements ShouldQueue
|
||||
|
||||
private $request_array = [];
|
||||
|
||||
private $message = '';
|
||||
|
||||
private $importables = [
|
||||
// 'company',
|
||||
'users',
|
||||
@ -148,6 +151,8 @@ class CompanyImport implements ShouldQueue
|
||||
$this->company = Company::where('company_key', $this->company->company_key)->firstOrFail();
|
||||
$this->account = $this->company->account;
|
||||
|
||||
nlog("Company ID = {$this->company->id}");
|
||||
|
||||
$this->backup_file = Cache::get($this->hash);
|
||||
|
||||
if ( empty( $this->backup_file ) )
|
||||
@ -163,14 +168,97 @@ class CompanyImport implements ShouldQueue
|
||||
|
||||
if(array_key_exists('import_data', $this->request_array) && $this->request_array['import_data'] == 'true') {
|
||||
|
||||
$this->preFlightChecks()
|
||||
->purgeCompanyData()
|
||||
->importData();
|
||||
try{
|
||||
|
||||
$this->preFlightChecks()
|
||||
->purgeCompanyData()
|
||||
->importData();
|
||||
|
||||
}
|
||||
catch(\Exception $e){
|
||||
|
||||
info($e->getMessage());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* On the hosted platform we cannot allow the
|
||||
* import to start if there are users > plan number
|
||||
* due to entity user_id dependencies
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function checkUserCount()
|
||||
{
|
||||
|
||||
if(Ninja::isSelfHost())
|
||||
return true;
|
||||
|
||||
$backup_users = $this->backup_file->users;
|
||||
|
||||
$company_users = $this->company->users;
|
||||
|
||||
$company_owner = $this->company->owner();
|
||||
|
||||
if(Ninja::isFreeHostedClient()){
|
||||
|
||||
if(count($backup_users) > 1){
|
||||
$this->message = 'Only one user can be in the import for a Free Account';
|
||||
}
|
||||
|
||||
if(count($backup_users) == 1 && $company_owner->email != $backup_users[0]->email) {
|
||||
$this->message = 'Account emails do not match. Account owner email must match backup user email';
|
||||
}
|
||||
|
||||
$backup_users_emails = array_column($backup_users, 'email');
|
||||
|
||||
$company_users_emails = $company_users->pluck('email')->toArray();
|
||||
|
||||
$existing_user_count = count(array_intersect($backup_users_emails, $company_users_emails));
|
||||
|
||||
if($existing_user_count > 1){
|
||||
|
||||
if($this->account->plan == 'pro')
|
||||
$this->message = 'Pro plan is limited to one user, you have multiple users in the backup file';
|
||||
|
||||
if($this->account->plan == 'enterprise'){
|
||||
|
||||
$total_import_users = count($backup_users_emails);
|
||||
|
||||
$account_plan_num_user = $this->account->num_users;
|
||||
|
||||
if($total_import_users > $account_plan_num_user){
|
||||
|
||||
$this->message = "Total user count ({$total_import_users}) greater than your plan allows ({$account_plan_num_user})";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(strlen($this->message) > 1){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(Ninja::isFreeHostedClient() && count($this->backup_file->clients) > config('ninja.quotas.free.clients')){
|
||||
|
||||
$client_count = count($this->backup_file->clients);
|
||||
|
||||
$client_limit = config('ninja.quotas.free.clients');
|
||||
|
||||
$this->message = "You are attempting to import ({$client_count}) clients, your current plan allows a total of ({$client_limit})";
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//check if this is a complete company import OR if it is selective
|
||||
/*
|
||||
@ -187,6 +275,18 @@ class CompanyImport implements ShouldQueue
|
||||
}
|
||||
|
||||
|
||||
if(!$this->checkUserCount())
|
||||
{
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new CompanyImportFailure($this->company, $this->message);
|
||||
$nmo->company = $this->company;
|
||||
$nmo->settings = $this->company->settings;
|
||||
$nmo->to_user = $this->company->owner();
|
||||
NinjaMailerJob::dispatchNow($nmo);
|
||||
|
||||
throw new \Exception('Company import check failed');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -239,6 +339,8 @@ class CompanyImport implements ShouldQueue
|
||||
|
||||
$method = "import_{$import}";
|
||||
|
||||
nlog($method);
|
||||
|
||||
$this->{$method}();
|
||||
|
||||
}
|
||||
|
64
app/Mail/Import/CompanyImportFailure.php
Normal file
64
app/Mail/Import/CompanyImportFailure.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\Mail\Import;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class CompanyImportFailure extends Mailable
|
||||
{
|
||||
// use Queueable, SerializesModels;
|
||||
|
||||
public $company;
|
||||
|
||||
public $settings;
|
||||
|
||||
public $logo;
|
||||
|
||||
public $title;
|
||||
|
||||
public $message;
|
||||
|
||||
public $whitelabel;
|
||||
|
||||
public $user_message;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($company, $user_message)
|
||||
{
|
||||
$this->company = $company;
|
||||
$this->user_message = $user_message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
$this->settings = $this->company->settings;
|
||||
$this->logo = $this->company->present()->logo();
|
||||
$this->title = ctrans('texts.max_companies');
|
||||
$this->message = ctrans('texts.max_companies_desc');
|
||||
$this->whitelabel = $this->company->account->isPaid();
|
||||
|
||||
return $this->from(config('mail.from.address'), config('mail.from.name'))
|
||||
->subject(ctrans('texts.company_import_failure_subject'))
|
||||
->view('email.migration.max_companies');
|
||||
}
|
||||
}
|
@ -4254,6 +4254,8 @@ $LANG = array(
|
||||
'account_passwordless_login' => 'Account passwordless login',
|
||||
'user_duplicate_error' => 'Cannot add the same user to the same company',
|
||||
'user_cross_linked_error' => 'User exists but cannot be crossed linked to multiple accounts',
|
||||
'company_import_failure_subject' => 'Error importing :company',
|
||||
'company_import_failure_body' => 'There was an error importing the company data, the error message was:',
|
||||
);
|
||||
|
||||
return $LANG;
|
||||
|
22
resources/views/email/import/import_failure.blade.php
Normal file
22
resources/views/email/import/import_failure.blade.php
Normal file
@ -0,0 +1,22 @@
|
||||
@component('email.template.master', ['design' => 'light', 'settings' => $settings])
|
||||
|
||||
@slot('header')
|
||||
@include('email.components.header', ['logo' => $logo])
|
||||
@endslot
|
||||
|
||||
<h2>{{ctrans('texts.company_import_failure_subject')}}</h2>
|
||||
|
||||
<p>{{ctrans('texts.company_import_failure_body')}}</p>
|
||||
|
||||
@if($user_message)
|
||||
<p>{{ $user_message }}</p>
|
||||
@endif
|
||||
|
||||
@if(isset($whitelabel) && !$whitelabel)
|
||||
@slot('footer')
|
||||
@component('email.components.footer', ['url' => 'https://invoiceninja.com', 'url_text' => '© InvoiceNinja'])
|
||||
For any info, please visit InvoiceNinja.
|
||||
@endcomponent
|
||||
@endslot
|
||||
@endif
|
||||
@endcomponent
|
@ -13,6 +13,6 @@
|
||||
|
||||
@section('body')
|
||||
<div class="flex flex-col">
|
||||
@livewire('credits-table')
|
||||
@livewire('credits-table', ['company' => $company])
|
||||
</div>
|
||||
@endsection
|
@ -14,5 +14,5 @@
|
||||
@csrf
|
||||
</form>
|
||||
|
||||
@livewire('documents-table', ['client' => $client])
|
||||
@livewire('documents-table', ['client' => $client, 'company' => $company])
|
||||
@endsection
|
||||
|
@ -20,6 +20,6 @@
|
||||
</form>
|
||||
</div>
|
||||
<div class="flex flex-col mt-4">
|
||||
@livewire('invoices-table')
|
||||
@livewire('invoices-table', ['company' => $company])
|
||||
</div>
|
||||
@endsection
|
||||
|
@ -19,7 +19,7 @@
|
||||
<div class="col-span-6 md:col-start-2 md:col-span-4">
|
||||
<div class="flex justify-end">
|
||||
<div class="flex justify-end mb-2">
|
||||
@livewire('pay-now-dropdown', ['total' => $total])
|
||||
@livewire('pay-now-dropdown', ['total' => $total, 'company' => $company])
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -47,7 +47,7 @@
|
||||
@if($settings->client_portal_allow_under_payment || $settings->client_portal_allow_over_payment)
|
||||
<button class="button button-primary bg-primary">{{ ctrans('texts.pay_now') }}</button>
|
||||
@else
|
||||
@livewire('pay-now-dropdown', ['total' => $invoice->partial > 0 ? $invoice->partial : $invoice->balance])
|
||||
@livewire('pay-now-dropdown', ['total' => $invoice->partial > 0 ? $invoice->partial : $invoice->balance, 'company' => $company])
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
@ -11,7 +11,7 @@
|
||||
@endpush
|
||||
|
||||
@section('body')
|
||||
@livewire('required-client-info', ['fields' => method_exists($gateway, 'getClientRequiredFields') ? $gateway->getClientRequiredFields() : [], 'contact' => auth('contact')->user(), 'countries' => $countries])
|
||||
@livewire('required-client-info', ['fields' => method_exists($gateway, 'getClientRequiredFields') ? $gateway->getClientRequiredFields() : [], 'contact' => auth('contact')->user(), 'countries' => $countries, 'company' => $company])
|
||||
|
||||
<div class="container mx-auto grid grid-cols-12 opacity-25 pointer-events-none" data-ref="gateway-container">
|
||||
<div class="col-span-12 lg:col-span-6 lg:col-start-4 overflow-hidden bg-white shadow rounded-lg">
|
||||
|
@ -3,6 +3,6 @@
|
||||
|
||||
@section('body')
|
||||
<div class="flex flex-col">
|
||||
@livewire('payment-methods-table', ['client' => $client])
|
||||
@livewire('payment-methods-table', ['client' => $client, 'company' => $company])
|
||||
</div>
|
||||
@endsection
|
||||
|
@ -3,6 +3,6 @@
|
||||
|
||||
@section('body')
|
||||
<div class="flex flex-col">
|
||||
@livewire('payments-table')
|
||||
@livewire('payments-table', ['company' => $company])
|
||||
</div>
|
||||
@endsection
|
@ -22,6 +22,6 @@
|
||||
</form>
|
||||
</div>
|
||||
<div class="flex flex-col mt-4">
|
||||
@livewire('quotes-table')
|
||||
@livewire('quotes-table', ['company' => $company])
|
||||
</div>
|
||||
@endsection
|
@ -34,7 +34,7 @@
|
||||
</div>
|
||||
<div class="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
|
||||
<div class="flex w-full rounded-md shadow-sm sm:ml-3 sm:w-auto">
|
||||
@livewire('recurring-invoice-cancellation', ['invoice' => $invoice])
|
||||
@livewire('recurring-invoice-cancellation', ['invoice' => $invoice, 'company' => $company])
|
||||
</div>
|
||||
<div class="mt-3 flex w-full rounded-md shadow-sm sm:mt-0 sm:w-auto">
|
||||
<button @click="open = false" type="button" class="button button-secondary button-block">
|
||||
|
@ -3,6 +3,6 @@
|
||||
|
||||
@section('body')
|
||||
<div class="flex flex-col">
|
||||
@livewire('recurring-invoices-table')
|
||||
@livewire('recurring-invoices-table', ['company' => $company])
|
||||
</div>
|
||||
@endsection
|
||||
|
@ -3,6 +3,6 @@
|
||||
|
||||
@section('body')
|
||||
<div class="flex flex-col">
|
||||
@livewire('subscription-recurring-invoices-table')
|
||||
@livewire('subscription-recurring-invoices-table', ['company' => $company])
|
||||
</div>
|
||||
@endsection
|
||||
|
@ -42,7 +42,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Payment box -->
|
||||
@livewire('subscription-plan-switch', compact('recurring_invoice', 'subscription', 'target', 'contact', 'amount'))
|
||||
@livewire('subscription-plan-switch', compact('recurring_invoice', 'subscription', 'target', 'contact', 'amount', 'company'))
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
|
@ -3,6 +3,6 @@
|
||||
|
||||
@section('body')
|
||||
<div class="flex flex-col">
|
||||
@livewire('tasks-table')
|
||||
@livewire('tasks-table', ['company' => $company])
|
||||
</div>
|
||||
@endsection
|
||||
|
Loading…
x
Reference in New Issue
Block a user