Преглед изворни кода

wip: Accounting Module

3.x
wallo пре 2 година
родитељ
комит
c72d4afbc0
38 измењених фајлова са 478 додато и 253 уклоњено
  1. 0
    4
      app/Actions/OptionAction/CreateCurrency.php
  2. 11
    3
      app/Filament/Resources/AccountResource/Pages/CreateAccount.php
  3. 11
    6
      app/Filament/Resources/AccountResource/Pages/EditAccount.php
  4. 11
    3
      app/Filament/Resources/CategoryResource/Pages/CreateCategory.php
  5. 11
    3
      app/Filament/Resources/CategoryResource/Pages/EditCategory.php
  6. 11
    3
      app/Filament/Resources/CurrencyResource/Pages/CreateCurrency.php
  7. 11
    6
      app/Filament/Resources/CurrencyResource/Pages/EditCurrency.php
  8. 0
    2
      app/Filament/Resources/CustomerResource/Pages/CreateCustomer.php
  9. 1
    10
      app/Filament/Resources/CustomerResource/Pages/EditCustomer.php
  10. 4
    4
      app/Filament/Resources/DiscountResource.php
  11. 11
    3
      app/Filament/Resources/DiscountResource/Pages/CreateDiscount.php
  12. 19
    1
      app/Filament/Resources/DiscountResource/Pages/EditDiscount.php
  13. 0
    2
      app/Filament/Resources/InvoiceResource/Pages/CreateInvoice.php
  14. 0
    9
      app/Filament/Resources/InvoiceResource/Pages/EditInvoice.php
  15. 11
    3
      app/Filament/Resources/TaxResource/Pages/CreateTax.php
  16. 11
    5
      app/Filament/Resources/TaxResource/Pages/EditTax.php
  17. 3
    22
      app/Http/Livewire/DefaultSetting.php
  18. 3
    4
      app/Models/Banking/Account.php
  19. 3
    1
      app/Models/Contact.php
  20. 3
    1
      app/Models/Document/Document.php
  21. 3
    1
      app/Models/Document/DocumentItem.php
  22. 3
    1
      app/Models/Document/DocumentTotal.php
  23. 3
    1
      app/Models/Item.php
  24. 3
    1
      app/Models/Setting/Category.php
  25. 13
    1
      app/Models/Setting/Currency.php
  26. 9
    1
      app/Models/Setting/DefaultSetting.php
  27. 3
    1
      app/Models/Setting/Discount.php
  28. 15
    1
      app/Models/Setting/DocumentDefault.php
  29. 3
    1
      app/Models/Setting/Tax.php
  30. 3
    67
      app/Observers/CompanyObserver.php
  31. 141
    0
      app/Services/DefaultSettingService.php
  32. 20
    0
      app/Traits/Blamable.php
  33. 25
    0
      app/Traits/CompanyOwned.php
  34. 12
    18
      app/Traits/HandlesDefaultSettingRecordUpdate.php
  35. 31
    18
      app/Traits/HandlesResourceRecordCreation.php
  36. 53
    46
      app/Traits/HandlesResourceRecordUpdate.php
  37. 2
    0
      database/migrations/2023_05_22_000100_create_document_defaults_table.php
  38. 1
    0
      database/migrations/2023_07_03_054805_create_default_settings_table.php

+ 0
- 4
app/Actions/OptionAction/CreateCurrency.php Прегледај датотеку

3
 namespace App\Actions\OptionAction;
3
 namespace App\Actions\OptionAction;
4
 
4
 
5
 use App\Models\Setting\Currency;
5
 use App\Models\Setting\Currency;
6
-use Illuminate\Support\Facades\Auth;
7
 
6
 
8
 class CreateCurrency
7
 class CreateCurrency
9
 {
8
 {
10
     public function create(string $code, string $name, string $rate): Currency
9
     public function create(string $code, string $name, string $rate): Currency
11
     {
10
     {
12
-        $companyId = Auth::user()->currentCompany->id;
13
-
14
         $defaultCurrency = Currency::getDefaultCurrency();
11
         $defaultCurrency = Currency::getDefaultCurrency();
15
 
12
 
16
         $hasDefaultCurrency = $defaultCurrency !== null;
13
         $hasDefaultCurrency = $defaultCurrency !== null;
25
             'decimal_mark' => config("money.{$code}.decimal_mark"),
22
             'decimal_mark' => config("money.{$code}.decimal_mark"),
26
             'thousands_separator' => config("money.{$code}.thousands_separator"),
23
             'thousands_separator' => config("money.{$code}.thousands_separator"),
27
             'enabled' => !$hasDefaultCurrency,
24
             'enabled' => !$hasDefaultCurrency,
28
-            'company_id' => $companyId,
29
         ]);
25
         ]);
30
     }
26
     }
31
 }
27
 }

+ 11
- 3
app/Filament/Resources/AccountResource/Pages/CreateAccount.php Прегледај датотеку

6
 use App\Models\Banking\Account;
6
 use App\Models\Banking\Account;
7
 use App\Traits\HandlesResourceRecordCreation;
7
 use App\Traits\HandlesResourceRecordCreation;
8
 use Filament\Resources\Pages\CreateRecord;
8
 use Filament\Resources\Pages\CreateRecord;
9
+use Filament\Support\Exceptions\Halt;
9
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Support\Facades\Auth;
11
 use Illuminate\Support\Facades\Auth;
11
 
12
 
22
 
23
 
23
     protected function mutateFormDataBeforeCreate(array $data): array
24
     protected function mutateFormDataBeforeCreate(array $data): array
24
     {
25
     {
25
-        $data['company_id'] = Auth::user()->currentCompany->id;
26
         $data['enabled'] = (bool)$data['enabled'];
26
         $data['enabled'] = (bool)$data['enabled'];
27
-        $data['created_by'] = Auth::id();
28
 
27
 
29
         return $data;
28
         return $data;
30
     }
29
     }
31
 
30
 
31
+    /**
32
+     * @throws Halt
33
+     */
32
     protected function handleRecordCreation(array $data): Model
34
     protected function handleRecordCreation(array $data): Model
33
     {
35
     {
34
-        return $this->handleRecordCreationWithUniqueField($data, new Account());
36
+        $user = Auth::user();
37
+
38
+        if (!$user) {
39
+            throw new Halt('No authenticated user found.');
40
+        }
41
+
42
+        return $this->handleRecordCreationWithUniqueField($data, new Account(), $user);
35
     }
43
     }
36
 }
44
 }

+ 11
- 6
app/Filament/Resources/AccountResource/Pages/EditAccount.php Прегледај датотеку

3
 namespace App\Filament\Resources\AccountResource\Pages;
3
 namespace App\Filament\Resources\AccountResource\Pages;
4
 
4
 
5
 use App\Filament\Resources\AccountResource;
5
 use App\Filament\Resources\AccountResource;
6
-use App\Models\Banking\Account;
7
 use App\Traits\HandlesResourceRecordUpdate;
6
 use App\Traits\HandlesResourceRecordUpdate;
8
-use Filament\Notifications\Notification;
9
 use Filament\Pages\Actions;
7
 use Filament\Pages\Actions;
10
 use Filament\Resources\Pages\EditRecord;
8
 use Filament\Resources\Pages\EditRecord;
9
+use Filament\Support\Exceptions\Halt;
11
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Model;
12
 use Illuminate\Support\Facades\Auth;
11
 use Illuminate\Support\Facades\Auth;
13
-use Illuminate\Support\Facades\DB;
14
 
12
 
15
 class EditAccount extends EditRecord
13
 class EditAccount extends EditRecord
16
 {
14
 {
32
 
30
 
33
     protected function mutateFormDataBeforeSave(array $data): array
31
     protected function mutateFormDataBeforeSave(array $data): array
34
     {
32
     {
35
-        $data['company_id'] = Auth::user()->currentCompany->id;
36
         $data['enabled'] = (bool)$data['enabled'];
33
         $data['enabled'] = (bool)$data['enabled'];
37
-        $data['updated_by'] = Auth::id();
38
 
34
 
39
         return $data;
35
         return $data;
40
     }
36
     }
41
 
37
 
38
+    /**
39
+     * @throws Halt
40
+     */
42
     protected function handleRecordUpdate(Model $record, array $data): Model
41
     protected function handleRecordUpdate(Model $record, array $data): Model
43
     {
42
     {
44
-        return $this->handleRecordUpdateWithUniqueField($record, $data);
43
+        $user = Auth::user();
44
+
45
+        if (!$user) {
46
+            throw new Halt('No authenticated user found.');
47
+        }
48
+
49
+        return $this->handleRecordUpdateWithUniqueField($record, $data, $user);
45
     }
50
     }
46
 }
51
 }

+ 11
- 3
app/Filament/Resources/CategoryResource/Pages/CreateCategory.php Прегледај датотеку

6
 use App\Models\Setting\Category;
6
 use App\Models\Setting\Category;
7
 use App\Traits\HandlesResourceRecordCreation;
7
 use App\Traits\HandlesResourceRecordCreation;
8
 use Filament\Resources\Pages\CreateRecord;
8
 use Filament\Resources\Pages\CreateRecord;
9
+use Filament\Support\Exceptions\Halt;
9
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Support\Facades\Auth;
11
 use Illuminate\Support\Facades\Auth;
11
 
12
 
22
 
23
 
23
     protected function mutateFormDataBeforeCreate(array $data): array
24
     protected function mutateFormDataBeforeCreate(array $data): array
24
     {
25
     {
25
-        $data['company_id'] = Auth::user()->currentCompany->id;
26
         $data['enabled'] = (bool)$data['enabled'];
26
         $data['enabled'] = (bool)$data['enabled'];
27
-        $data['created_by'] = Auth::id();
28
 
27
 
29
         return $data;
28
         return $data;
30
     }
29
     }
31
 
30
 
31
+    /**
32
+     * @throws Halt
33
+     */
32
     protected function handleRecordCreation(array $data): Model
34
     protected function handleRecordCreation(array $data): Model
