Andrew Wallo 1 vuosi sitten
vanhempi
commit
c697fc2fe0
44 muutettua tiedostoa jossa 924 lisäystä ja 604 poistoa
  1. 13
    0
      app/Enums/Accounting/AdjustmentCategory.php
  2. 13
    0
      app/Enums/Accounting/AdjustmentType.php
  3. 16
    0
      app/Enums/Common/OfferingType.php
  4. 130
    0
      app/Filament/Company/Clusters/Settings/Resources/AdjustmentResource.php
  5. 11
    0
      app/Filament/Company/Clusters/Settings/Resources/AdjustmentResource/Pages/CreateAdjustment.php
  6. 18
    0
      app/Filament/Company/Clusters/Settings/Resources/AdjustmentResource/Pages/EditAdjustment.php
  7. 4
    4
      app/Filament/Company/Clusters/Settings/Resources/AdjustmentResource/Pages/ListAdjustments.php
  8. 0
    189
      app/Filament/Company/Clusters/Settings/Resources/DiscountResource.php
  9. 0
    16
      app/Filament/Company/Clusters/Settings/Resources/DiscountResource/Pages/CreateDiscount.php
  10. 0
    24
      app/Filament/Company/Clusters/Settings/Resources/DiscountResource/Pages/EditDiscount.php
  11. 0
    25
      app/Filament/Company/Clusters/Settings/Resources/DiscountResource/Pages/ListDiscounts.php
  12. 0
    158
      app/Filament/Company/Clusters/Settings/Resources/TaxResource.php
  13. 0
    16
      app/Filament/Company/Clusters/Settings/Resources/TaxResource/Pages/CreateTax.php
  14. 0
    24
      app/Filament/Company/Clusters/Settings/Resources/TaxResource/Pages/EditTax.php
  15. 2
    0
      app/Filament/Company/Pages/Accounting/AccountChart.php
  16. 131
    0
      app/Filament/Company/Resources/Common/OfferingResource.php
  17. 11
    0
      app/Filament/Company/Resources/Common/OfferingResource/Pages/CreateOffering.php
  18. 19
    0
      app/Filament/Company/Resources/Common/OfferingResource/Pages/EditOffering.php
  19. 19
    0
      app/Filament/Company/Resources/Common/OfferingResource/Pages/ListOfferings.php
  20. 50
    0
      app/Filament/Company/Resources/Purchases/BuyableOfferingResource.php
  21. 21
    0
      app/Filament/Company/Resources/Purchases/BuyableOfferingResource/Pages/CreateBuyableOffering.php
  22. 29
    0
      app/Filament/Company/Resources/Purchases/BuyableOfferingResource/Pages/EditBuyableOffering.php
  23. 25
    0
      app/Filament/Company/Resources/Purchases/BuyableOfferingResource/Pages/ListBuyableOfferings.php
  24. 50
    0
      app/Filament/Company/Resources/Sales/SellableOfferingResource.php
  25. 21
    0
      app/Filament/Company/Resources/Sales/SellableOfferingResource/Pages/CreateSellableOffering.php
  26. 29
    0
      app/Filament/Company/Resources/Sales/SellableOfferingResource/Pages/EditSellableOffering.php
  27. 25
    0
      app/Filament/Company/Resources/Sales/SellableOfferingResource/Pages/ListSellableOfferings.php
  28. 36
    7
      app/Models/Accounting/Adjustment.php
  29. 33
    8
      app/Models/Common/Offering.php
  30. 6
    0
      app/Models/Company.php
  31. 40
    0
      app/Observers/AdjustmentObserver.php
  32. 10
    0
      app/Providers/FilamentCompaniesServiceProvider.php
  33. 24
    14
      app/Services/ChartOfAccountsService.php
  34. 17
    17
      composer.lock
  35. 17
    13
      config/chart-of-accounts.php
  36. 1
    1
      database/factories/Accounting/AccountFactory.php
  37. 0
    1
      database/factories/Accounting/AdjustmentFactory.php
  38. 2
    0
      database/migrations/2024_11_13_214149_create_offerings_table.php
  39. 3
    1
      database/migrations/2024_11_14_230753_create_adjustments_table.php
  40. 2
    6
      database/migrations/2024_11_15_225714_create_adjustmentables_table.php
  41. 78
    78
      package-lock.json
  42. 9
    1
      resources/data/lang/en.json
  43. 8
    0
      resources/views/filament/company/components/tables/columns/offering-status.blade.php
  44. 1
    1
      resources/views/filament/company/pages/accounting/chart.blade.php

+ 13
- 0
app/Enums/Accounting/AdjustmentCategory.php Näytä tiedosto

@@ -2,10 +2,13 @@
2 2
 
3 3
 namespace App\Enums\Accounting;
4 4
 
5
+use App\Enums\Concerns\ParsesEnum;
5 6
 use Filament\Support\Contracts\HasLabel;
6 7
 
7 8
 enum AdjustmentCategory: string implements HasLabel
8 9
 {
10
+    use ParsesEnum;
11
+
9 12
     case Tax = 'tax';
10 13
     case Discount = 'discount';
11 14
 
@@ -13,4 +16,14 @@ enum AdjustmentCategory: string implements HasLabel
13 16
     {
14 17
         return $this->name;
15 18
     }
19
+
20
+    public function isTax(): bool
21
+    {
22
+        return $this === self::Tax;
23
+    }
24
+
25
+    public function isDiscount(): bool
26
+    {
27
+        return $this === self::Discount;
28
+    }
16 29
 }

+ 13
- 0
app/Enums/Accounting/AdjustmentType.php Näytä tiedosto

@@ -2,12 +2,15 @@
2 2
 
3 3
 namespace App\Enums\Accounting;
4 4
 
5
+use App\Enums\Concerns\ParsesEnum;
5 6
 use Filament\Support\Contracts\HasColor;
6 7
 use Filament\Support\Contracts\HasIcon;
7 8
 use Filament\Support\Contracts\HasLabel;
8 9
 
9 10
 enum AdjustmentType: string implements HasColor, HasIcon, HasLabel
10 11
 {
12
+    use ParsesEnum;
13
+
11 14
     case Sales = 'sales';
12 15
     case Purchase = 'purchase';
13 16
 
@@ -31,4 +34,14 @@ enum AdjustmentType: string implements HasColor, HasIcon, HasLabel
31 34
             self::Purchase => 'heroicon-o-shopping-bag',
32 35
         };
33 36
     }
37
+
38
+    public function isSales(): bool
39
+    {
40
+        return $this === self::Sales;
41
+    }
42
+
43
+    public function isPurchase(): bool
44
+    {
45
+        return $this === self::Purchase;
46
+    }
34 47
 }

+ 16
- 0
app/Enums/Common/OfferingType.php Näytä tiedosto

@@ -0,0 +1,16 @@
1
+<?php
2
+
3
+namespace App\Enums\Common;
4
+
5
+use Filament\Support\Contracts\HasLabel;
6
+
7
+enum OfferingType: string implements HasLabel
8
+{
9
+    case Product = 'product';
10
+    case Service = 'service';
11
+
12
+    public function getLabel(): string
13
+    {
14
+        return $this->name;
15
+    }
16
+}

+ 130
- 0
app/Filament/Company/Clusters/Settings/Resources/AdjustmentResource.php Näytä tiedosto

@@ -0,0 +1,130 @@
1
+<?php
2
+
3
+namespace App\Filament\Company\Clusters\Settings\Resources;
4
+
5
+use App\Enums\Accounting\AdjustmentCategory;
6
+use App\Enums\Accounting\AdjustmentComputation;
7
+use App\Enums\Accounting\AdjustmentScope;
8
+use App\Enums\Accounting\AdjustmentType;
9
+use App\Filament\Company\Clusters\Settings;
10
+use App\Filament\Company\Clusters\Settings\Resources\AdjustmentResource\Pages;
11
+use App\Models\Accounting\Adjustment;
12
+use Filament\Forms;
13
+use Filament\Forms\Form;
14
+use Filament\Resources\Resource;
15
+use Filament\Tables;
16
+use Filament\Tables\Table;
17
+use Wallo\FilamentSelectify\Components\ToggleButton;
18
+
19
+class AdjustmentResource extends Resource
20
+{
21
+    protected static ?string $model = Adjustment::class;
22
+
23
+    protected static ?string $cluster = Settings::class;
24
+
25
+    public static function form(Form $form): Form
26
+    {
27
+        return $form
28
+            ->schema([
29
+                Forms\Components\Section::make('General')
30
+                    ->schema([
31
+                        Forms\Components\TextInput::make('name')
32
+                            ->autofocus()
33
+                            ->required()
34
+                            ->maxLength(255),
35
+                        Forms\Components\Textarea::make('description')
36
+                            ->label('Description')
37
+                            ->autosize(),
38
+                    ]),
39
+                Forms\Components\Section::make('Configuration')
40
+                    ->schema([
41
+                        Forms\Components\Select::make('category')
42
+                            ->localizeLabel()
43
+                            ->options(AdjustmentCategory::class)
44
+                            ->default(AdjustmentCategory::Tax)
45
+                            ->live()
46
+                            ->required(),
47
+                        Forms\Components\Select::make('type')
48
+                            ->localizeLabel()
49
+                            ->options(AdjustmentType::class)
50
+                            ->default(AdjustmentType::Sales)
51
+                            ->live()
52
+                            ->required(),
53
+                        ToggleButton::make('recoverable')
54
+                            ->label('Recoverable')
55
+                            ->default(false)
56
+                            ->visible(fn (Forms\Get $get) => AdjustmentCategory::parse($get('category')) === AdjustmentCategory::Tax && AdjustmentType::parse($get('type')) === AdjustmentType::Purchase),
57
+                    ])
58
+                    ->columns()
59
+                    ->visibleOn('create'),
60
+                Forms\Components\Section::make('Adjustment Details')
61
+                    ->schema([
62
+                        Forms\Components\Select::make('computation')
63
+                            ->localizeLabel()
64
+                            ->options(AdjustmentComputation::class)
65
+                            ->default(AdjustmentComputation::Percentage)
66
+                            ->live()
67
+                            ->required(),
68
+                        Forms\Components\TextInput::make('rate')
69
+                            ->localizeLabel()
70
+                            ->rate(static fn (Forms\Get $get) => $get('computation'))
71
+                            ->required(),
72
+                        Forms\Components\Select::make('scope')
73
+                            ->localizeLabel()
74
+                            ->options(AdjustmentScope::class),
75
+                    ])
76
+                    ->columns(),
77
+                Forms\Components\Section::make('Dates')
78
+                    ->schema([
79
+                        Forms\Components\DateTimePicker::make('start_date'),
80
+                        Forms\Components\DateTimePicker::make('end_date'),
81
+                    ])
82
+                    ->columns()
83
+                    ->visible(fn (Forms\Get $get) => AdjustmentCategory::parse($get('category')) === AdjustmentCategory::Discount),
84
+            ]);
85
+    }
86
+
87
+    public static function table(Table $table): Table
88
+    {
89
+        return $table
90
+            ->columns([
91
+                Tables\Columns\TextColumn::make('name')
92
+                    ->label('Name')
93
+                    ->sortable(),
94
+                Tables\Columns\TextColumn::make('category')
95
+                    ->searchable(),
96
+                Tables\Columns\TextColumn::make('type')
97
+                    ->searchable(),
98
+                Tables\Columns\TextColumn::make('rate')
99
+                    ->localizeLabel()
100
+                    ->rate(static fn (Adjustment $record) => $record->computation->value)
101
+                    ->searchable()
102
+                    ->sortable(),
103
+            ])
104
+            ->filters([
105
+                //
106
+            ])
107
+            ->actions([
108
+                Tables\Actions\EditAction::make(),
109
+            ])
110
+            ->bulkActions([
111
+                //
112
+            ]);
113
+    }
114
+
115
+    public static function getRelations(): array
116
+    {
117
+        return [
118
+            //
119
+        ];
120
+    }
121
+
122
+    public static function getPages(): array
123
+    {
124
+        return [
125
+            'index' => Pages\ListAdjustments::route('/'),
126
+            'create' => Pages\CreateAdjustment::route('/create'),
127
+            'edit' => Pages\EditAdjustment::route('/{record}/edit'),
128
+        ];
129
+    }
130
+}

