From 13ddf7721ee3ede053d222a87ecb464304045e16 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 19 Jan 2025 20:58:55 +1100 Subject: [PATCH 1/8] reversion of clean design changes --- resources/views/pdf-designs/clean.html | 237 +++++++++++-------------- 1 file changed, 103 insertions(+), 134 deletions(-) diff --git a/resources/views/pdf-designs/clean.html b/resources/views/pdf-designs/clean.html index 640537011c..1bba0cb3bd 100644 --- a/resources/views/pdf-designs/clean.html +++ b/resources/views/pdf-designs/clean.html @@ -8,7 +8,8 @@ } html { - + width: 210mm; + height: 200mm; } body { @@ -19,7 +20,9 @@ zoom: 80%; } - table tr td, table tr, th { + table tr td, + table tr, + th { font-size: $font_size !important; } @@ -36,7 +39,11 @@ margin: 0; padding: 0; } - + + #qr-bill{ + width:100% !important; + } + .header-container { display: grid; grid-template-columns: repeat(3, 1fr); @@ -58,7 +65,7 @@ line-height: var(--line-height); } - #company-details > p:first-child { + #company-details>p:first-child { color: var(--primary-color); } @@ -74,27 +81,25 @@ padding-left: 1rem; margin-bottom: 1rem; font-weight: bold; - font-size:120%; color: var(--primary-color); } .client-and-entity-wrapper { padding: 1rem; display: grid; - grid-template-columns: repeat(3, 1fr); + grid-template-columns: 1fr 1fr 1fr; border-top: 1px solid #d8d8d8; border-bottom: 1px solid #d8d8d8; - width:100%; } #entity-details { - display:flex; + display: flex; text-align: left; margin-right: 20px; line-height: var(--line-height) !important; } - #entity-details > tr, + #entity-details>tr, #entity-details th { font-weight: normal; padding-right: 15px; @@ -105,9 +110,10 @@ display: flex; flex-direction: column; line-height: var(--line-height); + padding-right: 30px; } - #client-details > :first-child { + #client-details> :first-child { font-weight: bold; } @@ -116,11 +122,11 @@ flex-direction: column; line-height: var(--line-height); } - + [data-ref="table"] { margin-top: 1rem; margin-bottom: 5px; - width: 100%; + min-width: 100%; table-layout: fixed; overflow-wrap: break-word; } @@ -131,23 +137,23 @@ color: grey; } - [data-ref="table"] > thead { + [data-ref="table"]>thead { text-align: left; } - [data-ref="table"] > thead > tr > th { + [data-ref="table"]>thead>tr>th { font-size: 1.1rem; - padding-bottom: 1rem; + padding-bottom: 1.5rem; padding-left: 1rem; } - [data-ref="table"] > tbody > tr > td { + [data-ref="table"]>tbody>tr>td { border-top: 1px solid #d8d8d8; border-bottom: 1px solid #d8d8d8; padding: 1rem 1rem; } - th.right-radius { + th.right-radius { padding-right: 1rem; text-align: right; } @@ -156,7 +162,11 @@ text-align: right; } - [data-ref="table"] > tbody > tr:nth-child(odd) { + [data-ref='product_table-product.item-td']{ + color: var(--primary-color); + } + + [data-ref="table"]>tbody>tr:nth-child(odd) { background-color: #f5f5f5; } @@ -168,11 +178,11 @@ padding-right: 1rem; padding-left: 1rem; gap: 80px; - page-break-inside:avoid; + page-break-inside: avoid; overflow: visible !important; } - #table-totals .totals-table-right-side > * { + #table-totals .totals-table-right-side>* { display: grid; grid-template-columns: 1fr 1fr; } @@ -186,28 +196,22 @@ text-align: right; } - #table-totals>.totals-table-right-side> * > :not([hidden]) ~ :not([hidden]) { + #table-totals>.totals-table-right-side>*> :not([hidden])~ :not([hidden]) { --tw-space-y-reverse: 0; margin-top: calc(.75rem * calc(1 - var(--tw-space-y-reverse))); margin-bottom: calc(.75rem * var(--tw-space-y-reverse)); } - #table-totals - > * - [data-element='product-table-balance-due-label'], - #table-totals - > * - [data-element='product-table-balance-due'] { + #table-totals>* [data-element='product-table-balance-due-label'], + #table-totals>* [data-element='product-table-balance-due'] { font-weight: bold; } - #table-totals - > * - [data-element='product-table-balance-due'] { + #table-totals>* [data-element='product-table-balance-due'] { color: var(--primary-color); } - #table-totals > * > :last-child { + #table-totals>*> :last-child { text-align: right; padding-right: 0.5rem; } @@ -234,7 +238,7 @@ text-align: right; margin-right: .75rem; } - + [data-ref*=".line_total-td"] { white-space: nowrap; } @@ -245,53 +249,25 @@ .repeating-footer-space { height: 10px; } + .repeating-header { position: fixed; top: 0; } + .repeating-footer { position: fixed; bottom: 0; } - [data-ref='task_table-task.description-th'], - [data-ref='task_table-task.description-td'], - [data-ref='product_table-product.description-th'], - [data-ref='product_table-product.description-td'] { - min-width: 150px !important; + [data-ref='product_table-product.description-td'], td { + min-width: 100%; + max-width: 300px; overflow-wrap: break-word; } - [data-ref='product_table-product.item-td']{ - color: var(--primary-color); - } - - [data-ref='product_table-product.item-th'], - [data-ref='product_table-product.unit_cost-th'], - [data-ref='product_table-product.quantity-th'], - [data-ref='product_table-product.line_total-th'] { - width: 12%; - } - - [data-ref='product_table-product.tax1-th'] { - width: 10%; - } - - [data-ref='task_table-task.hours-th'], - [data-ref='task_table-task.service-th'], - [data-ref='task_table-task.discount-th'], - [data-ref='task_table-task.cost-th'], - [data-ref='task_table-task.quantity-th'], - [data-ref='task_table-task.line_total-th'] { - width: 12%; - } - - [data-ref='task_table-task.tax1-th'] { - width: 10%; - } - .stamp { - transform: rotate(12deg); + transform: rotate(12deg); color: #555; font-size: 3rem; font-weight: 700; @@ -302,26 +278,26 @@ border-radius: 1rem; font-family: 'Courier'; mix-blend-mode: multiply; - z-index:200 !important; - position: fixed; + z-index: 200 !important; + position: fixed; text-align: center; - float:right; + float: right; } .is-paid { - color: #D23; - border: 1rem double #D23; + color: #D23; + border: 1rem double #D23; transform: rotate(-5deg); font-size: 6rem; font-family: "Open sans", Helvetica, Arial, sans-serif; border-radius: 0; padding: 0.5rem; opacity: 0.2; - z-index:200 !important; - position: fixed; + z-index: 200 !important; + position: fixed; display: $show_paid_stamp; - } + } .project-header { font-size: 1.2em; @@ -332,15 +308,9 @@ margin-right: 0; font-weight: bold; color: #505050; - } + } - .pqrcode { - - } - - #qr-bill{ - width:100% !important; - } + .pqrcode {} /** Useful snippets, uncomment to enable. **/ @@ -373,56 +343,56 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + +
-
 