33
     {
35
     {
34
-        return $this->handleRecordCreationWithUniqueField($data, new Category(), 'type');
36
+        $user = Auth::user();
37
+
38
+        if (!$user) {
39
+            throw new Halt('No authenticated user found.');
40
+        }
41
+
42
+        return $this->handleRecordCreationWithUniqueField($data, new Category(), $user, 'type');
35
     }
43
     }
36
 }
44
 }

+ 11
- 3
app/Filament/Resources/CategoryResource/Pages/EditCategory.php Прегледај датотеку

6
 use App\Traits\HandlesResourceRecordUpdate;
6
 use App\Traits\HandlesResourceRecordUpdate;
7
 use Filament\Pages\Actions;
7
 use Filament\Pages\Actions;
8
 use Filament\Resources\Pages\EditRecord;
8
 use Filament\Resources\Pages\EditRecord;
9
+use Filament\Support\Exceptions\Halt;
9
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Support\Facades\Auth;
11
 use Illuminate\Support\Facades\Auth;
11
 
12
 
29
 
30
 
30
     protected function mutateFormDataBeforeSave(array $data): array
31
     protected function mutateFormDataBeforeSave(array $data): array
31
     {
32
     {
32
-        $data['company_id'] = Auth::user()->currentCompany->id;
33
         $data['enabled'] = (bool)$data['enabled'];
33
         $data['enabled'] = (bool)$data['enabled'];
34
-        $data['updated_by'] = Auth::id();
35
 
34
 
36
         return $data;
35
         return $data;
37
     }
36
     }
38
 
37
 
38
+    /**
39
+     * @throws Halt
40
+     */
39
     protected function handleRecordUpdate(Model $record, array $data): Model
41
     protected function handleRecordUpdate(Model $record, array $data): Model
40
     {
42
     {
41
-        return $this->handleRecordUpdateWithUniqueField($record, $data, 'type');
43
+        $user = Auth::user();
44
+
45
+        if (!$user) {
46
+            throw new Halt('No authenticated user found.');
47
+        }
48
+
49
+        return $this->handleRecordUpdateWithUniqueField($record, $data, $user, 'type');
42
     }
50
     }
43
 }
51
 }

+ 11
- 3
app/Filament/Resources/CurrencyResource/Pages/CreateCurrency.php Прегледај датотеку

7
 use App\Traits\HandlesResourceRecordCreation;
7
 use App\Traits\HandlesResourceRecordCreation;
8
 use Filament\Pages\Actions;
8
 use Filament\Pages\Actions;
9
 use Filament\Resources\Pages\CreateRecord;
9
 use Filament\Resources\Pages\CreateRecord;
10
+use Filament\Support\Exceptions\Halt;
10
 use Illuminate\Database\Eloquent\Model;
11
 use Illuminate\Database\Eloquent\Model;
11
 use Illuminate\Support\Facades\Auth;
12
 use Illuminate\Support\Facades\Auth;
12
 use Illuminate\Support\Facades\DB;
13
 use Illuminate\Support\Facades\DB;
24
 
25
 
25
     protected function mutateFormDataBeforeCreate(array $data): array
26
     protected function mutateFormDataBeforeCreate(array $data): array
26
     {
27
     {
27
-        $data['company_id'] = Auth::user()->currentCompany->id;
28
         $data['enabled'] = (bool)$data['enabled'];
28
         $data['enabled'] = (bool)$data['enabled'];
29
-        $data['created_by'] = Auth::id();
30
 
29
 
31
         return $data;
30
         return $data;
32
     }
31
     }
33
 
32
 
33
+    /**
34
+     * @throws Halt
35
+     */
34
     protected function handleRecordCreation(array $data): Model
36
     protected function handleRecordCreation(array $data): Model
35
     {
37
     {
36
-        return $this->handleRecordCreationWithUniqueField($data, new Currency());
38
+        $user = Auth::user();
39
+
40
+        if (!$user) {
41
+            throw new Halt('No authenticated user found.');
42
+        }
43
+
44
+        return $this->handleRecordCreationWithUniqueField($data, new Currency(), $user);
37
     }
45
     }
38
 }
46
 }

+ 11
- 6
app/Filament/Resources/CurrencyResource/Pages/EditCurrency.php Прегледај датотеку

3
 namespace App\Filament\Resources\CurrencyResource\Pages;
3
 namespace App\Filament\Resources\CurrencyResource\Pages;
4
 
4
 
5
 use App\Filament\Resources\CurrencyResource;
5
 use App\Filament\Resources\CurrencyResource;
6
-use App\Models\Banking\Account;
7
-use App\Models\Setting\Currency;
8
 use App\Traits\HandlesResourceRecordUpdate;
6
 use App\Traits\HandlesResourceRecordUpdate;
9
 use Filament\Pages\Actions;
7
 use Filament\Pages\Actions;
10
 use Filament\Resources\Pages\EditRecord;
8
 use Filament\Resources\Pages\EditRecord;
9
+use Filament\Support\Exceptions\Halt;
11
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Model;
12
 use Illuminate\Support\Facades\Auth;
11
 use Illuminate\Support\Facades\Auth;
13
-use Illuminate\Support\Facades\DB;
14
 
12
 
15
 class EditCurrency extends EditRecord
13
 class EditCurrency extends EditRecord
16
 {
14
 {
32
 
30
 
33
     protected function mutateFormDataBeforeSave(array $data): array
31
     protected function mutateFormDataBeforeSave(array $data): array
34
     {
32
     {
35
-        $data['company_id'] = Auth::user()->currentCompany->id;
36
         $data['enabled'] = (bool)$data['enabled'];
33
         $data['enabled'] = (bool)$data['enabled'];
37
-        $data['updated_by'] = Auth::id();
38
 
34
 
39
         return $data;
35
         return $data;
40
     }
36
     }
41
 
37
 
38
+    /**
39
+     * @throws Halt
40
+     */
42
     protected function handleRecordUpdate(Model $record, array $data): Model
41
     protected function handleRecordUpdate(Model $record, array $data): Model
43
     {
42
     {
44
-        return $this->handleRecordUpdateWithUniqueField($record, $data);
43
+        $user = Auth::user();
44
+
45
+        if (!$user) {
46
+            throw new Halt('No authenticated user found.');
47
+        }
48
+
49
+        return $this->handleRecordUpdateWithUniqueField($record, $data, $user);
45
     }
50
     }
46
 
51
 
47
 }
52
 }

+ 0
- 2
app/Filament/Resources/CustomerResource/Pages/CreateCustomer.php Прегледај датотеку

19
 
19
 
20
     protected function mutateFormDataBeforeCreate(array $data): array
20
     protected function mutateFormDataBeforeCreate(array $data): array
21
     {
21
     {
22
-        $data['company_id'] = Auth::user()->currentCompany->id;
23
         $data['type'] = 'customer';
22
         $data['type'] = 'customer';
24
-        $data['created_by'] = Auth::id();
25
 
23
 
26
         return $data;
24
         return $data;
27
     }
25
     }

+ 1
- 10
app/Filament/Resources/CustomerResource/Pages/EditCustomer.php Прегледај датотеку

5
 use App\Filament\Resources\CustomerResource;
5
 use App\Filament\Resources\CustomerResource;
6
 use Filament\Pages\Actions;
6
 use Filament\Pages\Actions;
7
 use Filament\Resources\Pages\EditRecord;
7
 use Filament\Resources\Pages\EditRecord;
8
-use Illuminate\Support\Facades\Auth;
9
 
8
 
10
 class EditCustomer extends EditRecord
9
 class EditCustomer extends EditRecord
11
 {
10
 {
20
 
19
 
21
     protected function getRedirectUrl(): string
20
     protected function getRedirectUrl(): string
22
     {
21
     {
23
-        return $this->getResource()::getUrl('index');
24
-    }
25
-
26
-    protected function mutateFormDataBeforeSave(array $data): array
27
-    {
28
-        $data['company_id'] = Auth::user()->currentCompany->id;
29
-        $data['updated_by'] = Auth::id();
30
-
31
-        return $data;
22
+        return $this->previousUrl;
32
     }
23
     }
33
 }
24
 }

+ 4
- 4
app/Filament/Resources/DiscountResource.php Прегледај датотеку

72
                                 return today()->addDay();
72
                                 return today()->addDay();
73
                             }
73
                             }
74
 
74
 
75
-                            return $record?->start_date->isFuture() ? today()->addDay() : $record?->start_date;
75
+                            return $record?->start_date?->isFuture() ? today()->addDay() : $record?->start_date;
76
                         })
76
                         })