+ 11
- 0
app/Filament/Company/Clusters/Settings/Resources/AdjustmentResource/Pages/CreateAdjustment.php Näytä tiedosto

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

+ 18
- 0
app/Filament/Company/Clusters/Settings/Resources/AdjustmentResource/Pages/EditAdjustment.php Näytä tiedosto

@@ -0,0 +1,18 @@
1
+<?php
2
+
3
+namespace App\Filament\Company\Clusters\Settings\Resources\AdjustmentResource\Pages;
4
+
5
+use App\Filament\Company\Clusters\Settings\Resources\AdjustmentResource;
6
+use Filament\Resources\Pages\EditRecord;
7
+
8
+class EditAdjustment extends EditRecord
9
+{
10
+    protected static string $resource = AdjustmentResource::class;
11
+
12
+    protected function getHeaderActions(): array
13
+    {
14
+        return [
15
+            //
16
+        ];
17
+    }
18
+}

app/Filament/Company/Clusters/Settings/Resources/TaxResource/Pages/ListTaxes.php → app/Filament/Company/Clusters/Settings/Resources/AdjustmentResource/Pages/ListAdjustments.php Näytä tiedosto

@@ -1,15 +1,15 @@
1 1
 <?php
2 2
 
3
-namespace App\Filament\Company\Clusters\Settings\Resources\TaxResource\Pages;
3
+namespace App\Filament\Company\Clusters\Settings\Resources\AdjustmentResource\Pages;
4 4
 
5
-use App\Filament\Company\Clusters\Settings\Resources\TaxResource;
5
+use App\Filament\Company\Clusters\Settings\Resources\AdjustmentResource;
6 6
 use Filament\Actions;
7 7
 use Filament\Resources\Pages\ListRecords;
8 8
 use Filament\Support\Enums\MaxWidth;
9 9
 
