feat: replace Stripe Global Payouts with manual bank transfer system for France compliance
- Replace Stripe automatic payouts with manual admin-processed bank transfers - Add banking information fields (IBAN, bank name, account holder) to User model - Implement manual payout workflow: pending → approved → processing → completed - Add comprehensive admin interface for payout review and processing - Update Payout model with manual processing fields and workflow methods - Add transfer reference tracking and rejection/failure handling - Consolidate all migration fragments into clean "create" migrations - Add comprehensive documentation for manual payout workflow - Fix Event payout_status enum definition and database column issues This addresses France's lack of Stripe Global Payouts support by implementing a complete manual bank transfer workflow while maintaining audit trails and proper admin controls. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,76 +1,49 @@
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h1 class="text-3xl font-bold text-gray-900">Admin Payouts</h1>
|
||||
<h1 class="text-3xl font-bold text-gray-900">Manual Payout Administration</h1>
|
||||
</div>
|
||||
|
||||
<% if @payouts.any? %>
|
||||
<div class="bg-white rounded-lg shadow overflow-hidden">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Event</th>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Promoter</th>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Amount</th>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Date</th>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
<% @payouts.each do |payout| %>
|
||||
<tr>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="text-sm font-medium text-gray-900"><%= payout.event.name %></div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="text-sm text-gray-900"><%= payout.user.name.presence || payout.user.email %></div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="text-sm text-gray-900">€<%= payout.amount_euros %></div>
|
||||
<div class="text-sm text-gray-500">Net: €<%= payout.net_amount_euros %> (Fee: €<%= payout.fee_euros %>)</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<% case payout.status %>
|
||||
<% when 'pending' %>
|
||||
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800">
|
||||
Pending
|
||||
</span>
|
||||
<% when 'processing' %>
|
||||
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-100 text-blue-800">
|
||||
Processing
|
||||
</span>
|
||||
<% when 'completed' %>
|
||||
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">
|
||||
Completed
|
||||
</span>
|
||||
<% when 'failed' %>
|
||||
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">
|
||||
Failed
|
||||
</span>
|
||||
<% end %>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
<%= payout.created_at.strftime("%b %d, %Y") %>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
|
||||
<% if payout.can_process? %>
|
||||
<%= button_to "Process", admin_payout_path(payout), method: :post,
|
||||
class: "text-indigo-600 hover:text-indigo-900 bg-indigo-100 hover:bg-indigo-200 px-3 py-1 rounded" %>
|
||||
<% end %>
|
||||
<%= link_to "View", promoter_payout_path(payout), class: "text-indigo-600 hover:text-indigo-900 ml-2" %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<% if @payouts.respond_to?(:total_pages) %>
|
||||
<div class="mt-6">
|
||||
<%= paginate @payouts %>
|
||||
<!-- Pending Payouts - Require Review -->
|
||||
<% if @pending_payouts.any? %>
|
||||
<div class="mb-8">
|
||||
<h2 class="text-xl font-semibold text-gray-900 mb-4">📋 Pending Review (<%= @pending_payouts.count %>)</h2>
|
||||
<div class="bg-white rounded-lg shadow overflow-hidden">
|
||||
<%= render partial: 'payout_table', locals: { payouts: @pending_payouts, show_actions: true, section: 'pending' } %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% else %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Approved Payouts - Ready for Transfer -->
|
||||
<% if @approved_payouts.any? %>
|
||||
<div class="mb-8">
|
||||
<h2 class="text-xl font-semibold text-gray-900 mb-4">✅ Approved - Ready for Transfer (<%= @approved_payouts.count %>)</h2>
|
||||
<div class="bg-white rounded-lg shadow overflow-hidden">
|
||||
<%= render partial: 'payout_table', locals: { payouts: @approved_payouts, show_actions: true, section: 'approved' } %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Processing Payouts - Transfer Initiated -->
|
||||
<% if @processing_payouts.any? %>
|
||||
<div class="mb-8">
|
||||
<h2 class="text-xl font-semibold text-gray-900 mb-4">🔄 Processing - Transfer in Progress (<%= @processing_payouts.count %>)</h2>
|
||||
<div class="bg-white rounded-lg shadow overflow-hidden">
|
||||
<%= render partial: 'payout_table', locals: { payouts: @processing_payouts, show_actions: true, section: 'processing' } %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Recent Completed Payouts -->
|
||||
<% if @completed_payouts.any? %>
|
||||
<div class="mb-8">
|
||||
<h2 class="text-xl font-semibold text-gray-900 mb-4">✨ Recently Completed</h2>
|
||||
<div class="bg-white rounded-lg shadow overflow-hidden">
|
||||
<%= render partial: 'payout_table', locals: { payouts: @completed_payouts, show_actions: false, section: 'completed' } %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if @pending_payouts.empty? && @approved_payouts.empty? && @processing_payouts.empty? && @completed_payouts.empty? %>
|
||||
<div class="bg-white rounded-lg shadow p-6 text-center">
|
||||
<p class="text-gray-500">No payouts found.</p>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user