10.April 2026
This commit is contained in:
parent
a00c42e770
commit
f58c709945
208 changed files with 19280 additions and 2914 deletions
127
app/Services/SyS/AboOrdersOverview.php
Normal file
127
app/Services/SyS/AboOrdersOverview.php
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\UserAboOrder;
|
||||
|
||||
class AboOrdersOverview
|
||||
{
|
||||
/**
|
||||
* Payone-/Shop-Zahlungsstatus: tatsächlich eingezogen.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
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' => '<a href='.route('admin_sales_customers_detail', [$aboOrder->shopping_order_id]).'>'.$aboOrder->shopping_order_id.'</a>',
|
||||
'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;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue