module Billing module Stripe class PriceCatalog INTERVALS = %w[monthly yearly].freeze DEFAULT_INTERVAL = "yearly" # Importi in centesimi (EUR). Il yearly è il prezzo lancio addebitato. AMOUNTS = { "premium_light" => { "yearly" => { charge: 5900, list: 7900, equivalent_monthly: 492 }, "monthly" => { charge: 790 } }, "premium_full" => { "yearly" => { charge: 19_900, list: 24_900, equivalent_monthly: 1658 }, "monthly" => { charge: 2490 } } }.freeze class << self def normalize_interval(value) interval = value.to_s.presence || DEFAULT_INTERVAL raise ArgumentError, "Intervallo non valido" unless INTERVALS.include?(interval) interval end def price_id(plan_slug:, interval:) interval = normalize_interval(interval) id = price_id_for(plan_slug.to_s, interval) raise "Price ID Stripe mancante per #{plan_slug} (#{interval})" if id.blank? id end def configured?(plan_slug:, interval:) price_id_for(plan_slug.to_s, normalize_interval(interval)).present? end def label(plan_slug:, interval:) interval = normalize_interval(interval) format_interval_price(charge_cents(plan_slug, interval), interval) end def list_label(plan_slug:, interval: "yearly") interval = normalize_interval(interval) cents = list_cents(plan_slug, interval) return nil if cents.blank? format_interval_price(cents, interval) end def equivalent_monthly_label(plan_slug:) cents = AMOUNTS.dig(plan_slug.to_s, "yearly", :equivalent_monthly) return nil if cents.blank? format_interval_price(cents, "monthly") end def available_intervals(plan_slug:) INTERVALS.select { |interval| configured?(plan_slug: plan_slug, interval: interval) } end def infer_from_price_id(price_id) return nil if price_id.blank? { MatchLiveTv.stripe_premium_light_monthly_price_id => %w[premium_light monthly], MatchLiveTv.stripe_premium_light_yearly_price_id => %w[premium_light yearly], MatchLiveTv.stripe_premium_full_monthly_price_id => %w[premium_full monthly], MatchLiveTv.stripe_premium_full_yearly_price_id => %w[premium_full yearly] }.each do |configured_id, pair| return pair if configured_id.present? && configured_id == price_id end nil end def format_eur(cents) cents = cents.to_i whole, frac = cents.divmod(100) if frac.zero? "€#{whole}" else sep = I18n.locale.to_s == "en" ? "." : "," "€#{whole}#{sep}#{frac.to_s.rjust(2, '0')}" end end def catalog_intervals(plan_slug:) INTERVALS.select { |interval| AMOUNTS.dig(plan_slug.to_s, interval, :charge).present? } end def amount_cents(plan_slug:, interval:) interval = normalize_interval(interval) cents = charge_cents(plan_slug, interval) raise ArgumentError, "Prezzo listino non disponibile per #{plan_slug} (#{interval})" if cents.blank? cents end def format_interval_price(cents, interval) return nil if cents.blank? I18n.t("billing.prices.#{interval}", amount: format_eur(cents)) end private def charge_cents(plan_slug, interval) AMOUNTS.dig(plan_slug.to_s, interval, :charge) end def list_cents(plan_slug, interval) AMOUNTS.dig(plan_slug.to_s, interval, :list) end def price_id_for(plan_slug, interval) case [plan_slug, interval] when %w[premium_light monthly] MatchLiveTv.stripe_premium_light_monthly_price_id when %w[premium_light yearly] MatchLiveTv.stripe_premium_light_yearly_price_id when %w[premium_full monthly] MatchLiveTv.stripe_premium_full_monthly_price_id when %w[premium_full yearly] MatchLiveTv.stripe_premium_full_yearly_price_id else nil end end end end end end