Mostra il piano attivo dopo il bonifico e allinea il flusso società.
Dopo la conferma admin la card restava su «Paga con bonifico»; la società parte da Free, l'owner è staff trasmissione e le mail non bloccano se manca SMTP. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -23,23 +23,28 @@ module Public
|
||||
ClubMembership.create!(user: current_user, club: club, role: "owner")
|
||||
|
||||
first_team_name = params.dig(:first_team, :name).presence || t("club.new.default_first_team_name")
|
||||
club.teams.create!(
|
||||
first_team = club.teams.create!(
|
||||
name: first_team_name,
|
||||
sport: club.sport
|
||||
)
|
||||
|
||||
plan = params[:plan].presence_in(%w[free premium_light premium_full]) || "free"
|
||||
Billing::AssignPlan.call(club: club, plan_slug: plan)
|
||||
desired_plan = params[:plan].presence_in(%w[free premium_light premium_full]) || "free"
|
||||
Billing::AssignPlan.call(club: club, plan_slug: "free")
|
||||
Teams::StaffAssignment.designate_club_owner!(team: first_team, user: current_user)
|
||||
|
||||
if plan.in?(%w[premium_light premium_full]) && MatchLiveTv.stripe_enabled?
|
||||
unless club.billing_profile_complete?
|
||||
redirect_to public_club_billing_profile_path(club, plan: plan, interval: checkout_interval_param),
|
||||
alert: t("flash.clubs.complete_billing_first")
|
||||
return
|
||||
if desired_plan.in?(%w[premium_light premium_full])
|
||||
interval = Billing::Stripe::PriceCatalog::DEFAULT_INTERVAL
|
||||
if MatchLiveTv.stripe_enabled?
|
||||
unless club.billing_profile_complete?
|
||||
redirect_to public_club_billing_profile_path(club, plan: desired_plan, interval: interval),
|
||||
alert: t("flash.clubs.complete_billing_first")
|
||||
return
|
||||
end
|
||||
|
||||
redirect_to public_club_checkout_path(club, plan: desired_plan, interval: interval)
|
||||
else
|
||||
redirect_to public_club_billing_path(club), notice: t("flash.clubs.created_complete_subscription")
|
||||
end
|
||||
|
||||
interval = checkout_interval_param
|
||||
redirect_to public_club_checkout_path(club, plan: plan, interval: interval)
|
||||
else
|
||||
redirect_to public_club_path(club), notice: t("flash.clubs.created")
|
||||
end
|
||||
|
||||
@@ -19,6 +19,7 @@ module Public
|
||||
require_club_owner!(@club)
|
||||
team = @club.teams.create!(team_params)
|
||||
attach_branding_logo(team)
|
||||
Teams::StaffAssignment.designate_club_owner!(team: team, user: current_user)
|
||||
redirect_to public_club_path(@club), notice: t("flash.teams.added", name: team.name)
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
flash.now[:alert] = e.record.errors.full_messages.join(", ")
|
||||
|
||||
@@ -11,6 +11,13 @@ module Public
|
||||
quote = club&.active_billing_quote
|
||||
if quote
|
||||
if quote.plan_slug == target_plan.slug
|
||||
if current_paid_plan?(subscription, target_plan)
|
||||
return {
|
||||
kind: :current,
|
||||
label: "#{I18n.t('billing.actions.current_plan')} — #{quote.price_label}"
|
||||
}
|
||||
end
|
||||
|
||||
return { kind: :quoted, plan: target_plan, quote: quote, intervals: [quote.billing_interval] }
|
||||
end
|
||||
|
||||
@@ -19,6 +26,9 @@ module Public
|
||||
|
||||
intervals = bank_transfer_intervals_for(target_plan)
|
||||
unless MatchLiveTv.stripe_enabled?
|
||||
if current_paid_plan?(subscription, target_plan)
|
||||
return { kind: :current, label: current_plan_label(target_plan, subscription) }
|
||||
end
|
||||
if MatchLiveTv.bank_transfer_configured?
|
||||
return { kind: :bank_only, plan: target_plan, intervals: intervals }
|
||||
end
|
||||
@@ -28,6 +38,9 @@ module Public
|
||||
|
||||
stripe_intervals = Billing::Stripe::PriceCatalog.available_intervals(plan_slug: target_plan.slug)
|
||||
if stripe_intervals.empty?
|
||||
if current_paid_plan?(subscription, target_plan)
|
||||
return { kind: :current, label: current_plan_label(target_plan, subscription) }
|
||||
end
|
||||
if MatchLiveTv.bank_transfer_configured?
|
||||
return { kind: :bank_only, plan: target_plan, intervals: intervals }
|
||||
end
|
||||
@@ -54,6 +67,10 @@ module Public
|
||||
}
|
||||
end
|
||||
|
||||
if current_paid_plan?(subscription, target_plan)
|
||||
return { kind: :current, label: current_plan_label(target_plan, subscription) }
|
||||
end
|
||||
|
||||
if current_slug == "free" || !stripe_subscription_active
|
||||
{ kind: :checkout_options, plan: target_plan, intervals: stripe_intervals.presence || intervals, subscription: subscription }
|
||||
else
|
||||
@@ -136,8 +153,21 @@ module Public
|
||||
return false unless MatchLiveTv.bank_transfer_configured?
|
||||
return false if quote && !quote.matches?(plan.slug, interval)
|
||||
return false if pending_transfer&.awaiting_payment?
|
||||
return false if current_paid_plan?(club.subscription, plan)
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def current_paid_plan?(subscription, target_plan)
|
||||
return false unless subscription&.active? && subscription.premium?
|
||||
return false if subscription.plan_change_pending?
|
||||
|
||||
subscription.plan.slug == target_plan.slug
|
||||
end
|
||||
|
||||
def current_plan_label(target_plan, subscription)
|
||||
interval = subscription&.billing_interval.presence || Billing::Stripe::PriceCatalog::DEFAULT_INTERVAL
|
||||
"#{I18n.t('billing.actions.current_plan')} — #{Billing::Stripe::PriceCatalog.label(plan_slug: target_plan.slug, interval: interval)}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -88,7 +88,7 @@ module Billing
|
||||
mailer_action: :plan_activated_with_invoice
|
||||
)
|
||||
else
|
||||
BankTransferMailer.with(order: @order.reload).plan_activated.deliver_now
|
||||
MatchLiveTv.deliver_mail(BankTransferMailer.with(order: @order.reload).plan_activated)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -26,8 +26,10 @@ module Billing
|
||||
|
||||
@invoice.update!(status: "issued")
|
||||
|
||||
Billing::InvoiceMailer.with(invoice: @invoice).public_send(@mailer_action).deliver_now
|
||||
@invoice.update!(status: "sent", emailed_at: Time.current)
|
||||
mail = Billing::InvoiceMailer.with(invoice: @invoice).public_send(@mailer_action)
|
||||
if MatchLiveTv.deliver_mail(mail)
|
||||
@invoice.update!(status: "sent", emailed_at: Time.current)
|
||||
end
|
||||
|
||||
@invoice
|
||||
end
|
||||
|
||||
@@ -28,7 +28,7 @@ module Billing
|
||||
existing = @club.billing_transfer_orders.awaiting_payment.first
|
||||
if existing
|
||||
if existing.plan_slug == @plan_slug && existing.billing_interval == @interval && existing.amount_cents == amount_cents
|
||||
BankTransferMailer.with(order: existing).instructions.deliver_now
|
||||
MatchLiveTv.deliver_mail(BankTransferMailer.with(order: existing).instructions)
|
||||
return existing
|
||||
end
|
||||
|
||||
@@ -59,7 +59,7 @@ module Billing
|
||||
)
|
||||
end
|
||||
|
||||
BankTransferMailer.with(order: order).instructions.deliver_now
|
||||
MatchLiveTv.deliver_mail(BankTransferMailer.with(order: order).instructions)
|
||||
order
|
||||
end
|
||||
|
||||
|
||||
@@ -23,5 +23,12 @@ module Teams
|
||||
ut.update!(staff_kind: "transmission")
|
||||
ut
|
||||
end
|
||||
|
||||
def self.designate_club_owner!(team:, user:)
|
||||
membership = user.user_teams.find_or_initialize_by(team: team)
|
||||
membership.role = "member" if membership.new_record?
|
||||
membership.save!
|
||||
call(team: team, user: user, membership: membership)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -42,6 +42,10 @@
|
||||
</header>
|
||||
<div class="billing-pending-card__body">
|
||||
<p style="margin:0 0 12px">
|
||||
<%= t("admin.billing.index.transfers_table.holder") %>:
|
||||
<strong><%= MatchLiveTv.bank_transfer_account_holder %></strong><br>
|
||||
<%= t("admin.billing.index.transfers_table.iban") %>:
|
||||
<strong><%= MatchLiveTv.bank_transfer_iban %></strong><br>
|
||||
<%= t("admin.billing.index.transfers_table.causal") %>:
|
||||
<strong><%= order.payment_causal %></strong>
|
||||
</p>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<script src="/admin-dashboard.js?v=1" defer></script>
|
||||
<% end %>
|
||||
<link rel="stylesheet" href="/confirm-forms.css?v=4">
|
||||
<script src="/confirm-forms.js?v=6" defer></script>
|
||||
<script src="/confirm-forms.js?v=7" defer></script>
|
||||
</head>
|
||||
<body class="<%= content_for?(:body_class) ? yield(:body_class) : 'admin-body' %>">
|
||||
<header class="admin-header">
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<script src="/roster-form.js?v=1" defer></script>
|
||||
<script src="/password-toggle.js?v=2" defer></script>
|
||||
<link rel="stylesheet" href="/confirm-forms.css?v=4">
|
||||
<script src="/confirm-forms.js?v=6" defer></script>
|
||||
<script src="/confirm-forms.js?v=7" defer></script>
|
||||
<script src="/cookie-consent.js?v=1" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
</main>
|
||||
<%= render "shared/marketing_footer" %>
|
||||
<link rel="stylesheet" href="/confirm-forms.css?v=4">
|
||||
<script src="/confirm-forms.js?v=6" defer></script>
|
||||
<script src="/confirm-forms.js?v=7" defer></script>
|
||||
<script src="/cookie-consent.js?v=1" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
</div>
|
||||
<% else %>
|
||||
<% if @quote %>
|
||||
<%= render "shared/quoted_price_banner", quote: @quote %>
|
||||
<%= render "shared/quoted_price_banner", quote: @quote, subscription: @subscription %>
|
||||
<% elsif MatchLiveTv.stripe_enabled? %>
|
||||
<%= render "shared/stripe_secure_payment" %>
|
||||
<% end %>
|
||||
|
||||
@@ -24,15 +24,8 @@
|
||||
[t("club.new.plan_free"), "free"],
|
||||
[t("club.new.plan_light"), "premium_light"],
|
||||
[t("club.new.plan_full"), "premium_full"]
|
||||
], params[:plan] || "free"), id: "club_plan_select" %>
|
||||
<div id="club_plan_interval" style="margin-top:10px">
|
||||
<%= label_tag :interval, t("club.new.interval_label") %>
|
||||
<%= select_tag :interval, options_for_select([
|
||||
[t("club.new.interval_yearly"), "yearly"],
|
||||
[t("club.new.interval_monthly"), "monthly"]
|
||||
], params[:interval] || "yearly") %>
|
||||
</div>
|
||||
<%= render "shared/stripe_secure_payment", compact: true %>
|
||||
], params[:plan] || "free") %>
|
||||
<p class="muted" style="margin:8px 0 16px"><%= t("club.new.plan_hint") %></p>
|
||||
<%= submit_tag t("club.new.submit"), class: "btn btn-primary" %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
<% team = local_assigns[:team] %>
|
||||
<% club = local_assigns[:club] %>
|
||||
<% can_manage = local_assigns[:can_manage] %>
|
||||
<% owner_membership = local_assigns[:owner_membership] %>
|
||||
<% staff_memberships = local_assigns[:staff_memberships] %>
|
||||
<% pending_invitations = local_assigns[:pending_invitations] %>
|
||||
<% recordings = local_assigns[:recordings] %>
|
||||
<% entitlements = local_assigns[:entitlements] %>
|
||||
<% club_owner = club.owner %>
|
||||
<% extra_staff = staff_memberships.reject { |ut| ut.user_id == club_owner&.id } %>
|
||||
|
||||
<section class="team-streaming-staff" id="responsabili-trasmissione">
|
||||
<% if can_manage %>
|
||||
<% if owner_membership&.staff_kind.blank? %>
|
||||
<div class="card team-streaming-staff__self">
|
||||
<h2><%= t("team.streaming_staff.self_account_heading", email: current_user.email) %></h2>
|
||||
<p class="muted">
|
||||
<%= raw t("team.streaming_staff.self_account_hint") %>
|
||||
</p>
|
||||
<div class="team-details-actions">
|
||||
<%= button_to t("team.streaming_staff.self_assign_submit"), public_team_assign_self_staff_path(team), method: :post, params: { staff_kind: "transmission" }, class: "btn btn-primary" %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if club_owner %>
|
||||
<div class="card team-streaming-staff__self">
|
||||
<h2><%= t("team.streaming_staff.principal_heading") %></h2>
|
||||
<p>
|
||||
<%= raw t("team.streaming_staff.principal_body_html", email: club_owner.email) %>
|
||||
</p>
|
||||
<p class="muted">
|
||||
<%= raw t("team.streaming_staff.principal_score_hint_html") %>
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<h2><%= t("team.streaming_staff.staff_heading") %></h2>
|
||||
<div class="card">
|
||||
<% if staff_memberships.any? %>
|
||||
<% if extra_staff.any? %>
|
||||
<h2><%= t("team.streaming_staff.extra_staff_heading") %></h2>
|
||||
<div class="card">
|
||||
<table class="data">
|
||||
<thead><tr><th><%= t("team.streaming_staff.col_name") %></th><th><%= t("team.streaming_staff.col_email") %></th><th><%= t("team.streaming_staff.col_role") %></th><% if can_manage %><th></th><% end %></tr></thead>
|
||||
<tbody>
|
||||
<% staff_memberships.each do |ut| %>
|
||||
<% extra_staff.each do |ut| %>
|
||||
<tr>
|
||||
<td>
|
||||
<%= ut.user.name %>
|
||||
@@ -37,9 +37,7 @@
|
||||
<td><%= t("team.streaming_staff.role_transmission") %></td>
|
||||
<% if can_manage %>
|
||||
<td>
|
||||
<% if ut.user_id == current_user.id && team.club.owned_by?(current_user) %>
|
||||
<%= button_to t("team.streaming_staff.clear_self_staff"), public_team_clear_self_staff_path(team), method: :delete, class: "btn btn-secondary", style: "padding:4px 10px;font-size:0.8rem", form: { data: { turbo_confirm: t("team.streaming_staff.clear_self_staff_confirm"), confirm_kind: "delete" } } %>
|
||||
<% elsif ut.role == "member" %>
|
||||
<% if ut.role == "member" %>
|
||||
<%= button_to t("team.streaming_staff.revoke"), public_team_remove_member_path(team, ut.user), method: :delete, class: "btn btn-secondary", style: "padding:4px 10px;font-size:0.8rem", form: { data: { turbo_confirm: t("team.streaming_staff.revoke_confirm", name: ut.user.name), confirm_kind: "delete" } } %>
|
||||
<% end %>
|
||||
</td>
|
||||
@@ -48,13 +46,8 @@
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<% else %>
|
||||
<p class="muted">
|
||||
<%= t("team.streaming_staff.no_staff") %>
|
||||
<% if can_manage %><%= link_to t("team.streaming_staff.invite_someone"), "#invita-trasmissione" %>.<% end %>
|
||||
</p>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if can_manage %>
|
||||
<div class="card team-invite-form" id="invita-trasmissione">
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
<%# locals: (order:) %>
|
||||
<% return if order.blank? %>
|
||||
<div class="card" style="margin-top:16px;border-color:#3d3520;background:#1a1810">
|
||||
<p style="margin:0 0 8px;color:#ddd">
|
||||
<p style="margin:0;color:#ddd">
|
||||
<strong><%= t("billing.bank_transfer.pending_title") %></strong>
|
||||
<%= raw t("billing.bank_transfer.pending_body_html",
|
||||
plan: order.plan.name,
|
||||
price: order.price_label,
|
||||
causal: order.payment_causal) %>
|
||||
</p>
|
||||
<p style="margin:0;color:#aaa;font-size:0.9rem">
|
||||
<%= raw t("billing.bank_transfer.pending_proof_html",
|
||||
email_link: mail_to(MatchLiveTv.bank_transfer_proof_email, MatchLiveTv.bank_transfer_proof_email)) %>
|
||||
price: order.price_label) %>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
public_club_billing_bank_transfer_path(club, plan: plan.slug, interval: interval),
|
||||
method: :post,
|
||||
class: "btn btn-outline plan-interval-btn",
|
||||
form: { data: { turbo_confirm: t("billing.bank_transfer.hint") } } %>
|
||||
form: { data: { turbo_confirm: t("billing.bank_transfer.confirm") } } %>
|
||||
<% end %>
|
||||
</div>
|
||||
<p class="plan-action-hint" style="margin-top:8px"><%= t("billing.bank_transfer.hint") %></p>
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
<%# locals: (quote:) %>
|
||||
<%# locals: (quote:, subscription: nil) %>
|
||||
<% return if quote.blank? %>
|
||||
<% quoted_plan_active = current_paid_plan?(subscription, quote.plan) %>
|
||||
<div class="card" style="margin-top:16px;border-color:#2e5a3c;background:#142018">
|
||||
<p style="margin:0;color:#ddd">
|
||||
<strong><%= t("billing.bank_transfer.quote_banner_title") %></strong>
|
||||
<%= raw t("billing.bank_transfer.quote_banner_body_html", plan: quote.plan.name, price: quote.price_label) %>
|
||||
<% if quoted_plan_active %>
|
||||
<strong><%= t("billing.bank_transfer.quote_banner_active_title") %></strong>
|
||||
<%= raw t(
|
||||
"billing.bank_transfer.quote_banner_active_body_html",
|
||||
plan: quote.plan.name,
|
||||
price: quote.price_label,
|
||||
date: subscription&.current_period_end.present? ? l_local(subscription.current_period_end.to_date) : t("billing.subscription_status.end_of_period")
|
||||
) %>
|
||||
<% else %>
|
||||
<strong><%= t("billing.bank_transfer.quote_banner_title") %></strong>
|
||||
<%= raw t("billing.bank_transfer.quote_banner_body_html", plan: quote.plan.name, price: quote.price_label) %>
|
||||
<% end %>
|
||||
</p>
|
||||
<% if quote.note.present? %>
|
||||
<p style="margin:8px 0 0;color:#aaa;font-size:0.9rem"><%= t("billing.bank_transfer.quote_note", note: quote.note) %></p>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -97,6 +97,21 @@ module MatchLiveTv
|
||||
bank_transfer_iban.present? && bank_transfer_account_holder.present?
|
||||
end
|
||||
|
||||
def smtp_configured?
|
||||
ENV["SMTP_ADDRESS"].present?
|
||||
end
|
||||
|
||||
# In produzione senza SMTP non blocca il flusso (es. collaudo): la mail si può inviare a mano.
|
||||
def deliver_mail(mail)
|
||||
if Rails.env.production? && !smtp_configured?
|
||||
Rails.logger.info("[mail] skip (SMTP assente): #{mail.subject}")
|
||||
return false
|
||||
end
|
||||
|
||||
mail.deliver_now
|
||||
true
|
||||
end
|
||||
|
||||
def privacy_controller_name
|
||||
ENV.fetch("PRIVACY_CONTROLLER_NAME", "Emiliano Frascaro")
|
||||
end
|
||||
|
||||
@@ -309,6 +309,8 @@ it:
|
||||
club: Società
|
||||
plan: Piano
|
||||
amount: Importo
|
||||
holder: Intestatario
|
||||
iban: IBAN
|
||||
causal: Causale
|
||||
requested: Richiesto
|
||||
confirm_button: Conferma pagamento e attiva
|
||||
|
||||
@@ -83,11 +83,9 @@ de:
|
||||
first_team_name_placeholder: "z. B. Under 15"
|
||||
plan_label: "Starttarif (für den gesamten Verein)"
|
||||
plan_free: "Free — 1 Streaming-Konto pro Team, 1 Livestream"
|
||||
plan_light: Premium Light
|
||||
plan_full: Premium Full
|
||||
interval_label: Premium-Abrechnung
|
||||
interval_yearly: "Jährlich — 59 €/Jahr (Light) oder 199 €/Jahr (Full)"
|
||||
interval_monthly: "Monatlich — 7,90 €/Monat (Light) oder 24,90 €/Monat (Full)"
|
||||
plan_light: "Premium Light — 59 €/Jahr"
|
||||
plan_full: "Premium Full — 199 €/Jahr"
|
||||
plan_hint: "Karte, Überweisung oder monatliche Abrechnung wählst du danach auf der Abo-Seite. Ein kostenpflichtiger Tarif wird erst nach der Zahlung aktiv."
|
||||
submit: Verein erstellen
|
||||
billing:
|
||||
title: "Abonnement — %{name}"
|
||||
@@ -193,6 +191,10 @@ de:
|
||||
contact_trailer: für ein maßgeschneidertes Angebot.
|
||||
club_payments_link: Zahlungen und Rechnungen des Vereins
|
||||
streaming_staff:
|
||||
principal_heading: Hauptkonto
|
||||
principal_body_html: "Das Konto, mit dem der Verein registriert wurde (<strong>%{email}</strong>), ist <strong>für dieses Team vorgesehen</strong>: damit meldest du dich in der App an und startest den Livestream."
|
||||
principal_score_hint_html: "Für den Punktestand von einem anderen Telefon teile während des Streams den <strong>Regie-Link</strong> (kein zweites Konto nötig)."
|
||||
extra_staff_heading: Weitere Konten, die übertragen können
|
||||
self_account_heading: "Dein Konto (%{email})"
|
||||
self_account_hint: "Du kannst die Übertragung aus der App verwalten. Für den Punktestand von einem anderen Telefon teile den <strong>Regie-Link</strong> während des Streams (kein zweites Konto nötig)."
|
||||
self_assign_submit: Das mache ich — Übertragungsverantwortlicher
|
||||
@@ -613,6 +615,7 @@ de:
|
||||
clubs:
|
||||
already_registered: Du hast bereits einen Verein registriert
|
||||
created: Verein und erstes Team erstellt.
|
||||
created_complete_subscription: Verein erstellt. Schließe das Abo auf dieser Seite ab.
|
||||
updated: Verein aktualisiert.
|
||||
complete_billing_first: Vervollständige deine Rechnungsdaten, bevor du einen Premium-Tarif aktivierst.
|
||||
comped_change_denied: "Dieser Tarif ist ein von Match Live TV verwaltetes kostenloses Abonnement. Um zu einem kostenpflichtigen Abonnement zu wechseln, kontaktiere den Support."
|
||||
|
||||
@@ -78,11 +78,9 @@ en:
|
||||
first_team_name_placeholder: "e.g. Under 15"
|
||||
plan_label: "Starting plan (for the whole club)"
|
||||
plan_free: "Free — 1 transmitter account per team, 1 live stream"
|
||||
plan_light: Premium Light
|
||||
plan_full: Premium Full
|
||||
interval_label: Premium billing
|
||||
interval_yearly: "Yearly — €59/year (Light) or €199/year (Full)"
|
||||
interval_monthly: "Monthly — €7.90/month (Light) or €24.90/month (Full)"
|
||||
plan_light: "Premium Light — €59/year"
|
||||
plan_full: "Premium Full — €199/year"
|
||||
plan_hint: "Card, bank transfer or monthly billing are chosen later on the Subscription page. A paid plan activates only after payment."
|
||||
submit: Create club
|
||||
billing:
|
||||
title: "Subscription — %{name}"
|
||||
@@ -188,6 +186,10 @@ en:
|
||||
contact_trailer: for a custom offer.
|
||||
club_payments_link: Club payments and invoices
|
||||
streaming_staff:
|
||||
principal_heading: Main account
|
||||
principal_body_html: "The account used to register the club (<strong>%{email}</strong>) is the one <strong>designated for this team</strong>: use it in the app to start the live stream."
|
||||
principal_score_hint_html: "For scoring from another phone, share the <strong>control-room link</strong> during the stream (no second account needed)."
|
||||
extra_staff_heading: Other accounts that can broadcast
|
||||
self_account_heading: "Your account (%{email})"
|
||||
self_account_hint: "You can manage streaming from the app. For scoring from another phone, share the <strong>control-room link</strong> during the stream (no second account needed)."
|
||||
self_assign_submit: I'll do it — broadcast manager
|
||||
@@ -608,6 +610,7 @@ en:
|
||||
clubs:
|
||||
already_registered: You've already registered a club
|
||||
created: Club and first team created.
|
||||
created_complete_subscription: Club created. Complete your subscription on this page.
|
||||
updated: Club updated.
|
||||
complete_billing_first: Complete your billing details before activating a premium plan.
|
||||
comped_change_denied: "This plan is a complimentary subscription managed by Match Live TV. To switch to a paid subscription, contact support."
|
||||
|
||||
@@ -83,11 +83,9 @@ es:
|
||||
first_team_name_placeholder: "ej. Sub-15"
|
||||
plan_label: "Plan inicial (para todo el club)"
|
||||
plan_free: "Free — 1 cuenta de emisión por equipo, 1 directo"
|
||||
plan_light: Premium Light
|
||||
plan_full: Premium Full
|
||||
interval_label: Facturación premium
|
||||
interval_yearly: "Anual — 59 €/año (Light) o 199 €/año (Full)"
|
||||
interval_monthly: "Mensual — 7,90 €/mes (Light) o 24,90 €/mes (Full)"
|
||||
plan_light: "Premium Light — 59 €/año"
|
||||
plan_full: "Premium Full — 199 €/año"
|
||||
plan_hint: "La tarjeta, la transferencia o la facturación mensual se eligen después, en Abono. El plan de pago se activa solo tras el pago."
|
||||
submit: Crear club
|
||||
billing:
|
||||
title: "Suscripción — %{name}"
|
||||
@@ -193,6 +191,10 @@ es:
|
||||
contact_trailer: para una oferta a medida.
|
||||
club_payments_link: Pagos y facturas del club
|
||||
streaming_staff:
|
||||
principal_heading: Cuenta principal
|
||||
principal_body_html: "La cuenta con la que se registró el club (<strong>%{email}</strong>) es la <strong>designada para este equipo</strong>: con ella entras en la app y arrancas el directo."
|
||||
principal_score_hint_html: "Para el marcador desde otro teléfono, durante el directo comparte el <strong>enlace de control</strong> (no hace falta una segunda cuenta)."
|
||||
extra_staff_heading: Otras cuentas que pueden transmitir
|
||||
self_account_heading: "Tu cuenta (%{email})"
|
||||
self_account_hint: "Puedes gestionar la transmisión desde la app. Para el marcador desde otro teléfono, comparte el <strong>enlace de control</strong> durante el directo (no hace falta una segunda cuenta)."
|
||||
self_assign_submit: Yo me encargo — responsable de transmisión
|
||||
@@ -613,6 +615,7 @@ es:
|
||||
clubs:
|
||||
already_registered: Ya has registrado un club
|
||||
created: Club y primer equipo creados.
|
||||
created_complete_subscription: Club creado. Completa la suscripción en esta página.
|
||||
updated: Club actualizado.
|
||||
complete_billing_first: Completa tus datos de facturación antes de activar un plan premium.
|
||||
comped_change_denied: "Este plan es una suscripción de cortesía gestionada por Match Live TV. Para pasar a una suscripción de pago, contacta con soporte."
|
||||
|
||||
@@ -83,11 +83,9 @@ fr:
|
||||
first_team_name_placeholder: "ex. Under 15"
|
||||
plan_label: "Forfait de départ (pour tout le club)"
|
||||
plan_free: "Gratuit — 1 compte diffuseur par équipe, 1 direct"
|
||||
plan_light: Premium Light
|
||||
plan_full: Premium Full
|
||||
interval_label: Facturation premium
|
||||
interval_yearly: "Annuel — 59 €/an (Light) ou 199 €/an (Full)"
|
||||
interval_monthly: "Mensuel — 7,90 €/mois (Light) ou 24,90 €/mois (Full)"
|
||||
plan_light: "Premium Light — 59 €/an"
|
||||
plan_full: "Premium Full — 199 €/an"
|
||||
plan_hint: "Carte, virement ou mensualité se choisissent ensuite, sur la page Abonnement. Le forfait payant ne s'active qu'après le paiement."
|
||||
submit: Créer le club
|
||||
billing:
|
||||
title: "Abonnement — %{name}"
|
||||
@@ -193,6 +191,10 @@ fr:
|
||||
contact_trailer: pour une offre sur mesure.
|
||||
club_payments_link: Paiements et factures du club
|
||||
streaming_staff:
|
||||
principal_heading: Compte principal
|
||||
principal_body_html: "Le compte utilisé pour enregistrer le club (<strong>%{email}</strong>) est celui <strong>désigné pour cette équipe</strong> : c’est avec lui que tu te connectes à l’app et que tu lances le direct."
|
||||
principal_score_hint_html: "Pour le score depuis un autre téléphone, pendant le direct partage le <strong>lien régie</strong> (pas besoin d’un second compte)."
|
||||
extra_staff_heading: Autres comptes autorisés à diffuser
|
||||
self_account_heading: "Ton compte (%{email})"
|
||||
self_account_hint: "Tu peux gérer la diffusion depuis l'application. Pour le score depuis un autre téléphone, partage le <strong>lien régie</strong> pendant le direct (pas besoin d'un second compte)."
|
||||
self_assign_submit: C'est moi — responsable diffusion
|
||||
@@ -613,6 +615,7 @@ fr:
|
||||
clubs:
|
||||
already_registered: Tu as déjà inscrit un club
|
||||
created: Club et première équipe créés.
|
||||
created_complete_subscription: Club créé. Termine l'abonnement sur cette page.
|
||||
updated: Club mis à jour.
|
||||
complete_billing_first: Complète tes données de facturation avant d'activer un forfait premium.
|
||||
comped_change_denied: "Ce forfait est un abonnement offert géré par Match Live TV. Pour passer à un abonnement payant, contacte le support."
|
||||
|
||||
@@ -78,11 +78,9 @@ it:
|
||||
first_team_name_placeholder: "es. Under 15"
|
||||
plan_label: "Piano iniziale (per tutta la società)"
|
||||
plan_free: "Free — 1 account trasmettitore per squadra, 1 live"
|
||||
plan_light: Premium Light
|
||||
plan_full: Premium Full
|
||||
interval_label: Fatturazione premium
|
||||
interval_yearly: "Annuale — €59/anno (Light) o €199/anno (Full)"
|
||||
interval_monthly: "Mensile — €7,90/mese (Light) o €24,90/mese (Full)"
|
||||
plan_light: "Premium Light — €59/anno"
|
||||
plan_full: "Premium Full — €199/anno"
|
||||
plan_hint: "Carta, bonifico o cadenza mensile li scegli dopo, nella pagina Abbonamento. Il piano a pagamento si attiva solo dopo il pagamento."
|
||||
submit: Crea società
|
||||
billing:
|
||||
title: "Abbonamento — %{name}"
|
||||
@@ -188,6 +186,10 @@ it:
|
||||
contact_trailer: per un'offerta su misura.
|
||||
club_payments_link: Pagamenti e fatture della società
|
||||
streaming_staff:
|
||||
principal_heading: Account principale
|
||||
principal_body_html: "L'account con cui è stata registrata la società (<strong>%{email}</strong>) è quello <strong>designato per questa squadra</strong>: con quello accedi all'app e avvii la diretta."
|
||||
principal_score_hint_html: "Per il punteggio da un altro telefono, durante la diretta condividi il <strong>link regia</strong> (non serve un secondo account)."
|
||||
extra_staff_heading: Altri account che possono trasmettere
|
||||
self_account_heading: "Il tuo account (%{email})"
|
||||
self_account_hint: "Puoi gestire la trasmissione dall'app. Per il punteggio da un altro telefono, condividi il <strong>link regia</strong> durante la diretta (non serve un secondo account)."
|
||||
self_assign_submit: Sono io — responsabile trasmissione
|
||||
@@ -330,7 +332,7 @@ it:
|
||||
sdi_or_pec: "Codice destinatario SDI (7 caratteri) o PEC"
|
||||
sdi_invalid: "Codice destinatario SDI (7 caratteri)"
|
||||
actions:
|
||||
current_plan: Piano attuale
|
||||
current_plan: Piano attivo
|
||||
contact_for_free: "Per passare al piano Free, contatta il supporto."
|
||||
stripe_not_configured: Stripe non configurato
|
||||
stripe_prices_not_configured: Prezzi Stripe non configurati
|
||||
@@ -436,13 +438,15 @@ it:
|
||||
pay_button: Paga con bonifico
|
||||
pay_button_with_price: "Paga con bonifico — %{price}"
|
||||
or_label: oppure
|
||||
pending_title: Bonifico in attesa di conferma
|
||||
pending_body_html: "Hai richiesto <strong>%{plan}</strong> (%{price}). Il piano si attiverà dopo la conferma del pagamento. Causale: <strong>%{causal}</strong>."
|
||||
pending_proof_html: "Invia la distinta a %{email_link}."
|
||||
pending_title: Ordine in corso
|
||||
pending_body_html: "Hai richiesto <strong>%{plan}</strong> (%{price}). Resta in attesa: il piano si attiverà quando Match Live TV confermerà il pagamento."
|
||||
quote_banner_title: Prezzo concordato
|
||||
quote_banner_body_html: "Per questa società vale <strong>%{plan}</strong> a <strong>%{price}</strong>. Il pagamento avviene solo con bonifico (non con carta)."
|
||||
quote_banner_active_title: Piano attivo
|
||||
quote_banner_active_body_html: "In questo momento vale <strong>%{plan}</strong> a <strong>%{price}</strong>, fino al <strong>%{date}</strong>. Il rinnovo non è automatico."
|
||||
quote_note: "Nota commerciale: %{note}"
|
||||
hint: "Il piano resta quello attuale finché Match Live TV non conferma l'accredito."
|
||||
confirm: "Confermi la richiesta di bonifico? Il piano resta quello attuale finché Match Live TV non conferma l'accredito."
|
||||
renewal_html: "Con il bonifico l'abbonamento non si rinnova da solo: alla scadenza torna Free, salvo nuovo bonifico o rinnovo da parte nostra."
|
||||
regia:
|
||||
meta_title_fallback: "Regia — Match Live TV"
|
||||
@@ -627,6 +631,7 @@ it:
|
||||
clubs:
|
||||
already_registered: Hai già registrato una società
|
||||
created: Società e prima squadra create.
|
||||
created_complete_subscription: Società creata. Completa l'abbonamento in questa pagina.
|
||||
updated: Società aggiornata.
|
||||
complete_billing_first: Completa i dati di fatturazione prima di attivare un piano premium.
|
||||
comped_change_denied: "Il piano è un abbonamento omaggio gestito da Match Live TV. Per passare a un abbonamento a pagamento contatta il supporto."
|
||||
@@ -646,7 +651,7 @@ it:
|
||||
subscription_canceled: "Abbonamento disdetto. Resta attivo fino al %{date}; da quel giorno passerai al piano Free."
|
||||
stripe_error: "Errore Stripe: %{message}"
|
||||
invoice_pdf_unavailable: PDF fattura non disponibile.
|
||||
bank_transfer_requested: Istruzioni per il bonifico inviate all'email di fatturazione. Il piano si attiverà dopo la conferma del pagamento.
|
||||
bank_transfer_requested: Richiesta registrata. Il piano si attiverà dopo la conferma del pagamento.
|
||||
quote_checkout_denied: "Per questa società è attivo un prezzo concordato: usa il pagamento con bonifico."
|
||||
club_recordings:
|
||||
not_authorized: Non autorizzato
|
||||
|
||||
@@ -147,12 +147,13 @@
|
||||
var hasSite = options.hasSite !== false;
|
||||
var hasYoutube = !!options.hasYoutube;
|
||||
var isDelete = !!options.isDelete;
|
||||
var isReplayDelete = !!options.isReplayDelete;
|
||||
var canSite = hasSite;
|
||||
var canYoutube = hasYoutube;
|
||||
var canBoth = hasSite && hasYoutube;
|
||||
var choiceCount = (canSite ? 1 : 0) + (canYoutube ? 1 : 0) + (canBoth ? 1 : 0);
|
||||
// Una sola destinazione disponibile → conferma semplice, senza elenco
|
||||
var multi = !!options.multi && choiceCount > 1;
|
||||
var multi = isReplayDelete && choiceCount > 1;
|
||||
|
||||
if (canBoth) pendingScope = "both";
|
||||
else if (canSite) pendingScope = "site";
|
||||
@@ -175,9 +176,9 @@
|
||||
if (titleEl) {
|
||||
if (multi) {
|
||||
titleEl.textContent = I18N.multiDeleteTitle;
|
||||
} else if (pendingScope === "youtube") {
|
||||
} else if (isReplayDelete && pendingScope === "youtube") {
|
||||
titleEl.textContent = I18N.deleteYoutubeTitle;
|
||||
} else if (pendingScope === "site") {
|
||||
} else if (isReplayDelete && pendingScope === "site") {
|
||||
titleEl.textContent = I18N.deleteSiteTitle;
|
||||
} else {
|
||||
titleEl.textContent = isDelete ? I18N.deleteTitle : I18N.title;
|
||||
@@ -187,9 +188,9 @@
|
||||
if (messageEl) {
|
||||
if (multi) {
|
||||
messageEl.textContent = I18N.multiDeleteMessage;
|
||||
} else if (pendingScope === "youtube") {
|
||||
} else if (isReplayDelete && pendingScope === "youtube") {
|
||||
messageEl.textContent = I18N.deleteYoutubeMessage;
|
||||
} else if (pendingScope === "site") {
|
||||
} else if (isReplayDelete && pendingScope === "site") {
|
||||
messageEl.textContent = hasYoutube
|
||||
? I18N.deleteSiteMessageWithYoutube
|
||||
: I18N.deleteSiteMessageOnly;
|
||||
@@ -203,8 +204,8 @@
|
||||
|
||||
if (okBtn instanceof HTMLElement) {
|
||||
okBtn.hidden = multi;
|
||||
if (pendingScope === "youtube") okBtn.textContent = I18N.deleteYoutubeOk;
|
||||
else if (pendingScope === "site") okBtn.textContent = I18N.deleteSiteOk;
|
||||
if (isReplayDelete && pendingScope === "youtube") okBtn.textContent = I18N.deleteYoutubeOk;
|
||||
else if (isReplayDelete && pendingScope === "site") okBtn.textContent = I18N.deleteSiteOk;
|
||||
else okBtn.textContent = isDelete ? I18N.deleteOk : I18N.confirmOk;
|
||||
}
|
||||
|
||||
@@ -302,12 +303,14 @@
|
||||
form.getAttribute("data-has-youtube") === "1" ||
|
||||
mode === "delete-replay-youtube";
|
||||
var hasSiteAttr = form.getAttribute("data-has-site");
|
||||
var hasSite = hasSiteAttr == null ? true : hasSiteAttr === "1";
|
||||
var hasSite = isReplayDelete
|
||||
? hasSiteAttr == null || hasSiteAttr === "1"
|
||||
: hasSiteAttr === "1";
|
||||
var isDelete =
|
||||
form.getAttribute("data-confirm-kind") === "delete" || isReplayDelete;
|
||||
|
||||
openDialog(message, {
|
||||
multi: isReplayDelete,
|
||||
isReplayDelete: isReplayDelete,
|
||||
hasYoutube: hasYoutube,
|
||||
hasSite: hasSite,
|
||||
isDelete: isDelete
|
||||
|
||||
@@ -76,4 +76,72 @@ RSpec.describe Public::BillingHelper, type: :helper do
|
||||
)
|
||||
expect(action[:kind]).to eq(:none)
|
||||
end
|
||||
|
||||
it "con prezzo concordato non pagato resta sul bonifico" do
|
||||
quote = instance_double(Billing::ClubQuote, plan_slug: "premium_full", price_label: "€99/anno", billing_interval: "yearly")
|
||||
club = instance_double(Club, active_billing_quote: quote)
|
||||
subscription = instance_double(
|
||||
Subscription,
|
||||
active?: true,
|
||||
premium?: false,
|
||||
plan_change_pending?: false,
|
||||
plan: Plan["free"]
|
||||
)
|
||||
|
||||
action = helper.plan_billing_action(
|
||||
current_slug: "free",
|
||||
target_plan: premium_full,
|
||||
stripe_subscription_active: false,
|
||||
subscription: subscription,
|
||||
club: club
|
||||
)
|
||||
expect(action[:kind]).to eq(:quoted)
|
||||
expect(action[:quote]).to eq(quote)
|
||||
end
|
||||
|
||||
it "con prezzo concordato già pagato mostra il piano attivo" do
|
||||
quote = instance_double(Billing::ClubQuote, plan_slug: "premium_full", price_label: "€99/anno")
|
||||
club = instance_double(Club, active_billing_quote: quote)
|
||||
subscription = instance_double(
|
||||
Subscription,
|
||||
active?: true,
|
||||
premium?: true,
|
||||
plan_change_pending?: false,
|
||||
plan: premium_full,
|
||||
billing_interval: "yearly"
|
||||
)
|
||||
|
||||
action = helper.plan_billing_action(
|
||||
current_slug: "premium_full",
|
||||
target_plan: premium_full,
|
||||
stripe_subscription_active: false,
|
||||
current_interval: "yearly",
|
||||
subscription: subscription,
|
||||
club: club
|
||||
)
|
||||
expect(action[:kind]).to eq(:current)
|
||||
expect(action[:label]).to include("Piano attivo")
|
||||
expect(action[:label]).to include("€99/anno")
|
||||
end
|
||||
|
||||
it "con bonifico già attivo senza Stripe mostra il piano corrente" do
|
||||
subscription = instance_double(
|
||||
Subscription,
|
||||
active?: true,
|
||||
premium?: true,
|
||||
plan_change_pending?: false,
|
||||
plan: premium_full,
|
||||
billing_interval: "yearly"
|
||||
)
|
||||
|
||||
action = helper.plan_billing_action(
|
||||
current_slug: "premium_full",
|
||||
target_plan: premium_full,
|
||||
stripe_subscription_active: false,
|
||||
current_interval: "yearly",
|
||||
subscription: subscription
|
||||
)
|
||||
expect(action[:kind]).to eq(:current)
|
||||
expect(action[:label]).to include("Piano attivo")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -57,6 +57,33 @@ RSpec.describe "Public bank transfer billing", type: :request do
|
||||
get public_club_billing_path(club)
|
||||
expect(response.body).to include("Prezzo concordato")
|
||||
expect(response.body).to include("€120")
|
||||
expect(response.body).to include("Paga con bonifico")
|
||||
expect(response.body).not_to include("Attiva Full — €199/anno")
|
||||
end
|
||||
|
||||
it "con prezzo concordato già attivato mostra Piano attivo e nasconde il pagamento" do
|
||||
Billing::SetClubQuote.upsert(
|
||||
club: club, plan_slug: "premium_full", interval: "yearly",
|
||||
amount_euros: "99", note: "Test", admin: nil
|
||||
)
|
||||
Billing::AssignPlan.call(
|
||||
club: club,
|
||||
plan_slug: "premium_full",
|
||||
status: "active",
|
||||
stripe_attrs: {
|
||||
stripe_subscription_id: nil,
|
||||
billing_interval: "yearly",
|
||||
current_period_start: Time.current,
|
||||
current_period_end: 1.year.from_now,
|
||||
cancel_at_period_end: true
|
||||
}
|
||||
)
|
||||
|
||||
get public_club_billing_path(club)
|
||||
expect(response.body).to include("Piano attivo")
|
||||
expect(response.body).to include("In questo momento vale")
|
||||
expect(response.body).to include("€99")
|
||||
expect(response.body).not_to include("Paga con bonifico")
|
||||
expect(response.body).not_to include("Il piano resta quello attuale finché Match Live TV non conferma")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe "Public club create", type: :request do
|
||||
let!(:coach) do
|
||||
User.create!(email: "create-coach@test.it", name: "Coach", password: "Password123", role: "coach")
|
||||
end
|
||||
|
||||
def login!
|
||||
post public_login_path, params: { email: coach.email, password: "Password123" }
|
||||
end
|
||||
|
||||
def create_params(plan:)
|
||||
{
|
||||
club: {
|
||||
name: "Nuova Società",
|
||||
sport: "pallavolo",
|
||||
primary_color: "#e53935",
|
||||
secondary_color: "#ffffff"
|
||||
},
|
||||
first_team: { name: "Under 15" },
|
||||
plan: plan
|
||||
}
|
||||
end
|
||||
|
||||
it "mostra solo il piano iniziale, senza cadenza" do
|
||||
login!
|
||||
get public_new_club_path
|
||||
expect(response).to have_http_status(:ok)
|
||||
expect(response.body).to include("Piano iniziale")
|
||||
expect(response.body).not_to include("Fatturazione premium")
|
||||
end
|
||||
|
||||
it "crea la società sul piano Free" do
|
||||
login!
|
||||
expect {
|
||||
post public_clubs_path, params: create_params(plan: "free")
|
||||
}.to change(Club, :count).by(1)
|
||||
|
||||
club = Club.order(:created_at).last
|
||||
expect(response).to redirect_to(public_club_path(club))
|
||||
expect(club.subscription.plan.slug).to eq("free")
|
||||
team = club.teams.last
|
||||
membership = coach.user_teams.find_by(team: team)
|
||||
expect(membership&.staff_kind).to eq("transmission")
|
||||
end
|
||||
|
||||
it "se sceglie Full senza Stripe resta Free e va in billing" do
|
||||
login!
|
||||
allow(MatchLiveTv).to receive(:stripe_enabled?).and_return(false)
|
||||
|
||||
post public_clubs_path, params: create_params(plan: "premium_full")
|
||||
club = Club.order(:created_at).last
|
||||
expect(club.subscription.plan.slug).to eq("free")
|
||||
expect(response).to redirect_to(public_club_billing_path(club))
|
||||
end
|
||||
end
|
||||
@@ -22,9 +22,13 @@ RSpec.describe "Public team transmission invite", type: :request do
|
||||
get public_team_details_path(team)
|
||||
|
||||
expect(response).to have_http_status(:ok)
|
||||
expect(response.body).to include("Account principale")
|
||||
expect(response.body).to include("designato per questa squadra")
|
||||
expect(response.body).to include(coach.email)
|
||||
expect(response.body).to include("Invita un account a trasmettere")
|
||||
expect(response.body).to include('id="invita-trasmissione"')
|
||||
expect(response.body).to include("#responsabili-trasmissione")
|
||||
expect(response.body).not_to include("Sono io — responsabile trasmissione")
|
||||
expect(response.body).not_to include("Nessun responsabile trasmissione")
|
||||
end
|
||||
|
||||
it "GET /teams/:id/invite reindirizza ai dettagli con ancora" do
|
||||
|
||||
@@ -26,7 +26,7 @@ RSpec.describe Billing::RequestBankTransfer do
|
||||
)
|
||||
end
|
||||
|
||||
it "crea un ordine a listino e invia le istruzioni" do
|
||||
it "crea l'ordine a listino e invia le istruzioni" do
|
||||
expect {
|
||||
described_class.call(club: club, user: user, plan_slug: "premium_light", interval: "yearly")
|
||||
}.to change { club.billing_transfer_orders.count }.by(1)
|
||||
@@ -41,6 +41,18 @@ RSpec.describe Billing::RequestBankTransfer do
|
||||
expect(club.reload.subscription.plan.slug).to eq("free")
|
||||
end
|
||||
|
||||
it "crea comunque l'ordine se in produzione manca SMTP" do
|
||||
allow(MatchLiveTv).to receive(:smtp_configured?).and_return(false)
|
||||
allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new("production"))
|
||||
|
||||
expect {
|
||||
described_class.call(club: club, user: user, plan_slug: "premium_light", interval: "yearly")
|
||||
}.to change { club.billing_transfer_orders.count }.by(1)
|
||||
.and change { ActionMailer::Base.deliveries.size }.by(0)
|
||||
|
||||
expect(club.billing_transfer_orders.last).to be_awaiting_payment
|
||||
end
|
||||
|
||||
it "usa l'importo concordato se presente" do
|
||||
Billing::SetClubQuote.upsert(
|
||||
club: club, plan_slug: "premium_full", interval: "yearly",
|
||||
|
||||
@@ -19,6 +19,12 @@ RSpec.describe Teams::StaffAssignment do
|
||||
expect(team.entitlements.staff_count_for("transmission")).to eq(1)
|
||||
end
|
||||
|
||||
it "designa il titolare della società sulla squadra" do
|
||||
described_class.designate_club_owner!(team: team, user: owner)
|
||||
membership = owner.user_teams.find_by!(team: team)
|
||||
expect(membership.staff_kind).to eq("transmission")
|
||||
end
|
||||
|
||||
it "rejects duplicate email for transmission" do
|
||||
UserTeam.create!(user: other, team: team, role: "member", staff_kind: "transmission")
|
||||
expect {
|
||||
|
||||
Reference in New Issue
Block a user