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