From cae6bc929a5d08c9191fd12f1c15ed1258091aad Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Sat, 18 Apr 2026 16:24:52 +0700 Subject: [PATCH] feat: add formatted price and type label attributes to ProductPrice model and display in product table --- app/Models/ProductPrice.php | 17 ++++++++++++ .../admin/master/product/partials/columns.tsx | 26 +++++++++++++++++++ resources/js/types/product.ts | 2 ++ 3 files changed, 45 insertions(+) diff --git a/app/Models/ProductPrice.php b/app/Models/ProductPrice.php index 25fe98a..08b30f2 100644 --- a/app/Models/ProductPrice.php +++ b/app/Models/ProductPrice.php @@ -3,11 +3,14 @@ namespace App\Models; use App\Enums\PriceType; +use Illuminate\Database\Eloquent\Attributes\Appends; use Illuminate\Database\Eloquent\Attributes\Guarded; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; #[Guarded(['id'])] +#[Appends(['price_formatted', 'price_type_label'])] class ProductPrice extends Model { protected function casts(): array @@ -18,6 +21,20 @@ protected function casts(): array ]; } + protected function priceTypeLabel(): Attribute + { + return Attribute::make( + get: fn () => $this->price_type->label(), + ); + } + + protected function priceFormatted(): Attribute + { + return Attribute::make( + get: fn () => 'Rp '.number_format($this->price, 0, ',', '.'), + ); + } + public function product(): BelongsTo { return $this->belongsTo(Product::class); diff --git a/resources/js/pages/admin/master/product/partials/columns.tsx b/resources/js/pages/admin/master/product/partials/columns.tsx index 9f02192..eeb8586 100644 --- a/resources/js/pages/admin/master/product/partials/columns.tsx +++ b/resources/js/pages/admin/master/product/partials/columns.tsx @@ -79,6 +79,32 @@ export const getColumns = ({ onDelete, onToggleStatus, onPreviewImage }: ColumnP ); } }, + { + accessorKey: "prices", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const product = row.original; + const prices = product.prices; + + if (!prices || !Array.isArray(prices) || prices.length === 0) { + return -; + } + + return ( +
+ {prices.map((p, i) => ( +
+ {p.price_type_label}:{' '} + {p.price_formatted} +
+ ))} +
+ ); + }, + meta: { title: "Harga" }, + }, { accessorKey: "is_active", header: "Status", diff --git a/resources/js/types/product.ts b/resources/js/types/product.ts index e84d8a7..5d17eaa 100644 --- a/resources/js/types/product.ts +++ b/resources/js/types/product.ts @@ -5,6 +5,8 @@ export interface ProductPrice { product_id: number; price_type: 'purchase' | 'distributor' | 'agent' | 'reseller' | 'retail'; price: number; + price_formatted: string; + price_type_label: string; created_at: string; updated_at: string; }