77
                         ->maxDate(static function (callable $get, Discount|null $record = null) {
77
                         ->maxDate(static function (callable $get, Discount|null $record = null) {
78
                             $end_date = $get('end_date') ?? $record?->end_date;
78
                             $end_date = $get('end_date') ?? $record?->end_date;
83
                         ->displayFormat('F d, Y H:i')
83
                         ->displayFormat('F d, Y H:i')
84
                         ->withoutSeconds()
84
                         ->withoutSeconds()
85
                         ->reactive()
85
                         ->reactive()
86
-                        ->disabled(static fn ($context, Discount|null $record = null) => $context === 'edit' && $record?->start_date->isPast())
86
+                        ->disabled(static fn ($context, Discount|null $record = null) => $context === 'edit' && $record?->start_date?->isPast() ?? false)
87
                         ->helperText(static fn (Forms\Components\DateTimePicker $component) => $component->isDisabled() ? 'Start date cannot be changed after the discount has begun.' : null),
87
                         ->helperText(static fn (Forms\Components\DateTimePicker $component) => $component->isDisabled() ? 'Start date cannot be changed after the discount has begun.' : null),
88
                     Forms\Components\DateTimePicker::make('end_date')
88
                     Forms\Components\DateTimePicker::make('end_date')
89
                         ->label('End Date')
89
                         ->label('End Date')
148
                     ->sortable(),
148
                     ->sortable(),
149
                 Tables\Columns\TextColumn::make('start_date')
149
                 Tables\Columns\TextColumn::make('start_date')
150
                 ->label('Start Date')
150
                 ->label('Start Date')
151
-                ->formatStateUsing(static fn (Discount $record) => $record->start_date ? $record->start_date->format('F d, Y H:i') : null)
151
+                ->formatStateUsing(static fn (Discount $record) => $record->start_date ? $record->start_date->format('F d, Y H:i') : 'N/A')
152
                 ->searchable()
152
                 ->searchable()
153
                 ->sortable(),
153
                 ->sortable(),
154
                 Tables\Columns\TextColumn::make('end_date')
154
                 Tables\Columns\TextColumn::make('end_date')
155
                 ->label('End Date')
155
                 ->label('End Date')
156
-                ->formatStateUsing(static fn (Discount $record) => $record->end_date ? $record->end_date->format('F d, Y H:i') : null)
156
+                ->formatStateUsing(static fn (Discount $record) => $record->end_date ? $record->end_date->format('F d, Y H:i') : 'N/A')
157
                 ->color(static fn(Discount $record) => $record->end_date?->isPast() ? 'danger' : null)
157
                 ->color(static fn(Discount $record) => $record->end_date?->isPast() ? 'danger' : null)
158
                 ->searchable()
158
                 ->searchable()
159
                 ->sortable(),
159
                 ->sortable(),

+ 11
- 3
app/Filament/Resources/DiscountResource/Pages/CreateDiscount.php Прегледај датотеку

6
 use App\Models\Setting\Discount;
6
 use App\Models\Setting\Discount;
7
 use App\Traits\HandlesResourceRecordCreation;
7
 use App\Traits\HandlesResourceRecordCreation;
8
 use Filament\Resources\Pages\CreateRecord;
8
 use Filament\Resources\Pages\CreateRecord;
9
+use Filament\Support\Exceptions\Halt;
9
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Support\Facades\Auth;
11
 use Illuminate\Support\Facades\Auth;
11
 
12
 
22
 
23
 
23
     protected function mutateFormDataBeforeCreate(array $data): array
24
     protected function mutateFormDataBeforeCreate(array $data): array
24
     {
25
     {
25
-        $data['company_id'] = Auth::user()->currentCompany->id;
26
         $data['enabled'] = (bool)($data['enabled']);
26
         $data['enabled'] = (bool)($data['enabled']);
27
-        $data['created_by'] = Auth::id();
28
 
27
 
29
         return $data;
28
         return $data;
30
     }
29
     }
31
 
30
 
31
+    /**
32
+     * @throws Halt
33
+     */
32
     protected function handleRecordCreation(array $data): Model
34
     protected function handleRecordCreation(array $data): Model
33
     {
35
     {
34
-        return $this->handleRecordCreationWithUniqueField($data, new Discount(), 'type');
36
+        $user = Auth::user();
37
+
38
+        if (!$user) {
39
+            throw new Halt('No authenticated user found.');
40
+        }
41
+
42
+        return $this->handleRecordCreationWithUniqueField($data, new Discount(), $user, 'type');
35
     }
43
     }
36
 }
44
 }

+ 19
- 1
app/Filament/Resources/DiscountResource/Pages/EditDiscount.php Прегледај датотеку

6
 use App\Traits\HandlesResourceRecordUpdate;
6
 use App\Traits\HandlesResourceRecordUpdate;
7
 use Filament\Pages\Actions;
7
 use Filament\Pages\Actions;
8
 use Filament\Resources\Pages\EditRecord;
8
 use Filament\Resources\Pages\EditRecord;
9
+use Filament\Support\Exceptions\Halt;
9
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Model;
11
+use Illuminate\Support\Facades\Auth;
10
 
12
 
11
 class EditDiscount extends EditRecord
13
 class EditDiscount extends EditRecord
12
 {
14
 {
26
         return $this->previousUrl;
28
         return $this->previousUrl;
27
     }
29
     }
28
 
30
 
31
+    protected function mutateFormDataBeforeSave(array $data): array
32
+    {
33
+        $data['enabled'] = (bool)$data['enabled'];
34
+
35
+        return $data;
36
+    }
37
+
38
+    /**
39
+     * @throws Halt
40
+     */
29
     protected function handleRecordUpdate(Model $record, array $data): Model
41
     protected function handleRecordUpdate(Model $record, array $data): Model
30
     {
42
     {
31
-        return $this->handleRecordUpdateWithUniqueField($record, $data, 'type');
43
+        $user = Auth::user();
44
+
45
+        if (!$user) {
46
+            throw new Halt('No authenticated user found.');
47
+        }
48
+
49
+        return $this->handleRecordUpdateWithUniqueField($record, $data, $user, 'type');
32
     }
50
     }
33
 }
51
 }

+ 0
- 2
app/Filament/Resources/InvoiceResource/Pages/CreateInvoice.php Прегледај датотеку

18
 
18
 
19
     protected function mutateFormDataBeforeCreate(array $data): array
19
     protected function mutateFormDataBeforeCreate(array $data): array
20
     {
20
     {
21
-        $data['company_id'] = Auth::user()->currentCompany->id;
22
         $data['type'] = 'invoice';
21
         $data['type'] = 'invoice';
23
         $data['status'] = 'draft';
22
         $data['status'] = 'draft';
24
         $data['amount'] = 0;
23
         $data['amount'] = 0;
25
-        $data['created_by'] = Auth::id();
26
 
24
 
27
         return $data;
25
         return $data;
28
     }
26
     }

+ 0
- 9
app/Filament/Resources/InvoiceResource/Pages/EditInvoice.php Прегледај датотеку

5
 use App\Filament\Resources\InvoiceResource;
5
 use App\Filament\Resources\InvoiceResource;
6
 use Filament\Pages\Actions;
6
 use Filament\Pages\Actions;
7
 use Filament\Resources\Pages\EditRecord;
7
 use Filament\Resources\Pages\EditRecord;
8
-use Illuminate\Support\Facades\Auth;
9
 
8
 
10
 class EditInvoice extends EditRecord
9
 class EditInvoice extends EditRecord
11
 {
10
 {
22
     {
21
     {
23
         return $this->previousUrl;
22
         return $this->previousUrl;
24
     }
23
     }
25
-
26
-    protected function mutateFormDataBeforeSave(array $data): array
27
-    {
28
-        $data['company_id'] = Auth::user()->currentCompany->id;
29
-        $data['updated_by'] = Auth::id();
30
-
31
-        return $data;
32
-    }
33
 }
24
 }

+ 11
- 3
app/Filament/Resources/TaxResource/Pages/CreateTax.php Прегледај датотеку

6
 use App\Models\Setting\Tax;
6
 use App\Models\Setting\Tax;
7
 use App\Traits\HandlesResourceRecordCreation;
7
 use App\Traits\HandlesResourceRecordCreation;
8
 use Filament\Resources\Pages\CreateRecord;
8
 use Filament\Resources\Pages\CreateRecord;
9
+use Filament\Support\Exceptions\Halt;
9
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Support\Facades\Auth;
11
 use Illuminate\Support\Facades\Auth;
11
 
12
 
22
 
23
 
23
     protected function mutateFormDataBeforeCreate(array $data): array
24
     protected function mutateFormDataBeforeCreate(array $data): array
24
     {
25
     {
25
-        $data['company_id'] = Auth::user()->currentCompany->id;
26
         $data['enabled'] = (bool)$data['enabled'];
26
         $data['enabled'] = (bool)$data['enabled'];
27
-        $data['created_by'] = Auth::id();
28
 
27
 
29
         return $data;
28
         return $data;
30
     }
29
     }
31
 
30
 
31
+    /**
32
+     * @throws Halt
33
+     */
32
     protected function handleRecordCreation(array $data): Model
34
     protected function handleRecordCreation(array $data): Model
33
     {
35
     {
34
-        return $this->handleRecordCreationWithUniqueField($data, new Tax(), 'type');
36
+        $user = Auth::user();
37
+
38
+        if (!$user) {
39
+            throw new Halt('No authenticated user found.');
40
+        }
41
+
42
+        return $this->handleRecordCreationWithUniqueField($data, new Tax(), $user, 'type');
35
     }
43
     }
36
 }
44
 }

+ 11
- 5
app/Filament/Resources/TaxResource/Pages/EditTax.php Прегледај датотеку

3
 namespace App\Filament\Resources\TaxResource\Pages;
3
 namespace App\Filament\Resources\TaxResource\Pages;
4
 
4
 
5
 use App\Filament\Resources\TaxResource;
5
 use App\Filament\Resources\TaxResource;
6
-use App\Models\Setting\Tax;
7
 use App\Traits\HandlesResourceRecordUpdate;
6
 use App\Traits\HandlesResourceRecordUpdate;
8
 use Filament\Pages\Actions;
7
 use Filament\Pages\Actions;
9
 use Filament\Resources\Pages\EditRecord;
8
 use Filament\Resources\Pages\EditRecord;
9
+use Filament\Support\Exceptions\Halt;
10
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Model;
11
 use Illuminate\Support\Facades\Auth;
11
 use Illuminate\Support\Facades\Auth;
12
-use Illuminate\Support\Facades\DB;
13
 
12
 
14
 class EditTax extends EditRecord
13
 class EditTax extends EditRecord
15
 {
14
 {
31
 
30
 
32
     protected function mutateFormDataBeforeUpdate(array $data): array
31
     protected function mutateFormDataBeforeUpdate(array $data): array
33
     {
32
     {
34
-        $data['company_id'] = Auth::user()->currentCompany->id;
35
         $data['enabled'] = (bool)$data['enabled'];
33
         $data['enabled'] = (bool)$data['enabled'];
36
-        $data['updated_by'] = Auth::id();
37
 
34
 
38
         return $data;
35
         return $data;
39
     }
36
     }
40
 
37
 
38
+    /**
39
+     * @throws Halt
40
+     */
41
     protected function handleRecordUpdate(Model $record, array $data): Model
41
     protected function handleRecordUpdate(Model $record, array $data): Model
42
     {
42
     {
43
-        return $this->handleRecordUpdateWithUniqueField($record, $data, 'type');
43
+        $user = Auth::user();
44
+
45
+        if (!$user) {
46
+            throw new Halt('No authenticated user found.');
47
+        }
48
+
49
+        return $this->handleRecordUpdateWithUniqueField($record, $data, $user, 'type');
44
     }
50
     }
45
 }
51
 }