10
-class ListTaxes extends ListRecords
10
+class ListAdjustments extends ListRecords
11 11
 {
12
-    protected static string $resource = TaxResource::class;
12
+    protected static string $resource = AdjustmentResource::class;
13 13
 
14 14
     protected function getHeaderActions(): array
15 15
     {

+ 0
- 189
app/Filament/Company/Clusters/Settings/Resources/DiscountResource.php Näytä tiedosto

@@ -1,189 +0,0 @@
1
-<?php
2
-
3
-namespace App\Filament\Company\Clusters\Settings\Resources;
4
-
5
-use App\Concerns\NotifiesOnDelete;
6
-use App\Enums\Setting\DateFormat;
7
-use App\Enums\Setting\DiscountComputation;
8
-use App\Enums\Setting\DiscountScope;
9
-use App\Enums\Setting\DiscountType;
10
-use App\Enums\Setting\TimeFormat;
11
-use App\Filament\Company\Clusters\Settings;
12
-use App\Filament\Company\Clusters\Settings\Resources\DiscountResource\Pages;
13
-use App\Models\Setting\Discount;
14
-use App\Models\Setting\Localization;
15
-use Closure;
16
-use Filament\Forms;
17
-use Filament\Forms\Form;
18
-use Filament\Resources\Resource;
19
-use Filament\Support\Enums\FontWeight;
20
-use Filament\Tables;
21
-use Filament\Tables\Table;
22
-use Wallo\FilamentSelectify\Components\ToggleButton;
23
-
24
-class DiscountResource extends Resource
25
-{
26
-    use NotifiesOnDelete;
27
-
28
-    protected static ?string $model = Discount::class;
29
-
30
-    protected static ?string $modelLabel = 'Discount';
31
-
32
-    protected static ?string $cluster = Settings::class;
33
-
34
-    public static function getModelLabel(): string
35
-    {
36
-        $modelLabel = static::$modelLabel;
37
-
38
-        return translate($modelLabel);
39
-    }
40
-
41
-    public static function form(Form $form): Form
42
-    {
43
-        return $form
44
-            ->schema([
45
-                Forms\Components\Section::make('General')
46
-                    ->schema([
47
-                        Forms\Components\TextInput::make('name')
48
-                            ->autofocus()
49
-                            ->required()
50
-                            ->localizeLabel()
51
-                            ->maxLength(255)
52
-                            ->rule(static function (Forms\Get $get, Forms\Components\Component $component): Closure {
53
-                                return static function (string $attribute, $value, Closure $fail) use ($component, $get) {
54
-                                    $existingDiscount = Discount::where('name', $value)
55
-                                        ->whereKeyNot($component->getRecord()?->getKey())
56
-                                        ->where('type', $get('type'))
57
-                                        ->first();
58
-
59
-                                    if ($existingDiscount) {
60
-                                        $message = translate('The :Type :record ":name" already exists.', [
61
-                                            'Type' => $existingDiscount->type->getLabel(),
62
-                                            'record' => strtolower(static::getModelLabel()),
63
-                                            'name' => $value,
64
-                                        ]);
65
-
66
-                                        $fail($message);
67
-                                    }
68
-                                };
69
-                            }),
70
-                        Forms\Components\TextInput::make('description')
71
-                            ->localizeLabel(),
72
-                        Forms\Components\Select::make('computation')
73
-                            ->localizeLabel()
74
-                            ->options(DiscountComputation::class)
75
-                            ->default(DiscountComputation::Percentage)
76
-                            ->live()
77
-                            ->required(),
78
-                        Forms\Components\TextInput::make('rate')
79
-                            ->localizeLabel()
80
-                            ->rate(static fn (Forms\Get $get) => $get('computation'))
81
-                            ->required(),
82
-                        Forms\Components\Select::make('type')
83
-                            ->localizeLabel()
84
-                            ->options(DiscountType::class)
85
-                            ->default(DiscountType::Sales)
86
-                            ->required(),
87
-                        Forms\Components\Select::make('scope')
88
-                            ->localizeLabel()
89
-                            ->options(DiscountScope::class)
90
-                            ->nullable(),
91
-                        Forms\Components\DateTimePicker::make('start_date')
92
-                            ->localizeLabel()
93
-                            ->beforeOrEqual('end_date')
94
-                            ->seconds(false)
95
-                            ->disabled(static fn (string $operation, ?Discount $record = null) => $operation === 'edit' && $record?->start_date?->isPast() ?? false)
96
-                            ->helperText(static fn (Forms\Components\DateTimePicker $component) => $component->isDisabled() ? 'Start date cannot be changed after the discount has begun.' : null),
97
-                        Forms\Components\DateTimePicker::make('end_date')
98
-                            ->localizeLabel()
99
-                            ->afterOrEqual('start_date')
100
-                            ->seconds(false),
101
-                        ToggleButton::make('enabled')
102
-                            ->localizeLabel('Default')
103
-                            ->onLabel(Discount::enabledLabel())
104
-                            ->offLabel(Discount::disabledLabel()),
105
-                    ])->columns(),
106
-            ]);
107
-    }
108
-
109
-    public static function table(Table $table): Table
110
-    {
111
-        return $table
112
-            ->columns([
113
-                Tables\Columns\TextColumn::make('name')
114
-                    ->localizeLabel()
115
-                    ->weight(FontWeight::Medium)
116
-                    ->icon(static fn (Discount $record) => $record->isEnabled() ? 'heroicon-o-lock-closed' : null)
117
-                    ->tooltip(static function (Discount $record) {
118
-                        if ($record->isDisabled()) {
119
-                            return null;
120
-                        }
121
-
122
-                        return translate('Default :Type :Record', [
123
-                            'Type' => $record->type->getLabel(),
124
-                            'Record' => static::getModelLabel(),
125
-                        ]);
126
-                    })
127
-                    ->iconPosition('after')
128
-                    ->searchable()
129
-                    ->sortable(),
130
-                Tables\Columns\TextColumn::make('rate')
131
-                    ->localizeLabel()
132
-                    ->rate(static fn (Discount $record) => $record->computation->value)
133
-                    ->searchable()
134
-                    ->sortable(),
135
-                Tables\Columns\TextColumn::make('type')
136
-                    ->localizeLabel()
137
-                    ->badge()
138
-                    ->searchable()
139
-                    ->sortable(),
140
-                Tables\Columns\TextColumn::make('start_date')
141
-                    ->localizeLabel()
142
-                    ->formatStateUsing(static function (Discount $record) {
143
-                        $dateFormat = Localization::firstOrFail()->date_format->value ?? DateFormat::DEFAULT;
144
-                        $timeFormat = Localization::firstOrFail()->time_format->value ?? TimeFormat::DEFAULT;
145
-
146
-                        return $record->start_date ? $record->start_date->format("{$dateFormat} {$timeFormat}") : 'N/A';
147
-                    })
148
-                    ->searchable()
149
-                    ->sortable(),
150
-                Tables\Columns\TextColumn::make('end_date')
151
-                    ->localizeLabel()
152
-                    ->formatStateUsing(static function (Discount $record) {
153
-                        $dateFormat = Localization::firstOrFail()->date_format->value ?? DateFormat::DEFAULT;
154
-                        $timeFormat = Localization::firstOrFail()->time_format->value ?? TimeFormat::DEFAULT;
155
-
156
-                        return $record->end_date ? $record->end_date->format("{$dateFormat} {$timeFormat}") : 'N/A';
157
-                    })
158
-                    ->color(static fn (Discount $record) => $record->end_date?->isPast() ? 'danger' : null)
159
-                    ->searchable()
160
-                    ->sortable(),
161
-            ])
162
-            ->filters([
163
-                //
164
-            ])
165
-            ->actions([
166
-                Tables\Actions\EditAction::make(),
167
-            ])
168
-            ->bulkActions([
169
-                Tables\Actions\BulkActionGroup::make([
170
-                    Tables\Actions\DeleteBulkAction::make(),
171
-                ]),
172
-            ])
173
-            ->checkIfRecordIsSelectableUsing(static function (Discount $record) {
174
-                return $record->isDisabled();
175
-            })
176
-            ->emptyStateActions([
177
-                Tables\Actions\CreateAction::make(),
178
-            ]);
179
-    }
180
-
181
-    public static function getPages(): array
182
-    {
183
-        return [
184
-            'index' => Pages\ListDiscounts::route('/'),
185
-            'create' => Pages\CreateDiscount::route('/create'),
186
-            'edit' => Pages\EditDiscount::route('/{record}/edit'),
187
-        ];
188
-    }
189
-}

+ 0
- 16
app/Filament/Company/Clusters/Settings/Resources/DiscountResource/Pages/CreateDiscount.php Näytä tiedosto

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

+ 0
- 24
app/Filament/Company/Clusters/Settings/Resources/DiscountResource/Pages/EditDiscount.php Näytä tiedosto

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

+ 0
- 25
app/Filament/Company/Clusters/Settings/Resources/DiscountResource/Pages/ListDiscounts.php Näytä tiedosto

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

+ 0
- 158
app/Filament/Company/Clusters/Settings/Resources/TaxResource.php Näytä tiedosto

@@ -1,158 +0,0 @@
1
-<?php
2
-
3
-namespace App\Filament\Company\Clusters\Settings\Resources;
4
-
5
-use App\Concerns\NotifiesOnDelete;
6
-use App\Enums\Setting\TaxComputation;
7
-use App\Enums\Setting\TaxScope;
8
-use App\Enums\Setting\TaxType;
9
-use App\Filament\Company\Clusters\Settings;
10
-use App\Filament\Company\Clusters\Settings\Resources\TaxResource\Pages;
11
-use App\Models\Setting\Tax;
12
-use Closure;
13
-use Filament\Forms;
14
-use Filament\Forms\Form;
15
-use Filament\Resources\Resource;
16
-use Filament\Support\Enums\FontWeight;
17
-use Filament\Tables;
18
-use Filament\Tables\Table;
19
-use Wallo\FilamentSelectify\Components\ToggleButton;
20
-
21
-class TaxResource extends Resource
22
-{
23
-    use NotifiesOnDelete;
24
-
25
-    protected static ?string $model = Tax::class;
26
-
27
-    protected static ?string $modelLabel = 'Tax';
28
-
29
-    protected static ?string $cluster = Settings::class;
30
-
31
-    public static function getModelLabel(): string
32
-    {
33
-        $modelLabel = static::$modelLabel;
34
-
35
-        return translate($modelLabel);
36
-    }
37
-
38
-    public static function form(Form $form): Form
39
-    {
40
-        return $form
41
-            ->schema([
42
-                Forms\Components\Section::make('General')
43
-                    ->schema([
44
-                        Forms\Components\TextInput::make('name')
45
-                            ->autofocus()
46
-                            ->required()
47
-                            ->localizeLabel()
48
-                            ->maxLength(255)
49
-                            ->rule(static function (Forms\Get $get, Forms\Components\Component $component): Closure {
50
-                                return static function (string $attribute, $value, Closure $fail) use ($component, $get) {
51
-                                    $existingTax = Tax::where('name', $value)
52
-                                        ->whereKeyNot($component->getRecord()?->getKey())
53
-                                        ->where('type', $get('type'))
54
-                                        ->first();
55
-
56
-                                    if ($existingTax) {
57
-                                        $message = translate('The :Type :record ":name" already exists.', [
58
-                                            'Type' => $existingTax->type->getLabel(),
59
-                                            'record' => strtolower(static::getModelLabel()),
60
-                                            'name' => $value,
61
-                                        ]);
62
-
63
-                                        $fail($message);
64
-                                    }
65
-                                };
66
-                            }),
67
-                        Forms\Components\TextInput::make('description'),
68
-                        Forms\Components\Select::make('computation')
69
-                            ->localizeLabel()
70
-                            ->options(TaxComputation::class)
71
-                            ->default(TaxComputation::Percentage)
72
-                            ->live()
73
-                            ->required(),
74
-                        Forms\Components\TextInput::make('rate')
75
-                            ->localizeLabel()
76
-                            ->rate(static fn (Forms\Get $get) => $get('computation'))
77
-                            ->required(),
78
-                        Forms\Components\Select::make('type')
79
-                            ->localizeLabel()
80
-                            ->options(TaxType::class)
81
-                            ->default(TaxType::Sales)
82
-                            ->required(),
83
-                        Forms\Components\Select::make('scope')
84
-                            ->localizeLabel()
85
-                            ->options(TaxScope::class),
86
-                        ToggleButton::make('enabled')
87
-                            ->localizeLabel('Default')
88
-                            ->onLabel(Tax::enabledLabel())
89
-                            ->offLabel(Tax::disabledLabel()),
90
-                    ])->columns(),
91
-            ]);
92
-    }
93
-
94
-    public static function table(Table $table): Table
95
-    {
96
-        return $table
97
-            ->columns([
98
-                Tables\Columns\TextColumn::make('name')
99
-                    ->localizeLabel()
100
-                    ->weight(FontWeight::Medium)
101
-                    ->icon(static fn (Tax $record) => $record->isEnabled() ? 'heroicon-o-lock-closed' : null)
102
-                    ->tooltip(static function (Tax $record) {
103
-                        if ($record->isDisabled()) {
104
-                            return null;
105
-                        }
106
-
107
-                        return translate('Default :Type :Record', [
108
-                            'Type' => $record->type->getLabel(),
109
-                            'Record' => static::getModelLabel(),
110
-                        ]);
111
-                    })
112
-                    ->iconPosition('after')
113
-                    ->searchable()
114
-                    ->sortable(),
115
-                Tables\Columns\TextColumn::make('computation')
116
-                    ->localizeLabel()
117
-                    ->searchable()
118
-                    ->sortable(),
119
-                Tables\Columns\TextColumn::make('rate')
120
-                    ->localizeLabel()
121
-                    ->rate(static fn (Tax $record) => $record->computation->value)
122
-                    ->searchable()
123
-                    ->sortable(),
124
-                Tables\Columns\TextColumn::make('type')
125
-                    ->localizeLabel()
126
-                    ->badge()
127
-                    ->searchable()
128
-                    ->sortable(),
129
-            ])
130
-            ->filters([
131
-                //
132
-            ])
133
-            ->actions([
134
-                Tables\Actions\EditAction::make(),
135
-                Tables\Actions\DeleteAction::make(),
136
-            ])
137
-            ->bulkActions([
138
-                Tables\Actions\BulkActionGroup::make([
139
-                    Tables\Actions\DeleteBulkAction::make(),
140
-                ]),
141
-            ])
142
-            ->checkIfRecordIsSelectableUsing(static function (Tax $record) {
143
-                return $record->isDisabled();
144
-            })
145
-            ->emptyStateActions([
146
-                Tables\Actions\CreateAction::make(),
147
-            ]);
148
-    }
149
-
150
-    public static function getPages(): array
151
-    {
152
-        return [
153
-            'index' => Pages\ListTaxes::route('/'),
154
-            'create' => Pages\CreateTax::route('/create'),
155
-            'edit' => Pages\EditTax::route('/{record}/edit'),
156
-        ];
157
-    }
158
-}

+ 0
- 16
app/Filament/Company/Clusters/Settings/Resources/TaxResource/Pages/CreateTax.php Näytä tiedosto

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

+ 0
- 24
app/Filament/Company/Clusters/Settings/Resources/TaxResource/Pages/EditTax.php Näytä tiedosto

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

+ 2
- 0
app/Filament/Company/Pages/Accounting/AccountChart.php Näytä tiedosto

@@ -46,6 +46,8 @@ class AccountChart extends Page
46 46
     public function categories(): Collection
47 47
     {
48 48
         return AccountSubtype::withCount('accounts')
49
+            ->with('accounts')
50
+            ->with('accounts.adjustment')
49 51
             ->get()
50 52
             ->groupBy('category');
51 53
     }

+ 131
- 0
app/Filament/Company/Resources/Common/OfferingResource.php Näytä tiedosto

@@ -0,0 +1,131 @@
1
+<?php
2
+
3
+namespace App\Filament\Company\Resources\Common;
4
+
5
+use App\Enums\Common\OfferingType;
6
+use App\Filament\Company\Resources\Common\OfferingResource\Pages;
7
+use App\Models\Common\Offering;
8
+use App\Utilities\Currency\CurrencyAccessor;
9
+use Filament\Forms;
10
+use Filament\Forms\Form;
11
+use Filament\Resources\Resource;
12
+use Filament\Tables;
13
+use Filament\Tables\Table;
14
+
15
+class OfferingResource extends Resource
16
+{
17
+    protected static ?string $model = Offering::class;
18
+
19
+    public static function form(Form $form): Form
20
+    {
21
+        return $form
22
+            ->schema([
23
+                Forms\Components\Section::make('General')
24
+                    ->schema([
25
+                        Forms\Components\TextInput::make('name')
26
+                            ->autofocus()
27
+                            ->required()
28
+                            ->maxLength(255),
29
+                        Forms\Components\Textarea::make('description')
30
+                            ->label('Description')
31
+                            ->autosize(),
32
+                        Forms\Components\Select::make('type')
33
+                            ->options(OfferingType::class)
34
+                            ->searchable()
35
+                            ->required(),
36
+                        Forms\Components\TextInput::make('price')
37
+                            ->required()
38
+                            ->money(CurrencyAccessor::getDefaultCurrency()),
39
+                        Forms\Components\Checkbox::make('sellable')
40
+                            ->label('Sellable')
41
+                            ->live()
42
+                            ->dehydrated(false)
43
+                            ->default(false),
44
+                        Forms\Components\Checkbox::make('purchasable')
45
+                            ->label('Purchasable')
46
+                            ->live()
47
+                            ->dehydrated(false)
48
+                            ->default(false),
49
+                    ]),
50
+                // Sellable Section
51
+                Forms\Components\Section::make('Sellable Configuration')
52
+                    ->schema([
53
+                        Forms\Components\Select::make('income_account_id')
54
+                            ->relationship('incomeAccount', 'name')
55
+                            ->searchable()
56
+                            ->preload(),
57
+                        Forms\Components\Select::make('sales_taxes')
58
+                            ->relationship('salesTaxes', 'name')
59
+                            ->preload()
60
+                            ->multiple(),
61
+                        Forms\Components\Select::make('sales_discounts')
62
+                            ->relationship('salesDiscounts', 'name')
63
+                            ->preload()
64
+                            ->multiple(),
65
+                    ])
66
+                    ->columns(2)
67
+                    ->visible(fn (Forms\Get $get) => $get('sellable')),
68
+
69
+                // Purchasable Section
70
+                Forms\Components\Section::make('Purchasable Configuration')
71
+                    ->schema([
72
+                        Forms\Components\Select::make('expense_account_id')
73
+                            ->relationship('expenseAccount', 'name')
74
+                            ->searchable()
75
+                            ->preload(),
76
+                        Forms\Components\Select::make('purchase_taxes')
77
+                            ->relationship('purchaseTaxes', 'name')
78
+                            ->preload()
79
+                            ->multiple(),
80
+                        Forms\Components\Select::make('purchase_discounts')
81
+                            ->relationship('purchaseDiscounts', 'name')
82
+                            ->preload()
83
+                            ->multiple(),
84
+                    ])
85
+                    ->columns(2)
86
+                    ->visible(fn (Forms\Get $get) => $get('purchasable')),
87
+            ])->columns(1);
88
+    }
89
+
90
+    public static function table(Table $table): Table
91
+    {
92
+        return $table
93
+            ->columns([
94
+                Tables\Columns\ViewColumn::make('name')
95
+                    ->label('Name')
96
+                    ->view('filament.company.components.tables.columns.offering-status'),
97
+                Tables\Columns\TextColumn::make('type')
98
+                    ->searchable(),
99
+                Tables\Columns\TextColumn::make('price')
100
+                    ->money()
101
+                    ->sortable(),
102
+            ])
103
+            ->filters([
104
+                //
105
+            ])
106
+            ->actions([
107
+                Tables\Actions\EditAction::make(),
108
+            ])
109
+            ->bulkActions([
110
+                Tables\Actions\BulkActionGroup::make([
111
+                    Tables\Actions\DeleteBulkAction::make(),
112
+                ]),
113
+            ]);
114
+    }
115
+
116
+    public static function getRelations(): array
117
+    {
118
+        return [
119
+            //
120
+        ];
121
+    }
122
+
123
+    public static function getPages(): array
124
+    {
125
+        return [
126
+            'index' => Pages\ListOfferings::route('/'),
127
+            'create' => Pages\CreateOffering::route('/create'),
128
+            'edit' => Pages\EditOffering::route('/{record}/edit'),
129
+        ];
130
+    }
131
+}

+ 11
- 0
app/Filament/Company/Resources/Common/OfferingResource/Pages/CreateOffering.php Näytä tiedosto

@@ -0,0 +1,11 @@
1
+<?php
2
+
3
+namespace App\Filament\Company\Resources\Common\OfferingResource\Pages;
4
+
5
+use App\Filament\Company\Resources\Common\OfferingResource;
6
+use Filament\Resources\Pages\CreateRecord;
7
+
8
+class CreateOffering extends CreateRecord
9
+{
10
+    protected static string $resource = OfferingResource::class;
11
+}

+ 19
- 0
app/Filament/Company/Resources/Common/OfferingResource/Pages/EditOffering.php Näytä tiedosto

@@ -0,0 +1,19 @@
1
+<?php
2
+
3
+namespace App\Filament\Company\Resources\Common\OfferingResource\Pages;
4
+
5
+use App\Filament\Company\Resources\Common\OfferingResource;
6
+use Filament\Actions;
7
+use Filament\Resources\Pages\EditRecord;
8
+
9
+class EditOffering extends EditRecord
10
+{
11
+    protected static string $resource = OfferingResource::class;
12
+
13
+    protected function getHeaderActions(): array
14
+    {
15
+        return [
16
+            Actions\DeleteAction::make(),
17
+        ];
18
+    }
19
+}

+ 19
- 0
app/Filament/Company/Resources/Common/OfferingResource/Pages/ListOfferings.php Näytä tiedosto

@@ -0,0 +1,19 @@
1
+<?php
2
+
3
+namespace App\Filament\Company\Resources\Common\OfferingResource\Pages;
4
+
5
+use App\Filament\Company\Resources\Common\OfferingResource;
6
+use Filament\Actions;
7
+use Filament\Resources\Pages\ListRecords;
8
+
9
+class ListOfferings extends ListRecords
10
+{
11
+    protected static string $resource = OfferingResource::class;
12
+
13
+    protected function getHeaderActions(): array
14
+    {
15
+        return [
16
+            Actions\CreateAction::make(),
17
+        ];
18
+    }
19
+}

+ 50
- 0
app/Filament/Company/Resources/Purchases/BuyableOfferingResource.php Näytä tiedosto

@@ -0,0 +1,50 @@
1
+<?php
2
+
3
+namespace App\Filament\Company\Resources\Purchases;
4
+
5
+use App\Filament\Company\Resources\Common\OfferingResource;
6
+use App\Filament\Company\Resources\Purchases\BuyableOfferingResource\Pages;
7
+use App\Models\Common\Offering;
8
+use Filament\Forms\Form;
9
+use Filament\Resources\Resource;
10
+use Filament\Tables\Table;
11
+use Illuminate\Database\Eloquent\Builder;
12
+
13
+class BuyableOfferingResource extends Resource
14
+{
15
+    protected static ?string $model = Offering::class;
16
+
17
+    protected static ?string $pluralModelLabel = 'Products & Services';
18
+
19
+    public static function getEloquentQuery(): Builder
20
+    {
21
+        return parent::getEloquentQuery()
22
+            ->whereNotNull('expense_account_id');
23
+    }
24
+
25
+    public static function form(Form $form): Form
26
+    {
27
+        return OfferingResource::form($form);
28
+    }
29
+
30
+    public static function table(Table $table): Table
31
+    {
32
+        return OfferingResource::table($table);
33
+    }
34
+
35
+    public static function getRelations(): array
36
+    {
37
+        return [
38
+            //
39
+        ];
40
+    }
41
+
42
+    public static function getPages(): array
43
+    {
44
+        return [
45
+            'index' => Pages\ListBuyableOfferings::route('/'),
46
+            'create' => Pages\CreateBuyableOffering::route('/create'),
47
+            'edit' => Pages\EditBuyableOffering::route('/{record}/edit'),
48
+        ];
49
+    }
50
+}

+ 21
- 0
app/Filament/Company/Resources/Purchases/BuyableOfferingResource/Pages/CreateBuyableOffering.php Näytä tiedosto

@@ -0,0 +1,21 @@
1
+<?php
2
+
3
+namespace App\Filament\Company\Resources\Purchases\BuyableOfferingResource\Pages;
4
+
5
+use App\Filament\Company\Resources\Purchases\BuyableOfferingResource;
6
+use App\Filament\Company\Resources\Sales\SellableOfferingResource;
7
+use Filament\Resources\Pages\CreateRecord;
8
+
9
+class CreateBuyableOffering extends CreateRecord
10
+{
11
+    protected static string $resource = BuyableOfferingResource::class;
12
+
13
+    protected function getRedirectUrl(): string
14
+    {
15
+        if ($this->record->income_account_id && ! $this->record->expense_account_id) {
16
+            return SellableOfferingResource::getUrl();
17
+        } else {
18
+            return $this->getResource()::getUrl('index');
19
+        }
20
+    }
21
+}

+ 29
- 0
app/Filament/Company/Resources/Purchases/BuyableOfferingResource/Pages/EditBuyableOffering.php Näytä tiedosto

@@ -0,0 +1,29 @@
1
+<?php
2
+
3
+namespace App\Filament\Company\Resources\Purchases\BuyableOfferingResource\Pages;
4
+
5
+use App\Filament\Company\Resources\Purchases\BuyableOfferingResource;
6
+use App\Filament\Company\Resources\Sales\SellableOfferingResource;
7
+use Filament\Actions;
8
+use Filament\Resources\Pages\EditRecord;
9
+
10
+class EditBuyableOffering extends EditRecord
11
+{
12
+    protected static string $resource = BuyableOfferingResource::class;
13
+
14
+    protected function getHeaderActions(): array
15
+    {
16
+        return [
17
+            Actions\DeleteAction::make(),
18
+        ];
19
+    }
20
+
21
+    protected function getRedirectUrl(): string
22
+    {
23
+        if ($this->record->income_account_id && ! $this->record->expense_account_id) {
24
+            return SellableOfferingResource::getUrl();
25
+        } else {
26
+            return $this->getResource()::getUrl('index');
27
+        }
28
+    }
29
+}

+ 25
- 0
app/Filament/Company/Resources/Purchases/BuyableOfferingResource/Pages/ListBuyableOfferings.php Näytä tiedosto

@@ -0,0 +1,25 @@
1
+<?php
2
+
3
+namespace App\Filament\Company\Resources\Purchases\BuyableOfferingResource\Pages;
4
+
5
+use App\Filament\Company\Resources\Purchases\BuyableOfferingResource;
6
+use Filament\Actions;
7
+use Filament\Resources\Pages\ListRecords;
8
+use Illuminate\Contracts\Support\Htmlable;
9
+
10
+class ListBuyableOfferings extends ListRecords
11
+{
12
+    protected static string $resource = BuyableOfferingResource::class;
13
+
14
+    protected function getHeaderActions(): array
15
+    {
16
+        return [
17
+            Actions\CreateAction::make(),
18
+        ];
19
+    }
20
+
21
+    public function getHeading(): string | Htmlable
22
+    {
23
+        return 'Products & Services (Purchases)';
24
+    }
25
+}

+ 50
- 0
app/Filament/Company/Resources/Sales/SellableOfferingResource.php Näytä tiedosto

@@ -0,0 +1,50 @@
1
+<?php
2
+
3
+namespace App\Filament\Company\Resources\Sales;
4
+
5
+use App\Filament\Company\Resources\Common\OfferingResource;
6
+use App\Filament\Company\Resources\Sales\SellableOfferingResource\Pages;
7
+use App\Models\Common\Offering;
8
+use Filament\Forms\Form;
9
+use Filament\Resources\Resource;
10
+use Filament\Tables\Table;
11
+use Illuminate\Database\Eloquent\Builder;
12
+
13
+class SellableOfferingResource extends Resource
14
+{
15
+    protected static ?string $model = Offering::class;
16
+
17
+    protected static ?string $pluralModelLabel = 'Products & Services';
18
+
19
+    public static function getEloquentQuery(): Builder
20
+    {
21
+        return parent::getEloquentQuery()
22
+            ->whereNotNull('income_account_id');
23
+    }
24
+
25
+    public static function form(Form $form): Form
26
+    {
27
+        return OfferingResource::form($form);
28
+    }
29
+
30
+    public static function table(Table $table): Table
31
+    {
32
+        return OfferingResource::table($table);
33
+    }
34
+
35
+    public static function getRelations(): array
36
+    {
37
+        return [
38
+            //
39
+        ];
40
+    }
41
+
42
+    public static function getPages(): array
43
+    {
44
+        return [
45
+            'index' => Pages\ListSellableOfferings::route('/'),
46
+            'create' => Pages\CreateSellableOffering::route('/create'),
47
+            'edit' => Pages\EditSellableOffering::route('/{record}/edit'),
48
+        ];
49
+    }
50
+}

+ 21
- 0
app/Filament/Company/Resources/Sales/SellableOfferingResource/Pages/CreateSellableOffering.php Näytä tiedosto

@@ -0,0 +1,21 @@
1
+<?php
2
+
3
+namespace App\Filament\Company\Resources\Sales\SellableOfferingResource\Pages;
4
+
5
+use App\Filament\Company\Resources\Purchases\BuyableOfferingResource;
6
+use App\Filament\Company\Resources\Sales\SellableOfferingResource;
7
+use Filament\Resources\Pages\CreateRecord;
8
+
9
+class CreateSellableOffering extends CreateRecord
10
+{
11
+    protected static string $resource = SellableOfferingResource::class;
12
+
13
+    protected function getRedirectUrl(): string
14
+    {
15
+        if ($this->record->expense_account_id && ! $this->record->income_account_id) {
16
+            return BuyableOfferingResource::getUrl();
17
+        } else {
18
+            return $this->getResource()::getUrl('index');
19
+        }
20
+    }
21
+}

+ 29
- 0
app/Filament/Company/Resources/Sales/SellableOfferingResource/Pages/EditSellableOffering.php Näytä tiedosto

@@ -0,0 +1,29 @@
1
+<?php
2
+
3
+namespace App\Filament\Company\Resources\Sales\SellableOfferingResource\Pages;
4
+
5
+use App\Filament\Company\Resources\Purchases\BuyableOfferingResource;
6
+use App\Filament\Company\Resources\Sales\SellableOfferingResource;
7
+use Filament\Actions;
8
+use Filament\Resources\Pages\EditRecord;
9
+
10
+class EditSellableOffering extends EditRecord
11
+{
12
+    protected static string $resource = SellableOfferingResource::class;
13
+
14
+    protected function getHeaderActions(): array
15
+    {
16
+        return [
17
+            Actions\DeleteAction::make(),
18
+        ];
19
+    }
20
+
21
+    protected function getRedirectUrl(): string
22
+    {
23
+        if ($this->record->expense_account_id && ! $this->record->income_account_id) {
24
+            return BuyableOfferingResource::getUrl();
25
+        } else {
26
+            return $this->getResource()::getUrl('index');
27
+        }
28
+    }
29
+}

+ 25
- 0
app/Filament/Company/Resources/Sales/SellableOfferingResource/Pages/ListSellableOfferings.php Näytä tiedosto

@@ -0,0 +1,25 @@
1
+<?php
2
+
3
+namespace App\Filament\Company\Resources\Sales\SellableOfferingResource\Pages;
4
+
5
+use App\Filament\Company\Resources\Sales\SellableOfferingResource;
6
+use Filament\Actions;
7
+use Filament\Resources\Pages\ListRecords;
8
+use Illuminate\Contracts\Support\Htmlable;
9
+
10
+class ListSellableOfferings extends ListRecords
11
+{
12
+    protected static string $resource = SellableOfferingResource::class;
13
+
14
+    protected function getHeaderActions(): array
15
+    {
16
+        return [
17
+            Actions\CreateAction::make(),
18
+        ];
19
+    }
20
+
21
+    public function getHeading(): string | Htmlable
22
+    {
23
+        return 'Products & Services (Sales)';
24
+    }
25
+}

+ 36
- 7
app/Models/Accounting/Adjustment.php Näytä tiedosto

@@ -5,23 +5,25 @@ namespace App\Models\Accounting;
5 5
 use App\Casts\RateCast;
6 6
 use App\Concerns\Blamable;
7 7
 use App\Concerns\CompanyOwned;
8
-use App\Concerns\HasDefault;
9 8
 use App\Enums\Accounting\AdjustmentCategory;
10 9
 use App\Enums\Accounting\AdjustmentComputation;
11 10
 use App\Enums\Accounting\AdjustmentScope;
12 11
 use App\Enums\Accounting\AdjustmentType;
12
+use App\Models\Common\Offering;
13
+use App\Observers\AdjustmentObserver;
13 14
 use Database\Factories\Accounting\AdjustmentFactory;
15
+use Illuminate\Database\Eloquent\Attributes\ObservedBy;
14 16
 use Illuminate\Database\Eloquent\Factories\Factory;
15 17
 use Illuminate\Database\Eloquent\Factories\HasFactory;
16 18
 use Illuminate\Database\Eloquent\Model;
17 19
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
18
-use Illuminate\Database\Eloquent\Relations\MorphTo;
20
+use Illuminate\Database\Eloquent\Relations\MorphToMany;
19 21
 
22
+#[ObservedBy(AdjustmentObserver::class)]
20 23
 class Adjustment extends Model
21 24
 {
22 25
     use Blamable;
23 26
     use CompanyOwned;
24
-    use HasDefault;
25 27
     use HasFactory;
26 28
 
27 29
     protected $table = 'adjustments';
@@ -29,14 +31,16 @@ class Adjustment extends Model
29 31
     protected $fillable = [
30 32
         'company_id',
31 33
         'account_id',
34
+        'name',
35
+        'description',
32 36
         'category',
33 37
         'type',
38
+        'recoverable',
34 39
         'rate',
35 40
         'computation',
36 41
         'scope',
37 42
         'start_date',
38 43
         'end_date',
39
-        'enabled',
40 44
         'created_by',
41 45
         'updated_by',
42 46
     ];
@@ -44,12 +48,12 @@ class Adjustment extends Model
44 48
     protected $casts = [
45 49
         'category' => AdjustmentCategory::class,
46 50
         'type' => AdjustmentType::class,
51
+        'recoverable' => 'boolean',
47 52
         'rate' => RateCast::class,
48 53
         'computation' => AdjustmentComputation::class,
49 54
         'scope' => AdjustmentScope::class,
50 55
         'start_date' => 'datetime',
51 56
         'end_date' => 'datetime',
52
-        'enabled' => 'boolean',
53 57
     ];
54 58
 
55 59
     public function account(): BelongsTo
@@ -57,9 +61,34 @@ class Adjustment extends Model
57 61
         return $this->belongsTo(Account::class, 'account_id');
58 62
     }
59 63
 
60
-    public function adjustmentables(): MorphTo
64
+    public function offerings(): MorphToMany
61 65
     {
62
-        return $this->morphTo();
66
+        return $this->morphedByMany(Offering::class, 'adjustmentable', 'adjustmentables');
67
+    }
68
+
69
+    public function isSalesTax(): bool
70
+    {
71
+        return $this->category->isTax() && $this->type->isSales();
72
+    }
73
+
74
+    public function isNonRecoverablePurchaseTax(): bool
75
+    {
76
+        return $this->category->isTax() && $this->type->isPurchase() && $this->recoverable === false;
77
+    }
78
+
79
+    public function isRecoverablePurchaseTax(): bool
80
+    {
81
+        return $this->category->isTax() && $this->type->isPurchase() && $this->recoverable === true;
82
+    }
83
+
84
+    public function isSalesDiscount(): bool
85
+    {
86
+        return $this->category->isDiscount() && $this->type->isSales();
87
+    }
88
+
89
+    public function isPurchaseDiscount(): bool
90
+    {
91
+        return $this->category->isDiscount() && $this->type->isPurchase();
63 92
     }
64 93
 
65 94
     protected static function newFactory(): Factory

+ 33
- 8
app/Models/Common/Offering.php Näytä tiedosto

@@ -2,10 +2,14 @@
2 2
 
3 3
 namespace App\Models\Common;
4 4
 
5
+use App\Casts\MoneyCast;
6
+use App\Concerns\Blamable;
5 7
 use App\Concerns\CompanyOwned;
8
+use App\Enums\Accounting\AdjustmentCategory;
9
+use App\Enums\Accounting\AdjustmentType;
10
+use App\Enums\Common\OfferingType;
6 11
 use App\Models\Accounting\Account;
7
-use App\Models\Setting\Discount;
8
-use App\Models\Setting\Tax;
12
+use App\Models\Accounting\Adjustment;
9 13
 use Illuminate\Database\Eloquent\Factories\HasFactory;
10 14
 use Illuminate\Database\Eloquent\Model;
11 15
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -13,6 +17,7 @@ use Illuminate\Database\Eloquent\Relations\MorphToMany;
13 17
 
14 18
 class Offering extends Model
15 19
 {
20
+    use Blamable;
16 21
     use CompanyOwned;
17 22
     use HasFactory;
18 23
 
@@ -24,6 +29,13 @@ class Offering extends Model
24 29
         'price',
25 30
         'income_account_id',
26 31
         'expense_account_id',
32
+        'created_by',
33
+        'updated_by',
34
+    ];
35
+
36
+    protected $casts = [
37
+        'type' => OfferingType::class,
38
+        'price' => MoneyCast::class,
27 39
     ];
28 40
 
29 41
     public function incomeAccount(): BelongsTo
@@ -36,15 +48,28 @@ class Offering extends Model
36 48
         return $this->belongsTo(Account::class, 'expense_account_id');
37 49
     }
38 50
 
39
-    public function taxes(): MorphToMany
51
+    public function adjustments(): MorphToMany
52
+    {
53
+        return $this->morphToMany(Adjustment::class, 'adjustmentable', 'adjustmentables');
54
+    }
55
+
56
+    public function salesTaxes(): MorphToMany
57
+    {
58
+        return $this->adjustments()->where('category', AdjustmentCategory::Tax)->where('type', AdjustmentType::Sales);
59
+    }
60
+
61
+    public function purchaseTaxes(): MorphToMany
62
+    {
63
+        return $this->adjustments()->where('category', AdjustmentCategory::Tax)->where('type', AdjustmentType::Purchase);
64
+    }
65
+
66
+    public function salesDiscounts(): MorphToMany
40 67
     {
41
-        return $this->morphToMany(Tax::class, 'adjustmentable', 'adjustmentables')
42
-            ->wherePivot('adjustment_type', Tax::class);
68
+        return $this->adjustments()->where('category', AdjustmentCategory::Discount)->where('type', AdjustmentType::Sales);
43 69
     }
44 70
 
45
-    public function discounts(): MorphToMany
71
+    public function purchaseDiscounts(): MorphToMany
46 72
     {
47
-        return $this->morphToMany(Discount::class, 'adjustmentable', 'adjustmentables')
48
-            ->wherePivot('adjustment_type', Discount::class);
73
+        return $this->adjustments()->where('category', AdjustmentCategory::Discount)->where('type', AdjustmentType::Purchase);
49 74
     }
50 75
 }

