Browse Source

Merge pull request #107 from andrewdwallo/development-3.x

Development 3.x
3.x
Andrew Wallo 7 months ago
parent
commit
1e97b30938
No account linked to committer's email address
55 changed files with 648 additions and 151458 deletions
  1. 0
    29
      app/Actions/OptionAction/CreateCurrency.php
  2. 4
    94
      app/Filament/Company/Clusters/Settings/Resources/CurrencyResource.php
  3. 3
    5
      app/Filament/Company/Clusters/Settings/Resources/CurrencyResource/Pages/CreateCurrency.php
  4. 4
    7
      app/Filament/Company/Clusters/Settings/Resources/CurrencyResource/Pages/EditCurrency.php
  5. 3
    3
      app/Filament/Company/Clusters/Settings/Resources/DocumentDefaultResource.php
  6. 16
    7
      app/Filament/Company/Resources/Purchases/BillResource.php
  7. 1
    0
      app/Filament/Company/Resources/Sales/EstimateResource/Pages/ViewEstimate.php
  8. 1
    0
      app/Filament/Company/Resources/Sales/InvoiceResource/Pages/ViewInvoice.php
  9. 1
    0
      app/Filament/Company/Resources/Sales/RecurringInvoiceResource/Pages/ViewRecurringInvoice.php
  10. 5
    10
      app/Filament/Forms/Components/CreateCurrencySelect.php
  11. 48
    0
      app/Http/Controllers/DocumentPrintController.php
  12. 0
    1
      app/Models/Accounting/Bill.php
  13. 18
    0
      app/Models/Accounting/Document.php
  14. 0
    59
      app/Models/Locale/City.php
  15. 0
    11
      app/Models/Locale/Country.php
  16. 0
    172
      app/Models/Locale/Currency.php
  17. 0
    6
      app/Models/Locale/State.php
  18. 36
    0
      app/Models/Setting/Currency.php
  19. 30
    0
      app/Observers/CurrencyObserver.php
  20. 73
    0
      app/Policies/BankAccountPolicy.php
  21. 73
    0
      app/Policies/CurrencyPolicy.php
  22. 0
    28
      app/Policies/DefaultEnabledRecordPolicy.php
  23. 1
    0
      app/Providers/AppServiceProvider.php
  24. 0
    46
      app/Providers/AuthServiceProvider.php
  25. 0
    2
      app/Providers/SquireServiceProvider.php
  26. 0
    3
      app/Utilities/Currency/CurrencyConverter.php
  27. 0
    1
      bootstrap/providers.php
  28. 59
    55
      composer.lock
  29. 79
    79
      package-lock.json
  30. 3
    0
      resources/css/app.css
  31. 0
    150574
      resources/data/cities.csv
  32. 0
    159
      resources/data/currencies.csv
  33. 21
    0
      resources/js/custom-print.js
  34. 2
    2
      resources/views/components/company/document-template/container.blade.php
  35. 3
    0
      resources/views/components/company/document-template/footer.blade.php
  36. 3
    0
      resources/views/components/company/document-template/header.blade.php
  37. 3
    0
      resources/views/components/company/document-template/line-items.blade.php
  38. 1
    1
      resources/views/components/company/document-template/logo.blade.php
  39. 3
    0
      resources/views/components/company/document-template/metadata.blade.php
  40. 0
    3
      resources/views/components/company/invoice/footer.blade.php
  41. 0
    3
      resources/views/components/company/invoice/header.blade.php
  42. 0
    3
      resources/views/components/company/invoice/line-items.blade.php
  43. 0
    3
      resources/views/components/company/invoice/metadata.blade.php
  44. 0
    10
      resources/views/components/icons/decor-border-left.blade.php
  45. 0
    10
      resources/views/components/icons/decor-border-right.blade.php
  46. 12
    12
      resources/views/filament/company/components/document-templates/classic.blade.php
  47. 12
    12
      resources/views/filament/company/components/document-templates/default.blade.php
  48. 12
    12
      resources/views/filament/company/components/document-templates/modern.blade.php
  49. 1
    1
      resources/views/filament/infolists/components/document-preview.blade.php
  50. 11
    11
      resources/views/filament/infolists/components/document-templates/classic.blade.php
  51. 12
    12
      resources/views/filament/infolists/components/document-templates/default.blade.php
  52. 12
    12
      resources/views/filament/infolists/components/document-templates/modern.blade.php
  53. 75
    0
      resources/views/print-document.blade.php
  54. 6
    0
      routes/web.php
  55. 1
    0
      vite.config.js

+ 0
- 29
app/Actions/OptionAction/CreateCurrency.php View File

@@ -1,29 +0,0 @@
1
-<?php
2
-
3
-namespace App\Actions\OptionAction;
4
-
5
-use App\Models\Setting\Currency;
6
-use App\Utilities\Currency\CurrencyAccessor;
7
-
8
-class CreateCurrency
9
-{
10
-    public static function create(string $code, string $name, string $rate): Currency
11
-    {
12
-        $defaultCurrency = CurrencyAccessor::getDefaultCurrency();
13
-
14
-        $hasDefaultCurrency = $defaultCurrency !== null;
15
-        $currency = currency($code);
16
-
17
-        return Currency::create([
18
-            'name' => $name,
19
-            'code' => $code,
20
-            'rate' => $rate,
21
-            'precision' => $currency->getPrecision(),
22
-            'symbol' => $currency->getSymbol(),
23
-            'symbol_first' => $currency->isSymbolFirst(),
24
-            'decimal_mark' => $currency->getDecimalMark(),
25
-            'thousands_separator' => $currency->getThousandsSeparator(),
26
-            'enabled' => ! $hasDefaultCurrency,
27
-        ]);
28
-    }
29
-}

+ 4
- 94
app/Filament/Company/Clusters/Settings/Resources/CurrencyResource.php View File

@@ -2,29 +2,20 @@
2 2
 
3 3
 namespace App\Filament\Company\Clusters\Settings\Resources;
4 4
 
5
-use App\Concerns\ChecksForeignKeyConstraints;
6
-use App\Concerns\NotifiesOnDelete;
7 5
 use App\Facades\Forex;
8 6
 use App\Filament\Company\Clusters\Settings;
9 7
 use App\Filament\Company\Clusters\Settings\Resources\CurrencyResource\Pages;
10
-use App\Models\Accounting\Account;
11
-use App\Models\Setting\Currency;
12 8
 use App\Models\Setting\Currency as CurrencyModel;
13 9
 use App\Utilities\Currency\CurrencyAccessor;
14
-use Closure;
15 10
 use Filament\Forms;
16 11
 use Filament\Forms\Form;
17 12
 use Filament\Resources\Resource;
18 13
 use Filament\Support\Enums\FontWeight;
19 14
 use Filament\Tables;
20 15
 use Filament\Tables\Table;
21
-use Illuminate\Database\Eloquent\Collection;
22 16
 
23 17
 class CurrencyResource extends Resource
24 18
 {
25
-    use ChecksForeignKeyConstraints;
26
-    use NotifiesOnDelete;
27
-
28 19
     protected static ?string $model = CurrencyModel::class;
29 20
 
30 21
     protected static ?string $modelLabel = 'currency';
@@ -50,69 +41,25 @@ class CurrencyResource extends Resource
50 41
                             ->live()
51 42
                             ->required()
52 43
                             ->localizeLabel()
44
+                            ->disabledOn('edit')
53 45
                             ->afterStateUpdated(static function (Forms\Set $set, $state) {
54
-                                $fields = ['name', 'precision', 'symbol', 'symbol_first', 'decimal_mark', 'thousands_separator'];
55
-
56
-                                if ($state === null) {
57
-                                    array_walk($fields, static fn ($field) => $set($field, null));
58
-
46
+                                if (! $state) {
59 47
                                     return;
60 48
                                 }
61 49
 
62
-                                $currencyDetails = CurrencyAccessor::getAllCurrencies()[$state] ?? [];
63 50
                                 $defaultCurrencyCode = CurrencyAccessor::getDefaultCurrency();
64 51
                                 $exchangeRate = Forex::getCachedExchangeRate($defaultCurrencyCode, $state);
65 52
 
66 53
                                 if ($exchangeRate !== null) {
67 54
                                     $set('rate', $exchangeRate);
68 55
                                 }
69
-
70
-                                array_walk($fields, static fn ($field) => $set($field, $currencyDetails[$field] ?? null));
71 56
                             }),
72
-                        Forms\Components\TextInput::make('name')
73
-                            ->localizeLabel()
74
-                            ->maxLength(50)
75
-                            ->required(),
76 57
                         Forms\Components\TextInput::make('rate')
77 58
                             ->numeric()
78 59
                             ->rule('gt:0')
79 60
                             ->live()
80 61
                             ->localizeLabel()
81 62
                             ->required(),
82
-                        Forms\Components\Select::make('precision')
83
-                            ->localizeLabel()
84
-                            ->options(['0', '1', '2', '3', '4'])
85
-                            ->required(),
86
-                        Forms\Components\TextInput::make('symbol')
87
-                            ->localizeLabel()
88
-                            ->maxLength(5)
89
-                            ->required(),
90
-                        Forms\Components\Select::make('symbol_first')
91
-                            ->localizeLabel('Symbol position')
92
-                            ->boolean(translate('Before amount'), translate('After amount'), translate('Select a symbol position'))
93
-                            ->required(),
94
-                        Forms\Components\TextInput::make('decimal_mark')
95
-                            ->localizeLabel('Decimal separator')
96
-                            ->maxLength(1)
97
-                            ->rule(static function (Forms\Get $get): Closure {
98
-                                return static function ($attribute, $value, Closure $fail) use ($get) {
99
-                                    if ($value === $get('thousands_separator')) {
100
-                                        $fail(translate('Separators must be unique.'));
101
-                                    }
102
-                                };
103
-                            })
104
-                            ->required(),
105
-                        Forms\Components\TextInput::make('thousands_separator')
106
-                            ->localizeLabel()
107
-                            ->maxLength(1)
108
-                            ->rule(static function (Forms\Get $get): Closure {
109
-                                return static function ($attribute, $value, Closure $fail) use ($get) {
110
-                                    if ($value === $get('decimal_mark')) {
111
-                                        $fail(translate('Separators must be unique.'));
112
-                                    }
113
-                                };
114
-                            })
115
-                            ->nullable(),
116 63
                     ])->columns(),
117 64
             ]);
118 65
     }
@@ -153,47 +100,10 @@ class CurrencyResource extends Resource
153 100
             ])
154 101
             ->actions([
155 102
                 Tables\Actions\EditAction::make(),
156
-                Tables\Actions\DeleteAction::make()
157
-                    ->before(function (Tables\Actions\DeleteAction $action, Currency $record) {
158
-                        $modelsToCheck = [
159
-                            Account::class,
160
-                        ];
161
-
162
-                        $isUsed = self::isForeignKeyUsed('currency_code', $record->code, $modelsToCheck);
163
-
164
-                        if ($isUsed) {
165
-                            $reason = 'in use';
166
-                            self::notifyBeforeDelete($record, $reason);
167
-                            $action->cancel();
168
-                        }
169
-                    }),
170 103
             ])
171 104
             ->bulkActions([
172
-                Tables\Actions\BulkActionGroup::make([
173
-                    Tables\Actions\DeleteBulkAction::make()
174
-                        ->before(static function (Tables\Actions\DeleteBulkAction $action, Collection $records) {
175
-                            foreach ($records as $record) {
176
-                                $modelsToCheck = [
177
-                                    Account::class,
178
-                                ];
179
-
180
-                                $isUsed = self::isForeignKeyUsed('currency_code', $record->code, $modelsToCheck);
181
-
182
-                                if ($isUsed) {
183
-                                    $reason = 'in use';
184
-                                    self::notifyBeforeDelete($record, $reason);
185
-                                    $action->cancel();
186
-                                }
187
-                            }
188
-                        })
189
-                        ->hidden(function (Table $table) {
190
-                            return $table->getAllSelectableRecordsCount() === 0;
191
-                        }),
192
-                ]),
193
-            ])
194
-            ->checkIfRecordIsSelectableUsing(static function (CurrencyModel $record) {
195
-                return $record->isDisabled();
196
-            });
105
+                //
106
+            ]);
197 107
     }
198 108
 
199 109
     public static function getPages(): array

+ 3
- 5
app/Filament/Company/Clusters/Settings/Resources/CurrencyResource/Pages/CreateCurrency.php View File

@@ -2,15 +2,13 @@
2 2
 
3 3
 namespace App\Filament\Company\Clusters\Settings\Resources\CurrencyResource\Pages;
4 4
 
5
+use App\Concerns\RedirectToListPage;
5 6
 use App\Filament\Company\Clusters\Settings\Resources\CurrencyResource;
6 7
 use Filament\Resources\Pages\CreateRecord;
7 8
 
8 9
 class CreateCurrency extends CreateRecord
9 10
 {
10
-    protected static string $resource = CurrencyResource::class;
11
+    use RedirectToListPage;
11 12
 
12
-    protected function getRedirectUrl(): string
13
-    {
14
-        return $this->getResource()::getUrl('index');
15
-    }
13
+    protected static string $resource = CurrencyResource::class;
16 14
 }

+ 4
- 7
app/Filament/Company/Clusters/Settings/Resources/CurrencyResource/Pages/EditCurrency.php View File

@@ -2,23 +2,20 @@
2 2
 
3 3
 namespace App\Filament\Company\Clusters\Settings\Resources\CurrencyResource\Pages;
4 4
 
5
+use App\Concerns\RedirectToListPage;
5 6
 use App\Filament\Company\Clusters\Settings\Resources\CurrencyResource;
6
-use Filament\Actions;
7 7
 use Filament\Resources\Pages\EditRecord;
8 8
 
9 9
 class EditCurrency extends EditRecord
10 10
 {
11
+    use RedirectToListPage;
12
+
11 13
     protected static string $resource = CurrencyResource::class;
12 14
 
13 15
     protected function getHeaderActions(): array
14 16
     {
15 17
         return [
16
-            Actions\DeleteAction::make(),
18
+            //
17 19
         ];
18 20
     }
19
-
20
-    protected function getRedirectUrl(): string
21
-    {
22
-        return $this->getResource()::getUrl('index');
23
-    }
24 21
 }

+ 3
- 3
app/Filament/Company/Clusters/Settings/Resources/DocumentDefaultResource.php View File

@@ -130,17 +130,17 @@ class DocumentDefaultResource extends Resource
130 130
                             ->columnSpan(2)
131 131
                             ->hiddenLabel()
132 132
                             ->visible(static fn (Get $get) => $get('template') === 'default')
133
-                            ->view('filament.company.components.invoice-layouts.default'),
133
+                            ->view('filament.company.components.document-templates.default'),
134 134
                         Forms\Components\ViewField::make('preview.modern')
135 135
                             ->columnSpan(2)
136 136
                             ->hiddenLabel()
137 137
                             ->visible(static fn (Get $get) => $get('template') === 'modern')
138
-                            ->view('filament.company.components.invoice-layouts.modern'),
138
+                            ->view('filament.company.components.document-templates.modern'),
139 139
                         Forms\Components\ViewField::make('preview.classic')
