Andrew Wallo 7 月之前
父節點
當前提交
5599076abb
共有 36 個檔案被更改,包括 482 行新增1146 行删除
  1. 1
    1
      app/DTO/DocumentDTO.php
  2. 2
    4
      app/DTO/DocumentPreviewDTO.php
  3. 14
    4
      app/Enums/Accounting/DocumentType.php
  4. 0
    187
      app/Filament/Company/Clusters/Settings/Pages/Appearance.php
  5. 0
    350
      app/Filament/Company/Clusters/Settings/Pages/Invoice.php
  6. 103
    96
      app/Filament/Company/Clusters/Settings/Resources/DocumentDefaultResource.php
  7. 0
    11
      app/Filament/Company/Clusters/Settings/Resources/DocumentDefaultResource/Pages/CreateDocumentDefault.php
  8. 12
    5
      app/Filament/Company/Clusters/Settings/Resources/DocumentDefaultResource/Pages/EditDocumentDefault.php
  9. 0
    8
      app/Filament/Company/Clusters/Settings/Resources/DocumentDefaultResource/Pages/ListDocumentDefaults.php
  10. 1
    1
      app/Filament/Company/Resources/Purchases/BillResource.php
  11. 24
    12
      app/Filament/Company/Resources/Sales/EstimateResource.php
  12. 24
    13
      app/Filament/Company/Resources/Sales/InvoiceResource.php
  13. 22
    11
      app/Filament/Company/Resources/Sales/RecurringInvoiceResource.php
  14. 16
    0
      app/Filament/Forms/Components/DocumentFooterSection.php
  15. 2
    2
      app/Filament/Forms/Components/DocumentHeaderSection.php
  16. 0
    7
      app/Listeners/ConfigureCompanyDefault.php
  17. 6
    8
      app/Models/Accounting/Bill.php
  18. 7
    9
      app/Models/Accounting/Estimate.php
  19. 3
    6
      app/Models/Accounting/Invoice.php
  20. 0
    6
      app/Models/Company.php
  21. 0
    39
      app/Models/Setting/Appearance.php
  22. 6
    32
      app/Models/Setting/DocumentDefault.php
  23. 1
    17
      app/Services/CompanySettingsService.php
  24. 104
    104
      composer.lock
  25. 6
    5
      database/factories/Accounting/BillFactory.php
  26. 6
    5
      database/factories/Accounting/EstimateFactory.php
  27. 6
    5
      database/factories/Accounting/InvoiceFactory.php
  28. 1
    1
      database/factories/Accounting/RecurringInvoiceFactory.php
  29. 0
    24
      database/factories/Setting/AppearanceFactory.php
  30. 0
    11
      database/factories/Setting/CompanyDefaultFactory.php
  31. 23
    9
      database/factories/Setting/DocumentDefaultFactory.php
  32. 0
    32
      database/migrations/2023_09_12_014413_create_appearances_table.php
  33. 3
    5
      database/migrations/2023_09_12_032057_create_document_defaults_table.php
  34. 89
    89
      package-lock.json
  35. 0
    17
      resources/views/filament/company/pages/setting/appearance.blade.php
  36. 0
    10
      resources/views/filament/company/pages/setting/invoice.blade.php

+ 1
- 1
app/DTO/DocumentDTO.php 查看文件

46
         /** @var DocumentDefault $settings */
46
         /** @var DocumentDefault $settings */
47
         $settings = $document->company->documentDefaults()
47
         $settings = $document->company->documentDefaults()
48
             ->type($document::documentType())
48
             ->type($document::documentType())
49
-            ->first();
49
+            ->first() ?? $document->company->defaultInvoice;
50
 
50
 
51
         $currencyCode = $document->currency_code ?? CurrencyAccessor::getDefaultCurrency();
51
         $currencyCode = $document->currency_code ?? CurrencyAccessor::getDefaultCurrency();
52
 
52
 

+ 2
- 4
app/DTO/DocumentPreviewDTO.php 查看文件

22
             terms: $data['terms'] ?? $settings->terms,
22
             terms: $data['terms'] ?? $settings->terms,
23
             logo: $settings->logo_url,
23
             logo: $settings->logo_url,
24
             number: self::generatePreviewNumber($settings, $data),
24
             number: self::generatePreviewNumber($settings, $data),
25
-            referenceNumber: 'ORD-00001',
25
+            referenceNumber: $settings->getNumberNext('ORD-'),
26
             date: $company->locale->date_format->getLabel(),
26
             date: $company->locale->date_format->getLabel(),
27
             dueDate: $paymentTerms->getDueDate($company->locale->date_format->value),
27
             dueDate: $paymentTerms->getDueDate($company->locale->date_format->value),
28
             currencyCode: CurrencyAccessor::getDefaultCurrency(),
28
             currencyCode: CurrencyAccessor::getDefaultCurrency(),
45
     protected static function generatePreviewNumber(DocumentDefault $settings, ?array $data): string
45
     protected static function generatePreviewNumber(DocumentDefault $settings, ?array $data): string
46
     {
46
     {
47
         $prefix = $data['number_prefix'] ?? $settings->number_prefix ?? 'INV-';
47
         $prefix = $data['number_prefix'] ?? $settings->number_prefix ?? 'INV-';
48
-        $digits = $data['number_digits'] ?? $settings->number_digits ?? 5;
49
-        $next = $data['number_next'] ?? $settings->number_next;
50
 
48
 
51
-        return $settings->getNumberNext(padded: true, format: true, prefix: $prefix, digits: $digits, next: $next);
49
+        return $settings->getNumberNext($prefix);
52
     }
50
     }
53
 
51
 
54
     protected static function generateColumnLabels(DocumentDefault $settings, ?array $data): DocumentColumnLabelDTO
52
     protected static function generateColumnLabels(DocumentDefault $settings, ?array $data): DocumentColumnLabelDTO

+ 14
- 4
app/Enums/Accounting/DocumentType.php 查看文件

58
     {
58
     {
59
         return match ($this) {
59
         return match ($this) {
60
             self::Invoice => new DocumentLabelDTO(
60
             self::Invoice => new DocumentLabelDTO(
61
-                title: 'Invoice',
61
+                title: self::Invoice->getLabel(),
62
                 number: 'Invoice Number',
62
                 number: 'Invoice Number',
63
                 referenceNumber: 'P.O/S.O Number',
63
                 referenceNumber: 'P.O/S.O Number',
64
                 date: 'Invoice Date',
64
                 date: 'Invoice Date',
66
                 amountDue: 'Amount Due',
66
                 amountDue: 'Amount Due',
67
             ),
67
             ),
68
             self::RecurringInvoice => new DocumentLabelDTO(
68
             self::RecurringInvoice => new DocumentLabelDTO(
69
-                title: 'Recurring Invoice',
69
+                title: self::RecurringInvoice->getLabel(),
70
                 number: 'Invoice Number',
70
                 number: 'Invoice Number',
71
                 referenceNumber: 'P.O/S.O Number',
71
                 referenceNumber: 'P.O/S.O Number',
72
                 date: 'Invoice Date',
72
                 date: 'Invoice Date',
74
                 amountDue: 'Amount Due',
74
                 amountDue: 'Amount Due',
75
             ),
75
             ),
76
             self::Estimate => new DocumentLabelDTO(
76
             self::Estimate => new DocumentLabelDTO(
77
-                title: 'Estimate',
77
+                title: self::Estimate->getLabel(),
78
                 number: 'Estimate Number',
78
                 number: 'Estimate Number',
79
                 referenceNumber: 'Reference Number',
79
                 referenceNumber: 'Reference Number',
80
                 date: 'Estimate Date',
80
                 date: 'Estimate Date',
82
                 amountDue: 'Grand Total',
82
                 amountDue: 'Grand Total',
83
             ),
83
             ),
84
             self::Bill => new DocumentLabelDTO(
84
             self::Bill => new DocumentLabelDTO(
85
-                title: 'Bill',
85
+                title: self::Bill->getLabel(),
86
                 number: 'Bill Number',
86
                 number: 'Bill Number',
87
                 referenceNumber: 'P.O/S.O Number',
87
                 referenceNumber: 'P.O/S.O Number',
88
                 date: 'Bill Date',
88
                 date: 'Bill Date',
91
             ),
91
             ),
92
         };
92
         };
93
     }
93
     }
94
+
95
+    public function getDefaultPrefix(): ?string
96
+    {
97
+        return match ($this) {
98
+            self::Invoice => 'INV-',
99
+            self::Estimate => 'EST-',
100
+            self::Bill => 'BILL-',
101
+            default => null,
102
+        };
103
+    }
94
 }
104
 }

+ 0
- 187
app/Filament/Company/Clusters/Settings/Pages/Appearance.php 查看文件

1
-<?php
2
-
3
-namespace App\Filament\Company\Clusters\Settings\Pages;
4
-
5
-use App\Enums\Setting\Font;
6
-use App\Enums\Setting\PrimaryColor;
7
-use App\Filament\Company\Clusters\Settings;
8
-use App\Models\Setting\Appearance as AppearanceModel;
9
-use App\Services\CompanySettingsService;
10
-use Filament\Actions\Action;
11
-use Filament\Actions\ActionGroup;
12
-use Filament\Forms\Components\Component;
13
-use Filament\Forms\Components\Section;
14
-use Filament\Forms\Components\Select;
15
-use Filament\Forms\Form;
16
-use Filament\Notifications\Notification;
17
-use Filament\Pages\Concerns\InteractsWithFormActions;
18
-use Filament\Pages\Page;
19
-use Filament\Support\Enums\MaxWidth;
20
-use Filament\Support\Exceptions\Halt;
21
-use Illuminate\Auth\Access\AuthorizationException;
22
-use Illuminate\Contracts\Support\Htmlable;
23
-use Illuminate\Database\Eloquent\Model;
24
-use Livewire\Attributes\Locked;
25
-
26
-use function Filament\authorize;
27
-
28
-/**
29
- * @property Form $form
30
- */
31
-class Appearance extends Page
32
-{
33
-    use InteractsWithFormActions;
34
-
35
-    protected static ?string $title = 'Appearance';
36
-
37
-    protected static string $view = 'filament.company.pages.setting.appearance';
38
-
39
-    protected static ?string $cluster = Settings::class;
40
-
41
-    public ?array $data = [];
42
-
43
-    #[Locked]
44
-    public ?AppearanceModel $record = null;
45
-
46
-    public function getTitle(): string | Htmlable
47
-    {
48
-        return translate(static::$title);
49
-    }
50
-
51
-    public function getMaxContentWidth(): MaxWidth | string | null
52
-    {
53
-        return MaxWidth::ScreenTwoExtraLarge;
54
-    }
55
-
56
-    public static function getNavigationLabel(): string
57
-    {
58
-        return translate(static::$title);
59
-    }
60
-
61
-    public function mount(): void
62
-    {
63
-        $this->record = AppearanceModel::firstOrNew([
64
-            'company_id' => auth()->user()->currentCompany->id,
65
-        ]);
66
-
67
-        abort_unless(static::canView($this->record), 404);
68
-
69
-        $this->fillForm();
70
-    }
71
-
72
-    public function fillForm(): void
73
-    {
74
-        $data = $this->record->attributesToArray();
75
-
76
-        $this->form->fill($data);
77
-    }
78
-
79
-    public function save(): void
80
-    {
81
-        try {
82
-            $data = $this->form->getState();
83
-
84
-            $this->handleRecordUpdate($this->record, $data);
85
-
86
-        } catch (Halt $exception) {
87
-            return;
88
-        }
89
-
90
-        $this->getSavedNotification()->send();
91
-    }
92
-
93
-    protected function getSavedNotification(): Notification
94
-    {
95
-        return Notification::make()
96
-            ->success()
97
-            ->title(__('filament-panels::resources/pages/edit-record.notifications.saved.title'));
98
-    }
99
-
100
-    public function form(Form $form): Form
101
-    {
102
-        return $form
103
-            ->schema([
104
-                $this->getGeneralSection(),
105
-            ])
106
-            ->model($this->record)
107
-            ->statePath('data')
108
-            ->operation('edit');
109
-    }
110
-
111
-    protected function getGeneralSection(): Component
112
-    {
113
-        return Section::make('General')
114
-            ->schema([
115
-                Select::make('primary_color')
116
-                    ->allowHtml()
117
-                    ->softRequired()
118
-                    ->localizeLabel()
119
-                    ->options(
120
-                        collect(PrimaryColor::cases())
121
-                            ->sort(static fn ($a, $b) => $a->value <=> $b->value)
122
-                            ->mapWithKeys(static fn ($case) => [
123
-                                $case->value => "<span class='flex items-center gap-x-4'>
124
-                                <span class='rounded-full w-4 h-4' style='background:rgb(" . $case->getColor()[600] . ")'></span>
125
-                                <span>" . $case->getLabel() . '</span>
126
-                                </span>',
127
-                            ]),
128
-                    ),
129
-                Select::make('font')
130
-                    ->allowHtml()
131
-                    ->softRequired()
132
-                    ->localizeLabel()
133
-                    ->options(
134
-                        collect(Font::cases())
135
-                            ->mapWithKeys(static fn ($case) => [
136
-                                $case->value => "<span style='font-family:{$case->getLabel()}'>{$case->getLabel()}</span>",
137
-                            ]),
138
-                    ),
139
-            ])->columns();
140
-    }
141
-
142
-    protected function handleRecordUpdate(AppearanceModel $record, array $data): AppearanceModel
143
-    {
144
-        $record->fill($data);
145
-
146
-        $keysToWatch = [
147
-            'primary_color',
148
-            'font',
149
-        ];
150
-
151
-        if ($record->isDirty($keysToWatch)) {
152
-            CompanySettingsService::invalidateSettings($record->company_id);
153
-            $this->dispatch('appearanceUpdated');
154
-        }
155
-
156
-        $record->save();
157
-
158
-        return $record;
159
-    }
160
-
161
-    /**
162
-     * @return array<Action | ActionGroup>
163
-     */
164
-    protected function getFormActions(): array
165
-    {
166
-        return [
167
-            $this->getSaveFormAction(),
168
-        ];
169
-    }
170
-
171
-    protected function getSaveFormAction(): Action
172
-    {
173
-        return Action::make('save')
174
-            ->label(__('filament-panels::resources/pages/edit-record.form.actions.save.label'))
175
-            ->submit('save')
176
-            ->keyBindings(['mod+s']);
177
-    }
178
-
179
-    public static function canView(Model $record): bool
180
-    {
181
-        try {
182
-            return authorize('update', $record)->allowed();
183
-        } catch (AuthorizationException $exception) {
184
-            return $exception->toResponse()->allowed();
185
-        }
186
-    }
187
-}

+ 0
- 350
app/Filament/Company/Clusters/Settings/Pages/Invoice.php 查看文件

