@extends('layouts.app') @section('title', 'Product Report - ' . $product->name) @section('content')

{{ $product->name }}

SKU: {{ $product->sku }} @if($product->category) · {{ $product->category->name }} @endif @if($product->brand) · {{ $product->brand->name }} @endif @if($product->supplier) · Supplier: {{ $product->supplier->name }} @endif

@include('partials.pdf-button') Back to Products
Current Stock

{{ number_format($product->current_stock ?? 0) }}

Selling at {{ formatCurrency($product->selling_price) }}
Sold

{{ number_format($salesTotals->qty) }}

{{ $salesTotals->count }} sale(s) · {{ formatCurrency($salesTotals->amount) }}
Purchased

{{ number_format($purchaseTotals->qty) }}

{{ $purchaseTotals->count }} purchase(s) · {{ formatCurrency($purchaseTotals->amount) }}
Expiry Date

{{ $product->expiry_date ? \Carbon\Carbon::parse($product->expiry_date)->format('M d, Y') : '—' }}

Alert at {{ number_format($product->alert_quantity ?? 0) }}
@if(request('from') || request('to')) Clear @endif
@forelse($sales->getCollection()->groupBy(fn ($i) => \Carbon\Carbon::parse($i->sold_at)->toDateString()) as $day => $items) @foreach($items as $item) @php($seller = $item->sale?->user ?? $item->sale?->register?->user) @endforeach @empty @endforelse
Time Invoice Customer Payment Qty Price Subtotal Sold By
{{ \Carbon\Carbon::parse($day)->format('l, M d, Y') }} {{ number_format($salesPerDay[$day]->qty ?? 0) }} {{ formatCurrency($salesPerDay[$day]->amount ?? 0) }} day total
{{ \Carbon\Carbon::parse($item->sold_at)->format('H:i') }} @if($item->sale) {{ $item->sale->invoice_no }} @endif {{ $item->sale->customer_name ?? 'Walk-In Customer' }} {{ str_replace('_', ' ', $item->sale->payment_method ?? '—') }} {{ number_format($item->quantity) }} {{ formatCurrency($item->price) }} {{ formatCurrency($item->subtotal) }} {{ $seller->name ?? 'Unknown' }} @if($item->sale?->is_edited)
Edited by {{ $item->sale->editor->name ?? 'Unknown' }} {{ $item->sale->edited_at ? 'on ' . $item->sale->edited_at->format('M d, H:i') : '' }} @endif
No sales found for this product
{{ $sales->links() }}
@forelse($purchases->getCollection()->groupBy(fn ($i) => $i->date->toDateString()) as $day => $items) @foreach($items as $item) @endforeach @empty @endforelse
Reference Supplier Status Qty Unit Cost Line Total Expiry Recorded By
{{ \Carbon\Carbon::parse($day)->format('l, M d, Y') }} {{ number_format($purchasesPerDay[$day]->qty ?? 0) }} {{ formatCurrency($purchasesPerDay[$day]->amount ?? 0) }} day total
@if($item->url) {{ $item->reference }} @else {{ $item->reference }} @endif {{ $item->supplier }} @if($item->source === 'adjustment') {{ $item->status }} @else {{ $item->status }} @endif {{ number_format($item->quantity) }} {{ formatCurrency($item->unit_cost) }} {{ formatCurrency($item->line_total) }} {{ $item->expiry ? \Carbon\Carbon::parse($item->expiry)->format('M d, Y') : '—' }} {{ $item->user }}
No purchases found for this product

Includes stock added with stock adjustments (e.g. New Stock), dated when the stock was added and valued at the product's purchase price. Customer returns are not counted.

{{ $purchases->links() }}
@forelse($adjustments as $adjustment) @empty @endforelse
Date & Time Type Qty Change Previous → New Price Change Reason By
{{ $adjustment->created_at->format('M d, Y H:i') }} {{ $adjustment->adjustment_type_text }} {{ $adjustment->quantity_change }} {{ number_format($adjustment->previous_quantity) }} → {{ number_format($adjustment->new_quantity) }} @if($adjustment->previous_price != $adjustment->new_price) {{ formatCurrency($adjustment->previous_price) }} → {{ formatCurrency($adjustment->new_price) }} @else No change @endif {{ $adjustment->reason }} {{ $adjustment->user->name ?? 'Unknown' }}
No stock adjustments found for this product
{{ $adjustments->links() }}
@forelse($movements as $movement) @empty @endforelse
Date & Time Type Qty Change Stock After Reference Customer / Supplier By
{{ $movement->created_at->format('M d, Y H:i') }} {{ $movement->type }} {{ $movement->quantity_change >= 0 ? '+' : '' }}{{ number_format($movement->quantity_change) }} {{ number_format($movement->new_quantity) }} {{ $movement->reference_no ?? '—' }} {{ $movement->customer_supplier ?? '—' }} @if($movement->user) {{ $movement->user->name }} @else Not recorded @endif
No stock movements found for this product
{{ $movements->links() }}

Stock of this product when each register was opened and closed. Current stock: {{ number_format($product->current_stock ?? 0, 2) }}. est. = rebuilt from stock movements (registers closed before stock snapshots were recorded).

@forelse($registers as $register) @php($open = $register->stock_opening) @php($close = $register->stock_closing) @empty @endforelse
Day Register Opened Stock at Opening Closed Stock at Closing Change
{{ $register->opened_at->format('D, M d, Y') }} #{{ $register->id }} {{ $register->user->name ?? '' }} {{ $register->opened_at->format('H:i') }} @if($open) {{ number_format($open['qty'], 2) }} @if($open['estimated'])est.@endif @else — @endif @if($register->closed_at) {{ $register->closed_at->format($register->closed_at->isSameDay($register->opened_at) ? 'H:i' : 'M d, H:i') }} @else Still open @endif @if($close) {{ number_format($close['qty'], 2) }} @if($close['estimated'])est.@endif @elseif(!$register->closed_at) now {{ number_format($product->current_stock ?? 0, 2) }} @else — @endif @if($open && $close) @php($diff = $close['qty'] - $open['qty']) {{ $diff > 0 ? '+' : '' }}{{ number_format($diff, 2) }} @else — @endif
No registers opened in this period
{{ $registers->links() }}
@forelse($activities as $activity) @empty @endforelse
Date & Time Action Description By IP Address
{{ $activity->created_at->format('M d, Y H:i') }} {{ $activity->action }} {{ $activity->description }} {{ $activity->user->name ?? 'Unknown' }} {{ $activity->ip_address }}
No activity recorded for this product
{{ $activities->links() }}
@endsection @section('scripts') @endsection