@extends('layouts.app')
@section('content')
@php
$__roundOnlyAmount = function ($amount) {
$amount = max((float) $amount, 0);
$roundTo = 1000;
if ($amount <= 0) {
return 0;
}
return (float) (ceil($amount / $roundTo) * $roundTo);
};
$__meterMinRoundAmount = function ($amount) use ($__roundOnlyAmount) {
$amount = max((float) $amount, 0);
$minimumOrder = 10000;
if ($amount <= 0) {
return 0;
}
if ($amount < $minimumOrder) {
$amount = $minimumOrder;
}
return $__roundOnlyAmount($amount);
};
$__normalizeUnit = function ($unit) {
$unit = strtolower(trim((string) $unit));
$unit = str_replace(['²', '�'], ['2', '2'], $unit);
if (in_array($unit, ['m2', 'meter2', 'meter persegi', 'per meter persegi'], true)) {
return 'm2';
}
if (in_array($unit, ['meter', 'm', 'per meter'], true)) {
return 'meter';
}
return $unit ?: 'lembar';
};
$__parseM2FromDescription = function ($description) {
$description = strtolower(trim((string) $description));
if ($description === '') {
return 0;
}
$description = str_replace(['²', '�', '*'], ['2', '2', 'x'], $description);
if (preg_match('/([0-9]+(?:[\.,][0-9]+)?)\s*[x×]\s*([0-9]+(?:[\.,][0-9]+)?)/i', $description, $matches)) {
$width = (float) str_replace(',', '.', $matches[1]);
$height = (float) str_replace(',', '.', $matches[2]);
if ($width > 0 && $height > 0) {
if ($width >= 10 || $height >= 10) {
$width = $width / 100;
$height = $height / 100;
}
return round($width * $height, 4);
}
}
return 0;
};
$__itemDisplaySubtotal = function ($item) use ($__roundOnlyAmount, $__meterMinRoundAmount, $__normalizeUnit, $__parseM2FromDescription) {
$unit = $__normalizeUnit($item->size_unit ?? $item->unit ?? 'lembar');
$storedSubtotal = max((float) ($item->subtotal ?? $item->total_price ?? 0), 0);
if ($storedSubtotal > 0) {
return in_array($unit, ['m2', 'meter'], true)
? $__meterMinRoundAmount($storedSubtotal)
: $__roundOnlyAmount($storedSubtotal);
}
$qty = max((float) ($item->qty ?? 1), 0);
$basePrice = max((float) ($item->base_price ?? $item->calculated_price ?? $item->price ?? 0), 0);
$sizeValue = max((float) ($item->size_value ?? 0), 0);
if ($unit === 'm2') {
if ($sizeValue <= 0) {
$sizeValue = $__parseM2FromDescription($item->size_description ?? $item->size ?? '');
}
if ($sizeValue <= 0) {
$sizeValue = 1;
}
return $__meterMinRoundAmount($basePrice * $sizeValue * $qty);
}
if ($unit === 'meter') {
$sizeValue = $sizeValue > 0 ? $sizeValue : 1;
return $__meterMinRoundAmount($basePrice * $sizeValue * $qty);
}
return $__roundOnlyAmount($basePrice * $qty);
};
$__orderDisplaySubtotalBeforePpn = function ($order) use ($__itemDisplaySubtotal, $__roundOnlyAmount) {
$items = method_exists($order, 'items')
? ($order->relationLoaded('items') ? $order->items : $order->items()->get())
: collect();
$activeItems = $items->filter(function ($item) {
if (method_exists($item, 'isCancelled')) {
return !$item->isCancelled();
}
return !(bool) ($item->is_cancelled ?? false);
});
if ($activeItems->isNotEmpty()) {
return (float) $activeItems->sum(fn ($item) => $__itemDisplaySubtotal($item));
}
$subtotalBeforePpn = (float) ($order->subtotal_before_ppn ?? 0);
if ($subtotalBeforePpn > 0) {
return $__roundOnlyAmount($subtotalBeforePpn);
}
$total = (float) ($order->total_price ?? 0);
$ppn = (float) ($order->ppn_amount ?? 0);
if ((bool) ($order->use_ppn ?? false) && $ppn > 0 && $total > $ppn) {
return $__roundOnlyAmount($total - $ppn);
}
return $__roundOnlyAmount($total);
};
$__orderDisplayTotal = function ($order) use ($__orderDisplaySubtotalBeforePpn) {
$subtotal = $__orderDisplaySubtotalBeforePpn($order);
$ppn = ((bool) ($order->use_ppn ?? false) || (float) ($order->ppn_amount ?? 0) > 0)
? (float) ($order->ppn_amount ?? 0)
: 0;
return (float) ($subtotal + $ppn);
};
$__orderDisplayRemaining = function ($order) use ($__orderDisplayTotal) {
$paid = method_exists($order, 'getTotalPaid') ? (float) $order->getTotalPaid() : (float) ($order->paid_amount ?? 0);
return max((float) $__orderDisplayTotal($order) - $paid, 0);
};
$normalizeUnit = function ($unit) {
$unit = strtolower(trim((string) $unit));
return match ($unit) {
'm2', 'm�' => 'm2',
'meter', 'm' => 'meter',
'pcs', 'pc', 'piece', 'lembar' => 'lembar',
default => $unit !== '' ? $unit : 'lembar',
};
};
$formatQty = function ($value, $decimals = 2) {
$formatted = number_format((float) $value, $decimals, ',', '.');
$formatted = rtrim($formatted, '0');
$formatted = rtrim($formatted, ',');
return $formatted === '' ? '0' : $formatted;
};
$isItemCancelled = function ($item) {
if (method_exists($item, 'isCancelled')) {
return $item->isCancelled();
}
return (bool) ($item->is_cancelled ?? false);
};
$parseM2FromDescription = function ($description) {
$description = strtolower(trim((string) $description));
if ($description === '') {
return 1;
}
$description = str_replace(['�', '*'], 'x', $description);
if (!preg_match('/^\s*(\d+(?:\.\d+)?)\s*x\s*(\d+(?:\.\d+)?)\s*$/', $description, $matches)) {
return 1;
}
$a = (float) $matches[1];
$b = (float) $matches[2];
if ($a >= 10 || $b >= 10) {
$a = $a / 100;
$b = $b / 100;
}
return round($a * $b, 4);
};
$calculateItemSubtotal = function ($item) use ($__itemDisplaySubtotal) {
return round($__itemDisplaySubtotal($item), 2);
};
@endphp
Halaman ini dipakai untuk melihat order yang sudah dibayar, membuka bukti transaksi, memperbaiki data pembayaran, melakukan refund, atau mencetak beberapa nota sekaligus dengan sistem checklist.
Daftar order yang sudah pernah dibayar. Gunakan checklist untuk cetak nota gabungan.
| Invoice | Pelanggan | Total | Kasir | Waktu Bayar | Aksi | |
|---|---|---|---|---|---|---|
| id }}, @js($order->invoice_number), {{ (float) $displayTotal }}, @js($order->customer_name))" class="size-4 rounded border-gray-300 text-brand-500 focus:ring-brand-500 dark:border-gray-600 dark:bg-gray-700"> | {{ $order->invoice_number }} |
{{ $summaryText }}
|
Rp {{ number_format($displayTotal, 0, ',', '.') }}
@if($hasM2Item)
Total dihitung dari ukuran x harga/m2
@endif
|
{{ $order->cashier->name ?? '-' }} | {{ $order->paid_at?->format('d M Y H:i') ?? '-' }} | |
| Tidak ada data | ||||||