Bladeren bron

wip: Accounting Module

3.x
Andrew Wallo 2 jaren geleden
bovenliggende
commit
08c0aa1662

+ 2
- 0
app/Filament/Resources/AccountResource.php Bestand weergeven

@@ -2,6 +2,8 @@
2 2
 
3 3
 namespace App\Filament\Resources;
4 4
 
5
+use Akaunting\Money\Currency;
6
+use Akaunting\Money\Money;
5 7
 use App\Actions\Banking\CreateCurrencyFromAccount;
6 8
 use App\Filament\Resources\AccountResource\Pages;
7 9
 use App\Filament\Resources\AccountResource\RelationManagers;

+ 5
- 53
app/Filament/Resources/AccountResource/Pages/CreateAccount.php Bestand weergeven

@@ -4,20 +4,20 @@ namespace App\Filament\Resources\AccountResource\Pages;
4 4
 
5 5
 use App\Filament\Resources\AccountResource;
6 6
 use App\Models\Banking\Account;
7
-use Filament\Notifications\Notification;
8
-use Filament\Pages\Actions;
7
+use App\Traits\HandlesResourceRecordCreation;
9 8
 use Filament\Resources\Pages\CreateRecord;
10 9
 use Illuminate\Database\Eloquent\Model;
11 10
 use Illuminate\Support\Facades\Auth;
12
-use Illuminate\Support\Facades\DB;
13 11
 
14 12
 class CreateAccount extends CreateRecord
15 13
 {
14
+    use  HandlesResourceRecordCreation;
15
+
16 16
     protected static string $resource = AccountResource::class;
17 17
 
18 18
     protected function getRedirectUrl(): string
19 19
     {
20
-        return self::getResource()::getUrl('index');
20
+        return $this->previousUrl;
21 21
     }
22 22
 
23 23
     protected function mutateFormDataBeforeCreate(array $data): array
@@ -31,54 +31,6 @@ class CreateAccount extends CreateRecord
31 31
 
32 32
     protected function handleRecordCreation(array $data): Model
33 33
     {
34
-        return DB::transaction(function () use ($data) {
35
-            $currentCompanyId = auth()->user()->currentCompany->id;
36
-
37
-            $enabled = (bool)($data['enabled'] ?? false); // Ensure $enabled is always a boolean
38
-
39
-            if ($enabled === true) {
40
-                $this->disableExistingRecord($currentCompanyId);
41
-            } else {
42
-                $this->ensureAtLeastOneEnabled($currentCompanyId, $enabled);
43
-            }
44
-
45
-            $data['enabled'] = $enabled;
46
-
47
-            return parent::handleRecordCreation($data);
48
-        });
49
-    }
50
-
51
-    protected function disableExistingRecord($companyId): void
52
-    {
53
-        $existingEnabledRecord = Account::where('company_id', $companyId)
54
-            ->where('enabled', true)
55
-            ->first();
56
-
57
-        if ($existingEnabledRecord !== null) {
58
-            $existingEnabledRecord->enabled = false;
59
-            $existingEnabledRecord->save();
60
-            $this->defaultAccountChanged();
61
-        }
62
-    }
63
-
64
-    protected function ensureAtLeastOneEnabled($companyId, &$enabled): void
65
-    {
66
-        $enabledAccountsCount = Account::where('company_id', $companyId)
67
-            ->where('enabled', true)
68
-            ->count();
69
-
70
-        if ($enabledAccountsCount === 0) {
71
-            $enabled = true;
72
-        }
73
-    }
74
-
75
-    protected function defaultAccountChanged(): void
76
-    {
77
-        Notification::make()
78
-            ->warning()
79
-            ->title('Default account updated')
80
-            ->body('Your default account has been updated. Please check your account settings to review this change and ensure it is correct.')
81
-            ->persistent()
82
-            ->send();
34
+        return $this->handleRecordCreationWithUniqueField($data, new Account());
83 35
     }
84 36
 }

+ 5
- 43
app/Filament/Resources/CategoryResource/Pages/CreateCategory.php Bestand weergeven