1
-<?php
2
-
3
-namespace App\Filament\Company\Clusters\Settings\Pages;
4
-
5
-use App\Enums\Accounting\DocumentType;
6
-use App\Enums\Setting\Font;
7
-use App\Enums\Setting\PaymentTerms;
8
-use App\Enums\Setting\Template;
9
-use App\Filament\Company\Clusters\Settings;
10
-use App\Models\Setting\DocumentDefault as InvoiceModel;
11
-use Filament\Actions\Action;
12
-use Filament\Actions\ActionGroup;
13
-use Filament\Forms\Components\Checkbox;
14
-use Filament\Forms\Components\ColorPicker;
15
-use Filament\Forms\Components\Component;
16
-use Filament\Forms\Components\FileUpload;
17
-use Filament\Forms\Components\Grid;
18
-use Filament\Forms\Components\Section;
19
-use Filament\Forms\Components\Select;
20
-use Filament\Forms\Components\Textarea;
21
-use Filament\Forms\Components\TextInput;
22
-use Filament\Forms\Components\ViewField;
23
-use Filament\Forms\Form;
24
-use Filament\Forms\Get;
25
-use Filament\Forms\Set;
26
-use Filament\Notifications\Notification;
27
-use Filament\Pages\Concerns\InteractsWithFormActions;
28
-use Filament\Pages\Page;
29
-use Filament\Support\Enums\MaxWidth;
30
-use Filament\Support\Exceptions\Halt;
31
-use Illuminate\Auth\Access\AuthorizationException;
32
-use Illuminate\Contracts\Support\Htmlable;
33
-use Illuminate\Database\Eloquent\Model;
34
-use Illuminate\Support\Facades\Auth;
35
-use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
36
-
37
-use function Filament\authorize;
38
-
39
-/**
40
- * @property Form $form
41
- */
42
-class Invoice extends Page
43
-{
44
-    use InteractsWithFormActions;
45
-
46
-    protected static ?string $title = 'Invoice';
47
-
48
-    protected static string $view = 'filament.company.pages.setting.invoice';
49
-
50
-    protected static ?string $cluster = Settings::class;
51
-
52
-    public ?array $data = [];
53
-
54
-    public ?InvoiceModel $record = null;
55
-
56
-    public function getTitle(): string | Htmlable
57
-    {
58
-        return translate(static::$title);
59
-    }
60
-
61
-    public static function getNavigationLabel(): string
62
-    {
63
-        return translate(static::$title);
64
-    }
65
-
66
-    public function getMaxContentWidth(): MaxWidth | string | null
67
-    {
68
-        return MaxWidth::ScreenTwoExtraLarge;
69
-    }
70
-
71
-    public function mount(): void
72
-    {
73
-        $this->record = InvoiceModel::invoice()
74
-            ->firstOrNew([
75
-                'company_id' => auth()->user()->currentCompany->id,
76
-                'type' => DocumentType::Invoice->value,
77
-            ]);
78
-
79
-        abort_unless(static::canView($this->record), 404);
80
-
81
-        $this->fillForm();
82
-    }
83
-
84
-    public function fillForm(): void
85
-    {
86
-        $data = $this->record->attributesToArray();
87
-
88
-        $this->form->fill($data);
89
-    }
90
-
91
-    public function save(): void
92
-    {
93
-        try {
94
-            $data = $this->form->getState();
95
-
96
-            $this->handleRecordUpdate($this->record, $data);
97
-
98
-        } catch (Halt $exception) {
99
-            return;
100
-        }
101
-
102
-        $this->getSavedNotification()->send();
103
-    }
104
-
105
-    protected function getSavedNotification(): Notification
106
-    {
107
-        return Notification::make()
108
-            ->success()
109
-            ->title(__('filament-panels::resources/pages/edit-record.notifications.saved.title'));
110
-    }
111
-
112
-    public function form(Form $form): Form
113
-    {
114
-        return $form
115
-            ->live()
116
-            ->schema([
117
-                $this->getGeneralSection(),
118
-                $this->getContentSection(),
119
-                $this->getTemplateSection(),
120
-            ])
121
-            ->model($this->record)
122
-            ->statePath('data')
123
-            ->operation('edit');
124
-    }
125
-
126
-    protected function getGeneralSection(): Component
127
-    {
128
-        return Section::make('General')
129
-            ->schema([
130
-                TextInput::make('number_prefix')
131
-                    ->localizeLabel()
132
-                    ->nullable(),
133
-                Select::make('number_digits')
134
-                    ->softRequired()
135
-                    ->localizeLabel()
136
-                    ->options(InvoiceModel::availableNumberDigits()),
137
-                TextInput::make('number_next')
138
-                    ->softRequired()
139
-                    ->localizeLabel()
140
-                    ->mask(static function (Get $get) {
141
-                        return str_repeat('9', $get('number_digits'));
142
-                    })
143
-                    ->hint(function (Get $get, $state) {
144
-                        $number_prefix = $get('number_prefix');
145
-                        $number_digits = $get('number_digits');
146
-                        $number_next = $state;
147
-
148
-                        return $this->record->getNumberNext(true, true, $number_prefix, $number_digits, $number_next);
149
-                    }),
150
-                Select::make('payment_terms')
151
-                    ->softRequired()
152
-                    ->localizeLabel()
153
-                    ->options(PaymentTerms::class),
154
-            ])->columns();
155
-    }
156
-
157
-    protected function getContentSection(): Component
158
-    {
159
-        return Section::make('Content')
160
-            ->schema([
161
-                TextInput::make('header')
162
-                    ->localizeLabel()
163
-                    ->nullable(),
164
-                TextInput::make('subheader')
165
-                    ->localizeLabel()
166
-                    ->nullable(),
167
-                Textarea::make('terms')
168
-                    ->localizeLabel()
169
-                    ->nullable(),
170
-                Textarea::make('footer')
171
-                    ->localizeLabel('Footer')
172
-                    ->nullable(),
173
-            ])->columns();
174
-    }
175
-
176
-    protected function getTemplateSection(): Component
177
-    {
178
-        return Section::make('Template')
179
-            ->description('Choose the template and edit the column names.')
180
-            ->schema([
181
-                Grid::make(1)
182
-                    ->schema([
183
-                        FileUpload::make('logo')
184
-                            ->openable()
185
-                            ->maxSize(1024)
186
-                            ->localizeLabel()
187
-                            ->visibility('public')
188
-                            ->disk('public')
189
-                            ->directory('logos/document')
190
-                            ->imageResizeMode('contain')
191
-                            ->imageCropAspectRatio('3:2')
192
-                            ->panelAspectRatio('3:2')
193
-                            ->panelLayout('integrated')
194
-                            ->removeUploadedFileButtonPosition('center bottom')
195
-                            ->uploadButtonPosition('center bottom')
196
-                            ->uploadProgressIndicatorPosition('center bottom')
197
-                            ->getUploadedFileNameForStorageUsing(
198
-                                static fn (TemporaryUploadedFile $file): string => (string) str($file->getClientOriginalName())
199
-                                    ->prepend(Auth::user()->currentCompany->id . '_'),
200
-                            )
201
-                            ->extraAttributes([
202
-                                'class' => 'aspect-[3/2] w-[9.375rem] max-w-full',
203
-                            ])
204
-                            ->acceptedFileTypes(['image/png', 'image/jpeg', 'image/gif']),
205
-                        Checkbox::make('show_logo')
206
-                            ->localizeLabel(),
207
-                        ColorPicker::make('accent_color')
208
-                            ->localizeLabel(),
209
-                        Select::make('font')
210
-                            ->softRequired()
211
-                            ->localizeLabel()
212
-                            ->allowHtml()
213
-                            ->options(
214
-                                collect(Font::cases())
215
-                                    ->mapWithKeys(static fn ($case) => [
216
-                                        $case->value => "<span style='font-family:{$case->getLabel()}'>{$case->getLabel()}</span>",
217
-                                    ]),
218
-                            ),
219
-                        Select::make('template')
220
-                            ->softRequired()
221
-                            ->localizeLabel()
222
-                            ->options(Template::class),
223
-                        Select::make('item_name.option')
224
-                            ->softRequired()
225
-                            ->localizeLabel('Item name')
226
-                            ->options(InvoiceModel::getAvailableItemNameOptions())
227
-                            ->afterStateUpdated(static function (Get $get, Set $set, $state, $old) {
228
-                                if ($state !== 'other' && $old === 'other' && filled($get('item_name.custom'))) {
229
-                                    $set('item_name.old_custom', $get('item_name.custom'));
230
-                                    $set('item_name.custom', null);
231
-                                }
232
-
233
-                                if ($state === 'other' && $old !== 'other') {
234
-                                    $set('item_name.custom', $get('item_name.old_custom'));
235
-                                }
236
-                            }),
237
-                        TextInput::make('item_name.custom')
238
-                            ->hiddenLabel()
239
-                            ->disabled(static fn (callable $get) => $get('item_name.option') !== 'other')
240
-                            ->nullable(),
241
-                        Select::make('unit_name.option')
242
-                            ->softRequired()
243
-                            ->localizeLabel('Unit name')
244
-                            ->options(InvoiceModel::getAvailableUnitNameOptions())
245
-                            ->afterStateUpdated(static function (Get $get, Set $set, $state, $old) {
246
-                                if ($state !== 'other' && $old === 'other' && filled($get('unit_name.custom'))) {
247
-                                    $set('unit_name.old_custom', $get('unit_name.custom'));
248
-                                    $set('unit_name.custom', null);
249
-                                }
250
-
251
-                                if ($state === 'other' && $old !== 'other') {
252
-                                    $set('unit_name.custom', $get('unit_name.old_custom'));
253
-                                }
254
-                            }),
255
-                        TextInput::make('unit_name.custom')
256
-                            ->hiddenLabel()
257
-                            ->disabled(static fn (callable $get) => $get('unit_name.option') !== 'other')
258
-                            ->nullable(),
259
-                        Select::make('price_name.option')
260
-                            ->softRequired()
261
-                            ->localizeLabel('Price name')
262
-                            ->options(InvoiceModel::getAvailablePriceNameOptions())
263
-                            ->afterStateUpdated(static function (Get $get, Set $set, $state, $old) {
264
-                                if ($state !== 'other' && $old === 'other' && filled($get('price_name.custom'))) {
265
-                                    $set('price_name.old_custom', $get('price_name.custom'));
266
-                                    $set('price_name.custom', null);
267
-                                }
268
-
269
-                                if ($state === 'other' && $old !== 'other') {
270
-                                    $set('price_name.custom', $get('price_name.old_custom'));
271
-                                }
272
-                            }),
273
-                        TextInput::make('price_name.custom')
274
-                            ->hiddenLabel()
275
-                            ->disabled(static fn (callable $get) => $get('price_name.option') !== 'other')
276
-                            ->nullable(),
277
-                        Select::make('amount_name.option')
278
-                            ->softRequired()
279
-                            ->localizeLabel('Amount name')
280
-                            ->options(InvoiceModel::getAvailableAmountNameOptions())
281
-                            ->afterStateUpdated(static function (Get $get, Set $set, $state, $old) {
282
-                                if ($state !== 'other' && $old === 'other' && filled($get('amount_name.custom'))) {
283
-                                    $set('amount_name.old_custom', $get('amount_name.custom'));
284
-                                    $set('amount_name.custom', null);
285
-                                }
286
-
287
-                                if ($state === 'other' && $old !== 'other') {
288
-                                    $set('amount_name.custom', $get('amount_name.old_custom'));
289
-                                }
290
-                            }),
291
-                        TextInput::make('amount_name.custom')
292
-                            ->hiddenLabel()
293
-                            ->disabled(static fn (callable $get) => $get('amount_name.option') !== 'other')
294
-                            ->nullable(),
295
-                    ])->columnSpan(1),
296
-                Grid::make()
297
-                    ->schema([
298
-                        ViewField::make('preview.default')
299
-                            ->columnSpan(2)
300
-                            ->hiddenLabel()
301
-                            ->visible(static fn (Get $get) => $get('template') === 'default')
302
-                            ->view('filament.company.components.invoice-layouts.default'),
303
-                        ViewField::make('preview.modern')
304
-                            ->columnSpan(2)
305
-                            ->hiddenLabel()
306
-                            ->visible(static fn (Get $get) => $get('template') === 'modern')
307
-                            ->view('filament.company.components.invoice-layouts.modern'),
308
-                        ViewField::make('preview.classic')
309
-                            ->columnSpan(2)
310
-                            ->hiddenLabel()
311
-                            ->visible(static fn (Get $get) => $get('template') === 'classic')
312
-                            ->view('filament.company.components.invoice-layouts.classic'),
313
-                    ])->columnSpan(2),
314
-            ])->columns(3);
315
-    }
316
-
317
-    protected function handleRecordUpdate(InvoiceModel $record, array $data): InvoiceModel
318
-    {
319
-        $record->update($data);
320
-
321
-        return $record;
322
-    }
323
-
324
-    /**
325
-     * @return array<Action | ActionGroup>
326
-     */
327
-    protected function getFormActions(): array
328
-    {
329
-        return [
330
-            $this->getSaveFormAction(),
331
-        ];
332
-    }
333
-
334
-    protected function getSaveFormAction(): Action
335
-    {
336
-        return Action::make('save')
337
-            ->label(__('filament-panels::resources/pages/edit-record.form.actions.save.label'))
338
-            ->submit('save')
339
-            ->keyBindings(['mod+s']);
340
-    }
341
-
342
-    public static function canView(Model $record): bool
343
-    {
344
-        try {
345
-            return authorize('update', $record)->allowed();
346
-        } catch (AuthorizationException $exception) {
347
-            return $exception->toResponse()->allowed();
348
-        }
349
-    }
350
-}

+ 103
- 96
app/Filament/Company/Clusters/Settings/Resources/DocumentDefaultResource.php 查看文件

2
 
2
 
3
 namespace App\Filament\Company\Clusters\Settings\Resources;
3
 namespace App\Filament\Company\Clusters\Settings\Resources;
4
 
4
 
5
+use App\Enums\Accounting\DocumentType;
5
 use App\Enums\Setting\Font;
6
 use App\Enums\Setting\Font;
6
 use App\Enums\Setting\PaymentTerms;
7
 use App\Enums\Setting\PaymentTerms;
7
 use App\Enums\Setting\Template;
8
 use App\Enums\Setting\Template;
8
 use App\Filament\Company\Clusters\Settings;
9
 use App\Filament\Company\Clusters\Settings;
9
 use App\Filament\Company\Clusters\Settings\Resources\DocumentDefaultResource\Pages;
10
 use App\Filament\Company\Clusters\Settings\Resources\DocumentDefaultResource\Pages;
10
 use App\Models\Setting\DocumentDefault;
11
 use App\Models\Setting\DocumentDefault;
11
-use App\Models\Setting\DocumentDefault as InvoiceModel;
12
 use Filament\Forms;
12
 use Filament\Forms;
13
 use Filament\Forms\Components\Component;
13
 use Filament\Forms\Components\Component;
14
 use Filament\Forms\Form;
14
 use Filament\Forms\Form;
34
                 self::getGeneralSection(),
34
                 self::getGeneralSection(),
35
                 self::getContentSection(),
35
                 self::getContentSection(),
36
                 self::getTemplateSection(),
36
                 self::getTemplateSection(),
37
+                self::getBillColumnLabelsSection(),
37
             ]);
38
             ]);
38
     }
39
     }
39
 
40
 
44
                 Forms\Components\TextInput::make('number_prefix')
45
                 Forms\Components\TextInput::make('number_prefix')
45
                     ->localizeLabel()
46
                     ->localizeLabel()
46
                     ->nullable(),
47
                     ->nullable(),
47
-                Forms\Components\Select::make('number_digits')
48
-                    ->softRequired()
49
-                    ->localizeLabel()
50
-                    ->options(InvoiceModel::availableNumberDigits()),
51
-                Forms\Components\TextInput::make('number_next')
52
-                    ->softRequired()
53
-                    ->localizeLabel()
54
-                    ->mask(static function (Get $get) {
55
-                        return str_repeat('9', $get('number_digits'));
56
-                    })
57
-                    ->hint(function (Get $get, $state, DocumentDefault $record) {
58
-                        $number_prefix = $get('number_prefix');
59
-                        $number_digits = $get('number_digits');
60
-                        $number_next = $state;
61
-
62
-                        return $record->getNumberNext(true, true, $number_prefix, $number_digits, $number_next);
63
-                    }),
64
                 Forms\Components\Select::make('payment_terms')
48
                 Forms\Components\Select::make('payment_terms')
65
                     ->softRequired()
49
                     ->softRequired()
66
                     ->localizeLabel()
50
                     ->localizeLabel()
71
     public static function getContentSection(): Forms\Components\Component
55
     public static function getContentSection(): Forms\Components\Component
