module Billing module Stripe # Passa a Free se il periodo pagato รจ scaduto (es. disdetta o webhook mancato in locale). class FinalizeSubscription def self.call(club:) new(club: club).call end def initialize(club:) @club = club end def call sub = @club.subscription return false unless sub&.stripe_subscription_id.present? return false if sub.free? return false if sub.admin_comped? stripe_sub = ::Stripe::Subscription.retrieve(sub.stripe_subscription_id) if stripe_sub.status.in?(%w[canceled incomplete_expired]) downgrade!(sub) return true end period_end = period_end_time(sub, stripe_sub) return false if period_end.blank? || period_end > Time.current if sub.cancel_at_period_end? || stripe_sub.cancel_at_period_end downgrade!(sub) return true end false rescue ::Stripe::InvalidRequestError => e downgrade!(sub) if e.message.include?("No such subscription") false end private def period_end_time(sub, stripe_sub) local = sub.current_period_end return local if local.present? start_at, end_at = SubscriptionPeriod.times(stripe_sub) end_at end def downgrade!(sub) Billing::AssignPlan.call( club: @club, plan_slug: "free", status: "active", stripe_attrs: { stripe_subscription_id: nil, current_period_start: nil, current_period_end: nil, cancel_at_period_end: false, billing_interval: nil } ) end end end end