Aggiunge abbonamenti omaggio admin per sponsor e promozioni.
Gli admin possono concedere o revocare Premium Light/Full senza Stripe; il piano omaggio ha priorità sui webhook e la società vede un messaggio dedicato. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
101
backend/app/services/billing/admin_comped_subscription.rb
Normal file
101
backend/app/services/billing/admin_comped_subscription.rb
Normal file
@@ -0,0 +1,101 @@
|
||||
module Billing
|
||||
class AdminCompedSubscription
|
||||
class Error < StandardError; end
|
||||
|
||||
VALID_PLANS = %w[premium_light premium_full].freeze
|
||||
|
||||
def self.grant(club:, plan_slug:, reason:, admin:)
|
||||
new(club: club, plan_slug: plan_slug, reason: reason, admin: admin).grant
|
||||
end
|
||||
|
||||
def self.revoke(club:, admin:)
|
||||
new(club: club, admin: admin).revoke
|
||||
end
|
||||
|
||||
def initialize(club:, plan_slug: nil, reason: nil, admin: nil)
|
||||
@club = club
|
||||
@plan_slug = plan_slug.to_s.presence
|
||||
@reason = reason.to_s.strip.presence
|
||||
@admin = admin
|
||||
end
|
||||
|
||||
def grant
|
||||
raise Error, "Piano non valido" unless @plan_slug.in?(VALID_PLANS)
|
||||
|
||||
release_stripe_schedule!
|
||||
|
||||
AssignPlan.call(
|
||||
club: @club,
|
||||
plan_slug: @plan_slug,
|
||||
status: "active",
|
||||
stripe_attrs: comped_attrs.merge(
|
||||
pending_plan_id: nil,
|
||||
pending_billing_interval: nil,
|
||||
stripe_schedule_id: nil,
|
||||
cancel_at_period_end: false
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
def revoke
|
||||
sub = @club.subscription
|
||||
raise Error, "Nessun abbonamento omaggio attivo" unless sub&.admin_comped?
|
||||
|
||||
if sub.stripe_subscription_id.present? && MatchLiveTv.stripe_enabled?
|
||||
stripe_sub = ::Stripe::Subscription.retrieve(sub.stripe_subscription_id)
|
||||
if stripe_sub.status.in?(%w[active trialing past_due])
|
||||
Billing::Stripe::CheckoutSync.from_subscription(stripe_sub, club: @club)
|
||||
clear_comped_flags!(sub.reload)
|
||||
return sub
|
||||
end
|
||||
end
|
||||
|
||||
AssignPlan.call(
|
||||
club: @club,
|
||||
plan_slug: "free",
|
||||
status: "active",
|
||||
stripe_attrs: {
|
||||
admin_comped: false,
|
||||
admin_comped_reason: nil,
|
||||
admin_comped_at: nil,
|
||||
admin_comped_by_id: nil,
|
||||
pending_plan_id: nil,
|
||||
pending_billing_interval: nil,
|
||||
stripe_schedule_id: nil
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def comped_attrs
|
||||
{
|
||||
admin_comped: true,
|
||||
admin_comped_reason: @reason,
|
||||
admin_comped_at: Time.current,
|
||||
admin_comped_by_id: @admin&.id
|
||||
}
|
||||
end
|
||||
|
||||
def clear_comped_flags!(sub)
|
||||
sub.update!(
|
||||
admin_comped: false,
|
||||
admin_comped_reason: nil,
|
||||
admin_comped_at: nil,
|
||||
admin_comped_by_id: nil
|
||||
)
|
||||
end
|
||||
|
||||
def release_stripe_schedule!
|
||||
sub = @club.subscription
|
||||
return if sub.blank? || sub.stripe_schedule_id.blank?
|
||||
return unless MatchLiveTv.stripe_enabled?
|
||||
|
||||
::Stripe::SubscriptionSchedule.release(sub.stripe_schedule_id)
|
||||
rescue ::Stripe::InvalidRequestError
|
||||
nil
|
||||
ensure
|
||||
sub&.update!(stripe_schedule_id: nil, pending_plan_id: nil, pending_billing_interval: nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user