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>
102 lines
2.7 KiB
Ruby
102 lines
2.7 KiB
Ruby
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
|