Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions database/migrations/2025_07_24_092819_create_tax_classes_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

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

return new class extends Migration
{
public function up(): void
{
Schema::create('pim_tax_classes', function (Blueprint $table) {
$table->id();

if (config('eclipse-catalogue.tenancy.model')) {
$tenantClass = config('eclipse-catalogue.tenancy.model');
/** @var \Illuminate\Database\Eloquent\Model $tenant */
$tenant = new $tenantClass;
$table->foreignId(config('eclipse-catalogue.tenancy.foreign_key'))
->constrained($tenant->getTable(), $tenant->getKeyName())
->cascadeOnUpdate()
->cascadeOnDelete();
}

$table->decimal('rate', total: 5);
$table->boolean('is_default')
->default(false);
$table->timestamps();
$table->softDeletes();
});
}

public function down(): void
{
Schema::dropIfExists('pim_tax_classes');
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

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

return new class extends Migration
{
public function up(): void
{
Schema::table('pim_tax_classes', function (Blueprint $table) {
$table->string('name')->after('id');
$table->text('description')->nullable()->after('name');
});
}

public function down(): void
{
Schema::table('pim_tax_classes', function (Blueprint $table) {
$table->dropColumn(['name', 'description']);
});
}
};
16 changes: 16 additions & 0 deletions resources/lang/en/tax-class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

return [
'singular' => 'Tax class',
'plural' => 'Tax classes',
'fields' => [
'name' => 'Name',
'description' => 'Description',
'rate' => 'Rate (%)',
'is_default' => 'Default class',
],
'messages' => [
'default_class_help' => 'Only one class can be set as default',
'cannot_delete_default' => 'Cannot delete the default tax class.',
],
];
16 changes: 16 additions & 0 deletions resources/lang/sl/tax-class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

return [
'singular' => 'Davčni razred',
'plural' => 'Davčni razredi',
'fields' => [
'name' => 'Ime',
'description' => 'Opis',
'rate' => 'Stopnja (%)',
'is_default' => 'Privzeti razred',
],
'messages' => [
'default_class_help' => 'Samo en razred je lahko nastavljen kot privzet',
'cannot_delete_default' => 'Privzetega davčnega razreda ni mogoče izbrisati.',
],
];
182 changes: 182 additions & 0 deletions src/Filament/Resources/TaxClassResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
<?php

namespace Eclipse\Catalogue\Filament\Resources;

use BezhanSalleh\FilamentShield\Contracts\HasShieldPermissions;
use Eclipse\Catalogue\Filament\Resources\TaxClassResource\Pages;
use Eclipse\Catalogue\Models\TaxClass;
use Filament\Facades\Filament;
use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables\Actions\DeleteAction;
use Filament\Tables\Actions\EditAction;
use Filament\Tables\Actions\ForceDeleteAction;
use Filament\Tables\Actions\RestoreAction;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\TrashedFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;

class TaxClassResource extends Resource implements HasShieldPermissions
{
protected static ?string $model = TaxClass::class;

protected static ?string $slug = 'tax-classes';

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

protected static ?string $navigationGroup = 'Catalogue';

protected static ?string $recordTitleAttribute = 'name';

protected static bool $isScopedToTenant = true;

protected static ?string $tenantOwnershipRelationshipName = 'tenant';

public static function getModelLabel(): string
{
return __('eclipse-catalogue::tax-class.singular');
}

public static function getPluralModelLabel(): string
{
return __('eclipse-catalogue::tax-class.plural');
}

public static function form(Form $form): Form
{
return $form
->schema([
TextInput::make('name')
->label(__('eclipse-catalogue::tax-class.fields.name'))
->required()
->maxLength(255)
->unique(
table: 'pim_tax_classes',
column: 'name',
ignoreRecord: true,
modifyRuleUsing: function ($rule) {
// Add tenant scope to unique validation
$tenantFK = config('eclipse-catalogue.tenancy.foreign_key');
$tenantId = Filament::getTenant()?->id;
if ($tenantFK && $tenantId) {
$rule->where($tenantFK, $tenantId);
}

return $rule;
}
),

Textarea::make('description')
->label(__('eclipse-catalogue::tax-class.fields.description'))
->rows(3)
->maxLength(65535),

TextInput::make('rate')
->label(__('eclipse-catalogue::tax-class.fields.rate'))
->required()
->numeric()
->minValue(0)
->maxValue(100)
->step(0.01)
->suffix('%'),

Toggle::make('is_default')
->label(__('eclipse-catalogue::tax-class.fields.is_default'))
->helperText(__('eclipse-catalogue::tax-class.messages.default_class_help')),

Placeholder::make('created_at')
->label('Created Date')
->content(fn (?TaxClass $record): string => $record?->created_at?->diffForHumans() ?? '-'),

Placeholder::make('updated_at')
->label('Last Modified Date')
->content(fn (?TaxClass $record): string => $record?->updated_at?->diffForHumans() ?? '-'),
]);
}

public static function table(Table $table): Table
{
return $table
->columns([
TextColumn::make('id')
->sortable(),

TextColumn::make('name')
->searchable()
->sortable(),

TextColumn::make('description')
->searchable()
->limit(50)
->toggleable(isToggledHiddenByDefault: true),

TextColumn::make('rate')
->suffix('%')
->sortable(),

IconColumn::make('is_default')
->label('Default')
->boolean()
->sortable(),

TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),

TextColumn::make('updated_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
TrashedFilter::make(),
])
->actions([
EditAction::make(),
DeleteAction::make(),
RestoreAction::make(),
ForceDeleteAction::make(),
]);
}

public static function getPages(): array
{
return [
'index' => Pages\ListTaxClasses::route('/'),
'create' => Pages\CreateTaxClass::route('/create'),
'edit' => Pages\EditTaxClass::route('/{record}/edit'),
];
}

public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()
->withoutGlobalScopes([
SoftDeletingScope::class,
]);
}

public static function getPermissionPrefixes(): array
{
return [
'view_any',
'view',
'create',
'update',
'restore',
'restore_any',
'delete',
'delete_any',
'force_delete',
'force_delete_any',
];
}
}
41 changes: 41 additions & 0 deletions src/Filament/Resources/TaxClassResource/Pages/CreateTaxClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Eclipse\Catalogue\Filament\Resources\TaxClassResource\Pages;

use Eclipse\Catalogue\Filament\Resources\TaxClassResource;
use Eclipse\Catalogue\Models\TaxClass;
use Filament\Facades\Filament;
use Filament\Resources\Pages\CreateRecord;

class CreateTaxClass extends CreateRecord
{
protected static string $resource = TaxClassResource::class;

protected function mutateFormDataBeforeCreate(array $data): array
{
// If this class is being set as default, unset all other defaults within the same tenant
if ($data['is_default'] ?? false) {
$query = TaxClass::where('is_default', true);

// Add tenant scope if tenancy is configured
$tenantFK = config('eclipse-catalogue.tenancy.foreign_key');
$tenantId = Filament::getTenant()?->id;
if ($tenantFK && $tenantId) {
$query->where($tenantFK, $tenantId);
}

$query->update(['is_default' => false]);
}

// Auto-set current tenant_id if tenancy is configured
$tenantFK = config('eclipse-catalogue.tenancy.foreign_key');
$tenantId = Filament::getTenant()?->id;
if ($tenantFK && $tenantId) {
$data[$tenantFK] = $tenantId;
} elseif ($tenantFK) {
throw new \Exception('Current tenant not available. Cannot create TaxClass without tenant context.');
}

return $data;
}
}
57 changes: 57 additions & 0 deletions src/Filament/Resources/TaxClassResource/Pages/EditTaxClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

namespace Eclipse\Catalogue\Filament\Resources\TaxClassResource\Pages;

use Eclipse\Catalogue\Filament\Resources\TaxClassResource;
use Eclipse\Catalogue\Models\TaxClass;
use Filament\Actions\DeleteAction;
use Filament\Actions\ForceDeleteAction;
use Filament\Actions\RestoreAction;
use Filament\Facades\Filament;
use Filament\Resources\Pages\EditRecord;

class EditTaxClass extends EditRecord
{
protected static string $resource = TaxClassResource::class;

protected function getHeaderActions(): array
{
return [
DeleteAction::make(),
ForceDeleteAction::make(),
RestoreAction::make(),
];
}

protected function mutateFormDataBeforeSave(array $data): array
{
// If this class is being set as default, unset all other defaults within the same tenant
if ($data['is_default'] ?? false) {
$query = TaxClass::where('is_default', true)
->where('id', '!=', $this->record->id);

// Add tenant scope if tenancy is configured
$tenantFK = config('eclipse-catalogue.tenancy.foreign_key');
$tenantId = $this->record->getAttribute($tenantFK);
if ($tenantFK && $tenantId) {
$query->where($tenantFK, $tenantId);
}

$query->update(['is_default' => false]);
}

// Ensure tenant id is preserved if tenancy is configured
$tenantFK = config('eclipse-catalogue.tenancy.foreign_key');
if ($tenantFK && ! isset($data[$tenantFK])) {
// Use current tenant from Filament or preserve existing
$tenantId = Filament::getTenant()?->id;
if ($tenantId) {
$data[$tenantFK] = $tenantId;
} else {
$data[$tenantFK] = $this->record->getAttribute($tenantFK);
}
}

return $data;
}
}
19 changes: 19 additions & 0 deletions src/Filament/Resources/TaxClassResource/Pages/ListTaxClasses.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Eclipse\Catalogue\Filament\Resources\TaxClassResource\Pages;

use Eclipse\Catalogue\Filament\Resources\TaxClassResource;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;

class ListTaxClasses extends ListRecords
{
protected static string $resource = TaxClassResource::class;

protected function getHeaderActions(): array
{
return [
CreateAction::make(),
];
}
}
Loading