From 75bcf2b779f157e93732b33c1a9602b2487396ac Mon Sep 17 00:00:00 2001 From: Nisse Lommerde Date: Tue, 14 Jan 2025 17:17:04 -0500 Subject: [PATCH] WIP Tax Rates --- .../Resources/CustomerReportResource.php | 38 ++++--- .../Admin/Resources/InvoiceResource.php | 7 +- .../OrderResource/Pages/EditOrder.php | 20 +++- .../Admin/Resources/TaxRateResource.php | 100 ++++++++++++++++++ .../TaxRateResource/Pages/CreateTaxRate.php | 11 ++ .../TaxRateResource/Pages/EditTaxRate.php | 19 ++++ .../TaxRateResource/Pages/ListTaxRates.php | 19 ++++ app/Filament/Admin/Resources/TaxResource.php | 71 ------------- .../Resources/TaxResource/Pages/CreateTax.php | 11 -- .../Resources/TaxResource/Pages/EditTax.php | 19 ---- .../Resources/TaxResource/Pages/ListTaxes.php | 19 ---- app/Models/Invoice.php | 12 ++- app/Models/TaxRate.php | 14 +++ database/factories/InvoiceFactory.php | 3 + database/factories/TaxRateFactory.php | 23 ++++ .../migrations/1_create_tax_rates_table.php | 29 +++++ ...024_09_08_163053_create_invoices_table.php | 3 + database/seeders/DatabaseSeeder.php | 1 + database/seeders/TaxRateSeeder.php | 18 ++++ 19 files changed, 289 insertions(+), 148 deletions(-) create mode 100644 app/Filament/Admin/Resources/TaxRateResource.php create mode 100644 app/Filament/Admin/Resources/TaxRateResource/Pages/CreateTaxRate.php create mode 100644 app/Filament/Admin/Resources/TaxRateResource/Pages/EditTaxRate.php create mode 100644 app/Filament/Admin/Resources/TaxRateResource/Pages/ListTaxRates.php delete mode 100644 app/Filament/Admin/Resources/TaxResource.php delete mode 100644 app/Filament/Admin/Resources/TaxResource/Pages/CreateTax.php delete mode 100644 app/Filament/Admin/Resources/TaxResource/Pages/EditTax.php delete mode 100644 app/Filament/Admin/Resources/TaxResource/Pages/ListTaxes.php create mode 100644 app/Models/TaxRate.php create mode 100644 database/factories/TaxRateFactory.php create mode 100644 database/migrations/1_create_tax_rates_table.php create mode 100644 database/seeders/TaxRateSeeder.php diff --git a/app/Filament/Admin/Resources/CustomerReportResource.php b/app/Filament/Admin/Resources/CustomerReportResource.php index 76e340c..e3f7a6b 100644 --- a/app/Filament/Admin/Resources/CustomerReportResource.php +++ b/app/Filament/Admin/Resources/CustomerReportResource.php @@ -11,7 +11,6 @@ use Filament\Tables\Columns\Summarizers\Summarizer; use Filament\Tables\Table; use Illuminate\Database\Eloquent\Model; -use Illuminate\Database\Query\Builder; class CustomerReportResource extends Resource { @@ -45,14 +44,13 @@ public static function table(Table $table): Table Tables\Columns\TextColumn::make('subtotal') ->money() - ->summarize(Summarizer::make()->using(function (Builder $query, Table $table) { - return '$'. - number_format( - round(Invoice::whereBetween('date', [ - $table->getFilter('created_at')->getState()['created_at'] ?? '1900-01-01', - $table->getFilter('created_until')->getState()['created_until'] ?? '2100-01-01', - ])->sum('subtotal'), 2), 2, '.', ','); + ->summarize(Summarizer::make()->using(function ($query, Table $table) { + $createdAt = $table->getfilter('created_at')->getstate()['created_at'] ?? '1900-01-01'; + $createdUntil = $table->getfilter('created_until')->getstate()['created_until'] ?? '2100-01-01'; + $invoiceSum = invoice::wherebetween('date', [$createdAt, $createdUntil])->sum('subtotal'); + + return '$'.number_format(round($invoiceSum, 2), 2, '.', ','); })) ->alignRight() ->getStateUsing(function (Table $table, Model $record) { @@ -77,23 +75,23 @@ public static function table(Table $table): Table ->label('PST') ->money() ->alignRight() - ->getStateUsing(function (Table $table, Model $record) { - return $record->getPstAttribute( - $table->getFilter('created_at')->getState()['created_at'], - $table->getFilter('created_until')->getState()['created_until'] - ); + ->getStateUsing(function (Table $table, Customer $record) { + // return $record->invoices()->; + // return $record->getPstAttribute( + // $table->getFilter('created_at')->getState()['created_at'], + // $table->getFilter('created_until')->getState()['created_until'] + // ); }), Tables\Columns\TextColumn::make('total') ->money() - ->summarize(Summarizer::make()->using(function (Builder $query, Table $table) { - return '$'. - number_format( - round(Invoice::whereBetween('date', [ - $table->getFilter('created_at')->getState()['created_at'] ?? '1900-01-01', - $table->getFilter('created_until')->getState()['created_until'] ?? '2100-01-01', - ])->sum('total'), 2), 2, '.', ','); + ->summarize(summarizer::make()->using(function ($query, table $table) { + $createdAt = $table->getfilter('created_at')->getstate()['created_at'] ?? '1900-01-01'; + $createdUntil = $table->getfilter('created_until')->getstate()['created_until'] ?? '2100-01-01'; + $invoiceSum = invoice::wherebetween('date', [$createdAt, $createdUntil])->sum('total'); + + return '$'.number_format(round($invoiceSum, 2), 2, '.', ','); })) ->weight('bold') ->alignRight() diff --git a/app/Filament/Admin/Resources/InvoiceResource.php b/app/Filament/Admin/Resources/InvoiceResource.php index 1d14fab..c522229 100644 --- a/app/Filament/Admin/Resources/InvoiceResource.php +++ b/app/Filament/Admin/Resources/InvoiceResource.php @@ -95,12 +95,15 @@ public static function form(Form $form): Form Section::make() ->schema([ Placeholder::make('created_at') - ->label('Created at') + ->label('Created') ->content(fn (Invoice $record): ?string => $record->created_at?->diffForHumans()), Placeholder::make('updated_at') - ->label('Last modified at') + ->label('Last modified') ->content(fn (Invoice $record): ?string => $record->updated_at?->diffForHumans()), + + Placeholder::make('Tax Rates') + ->content(fn (Invoice $record): ?string => $record->gst_rate.'% GST, '.$record->pst_rate.'% PST'), ]) ->columnSpan(1) ->hidden(fn (?Invoice $record) => $record === null), diff --git a/app/Filament/Admin/Resources/OrderResource/Pages/EditOrder.php b/app/Filament/Admin/Resources/OrderResource/Pages/EditOrder.php index 3f892a0..569e5e0 100644 --- a/app/Filament/Admin/Resources/OrderResource/Pages/EditOrder.php +++ b/app/Filament/Admin/Resources/OrderResource/Pages/EditOrder.php @@ -3,6 +3,7 @@ namespace App\Filament\Admin\Resources\OrderResource\Pages; use App\Enums\OrderAttributes; +use App\Enums\OrderStatus; use App\Filament\Admin\Resources\OrderResource; use App\Models\Order; use App\Models\OrderProduct; @@ -148,7 +149,9 @@ protected function getHeaderActions(): array ->label('Save changes') ->action('save') ->icon('lucide-save'), + Actions\ReplicateAction::make() + ->label('Duplicate') ->icon('lucide-copy') ->color('info') ->mutateRecordDataUsing(function (array $data): array { @@ -157,12 +160,27 @@ protected function getHeaderActions(): array return $data; }) - ->beforeReplicaSaved(function (Model $replica): void {}) + ->beforeReplicaSaved(function (Order $replica): void { + $replica->customer_po = 'Repeat of '.$replica->customer_po; + $replica->status = OrderStatus::DRAFT; + $replica->printed = false; + $replica->pre_production = false; + $replica->order_date = today(); + $replica->due_date = today()->addDays(10); + $replica->save(); + }) ->successRedirectUrl(fn (Model $replica): string => OrderResource::getUrl('edit', [$replica])), + + // Action::make('invoice') + // ->visible(fn () => auth()->user()->is_admin) + // ->label('To Invoice') + // ->icon('lucide-receipt-text'), + // Action::make('print') ->icon('lucide-printer') ->url(fn (Order $record) => route('orders.pdf', $record)) ->openUrlInNewTab(), + Actions\DeleteAction::make() ->icon('lucide-trash-2'), ]; diff --git a/app/Filament/Admin/Resources/TaxRateResource.php b/app/Filament/Admin/Resources/TaxRateResource.php new file mode 100644 index 0000000..b5f3468 --- /dev/null +++ b/app/Filament/Admin/Resources/TaxRateResource.php @@ -0,0 +1,100 @@ +schema([ + Section::make([ + TextInput::make('name') + ->disabledOn('edit'), + TextInput::make('value') + ->label('Value in percentage') + ->numeric() + ->prefix('%'), + ]) + ->columns(1) + ->columnSpan(2), + + Section::make() + ->schema([ + Placeholder::make('created_at') + ->label('Created') + ->content(fn (TaxRate $record): ?string => $record->created_at?->diffForHumans()), + + Placeholder::make('updated_at') + ->label('Last modified') + ->content(fn (TaxRate $record): ?string => $record->updated_at?->diffForHumans()), + ]) + ->columnSpan(1) + ->hidden(fn (?TaxRate $record) => $record === null), + ])->columns(3); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + TextColumn::make('name') + ->weight(FontWeight::Bold), + TextColumn::make('value') + ->extraHeaderAttributes(['class' => 'w-full']) + ->suffix(' %'), + ]) + ->filters([ + // + ]) + ->actions([ + Tables\Actions\EditAction::make(), + ]) + ->bulkActions([ + Tables\Actions\BulkActionGroup::make([ + Tables\Actions\DeleteBulkAction::make(), + ]), + ]); + } + + public static function getRelations(): array + { + return [ + // + ]; + } + + public static function canAccess(): bool + { + return auth()->user()->is_admin; + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListTaxRates::route('/'), + 'create' => Pages\CreateTaxRate::route('/create'), + 'edit' => Pages\EditTaxRate::route('/{record}/edit'), + ]; + } +} diff --git a/app/Filament/Admin/Resources/TaxRateResource/Pages/CreateTaxRate.php b/app/Filament/Admin/Resources/TaxRateResource/Pages/CreateTaxRate.php new file mode 100644 index 0000000..ac778a6 --- /dev/null +++ b/app/Filament/Admin/Resources/TaxRateResource/Pages/CreateTaxRate.php @@ -0,0 +1,11 @@ +schema([ - // - ]); - } - - public static function table(Table $table): Table - { - return $table - ->columns([ - // - ]) - ->filters([ - // - ]) - ->actions([ - Tables\Actions\EditAction::make(), - ]) - ->bulkActions([ - Tables\Actions\BulkActionGroup::make([ - Tables\Actions\DeleteBulkAction::make(), - ]), - ]); - } - - public static function canAccess(): bool - { - return auth()->user()->is_admin; - } - - public static function getRelations(): array - { - return [ - // - ]; - } - - public static function getPages(): array - { - return [ - 'index' => Pages\ListTaxes::route('/'), - 'create' => Pages\CreateTax::route('/create'), - 'edit' => Pages\EditTax::route('/{record}/edit'), - ]; - } -} diff --git a/app/Filament/Admin/Resources/TaxResource/Pages/CreateTax.php b/app/Filament/Admin/Resources/TaxResource/Pages/CreateTax.php deleted file mode 100644 index c9338fe..0000000 --- a/app/Filament/Admin/Resources/TaxResource/Pages/CreateTax.php +++ /dev/null @@ -1,11 +0,0 @@ -attributes['internal_id'] = 'TN4'.str_pad($model->id, 4, '0', STR_PAD_LEFT); + $model->attributes['pst_rate'] = TaxRate::where('name', 'PST')->value('value'); + $model->attributes['gst_rate'] = TaxRate::where('name', 'GST')->value('value'); $model->save(); }); } @@ -64,11 +68,9 @@ public function setGstAttribute(int $value): void $this->save(); $this->calculateTotals(); - - // dd('value: '.$value.', model: '.$this->gst); } - public function setStatus(InvoiceStatus $status) + public function setStatus(InvoiceStatus $status): void { if ($this->status !== $status) { $this->status = $status; @@ -93,7 +95,7 @@ public function calculateTotals(): void public function getGstAmountAttribute(): float { if ($this->gst) { - return number_format($this->subtotal * 0.05, 2); + return round($this->subtotal * ($this->gst_rate / 100), 2); } return 0.00; @@ -102,7 +104,7 @@ public function getGstAmountAttribute(): float public function getPstAmountAttribute(): float { if ($this->pst) { - return number_format($this->subtotal * 0.07, 2); + return round($this->subtotal * ($this->pst_rate / 100), 2); } return 0.00; diff --git a/app/Models/TaxRate.php b/app/Models/TaxRate.php new file mode 100644 index 0000000..6a9a757 --- /dev/null +++ b/app/Models/TaxRate.php @@ -0,0 +1,14 @@ + */ + use HasFactory; + + protected $fillable = ['name', 'value']; +} diff --git a/database/factories/InvoiceFactory.php b/database/factories/InvoiceFactory.php index 1c87eb8..6befd1e 100644 --- a/database/factories/InvoiceFactory.php +++ b/database/factories/InvoiceFactory.php @@ -5,6 +5,7 @@ use App\Enums\InvoiceStatus; use App\Models\Customer; use App\Models\Invoice; +use App\Models\TaxRate; use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Support\Carbon; @@ -18,6 +19,8 @@ public function definition(): array return [ 'created_at' => Carbon::now()->subDays(rand(1, 30)), + 'pst_rate' => TaxRate::where('name', 'PST')->value('value'), + 'gst_rate' => TaxRate::where('name', 'GST')->value('value'), 'gst' => true, 'pst' => $this->faker->boolean(40), 'date' => Carbon::now()->subDays(rand(1, 60)), diff --git a/database/factories/TaxRateFactory.php b/database/factories/TaxRateFactory.php new file mode 100644 index 0000000..1a697b0 --- /dev/null +++ b/database/factories/TaxRateFactory.php @@ -0,0 +1,23 @@ + + */ +class TaxRateFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + // + ]; + } +} diff --git a/database/migrations/1_create_tax_rates_table.php b/database/migrations/1_create_tax_rates_table.php new file mode 100644 index 0000000..1d422d8 --- /dev/null +++ b/database/migrations/1_create_tax_rates_table.php @@ -0,0 +1,29 @@ +id(); + $table->string('name'); + $table->decimal('value', 8, 2); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('tax_rates'); + } +}; diff --git a/database/migrations/2024_09_08_163053_create_invoices_table.php b/database/migrations/2024_09_08_163053_create_invoices_table.php index 9e82534..58df7f7 100644 --- a/database/migrations/2024_09_08_163053_create_invoices_table.php +++ b/database/migrations/2024_09_08_163053_create_invoices_table.php @@ -19,6 +19,9 @@ public function up(): void $table->decimal('subtotal', 8, 2)->default(0.00); $table->decimal('total', 8, 2)->default(0.00); + $table->decimal('pst_rate', 8, 2); + $table->decimal('gst_rate', 8, 2); + $table->boolean('gst')->default(false); $table->boolean('pst')->default(false); diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 1462362..5756bbe 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -15,6 +15,7 @@ class DatabaseSeeder extends Seeder public function run(): void { $this->call([ + TaxRateSeeder::class, CustomerSeeder::class, ContactSeeder::class, ShippingEntrySeeder::class, diff --git a/database/seeders/TaxRateSeeder.php b/database/seeders/TaxRateSeeder.php new file mode 100644 index 0000000..639cd03 --- /dev/null +++ b/database/seeders/TaxRateSeeder.php @@ -0,0 +1,18 @@ + 'GST', 'value' => 5.00]); + TaxRate::create(['name' => 'PST', 'value' => 7.00]); + } +}