Work on invoice reports
This commit is contained in:
parent
74a5a43c85
commit
9e8eb05e88
@ -2,21 +2,19 @@
|
|||||||
|
|
||||||
namespace App\Filament\Resources;
|
namespace App\Filament\Resources;
|
||||||
|
|
||||||
use App\Enums\InvoiceStatus;
|
|
||||||
use App\Filament\Resources\InvoiceReportResource\Pages;
|
use App\Filament\Resources\InvoiceReportResource\Pages;
|
||||||
use App\Models\Order;
|
|
||||||
use Filament\Forms\Components\DatePicker;
|
use Filament\Forms\Components\DatePicker;
|
||||||
|
use Filament\Forms\Components\Section;
|
||||||
|
use Filament\Forms\Components\Select;
|
||||||
|
use Filament\Forms\Components\ToggleButtons;
|
||||||
use Filament\Forms\Form;
|
use Filament\Forms\Form;
|
||||||
use Filament\Resources\Resource;
|
use Filament\Resources\Resource;
|
||||||
use Filament\Tables;
|
use Filament\Support\Enums\FontFamily;
|
||||||
use Filament\Tables\Grouping\Group;
|
use Filament\Tables\Columns\TextColumn;
|
||||||
use Filament\Tables\Table;
|
use Filament\Tables\Table;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
|
||||||
|
|
||||||
class InvoiceReportResource extends Resource
|
class InvoiceReportResource extends Resource
|
||||||
{
|
{
|
||||||
protected static ?string $model = Order::class;
|
|
||||||
|
|
||||||
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
|
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
|
||||||
|
|
||||||
protected static ?string $navigationGroup = 'Reports';
|
protected static ?string $navigationGroup = 'Reports';
|
||||||
@ -29,7 +27,27 @@ public static function form(Form $form): Form
|
|||||||
{
|
{
|
||||||
return $form
|
return $form
|
||||||
->schema([
|
->schema([
|
||||||
//
|
Section::make([
|
||||||
|
Select::make('customer_id')
|
||||||
|
->relationship('customer', 'company_name')
|
||||||
|
->preload()
|
||||||
|
->required()
|
||||||
|
->searchable(),
|
||||||
|
ToggleButtons::make('filter_paid')
|
||||||
|
->boolean()
|
||||||
|
->required()
|
||||||
|
->default(false)
|
||||||
|
->colors([
|
||||||
|
'true' => 'info',
|
||||||
|
'false' => 'info',
|
||||||
|
])
|
||||||
|
->inline(),
|
||||||
|
DatePicker::make('date_start')
|
||||||
|
->required(),
|
||||||
|
DatePicker::make('date_end')
|
||||||
|
->required()
|
||||||
|
->default(today()),
|
||||||
|
])->columns(2),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,110 +55,37 @@ public static function table(Table $table): Table
|
|||||||
{
|
{
|
||||||
return $table
|
return $table
|
||||||
->columns([
|
->columns([
|
||||||
Tables\Columns\TextColumn::make('invoice.date')
|
TextColumn::make('id')
|
||||||
->label('Date')
|
->formatStateUsing(fn ($state) => 'TN-INR-'.$state)
|
||||||
->date('Y-m-d'),
|
->fontFamily(FontFamily::Mono)
|
||||||
|
->color('primary'),
|
||||||
Tables\Columns\TextColumn::make('invoice.internal_id')
|
TextColumn::make('customer.company_name')
|
||||||
->color('primary')
|
|
||||||
->fontFamily('mono'),
|
|
||||||
|
|
||||||
Tables\Columns\TextColumn::make('customer_po')
|
|
||||||
->color('code')
|
|
||||||
->weight('bold')
|
|
||||||
->extraHeaderAttributes(['class' => 'w-full']),
|
->extraHeaderAttributes(['class' => 'w-full']),
|
||||||
|
TextColumn::make('date_start')
|
||||||
Tables\Columns\TextColumn::make('total_service_price')
|
->label('Start Date')
|
||||||
->label('Subtotal')
|
->date('Y-m-d'),
|
||||||
->alignRight()
|
TextColumn::make('date_end')
|
||||||
|
->label('End Date')
|
||||||
|
->date('Y-m-d'),
|
||||||
|
TextColumn::make('total')
|
||||||
->money(),
|
->money(),
|
||||||
|
|
||||||
Tables\Columns\TextColumn::make('pst')
|
|
||||||
->label('PST')
|
|
||||||
->alignRight()
|
|
||||||
->getStateUsing(fn (Order $record) => $record->invoice->pst ? $record->total_service_price * 0.07 : 0.00)
|
|
||||||
->formatStateUsing(function ($state) {
|
|
||||||
return $state == 0.00 ? '-' : '$'.$state;
|
|
||||||
}),
|
|
||||||
|
|
||||||
Tables\Columns\TextColumn::make('gst')
|
|
||||||
->label('GST')
|
|
||||||
->getStateUsing(fn (Order $record) => $record->total_service_price * 0.05)
|
|
||||||
->alignRight()
|
|
||||||
->money(),
|
|
||||||
|
|
||||||
Tables\Columns\TextColumn::make('invoice.total')
|
|
||||||
->label('Total')
|
|
||||||
->getStateUsing(function (Order $record) {
|
|
||||||
$total = $record->total_service_price * 1.05;
|
|
||||||
|
|
||||||
if ($record->invoice->pst) {
|
|
||||||
$total += $record->total_service_price * 0.07;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $total;
|
|
||||||
})
|
|
||||||
->alignRight()
|
|
||||||
->money(),
|
|
||||||
|
|
||||||
Tables\Columns\TextColumn::make('invoice.status')
|
|
||||||
->badge(InvoiceStatus::class),
|
|
||||||
])
|
])
|
||||||
|
->defaultSort('created_at', 'desc')
|
||||||
|
|
||||||
->filters([
|
->filters([
|
||||||
Tables\Filters\SelectFilter::make('customer')
|
])
|
||||||
->relationship('customer', 'company_name')
|
->actions([]);
|
||||||
->preload()
|
// ->defaultGroup(
|
||||||
->searchable()
|
// Group::make('date')
|
||||||
->placeholder('Select a customer...')
|
// ->getKeyFromRecordUsing(fn (Order $record): string => $record->invoice->date->format('Y-m-0'))
|
||||||
->selectablePlaceholder(false)
|
// ->getTitleFromRecordUsing(fn (Order $record): string => $record->invoice->date->format('F Y'))
|
||||||
->query(function (array $data, Builder $query): Builder {
|
// ->orderQueryUsing(function (Builder $query) {
|
||||||
return $query->where('orders.customer_id', $data['value'] ?? '-1');
|
//
|
||||||
}),
|
// return $query->join('invoices', 'orders.invoice_id', '=', 'invoices.id')
|
||||||
|
// ->orderBy('invoices.date', 'desc');
|
||||||
Tables\Filters\Filter::make('date_from')
|
// })
|
||||||
->form([DatePicker::make('date_from')])
|
// ->titlePrefixedWithLabel(false),
|
||||||
->query(function (Builder $query, array $data): Builder {
|
// );
|
||||||
return $query->when($data['date_from'], function (Builder $query, $date) {
|
|
||||||
return $query->whereHas('invoice', fn ($query) => $query->whereDate('date', '>=', $date));
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
|
|
||||||
Tables\Filters\Filter::make('date_until')
|
|
||||||
->form([DatePicker::make('date_until')])
|
|
||||||
->query(function (Builder $query, array $data): Builder {
|
|
||||||
return $query->when($data['date_until'], function (Builder $query, $date) {
|
|
||||||
return $query->whereHas('invoice', fn ($query) => $query->whereDate('date', '<=', $date));
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
|
|
||||||
Tables\Filters\SelectFilter::make('invoice_status')
|
|
||||||
->options(InvoiceStatus::class)
|
|
||||||
->query(function (Builder $query, array $data): Builder {
|
|
||||||
return $query->when($data['value'], fn (Builder $query, $value) => $query->whereHas('invoice', fn (Builder $query) => $query->where('status', $value)));
|
|
||||||
}),
|
|
||||||
|
|
||||||
], layout: Tables\Enums\FiltersLayout::AboveContent)
|
|
||||||
->hiddenFilterIndicators()
|
|
||||||
|
|
||||||
->actions([])
|
|
||||||
->defaultGroup(
|
|
||||||
Group::make('date')
|
|
||||||
->getKeyFromRecordUsing(fn (Order $record): string => $record->invoice->date->format('Y-m-0'))
|
|
||||||
->getTitleFromRecordUsing(fn (Order $record): string => $record->invoice->date->format('F Y'))
|
|
||||||
->orderQueryUsing(function (Builder $query) {
|
|
||||||
|
|
||||||
return $query->join('invoices', 'orders.invoice_id', '=', 'invoices.id')
|
|
||||||
->orderBy('invoices.date', 'desc');
|
|
||||||
})
|
|
||||||
->titlePrefixedWithLabel(false),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getEloquentQuery(): \Illuminate\Database\Eloquent\Builder
|
|
||||||
{
|
|
||||||
return Order::query()
|
|
||||||
->has('invoice');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getRelations(): array
|
public static function getRelations(): array
|
||||||
@ -153,7 +98,9 @@ public static function getRelations(): array
|
|||||||
public static function getPages(): array
|
public static function getPages(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'index' => Pages\ListInvoiceReports::route('/'),
|
'index' => Pages\ListInvoiceReports::route('/'),
|
||||||
|
'edit' => Pages\EditInvoiceReport::route('/{record}/edit'),
|
||||||
|
'create' => Pages\CreateInvoiceReport::route('/create'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
namespace App\Filament\Resources\InvoiceReportResource\Pages;
|
namespace App\Filament\Resources\InvoiceReportResource\Pages;
|
||||||
|
|
||||||
use App\Filament\Resources\InvoiceReportResource;
|
use App\Filament\Resources\InvoiceReportResource;
|
||||||
use Filament\Actions\Action;
|
use Filament\Actions;
|
||||||
use Filament\Resources\Pages\ListRecords;
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
|
||||||
class ListInvoiceReports extends ListRecords
|
class ListInvoiceReports extends ListRecords
|
||||||
@ -15,9 +15,7 @@ class ListInvoiceReports extends ListRecords
|
|||||||
protected function getHeaderActions(): array
|
protected function getHeaderActions(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
Action::make('generateReport')
|
Actions\CreateAction::make(),
|
||||||
->label('Make Report')
|
|
||||||
->icon('lucide-printer'),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,8 @@ public static function table(Table $table): Table
|
|||||||
DatePicker::make('created_until')
|
DatePicker::make('created_until')
|
||||||
->label('Until date'),
|
->label('Until date'),
|
||||||
]),
|
]),
|
||||||
], layout: Tables\Enums\FiltersLayout::AboveContentCollapsible)
|
], layout: Tables\Enums\FiltersLayout::AboveContent)
|
||||||
|
// ])
|
||||||
->actions([
|
->actions([
|
||||||
])
|
])
|
||||||
|
|
||||||
|
28
app/Models/InvoiceReport.php
Normal file
28
app/Models/InvoiceReport.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
|
class InvoiceReport extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'customer_id',
|
||||||
|
'date_start',
|
||||||
|
'date_end',
|
||||||
|
'filter_paid',
|
||||||
|
'subtotal',
|
||||||
|
'pst',
|
||||||
|
'gst',
|
||||||
|
'total',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function customer(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Customer::class);
|
||||||
|
}
|
||||||
|
}
|
29
database/factories/InvoiceReportFactory.php
Normal file
29
database/factories/InvoiceReportFactory.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use App\Models\Customer;
|
||||||
|
use App\Models\InvoiceReport;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
|
class InvoiceReportFactory extends Factory
|
||||||
|
{
|
||||||
|
protected $model = InvoiceReport::class;
|
||||||
|
|
||||||
|
public function definition(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'customer_id' => Customer::all()->shuffle()->first()->id,
|
||||||
|
'date_start' => Carbon::now()->subYear(),
|
||||||
|
'date_end' => Carbon::now(),
|
||||||
|
'filter_paid' => $this->faker->boolean(90),
|
||||||
|
/* 'subtotal' => $this->faker->randomFloat(),
|
||||||
|
'pst' => $this->faker->randomFloat(),
|
||||||
|
'gst' => $this->faker->randomFloat(),
|
||||||
|
'total' => $this->faker->randomFloat(),*/
|
||||||
|
'created_at' => Carbon::now(),
|
||||||
|
'updated_at' => Carbon::now(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
<?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('invoice_reports', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
|
||||||
|
$table->foreignId('customer_id')->constrained();
|
||||||
|
|
||||||
|
$table->date('date_start');
|
||||||
|
$table->date('date_end');
|
||||||
|
$table->boolean('filter_paid');
|
||||||
|
$table->float('subtotal', 2)->default(0);
|
||||||
|
$table->float('pst', 2)->default(0);
|
||||||
|
$table->float('gst', 2)->default(0);
|
||||||
|
$table->float('total', 2)->default(0);
|
||||||
|
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('invoice_reports');
|
||||||
|
}
|
||||||
|
};
|
@ -26,6 +26,7 @@ public function run(): void
|
|||||||
ServiceFileSeeder::class,
|
ServiceFileSeeder::class,
|
||||||
QuoteSeeder::class,
|
QuoteSeeder::class,
|
||||||
InvoiceSeeder::class,
|
InvoiceSeeder::class,
|
||||||
|
InvoiceReportSeeder::class,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
User::factory()->create([
|
User::factory()->create([
|
||||||
|
14
database/seeders/InvoiceReportSeeder.php
Normal file
14
database/seeders/InvoiceReportSeeder.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use App\Models\InvoiceReport;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
|
class InvoiceReportSeeder extends Seeder
|
||||||
|
{
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
InvoiceReport::factory()->count(5)->create();
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,7 @@ class OrderSeeder extends Seeder
|
|||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
foreach (Customer::all() as $customer) {
|
foreach (Customer::all() as $customer) {
|
||||||
Order::factory(rand(50, 150), ['customer_id' => $customer])->create();
|
Order::factory(rand(10, 50), ['customer_id' => $customer])->create();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1
mprocs.log
Normal file
1
mprocs.log
Normal file
@ -0,0 +1 @@
|
|||||||
|
ERROR [mprocs::error] Error: channel closed
|
5
mprocs.yaml
Normal file
5
mprocs.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
procs:
|
||||||
|
sail:
|
||||||
|
shell: "/home/nisse/Code/topnotch_website/vendor/bin/sail up"
|
||||||
|
npm:
|
||||||
|
shell: "npm run dev"
|
Loading…
x
Reference in New Issue
Block a user