140 140
                             ->columnSpan(2)
141 141
                             ->hiddenLabel()
142 142
                             ->visible(static fn (Get $get) => $get('template') === 'classic')
143
-                            ->view('filament.company.components.invoice-layouts.classic'),
143
+                            ->view('filament.company.components.document-templates.classic'),
144 144
                     ])->columnSpan(2),
145 145
             ])->columns(3);
146 146
     }

+ 16
- 7
app/Filament/Company/Resources/Purchases/BillResource.php View File

@@ -44,6 +44,8 @@ class BillResource extends Resource
44 44
     {
45 45
         $company = Auth::user()->currentCompany;
46 46
 
47
+        $settings = $company->defaultBill;
48
+
47 49
         return $form
48 50
             ->schema([
49 51
                 Forms\Components\Section::make('Bill Details')
@@ -108,22 +110,29 @@ class BillResource extends Resource
108 110
                             ->relationship()
109 111
                             ->saveRelationshipsUsing(null)
110 112
                             ->dehydrated(true)
111
-                            ->headers(function (Forms\Get $get) {
113
+                            ->headers(function (Forms\Get $get) use ($settings) {
112 114
                                 $hasDiscounts = DocumentDiscountMethod::parse($get('discount_method'))->isPerLineItem();
113 115
 
114 116
                                 $headers = [
115
-                                    Header::make('Items')->width($hasDiscounts ? '15%' : '20%'),
116
-                                    Header::make('Description')->width($hasDiscounts ? '25%' : '30%'),  // Increase when no discounts
117
-                                    Header::make('Quantity')->width('10%'),
118
-                                    Header::make('Price')->width('10%'),
119
-                                    Header::make('Taxes')->width($hasDiscounts ? '15%' : '20%'),       // Increase when no discounts
117
+                                    Header::make($settings->resolveColumnLabel('item_name', 'Items'))
118
+                                        ->width($hasDiscounts ? '15%' : '20%'),
119
+                                    Header::make('Description')
120
+                                        ->width($hasDiscounts ? '25%' : '30%'),
121
+                                    Header::make($settings->resolveColumnLabel('unit_name', 'Quantity'))
122
+                                        ->width('10%'),
123
+                                    Header::make($settings->resolveColumnLabel('price_name', 'Price'))
124
+                                        ->width('10%'),
125
+                                    Header::make('Taxes')
126
+                                        ->width($hasDiscounts ? '15%' : '20%'),
120 127
                                 ];
121 128
 
122 129
                                 if ($hasDiscounts) {
123 130
                                     $headers[] = Header::make('Discounts')->width('15%');
124 131
                                 }
125 132
 
126
-                                $headers[] = Header::make('Amount')->width('10%')->align('right');
133
+                                $headers[] = Header::make($settings->resolveColumnLabel('amount_name', 'Amount'))
134
+                                    ->width('10%')
135
+                                    ->align('right');
127 136
 
128 137
                                 return $headers;
129 138
                             })

+ 1
- 0
app/Filament/Company/Resources/Sales/EstimateResource/Pages/ViewEstimate.php View File

@@ -43,6 +43,7 @@ class ViewEstimate extends ViewRecord
43 43
                     Estimate::getMarkAsSentAction(),
44 44
                     Estimate::getMarkAsAcceptedAction(),
45 45
                     Estimate::getMarkAsDeclinedAction(),
46
+                    Estimate::getPrintDocumentAction(),
46 47
                     Estimate::getReplicateAction(),
47 48
                     Estimate::getConvertToInvoiceAction(),
48 49
                 ])->dropdown(false),

+ 1
- 0
app/Filament/Company/Resources/Sales/InvoiceResource/Pages/ViewInvoice.php View File

@@ -41,6 +41,7 @@ class ViewInvoice extends ViewRecord
41 41
                 Actions\ActionGroup::make([
42 42
                     Invoice::getApproveDraftAction(),
43 43
                     Invoice::getMarkAsSentAction(),
44
+                    Invoice::getPrintDocumentAction(),
44 45
                     Invoice::getReplicateAction(),
45 46
                 ])->dropdown(false),
46 47
                 Actions\DeleteAction::make(),

+ 1
- 0
app/Filament/Company/Resources/Sales/RecurringInvoiceResource/Pages/ViewRecurringInvoice.php View File

@@ -41,6 +41,7 @@ class ViewRecurringInvoice extends ViewRecord
41 41
                 Actions\ActionGroup::make([
42 42
                     RecurringInvoice::getManageScheduleAction(),
43 43
                     RecurringInvoice::getApproveDraftAction(),
44
+                    RecurringInvoice::getPrintDocumentAction(),
44 45
                 ])->dropdown(false),
45 46
                 Actions\DeleteAction::make(),
46 47
             ])

+ 5
- 10
app/Filament/Forms/Components/CreateCurrencySelect.php View File

@@ -2,7 +2,7 @@
2 2
 
3 3
 namespace App\Filament\Forms\Components;
4 4
 
5
-use App\Actions\OptionAction\CreateCurrency;
5
+use App\Models\Setting\Currency;
6 6
 use App\Utilities\Currency\CurrencyAccessor;
7 7
 use App\Utilities\Currency\CurrencyConverter;
8 8
 use Filament\Forms\Components\Actions\Action;
@@ -31,11 +31,10 @@ class CreateCurrencySelect extends Select
31 31
 
32 32
         $this->createOptionUsing(static function (array $data) {
33 33
             return DB::transaction(static function () use ($data) {
34
-                $currency = CreateCurrency::create(
35
-                    $data['code'],
36
-                    $data['name'],
37
-                    $data['rate']
38
-                );
34
+                $currency = Currency::create([
35
+                    'code' => $data['code'],
36
+                    'rate' => $data['rate'],
37
+                ]);
39 38
 
40 39
                 return $currency->code;
41 40
             });
@@ -54,10 +53,6 @@ class CreateCurrencySelect extends Select
54 53
                     CurrencyConverter::handleCurrencyChange($set, $state);
55 54
                 })
56 55
                 ->required(),
57
-            TextInput::make('name')
58
-                ->localizeLabel()
59
-                ->maxLength(100)
60
-                ->required(),
61 56
             TextInput::make('rate')
62 57
                 ->localizeLabel()
63 58
                 ->numeric()

+ 48
- 0
app/Http/Controllers/DocumentPrintController.php View File

@@ -0,0 +1,48 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers;
4
+
5
+use App\DTO\DocumentDTO;
6
+use App\Enums\Accounting\DocumentType;
7
+use App\Enums\Setting\Template;
8
+use App\Models\Accounting\Estimate;
9
+use App\Models\Accounting\Invoice;
10
+use App\Models\Accounting\RecurringInvoice;
11
+use App\Models\Setting\DocumentDefault;
12
+use Illuminate\Http\Request;
13
+
14
+class DocumentPrintController extends Controller
15
+{
16
+    protected array $documentModels = [
17
+        'invoice' => Invoice::class,
18
+        'recurring_invoice' => RecurringInvoice::class,
19
+        'estimate' => Estimate::class,
20
+    ];
21
+
22
+    public function show(Request $request, string $documentType, int $id)
23
+    {
24
+        if (! isset($this->documentModels[$documentType])) {
25
+            abort(404, "Invalid document type: {$documentType}");
26
+        }
27
+
28
+        $modelClass = $this->documentModels[$documentType];
29
+        $document = $modelClass::findOrFail($id);
30
+        $documentTypeEnum = $document::documentType();
31
+
32
+        if ($documentTypeEnum === DocumentType::RecurringInvoice) {
33
+            $documentTypeEnum = DocumentType::Invoice;
34
+        }
35
+
36
+        $defaults = DocumentDefault::query()
37
+            ->type($documentTypeEnum)
38
+            ->first();
39
+
40
+        $template = $defaults?->template ?? Template::Default;
41
+        $document = DocumentDTO::fromModel($document);
42
+
43
+        return view('print-document', [
44
+            'document' => $document,
45
+            'template' => $template,
46
+        ]);
47
+    }
48
+}

+ 0
- 1
app/Models/Accounting/Bill.php View File

@@ -15,7 +15,6 @@ use App\Filament\Company\Resources\Purchases\BillResource;
15 15
 use App\Models\Banking\BankAccount;
16 16
 use App\Models\Common\Vendor;
17 17
 use App\Models\Company;
18
-use App\Models\Setting\Currency;
19 18
 use App\Models\Setting\DocumentDefault;
20 19
 use App\Observers\BillObserver;
21 20
 use App\Utilities\Currency\CurrencyAccessor;

+ 18
- 0
app/Models/Accounting/Document.php View File

@@ -6,10 +6,13 @@ use App\Concerns\Blamable;
6 6
 use App\Concerns\CompanyOwned;
7 7
 use App\Enums\Accounting\DocumentType;
8 8
 use App\Models\Setting\Currency;
9
+use Filament\Actions\Action;
10
+use Filament\Actions\MountableAction;
9 11
 use Illuminate\Database\Eloquent\Factories\HasFactory;
10 12
 use Illuminate\Database\Eloquent\Model;
11 13
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
12 14
 use Illuminate\Database\Eloquent\Relations\MorphMany;
15
+use Livewire\Component;
13 16
 
14 17
 abstract class Document extends Model
15 18
 {
@@ -32,6 +35,21 @@ abstract class Document extends Model
32 35
         return $this->lineItems()->exists();
33 36
     }
34 37
 
38
+    public static function getPrintDocumentAction(string $action = Action::class): MountableAction
39
+    {
40
+        return $action::make('printPdf')
41
+            ->label('Print')
42
+            ->icon('heroicon-m-printer')
43
+            ->action(function (self $record, Component $livewire) {
44
+                $url = route('documents.print', [
45
+                    'documentType' => $record::documentType(),
46
+                    'id' => $record->id,
47
+                ]);
48
+
49
+                $livewire->js("window.printPdf('{$url}')");
50
+            });
51
+    }
52
+
35 53
     abstract public static function documentType(): DocumentType;
36 54
 
37 55
     abstract public function documentNumber(): ?string;

+ 0
- 59
app/Models/Locale/City.php View File

@@ -1,59 +0,0 @@
1
-<?php
2
-
3
-namespace App\Models\Locale;
4
-
5
-use Illuminate\Database\Eloquent\Relations\BelongsTo;
6
-use Illuminate\Support\Collection;
7
-use Squire\Model;
8
-
9
-/**
10
- * @property int $id
11
- * @property string $name
12
- * @property int $state_id
13
- * @property string $state_code
14
- * @property string $country_id
15
- * @property float $latitude
16
- * @property float $longitude
17
- */
18
-class City extends Model
19
-{
20
-    public static array $schema = [
21
-        'id' => 'integer',
22
-        'name' => 'string',
23
-        'state_id' => 'integer',
24
-        'state_code' => 'string',
25
-        'country_id' => 'string',
26
-        'latitude' => 'float',
27
-        'longitude' => 'float',
28
-    ];
29
-
30
-    public static function getCitiesByCountryAndState(?string $countryCode, ?string $stateId): Collection
31
-    {
32
-        if ($stateId === null || $countryCode === null) {
33
-            return collect();
34
-        }
35
-
36
-        return self::query()->where('country_id', $countryCode)
37
-            ->where('state_id', $stateId)
38
-            ->get();
39
-    }
40
-
41
-    public static function getCityOptions(?string $countryCode = null, ?string $stateId = null): Collection
42
-    {
43
-        if ($countryCode === null || $stateId === null) {
44
-            return collect();
45
-        }
46
-
47
-        return self::getCitiesByCountryAndState($countryCode, $stateId)->pluck('name', 'id');
48
-    }
49
-
50
-    public function state(): BelongsTo
51
-    {
52
-        return $this->belongsTo(State::class, 'state_id', 'id');
53
-    }
54
-
55
-    public function country(): BelongsTo
56
-    {
57
-        return $this->belongsTo(Country::class, 'country_id', 'id');
58
-    }
59
-}

+ 0
- 11
app/Models/Locale/Country.php View File

@@ -4,7 +4,6 @@ namespace App\Models\Locale;
4 4
 
5 5
 use App\Models\Common\Address;
6 6
 use Illuminate\Database\Eloquent\Casts\Attribute;
7
-use Illuminate\Database\Eloquent\Relations\BelongsTo;
8 7
 use Illuminate\Database\Eloquent\Relations\HasMany;
9 8
 use Illuminate\Support\Collection;
10 9
 use Squire\Model;
@@ -44,11 +43,6 @@ class Country extends Model
44 43
         'flag' => 'string',
45 44
     ];
46 45
 
47
-    public function currency(): BelongsTo
48
-    {
49
-        return $this->belongsTo(Currency::class, 'currency_code', 'code');
50
-    }
51
-
52 46
     public function addresses(): HasMany
53 47
     {
54 48
         return $this->hasMany(Address::class, 'country_code', 'id');
@@ -59,11 +53,6 @@ class Country extends Model
59 53
         return $this->hasMany(State::class, 'country_id', 'id');
60 54
     }
61 55
 
62
-    public function cities(): HasMany
63
-    {
64
-        return $this->hasMany(City::class, 'country_id', 'id');
65
-    }
66
-
67 56
     protected function name(): Attribute
68 57
     {
69 58
         return Attribute::get(static function (mixed $value, array $attributes): string {

+ 0
- 172
app/Models/Locale/Currency.php View File

@@ -1,172 +0,0 @@
1
-<?php
2
-
3
-namespace App\Models\Locale;
4
-
5
-use Illuminate\Database\Eloquent\Model;
6
-use Illuminate\Database\Eloquent\Relations\HasMany;
7
-use Illuminate\Support\Collection;
8
-use Illuminate\Support\Facades\Cache;
9
-
10
-class Currency extends Model
11
-{
12
-    protected $table = 'currencies';
13
-
14
-    protected $guarded = [];
15
-
16
-    protected $casts = [
17
-        'code' => 'string',
18
-        'name' => 'string',
19
-        'symbol' => 'string',
20
-        'precision' => 'int',
21
-        'decimal_mark' => 'string',
22
-        'thousands_separator' => 'string',
23
-        'symbol_first' => 'bool',
24
-        'subunit' => 'int',
25
-    ];
26
-
27
-    public function countries(): HasMany
28
-    {
29
-        return $this->hasMany(Country::class, 'currency_code', 'code');
30
-    }
31
-
32
-    public static function allCached(): Collection
33
-    {
34
-        return collect(Cache::get('currencies') ?? []);
35
-    }
36
-
37
-    // To find a currency by its code
38
-    public static function findByCode(string $code): ?self
39
-    {
40
-        return self::allCached()->firstWhere('code', $code);
41
-    }
42
-
43
-    // To find a currency by its name
44
-    public static function findByName(string $name): ?self
45
-    {
46
-        return self::allCached()->firstWhere('name', $name);
47
-    }
48
-
49
-    // Get currency name by its code
50
-    public static function getNameByCode(string $code): ?string
51
-    {
52
-        $currency = self::findByCode($code);
53
-
54
-        return $currency->name ?? null;
55
-    }
56
-
57
-    // Get currency code by its name
58
-    public static function getCodeByName(string $name): ?string
59
-    {
60
-        $currency = self::findByName($name);
61
-
62
-        return $currency->code ?? null;
63
-    }
64
-
65
-    // Get currency symbol by its code
66
-    public static function getSymbolByCode(string $code): ?string
67
-    {
68
-        $currency = self::findByCode($code);
69
-
70
-        return $currency->symbol ?? null;
71
-    }
72
-
73
-    // Get currency symbol by its name
74
-    public static function getSymbolByName(string $name): ?string
75
-    {
76
-        $currency = self::findByName($name);
77
-
78
-        return $currency->symbol ?? null;
79
-    }
80
-
81
-    // Get currency precision by its code
82
-    public static function getPrecisionByCode(string $code): ?int
83
-    {
84
-        $currency = self::findByCode($code);
85
-
86
-        return $currency->precision ?? null;
87
-    }
88
-
89
-    // Get currency precision by its name
90
-    public static function getPrecisionByName(string $name): ?int
91
-    {
92
-        $currency = self::findByName($name);
93
-
94
-        return $currency->precision ?? null;
95
-    }
96
-
97
-    // Get currency decimal mark by its code
98
-    public static function getDecimalMarkByCode(string $code): ?string
99
-    {
100
-        $currency = self::findByCode($code);
101
-
102
-        return $currency->decimal_mark ?? null;
103
-    }
104
-
105
-    // Get currency decimal mark by its name
106
-    public static function getDecimalMarkByName(string $name): ?string
107
-    {
108
-        $currency = self::findByName($name);
109
-
110
-        return $currency->decimal_mark ?? null;
111
-    }
112
-
113
-    // Get currency thousands separator by its code
114
-    public static function getThousandsSeparatorByCode(string $code): ?string
115
-    {
116
-        $currency = self::findByCode($code);
117
-
118
-        return $currency->thousands_separator ?? null;
119
-    }
120
-
121
-    // Get currency thousands separator by its name
122
-    public static function getThousandsSeparatorByName(string $name): ?string
123
-    {
124
-        $currency = self::findByName($name);
125
-
126
-        return $currency->thousands_separator ?? null;
127
-    }
128
-
129
-    // Get currency symbol first by its code
130
-    public static function getSymbolFirstByCode(string $code): ?bool
131
-    {
132
-        $currency = self::findByCode($code);
133
-
134
-        return $currency->symbol_first ?? null;
135
-    }
136
-
137
-    // Get currency symbol first by its name
138
-    public static function getSymbolFirstByName(string $name): ?bool
139
-    {
140
-        $currency = self::findByName($name);
141
-
142
-        return $currency->symbol_first ?? null;
143
-    }
144
-
145
-    // Get currency subunit by its code
146
-    public static function getSubunitByCode(string $code): ?int
147
-    {
148
-        $currency = self::findByCode($code);
149
-
150
-        return $currency->subunit ?? null;
151
-    }
152
-
153
-    // Get currency subunit by its name
154
-    public static function getSubunitByName(string $name): ?int
155
-    {
156
-        $currency = self::findByName($name);
157
-
158
-        return $currency->subunit ?? null;
159
-    }
160
-
161
-    // Get all currency codes
162
-    public static function getAllCodes(): Collection
163
-    {
164
-        return self::allCached()->pluck('code');
165
-    }
166
-
167
-    // Get all currency names
168
-    public static function getAllNames(): Collection
169
-    {
170
-        return self::allCached()->pluck('name');
171
-    }
172
-}

+ 0
- 6
app/Models/Locale/State.php View File

@@ -3,7 +3,6 @@
3 3
 namespace App\Models\Locale;
4 4
 
5 5
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
6
-use Illuminate\Database\Eloquent\Relations\HasMany;
7 6
 use Squire\Model;
8 7
 
9 8
 /**
@@ -71,9 +70,4 @@ class State extends Model
71 70
     {
72 71
         return $this->belongsTo(Country::class, 'country_id', 'id');
73 72
     }
74
-
75
-    public function cities(): HasMany
76
-    {
77
-        return $this->hasMany(City::class, 'state_id', 'id');
78
-    }
79 73
 }

+ 36
- 0
app/Models/Setting/Currency.php View File

@@ -9,6 +9,12 @@ use App\Concerns\HasDefault;
9 9
 use App\Concerns\SyncsWithCompanyDefaults;
10 10
 use App\Facades\Forex;
11 11
 use App\Models\Accounting\Account;
12
+use App\Models\Accounting\Bill;
13
+use App\Models\Accounting\Estimate;
14
+use App\Models\Accounting\Invoice;
15
+use App\Models\Accounting\RecurringInvoice;
16
+use App\Models\Common\Client;
17
+use App\Models\Common\Vendor;
12 18
 use App\Observers\CurrencyObserver;
13 19
 use App\Utilities\Currency\CurrencyAccessor;
14 20
 use Database\Factories\Setting\CurrencyFactory;
@@ -80,6 +86,36 @@ class Currency extends Model
80 86
         return $this->hasMany(Account::class, 'currency_code', 'code');
81 87
     }
82 88
 
89
+    public function bills(): HasMany
90
+    {
91
+        return $this->hasMany(Bill::class, 'currency_code', 'code');
92
+    }
93
+
94
+    public function clients(): HasMany
95
+    {
96
+        return $this->hasMany(Client::class, 'currency_code', 'code');
97
+    }
98
+
99
+    public function estimates(): HasMany
100
+    {
101
+        return $this->hasMany(Estimate::class, 'currency_code', 'code');
102
+    }
103
+
104
+    public function invoices(): HasMany
105
+    {
106
+        return $this->hasMany(Invoice::class, 'currency_code', 'code');
107
+    }
108
+
109
+    public function recurringInvoices(): HasMany
110
+    {
111
+        return $this->hasMany(RecurringInvoice::class, 'currency_code', 'code');
112
+    }
113
+
114
+    public function vendors(): HasMany
115
+    {
116
+        return $this->hasMany(Vendor::class, 'currency_code', 'code');
117
+    }
118
+
83 119
     protected static function newFactory(): Factory
84 120
     {
85 121
         return CurrencyFactory::new();

+ 30
- 0
app/Observers/CurrencyObserver.php View File

@@ -5,9 +5,15 @@ namespace App\Observers;
5 5
 use App\Events\CurrencyRateChanged;
6 6
 use App\Events\DefaultCurrencyChanged;
7 7
 use App\Models\Setting\Currency;
8
+use App\Utilities\Currency\CurrencyAccessor;
8 9
 
9 10
 class CurrencyObserver
10 11
 {
12
+    public function creating(Currency $currency): void
13
+    {
14
+        $this->setStandardCurrencyAttributes($currency);
15
+    }
16
+
11 17
     /**
12 18
      * Handle the Currency "updated" event.
13 19
      */
@@ -21,4 +27,28 @@ class CurrencyObserver
21 27
             event(new CurrencyRateChanged($currency, $currency->getOriginal('rate'), $currency->rate));
22 28
         }
23 29
     }
30
+
31
+    protected function setStandardCurrencyAttributes(Currency $currency): void
32
+    {
33
+        if (empty($currency->code)) {
34
+            return;
35
+        }
36
+
37
+        $defaultCurrency = CurrencyAccessor::getDefaultCurrency();
38
+
39
+        $hasDefaultCurrency = $defaultCurrency !== null;
40
+
41
+        $originalRate = $currency->rate;
42
+
43
+        $currencyAttributes = Currency::factory()
44
+            ->forCurrency($currency->code)
45
+            ->make([
46
+                'enabled' => ! $hasDefaultCurrency,
47
+            ])
48
+            ->getAttributes();
49
+
50
+        $currencyAttributes['rate'] = $originalRate;
51
+
52
+        $currency->fill($currencyAttributes);
53
+    }
24 54
 }

+ 73
- 0
app/Policies/BankAccountPolicy.php View File

@@ -0,0 +1,73 @@
1
+<?php
2
+
3
+namespace App\Policies;
4
+
5
+use App\Models\Banking\BankAccount;
6
+use App\Models\User;
7
+use Illuminate\Auth\Access\HandlesAuthorization;
8
+
9
+class BankAccountPolicy
10
+{
11
+    use HandlesAuthorization;
12
+
13
+    /**
14
+     * Determine whether the user can view any models.
15
+     */
16
+    public function viewAny(User $user): bool
17
+    {
18
+        return true;
19
+    }
20
+
21
+    /**
22
+     * Determine whether the user can view the model.
23
+     */
24
+    public function view(User $user, BankAccount $bankAccount): bool
25
+    {
26
+        return true;
27
+    }
28
+
29
+    /**
30
+     * Determine whether the user can create models.
31
+     */
32
+    public function create(User $user): bool
33
+    {
34
+        return true;
35
+    }
36
+
37
+    /**
38
+     * Determine whether the user can update the model.
39
+     */
40
+    public function update(User $user, BankAccount $bankAccount): bool
41
+    {
42
+        return true;
43
+    }
44
+
45
+    /**
46
+     * Determine whether the user can delete the model.
47
+     */
48
+    public function delete(User $user, BankAccount $bankAccount): bool
49
+    {
50
+        return $bankAccount->isDisabled();
51
+    }
52
+
53
+    public function deleteAny(User $user): bool
54
+    {
55
+        return true;
56
+    }
57
+
58
+    /**
59
+     * Determine whether the user can restore the model.
60
+     */
61
+    public function restore(User $user, BankAccount $bankAccount): bool
62
+    {
63
+        return false;
64
+    }
65
+
66
+    /**
67
+     * Determine whether the user can permanently delete the model.
68
+     */
69
+    public function forceDelete(User $user, BankAccount $bankAccount): bool
70
+    {
71
+        return false;
72
+    }
73
+}

+ 73
- 0
app/Policies/CurrencyPolicy.php View File

@@ -0,0 +1,73 @@
1
+<?php
2
+
3
+namespace App\Policies;
4
+
5
+use App\Models\Setting\Currency;
6
+use App\Models\User;
7
+use Illuminate\Auth\Access\HandlesAuthorization;
8
+
9
+class CurrencyPolicy
10
+{
11
+    use HandlesAuthorization;
12
+
13
+    /**
14
+     * Determine whether the user can view any models.
15
+     */
16
+    public function viewAny(User $user): bool
17
+    {
18
+        return true;
19
+    }
20
+
21
+    /**
22
+     * Determine whether the user can view the model.
23
+     */
24
+    public function view(User $user, Currency $currency): bool
25
+    {
26
+        return true;
27
+    }
28
+
29
+    /**
30
+     * Determine whether the user can create models.
31
+     */
32
+    public function create(User $user): bool
33
+    {
34
+        return true;
35
+    }
36
+
37
+    /**
38
+     * Determine whether the user can update the model.
39
+     */
40
+    public function update(User $user, Currency $currency): bool
41
+    {
42
+        return $currency->isDisabled();
43
+    }
44
+
45
+    /**
46
+     * Determine whether the user can delete the model.
47
+     */
48
+    public function delete(User $user, Currency $currency): bool
49
+    {
50
+        return false;
51
+    }
52
+
53
+    public function deleteAny(User $user): bool
54
+    {
55
+        return false;
56
+    }
57
+
58
+    /**
59
+     * Determine whether the user can restore the model.
60
+     */
61
+    public function restore(User $user, Currency $currency): bool
62
+    {
63
+        return false;
64
+    }
65
+
66
+    /**
67
+     * Determine whether the user can permanently delete the model.
68
+     */
69
+    public function forceDelete(User $user, Currency $currency): bool
70
+    {
71
+        return false;
72
+    }
73
+}

+ 0
- 28
app/Policies/DefaultEnabledRecordPolicy.php View File

@@ -1,28 +0,0 @@
1
-<?php
2
-
3
-namespace App\Policies;
4
-
5
-use App\Concerns\SyncsWithCompanyDefaults;
6
-use App\Models\User;
7
-use Illuminate\Database\Eloquent\Model;
8
-
9
-class DefaultEnabledRecordPolicy
10
-{
11
-    /**
12
-     * Create a new policy instance.
13
-     */
14
-    public function __construct()
15
-    {
16
-        //
17
-    }
18
-
19
-    /**
20
-     * Determine whether the company can delete the existing record.
21
-     */
22
-    public function delete(User $user, Model $model): bool
23
-    {
24
-        $hasEnabledRecord = in_array(SyncsWithCompanyDefaults::class, class_uses_recursive($model), true);
25
-
26
-        return ! ($hasEnabledRecord && $model->getAttribute('enabled') === true);
27
-    }
28
-}

+ 1
- 0
app/Providers/AppServiceProvider.php View File

@@ -32,6 +32,7 @@ class AppServiceProvider extends ServiceProvider
32 32
         FilamentAsset::register([
33 33
             Js::make('top-navigation', __DIR__ . '/../../resources/js/top-navigation.js'),
34 34
             Js::make('history-fix', __DIR__ . '/../../resources/js/history-fix.js'),
35
+            Js::make('custom-print', __DIR__ . '/../../resources/js/custom-print.js'),
35 36
         ]);
36 37
     }
37 38
 }

+ 0
- 46
app/Providers/AuthServiceProvider.php View File

@@ -1,46 +0,0 @@
1
-<?php
2
-
3
-namespace App\Providers;
4
-
5
-use App\Models\Banking;
6
-use App\Models\Setting;
7
-use App\Policies\DefaultEnabledRecordPolicy;
8
-use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
9
-use Illuminate\Support\Facades\Gate;
10
-
11
-class AuthServiceProvider extends ServiceProvider
12
-{
13
-    /**
14
-     * The model to policy mappings for the application.
15
-     *
16
-     * @var array<class-string, class-string>
17
-     */
18
-    protected $policies = [
19
-        //
20
-    ];
21
-
22
-    /**
23
-     * Register any authentication / authorization services.
24
-     */
25
-    public function boot(): void
26
-    {
27
-        $this->registerPolicies();
28
-
29
-        $this->registerEnabledRecordPolicy();
30
-    }
31
-
32
-    /**
33
-     * Register the policy for the enabled record.
34
-     */
35
-    protected function registerEnabledRecordPolicy(): void
36
-    {
37
-        $models = [
38
-            Setting\Currency::class,
39
-            Banking\BankAccount::class,
40
-        ];
41
-
42
-        foreach ($models as $model) {
43
-            Gate::policy($model, DefaultEnabledRecordPolicy::class);
44
-        }
45
-    }
46
-}

+ 0
- 2
app/Providers/SquireServiceProvider.php View File

@@ -2,7 +2,6 @@
2 2
 
3 3
 namespace App\Providers;
4 4
 
5
-use App\Models\Locale\City;
6 5
 use App\Models\Locale\Country;
7 6
 use App\Models\Locale\State;
8 7
 use Illuminate\Support\ServiceProvider;
@@ -16,6 +15,5 @@ class SquireServiceProvider extends ServiceProvider
16 15
     {
17 16
         Repository::registerSource(Country::class, 'en', resource_path('data/countries.csv'));
18 17
         Repository::registerSource(State::class, 'en', resource_path('data/states.csv'));
19
-        Repository::registerSource(City::class, 'en', resource_path('data/cities.csv'));
20 18
     }
21 19
 }

+ 0
- 3
app/Utilities/Currency/CurrencyConverter.php View File