@@ -4,19 +4,20 @@ namespace App\Filament\Resources\CategoryResource\Pages;
4 4
 
5 5
 use App\Filament\Resources\CategoryResource;
6 6
 use App\Models\Setting\Category;
7
-use Filament\Pages\Actions;
7
+use App\Traits\HandlesResourceRecordCreation;
8 8
 use Filament\Resources\Pages\CreateRecord;
9 9
 use Illuminate\Database\Eloquent\Model;
10 10
 use Illuminate\Support\Facades\Auth;
11
-use Illuminate\Support\Facades\DB;
12 11
 
13 12
 class CreateCategory extends CreateRecord
14 13
 {
14
+    use HandlesResourceRecordCreation;
15
+
15 16
     protected static string $resource = CategoryResource::class;
16 17
 
17 18
     protected function getRedirectUrl(): string
18 19
     {
19
-        return $this->getResource()::getUrl('index');
20
+        return $this->previousUrl;
20 21
     }
21 22
 
22 23
     protected function mutateFormDataBeforeCreate(array $data): array
@@ -30,45 +31,6 @@ class CreateCategory extends CreateRecord
30 31
 
31 32
     protected function handleRecordCreation(array $data): Model
32 33
     {
33
-        return DB::transaction(function () use ($data) {
34
-            $currentCompanyId = auth()->user()->currentCompany->id;
35
-            $type = $data['type'] ?? null;
36
-            $enabled = (bool)($data['enabled'] ?? false);
37
-
38
-            if ($enabled === true) {
39
-                $this->disableExistingRecord($currentCompanyId, $type);
40
-            } else {
41
-                $this->ensureAtLeastOneEnabled($currentCompanyId, $type, $enabled);
42
-            }
43
-
44
-            $data['enabled'] = $enabled;
45
-
46
-            return parent::handleRecordCreation($data);
47
-        });
48
-    }
49
-
50
-    protected function disableExistingRecord(int $companyId, string $type): void
51
-    {
52
-        $existingEnabledRecord = Category::where('company_id', $companyId)
53
-            ->where('enabled', true)
54
-            ->where('type', $type)
55
-            ->first();
56
-
57
-        if ($existingEnabledRecord !== null) {
58
-            $existingEnabledRecord->enabled = false;
59
-            $existingEnabledRecord->save();
60
-        }
61
-    }
62
-
63
-    protected function ensureAtLeastOneEnabled(int $companyId, string $type, bool &$enabled): void
64
-    {
65
-        $otherEnabledRecords = Category::where('company_id', $companyId)
66
-            ->where('enabled', true)
67
-            ->where('type', $type)
68
-            ->count();
69
-
70
-        if ($otherEnabledRecords === 0) {
71
-            $enabled = true;
72
-        }
34
+        return $this->handleRecordCreationWithUniqueField($data, new Category(), 'type');
73 35
     }
74 36
 }

+ 5
- 39
app/Filament/Resources/CurrencyResource/Pages/CreateCurrency.php Bestand weergeven

@@ -4,6 +4,7 @@ namespace App\Filament\Resources\CurrencyResource\Pages;
4 4
 
5 5
 use App\Filament\Resources\CurrencyResource;
6 6
 use App\Models\Setting\Currency;
7
+use App\Traits\HandlesResourceRecordCreation;
7 8
 use Filament\Pages\Actions;
8 9
 use Filament\Resources\Pages\CreateRecord;
9 10
 use Illuminate\Database\Eloquent\Model;
@@ -12,11 +13,13 @@ use Illuminate\Support\Facades\DB;
12 13
 
13 14
 class CreateCurrency extends CreateRecord