+ 6
- 0
app/Models/Company.php Näytä tiedosto

@@ -7,6 +7,7 @@ use App\Models\Accounting\AccountSubtype;
7 7
 use App\Models\Banking\BankAccount;
8 8
 use App\Models\Banking\ConnectedBankAccount;
9 9
 use App\Models\Common\Contact;
10
+use App\Models\Common\Offering;
10 11
 use App\Models\Core\Department;
11 12
 use App\Models\Setting\Appearance;
12 13
 use App\Models\Setting\CompanyDefault;
@@ -139,4 +140,9 @@ class Company extends FilamentCompaniesCompany implements HasAvatar
139 140
     {
140 141
         return $this->hasMany(Accounting\Transaction::class, 'company_id');
141 142
     }
143
+
144
+    public function offerings(): HasMany
145
+    {
146
+        return $this->hasMany(Offering::class, 'company_id');
147
+    }
142 148
 }

+ 40
- 0
app/Observers/AdjustmentObserver.php Näytä tiedosto

@@ -0,0 +1,40 @@
1
+<?php
2
+
3
+namespace App\Observers;
4
+
5
+use App\Models\Accounting\Account;
6
+use App\Models\Accounting\Adjustment;
7
+
8
+class AdjustmentObserver
9
+{
10
+    public function creating(Adjustment $adjustment): void
11
+    {
12
+        if ($adjustment->account_id === null && ! $adjustment->isNonRecoverablePurchaseTax()) {
13
+            $account = null;
14
+
15
+            if ($adjustment->isSalesTax()) {
16
+                $account = Account::factory()->forSalesTax($adjustment->name, $adjustment->description)->create();
17
+            } elseif ($adjustment->isRecoverablePurchaseTax()) {
18
+                $account = Account::factory()->forPurchaseTax($adjustment->name, $adjustment->description)->create();
19
+            } elseif ($adjustment->isSalesDiscount()) {
20
+                $account = Account::factory()->forSalesDiscount($adjustment->name, $adjustment->description)->create();
21
+            } elseif ($adjustment->isPurchaseDiscount()) {
22
+                $account = Account::factory()->forPurchaseDiscount($adjustment->name, $adjustment->description)->create();
23
+            }
24
+
25
+            if ($account) {
26
+                $adjustment->account()->associate($account);
27
+            }
28
+        }
29
+    }
30
+
31
+    public function updating(Adjustment $adjustment): void
32
+    {
33
+        if ($adjustment->account) {
34
+            $adjustment->account->update([
35
+                'name' => $adjustment->name,
36
+                'description' => $adjustment->description,
37
+            ]);
38
+        }
39
+    }
40
+}