72
     {
56
     {
73
         return Forms\Components\Section::make('Content')
57
         return Forms\Components\Section::make('Content')
58
+            ->hidden(static fn (DocumentDefault $record) => $record->type === DocumentType::Bill)
74
             ->schema([
59
             ->schema([
75
                 Forms\Components\TextInput::make('header')
60
                 Forms\Components\TextInput::make('header')
76
                     ->localizeLabel()
61
                     ->localizeLabel()
91
     {
76
     {
92
         return Forms\Components\Section::make('Template')
77
         return Forms\Components\Section::make('Template')
93
             ->description('Choose the template and edit the column names.')
78
             ->description('Choose the template and edit the column names.')
79
+            ->hidden(static fn (DocumentDefault $record) => $record->type === DocumentType::Bill)
94
             ->schema([
80
             ->schema([
95
                 Forms\Components\Grid::make(1)
81
                 Forms\Components\Grid::make(1)
96
                     ->schema([
82
                     ->schema([
134
                             ->softRequired()
120
                             ->softRequired()
135
                             ->localizeLabel()
121
                             ->localizeLabel()
136
                             ->options(Template::class),
122
                             ->options(Template::class),
137
-                        Forms\Components\Select::make('item_name.option')
138
-                            ->softRequired()
139
-                            ->localizeLabel('Item name')
140
-                            ->options(InvoiceModel::getAvailableItemNameOptions())
141
-                            ->afterStateUpdated(static function (Get $get, Set $set, $state, $old) {
142
-                                if ($state !== 'other' && $old === 'other' && filled($get('item_name.custom'))) {
143
-                                    $set('item_name.old_custom', $get('item_name.custom'));
144
-                                    $set('item_name.custom', null);
145
-                                }
146
-
147
-                                if ($state === 'other' && $old !== 'other') {
148
-                                    $set('item_name.custom', $get('item_name.old_custom'));
149
-                                }
150
-                            }),
151
-                        Forms\Components\TextInput::make('item_name.custom')
152
-                            ->hiddenLabel()
153
-                            ->disabled(static fn (callable $get) => $get('item_name.option') !== 'other')
154
-                            ->nullable(),
155
-                        Forms\Components\Select::make('unit_name.option')
156
-                            ->softRequired()
157
-                            ->localizeLabel('Unit name')
158
-                            ->options(InvoiceModel::getAvailableUnitNameOptions())
159
-                            ->afterStateUpdated(static function (Get $get, Set $set, $state, $old) {
160
-                                if ($state !== 'other' && $old === 'other' && filled($get('unit_name.custom'))) {
161
-                                    $set('unit_name.old_custom', $get('unit_name.custom'));
162
-                                    $set('unit_name.custom', null);
163
-                                }
164
-
165
-                                if ($state === 'other' && $old !== 'other') {
166
-                                    $set('unit_name.custom', $get('unit_name.old_custom'));
167
-                                }
168
-                            }),
169
-                        Forms\Components\TextInput::make('unit_name.custom')
170
-                            ->hiddenLabel()
171
-                            ->disabled(static fn (callable $get) => $get('unit_name.option') !== 'other')
172
-                            ->nullable(),
173
-                        Forms\Components\Select::make('price_name.option')
174
-                            ->softRequired()
175
-                            ->localizeLabel('Price name')
176
-                            ->options(InvoiceModel::getAvailablePriceNameOptions())
177
-                            ->afterStateUpdated(static function (Get $get, Set $set, $state, $old) {
178
-                                if ($state !== 'other' && $old === 'other' && filled($get('price_name.custom'))) {
179
-                                    $set('price_name.old_custom', $get('price_name.custom'));
180
-                                    $set('price_name.custom', null);
181
-                                }
182
-
183
-                                if ($state === 'other' && $old !== 'other') {
184
-                                    $set('price_name.custom', $get('price_name.old_custom'));
185
-                                }
186
-                            }),
187
-                        Forms\Components\TextInput::make('price_name.custom')
188
-                            ->hiddenLabel()
189
-                            ->disabled(static fn (callable $get) => $get('price_name.option') !== 'other')
190
-                            ->nullable(),
191
-                        Forms\Components\Select::make('amount_name.option')
192
-                            ->softRequired()
193
-                            ->localizeLabel('Amount name')
194
-                            ->options(InvoiceModel::getAvailableAmountNameOptions())
195
-                            ->afterStateUpdated(static function (Get $get, Set $set, $state, $old) {
196
-                                if ($state !== 'other' && $old === 'other' && filled($get('amount_name.custom'))) {
197
-                                    $set('amount_name.old_custom', $get('amount_name.custom'));
198
-                                    $set('amount_name.custom', null);
199
-                                }
200
-
201
-                                if ($state === 'other' && $old !== 'other') {
202
-                                    $set('amount_name.custom', $get('amount_name.old_custom'));
203
-                                }
204
-                            }),
205
-                        Forms\Components\TextInput::make('amount_name.custom')
206
-                            ->hiddenLabel()
207
-                            ->disabled(static fn (callable $get) => $get('amount_name.option') !== 'other')
208
-                            ->nullable(),
123
+                        ...static::getColumnLabelsSchema(),
209
                     ])->columnSpan(1),
124
                     ])->columnSpan(1),
210
                 Forms\Components\Grid::make()
125
                 Forms\Components\Grid::make()
211
                     ->schema([
126
                     ->schema([
228
             ])->columns(3);
143
             ])->columns(3);
229
     }
144
     }
230
 
145
 
146
+    public static function getBillColumnLabelsSection(): Component
147
+    {
148
+        return Forms\Components\Section::make('Column Labels')
149
+            ->visible(static fn (DocumentDefault $record) => $record->type === DocumentType::Bill)
150
+            ->schema(static::getColumnLabelsSchema())->columns();
151
+    }
152
+
153
+    public static function getColumnLabelsSchema(): array
154
+    {
155
+        return [
156
+            Forms\Components\Select::make('item_name.option')
157
+                ->softRequired()
158
+                ->localizeLabel('Item name')
159
+                ->options(DocumentDefault::getAvailableItemNameOptions())
160
+                ->afterStateUpdated(static function (Get $get, Set $set, $state, $old) {
161
+                    if ($state !== 'other' && $old === 'other' && filled($get('item_name.custom'))) {
162
+                        $set('item_name.old_custom', $get('item_name.custom'));
163
+                        $set('item_name.custom', null);
164
+                    }
165
+
166
+                    if ($state === 'other' && $old !== 'other') {
167
+                        $set('item_name.custom', $get('item_name.old_custom'));
168
+                    }
169
+                }),
170
+            Forms\Components\TextInput::make('item_name.custom')
171
+                ->hiddenLabel()
172
+                ->extraFieldWrapperAttributes(static fn (DocumentDefault $record) => [
173
+                    'class' => $record->type === DocumentType::Bill ? 'report-hidden-label' : '',
174
+                ])
175
+                ->disabled(static fn (callable $get) => $get('item_name.option') !== 'other')
176
+                ->nullable(),
177
+            Forms\Components\Select::make('unit_name.option')
178
+                ->softRequired()
179
+                ->localizeLabel('Unit name')
180
+                ->options(DocumentDefault::getAvailableUnitNameOptions())
181
+                ->afterStateUpdated(static function (Get $get, Set $set, $state, $old) {
182
+                    if ($state !== 'other' && $old === 'other' && filled($get('unit_name.custom'))) {
183
+                        $set('unit_name.old_custom', $get('unit_name.custom'));
184
+                        $set('unit_name.custom', null);
185
+                    }
186
+
187
+                    if ($state === 'other' && $old !== 'other') {
188
+                        $set('unit_name.custom', $get('unit_name.old_custom'));
189
+                    }
190
+                }),
191
+            Forms\Components\TextInput::make('unit_name.custom')
192
+                ->hiddenLabel()
193
+                ->extraFieldWrapperAttributes(static fn (DocumentDefault $record) => [
194
+                    'class' => $record->type === DocumentType::Bill ? 'report-hidden-label' : '',
195
+                ])
196
+                ->disabled(static fn (callable $get) => $get('unit_name.option') !== 'other')
197
+                ->nullable(),
198
+            Forms\Components\Select::make('price_name.option')
199
+                ->softRequired()
200
+                ->localizeLabel('Price name')
201
+                ->options(DocumentDefault::getAvailablePriceNameOptions())
202
+                ->afterStateUpdated(static function (Get $get, Set $set, $state, $old) {
203
+                    if ($state !== 'other' && $old === 'other' && filled($get('price_name.custom'))) {
204
+                        $set('price_name.old_custom', $get('price_name.custom'));
205
+                        $set('price_name.custom', null);
206
+                    }
207
+
208
+                    if ($state === 'other' && $old !== 'other') {
209
+                        $set('price_name.custom', $get('price_name.old_custom'));
210
+                    }
211
+                }),
212
+            Forms\Components\TextInput::make('price_name.custom')
213
+                ->hiddenLabel()
214
+                ->extraFieldWrapperAttributes(static fn (DocumentDefault $record) => [
215
+                    'class' => $record->type === DocumentType::Bill ? 'report-hidden-label' : '',
216
+                ])
217
+                ->disabled(static fn (callable $get) => $get('price_name.option') !== 'other')
218
+                ->nullable(),
219
+            Forms\Components\Select::make('amount_name.option')
220
+                ->softRequired()
221
+                ->localizeLabel('Amount name')
222
+                ->options(DocumentDefault::getAvailableAmountNameOptions())
223
+                ->afterStateUpdated(static function (Get $get, Set $set, $state, $old) {
224
+                    if ($state !== 'other' && $old === 'other' && filled($get('amount_name.custom'))) {
225
+                        $set('amount_name.old_custom', $get('amount_name.custom'));
226
+                        $set('amount_name.custom', null);
227
+                    }
228
+
229
+                    if ($state === 'other' && $old !== 'other') {
230
+                        $set('amount_name.custom', $get('amount_name.old_custom'));
231
+                    }
232
+                }),
233
+            Forms\Components\TextInput::make('amount_name.custom')
234
+                ->hiddenLabel()
235
+                ->extraFieldWrapperAttributes(static fn (DocumentDefault $record) => [
236
+                    'class' => $record->type === DocumentType::Bill ? 'report-hidden-label' : '',
237
+                ])
238
+                ->disabled(static fn (callable $get) => $get('amount_name.option') !== 'other')
239
+                ->nullable(),
240
+        ];
241
+    }
242
+
231
     public static function table(Table $table): Table
243
     public static function table(Table $table): Table
232
     {
244
     {
233
         return $table
245
         return $table
235
                 Tables\Columns\TextColumn::make('type')
247
                 Tables\Columns\TextColumn::make('type')
236
                     ->badge(),
248
                     ->badge(),
237
                 Tables\Columns\TextColumn::make('number_prefix'),
249
                 Tables\Columns\TextColumn::make('number_prefix'),
238
-                Tables\Columns\TextColumn::make('number_next')
239
-                    ->label('Next Number'),
240
                 Tables\Columns\TextColumn::make('template')
250
                 Tables\Columns\TextColumn::make('template')
241
                     ->badge(),
251
                     ->badge(),
242
                 Tables\Columns\IconColumn::make('show_logo')
252
                 Tables\Columns\IconColumn::make('show_logo')
249
                 Tables\Actions\EditAction::make(),
259
                 Tables\Actions\EditAction::make(),
250
             ])
260
             ])
251
             ->bulkActions([
261
             ->bulkActions([
252
-                Tables\Actions\BulkActionGroup::make([
253
-                    Tables\Actions\DeleteBulkAction::make(),
254
-                ]),
262
+                //
255
             ]);
263
             ]);
256
     }
264
     }
257
 
265
 
266
     {
274
     {
267
         return [
275
         return [
268
             'index' => Pages\ListDocumentDefaults::route('/'),
276
             'index' => Pages\ListDocumentDefaults::route('/'),
269
-            'create' => Pages\CreateDocumentDefault::route('/create'),
270
             'edit' => Pages\EditDocumentDefault::route('/{record}/edit'),
277
             'edit' => Pages\EditDocumentDefault::route('/{record}/edit'),
271
         ];
278
         ];
272
     }
279
     }

+ 0
- 11
app/Filament/Company/Clusters/Settings/Resources/DocumentDefaultResource/Pages/CreateDocumentDefault.php 查看文件

1
-<?php
2
-
3
-namespace App\Filament\Company\Clusters\Settings\Resources\DocumentDefaultResource\Pages;
4
-
5
-use App\Filament\Company\Clusters\Settings\Resources\DocumentDefaultResource;
6
-use Filament\Resources\Pages\CreateRecord;
7
-
8
-class CreateDocumentDefault extends CreateRecord
9
-{
10
-    protected static string $resource = DocumentDefaultResource::class;
11
-}

+ 12
- 5
app/Filament/Company/Clusters/Settings/Resources/DocumentDefaultResource/Pages/EditDocumentDefault.php 查看文件

3
 namespace App\Filament\Company\Clusters\Settings\Resources\DocumentDefaultResource\Pages;
3
 namespace App\Filament\Company\Clusters\Settings\Resources\DocumentDefaultResource\Pages;
4
 
4
 
5
 use App\Filament\Company\Clusters\Settings\Resources\DocumentDefaultResource;
5
 use App\Filament\Company\Clusters\Settings\Resources\DocumentDefaultResource;
6
-use Filament\Actions;
7
 use Filament\Resources\Pages\EditRecord;
6
 use Filament\Resources\Pages\EditRecord;
7
+use Illuminate\Contracts\Support\Htmlable;
8
 
8
 
9
 class EditDocumentDefault extends EditRecord
9
 class EditDocumentDefault extends EditRecord
10
 {
10
 {
11
     protected static string $resource = DocumentDefaultResource::class;
11
     protected static string $resource = DocumentDefaultResource::class;
12
 
12
 
13
-    protected function getHeaderActions(): array
13
+    public function getRecordTitle(): string | Htmlable
14
     {
14
     {
15
-        return [
16
-            Actions\DeleteAction::make(),
17
-        ];
15
+        return $this->record->type->getLabel();
16
+    }
17
+
18
+    public function getBreadcrumbs(): array
19
+    {
20
+        $breadcrumbs = parent::getBreadcrumbs();
21
+
22
+        array_pop($breadcrumbs);
23
+
24
+        return $breadcrumbs;
18
     }
25
     }
19
 }
26
 }

+ 0
- 8
app/Filament/Company/Clusters/Settings/Resources/DocumentDefaultResource/Pages/ListDocumentDefaults.php 查看文件

3
 namespace App\Filament\Company\Clusters\Settings\Resources\DocumentDefaultResource\Pages;
3
 namespace App\Filament\Company\Clusters\Settings\Resources\DocumentDefaultResource\Pages;
4
 
4
 
5
 use App\Filament\Company\Clusters\Settings\Resources\DocumentDefaultResource;
5
 use App\Filament\Company\Clusters\Settings\Resources\DocumentDefaultResource;
6
-use Filament\Actions;
7
 use Filament\Resources\Pages\ListRecords;
6
 use Filament\Resources\Pages\ListRecords;
8
 use Filament\Support\Enums\MaxWidth;
7
 use Filament\Support\Enums\MaxWidth;
9
 
8
 
11
 {
10
 {
12
     protected static string $resource = DocumentDefaultResource::class;
11
     protected static string $resource = DocumentDefaultResource::class;
13
 
12
 
14
-    protected function getHeaderActions(): array
15
-    {
16
-        return [
17
-            Actions\CreateAction::make(),
18
-        ];
19
-    }
20
-
21
     public function getMaxContentWidth(): MaxWidth | string | null
13
     public function getMaxContentWidth(): MaxWidth | string | null
22
     {
14
     {
23
         return MaxWidth::ScreenTwoExtraLarge;
15
         return MaxWidth::ScreenTwoExtraLarge;

+ 1
- 1
app/Filament/Company/Resources/Purchases/BillResource.php 查看文件

72
                             Forms\Components\Group::make([
72
                             Forms\Components\Group::make([
73
                                 Forms\Components\TextInput::make('bill_number')
73
                                 Forms\Components\TextInput::make('bill_number')
74
                                     ->label('Bill number')
74
                                     ->label('Bill number')
75
-                                    ->default(fn () => Bill::getNextDocumentNumber())
75
+                                    ->default(static fn () => Bill::getNextDocumentNumber())
76
                                     ->required(),
76
                                     ->required(),
77
                                 Forms\Components\TextInput::make('order_number')
77
                                 Forms\Components\TextInput::make('order_number')
78
                                     ->label('P.O/S.O Number'),
78
                                     ->label('P.O/S.O Number'),

+ 24
- 12
app/Filament/Company/Resources/Sales/EstimateResource.php 查看文件

41
     {
41
     {
42
         $company = Auth::user()->currentCompany;
42
         $company = Auth::user()->currentCompany;
43
 
43
 
44
+        $settings = $company->defaultEstimate;
45
+
44
         return $form
46
         return $form
45
             ->schema([
47
             ->schema([
46
                 DocumentHeaderSection::make('Estimate Header')
48
                 DocumentHeaderSection::make('Estimate Header')
47
-                    ->defaultHeader('Estimate'),
49
+                    ->defaultHeader($settings->header)
50
+                    ->defaultSubheader($settings->subheader),
48
                 Forms\Components\Section::make('Estimate Details')
51
                 Forms\Components\Section::make('Estimate Details')
49
                     ->schema([
52
                     ->schema([
50
                         Forms\Components\Split::make([
53
                         Forms\Components\Split::make([
71
                             Forms\Components\Group::make([
74
                             Forms\Components\Group::make([
72
                                 Forms\Components\TextInput::make('estimate_number')
75
                                 Forms\Components\TextInput::make('estimate_number')
73
                                     ->label('Estimate number')
76
                                     ->label('Estimate number')
74
-                                    ->default(fn () => Estimate::getNextDocumentNumber()),
77
+                                    ->default(static fn () => Estimate::getNextDocumentNumber()),
75
                                 Forms\Components\TextInput::make('reference_number')
78
                                 Forms\Components\TextInput::make('reference_number')
76
                                     ->label('Reference number'),
79
                                     ->label('Reference number'),
77
                                 Forms\Components\DatePicker::make('date')
80
                                 Forms\Components\DatePicker::make('date')
88
                                     }),
91
                                     }),
89
                                 Forms\Components\DatePicker::make('expiration_date')
92
                                 Forms\Components\DatePicker::make('expiration_date')
90
                                     ->label('Expiration date')
93
                                     ->label('Expiration date')
91
-                                    ->default(function () use ($company) {
92
-                                        return now()->addDays($company->defaultInvoice->payment_terms->getDays());
94
+                                    ->default(function () use ($settings) {
95
+                                        return now()->addDays($settings->payment_terms->getDays());
93
                                     })
96
                                     })
94
                                     ->minDate(static function (Forms\Get $get) {
97
                                     ->minDate(static function (Forms\Get $get) {
95
                                         return $get('date') ?? now();
98
                                         return $get('date') ?? now();
113
                             ->relationship()
116
                             ->relationship()
114
                             ->saveRelationshipsUsing(null)
117
                             ->saveRelationshipsUsing(null)
115
                             ->dehydrated(true)
118
                             ->dehydrated(true)
116
-                            ->headers(function (Forms\Get $get) {
119
+                            ->headers(function (Forms\Get $get) use ($settings) {
117
                                 $hasDiscounts = DocumentDiscountMethod::parse($get('discount_method'))->isPerLineItem();
120
                                 $hasDiscounts = DocumentDiscountMethod::parse($get('discount_method'))->isPerLineItem();
118
 
121
 
119
                                 $headers = [
122
                                 $headers = [
120
-                                    Header::make('Items')->width($hasDiscounts ? '15%' : '20%'),
121
-                                    Header::make('Description')->width($hasDiscounts ? '25%' : '30%'),  // Increase when no discounts
122
-                                    Header::make('Quantity')->width('10%'),
123
-                                    Header::make('Price')->width('10%'),
124
-                                    Header::make('Taxes')->width($hasDiscounts ? '15%' : '20%'),       // Increase when no discounts
123
+                                    Header::make($settings->resolveColumnLabel('item_name', 'Items'))
124
+                                        ->width($hasDiscounts ? '15%' : '20%'),
125
+                                    Header::make('Description')
126
+                                        ->width($hasDiscounts ? '25%' : '30%'),
127
+                                    Header::make($settings->resolveColumnLabel('unit_name', 'Quantity'))
128
+                                        ->width('10%'),
129
+                                    Header::make($settings->resolveColumnLabel('price_name', 'Price'))
130
+                                        ->width('10%'),
131
+                                    Header::make('Taxes')
132
+                                        ->width($hasDiscounts ? '15%' : '20%'),
125
                                 ];
133
                                 ];
126
 
134
 
127
                                 if ($hasDiscounts) {
135
                                 if ($hasDiscounts) {
128
                                     $headers[] = Header::make('Discounts')->width('15%');
136
                                     $headers[] = Header::make('Discounts')->width('15%');
129
                                 }
137
                                 }
130
 
138
 
131
-                                $headers[] = Header::make('Amount')->width('10%')->align('right');
139
+                                $headers[] = Header::make($settings->resolveColumnLabel('amount_name', 'Amount'))
140
+                                    ->width('10%')
141
+                                    ->align('right');
132
 
142
 
133
                                 return $headers;
143
                                 return $headers;
134
                             })
144
                             })
229
                         DocumentTotals::make()
239
                         DocumentTotals::make()
230
                             ->type(DocumentType::Estimate),
240
                             ->type(DocumentType::Estimate),
231
                         Forms\Components\Textarea::make('terms')
241
                         Forms\Components\Textarea::make('terms')
242
+                            ->default($settings->terms)
232
                             ->columnSpanFull(),
243
                             ->columnSpanFull(),
233
                     ]),
244
                     ]),
234
-                DocumentFooterSection::make('Estimate Footer'),
245
+                DocumentFooterSection::make('Estimate Footer')
246
+                    ->defaultFooter($settings->footer),
235
             ]);
247
             ]);
236
     }
248
     }
237
 
249
 

+ 24
- 13
app/Filament/Company/Resources/Sales/InvoiceResource.php 查看文件

49
     {
49
     {
50
         $company = Auth::user()->currentCompany;
50
         $company = Auth::user()->currentCompany;
51
 
51
 
52
+        $settings = $company->defaultInvoice;
53
+
52
         return $form
54
         return $form
53
             ->schema([
55
             ->schema([
54
                 DocumentHeaderSection::make('Invoice Header')
56
                 DocumentHeaderSection::make('Invoice Header')
55
-                    ->defaultHeader(static fn () => $company->defaultInvoice->header)
56
-                    ->defaultSubheader(static fn () => $company->defaultInvoice->subheader),
57
+                    ->defaultHeader($settings->header)
58
+                    ->defaultSubheader($settings->subheader),
57
                 Forms\Components\Section::make('Invoice Details')
59
                 Forms\Components\Section::make('Invoice Details')
58
                     ->schema([
60
                     ->schema([
59
                         Forms\Components\Split::make([
61
                         Forms\Components\Split::make([
83
                             Forms\Components\Group::make([
85
                             Forms\Components\Group::make([
84
                                 Forms\Components\TextInput::make('invoice_number')
86
                                 Forms\Components\TextInput::make('invoice_number')
85
                                     ->label('Invoice number')
87
                                     ->label('Invoice number')
86
-                                    ->default(fn () => Invoice::getNextDocumentNumber()),
88
+                                    ->default(static fn () => Invoice::getNextDocumentNumber()),
87
                                 Forms\Components\TextInput::make('order_number')
89
                                 Forms\Components\TextInput::make('order_number')
88
                                     ->label('P.O/S.O Number'),
90
                                     ->label('P.O/S.O Number'),
89
                                 Forms\Components\DatePicker::make('date')
91
                                 Forms\Components\DatePicker::make('date')
103
                                     }),
105
                                     }),
104
                                 Forms\Components\DatePicker::make('due_date')
106
                                 Forms\Components\DatePicker::make('due_date')
105
                                     ->label('Payment due')
107
                                     ->label('Payment due')
106
-                                    ->default(function () use ($company) {
107
-                                        return now()->addDays($company->defaultInvoice->payment_terms->getDays());
108
+                                    ->default(function () use ($settings) {
109
+                                        return now()->addDays($settings->payment_terms->getDays());
108
                                     })
110
                                     })
109
                                     ->minDate(static function (Forms\Get $get) {
111
                                     ->minDate(static function (Forms\Get $get) {
110
                                         return $get('date') ?? now();
112
                                         return $get('date') ?? now();
128
                             ->relationship()
130
                             ->relationship()
129
                             ->saveRelationshipsUsing(null)
131
                             ->saveRelationshipsUsing(null)
130
                             ->dehydrated(true)
132
                             ->dehydrated(true)
131
-                            ->headers(function (Forms\Get $get) {
133
+                            ->headers(function (Forms\Get $get) use ($settings) {
132
                                 $hasDiscounts = DocumentDiscountMethod::parse($get('discount_method'))->isPerLineItem();
134
                                 $hasDiscounts = DocumentDiscountMethod::parse($get('discount_method'))->isPerLineItem();
133
 
135
 
134
                                 $headers = [
136
                                 $headers = [
135
-                                    Header::make('Items')->width($hasDiscounts ? '15%' : '20%'),
136
-                                    Header::make('Description')->width($hasDiscounts ? '25%' : '30%'),  // Increase when no discounts
137
-                                    Header::make('Quantity')->width('10%'),
138
-                                    Header::make('Price')->width('10%'),
139
-                                    Header::make('Taxes')->width($hasDiscounts ? '15%' : '20%'),       // Increase when no discounts
137
+                                    Header::make($settings->resolveColumnLabel('item_name', 'Items'))
138
+                                        ->width($hasDiscounts ? '15%' : '20%'),
139
+                                    Header::make('Description')
140
+                                        ->width($hasDiscounts ? '25%' : '30%'),
141
+                                    Header::make($settings->resolveColumnLabel('unit_name', 'Quantity'))
142
+                                        ->width('10%'),
143
+                                    Header::make($settings->resolveColumnLabel('price_name', 'Price'))
144
+                                        ->width('10%'),
145
+                                    Header::make('Taxes')
146
+                                        ->width($hasDiscounts ? '15%' : '20%'),
140
                                 ];
147
                                 ];
141
 
148
 
142
                                 if ($hasDiscounts) {
149
                                 if ($hasDiscounts) {
143
                                     $headers[] = Header::make('Discounts')->width('15%');
150
                                     $headers[] = Header::make('Discounts')->width('15%');
144
                                 }
151
                                 }
145
 
152
 
146
-                                $headers[] = Header::make('Amount')->width('10%')->align('right');
153
+                                $headers[] = Header::make($settings->resolveColumnLabel('amount_name', 'Amount'))
154
+                                    ->width('10%')
155
+                                    ->align('right');
147
 
156
 
148
                                 return $headers;
157
                                 return $headers;
149
                             })
158
                             })
244
                         DocumentTotals::make()
253
                         DocumentTotals::make()
245
                             ->type(DocumentType::Invoice),
254
                             ->type(DocumentType::Invoice),
246
                         Forms\Components\Textarea::make('terms')
255
                         Forms\Components\Textarea::make('terms')
256
+                            ->default($settings->terms)
247
                             ->columnSpanFull(),
257
                             ->columnSpanFull(),
248
                     ]),
258
                     ]),
249
-                DocumentFooterSection::make('Invoice Footer'),
259
+                DocumentFooterSection::make('Invoice Footer')
260
+                    ->defaultFooter($settings->footer),
250
             ]);
261
             ]);
251
     }
262
     }
252
 
263
 

+ 22
- 11
app/Filament/Company/Resources/Sales/RecurringInvoiceResource.php 查看文件

36
     {
36
     {
37
         $company = Auth::user()->currentCompany;
37
         $company = Auth::user()->currentCompany;
38
 
38
 
39
+        $settings = $company->defaultInvoice;
40
+
39
         return $form
41
         return $form
40
             ->schema([
42
             ->schema([
41
                 DocumentHeaderSection::make('Invoice Header')
43
                 DocumentHeaderSection::make('Invoice Header')
42
-                    ->defaultHeader(static fn () => $company->defaultInvoice->header)
43
-                    ->defaultSubheader(static fn () => $company->defaultInvoice->subheader),
44
+                    ->defaultHeader($settings->header)
45
+                    ->defaultSubheader($settings->subheader),
44
                 Forms\Components\Section::make('Invoice Details')
46
                 Forms\Components\Section::make('Invoice Details')
45
                     ->schema([
47
                     ->schema([
46
                         Forms\Components\Split::make([
48
                         Forms\Components\Split::make([
77
                                     ->label('Payment due')
79
                                     ->label('Payment due')
78
                                     ->options(PaymentTerms::class)
80
                                     ->options(PaymentTerms::class)
79
                                     ->softRequired()
81
                                     ->softRequired()
80
-                                    ->default($company->defaultInvoice->payment_terms)
82
+                                    ->default($settings->payment_terms)
81
                                     ->live(),
83
                                     ->live(),
82
                                 Forms\Components\Select::make('discount_method')
84
                                 Forms\Components\Select::make('discount_method')
83
                                     ->label('Discount method')
85
                                     ->label('Discount method')
98
                             ->relationship()
100
                             ->relationship()
99
                             ->saveRelationshipsUsing(null)
101
                             ->saveRelationshipsUsing(null)
100
                             ->dehydrated(true)
102
                             ->dehydrated(true)
101
-                            ->headers(function (Forms\Get $get) {
103
+                            ->headers(function (Forms\Get $get) use ($settings) {
102
                                 $hasDiscounts = DocumentDiscountMethod::parse($get('discount_method'))->isPerLineItem();
104
                                 $hasDiscounts = DocumentDiscountMethod::parse($get('discount_method'))->isPerLineItem();
103
 
105
 
104
                                 $headers = [
106
                                 $headers = [
105
-                                    Header::make('Items')->width($hasDiscounts ? '15%' : '20%'),
106
-                                    Header::make('Description')->width($hasDiscounts ? '25%' : '30%'),  // Increase when no discounts
107
-                                    Header::make('Quantity')->width('10%'),
108
-                                    Header::make('Price')->width('10%'),
109
-                                    Header::make('Taxes')->width($hasDiscounts ? '15%' : '20%'),       // Increase when no discounts
107
+                                    Header::make($settings->resolveColumnLabel('item_name', 'Items'))
108
+                                        ->width($hasDiscounts ? '15%' : '20%'),
109
+                                    Header::make('Description')
110
+                                        ->width($hasDiscounts ? '25%' : '30%'),
111
+                                    Header::make($settings->resolveColumnLabel('unit_name', 'Quantity'))
112
+                                        ->width('10%'),
113
+                                    Header::make($settings->resolveColumnLabel('price_name', 'Price'))
114
+                                        ->width('10%'),
115
+                                    Header::make('Taxes')
116
+                                        ->width($hasDiscounts ? '15%' : '20%'),
110
                                 ];
117
                                 ];
111
 
118
 
112
                                 if ($hasDiscounts) {
119
                                 if ($hasDiscounts) {
113
                                     $headers[] = Header::make('Discounts')->width('15%');
120
                                     $headers[] = Header::make('Discounts')->width('15%');
114
                                 }
121
                                 }
115
 
122
 
116
-                                $headers[] = Header::make('Amount')->width('10%')->align('right');
123
+                                $headers[] = Header::make($settings->resolveColumnLabel('amount_name', 'Amount'))
124
+                                    ->width('10%')
125
+                                    ->align('right');
117
 
126
 
118
                                 return $headers;
127
                                 return $headers;
119
                             })
128
                             })
214
                         DocumentTotals::make()
223
                         DocumentTotals::make()
215
                             ->type(DocumentType::Invoice),
224
                             ->type(DocumentType::Invoice),
216
                         Forms\Components\Textarea::make('terms')
225
                         Forms\Components\Textarea::make('terms')
226
+                            ->default($settings->terms)
217
                             ->columnSpanFull(),
227
                             ->columnSpanFull(),
218
                     ]),
228
                     ]),
219
-                DocumentFooterSection::make('Invoice Footer'),
229
+                DocumentFooterSection::make('Invoice Footer')
230
+                    ->defaultFooter($settings->footer),
220
             ]);
231
             ]);
221
     }
232
     }
222
 
233
 

+ 16
- 0
app/Filament/Forms/Components/DocumentFooterSection.php 查看文件

2
 
2
 
3
 namespace App\Filament\Forms\Components;
3
 namespace App\Filament\Forms\Components;
4
 
4
 
5
+use Closure;
5
 use Filament\Forms\Components\Section;
6
 use Filament\Forms\Components\Section;
6
 use Filament\Forms\Components\Textarea;
7
 use Filament\Forms\Components\Textarea;
7
 
8
 
8
 class DocumentFooterSection extends Section
9
 class DocumentFooterSection extends Section
9
 {
10
 {
11
+    protected string | Closure | null $defaultFooter = null;
12
+
13
+    public function defaultFooter(string | Closure | null $footer): static
14
+    {
15
+        $this->defaultFooter = $footer;
16
+
17
+        return $this;
18
+    }
19
+
10
     protected function setUp(): void
20
     protected function setUp(): void
11
     {
21
     {
12
         parent::setUp();
22
         parent::setUp();
16
 
26
 
17
         $this->schema([
27
         $this->schema([
18
             Textarea::make('footer')
28
             Textarea::make('footer')
29
+                ->default(fn () => $this->getDefaultFooter())
19
                 ->columnSpanFull(),
30
                 ->columnSpanFull(),
20
         ]);
31
         ]);
21
     }
32
     }
33
+
34
+    public function getDefaultFooter(): ?string
35
+    {
36
+        return $this->evaluate($this->defaultFooter);
37
+    }
22
 }
38
 }

+ 2
- 2
app/Filament/Forms/Components/DocumentHeaderSection.php 查看文件

19
 
19
 
20
     protected string | Closure | null $defaultSubheader = null;
20
     protected string | Closure | null $defaultSubheader = null;
21
 
21
 
22
-    public function defaultHeader(string | Closure $header): static
22
+    public function defaultHeader(string | Closure | null $header): static
23
     {
23
     {
24
         $this->defaultHeader = $header;
24
         $this->defaultHeader = $header;
25
 
25
 
26
         return $this;
26
         return $this;
27
     }
27
     }
28
 
28
 
29
-    public function defaultSubheader(string | Closure $subheader): static
29
+    public function defaultSubheader(string | Closure | null $subheader): static
30
     {
30
     {
31
         $this->defaultSubheader = $subheader;
31
         $this->defaultSubheader = $subheader;
32
 
32
 

+ 0
- 7
app/Listeners/ConfigureCompanyDefault.php 查看文件

2
 
2
 
3
 namespace App\Listeners;
3
 namespace App\Listeners;
4
 
4
 
5
-use App\Enums\Setting\PrimaryColor;
6
 use App\Events\CompanyConfigured;
5
 use App\Events\CompanyConfigured;
7
 use App\Services\CompanySettingsService;
6
 use App\Services\CompanySettingsService;
8
 use App\Utilities\Currency\ConfigureCurrencies;
7
 use App\Utilities\Currency\ConfigureCurrencies;
11
 use Filament\Forms\Components\Section;
10
 use Filament\Forms\Components\Section;
12
 use Filament\Forms\Components\Tabs\Tab;
11
 use Filament\Forms\Components\Tabs\Tab;
13
 use Filament\Resources\Components\Tab as ResourcesTab;
12
 use Filament\Resources\Components\Tab as ResourcesTab;
14
-use Filament\Support\Facades\FilamentColor;
15
 
13
 
16
 class ConfigureCompanyDefault
14
 class ConfigureCompanyDefault
17
 {
15
 {
32
         config(['app.timezone' => $settings['default_timezone']]);
30
         config(['app.timezone' => $settings['default_timezone']]);
33
         date_default_timezone_set($settings['default_timezone']);
31
         date_default_timezone_set($settings['default_timezone']);
34
 
32
 
35
-        FilamentColor::register([
36
-            'primary' => PrimaryColor::from($settings['default_primary_color'])->getColor(),
37
-        ]);
38
-
39
         Filament::getPanel('company')
33
         Filament::getPanel('company')
40
-            ->font($settings['default_font'])
41
             ->brandName($company->name);
34
             ->brandName($company->name);
42
 
35
 
43
         DatePicker::configureUsing(static function (DatePicker $component) use ($settings) {
36
         DatePicker::configureUsing(static function (DatePicker $component) use ($settings) {

+ 6
- 8
app/Models/Accounting/Bill.php 查看文件

14
 use App\Filament\Company\Resources\Purchases\BillResource;
14
 use App\Filament\Company\Resources\Purchases\BillResource;
15
 use App\Models\Banking\BankAccount;
15
 use App\Models\Banking\BankAccount;
16
 use App\Models\Common\Vendor;
16
 use App\Models\Common\Vendor;
17
+use App\Models\Company;
17
 use App\Models\Setting\Currency;
18
 use App\Models\Setting\Currency;
19
+use App\Models\Setting\DocumentDefault;
18
 use App\Observers\BillObserver;
20
 use App\Observers\BillObserver;
19
 use App\Utilities\Currency\CurrencyAccessor;
21
 use App\Utilities\Currency\CurrencyAccessor;
20
 use App\Utilities\Currency\CurrencyConverter;
22
 use App\Utilities\Currency\CurrencyConverter;
171
         return $this->payments->isNotEmpty();
173
         return $this->payments->isNotEmpty();
172
     }
174
     }
173
 
175
 
174
-    public static function getNextDocumentNumber(): string
176
+    public static function getNextDocumentNumber(?Company $company = null): string
175
     {
177
     {
176
-        $company = auth()->user()->currentCompany;
178
+        $company ??= auth()->user()?->currentCompany;
177
 
179
 
178
         if (! $company) {
180
         if (! $company) {
179
             throw new \RuntimeException('No current company is set for the user.');
181
             throw new \RuntimeException('No current company is set for the user.');
181
 
183
 
182
         $defaultBillSettings = $company->defaultBill;
184
         $defaultBillSettings = $company->defaultBill;
183
 
185
 
184
-        $numberPrefix = $defaultBillSettings->number_prefix;
185
-        $numberDigits = $defaultBillSettings->number_digits;
186
+        $numberPrefix = $defaultBillSettings->number_prefix ?? '';
186
 
187
 
187
         $latestDocument = static::query()
188
         $latestDocument = static::query()
188
             ->whereNotNull('bill_number')
189
             ->whereNotNull('bill_number')
191
 
192
 
192
         $lastNumberNumericPart = $latestDocument
193
         $lastNumberNumericPart = $latestDocument
193
             ? (int) substr($latestDocument->bill_number, strlen($numberPrefix))
194
             ? (int) substr($latestDocument->bill_number, strlen($numberPrefix))
194
-            : 0;
195
+            : DocumentDefault::getBaseNumber();
195
 
196
 
196
         $numberNext = $lastNumberNumericPart + 1;
197
         $numberNext = $lastNumberNumericPart + 1;
197
 
198
 
198
         return $defaultBillSettings->getNumberNext(
199
         return $defaultBillSettings->getNumberNext(
199
-            padded: true,
200
-            format: true,
201
             prefix: $numberPrefix,
200
             prefix: $numberPrefix,
202
-            digits: $numberDigits,
203
             next: $numberNext
201
             next: $numberNext
204
         );
202
         );
205
     }
203
     }

+ 7
- 9
app/Models/Accounting/Estimate.php 查看文件

13
 use App\Filament\Company\Resources\Sales\EstimateResource;
13
 use App\Filament\Company\Resources\Sales\EstimateResource;
14
 use App\Filament\Company\Resources\Sales\InvoiceResource;
14
 use App\Filament\Company\Resources\Sales\InvoiceResource;
15
 use App\Models\Common\Client;
15
 use App\Models\Common\Client;
16
+use App\Models\Company;
17
+use App\Models\Setting\DocumentDefault;
16
 use App\Observers\EstimateObserver;
18
 use App\Observers\EstimateObserver;
17
 use Filament\Actions\Action;
19
 use Filament\Actions\Action;
18
 use Filament\Actions\MountableAction;
20
 use Filament\Actions\MountableAction;
212
         ]);
214
         ]);
213
     }
215
     }
214
 
216
 
215
-    public static function getNextDocumentNumber(): string
217
+    public static function getNextDocumentNumber(?Company $company = null): string
216
     {
218
     {
217
-        $company = auth()->user()->currentCompany;
219
+        $company ??= auth()->user()?->currentCompany;
218
 
220
 
219
         if (! $company) {
221
         if (! $company) {
220
             throw new \RuntimeException('No current company is set for the user.');
222
             throw new \RuntimeException('No current company is set for the user.');
221
         }
223
         }
222
 
224
 
223
-        $defaultEstimateSettings = $company->defaultInvoice;
225
+        $defaultEstimateSettings = $company->defaultEstimate;
224
 
226
 
225
-        $numberPrefix = 'EST-';
226
-        $numberDigits = $defaultEstimateSettings->number_digits;
227
+        $numberPrefix = $defaultEstimateSettings->number_prefix ?? '';
227
 
228
 
228
         $latestDocument = static::query()
229
         $latestDocument = static::query()
229
             ->whereNotNull('estimate_number')
230
             ->whereNotNull('estimate_number')
232
 
233
 
233
         $lastNumberNumericPart = $latestDocument
234
         $lastNumberNumericPart = $latestDocument
234
             ? (int) substr($latestDocument->estimate_number, strlen($numberPrefix))
235
             ? (int) substr($latestDocument->estimate_number, strlen($numberPrefix))
235
-            : 0;
236
+            : DocumentDefault::getBaseNumber();
236
 
237
 
237
         $numberNext = $lastNumberNumericPart + 1;
238
         $numberNext = $lastNumberNumericPart + 1;
238
 
239
 
239
         return $defaultEstimateSettings->getNumberNext(
240
         return $defaultEstimateSettings->getNumberNext(
240
-            padded: true,
241
-            format: true,
242
             prefix: $numberPrefix,
241
             prefix: $numberPrefix,
243
-            digits: $numberDigits,
244
             next: $numberNext
242
             next: $numberNext
245
         );
243
         );
246
     }
244
     }

+ 3
- 6
app/Models/Accounting/Invoice.php 查看文件

15
 use App\Models\Banking\BankAccount;
15
 use App\Models\Banking\BankAccount;
16
 use App\Models\Common\Client;
16
 use App\Models\Common\Client;
17
 use App\Models\Company;
17
 use App\Models\Company;
18
+use App\Models\Setting\DocumentDefault;
18
 use App\Observers\InvoiceObserver;
19
 use App\Observers\InvoiceObserver;
19
 use App\Utilities\Currency\CurrencyAccessor;
20
 use App\Utilities\Currency\CurrencyAccessor;
20
 use App\Utilities\Currency\CurrencyConverter;
21
 use App\Utilities\Currency\CurrencyConverter;
268
 
269
 
269
         $defaultInvoiceSettings = $company->defaultInvoice;
270
         $defaultInvoiceSettings = $company->defaultInvoice;
270
 
271
 
271
-        $numberPrefix = $defaultInvoiceSettings->number_prefix;
272
-        $numberDigits = $defaultInvoiceSettings->number_digits;
272
+        $numberPrefix = $defaultInvoiceSettings->number_prefix ?? '';
273
 
273
 
274
         $latestDocument = static::query()
274
         $latestDocument = static::query()
275
             ->whereNotNull('invoice_number')
275
             ->whereNotNull('invoice_number')
278
 
278
 
279
         $lastNumberNumericPart = $latestDocument
279
         $lastNumberNumericPart = $latestDocument
280
             ? (int) substr($latestDocument->invoice_number, strlen($numberPrefix))
280
             ? (int) substr($latestDocument->invoice_number, strlen($numberPrefix))
281
-            : 0;
281
+            : DocumentDefault::getBaseNumber();
282
 
282
 
283
         $numberNext = $lastNumberNumericPart + 1;
283
         $numberNext = $lastNumberNumericPart + 1;
284
 
284
 
285
         return $defaultInvoiceSettings->getNumberNext(
285
         return $defaultInvoiceSettings->getNumberNext(
286
-            padded: true,
287
-            format: true,
288
             prefix: $numberPrefix,
286
             prefix: $numberPrefix,
289
-            digits: $numberDigits,
290
             next: $numberNext
287
             next: $numberNext
291
         );
288
         );
292
     }
289
     }

+ 0
- 6
app/Models/Company.php 查看文件

10
 use App\Models\Common\Contact;
10
 use App\Models\Common\Contact;
11
 use App\Models\Common\Offering;
11
 use App\Models\Common\Offering;
12
 use App\Models\Core\Department;
12
 use App\Models\Core\Department;
13
-use App\Models\Setting\Appearance;
14
 use App\Models\Setting\CompanyDefault;
13
 use App\Models\Setting\CompanyDefault;
15
 use App\Models\Setting\CompanyProfile;
14
 use App\Models\Setting\CompanyProfile;
16
 use App\Models\Setting\Currency;
15
 use App\Models\Setting\Currency;
94
         return $this->hasMany(Accounting\Bill::class, 'company_id');
93
         return $this->hasMany(Accounting\Bill::class, 'company_id');
95
     }
94
     }
96
 
95
 
97
-    public function appearance(): HasOne
98
-    {
99
-        return $this->hasOne(Appearance::class, 'company_id');
100
-    }
101
-
102
     public function accountSubtypes(): HasMany
96
     public function accountSubtypes(): HasMany
103
     {
97
     {
104
         return $this->hasMany(AccountSubtype::class, 'company_id');
98
         return $this->hasMany(AccountSubtype::class, 'company_id');

+ 0
- 39
app/Models/Setting/Appearance.php 查看文件

1
-<?php
2
-
3
-namespace App\Models\Setting;
4
-
5
-use App\Concerns\Blamable;
6
-use App\Concerns\CompanyOwned;
7
-use App\Enums\Setting\Font;
8
-use App\Enums\Setting\PrimaryColor;
9
-use Database\Factories\Setting\AppearanceFactory;
10
-use Illuminate\Database\Eloquent\Factories\Factory;
11
-use Illuminate\Database\Eloquent\Factories\HasFactory;
12
-use Illuminate\Database\Eloquent\Model;
13
-
14
-class Appearance extends Model
15
-{
16
-    use Blamable;
17
-    use CompanyOwned;
18
-    use HasFactory;
19
-
20
-    protected $table = 'appearances';
21
-
22
-    protected $fillable = [
23
-        'company_id',
24
-        'primary_color',
25
-        'font',
26
-        'created_by',
27
-        'updated_by',
28
-    ];
29
-
30
-    protected $casts = [
31
-        'primary_color' => PrimaryColor::class,
32
-        'font' => Font::class,
33
-    ];
34
-
35
-    protected static function newFactory(): Factory
36
-    {
37
-        return AppearanceFactory::new();
38
-    }
39
-}

+ 6
- 32
app/Models/Setting/DocumentDefault.php 查看文件

2
 
2
 
3
 namespace App\Models\Setting;
3
 namespace App\Models\Setting;
4
 
4
 
5
-use App\Casts\TrimLeadingZeroCast;
6
 use App\Concerns\Blamable;
5
 use App\Concerns\Blamable;
7
 use App\Concerns\CompanyOwned;
6
 use App\Concerns\CompanyOwned;
8
 use App\Enums\Accounting\DocumentType;
7
 use App\Enums\Accounting\DocumentType;
32
         'logo',
31
         'logo',
33
         'show_logo',
32
         'show_logo',
34
         'number_prefix',
33
         'number_prefix',
35
-        'number_digits',
36
-        'number_next',
37
         'payment_terms',
34
         'payment_terms',
38
         'header',
35
         'header',
39
         'subheader',
36
         'subheader',
53
     protected $casts = [
50
     protected $casts = [
54
         'type' => DocumentType::class,
51
         'type' => DocumentType::class,
55
         'show_logo' => 'boolean',
52
         'show_logo' => 'boolean',
56
-        'number_next' => TrimLeadingZeroCast::class,
57
         'payment_terms' => PaymentTerms::class,
53
         'payment_terms' => PaymentTerms::class,
58
         'font' => Font::class,
54
         'font' => Font::class,
59
         'template' => Template::class,
55
         'template' => Template::class,
99
         return $query->type(DocumentType::Estimate);
95
         return $query->type(DocumentType::Estimate);
100
     }
96
     }
101
 
97
 
102
-    public static function availableNumberDigits(): array
98
+    public function getNumberNext(?string $prefix = null, int | string | null $next = null): string
103
     {
99
     {
104
-        return array_combine(range(1, 20), range(1, 20));
105
-    }
106
-
107
-    public function getNumberNext(?bool $padded = null, ?bool $format = null, ?string $prefix = null, int | string | null $digits = null, int | string | null $next = null): string
108
-    {
109
-        [$number_prefix, $number_digits, $number_next] = $this->initializeAttributes($prefix, $digits, $next);
110
-
111
-        return match (true) {
112
-            $format && $padded => $number_prefix . $this->getPaddedNumberNext($number_next, $number_digits),
113
-            $format => $number_prefix . $number_next,
114
-            $padded => $this->getPaddedNumberNext($number_next, $number_digits),
115
-            default => $number_next,
116
-        };
117
-    }
118
-
119
-    public function initializeAttributes(?string $prefix, int | string | null $digits, int | string | null $next): array
120
-    {
121
-        $number_prefix = $prefix ?? $this->number_prefix;
122
-        $number_digits = $digits ?? $this->number_digits;
123
-        $number_next = $next ?? $this->number_next;
100
+        $numberPrefix = $prefix ?? $this->number_prefix ?? '';
101
+        $numberNext = (string) ($next ?? (static::getBaseNumber() + 1));
124
 
102
 
125
-        return [$number_prefix, $number_digits, $number_next];
103
+        return $numberPrefix . $numberNext;
126
     }
104
     }
127
 
105
 
128
-    /**
129
-     * Get the next number with padding for dynamic display purposes.
130
-     * Even if number_next is a string, it will be cast to an integer.
131
-     */
132
-    public function getPaddedNumberNext(int | string | null $number_next, int | string | null $number_digits): string
106
+    public static function getBaseNumber(): int
133
     {
107
     {
134
-        return str_pad($number_next, $number_digits, '0', STR_PAD_LEFT);
108
+        return 1000;
135
     }
109
     }
136
 
110
 
137
     public static function getAvailableItemNameOptions(): array
111
     public static function getAvailableItemNameOptions(): array

+ 1
- 17
app/Services/CompanySettingsService.php 查看文件

3
 namespace App\Services;
3
 namespace App\Services;
4
 
4
 
5
 use App\Enums\Setting\DateFormat;
5
 use App\Enums\Setting\DateFormat;
6
-use App\Enums\Setting\Font;
7
-use App\Enums\Setting\PrimaryColor;
8
 use App\Enums\Setting\WeekStart;
6
 use App\Enums\Setting\WeekStart;
9
 use App\Models\Company;
7
 use App\Models\Company;
10
 use Illuminate\Support\Facades\Cache;
8
 use Illuminate\Support\Facades\Cache;
16
         $cacheKey = "company_settings_{$companyId}";
14
         $cacheKey = "company_settings_{$companyId}";
17
 
15
 
18
         return Cache::rememberForever($cacheKey, function () use ($companyId) {
16
         return Cache::rememberForever($cacheKey, function () use ($companyId) {
19
-            $company = Company::with(['locale', 'appearance'])->find($companyId);
17
+            $company = Company::with(['locale'])->find($companyId);
20
 
18
 
21
             if (! $company) {
19
             if (! $company) {
22
                 return self::getDefaultSettings();
20
                 return self::getDefaultSettings();
26
                 'default_language' => $company->locale->language ?? config('transmatic.source_locale'),
24
                 'default_language' => $company->locale->language ?? config('transmatic.source_locale'),
27
                 'default_timezone' => $company->locale->timezone ?? config('app.timezone'),
25
                 'default_timezone' => $company->locale->timezone ?? config('app.timezone'),
28
                 'default_currency' => $company->currency_code ?? 'USD',
26
                 'default_currency' => $company->currency_code ?? 'USD',
29
-                'default_primary_color' => $company->appearance->primary_color->value ?? PrimaryColor::DEFAULT,
30
-                'default_font' => $company->appearance->font->value ?? Font::DEFAULT,
31
                 'default_date_format' => $company->locale->date_format->value ?? DateFormat::DEFAULT,
27
                 'default_date_format' => $company->locale->date_format->value ?? DateFormat::DEFAULT,
32
                 'default_week_start' => $company->locale->week_start->value ?? WeekStart::DEFAULT,
28
                 'default_week_start' => $company->locale->week_start->value ?? WeekStart::DEFAULT,
33
             ];
29
             ];
46
             'default_language' => config('transmatic.source_locale'),
42
             'default_language' => config('transmatic.source_locale'),
47
             'default_timezone' => config('app.timezone'),
43
             'default_timezone' => config('app.timezone'),
48
             'default_currency' => 'USD',
44
             'default_currency' => 'USD',
49
-            'default_primary_color' => PrimaryColor::DEFAULT,
50
-            'default_font' => Font::DEFAULT,
51
             'default_date_format' => DateFormat::DEFAULT,
45
             'default_date_format' => DateFormat::DEFAULT,
52
             'default_week_start' => WeekStart::DEFAULT,
46
             'default_week_start' => WeekStart::DEFAULT,
53
         ];
47
         ];
75
         return self::getSpecificSetting($companyId, 'default_currency', 'USD');
69
         return self::getSpecificSetting($companyId, 'default_currency', 'USD');
76
     }
70
     }
77
 
71
 
78
-    public static function getDefaultPrimaryColor(int $companyId): string
79
-    {
80
-        return self::getSpecificSetting($companyId, 'default_primary_color', PrimaryColor::DEFAULT);
81
-    }
82
-
83
-    public static function getDefaultFont(int $companyId): string
84
-    {
85
-        return self::getSpecificSetting($companyId, 'default_font', Font::DEFAULT);
86
-    }
87
-
88
     public static function getDefaultDateFormat(int $companyId): string
72
     public static function getDefaultDateFormat(int $companyId): string
89
     {
73
     {
90
         return self::getSpecificSetting($companyId, 'default_date_format', DateFormat::DEFAULT);
74
         return self::getSpecificSetting($companyId, 'default_date_format', DateFormat::DEFAULT);

+ 104
- 104
composer.lock 查看文件

77
         },
77
         },
78
         {
78
         {
79
             "name": "andrewdwallo/filament-companies",
79
             "name": "andrewdwallo/filament-companies",
80
-            "version": "v4.1.1",
80
+            "version": "v4.1.2",
81
             "source": {
81
             "source": {
82
                 "type": "git",
82
                 "type": "git",
83
                 "url": "https://github.com/andrewdwallo/filament-companies.git",
83
                 "url": "https://github.com/andrewdwallo/filament-companies.git",
84
-                "reference": "a467d249285a066cbb915e2bb944eb00830ef060"
84
+                "reference": "e8472f6c5e74d4a3f4ffd7796752c779741ec699"
85
             },
85
             },
86
             "dist": {
86
             "dist": {
87
                 "type": "zip",
87
                 "type": "zip",
88
-                "url": "https://api.github.com/repos/andrewdwallo/filament-companies/zipball/a467d249285a066cbb915e2bb944eb00830ef060",
89
-                "reference": "a467d249285a066cbb915e2bb944eb00830ef060",
88
+                "url": "https://api.github.com/repos/andrewdwallo/filament-companies/zipball/e8472f6c5e74d4a3f4ffd7796752c779741ec699",
89
+                "reference": "e8472f6c5e74d4a3f4ffd7796752c779741ec699",
90
                 "shasum": ""
90
                 "shasum": ""
91
             },
91
             },
92
             "require": {
92
             "require": {
150
             ],
150
             ],
151
             "support": {
151
             "support": {
152
                 "issues": "https://github.com/andrewdwallo/filament-companies/issues",
152
                 "issues": "https://github.com/andrewdwallo/filament-companies/issues",
153
-                "source": "https://github.com/andrewdwallo/filament-companies/tree/v4.1.1"
153
+                "source": "https://github.com/andrewdwallo/filament-companies/tree/v4.1.2"
154
             },
154
             },
155
-            "time": "2025-02-16T19:05:34+00:00"
155
+            "time": "2025-02-20T01:18:23+00:00"
156
         },
156
         },
157
         {
157
         {
158
             "name": "andrewdwallo/filament-selectify",
158
             "name": "andrewdwallo/filament-selectify",
497
         },
497
         },
498
         {
498
         {
499
             "name": "aws/aws-sdk-php",
499
             "name": "aws/aws-sdk-php",
500
-            "version": "3.339.14",
500
+            "version": "3.339.19",
501
             "source": {
501
             "source": {
502
                 "type": "git",
502
                 "type": "git",
503
                 "url": "https://github.com/aws/aws-sdk-php.git",
503
                 "url": "https://github.com/aws/aws-sdk-php.git",
504
-                "reference": "532eb5e502c5b1181456023e41d61445b2c7101d"
504
+                "reference": "18f05efe983860ad899082e04c13f06ec9fd6e41"
505
             },
505
             },
506
             "dist": {
506
             "dist": {
507
                 "type": "zip",
507
                 "type": "zip",
508
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/532eb5e502c5b1181456023e41d61445b2c7101d",
509
-                "reference": "532eb5e502c5b1181456023e41d61445b2c7101d",
508
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/18f05efe983860ad899082e04c13f06ec9fd6e41",
509
+                "reference": "18f05efe983860ad899082e04c13f06ec9fd6e41",
510
                 "shasum": ""
510
                 "shasum": ""
511
             },
511
             },
512
             "require": {
512
             "require": {
588
             "support": {
588
             "support": {
589
                 "forum": "https://github.com/aws/aws-sdk-php/discussions",
589
                 "forum": "https://github.com/aws/aws-sdk-php/discussions",
590
                 "issues": "https://github.com/aws/aws-sdk-php/issues",
590
                 "issues": "https://github.com/aws/aws-sdk-php/issues",
591
-                "source": "https://github.com/aws/aws-sdk-php/tree/3.339.14"
591
+                "source": "https://github.com/aws/aws-sdk-php/tree/3.339.19"
592
             },
592
             },
593
-            "time": "2025-02-14T19:11:38+00:00"
593
+            "time": "2025-02-21T19:13:15+00:00"
594
         },
594
         },
595
         {
595
         {
596
             "name": "aws/aws-sdk-php-laravel",
596
             "name": "aws/aws-sdk-php-laravel",
1152
         },
1152
         },
1153
         {
1153
         {
1154
             "name": "danharrin/livewire-rate-limiting",
1154
             "name": "danharrin/livewire-rate-limiting",
1155
-            "version": "v2.0.2",
1155
+            "version": "v2.1.0",
1156
             "source": {
1156
             "source": {
1157
                 "type": "git",
1157
                 "type": "git",
1158
                 "url": "https://github.com/danharrin/livewire-rate-limiting.git",
1158
                 "url": "https://github.com/danharrin/livewire-rate-limiting.git",
1159
-                "reference": "003817754b11f7189b9bd1252c27f2fbb4505a2d"
1159
+                "reference": "14dde653a9ae8f38af07a0ba4921dc046235e1a0"
1160
             },
1160
             },
1161
             "dist": {
1161
             "dist": {
1162
                 "type": "zip",
1162
                 "type": "zip",
1163
-                "url": "https://api.github.com/repos/danharrin/livewire-rate-limiting/zipball/003817754b11f7189b9bd1252c27f2fbb4505a2d",
1164
-                "reference": "003817754b11f7189b9bd1252c27f2fbb4505a2d",
1163
+                "url": "https://api.github.com/repos/danharrin/livewire-rate-limiting/zipball/14dde653a9ae8f38af07a0ba4921dc046235e1a0",
1164
+                "reference": "14dde653a9ae8f38af07a0ba4921dc046235e1a0",
1165
                 "shasum": ""
1165
                 "shasum": ""
1166
             },
1166
             },
1167
             "require": {
1167
             "require": {
1168
-                "illuminate/support": "^9.0|^10.0|^11.0",
1168
+                "illuminate/support": "^9.0|^10.0|^11.0|^12.0",
1169
                 "php": "^8.0"
1169
                 "php": "^8.0"
1170
             },
1170
             },
1171
             "require-dev": {
1171
             "require-dev": {
1172
                 "livewire/livewire": "^3.0",
1172
                 "livewire/livewire": "^3.0",
1173
                 "livewire/volt": "^1.3",
1173
                 "livewire/volt": "^1.3",
1174
-                "orchestra/testbench": "^7.0|^8.0|^9.0",
1175
-                "phpunit/phpunit": "^9.0|^10.0"
1174
+                "orchestra/testbench": "^7.0|^8.0|^9.0|^10.0",
1175
+                "phpunit/phpunit": "^9.0|^10.0|^11.5.3"
1176
             },
1176
             },
1177
             "type": "library",
1177
             "type": "library",
1178
             "autoload": {
1178
             "autoload": {
1202
                     "type": "github"
1202
                     "type": "github"
1203
                 }
1203
                 }
1204
             ],
1204
             ],
1205
-            "time": "2025-02-14T10:47:35+00:00"
1205
+            "time": "2025-02-21T08:52:11+00:00"
1206
         },
1206
         },
1207
         {
1207
         {
1208
             "name": "dflydev/dot-access-data",
1208
             "name": "dflydev/dot-access-data",
1732
         },
1732
         },
1733
         {
1733
         {
1734
             "name": "filament/actions",
1734
             "name": "filament/actions",
1735
-            "version": "v3.2.140",
1735
+            "version": "v3.2.142",
1736
             "source": {
1736
             "source": {
1737
                 "type": "git",
1737
                 "type": "git",
1738
                 "url": "https://github.com/filamentphp/actions.git",
1738
                 "url": "https://github.com/filamentphp/actions.git",
1739
-                "reference": "cc8a0705a497508f499df29257cb3e0619a5ea04"
1739
+                "reference": "0decaf9a48858ff105fc38ed47d36e26995c533b"
1740
             },
1740
             },
1741
             "dist": {
1741
             "dist": {
1742
                 "type": "zip",
1742
                 "type": "zip",
1743
-                "url": "https://api.github.com/repos/filamentphp/actions/zipball/cc8a0705a497508f499df29257cb3e0619a5ea04",
1744
-                "reference": "cc8a0705a497508f499df29257cb3e0619a5ea04",
1743
+                "url": "https://api.github.com/repos/filamentphp/actions/zipball/0decaf9a48858ff105fc38ed47d36e26995c533b",
1744
+                "reference": "0decaf9a48858ff105fc38ed47d36e26995c533b",
1745
                 "shasum": ""
1745
                 "shasum": ""
1746
             },
1746
             },
1747
             "require": {
1747
             "require": {
1781
                 "issues": "https://github.com/filamentphp/filament/issues",
1781
                 "issues": "https://github.com/filamentphp/filament/issues",
1782
                 "source": "https://github.com/filamentphp/filament"
1782
                 "source": "https://github.com/filamentphp/filament"
1783
             },
1783
             },
1784
-            "time": "2025-02-10T08:14:18+00:00"
1784
+            "time": "2025-02-20T23:14:35+00:00"
1785
         },
1785
         },
1786
         {
1786
         {
1787
             "name": "filament/filament",
1787
             "name": "filament/filament",
1788
-            "version": "v3.2.140",
1788
+            "version": "v3.2.142",
1789
             "source": {
1789
             "source": {
1790
                 "type": "git",
1790
                 "type": "git",
1791
                 "url": "https://github.com/filamentphp/panels.git",
1791
                 "url": "https://github.com/filamentphp/panels.git",
1792
-                "reference": "2d94d24eed26c063e6d04bea4d2cd2b8f62926f9"
1792
+                "reference": "c68bd2a46bdb02df7b8145aafb2f505062bcbded"
1793
             },
1793
             },
1794
             "dist": {
1794
             "dist": {
1795
                 "type": "zip",
1795
                 "type": "zip",
1796
-                "url": "https://api.github.com/repos/filamentphp/panels/zipball/2d94d24eed26c063e6d04bea4d2cd2b8f62926f9",
1797
-                "reference": "2d94d24eed26c063e6d04bea4d2cd2b8f62926f9",
1796
+                "url": "https://api.github.com/repos/filamentphp/panels/zipball/c68bd2a46bdb02df7b8145aafb2f505062bcbded",
1797
+                "reference": "c68bd2a46bdb02df7b8145aafb2f505062bcbded",
1798
                 "shasum": ""
1798
                 "shasum": ""
1799
             },
1799
             },
1800
             "require": {
1800
             "require": {
1846
                 "issues": "https://github.com/filamentphp/filament/issues",
1846
                 "issues": "https://github.com/filamentphp/filament/issues",
1847
                 "source": "https://github.com/filamentphp/filament"
1847
                 "source": "https://github.com/filamentphp/filament"
1848
             },
1848
             },
1849
-            "time": "2025-02-11T07:46:34+00:00"
1849
+            "time": "2025-02-19T08:42:25+00:00"
1850
         },
1850
         },
1851
         {
1851
         {
1852
             "name": "filament/forms",
1852
             "name": "filament/forms",
1853
-            "version": "v3.2.140",
1853
+            "version": "v3.2.142",
1854
             "source": {
1854
             "source": {
1855
                 "type": "git",
1855
                 "type": "git",
1856
                 "url": "https://github.com/filamentphp/forms.git",
1856
                 "url": "https://github.com/filamentphp/forms.git",
1857
-                "reference": "de69a442a458160aa29d382b952d8f1c0b641a32"
1857
+                "reference": "357a5d4c92661911949ebe56c5f281267d908609"
1858
             },
1858
             },
1859
             "dist": {
1859
             "dist": {
1860
                 "type": "zip",
1860
                 "type": "zip",
1861
-                "url": "https://api.github.com/repos/filamentphp/forms/zipball/de69a442a458160aa29d382b952d8f1c0b641a32",
1862
-                "reference": "de69a442a458160aa29d382b952d8f1c0b641a32",
1861
+                "url": "https://api.github.com/repos/filamentphp/forms/zipball/357a5d4c92661911949ebe56c5f281267d908609",
1862
+                "reference": "357a5d4c92661911949ebe56c5f281267d908609",
1863
                 "shasum": ""
1863
                 "shasum": ""
1864
             },
1864
             },
1865
             "require": {
1865
             "require": {
1902
                 "issues": "https://github.com/filamentphp/filament/issues",
1902
                 "issues": "https://github.com/filamentphp/filament/issues",
1903
                 "source": "https://github.com/filamentphp/filament"
1903
                 "source": "https://github.com/filamentphp/filament"
1904
             },
1904
             },
1905
-            "time": "2025-02-10T10:37:19+00:00"
1905
+            "time": "2025-02-20T23:14:35+00:00"
1906
         },
1906
         },
1907
         {
1907
         {
1908
             "name": "filament/infolists",
1908
             "name": "filament/infolists",
1909
-            "version": "v3.2.140",
1909
+            "version": "v3.2.142",
1910
             "source": {
1910
             "source": {
1911
                 "type": "git",
1911
                 "type": "git",
1912
                 "url": "https://github.com/filamentphp/infolists.git",
1912
                 "url": "https://github.com/filamentphp/infolists.git",
1913
-                "reference": "f6807434251196bed526540646da53efb6241ddc"
1913
+                "reference": "e015d90d88294385274cdb01a00e1c08dbc6b6d7"
1914
             },
1914
             },
1915
             "dist": {
1915
             "dist": {
1916
                 "type": "zip",
1916
                 "type": "zip",
1917
-                "url": "https://api.github.com/repos/filamentphp/infolists/zipball/f6807434251196bed526540646da53efb6241ddc",
1918
-                "reference": "f6807434251196bed526540646da53efb6241ddc",
1917
+                "url": "https://api.github.com/repos/filamentphp/infolists/zipball/e015d90d88294385274cdb01a00e1c08dbc6b6d7",
1918
+                "reference": "e015d90d88294385274cdb01a00e1c08dbc6b6d7",
1919
                 "shasum": ""
1919
                 "shasum": ""
1920
             },
1920
             },
1921
             "require": {
1921
             "require": {
1953
                 "issues": "https://github.com/filamentphp/filament/issues",
1953
                 "issues": "https://github.com/filamentphp/filament/issues",
1954
                 "source": "https://github.com/filamentphp/filament"
1954
                 "source": "https://github.com/filamentphp/filament"
1955
             },
1955
             },
1956
-            "time": "2025-02-10T08:14:18+00:00"
1956
+            "time": "2025-02-19T08:42:24+00:00"
1957
         },
1957
         },
1958
         {
1958
         {
1959
             "name": "filament/notifications",
1959
             "name": "filament/notifications",
1960
-            "version": "v3.2.140",
1960
+            "version": "v3.2.142",
1961
             "source": {
1961
             "source": {
1962
                 "type": "git",
1962
                 "type": "git",
1963
                 "url": "https://github.com/filamentphp/notifications.git",
1963
                 "url": "https://github.com/filamentphp/notifications.git",
1964
-                "reference": "1b5c8cf1e8cf2022e437637d7cceb4ad378982a4"
1964
+                "reference": "5c7809f5672ec721f09a65b3a6394bd79b2a9ee2"
1965
             },
1965
             },
1966
             "dist": {
1966
             "dist": {
1967
                 "type": "zip",
1967
                 "type": "zip",
1968
-                "url": "https://api.github.com/repos/filamentphp/notifications/zipball/1b5c8cf1e8cf2022e437637d7cceb4ad378982a4",
1969
-                "reference": "1b5c8cf1e8cf2022e437637d7cceb4ad378982a4",
1968
+                "url": "https://api.github.com/repos/filamentphp/notifications/zipball/5c7809f5672ec721f09a65b3a6394bd79b2a9ee2",
1969
+                "reference": "5c7809f5672ec721f09a65b3a6394bd79b2a9ee2",
1970
                 "shasum": ""
1970
                 "shasum": ""
1971
             },
1971
             },
1972
             "require": {
1972
             "require": {
2005
                 "issues": "https://github.com/filamentphp/filament/issues",
2005
                 "issues": "https://github.com/filamentphp/filament/issues",
2006
                 "source": "https://github.com/filamentphp/filament"
2006
                 "source": "https://github.com/filamentphp/filament"
2007
             },
2007
             },
2008
-            "time": "2025-02-10T08:14:22+00:00"
2008
+            "time": "2025-02-19T08:42:24+00:00"
2009
         },
2009
         },
2010
         {
2010
         {
2011
             "name": "filament/support",
2011
             "name": "filament/support",
2012
-            "version": "v3.2.140",
2012
+            "version": "v3.2.142",
2013
             "source": {
2013
             "source": {
2014
                 "type": "git",
2014
                 "type": "git",
2015
                 "url": "https://github.com/filamentphp/support.git",
2015
                 "url": "https://github.com/filamentphp/support.git",
2016
-                "reference": "95223f4bbfaa8c817efeacb4e2e7ca6928297610"
2016
+                "reference": "84b4fe507e250ed37e69d92854753761ad5d7908"
2017
             },
2017
             },
2018
             "dist": {
2018
             "dist": {
2019
                 "type": "zip",
2019
                 "type": "zip",
2020
-                "url": "https://api.github.com/repos/filamentphp/support/zipball/95223f4bbfaa8c817efeacb4e2e7ca6928297610",
2021
-                "reference": "95223f4bbfaa8c817efeacb4e2e7ca6928297610",
2020
+                "url": "https://api.github.com/repos/filamentphp/support/zipball/84b4fe507e250ed37e69d92854753761ad5d7908",
2021
+                "reference": "84b4fe507e250ed37e69d92854753761ad5d7908",
2022
                 "shasum": ""
2022
                 "shasum": ""
2023
             },
2023
             },
2024
             "require": {
2024
             "require": {
2064
                 "issues": "https://github.com/filamentphp/filament/issues",
2064
                 "issues": "https://github.com/filamentphp/filament/issues",
2065
                 "source": "https://github.com/filamentphp/filament"
2065
                 "source": "https://github.com/filamentphp/filament"
2066
             },
2066
             },
2067
-            "time": "2025-02-10T08:14:57+00:00"
2067
+            "time": "2025-02-20T23:14:48+00:00"
2068
         },
2068
         },
2069
         {
2069
         {
2070
             "name": "filament/tables",
2070
             "name": "filament/tables",
2071
-            "version": "v3.2.140",
2071
+            "version": "v3.2.142",
2072
             "source": {
2072
             "source": {
2073
                 "type": "git",
2073
                 "type": "git",
2074
                 "url": "https://github.com/filamentphp/tables.git",
2074
                 "url": "https://github.com/filamentphp/tables.git",
2075
-                "reference": "c1bf374b1c3286c2b70c3898c269b89cc966d560"
2075
+                "reference": "1eb41bbc46a3b0deba2adcdcaa3bd2556a0a0d08"
2076
             },
2076
             },
2077
             "dist": {
2077
             "dist": {
2078
                 "type": "zip",
2078
                 "type": "zip",
2079
-                "url": "https://api.github.com/repos/filamentphp/tables/zipball/c1bf374b1c3286c2b70c3898c269b89cc966d560",
2080
-                "reference": "c1bf374b1c3286c2b70c3898c269b89cc966d560",
2079
+                "url": "https://api.github.com/repos/filamentphp/tables/zipball/1eb41bbc46a3b0deba2adcdcaa3bd2556a0a0d08",
2080
+                "reference": "1eb41bbc46a3b0deba2adcdcaa3bd2556a0a0d08",
2081
                 "shasum": ""
2081
                 "shasum": ""
2082
             },
2082
             },
2083
             "require": {
2083
             "require": {
2116
                 "issues": "https://github.com/filamentphp/filament/issues",
2116
                 "issues": "https://github.com/filamentphp/filament/issues",
2117
                 "source": "https://github.com/filamentphp/filament"
2117
                 "source": "https://github.com/filamentphp/filament"
2118
             },
2118
             },
2119
-            "time": "2025-02-10T08:14:59+00:00"
2119
+            "time": "2025-02-20T23:14:49+00:00"
2120
         },
2120
         },
2121
         {
2121
         {
2122
             "name": "filament/widgets",
2122
             "name": "filament/widgets",
2123
-            "version": "v3.2.140",
2123
+            "version": "v3.2.142",
2124
             "source": {
2124
             "source": {
2125
                 "type": "git",
2125
                 "type": "git",
2126
                 "url": "https://github.com/filamentphp/widgets.git",
2126
                 "url": "https://github.com/filamentphp/widgets.git",
2127
-                "reference": "c0d29d9822c56ca37af6b04edb2fc51b02002fee"
2127
+                "reference": "3bbd19044e19f93711f3690c441a3a0d35696aa1"
2128
             },
2128
             },
2129
             "dist": {
2129
             "dist": {
2130
                 "type": "zip",
2130
                 "type": "zip",
2131
-                "url": "https://api.github.com/repos/filamentphp/widgets/zipball/c0d29d9822c56ca37af6b04edb2fc51b02002fee",
2132
-                "reference": "c0d29d9822c56ca37af6b04edb2fc51b02002fee",
2131
+                "url": "https://api.github.com/repos/filamentphp/widgets/zipball/3bbd19044e19f93711f3690c441a3a0d35696aa1",
2132
+                "reference": "3bbd19044e19f93711f3690c441a3a0d35696aa1",
2133
                 "shasum": ""
2133
                 "shasum": ""
2134
             },
2134
             },
2135
             "require": {
2135
             "require": {
2160
                 "issues": "https://github.com/filamentphp/filament/issues",
2160
                 "issues": "https://github.com/filamentphp/filament/issues",
2161
                 "source": "https://github.com/filamentphp/filament"
2161
                 "source": "https://github.com/filamentphp/filament"
2162
             },
2162
             },
2163
-            "time": "2025-02-10T10:37:39+00:00"
2163
+            "time": "2025-02-19T08:42:37+00:00"
2164
         },
2164
         },
2165
         {
2165
         {
2166
             "name": "firebase/php-jwt",
2166
             "name": "firebase/php-jwt",
3050
         },
3050
         },
3051
         {
3051
         {
3052
             "name": "laravel/framework",
3052
             "name": "laravel/framework",
3053
-            "version": "v11.42.1",
3053
+            "version": "v11.43.2",
3054
             "source": {
3054
             "source": {
3055
                 "type": "git",
3055
                 "type": "git",
3056
                 "url": "https://github.com/laravel/framework.git",
3056
                 "url": "https://github.com/laravel/framework.git",
3057
-                "reference": "ff392f42f6c55cc774ce75553a11c6b031da67f8"
3057
+                "reference": "99d1573698abc42222f04d25fcd5b213d0eedf21"
3058
             },
3058
             },
3059
             "dist": {
3059
             "dist": {
3060
                 "type": "zip",
3060
                 "type": "zip",
3061
-                "url": "https://api.github.com/repos/laravel/framework/zipball/ff392f42f6c55cc774ce75553a11c6b031da67f8",
3062
-                "reference": "ff392f42f6c55cc774ce75553a11c6b031da67f8",
3061
+                "url": "https://api.github.com/repos/laravel/framework/zipball/99d1573698abc42222f04d25fcd5b213d0eedf21",
3062
+                "reference": "99d1573698abc42222f04d25fcd5b213d0eedf21",
3063
                 "shasum": ""
3063
                 "shasum": ""
3064
             },
3064
             },
3065
             "require": {
3065
             "require": {
3261
                 "issues": "https://github.com/laravel/framework/issues",
3261
                 "issues": "https://github.com/laravel/framework/issues",
3262
                 "source": "https://github.com/laravel/framework"
3262
                 "source": "https://github.com/laravel/framework"
3263
             },
3263
             },
3264
-            "time": "2025-02-12T20:58:18+00:00"
3264
+            "time": "2025-02-19T21:53:48+00:00"
3265
         },
3265
         },
3266
         {
3266
         {
3267
             "name": "laravel/prompts",
3267
             "name": "laravel/prompts",
4736
         },
4736
         },
4737
         {
4737
         {
4738
             "name": "nesbot/carbon",
4738
             "name": "nesbot/carbon",
4739
-            "version": "3.8.5",
4739
+            "version": "3.8.6",
4740
             "source": {
4740
             "source": {
4741
                 "type": "git",
4741
                 "type": "git",
4742
                 "url": "https://github.com/CarbonPHP/carbon.git",
4742
                 "url": "https://github.com/CarbonPHP/carbon.git",
4743
-                "reference": "b1a53a27898639579a67de42e8ced5d5386aa9a4"
4743
+                "reference": "ff2f20cf83bd4d503720632ce8a426dc747bf7fd"
4744
             },
4744
             },
4745
             "dist": {
4745
             "dist": {
4746
                 "type": "zip",
4746
                 "type": "zip",
4747
-                "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/b1a53a27898639579a67de42e8ced5d5386aa9a4",
4748
-                "reference": "b1a53a27898639579a67de42e8ced5d5386aa9a4",
4747
+                "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/ff2f20cf83bd4d503720632ce8a426dc747bf7fd",
4748
+                "reference": "ff2f20cf83bd4d503720632ce8a426dc747bf7fd",
4749
                 "shasum": ""
4749
                 "shasum": ""
4750
             },
4750
             },
4751
             "require": {
4751
             "require": {
4838
                     "type": "tidelift"
4838
                     "type": "tidelift"
4839
                 }
4839
                 }
4840
             ],
4840
             ],
4841
-            "time": "2025-02-11T16:28:45+00:00"
4841
+            "time": "2025-02-20T17:33:38+00:00"
4842
         },
4842
         },
4843
         {
4843
         {
4844
             "name": "nette/schema",
4844
             "name": "nette/schema",
9711
         },
9711
         },
9712
         {
9712
         {
9713
             "name": "laravel/pint",
9713
             "name": "laravel/pint",
9714
-            "version": "v1.20.0",
9714
+            "version": "v1.21.0",
9715
             "source": {
9715
             "source": {
9716
                 "type": "git",
9716
                 "type": "git",
9717
                 "url": "https://github.com/laravel/pint.git",
9717
                 "url": "https://github.com/laravel/pint.git",
9718
-                "reference": "53072e8ea22213a7ed168a8a15b96fbb8b82d44b"
9718
+                "reference": "531fa0871fbde719c51b12afa3a443b8f4e4b425"
9719
             },
9719
             },
9720
             "dist": {
9720
             "dist": {
9721
                 "type": "zip",
9721
                 "type": "zip",
9722
-                "url": "https://api.github.com/repos/laravel/pint/zipball/53072e8ea22213a7ed168a8a15b96fbb8b82d44b",
9723
-                "reference": "53072e8ea22213a7ed168a8a15b96fbb8b82d44b",
9722
+                "url": "https://api.github.com/repos/laravel/pint/zipball/531fa0871fbde719c51b12afa3a443b8f4e4b425",
9723
+                "reference": "531fa0871fbde719c51b12afa3a443b8f4e4b425",
9724
                 "shasum": ""
9724
                 "shasum": ""
9725
             },
9725
             },
9726
             "require": {
9726
             "require": {
9728
                 "ext-mbstring": "*",
9728
                 "ext-mbstring": "*",
9729
                 "ext-tokenizer": "*",
9729
                 "ext-tokenizer": "*",
9730
                 "ext-xml": "*",
9730
                 "ext-xml": "*",
9731
-                "php": "^8.1.0"
9731
+                "php": "^8.2.0"
9732
             },
9732
             },
9733
             "require-dev": {
9733
             "require-dev": {
9734
-                "friendsofphp/php-cs-fixer": "^3.66.0",
9735
-                "illuminate/view": "^10.48.25",
9736
-                "larastan/larastan": "^2.9.12",
9737
-                "laravel-zero/framework": "^10.48.25",
9734
+                "friendsofphp/php-cs-fixer": "^3.68.5",
9735
+                "illuminate/view": "^11.42.0",
9736
+                "larastan/larastan": "^3.0.4",
9737
+                "laravel-zero/framework": "^11.36.1",
9738
                 "mockery/mockery": "^1.6.12",
9738
                 "mockery/mockery": "^1.6.12",
9739
-                "nunomaduro/termwind": "^1.17.0",
9739
+                "nunomaduro/termwind": "^2.3",
9740
                 "pestphp/pest": "^2.36.0"
9740
                 "pestphp/pest": "^2.36.0"
9741
             },
9741
             },
9742
             "bin": [
9742
             "bin": [
9773
                 "issues": "https://github.com/laravel/pint/issues",
9773
                 "issues": "https://github.com/laravel/pint/issues",
9774
                 "source": "https://github.com/laravel/pint"
9774
                 "source": "https://github.com/laravel/pint"
9775
             },
9775
             },
9776
-            "time": "2025-01-14T16:20:53+00:00"
9776
+            "time": "2025-02-18T03:18:57+00:00"
9777
         },
9777
         },
9778
         {
9778
         {
9779
             "name": "laravel/sail",
9779
             "name": "laravel/sail",
10892
         },
10892
         },
10893
         {
10893
         {
10894
             "name": "phpstan/phpdoc-parser",
10894
             "name": "phpstan/phpdoc-parser",
10895
-            "version": "2.0.1",
10895
+            "version": "2.1.0",
10896
             "source": {
10896
             "source": {
10897
                 "type": "git",
10897
                 "type": "git",
10898
                 "url": "https://github.com/phpstan/phpdoc-parser.git",
10898
                 "url": "https://github.com/phpstan/phpdoc-parser.git",
10899
-                "reference": "72e51f7c32c5aef7c8b462195b8c599b11199893"
10899
+                "reference": "9b30d6fd026b2c132b3985ce6b23bec09ab3aa68"
10900
             },
10900
             },
10901
             "dist": {
10901
             "dist": {
10902
                 "type": "zip",
10902
                 "type": "zip",
10903
-                "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/72e51f7c32c5aef7c8b462195b8c599b11199893",
10904
-                "reference": "72e51f7c32c5aef7c8b462195b8c599b11199893",
10903
+                "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/9b30d6fd026b2c132b3985ce6b23bec09ab3aa68",
10904
+                "reference": "9b30d6fd026b2c132b3985ce6b23bec09ab3aa68",
10905
                 "shasum": ""
10905
                 "shasum": ""
10906
             },
10906
             },
10907
             "require": {
10907
             "require": {
10933
             "description": "PHPDoc parser with support for nullable, intersection and generic types",
10933
             "description": "PHPDoc parser with support for nullable, intersection and generic types",
10934
             "support": {
10934
             "support": {
10935
                 "issues": "https://github.com/phpstan/phpdoc-parser/issues",
10935
                 "issues": "https://github.com/phpstan/phpdoc-parser/issues",
10936
-                "source": "https://github.com/phpstan/phpdoc-parser/tree/2.0.1"
10936
+                "source": "https://github.com/phpstan/phpdoc-parser/tree/2.1.0"
10937
             },
10937
             },
10938
-            "time": "2025-02-13T12:25:43+00:00"
10938
+            "time": "2025-02-19T13:28:12+00:00"
10939
         },
10939
         },
10940
         {
10940
         {
10941
             "name": "phpunit/php-code-coverage",
10941
             "name": "phpunit/php-code-coverage",
12495
         },
12495
         },
12496
         {
12496
         {
12497
             "name": "spatie/ignition",
12497
             "name": "spatie/ignition",
12498
-            "version": "1.15.0",
12498
+            "version": "1.15.1",
12499
             "source": {
12499
             "source": {
12500
                 "type": "git",
12500
                 "type": "git",
12501
                 "url": "https://github.com/spatie/ignition.git",
12501
                 "url": "https://github.com/spatie/ignition.git",
12502
-                "reference": "e3a68e137371e1eb9edc7f78ffa733f3b98991d2"
12502
+                "reference": "31f314153020aee5af3537e507fef892ffbf8c85"
12503
             },
12503
             },
12504
             "dist": {
12504
             "dist": {
12505
                 "type": "zip",
12505
                 "type": "zip",
12506
-                "url": "https://api.github.com/repos/spatie/ignition/zipball/e3a68e137371e1eb9edc7f78ffa733f3b98991d2",
12507
-                "reference": "e3a68e137371e1eb9edc7f78ffa733f3b98991d2",
12506
+                "url": "https://api.github.com/repos/spatie/ignition/zipball/31f314153020aee5af3537e507fef892ffbf8c85",
12507
+                "reference": "31f314153020aee5af3537e507fef892ffbf8c85",
12508
                 "shasum": ""
12508
                 "shasum": ""
12509
             },
12509
             },
12510
             "require": {
12510
             "require": {
12517
                 "symfony/var-dumper": "^5.4|^6.0|^7.0"
12517
                 "symfony/var-dumper": "^5.4|^6.0|^7.0"
12518
             },
12518
             },
12519
             "require-dev": {
12519
             "require-dev": {
12520
-                "illuminate/cache": "^9.52|^10.0|^11.0",
12520
+                "illuminate/cache": "^9.52|^10.0|^11.0|^12.0",
12521
                 "mockery/mockery": "^1.4",
12521
                 "mockery/mockery": "^1.4",
12522
                 "pestphp/pest": "^1.20|^2.0",
12522
                 "pestphp/pest": "^1.20|^2.0",
12523
                 "phpstan/extension-installer": "^1.1",
12523
                 "phpstan/extension-installer": "^1.1",
12574
                     "type": "github"
12574
                     "type": "github"
12575
                 }
12575
                 }
12576
             ],
12576
             ],
12577
-            "time": "2024-06-12T14:55:22+00:00"
12577
+            "time": "2025-02-21T14:31:39+00:00"
12578
         },
12578
         },
12579
         {
12579
         {
12580
             "name": "spatie/laravel-ignition",
12580
             "name": "spatie/laravel-ignition",
12581
-            "version": "2.9.0",
12581
+            "version": "2.9.1",
12582
             "source": {
12582
             "source": {
12583
                 "type": "git",
12583
                 "type": "git",
12584
                 "url": "https://github.com/spatie/laravel-ignition.git",
12584
                 "url": "https://github.com/spatie/laravel-ignition.git",
12585
-                "reference": "62042df15314b829d0f26e02108f559018e2aad0"
12585
+                "reference": "1baee07216d6748ebd3a65ba97381b051838707a"
12586
             },
12586
             },
12587
             "dist": {
12587
             "dist": {
12588
                 "type": "zip",
12588
                 "type": "zip",
12589
-                "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/62042df15314b829d0f26e02108f559018e2aad0",
12590
-                "reference": "62042df15314b829d0f26e02108f559018e2aad0",
12589
+                "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/1baee07216d6748ebd3a65ba97381b051838707a",
12590
+                "reference": "1baee07216d6748ebd3a65ba97381b051838707a",
12591
                 "shasum": ""
12591
                 "shasum": ""
12592
             },
12592
             },
12593
             "require": {
12593
             "require": {
12594
                 "ext-curl": "*",
12594
                 "ext-curl": "*",
12595
                 "ext-json": "*",
12595
                 "ext-json": "*",
12596
                 "ext-mbstring": "*",
12596
                 "ext-mbstring": "*",
12597
-                "illuminate/support": "^10.0|^11.0",
12597
+                "illuminate/support": "^10.0|^11.0|^12.0",
12598
                 "php": "^8.1",
12598
                 "php": "^8.1",
12599
                 "spatie/ignition": "^1.15",
12599
                 "spatie/ignition": "^1.15",
12600
                 "symfony/console": "^6.2.3|^7.0",
12600
                 "symfony/console": "^6.2.3|^7.0",
12603
             "require-dev": {
12603
             "require-dev": {
12604
                 "livewire/livewire": "^2.11|^3.3.5",
12604
                 "livewire/livewire": "^2.11|^3.3.5",
12605
                 "mockery/mockery": "^1.5.1",
12605
                 "mockery/mockery": "^1.5.1",
12606
-                "openai-php/client": "^0.8.1",
12607
-                "orchestra/testbench": "8.22.3|^9.0",
12608
-                "pestphp/pest": "^2.34",
12606
+                "openai-php/client": "^0.8.1|^0.10",
12607
+                "orchestra/testbench": "8.22.3|^9.0|^10.0",
12608
+                "pestphp/pest": "^2.34|^3.7",
12609
                 "phpstan/extension-installer": "^1.3.1",
12609
                 "phpstan/extension-installer": "^1.3.1",
12610
-                "phpstan/phpstan-deprecation-rules": "^1.1.1",
12611
-                "phpstan/phpstan-phpunit": "^1.3.16",
12610
+                "phpstan/phpstan-deprecation-rules": "^1.1.1|^2.0",
12611
+                "phpstan/phpstan-phpunit": "^1.3.16|^2.0",
12612
                 "vlucas/phpdotenv": "^5.5"
12612
                 "vlucas/phpdotenv": "^5.5"
12613
             },
12613
             },
12614
             "suggest": {
12614
             "suggest": {
12665
                     "type": "github"
12665
                     "type": "github"
12666
                 }
12666
                 }
12667
             ],
12667
             ],
12668
-            "time": "2024-12-02T08:43:31+00:00"
12668
+            "time": "2025-02-20T13:13:55+00:00"
12669
         },
12669
         },
12670
         {
12670
         {
12671
             "name": "spatie/laravel-ray",
12671
             "name": "spatie/laravel-ray",

+ 6
- 5
database/factories/Accounting/BillFactory.php 查看文件

8
 use App\Models\Accounting\DocumentLineItem;
8
 use App\Models\Accounting\DocumentLineItem;
9
 use App\Models\Banking\BankAccount;
9
 use App\Models\Banking\BankAccount;
10
 use App\Models\Common\Vendor;
10
 use App\Models\Common\Vendor;
11
+use App\Models\Setting\DocumentDefault;
11
 use App\Utilities\Currency\CurrencyConverter;
12
 use App\Utilities\Currency\CurrencyConverter;
12
 use Illuminate\Database\Eloquent\Factories\Factory;
13
 use Illuminate\Database\Eloquent\Factories\Factory;
13
 use Illuminate\Support\Carbon;
14
 use Illuminate\Support\Carbon;
42
         return [
43
         return [
43
             'company_id' => 1,
44
             'company_id' => 1,
44
             'vendor_id' => Vendor::inRandomOrder()->value('id'),
45
             'vendor_id' => Vendor::inRandomOrder()->value('id'),
45
-            'bill_number' => $this->faker->unique()->numerify('BILL-#####'),
46
-            'order_number' => $this->faker->unique()->numerify('PO-#####'),
46
+            'bill_number' => $this->faker->unique()->numerify('BILL-####'),
47
+            'order_number' => $this->faker->unique()->numerify('PO-####'),
47
             'date' => $billDate,
48
             'date' => $billDate,
48
             'due_date' => Carbon::parse($billDate)->addDays($dueDays),
49
             'due_date' => Carbon::parse($billDate)->addDays($dueDays),
49
             'status' => BillStatus::Open,
50
             'status' => BillStatus::Open,
179
         return $this->afterCreating(function (Bill $bill) {
180
         return $this->afterCreating(function (Bill $bill) {
180
             $this->ensureInitialized($bill);
181
             $this->ensureInitialized($bill);
181
 
182
 
182
-            $paddedId = str_pad((string) $bill->id, 5, '0', STR_PAD_LEFT);
183
+            $number = DocumentDefault::getBaseNumber() + $bill->id;
183
 
184
 
184
             $bill->updateQuietly([
185
             $bill->updateQuietly([
185
-                'bill_number' => "BILL-{$paddedId}",
186
-                'order_number' => "PO-{$paddedId}",
186
+                'bill_number' => "BILL-{$number}",
187
+                'order_number' => "PO-{$number}",
187
             ]);
188
             ]);
188
 
189
 
189
             if ($bill->wasInitialized() && $bill->is_currently_overdue) {
190
             if ($bill->wasInitialized() && $bill->is_currently_overdue) {

+ 6
- 5
database/factories/Accounting/EstimateFactory.php 查看文件

6
 use App\Models\Accounting\DocumentLineItem;
6
 use App\Models\Accounting\DocumentLineItem;
7
 use App\Models\Accounting\Estimate;
7
 use App\Models\Accounting\Estimate;
8
 use App\Models\Common\Client;
8
 use App\Models\Common\Client;
9
+use App\Models\Setting\DocumentDefault;
9
 use Illuminate\Database\Eloquent\Factories\Factory;
10
 use Illuminate\Database\Eloquent\Factories\Factory;
10
 use Illuminate\Support\Carbon;
11
 use Illuminate\Support\Carbon;
11
 
12
 
33
             'client_id' => Client::inRandomOrder()->value('id'),
34
             'client_id' => Client::inRandomOrder()->value('id'),
34
             'header' => 'Estimate',
35
             'header' => 'Estimate',
35
             'subheader' => 'Estimate',
36
             'subheader' => 'Estimate',
36
-            'estimate_number' => $this->faker->unique()->numerify('EST-#####'),
37
-            'reference_number' => $this->faker->unique()->numerify('REF-#####'),
37
+            'estimate_number' => $this->faker->unique()->numerify('EST-####'),
38
+            'reference_number' => $this->faker->unique()->numerify('REF-####'),
38
             'date' => $estimateDate,
39
             'date' => $estimateDate,
39
             'expiration_date' => Carbon::parse($estimateDate)->addDays($this->faker->numberBetween(14, 30)),
40
             'expiration_date' => Carbon::parse($estimateDate)->addDays($this->faker->numberBetween(14, 30)),
40
             'status' => EstimateStatus::Draft,
41
             'status' => EstimateStatus::Draft,
152
         return $this->afterCreating(function (Estimate $estimate) {
153
         return $this->afterCreating(function (Estimate $estimate) {
153
             $this->ensureLineItems($estimate);
154
             $this->ensureLineItems($estimate);
154
 
155
 
155
-            $paddedId = str_pad((string) $estimate->id, 5, '0', STR_PAD_LEFT);
156
+            $number = DocumentDefault::getBaseNumber() + $estimate->id;
156
 
157
 
157
             $estimate->updateQuietly([
158
             $estimate->updateQuietly([
158
-                'estimate_number' => "EST-{$paddedId}",
159
-                'reference_number' => "REF-{$paddedId}",
159
+                'estimate_number' => "EST-{$number}",
160
+                'reference_number' => "REF-{$number}",
160
             ]);
161
             ]);
161
 
162
 
162
             if ($estimate->wasApproved() && $estimate->is_currently_expired) {
163
             if ($estimate->wasApproved() && $estimate->is_currently_expired) {

+ 6
- 5
database/factories/Accounting/InvoiceFactory.php 查看文件

8
 use App\Models\Accounting\Invoice;
8
 use App\Models\Accounting\Invoice;
9
 use App\Models\Banking\BankAccount;
9
 use App\Models\Banking\BankAccount;
10
 use App\Models\Common\Client;
10
 use App\Models\Common\Client;
11
+use App\Models\Setting\DocumentDefault;
11
 use App\Utilities\Currency\CurrencyConverter;
12
 use App\Utilities\Currency\CurrencyConverter;
12
 use Illuminate\Database\Eloquent\Factories\Factory;
13
 use Illuminate\Database\Eloquent\Factories\Factory;
13
 use Illuminate\Support\Carbon;
14
 use Illuminate\Support\Carbon;
36
             'client_id' => Client::inRandomOrder()->value('id'),
37
             'client_id' => Client::inRandomOrder()->value('id'),
37
             'header' => 'Invoice',
38
             'header' => 'Invoice',
38
             'subheader' => 'Invoice',
39
             'subheader' => 'Invoice',
39
-            'invoice_number' => $this->faker->unique()->numerify('INV-#####'),
40
-            'order_number' => $this->faker->unique()->numerify('ORD-#####'),
40
+            'invoice_number' => $this->faker->unique()->numerify('INV-####'),
41
+            'order_number' => $this->faker->unique()->numerify('ORD-####'),
41
             'date' => $invoiceDate,
42
             'date' => $invoiceDate,
42
             'due_date' => Carbon::parse($invoiceDate)->addDays($this->faker->numberBetween(14, 60)),
43
             'due_date' => Carbon::parse($invoiceDate)->addDays($this->faker->numberBetween(14, 60)),
43
             'status' => InvoiceStatus::Draft,
44
             'status' => InvoiceStatus::Draft,
197
         return $this->afterCreating(function (Invoice $invoice) {
198
         return $this->afterCreating(function (Invoice $invoice) {
198
             $this->ensureLineItems($invoice);
199
             $this->ensureLineItems($invoice);
199
 
200
 
200
-            $paddedId = str_pad((string) $invoice->id, 5, '0', STR_PAD_LEFT);
201
+            $number = DocumentDefault::getBaseNumber() + $invoice->id;
201
 
202
 
202
             $invoice->updateQuietly([
203
             $invoice->updateQuietly([
203
-                'invoice_number' => "INV-{$paddedId}",
204
-                'order_number' => "ORD-{$paddedId}",
204
+                'invoice_number' => "INV-{$number}",
205
+                'order_number' => "ORD-{$number}",
205
             ]);
206
             ]);
206
 
207
 
207
             if ($invoice->wasApproved() && $invoice->is_currently_overdue) {
208
             if ($invoice->wasApproved() && $invoice->is_currently_overdue) {

+ 1
- 1
database/factories/Accounting/RecurringInvoiceFactory.php 查看文件

38
             'client_id' => Client::inRandomOrder()->value('id'),
38
             'client_id' => Client::inRandomOrder()->value('id'),
39
             'header' => 'Invoice',
39
             'header' => 'Invoice',
40
             'subheader' => 'Invoice',
40
             'subheader' => 'Invoice',
41
-            'order_number' => $this->faker->unique()->numerify('ORD-#####'),
41
+            'order_number' => $this->faker->unique()->numerify('ORD-####'),
42
             'payment_terms' => PaymentTerms::Net30,
42
             'payment_terms' => PaymentTerms::Net30,
43
             'status' => RecurringInvoiceStatus::Draft,
43
             'status' => RecurringInvoiceStatus::Draft,
44
             'currency_code' => 'USD',
44
             'currency_code' => 'USD',

+ 0
- 24
database/factories/Setting/AppearanceFactory.php 查看文件

1
-<?php
2
-
3
-namespace Database\Factories\Setting;
4
-
5
-use App\Models\Setting\Appearance;
6
-use Illuminate\Database\Eloquent\Factories\Factory;
7
-
8
-/**
9
- * @extends Factory<Appearance>
10
- */
11
-class AppearanceFactory extends Factory
12
-{
13
-    /**
14
-     * Define the model's default state.
15
-     *
16
-     * @return array<string, mixed>
17
-     */
18
-    public function definition(): array
19
-    {
20
-        return [
21
-            //
22
-        ];
23
-    }
24
-}

+ 0
- 11
database/factories/Setting/CompanyDefaultFactory.php 查看文件

4
 
4
 
5
 use App\Faker\CurrencyCode;
5
 use App\Faker\CurrencyCode;
6
 use App\Models\Company;
6
 use App\Models\Company;
7
-use App\Models\Setting\Appearance;
8
 use App\Models\Setting\CompanyDefault;
7
 use App\Models\Setting\CompanyDefault;
9
 use App\Models\Setting\Currency;
8
 use App\Models\Setting\Currency;
10
 use App\Models\Setting\DocumentDefault;
9
 use App\Models\Setting\DocumentDefault;
44
         }
43
         }
45
 
44
 
46
         $currency = $this->createCurrency($company, $user, $currencyCode);
45
         $currency = $this->createCurrency($company, $user, $currencyCode);
47
-        $this->createAppearance($company, $user);
48
         $this->createDocumentDefaults($company, $user);
46
         $this->createDocumentDefaults($company, $user);
49
         $this->createLocalization($company, $user, $countryCode, $language);
47
         $this->createLocalization($company, $user, $countryCode, $language);
50
 
48
 
68
         ]);
66
         ]);
69
     }
67
     }
70
 
68
 
71
-    private function createAppearance(Company $company, User $user): void
72
-    {
73
-        Appearance::factory()->createQuietly([
74
-            'company_id' => $company->id,
75
-            'created_by' => $user->id,
76
-            'updated_by' => $user->id,
77
-        ]);
78
-    }
79
-
80
     private function createDocumentDefaults(Company $company, User $user): void
69
     private function createDocumentDefaults(Company $company, User $user): void
81
     {
70
     {
82
         DocumentDefault::factory()->invoice()->createQuietly([
71
         DocumentDefault::factory()->invoice()->createQuietly([

+ 23
- 9
database/factories/Setting/DocumentDefaultFactory.php 查看文件

3
 namespace Database\Factories\Setting;
3
 namespace Database\Factories\Setting;
4
 
4
 
5
 use App\Enums\Accounting\DocumentType;
5
 use App\Enums\Accounting\DocumentType;
6
+use App\Enums\Setting\Font;
7
+use App\Enums\Setting\Template;
6
 use App\Models\Setting\DocumentDefault;
8
 use App\Models\Setting\DocumentDefault;
7
 use Illuminate\Database\Eloquent\Factories\Factory;
9
 use Illuminate\Database\Eloquent\Factories\Factory;
8
 
10
 
26
     public function definition(): array
28
     public function definition(): array
27
     {
29
     {
28
         return [
30
         return [
29
-            //
31
+            'company_id' => 1,
32
+            'payment_terms' => 'due_upon_receipt',
30
         ];
33
         ];
31
     }
34
     }
32
 
35
 
33
     /**
36
     /**
34
      * The model's common default state.
37
      * The model's common default state.
35
      */
38
      */
36
-    private function baseState(DocumentType $type, string $prefix, string $header): array
39
+    private function baseState(DocumentType $type): array
37
     {
40
     {
38
-        return [
39
-            'type' => $type->value,
40
-            'number_prefix' => $prefix,
41
-            'header' => $header,
41
+        $state = [
42
+            'type' => $type,
43
+            'number_prefix' => $type->getDefaultPrefix(),
42
             'item_name' => ['option' => 'items', 'custom' => null],
44
             'item_name' => ['option' => 'items', 'custom' => null],
43
             'unit_name' => ['option' => 'quantity', 'custom' => null],
45
             'unit_name' => ['option' => 'quantity', 'custom' => null],
44
             'price_name' => ['option' => 'price', 'custom' => null],
46
             'price_name' => ['option' => 'price', 'custom' => null],
45
             'amount_name' => ['option' => 'amount', 'custom' => null],
47
             'amount_name' => ['option' => 'amount', 'custom' => null],
46
         ];
48
         ];
49
+
50
+        if ($type !== DocumentType::Bill) {
51
+            $state = [...$state,
52
+                'header' => $type->getLabel(),
53
+                'show_logo' => false,
54
+                'accent_color' => '#4F46E5',
55
+                'font' => Font::Inter,
56
+                'template' => Template::Default,
57
+            ];
58
+        }
59
+
60
+        return $state;
47
     }
61
     }
48
 
62
 
49
     /**
63
     /**
51
      */
65
      */
52
     public function invoice(): self
66
     public function invoice(): self
53
     {
67
     {
54
-        return $this->state($this->baseState(DocumentType::Invoice, 'INV-', 'Invoice'));
68
+        return $this->state($this->baseState(DocumentType::Invoice));
55
     }
69
     }
56
 
70
 
57
     /**
71
     /**
59
      */
73
      */
60
     public function bill(): self
74
     public function bill(): self
61
     {
75
     {
62
-        return $this->state($this->baseState(DocumentType::Bill, 'BILL-', 'Bill'));
76
+        return $this->state($this->baseState(DocumentType::Bill));
63
     }
77
     }
64
 
78
 
65
     /**
79
     /**
67
      */
81
      */
68
     public function estimate(): self
82
     public function estimate(): self
69
     {
83
     {
70
-        return $this->state($this->baseState(DocumentType::Estimate, 'EST-', 'Estimate'));
84
+        return $this->state($this->baseState(DocumentType::Estimate));
71
     }
85
     }
72
 }
86
 }

+ 0
- 32
database/migrations/2023_09_12_014413_create_appearances_table.php 查看文件

1
-<?php
2
-
3
-use Illuminate\Database\Migrations\Migration;
4
-use Illuminate\Database\Schema\Blueprint;
5
-use Illuminate\Support\Facades\Schema;
6
-
7
-return new class extends Migration
8
-{
9
-    /**
10
-     * Run the migrations.
11
-     */
12
-    public function up(): void
13
-    {
14
-        Schema::create('appearances', function (Blueprint $table) {
15
-            $table->id();
16
-            $table->foreignId('company_id')->constrained()->onDelete('cascade');
17
-            $table->string('primary_color')->default('indigo');
18
-            $table->string('font')->default('inter');
19
-            $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
20
-            $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
21
-            $table->timestamps();
22
-        });
23
-    }
24
-
25
-    /**
26
-     * Reverse the migrations.
27
-     */
28
-    public function down(): void
29
-    {
30
-        Schema::dropIfExists('appearances');
31
-    }
32
-};

+ 3
- 5
database/migrations/2023_09_12_032057_create_document_defaults_table.php 查看文件

18
             $table->string('logo')->nullable();
18
             $table->string('logo')->nullable();
19
             $table->boolean('show_logo')->default(false);
19
             $table->boolean('show_logo')->default(false);
20
             $table->string('number_prefix')->nullable();
20
             $table->string('number_prefix')->nullable();
21
-            $table->unsignedTinyInteger('number_digits')->default(5);
22
-            $table->unsignedBigInteger('number_next')->default(1);
23
             $table->string('payment_terms')->default('due_upon_receipt');
21
             $table->string('payment_terms')->default('due_upon_receipt');
24
             $table->string('header')->nullable();
22
             $table->string('header')->nullable();
25
             $table->string('subheader')->nullable();
23
             $table->string('subheader')->nullable();
26
             $table->text('terms')->nullable();
24
             $table->text('terms')->nullable();
27
             $table->text('footer')->nullable();
25
             $table->text('footer')->nullable();
28
-            $table->string('accent_color')->default('#4F46E5');
29
-            $table->string('font')->default('inter');
30
-            $table->string('template')->default('default');
26
+            $table->string('accent_color')->nullable();
27
+            $table->string('font')->nullable();
28
+            $table->string('template')->nullable();
31
             $table->json('item_name')->nullable();
29
             $table->json('item_name')->nullable();
32
             $table->json('unit_name')->nullable();
30
             $table->json('unit_name')->nullable();
33
             $table->json('price_name')->nullable();
31
             $table->json('price_name')->nullable();

+ 89
- 89
package-lock.json 查看文件

575
             }
575
             }
576
         },
576
         },
577
         "node_modules/@rollup/rollup-android-arm-eabi": {
577
         "node_modules/@rollup/rollup-android-arm-eabi": {
578
-            "version": "4.34.7",
579
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.7.tgz",
580
-            "integrity": "sha512-l6CtzHYo8D2TQ3J7qJNpp3Q1Iye56ssIAtqbM2H8axxCEEwvN7o8Ze9PuIapbxFL3OHrJU2JBX6FIIVnP/rYyw==",
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==",
581
             "cpu": [
581
             "cpu": [
582
                 "arm"
582
                 "arm"
583
             ],
583
             ],
589
             ]
589
             ]
590
         },
590
         },
591
         "node_modules/@rollup/rollup-android-arm64": {
591
         "node_modules/@rollup/rollup-android-arm64": {
592
-            "version": "4.34.7",
593
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.7.tgz",
594
-            "integrity": "sha512-KvyJpFUueUnSp53zhAa293QBYqwm94TgYTIfXyOTtidhm5V0LbLCJQRGkQClYiX3FXDQGSvPxOTD/6rPStMMDg==",
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==",
595
             "cpu": [
595
             "cpu": [
596
                 "arm64"
596
                 "arm64"
597
             ],
597
             ],
603
             ]
603
             ]
604
         },
604
         },
605
         "node_modules/@rollup/rollup-darwin-arm64": {
605
         "node_modules/@rollup/rollup-darwin-arm64": {
606
-            "version": "4.34.7",
607
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.7.tgz",
608
-            "integrity": "sha512-jq87CjmgL9YIKvs8ybtIC98s/M3HdbqXhllcy9EdLV0yMg1DpxES2gr65nNy7ObNo/vZ/MrOTxt0bE5LinL6mA==",
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==",
609
             "cpu": [
609
             "cpu": [
610
                 "arm64"
610
                 "arm64"
611
             ],
611
             ],
617
             ]
617
             ]
618
         },
618
         },
619
         "node_modules/@rollup/rollup-darwin-x64": {
619
         "node_modules/@rollup/rollup-darwin-x64": {
620
-            "version": "4.34.7",
621
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.7.tgz",
622
-            "integrity": "sha512-rSI/m8OxBjsdnMMg0WEetu/w+LhLAcCDEiL66lmMX4R3oaml3eXz3Dxfvrxs1FbzPbJMaItQiksyMfv1hoIxnA==",
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==",
623
             "cpu": [
623
             "cpu": [
624
                 "x64"
624
                 "x64"
625
             ],
625
             ],
631
             ]
631
             ]
632
         },
632
         },
633
         "node_modules/@rollup/rollup-freebsd-arm64": {
633
         "node_modules/@rollup/rollup-freebsd-arm64": {
634
-            "version": "4.34.7",
635
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.7.tgz",
636
-            "integrity": "sha512-oIoJRy3ZrdsXpFuWDtzsOOa/E/RbRWXVokpVrNnkS7npz8GEG++E1gYbzhYxhxHbO2om1T26BZjVmdIoyN2WtA==",
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==",
637
             "cpu": [
637
             "cpu": [
638
                 "arm64"
638
                 "arm64"
639
             ],
639
             ],
645
             ]
645
             ]
646
         },
646
         },
647
         "node_modules/@rollup/rollup-freebsd-x64": {
647
         "node_modules/@rollup/rollup-freebsd-x64": {
648
-            "version": "4.34.7",
649
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.7.tgz",
650
-            "integrity": "sha512-X++QSLm4NZfZ3VXGVwyHdRf58IBbCu9ammgJxuWZYLX0du6kZvdNqPwrjvDfwmi6wFdvfZ/s6K7ia0E5kI7m8Q==",
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==",
651
             "cpu": [
651
             "cpu": [
652
                 "x64"
652
                 "x64"
653
             ],
653
             ],
659
             ]
659
             ]
660
         },
660
         },
661
         "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
661
         "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
662
-            "version": "4.34.7",
663
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.7.tgz",
664
-            "integrity": "sha512-Z0TzhrsNqukTz3ISzrvyshQpFnFRfLunYiXxlCRvcrb3nvC5rVKI+ZXPFG/Aa4jhQa1gHgH3A0exHaRRN4VmdQ==",
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==",
665
             "cpu": [
665
             "cpu": [
666
                 "arm"
666
                 "arm"
667
             ],
667
             ],
673
             ]
673
             ]
674
         },
674
         },
675
         "node_modules/@rollup/rollup-linux-arm-musleabihf": {
675
         "node_modules/@rollup/rollup-linux-arm-musleabihf": {
676
-            "version": "4.34.7",
677
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.7.tgz",
678
-            "integrity": "sha512-nkznpyXekFAbvFBKBy4nNppSgneB1wwG1yx/hujN3wRnhnkrYVugMTCBXED4+Ni6thoWfQuHNYbFjgGH0MBXtw==",
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==",
679
             "cpu": [
679
             "cpu": [
680
                 "arm"
680
                 "arm"
681
             ],
681
             ],
687
             ]
687
             ]
688
         },
688
         },
689
         "node_modules/@rollup/rollup-linux-arm64-gnu": {
689
         "node_modules/@rollup/rollup-linux-arm64-gnu": {
690
-            "version": "4.34.7",
691
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.7.tgz",
692
-            "integrity": "sha512-KCjlUkcKs6PjOcxolqrXglBDcfCuUCTVlX5BgzgoJHw+1rWH1MCkETLkLe5iLLS9dP5gKC7mp3y6x8c1oGBUtA==",
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==",
693
             "cpu": [
693
             "cpu": [
694
                 "arm64"
694
                 "arm64"
695
             ],
695
             ],
701
             ]
701
             ]
702
         },
702
         },
703
         "node_modules/@rollup/rollup-linux-arm64-musl": {
703
         "node_modules/@rollup/rollup-linux-arm64-musl": {
704
-            "version": "4.34.7",
705
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.7.tgz",
706
-            "integrity": "sha512-uFLJFz6+utmpbR313TTx+NpPuAXbPz4BhTQzgaP0tozlLnGnQ6rCo6tLwaSa6b7l6gRErjLicXQ1iPiXzYotjw==",
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==",
707
             "cpu": [
707
             "cpu": [
708
                 "arm64"
708
                 "arm64"
709
             ],
709
             ],
715
             ]
715
             ]
716
         },
716
         },
717
         "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
717
         "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
718
-            "version": "4.34.7",
719
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.7.tgz",
720
-            "integrity": "sha512-ws8pc68UcJJqCpneDFepnwlsMUFoWvPbWXT/XUrJ7rWUL9vLoIN3GAasgG+nCvq8xrE3pIrd+qLX/jotcLy0Qw==",
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==",
721
             "cpu": [
721
             "cpu": [
722
                 "loong64"
722
                 "loong64"
723
             ],
723
             ],
729
             ]
729
             ]
730
         },
730
         },
731
         "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
731
         "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
732
-            "version": "4.34.7",
733
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.7.tgz",
734
-            "integrity": "sha512-vrDk9JDa/BFkxcS2PbWpr0C/LiiSLxFbNOBgfbW6P8TBe9PPHx9Wqbvx2xgNi1TOAyQHQJ7RZFqBiEohm79r0w==",
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==",
735
             "cpu": [
735
             "cpu": [
736
                 "ppc64"
736
                 "ppc64"
737
             ],
737
             ],
743
             ]
743
             ]
744
         },
744
         },
745
         "node_modules/@rollup/rollup-linux-riscv64-gnu": {
745
         "node_modules/@rollup/rollup-linux-riscv64-gnu": {
746
-            "version": "4.34.7",
747
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.7.tgz",
748
-            "integrity": "sha512-rB+ejFyjtmSo+g/a4eovDD1lHWHVqizN8P0Hm0RElkINpS0XOdpaXloqM4FBkF9ZWEzg6bezymbpLmeMldfLTw==",
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==",
749
             "cpu": [
749
             "cpu": [
750
                 "riscv64"
750
                 "riscv64"
751
             ],
751
             ],
757
             ]
757
             ]
758
         },
758
         },
759
         "node_modules/@rollup/rollup-linux-s390x-gnu": {
759
         "node_modules/@rollup/rollup-linux-s390x-gnu": {
760
-            "version": "4.34.7",
761
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.7.tgz",
762
-            "integrity": "sha512-nNXNjo4As6dNqRn7OrsnHzwTgtypfRA3u3AKr0B3sOOo+HkedIbn8ZtFnB+4XyKJojIfqDKmbIzO1QydQ8c+Pw==",
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==",
763
             "cpu": [
763
             "cpu": [
764
                 "s390x"
764
                 "s390x"
765
             ],
765
             ],
771
             ]
771
             ]
772
         },
772
         },
773
         "node_modules/@rollup/rollup-linux-x64-gnu": {
773
         "node_modules/@rollup/rollup-linux-x64-gnu": {
774
-            "version": "4.34.7",
775
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.7.tgz",
776
-            "integrity": "sha512-9kPVf9ahnpOMSGlCxXGv980wXD0zRR3wyk8+33/MXQIpQEOpaNe7dEHm5LMfyRZRNt9lMEQuH0jUKj15MkM7QA==",
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==",
777
             "cpu": [
777
             "cpu": [
778
                 "x64"
778
                 "x64"
779
             ],
779
             ],
785
             ]
785
             ]
786
         },
786
         },
787
         "node_modules/@rollup/rollup-linux-x64-musl": {
787
         "node_modules/@rollup/rollup-linux-x64-musl": {
788
-            "version": "4.34.7",
789
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.7.tgz",
790
-            "integrity": "sha512-7wJPXRWTTPtTFDFezA8sle/1sdgxDjuMoRXEKtx97ViRxGGkVQYovem+Q8Pr/2HxiHp74SSRG+o6R0Yq0shPwQ==",
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==",
791
             "cpu": [
791
             "cpu": [
792
                 "x64"
792
                 "x64"
793
             ],
793
             ],
799
             ]
799
             ]
800
         },
800
         },
801
         "node_modules/@rollup/rollup-win32-arm64-msvc": {
801
         "node_modules/@rollup/rollup-win32-arm64-msvc": {
802
-            "version": "4.34.7",
803
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.7.tgz",
804
-            "integrity": "sha512-MN7aaBC7mAjsiMEZcsJvwNsQVNZShgES/9SzWp1HC9Yjqb5OpexYnRjF7RmE4itbeesHMYYQiAtUAQaSKs2Rfw==",
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==",
805
             "cpu": [
805
             "cpu": [
806
                 "arm64"
806
                 "arm64"
807
             ],
807
             ],
813
             ]
813
             ]
814
         },
814
         },
815
         "node_modules/@rollup/rollup-win32-ia32-msvc": {
815
         "node_modules/@rollup/rollup-win32-ia32-msvc": {
816
-            "version": "4.34.7",
817
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.7.tgz",
818
-            "integrity": "sha512-aeawEKYswsFu1LhDM9RIgToobquzdtSc4jSVqHV8uApz4FVvhFl/mKh92wc8WpFc6aYCothV/03UjY6y7yLgbg==",
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==",
819
             "cpu": [
819
             "cpu": [
820
                 "ia32"
820
                 "ia32"
821
             ],
821
             ],
827
             ]
827
             ]
828
         },
828
         },
829
         "node_modules/@rollup/rollup-win32-x64-msvc": {
829
         "node_modules/@rollup/rollup-win32-x64-msvc": {
830
-            "version": "4.34.7",
831
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.7.tgz",
832
-            "integrity": "sha512-4ZedScpxxIrVO7otcZ8kCX1mZArtH2Wfj3uFCxRJ9NO80gg1XV0U/b2f/MKaGwj2X3QopHfoWiDQ917FRpwY3w==",
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==",
833
             "cpu": [
833
             "cpu": [
834
                 "x64"
834
                 "x64"
835
             ],
835
             ],
1264
             "license": "MIT"
1264
             "license": "MIT"
1265
         },
1265
         },
1266
         "node_modules/electron-to-chromium": {
1266
         "node_modules/electron-to-chromium": {
1267
-            "version": "1.5.101",
1268
-            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.101.tgz",
1269
-            "integrity": "sha512-L0ISiQrP/56Acgu4/i/kfPwWSgrzYZUnQrC0+QPFuhqlLP1Ir7qzPPDVS9BcKIyWTRU8+o6CC8dKw38tSWhYIA==",
1267
+            "version": "1.5.103",
1268
+            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.103.tgz",
1269
+            "integrity": "sha512-P6+XzIkfndgsrjROJWfSvVEgNHtPgbhVyTkwLjUM2HU/h7pZRORgaTlHqfAikqxKmdJMLW8fftrdGWbd/Ds0FA==",
1270
             "dev": true,
1270
             "dev": true,
1271
             "license": "ISC"
1271
             "license": "ISC"
1272
         },
1272
         },
2077
             }
2077
             }
2078
         },
2078
         },