@@ -101,13 +101,10 @@ class CurrencyConverter
101 101
 
102 102
     public static function handleCurrencyChange(Set $set, $state): void
103 103
     {
104
-        $currency = currency($state);
105 104
         $defaultCurrencyCode = CurrencyAccessor::getDefaultCurrency();
106 105
         $forexEnabled = Forex::isEnabled();
107 106
         $exchangeRate = $forexEnabled ? Forex::getCachedExchangeRate($defaultCurrencyCode, $state) : null;
108 107
 
109
-        $set('name', $currency->getName() ?? '');
110
-
111 108
         if ($forexEnabled && $exchangeRate !== null) {
112 109
             $set('rate', $exchangeRate);
113 110
         }

+ 0
- 1
bootstrap/providers.php View File

@@ -2,7 +2,6 @@
2 2
 
3 3
 return [
4 4
     App\Providers\AppServiceProvider::class,
5
-    App\Providers\AuthServiceProvider::class,
6 5
     App\Providers\Filament\CompanyPanelProvider::class,
7 6
     App\Providers\Filament\UserPanelProvider::class,
8 7
     App\Providers\Faker\FakerServiceProvider::class,

+ 59
- 55
composer.lock View File

@@ -77,24 +77,24 @@
77 77
         },
78 78
         {
79 79
             "name": "andrewdwallo/filament-companies",
80
-            "version": "v4.1.2",
80
+            "version": "v4.2.0",
81 81
             "source": {
82 82
                 "type": "git",
83 83
                 "url": "https://github.com/andrewdwallo/filament-companies.git",
84
-                "reference": "e8472f6c5e74d4a3f4ffd7796752c779741ec699"
84
+                "reference": "7e2a03b954600427f9ba76b8ecc9279d967a1c4c"
85 85
             },
86 86
             "dist": {
87 87
                 "type": "zip",
88
-                "url": "https://api.github.com/repos/andrewdwallo/filament-companies/zipball/e8472f6c5e74d4a3f4ffd7796752c779741ec699",
89
-                "reference": "e8472f6c5e74d4a3f4ffd7796752c779741ec699",
88
+                "url": "https://api.github.com/repos/andrewdwallo/filament-companies/zipball/7e2a03b954600427f9ba76b8ecc9279d967a1c4c",
89
+                "reference": "7e2a03b954600427f9ba76b8ecc9279d967a1c4c",
90 90
                 "shasum": ""
91 91
             },
92 92
             "require": {
93 93
                 "ext-json": "*",
94 94
                 "filament/filament": "^3.2.29",
95
-                "illuminate/console": "^11.0",
96
-                "illuminate/contracts": "^11.0",
97
-                "illuminate/support": "^11.0",
95
+                "illuminate/console": "^11.0|^12.0",
96
+                "illuminate/contracts": "^11.0|^12.0",
97
+                "illuminate/support": "^11.0|^12.0",
98 98
                 "laravel/socialite": "^5.12",
99 99
                 "matomo/device-detector": "^6.1",
100 100
                 "php": "^8.2"
@@ -104,8 +104,8 @@
104 104
                 "laravel/sanctum": "^4.0",
105 105
                 "livewire/livewire": "^3.4.9",
106 106
                 "mockery/mockery": "^1.6",
107
-                "orchestra/testbench": "^9.0",
108
-                "phpunit/phpunit": "^10.5"
107
+                "orchestra/testbench": "^9.0|^10.0",
108
+                "phpunit/phpunit": "^10.5|^11.5.3"
109 109
             },
110 110
             "type": "library",
111 111
             "extra": {
@@ -150,9 +150,9 @@
150 150
             ],
151 151
             "support": {
152 152
                 "issues": "https://github.com/andrewdwallo/filament-companies/issues",
153
-                "source": "https://github.com/andrewdwallo/filament-companies/tree/v4.1.2"
153
+                "source": "https://github.com/andrewdwallo/filament-companies/tree/v4.2.0"
154 154
             },
155
-            "time": "2025-02-20T01:18:23+00:00"
155
+            "time": "2025-03-01T18:46:48+00:00"
156 156
         },
157 157
         {
158 158
             "name": "andrewdwallo/filament-selectify",
@@ -220,23 +220,23 @@
220 220
         },
221 221
         {
222 222
             "name": "andrewdwallo/transmatic",
223
-            "version": "v1.1.1",
223
+            "version": "v1.2.0",
224 224
             "source": {
225 225
                 "type": "git",
226 226
                 "url": "https://github.com/andrewdwallo/transmatic.git",
227
-                "reference": "30f5384e7e3b693beaf528b01650570a916daf47"
227
+                "reference": "b70c5a5ed58e6ed951651cb4ea00357e53c1748d"
228 228
             },
229 229
             "dist": {
230 230
                 "type": "zip",
231
-                "url": "https://api.github.com/repos/andrewdwallo/transmatic/zipball/30f5384e7e3b693beaf528b01650570a916daf47",
232
-                "reference": "30f5384e7e3b693beaf528b01650570a916daf47",
231
+                "url": "https://api.github.com/repos/andrewdwallo/transmatic/zipball/b70c5a5ed58e6ed951651cb4ea00357e53c1748d",
232
+                "reference": "b70c5a5ed58e6ed951651cb4ea00357e53c1748d",
233 233
                 "shasum": ""
234 234
             },
235 235
             "require": {
236 236
                 "aws/aws-sdk-php-laravel": "^3.8",
237 237
                 "ext-intl": "*",
238 238
                 "ext-json": "*",
239
-                "illuminate/contracts": "^10.0|^11.0",
239
+                "illuminate/contracts": "^10.0|^11.0|^12.0",
240 240
                 "php": "^8.1",
241 241
                 "spatie/laravel-package-tools": "^1.14.0"
242 242
             },
@@ -244,10 +244,10 @@
244 244
                 "larastan/larastan": "^2.9",
245 245
                 "laravel/pint": "^1.0",
246 246
                 "nunomaduro/collision": "^7.8|^8.0",
247
-                "orchestra/testbench": "^8.8|^9.0",
248
-                "pestphp/pest": "^2.20",
249
-                "pestphp/pest-plugin-arch": "^2.0",
250
-                "pestphp/pest-plugin-laravel": "^2.0",
247
+                "orchestra/testbench": "^8.8|^9.0|^10.0",
248
+                "pestphp/pest": "^2.20|^3.0",
249
+                "pestphp/pest-plugin-arch": "^2.0|^3.0",
250
+                "pestphp/pest-plugin-laravel": "^2.0|^3.0",
251 251
                 "phpstan/extension-installer": "^1.1",
252 252
                 "phpstan/phpstan-deprecation-rules": "^1.0",
253 253
                 "phpstan/phpstan-phpunit": "^1.0",
@@ -296,9 +296,9 @@
296 296
             ],
297 297
             "support": {
298 298
                 "issues": "https://github.com/andrewdwallo/transmatic/issues",
299
-                "source": "https://github.com/andrewdwallo/transmatic/tree/v1.1.1"
299
+                "source": "https://github.com/andrewdwallo/transmatic/tree/v1.2.0"
300 300
             },
301
-            "time": "2025-01-26T05:48:43+00:00"
301
+            "time": "2025-03-02T00:21:46+00:00"
302 302
         },
303 303
         {
304 304
             "name": "anourvalar/eloquent-serialize",
@@ -497,16 +497,16 @@
497 497
         },
498 498
         {
499 499
             "name": "aws/aws-sdk-php",
500
-            "version": "3.340.3",
500
+            "version": "3.340.4",
501 501
             "source": {
502 502
                 "type": "git",
503 503
                 "url": "https://github.com/aws/aws-sdk-php.git",
504
-                "reference": "d5ce8f22952710da40be75ad69e2f04d47598a5d"
504
+                "reference": "2896cfb3f6b2bd06757b16e99e1cab93c9598af3"
505 505
             },
506 506
             "dist": {
507 507
                 "type": "zip",
508
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/d5ce8f22952710da40be75ad69e2f04d47598a5d",
509
-                "reference": "d5ce8f22952710da40be75ad69e2f04d47598a5d",
508
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/2896cfb3f6b2bd06757b16e99e1cab93c9598af3",
509
+                "reference": "2896cfb3f6b2bd06757b16e99e1cab93c9598af3",
510 510
                 "shasum": ""
511 511
             },
512 512
             "require": {
@@ -588,9 +588,9 @@
588 588
             "support": {
589 589
                 "forum": "https://github.com/aws/aws-sdk-php/discussions",
590 590
                 "issues": "https://github.com/aws/aws-sdk-php/issues",
591
-                "source": "https://github.com/aws/aws-sdk-php/tree/3.340.3"
591
+                "source": "https://github.com/aws/aws-sdk-php/tree/3.340.4"
592 592
             },
593
-            "time": "2025-02-27T19:11:54+00:00"
593
+            "time": "2025-02-28T19:13:38+00:00"
594 594
         },
595 595
         {
596 596
             "name": "aws/aws-sdk-php-laravel",
@@ -900,16 +900,16 @@
900 900
         },
901 901
         {
902 902
             "name": "brick/math",
903
-            "version": "0.12.2",
903
+            "version": "0.12.3",
904 904
             "source": {
905 905
                 "type": "git",
906 906
                 "url": "https://github.com/brick/math.git",
907
-                "reference": "901eddb1e45a8e0f689302e40af871c181ecbe40"
907
+                "reference": "866551da34e9a618e64a819ee1e01c20d8a588ba"
908 908
             },
909 909
             "dist": {
910 910
                 "type": "zip",
911
-                "url": "https://api.github.com/repos/brick/math/zipball/901eddb1e45a8e0f689302e40af871c181ecbe40",
912
-                "reference": "901eddb1e45a8e0f689302e40af871c181ecbe40",
911
+                "url": "https://api.github.com/repos/brick/math/zipball/866551da34e9a618e64a819ee1e01c20d8a588ba",
912
+                "reference": "866551da34e9a618e64a819ee1e01c20d8a588ba",
913 913
                 "shasum": ""
914 914
             },
915 915
             "require": {
@@ -948,7 +948,7 @@
948 948
             ],
949 949
             "support": {
950 950
                 "issues": "https://github.com/brick/math/issues",
951
-                "source": "https://github.com/brick/math/tree/0.12.2"
951
+                "source": "https://github.com/brick/math/tree/0.12.3"
952 952
             },
953 953
             "funding": [
954 954
                 {
@@ -956,7 +956,7 @@
956 956
                     "type": "github"
957 957
                 }
958 958
             ],
959
-            "time": "2025-02-26T10:21:45+00:00"
959
+            "time": "2025-02-28T13:11:00+00:00"
960 960
         },
961 961
         {
962 962
             "name": "carbonphp/carbon-doctrine-types",
@@ -3777,16 +3777,16 @@
3777 3777
         },
3778 3778
         {
3779 3779
             "name": "league/csv",
3780
-            "version": "9.21.0",
3780
+            "version": "9.22.0",
3781 3781
             "source": {
3782 3782
                 "type": "git",
3783 3783
                 "url": "https://github.com/thephpleague/csv.git",
3784
-                "reference": "72196d11ebba22d868954cb39c0c7346207430cc"
3784
+                "reference": "afc109aa11f3086b8be8dfffa04ac31480b36b76"
3785 3785
             },
3786 3786
             "dist": {
3787 3787
                 "type": "zip",
3788
-                "url": "https://api.github.com/repos/thephpleague/csv/zipball/72196d11ebba22d868954cb39c0c7346207430cc",
3789
-                "reference": "72196d11ebba22d868954cb39c0c7346207430cc",
3788
+                "url": "https://api.github.com/repos/thephpleague/csv/zipball/afc109aa11f3086b8be8dfffa04ac31480b36b76",
3789
+                "reference": "afc109aa11f3086b8be8dfffa04ac31480b36b76",
3790 3790
                 "shasum": ""
3791 3791
             },
3792 3792
             "require": {
@@ -3796,19 +3796,23 @@
3796 3796
             "require-dev": {
3797 3797
                 "ext-dom": "*",
3798 3798
                 "ext-xdebug": "*",
3799
-                "friendsofphp/php-cs-fixer": "^3.64.0",
3800
-                "phpbench/phpbench": "^1.3.1",
3801
-                "phpstan/phpstan": "^1.12.11",
3799
+                "friendsofphp/php-cs-fixer": "^3.69.0",
3800
+                "phpbench/phpbench": "^1.4.0",
3801
+                "phpstan/phpstan": "^1.12.18",
3802 3802
                 "phpstan/phpstan-deprecation-rules": "^1.2.1",
3803
-                "phpstan/phpstan-phpunit": "^1.4.1",
3804
-                "phpstan/phpstan-strict-rules": "^1.6.1",
3805
-                "phpunit/phpunit": "^10.5.16 || ^11.4.3",
3806
-                "symfony/var-dumper": "^6.4.8 || ^7.1.8"
3803
+                "phpstan/phpstan-phpunit": "^1.4.2",
3804
+                "phpstan/phpstan-strict-rules": "^1.6.2",
3805
+                "phpunit/phpunit": "^10.5.16 || ^11.5.7",
3806
+                "symfony/var-dumper": "^6.4.8 || ^7.2.3"
3807 3807
             },
3808 3808
             "suggest": {
3809 3809
                 "ext-dom": "Required to use the XMLConverter and the HTMLConverter classes",
3810 3810
                 "ext-iconv": "Needed to ease transcoding CSV using iconv stream filters",
3811
-                "ext-mbstring": "Needed to ease transcoding CSV using mb stream filters"
3811
+                "ext-mbstring": "Needed to ease transcoding CSV using mb stream filters",
3812
+                "ext-mysqli": "Requiered to use the package with the MySQLi extension",
3813
+                "ext-pdo": "Required to use the package with the PDO extension",
3814
+                "ext-pgsql": "Requiered to use the package with the PgSQL extension",
3815
+                "ext-sqlite3": "Required to use the package with the SQLite3 extension"
3812 3816
             },
3813 3817
             "type": "library",
3814 3818
             "extra": {
@@ -3821,7 +3825,7 @@
3821 3825
                     "src/functions_include.php"
3822 3826
                 ],
3823 3827
                 "psr-4": {
3824
-                    "League\\Csv\\": "src/"
3828
+                    "League\\Csv\\": "src"
3825 3829
                 }
3826 3830
             },
3827 3831
             "notification-url": "https://packagist.org/downloads/",
@@ -3860,7 +3864,7 @@
3860 3864
                     "type": "github"
3861 3865
                 }
3862 3866
             ],
3863
-            "time": "2025-01-08T19:27:58+00:00"
3867
+            "time": "2025-02-28T10:00:39+00:00"
3864 3868
         },
3865 3869
         {
3866 3870
             "name": "league/flysystem",
@@ -10646,16 +10650,16 @@
10646 10650
         },