14 15
 {
16
+    use HandlesResourceRecordCreation;
17
+
15 18
     protected static string $resource = CurrencyResource::class;
16 19
 
17 20
     protected function getRedirectUrl(): string
18 21
     {
19
-        return $this->getResource()::getUrl('index');
22
+        return $this->previousUrl;
20 23
     }
21 24
 
22 25
     protected function mutateFormDataBeforeCreate(array $data): array
@@ -30,43 +33,6 @@ class CreateCurrency extends CreateRecord
30 33
 
31 34
     protected function handleRecordCreation(array $data): Model
32 35
     {
33
-        return DB::transaction(function () use ($data) {
34
-            $currentCompanyId = auth()->user()->currentCompany->id;
35
-
36
-            $enabled = (bool)($data['enabled'] ?? false); // Ensure $enabled is always a boolean
37
-
38
-            if ($enabled === true) {
39
-                $this->disableExistingRecord($currentCompanyId);
40
-            } else {
41
-                $this->ensureAtLeastOneEnabled($currentCompanyId, $enabled);
42
-            }
43
-
44
-            $data['enabled'] = $enabled;
45
-
46
-            return parent::handleRecordCreation($data);
47
-        });
48
-    }
49
-
50
-    protected function disableExistingRecord($companyId): void
51
-    {
52
-        $existingEnabledRecord = Currency::where('company_id', $companyId)
53
-            ->where('enabled', true)
54
-            ->first();
55
-
56
-        if ($existingEnabledRecord !== null) {
57
-            $existingEnabledRecord->enabled = false;
58
-            $existingEnabledRecord->save();
59
-        }
60
-    }
61
-
62
-    protected function ensureAtLeastOneEnabled($companyId, &$enabled): void
63
-    {
64
-        $enabledAccountsCount = Currency::where('company_id', $companyId)
65
-            ->where('enabled', true)
66
-            ->count();
67
-
68
-        if ($enabledAccountsCount === 0) {
69
-            $enabled = true;
70
-        }
36
+        return $this->handleRecordCreationWithUniqueField($data, new Currency());
71 37
     }
72 38
 }

+ 22
- 14
app/Filament/Resources/DiscountResource.php Bestand weergeven

@@ -53,15 +53,7 @@ class DiscountResource extends Resource
53 53
                             ->normalizeZeros()
54 54
                             ->padFractionalZeros()
55 55
                         )
56
-                        ->suffix(static function (callable $get) {
57
-                            $computation = $get('computation');
58
-
59
-                            if ($computation === 'percentage') {
60
-                                return '%';
61
-                            }
62
-
63
-                            return null;
64
-                        })
56
+                        ->suffix(static fn (callable $get) => $get('computation') === 'percentage' ? '%' : null)
65 57
                         ->default(0.0000)
66 58
                         ->required(),
67 59
                     Forms\Components\Select::make('type')
@@ -76,17 +68,33 @@ class DiscountResource extends Resource
76 68
                         ->searchable(),
77 69
                     Forms\Components\DateTimePicker::make('start_date')
78 70
                         ->label('Start Date')
79
-                        ->minDate(now())
80
-                        ->maxDate(now()->addYear())
71
+                        ->minDate(static function ($context, Discount|null $record = null) {
72
+                            if ($context === 'create') {
73
+                                return today()->addDay();
74
+                            }
75
+
76
+                            return $record?->start_date->isFuture() ? today()->addDay() : $record?->start_date;
77
+                        })
78
+                        ->maxDate(static function (callable $get, Discount|null $record = null) {
79
+                            $end_date = $get('end_date') ?? $record?->end_date;
80
+
81
+                            return $end_date ?: today()->addYear();
82
+                        })
81 83
                         ->format('Y-m-d H:i:s')
82 84
                         ->displayFormat('F d, Y H:i')
83 85
                         ->withoutSeconds()
84
-                        ->disabled(static fn (Discount $record) => $record->start_date->isPast())
86
+                        ->reactive()
87
+                        ->disabled(static fn ($context, Discount|null $record = null) => $context === 'edit' && $record?->start_date->isPast())
85 88
                         ->helperText(static fn (Forms\Components\DateTimePicker $component) => $component->isDisabled() ? 'Start date cannot be changed after the discount has begun.' : null),
86 89
                     Forms\Components\DateTimePicker::make('end_date')
87 90
                         ->label('End Date')