+ 10
- 0
app/Providers/FilamentCompaniesServiceProvider.php Näytä tiedosto

@@ -27,6 +27,8 @@ use App\Filament\Company\Pages\Service\ConnectedAccount;
27 27
 use App\Filament\Company\Pages\Service\LiveCurrency;
28 28
 use App\Filament\Company\Resources\Banking\AccountResource;
29 29
 use App\Filament\Company\Resources\Core\DepartmentResource;
30
+use App\Filament\Company\Resources\Purchases\BuyableOfferingResource;
31
+use App\Filament\Company\Resources\Sales\SellableOfferingResource;
30 32
 use App\Filament\Components\PanelShiftDropdown;
31 33
 use App\Filament\User\Clusters\Account;
32 34
 use App\Http\Middleware\ConfigureCurrentCompany;
@@ -121,6 +123,14 @@ class FilamentCompaniesServiceProvider extends PanelProvider
121 123
                         ...Settings::getNavigationItems(),
122 124
                     ])
123 125
                     ->groups([
126
+                        NavigationGroup::make('Sales & Payments')
127
+                            ->label('Sales & Payments')
128
+                            ->icon('heroicon-o-currency-dollar')
129
+                            ->items(SellableOfferingResource::getNavigationItems()),
130
+                        NavigationGroup::make('Purchases')
131
+                            ->label('Purchases')
132
+                            ->icon('heroicon-o-shopping-cart')
133
+                            ->items(BuyableOfferingResource::getNavigationItems()),
124 134
                         NavigationGroup::make('Accounting')
125 135
                             ->localizeLabel()
126 136
                             ->icon('heroicon-o-clipboard-document-list')

+ 24
- 14
app/Services/ChartOfAccountsService.php Näytä tiedosto

@@ -4,6 +4,7 @@ namespace App\Services;
4 4
 
5 5
 use App\Enums\Accounting\AccountType;
6 6
 use App\Enums\Banking\BankAccountType;
7
+use App\Models\Accounting\Account;
7 8
 use App\Models\Accounting\AccountSubtype;
8 9
 use App\Models\Accounting\Adjustment;
9 10
 use App\Models\Banking\BankAccount;
@@ -17,6 +18,9 @@ class ChartOfAccountsService
17 18
     {
18 19
         $chartOfAccounts = config('chart-of-accounts.default');
19 20
 
21
+        // Always create a non-recoverable "Purchase Tax" adjustment, even without an account
22
+        $this->createAdjustmentForAccount($company, 'tax', 'purchase', false);
23
+
20 24
         foreach ($chartOfAccounts as $type => $subtypes) {
21 25
             foreach ($subtypes as $subtypeName => $subtypeConfig) {
22 26
                 $subtype = $company->accountSubtypes()
@@ -57,6 +61,7 @@ class ChartOfAccountsService
57 61
 
58 62
             foreach ($subtypeConfig['accounts'] as $accountName => $accountDetails) {
59 63
                 // Create the Account without directly setting bank_account_id
64
+                /** @var Account $account */
60 65
                 $account = $company->accounts()->createQuietly([
61 66
                     'subtype_id' => $subtype->id,
62 67
                     'category' => $subtype->type->getCategory()->value,
@@ -79,11 +84,16 @@ class ChartOfAccountsService
79 84
                     $bankAccount->saveQuietly();
80 85
                 }
81 86
 
82
-                if (isset($subtypeConfig['adjustment_category'], $subtypeConfig['adjustment_type'])) {
83
-                    $adjustment = $this->createAdjustmentForAccount($company, $subtypeConfig['adjustment_category'], $subtypeConfig['adjustment_type']);
87
+                if (isset($subtypeConfig['adjustment_category'], $subtypeConfig['adjustment_type'], $subtypeConfig['adjustment_recoverable'])) {
88
+                    $adjustment = $this->createAdjustmentForAccount($company, $subtypeConfig['adjustment_category'], $subtypeConfig['adjustment_type'], $subtypeConfig['adjustment_recoverable']);
84 89
 
85 90
                     // Associate the Adjustment with the Account
86 91
                     $adjustment->account()->associate($account);
92
+
93
+                    $adjustment->name = $account->name;
94
+
95
+                    $adjustment->description = $account->description;
96
+
87 97
                     $adjustment->saveQuietly();
88 98
                 }
89 99
             }
@@ -102,27 +112,27 @@ class ChartOfAccountsService
102 112
         ]);
103 113
     }
104 114
 
105
-    private function createAdjustmentForAccount(Company $company, string $category, string $type): Adjustment
115
+    private function createAdjustmentForAccount(Company $company, string $category, string $type, bool $recoverable): Adjustment
106 116
     {
107
-        $noDefaultAdjustmentType = $company->adjustments()->where('category', $category)
108
-            ->where('type', $type)
109
-            ->where('enabled', true)
110
-            ->doesntExist();
111
-
112 117
         $defaultRate = match ([$category, $type]) {
113
-            ['tax', 'sales'] => 8,          // Default 8% for Sales Tax
114
-            ['tax', 'purchase'] => 8,       // Default 8% for Purchase Tax
115
-            ['discount', 'sales'] => 5,     // Default 5% for Sales Discount
116
-            ['discount', 'purchase'] => 5,  // Default 5% for Purchase Discount
117
-            default => 0,                   // Default to 0 if unspecified
118
+            ['tax', 'sales'], ['tax', 'purchase'] => '8',
119
+            ['discount', 'sales'], ['discount', 'purchase'] => '5',
120
+            default => '0',
118 121
         };
119 122
 
123
+        if ($category === 'tax' && $type === 'purchase' && $recoverable === false) {
124
+            $name = 'Purchase Tax';
125
+            $description = 'This tax is non-recoverable and is included as part of the total cost of the purchase. The tax amount is embedded into the associated expense or asset account based on the type of purchase.';
126
+        }
127
+
120 128
         return $company->adjustments()->createQuietly([
129
+            'name' => $name ?? null,
130
+            'description' => $description ?? null,
121 131
             'category' => $category,
122 132
             'type' => $type,
133
+            'recoverable' => $recoverable,
123 134
             'rate' => $defaultRate,
124 135
             'computation' => 'percentage',
125
-            'enabled' => $noDefaultAdjustmentType,
126 136
             'created_by' => $company->owner->id,
127 137
             'updated_by' => $company->owner->id,
128 138
         ]);

+ 17
- 17
composer.lock Näytä tiedosto

@@ -302,16 +302,16 @@
302 302
         },
303 303
         {
304 304
             "name": "anourvalar/eloquent-serialize",
305
-            "version": "1.2.25",
305
+            "version": "1.2.26",
306 306
             "source": {
307 307
                 "type": "git",
308 308
                 "url": "https://github.com/AnourValar/eloquent-serialize.git",
309
-                "reference": "6d7a868ae4218b9d7796334ff9a17e1539bad48a"
309
+                "reference": "756c1232ff0d02321fd90f4fe3c221d6a7b8d697"
310 310
             },
311 311
             "dist": {
312 312
                 "type": "zip",
313
-                "url": "https://api.github.com/repos/AnourValar/eloquent-serialize/zipball/6d7a868ae4218b9d7796334ff9a17e1539bad48a",
314
-                "reference": "6d7a868ae4218b9d7796334ff9a17e1539bad48a",
313
+                "url": "https://api.github.com/repos/AnourValar/eloquent-serialize/zipball/756c1232ff0d02321fd90f4fe3c221d6a7b8d697",
314
+                "reference": "756c1232ff0d02321fd90f4fe3c221d6a7b8d697",
315 315
                 "shasum": ""
316 316
             },
317 317
             "require": {
@@ -362,9 +362,9 @@
362 362
             ],
363 363
             "support": {
364 364
                 "issues": "https://github.com/AnourValar/eloquent-serialize/issues",
365
-                "source": "https://github.com/AnourValar/eloquent-serialize/tree/1.2.25"
365
+                "source": "https://github.com/AnourValar/eloquent-serialize/tree/1.2.26"
366 366
             },
367
-            "time": "2024-09-16T12:59:37+00:00"
367
+            "time": "2024-11-16T12:29:47+00:00"
368 368
         },
369 369
         {
370 370
             "name": "awcodes/filament-table-repeater",
@@ -497,16 +497,16 @@
497 497
         },
498 498
         {
499 499
             "name": "aws/aws-sdk-php",
500
-            "version": "3.327.0",
500
+            "version": "3.328.0",
501 501
             "source": {
502 502
                 "type": "git",
503 503
                 "url": "https://github.com/aws/aws-sdk-php.git",
504
-                "reference": "ba4a7ac2544de61b33f693c461f8b09c0353298f"
504
+                "reference": "a99b58e166ae367f2b067937afb04e843e900745"
505 505
             },
506 506
             "dist": {
507 507
                 "type": "zip",
508
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/ba4a7ac2544de61b33f693c461f8b09c0353298f",
509
-                "reference": "ba4a7ac2544de61b33f693c461f8b09c0353298f",
508
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/a99b58e166ae367f2b067937afb04e843e900745",
509
+                "reference": "a99b58e166ae367f2b067937afb04e843e900745",
510 510
                 "shasum": ""
511 511
             },
512 512
             "require": {
@@ -589,9 +589,9 @@
589 589
             "support": {
590 590
                 "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
591 591
                 "issues": "https://github.com/aws/aws-sdk-php/issues",
592
-                "source": "https://github.com/aws/aws-sdk-php/tree/3.327.0"
592
+                "source": "https://github.com/aws/aws-sdk-php/tree/3.328.0"
593 593
             },
594
-            "time": "2024-11-14T19:06:19+00:00"
594
+            "time": "2024-11-15T19:06:57+00:00"
595 595
         },
596 596
         {
597 597
             "name": "aws/aws-sdk-php-laravel",
@@ -2908,16 +2908,16 @@
2908 2908
         },
2909 2909
         {
2910 2910
             "name": "laravel/framework",
2911
-            "version": "v11.31.0",
2911
+            "version": "v11.32.0",
2912 2912
             "source": {
2913 2913
                 "type": "git",
2914 2914
                 "url": "https://github.com/laravel/framework.git",
2915
-                "reference": "365090ed2c68244e3141cdb5e247cdf3dfba2c40"
2915
+                "reference": "bc2aad63f83ee5089be7b21cf29d645ccf31e927"
2916 2916
             },
2917 2917
             "dist": {
2918 2918
                 "type": "zip",
2919
-                "url": "https://api.github.com/repos/laravel/framework/zipball/365090ed2c68244e3141cdb5e247cdf3dfba2c40",
2920
-                "reference": "365090ed2c68244e3141cdb5e247cdf3dfba2c40",
2919
+                "url": "https://api.github.com/repos/laravel/framework/zipball/bc2aad63f83ee5089be7b21cf29d645ccf31e927",
2920
+                "reference": "bc2aad63f83ee5089be7b21cf29d645ccf31e927",
2921 2921
                 "shasum": ""
2922 2922
             },
2923 2923
             "require": {
@@ -3113,7 +3113,7 @@
3113 3113
                 "issues": "https://github.com/laravel/framework/issues",
3114 3114
                 "source": "https://github.com/laravel/framework"
3115 3115
             },
3116
-            "time": "2024-11-12T15:36:15+00:00"
3116
+            "time": "2024-11-15T17:04:33+00:00"
3117 3117
         },
3118 3118
         {
3119 3119
             "name": "laravel/prompts",

+ 17
- 13
config/chart-of-accounts.php Näytä tiedosto

@@ -26,6 +26,20 @@ return [
26 26
                     ],
27 27
                 ],
28 28
             ],
29
+            'Input Tax Recoverable' => [
30
+                'description' => 'The amount of sales tax paid on purchases that can be recovered from the government.',
31
+                'multi_currency' => false,
32
+                'base_code' => '1150',
33
+                'inverse_cash_flow' => true,
34
+                'adjustment_category' => 'tax',
35
+                'adjustment_type' => 'purchase',
36
+                'adjustment_recoverable' => true,
37
+                'accounts' => [
38
+                    'Input Tax' => [
39
+                        'description' => null,
40
+                    ],
41
+                ],
42
+            ],
29 43
             'Inventory' => [
30 44
                 'description' => 'The raw materials, work-in-progress goods and completely finished goods that are considered to be the portion of a business\'s assets that are ready or will be ready for sale.',
31 45
                 'multi_currency' => true,
@@ -126,6 +140,7 @@ return [
126 140
                 'inverse_cash_flow' => false,
127 141
                 'adjustment_category' => 'tax',
128 142
                 'adjustment_type' => 'sales',
143
+                'adjustment_recoverable' => false,
129 144
                 'accounts' => [
130 145
                     'Sales Tax' => [
131 146
                         'description' => null,
@@ -288,6 +303,7 @@ return [
288 303
                 'inverse_cash_flow' => false,
289 304
                 'adjustment_category' => 'discount',
290 305
                 'adjustment_type' => 'sales',
306
+                'adjustment_recoverable' => false,
291 307
                 'accounts' => [
292 308
                     'Sales Discount' => [
293 309
                         'description' => null,
@@ -430,19 +446,6 @@ return [
430 446
                 'base_code' => '5600',
431 447
                 'inverse_cash_flow' => true,
432 448
             ],
433
-            'Purchase Taxes' => [
434
-                'description' => 'Taxes paid on purchases of goods or services, such as value-added tax (VAT), goods and services tax (GST), or customs duties.',
435
-                'multi_currency' => false,
436
-                'base_code' => '5650',
437
-                'inverse_cash_flow' => true,
438
-                'adjustment_category' => 'tax',
439
-                'adjustment_type' => 'purchase',
440
-                'accounts' => [
441
-                    'Purchase Tax' => [
442
-                        'description' => null,
443
-                    ],
444
-                ],
445
-            ],
446 449
             'Other Non-Operating Expense' => [
447 450
                 'description' => 'Expenses not related to primary business activities, like losses from asset disposals, legal settlements, restructuring costs, or foreign exchange losses.',
448 451
                 'multi_currency' => false,
@@ -474,6 +477,7 @@ return [
474 477
                 'inverse_cash_flow' => true,
475 478
                 'adjustment_category' => 'discount',
476 479
                 'adjustment_type' => 'purchase',
480
+                'adjustment_recoverable' => false,
477 481
                 'accounts' => [
478 482
                     'Purchase Discount' => [
479 483
                         'description' => null,

+ 1
- 1
database/factories/Accounting/AccountFactory.php Näytä tiedosto

@@ -92,7 +92,7 @@ class AccountFactory extends Factory
92 92
 
93 93
     public function forPurchaseTax(?string $name = null, ?string $description = null): static
94 94
     {
95
-        $accountSubtype = AccountSubtype::where('name', 'Purchase Taxes')->first();
95
+        $accountSubtype = AccountSubtype::where('name', 'Input Tax Recoverable')->first();
96 96
 
97 97
         return $this->state([
98 98
             'name' => $name,

+ 0
- 1
database/factories/Accounting/AdjustmentFactory.php Näytä tiedosto

@@ -44,7 +44,6 @@ class AdjustmentFactory extends Factory
44 44
             'scope' => $this->faker->randomElement(AdjustmentScope::class),
45 45
             'start_date' => $startDate,
46 46
             'end_date' => $endDate,
47
-            'enabled' => false,
48 47
         ];
49 48
     }
50 49
 

+ 2
- 0
database/migrations/2024_11_13_214149_create_offerings_table.php Näytä tiedosto

@@ -20,6 +20,8 @@ return new class extends Migration
20 20
             $table->integer('price')->default(0);
21 21
             $table->foreignId('income_account_id')->nullable()->constrained('accounts')->nullOnDelete(); // income account e.g. sales/invoice
22 22
             $table->foreignId('expense_account_id')->nullable()->constrained('accounts')->nullOnDelete(); // expense account e.g. purchase/bill
23
+            $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
24
+            $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
23 25
             $table->timestamps();
24 26
         });
25 27
     }

+ 3
- 1
database/migrations/2024_11_14_230753_create_adjustments_table.php Näytä tiedosto

@@ -15,14 +15,16 @@ return new class extends Migration
15 15
             $table->id();
16 16
             $table->foreignId('company_id')->constrained()->cascadeOnDelete();
17 17
             $table->foreignId('account_id')->nullable()->constrained('accounts')->nullOnDelete();
18
+            $table->string('name')->nullable();
19
+            $table->text('description')->nullable();
18 20
             $table->string('category')->default('tax');
19 21
             $table->string('type')->default('sales');
22
+            $table->boolean('recoverable')->default(false);
20 23
             $table->integer('rate')->default(0);
21 24
             $table->string('computation')->default('percentage');
22 25
             $table->string('scope')->nullable();
23 26
             $table->dateTime('start_date')->nullable();
24 27
             $table->dateTime('end_date')->nullable();
25
-            $table->boolean('enabled')->default(true);
26 28
             $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
27 29
             $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
28 30
             $table->timestamps();

database/migrations/2024_11_13_225714_create_adjustmentables_table.php → database/migrations/2024_11_15_225714_create_adjustmentables_table.php Näytä tiedosto

@@ -13,13 +13,9 @@ return new class extends Migration
13 13
     {
14 14
         Schema::create('adjustmentables', function (Blueprint $table) {
15 15
             $table->id();
16
-            $table->unsignedBigInteger('adjustment_id');   // No foreign key constraint due to polymorphism
17
-            $table->string('adjustment_type');             // Type of adjustment (e.g., "App\Models\Tax" or "App\Models\Discount")
18
-            $table->morphs('adjustmentable');              // Creates adjustmentable_id and adjustmentable_type
19
-            $table->timestamps();
16
+            $table->foreignId('adjustment_id')->constrained()->cascadeOnDelete();
17
+            $table->morphs('adjustmentable');
20 18
 
21
-            // Optional indexes for efficient querying
22
-            $table->index(['adjustment_id', 'adjustment_type']);
23 19
             $table->index(['adjustmentable_id', 'adjustmentable_type']);
24 20
         });
25 21
     }

+ 78
- 78
package-lock.json Näytä tiedosto

@@ -541,9 +541,9 @@
541 541
             }
542 542
         },
543 543
         "node_modules/@rollup/rollup-android-arm-eabi": {
544
-            "version": "4.26.0",
545
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.26.0.tgz",
546
-            "integrity": "sha512-gJNwtPDGEaOEgejbaseY6xMFu+CPltsc8/T+diUTTbOQLqD+bnrJq9ulH6WD69TqwqWmrfRAtUv30cCFZlbGTQ==",
544
+            "version": "4.27.2",
545
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.27.2.tgz",
546
+            "integrity": "sha512-Tj+j7Pyzd15wAdSJswvs5CJzJNV+qqSUcr/aCD+jpQSBtXvGnV0pnrjoc8zFTe9fcKCatkpFpOO7yAzpO998HA==",
547 547
             "cpu": [
548 548
                 "arm"
549 549
             ],
@@ -555,9 +555,9 @@
555 555
             ]
556 556
         },
557 557
         "node_modules/@rollup/rollup-android-arm64": {
558
-            "version": "4.26.0",
559
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.26.0.tgz",
560
-            "integrity": "sha512-YJa5Gy8mEZgz5JquFruhJODMq3lTHWLm1fOy+HIANquLzfIOzE9RA5ie3JjCdVb9r46qfAQY/l947V0zfGJ0OQ==",
558
+            "version": "4.27.2",
559
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.27.2.tgz",
560
+            "integrity": "sha512-xsPeJgh2ThBpUqlLgRfiVYBEf/P1nWlWvReG+aBWfNv3XEBpa6ZCmxSVnxJgLgkNz4IbxpLy64h2gCmAAQLneQ==",
561 561
             "cpu": [
562 562
                 "arm64"
563 563
             ],
@@ -569,9 +569,9 @@
569 569
             ]
570 570
         },
571 571
         "node_modules/@rollup/rollup-darwin-arm64": {
572
-            "version": "4.26.0",
573
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.26.0.tgz",
574
-            "integrity": "sha512-ErTASs8YKbqTBoPLp/kA1B1Um5YSom8QAc4rKhg7b9tyyVqDBlQxy7Bf2wW7yIlPGPg2UODDQcbkTlruPzDosw==",
572
+            "version": "4.27.2",
573
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.27.2.tgz",
574
+            "integrity": "sha512-KnXU4m9MywuZFedL35Z3PuwiTSn/yqRIhrEA9j+7OSkji39NzVkgxuxTYg5F8ryGysq4iFADaU5osSizMXhU2A==",
575 575
             "cpu": [
576 576
                 "arm64"
577 577
             ],
@@ -583,9 +583,9 @@
583 583
             ]
584 584
         },
585 585
         "node_modules/@rollup/rollup-darwin-x64": {
586
-            "version": "4.26.0",
587
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.26.0.tgz",
588
-            "integrity": "sha512-wbgkYDHcdWW+NqP2mnf2NOuEbOLzDblalrOWcPyY6+BRbVhliavon15UploG7PpBRQ2bZJnbmh8o3yLoBvDIHA==",
586
+            "version": "4.27.2",
587
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.27.2.tgz",
588
+            "integrity": "sha512-Hj77A3yTvUeCIx/Vi+4d4IbYhyTwtHj07lVzUgpUq9YpJSEiGJj4vXMKwzJ3w5zp5v3PFvpJNgc/J31smZey6g==",
589 589
             "cpu": [
590 590
                 "x64"
591 591
             ],
@@ -597,9 +597,9 @@
597 597
             ]
598 598
         },
599 599
         "node_modules/@rollup/rollup-freebsd-arm64": {
600
-            "version": "4.26.0",
601
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.26.0.tgz",
602
-            "integrity": "sha512-Y9vpjfp9CDkAG4q/uwuhZk96LP11fBz/bYdyg9oaHYhtGZp7NrbkQrj/66DYMMP2Yo/QPAsVHkV891KyO52fhg==",
600
+            "version": "4.27.2",
601
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.27.2.tgz",
602
+            "integrity": "sha512-RjgKf5C3xbn8gxvCm5VgKZ4nn0pRAIe90J0/fdHUsgztd3+Zesb2lm2+r6uX4prV2eUByuxJNdt647/1KPRq5g==",
603 603
             "cpu": [
604 604
                 "arm64"
605 605
             ],
@@ -611,9 +611,9 @@
611 611
             ]
612 612
         },
613 613
         "node_modules/@rollup/rollup-freebsd-x64": {
614
-            "version": "4.26.0",
615
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.26.0.tgz",
616
-            "integrity": "sha512-A/jvfCZ55EYPsqeaAt/yDAG4q5tt1ZboWMHEvKAH9Zl92DWvMIbnZe/f/eOXze65aJaaKbL+YeM0Hz4kLQvdwg==",
614
+            "version": "4.27.2",
615
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.27.2.tgz",
616
+            "integrity": "sha512-duq21FoXwQtuws+V9H6UZ+eCBc7fxSpMK1GQINKn3fAyd9DFYKPJNcUhdIKOrMFjLEJgQskoMoiuizMt+dl20g==",
617 617
             "cpu": [
618 618
                 "x64"
619 619
             ],
@@ -625,9 +625,9 @@
625 625
             ]
626 626
         },
627 627
         "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
628
-            "version": "4.26.0",
629
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.26.0.tgz",
630
-            "integrity": "sha512-paHF1bMXKDuizaMODm2bBTjRiHxESWiIyIdMugKeLnjuS1TCS54MF5+Y5Dx8Ui/1RBPVRE09i5OUlaLnv8OGnA==",
628
+            "version": "4.27.2",
629
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.27.2.tgz",
630
+            "integrity": "sha512-6npqOKEPRZkLrMcvyC/32OzJ2srdPzCylJjiTJT2c0bwwSGm7nz2F9mNQ1WrAqCBZROcQn91Fno+khFhVijmFA==",
631 631
             "cpu": [
632 632
                 "arm"
633 633
             ],
@@ -639,9 +639,9 @@
639 639
             ]
640 640
         },
641 641
         "node_modules/@rollup/rollup-linux-arm-musleabihf": {
642
-            "version": "4.26.0",
643
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.26.0.tgz",
644
-            "integrity": "sha512-cwxiHZU1GAs+TMxvgPfUDtVZjdBdTsQwVnNlzRXC5QzIJ6nhfB4I1ahKoe9yPmoaA/Vhf7m9dB1chGPpDRdGXg==",
642
+            "version": "4.27.2",
643
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.27.2.tgz",
644
+            "integrity": "sha512-V9Xg6eXtgBtHq2jnuQwM/jr2mwe2EycnopO8cbOvpzFuySCGtKlPCI3Hj9xup/pJK5Q0388qfZZy2DqV2J8ftw==",
645 645
             "cpu": [
646 646
                 "arm"
647 647
             ],
@@ -653,9 +653,9 @@
653 653
             ]
654 654
         },
655 655
         "node_modules/@rollup/rollup-linux-arm64-gnu": {
656
-            "version": "4.26.0",
657
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.26.0.tgz",
658
-            "integrity": "sha512-4daeEUQutGRCW/9zEo8JtdAgtJ1q2g5oHaoQaZbMSKaIWKDQwQ3Yx0/3jJNmpzrsScIPtx/V+1AfibLisb3AMQ==",
656
+            "version": "4.27.2",
657
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.27.2.tgz",
658
+            "integrity": "sha512-uCFX9gtZJoQl2xDTpRdseYuNqyKkuMDtH6zSrBTA28yTfKyjN9hQ2B04N5ynR8ILCoSDOrG/Eg+J2TtJ1e/CSA==",
659 659
             "cpu": [
660 660
                 "arm64"
661 661
             ],
@@ -667,9 +667,9 @@
667 667
             ]
668 668
         },
669 669
         "node_modules/@rollup/rollup-linux-arm64-musl": {
670
-            "version": "4.26.0",
671
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.26.0.tgz",
672
-            "integrity": "sha512-eGkX7zzkNxvvS05ROzJ/cO/AKqNvR/7t1jA3VZDi2vRniLKwAWxUr85fH3NsvtxU5vnUUKFHKh8flIBdlo2b3Q==",
670
+            "version": "4.27.2",
671
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.27.2.tgz",
672
+            "integrity": "sha512-/PU9P+7Rkz8JFYDHIi+xzHabOu9qEWR07L5nWLIUsvserrxegZExKCi2jhMZRd0ATdboKylu/K5yAXbp7fYFvA==",
673 673
             "cpu": [
674 674
                 "arm64"
675 675
             ],
@@ -681,9 +681,9 @@
681 681
             ]
682 682
         },