10647 10651
         {
10648 10652
             "name": "php-di/php-di",
10649
-            "version": "7.0.8",
10653
+            "version": "7.0.9",
10650 10654
             "source": {
10651 10655
                 "type": "git",
10652 10656
                 "url": "https://github.com/PHP-DI/PHP-DI.git",
10653
-                "reference": "98ddc81f8f768a2ad39e4cbe737285eaeabe577a"
10657
+                "reference": "d8480267f5cf239650debba704f3ecd15b638cde"
10654 10658
             },
10655 10659
             "dist": {
10656 10660
                 "type": "zip",
10657
-                "url": "https://api.github.com/repos/PHP-DI/PHP-DI/zipball/98ddc81f8f768a2ad39e4cbe737285eaeabe577a",
10658
-                "reference": "98ddc81f8f768a2ad39e4cbe737285eaeabe577a",
10661
+                "url": "https://api.github.com/repos/PHP-DI/PHP-DI/zipball/d8480267f5cf239650debba704f3ecd15b638cde",
10662
+                "reference": "d8480267f5cf239650debba704f3ecd15b638cde",
10659 10663
                 "shasum": ""
10660 10664
             },
10661 10665
             "require": {
@@ -10672,7 +10676,7 @@
10672 10676
                 "friendsofphp/proxy-manager-lts": "^1",
10673 10677
                 "mnapoli/phpunit-easymock": "^1.3",
10674 10678
                 "phpunit/phpunit": "^9.6",
10675
-                "vimeo/psalm": "^4.6"
10679
+                "vimeo/psalm": "^5|^6"
10676 10680
             },
10677 10681
             "suggest": {
10678 10682
                 "friendsofphp/proxy-manager-lts": "Install it if you want to use lazy injection (version ^1)"
@@ -10703,7 +10707,7 @@
10703 10707
             ],
10704 10708
             "support": {
10705 10709
                 "issues": "https://github.com/PHP-DI/PHP-DI/issues",
10706
-                "source": "https://github.com/PHP-DI/PHP-DI/tree/7.0.8"
10710
+                "source": "https://github.com/PHP-DI/PHP-DI/tree/7.0.9"
10707 10711
             },
10708 10712
             "funding": [
10709 10713
                 {
@@ -10715,7 +10719,7 @@
10715 10719
                     "type": "tidelift"
10716 10720
                 }
10717 10721
             ],
10718
-            "time": "2025-01-28T21:02:46+00:00"
10722
+            "time": "2025-02-28T12:46:35+00:00"
10719 10723
         },
10720 10724
         {
10721 10725
             "name": "phpdocumentor/reflection-common",

+ 79
- 79
package-lock.json View File

@@ -575,9 +575,9 @@
575 575
             }
576 576
         },
577 577
         "node_modules/@rollup/rollup-android-arm-eabi": {
578
-            "version": "4.34.8",
579
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz",
580
-            "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==",
578
+            "version": "4.34.9",
579
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.9.tgz",
580
+            "integrity": "sha512-qZdlImWXur0CFakn2BJ2znJOdqYZKiedEPEVNTBrpfPjc/YuTGcaYZcdmNFTkUj3DU0ZM/AElcM8Ybww3xVLzA==",
581 581
             "cpu": [
582 582
                 "arm"
583 583
             ],
@@ -589,9 +589,9 @@
589 589
             ]
590 590
         },
591 591
         "node_modules/@rollup/rollup-android-arm64": {
592
-            "version": "4.34.8",
593
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz",
594
-            "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==",
592
+            "version": "4.34.9",
593
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.9.tgz",
594
+            "integrity": "sha512-4KW7P53h6HtJf5Y608T1ISKvNIYLWRKMvfnG0c44M6In4DQVU58HZFEVhWINDZKp7FZps98G3gxwC1sb0wXUUg==",
595 595
             "cpu": [
596 596
                 "arm64"
597 597
             ],
@@ -603,9 +603,9 @@
603 603
             ]
604 604
         },
605 605
         "node_modules/@rollup/rollup-darwin-arm64": {
606
-            "version": "4.34.8",
607
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz",
608
-            "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==",
606
+            "version": "4.34.9",
607
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.9.tgz",
608
+            "integrity": "sha512-0CY3/K54slrzLDjOA7TOjN1NuLKERBgk9nY5V34mhmuu673YNb+7ghaDUs6N0ujXR7fz5XaS5Aa6d2TNxZd0OQ==",
609 609
             "cpu": [
610 610
                 "arm64"
611 611
             ],
@@ -617,9 +617,9 @@
617 617
             ]
618 618
         },
619 619
         "node_modules/@rollup/rollup-darwin-x64": {
620
-            "version": "4.34.8",
621
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz",
622
-            "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==",
620
+            "version": "4.34.9",
621
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.9.tgz",
622
+            "integrity": "sha512-eOojSEAi/acnsJVYRxnMkPFqcxSMFfrw7r2iD9Q32SGkb/Q9FpUY1UlAu1DH9T7j++gZ0lHjnm4OyH2vCI7l7Q==",
623 623
             "cpu": [
624 624
                 "x64"
625 625
             ],
@@ -631,9 +631,9 @@
631 631
             ]
632 632
         },
633 633
         "node_modules/@rollup/rollup-freebsd-arm64": {
634
-            "version": "4.34.8",
635
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz",
636
-            "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==",
634
+            "version": "4.34.9",
635
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.9.tgz",
636
+            "integrity": "sha512-2lzjQPJbN5UnHm7bHIUKFMulGTQwdvOkouJDpPysJS+QFBGDJqcfh+CxxtG23Ik/9tEvnebQiylYoazFMAgrYw==",
637 637
             "cpu": [
638 638
                 "arm64"
639 639
             ],
@@ -645,9 +645,9 @@
645 645
             ]
646 646
         },
647 647
         "node_modules/@rollup/rollup-freebsd-x64": {
648
-            "version": "4.34.8",
649
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz",
650
-            "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==",
648
+            "version": "4.34.9",
649
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.9.tgz",
650
+            "integrity": "sha512-SLl0hi2Ah2H7xQYd6Qaiu01kFPzQ+hqvdYSoOtHYg/zCIFs6t8sV95kaoqjzjFwuYQLtOI0RZre/Ke0nPaQV+g==",
651 651
             "cpu": [
652 652
                 "x64"
653 653
             ],
@@ -659,9 +659,9 @@
659 659
             ]
660 660
         },
661 661
         "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
662
-            "version": "4.34.8",
663
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz",
664
-            "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==",
662
+            "version": "4.34.9",
663
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.9.tgz",
664
+            "integrity": "sha512-88I+D3TeKItrw+Y/2ud4Tw0+3CxQ2kLgu3QvrogZ0OfkmX/DEppehus7L3TS2Q4lpB+hYyxhkQiYPJ6Mf5/dPg==",
665 665
             "cpu": [
666 666
                 "arm"
667 667
             ],
@@ -673,9 +673,9 @@
673 673
             ]
674 674
         },
675 675
         "node_modules/@rollup/rollup-linux-arm-musleabihf": {
676
-            "version": "4.34.8",
677
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz",
678
-            "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==",
676
+            "version": "4.34.9",
677
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.9.tgz",
678
+            "integrity": "sha512-3qyfWljSFHi9zH0KgtEPG4cBXHDFhwD8kwg6xLfHQ0IWuH9crp005GfoUUh/6w9/FWGBwEHg3lxK1iHRN1MFlA==",
679 679
             "cpu": [
680 680
                 "arm"
681 681
             ],
@@ -687,9 +687,9 @@
687 687
             ]
688 688
         },
689 689
         "node_modules/@rollup/rollup-linux-arm64-gnu": {
690
-            "version": "4.34.8",
691
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz",
692
-            "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==",
690
+            "version": "4.34.9",
691
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.9.tgz",
692
+            "integrity": "sha512-6TZjPHjKZUQKmVKMUowF3ewHxctrRR09eYyvT5eFv8w/fXarEra83A2mHTVJLA5xU91aCNOUnM+DWFMSbQ0Nxw==",
693 693
             "cpu": [
694 694
                 "arm64"
695 695
             ],
@@ -701,9 +701,9 @@
701 701
             ]
702 702
         },
703 703
         "node_modules/@rollup/rollup-linux-arm64-musl": {
704
-            "version": "4.34.8",
705
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz",
706
-            "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==",
704
+            "version": "4.34.9",
705
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.9.tgz",
706
+            "integrity": "sha512-LD2fytxZJZ6xzOKnMbIpgzFOuIKlxVOpiMAXawsAZ2mHBPEYOnLRK5TTEsID6z4eM23DuO88X0Tq1mErHMVq0A==",
707 707
             "cpu": [
708 708
                 "arm64"
709 709
             ],
@@ -715,9 +715,9 @@
715 715
             ]
716 716
         },
717 717
         "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
718
-            "version": "4.34.8",
719
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz",
720
-            "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==",
718
+            "version": "4.34.9",
719
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.9.tgz",
720
+            "integrity": "sha512-dRAgTfDsn0TE0HI6cmo13hemKpVHOEyeciGtvlBTkpx/F65kTvShtY/EVyZEIfxFkV5JJTuQ9tP5HGBS0hfxIg==",
721 721
             "cpu": [
722 722
                 "loong64"
723 723
             ],
@@ -729,9 +729,9 @@
729 729
             ]
730 730
         },
731 731
         "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
732
-            "version": "4.34.8",
733
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz",
734
-            "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==",
732
+            "version": "4.34.9",
733
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.9.tgz",
734
+            "integrity": "sha512-PHcNOAEhkoMSQtMf+rJofwisZqaU8iQ8EaSps58f5HYll9EAY5BSErCZ8qBDMVbq88h4UxaNPlbrKqfWP8RfJA==",
735 735
             "cpu": [
736 736
                 "ppc64"
737 737
             ],
@@ -743,9 +743,9 @@
743 743
             ]
744 744
         },
745 745
         "node_modules/@rollup/rollup-linux-riscv64-gnu": {
746
-            "version": "4.34.8",
747
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz",
748
-            "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==",
746
+            "version": "4.34.9",
747
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.9.tgz",
748
+            "integrity": "sha512-Z2i0Uy5G96KBYKjeQFKbbsB54xFOL5/y1P5wNBsbXB8yE+At3oh0DVMjQVzCJRJSfReiB2tX8T6HUFZ2k8iaKg==",
749 749
             "cpu": [
750 750
                 "riscv64"
751 751
             ],
@@ -757,9 +757,9 @@
757 757
             ]
758 758
         },
759 759
         "node_modules/@rollup/rollup-linux-s390x-gnu": {
760
-            "version": "4.34.8",
761
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz",
762
-            "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==",
760
+            "version": "4.34.9",
761
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.9.tgz",
762
+            "integrity": "sha512-U+5SwTMoeYXoDzJX5dhDTxRltSrIax8KWwfaaYcynuJw8mT33W7oOgz0a+AaXtGuvhzTr2tVKh5UO8GVANTxyQ==",
763 763
             "cpu": [
764 764
                 "s390x"
765 765
             ],
@@ -771,9 +771,9 @@
771 771
             ]
772 772
         },
773 773
         "node_modules/@rollup/rollup-linux-x64-gnu": {
774
-            "version": "4.34.8",
775
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz",
776
-            "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==",
774
+            "version": "4.34.9",
775
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.9.tgz",
776
+            "integrity": "sha512-FwBHNSOjUTQLP4MG7y6rR6qbGw4MFeQnIBrMe161QGaQoBQLqSUEKlHIiVgF3g/mb3lxlxzJOpIBhaP+C+KP2A==",
777 777
             "cpu": [
778 778
                 "x64"
779 779
             ],
@@ -785,9 +785,9 @@
785 785
             ]
786 786
         },
787 787
         "node_modules/@rollup/rollup-linux-x64-musl": {
788
-            "version": "4.34.8",
789
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz",
790
-            "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==",
788
+            "version": "4.34.9",
789
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.9.tgz",
790
+            "integrity": "sha512-cYRpV4650z2I3/s6+5/LONkjIz8MBeqrk+vPXV10ORBnshpn8S32bPqQ2Utv39jCiDcO2eJTuSlPXpnvmaIgRA==",
791 791
             "cpu": [
792 792
                 "x64"
793 793
             ],
@@ -799,9 +799,9 @@
799 799
             ]
800 800
         },
801 801
         "node_modules/@rollup/rollup-win32-arm64-msvc": {
802
-            "version": "4.34.8",
803
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz",
804
-            "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==",
802
+            "version": "4.34.9",
803
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.9.tgz",
804
+            "integrity": "sha512-z4mQK9dAN6byRA/vsSgQiPeuO63wdiDxZ9yg9iyX2QTzKuQM7T4xlBoeUP/J8uiFkqxkcWndWi+W7bXdPbt27Q==",
805 805
             "cpu": [
806 806
                 "arm64"
807 807
             ],
@@ -813,9 +813,9 @@
813 813
             ]
814 814
         },
815 815
         "node_modules/@rollup/rollup-win32-ia32-msvc": {
816
-            "version": "4.34.8",
817
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz",
818
-            "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==",
816
+            "version": "4.34.9",
817
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.9.tgz",
818
+            "integrity": "sha512-KB48mPtaoHy1AwDNkAJfHXvHp24H0ryZog28spEs0V48l3H1fr4i37tiyHsgKZJnCmvxsbATdZGBpbmxTE3a9w==",
819 819
             "cpu": [
820 820
                 "ia32"
821 821
             ],
@@ -827,9 +827,9 @@
827 827
             ]
828 828
         },
829 829
         "node_modules/@rollup/rollup-win32-x64-msvc": {
830
-            "version": "4.34.8",
831
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz",
832
-            "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==",
830
+            "version": "4.34.9",
831
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.9.tgz",
832
+            "integrity": "sha512-AyleYRPU7+rgkMWbEh71fQlrzRfeP6SyMnRf9XX4fCdDPAJumdSBqYEcWPMzVQ4ScAl7E4oFfK0GUVn77xSwbw==",
833 833
             "cpu": [
834 834
                 "x64"
835 835
             ],
@@ -2412,9 +2412,9 @@
2412 2412
             }
2413 2413
         },