88
-                        ->minDate(now())
89
-                        ->maxDate(now()->addYears(2))
91
+                        ->reactive()
92
+                        ->minDate(static function (callable $get, Discount|null $record = null) {
93
+                            $start_date = $get('start_date') ?? $record?->start_date;
94
+
95
+                            return $start_date ?: today()->addDay();
96
+                        })
97
+                        ->maxDate(today()->addYear())
90 98
                         ->format('Y-m-d H:i:s')
91 99
                         ->displayFormat('F d, Y H:i')
92 100
                         ->withoutSeconds(),

+ 25
- 1
app/Filament/Resources/DiscountResource/Pages/CreateDiscount.php Bestand weergeven

@@ -3,10 +3,34 @@
3 3
 namespace App\Filament\Resources\DiscountResource\Pages;
4 4
 
5 5
 use App\Filament\Resources\DiscountResource;
6
-use Filament\Pages\Actions;
6
+use App\Models\Setting\Discount;
7
+use App\Traits\HandlesResourceRecordCreation;
7 8
 use Filament\Resources\Pages\CreateRecord;
9
+use Illuminate\Database\Eloquent\Model;
10
+use Illuminate\Support\Facades\Auth;
8 11
 
9 12
 class CreateDiscount extends CreateRecord
10 13
 {
14
+    use HandlesResourceRecordCreation;
15
+
11 16
     protected static string $resource = DiscountResource::class;
17
+
18
+    protected function getRedirectUrl(): string
19
+    {
20
+        return $this->previousUrl;
21
+    }
22
+
23
+    protected function mutateFormDataBeforeCreate(array $data): array
24
+    {
25
+        $data['company_id'] = Auth::user()->currentCompany->id;
26
+        $data['enabled'] = (bool)($data['enabled']);
27
+        $data['created_by'] = Auth::id();
28
+
29
+        return $data;
30
+    }
31
+
32
+    protected function handleRecordCreation(array $data): Model
33
+    {
34
+        return $this->handleRecordCreationWithUniqueField($data, new Discount(), 'type');
35
+    }
12 36
 }

+ 5
- 43
app/Filament/Resources/TaxResource/Pages/CreateTax.php Bestand weergeven

@@ -4,19 +4,20 @@ namespace App\Filament\Resources\TaxResource\Pages;
4 4
 
5 5
 use App\Filament\Resources\TaxResource;
6 6
 use App\Models\Setting\Tax;
7
-use Filament\Pages\Actions;
7
+use App\Traits\HandlesResourceRecordCreation;
8 8
 use Filament\Resources\Pages\CreateRecord;
9 9
 use Illuminate\Database\Eloquent\Model;
10 10
 use Illuminate\Support\Facades\Auth;
11
-use Illuminate\Support\Facades\DB;
12 11
 
13 12
 class CreateTax extends CreateRecord
14 13
 {
14
+    use HandlesResourceRecordCreation;
15
+
15 16
     protected static string $resource = TaxResource::class;
16 17
 
17 18
     protected function getRedirectUrl(): string
18 19
     {
19
-        return $this->getResource()::getUrl('index');
20
+        return $this->previousUrl;
20 21
     }
21 22
 
22 23
     protected function mutateFormDataBeforeCreate(array $data): array
@@ -30,45 +31,6 @@ class CreateTax extends CreateRecord
30 31
 
31 32
     protected function handleRecordCreation(array $data): Model
32 33
     {
33
-        return DB::transaction(function () use ($data) {
34
-            $currentCompanyId = auth()->user()->currentCompany->id;
35
-            $type = $data['type'] ?? null;
36
-            $enabled = (bool)($data['enabled'] ?? false);
37
-
38
-            if ($enabled === true) {
39
-                $this->disableExistingRecord($currentCompanyId, $type);
40
-            } else {
41
-                $this->ensureAtLeastOneEnabled($currentCompanyId, $type, $enabled);
42
-            }
43
-
44
-            $data['enabled'] = $enabled;
45
-
46
-            return parent::handleRecordCreation($data);
47
-        });
48
-    }
49
-
50
-    protected function disableExistingRecord(int $companyId, string $type): void
51
-    {
52
-        $existingEnabledRecord = Tax::where('company_id', $companyId)
53
-            ->where('enabled', true)
54
-            ->where('type', $type)
55
-            ->first();
56
-
57
-        if ($existingEnabledRecord !== null) {
58
-            $existingEnabledRecord->enabled = false;
59
-            $existingEnabledRecord->save();
60
-        }
61
-    }
62
-
63
-    protected function ensureAtLeastOneEnabled(int $companyId, string $type, bool &$enabled): void
64
-    {
65
-        $otherEnabledRecords = Tax::where('company_id', $companyId)
66
-            ->where('enabled', true)
67
-            ->where('type', $type)
68
-            ->count();
69
-
70
-        if ($otherEnabledRecords === 0) {
71
-            $enabled = true;
72
-        }
34
+        return $this->handleRecordCreationWithUniqueField($data, new Tax(), 'type');
73 35
     }
74 36
 }