-
-
-
-
- -
-
-
-
-

$entity_label

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
$status_logo
-
-
- -
+
 
+
+
+
+
+ +
+
+
+
+

$entity_label

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
$status_logo
+
+
+ +
@@ -430,6 +400,5 @@ $entity_images \ No newline at end of file From cbbde5e2ae70089df0ffe1fd2aca001d4c6b1c9e Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 19 Jan 2025 21:13:57 +1100 Subject: [PATCH 2/8] Prevent destructive commands in production --- app/Console/Commands/DemoMode.php | 2 +- app/Providers/AppServiceProvider.php | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/Console/Commands/DemoMode.php b/app/Console/Commands/DemoMode.php index 8e4014d1ef..ea50084b50 100644 --- a/app/Console/Commands/DemoMode.php +++ b/app/Console/Commands/DemoMode.php @@ -78,7 +78,7 @@ class DemoMode extends Command { set_time_limit(0); - if (config('ninja.is_docker')) { + if (config('ninja.is_docker') || Ninja::isHosted()) { return; } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 28ec30b25f..32709635d7 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -145,6 +145,11 @@ class AppServiceProvider extends ServiceProvider return $this; }); + + //Prevents destructive commands from being run in hosted environments + \DB::prohibitDestructiveCommands(Ninja::isHosted()); + + } public function register(): void From 991db9e0a224ed0bd80e30f0b983f1a4f79c49c4 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 19 Jan 2025 21:42:34 +1100 Subject: [PATCH 3/8] updates for base designs --- resources/views/pdf-designs/bold.html | 70 ++++------------------- resources/views/pdf-designs/calm.html | 18 +++--- resources/views/pdf-designs/creative.html | 50 +++------------- 3 files changed, 27 insertions(+), 111 deletions(-) diff --git a/resources/views/pdf-designs/bold.html b/resources/views/pdf-designs/bold.html index 13eab3e009..2775ee7312 100644 --- a/resources/views/pdf-designs/bold.html +++ b/resources/views/pdf-designs/bold.html @@ -13,6 +13,9 @@ font-family: $font_name, Helvetica, sans-serif; font-size: $font_size !important; zoom: 80%; + margin: 0; + padding: 0; + } table tr td, table tr, th { @@ -20,7 +23,9 @@ } - body, html { + html { + width: 210mm; + height: 200mm; margin: 0; padding: 0; } @@ -163,11 +168,11 @@ padding: 1.5rem; } - [data-ref="table"] > tbody > tr > td:last-child { - text-align: right; + td.right-radius { + text-align: right !important; } - [data-ref="table"] > tbody > tr > td:first-child { + td.left-radius{ font-weight: bold; } @@ -299,61 +304,10 @@ margin-top: 1rem; } - [data-ref='product_table-product.item-td']{ - font-weight: bold; + [data-ref='product_table-product.description-th'] { + width:30%; + overflow-wrap: break-word; } - - [data-ref='product_table-product.item-th']{ - width: 10%; - } - - [data-ref='product_table-product.unit_cost-th'], - [data-ref='product_table-product.quantity-th']{ - width: 12%; - } - - [data-ref='product_table-product.product1-th'], - [data-ref='product_table-product.product2-th'], - [data-ref='product_table-product.product3-th'], - [data-ref='product_table-product.product4-th'], - [data-ref='product_table-product.tax1-th'] { - width: 10%; - } - - [data-ref='product_table-product.line_total-th'], - [data-ref='product_table-product.line_total-td'], - [data-ref='task_table-task.line_total-th'], - [data-ref='task_table-task.line_total-td'] { - width: 12%; - text-align: right !important; - padding-right: 1rem !important; - } - - [data-ref='product_table-product.description-th'], - [data-ref='task_table-task.description-th'] { - overflow-wrap: break-word; - min-width: 150px !important; - } - - [data-ref='task_table-task.hours-th'], - [data-ref='task_table-task.discount-th'], - [data-ref='task_table-task.cost-th'], - [data-ref='task_table-task.quantity-th'], - [data-ref='task_table-task.task1-th'], - [data-ref='task_table-task.task2-th'], - [data-ref='task_table-task.task3-th'], - [data-ref='task_table-task.task4-th'] { - width: 12%; - } - - [data-ref='task_table-task.service-th']{ - width: 10%; - } - - [data-ref='task_table-task.tax1-th'] { - width: 10%; - } - .left-radius { padding-left: 1rem; diff --git a/resources/views/pdf-designs/calm.html b/resources/views/pdf-designs/calm.html index fd2a9624f4..c85d70cc87 100644 --- a/resources/views/pdf-designs/calm.html +++ b/resources/views/pdf-designs/calm.html @@ -158,17 +158,17 @@ background-color: #f5f5f5; } - [data-ref="table"]>thead>tr>th:last-child { - text-align: right; - } - [data-ref="table"]>tbody>tr>td { border-bottom: 1px solid #e6e6e6; padding: 0.75rem; } - [data-ref="table"]>tbody>tr>td:last-child { - text-align: right; + th.right-radius { + text-align: right !important; + } + + td.right-radius { + text-align: right !important; } [data-ref="table"]>tbody>tr:nth-child(even) { @@ -285,10 +285,8 @@ margin-top: 40px; } - [data-element='product_table-product.description-td'], - td { - min-width: 100%; - max-width: 300px; + [data-ref='product_table-product.description-th'] { + width: 35%; overflow-wrap: break-word; } diff --git a/resources/views/pdf-designs/creative.html b/resources/views/pdf-designs/creative.html index 6ff4a6afd3..590aea888b 100644 --- a/resources/views/pdf-designs/creative.html +++ b/resources/views/pdf-designs/creative.html @@ -146,9 +146,9 @@ } - [data-ref='product_table-product.description-th'], - [data-ref='product_table-product.description-td'] { - min-width: 150px !important; + [data-ref='product_table-product.description-th'], + [data-ref='task_table-task.description-th'] { + width: 35% !important; overflow-wrap: break-word; } @@ -156,42 +156,6 @@ color: var(--primary-color); } - [data-ref='product_table-product.item-th'], - [data-ref='product_table-product.unit_cost-th'], - [data-ref='product_table-product.quantity-th'] { - width: 12%; - } - - [data-ref='product_table-product.tax1-th'] { - width: 6%; - } - - [data-ref='product_table-product.line_total-th'] { - width: 10%; - } - - [data-ref='task_table-task.description-th'], - [data-ref='task_table-task.description-td'] { - min-width: 100px !important; - overflow-wrap: break-word; - } - - [data-ref='task_table-task.hours-th'], - [data-ref='task_table-task.service-th'], - [data-ref='task_table-task.discount-th'], - [data-ref='task_table-task.cost-th'], - [data-ref='task_table-task.quantity-th'] { - width: 12%; - } - - [data-ref='task_table-task.tax1-th'] { - width: 6%; - } - - [data-ref='task_table-task.line_total-th'] { - width: 10%; - } - [data-ref="table"] > thead { text-align: left; } @@ -201,12 +165,12 @@ padding: 1rem; } - [data-ref="table"] > thead > tr > th:last-child { - text-align: right; + th.right-radius { + text-align: right !important; } - [data-ref="table"] > tbody > tr > td:last-child { - text-align: right; + td.right-radius { + text-align: right !important; } [data-ref="table"] > tbody > tr > td { From 1abf6564343bcb25529b97a43792d99e06fc3fc6 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 19 Jan 2025 21:45:17 +1100 Subject: [PATCH 4/8] Change startup script for db tests --- .github/workflows/phpunit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 2a3b53adac..91e7aab941 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -120,7 +120,7 @@ jobs: - name: Migrate Database run: | - php artisan migrate:fresh --seed --force && php artisan db:seed --force + php artisan migrate:fresh && php artisan db:seed - name: Run Testsuite run: | From d71e084f6309686d606476b682b789b75b885892 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 19 Jan 2025 21:48:18 +1100 Subject: [PATCH 5/8] Change startup script for db tests --- .github/workflows/phpunit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 91e7aab941..63d6c5ae13 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -120,7 +120,7 @@ jobs: - name: Migrate Database run: | - php artisan migrate:fresh && php artisan db:seed + php artisan migrate && php artisan db:seed - name: Run Testsuite run: | From eb574f3444d88e665901eb189d6e944ed9a770a0 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 20 Jan 2025 08:36:44 +1100 Subject: [PATCH 6/8] Fixes for client documents query --- app/Livewire/DocumentsTable.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/Livewire/DocumentsTable.php b/app/Livewire/DocumentsTable.php index 46b6483977..bcfb6bb085 100644 --- a/app/Livewire/DocumentsTable.php +++ b/app/Livewire/DocumentsTable.php @@ -118,12 +118,14 @@ class DocumentsTable extends Component protected function documents() { - return $this->client()->documents() + $client = $this->client(); + + return $client->documents() ->where('is_public', true) ->orWhere(function ($query){ - $query->whereHasMorph('documentable', [Company::class], function ($q) { - $q->where('is_public', true); + $query->whereHasMorph('documentable', [Company::class], function ($q) use ($client) { + $q->where('is_public', true)->where('company_id', $client->company_id); }); }); From 8de86a2abd668e61c6db0726fc961c79a969d37d Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 20 Jan 2025 08:41:05 +1100 Subject: [PATCH 7/8] Fixes for client documents query --- app/Livewire/DocumentsTable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Livewire/DocumentsTable.php b/app/Livewire/DocumentsTable.php index bcfb6bb085..77c623e5cd 100644 --- a/app/Livewire/DocumentsTable.php +++ b/app/Livewire/DocumentsTable.php @@ -122,7 +122,7 @@ class DocumentsTable extends Component return $client->documents() ->where('is_public', true) - ->orWhere(function ($query){ + ->orWhere(function ($query) use ($client) { $query->whereHasMorph('documentable', [Company::class], function ($q) use ($client) { $q->where('is_public', true)->where('company_id', $client->company_id); From bfb771f6aaa42a096b677e671df4fae064b6072f Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 20 Jan 2025 09:38:38 +1100 Subject: [PATCH 8/8] Fixes for nested elements when purifying --- app/Services/Pdf/Purify.php | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/app/Services/Pdf/Purify.php b/app/Services/Pdf/Purify.php index 5ce983f8b1..b737dd58dd 100644 --- a/app/Services/Pdf/Purify.php +++ b/app/Services/Pdf/Purify.php @@ -301,10 +301,25 @@ class Purify } else { // First, remove ALL attributes from the node - while ($node->attributes->length > 0) { - $attr = $node->attributes->item(0); - $node->removeAttribute($attr->nodeName); - } + // while ($node->attributes->length > 0) { + // $attr = $node->attributes->item(0); + // $node->removeAttribute($attr->nodeName); + // } + + +if ($node instanceof \DOMElement) { + // Create a list of attributes to remove + $attributes_to_remove = []; + foreach ($node->attributes as $attr) { + $attributes_to_remove[] = $attr->nodeName; + } + + // Remove the attributes + foreach ($attributes_to_remove as $attr_name) { + $node->removeAttribute($attr_name); + } +} + } // Then add back only the allowed attributes