Andrew Wallo пре 8 месеци
родитељ
комит
b910e49635

+ 19
- 0
app/DTO/ClientPreviewDTO.php Прегледај датотеку

@@ -0,0 +1,19 @@
1
+<?php
2
+
3
+namespace App\DTO;
4
+
5
+readonly class ClientPreviewDTO extends ClientDTO
6
+{
7
+    public static function fake(): self
8
+    {
9
+        return new self(
10
+            name: 'John Doe',
11
+            addressLine1: '1234 Elm St',
12
+            addressLine2: 'Suite 123',
13
+            city: 'Springfield',
14
+            state: 'Illinois',
15
+            postalCode: '62701',
16
+            country: 'United States',
17
+        );
18
+    }
19
+}

+ 40
- 0
app/DTO/DocumentColumnLabelDTO.php Прегледај датотеку

@@ -0,0 +1,40 @@
1
+<?php
2
+
3
+namespace App\DTO;
4
+
5
+use App\Models\Setting\DocumentDefault;
6
+
7
+readonly class DocumentColumnLabelDTO
8
+{
9
+    public function __construct(
10
+        public string $items = 'Items',
11
+        public string $units = 'Quantity',
12
+        public string $price = 'Price',
13
+        public string $amount = 'Amount',
14
+    ) {}
15
+
16
+    public function toArray(): array
17
+    {
18
+        return [
19
+            'items' => $this->items,
20
+            'units' => $this->units,
21
+            'price' => $this->price,
22
+            'amount' => $this->amount,
23
+        ];
24
+    }
25
+
26
+    public static function fromModel(DocumentDefault $settings): self
27
+    {
28
+        return new self(
29
+            items: $settings->resolveColumnLabel('item_name', 'Items'),
30
+            units: $settings->resolveColumnLabel('unit_name', 'Quantity'),
31
+            price: $settings->resolveColumnLabel('price_name', 'Price'),
32
+            amount: $settings->resolveColumnLabel('amount_name', 'Amount'),
33
+        );
34
+    }
35
+
36
+    public static function getDefaultLabels(): self
37
+    {
38
+        return new self;
39
+    }
40
+}

+ 26
- 10
app/DTO/DocumentDTO.php Прегледај датотеку

@@ -2,10 +2,13 @@
2 2
 
3 3
 namespace App\DTO;
4 4
 
5
+use App\Enums\Setting\Font;
5 6
 use App\Models\Accounting\Document;
6 7
 use App\Models\Setting\DocumentDefault;
7 8
 use App\Utilities\Currency\CurrencyAccessor;
8 9
 use App\Utilities\Currency\CurrencyConverter;
10
+use Filament\FontProviders\BunnyFontProvider;
11
+use Illuminate\Contracts\Support\Htmlable;
9 12
 
10 13
 readonly class DocumentDTO
11 14
 {
@@ -13,7 +16,8 @@ readonly class DocumentDTO
13 16
      * @param  LineItemDTO[]  $lineItems
14 17
      */
15 18
     public function __construct(
16
-        public ?string $header,
19
+        public string $header,
20
+        public ?string $subheader,
17 21
         public ?string $footer,
18 22
         public ?string $terms,
19 23
         public ?string $logo,
@@ -23,16 +27,18 @@ readonly class DocumentDTO
23 27
         public string $dueDate,
24 28
         public string $currencyCode,
25 29
         public string $subtotal,
26
-        public string $discount,
27
-        public string $tax,
30
+        public ?string $discount,
31
+        public ?string $tax,
28 32
         public string $total,
29 33
         public string $amountDue,
30 34
         public CompanyDTO $company,
31 35
         public ClientDTO $client,
32 36
         public iterable $lineItems,
33 37
         public DocumentLabelDTO $label,
38
+        public DocumentColumnLabelDTO $columnLabel,
34 39
         public string $accentColor = '#000000',
35 40
         public bool $showLogo = true,
41
+        public Font $font = Font::Inter,
36 42
     ) {}
37 43
 
38 44
     public static function fromModel(Document $document): self
@@ -40,8 +46,11 @@ readonly class DocumentDTO
40 46
         /** @var DocumentDefault $settings */
41 47
         $settings = $document->company->defaultInvoice;
42 48
 
49
+        $currencyCode = $document->currency_code ?? CurrencyAccessor::getDefaultCurrency();
50
+
43 51
         return new self(
44 52
             header: $document->header,
53
+            subheader: $document->subheader,
45 54
             footer: $document->footer,
46 55
             terms: $document->terms,
47 56
             logo: $document->logo,
@@ -49,23 +58,30 @@ readonly class DocumentDTO
49 58
             referenceNumber: $document->referenceNumber(),
50 59
             date: $document->documentDate(),
51 60
             dueDate: $document->dueDate(),
52
-            currencyCode: $document->currency_code ?? CurrencyAccessor::getDefaultCurrency(),
53
-            subtotal: self::formatToMoney($document->subtotal, $document->currency_code),
54
-            discount: self::formatToMoney($document->discount_total, $document->currency_code),
55
-            tax: self::formatToMoney($document->tax_total, $document->currency_code),
56
-            total: self::formatToMoney($document->total, $document->currency_code),
57
-            amountDue: self::formatToMoney($document->amountDue(), $document->currency_code),
61
+            currencyCode: $currencyCode,
62
+            subtotal: self::formatToMoney($document->subtotal, $currencyCode),
63
+            discount: self::formatToMoney($document->discount_total, $currencyCode),
64
+            tax: self::formatToMoney($document->tax_total, $currencyCode),
65
+            total: self::formatToMoney($document->total, $currencyCode),
66
+            amountDue: self::formatToMoney($document->amountDue(), $currencyCode),
58 67
             company: CompanyDTO::fromModel($document->company),
59 68
             client: ClientDTO::fromModel($document->client),
60 69
             lineItems: $document->lineItems->map(fn ($item) => LineItemDTO::fromModel($item)),
61 70
             label: $document->documentType()->getLabels(),
71
+            columnLabel: DocumentColumnLabelDTO::fromModel($settings),
62 72
             accentColor: $settings->accent_color ?? '#000000',
63 73
             showLogo: $settings->show_logo ?? false,
74
+            font: $settings->font ?? Font::Inter,
64 75
         );
65 76
     }
66 77
 
67
-    private static function formatToMoney(float | string $value, ?string $currencyCode): string
78
+    protected static function formatToMoney(float | string $value, ?string $currencyCode): string
68 79
     {
69 80
         return CurrencyConverter::formatToMoney($value, $currencyCode);
70 81
     }
82
+
83
+    public function getFontHtml(): Htmlable
84
+    {
85
+        return app(BunnyFontProvider::class)->getHtml($this->font->getLabel());
86
+    }
71 87
 }

+ 64
- 0
app/DTO/DocumentPreviewDTO.php Прегледај датотеку