+ 2
- 2
app/Http/Livewire/DefaultSetting.php Bestand weergeven

@@ -7,7 +7,7 @@ use App\Models\Setting\Category;
7 7
 use App\Models\Setting\Currency;
8 8
 use App\Models\Setting\DefaultSetting as Defaults;
9 9
 use App\Models\Setting\Tax;
10
-use App\Traits\HandlesRecordCreation;
10
+use App\Traits\HandlesDefaultSettingRecordCreation;
11 11
 use Filament\Forms\ComponentContainer;
12 12
 use Filament\Forms\Components\Section;
13 13
 use Filament\Forms\Components\Select;
@@ -23,7 +23,7 @@ use Livewire\Component;
23 23
  */
24 24
 class DefaultSetting extends Component implements HasForms
25 25
 {
26
-    use InteractsWithForms, HandlesRecordCreation;
26
+    use InteractsWithForms, HandlesDefaultSettingRecordCreation;
27 27
 
28 28
     public Defaults $defaultSetting;
29 29
 

+ 6
- 0
app/Models/Setting/Discount.php Bestand weergeven

@@ -20,6 +20,7 @@ class Discount extends Model
20 20
     protected $table = 'discounts';
21 21
 
22 22
     protected $fillable = [
23
+        'company_id',
23 24
         'name',
24 25
         'description',
25 26
         'rate',
@@ -39,6 +40,11 @@ class Discount extends Model
39 40
         'end_date' => 'datetime',
40 41
     ];
41 42
 
43
+    public function company(): BelongsTo
44
+    {
45
+        return $this->belongsTo(FilamentCompanies::companyModel(), 'company_id');
46
+    }
47
+
42 48
     public function createdBy(): BelongsTo
43 49
     {
44 50
         return $this->belongsTo(FilamentCompanies::userModel(), 'created_by');

app/Traits/HandlesRecordCreation.php → app/Traits/HandlesDefaultSettingRecordCreation.php Bestand weergeven

@@ -5,7 +5,7 @@ namespace App\Traits;
5 5
 use Illuminate\Database\Eloquent\Model;
6 6
 use Illuminate\Support\Facades\Auth;
7 7
 
8
-trait HandlesRecordCreation
8
+trait HandlesDefaultSettingRecordCreation
9 9
 {
10 10
     abstract protected function getRelatedEntities(): array;
11 11
     abstract protected function getFormModel(): string;

+ 62
- 0
app/Traits/HandlesResourceRecordCreation.php Bestand weergeven

@@ -0,0 +1,62 @@
1
+<?php
2
+
3
+namespace App\Traits;
4
+
5
+use Illuminate\Database\Eloquent\Model;
6
+use Illuminate\Support\Facades\Auth;
7
+use Illuminate\Support\Facades\DB;
8
+
9
+trait HandlesResourceRecordCreation
10
+{
11
+    protected function handleRecordCreationWithUniqueField(array $data, Model $model, string|null $uniqueField = null): Model
12
+    {
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);
17
+
18
+            if ($enabled === true) {
19
+                $this->disableExistingRecord($currentCompanyId, $model, $uniqueField, $uniqueFieldValue);
20
+            } else {
21
+                $this->ensureAtLeastOneEnabled($currentCompanyId, $model, $enabled, $uniqueField, $uniqueFieldValue);
22
+            }
23
+
24
+            $data['enabled'] = $enabled;
25
+
26
+            return $model::create($data);
27
+        });
28
+    }
29
+
30
+    protected function disableExistingRecord(int $companyId, Model $model, string|null $uniqueField = null, string|null $uniqueFieldValue = null): void
31
+    {
32
+        $query = $model::where('company_id', $companyId)
33
+            ->where('enabled', true);
34
+
35
+        if($uniqueField && $uniqueFieldValue){
36
+            $query->where($uniqueField, $uniqueFieldValue);
37
+        }
38
+
39
+        $existingEnabledRecord = $query->first();
40
+
41
+        if ($existingEnabledRecord !== null) {
42
+            $existingEnabledRecord->enabled = false;
43
+            $existingEnabledRecord->save();
44
+        }
45
+    }
46
+
47
+    protected function ensureAtLeastOneEnabled(int $companyId, Model $model, bool &$enabled, string|null $uniqueField = null, string|null $uniqueFieldValue = null): void
48
+    {
49
+        $query = $model::where('company_id', $companyId)
50
+            ->where('enabled', true);
51
+
52
+        if($uniqueField && $uniqueFieldValue){
53
+            $query->where($uniqueField, $uniqueFieldValue);
54
+        }
55
+
56
+        $otherEnabledRecords = $query->count();
57
+
58
+        if ($otherEnabledRecords === 0) {
59
+            $enabled = true;
60
+        }
61
+    }
62
+}