+ 3
- 22
app/Http/Livewire/DefaultSetting.php Прегледај датотеку

7
 use App\Models\Setting\Currency;
7
 use App\Models\Setting\Currency;
8
 use App\Models\Setting\DefaultSetting as Defaults;
8
 use App\Models\Setting\DefaultSetting as Defaults;
9
 use App\Models\Setting\Tax;
9
 use App\Models\Setting\Tax;
10
-use App\Traits\HandlesDefaultSettingRecordCreation;
10
+use App\Traits\HandlesDefaultSettingRecordUpdate;
11
 use Filament\Forms\ComponentContainer;
11
 use Filament\Forms\ComponentContainer;
12
 use Filament\Forms\Components\Section;
12
 use Filament\Forms\Components\Section;
13
 use Filament\Forms\Components\Select;
13
 use Filament\Forms\Components\Select;
15
 use Filament\Forms\Contracts\HasForms;
15
 use Filament\Forms\Contracts\HasForms;
16
 use Filament\Notifications\Notification;
16
 use Filament\Notifications\Notification;
17
 use Illuminate\Contracts\View\View;
17
 use Illuminate\Contracts\View\View;
18
-use Illuminate\Support\Facades\Auth;
19
 use Livewire\Component;
18
 use Livewire\Component;
20
 
19
 
21
 /**
20
 /**
23
  */
22
  */
24
 class DefaultSetting extends Component implements HasForms
23
 class DefaultSetting extends Component implements HasForms
