Commit 72f10f27 authored by Mahmoud Aglan's avatar Mahmoud Aglan

Fix: invoice summary now subtracts refunds from totals

The payment summary panel was only counting inbound payments,
ignoring outbound refunds entirely. Now shows net amounts
(inbound - refunds) per method, and displays a refund line
when refunds exist in the selected period.
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent ea844fa1
...@@ -65,12 +65,12 @@ public function setSummaryPreset(string $preset): void ...@@ -65,12 +65,12 @@ public function setSummaryPreset(string $preset): void
public function updatedSearch(): void { $this->resetPage(); } public function updatedSearch(): void { $this->resetPage(); }
public function updatedStatus(): void { $this->resetPage(); } public function updatedStatus(): void { $this->resetPage(); }
private function buildSummaryQuery(): \Illuminate\Database\Eloquent\Builder private function buildSummaryQuery(string $direction = 'inbound'): \Illuminate\Database\Eloquent\Builder
{ {
return Payment::query() return Payment::query()
->whereBetween('payment_date', [$this->summaryFrom, $this->summaryTo]) ->whereBetween('payment_date', [$this->summaryFrom, $this->summaryTo])
->where('status', 'confirmed') ->where('status', 'confirmed')
->where('direction', 'inbound'); ->where('direction', $direction);
} }
public function render() public function render()
...@@ -92,8 +92,14 @@ public function render() ...@@ -92,8 +92,14 @@ public function render()
$this->applyRoleScope($query); $this->applyRoleScope($query);
// Payment breakdown by method for summary panel // Payment breakdown by method for summary panel (inbound - refunds)
$breakdownRaw = $this->buildSummaryQuery() $inboundRaw = $this->buildSummaryQuery('inbound')
->selectRaw('method, SUM(amount) as total, COUNT(*) as count')
->groupBy('method')
->get()
->keyBy('method');
$refundRaw = $this->buildSummaryQuery('outbound')
->selectRaw('method, SUM(amount) as total, COUNT(*) as count') ->selectRaw('method, SUM(amount) as total, COUNT(*) as count')
->groupBy('method') ->groupBy('method')
->get() ->get()
...@@ -101,16 +107,20 @@ public function render() ...@@ -101,16 +107,20 @@ public function render()
$allMethods = PaymentMethod::cases(); $allMethods = PaymentMethod::cases();
$breakdown = collect($allMethods)->map(function (PaymentMethod $m) use ($breakdownRaw) { $breakdown = collect($allMethods)->map(function (PaymentMethod $m) use ($inboundRaw, $refundRaw) {
$row = $breakdownRaw->get($m->value); $inRow = $inboundRaw->get($m->value);
$refRow = $refundRaw->get($m->value);
$netTotal = ($inRow?->total ?? 0) - ($refRow?->total ?? 0);
return [ return [
'value' => $m->value, 'value' => $m->value,
'label' => $m->label(), 'label' => $m->label(),
'total' => $row?->total ?? 0, 'total' => $netTotal,
'count' => $row?->count ?? 0, 'count' => ($inRow?->count ?? 0) - ($refRow?->count ?? 0),
]; ];
}); });
$totalRefunds = $refundRaw->sum('total');
$primaryTotal = $breakdown->firstWhere('value', $this->primaryMethod)['total'] ?? 0; $primaryTotal = $breakdown->firstWhere('value', $this->primaryMethod)['total'] ?? 0;
$primaryCount = $breakdown->firstWhere('value', $this->primaryMethod)['count'] ?? 0; $primaryCount = $breakdown->firstWhere('value', $this->primaryMethod)['count'] ?? 0;
$otherTotal = $breakdown->where('value', '!=', $this->primaryMethod)->sum('total'); $otherTotal = $breakdown->where('value', '!=', $this->primaryMethod)->sum('total');
...@@ -131,6 +141,7 @@ public function render() ...@@ -131,6 +141,7 @@ public function render()
'otherTotal' => $otherTotal, 'otherTotal' => $otherTotal,
'otherCount' => $otherCount, 'otherCount' => $otherCount,
'grandTotal' => $grandTotal, 'grandTotal' => $grandTotal,
'totalRefunds' => $totalRefunds,
]); ]);
} }
} }
...@@ -151,13 +151,23 @@ class="text-xs border border-gray-300 rounded-lg px-2 py-1 focus:ring-2 focus:ri ...@@ -151,13 +151,23 @@ class="text-xs border border-gray-300 rounded-lg px-2 py-1 focus:ring-2 focus:ri
</div> </div>
{{-- Grand total --}} {{-- Grand total --}}
<div class="flex items-center justify-between mt-3 pt-3 border-t border-gray-100"> <div class="mt-3 pt-3 border-t border-gray-100 space-y-1">
<span class="text-sm text-gray-500">{{ __('إجمالي المدفوعات') }}</span> @if($totalRefunds > 0)
<div class="flex items-center justify-between">
<span class="text-sm text-red-500">{{ __('مستردات') }}</span>
<span class="text-sm font-medium text-red-600" dir="ltr">
-{{ number_format($totalRefunds / 100, 2) }} {{ __('ج.م') }}
</span>
</div>
@endif
<div class="flex items-center justify-between">
<span class="text-sm text-gray-500">{{ __('صافي المدفوعات') }}</span>
<span class="text-base font-bold text-gray-800" dir="ltr"> <span class="text-base font-bold text-gray-800" dir="ltr">
{{ number_format($grandTotal / 100, 2) }} {{ __('ج.م') }} {{ number_format($grandTotal / 100, 2) }} {{ __('ج.م') }}
</span> </span>
</div> </div>
</div> </div>
</div>
{{-- Flash Messages --}} {{-- Flash Messages --}}
@if(session('success')) @if(session('success'))
......
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