@@ -0,0 +1,64 @@
1
+<?php
2
+
3
+namespace App\DTO;
4
+
5
+use App\Enums\Accounting\DocumentType;
6
+use App\Enums\Setting\Font;
7
+use App\Enums\Setting\PaymentTerms;
8
+use App\Models\Setting\DocumentDefault;
9
+use App\Utilities\Currency\CurrencyAccessor;
10
+
11
+readonly class DocumentPreviewDTO extends DocumentDTO
12
+{
13
+    public static function fromSettings(DocumentDefault $settings, ?array $data = null): self
14
+    {
15
+        $company = $settings->company;
16
+
17
+        $paymentTerms = PaymentTerms::parse($data['payment_terms']) ?? $settings->payment_terms;
18
+
19
+        return new self(
20
+            header: $data['header'] ?? $settings->header ?? 'Invoice',
21
+            subheader: $data['subheader'] ?? $settings->subheader,
22
+            footer: $data['footer'] ?? $settings->footer,
23
+            terms: $data['terms'] ?? $settings->terms,
24
+            logo: $settings->logo_url,
25
+            number: self::generatePreviewNumber($settings, $data),
26
+            referenceNumber: 'ORD-00001',
27
+            date: $company->locale->date_format->getLabel(),
28
+            dueDate: $paymentTerms->getDueDate($company->locale->date_format->value),
29
+            currencyCode: CurrencyAccessor::getDefaultCurrency(),
30
+            subtotal: self::formatToMoney('1000', null),
31
+            discount: self::formatToMoney('100', null),
32
+            tax: self::formatToMoney('50', null),
33
+            total: self::formatToMoney('950', null),
34
+            amountDue: self::formatToMoney('950', null),
35
+            company: CompanyDTO::fromModel($company),
36
+            client: ClientPreviewDTO::fake(),
37
+            lineItems: LineItemPreviewDTO::fakeItems(),
38
+            label: DocumentType::Invoice->getLabels(),
39
+            columnLabel: self::generateColumnLabels($settings, $data),
40
+            accentColor: $data['accent_color'] ?? $settings->accent_color ?? '#000000',
41
+            showLogo: $data['show_logo'] ?? $settings->show_logo ?? true,
42
+            font: Font::tryFrom($data['font']) ?? $settings->font ?? Font::Inter,
43
+        );
44
+    }
45
+
46
+    protected static function generatePreviewNumber(DocumentDefault $settings, ?array $data): string
47
+    {
48
+        $prefix = $data['number_prefix'] ?? $settings->number_prefix ?? 'INV-';
49
+        $digits = $data['number_digits'] ?? $settings->number_digits ?? 5;
50
+        $next = $data['number_next'] ?? $settings->number_next;
51
+
52
+        return $settings->getNumberNext(padded: true, format: true, prefix: $prefix, digits: $digits, next: $next);
53
+    }
54
+
55
+    protected static function generateColumnLabels(DocumentDefault $settings, ?array $data): DocumentColumnLabelDTO
56
+    {
57
+        return new DocumentColumnLabelDTO(
58
+            items: $settings->resolveColumnLabel('item_name', 'Items', $data),
59
+            units: $settings->resolveColumnLabel('unit_name', 'Quantity', $data),
60
+            price: $settings->resolveColumnLabel('price_name', 'Price', $data),
61
+            amount: $settings->resolveColumnLabel('amount_name', 'Amount', $data),
62
+        );
63
+    }
64
+}

+ 1
- 1
app/DTO/LineItemDTO.php Прегледај датотеку

@@ -26,7 +26,7 @@ readonly class LineItemDTO
26 26
         );
27 27
     }
28 28
 
29
-    private static function formatToMoney(float | string $value, ?string $currencyCode): string
29
+    protected static function formatToMoney(float | string $value, ?string $currencyCode): string
30 30
     {
31 31
         return CurrencyConverter::formatToMoney($value, $currencyCode);
32 32
     }

+ 33
- 0
app/DTO/LineItemPreviewDTO.php Прегледај датотеку

@@ -0,0 +1,33 @@
1
+<?php
2
+
3
+namespace App\DTO;
4
+
5
+readonly class LineItemPreviewDTO extends LineItemDTO
6
+{
7
+    public static function fakeItems(): array
8
+    {
9
+        return [
10
+            new self(
11
+                name: 'Item 1',
12
+                description: 'Sample item description',
13
+                quantity: 2,
14
+                unitPrice: self::formatToMoney(150.00, null),
15
+                subtotal: self::formatToMoney(300.00, null),
16
+            ),
17
+            new self(
18
+                name: 'Item 2',
19
+                description: 'Another sample item description',
20
+                quantity: 3,
21
+                unitPrice: self::formatToMoney(200.00, null),
22
+                subtotal: self::formatToMoney(600.00, null),
23
+            ),
24
+            new self(
25
+                name: 'Item 3',
26
+                description: 'Yet another sample item description',
27
+                quantity: 1,
28
+                unitPrice: self::formatToMoney(180.00, null),
29
+                subtotal: self::formatToMoney(180.00, null),
30
+            ),
31
+        ];
32
+    }
33
+}

+ 4
- 4
app/Enums/Concerns/ParsesEnum.php Прегледај датотеку

@@ -4,16 +4,16 @@ namespace App\Enums\Concerns;
4 4
 
5 5
 trait ParsesEnum
