- Add trial balance and general ledger pages to client resource with interactive tables - Implement sales and expenses relation managers for client-specific transactions - Enhance transaction handling with proper tax and withholding calculations - Add date casting to Transaction model and define client relationships - Configure super admin role bypass in AppServiceProvider - Update Filament components and fix JavaScript formatting issues
143 lines
6.8 KiB
PHP
143 lines
6.8 KiB
PHP
<?php
|
|
|
|
namespace App\Filament\Resources\ClientResource\Pages;
|
|
|
|
use App\Filament\Resources\ClientResource;
|
|
use App\Models\Ledger;
|
|
use Filament\Resources\Pages\Page;
|
|
use Filament\Tables\Concerns\InteractsWithTable;
|
|
use Filament\Tables\Contracts\HasTable;
|
|
use Filament\Tables\Table;
|
|
use Filament\Tables\Columns\TextColumn;
|
|
use Filament\Tables\Filters\SelectFilter;
|
|
use Filament\Tables\Filters\Filter;
|
|
use Filament\Forms\Components\DatePicker;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Filament\Resources\Pages\Concerns\InteractsWithRecord;
|
|
use pxlrbt\FilamentExcel\Actions\Tables\ExportAction;
|
|
use pxlrbt\FilamentExcel\Exports\ExcelExport;
|
|
use pxlrbt\FilamentExcel\Columns\Column;
|
|
|
|
class GeneralLedger extends Page implements HasTable
|
|
{
|
|
use InteractsWithTable;
|
|
use InteractsWithRecord;
|
|
|
|
protected static string $resource = ClientResource::class;
|
|
|
|
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
|
|
|
protected static string $view = 'filament.resources.client-resource.pages.general-ledger';
|
|
|
|
public function mount(int | string $record): void
|
|
{
|
|
$this->record = $this->resolveRecord($record);
|
|
}
|
|
|
|
public function table(Table $table): Table
|
|
{
|
|
return $table
|
|
->query(
|
|
Ledger::query()
|
|
->where('client_id', $this->getRecord()->id)
|
|
->with(['account', 'transaction', 'journal'])
|
|
)
|
|
->columns([
|
|
TextColumn::make('date')
|
|
->label('Date')
|
|
->state(function (Ledger $record) {
|
|
return $record->transaction?->happened_on?->format('Y-m-d')
|
|
?? $record->journal?->happened_on?->format('Y-m-d')
|
|
?? $record->created_at->format('Y-m-d');
|
|
})
|
|
->sortable(),
|
|
TextColumn::make('account.account')
|
|
->label('Account')
|
|
->searchable()
|
|
->sortable(),
|
|
TextColumn::make('description')
|
|
->limit(50)
|
|
->tooltip(function (TextColumn $column): ?string {
|
|
$state = $column->getState();
|
|
if (strlen($state) <= $column->getCharacterLimit()) {
|
|
return null;
|
|
}
|
|
return $state;
|
|
}),
|
|
TextColumn::make('debit_amount')
|
|
->label('Debit')
|
|
->money('PHP')
|
|
->sortable(),
|
|
TextColumn::make('credit_amount')
|
|
->label('Credit')
|
|
->money('PHP')
|
|
->sortable(),
|
|
])
|
|
->filters([
|
|
SelectFilter::make('account')
|
|
->relationship('account', 'account', fn (Builder $query) => $query->where('client_id', $this->getRecord()->id))
|
|
->searchable()
|
|
->preload(),
|
|
Filter::make('date_range')
|
|
->form([
|
|
DatePicker::make('from'),
|
|
DatePicker::make('to'),
|
|
])
|
|
->query(function (Builder $query, array $data): Builder {
|
|
return $query
|
|
->when(
|
|
$data['from'],
|
|
fn (Builder $query, $date): Builder => $query->where(function ($q) use ($date) {
|
|
$q->whereHas('transaction', fn ($q) => $q->whereDate('happened_on', '>=', $date))
|
|
->orWhereHas('journal', fn ($q) => $q->whereDate('happened_on', '>=', $date))
|
|
->orWhere(fn($q) => $q->whereDoesntHave('transaction')->whereDoesntHave('journal')->whereDate('created_at', '>=', $date));
|
|
})
|
|
)
|
|
->when(
|
|
$data['to'],
|
|
fn (Builder $query, $date): Builder => $query->where(function ($q) use ($date) {
|
|
$q->whereHas('transaction', fn ($q) => $q->whereDate('happened_on', '<=', $date))
|
|
->orWhereHas('journal', fn ($q) => $q->whereDate('happened_on', '<=', $date))
|
|
->orWhere(fn($q) => $q->whereDoesntHave('transaction')->whereDoesntHave('journal')->whereDate('created_at', '<=', $date));
|
|
})
|
|
);
|
|
})
|
|
])
|
|
->defaultSort('created_at', 'desc')
|
|
->groups([
|
|
'account.account',
|
|
])
|
|
->headerActions([
|
|
ExportAction::make()
|
|
->label('Export General Ledger')
|
|
->exports([
|
|
ExcelExport::make()
|
|
->fromTable()
|
|
->withFilename(fn () => $this->getRecord()->name . ' - General Ledger - ' . date('Y-m-d'))
|
|
->withColumns([
|
|
Column::make('date')
|
|
->heading('Date')
|
|
->formatStateUsing(fn ($record) => $record->transaction?->happened_on?->format('Y-m-d')
|
|
?? $record->journal?->happened_on?->format('Y-m-d')
|
|
?? $record->created_at->format('Y-m-d')),
|
|
Column::make('reference')
|
|
->heading('Reference')
|
|
->formatStateUsing(fn ($record) => match(true) {
|
|
$record->transaction && $record->transaction->transactionable =>
|
|
$record->transaction->transactionable->voucher_number
|
|
?? $record->transaction->transactionable->reference_number
|
|
?? 'TR-'.$record->transaction->id,
|
|
$record->transaction => 'TR-'.$record->transaction->id,
|
|
$record->journal => $record->journal->series ?? 'JV-'.$record->journal->id,
|
|
default => 'L-'.$record->id,
|
|
}),
|
|
Column::make('account.account')->heading('Account'),
|
|
Column::make('description')->heading('Description'),
|
|
Column::make('debit_amount')->heading('Debit'),
|
|
Column::make('credit_amount')->heading('Credit'),
|
|
])
|
|
])
|
|
]);
|
|
}
|
|
}
|