feat: add formatted price and type label attributes to ProductPrice model and display in product table
This commit is contained in:
parent
d06d32f3f8
commit
cae6bc929a
@ -3,11 +3,14 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Enums\PriceType;
|
use App\Enums\PriceType;
|
||||||
|
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||||
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
#[Guarded(['id'])]
|
||||||
|
#[Appends(['price_formatted', 'price_type_label'])]
|
||||||
class ProductPrice extends Model
|
class ProductPrice extends Model
|
||||||
{
|
{
|
||||||
protected function casts(): array
|
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
|
public function product(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Product::class);
|
return $this->belongsTo(Product::class);
|
||||||
|
|||||||
@ -79,6 +79,32 @@ export const getColumns = ({ onDelete, onToggleStatus, onPreviewImage }: ColumnP
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "prices",
|
||||||
|
header: ({ column }) => (
|
||||||
|
<DataTableColumnHeader column={column} title="Harga" />
|
||||||
|
),
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const product = row.original;
|
||||||
|
const prices = product.prices;
|
||||||
|
|
||||||
|
if (!prices || !Array.isArray(prices) || prices.length === 0) {
|
||||||
|
return <span className="text-muted-foreground text-xs italic">-</span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
|
{prices.map((p, i) => (
|
||||||
|
<div key={i} className="text-xs whitespace-nowrap">
|
||||||
|
<span className="text-muted-foreground">{p.price_type_label}:</span>{' '}
|
||||||
|
<span className="font-medium text-primary">{p.price_formatted}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
meta: { title: "Harga" },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "is_active",
|
accessorKey: "is_active",
|
||||||
header: "Status",
|
header: "Status",
|
||||||
|
|||||||
@ -5,6 +5,8 @@ export interface ProductPrice {
|
|||||||
product_id: number;
|
product_id: number;
|
||||||
price_type: 'purchase' | 'distributor' | 'agent' | 'reseller' | 'retail';
|
price_type: 'purchase' | 'distributor' | 'agent' | 'reseller' | 'retail';
|
||||||
price: number;
|
price: number;
|
||||||
|
price_formatted: string;
|
||||||
|
price_type_label: string;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
updated_at: string;
|
updated_at: string;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user