6 6
 {
7
-    public static function parse(string | self | null $value): ?self
7
+    public static function parse(string | self | null $value): ?static
8 8
     {
9
-        if ($value === null) {
9
+        if (! $value) {
10 10
             return null;
11 11
         }
12 12
 
13
-        if ($value instanceof self) {
13
+        if ($value instanceof static) {
14 14
             return $value;
15 15
         }
16 16
 
17
-        return self::from($value);
17
+        return static::tryFrom($value);
18 18
     }
19 19
 }

+ 3
- 0
app/Enums/Setting/PaymentTerms.php Прегледај датотеку

@@ -2,10 +2,13 @@
2 2
 
3 3
 namespace App\Enums\Setting;
4 4
 
5
+use App\Enums\Concerns\ParsesEnum;
5 6
 use Filament\Support\Contracts\HasLabel;
6 7
 
7 8
 enum PaymentTerms: string implements HasLabel
8 9
 {
10
+    use ParsesEnum;
11
+
9 12
     case DueUponReceipt = 'due_upon_receipt';
10 13
     case Net7 = 'net_7';
11 14
     case Net10 = 'net_10';

+ 17
- 0
app/Models/Setting/DocumentDefault.php Прегледај датотеку

@@ -187,6 +187,23 @@ class DocumentDefault extends Model
187 187
         return $options[$optionValue] ?? null;
188 188
     }
189 189
 
190
+    public function resolveColumnLabel(string $column, string $default, ?array $data = null): string
191
+    {
192
+        if ($data) {
193
+            $custom = $data[$column]['custom'] ?? null;
194
+            $option = $data[$column]['option'] ?? null;
195
+        } else {
196
+            $custom = $this->{$column}['custom'] ?? null;
197
+            $option = $this->{$column}['option'] ?? null;
198
+        }
199
+
200
+        if ($custom) {
201
+            return $custom;
202
+        }
203
+
204
+        return $this->getLabelOptionFor($column, $option) ?? $default;
205
+    }
206
+
190 207
     protected static function newFactory(): Factory
191 208
     {
192 209
         return DocumentDefaultFactory::new();

+ 0
- 209
app/View/Models/InvoiceViewModel.php Прегледај датотеку

@@ -1,209 +0,0 @@
1
-<?php
2
-
3
-namespace App\View\Models;
4
-
5
-use App\Enums\Setting\Font;
6
-use App\Enums\Setting\PaymentTerms;
7
-use App\Models\Setting\DocumentDefault;
8
-use Filament\Panel\Concerns\HasFont;
9
-
10
-class InvoiceViewModel
11
-{
12
-    use HasFont;
13
-
14
-    public function __construct(
15
-        public DocumentDefault $invoice,
16
-        public ?array $data = null
17
-    ) {}
18
-
19
-    public function logo(): ?string
20
-    {
21
-        return $this->invoice->logo_url;
22
-    }
23
-
24
-    public function show_logo(): bool
25
-    {
26
-        return $this->data['show_logo'] ?? $this->invoice->show_logo ?? false;
27
-    }
28
-
29
-    // Company related methods
30
-    public function company_name(): string
31
-    {
32
-        return $this->invoice->company->name;
33
-    }
34
-
35
-    public function company_address(): ?string
36
-    {
37
-        return $this->invoice->company->profile->address ?? null;
38
-    }
39
-
40
-    public function company_phone(): ?string
41
-    {
42
-        return $this->invoice->company->profile->phone_number ?? null;
43
-    }
44
-
45
-    public function company_city(): ?string
46
-    {
47
-        return $this->invoice->company->profile->city->name ?? null;
48
-    }
49
-
50
-    public function company_state(): ?string
51
-    {
52
-        return $this->invoice->company->profile->state->name ?? null;
53
-    }
54
-
55
-    public function company_zip(): ?string
56
-    {
57
-        return $this->invoice->company->profile->zip_code ?? null;
58
-    }
59
-
60
-    public function company_country(): ?string
61
-    {
62
-        return $this->invoice->company->profile->state->country->name ?? null;
63
-    }
64
-
65
-    // Invoice numbering related methods
66
-    public function number_prefix(): string
67
-    {
68
-        return $this->data['number_prefix'] ?? $this->invoice->number_prefix ?? 'INV-';
69
-    }
70
-
71
-    public function number_digits(): int
72
-    {
73
-        return $this->data['number_digits'] ?? $this->invoice->number_digits ?? 5;
74
-    }
75
-
76
-    public function number_next(): string
77
-    {
78
-        return $this->data['number_next'] ?? $this->invoice->number_next;
79
-    }
80
-
81
-    public function invoice_number(): string
82
-    {
83
-        return $this->invoice->getNumberNext(padded: true, format: true, prefix: $this->number_prefix(), digits: $this->number_digits(), next: $this->number_next());
84
-    }
85
-
86
-    // Invoice date related methods
87
-    public function invoice_date(): string
88
-    {
89
-        return $this->invoice->company->locale->date_format->getLabel();
90
-    }
91
-
92
-    public function payment_terms(): string
93
-    {
94
-        return $this->data['payment_terms'] ?? $this->invoice->payment_terms?->value ?? PaymentTerms::DEFAULT;
95
-    }
96
-
97
-    public function invoice_due_date(): string
98
-    {
99
-        $dateFormat = $this->invoice->company->locale->date_format->value;
100
-
101
-        return PaymentTerms::from($this->payment_terms())->getDueDate($dateFormat);
102
-    }
103
-
104
-    // Invoice header related methods
105
-    public function header(): string
106
-    {
107
-        return $this->data['header'] ?? $this->invoice->header ?? 'Invoice';
108
-    }
109
-
110
-    public function subheader(): ?string
111
-    {
112
-        return $this->data['subheader'] ?? $this->invoice->subheader ?? null;
113
-    }
114
-
115
-    // Invoice styling
116
-    public function accent_color(): string
117
-    {
118
-        return $this->data['accent_color'] ?? $this->invoice->accent_color;
119
-    }
120
-
121
-    public function fontFamily(): string
122
-    {
123
-        if ($this->data['font']) {
124
-            return Font::from($this->data['font'])->getLabel();
125
-        }
126
-
127
-        if ($this->invoice->font) {
128
-            return $this->invoice->font->getLabel();
129
-        }
130
-
131
-        return Font::from(Font::DEFAULT)->getLabel();
132
-    }
133
-
134
-    public function footer(): ?string
135
-    {
136
-        return $this->data['footer'] ?? $this->invoice->footer ?? null;
137
-    }
138
-
139
-    public function terms(): ?string
140
-    {
141
-        return $this->data['terms'] ?? $this->invoice->terms ?? null;
142
-    }
143
-
144
-    public function getItemColumnName(string $column, string $default): string
145
-    {
146
-        $custom = $this->data[$column]['custom'] ?? $this->invoice->{$column . '_custom'} ?? null;
147
-
148
-        if ($custom) {
149
-            return $custom;
150
-        }
151
-
152
-        $option = $this->data[$column]['option'] ?? $this->invoice->{$column . '_option'} ?? null;
153
-
154
-        return $option ? $this->invoice->getLabelOptionFor($column, $option) : translate($default);
155
-    }
156
-
157
-    // Invoice column related methods
158
-    public function item_name(): string
159
-    {
160
-        return $this->getItemColumnName('item_name', 'Items');
161
-    }
162
-
163
-    public function unit_name(): string
164
-    {
165
-        return $this->getItemColumnName('unit_name', 'Quantity');
166
-    }
167
-
168
-    public function price_name(): string
169
-    {
170
-        return $this->getItemColumnName('price_name', 'Price');
171
-    }
172
-
173
-    public function amount_name(): string
174
-    {
175
-        return $this->getItemColumnName('amount_name', 'Amount');
176
-    }
177
-
178
-    public function buildViewData(): array
179
-    {
180
-        return [
181
-            'logo' => $this->logo(),
182
-            'show_logo' => $this->show_logo(),
183
-            'company_name' => $this->company_name(),
184
-            'company_address' => $this->company_address(),
185
-            'company_phone' => $this->company_phone(),
186
-            'company_city' => $this->company_city(),
187
-            'company_state' => $this->company_state(),
188
-            'company_zip' => $this->company_zip(),
189
-            'company_country' => $this->company_country(),
190
-            'number_prefix' => $this->number_prefix(),
191
-            'number_digits' => $this->number_digits(),
192
-            'number_next' => $this->number_next(),
193
-            'invoice_number' => $this->invoice_number(),
194
-            'invoice_date' => $this->invoice_date(),
195
-            'invoice_due_date' => $this->invoice_due_date(),
196
-            'header' => $this->header(),
197
-            'subheader' => $this->subheader(),
198
-            'accent_color' => $this->accent_color(),
199
-            'font_family' => $this->fontFamily(),
200
-            'font_html' => $this->font($this->fontFamily())->getFontHtml(),
201
-            'footer' => $this->footer(),
202
-            'terms' => $this->terms(),
203
-            'item_name' => $this->item_name(),
204
-            'unit_name' => $this->unit_name(),
205
-            'price_name' => $this->price_name(),
206
-            'amount_name' => $this->amount_name(),
207
-        ];
208
-    }
209
-}

+ 0
- 1
composer.json Прегледај датотеку

@@ -25,7 +25,6 @@
25 25
         "laravel/framework": "^11.0",
26 26
         "laravel/sanctum": "^4.0",
27 27
         "laravel/tinker": "^2.9",
28
-        "spatie/laravel-view-models": "^1.6",
29 28
         "squirephp/model": "^3.4",
30 29
         "squirephp/repository": "^3.4",
31 30
         "symfony/intl": "^6.3"

+ 7
- 76
composer.lock Прегледај датотеку

@@ -4,7 +4,7 @@
4 4
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5 5
         "This file is @generated automatically"
6 6
     ],
7
-    "content-hash": "decc627f2a7bd0c6546114ebb1f500f9",
7
+    "content-hash": "095bb4040f9910ddd128bd53c0670a55",
8 8
     "packages": [
9 9
         {
10 10
             "name": "akaunting/laravel-money",
@@ -6491,16 +6491,16 @@
6491 6491
         },
6492 6492
         {
6493 6493
             "name": "spatie/laravel-package-tools",
6494
-            "version": "1.18.0",
6494
+            "version": "1.18.2",
6495 6495
             "source": {
6496 6496
                 "type": "git",
6497 6497
                 "url": "https://github.com/spatie/laravel-package-tools.git",
6498
-                "reference": "8332205b90d17164913244f4a8e13ab7e6761d29"
6498
+                "reference": "d41c44a7eab604c3eb0cad93210612d4c1429c20"
6499 6499
             },
6500 6500
             "dist": {
6501 6501
                 "type": "zip",
6502
-                "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/8332205b90d17164913244f4a8e13ab7e6761d29",
6503
-                "reference": "8332205b90d17164913244f4a8e13ab7e6761d29",
6502
+                "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/d41c44a7eab604c3eb0cad93210612d4c1429c20",
6503
+                "reference": "d41c44a7eab604c3eb0cad93210612d4c1429c20",
6504 6504
                 "shasum": ""
6505 6505
             },
6506 6506
             "require": {
@@ -6539,7 +6539,7 @@
6539 6539
             ],
6540 6540
             "support": {
6541 6541
                 "issues": "https://github.com/spatie/laravel-package-tools/issues",
6542
-                "source": "https://github.com/spatie/laravel-package-tools/tree/1.18.0"
6542
+                "source": "https://github.com/spatie/laravel-package-tools/tree/1.18.2"
6543 6543
             },
6544 6544
             "funding": [
6545 6545
                 {
@@ -6547,76 +6547,7 @@
6547 6547
                     "type": "github"
6548 6548
                 }
6549 6549
             ],
6550
-            "time": "2024-12-30T13:13:39+00:00"
6551
-        },
6552
-        {
6553
-            "name": "spatie/laravel-view-models",
6554
-            "version": "1.6.0",
6555
-            "source": {
6556
-                "type": "git",
6557
-                "url": "https://github.com/spatie/laravel-view-models.git",
6558
-                "reference": "c8c74e26e2cc78d04e581867ce74c8b772279015"
6559
-            },
6560
-            "dist": {
6561
-                "type": "zip",
6562
-                "url": "https://api.github.com/repos/spatie/laravel-view-models/zipball/c8c74e26e2cc78d04e581867ce74c8b772279015",
6563
-                "reference": "c8c74e26e2cc78d04e581867ce74c8b772279015",
6564
-                "shasum": ""
6565
-            },
6566
-            "require": {
6567
-                "illuminate/support": "^8.0|^9.0|^10.0|^11.0",
6568
-                "php": "^7.3|^8.0"
6569
-            },
6570
-            "require-dev": {
6571
-                "orchestra/testbench": "^6.23|^7.0|^8.0|^9.0",
6572
-                "pestphp/pest": "^1.22|^2.34"
6573
-            },
6574
-            "type": "library",
6575
-            "extra": {
6576
-                "laravel": {
6577
-                    "providers": [
6578
-                        "Spatie\\ViewModels\\Providers\\ViewModelsServiceProvider"
6579
-                    ]
6580
-                }
6581
-            },
6582
-            "autoload": {
6583
-                "psr-4": {
6584
-                    "Spatie\\ViewModels\\": "src"
6585
-                }
6586
-            },
6587
-            "notification-url": "https://packagist.org/downloads/",
6588
-            "license": [
6589
-                "MIT"
6590
-            ],
6591
-            "authors": [
6592
-                {
6593
-                    "name": "Brent Roose",
6594
-                    "email": "brent@spatie.be",
6595
-                    "homepage": "https://spatie.be",
6596
-                    "role": "Developer"
6597
-                }
6598
-            ],
6599
-            "description": "View models in Laravel",
6600
-            "homepage": "https://github.com/spatie/laravel-view-models",
6601
-            "keywords": [
6602
-                "laravel-view-models",
6603
-                "spatie"
6604
-            ],
6605
-            "support": {
6606
-                "issues": "https://github.com/spatie/laravel-view-models/issues",
6607
-                "source": "https://github.com/spatie/laravel-view-models/tree/1.6.0"
6608
-            },
6609
-            "funding": [
6610
-                {
6611
-                    "url": "https://spatie.be/open-source/support-us",
6612
-                    "type": "custom"
6613
-                },
6614
-                {
6615
-                    "url": "https://github.com/spatie",
6616
-                    "type": "github"
6617
-                }
6618
-            ],
6619
-            "time": "2024-03-13T17:58:20+00:00"
6550
+            "time": "2025-01-20T14:14:17+00:00"
6620 6551
         },
6621 6552
         {
6622 6553
             "name": "squirephp/model",

+ 6
- 6
package-lock.json Прегледај датотеку

@@ -1235,9 +1235,9 @@
1235 1235
             "license": "MIT"
1236 1236
         },
1237 1237
         "node_modules/electron-to-chromium": {
1238
-            "version": "1.5.83",
1239
-            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.83.tgz",
1240
-            "integrity": "sha512-LcUDPqSt+V0QmI47XLzZrz5OqILSMGsPFkDYus22rIbgorSvBYEFqq854ltTmUdHkY92FSdAAvsh4jWEULMdfQ==",
1238
+            "version": "1.5.84",
1239
+            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.84.tgz",
1240
+            "integrity": "sha512-I+DQ8xgafao9Ha6y0qjHHvpZ9OfyA1qKlkHkjywxzniORU2awxyz7f/iVJcULmrF2yrM3nHQf+iDjJtbbexd/g==",
1241 1241
             "dev": true,
1242 1242
             "license": "ISC"
1243 1243
         },
@@ -2624,9 +2624,9 @@
2624 2624
             "license": "MIT"
2625 2625
         },
2626 2626
         "node_modules/vite": {
2627
-            "version": "6.0.7",
2628
-            "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.7.tgz",
2629
-            "integrity": "sha512-RDt8r/7qx9940f8FcOIAH9PTViRrghKaK2K1jY3RaAURrEUbm9Du1mJ72G+jlhtG3WwodnfzY8ORQZbBavZEAQ==",
2627
+            "version": "6.0.10",
2628
+            "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.10.tgz",
2629
+            "integrity": "sha512-MEszunEcMo6pFsfXN1GhCFQqnE25tWRH0MA4f0Q7uanACi4y1Us+ZGpTMnITwCTnYzB2b9cpmnelTlxgTBmaBA==",
2630 2630
             "dev": true,
2631 2631
             "license": "MIT",
2632 2632
             "dependencies": {

+ 49
- 59
resources/views/filament/company/components/invoice-layouts/classic.blade.php Прегледај датотеку

@@ -1,15 +1,13 @@
1 1
 @php
2 2
     $data = $this->form->getRawState();
3
-    $viewModel = new \App\View\Models\InvoiceViewModel($this->record, $data);
4
-    $viewSpecial = $viewModel->buildViewData();
5
-    extract($viewSpecial,\EXTR_SKIP);
3
+    $document = \App\DTO\DocumentPreviewDTO::fromSettings($this->record, $data);
6 4
 @endphp
7 5
 
8
-{!! $font_html !!}
6
+{!! $document->getFontHtml() !!}
9 7
 
10 8
 <style>
11 9
     .inv-paper {
12
-        font-family: '{{ $font_family }}', sans-serif;
10
+        font-family: '{{ $document->font->getLabel() }}', sans-serif;
13 11
     }
14 12
 </style>
15 13
 
@@ -18,63 +16,65 @@
18 16
     <x-company.invoice.header class="default-template-header">
19 17
         <div class="w-2/3 text-left ml-6">
20 18
             <div class="text-xs">
21
-                <h2 class="text-base font-semibold">{{ $company_name }}</h2>
22
-                @if($company_address && $company_city && $company_state && $company_zip)
23
-                    <p>{{ $company_address }}</p>
24
-                    <p>{{ $company_city }}, {{ $company_state }} {{ $company_zip }}</p>
25
-                    <p>{{ $company_country }}</p>
19
+                <h2 class="text-base font-semibold">{{ $document->company->name }}</h2>
20
+                @if($formattedAddress = $document->company->getFormattedAddressHtml())
21
+                    {!! $formattedAddress !!}
26 22
                 @endif
27 23
             </div>
28 24
         </div>
29 25
 
30 26
         <div class="w-1/3 flex justify-end mr-6">
31
-            @if($logo && $show_logo)
32
-                <x-company.invoice.logo :src="$logo"/>
27
+            @if($document->logo && $document->showLogo)
28
+                <x-company.invoice.logo :src="$document->logo"/>
33 29
             @endif
34 30
         </div>
35 31
     </x-company.invoice.header>
36 32
 
37 33
     <x-company.invoice.metadata class="classic-template-metadata">
38 34
         <div class="items-center flex">
39
-            <hr class="grow-[2] py-0.5 border-solid border-y-2" style="border-color: {{ $accent_color }};">
35
+            <hr class="grow-[2] py-0.5 border-solid border-y-2" style="border-color: {{ $document->accentColor }};">
40 36
             <div class="items-center flex mx-5">
41
-                <x-icons.decor-border-left color="{{ $accent_color }}"/>
42
-                <div class="px-2.5 border-solid border-y-2 py-1 -mx-3" style="border-color: {{ $accent_color }};">
43
-                    <div class="px-2.5 border-solid border-y-2 py-3" style="border-color: {{ $accent_color }};">
37
+                <x-icons.decor-border-left color="{{ $document->accentColor }}"/>
38
+                <div class="px-2.5 border-solid border-y-2 py-1 -mx-3" style="border-color: {{ $document->accentColor }};">
39
+                    <div class="px-2.5 border-solid border-y-2 py-3" style="border-color: {{ $document->accentColor }};">
44 40
                         <div class="inline text-2xl font-semibold"
45
-                             style="color: {{ $accent_color }};">{{ $header }}</div>
41
+                             style="color: {{ $document->accentColor }};">{{ $document->header }}</div>
46 42
                     </div>
47 43
                 </div>
48
-                <x-icons.decor-border-right color="{{ $accent_color }}"/>
44
+                <x-icons.decor-border-right color="{{ $document->accentColor }}"/>
49 45
             </div>
50
-            <hr class="grow-[2] py-0.5 border-solid border-y-2" style="border-color: {{ $accent_color }};">
46
+            <hr class="grow-[2] py-0.5 border-solid border-y-2" style="border-color: {{ $document->accentColor }};">
51 47
         </div>
52
-        <div class="mt-2 text-sm text-center text-gray-600 dark:text-gray-400">{{ $subheader }}</div>
48
+        <div class="mt-2 text-sm text-center text-gray-600 dark:text-gray-400">{{ $document->subheader }}</div>
53 49
 
54 50
         <div class="flex justify-between items-end">
55 51
             <!-- Billing Details -->
56 52
             <div class="text-xs">
57 53
                 <h3 class="text-gray-600 dark:text-gray-400 font-medium tracking-tight mb-1">BILL TO</h3>
58
-                <p class="text-base font-bold">John Doe</p>
59
-                <p>123 Main Street</p>
60
-                <p>New York, New York 10001</p>
61
-                <p>United States</p>
54
+                <p class="text-base font-bold">{{ $document->client->name }}</p>
55
+                @if($formattedAddress = $document->client->getFormattedAddressHtml())
56
+                    {!! $formattedAddress !!}
57
+                @endif
62 58
             </div>
63 59
 
64 60
             <div class="text-xs">
65 61
                 <table class="min-w-full">
66 62
                     <tbody>
67 63
                     <tr>
68
-                        <td class="font-semibold text-right pr-2">Invoice Number:</td>
69
-                        <td class="text-left pl-2">{{ $invoice_number }}</td>
64
+                        <td class="font-semibold text-right pr-2">{{ $document->label->number }}:</td>
65
+                        <td class="text-left pl-2">{{ $document->number }}</td>
66
+                    </tr>
67
+                    <tr>
68
+                        <td class="font-semibold text-right pr-2">{{ $document->label->referenceNumber }}:</td>
69
+                        <td class="text-left pl-2">{{ $document->referenceNumber }}</td>
70 70
                     </tr>
71 71
                     <tr>
72
-                        <td class="font-semibold text-right pr-2">Invoice Date:</td>
73
-                        <td class="text-left pl-2">{{ $invoice_date }}</td>
72
+                        <td class="font-semibold text-right pr-2">{{ $document->label->date }}:</td>
73
+                        <td class="text-left pl-2">{{ $document->date }}</td>
74 74
                     </tr>
75 75
                     <tr>
76
-                        <td class="font-semibold text-right pr-2">Payment Due:</td>
77
-                        <td class="text-left pl-2">{{ $invoice_due_date }}</td>
76
+                        <td class="font-semibold text-right pr-2">{{ $document->label->dueDate }}:</td>
77
+                        <td class="text-left pl-2">{{ $document->dueDate }}</td>
78 78
                     </tr>
79 79
                     </tbody>
80 80
                 </table>
@@ -87,31 +87,21 @@
87 87
         <table class="w-full text-left table-fixed">
88 88
             <thead class="text-sm leading-8">
89 89
             <tr>
90
-                <th class="text-left">{{ $item_name }}</th>
91
-                <th class="text-center">{{ $unit_name }}</th>
92
-                <th class="text-right">{{ $price_name }}</th>
93
-                <th class="text-right">{{ $amount_name }}</th>
90
+                <th class="text-left">{{ $document->columnLabel->items }}</th>
91
+                <th class="text-center">{{ $document->columnLabel->units }}</th>
92
+                <th class="text-right">{{ $document->columnLabel->price }}</th>
93
+                <th class="text-right">{{ $document->columnLabel->amount }}</th>
94 94
             </tr>
95 95
             </thead>
96 96
             <tbody class="text-xs border-t-2 border-b-2 border-dotted border-gray-300 leading-8">
97
-            <tr>
98
-                <td class="text-left font-semibold">Item 1</td>
99
-                <td class="text-center">2</td>
100
-                <td class="text-right">$150.00</td>
101
-                <td class="text-right">$300.00</td>
102
-            </tr>
103
-            <tr>
104
-                <td class="text-left font-semibold">Item 2</td>
105
-                <td class="text-center">3</td>
106
-                <td class="text-right">$200.00</td>
107
-                <td class="text-right">$600.00</td>
108
-            </tr>
109
-            <tr>
110
-                <td class="text-left font-semibold">Item 3</td>
111
-                <td class="text-center">1</td>
112
-                <td class="text-right">$180.00</td>
113
-                <td class="text-right">$180.00</td>
114
-            </tr>
97
+            @foreach($document->lineItems as $item)
98
+                <tr>
99
+                    <td class="text-left font-semibold">{{ $item->name }}</td>
100
+                    <td class="text-center">{{ $item->quantity }}</td>
101
+                    <td class="text-right">{{ $item->unitPrice }}</td>
102
+                    <td class="text-right">{{ $item->subtotal }}</td>
103
+                </tr>
104
+            @endforeach
115 105
             </tbody>
116 106
         </table>
117 107
 
@@ -120,7 +110,7 @@
120 110
             <!-- Notes Section -->
121 111
             <div class="w-1/2 border border-dashed border-gray-300 p-2 mt-4">
122 112
                 <h4 class="font-semibold mb-2">Notes</h4>
123
-                <p>{{ $footer }}</p>
113
+                <p>{{ $document->footer }}</p>
124 114
             </div>
125 115
 
126 116
             <!-- Financial Summary -->
@@ -129,23 +119,23 @@
129 119
                     <tbody class="text-xs leading-loose">
130 120
                     <tr>
131 121
                         <td class="text-right font-semibold">Subtotal:</td>
132
-                        <td class="text-right">$1080.00</td>
122
+                        <td class="text-right">{{ $document->subtotal }}</td>
133 123
                     </tr>
134 124
                     <tr class="text-success-800 dark:text-success-600">
135 125
                         <td class="text-right">Discount (5%):</td>
136
-                        <td class="text-right">($54.00)</td>
126
+                        <td class="text-right">({{ $document->discount }})</td>
137 127
                     </tr>
138 128
                     <tr>
139 129
                         <td class="text-right">Sales Tax (10%):</td>
140
-                        <td class="text-right">$102.60</td>
130
+                        <td class="text-right">{{ $document->tax }}</td>
141 131
                     </tr>
142 132
                     <tr>
143 133
                         <td class="text-right font-semibold">Total:</td>
144
-                        <td class="text-right">$1128.60</td>
134
+                        <td class="text-right">{{ $document->total }}</td>
145 135
                     </tr>
146 136
                     <tr>
147 137
                         <td class="text-right font-semibold">Amount Due (USD):</td>
148
-                        <td class="text-right">$1128.60</td>
138
+                        <td class="text-right">{{ $document->amountDue }}</td>
149 139
                     </tr>
150 140
                     </tbody>
151 141
                 </table>
@@ -156,6 +146,6 @@
156 146
     <!-- Footer -->
157 147
     <x-company.invoice.footer class="classic-template-footer">
158 148
         <h4 class="font-semibold px-6 mb-2">Terms & Conditions</h4>
159
-        <p class="px-6 break-words line-clamp-4">{{ $terms }}</p>
149
+        <p class="px-6 break-words line-clamp-4">{{ $document->terms }}</p>
160 150
     </x-company.invoice.footer>
161 151
 </x-company.invoice.container>

+ 47
- 57
resources/views/filament/company/components/invoice-layouts/default.blade.php Прегледај датотеку

@@ -1,15 +1,13 @@
1 1
 @php
2 2
     $data = $this->form->getRawState();
3
-    $viewModel = new \App\View\Models\InvoiceViewModel($this->record, $data);
4
-    $viewSpecial = $viewModel->buildViewData();
5
-    extract($viewSpecial,\EXTR_SKIP);
3
+    $document = \App\DTO\DocumentPreviewDTO::fromSettings($this->record, $data);
6 4
 @endphp
7 5
 
8
-{!! $font_html !!}
6
+{!! $document->getFontHtml() !!}
9 7
 
10 8
 <style>
11 9
     .inv-paper {
12
-        font-family: '{{ $font_family }}', sans-serif;
10
+        font-family: '{{ $document->font->getLabel() }}', sans-serif;
13 11
     }
14 12
 </style>
15 13
 
@@ -17,18 +15,16 @@
17 15
 
18 16
     <x-company.invoice.header class="default-template-header border-b-2 p-6 pb-4">
19 17
         <div class="w-2/3">
20
-            @if($logo && $show_logo)
21
-                <x-company.invoice.logo :src="$logo"/>
18
+            @if($document->logo && $document->showLogo)
19
+                <x-company.invoice.logo :src="$document->logo"/>
22 20
             @endif
23 21
         </div>
24 22
 
25 23
         <div class="w-1/3 text-right">
26 24
             <div class="text-xs">
27
-                <h2 class="font-semibold">{{ $company_name }}</h2>
28
-                @if($company_address && $company_city && $company_state && $company_zip)
29
-                    <p>{{ $company_address }}</p>
30
-                    <p>{{ $company_city }}, {{ $company_state }} {{ $company_zip }}</p>
31
-                    <p>{{ $company_country }}</p>
25
+                <h2 class="font-semibold">{{ $document->company->name }}</h2>
26
+                @if($formattedAddress = $document->company->getFormattedAddressHtml())
27
+                    {!! $formattedAddress !!}
32 28
                 @endif
33 29
             </div>
34 30
         </div>
@@ -36,9 +32,9 @@
36 32
 
37 33
     <x-company.invoice.metadata class="default-template-metadata space-y-6">
38 34
         <div>
39
-            <h1 class="text-3xl font-light uppercase">{{ $header }}</h1>
40
-            @if ($subheader)
41
-                <h2 class="text-sm text-gray-600 dark:text-gray-400">{{ $subheader }}</h2>
35
+            <h1 class="text-3xl font-light uppercase">{{ $document->header }}</h1>
36
+            @if ($document->subheader)
37
+                <h2 class="text-sm text-gray-600 dark:text-gray-400">{{ $document->subheader }}</h2>
42 38
             @endif
43 39
         </div>
44 40
 
@@ -46,26 +42,30 @@
46 42
             <!-- Billing Details -->
47 43
             <div class="text-xs">
48 44
                 <h3 class="text-gray-600 dark:text-gray-400 font-medium tracking-tight mb-1">BILL TO</h3>
49
-                <p class="text-base font-bold">John Doe</p>
50
-                <p>123 Main Street</p>
51
-                <p>New York, New York 10001</p>
52
-                <p>United States</p>
45
+                <p class="text-base font-bold">{{ $document->client->name }}</p>
46
+                @if($formattedAddress = $document->client->getFormattedAddressHtml())
47
+                    {!! $formattedAddress !!}
48
+                @endif
53 49
             </div>
54 50
 
55 51
             <div class="text-xs">
56 52
                 <table class="min-w-full">
57 53
                     <tbody>
58 54
                     <tr>
59
-                        <td class="font-semibold text-right pr-2">Invoice Number:</td>
60
-                        <td class="text-left pl-2">{{ $invoice_number }}</td>
55
+                        <td class="font-semibold text-right pr-2">{{ $document->label->number }}:</td>
56
+                        <td class="text-left pl-2">{{ $document->number }}</td>
57
+                    </tr>
58
+                    <tr>
59
+                        <td class="font-semibold text-right pr-2">{{ $document->label->referenceNumber }}:</td>
60
+                        <td class="text-left pl-2">{{ $document->referenceNumber }}</td>
61 61
                     </tr>
62 62
                     <tr>
63
-                        <td class="font-semibold text-right pr-2">Invoice Date:</td>
64
-                        <td class="text-left pl-2">{{ $invoice_date }}</td>
63
+                        <td class="font-semibold text-right pr-2">{{ $document->label->date }}:</td>
64
+                        <td class="text-left pl-2">{{ $document->date }}</td>
65 65
                     </tr>
66 66
                     <tr>
67
-                        <td class="font-semibold text-right pr-2">Payment Due:</td>
68
-                        <td class="text-left pl-2">{{ $invoice_due_date }}</td>
67
+                        <td class="font-semibold text-right pr-2">{{ $document->label->dueDate }}:</td>
68
+                        <td class="text-left pl-2">{{ $document->dueDate }}</td>
69 69
                     </tr>
70 70
                     </tbody>
71 71
                 </table>
@@ -76,59 +76,49 @@
76 76
     <!-- Line Items Table -->
77 77
     <x-company.invoice.line-items class="default-template-line-items">
78 78
         <table class="w-full text-left table-fixed">
79
-            <thead class="text-sm leading-8" style="background: {{ $accent_color }}">
79
+            <thead class="text-sm leading-8" style="background: {{ $document->accentColor }}">
80 80
             <tr class="text-white">
81
-                <th class="text-left pl-6">{{ $item_name }}</th>
82
-                <th class="text-center">{{ $unit_name }}</th>
83
-                <th class="text-right">{{ $price_name }}</th>
84
-                <th class="text-right pr-6">{{ $amount_name }}</th>
81
+                <th class="text-left pl-6">{{ $document->columnLabel->items }}</th>
82
+                <th class="text-center">{{ $document->columnLabel->units }}</th>
83
+                <th class="text-right">{{ $document->columnLabel->price }}</th>
84
+                <th class="text-right pr-6">{{ $document->columnLabel->amount }}</th>
85 85
             </tr>
86 86
             </thead>
87 87
             <tbody class="text-xs border-b-2 border-gray-300 leading-8">
88
-            <tr>
89
-                <td class="text-left pl-6 font-semibold">Item 1</td>
90
-                <td class="text-center">2</td>
91
-                <td class="text-right">$150.00</td>
92
-                <td class="text-right pr-6">$300.00</td>
93
-            </tr>
94
-            <tr>
95
-                <td class="text-left pl-6 font-semibold">Item 2</td>
96
-                <td class="text-center">3</td>
97
-                <td class="text-right">$200.00</td>
98
-                <td class="text-right pr-6">$600.00</td>
99
-            </tr>
100
-            <tr>
101
-                <td class="text-left pl-6 font-semibold">Item 3</td>
102
-                <td class="text-center">1</td>
103
-                <td class="text-right">$180.00</td>
104
-                <td class="text-right pr-6">$180.00</td>
105
-            </tr>
88
+            @foreach($document->lineItems as $item)
89
+                <tr>
90
+                    <td class="text-left pl-6 font-semibold">{{ $item->name }}</td>
91
+                    <td class="text-center">{{ $item->quantity }}</td>
92
+                    <td class="text-right">{{ $item->unitPrice }}</td>
93
+                    <td class="text-right pr-6">{{ $item->subtotal }}</td>
94
+                </tr>
95
+            @endforeach
106 96
             </tbody>
107 97
             <tfoot class="text-xs leading-loose">
108 98
             <tr>
109 99
                 <td class="pl-6" colspan="2"></td>
110 100
                 <td class="text-right font-semibold">Subtotal:</td>
111
-                <td class="text-right pr-6">$1080.00</td>
101
+                <td class="text-right pr-6">{{ $document->subtotal }}</td>
112 102
             </tr>
113 103
             <tr class="text-success-800 dark:text-success-600">
114 104
                 <td class="pl-6" colspan="2"></td>
115 105
                 <td class="text-right">Discount (5%):</td>
116
-                <td class="text-right pr-6">($54.00)</td>
106
+                <td class="text-right pr-6">({{ $document->discount }})</td>
117 107
             </tr>
118 108
             <tr>
119 109
                 <td class="pl-6" colspan="2"></td>
120
-                <td class="text-right">Sales Tax (10%):</td>
121
-                <td class="text-right pr-6">$102.60</td>
110
+                <td class="text-right">Tax:</td>
111
+                <td class="text-right pr-6">{{ $document->tax }}</td>
122 112
             </tr>
123 113
             <tr>
124 114
                 <td class="pl-6" colspan="2"></td>
125 115
                 <td class="text-right font-semibold border-t">Total:</td>
126
-                <td class="text-right border-t pr-6">$1128.60</td>
116
+                <td class="text-right border-t pr-6">{{ $document->total }}</td>
127 117
             </tr>
128 118
             <tr>
129 119
                 <td class="pl-6" colspan="2"></td>
130
-                <td class="text-right font-semibold border-t-4 border-double">Amount Due (USD):</td>
131
-                <td class="text-right border-t-4 border-double pr-6">$1128.60</td>
120
+                <td class="text-right font-semibold border-t-4 border-double">{{ $document->label->amountDue }} ({{ $document->currencyCode }}):</td>
121
+                <td class="text-right border-t-4 border-double pr-6">{{ $document->amountDue }}</td>
132 122
             </tr>
133 123
             </tfoot>
134 124
         </table>
@@ -136,9 +126,9 @@
136 126
 
137 127
     <!-- Footer Notes -->
138 128
     <x-company.invoice.footer class="default-template-footer">
139
-        <p class="px-6">{{ $footer }}</p>
129
+        <p class="px-6">{{ $document->footer }}</p>
140 130
         <span class="border-t-2 my-2 border-gray-300 block w-full"></span>
141 131
         <h4 class="font-semibold px-6 mb-2">Terms & Conditions</h4>
142
-        <p class="px-6 break-words line-clamp-4">{{ $terms }}</p>
132
+        <p class="px-6 break-words line-clamp-4">{{ $document->terms }}</p>
143 133
     </x-company.invoice.footer>
144 134
 </x-company.invoice.container>

+ 85
- 76
resources/views/filament/company/components/invoice-layouts/modern.blade.php Прегледај датотеку

@@ -1,15 +1,13 @@
1 1
 @php
2 2
     $data = $this->form->getRawState();
3
-    $viewModel = new \App\View\Models\InvoiceViewModel($this->record, $data);
4
-    $viewSpecial = $viewModel->buildViewData();
5
-    extract($viewSpecial,\EXTR_SKIP);
3
+    $document = \App\DTO\DocumentPreviewDTO::fromSettings($this->record, $data);
6 4
 @endphp
7 5
 
8
-{!! $font_html !!}
6
+{!! $document->getFontHtml() !!}
9 7
 
10 8
 <style>
11 9
     .inv-paper {
12
-        font-family: '{{ $font_family }}', sans-serif;
10
+        font-family: '{{ $document->font->getLabel() }}', sans-serif;
13 11
     }
14 12
 </style>
15 13
 
@@ -19,16 +17,16 @@
19 17
     <x-company.invoice.header class="bg-gray-800 h-20">
20 18
         <!-- Logo -->
21 19
         <div class="w-2/3">
22
-            @if($logo && $show_logo)
23
-                <x-company.invoice.logo class="ml-6" :src="$logo"/>
20
+            @if($document->logo && $document->showLogo)
21
+                <x-company.invoice.logo class="ml-6" :src="$document->logo"/>
24 22
             @endif
25 23
         </div>
26 24
 
27 25
         <!-- Ribbon Container -->
28 26
         <div class="w-1/3 absolute right-0 top-0 p-2 h-28 flex flex-col justify-end rounded-bl-sm"
29
-             style="background: {{ $accent_color }};">
30
-            @if($header)
31
-                <h1 class="text-3xl font-bold text-white text-center uppercase">{{ $header }}</h1>
27
+             style="background: {{ $document->accentColor }};">
28
+            @if($document->header)
29
+                <h1 class="text-3xl font-bold text-white text-center uppercase">{{ $document->header }}</h1>
32 30
             @endif
33 31
         </div>
34 32
     </x-company.invoice.header>
@@ -36,38 +34,44 @@
36 34
     <!-- Company Details -->
37 35
     <x-company.invoice.metadata class="modern-template-metadata space-y-6">
38 36
         <div class="text-xs">
39
-            <h2 class="text-base font-semibold">{{ $company_name }}</h2>
40
-            @if($company_address && $company_city && $company_state && $company_zip)
41
-                <p>{{ $company_address }}</p>
42
-                <p>{{ $company_city }}, {{ $company_state }} {{ $company_zip }}</p>
43
-                <p>{{ $company_country }}</p>
37
+            <h2 class="text-base font-semibold">{{ $document->company->name }}</h2>
38
+            @if($formattedAddress = $document->company->getFormattedAddressHtml())
39
+                {!! $formattedAddress !!}
44 40
             @endif
45 41
         </div>
46 42
 
47 43
         <div class="flex justify-between items-end">
48 44
             <!-- Billing Details -->
49
-            <div class="text-xs">
45
+            <div class="text-xs tracking-tight">
50 46
                 <h3 class="text-gray-600 dark:text-gray-400 font-medium tracking-tight mb-1">BILL TO</h3>
51
-                <p class="text-base font-bold" style="color: {{ $accent_color }}">John Doe</p>
52
-                <p>123 Main Street</p>
53
-                <p>New York, New York 10001</p>
54
-                <p>United States</p>
47
+                <p class="text-base font-bold"
48
+                   style="color: {{ $document->accentColor }}">{{ $document->client->name }}</p>
49
+
50
+                @if($formattedAddress = $document->client->getFormattedAddressHtml())
51
+                    {!! $formattedAddress !!}
52
+                @endif
55 53
             </div>
56 54
 
57
-            <div class="text-xs">
55
+            <div class="text-xs tracking-tight">
58 56
                 <table class="min-w-full">
59 57
                     <tbody>
60 58
                     <tr>
61
-                        <td class="font-semibold text-right pr-2">Invoice Number:</td>
62
-                        <td class="text-left pl-2">{{ $invoice_number }}</td>
59
+                        <td class="font-semibold text-right pr-2">{{ $document->label->number }}:</td>
60
+                        <td class="text-left pl-2">{{ $document->number }}</td>
63 61
                     </tr>
62
+                    @if($document->referenceNumber)
63
+                        <tr>
64
+                            <td class="font-semibold text-right pr-2">{{ $document->label->referenceNumber }}:</td>
65
+                            <td class="text-left pl-2">{{ $document->referenceNumber }}</td>
66
+                        </tr>
67
+                    @endif
64 68
                     <tr>
65
-                        <td class="font-semibold text-right pr-2">Invoice Date:</td>
66
-                        <td class="text-left pl-2">{{ $invoice_date }}</td>
69
+                        <td class="font-semibold text-right pr-2">{{ $document->label->date }}:</td>
70
+                        <td class="text-left pl-2">{{ $document->date }}</td>
67 71
                     </tr>
68 72
                     <tr>
69
-                        <td class="font-semibold text-right pr-2">Payment Due:</td>
70
-                        <td class="text-left pl-2">{{ $invoice_due_date }}</td>
73
+                        <td class="font-semibold text-right pr-2">{{ $document->label->dueDate }}:</td>
74
+                        <td class="text-left pl-2">{{ $document->dueDate }}</td>
71 75
                     </tr>
72 76
                     </tbody>
73 77
                 </table>
@@ -80,69 +84,74 @@
80 84
         <table class="w-full text-left table-fixed">
81 85
             <thead class="text-sm leading-8">
82 86
             <tr class="text-gray-600 dark:text-gray-400">
83
-                <th class="text-left pl-6">{{ $item_name }}</th>
84
-                <th class="text-center">{{ $unit_name }}</th>
85
-                <th class="text-right">{{ $price_name }}</th>
86
-                <th class="text-right pr-6">{{ $amount_name }}</th>
87
+                <th class="text-left pl-6 w-[50%]">{{ $document->columnLabel->items }}</th>
88
+                <th class="text-center w-[10%]">{{ $document->columnLabel->units }}</th>
89
+                <th class="text-right w-[20%]">{{ $document->columnLabel->price }}</th>
90
+                <th class="text-right pr-6 w-[20%]">{{ $document->columnLabel->amount }}</th>
87 91
             </tr>
88 92
             </thead>
89
-            <tbody class="text-xs border-t-2 border-b-2 leading-8">
90
-            <tr class="bg-gray-100 dark:bg-gray-800">
91
-                <td class="text-left pl-6 font-semibold">Item 1</td>
92
-                <td class="text-center">2</td>
93
-                <td class="text-right">$150.00</td>
94
-                <td class="text-right pr-6">$300.00</td>
95
-            </tr>
96
-            <tr>
97
-                <td class="text-left pl-6 font-semibold">Item 2</td>
98
-                <td class="text-center">3</td>
99
-                <td class="text-right">$200.00</td>
100
-                <td class="text-right pr-6">$600.00</td>
101
-            </tr>
102
-            <tr class="bg-gray-100 dark:bg-gray-800">
103
-                <td class="text-left pl-6 font-semibold">Item 3</td>
104
-                <td class="text-center">1</td>
105
-                <td class="text-right">$180.00</td>
106
-                <td class="text-right pr-6">$180.00</td>
107
-            </tr>
93
+            <tbody class="text-xs tracking-tight border-y-2">
94
+            @foreach($document->lineItems as $index => $item)
95
+                <tr @class(['bg-gray-100 dark:bg-gray-800' => $index % 2 === 0])>
96
+                    <td class="text-left pl-6 font-semibold py-2">
97
+                        {{ $item->name }}
98
+                        @if($item->description)
99
+                            <div class="text-gray-600 font-normal line-clamp-2">{{ $item->description }}</div>
100
+                        @endif
101
+                    </td>
102
+                    <td class="text-center">{{ $item->quantity }}</td>
103
+                    <td class="text-right">{{ $item->unitPrice }}</td>
104
+                    <td class="text-right pr-6">{{ $item->subtotal }}</td>
105
+                </tr>
106
+            @endforeach
108 107
             </tbody>
109
-            <tfoot class="text-xs leading-loose">
108
+            <tfoot class="text-xs tracking-tight">
110 109
             <tr>
111
-                <td class="pl-6" colspan="2"></td>
112
-                <td class="text-right font-semibold">Subtotal:</td>
113
-                <td class="text-right pr-6">$1080.00</td>
114
-            </tr>
115
-            <tr class="text-success-800 dark:text-success-600">
116
-                <td class="pl-6" colspan="2"></td>
117
-                <td class="text-right">Discount (5%):</td>
118
-                <td class="text-right pr-6">($54.00)</td>
119
-            </tr>
120
-            <tr>
121
-                <td class="pl-6" colspan="2"></td>
122
-                <td class="text-right">Sales Tax (10%):</td>
123
-                <td class="text-right pr-6">$102.60</td>
124
-            </tr>
125
-            <tr>
126
-                <td class="pl-6" colspan="2"></td>
127
-                <td class="text-right font-semibold border-t">Total:</td>
128
-                <td class="text-right border-t pr-6">$1128.60</td>
110
+                <td class="pl-6 py-1" colspan="2"></td>
111
+                <td class="text-right font-semibold py-1">Subtotal:</td>
112
+                <td class="text-right pr-6 py-1">{{ $document->subtotal }}</td>
129 113
             </tr>
114
+            @if($document->discount)
115
+                <tr class="text-success-800 dark:text-success-600">
116
+                    <td class="pl-6 py-1" colspan="2"></td>
117
+                    <td class="text-right py-1">Discount:</td>
118
+                    <td class="text-right pr-6 py-1">
119
+                        ({{ $document->discount }})
120
+                    </td>
121
+                </tr>
122
+            @endif
123
+            @if($document->tax)
124
+                <tr>
125
+                    <td class="pl-6 py-1" colspan="2"></td>
126
+                    <td class="text-right py-1">Tax:</td>
127
+                    <td class="text-right pr-6 py-1">{{ $document->tax }}</td>
128
+                </tr>
129
+            @endif
130 130
             <tr>
131
-                <td class="pl-6" colspan="2"></td>
132
-                <td class="text-right font-semibold border-t-4 border-double">Amount Due (USD):</td>
133
-                <td class="text-right border-t-4 border-double pr-6">$1128.60</td>
131
+                <td class="pl-6 py-1" colspan="2"></td>
132
+                <td class="text-right font-semibold border-t py-1">Total:</td>
133
+                <td class="text-right border-t pr-6 py-1">{{ $document->total }}</td>
134 134
             </tr>
135
+            @if($document->amountDue)
136
+                <tr>
137
+                    <td class="pl-6 py-1" colspan="2"></td>
138
+                    <td class="text-right font-semibold border-t-4 border-double py-1">{{ $document->label->amountDue }}
139
+                        ({{ $document->currencyCode }}):
140
+                    </td>
141
+                    <td class="text-right border-t-4 border-double pr-6 py-1">{{ $document->amountDue }}</td>
142
+                </tr>
143
+            @endif
135 144
             </tfoot>
136 145
         </table>
137 146
     </x-company.invoice.line-items>
138 147
 
139 148
     <!-- Footer Notes -->
140
-    <x-company.invoice.footer class="modern-template-footer">
141
-        <h4 class="font-semibold px-6" style="color: {{ $accent_color }}">Terms & Conditions</h4>
149
+    <x-company.invoice.footer class="modern-template-footer tracking-tight">
150
+        <h4 class="font-semibold px-6" style="color: {{ $document->accentColor }}">Terms & Conditions</h4>
142 151
         <span class="border-t-2 my-2 border-gray-300 block w-full"></span>
143 152
         <div class="flex justify-between space-x-4 px-6">
144
-            <p class="w-1/2 break-words line-clamp-4">{{ $terms }}</p>
145
-            <p class="w-1/2 break-words line-clamp-4">{{ $footer }}</p>
153
+            <p class="w-1/2 break-words line-clamp-4">{{ $document->terms }}</p>
154
+            <p class="w-1/2 break-words line-clamp-4">{{ $document->footer }}</p>
146 155
         </div>
147 156
     </x-company.invoice.footer>
148 157
 </x-company.invoice.container>

+ 12
- 4
resources/views/filament/infolists/components/document-preview.blade.php Прегледај датотеку

@@ -2,6 +2,14 @@
2 2
     $document = \App\DTO\DocumentDTO::fromModel($getRecord());
3 3
 @endphp
4 4
 
5
+{!! $document->getFontHtml() !!}
6
+
7
+<style>
8
+    .inv-paper {
9
+        font-family: '{{ $document->font->getLabel() }}', sans-serif;
10
+    }
11
+</style>
12
+
5 13
 <div {{ $attributes }}>
6 14
     <x-company.invoice.container class="modern-template-container">
7 15
         <!-- Colored Header with Logo -->
@@ -75,10 +83,10 @@
75 83
             <table class="w-full text-left table-fixed">
76 84
                 <thead class="text-sm leading-relaxed">
77 85
                 <tr class="text-gray-600 dark:text-gray-400">
78
-                    <th class="text-left pl-6 w-[45%] py-4">Items</th>
79
-                    <th class="text-center w-[15%] py-4">Quantity</th>
80
-                    <th class="text-right w-[20%] py-4">Price</th>
81
-                    <th class="text-right pr-6 w-[20%] py-4">Amount</th>
86
+                    <th class="text-left pl-6 w-[50%] py-4">{{ $document->columnLabel->items }}</th>
87
+                    <th class="text-center w-[10%] py-4">{{ $document->columnLabel->units }}</th>
88
+                    <th class="text-right w-[20%] py-4">{{ $document->columnLabel->price }}</th>
89
+                    <th class="text-right pr-6 w-[20%] py-4">{{ $document->columnLabel->amount }}</th>
82 90
                 </tr>
83 91
                 </thead>
84 92
                 <tbody class="text-sm tracking-tight border-y-2">

Loading…
Откажи
Сачувај