2414 2414
         "node_modules/rollup": {
2415
-            "version": "4.34.8",
2416
-            "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz",
2417
-            "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==",
2415
+            "version": "4.34.9",
2416
+            "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.9.tgz",
2417
+            "integrity": "sha512-nF5XYqWWp9hx/LrpC8sZvvvmq0TeTjQgaZHYmAgwysT9nh8sWnZhBnM8ZyVbbJFIQBLwHDNoMqsBZBbUo4U8sQ==",
2418 2418
             "dev": true,
2419 2419
             "license": "MIT",
2420 2420
             "dependencies": {
@@ -2428,25 +2428,25 @@
2428 2428
                 "npm": ">=8.0.0"
2429 2429
             },
2430 2430
             "optionalDependencies": {
2431
-                "@rollup/rollup-android-arm-eabi": "4.34.8",
2432
-                "@rollup/rollup-android-arm64": "4.34.8",
2433
-                "@rollup/rollup-darwin-arm64": "4.34.8",
2434
-                "@rollup/rollup-darwin-x64": "4.34.8",
2435
-                "@rollup/rollup-freebsd-arm64": "4.34.8",
2436
-                "@rollup/rollup-freebsd-x64": "4.34.8",
2437
-                "@rollup/rollup-linux-arm-gnueabihf": "4.34.8",
2438
-                "@rollup/rollup-linux-arm-musleabihf": "4.34.8",
2439
-                "@rollup/rollup-linux-arm64-gnu": "4.34.8",
2440
-                "@rollup/rollup-linux-arm64-musl": "4.34.8",
2441
-                "@rollup/rollup-linux-loongarch64-gnu": "4.34.8",
2442
-                "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8",
2443
-                "@rollup/rollup-linux-riscv64-gnu": "4.34.8",
2444
-                "@rollup/rollup-linux-s390x-gnu": "4.34.8",
2445
-                "@rollup/rollup-linux-x64-gnu": "4.34.8",
2446
-                "@rollup/rollup-linux-x64-musl": "4.34.8",
2447
-                "@rollup/rollup-win32-arm64-msvc": "4.34.8",
2448
-                "@rollup/rollup-win32-ia32-msvc": "4.34.8",
2449
-                "@rollup/rollup-win32-x64-msvc": "4.34.8",
2431
+                "@rollup/rollup-android-arm-eabi": "4.34.9",
2432
+                "@rollup/rollup-android-arm64": "4.34.9",
2433
+                "@rollup/rollup-darwin-arm64": "4.34.9",
2434
+                "@rollup/rollup-darwin-x64": "4.34.9",
2435
+                "@rollup/rollup-freebsd-arm64": "4.34.9",
2436
+                "@rollup/rollup-freebsd-x64": "4.34.9",
2437
+                "@rollup/rollup-linux-arm-gnueabihf": "4.34.9",
2438
+                "@rollup/rollup-linux-arm-musleabihf": "4.34.9",
2439
+                "@rollup/rollup-linux-arm64-gnu": "4.34.9",
2440
+                "@rollup/rollup-linux-arm64-musl": "4.34.9",
2441
+                "@rollup/rollup-linux-loongarch64-gnu": "4.34.9",
2442
+                "@rollup/rollup-linux-powerpc64le-gnu": "4.34.9",
2443
+                "@rollup/rollup-linux-riscv64-gnu": "4.34.9",
2444
+                "@rollup/rollup-linux-s390x-gnu": "4.34.9",
2445
+                "@rollup/rollup-linux-x64-gnu": "4.34.9",
2446
+                "@rollup/rollup-linux-x64-musl": "4.34.9",
2447
+                "@rollup/rollup-win32-arm64-msvc": "4.34.9",
2448
+                "@rollup/rollup-win32-ia32-msvc": "4.34.9",
2449
+                "@rollup/rollup-win32-x64-msvc": "4.34.9",
2450 2450
                 "fsevents": "~2.3.2"
2451 2451
             }
2452 2452
         },

+ 3
- 0
resources/css/app.css View File

@@ -0,0 +1,3 @@
1
+@tailwind base;
2
+@tailwind components;
3
+@tailwind utilities;

+ 0
- 150574
resources/data/cities.csv
File diff suppressed because it is too large
View File


+ 0
- 159
resources/data/currencies.csv View File

@@ -1,159 +0,0 @@
1
-name,currency,code,precision,symbol,decimal_mark,thousands_separator,symbol_first,subunit
2
-Afghani,AFN,971,2,؋,.,",",FALSE,100
3
-Euro,EUR,978,2,€,",",.,TRUE,100
4
-Lek,ALL,008,2,L,.,",",FALSE,100
5
-Algerian Dinar,DZD,012,2,دج,.,",",FALSE,100
6
-US Dollar,USD,840,2,$,.,",",TRUE,100
7
-Kwanza,AOA,973,2,Kz,.,",",FALSE,100
8
-East Caribbean Dollar,XCD,951,2,$,.,",",TRUE,100
9
-Argentine Peso,ARS,032,2,$,",",.,TRUE,100
10
-Armenian Dram,AMD,051,2,֏,.,",",FALSE,100
11
-Aruban Florin,AWG,533,2,ƒ,.,",",FALSE,100
12
-Australian Dollar,AUD,036,2,$,.,",",TRUE,100
13
-Azerbaijan Manat,AZN,944,2,₼,.,",",TRUE,100
14
-Bahamian Dollar,BSD,044,2,$,.,",",TRUE,100
15
-Bahraini Dinar,BHD,048,3,.د.ب,.,",",TRUE,1000
16
-Taka,BDT,050,2,৳,.,",",TRUE,100
17
-Barbados Dollar,BBD,052,2,$,.,",",TRUE,100
18
-Belarusian Ruble,BYN,933,2,Br,",","",FALSE,1
19
-Belize Dollar,BZD,084,2,BZ$,.,",",TRUE,100
20
-CFA Franc BCEAO,XOF,952,0,CFA,.,",",FALSE,1
21
-Bermudian Dollar,BMD,060,2,$,.,",",TRUE,100
22
-Indian Rupee,INR,356,2,₹,.,",",TRUE,100
23
-Ngultrum,BTN,064,2,Nu.,.,",",FALSE,100
24
-Boliviano,BOB,068,2,$b,.,",",TRUE,100
25
-Convertible Mark,BAM,977,2,KM,",",.,TRUE,100
26
-Pula,BWP,072,2,P,.,",",TRUE,100
27
-Norwegian Krone,NOK,578,2,kr,",","",FALSE,100
28
-Brazilian Real,BRL,986,2,R$,",",.,TRUE,100
29
-Brunei Dollar,BND,096,2,$,.,",",TRUE,100
30
-Bulgarian Lev,BGN,975,2,лв,",","",FALSE,100
31
-Burundi Franc,BIF,108,0,FBu,.,",",FALSE,1
32
-Cabo Verde Escudo,CVE,132,2,$,.,",",FALSE,100
33
-Riel,KHR,116,2,៛,.,",",FALSE,100
34
-CFA Franc BEAC,XAF,950,0,FCFA,.,",",FALSE,1
35
-Canadian Dollar,CAD,124,2,$,.,",",TRUE,100
36
-Cayman Islands Dollar,KYD,136,2,$,.,",",TRUE,100
37
-Chilean Peso,CLP,152,0,$,.,.,TRUE,1
38
-Yuan Renminbi,CNY,156,2,¥,.,",",TRUE,100
39
-Colombian Peso,COP,170,2,$,.,",",TRUE,100
40
-Comorian Franc ,KMF,174,0,CF,.,",",FALSE,1
41
-Congolese Franc,CDF,976,2,FC,.,",",FALSE,100
42
-New Zealand Dollar,NZD,554,2,$,.,",",TRUE,100
43
-Costa Rican Colon,CRC,188,2,₡,.,",",TRUE,100
44
-Cuban Peso,CUP,192,2,₱,.,",",TRUE,100
45
-Peso Convertible,CUC,931,2,$,.,",",FALSE,100
46
-Netherlands Antillean Guilder,ANG,532,2,ƒ,.,",",TRUE,100
47
-Czech Koruna,CZK,203,2,Kč,",",.,FALSE,100
48
-Danish Krone,DKK,208,2,kr,",",.,FALSE,100
49
-Djibouti Franc,DJF,262,0,Fdj,.,",",FALSE,1
50
-Dominican Peso,DOP,214,2,RD$,.,",",TRUE,100
51
-Egyptian Pound,EGP,818,2,£,.,",",TRUE,100
52
-El Salvador Colon,SVC,222,2,$,.,",",TRUE,100
53
-Nakfa,ERN,232,2,Nfk,.,",",FALSE,100
54
-Lilangeni,SZL,748,2,E,.,",",TRUE,100
55
-Ethiopian Birr,ETB,230,2,Br,.,",",FALSE,100
56
-Falkland Islands Pound,FKP,238,2,£,.,",",FALSE,100
57
-Fiji Dollar,FJD,242,2,$,.,",",FALSE,100
58
-CFP Franc,XPF,953,0,₣,.,",",FALSE,1
59
-Dalasi,GMD,270,2,D,.,",",FALSE,100
60
-Lari,GEL,981,2,₾,",",.,TRUE,100
61
-Ghana Cedi,GHS,936,2,GH₵,.,",",TRUE,100
62
-Gibraltar Pound,GIP,292,2,£,.,",",TRUE,100
63
-Quetzal,GTQ,320,2,Q,.,",",TRUE,100
64
-Pound Sterling,GBP,826,2,£,.,",",TRUE,100
65
-Guinean Franc,GNF,324,0,FG,.,",",FALSE,1
66
-Guyana Dollar,GYD,328,2,$,.,",",FALSE,100
67
-Gourde,HTG,332,2,G,.,",",FALSE,100
68
-Lempira,HNL,340,2,L,.,",",TRUE,100
69
-Hong Kong Dollar,HKD,344,2,$,.,",",TRUE,100
70
-Forint,HUF,348,2,Ft,",","",FALSE,100
71
-Iceland Krona,ISK,352,0,kr,",",.,TRUE,1
72
-Rupiah,IDR,360,2,Rp,",",.,TRUE,100
73
-Iranian Rial,IRR,364,2,﷼,.,",",TRUE,100
74
-Iraqi Dinar,IQD,368,3,ع.د,.,",",FALSE,1000
75
-New Israeli Sheqel,ILS,376,2,₪,.,",",TRUE,100
76
-Jamaican Dollar,JMD,388,2,J$,.,",",TRUE,100
77
-Yen,JPY,392,0,¥,.,",",TRUE,1
78
-Jordanian Dinar,JOD,400,3,JD,.,",",TRUE,100
79
-Tenge,KZT,398,2,₸,.,",",FALSE,100
80
-Kenyan Shilling,KES,404,2,KSh,.,",",TRUE,100
81
-North Korean Won,KPW,408,2,₩,.,",",FALSE,100
82
-Won,KRW,410,0,₩,.,",",TRUE,1
83
-Kuwaiti Dinar,KWD,414,3,KD,.,",",TRUE,1000
84
-Som,KGS,417,2,лв,.,",",FALSE,100
85
-Lao Kip,LAK,418,2,₭,.,",",FALSE,100
86
-Lebanese Pound,LBP,422,2,£,.,",",TRUE,100
87
-Loti,LSL,426,2,M,.,",",FALSE,100
88
-Rand,ZAR,710,2,R,.,",",TRUE,100
89
-Liberian Dollar,LRD,430,2,$,.,",",FALSE,100
90
-Libyan Dinar,LYD,434,3,LD,.,",",FALSE,1000
91
-Swiss Franc,CHF,756,2,Fr.,.,",",TRUE,100
92
-Pataca,MOP,446,2,MOP$,.,",",FALSE,100
93
-Denar,MKD,807,2,ден,",","",FALSE,100
94
-Malagasy Ariary,MGA,969,2,Ar,.,",",TRUE,5
95
-Malawi Kwacha,MWK,454,2,MK,.,",",FALSE,100
96
-Malaysian Ringgit,MYR,458,2,RM,.,",",TRUE,100
97
-Rufiyaa,MVR,462,2,Rf,.,",",FALSE,100
98
-Ouguiya,MRU,929,2,UM,",","",FALSE,5
99
-Mauritius Rupee,MUR,480,2,₨,.,",",TRUE,100
100
-Mexican Peso,MXN,484,2,$,.,",",TRUE,100
101
-Moldovan Leu,MDL,498,2,lei,.,",",FALSE,100
102
-Tugrik,MNT,496,2,₮,.,",",FALSE,100
103
-Moroccan Dirham,MAD,504,2,د.م.,.,",",FALSE,100
104
-Mozambique Metical,MZN,943,2,MT,.,",",TRUE,100
105
-Kyat,MMK,104,2,K,.,",",FALSE,100
106
-Namibia Dollar,NAD,516,2,$,.,",",FALSE,100
107
-Nepalese Rupee,NPR,524,2,₨,.,",",TRUE,100
108
-Cordoba Oro,NIO,558,2,C$,.,",",FALSE,100
109
-Naira,NGN,566,2,₦,.,",",TRUE,100
110
-Rial Omani,OMR,512,3,﷼,.,",",TRUE,1000
111
-Pakistan Rupee,PKR,586,2,₨,.,",",TRUE,100
112
-Balboa,PAB,590,2,B/.,.,",",FALSE,100
113
-Kina,PGK,598,2,K,.,",",FALSE,100
114
-Guarani,PYG,600,0,Gs,.,",",TRUE,1
115
-Sol,PEN,604,2,S/.,.,",",TRUE,100
116
-Philippine Peso,PHP,608,2,₱,.,",",TRUE,100
117
-Zloty,PLN,985,2,zł,",","",FALSE,100
118
-Qatari Rial,QAR,634,2,﷼,.,",",FALSE,100
119
-Romanian Leu,RON,946,2,lei,",",.,TRUE,100
120
-Russian Ruble,RUB,643,2,₽,",","",FALSE,100
121
-Rwanda Franc,RWF,646,0,R₣,.,",",FALSE,1
122
-Saint Helena Pound,SHP,654,2,£,.,",",FALSE,100
123
-Tala,WST,882,2,WS$,.,",",FALSE,100
124
-Dobra,STN,930,2,Db,",","",FALSE,100
125
-Saudi Riyal,SAR,682,2,﷼,.,",",TRUE,100
126
-Serbian Dinar,RSD,941,2,Дин.,",","",TRUE,100
127
-Seychelles Rupee,SCR,690,2,₨,.,",",FALSE,100
128
-Leone,SLL,694,2,Le,.,",",FALSE,100
129
-Leone,SLE,925,2,Le,.,",",FALSE,100
130
-Singapore Dollar,SGD,702,2,S$,.,",",TRUE,100
131
-Solomon Islands Dollar,SBD,090,2,$,.,",",FALSE,100
132
-Somali Shilling,SOS,706,2,S,.,",",FALSE,100
133
-South Sudanese Pound,SSP,728,2,£,.,",",FALSE,100
134
-Sri Lanka Rupee,LKR,144,2,₨,.,",",FALSE,100
135
-Sudanese Pound,SDG,938,2,ج.س.,.,",",TRUE,100
136
-Surinam Dollar,SRD,968,2,$,.,",",FALSE,100
137
-Swedish Krona,SEK,752,2,kr,",","",FALSE,100
138
-Syrian Pound,SYP,760,2,£,.,",",FALSE,100
139
-New Taiwan Dollar,TWD,901,2,NT$,.,",",TRUE,100
140
-Somoni,TJS,972,2,SM,.,",",FALSE,100
141
-Tanzanian Shilling,TZS,834,2,TSh,.,",",TRUE,100
142
-Baht,THB,764,2,฿,.,",",TRUE,100
143
-Pa’anga,TOP,776,2,T$,.,",",TRUE,100
144
-Trinidad and Tobago Dollar,TTD,780,2,TT$,.,",",FALSE,100
145
-Tunisian Dinar,TND,788,3,د.ت,.,",",FALSE,1000
146
-Turkish Lira,TRY,949,2,₺,",",",",TRUE,100
147
-Turkmenistan New Manat,TMT,934,2,T,.,",",FALSE,100
148
-Uganda Shilling,UGX,800,0,USh,.,",",FALSE,1
149
-Hryvnia,UAH,980,2,₴,",","",FALSE,100
150
-UAE Dirham,AED,784,2,د.إ,.,",",TRUE,100
151
-Peso Uruguayo,UYU,858,2,$U,",",.,TRUE,100
152
-Uzbekistan Sum,UZS,860,2,лв,.,",",TRUE,100
153
-Vatu,VUV,548,0,VT,.,",",TRUE,1
154
-Bolívar Soberano,VES,928,2,Bs.S,",","",TRUE,100
155
-Bolívar Soberano,VED,926,2,Bs.,",","",TRUE,100
156
-Dong,VND,704,0,₫,.,",",TRUE,1
157
-Yemeni Rial,YER,886,2,﷼,.,",",FALSE,100
158
-Zambian Kwacha,ZMW,967,2,ZK,.,",",FALSE,100
159
-Zimbabwe Dollar,ZWL,932,2,$,.,",",TRUE,100

