From d26e347d6dbe24cf7b79634a79485e5060e8eaeb Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 3 Feb 2021 10:59:58 +1100 Subject: [PATCH 1/2] Working on migrations --- app/Console/Commands/ImportMigrations.php | 2 ++ resources/views/email/admin/generic.blade.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/Console/Commands/ImportMigrations.php b/app/Console/Commands/ImportMigrations.php index ccb51a7bbc28..44de5a4a4e2b 100644 --- a/app/Console/Commands/ImportMigrations.php +++ b/app/Console/Commands/ImportMigrations.php @@ -80,6 +80,8 @@ class ImportMigrations extends Command $path = $this->option('path') ?? public_path('storage/migrations/import'); + nlog(public_path('storage/migrations/import')); + $directory = new DirectoryIterator($path); foreach ($directory as $file) { diff --git a/resources/views/email/admin/generic.blade.php b/resources/views/email/admin/generic.blade.php index fb438dc4ef06..f8bf3d4c7681 100644 --- a/resources/views/email/admin/generic.blade.php +++ b/resources/views/email/admin/generic.blade.php @@ -26,7 +26,7 @@ {{ $signature }} @endslot - @if(!$whitelabel) + @if(isset($whitelabel) && !$whitelabel) @slot('footer') @component('email.components.footer', ['url' => 'https://invoiceninja.com', 'url_text' => '© InvoiceNinja']) For any info, please visit InvoiceNinja. From 2e2843c27d7cebeaea16596011629be6cc77912e Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 3 Feb 2021 23:29:44 +1100 Subject: [PATCH 2/2] Fixes for migrations --- app/Console/Commands/CheckData.php | 54 +++++++++-------- app/Http/Controllers/ProjectController.php | 4 ++ app/Jobs/Util/Import.php | 59 ++++++++++++++----- app/Mail/MigrationCompleted.php | 10 +++- app/Repositories/BaseRepository.php | 2 +- .../Migration/InvoiceMigrationRepository.php | 8 +++ .../Migration/PaymentMigrationRepository.php | 10 +++- app/Utils/Traits/Payment/Refundable.php | 2 +- config/ninja.php | 1 + 9 files changed, 105 insertions(+), 45 deletions(-) diff --git a/app/Console/Commands/CheckData.php b/app/Console/Commands/CheckData.php index ee12a25b9981..513199e863aa 100644 --- a/app/Console/Commands/CheckData.php +++ b/app/Console/Commands/CheckData.php @@ -289,30 +289,6 @@ class CheckData extends Command } } - private function checkInvoiceBalances() - { - $wrong_balances = 0; - $wrong_paid_to_dates = 0; - - foreach (Client::where('is_deleted', 0)->cursor() as $client) { - $invoice_balance = $client->invoices->where('is_deleted', false)->where('status_id', '>', 1)->sum('balance'); - $credit_balance = $client->credits->where('is_deleted', false)->sum('balance'); - - // $invoice_balance -= $credit_balance;//doesn't make sense to remove the credit amount - - $ledger = CompanyLedger::where('client_id', $client->id)->orderBy('id', 'DESC')->first(); - - if ($ledger && number_format($invoice_balance, 4) != number_format($client->balance, 4)) { - $wrong_balances++; - $this->logMessage("# {$client->id} " . $client->present()->name.' - '.$client->number." - Balance Failure - Invoice Balances = {$invoice_balance} Client Balance = {$client->balance} Ledger Balance = {$ledger->balance}"); - - $this->isValid = false; - } - } - - $this->logMessage("{$wrong_balances} clients with incorrect balances"); - } - private function checkPaidToDates() { $wrong_paid_to_dates = 0; @@ -390,7 +366,9 @@ class CheckData extends Command $invoice_balance = Invoice::where('client_id', $client->id)->where('is_deleted', false)->where('status_id', '>', 1)->withTrashed()->sum('balance'); $credit_balance = Credit::where('client_id', $client->id)->where('is_deleted', false)->withTrashed()->sum('balance'); - // $invoice_balance -= $credit_balance; + /*Legacy - V4 will add credits to the balance - we may need to reverse engineer this and remove the credits from the client balance otherwise we need this hack here and in the invoice balance check.*/ + if($client->balance != $invoice_balance) + $invoice_balance -= $credit_balance; $ledger = CompanyLedger::where('client_id', $client->id)->orderBy('id', 'DESC')->first(); @@ -405,6 +383,32 @@ class CheckData extends Command $this->logMessage("{$wrong_paid_to_dates} clients with incorrect client balances"); } + + private function checkInvoiceBalances() + { + $wrong_balances = 0; + $wrong_paid_to_dates = 0; + + foreach (Client::where('is_deleted', 0)->cursor() as $client) { + $invoice_balance = $client->invoices->where('is_deleted', false)->where('status_id', '>', 1)->sum('balance'); + $credit_balance = $client->credits->where('is_deleted', false)->sum('balance'); + + if($client->balance != $invoice_balance) + $invoice_balance -= $credit_balance;//doesn't make sense to remove the credit amount + + $ledger = CompanyLedger::where('client_id', $client->id)->orderBy('id', 'DESC')->first(); + + if ($ledger && number_format($invoice_balance, 4) != number_format($client->balance, 4)) { + $wrong_balances++; + $this->logMessage("# {$client->id} " . $client->present()->name.' - '.$client->number." - Balance Failure - Invoice Balances = {$invoice_balance} Client Balance = {$client->balance} Ledger Balance = {$ledger->balance}"); + + $this->isValid = false; + } + } + + $this->logMessage("{$wrong_balances} clients with incorrect balances"); + } + private function checkLogoFiles() { // $accounts = DB::table('accounts') diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php index 97086618f1ed..2c8da54d3e0f 100644 --- a/app/Http/Controllers/ProjectController.php +++ b/app/Http/Controllers/ProjectController.php @@ -266,6 +266,10 @@ class ProjectController extends BaseController $project->number = empty($project->number) ? $this->getNextProjectNumber($project) : $project->number; $project->save(); + if ($request->has('documents')) { + $this->saveDocuments($request->input('documents'), $project); + } + return $this->itemResponse($project->fresh()); } diff --git a/app/Jobs/Util/Import.php b/app/Jobs/Util/Import.php index 7aab42ff4518..16552117ab53 100644 --- a/app/Jobs/Util/Import.php +++ b/app/Jobs/Util/Import.php @@ -649,7 +649,8 @@ class Import implements ShouldQueue unset($resource['invitations'][$key]['recurring_invoice_id']); } - $modified['invitations'] = $resource['invitations']; + $modified['invitations'] = $this->deDuplicateInvitations($resource['invitations']); + } $invoice = $invoice_repository->save( @@ -710,8 +711,10 @@ class Import implements ShouldQueue unset($resource['invitations'][$key]['invoice_id']); } - $modified['invitations'] = $resource['invitations']; + $modified['invitations'] = $this->deDuplicateInvitations($resource['invitations']); + } + $invoice = $invoice_repository->save( $modified, InvoiceFactory::create($this->company->id, $modified['user_id']) @@ -732,6 +735,13 @@ class Import implements ShouldQueue $invoice_repository = null; } + + /* Prevent edge case where V4 has inserted multiple invitations for a resource for a client contact */ + private function deDuplicateInvitations($invitations) + { + return array_intersect_key($invitations, array_unique(array_column($invitations, 'client_contact_id'))); + } + private function processCredits(array $data): void { Credit::unguard(); @@ -811,6 +821,19 @@ class Import implements ShouldQueue unset($modified['id']); + + if (array_key_exists('invitations', $resource)) { + foreach ($resource['invitations'] as $key => $invite) { + $resource['invitations'][$key]['client_contact_id'] = $this->transformId('client_contacts', $invite['client_contact_id']); + $resource['invitations'][$key]['user_id'] = $modified['user_id']; + $resource['invitations'][$key]['company_id'] = $this->company->id; + unset($resource['invitations'][$key]['invoice_id']); + } + + $modified['invitations'] = $this->deDuplicateInvitations($resource['invitations']); + + } + $quote = $quote_repository->save( $modified, QuoteFactory::create($this->company->id, $modified['user_id']) @@ -950,6 +973,7 @@ class Import implements ShouldQueue /* No validators since data provided by database is already valid. */ foreach ($data as $resource) { + $modified = $resource; if (array_key_exists('invoice_id', $resource) && $resource['invoice_id'] && ! array_key_exists('invoices', $this->ids)) { @@ -974,20 +998,27 @@ class Import implements ShouldQueue $file_name = $resource['name']; $file_path = sys_get_temp_dir().'/'.$file_name; - file_put_contents($file_path, $this->curlGet($file_url)); - $finfo = new \finfo(FILEINFO_MIME_TYPE); - $file_info = $finfo->file($file_path); + try { + file_put_contents($file_path, $this->curlGet($file_url)); + $finfo = new \finfo(FILEINFO_MIME_TYPE); + $file_info = $finfo->file($file_path); - $uploaded_file = new UploadedFile( - $file_path, - $file_name, - $file_info, - filesize($file_path), - 0, - false - ); + $uploaded_file = new UploadedFile( + $file_path, + $file_name, + $file_info, + filesize($file_path), + 0, + false + ); - $this->saveDocument($uploaded_file, $entity, $is_public = true); + $this->saveDocument($uploaded_file, $entity, $is_public = true); + } + catch(\Exception $e) { + + //do nothing, gracefully :) + + } } diff --git a/app/Mail/MigrationCompleted.php b/app/Mail/MigrationCompleted.php index 53a5d7f786be..db06b6531644 100644 --- a/app/Mail/MigrationCompleted.php +++ b/app/Mail/MigrationCompleted.php @@ -34,8 +34,12 @@ class MigrationCompleted extends Mailable $data['company'] = $this->company; $data['whitelabel'] = $this->company->account->isPaid() ? true : false; - return $this->from(config('mail.from.address'), config('mail.from.name')) - ->view('email.import.completed', $data) - ->attach($this->company->invoices->first()->pdf_file_path()); + $result = $this->from(config('mail.from.address'), config('mail.from.name')) + ->view('email.import.completed', $data); + + if($this->company->invoices->count() >=1) + $result->attach($this->company->invoices->first()->pdf_file_path()); + + return $result; } } diff --git a/app/Repositories/BaseRepository.php b/app/Repositories/BaseRepository.php index b295419b3fb9..a0bb23d99617 100644 --- a/app/Repositories/BaseRepository.php +++ b/app/Repositories/BaseRepository.php @@ -310,7 +310,7 @@ class BaseRepository $model = $model->calc()->getCredit(); - $model->ledger()->updateCreditBalance(($state['finished_amount'] - $state['starting_amount'])); + // $model->ledger()->updateCreditBalance(-1*($state['finished_amount'] - $state['starting_amount'])); if (! $model->design_id) $model->design_id = $this->decodePrimaryKey($client->getSetting('credit_design_id')); diff --git a/app/Repositories/Migration/InvoiceMigrationRepository.php b/app/Repositories/Migration/InvoiceMigrationRepository.php index 9fff645bf7f0..7d0a74b0c696 100644 --- a/app/Repositories/Migration/InvoiceMigrationRepository.php +++ b/app/Repositories/Migration/InvoiceMigrationRepository.php @@ -182,6 +182,14 @@ class InvoiceMigrationRepository extends BaseRepository } } + if($data['is_deleted']){ + $model->is_deleted = true; + $model->save(); + } + + if($data['deleted_at']) + $model->delete(); + $model->save(); return $model->fresh(); diff --git a/app/Repositories/Migration/PaymentMigrationRepository.php b/app/Repositories/Migration/PaymentMigrationRepository.php index 8140b63fea6c..470e2401d7f2 100644 --- a/app/Repositories/Migration/PaymentMigrationRepository.php +++ b/app/Repositories/Migration/PaymentMigrationRepository.php @@ -114,11 +114,18 @@ class PaymentMigrationRepository extends BaseRepository $payment->invoices()->saveMany($invoices); $payment->invoices->each(function ($inv) use ($invoice_totals, $refund_totals) { + $inv->pivot->amount = $invoice_totals; $inv->pivot->refunded = $refund_totals; $inv->pivot->save(); $inv->paid_to_date += $invoice_totals; + + if($inv->balance > 0) + $inv->balance -= $invoice_totals; + + $inv->balance = max(0, $inv->balance); + $inv->save(); }); @@ -135,7 +142,8 @@ class PaymentMigrationRepository extends BaseRepository $cre->pivot->amount = $credit_totals; $cre->pivot->save(); - $cre->paid_to_date += $invoice_totals; + $cre->paid_to_date += $credit_totals; + $cre->balance -= $credit_totals; $cre->save(); }); } diff --git a/app/Utils/Traits/Payment/Refundable.php b/app/Utils/Traits/Payment/Refundable.php index 7a05c2196fa2..39636065f01a 100644 --- a/app/Utils/Traits/Payment/Refundable.php +++ b/app/Utils/Traits/Payment/Refundable.php @@ -188,7 +188,7 @@ trait Refundable $client_balance_adjustment = $this->adjustInvoices($data); - $credit_note->ledger()->updateCreditBalance($client_balance_adjustment, $ledger_string); + // $credit_note->ledger()->updateCreditBalance($client_balance_adjustment, $ledger_string); $this->client->paid_to_date -= $data['amount']; $this->client->save(); diff --git a/config/ninja.php b/config/ninja.php index 53b659058f8b..02aeeb4e0cb9 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -139,4 +139,5 @@ return [ 'log_pdf_html' => env('LOG_PDF_HTML', false), 'expanded_logging' => env('EXPANDED_LOGGING', false), 'snappdf_chromium_path' => env('SNAPPDF_CHROMIUM_PATH', false), + 'v4_migration_version' => '4.5.31', ];