683 683
         "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
684
-            "version": "4.26.0",
685
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.26.0.tgz",
686
-            "integrity": "sha512-Odp/lgHbW/mAqw/pU21goo5ruWsytP7/HCC/liOt0zcGG0llYWKrd10k9Fj0pdj3prQ63N5yQLCLiE7HTX+MYw==",
684
+            "version": "4.27.2",
685
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.27.2.tgz",
686
+            "integrity": "sha512-eCHmol/dT5odMYi/N0R0HC8V8QE40rEpkyje/ZAXJYNNoSfrObOvG/Mn+s1F/FJyB7co7UQZZf6FuWnN6a7f4g==",
687 687
             "cpu": [
688 688
                 "ppc64"
689 689
             ],
@@ -695,9 +695,9 @@
695 695
             ]
696 696
         },
697 697
         "node_modules/@rollup/rollup-linux-riscv64-gnu": {
698
-            "version": "4.26.0",
699
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.26.0.tgz",
700
-            "integrity": "sha512-MBR2ZhCTzUgVD0OJdTzNeF4+zsVogIR1U/FsyuFerwcqjZGvg2nYe24SAHp8O5sN8ZkRVbHwlYeHqcSQ8tcYew==",
698
+            "version": "4.27.2",
699
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.27.2.tgz",
700
+            "integrity": "sha512-DEP3Njr9/ADDln3kNi76PXonLMSSMiCir0VHXxmGSHxCxDfQ70oWjHcJGfiBugzaqmYdTC7Y+8Int6qbnxPBIQ==",
701 701
             "cpu": [
702 702
                 "riscv64"
703 703
             ],
@@ -709,9 +709,9 @@
709 709
             ]
