Commit 9895319f authored by Mahmoud Aglan's avatar Mahmoud Aglan

Fix low stock, inventory movements, product sales, POS reports + payment search filter

1. Low stock: use min_stock_level (not reorder_point), eager-load inventoryLevels
2. Inventory movements: reference is a morphTo — show class_basename#id instead of raw object
3. Product sales: pos_transaction_items has item_type/item_id (not product_id)
4. POS transactions: relationship is processedBy (not user), field is receipt_number
5. Collect payment wizard: only search participants with outstanding invoices
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 50db0586
......@@ -490,21 +490,21 @@ public function trainerWorkload(string $from, string $to, ?int $branchId = null)
public function lowStockReport(?int $branchId = null): Collection
{
return Product::with(['category'])
return Product::with(['category', 'inventoryLevels'])
->where('track_inventory', true)
->where('is_active', true)
->get()
->map(function ($product) {
$level = $product->inventoryLevels()->first();
$level = $product->inventoryLevels->first();
$onHand = $level?->quantity_on_hand ?? 0;
$reorder = $product->reorder_point ?? 0;
$minStock = $product->min_stock_level ?? 0;
return [
'product' => $product->name_ar ?? $product->name ?? '',
'sku' => $product->sku ?? '',
'category' => $product->category?->name_ar ?? '',
'on_hand' => $onHand,
'reorder_point' => $reorder,
'status' => $onHand <= 0 ? 'نفد' : ($onHand <= $reorder ? 'منخفض' : 'متوفر'),
'reorder_point' => $minStock,
'status' => $onHand <= 0 ? 'نفد' : ($onHand <= $minStock ? 'منخفض' : 'متوفر'),
];
})
->filter(fn ($p) => $p['on_hand'] <= $p['reorder_point'])
......@@ -529,7 +529,7 @@ public function inventoryMovementReport(string $from, string $to, ?int $branchId
'quantity' => $m->quantity,
'before' => $m->quantity_before ?? 0,
'after' => $m->quantity_after ?? 0,
'reference' => $m->reference ?? '',
'reference' => $m->reference_type ? class_basename($m->reference_type) . '#' . $m->reference_id : '—',
]);
}
......@@ -537,10 +537,10 @@ public function productSalesReport(string $from, string $to, ?int $branchId = nu
{
return DB::table('pos_transaction_items')
->join('pos_transactions', 'pos_transactions.id', '=', 'pos_transaction_items.pos_transaction_id')
->join('products', 'products.id', '=', 'pos_transaction_items.product_id')
->join('products', 'products.id', '=', 'pos_transaction_items.item_id')
->where('pos_transaction_items.item_type', 'product')
->whereBetween('pos_transactions.processed_at', [$from, $to . ' 23:59:59'])
->when($branchId, fn ($q) => $q->where('pos_transactions.branch_id', $branchId))
->whereNotNull('pos_transaction_items.product_id')
->select(
'products.name_ar as product',
'products.sku',
......@@ -556,7 +556,7 @@ public function productSalesReport(string $from, string $to, ?int $branchId = nu
public function posTransactionReport(string $from, string $to, ?int $branchId = null): Collection
{
return POSTransaction::with(['user', 'branch'])
return POSTransaction::with(['processedBy', 'branch'])
->whereBetween('processed_at', [$from, $to . ' 23:59:59'])
->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
->orderByDesc('processed_at')
......@@ -564,12 +564,12 @@ public function posTransactionReport(string $from, string $to, ?int $branchId =
->get()
->map(fn ($t) => [
'date' => $t->processed_at?->format('Y-m-d H:i'),
'number' => $t->transaction_number ?? '',
'number' => $t->receipt_number ?? '',
'total' => $t->total_amount,
'discount' => $t->discount_amount ?? 0,
'items_count' => $t->items_count ?? 0,
'payment_method' => $t->payment_method?->value ?? $t->payment_method ?? '',
'cashier' => $t->user?->name ?? '',
'items_count' => $t->items()->count(),
'payment_method' => $t->payment_method ?? '',
'cashier' => $t->processedBy?->name ?? '',
'branch' => $t->branch?->name_ar ?? '',
]);
}
......
......@@ -195,6 +195,7 @@ public function render()
$searchResults = Participant::query()
->with('person')
->where('branch_id', $this->branchId)
->whereHas('invoices', fn ($iq) => $iq->whereIn('status', ['sent', 'partially_paid', 'overdue']))
->where(function ($q) {
$search = $this->search;
$q->where('participant_number', 'ilike', "%{$search}%")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment