Skip to content

Commit

Permalink
Merge pull request #350 from liberu-accounting/sweep/Add-Tax-Rate-Man…
Browse files Browse the repository at this point in the history
…agement-and-Invoice-Tax-Calculation-Features

Add Tax Rate Management and Invoice Tax Calculation Features
  • Loading branch information
curtisdelicata authored Dec 24, 2024
2 parents a87ea48 + 265cf28 commit 3679aab
Show file tree
Hide file tree
Showing 5 changed files with 220 additions and 1 deletion.
25 changes: 24 additions & 1 deletion app/Filament/App/Resources/InvoiceResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,30 @@ public static function form(Form $form): Form
->label('Customer'),
DatePicker::make('invoice_date'),
TextInput::make('total_amount')
->numeric(),
->numeric()
->reactive()
->afterStateUpdated(function ($state, callable $set, $get) {
if ($get('tax_rate_id')) {
$taxRate = TaxRate::find($get('tax_rate_id'));
$taxAmount = $state * ($taxRate->rate / 100);
$set('tax_amount', $taxAmount);
}
}),
BelongsToSelect::make('tax_rate_id')
->relationship('taxRate', 'name')
->label('Tax Rate')
->reactive()
->afterStateUpdated(function ($state, callable $set, $get) {
if ($state && $get('total_amount')) {
$taxRate = TaxRate::find($state);
$taxAmount = $get('total_amount') * ($taxRate->rate / 100);
$set('tax_amount', $taxAmount);
}
}),
TextInput::make('tax_amount')
->numeric()
->disabled()
->label('Tax Amount'),
Select::make('payment_status')
->options([
'pending' => 'Pending',
Expand Down
82 changes: 82 additions & 0 deletions app/Filament/App/Resources/TaxRateResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@


<?php

namespace App\Filament\App\Resources;

use App\Models\TaxRate;
use Filament\Forms;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Forms\Form;
use Filament\Tables\Table;

class TaxRateResource extends Resource
{
protected static ?string $model = TaxRate::class;

protected static ?string $navigationIcon = 'heroicon-o-calculator';

public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('name')
->required()
->maxLength(255),
Forms\Components\TextInput::make('rate')
->required()
->numeric()
->step(0.01)
->suffix('%'),
Forms\Components\Textarea::make('description')
->maxLength(65535),
Forms\Components\Toggle::make('is_compound')
->label('Compound Tax')
->helperText('Apply this tax after other taxes'),
Forms\Components\Toggle::make('is_active')
->label('Active')
->default(true),
]);
}

public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('name')
->searchable(),
Tables\Columns\TextColumn::make('rate')
->suffix('%')
->sortable(),
Tables\Columns\IconColumn::make('is_active')
->boolean(),
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
Tables\Filters\TernaryFilter::make('is_active')
->label('Active'),
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}

public static function getPages(): array
{
return [
'index' => Pages\ListTaxRates::route('/'),
'create' => Pages\CreateTaxRate::route('/create'),
'edit' => Pages\EditTaxRate::route('/{record}/edit'),
];
}
}
28 changes: 28 additions & 0 deletions app/Models/Invoice.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,39 @@ class Invoice extends Model
"customer_id",
"invoice_date",
"total_amount",
"tax_amount",
"tax_rate_id",
"payment_status"
];

protected $casts = [
'total_amount' => 'decimal:2',
'tax_amount' => 'decimal:2',
];

public function customer()
{
return $this->belongsTo(Customer::class);
}

public function taxRate()
{
return $this->belongsTo(TaxRate::class);
}

public function calculateTax()
{
if (!$this->taxRate) {
return 0;
}

$taxAmount = $this->total_amount * ($this->taxRate->rate / 100);
$this->tax_amount = $taxAmount;
return $taxAmount;
}

public function getTotalWithTax()
{
return $this->total_amount + $this->tax_amount;
}
}
44 changes: 44 additions & 0 deletions app/Models/TaxRate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@


<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class TaxRate extends Model
{
use HasFactory;

protected $primaryKey = 'tax_rate_id';

protected $fillable = [
'name',
'rate',
'description',
'is_compound',
'is_active'
];

protected $casts = [
'rate' => 'float',
'is_compound' => 'boolean',
'is_active' => 'boolean'
];

public function invoices()
{
return $this->hasMany(Invoice::class);
}

public function customers()
{
return $this->belongsToMany(Customer::class);
}

public function suppliers()
{
return $this->belongsToMany(Supplier::class);
}
}
42 changes: 42 additions & 0 deletions database/migrations/2024_01_10_000000_create_tax_rates_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@


<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
public function up()
{
Schema::create('tax_rates', function (Blueprint $table) {
$table->id('tax_rate_id');
$table->string('name');
$table->decimal('rate', 5, 2);
$table->text('description')->nullable();
$table->boolean('is_compound')->default(false);
$table->boolean('is_active')->default(true);
$table->timestamps();
});

Schema::create('customer_tax_rate', function (Blueprint $table) {
$table->foreignId('customer_id')->constrained('customers', 'customer_id');
$table->foreignId('tax_rate_id')->constrained('tax_rates', 'tax_rate_id');
$table->primary(['customer_id', 'tax_rate_id']);
});

Schema::create('supplier_tax_rate', function (Blueprint $table) {
$table->foreignId('supplier_id')->constrained('suppliers', 'supplier_id');
$table->foreignId('tax_rate_id')->constrained('tax_rates', 'tax_rate_id');
$table->primary(['supplier_id', 'tax_rate_id']);
});
}

public function down()
{
Schema::dropIfExists('supplier_tax_rate');
Schema::dropIfExists('customer_tax_rate');
Schema::dropIfExists('tax_rates');
}
};

0 comments on commit 3679aab

Please sign in to comment.