Billing: fatture manuali, profilo obbligatorio e piani Stripe mensile/annuale.

Rimuove link al portale Stripe in area cliente, aggiunge flusso admin per PDF
fattura e email, blocca checkout senza dati di fatturazione, allinea prezzi
a €4,90/€39,90 e €9,90/€69,90, locale italiano e documentazione deploy.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-02 17:10:12 +02:00
parent 148402a97c
commit a5e781729c
78 changed files with 2457 additions and 424 deletions

View File

@@ -1,15 +1,14 @@
<%# locals: (club:, payments:, invoices:) %>
<%# locals: (club:, payments:) %>
<section class="billing-documents" style="margin-top:40px">
<h2>Pagamenti e fatture</h2>
<p style="color:#888;font-size:0.9rem">
Qui trovi lo storico dei pagamenti e le fatture emesse alla società.
I pagamenti premium sono elaborati in modo sicuro tramite Stripe.
Storico dei pagamenti della società e relative fatture emesse da Match Live TV.
</p>
<% unless club.billing_profile_complete? %>
<div class="flash alert" style="margin:16px 0">
<strong>Dati di fatturazione incompleti.</strong>
Compila ragione sociale, indirizzo, P.IVA/CF e SDI o PEC per ricevere le fatture.
Compila ragione sociale, indirizzo, P.IVA/CF e SDI o PEC per ricevere le fatture via email.
<%= link_to "Completa ora", public_club_billing_profile_path(club), class: "btn btn-secondary", style: "margin-top:10px;display:inline-block" %>
</div>
<% else %>
@@ -19,14 +18,7 @@
</p>
<% end %>
<% if MatchLiveTv.stripe_enabled? && club.subscription&.stripe_customer_id.present? %>
<%= button_to "Sincronizza pagamenti da Stripe",
public_club_billing_sync_payments_path(club),
class: "btn btn-secondary",
style: "margin:12px 0" %>
<% end %>
<h3 style="margin-top:28px;font-size:1.1rem">Pagamenti effettuati</h3>
<h3 style="margin-top:28px;font-size:1.1rem">Pagamenti e fatture</h3>
<% if payments.any? %>
<table class="data billing-table">
<thead>
@@ -34,54 +26,34 @@
<th>Data</th>
<th>Descrizione</th>
<th>Importo</th>
<th>Stato</th>
<th>Stato pagamento</th>
<th>Fattura</th>
<th></th>
</tr>
</thead>
<tbody>
<% payments.each do |payment| %>
<% inv = payment.invoice_for_display %>
<tr>
<td><%= payment.paid_at ? l(payment.paid_at, format: :short) : "—" %></td>
<td><%= payment.description.presence || payment.plan_slug&.humanize || "Abbonamento" %></td>
<td><%= payment.paid_at ? l_local(payment.paid_at, format: :short) : "—" %></td>
<td><%= payment.display_description %></td>
<td><%= payment.formatted_amount %></td>
<td><%= payment.status %></td>
<td><%= payment.display_status %></td>
<td>
<% if payment.receipt_url.present? %>
<%= link_to "Ricevuta Stripe", payment.receipt_url, target: "_blank", rel: "noopener" %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% else %>
<p style="color:#888">Nessun pagamento registrato. Dopo un abbonamento premium comparirà qui (anche tramite «Sincronizza pagamenti»).</p>
<% end %>
<h3 style="margin-top:28px;font-size:1.1rem">Fatture</h3>
<% if invoices.any? %>
<table class="data billing-table">
<thead>
<tr>
<th>Numero</th>
<th>Data</th>
<th>Importo</th>
<th>Stato</th>
<th></th>
</tr>
</thead>
<tbody>
<% invoices.each do |invoice| %>
<tr>
<td><%= invoice.number %></td>
<td><%= l(invoice.issued_on) %></td>
<td><%= invoice.formatted_amount %></td>
<td><%= invoice.status %></td>
<td>
<% if invoice.downloadable? %>
<%= link_to "Scarica PDF", public_club_billing_invoice_path(club, invoice) %>
<% if inv.present? %>
<%= inv.display_number %>
· <%= inv.display_status %>
<% else %>
<% end %>
</td>
<td>
<% if inv&.downloadable? %>
<%= link_to "Scarica PDF", public_club_billing_invoice_path(club, inv) %>
<% elsif inv&.draft? %>
<span style="color:#888">PDF in preparazione</span>
<% else %>
<span style="color:#888">—</span>
<% end %>
</td>
</tr>
@@ -89,6 +61,6 @@
</tbody>
</table>
<% else %>
<p style="color:#888">Nessuna fattura disponibile. Compariranno qui dopo lemissione.</p>
<p style="color:#888">Nessun pagamento registrato. Dopo un abbonamento premium comparirà qui.</p>
<% end %>
</section>