710 710
         },
711 711
         "node_modules/@rollup/rollup-linux-s390x-gnu": {
712
-            "version": "4.26.0",
713
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.26.0.tgz",
714
-            "integrity": "sha512-YYcg8MkbN17fMbRMZuxwmxWqsmQufh3ZJFxFGoHjrE7bv0X+T6l3glcdzd7IKLiwhT+PZOJCblpnNlz1/C3kGQ==",
712
+            "version": "4.27.2",
713
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.27.2.tgz",
714
+            "integrity": "sha512-NHGo5i6IE/PtEPh5m0yw5OmPMpesFnzMIS/lzvN5vknnC1sXM5Z/id5VgcNPgpD+wHmIcuYYgW+Q53v+9s96lQ==",
715 715
             "cpu": [
716 716
                 "s390x"
717 717
             ],
@@ -723,9 +723,9 @@
723 723
             ]
724 724
         },
725 725
         "node_modules/@rollup/rollup-linux-x64-gnu": {
726
-            "version": "4.26.0",
727
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.26.0.tgz",
728
-            "integrity": "sha512-ZuwpfjCwjPkAOxpjAEjabg6LRSfL7cAJb6gSQGZYjGhadlzKKywDkCUnJ+KEfrNY1jH5EEoSIKLCb572jSiglA==",
726
+            "version": "4.27.2",
727
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.27.2.tgz",
728
+            "integrity": "sha512-PaW2DY5Tan+IFvNJGHDmUrORadbe/Ceh8tQxi8cmdQVCCYsLoQo2cuaSj+AU+YRX8M4ivS2vJ9UGaxfuNN7gmg==",
729 729
             "cpu": [
730 730
                 "x64"
731 731
             ],
@@ -737,9 +737,9 @@
737 737
             ]
