From 83e092548fe10e2640315530ae07b57669075ef9 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 10 Oct 2022 07:14:34 +1100 Subject: [PATCH 01/14] v5.5.31 --- VERSION.txt | 2 +- config/ninja.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index 4c04b5719d54..9c6da40607ea 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -5.5.30 \ No newline at end of file +5.5.31 \ No newline at end of file diff --git a/config/ninja.php b/config/ninja.php index 8abbc7510ba6..cac1d3333d1f 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -14,8 +14,8 @@ return [ 'require_https' => env('REQUIRE_HTTPS', true), 'app_url' => rtrim(env('APP_URL', ''), '/'), 'app_domain' => env('APP_DOMAIN', 'invoicing.co'), - 'app_version' => '5.5.30', - 'app_tag' => '5.5.30', + 'app_version' => '5.5.31', + 'app_tag' => '5.5.31', 'minimum_client_version' => '5.0.16', 'terms_version' => '1.0.1', 'api_secret' => env('API_SECRET', ''), From 48e21e949549f8c7770bd7ae6df642c5317f8a02 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 10 Oct 2022 14:26:53 +1100 Subject: [PATCH 02/14] fixes for purge client --- app/Http/Controllers/ClientController.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/ClientController.php b/app/Http/Controllers/ClientController.php index b99917040a0e..800037c8b11b 100644 --- a/app/Http/Controllers/ClientController.php +++ b/app/Http/Controllers/ClientController.php @@ -640,7 +640,14 @@ class ClientController extends BaseController { //delete all documents $client->documents->each(function ($document) { - Storage::disk(config('filesystems.default'))->delete($document->url); + + try{ + Storage::disk(config('filesystems.default'))->delete($document->url); + } + catch(\Exception $e){ + nlog($e->getMessage()); + } + }); //force delete the client From 58e38f3313c0413260bc7ab3a66fd9a10e00221e Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 10 Oct 2022 17:47:52 +1100 Subject: [PATCH 03/14] Add Preloader --- preload.php | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 preload.php diff --git a/preload.php b/preload.php new file mode 100644 index 000000000000..6bf7ece52e44 --- /dev/null +++ b/preload.php @@ -0,0 +1,136 @@ +paths = $paths; + + // We'll use composer's classmap + // to easily find which classes to autoload, + // based on their filename + $classMap = require __DIR__ . '/vendor/composer/autoload_classmap.php'; + + $this->fileMap = array_flip($classMap); + } + + public function paths(string ...$paths): Preloader + { + $this->paths = array_merge( + $this->paths, + $paths + ); + + return $this; + } + + public function ignore(string ...$names): Preloader + { + $this->ignores = array_merge( + $this->ignores, + $names + ); + + return $this; + } + + public function load(): void + { + // We'll loop over all registered paths + // and load them one by one + foreach ($this->paths as $path) { + $this->loadPath(rtrim($path, '/')); + } + + $count = self::$count; + + echo "[Preloader] Preloaded {$count} classes" . PHP_EOL; + } + + private function loadPath(string $path): void + { + // If the current path is a directory, + // we'll load all files in it + if (is_dir($path)) { + $this->loadDir($path); + + return; + } + + // Otherwise we'll just load this one file + $this->loadFile($path); + } + + private function loadDir(string $path): void + { + $handle = opendir($path); + + // We'll loop over all files and directories + // in the current path, + // and load them one by one + while ($file = readdir($handle)) { + if (in_array($file, ['.', '..'])) { + continue; + } + + $this->loadPath("{$path}/{$file}"); + } + + closedir($handle); + } + + private function loadFile(string $path): void + { + // We resolve the classname from composer's autoload mapping + $class = $this->fileMap[$path] ?? null; + + // And use it to make sure the class shouldn't be ignored + if ($this->shouldIgnore($class)) { + return; + } + + // Finally we require the path, + // causing all its dependencies to be loaded as well + require_once($path); + + self::$count++; + + echo "[Preloader] Preloaded `{$class}`" . PHP_EOL; + } + + private function shouldIgnore(?string $name): bool + { + if ($name === null) { + return true; + } + + foreach ($this->ignores as $ignore) { + if (strpos($name, $ignore) === 0) { + return true; + } + } + + return false; + } +} + +(new Preloader()) + ->paths(__DIR__ . '/vendor/laravel') + ->ignore( + \Illuminate\Filesystem\Cache::class, + \Illuminate\Log\LogManager::class, + \Illuminate\Http\Testing\File::class, + \Illuminate\Http\UploadedFile::class, + \Illuminate\Support\Carbon::class, + ) + ->load(); \ No newline at end of file From 73f425f0ca477e3335b224281b11b4256a9b3ad9 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 10 Oct 2022 18:04:45 +1100 Subject: [PATCH 04/14] Fixes for document indexing --- ...22_10_10_070137_add_documentable_index.php | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 database/migrations/2022_10_10_070137_add_documentable_index.php diff --git a/database/migrations/2022_10_10_070137_add_documentable_index.php b/database/migrations/2022_10_10_070137_add_documentable_index.php new file mode 100644 index 000000000000..19fb9cfbbb40 --- /dev/null +++ b/database/migrations/2022_10_10_070137_add_documentable_index.php @@ -0,0 +1,30 @@ +index(['documentable_id', 'documentable_type','deleted_at']); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +}; From bd6071b46e18850959d39dd5f2b09a3ba9e4472d Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 10 Oct 2022 18:23:27 +1100 Subject: [PATCH 05/14] Fixes for document indexing --- .../2022_10_10_070137_add_documentable_index.php | 4 ++++ .../components/livewire/documents-table.blade.php | 9 +-------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/database/migrations/2022_10_10_070137_add_documentable_index.php b/database/migrations/2022_10_10_070137_add_documentable_index.php index 19fb9cfbbb40..95d125842ddb 100644 --- a/database/migrations/2022_10_10_070137_add_documentable_index.php +++ b/database/migrations/2022_10_10_070137_add_documentable_index.php @@ -16,6 +16,10 @@ return new class extends Migration Schema::table('documents', function (Blueprint $table) { $table->index(['documentable_id', 'documentable_type','deleted_at']); }); + + Schema::table('expenses', function (Blueprint $table) { + $table->index(['invoice_id', 'deleted_at']); + }); } /** diff --git a/resources/views/portal/ninja2020/components/livewire/documents-table.blade.php b/resources/views/portal/ninja2020/components/livewire/documents-table.blade.php index 61beb2645a7d..5ac0423432ec 100644 --- a/resources/views/portal/ninja2020/components/livewire/documents-table.blade.php +++ b/resources/views/portal/ninja2020/components/livewire/documents-table.blade.php @@ -77,11 +77,6 @@ {{ ctrans('texts.name') }} - - - {{ ctrans('texts.type') }} - - {{ ctrans('texts.size') }} @@ -102,9 +97,7 @@ {{ Illuminate\Support\Str::limit($document->name, 20) }} - - {{ App\Models\Document::$types[$document->type]['mime'] }} - + {{ $document->size / 1000 }} kB From 46aa56272352def1cf197b1efca9fc6dd04203c2 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 10 Oct 2022 18:24:25 +1100 Subject: [PATCH 06/14] Fixes for document indexing --- resources/views/portal/ninja2020/documents/show.blade.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/resources/views/portal/ninja2020/documents/show.blade.php b/resources/views/portal/ninja2020/documents/show.blade.php index 44aa18ee08d9..8e170b353244 100644 --- a/resources/views/portal/ninja2020/documents/show.blade.php +++ b/resources/views/portal/ninja2020/documents/show.blade.php @@ -24,14 +24,6 @@ {{ Illuminate\Support\Str::limit($document->name, 40) }} -
-
- {{ ctrans('texts.type') }} -
-
- {{ App\Models\Document::$types[$document->type]['mime'] }} -
-
{{ ctrans('texts.hash') }} From 9b723f11cbdfd1d7e37472d136ae4b13f2823d58 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 10 Oct 2022 18:45:33 +1100 Subject: [PATCH 07/14] Fixes for document indexing --- ...22_10_10_070137_add_documentable_index.php | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/database/migrations/2022_10_10_070137_add_documentable_index.php b/database/migrations/2022_10_10_070137_add_documentable_index.php index 95d125842ddb..b590015e8823 100644 --- a/database/migrations/2022_10_10_070137_add_documentable_index.php +++ b/database/migrations/2022_10_10_070137_add_documentable_index.php @@ -13,13 +13,24 @@ return new class extends Migration */ public function up() { - Schema::table('documents', function (Blueprint $table) { + Schema::table('documents', function (Blueprint $table) { $table->index(['documentable_id', 'documentable_type','deleted_at']); - }); + }); - Schema::table('expenses', function (Blueprint $table) { + Schema::table('expenses', function (Blueprint $table) { $table->index(['invoice_id', 'deleted_at']); - }); + }); + + Schema::table('company_tokens', function (Blueprint $table) { + $table->dropIndex('company_tokens_token_index'); + $table->index(['token','deleted_at']); + }); + + Schema::table('invoice_invitations', function (Blueprint $table) { + $table->dropIndex('invoice_invitations_key_index'); + $table->index(['key','deleted_at']); + }); + } /** From 2c6c7e964c62d55c1189320e372dc48c800fe6d5 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 10 Oct 2022 20:01:15 +1100 Subject: [PATCH 08/14] Fixes for indexes --- .../migrations/2022_10_10_070137_add_documentable_index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/migrations/2022_10_10_070137_add_documentable_index.php b/database/migrations/2022_10_10_070137_add_documentable_index.php index b590015e8823..c97c96501319 100644 --- a/database/migrations/2022_10_10_070137_add_documentable_index.php +++ b/database/migrations/2022_10_10_070137_add_documentable_index.php @@ -14,7 +14,7 @@ return new class extends Migration public function up() { Schema::table('documents', function (Blueprint $table) { - $table->index(['documentable_id', 'documentable_type','deleted_at']); + $table->index(['documentable_id', 'documentable_type', 'deleted_at']); }); Schema::table('expenses', function (Blueprint $table) { From b8cbd65f87892ddd897e83c6ff07a50cbc033e0b Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 12 Oct 2022 07:53:29 +1100 Subject: [PATCH 09/14] Add to fillable --- app/Models/CompanyGateway.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Models/CompanyGateway.php b/app/Models/CompanyGateway.php index 81f2420d514b..0c72d9c4a521 100644 --- a/app/Models/CompanyGateway.php +++ b/app/Models/CompanyGateway.php @@ -42,6 +42,7 @@ class CompanyGateway extends BaseModel 'require_postal_code', 'require_client_phone', 'require_contact_name', + 'require_contact_email', 'update_details', 'config', 'fees_and_limits', From 8e5c825750db76d5276b71ea527922d83a91e4e0 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 12 Oct 2022 11:27:14 +1100 Subject: [PATCH 10/14] fixes for storage paths in self host --- app/Models/Credit.php | 12 +++++++++++- app/Models/Invoice.php | 11 +++++++++++ app/Models/Quote.php | 10 ++++++++++ app/Models/SystemLog.php | 4 ++++ app/Services/Payment/RefundPayment.php | 4 ++++ app/Utils/HtmlEngine.php | 10 +++++----- app/Utils/Traits/MakesInvoiceValues.php | 8 ++++---- 7 files changed, 49 insertions(+), 10 deletions(-) diff --git a/app/Models/Credit.php b/app/Models/Credit.php index f1aac09e2aff..77e72dfedbeb 100644 --- a/app/Models/Credit.php +++ b/app/Models/Credit.php @@ -288,11 +288,21 @@ class Credit extends BaseModel return Storage::disk(config('filesystems.default'))->{$type}($file_path); } + try { + $file_exists = Storage::disk(config('filesystems.default'))->exists($file_path); + } catch (\Exception $e) { + nlog($e->getMessage()); + } + + if ($file_exists) { + 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 = (new CreateEntityPdf($invitation))->handle(); return Storage::disk('public')->{$type}($file_path); diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index 6740f6c9ecd2..2a5cf63a0688 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -451,6 +451,17 @@ class Invoice extends BaseModel return Storage::disk(config('filesystems.default'))->{$type}($file_path); } + try { + $file_exists = Storage::disk(config('filesystems.default'))->exists($file_path); + } catch (\Exception $e) { + nlog($e->getMessage()); + } + + if ($file_exists) { + return Storage::disk(config('filesystems.default'))->{$type}($file_path); + } + + try { $file_exists = Storage::disk('public')->exists($file_path); } catch (\Exception $e) { diff --git a/app/Models/Quote.php b/app/Models/Quote.php index c512c288aa19..ddbad4a9687a 100644 --- a/app/Models/Quote.php +++ b/app/Models/Quote.php @@ -247,6 +247,16 @@ class Quote extends BaseModel return Storage::disk(config('filesystems.default'))->{$type}($file_path); } + try { + $file_exists = Storage::disk(config('filesystems.default'))->exists($file_path); + } catch (\Exception $e) { + nlog($e->getMessage()); + } + + if ($file_exists) { + return Storage::disk(config('filesystems.default'))->{$type}($file_path); + } + if (Storage::disk('public')->exists($file_path)) { return Storage::disk('public')->{$type}($file_path); } diff --git a/app/Models/SystemLog.php b/app/Models/SystemLog.php index 16d0eebac678..6d84e4b349f4 100644 --- a/app/Models/SystemLog.php +++ b/app/Models/SystemLog.php @@ -41,6 +41,8 @@ class SystemLog extends Model const CATEGORY_SECURITY = 5; + const CATEGORY_LOG = 6; + /* Event IDs*/ const EVENT_PAYMENT_RECONCILIATION_FAILURE = 10; @@ -127,6 +129,8 @@ class SystemLog extends Model const TYPE_LOGIN_FAILURE = 801; + const TYPE_GENERIC = 900; + protected $fillable = [ 'client_id', 'company_id', diff --git a/app/Services/Payment/RefundPayment.php b/app/Services/Payment/RefundPayment.php index 7755719457d5..57e8de922f05 100644 --- a/app/Services/Payment/RefundPayment.php +++ b/app/Services/Payment/RefundPayment.php @@ -16,10 +16,12 @@ use App\Factory\CreditFactory; use App\Factory\InvoiceItemFactory; use App\Jobs\Ninja\TransactionLog; use App\Jobs\Payment\EmailRefundPayment; +use App\Jobs\Util\SystemLogger; use App\Models\Activity; use App\Models\Credit; use App\Models\Invoice; use App\Models\Payment; +use App\Models\SystemLog; use App\Models\TransactionEvent; use App\Repositories\ActivityRepository; use App\Utils\Ninja; @@ -77,6 +79,8 @@ class RefundPayment TransactionLog::dispatch(TransactionEvent::PAYMENT_REFUND, $transaction, $this->payment->company->db); + SystemLogger::dispatch(['user' => auth()->user() ? auth()->user()->email : '', 'paymentables' => $this->payment->paymentables->makeHidden(['id','payment_id', 'paymentable_id','paymentable_type', 'deleted_at'])->toArray(), 'request' => request() ? request()->all() : []], SystemLog::CATEGORY_LOG, SystemLog::EVENT_USER, SystemLog::TYPE_GENERIC, $this->payment->client, $this->payment->company); + return $this->payment; } diff --git a/app/Utils/HtmlEngine.php b/app/Utils/HtmlEngine.php index 47da35455d9f..4806a89d1d35 100644 --- a/app/Utils/HtmlEngine.php +++ b/app/Utils/HtmlEngine.php @@ -150,7 +150,7 @@ class HtmlEngine $data['$number'] = ['value' => $this->entity->number ?: ' ', 'label' => ctrans('texts.invoice_number')]; $data['$invoice'] = ['value' => $this->entity->number ?: ' ', 'label' => ctrans('texts.invoice_number')]; $data['$number_short'] = ['value' => $this->entity->number ?: ' ', 'label' => ctrans('texts.invoice_number_short')]; - $data['$entity.terms'] = ['value' => Helpers::processReservedKeywords(\nl2br($this->entity->terms), $this->client) ?: '', 'label' => ctrans('texts.invoice_terms')]; + $data['$entity.terms'] = ['value' => Helpers::processReservedKeywords(\nl2br($this->entity->terms ?: ''), $this->client) ?: '', 'label' => ctrans('texts.invoice_terms')]; $data['$terms'] = &$data['$entity.terms']; $data['$view_link'] = ['value' => ''.ctrans('texts.view_invoice').'', 'label' => ctrans('texts.view_invoice')]; $data['$viewLink'] = &$data['$view_link']; @@ -185,7 +185,7 @@ class HtmlEngine $data['$entity'] = ['value' => '', 'label' => ctrans('texts.quote')]; $data['$number'] = ['value' => $this->entity->number ?: '', 'label' => ctrans('texts.quote_number')]; $data['$number_short'] = ['value' => $this->entity->number ?: '', 'label' => ctrans('texts.quote_number_short')]; - $data['$entity.terms'] = ['value' => Helpers::processReservedKeywords(\nl2br($this->entity->terms), $this->client) ?: '', 'label' => ctrans('texts.quote_terms')]; + $data['$entity.terms'] = ['value' => Helpers::processReservedKeywords(\nl2br($this->entity->terms ?: ''), $this->client) ?: '', 'label' => ctrans('texts.quote_terms')]; $data['$terms'] = &$data['$entity.terms']; $data['$view_link'] = ['value' => ''.ctrans('texts.view_quote').'', 'label' => ctrans('texts.view_quote')]; $data['$viewLink'] = &$data['$view_link']; @@ -210,7 +210,7 @@ class HtmlEngine $data['$entity'] = ['value' => '', 'label' => ctrans('texts.credit')]; $data['$number'] = ['value' => $this->entity->number ?: '', 'label' => ctrans('texts.credit_number')]; $data['$number_short'] = ['value' => $this->entity->number ?: '', 'label' => ctrans('texts.credit_number_short')]; - $data['$entity.terms'] = ['value' => Helpers::processReservedKeywords(\nl2br($this->entity->terms), $this->client) ?: '', 'label' => ctrans('texts.credit_terms')]; + $data['$entity.terms'] = ['value' => Helpers::processReservedKeywords(\nl2br($this->entity->terms ?: ''), $this->client) ?: '', 'label' => ctrans('texts.credit_terms')]; $data['$terms'] = &$data['$entity.terms']; $data['$view_link'] = ['value' => ''.ctrans('texts.view_credit').'', 'label' => ctrans('texts.view_credit')]; $data['$viewButton'] = &$data['$view_link']; @@ -303,7 +303,7 @@ class HtmlEngine $data['$invoice.custom2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice2', $this->entity->custom_value2, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice2')]; $data['$invoice.custom3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice3', $this->entity->custom_value3, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice3')]; $data['$invoice.custom4'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice4', $this->entity->custom_value4, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice4')]; - $data['$invoice.public_notes'] = ['value' => Helpers::processReservedKeywords(\nl2br($this->entity->public_notes), $this->client) ?: '', 'label' => ctrans('texts.public_notes')]; + $data['$invoice.public_notes'] = ['value' => Helpers::processReservedKeywords(\nl2br($this->entity->public_notes ?: ''), $this->client) ?: '', 'label' => ctrans('texts.public_notes')]; $data['$entity.public_notes'] = &$data['$invoice.public_notes']; $data['$public_notes'] = &$data['$invoice.public_notes']; $data['$notes'] = &$data['$public_notes']; @@ -535,7 +535,7 @@ class HtmlEngine $data['$description'] = ['value' => '', 'label' => ctrans('texts.description')]; //$data['$entity_footer'] = ['value' => $this->client->getSetting("{$this->entity_string}_footer"), 'label' => '']; - $data['$entity_footer'] = ['value' => Helpers::processReservedKeywords(\nl2br($this->entity->footer), $this->client), 'label' => '']; + $data['$entity_footer'] = ['value' => Helpers::processReservedKeywords(\nl2br($this->entity->footer ?: ''), $this->client), 'label' => '']; $data['$footer'] = &$data['$entity_footer']; $data['$page_size'] = ['value' => $this->settings->page_size, 'label' => '']; diff --git a/app/Utils/Traits/MakesInvoiceValues.php b/app/Utils/Traits/MakesInvoiceValues.php index ab020712c33f..e9e009a7b989 100644 --- a/app/Utils/Traits/MakesInvoiceValues.php +++ b/app/Utils/Traits/MakesInvoiceValues.php @@ -300,10 +300,10 @@ trait MakesInvoiceValues $data[$key][$table_type.'.notes'] = Helpers::processReservedKeywords($item->notes, $entity); $data[$key][$table_type.'.description'] = Helpers::processReservedKeywords($item->notes, $entity); - $data[$key][$table_type.".{$_table_type}1"] = strlen($item->custom_value1) > 1 ? $helpers->formatCustomFieldValue($this->company->custom_fields, "{$_table_type}1", $item->custom_value1, $entity) : ''; - $data[$key][$table_type.".{$_table_type}2"] = strlen($item->custom_value2) > 2 ? $helpers->formatCustomFieldValue($this->company->custom_fields, "{$_table_type}2", $item->custom_value2, $entity) : ''; - $data[$key][$table_type.".{$_table_type}3"] = strlen($item->custom_value3) > 3 ? $helpers->formatCustomFieldValue($this->company->custom_fields, "{$_table_type}3", $item->custom_value3, $entity) : ''; - $data[$key][$table_type.".{$_table_type}4"] = strlen($item->custom_value4) > 4 ? $helpers->formatCustomFieldValue($this->company->custom_fields, "{$_table_type}4", $item->custom_value4, $entity) : ''; + $data[$key][$table_type.".{$_table_type}1"] = strlen($item->custom_value1) >= 1 ? $helpers->formatCustomFieldValue($this->company->custom_fields, "{$_table_type}1", $item->custom_value1, $entity) : ''; + $data[$key][$table_type.".{$_table_type}2"] = strlen($item->custom_value2) >= 1 ? $helpers->formatCustomFieldValue($this->company->custom_fields, "{$_table_type}2", $item->custom_value2, $entity) : ''; + $data[$key][$table_type.".{$_table_type}3"] = strlen($item->custom_value3) >= 1 ? $helpers->formatCustomFieldValue($this->company->custom_fields, "{$_table_type}3", $item->custom_value3, $entity) : ''; + $data[$key][$table_type.".{$_table_type}4"] = strlen($item->custom_value4) >= 1 ? $helpers->formatCustomFieldValue($this->company->custom_fields, "{$_table_type}4", $item->custom_value4, $entity) : ''; if ($item->quantity > 0 || $item->cost > 0) { $data[$key][$table_type.'.quantity'] = Number::formatValueNoTrailingZeroes($item->quantity, $entity_currency); From 271a81da3e1db93e6666da1629725c6b2283acc7 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 12 Oct 2022 12:55:11 +1100 Subject: [PATCH 11/14] Clean up for preload --- app/Services/Invoice/InvoiceService.php | 6 +++++- app/Services/Invoice/UpdateReminder.php | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index c20594a03e3a..3e1d220ae4e4 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -268,7 +268,11 @@ class InvoiceService return $this; } - $this->invoice->due_date = Carbon::parse($this->invoice->date)->addDays($this->invoice->client->getSetting('payment_terms')); + //12-10-2022 + if($this->invoice->partial > 0 && !$this->invoice->partial_due_date) + $this->invoice->partial_due_date = Carbon::parse($this->invoice->date)->addDays($this->invoice->client->getSetting('payment_terms')); + else + $this->invoice->due_date = Carbon::parse($this->invoice->date)->addDays($this->invoice->client->getSetting('payment_terms')); return $this; } diff --git a/app/Services/Invoice/UpdateReminder.php b/app/Services/Invoice/UpdateReminder.php index 642c36b53283..24a4409b5e32 100644 --- a/app/Services/Invoice/UpdateReminder.php +++ b/app/Services/Invoice/UpdateReminder.php @@ -28,6 +28,7 @@ class UpdateReminder extends AbstractService $this->settings = $settings; } + /* We only support setting reminders based on the due date, not the partial due date */ public function run() { if (! $this->settings) { From fa4d4d3a22df499f52259494d6f7287e5683ef4c Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 12 Oct 2022 13:24:05 +1100 Subject: [PATCH 12/14] Minor fixes for recurring invoices --- app/Factory/RecurringInvoiceToInvoiceFactory.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Factory/RecurringInvoiceToInvoiceFactory.php b/app/Factory/RecurringInvoiceToInvoiceFactory.php index 67536c413813..c5b4a241e7e7 100644 --- a/app/Factory/RecurringInvoiceToInvoiceFactory.php +++ b/app/Factory/RecurringInvoiceToInvoiceFactory.php @@ -25,9 +25,9 @@ class RecurringInvoiceToInvoiceFactory $invoice->discount = $recurring_invoice->discount; $invoice->is_amount_discount = $recurring_invoice->is_amount_discount; $invoice->po_number = $recurring_invoice->po_number; - $invoice->footer = self::tranformObject($recurring_invoice->footer, $client); - $invoice->terms = self::tranformObject($recurring_invoice->terms, $client); - $invoice->public_notes = self::tranformObject($recurring_invoice->public_notes, $client); + $invoice->footer = $recurring_invoice->footer ? self::tranformObject($recurring_invoice->footer, $client) : null; + $invoice->terms = $recurring_invoice->terms ? self::tranformObject($recurring_invoice->terms, $client) : null; + $invoice->public_notes = $recurring_invoice->public_notes ? self::tranformObject($recurring_invoice->public_notes, $client) : null; $invoice->private_notes = $recurring_invoice->private_notes; $invoice->is_deleted = $recurring_invoice->is_deleted; $invoice->line_items = self::transformItems($recurring_invoice, $client); From 0892b6035fbd54b07b7d4a34a1fb2883abaea86a Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 12 Oct 2022 13:39:08 +1100 Subject: [PATCH 13/14] handle invoices going from zero balance to positive balance --- app/Services/Invoice/InvoiceService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index 3e1d220ae4e4..bb76f66b62ef 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -313,7 +313,7 @@ class InvoiceService } elseif ($this->invoice->balance > 0 && $this->invoice->balance < $this->invoice->amount) { $this->invoice->status_id = Invoice::STATUS_PARTIAL; } - elseif ($this->invoice->balance < 0) { + elseif ($this->invoice->balance > 0) { $this->invoice->status_id = Invoice::STATUS_SENT; } From 6728754d4b0c10ee241e07165e400cfae433e19f Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 12 Oct 2022 17:05:24 +1100 Subject: [PATCH 14/14] Minor fixes --- app/Console/Commands/CreateTestData.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Console/Commands/CreateTestData.php b/app/Console/Commands/CreateTestData.php index 866c3588ccfe..8be45787b460 100644 --- a/app/Console/Commands/CreateTestData.php +++ b/app/Console/Commands/CreateTestData.php @@ -437,7 +437,7 @@ class CreateTestData extends Command 'company_id' => $client->company->id, ]); - Document::factory()->count(50)->create([ + Document::factory()->count(5)->create([ 'user_id' => $client->user->id, 'company_id' => $client->company_id, 'documentable_type' => Vendor::class,