Add financial dashboard for organizer in payouts tab
- 6 KPIs: encaissé, en attente, remboursé, com E-Ticket, com Stripe, net perçu - Calculated from all orders linked to organizer's events - Displayed above export buttons and payouts table Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
- [ ] Ajouter une notification admin quand un orga accepte/refuse une invitation
|
||||
|
||||
### Paiements & Finances
|
||||
- [ ] Ajouter le dashboard financier pour l'orga (total encaissé, en attente, remboursé)
|
||||
- [x] Ajouter le dashboard financier pour l'orga (encaissé, en attente, remboursé, com E-Ticket, com Stripe, net perçu)
|
||||
- [x] Ajouter les virements Stripe (payouts) dans l'onglet de l'orga (déjà en place)
|
||||
- [x] Générer un récapitulatif mensuel des ventes (export CSV + PDF, admin et orga)
|
||||
|
||||
|
||||
@@ -73,6 +73,35 @@ class AccountController extends AbstractController
|
||||
$events = $paginator->paginate($eventsQuery, $request->query->getInt('page', 1), 10);
|
||||
}
|
||||
|
||||
$financeStats = ['paid' => 0, 'pending' => 0, 'refunded' => 0, 'cancelled' => 0, 'commissionEticket' => 0, 'commissionStripe' => 0, 'net' => 0];
|
||||
if ($isOrganizer) {
|
||||
$orgaOrders = $em->createQueryBuilder()
|
||||
->select('o')
|
||||
->from(BilletBuyer::class, 'o')
|
||||
->join('o.event', 'e')
|
||||
->where('e.account = :user')
|
||||
->setParameter('user', $user)
|
||||
->getQuery()
|
||||
->getResult();
|
||||
|
||||
$rate = $user->getCommissionRate() ?? 3;
|
||||
foreach ($orgaOrders as $o) {
|
||||
$ht = $o->getTotalHT() / 100;
|
||||
if (BilletBuyer::STATUS_PAID === $o->getStatus()) {
|
||||
$financeStats['paid'] += $ht;
|
||||
$financeStats['commissionEticket'] += $ht * ($rate / 100);
|
||||
$financeStats['commissionStripe'] += $ht * 0.015 + 0.25;
|
||||
} elseif (BilletBuyer::STATUS_PENDING === $o->getStatus()) {
|
||||
$financeStats['pending'] += $ht;
|
||||
} elseif (BilletBuyer::STATUS_REFUNDED === $o->getStatus()) {
|
||||
$financeStats['refunded'] += $ht;
|
||||
} elseif (BilletBuyer::STATUS_CANCELLED === $o->getStatus()) {
|
||||
$financeStats['cancelled'] += $ht;
|
||||
}
|
||||
}
|
||||
$financeStats['net'] = $financeStats['paid'] - $financeStats['commissionEticket'] - $financeStats['commissionStripe'];
|
||||
}
|
||||
|
||||
$orders = $em->getRepository(BilletBuyer::class)->findBy(
|
||||
['user' => $user],
|
||||
['createdAt' => 'DESC'],
|
||||
@@ -94,6 +123,7 @@ class AccountController extends AbstractController
|
||||
'events' => $events,
|
||||
'orders' => $orders,
|
||||
'userTickets' => $userTickets,
|
||||
'financeStats' => $financeStats,
|
||||
'breadcrumbs' => [
|
||||
self::BREADCRUMB_HOME,
|
||||
self::BREADCRUMB_ACCOUNT,
|
||||
|
||||
@@ -415,6 +415,33 @@
|
||||
</div>
|
||||
|
||||
{% elseif tab == 'payouts' %}
|
||||
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4 mb-6">
|
||||
<div class="card-brutal p-4 text-center">
|
||||
<div class="text-[10px] font-black uppercase tracking-widest text-gray-500 mb-1">Encaisse</div>
|
||||
<div class="text-xl font-black text-green-600">{{ financeStats.paid|number_format(2, ',', ' ') }} €</div>
|
||||
</div>
|
||||
<div class="card-brutal p-4 text-center">
|
||||
<div class="text-[10px] font-black uppercase tracking-widest text-gray-500 mb-1">En attente</div>
|
||||
<div class="text-xl font-black text-yellow-600">{{ financeStats.pending|number_format(2, ',', ' ') }} €</div>
|
||||
</div>
|
||||
<div class="card-brutal p-4 text-center">
|
||||
<div class="text-[10px] font-black uppercase tracking-widest text-gray-500 mb-1">Rembourse</div>
|
||||
<div class="text-xl font-black text-red-600">{{ financeStats.refunded|number_format(2, ',', ' ') }} €</div>
|
||||
</div>
|
||||
<div class="card-brutal p-4 text-center">
|
||||
<div class="text-[10px] font-black uppercase tracking-widest text-gray-500 mb-1">Com E-Ticket</div>
|
||||
<div class="text-xl font-black text-red-500">{{ financeStats.commissionEticket|number_format(2, ',', ' ') }} €</div>
|
||||
</div>
|
||||
<div class="card-brutal p-4 text-center">
|
||||
<div class="text-[10px] font-black uppercase tracking-widest text-gray-500 mb-1">Com Stripe</div>
|
||||
<div class="text-xl font-black text-red-500">{{ financeStats.commissionStripe|number_format(2, ',', ' ') }} €</div>
|
||||
</div>
|
||||
<div class="card-brutal p-4 text-center bg-green-50">
|
||||
<div class="text-[10px] font-black uppercase tracking-widest text-gray-500 mb-1">Net percu</div>
|
||||
<div class="text-xl font-black text-green-600">{{ financeStats.net|number_format(2, ',', ' ') }} €</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-brutal overflow-hidden mb-6">
|
||||
<div class="section-header">
|
||||
<h2 class="text-[10px] font-black uppercase tracking-widest text-white">Export mensuel</h2>
|
||||
|
||||
Reference in New Issue
Block a user