From 7740160b4fe4311615182e574bb87c05f418805d Mon Sep 17 00:00:00 2001 From: Nisse Lommerde Date: Fri, 15 Nov 2024 15:22:57 -0500 Subject: [PATCH] Product Services filtering seems to work --- .../Resources/ServiceTypeResource.php | 48 +++++++++++++++-- app/Models/ServiceType.php | 51 ++++++++++++++---- database/factories/ProductServiceFactory.php | 2 +- time.ods | Bin 12267 -> 13254 bytes 4 files changed, 86 insertions(+), 15 deletions(-) diff --git a/app/Filament/Resources/ServiceTypeResource.php b/app/Filament/Resources/ServiceTypeResource.php index 3d5eb59..39d3a20 100644 --- a/app/Filament/Resources/ServiceTypeResource.php +++ b/app/Filament/Resources/ServiceTypeResource.php @@ -5,13 +5,18 @@ namespace App\Filament\Resources; use App\Filament\Resources\ServiceTypeResource\Pages; use App\Filament\Resources\ServiceTypeResource\Widgets\ServiceTypeOverview; use App\Models\ServiceType; +use Filament\Forms\Components\DatePicker; +use Filament\Forms\Components\Split; use Filament\Forms\Form; use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Table; +use Illuminate\Database\Eloquent\Model; class ServiceTypeResource extends Resource { + private ?string $quantity = 'priv'; + protected static ?string $model = ServiceType::class; protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack'; @@ -38,21 +43,54 @@ class ServiceTypeResource extends Resource { return $table ->columns([ - Tables\Columns\TextColumn::make('name') - ->getStateUsing(function () { - return 'test'; + Tables\Columns\TextColumn::make('name'), + Tables\Columns\TextColumn::make('quantity') + ->getStateUsing(function (Table $table, Model $record) { + return $record->getQuantityAttribute( + $table->getFilter('dates')->getState()['created_from'], + $table->getFilter('dates')->getState()['created_until'] + ); }), - Tables\Columns\TextColumn::make('quantity'), + Tables\Columns\TextColumn::make('amount') + ->getStateUsing(function (Table $table, Model $record) { + return $record->getAmountAttribute( + $table->getFilter('dates')->getState()['created_from'], + $table->getFilter('dates')->getState()['created_until'] + ); + }) ->prefix('$'), + Tables\Columns\TextColumn::make('salesPercentage') + ->getStateUsing(function (Table $table, Model $record) { + return $record->getSalesPercentageAttribute( + $table->getFilter('dates')->getState()['created_from'], + $table->getFilter('dates')->getState()['created_until'] + ); + }) ->suffix('%') ->label('Percentage'), + Tables\Columns\TextColumn::make('averagePrice') + ->getStateUsing(function (Table $table, Model $record) { + return $record->getAveragePriceAttribute( + $table->getFilter('dates')->getState()['created_from'], + $table->getFilter('dates')->getState()['created_until'] + ); + }) ->prefix('$'), ]) ->filters([ - // + Tables\Filters\Filter::make('dates') + ->form([ + Split::make([ + DatePicker::make('created_from') + ->label('From date'), + DatePicker::make('created_until') + ->reactive() + ->label('Until date'), + ]), + ]), ]) ->actions([ ]) diff --git a/app/Models/ServiceType.php b/app/Models/ServiceType.php index e42fddd..8f8a46d 100644 --- a/app/Models/ServiceType.php +++ b/app/Models/ServiceType.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -24,27 +25,59 @@ class ServiceType extends Model //to do: date between? - public function getQuantityAttribute(): int + public function getQuantityAttribute($created_at = null, $created_until = null): int { - return $this->productServices()->sum('amount'); + return $this->productServices() + ->when($created_at, function (Builder $query) use ($created_at) { + return $query->whereDate('created_at', '>=', $created_at); + }) + ->when($created_until, function (Builder $query) use ($created_until) { + return $query->whereDate('created_at', '<=', $created_until); + }) + ->sum('amount'); } - public function getAmountAttribute(): string + public function getAmountAttribute($created_at = null, $created_until = null): string { - return number_format($this->productServices()->sum('amount_price'), 2); + return number_format( + $this->productServices() + ->when($created_at, function (Builder $query) use ($created_at) { + return $query->whereDate('created_at', '>=', $created_at); + }) + ->when($created_until, function (Builder $query) use ($created_until) { + return $query->whereDate('created_at', '<=', $created_until); + }) + ->sum('amount_price'), + 2 + ); } - public function getSalesPercentageAttribute(): float + public function getSalesPercentageAttribute($created_at = null, $created_until = null): float { - $total = ProductService::all()->count(); - $part = ProductService::where('service_type_id', $this->id)->count(); + $total = ProductService::when($created_at, function (Builder $query) use ($created_at) { + return $query->whereDate('created_at', '>=', $created_at); + }) + ->when($created_until, function (Builder $query) use ($created_until) { + return $query->whereDate('created_at', '<=', $created_until); + }) + ->count(); + + $part = ProductService::where('service_type_id', $this->id) + ->when($created_at, function (Builder $query) use ($created_at) { + return $query->whereDate('created_at', '>=', $created_at); + }) + ->when($created_until, function (Builder $query) use ($created_until) { + return $query->whereDate('created_at', '<=', $created_until); + }) + ->count(); return round(($part / $total) * 100, 2); } - public function getAveragePriceAttribute(): string + public function getAveragePriceAttribute($created_at = null, $created_until = null): string { - return number_format(floatval($this->amount) / $this->quantity, 2); + return number_format(floatval($this->getAmountAttribute($created_at, $created_until)) / + $this->getQuantityAttribute($created_at, $created_until), 2); } public function productServices(): HasMany diff --git a/database/factories/ProductServiceFactory.php b/database/factories/ProductServiceFactory.php index 64465de..1e3c3b8 100644 --- a/database/factories/ProductServiceFactory.php +++ b/database/factories/ProductServiceFactory.php @@ -13,7 +13,7 @@ class ProductServiceFactory extends Factory public function definition(): array { return [ - 'created_at' => Carbon::now(), + 'created_at' => Carbon::now()->subDays(rand(0, 31)), 'updated_at' => Carbon::now(), 'placement' => $this->faker->randomElement(['L/C', 'C/F', 'F/B', 'R/C']), 'amount' => $this->faker->randomNumber(1), diff --git a/time.ods b/time.ods index 2e098828e206627ff03e30de61c3b63aacfbf7e8..26ed7c049924f873d5a78709d1fc1e0438182673 100644 GIT binary patch delta 10803 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 Z73BPT`f>&7F=qH-ZGv16Gz9+=`5)_f?gan< delta 9772 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 M{0PsT=a10;0r{4>D*ylh