+ 6
- 6
composer.lock Bestand weergeven

@@ -10495,16 +10495,16 @@
10495 10495
         },
10496 10496
         {
10497 10497
             "name": "spatie/flare-client-php",
10498
-            "version": "1.4.0",
10498
+            "version": "1.4.1",
10499 10499
             "source": {
10500 10500
                 "type": "git",
10501 10501
                 "url": "https://github.com/spatie/flare-client-php.git",
10502
-                "reference": "82138174d5fe2829a7f085a6bdb2a06f6def9f7a"
10502
+                "reference": "943894c6a6b00501365ac0b91ae0dce56f2226fa"
10503 10503
             },
10504 10504
             "dist": {
10505 10505
                 "type": "zip",
10506
-                "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/82138174d5fe2829a7f085a6bdb2a06f6def9f7a",
10507
-                "reference": "82138174d5fe2829a7f085a6bdb2a06f6def9f7a",
10506
+                "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/943894c6a6b00501365ac0b91ae0dce56f2226fa",
10507
+                "reference": "943894c6a6b00501365ac0b91ae0dce56f2226fa",
10508 10508
                 "shasum": ""
10509 10509
             },
10510 10510
             "require": {
@@ -10553,7 +10553,7 @@
10553 10553
             ],
10554 10554
             "support": {
10555 10555
                 "issues": "https://github.com/spatie/flare-client-php/issues",
10556
-                "source": "https://github.com/spatie/flare-client-php/tree/1.4.0"
10556
+                "source": "https://github.com/spatie/flare-client-php/tree/1.4.1"
10557 10557
             },
10558 10558
             "funding": [
10559 10559
                 {
@@ -10561,7 +10561,7 @@
10561 10561
                     "type": "github"
10562 10562
                 }
10563 10563
             ],
10564
-            "time": "2023-06-28T11:08:09+00:00"
10564
+            "time": "2023-07-06T09:29:49+00:00"
10565 10565
         },
10566 10566
         {
10567 10567
             "name": "spatie/ignition",

+ 1
- 1
database/migrations/2023_05_11_044321_create_accounts_table.php Bestand weergeven

@@ -18,7 +18,7 @@ return new class extends Migration
18 18
             $table->string('name', 100)->index();
19 19
             $table->string('number', 20);
20 20
             $table->string('currency_code')->default('USD');
21
-            $table->decimal('opening_balance', 15, 4)->default(0.0000);
21
+            $table->double('opening_balance', 15, 4)->default(0.00);
22 22
             $table->string('description')->nullable();
23 23
             $table->text('notes')->nullable();
24 24
             $table->string('status')->default('open');

Laden…
Annuleren
Opslaan