Class: Gold::Billing
- Inherits:
-
ApplicationRecord
- Object
- ApplicationRecord
- Gold::Billing
- Includes:
- Statesman::Adapters::ActiveRecordQueries
- Defined in:
- app/models/gold/billing.rb
Overview
Class that tracks all billing details. Intended to be associated with a shop class that the app uses
Class Method Summary collapse
- .initial_state ⇒ Object
-
.lookup_for_domain!(domain) ⇒ Object
Finds a billing instance for a particular shop, using the shop’s domain as the key to look it up.
- .transition_class ⇒ Object
Instance Method Summary collapse
-
#after_shop_update! ⇒ Object
Provides a way to let Gold know that the shop has changed.
- #calculate_price(tier) ⇒ Object
- #calculate_trial_days(tier, now = Time.current) ⇒ Object
- #last_selected_tier ⇒ Object
- #qualifies_for_tier?(tier) ⇒ Boolean
-
#shopify_plan ⇒ Object
Returns the Shopify plan for this shop.
-
#state_machine ⇒ Object
rubocop:enable Rails/ReflectionClassName.
- #tier ⇒ Object
- #tier=(tier) ⇒ Object
- #trial_days_left ⇒ Object
Class Method Details
.initial_state ⇒ Object
14 15 16 |
# File 'app/models/gold/billing.rb', line 14 def initial_state :new end |
.lookup_for_domain!(domain) ⇒ Object
Finds a billing instance for a particular shop, using the shop’s domain as the key to look it up. Because this is not stored in the Billing model, a join against the shop association is required.
21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'app/models/gold/billing.rb', line 21 def lookup_for_domain!(domain) # This is a little bit hard to follow, but `#joins` uses the name of the # association as defined below as "shop" and `#where` expects the name # of the associated table, which we can query from the class using # `#table_name`. joins(:shop) .where( Gold.shop_class.table_name => { Gold.shop_domain_attribute => domain } ) .first! end |
.transition_class ⇒ Object
10 11 12 |
# File 'app/models/gold/billing.rb', line 10 def transition_class Gold::Transition end |
Instance Method Details
#after_shop_update! ⇒ Object
Provides a way to let Gold know that the shop has changed. Your app should call this whenever a new shop update webhook is received or is manually overridden
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'app/models/gold/billing.rb', line 106 def after_shop_update! return_url = Engine.routes.url_helpers.process_charge_url Gold.logger.info("Received shop update from '#{shop.shopify_domain}'") shop.with_shopify_session do case current_state when :affiliate if shopify_plan. # If an affiliate has converted, change them to a paid plan ConvertAffiliateToPaidOp.new(self, return_url).call end when :billing # If their plan has been frozen, move to frozen state FreezeOp.new(self).call if can_transition_to?(:frozen) when :frozen CheckChargeOp.new(self).call unless shopify_plan.frozen? end end end |
#calculate_price(tier) ⇒ Object
100 101 102 |
# File 'app/models/gold/billing.rb', line 100 def calculate_price(tier) tier.monthly_price * (100 - discount_percentage) / 100 end |
#calculate_trial_days(tier, now = Time.current) ⇒ Object
81 82 83 84 85 86 87 88 89 90 |
# File 'app/models/gold/billing.rb', line 81 def calculate_trial_days(tier, now = Time.current) starts_at = trial_starts_at || now trial_ends_at = starts_at.advance(days: tier.trial_days) trial_period = trial_ends_at - now if trial_period > 0 (trial_period / 1.day).ceil else 0 end end |
#last_selected_tier ⇒ Object
66 67 68 |
# File 'app/models/gold/billing.rb', line 66 def last_selected_tier @last_selected_tier ||= find_last_selected_tier end |
#qualifies_for_tier?(tier) ⇒ Boolean
92 93 94 |
# File 'app/models/gold/billing.rb', line 92 def qualifies_for_tier?(tier) shop ? shop.qualifies_for_tier?(tier) : true end |
#shopify_plan ⇒ Object
Returns the Shopify plan for this shop.
71 72 73 74 75 76 77 78 79 |
# File 'app/models/gold/billing.rb', line 71 def shopify_plan if shopify_plan_override ShopifyPlan.new(shopify_plan_override) elsif shop ShopifyPlan.new(shop.shopify_plan_name) else ShopifyPlan.new(ShopifyAPI::Shop.current.plan_name) end end |
#state_machine ⇒ Object
rubocop:enable Rails/ReflectionClassName
43 44 45 46 47 |
# File 'app/models/gold/billing.rb', line 43 def state_machine transition_class = self.class.transition_class @state_machine ||= Machine.new(self, transition_class: transition_class, association_name: :transitions) end |
#tier ⇒ Object
57 58 59 |
# File 'app/models/gold/billing.rb', line 57 def tier @tier ||= Tier.find(tier_id) end |
#tier=(tier) ⇒ Object
61 62 63 64 |
# File 'app/models/gold/billing.rb', line 61 def tier=(tier) @tier = tier self[:tier_id] = tier.id end |
#trial_days_left ⇒ Object
96 97 98 |
# File 'app/models/gold/billing.rb', line 96 def trial_days_left calculate_trial_days(tier) end |