+ 21
- 0
resources/js/custom-print.js View File

@@ -0,0 +1,21 @@
1
+function printPdf(url, title) {
2
+    if (title) {
3
+        document.title = title;
4
+    }
5
+
6
+    const iframe = document.createElement('iframe');
7
+    iframe.style.visibility = 'hidden';
8
+    iframe.style.position = 'absolute';
9
+    iframe.style.width = '0';
10
+    iframe.style.height = '0';
11
+    iframe.src = url;
12
+    document.body.appendChild(iframe);
13
+
14
+    iframe.onload = function () {
15
+        try {
16
+            iframe.contentWindow.print();
17
+        } catch (e) {
18
+            console.error('Error printing PDF:', e);
19
+        }
20
+    };
21
+}

resources/views/components/company/invoice/container.blade.php → resources/views/components/company/document-template/container.blade.php View File

@@ -2,10 +2,10 @@
2 2
     'preview' => false,
3 3
 ])
4 4
 
5
-<div class="inv-container flex justify-center p-6">
5
+<div class="doc-template-container flex justify-center p-6">
6 6
     <div
7 7
         @class([
8
-            'inv-paper bg-[#ffffff] dark:bg-gray-800 rounded-sm shadow-xl',
8
+            'doc-template-paper bg-[#ffffff] dark:bg-gray-800 rounded-sm shadow-xl',
9 9
             'w-full max-w-[820px] max-h-[1024px] overflow-y-auto' => $preview === false,
10 10
             'w-[38.25rem] h-[49.5rem] overflow-hidden' => $preview === true,
11 11
         ])

+ 3
- 0
resources/views/components/company/document-template/footer.blade.php View File

@@ -0,0 +1,3 @@
1
+<footer {{ $attributes->class(['doc-template-footer text-xs text-gray-600 dark:text-gray-300 min-h-60']) }}>
2
+    {{ $slot }}
3
+</footer>

+ 3
- 0
resources/views/components/company/document-template/header.blade.php View File

@@ -0,0 +1,3 @@
1
+<header {{ $attributes->class(['doc-template-header flex py-2 relative']) }}>
2
+    {{ $slot }}
3
+</header>

+ 3
- 0
resources/views/components/company/document-template/line-items.blade.php View File

@@ -0,0 +1,3 @@
1
+<div {{ $attributes->class(['doc-template-line-items py-6']) }}>
2
+    {{ $slot }}
3
+</div>

resources/views/components/company/invoice/logo.blade.php → resources/views/components/company/document-template/logo.blade.php View File

