module Billing class TransferOrder < ApplicationRecord self.table_name = "billing_transfer_orders" KINDS = %w[list_price commercial_quote].freeze STATUSES = %w[awaiting_payment paid cancelled].freeze PLAN_SLUGS = ClubQuote::PLAN_SLUGS INTERVALS = ClubQuote::INTERVALS belongs_to :club belongs_to :billing_club_quote, class_name: "Billing::ClubQuote", optional: true belongs_to :billing_payment, class_name: "Billing::Payment", optional: true belongs_to :requested_by_user, class_name: "User", optional: true belongs_to :confirmed_by_admin, class_name: "AdminAccount", optional: true validates :plan_slug, inclusion: { in: PLAN_SLUGS } validates :billing_interval, inclusion: { in: INTERVALS } validates :amount_cents, numericality: { greater_than: 0 } validates :kind, inclusion: { in: KINDS } validates :status, inclusion: { in: STATUSES } validates :reference_code, presence: true, uniqueness: true validates :currency, presence: true scope :awaiting_payment, -> { where(status: "awaiting_payment").order(created_at: :desc) } scope :recent, -> { order(created_at: :desc) } def awaiting_payment? status == "awaiting_payment" end def paid? status == "paid" end def quoted? kind == "commercial_quote" end def plan Plan[plan_slug] end def formatted_amount format("%.2f €", amount_cents / 100.0) end def price_label Billing::Stripe::PriceCatalog.format_interval_price(amount_cents, billing_interval) end def payment_causal "MLTV #{reference_code} #{club.name}".truncate(140, omission: "") end def cancel! return self unless awaiting_payment? transaction do update!(status: "cancelled", cancelled_at: Time.current) if billing_payment&.status == "pending" billing_payment.update!(status: "failed") end end self end end end