*/ private const SUCCESS_TXACTIONS = ['paid', 'extern_paid', 'invoice_paid']; public static function show() { $filter = request('filter', 'all'); $aboOrders = UserAboOrder::with([ 'user_abo', 'user_abo.user', 'user_abo.user.account', 'shopping_order', 'shopping_order.shopping_user', 'shopping_order.shopping_payments', ]) ->whereHas('shopping_order') ->when($filter === 'berater', fn ($q) => $q->whereHas('user_abo', fn ($q) => $q->where('is_for', 'me'))) ->when($filter === 'kunde', fn ($q) => $q->whereHas('user_abo', fn ($q) => $q->where('is_for', '!=', 'me'))) ->orderByDesc('created_at') ->get(); $summary = [ 'total_orders' => $aboOrders->count(), 'total_diff' => 0.0, 'affected_orders' => 0, ]; $rows = []; foreach ($aboOrders as $aboOrder) { $order = $aboOrder->shopping_order; if (! $order) { continue; } $subtotalWs = (float) $order->subtotal_ws; $totalShipping = (float) $order->total_shipping; $tax = (float) $order->tax; $expectedCents = (int) round($totalShipping * 100); $actualCents = self::actualChargedCentsFromPayments($order); $actualEur = $actualCents !== null ? round($actualCents / 100, 2) : null; $diff = ($actualCents !== null) ? round(($expectedCents - $actualCents) / 100, 2) : null; if ($diff !== null && abs($diff) <= 0.01) { $diff = 0; } $payments = $order->shopping_payments; $paymentTxSummary = $payments->isEmpty() ? null : $payments->pluck('txaction')->filter()->unique()->implode(', '); $user = $aboOrder->user_abo->user ?? null; $rows[] = [ 'abo_order_id' => $aboOrder->id, 'abo_id' => $aboOrder->user_abo_id, 'order_id' => 'shopping_order_id]).'>'.$aboOrder->shopping_order_id.'', 'user_id' => $user->id ?? null, 'user_name' => $aboOrder->shopping_order->shopping_user ? ($aboOrder->shopping_order->shopping_user->billing_firstname ?? '').' '.($aboOrder->shopping_order->shopping_user->billing_lastname ?? '') : '-', 'user_email' => $aboOrder->shopping_order->shopping_user ? $aboOrder->shopping_order->shopping_user->billing_email ?? '-' : '-', 'is_for' => $aboOrder->user_abo->is_for ?? '-', 'subtotal_ws' => $subtotalWs, 'tax' => $tax, 'total_shipping' => $totalShipping, 'actual_charged_eur' => $actualEur, 'payment_count' => $payments->count(), 'payment_txactions' => $paymentTxSummary, 'diff' => $diff, 'status' => $aboOrder->status, 'paid' => $aboOrder->paid, 'txaction' => $order->txaction, 'created_at' => $aboOrder->created_at, ]; if ($diff !== null && abs($diff) >= 0.01) { $summary['total_diff'] += $diff; $summary['affected_orders']++; } } $summary['total_diff'] = round($summary['total_diff'], 2); return view('sys.tools.abo-orders-overview', [ 'rows' => $rows, 'summary' => $summary, 'filter' => $filter, ]); } /** * Summiert erfolgreiche Abbuchungen aus `shopping_payments` (Cent). * Kein Treffer bei erfolgreichen Status → null (kein belastbarer Eingang). */ public static function actualChargedCentsFromPayments(ShoppingOrder $order): ?int { $payments = $order->shopping_payments; if ($payments === null || $payments->isEmpty()) { return null; } $successful = $payments->filter( fn ($p) => in_array($p->txaction, self::SUCCESS_TXACTIONS, true) ); $sum = (int) $successful->sum('amount'); return $sum > 0 ? $sum : null; } }