2079
         "node_modules/postcss": {
2079
         "node_modules/postcss": {
2080
-            "version": "8.5.2",
2081
-            "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz",
2082
-            "integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==",
2080
+            "version": "8.5.3",
2081
+            "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
2082
+            "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
2083
             "dev": true,
2083
             "dev": true,
2084
             "funding": [
2084
             "funding": [
2085
                 {
2085
                 {
2412
             }
2412
             }
2413
         },
2413
         },
2414
         "node_modules/rollup": {
2414
         "node_modules/rollup": {
2415
-            "version": "4.34.7",
2416
-            "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.7.tgz",
2417
-            "integrity": "sha512-8qhyN0oZ4x0H6wmBgfKxJtxM7qS98YJ0k0kNh5ECVtuchIJ7z9IVVvzpmtQyT10PXKMtBxYr1wQ5Apg8RS8kXQ==",
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==",
2418
             "dev": true,
2418
             "dev": true,
2419
             "license": "MIT",
2419
             "license": "MIT",
2420
             "dependencies": {
2420
             "dependencies": {
2428
                 "npm": ">=8.0.0"
2428
                 "npm": ">=8.0.0"
2429
             },
2429
             },
2430
             "optionalDependencies": {
2430
             "optionalDependencies": {
2431
-                "@rollup/rollup-android-arm-eabi": "4.34.7",
2432
-                "@rollup/rollup-android-arm64": "4.34.7",
2433
-                "@rollup/rollup-darwin-arm64": "4.34.7",
2434
-                "@rollup/rollup-darwin-x64": "4.34.7",
2435
-                "@rollup/rollup-freebsd-arm64": "4.34.7",
2436
-                "@rollup/rollup-freebsd-x64": "4.34.7",
2437
-                "@rollup/rollup-linux-arm-gnueabihf": "4.34.7",
2438
-                "@rollup/rollup-linux-arm-musleabihf": "4.34.7",
2439
-                "@rollup/rollup-linux-arm64-gnu": "4.34.7",
2440
-                "@rollup/rollup-linux-arm64-musl": "4.34.7",
2441
-                "@rollup/rollup-linux-loongarch64-gnu": "4.34.7",
2442
-                "@rollup/rollup-linux-powerpc64le-gnu": "4.34.7",
2443
-                "@rollup/rollup-linux-riscv64-gnu": "4.34.7",
2444
-                "@rollup/rollup-linux-s390x-gnu": "4.34.7",
2445
-                "@rollup/rollup-linux-x64-gnu": "4.34.7",
2446
-                "@rollup/rollup-linux-x64-musl": "4.34.7",
2447
-                "@rollup/rollup-win32-arm64-msvc": "4.34.7",
2448
-                "@rollup/rollup-win32-ia32-msvc": "4.34.7",
2449
-                "@rollup/rollup-win32-x64-msvc": "4.34.7",
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",
2450
                 "fsevents": "~2.3.2"
2450
                 "fsevents": "~2.3.2"
2451
             }
2451
             }
2452
         },
2452
         },
2794
             "license": "MIT"
2794
             "license": "MIT"
2795
         },
2795
         },