738 738
         },
739 739
         "node_modules/@rollup/rollup-linux-x64-musl": {
740
-            "version": "4.26.0",
741
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.26.0.tgz",
742
-            "integrity": "sha512-+HJD2lFS86qkeF8kNu0kALtifMpPCZU80HvwztIKnYwym3KnA1os6nsX4BGSTLtS2QVAGG1P3guRgsYyMA0Yhg==",
740
+            "version": "4.27.2",
741
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.27.2.tgz",
742
+            "integrity": "sha512-dOlWEMg2gI91Qx5I/HYqOD6iqlJspxLcS4Zlg3vjk1srE67z5T2Uz91yg/qA8sY0XcwQrFzWWiZhMNERylLrpQ==",
743 743
             "cpu": [
744 744
                 "x64"
745 745
             ],
@@ -751,9 +751,9 @@
751 751
             ]
752 752
         },
753 753
         "node_modules/@rollup/rollup-win32-arm64-msvc": {
754
-            "version": "4.26.0",
755
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.26.0.tgz",
756
-            "integrity": "sha512-WUQzVFWPSw2uJzX4j6YEbMAiLbs0BUysgysh8s817doAYhR5ybqTI1wtKARQKo6cGop3pHnrUJPFCsXdoFaimQ==",
754
+            "version": "4.27.2",
755
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.27.2.tgz",
756
+            "integrity": "sha512-euMIv/4x5Y2/ImlbGl88mwKNXDsvzbWUlT7DFky76z2keajCtcbAsN9LUdmk31hAoVmJJYSThgdA0EsPeTr1+w==",
757 757
             "cpu": [
758 758
                 "arm64"
759 759
             ],
@@ -765,9 +765,9 @@
765 765
             ]
766 766
         },
767 767
         "node_modules/@rollup/rollup-win32-ia32-msvc": {
768
-            "version": "4.26.0",
769
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.26.0.tgz",
770
-            "integrity": "sha512-D4CxkazFKBfN1akAIY6ieyOqzoOoBV1OICxgUblWxff/pSjCA2khXlASUx7mK6W1oP4McqhgcCsu6QaLj3WMWg==",
768
+            "version": "4.27.2",
769
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.27.2.tgz",
770
+            "integrity": "sha512-RsnE6LQkUHlkC10RKngtHNLxb7scFykEbEwOFDjr3CeCMG+Rr+cKqlkKc2/wJ1u4u990urRHCbjz31x84PBrSQ==",
771 771
             "cpu": [
772 772
                 "ia32"
773 773
             ],
@@ -779,9 +779,9 @@
779 779
             ]
780 780
         },
781 781
         "node_modules/@rollup/rollup-win32-x64-msvc": {
782
-            "version": "4.26.0",
783
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.26.0.tgz",
784
-            "integrity": "sha512-2x8MO1rm4PGEP0xWbubJW5RtbNLk3puzAMaLQd3B3JHVw4KcHlmXcO+Wewx9zCoo7EUFiMlu/aZbCJ7VjMzAag==",
782
+            "version": "4.27.2",
783
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.27.2.tgz",
784
+            "integrity": "sha512-foJM5vv+z2KQmn7emYdDLyTbkoO5bkHZE1oth2tWbQNGW7mX32d46Hz6T0MqXdWS2vBZhaEtHqdy9WYwGfiliA==",
785 785
             "cpu": [
786 786
                 "x64"
787 787
             ],
@@ -1187,9 +1187,9 @@
1187 1187
             "license": "MIT"
1188 1188
         },
1189 1189
         "node_modules/electron-to-chromium": {
1190
-            "version": "1.5.59",
1191
-            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.59.tgz",
1192
-            "integrity": "sha512-faAXB6+gEbC8FsiRdpOXgOe4snP49YwjiXynEB8Mp7sUx80W5eN+BnnBHJ/F7eIeLzs+QBfDD40bJMm97oEFcw==",
1190
+            "version": "1.5.62",
1191
+            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.62.tgz",
1192
+            "integrity": "sha512-t8c+zLmJHa9dJy96yBZRXGQYoiCEnHYgFwn1asvSPZSUdVxnB62A4RASd7k41ytG3ErFBA0TpHlKg9D9SQBmLg==",
1193 1193
             "dev": true,
1194 1194
             "license": "ISC"
1195 1195
         },
@@ -2199,9 +2199,9 @@
2199 2199
             }
2200 2200
         },
2201 2201
         "node_modules/rollup": {
2202
-            "version": "4.26.0",
2203
-            "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.26.0.tgz",
2204
-            "integrity": "sha512-ilcl12hnWonG8f+NxU6BlgysVA0gvY2l8N0R84S1HcINbW20bvwuCngJkkInV6LXhwRpucsW5k1ovDwEdBVrNg==",
2202
+            "version": "4.27.2",
2203
+            "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.27.2.tgz",
2204
+            "integrity": "sha512-KreA+PzWmk2yaFmZVwe6GB2uBD86nXl86OsDkt1bJS9p3vqWuEQ6HnJJ+j/mZi/q0920P99/MVRlB4L3crpF5w==",
2205 2205
             "dev": true,
2206 2206
             "license": "MIT",
2207 2207
             "dependencies": {
@@ -2215,24 +2215,24 @@
2215 2215
                 "npm": ">=8.0.0"
2216 2216
             },
2217 2217
             "optionalDependencies": {
2218
-                "@rollup/rollup-android-arm-eabi": "4.26.0",
2219
-                "@rollup/rollup-android-arm64": "4.26.0",
2220
-                "@rollup/rollup-darwin-arm64": "4.26.0",
2221
-                "@rollup/rollup-darwin-x64": "4.26.0",
2222
-                "@rollup/rollup-freebsd-arm64": "4.26.0",
2223
-                "@rollup/rollup-freebsd-x64": "4.26.0",
2224
-                "@rollup/rollup-linux-arm-gnueabihf": "4.26.0",
2225
-                "@rollup/rollup-linux-arm-musleabihf": "4.26.0",
2226
-                "@rollup/rollup-linux-arm64-gnu": "4.26.0",
2227
-                "@rollup/rollup-linux-arm64-musl": "4.26.0",
2228
-                "@rollup/rollup-linux-powerpc64le-gnu": "4.26.0",
2229
-                "@rollup/rollup-linux-riscv64-gnu": "4.26.0",
2230
-                "@rollup/rollup-linux-s390x-gnu": "4.26.0",
2231
-                "@rollup/rollup-linux-x64-gnu": "4.26.0",
2232
-                "@rollup/rollup-linux-x64-musl": "4.26.0",
2233
-                "@rollup/rollup-win32-arm64-msvc": "4.26.0",
2234
-                "@rollup/rollup-win32-ia32-msvc": "4.26.0",
2235
-                "@rollup/rollup-win32-x64-msvc": "4.26.0",
2218
+                "@rollup/rollup-android-arm-eabi": "4.27.2",
2219
+                "@rollup/rollup-android-arm64": "4.27.2",
2220
+                "@rollup/rollup-darwin-arm64": "4.27.2",
2221
+                "@rollup/rollup-darwin-x64": "4.27.2",
2222
+                "@rollup/rollup-freebsd-arm64": "4.27.2",
2223
+                "@rollup/rollup-freebsd-x64": "4.27.2",
2224
+                "@rollup/rollup-linux-arm-gnueabihf": "4.27.2",
2225
+                "@rollup/rollup-linux-arm-musleabihf": "4.27.2",
2226
+                "@rollup/rollup-linux-arm64-gnu": "4.27.2",
2227
+                "@rollup/rollup-linux-arm64-musl": "4.27.2",
2228
+                "@rollup/rollup-linux-powerpc64le-gnu": "4.27.2",
2229
+                "@rollup/rollup-linux-riscv64-gnu": "4.27.2",
2230
+                "@rollup/rollup-linux-s390x-gnu": "4.27.2",
2231
+                "@rollup/rollup-linux-x64-gnu": "4.27.2",
2232
+                "@rollup/rollup-linux-x64-musl": "4.27.2",
2233
+                "@rollup/rollup-win32-arm64-msvc": "4.27.2",
2234
+                "@rollup/rollup-win32-ia32-msvc": "4.27.2",
2235
+                "@rollup/rollup-win32-x64-msvc": "4.27.2",
2236 2236
                 "fsevents": "~2.3.2"
2237 2237
             }
2238 2238
         },

+ 9
- 1
resources/data/lang/en.json Näytä tiedosto

@@ -189,5 +189,13 @@
189 189
     "Edit": "Edit",
190 190
     "Notes": "Notes",
191 191
     "Terms": "Terms",
192
-    "Ending Balance": "Ending Balance"
192
+    "Ending Balance": "Ending Balance",
193
+    "Default :Type :Category": "Default :Type :Category",
194
+    "Category": "Category",
195
+    "Configuration": "Configuration",
196
+    "Dates": "Dates",
197
+    "Adjustment Details": "Adjustment Details",
198
+    "Adjustments": "Adjustments",
199
+    "Sellable Configuration": "Sellable Configuration",
200
+    "Purchasable Configuration": "Purchasable Configuration"
193 201
 }

+ 8
- 0
resources/views/filament/company/components/tables/columns/offering-status.blade.php Näytä tiedosto

@@ -0,0 +1,8 @@
1
+<div class="flex items-center space-x-2 text-sm leading-6">
2
+    <span>{{ $getState() }}</span>
3
+    @if ($getRecord()->income_account_id && $getRecord()->expense_account_id)
4
+        <x-filament::badge>
5
+            Sell & Buy
6
+        </x-filament::badge>
7
+    @endif
8
+</div>

+ 1
- 1
resources/views/filament/company/pages/accounting/chart.blade.php Näytä tiedosto

@@ -76,7 +76,7 @@
76 76
                                         </td>
77 77
                                         <td colspan="1" class="es-table__cell px-4 py-4">
78 78
                                             <div>
79
-                                                @if($account->default === false)
79
+                                                @if($account->default === false && !$account->adjustment)
80 80
                                                     {{ ($this->editChartAction)(['chart' => $account->id]) }}
81 81
                                                 @endif
82 82
                                             </div>

Loading…
Peruuta
Tallenna