@@ -6,7 +6,7 @@
6 6
 <img {{
7 7
     $attributes
8 8
         ->class([
9
-            'inv-logo object-contain',
9
+            'doc-template-logo object-contain',
10 10
             match ($size) {
11 11
                 'sm' => 'max-h-8',
12 12
                 'md' => 'max-h-16',

+ 3
- 0
resources/views/components/company/document-template/metadata.blade.php View File

@@ -0,0 +1,3 @@
1
+<section {{ $attributes->class(['doc-template-metadata px-6 pt-4']) }}>
2
+    {{ $slot }}
3
+</section>

+ 0
- 3
resources/views/components/company/invoice/footer.blade.php View File

@@ -1,3 +0,0 @@
1
-<footer {{ $attributes->class(['inv-footer text-xs text-gray-600 dark:text-gray-300 min-h-60']) }}>
2
-    {{ $slot }}
3
-</footer>

+ 0
- 3
resources/views/components/company/invoice/header.blade.php View File

@@ -1,3 +0,0 @@
1
-<header {{ $attributes->class(['inv-header flex py-2 relative']) }}>
2
-    {{ $slot }}
3
-</header>

+ 0
- 3
resources/views/components/company/invoice/line-items.blade.php View File

@@ -1,3 +0,0 @@
1
-<div {{ $attributes->class(['inv-line-items py-6']) }}>
2
-    {{ $slot }}
3
-</div>

+ 0
- 3
resources/views/components/company/invoice/metadata.blade.php View File

@@ -1,3 +0,0 @@
1
-<section {{ $attributes->class(['inv-metadata px-6 pt-4']) }}>
2
-    {{ $slot }}
3
-</section>

+ 0
- 10
resources/views/components/icons/decor-border-left.blade.php View File

@@ -1,10 +0,0 @@
1
-@props([
2
-    'color' => 'currentColor',
3
-])
4
-
5
-<svg xmlns="http://www.w3.org/2000/svg" height="72" width="28" viewBox="0 0 28 72" aria-hidden="true" {{ $attributes }}>
6
-    <g fill="none" stroke-width="2" stroke="{{ $color }}">
7
-        <path d="M183 57.038v-42.076c-.33.025-.664.038-1 .038-7.18 0-13-5.82-13-13 0-.336.013-.67.038-1h-154.076c.025.33.038.664.038 1 0 7.18-5.82 13-13 13-.336 0-.67-.013-1-.038v42.076c.33-.025.664-.038 1-.038 7.18 0 13 5.82 13 13 0 .336-.013.67-.038 1h154.076c-.025-.33-.038-.664-.038-1 0-7.18 5.82-13 13-13 .336 0 .67.013 1 .038z" />
8
-        <path d="M177 51.503v-31.007c-.33.024-.664.037-1 .037-7.18 0-13-5.626-13-12.567 0-.325.013-.648.038-.967h-142.076c.025.319.038.641.038.967 0 6.94-5.82 12.567-13 12.567-.336 0-.67-.012-1-.037v31.007c.33-.024.664-.037 1-.037 7.18 0 13 5.626 13 12.567 0 .325-.013.648-.038.967h142.076c-.025-.319-.038-.641-.038-.967 0-6.94 5.82-12.567 13-12.567.336 0 .67.012 1 .037z" />
9
-    </g>
10
-</svg>

+ 0
- 10
resources/views/components/icons/decor-border-right.blade.php View File

@@ -1,10 +0,0 @@
1
-@props([
2
-    'color' => 'currentColor',
3
-])
4
-
5
-<svg xmlns="http://www.w3.org/2000/svg" height="72" width="28" viewBox="0 0 28 72" aria-hidden="true" {{ $attributes }}>
6
-    <g fill="none" stroke-width="2" stroke="{{ $color }}">
7
-        <path d="M27 57.038v-42.076c-.33.025-.664.038-1 .038-7.18 0-13-5.82-13-13 0-.336.013-.67.038-1h-154.076c.025.33.038.664.038 1 0 7.18-5.82 13-13 13-.336 0-.67-.013-1-.038v42.076c.33-.025.664-.038 1-.038 7.18 0 13 5.82 13 13 0 .336-.013.67-.038 1h154.076c-.025-.33-.038-.664-.038-1 0-7.18 5.82-13 13-13 .336 0 .67.013 1 .038z"></path>
8
-        <path d="M21 51.503v-31.007c-.33.024-.664.037-1 .037-7.18 0-13-5.626-13-12.567 0-.325.013-.648.038-.967h-142.076c.025.319.038.641.038.967 0 6.94-5.82 12.567-13 12.567-.336 0-.67-.012-1-.037v31.007c.33-.024.664-.037 1-.037 7.18 0 13 5.626 13 12.567 0 .325-.013.648-.038.967h142.076c-.025-.319-.038-.641-.038-.967 0-6.94 5.82-12.567 13-12.567.336 0 .67.012 1 .037z"></path>
9
-    </g>
10
-</svg>

resources/views/filament/company/components/invoice-layouts/classic.blade.php → resources/views/filament/company/components/document-templates/classic.blade.php View File

@@ -6,14 +6,14 @@
6 6
 {!! $document->getFontHtml() !!}
7 7
 
8 8
 <style>
9
-    .inv-paper {
9
+    .doc-template-paper {
10 10
         font-family: '{{ $document->font->getLabel() }}', sans-serif;
11 11
     }
12 12
 </style>
13 13
 
14
-<x-company.invoice.container class="classic-template-container" preview>
14
+<x-company.document-template.container class="classic-template-container" preview>
15 15
     <!-- Header Section -->
16
-    <x-company.invoice.header class="default-template-header">
16
+    <x-company.document-template.header class="default-template-header">
17 17
         <div class="w-2/3 text-left ml-6">
18 18
             <div class="text-xs">
19 19
                 <h2 class="text-base font-semibold">{{ $document->company->name }}</h2>
@@ -25,12 +25,12 @@
25 25
 
26 26
         <div class="w-1/3 flex justify-end mr-6">
27 27
             @if($document->logo && $document->showLogo)
28
-                <x-company.invoice.logo :src="$document->logo"/>
28
+                <x-company.document-template.logo :src="$document->logo"/>
29 29
             @endif
30 30
         </div>
31
-    </x-company.invoice.header>
31
+    </x-company.document-template.header>
32 32
 
33
-    <x-company.invoice.metadata class="classic-template-metadata">
33
+    <x-company.document-template.metadata class="classic-template-metadata">
34 34
         <div class="items-center flex">
35 35
             <hr class="grow-[2] py-0.5 border-solid border-y-2" style="border-color: {{ $document->accentColor }};">
36 36
             <x-icons.document-header-decoration
@@ -75,10 +75,10 @@
75 75
                 </table>
76 76
             </div>
77 77
         </div>
78
-    </x-company.invoice.metadata>
78
+    </x-company.document-template.metadata>
79 79
 
80 80
     <!-- Line Items -->
81
-    <x-company.invoice.line-items class="classic-template-line-items px-6">
81
+    <x-company.document-template.line-items class="classic-template-line-items px-6">
82 82
         <table class="w-full text-left table-fixed">
83 83
             <thead class="text-sm leading-8">
84 84
             <tr>
@@ -136,11 +136,11 @@
136 136
                 </table>
137 137
             </div>
138 138
         </div>
139
-    </x-company.invoice.line-items>
139
+    </x-company.document-template.line-items>
140 140
 
141 141
     <!-- Footer -->
142
-    <x-company.invoice.footer class="classic-template-footer">
142
+    <x-company.document-template.footer class="classic-template-footer">
143 143
         <h4 class="font-semibold px-6 mb-2">Terms & Conditions</h4>
144 144
         <p class="px-6 break-words line-clamp-4">{{ $document->terms }}</p>
145
-    </x-company.invoice.footer>
146
-</x-company.invoice.container>
145
+    </x-company.document-template.footer>
146
+</x-company.document-template.container>

resources/views/filament/company/components/invoice-layouts/default.blade.php → resources/views/filament/company/components/document-templates/default.blade.php View File

@@ -6,17 +6,17 @@
6 6
 {!! $document->getFontHtml() !!}
7 7
 
8 8
 <style>
9
-    .inv-paper {
9
+    .doc-template-paper {
10 10
         font-family: '{{ $document->font->getLabel() }}', sans-serif;
11 11
     }
12 12
 </style>
13 13
 
14
-<x-company.invoice.container class="default-template-container" preview>
14
+<x-company.document-template.container class="default-template-container" preview>
15 15
 
16
-    <x-company.invoice.header class="default-template-header border-b-2 p-6 pb-4">
16
+    <x-company.document-template.header class="default-template-header border-b-2 p-6 pb-4">
17 17
         <div class="w-2/3">
18 18
             @if($document->logo && $document->showLogo)
19
-                <x-company.invoice.logo :src="$document->logo"/>
19
+                <x-company.document-template.logo :src="$document->logo"/>
20 20
             @endif
21 21
         </div>
22 22
 
@@ -28,9 +28,9 @@
28 28
                 @endif
29 29
             </div>
30 30
         </div>
31
-    </x-company.invoice.header>
31
+    </x-company.document-template.header>
32 32
 
33
-    <x-company.invoice.metadata class="default-template-metadata space-y-6">
33
+    <x-company.document-template.metadata class="default-template-metadata space-y-6">
34 34
         <div>
35 35
             <h1 class="text-3xl font-light uppercase">{{ $document->header }}</h1>
36 36
             @if ($document->subheader)
@@ -71,10 +71,10 @@
71 71
                 </table>
72 72
             </div>
73 73
         </div>
74
-    </x-company.invoice.metadata>
74
+    </x-company.document-template.metadata>
75 75
 
76 76
     <!-- Line Items Table -->
77
-    <x-company.invoice.line-items class="default-template-line-items">
77
+    <x-company.document-template.line-items class="default-template-line-items">
78 78
         <table class="w-full text-left table-fixed">
79 79
             <thead class="text-sm leading-8" style="background: {{ $document->accentColor }}">
80 80
             <tr class="text-white">
@@ -122,13 +122,13 @@
122 122
             </tr>
123 123
             </tfoot>
124 124
         </table>
125
-    </x-company.invoice.line-items>
125
+    </x-company.document-template.line-items>
126 126
 
127 127
     <!-- Footer Notes -->
128
-    <x-company.invoice.footer class="default-template-footer">
128
+    <x-company.document-template.footer class="default-template-footer">
129 129
         <p class="px-6">{{ $document->footer }}</p>
130 130
         <span class="border-t-2 my-2 border-gray-300 block w-full"></span>
131 131
         <h4 class="font-semibold px-6 mb-2">Terms & Conditions</h4>
132 132
         <p class="px-6 break-words line-clamp-4">{{ $document->terms }}</p>
133
-    </x-company.invoice.footer>
134
-</x-company.invoice.container>
133
+    </x-company.document-template.footer>
134
+</x-company.document-template.container>

resources/views/filament/company/components/invoice-layouts/modern.blade.php → resources/views/filament/company/components/document-templates/modern.blade.php View File

@@ -6,19 +6,19 @@
6 6
 {!! $document->getFontHtml() !!}
7 7
 
8 8
 <style>
9
-    .inv-paper {
9
+    .doc-template-paper {
10 10
         font-family: '{{ $document->font->getLabel() }}', sans-serif;
11 11
     }
12 12
 </style>
13 13
 
14
-<x-company.invoice.container class="modern-template-container" preview>
14
+<x-company.document-template.container class="modern-template-container" preview>
15 15
 
16 16
     <!-- Colored Header with Logo -->
17
-    <x-company.invoice.header class="bg-gray-800 h-20">
17
+    <x-company.document-template.header class="bg-gray-800 h-20">
18 18
         <!-- Logo -->
19 19
         <div class="w-2/3">
20 20
             @if($document->logo && $document->showLogo)
21
-                <x-company.invoice.logo class="ml-6" :src="$document->logo"/>
21
+                <x-company.document-template.logo class="ml-6" :src="$document->logo"/>
22 22
             @endif
23 23
         </div>
24 24
 
@@ -29,10 +29,10 @@
29 29
                 <h1 class="text-3xl font-bold text-white text-center uppercase">{{ $document->header }}</h1>
30 30
             @endif
31 31
         </div>
32
-    </x-company.invoice.header>
32
+    </x-company.document-template.header>
33 33
 
34 34
     <!-- Company Details -->
35
-    <x-company.invoice.metadata class="modern-template-metadata space-y-6">
35
+    <x-company.document-template.metadata class="modern-template-metadata space-y-6">
36 36
         <div class="text-xs">
37 37
             <h2 class="text-base font-semibold">{{ $document->company->name }}</h2>
38 38
             @if($formattedAddress = $document->company->getFormattedAddressHtml())
@@ -77,10 +77,10 @@
77 77
                 </table>
78 78
             </div>
79 79
         </div>
80
-    </x-company.invoice.metadata>
80
+    </x-company.document-template.metadata>
81 81
 
82 82
     <!-- Line Items Table -->
83
-    <x-company.invoice.line-items class="modern-template-line-items">
83
+    <x-company.document-template.line-items class="modern-template-line-items">
84 84
         <table class="w-full text-left table-fixed">
85 85
             <thead class="text-sm leading-8">
86 86
             <tr class="text-gray-600 dark:text-gray-400">
@@ -143,15 +143,15 @@
143 143
             @endif
144 144
             </tfoot>
145 145
         </table>
146
-    </x-company.invoice.line-items>
146
+    </x-company.document-template.line-items>
147 147
 
148 148
     <!-- Footer Notes -->
149
-    <x-company.invoice.footer class="modern-template-footer tracking-tight">
149
+    <x-company.document-template.footer class="modern-template-footer tracking-tight">
150 150
         <h4 class="font-semibold px-6" style="color: {{ $document->accentColor }}">Terms & Conditions</h4>
151 151
         <span class="border-t-2 my-2 border-gray-300 block w-full"></span>
152 152
         <div class="flex justify-between space-x-4 px-6">
153 153
             <p class="w-1/2 break-words line-clamp-4">{{ $document->terms }}</p>
154 154
             <p class="w-1/2 break-words line-clamp-4">{{ $document->footer }}</p>
155 155
         </div>
156
-    </x-company.invoice.footer>
157
-</x-company.invoice.container>
156
+    </x-company.document-template.footer>
157
+</x-company.document-template.container>

+ 1
- 1
resources/views/filament/infolists/components/document-preview.blade.php View File

@@ -6,7 +6,7 @@
6 6
 {!! $document->getFontHtml() !!}
7 7
 
8 8
 <style>
9
-    .inv-paper {
9
+    .doc-template-paper {
10 10
         font-family: '{{ $document->font->getLabel() }}', sans-serif;
11 11
     }
12 12
 </style>

+ 11
- 11
resources/views/filament/infolists/components/document-templates/classic.blade.php View File

@@ -1,6 +1,6 @@
1
-<x-company.invoice.container class="classic-template-container">
1
+<x-company.document-template.container class="classic-template-container">
2 2
     <!-- Header Section -->
3
-    <x-company.invoice.header class="default-template-header">
3
+    <x-company.document-template.header class="default-template-header">
4 4
         <div class="w-2/3 text-left ml-6">
5 5
             <div class="text-sm tracking-tight">
6 6
                 <h2 class="text-lg font-semibold">{{ $document->company->name }}</h2>
@@ -12,12 +12,12 @@
12 12
 
13 13
         <div class="w-1/3 flex justify-end mr-6">
14 14
             @if($document->logo && $document->showLogo)
15
-                <x-company.invoice.logo :src="$document->logo"/>
15
+                <x-company.document-template.logo :src="$document->logo"/>
16 16
             @endif
17 17
         </div>
18
-    </x-company.invoice.header>
18
+    </x-company.document-template.header>
19 19
 
20
-    <x-company.invoice.metadata class="classic-template-metadata space-y-8">
20
+    <x-company.document-template.metadata class="classic-template-metadata space-y-8">
21 21
         <div class="items-center flex">
22 22
             <hr class="grow-[2] py-0.5 border-solid border-y-2" style="border-color: {{ $document->accentColor }};">
23 23
             <x-icons.document-header-decoration
@@ -62,10 +62,10 @@
62 62
                 </table>
63 63
             </div>
64 64
         </div>
65
-    </x-company.invoice.metadata>
65
+    </x-company.document-template.metadata>
66 66
 
67 67
     <!-- Line Items -->
68
-    <x-company.invoice.line-items class="classic-template-line-items">
68
+    <x-company.document-template.line-items class="classic-template-line-items">
69 69
         <table class="w-full text-left table-fixed">
70 70
             <thead class="text-sm leading-relaxed">
71 71
             <tr>
@@ -138,11 +138,11 @@
138 138
                 </table>
139 139
             </div>
140 140
         </div>
141
-    </x-company.invoice.line-items>
141
+    </x-company.document-template.line-items>
142 142
 
143 143
     <!-- Footer -->
144
-    <x-company.invoice.footer class="classic-template-footer tracking-tight min-h-48">
144
+    <x-company.document-template.footer class="classic-template-footer tracking-tight min-h-48">
145 145
         <h4 class="font-semibold px-6 mb-2 text-sm">Terms & Conditions</h4>
146 146
         <p class="px-6 break-words line-clamp-4 text-sm">{{ $document->terms }}</p>
147
-    </x-company.invoice.footer>
148
-</x-company.invoice.container>
147
+    </x-company.document-template.footer>
148
+</x-company.document-template.container>

+ 12
- 12
resources/views/filament/infolists/components/document-templates/default.blade.php View File

@@ -1,9 +1,9 @@
1
-<x-company.invoice.container class="default-template-container">
1
+<x-company.document-template.container class="default-template-container">
2 2
 
3
-    <x-company.invoice.header class="default-template-header border-b-2 p-6 pb-4">
3
+    <x-company.document-template.header class="default-template-header border-b-2 p-6 pb-4">
4 4
         <div class="w-2/3">
5 5
             @if($document->logo && $document->showLogo)
6
-                <x-company.invoice.logo :src="$document->logo"/>
6
+                <x-company.document-template.logo :src="$document->logo"/>
7 7
             @endif
8 8
         </div>
9 9
 
@@ -15,9 +15,9 @@
15 15
                 @endif
16 16
             </div>
17 17
         </div>
18
-    </x-company.invoice.header>
18
+    </x-company.document-template.header>
19 19
 
20
-    <x-company.invoice.metadata class="default-template-metadata space-y-8">
20
+    <x-company.document-template.metadata class="default-template-metadata space-y-8">
21 21
         <div>
22 22
             <h1 class="text-4xl font-light uppercase">{{ $document->header }}</h1>
23 23
             @if ($document->subheader)
@@ -60,10 +60,10 @@
60 60
                 </table>
61 61
             </div>
62 62
         </div>
63
-    </x-company.invoice.metadata>
63
+    </x-company.document-template.metadata>
64 64
 
65 65
     <!-- Line Items Table -->
66
-    <x-company.invoice.line-items class="default-template-line-items">
66
+    <x-company.document-template.line-items class="default-template-line-items">
67 67
         <table class="w-full text-left table-fixed">
68 68
             <thead class="text-sm leading-relaxed" style="background: {{ $document->accentColor }}">
69 69
             <tr class="text-white">
@@ -88,7 +88,7 @@
88 88
                 </tr>
89 89
             @endforeach
90 90
             </tbody>
91
-            <tfoot class="text-sm tracking-tight">
91
+            <tfoot class="text-sm tracking-tight summary-section">
92 92
             <tr>
93 93
                 <td class="pl-6 py-2" colspan="2"></td>
94 94
                 <td class="text-right font-semibold py-2">Subtotal:</td>
@@ -126,13 +126,13 @@
126 126
             @endif
127 127
             </tfoot>
128 128
         </table>
129
-    </x-company.invoice.line-items>
129
+    </x-company.document-template.line-items>
130 130
 
131 131
     <!-- Footer Notes -->
132
-    <x-company.invoice.footer class="default-template-footer tracking-tight">
132
+    <x-company.document-template.footer class="default-template-footer tracking-tight">
133 133
         <p class="px-6 text-sm">{{ $document->footer }}</p>
134 134
         <span class="border-t-2 my-2 border-gray-300 block w-full"></span>
135 135
         <h4 class="font-semibold px-6 mb-2 text-sm">Terms & Conditions</h4>
136 136
         <p class="px-6 break-words line-clamp-4 text-sm">{{ $document->terms }}</p>
137
-    </x-company.invoice.footer>
138
-</x-company.invoice.container>
137
+    </x-company.document-template.footer>
138
+</x-company.document-template.container>

+ 12
- 12
resources/views/filament/infolists/components/document-templates/modern.blade.php View File

@@ -1,10 +1,10 @@
1
-<x-company.invoice.container class="modern-template-container">
1
+<x-company.document-template.container class="modern-template-container">
2 2
     <!-- Colored Header with Logo -->
3
-    <x-company.invoice.header class="bg-gray-800 h-24">
3
+    <x-company.document-template.header class="bg-gray-800 h-24">
4 4
         <!-- Logo -->
5 5
         <div class="w-2/3">
6 6
             @if($document->logo && $document->showLogo)
7
-                <x-company.invoice.logo class="ml-8" :src="$document->logo"/>
7
+                <x-company.document-template.logo class="ml-8" :src="$document->logo"/>
8 8
             @endif
9 9
         </div>
10 10
 
@@ -15,10 +15,10 @@
15 15
                 <h1 class="text-4xl font-bold text-white text-center uppercase">{{ $document->header }}</h1>
16 16
             @endif
17 17
         </div>
18
-    </x-company.invoice.header>
18
+    </x-company.document-template.header>
19 19
 
20 20
     <!-- Company Details -->
21
-    <x-company.invoice.metadata class="modern-template-metadata space-y-8">
21
+    <x-company.document-template.metadata class="modern-template-metadata space-y-8">
22 22
         <div class="text-sm">
23 23
             <h2 class="text-lg font-semibold">{{ $document->company->name }}</h2>
24 24
             @if($formattedAddress = $document->company->getFormattedAddressHtml())
@@ -63,10 +63,10 @@
63 63
                 </table>
64 64
             </div>
65 65
         </div>
66
-    </x-company.invoice.metadata>
66
+    </x-company.document-template.metadata>
67 67
 
68 68
     <!-- Line Items Table -->
69
-    <x-company.invoice.line-items class="modern-template-line-items">
69
+    <x-company.document-template.line-items class="modern-template-line-items">
70 70
         <table class="w-full text-left table-fixed">
71 71
             <thead class="text-sm leading-relaxed">
72 72
             <tr class="text-gray-600 dark:text-gray-400">
@@ -91,7 +91,7 @@
91 91
                 </tr>
92 92
             @endforeach
93 93
             </tbody>
94
-            <tfoot class="text-sm tracking-tight">
94
+            <tfoot class="text-sm tracking-tight summary-section">
95 95
             <tr>
96 96
                 <td class="pl-6 py-2" colspan="2"></td>
97 97
                 <td class="text-right font-semibold py-2">Subtotal:</td>
@@ -129,10 +129,10 @@
129 129
             @endif
130 130
             </tfoot>
131 131
         </table>
132
-    </x-company.invoice.line-items>
132
+    </x-company.document-template.line-items>
133 133
 
134 134
     <!-- Footer Notes -->
135
-    <x-company.invoice.footer class="modern-template-footer tracking-tight">
135
+    <x-company.document-template.footer class="modern-template-footer tracking-tight">
136 136
         <h4 class="font-semibold px-6 text-sm" style="color: {{ $document->accentColor }}">
137 137
             Terms & Conditions
138 138
         </h4>
@@ -141,5 +141,5 @@
141 141
             <p class="w-1/2 break-words line-clamp-4">{{ $document->terms }}</p>
142 142
             <p class="w-1/2 break-words line-clamp-4">{{ $document->footer }}</p>
143 143
         </div>
144
-    </x-company.invoice.footer>
145
-</x-company.invoice.container>
144
+    </x-company.document-template.footer>
145
+</x-company.document-template.container>

+ 75
- 0
resources/views/print-document.blade.php View File

@@ -0,0 +1,75 @@
1
+<!DOCTYPE html>
2
+<html>
3
+<head>
4
+    <title>Invoice #{{ $document->number }}</title>
5
+    <meta charset="utf-8">
6
+    <meta name="viewport" content="width=device-width, initial-scale=1">
7
+
8
+    <!-- Include Tailwind -->
9
+    <script src="https://cdn.tailwindcss.com"></script>
10
+
11
+    {!! $document->getFontHtml() !!}
12
+
13
+    <style>
14
+        body {
15
+            background-color: white;
16
+            color: black;
17
+        }
18
+
19
+        .doc-template-paper {
20
+            font-family: '{{ $document->font->getLabel() }}', sans-serif;
21
+        }
22
+
23
+        @media print {
24
+            body {
25
+                print-color-adjust: exact !important;
26
+                -webkit-print-color-adjust: exact !important;
27
+                margin: 0;
28
+                padding: 0;
29
+            }
30
+
31
+            @page {
32
+                size: auto;
33
+                margin: 7.5mm 0;
34
+            }
35
+
36
+            @page:first {
37
+                margin-top: 0;
38
+            }
39
+
40
+            .doc-template-container {
41
+                padding: 0 !important;
42
+                margin: 0 !important;
43
+            }
44
+
45
+            .doc-template-paper {
46
+                box-shadow: none !important;
47
+                border-radius: 0 !important;
48
+                overflow: hidden !important;
49
+                max-height: none !important;
50
+            }
51
+
52
+            .doc-template-line-items .summary-section {
53
+                display: table-row-group;
54
+                page-break-inside: avoid;
55
+            }
56
+
57
+            .doc-template-line-items tr {
58
+                page-break-inside: avoid;
59
+                page-break-after: auto;
60
+            }
61
+
62
+            .doc-template-footer {
63
+                page-break-inside: avoid;
64
+                page-break-before: auto;
65
+            }
66
+        }
67
+    </style>
68
+</head>
69
+<body>
70
+    @include("filament.infolists.components.document-templates.{$template->value}", [
71
+        'document' => $document,
72
+        'preview' => false,
73
+    ])
74
+</body>
75
+</html>

+ 6
- 0
routes/web.php View File

@@ -1,7 +1,13 @@
1 1
 <?php
2 2
 
3
+use App\Http\Controllers\DocumentPrintController;
3 4
 use Illuminate\Support\Facades\Route;
4 5
 
5 6
 Route::get('/', function () {
6 7
     return view('welcome');
7 8
 });
9
+
10
+Route::middleware(['auth'])->group(function () {
11
+    Route::get('documents/{documentType}/{id}/print', [DocumentPrintController::class, 'show'])
12
+        ->name('documents.print');
13
+});

+ 1
- 0
vite.config.js View File

@@ -6,6 +6,7 @@ export default defineConfig({
6 6
         laravel({
7 7
             input: [
8 8
                 'resources/js/app.js',
9
+                'resources/css/app.css',
9 10
                 'resources/css/filament/company/theme.css',
10 11
                 'resources/css/filament/user/theme.css',
11 12
             ],

Loading…
Cancel
Save