25
 {
24
 {
26
-    use InteractsWithForms, HandlesDefaultSettingRecordCreation;
25
+    use InteractsWithForms, HandlesDefaultSettingRecordUpdate;
27
 
26
 
28
     public Defaults $defaultSetting;
27
     public Defaults $defaultSetting;
29
 
28
 
55
                     Select::make('account_id')
54
                     Select::make('account_id')
56
                         ->label('Account')
55
                         ->label('Account')
57
                         ->options(Defaults::getAccounts())
56
                         ->options(Defaults::getAccounts())
58
-                        ->default(Defaults::getDefaultAccount())
59
                         ->searchable()
57
                         ->searchable()
60
                         ->validationAttribute('Account')
58
                         ->validationAttribute('Account')
61
                         ->nullable(),
59
                         ->nullable(),
62
                     Select::make('currency_code')
60
                     Select::make('currency_code')
63
                         ->label('Currency')
61
                         ->label('Currency')
64
                         ->options(Defaults::getCurrencies())
62
                         ->options(Defaults::getCurrencies())
65
-                        ->default(Defaults::getDefaultCurrency())
66
                         ->searchable()
63
                         ->searchable()
67
                         ->validationAttribute('Currency')
64
                         ->validationAttribute('Currency')
68
                         ->nullable(),
65
                         ->nullable(),
72
                     Select::make('sales_tax_id')
69
                     Select::make('sales_tax_id')
73
                         ->label('Sales Tax')
70
                         ->label('Sales Tax')
74
                         ->options(Defaults::getSalesTaxes())
71
                         ->options(Defaults::getSalesTaxes())
75
-                        ->default(Defaults::getDefaultSalesTax())
76
                         ->searchable()
72
                         ->searchable()
77
                         ->validationAttribute('Sales Tax')
73
                         ->validationAttribute('Sales Tax')
78
                         ->nullable(),
74
                         ->nullable(),
79
                     Select::make('purchase_tax_id')
75
                     Select::make('purchase_tax_id')
80
                         ->label('Purchase Tax')
76
                         ->label('Purchase Tax')
81
                         ->options(Defaults::getPurchaseTaxes())
77
                         ->options(Defaults::getPurchaseTaxes())
82
-                        ->default(Defaults::getDefaultPurchaseTax())
83
                         ->searchable()
78
                         ->searchable()
84
                         ->validationAttribute('Purchase Tax')
79
                         ->validationAttribute('Purchase Tax')
85
                         ->nullable(),
80
                         ->nullable(),
86
                     Select::make('sales_discount_id')
81
                     Select::make('sales_discount_id')
87
                         ->label('Sales Discount')
82
                         ->label('Sales Discount')
88
                         ->options(Defaults::getSalesDiscounts())
83
                         ->options(Defaults::getSalesDiscounts())
89
-                        ->default(Defaults::getDefaultSalesDiscount())
90
                         ->searchable()
84
                         ->searchable()
91
                         ->validationAttribute('Sales Discount')
85
                         ->validationAttribute('Sales Discount')
92
                         ->nullable(),
86
                         ->nullable(),
93
                     Select::make('purchase_discount_id')
87
                     Select::make('purchase_discount_id')
94
                         ->label('Purchase Discount')
88
                         ->label('Purchase Discount')
95
                         ->options(Defaults::getPurchaseDiscounts())
89
                         ->options(Defaults::getPurchaseDiscounts())
96
-                        ->default(Defaults::getDefaultPurchaseDiscount())
97
                         ->searchable()
90
                         ->searchable()
98
                         ->validationAttribute('Purchase Discount')
91
                         ->validationAttribute('Purchase Discount')
99
                         ->nullable(),
92
                         ->nullable(),
103
                     Select::make('income_category_id')
96
                     Select::make('income_category_id')
104
                         ->label('Income Category')
97
                         ->label('Income Category')
105
                         ->options(Defaults::getIncomeCategories())
98
                         ->options(Defaults::getIncomeCategories())
106
-                        ->default(Defaults::getDefaultIncomeCategory())
107
                         ->searchable()
99
                         ->searchable()
108
                         ->validationAttribute('Income Category')
100
                         ->validationAttribute('Income Category')
109
                         ->nullable(),
101
                         ->nullable(),
110
                     Select::make('expense_category_id')
102
                     Select::make('expense_category_id')
111
                         ->label('Expense Category')
103
                         ->label('Expense Category')
112
                         ->options(Defaults::getExpenseCategories())
104
                         ->options(Defaults::getExpenseCategories())
113
-                        ->default(Defaults::getDefaultExpenseCategory())
114
                         ->searchable()
105
                         ->searchable()
115
                         ->validationAttribute('Expense Category')
106
                         ->validationAttribute('Expense Category')
116
                         ->nullable(),
107
                         ->nullable(),
122
     {
113
     {
123
         $data = $this->form->getState();
114
         $data = $this->form->getState();
124
 
115
 
125
-        $data = $this->mutateFormDataBeforeCreate($data);
126
-
127
-        $this->record = $this->handleRecordCreation($data);
116
+        $this->record = $this->handleRecordUpdate($data);
128
 
117
 
129
         $this->form->model($this->record)->saveRelationships();
118
         $this->form->model($this->record)->saveRelationships();
130
 
119
 
131
         $this->getSavedNotification()?->send();
120
         $this->getSavedNotification()?->send();
132
     }
121
     }
133
 
122
 
134
-    protected function mutateFormDataBeforeCreate(array $data): array
135
-    {
136
-        $data['company_id'] = Auth::user()->currentCompany->id;
137
-        $data['updated_by'] = Auth::id();
138
-
139
-        return $data;
140
-    }
141
-
142
     protected function getRelatedEntities(): array
123
     protected function getRelatedEntities(): array
143
     {
124
     {
144
         return [
125
         return [

+ 3
- 4
app/Models/Banking/Account.php Прегледај датотеку

5
 use App\Scopes\CurrentCompanyScope;
5
 use App\Scopes\CurrentCompanyScope;
6
 use App\Models\Setting\Currency;
6
 use App\Models\Setting\Currency;
7
 use App\Models\Setting\DefaultSetting;
7
 use App\Models\Setting\DefaultSetting;
8
+use App\Traits\Blamable;
9
+use App\Traits\CompanyOwned;
8
 use Database\Factories\AccountFactory;
10
 use Database\Factories\AccountFactory;
9
 use Illuminate\Database\Eloquent\Factories\Factory;
11
 use Illuminate\Database\Eloquent\Factories\Factory;
10
 use Illuminate\Database\Eloquent\Factories\HasFactory;
12
 use Illuminate\Database\Eloquent\Factories\HasFactory;
12
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
14
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
13
 use Illuminate\Database\Eloquent\Relations\HasMany;
15
 use Illuminate\Database\Eloquent\Relations\HasMany;
14
 use Illuminate\Database\Eloquent\Relations\HasOne;
16
 use Illuminate\Database\Eloquent\Relations\HasOne;
15
-use Illuminate\Support\Facades\Auth;
16
-use Illuminate\Support\Facades\Config;
17
 use Spatie\Tags\HasTags;
17
 use Spatie\Tags\HasTags;
18
 use Wallo\FilamentCompanies\FilamentCompanies;
18
 use Wallo\FilamentCompanies\FilamentCompanies;
19
 
19
 
20
 class Account extends Model
20
 class Account extends Model
21
 {
21
 {
22
-    use HasFactory;
23
-    use HasTags;
22
+    use Blamable, CompanyOwned, HasFactory, HasTags;
24
 
23
 
25
     protected $table = 'accounts';
24
     protected $table = 'accounts';
26
 
25
 

+ 3
- 1
app/Models/Contact.php Прегледај датотеку

5
 use App\Models\Document\Document;
5
 use App\Models\Document\Document;
6
 use App\Models\Setting\Currency;
6
 use App\Models\Setting\Currency;
7
 use App\Scopes\CurrentCompanyScope;
7
 use App\Scopes\CurrentCompanyScope;
8
+use App\Traits\Blamable;
9
+use App\Traits\CompanyOwned;
8
 use Illuminate\Database\Eloquent\Factories\HasFactory;
10
 use Illuminate\Database\Eloquent\Factories\HasFactory;
9
 use Illuminate\Database\Eloquent\Model;
11
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
12
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
15
 
17
 
16
 class Contact extends Model
18
 class Contact extends Model
17
 {
19
 {
18
-    use HasFactory;
20
+    use Blamable, CompanyOwned, HasFactory;
19
 
21
 
20
     protected $table = 'contacts';
22
     protected $table = 'contacts';
21
 
23
 

+ 3
- 1
app/Models/Document/Document.php Прегледај датотеку

8
 use App\Models\Setting\Discount;
8
 use App\Models\Setting\Discount;
9
 use App\Models\Setting\DocumentDefault;
9
 use App\Models\Setting\DocumentDefault;
10
 use App\Models\Setting\Tax;
10
 use App\Models\Setting\Tax;
11
+use App\Traits\Blamable;
12
+use App\Traits\CompanyOwned;
11
 use Database\Factories\DocumentFactory;
13
 use Database\Factories\DocumentFactory;
12
 use Illuminate\Database\Eloquent\Factories\Factory;
14
 use Illuminate\Database\Eloquent\Factories\Factory;
13
 use Illuminate\Database\Eloquent\Factories\HasFactory;
15
 use Illuminate\Database\Eloquent\Factories\HasFactory;
19
 
21
 
20
 class Document extends Model
22
 class Document extends Model
21
 {
23
 {
22
-    use HasFactory;
24
+    use Blamable, CompanyOwned, HasFactory;
23
 
25
 
24
     protected $table = 'documents';
26
     protected $table = 'documents';
25
 
27
 

+ 3
- 1
app/Models/Document/DocumentItem.php Прегледај датотеку

5
 use App\Models\Item;
5
 use App\Models\Item;
6
 use App\Models\Setting\Discount;
6
 use App\Models\Setting\Discount;
7
 use App\Models\Setting\Tax;
7
 use App\Models\Setting\Tax;
8
+use App\Traits\Blamable;
9
+use App\Traits\CompanyOwned;
8
 use Database\Factories\DocumentItemFactory;
10
 use Database\Factories\DocumentItemFactory;
9
 use Illuminate\Database\Eloquent\Factories\Factory;
11
 use Illuminate\Database\Eloquent\Factories\Factory;
10
 use Illuminate\Database\Eloquent\Factories\HasFactory;
12
 use Illuminate\Database\Eloquent\Factories\HasFactory;
14
 
16
 
15
 class DocumentItem extends Model
17
 class DocumentItem extends Model
16
 {
18
 {
17
-    use HasFactory;
19
+    use Blamable, CompanyOwned, HasFactory;
18
 
20
 
19
     protected $table = 'document_items';
21
     protected $table = 'document_items';
20
 
22
 

+ 3
- 1
app/Models/Document/DocumentTotal.php Прегледај датотеку

2
 
2
 
3
 namespace App\Models\Document;
3
 namespace App\Models\Document;
4
 
4
 
5
+use App\Traits\Blamable;
6
+use App\Traits\CompanyOwned;
5
 use Database\Factories\DocumentTotalFactory;
7
 use Database\Factories\DocumentTotalFactory;
6
 use Illuminate\Database\Eloquent\Factories\Factory;
8
 use Illuminate\Database\Eloquent\Factories\Factory;
7
 use Illuminate\Database\Eloquent\Factories\HasFactory;
9
 use Illuminate\Database\Eloquent\Factories\HasFactory;
11
 
13
 
12
 class DocumentTotal extends Model
14
 class DocumentTotal extends Model
13
 {
15
 {
14
-    use HasFactory;
16
+    use Blamable, CompanyOwned, HasFactory;
15
 
17
 
16
     protected $table = 'document_totals';
18
     protected $table = 'document_totals';
17
 
19
 

+ 3
- 1
app/Models/Item.php Прегледај датотеку

6
 use App\Models\Setting\Category;
6
 use App\Models\Setting\Category;
7
 use App\Models\Setting\Discount;
7
 use App\Models\Setting\Discount;
8
 use App\Models\Setting\Tax;
8
 use App\Models\Setting\Tax;
9
+use App\Traits\Blamable;
10
+use App\Traits\CompanyOwned;
9
 use Illuminate\Database\Eloquent\Factories\HasFactory;
11
 use Illuminate\Database\Eloquent\Factories\HasFactory;
10
 use Illuminate\Database\Eloquent\Model;
12
 use Illuminate\Database\Eloquent\Model;
11
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
13
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
14
 
16
 
15
 class Item extends Model
17
 class Item extends Model
16
 {
18
 {
17
-    use HasFactory;
19
+    use Blamable, CompanyOwned, HasFactory;
18
 
20
 
19
     protected $table = 'items';
21
     protected $table = 'items';
20
 
22
 

+ 3
- 1
app/Models/Setting/Category.php Прегледај датотеку

5
 use App\Models\Document\Document;
5
 use App\Models\Document\Document;
6
 use App\Models\Item;
6
 use App\Models\Item;
7
 use App\Scopes\CurrentCompanyScope;
7
 use App\Scopes\CurrentCompanyScope;
8
+use App\Traits\Blamable;
9
+use App\Traits\CompanyOwned;
8
 use Database\Factories\CategoryFactory;
10
 use Database\Factories\CategoryFactory;
9
 use Illuminate\Database\Eloquent\Factories\Factory;
11
 use Illuminate\Database\Eloquent\Factories\Factory;
10
 use Illuminate\Database\Eloquent\Factories\HasFactory;
12
 use Illuminate\Database\Eloquent\Factories\HasFactory;
16
 
18
 
17
 class Category extends Model
19
 class Category extends Model
18
 {
20
 {
19
-    use HasFactory;
21
+    use Blamable, CompanyOwned, HasFactory;
20
 
22
 
21
     protected $table = 'categories';
23
     protected $table = 'categories';
22
 
24
 

+ 13
- 1
app/Models/Setting/Currency.php Прегледај датотеку

4
 
4
 
5
 use App\Models\Banking\Account;
5
 use App\Models\Banking\Account;
6
 use App\Scopes\CurrentCompanyScope;
6
 use App\Scopes\CurrentCompanyScope;
7
+use App\Traits\Blamable;
8
+use App\Traits\CompanyOwned;
7
 use Database\Factories\CurrencyFactory;
9
 use Database\Factories\CurrencyFactory;
8
 use Illuminate\Database\Eloquent\Factories\Factory;
10
 use Illuminate\Database\Eloquent\Factories\Factory;
9
 use Illuminate\Database\Eloquent\Factories\HasFactory;
11
 use Illuminate\Database\Eloquent\Factories\HasFactory;
16
 
18
 
17
 class Currency extends Model
19
 class Currency extends Model
18
 {
20
 {
19
-    use HasFactory;
21
+    use Blamable, CompanyOwned, HasFactory;
20
 
22
 
21
     protected $table = 'currencies';
23
     protected $table = 'currencies';
22
 
24
 
60
         return $this->hasMany(Account::class, 'currency_code', 'code');
62
         return $this->hasMany(Account::class, 'currency_code', 'code');
61
     }
63
     }
62
 
64
 
65
+    public function createdBy(): BelongsTo
66
+    {
67
+        return $this->belongsTo(FilamentCompanies::userModel(), 'created_by');
68
+    }
69
+
70
+    public function updatedBy(): BelongsTo
71
+    {
72
+        return $this->belongsTo(FilamentCompanies::userModel(), 'updated_by');
73
+    }
74
+
63
     public static function getCurrencyCodes(): array
75
     public static function getCurrencyCodes(): array
64
     {
76
     {
65
         $allCodes = array_keys(Config::get('money'));
77
         $allCodes = array_keys(Config::get('money'));

+ 9
- 1
app/Models/Setting/DefaultSetting.php Прегледај датотеку

4
 
4
 
5
 use App\Models\Banking\Account;
5
 use App\Models\Banking\Account;
6
 use App\Scopes\CurrentCompanyScope;
6
 use App\Scopes\CurrentCompanyScope;
7
+use App\Traits\Blamable;
8
+use App\Traits\CompanyOwned;
7
 use Illuminate\Database\Eloquent\Factories\HasFactory;
9
 use Illuminate\Database\Eloquent\Factories\HasFactory;
8
 use Illuminate\Database\Eloquent\Model;
10
 use Illuminate\Database\Eloquent\Model;
9
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
11
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
11
 
13
 
12
 class DefaultSetting extends Model
14
 class DefaultSetting extends Model
13
 {
15
 {
14
-    use HasFactory;
16
+    use Blamable, CompanyOwned, HasFactory;
15
 
17
 
16
     protected $table = 'default_settings';
18
     protected $table = 'default_settings';
17
 
19
 
25
         'purchase_discount_id',
27
         'purchase_discount_id',
26
         'income_category_id',
28
         'income_category_id',
27
         'expense_category_id',
29
         'expense_category_id',
30
+        'created_by',
28
         'updated_by',
31
         'updated_by',
29
     ];
32
     ];
30
 
33
 
84
             ->where('type', 'expense');
87
             ->where('type', 'expense');
85
     }
88
     }
86
 
89
 
90
+    public function createdBy(): BelongsTo
91
+    {
92
+        return $this->belongsTo(FilamentCompanies::userModel(), 'created_by');
93
+    }
94
+
87
     public function updatedBy(): BelongsTo
95
     public function updatedBy(): BelongsTo
88
     {
96
     {
89
         return $this->belongsTo(FilamentCompanies::userModel(), 'updated_by');
97
         return $this->belongsTo(FilamentCompanies::userModel(), 'updated_by');

+ 3
- 1
app/Models/Setting/Discount.php Прегледај датотеку

5
 use App\Models\Document\DocumentItem;
5
 use App\Models\Document\DocumentItem;
6
 use App\Models\Item;
6
 use App\Models\Item;
7
 use App\Scopes\CurrentCompanyScope;
7
 use App\Scopes\CurrentCompanyScope;
8
+use App\Traits\Blamable;
9
+use App\Traits\CompanyOwned;
8
 use Database\Factories\DiscountFactory;
10
 use Database\Factories\DiscountFactory;
9
 use Illuminate\Database\Eloquent\Factories\Factory;
11
 use Illuminate\Database\Eloquent\Factories\Factory;
10
 use Illuminate\Database\Eloquent\Factories\HasFactory;
12
 use Illuminate\Database\Eloquent\Factories\HasFactory;
16
 
18
 
17
 class Discount extends Model
19
 class Discount extends Model
18
 {
20
 {
19
-    use HasFactory;
21
+    use Blamable, CompanyOwned, HasFactory;
20
 
22
 
21
     protected $table = 'discounts';
23
     protected $table = 'discounts';
22
 
24
 

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

4
 
4
 
5
 use App\Models\Document\Document;
5
 use App\Models\Document\Document;
6
 use App\Scopes\CurrentCompanyScope;
6
 use App\Scopes\CurrentCompanyScope;
7
+use App\Traits\Blamable;
8
+use App\Traits\CompanyOwned;
7
 use Database\Factories\DocumentDefaultFactory;
9
 use Database\Factories\DocumentDefaultFactory;
8
 use Illuminate\Database\Eloquent\Factories\Factory;
10
 use Illuminate\Database\Eloquent\Factories\Factory;
9
 use Illuminate\Database\Eloquent\Factories\HasFactory;
11
 use Illuminate\Database\Eloquent\Factories\HasFactory;
14
 
16
 
15
 class DocumentDefault extends Model
17
 class DocumentDefault extends Model
16
 {
18
 {
17
-    use HasFactory;
19
+    use Blamable, CompanyOwned, HasFactory;
18
 
20
 
19
     protected $table = 'document_defaults';
21
     protected $table = 'document_defaults';
20
 
22
 
31
         'notes',
33
         'notes',
32
         'terms',
34
         'terms',
33
         'footer',
35
         'footer',
36
+        'created_by',
37
+        'updated_by',
34
     ];
38
     ];
35
 
39
 
36
     protected static function booted(): void
40
     protected static function booted(): void
48
         return $this->hasMany(Document::class);
52
         return $this->hasMany(Document::class);
49
     }
53
     }
50
 
54
 
55
+    public function createdBy(): BelongsTo
56
+    {
57
+        return $this->belongsTo(FilamentCompanies::userModel(), 'created_by');
58
+    }
59
+
60
+    public function updatedBy(): BelongsTo
61
+    {
62
+        return $this->belongsTo(FilamentCompanies::userModel(), 'updated_by');
63
+    }
64
+
51
     public static function getDocumentNumberDigits(): array
65
     public static function getDocumentNumberDigits(): array
52
     {
66
     {
53
         return array_combine(range(1, 20), range(1, 20));
67
         return array_combine(range(1, 20), range(1, 20));

+ 3
- 1
app/Models/Setting/Tax.php Прегледај датотеку

6
 use App\Models\Document\DocumentItem;
6
 use App\Models\Document\DocumentItem;
7
 use App\Models\Item;
7
 use App\Models\Item;
8
 use App\Scopes\CurrentCompanyScope;
8
 use App\Scopes\CurrentCompanyScope;
9
+use App\Traits\Blamable;
10
+use App\Traits\CompanyOwned;
9
 use Database\Factories\TaxFactory;
11
 use Database\Factories\TaxFactory;
10
 use Illuminate\Database\Eloquent\Factories\Factory;
12
 use Illuminate\Database\Eloquent\Factories\Factory;
11
 use Illuminate\Database\Eloquent\Factories\HasFactory;
13
 use Illuminate\Database\Eloquent\Factories\HasFactory;
17
 
19
 
18
 class Tax extends Model
20
 class Tax extends Model
19
 {
21
 {
20
-    use HasFactory;
22
+    use Blamable, CompanyOwned, HasFactory;
21
 
23
 
22
     protected $table = 'taxes';
24
     protected $table = 'taxes';
23
 
25
 

+ 3
- 67
app/Observers/CompanyObserver.php Прегледај датотеку

3
 namespace App\Observers;
3
 namespace App\Observers;
4
 
4
 
5
 use App\Models\Company;
5
 use App\Models\Company;
6
-use App\Models\Setting\Category;
7
-use App\Models\Setting\Currency;
8
-use App\Models\Setting\Discount;
9
-use App\Models\Setting\DocumentDefault;
10
-use App\Models\Setting\Tax;
6
+use App\Services\DefaultSettingService;
11
 
7
 
12
 class CompanyObserver
8
 class CompanyObserver
13
 {
9
 {
16
      */
12
      */
17
     public function created(Company $company): void
13
     public function created(Company $company): void
18
     {
14
     {
19
-        $incomeCategories = ['Salary', 'Bonus', 'Interest', 'Dividends', 'Rentals'];
20
-        $expenseCategories = ['Rent', 'Utilities', 'Food', 'Transportation', 'Entertainment'];
21
-
22
-        $shuffledCategories = [
23
-            ...array_map(static fn ($name) => ['name' => $name, 'type' => 'income'], $incomeCategories),
24
-            ...array_map(static fn ($name) => ['name' => $name, 'type' => 'expense'], $expenseCategories),
25
-        ];
26
-
27
-        shuffle($shuffledCategories);
28
-
29
-        $incomeEnabled = $expenseEnabled = false;
30
-
31
-        foreach ($shuffledCategories as $category) {
32
-            $enabled = false;
33
-            if (!$incomeEnabled && $category['type'] === 'income') {
34
-                $enabled = $incomeEnabled = true;
35
-            } elseif (!$expenseEnabled && $category['type'] === 'expense') {
36
-                $enabled = $expenseEnabled = true;
37
-            }
38
-
39
-            Category::factory()->create([
40
-                'company_id' => $company->id,
41
-                'name' => $category['name'],
42
-                'type' => $category['type'],
43
-                'enabled' => $enabled,
44
-                'created_by' => $company->user_id,
45
-            ]);
46
-        }
47
-
48
-
49
-        DocumentDefault::factory()->invoice()->create([
50
-            'company_id' => $company->id,
51
-        ]);
52
-
53
-        DocumentDefault::factory()->bill()->create([
54
-            'company_id' => $company->id,
55
-        ]);
56
-
57
-        Currency::factory()->create([
58
-            'company_id' => $company->id,
59
-            'created_by' => $company->user_id,
60
-        ]);
61
-
62
-        Tax::factory()->salesTax()->create([
63
-            'company_id' => $company->id,
64
-            'created_by' => $company->user_id,
65
-        ]);
66
-
67
-        Tax::factory()->purchaseTax()->create([
68
-            'company_id' => $company->id,
69
-            'created_by' => $company->user_id,
70
-        ]);
71
-
72
-        Discount::factory()->salesDiscount()->create([
73
-            'company_id' => $company->id,
74
-            'created_by' => $company->user_id,
75
-        ]);
76
-
77
-        Discount::factory()->purchaseDiscount()->create([
78
-            'company_id' => $company->id,
79
-            'created_by' => $company->user_id,
80
-        ]);
15
+        $defaultSettingService = new DefaultSettingService();
16
+        $defaultSettingService->createDefaultSettings($company);
81
     }
17
     }
82
 
18
 
83
     /**
19
     /**

+ 141
- 0
app/Services/DefaultSettingService.php Прегледај датотеку

1
+<?php
2
+
3
+namespace App\Services;
4
+
5
+use App\Models\Company;
6
+use App\Models\Setting\Category;
7
+use App\Models\Setting\Currency;
8
+use App\Models\Setting\DefaultSetting;
9
+use App\Models\Setting\Discount;
10
+use App\Models\Setting\DocumentDefault;
11
+use App\Models\Setting\Tax;
12
+use Illuminate\Support\Facades\Auth;
13
+
14
+class DefaultSettingService
15
+{
16
+    public function createDefaultSettings(Company $company): void
17
+    {
18
+        $categories = $this->createDefaultCategories($company);
19
+        $currency = $this->createDefaultCurrency($company);
20
+        $salesTax = $this->createDefaultSalesTax($company);
21
+        $purchaseTax = $this->createDefaultPurchaseTax($company);
22
+        $salesDiscount = $this->createDefaultSalesDiscount($company);
23
+        $purchaseDiscount = $this->createDefaultPurchaseDiscount($company);
24
+
25
+        $defaultSettings = [
26
+            'company_id' => $company->id,
27
+            'income_category_id' => $categories['income_category_id'],
28
+            'expense_category_id' => $categories['expense_category_id'],
29
+            'currency_code' => $currency->code,
30
+            'sales_tax_id' => $salesTax->id,
31
+            'purchase_tax_id' => $purchaseTax->id,
32
+            'sales_discount_id' => $salesDiscount->id,
33
+            'purchase_discount_id' => $purchaseDiscount->id,
34
+            'created_by' => $company->owner->id,
35
+            'updated_by' => $company->owner->id,
36
+        ];
37
+
38
+        DefaultSetting::create($defaultSettings);
39
+
40
+        $this->createDefaultDocuments($company);
41
+    }
42
+
43
+    private function createDefaultCategories(Company $company): array
44
+    {
45
+        $incomeCategories = ['Salary', 'Bonus', 'Interest', 'Dividends', 'Rentals'];
46
+        $expenseCategories = ['Rent', 'Utilities', 'Food', 'Transportation', 'Entertainment'];
47
+
48
+        $shuffledCategories = [
49
+            ...array_map(static fn ($name) => ['name' => $name, 'type' => 'income'], $incomeCategories),
50
+            ...array_map(static fn ($name) => ['name' => $name, 'type' => 'expense'], $expenseCategories),
51
+        ];
52
+
53
+        shuffle($shuffledCategories);
54
+
55
+        $incomeEnabled = $expenseEnabled = false;
56
+
57
+        $defaultSettings = [];
58
+
59
+        foreach ($shuffledCategories as $category) {
60
+            $enabled = false;
61
+            if (!$incomeEnabled && $category['type'] === 'income') {
62
+                $enabled = $incomeEnabled = true;
63
+            } elseif (!$expenseEnabled && $category['type'] === 'expense') {
64
+                $enabled = $expenseEnabled = true;
65
+            }
66
+
67
+            $categoryModel = Category::factory()->create([
68
+                'company_id' => $company->id,
69
+                'name' => $category['name'],
70
+                'type' => $category['type'],
71
+                'enabled' => $enabled,
72
+                'created_by' => Auth::id(),
73
+                'updated_by' => Auth::id(),
74
+            ]);
75
+
76
+            $defaultSettings[$category['type'] . '_category_id'] = $categoryModel->id;
77
+        }
78
+
79
+        return $defaultSettings;
80
+    }
81
+
82
+    private function createDefaultDocuments(Company $company): void
83
+    {
84
+        DocumentDefault::factory()->invoice()->create([
85
+            'company_id' => $company->id,
86
+            'created_by' => Auth::id(),
87
+            'updated_by' => Auth::id(),
88
+        ]);
89
+
90
+        DocumentDefault::factory()->bill()->create([
91
+            'company_id' => $company->id,
92
+            'created_by' => Auth::id(),
93
+            'updated_by' => Auth::id(),
94
+        ]);
95
+    }
96
+
97
+    private function createDefaultCurrency(Company $company): Currency
98
+    {
99
+        return Currency::factory()->create([
100
+            'company_id' => $company->id,
101
+            'created_by' => Auth::id(),
102
+            'updated_by' => Auth::id(),
103
+        ]);
104
+    }
105
+
106
+    private function createDefaultSalesTax(Company $company): Tax
107
+    {
108
+        return Tax::factory()->salesTax()->create([
109
+            'company_id' => $company->id,
110
+            'created_by' => Auth::id(),
111
+            'updated_by' => Auth::id(),
112
+        ]);
113
+    }
114
+
115
+    private function createDefaultPurchaseTax(Company $company): Tax
116
+    {
117
+        return Tax::factory()->purchaseTax()->create([
118
+            'company_id' => $company->id,
119
+            'created_by' => Auth::id(),
120
+            'updated_by' => Auth::id(),
121
+        ]);
122
+    }
123
+
124
+    private function createDefaultSalesDiscount(Company $company): Discount
125
+    {
126
+        return Discount::factory()->salesDiscount()->create([
127
+            'company_id' => $company->id,
128
+            'created_by' => Auth::id(),
129
+            'updated_by' => Auth::id(),
130
+        ]);
131
+    }
132
+
133
+    private function createDefaultPurchaseDiscount(Company $company): Discount
134
+    {
135
+        return Discount::factory()->purchaseDiscount()->create([
136
+            'company_id' => $company->id,
137
+            'created_by' => Auth::id(),
138
+            'updated_by' => Auth::id(),
139
+        ]);
140
+    }
141
+}

+ 20
- 0
app/Traits/Blamable.php Прегледај датотеку

1
+<?php
2
+
3
+namespace App\Traits;
4
+
5
+use Illuminate\Support\Facades\Auth;
6
+
7
+trait Blamable
8
+{
9
+    public static function bootBlamable(): void
10
+    {
11
+        static::created(static function ($model) {
12
+            $model->created_by = Auth::check() ? Auth::id() : null;
13
+            $model->updated_by = Auth::check() ? Auth::id() : null;
14
+        });
15
+
16
+        static::updated(static function ($model) {
17
+            $model->updated_by = Auth::check() ? Auth::id() : null;
18
+        });
19
+    }
20
+}

+ 25
- 0
app/Traits/CompanyOwned.php Прегледај датотеку

1
+<?php
2
+
3
+namespace App\Traits;
4
+
5
+use Filament\Notifications\Notification;
6
+use Illuminate\Support\Facades\Auth;
7
+
8
+trait CompanyOwned
9
+{
10
+    public static function bootCompanyOwned(): void
11
+    {
12
+        static::created(static function ($model) {
13
+            if (Auth::check() && Auth::user()->currentCompany) {
14
+                $model->company_id = Auth::user()->currentCompany->id;
15
+            } else {
16
+                Notification::make()
17
+                    ->danger()
18
+                    ->title('Oops! Unable to Assign Company')
19
+                    ->body('We encountered an issue while creating the record. Please ensure you are logged in and have a valid company associated with your account.')
20
+                    ->persistent()
21
+                    ->send();
22
+            }
23
+        });
24
+    }
25
+}

app/Traits/HandlesDefaultSettingRecordCreation.php → app/Traits/HandlesDefaultSettingRecordUpdate.php Прегледај датотеку

5
 use Illuminate\Database\Eloquent\Model;
5
 use Illuminate\Database\Eloquent\Model;
6
 use Illuminate\Support\Facades\Auth;
6
 use Illuminate\Support\Facades\Auth;
7
 
7
 
8
-trait HandlesDefaultSettingRecordCreation
8
+trait HandlesDefaultSettingRecordUpdate
9
 {
9
 {
10
     abstract protected function getRelatedEntities(): array;
10
     abstract protected function getRelatedEntities(): array;
11
     abstract protected function getFormModel(): string;
11
     abstract protected function getFormModel(): string;
12
 
12
 
13
-    protected function handleRecordCreation(array $data): Model
13
+    protected function handleRecordUpdate(array $data): Model
14
     {
14
     {
15
         $relatedEntities = $this->getRelatedEntities();
15
         $relatedEntities = $this->getRelatedEntities();
16
-
17
         $model = $this->getFormModel();
16
         $model = $this->getFormModel();
18
 
17
 
19
         $existingRecord = $model::where('company_id', Auth::user()->currentCompany->id)
18
         $existingRecord = $model::where('company_id', Auth::user()->currentCompany->id)
20
             ->latest()
19
             ->latest()
21
             ->first();
20
             ->first();
22
 
21
 
23
-        $newData = [
24
-            'company_id' => Auth::user()->currentCompany->id,
25
-            'updated_by' => Auth::id(),
26
-        ];
27
-
28
         foreach ($relatedEntities as $field => $params) {
22
         foreach ($relatedEntities as $field => $params) {
29
             [$class, $key, $type] = array_pad($params, 3, null);
23
             [$class, $key, $type] = array_pad($params, 3, null);
30
 
24
 
31
             if ($existingRecord === null || !isset($existingRecord->{$field})) {
25
             if ($existingRecord === null || !isset($existingRecord->{$field})) {
32
-                $newData[$field] = $data[$field];
33
                 continue;
26
                 continue;
34
             }
27
             }
35
 
28
 
36
             if (isset($data[$field]) && $data[$field] !== $existingRecord->{$field}) {
29
             if (isset($data[$field]) && $data[$field] !== $existingRecord->{$field}) {
37
                 $this->updateEnabledRecord($class, $key, $existingRecord->{$field}, $type, false);
30
                 $this->updateEnabledRecord($class, $key, $existingRecord->{$field}, $type, false);
38
                 $this->updateEnabledRecord($class, $key, $data[$field], $type, true);
31
                 $this->updateEnabledRecord($class, $key, $data[$field], $type, true);
39
-
40
-                $newData[$field] = $data[$field];
41
-            } else {
42
-                $newData[$field] = $existingRecord->{$field};
43
             }
32
             }
44
         }
33
         }
45
 
34
 
46
-        return $model::create($newData);
35
+        $defaults = $model::where('company_id', Auth::user()->currentCompany->id)->first();
36
+
37
+        if ($defaults === null) {
38
+            $defaults = $model::create($data);
39
+        } else {
40
+            $defaults->update($data);
41
+        }
42
+
43
+        return $defaults;
47
     }
44
     }
48
 
45
 
49
     protected function updateEnabledRecord($class, $key, $value, $type = null, $enabled = true): void
46
     protected function updateEnabledRecord($class, $key, $value, $type = null, $enabled = true): void
56
         }
53
         }
57
 
54
 
58
         $query->where($key, $value)
55
         $query->where($key, $value)
59
-            ->update([
60
-                'enabled' => $enabled,
61
-                'updated_by' => Auth::id(),
62
-            ]);
56
+            ->update(compact('enabled'));
63
     }
57
     }
64
 }
58
 }
65
 
59
 

+ 31
- 18
app/Traits/HandlesResourceRecordCreation.php Прегледај датотеку

2
 
2
 
3
 namespace App\Traits;
3
 namespace App\Traits;
4
 
4
 
5
+use App\Models\User;
6
+use Filament\Support\Exceptions\Halt;
7
+use Illuminate\Auth\Access\AuthorizationException;
5
 use Illuminate\Database\Eloquent\Model;
8
 use Illuminate\Database\Eloquent\Model;
6
-use Illuminate\Support\Facades\Auth;
7
 use Illuminate\Support\Facades\DB;
9
 use Illuminate\Support\Facades\DB;
10
+use Illuminate\Validation\ValidationException;
11
+use Throwable;
8
 
12
 
9
 trait HandlesResourceRecordCreation
13
 trait HandlesResourceRecordCreation
10
 {
14
 {
11
-    protected function handleRecordCreationWithUniqueField(array $data, Model $model, string|null $uniqueField = null): Model
15
+    /**
16
+     * @throws Halt
17
+     */
18
+    protected function handleRecordCreationWithUniqueField(array $data, Model $model, User $user, string|null $uniqueField = null, ?string $uniqueFieldValue = null): Model
12
     {
19
     {
13
-        return DB::transaction(function () use ($data, $uniqueField, $model) {
14
-            $currentCompanyId = Auth::user()->currentCompany->id;
15
-            $uniqueFieldValue = $data[$uniqueField] ?? null;
16
-            $enabled = (bool)($data['enabled'] ?? false);
20
+        try {
21
+            return DB::transaction(function () use ($data, $user, $model, $uniqueField, $uniqueFieldValue) {
22
+                $enabled = (bool)($data['enabled'] ?? false);
17
 
23
 
18
-            if ($enabled === true) {
19
-                $this->disableExistingRecord($currentCompanyId, $model, $uniqueField, $uniqueFieldValue);
20
-            } else {
21
-                $this->ensureAtLeastOneEnabled($currentCompanyId, $model, $enabled, $uniqueField, $uniqueFieldValue);
22
-            }
24
+                if ($enabled === true) {
25
+                    $this->disableExistingRecord($user->currentCompany->id, $model, $uniqueField, $uniqueFieldValue);
26
+                } else {
27
+                    $this->ensureAtLeastOneEnabled($user->currentCompany->id, $model, $enabled, $uniqueField, $uniqueFieldValue);
28
+                }
23
 
29
 
24
-            $data['enabled'] = $enabled;
30
+                $data['enabled'] = $enabled;
25
 
31
 
26
-            return $model::create($data);
27
-        });
32
+                return tap($model)->create($data);
33
+            });
34
+        } catch (ValidationException) {
35
+            throw new Halt('Invalid data provided. Please check the form and try again.');
36
+        } catch (AuthorizationException) {
37
+            throw new Halt('You are not authorized to perform this action.');
38
+        } catch (Throwable) {
39
+            throw new Halt('An unexpected error occurred. Please try again.');
40
+        }
28
     }
41
     }
29
 
42
 
30
     protected function disableExistingRecord(int $companyId, Model $model, string|null $uniqueField = null, string|null $uniqueFieldValue = null): void
43
     protected function disableExistingRecord(int $companyId, Model $model, string|null $uniqueField = null, string|null $uniqueFieldValue = null): void
31
     {
44
     {
32
-        $query = $model::where('company_id', $companyId)
45
+        $query = $model::query()->where('company_id', $companyId)
33
             ->where('enabled', true);
46
             ->where('enabled', true);
34
 
47
 
35
         if($uniqueField && $uniqueFieldValue){
48
         if($uniqueField && $uniqueFieldValue){
46
 
59
 
47
     protected function ensureAtLeastOneEnabled(int $companyId, Model $model, bool &$enabled, string|null $uniqueField = null, string|null $uniqueFieldValue = null): void
60
     protected function ensureAtLeastOneEnabled(int $companyId, Model $model, bool &$enabled, string|null $uniqueField = null, string|null $uniqueFieldValue = null): void
48
     {
61
     {
49
-        $query = $model::where('company_id', $companyId)
62
+        $query = $model::query()->where('company_id', $companyId)
50
             ->where('enabled', true);
63
             ->where('enabled', true);
51
 
64
 
52
         if($uniqueField && $uniqueFieldValue){
65
         if($uniqueField && $uniqueFieldValue){
53
             $query->where($uniqueField, $uniqueFieldValue);
66
             $query->where($uniqueField, $uniqueFieldValue);
54
         }
67
         }
55
 
68
 
56
-        $otherEnabledRecords = $query->count();
69
+        $otherEnabledRecord = $query->first();
57
 
70
 
58
-        if ($otherEnabledRecords === 0) {
71
+        if ($otherEnabledRecord === null) {
59
             $enabled = true;
72
             $enabled = true;
60
         }
73
         }
61
     }
74
     }

+ 53
- 46
app/Traits/HandlesResourceRecordUpdate.php Прегледај датотеку

2
 
2
 
3
 namespace App\Traits;
3
 namespace App\Traits;
4
 
4
 
5
+use App\Models\User;
6
+use Filament\Support\Exceptions\Halt;
7
+use Illuminate\Auth\Access\AuthorizationException;
8
+use Illuminate\Database\Eloquent\Builder;
5
 use Illuminate\Database\Eloquent\Model;
9
 use Illuminate\Database\Eloquent\Model;
6
-use Illuminate\Support\Facades\Auth;
7
 use Illuminate\Support\Facades\DB;
10
 use Illuminate\Support\Facades\DB;
11
+use Illuminate\Validation\ValidationException;
12
+use Throwable;
8
 
13
 
9
 trait HandlesResourceRecordUpdate
14
 trait HandlesResourceRecordUpdate
10
 {
15
 {
11
-    protected function handleRecordUpdateWithUniqueField(Model $record, array $data, string|null $uniqueField = null): Model
16
+    /**
17
+     * @throws Halt
18
+     */
19
+    protected function handleRecordUpdateWithUniqueField(Model $record, array $data, User $user, string|null $uniqueField = null): Model
12
     {
20
     {
13
-        return DB::transaction(function () use ($uniqueField, $record, $data) {
14
-            $companyId = Auth::user()->currentCompany->id;
15
-            $oldValue = $uniqueField ? $record->{$uniqueField} : null;
16
-            $newValue = $uniqueField ? $data[$uniqueField] : null;
17
-            $enabled = (bool)($data['enabled'] ?? false);
18
-
19
-            if ($oldValue !== $newValue && $record->enabled) {
20
-                $this->enableAnotherOfSameValue($companyId, $record, $uniqueField, $oldValue);
21
-            }
22
-
23
-            if ($enabled === true) {
24
-                $this->disableOthersOfSameValue($companyId, $record, $uniqueField, $newValue);
25
-            } elseif ($enabled === false) {
26
-                $this->ensureAtLeastOneEnabled($companyId, $record, $uniqueField, $newValue, $enabled);
27
-            }
28
-
29
-            $data['enabled'] = $enabled;
30
-
31
-            return tap($record)->update($data);
32
-        });
21
+        try {
22
+            return DB::transaction(function () use ($user, $uniqueField, $record, $data) {
23
+                $companyId = $user->currentCompany->id;
24
+                $oldValue = $uniqueField ? $record->{$uniqueField} : null;
25
+                $newValue = $uniqueField ? $data[$uniqueField] : null;
26
+                $enabled = (bool)($data['enabled'] ?? false);
27
+
28
+                if ($oldValue !== $newValue && $record->enabled) {
29
+                    $this->toggleRecord($companyId, $record, $uniqueField, $oldValue, false, true);
30
+                }
31
+
32
+                if ($enabled === true) {
33
+                    $this->toggleRecord($companyId, $record, $uniqueField, $newValue, true, false);
34
+                } elseif ($enabled === false) {
35
+                    $this->ensureAtLeastOneEnabled($companyId, $record, $uniqueField, $newValue, $enabled);
36
+                }
37
+
38
+                $data['enabled'] = $enabled;
39
+
40
+                return tap($record)->update($data);
41
+            });
42
+        } catch (ValidationException) {
43
+            throw new Halt('Invalid data provided. Please check the form and try again.');
44
+        } catch (AuthorizationException) {
45
+            throw new Halt('You are not authorized to perform this action.');
46
+        } catch (Throwable) {
47
+            throw new Halt('An unexpected error occurred. Please try again.');
48
+        }
33
     }
49
     }
34
 
50
 
35
-    protected function enableAnotherOfSameValue(int $companyId, Model $record, ?string $uniqueField, $value): void
51
+    protected function toggleRecord(int $companyId, Model $record, ?string $uniqueField, $value, bool $enabled, bool $newStatus): void
36
     {
52
     {
37
-        $query = $record::where('company_id', $companyId)
38
-            ->where('id', '!=', $record->id)
39
-            ->where('enabled', false);
53
+        $query = $this->buildQuery($companyId, $record, $uniqueField, $value, $enabled);
40
 
54
 
41
-        if($uniqueField){
42
-            $query->where($uniqueField, $value);
43
-        }
44
-
45
-        $otherRecord = $query->first();
55
+        if ($newStatus) {
56
+            $otherRecord = $query->first();
46
 
57
 
47
-        if ($otherRecord) {
48
-            $otherRecord->enabled = true;
49
-            $otherRecord->save();
58
+            if ($otherRecord) {
59
+                $otherRecord->enabled = true;
60
+                $otherRecord->save();
61
+            }
62
+        } else {
63
+            $query->update(['enabled' => false]);
50
         }
64
         }
51
     }
65
     }
52
 
66
 
53
-    protected function disableOthersOfSameValue(int $companyId, Model $record, ?string $uniqueField, $value): void
67
+    protected function buildQuery(int $companyId, Model $record, ?string $uniqueField, $value, bool $enabled): Builder
54
     {
68
     {
55
-        $query = $record::where('company_id', $companyId)
69
+        $query = $record::query()->where('company_id', $companyId)
56
             ->where('id', '!=', $record->id)
70
             ->where('id', '!=', $record->id)
57
-            ->where('enabled', true);
71
+            ->where('enabled', $enabled);
58
 
72
 
59
         if($uniqueField){
73
         if($uniqueField){
60
             $query->where($uniqueField, $value);
74
             $query->where($uniqueField, $value);
61
         }
75
         }
62
 
76
 
63
-        $query->update(['enabled' => false]);
77
+        return $query;
64
     }
78
     }
65
 
79
 
66
     protected function ensureAtLeastOneEnabled(int $companyId, Model $record, ?string $uniqueField, $value, bool &$enabled): void
80
     protected function ensureAtLeastOneEnabled(int $companyId, Model $record, ?string $uniqueField, $value, bool &$enabled): void
67
     {
81
     {
68
-        $query = $record::where('company_id', $companyId)
69
-            ->where('id', '!=', $record->id)
70
-            ->where('enabled', true);
71
-
72
-        if($uniqueField){
73
-            $query->where($uniqueField, $value);
74
-        }
75
-
82
+        $query = $this->buildQuery($companyId, $record, $uniqueField, $value, true);
76
         $enabledCount = $query->count();
83
         $enabledCount = $query->count();
77
 
84
 
78
         if ($enabledCount === 0) {
85
         if ($enabledCount === 0) {

+ 2
- 0
database/migrations/2023_05_22_000100_create_document_defaults_table.php Прегледај датотеку

25
             $table->text('notes')->nullable();
25
             $table->text('notes')->nullable();
26
             $table->text('terms')->nullable();
26
             $table->text('terms')->nullable();
27
             $table->string('footer')->nullable();
27
             $table->string('footer')->nullable();
28
+            $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
29
+            $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
28
             $table->timestamps();
30
             $table->timestamps();
29
         });
31
         });
30
     }
32
     }

+ 1
- 0
database/migrations/2023_07_03_054805_create_default_settings_table.php Прегледај датотеку

22
             $table->foreignId('purchase_discount_id')->nullable()->constrained('discounts')->nullOnDelete();
22
             $table->foreignId('purchase_discount_id')->nullable()->constrained('discounts')->nullOnDelete();
23
             $table->foreignId('income_category_id')->nullable()->constrained('categories')->nullOnDelete();
23
             $table->foreignId('income_category_id')->nullable()->constrained('categories')->nullOnDelete();
24
             $table->foreignId('expense_category_id')->nullable()->constrained('categories')->nullOnDelete();
24
             $table->foreignId('expense_category_id')->nullable()->constrained('categories')->nullOnDelete();
25
+            $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
25
             $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
26
             $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
26
             $table->timestamps();
27
             $table->timestamps();
27
 
28
 

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