2796
         "node_modules/vite": {
2796
         "node_modules/vite": {
2797
-            "version": "6.1.0",
2798
-            "resolved": "https://registry.npmjs.org/vite/-/vite-6.1.0.tgz",
2799
-            "integrity": "sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ==",
2797
+            "version": "6.1.1",
2798
+            "resolved": "https://registry.npmjs.org/vite/-/vite-6.1.1.tgz",
2799
+            "integrity": "sha512-4GgM54XrwRfrOp297aIYspIti66k56v16ZnqHvrIM7mG+HjDlAwS7p+Srr7J6fGvEdOJ5JcQ/D9T7HhtdXDTzA==",
2800
             "dev": true,
2800
             "dev": true,
2801
             "license": "MIT",
2801
             "license": "MIT",
2802
             "dependencies": {
2802
             "dependencies": {
2803
                 "esbuild": "^0.24.2",
2803
                 "esbuild": "^0.24.2",
2804
-                "postcss": "^8.5.1",
2804
+                "postcss": "^8.5.2",
2805
                 "rollup": "^4.30.1"
2805
                 "rollup": "^4.30.1"
2806
             },
2806
             },
2807
             "bin": {
2807
             "bin": {

+ 0
- 17
resources/views/filament/company/pages/setting/appearance.blade.php 查看文件

1
-<x-filament-panels::page style="margin-bottom: 500px">
2
-    <x-filament-panels::form wire:submit="save">
3
-        {{ $this->form }}
4
-
5
-        <x-filament-panels::form.actions
6
-            :actions="$this->getCachedFormActions()"
7
-            :full-width="$this->hasFullWidthFormActions()"
8
-        />
9
-    </x-filament-panels::form>
10
-</x-filament-panels::page>
11
-<script>
12
-    document.addEventListener('livewire:init', function () {
13
-        Livewire.on('appearanceUpdated', function () {
14
-            window.location.reload();
15
-        });
16
-    });
17
-</script>

+ 0
- 10
resources/views/filament/company/pages/setting/invoice.blade.php 查看文件

1
-<x-filament-panels::page style="margin-bottom: 500px">
2
-    <x-filament-panels::form wire:submit="save">
3
-        {{ $this->form }}
4
-
5
-        <x-filament-panels::form.actions
6
-            :actions="$this->getCachedFormActions()"
7
-            :full-width="$this->hasFullWidthFormActions()"
8
-        />
9
-    </x-filament-panels::form>
10
-</x-filament-panels::page>

Loading…
取消
儲存