feat: add total quantity formatting to Purchase model and update related components

- Implemented totalQuantityFormatted method in Purchase model to format total quantities by unit.
- Updated PurchaseGroupedTable.vue to display total quantity formatted in the purchase details.
- Modified TypeScript type definition to include total_quantity_formatted property.
This commit is contained in:
Yoga Pangestu 2026-07-29 08:59:02 +07:00
parent 06ad8a6e8a
commit 7dec701770
3 changed files with 26 additions and 0 deletions

View File

@ -25,6 +25,7 @@
'shipping_cost_formatted',
'subtotal_formatted',
'total_formatted',
'total_quantity_formatted',
])]
class Purchase extends Model implements HasMedia
{
@ -78,6 +79,28 @@ public function totalFormatted(): Attribute
);
}
public function totalQuantityFormatted(): Attribute
{
return Attribute::make(
get: function () {
$groups = [];
foreach ($this->items as $item) {
$unit = $item->unit_abbreviation ?? $item->rawMaterialPrice?->rawMaterial?->unit?->abbreviation() ?? '';
$groups[$unit] = ($groups[$unit] ?? 0) + (float) $item->quantity;
}
return collect($groups)
->filter(fn (float $total) => $total > 0)
->map(function (float $total, string $unit) {
$formatted = rtrim(rtrim(number_format($total, 2, ',', '.'), '0'), ',');
return "{$formatted} {$unit}";
})
->join(', ');
},
);
}
// 4. Other Methods
public static function mediaModuleName(): string
{

View File

@ -145,6 +145,8 @@ function openVerificationDetail(requestId: number | undefined) {
</p>
</div>
<div class="flex flex-wrap gap-x-4 gap-y-1 text-sm">
<span v-if="purchase.total_quantity_formatted">Total Jumlah
<strong class="text-primary">{{ purchase.total_quantity_formatted }}</strong></span>
<span>Subtotal <strong class="text-primary">{{ purchase.subtotal_formatted
}}</strong></span>
<span>Diskon <strong class="text-primary">{{ purchase.discount_formatted

View File

@ -41,6 +41,7 @@ export type PurchaseListItem = {
shipping_cost: number;
shipping_cost_formatted: string;
total_formatted: string;
total_quantity_formatted?: string;
notes: string | null;
created_at_formatted: string;
created_by_name?: string;