saucy 0.15.2 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. data/.gitignore +2 -0
  2. data/CHANGELOG.md +3 -7
  3. data/Gemfile +1 -10
  4. data/Gemfile.lock +42 -3
  5. data/README.md +5 -0
  6. data/Rakefile +12 -3
  7. data/app/controllers/accounts_controller.rb +2 -1
  8. data/app/mailers/billing_mailer.rb +8 -0
  9. data/app/models/canceled_account.rb +12 -7
  10. data/app/views/accounts/_projects.html.erb +1 -1
  11. data/app/views/billing_mailer/cancelation_notification.text.erb +3 -0
  12. data/app/views/invitation_mailer/invitation.text.erb +1 -1
  13. data/app/views/invitations/show.html.erb +1 -1
  14. data/app/views/memberships/edit.html.erb +2 -2
  15. data/app/views/memberships/index.html.erb +1 -1
  16. data/app/views/projects/_form.html.erb +5 -5
  17. data/app/views/projects/edit.html.erb +2 -2
  18. data/app/views/projects/index.html.erb +3 -3
  19. data/app/views/projects/new.html.erb +1 -1
  20. data/app/views/shared/_project_dropdown.html.erb +3 -3
  21. data/config/routes.rb +2 -6
  22. data/cucumber.yml +1 -0
  23. data/{lib/generators/saucy/features/templates/features → features/engine}/admin_reporting.feature +0 -0
  24. data/{lib/generators/saucy/features/templates/features → features/engine}/edit_profile.feature +0 -0
  25. data/{lib/generators/saucy/features/templates/features → features/engine}/edit_project_permissions.feature +0 -0
  26. data/{lib/generators/saucy/features/templates/features → features/engine}/edit_user_permissions.feature +0 -0
  27. data/{lib/generators/saucy/features/templates/features → features/engine}/manage_account.feature +0 -0
  28. data/{lib/generators/saucy/features/templates/features → features/engine}/manage_billing.feature +1 -1
  29. data/{lib/generators/saucy/features/templates/features → features/engine}/manage_plan.feature +0 -0
  30. data/{lib/generators/saucy/features/templates/features → features/engine}/manage_projects.feature +0 -0
  31. data/{lib/generators/saucy/features/templates/features → features/engine}/manage_users.feature +0 -0
  32. data/{lib/generators/saucy/features/templates/features → features/engine}/new_account.feature +0 -0
  33. data/{lib/generators/saucy/features/templates/features → features/engine}/project_dropdown.feature +0 -0
  34. data/{lib/generators/saucy/features/templates/features → features/engine}/sign_up.feature +0 -0
  35. data/{lib/generators/saucy/features/templates/features → features/engine}/sign_up_coupon.feature +0 -0
  36. data/{lib/generators/saucy/features/templates/features → features/engine}/sign_up_paid.feature +0 -0
  37. data/{lib/generators/saucy/features/templates/features → features/engine}/trial_plans.feature +0 -0
  38. data/features/integration/run_features.feature +46 -0
  39. data/features/step_definitions/clearance_steps.rb +123 -0
  40. data/{lib/generators/saucy/features/templates/step_definitions → features/step_definitions/engine}/account_steps.rb +0 -0
  41. data/features/step_definitions/engine/braintree_steps.rb +24 -0
  42. data/{lib/generators/saucy/features/templates/step_definitions → features/step_definitions/engine}/country_steps.rb +0 -0
  43. data/{lib/generators/saucy/features/templates/step_definitions → features/step_definitions/engine}/cron_steps.rb +3 -5
  44. data/{lib/generators/saucy/features/templates/step_definitions → features/step_definitions/engine}/email_steps.rb +0 -0
  45. data/{lib/generators/saucy/features/templates/step_definitions → features/step_definitions/engine}/factory_girl_steps.rb +0 -0
  46. data/{lib/generators/saucy/features/templates/step_definitions → features/step_definitions/engine}/html_steps.rb +0 -0
  47. data/{lib/generators/saucy/features/templates/step_definitions → features/step_definitions/engine}/plan_steps.rb +0 -0
  48. data/{lib/generators/saucy/features/templates/step_definitions → features/step_definitions/engine}/project_steps.rb +0 -0
  49. data/{lib/generators/saucy/features/templates/step_definitions → features/step_definitions/engine}/session_steps.rb +0 -0
  50. data/{lib/generators/saucy/features/templates/step_definitions → features/step_definitions/engine}/user_steps.rb +0 -0
  51. data/features/step_definitions/rails_steps.rb +26 -8
  52. data/features/step_definitions/saucy_steps.rb +5 -0
  53. data/features/step_definitions/web_steps.rb +253 -0
  54. data/features/support/engine/braintree.rb +5 -0
  55. data/features/support/env.rb +18 -0
  56. data/features/support/factory_girl.rb +2 -0
  57. data/features/support/paths.rb +68 -0
  58. data/features/support/rails.rb +4 -0
  59. data/features/support/selectors.rb +11 -0
  60. data/lib/generators/saucy/features/features_generator.rb +7 -3
  61. data/lib/saucy/account.rb +55 -57
  62. data/lib/saucy/account_authorization.rb +39 -42
  63. data/lib/saucy/plan.rb +14 -16
  64. data/lib/saucy/project.rb +42 -44
  65. data/lib/saucy/projects_controller.rb +53 -55
  66. data/lib/saucy/subscription.rb +189 -191
  67. data/lib/saucy/user.rb +5 -7
  68. data/lib/saucy/version.rb +1 -1
  69. data/saucy.gemspec +21 -5
  70. data/spec/controllers/accounts_controller_spec.rb +2 -1
  71. data/spec/controllers/projects_controller_spec.rb +1 -1
  72. data/spec/dummy/Rakefile +7 -0
  73. data/spec/dummy/app/assets/javascripts/application.js +9 -0
  74. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  75. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  76. data/spec/dummy/app/controllers/homes_controller.rb +2 -0
  77. data/spec/dummy/app/controllers/projects_controller.rb +3 -0
  78. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  79. data/spec/dummy/app/mailers/.gitkeep +0 -0
  80. data/spec/dummy/app/models/.gitkeep +0 -0
  81. data/spec/dummy/app/models/account.rb +3 -0
  82. data/spec/dummy/app/models/plan.rb +3 -0
  83. data/spec/dummy/app/models/project.rb +3 -0
  84. data/spec/dummy/app/models/user.rb +4 -0
  85. data/spec/dummy/app/views/homes/show.html.erb +1 -0
  86. data/spec/dummy/app/views/layouts/application.html.erb +24 -0
  87. data/spec/dummy/config.ru +4 -0
  88. data/spec/dummy/config/application.rb +48 -0
  89. data/spec/dummy/config/boot.rb +10 -0
  90. data/spec/dummy/config/database.yml +25 -0
  91. data/spec/dummy/config/environment.rb +5 -0
  92. data/spec/dummy/config/environments/development.rb +30 -0
  93. data/spec/dummy/config/environments/production.rb +60 -0
  94. data/spec/dummy/config/environments/test.rb +42 -0
  95. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  96. data/spec/dummy/config/initializers/clearance.rb +3 -0
  97. data/spec/dummy/config/initializers/inflections.rb +10 -0
  98. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  99. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  100. data/spec/dummy/config/initializers/session_store.rb +8 -0
  101. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  102. data/spec/dummy/config/locales/en.yml +5 -0
  103. data/spec/dummy/config/routes.rb +59 -0
  104. data/spec/dummy/db/migrate/20120201000751_create_diesel_clearance_users.rb +19 -0
  105. data/spec/dummy/db/migrate/20120201001546_create_saucy_tables.rb +122 -0
  106. data/spec/dummy/db/migrate/20120201001548_create_canceled_accounts.rb +14 -0
  107. data/spec/dummy/lib/assets/.gitkeep +0 -0
  108. data/spec/dummy/log/.gitkeep +0 -0
  109. data/spec/dummy/public/404.html +26 -0
  110. data/spec/dummy/public/422.html +26 -0
  111. data/spec/dummy/public/500.html +26 -0
  112. data/spec/dummy/public/favicon.ico +0 -0
  113. data/spec/dummy/script/rails +6 -0
  114. data/spec/mailers/billing_mailer_spec.rb +12 -2
  115. data/spec/models/canceled_account_spec.rb +8 -6
  116. data/spec/models/subscription_spec.rb +47 -53
  117. data/spec/spec_helper.rb +8 -11
  118. data/spec/support/braintree.rb +2 -4
  119. data/spec/support/factories.rb +1 -0
  120. metadata +447 -125
  121. data/db/migrate/20120206155222_add_subscription_token_to_canceled_accounts.rb +0 -5
  122. data/features/run_features.feature +0 -84
  123. data/lib/generators/saucy/features/templates/step_definitions/braintree_steps.rb +0 -25
  124. data/lib/generators/saucy/features/templates/support/braintree.rb +0 -5
  125. data/lib/generators/saucy/specs/specs_generator.rb +0 -20
  126. data/lib/generators/saucy/specs/templates/support/braintree.rb +0 -5
  127. data/lib/saucy/fake_braintree.rb +0 -134
  128. data/lib/saucy/routing_extensions.rb +0 -116
  129. data/spec/dummy/db/migrate/20120206155222_add_subscription_token_to_canceled_accounts.rb +0 -5
  130. data/spec/environment.rb +0 -98
  131. data/spec/route_extensions_spec.rb +0 -51
  132. data/spec/scaffold/config/database.yml +0 -6
  133. data/spec/scaffold/config/routes.rb +0 -5
  134. data/spec/scaffold/views/layouts/application.html.erb +0 -1
@@ -13,77 +13,75 @@ module Saucy
13
13
  layout Saucy::Layouts.to_proc
14
14
  end
15
15
 
16
- module InstanceMethods
17
- def new
18
- @project = current_account.projects.build_with_default_permissions
19
- if @project.keyword.blank?
20
- @project.keyword = 'keyword'
21
- end
16
+ def new
17
+ @project = current_account.projects.build_with_default_permissions
18
+ if @project.keyword.blank?
19
+ @project.keyword = 'keyword'
22
20
  end
21
+ end
23
22
 
24
- def create
25
- @project = current_account.projects.build(params[:project])
26
- if @project.save
27
- redirect_to project_url(@project)
28
- else
29
- render :action => :new
30
- end
23
+ def create
24
+ @project = current_account.projects.build(params[:project])
25
+ if @project.save
26
+ redirect_to account_project_url(current_account, @project)
27
+ else
28
+ render :action => :new
31
29
  end
30
+ end
32
31
 
33
- def edit
34
- @project = current_project
35
- set_project_account_if_moving
36
- end
32
+ def edit
33
+ @project = current_project
34
+ set_project_account_if_moving
35
+ end
37
36
 
38
- def update
39
- @project = current_project
40
- set_project_account_if_moving
41
- if @project.update_attributes params[:project]
42
- redirect_to account_projects_url(@project.account), :notice => 'Project was updated.'
43
- else
44
- render :action => :edit
45
- end
37
+ def update
38
+ @project = current_project
39
+ set_project_account_if_moving
40
+ if @project.update_attributes params[:project]
41
+ redirect_to account_projects_url(@project.account), :notice => 'Project was updated.'
42
+ else
43
+ render :action => :edit
46
44
  end
45
+ end
47
46
 
48
- def show
49
- current_project
50
- end
47
+ def show
48
+ current_project
49
+ end
51
50
 
52
- def destroy
53
- current_project.destroy
54
- redirect_to account_projects_url(current_project.account), :notice => "Project has been deleted"
55
- end
51
+ def destroy
52
+ current_project.destroy
53
+ redirect_to account_projects_url(current_project.account), :notice => "Project has been deleted"
54
+ end
56
55
 
57
- def index
58
- @active_projects = current_account.projects.active
59
- @archived_projects = current_account.projects.archived
60
- end
56
+ def index
57
+ @active_projects = current_account.projects.active
58
+ @archived_projects = current_account.projects.archived
59
+ end
61
60
 
62
- private
61
+ private
63
62
 
64
- def set_project_account_if_moving
65
- if params[:project] && params[:project][:account_id]
66
- @project.account_id = params[:project][:account_id]
67
- end
63
+ def set_project_account_if_moving
64
+ if params[:project] && params[:project][:account_id]
65
+ @project.account_id = params[:project][:account_id]
68
66
  end
67
+ end
69
68
 
70
- def current_project
71
- @project ||= current_account.projects.find_by_keyword!(params[:id])
72
- end
69
+ def current_project
70
+ @project ||= current_account.projects.find_by_keyword!(params[:id])
71
+ end
73
72
 
74
- def current_project?
75
- params[:id].present?
76
- end
73
+ def current_project?
74
+ params[:id].present?
75
+ end
77
76
 
78
- def ensure_account_within_projects_limit
79
- ensure_account_within_limit("projects")
80
- end
77
+ def ensure_account_within_projects_limit
78
+ ensure_account_within_limit("projects")
79
+ end
81
80
 
82
- def ensure_admin_for_project_account
83
- if params[:project] && params[:project][:account_id]
84
- if !current_user.admin_of?(::Account.find(params[:project][:account_id]))
85
- redirect_to account_projects_url(current_account), :alert => t('account.permission_denied', :default => "You do not have permission to this account.")
86
- end
81
+ def ensure_admin_for_project_account
82
+ if params[:project] && params[:project][:account_id]
83
+ if !current_user.admin_of?(::Account.find(params[:project][:account_id]))
84
+ redirect_to account_projects_url(current_account), :alert => t('account.permission_denied', :default => "You do not have permission to this account.")
87
85
  end
88
86
  end
89
87
  end
@@ -42,242 +42,240 @@ module Saucy
42
42
  memoize :subscription
43
43
  end
44
44
 
45
- module InstanceMethods
46
- def customer
47
- Braintree::Customer.find(customer_token) if customer_token
48
- end
45
+ def customer
46
+ Braintree::Customer.find(customer_token) if customer_token
47
+ end
49
48
 
50
- def credit_card
51
- customer.credit_cards[0] if customer && customer.credit_cards.any?
52
- end
49
+ def credit_card
50
+ customer.credit_cards[0] if customer && customer.credit_cards.any?
51
+ end
53
52
 
54
- def billing_address
55
- credit_card.billing_address if credit_card
56
- end
53
+ def billing_address
54
+ credit_card.billing_address if credit_card
55
+ end
57
56
 
58
- def subscription
59
- Braintree::Subscription.find(subscription_token) if subscription_token
60
- end
57
+ def subscription
58
+ Braintree::Subscription.find(subscription_token) if subscription_token
59
+ end
61
60
 
62
- def save_customer_and_subscription!(attributes)
63
- successful = true
64
- self.plan = ::Plan.find(attributes[:plan_id]) if changing_plan?(attributes)
65
- if changing_customer_attributes?(attributes)
66
- successful = update_customer(attributes)
67
- end
68
- if successful && past_due?
69
- successful = retry_subscription_charge!
70
- end
71
- if successful && changing_plan?(attributes)
72
- save_subscription
73
- flush_cache :subscription
74
- end
75
- successful && save
61
+ def save_customer_and_subscription!(attributes)
62
+ successful = true
63
+ self.plan = ::Plan.find(attributes[:plan_id]) if changing_plan?(attributes)
64
+ if changing_customer_attributes?(attributes)
65
+ successful = update_customer(attributes)
76
66
  end
77
-
78
- def can_change_plan_to?(new_plan)
79
- within_limits_for?(new_plan) && !past_trial_for?(new_plan)
67
+ if successful && past_due?
68
+ successful = retry_subscription_charge!
80
69
  end
81
-
82
- def past_due?
83
- subscription_status == Braintree::Subscription::Status::PastDue
70
+ if successful && changing_plan?(attributes)
71
+ save_subscription
72
+ flush_cache :subscription
84
73
  end
74
+ successful && save
75
+ end
85
76
 
86
- def most_recent_transaction
87
- subscription.transactions.sort_by(&:created_at).last
88
- end
77
+ def can_change_plan_to?(new_plan)
78
+ within_limits_for?(new_plan) && !past_trial_for?(new_plan)
79
+ end
89
80
 
90
- private
81
+ def past_due?
82
+ subscription_status == Braintree::Subscription::Status::PastDue
83
+ end
91
84
 
92
- def within_limits_for?(new_plan)
93
- new_plan.limits.where(:value_type => :number).all? do |limit|
94
- new_plan.limit(limit.name).value >= send(:"#{limit.name}_count")
95
- end
96
- end
85
+ def most_recent_transaction
86
+ subscription.transactions.sort_by(&:created_at).last
87
+ end
97
88
 
98
- def past_trial_for?(new_plan)
99
- new_plan.trial? && past_trial?
100
- end
89
+ private
101
90
 
102
- def retry_subscription_charge!
103
- authorized_transaction = Braintree::Subscription.retry_charge(subscription.id).transaction
104
- result = Braintree::Transaction.submit_for_settlement(authorized_transaction.id)
105
- handle_errors(authorized_transaction, result.errors) if !result.success?
106
- update_subscription_cache!
107
- result.success?
91
+ def within_limits_for?(new_plan)
92
+ new_plan.limits.where(:value_type => :number).all? do |limit|
93
+ new_plan.limit(limit.name).value >= send(:"#{limit.name}_count")
108
94
  end
95
+ end
109
96
 
110
- def update_subscription_cache!
111
- zone = ActiveSupport::TimeZone[Saucy::Configuration.merchant_account_time_zone]
112
- flush_cache :subscription
113
- update_attribute(:subscription_status, subscription.status)
114
- update_attribute(:next_billing_date, zone.parse(subscription.next_billing_date))
115
- end
97
+ def past_trial_for?(new_plan)
98
+ new_plan.trial? && past_trial?
99
+ end
116
100
 
117
- def changing_plan?(attributes)
118
- attributes[:plan_id].present?
119
- end
101
+ def retry_subscription_charge!
102
+ authorized_transaction = Braintree::Subscription.retry_charge(subscription.id).transaction
103
+ result = Braintree::Transaction.submit_for_settlement(authorized_transaction.id)
104
+ handle_errors(authorized_transaction, result.errors) if !result.success?
105
+ update_subscription_cache!
106
+ result.success?
107
+ end
120
108
 
121
- def changing_customer_attributes?(attributes)
122
- CUSTOMER_ATTRIBUTES.any? { |attribute| attributes[attribute].present? }
123
- end
109
+ def update_subscription_cache!
110
+ zone = ActiveSupport::TimeZone[Saucy::Configuration.merchant_account_time_zone]
111
+ flush_cache :subscription
112
+ update_attribute(:subscription_status, subscription.status)
113
+ update_attribute(:next_billing_date, zone.parse(subscription.next_billing_date))
114
+ end
124
115
 
125
- def set_customer_attributes(attributes)
126
- CUSTOMER_ATTRIBUTES.each do |attribute|
127
- send("#{attribute}=", attributes[attribute]) if attributes[attribute].present?
128
- end
116
+ def changing_plan?(attributes)
117
+ attributes[:plan_id].present?
118
+ end
119
+
120
+ def changing_customer_attributes?(attributes)
121
+ CUSTOMER_ATTRIBUTES.any? { |attribute| attributes[attribute].present? }
122
+ end
123
+
124
+ def set_customer_attributes(attributes)
125
+ CUSTOMER_ATTRIBUTES.each do |attribute|
126
+ send("#{attribute}=", attributes[attribute]) if attributes[attribute].present?
129
127
  end
128
+ end
130
129
 
131
- def update_customer(attributes)
132
- set_customer_attributes(attributes)
133
- if valid?
134
- result = Braintree::Customer.update(customer_token, customer_attributes)
135
- handle_customer_result(result)
136
- if !result.success?
137
- Airbrake.notify(nil,
138
- :error_class => "Customer update",
139
- :error_message => "Customer update failed",
140
- :parameters => { :customer_token => customer_token, :customer_attributes => customer_attributes }
141
- )
142
- end
143
- result.success?
144
- else
130
+ def update_customer(attributes)
131
+ set_customer_attributes(attributes)
132
+ if valid?
133
+ result = Braintree::Customer.update(customer_token, customer_attributes)
134
+ handle_customer_result(result)
135
+ if !result.success?
145
136
  Airbrake.notify(nil,
146
- :error_class => "Subscription Validation",
147
- :error_message => "Customer failed validation",
148
- :parameters => customer_attributes
137
+ :error_class => "Customer update",
138
+ :error_message => "Customer update failed",
139
+ :parameters => { :customer_token => customer_token, :customer_attributes => customer_attributes }
149
140
  )
150
141
  end
142
+ result.success?
143
+ else
144
+ Airbrake.notify(nil,
145
+ :error_class => "Subscription Validation",
146
+ :error_message => "Customer failed validation",
147
+ :parameters => customer_attributes
148
+ )
151
149
  end
150
+ end
152
151
 
153
- def save_subscription
154
- if subscription
155
- Braintree::Subscription.update(subscription_token,
156
- :plan_id => plan_id,
157
- :price => plan.price.to_s)
158
- elsif plan.billed?
159
- valid? && create_subscription
160
- end
152
+ def save_subscription
153
+ if subscription
154
+ Braintree::Subscription.update(subscription_token,
155
+ :plan_id => plan_id,
156
+ :price => plan.price.to_s)
157
+ elsif plan.billed?
158
+ valid? && create_subscription
161
159
  end
160
+ end
162
161
 
163
- def customer_attributes
164
- {
165
- :email => billing_email,
166
- :credit_card => credit_card_attributes
167
- }
168
- end
162
+ def customer_attributes
163
+ {
164
+ :email => billing_email,
165
+ :credit_card => credit_card_attributes
166
+ }
167
+ end
169
168
 
170
- def credit_card_attributes
171
- if plan.billed?
172
- card_attributes = { :cardholder_name => cardholder_name,
173
- :number => card_number,
174
- :expiration_month => expiration_month,
175
- :expiration_year => expiration_year,
176
- :cvv => verification_code,
177
- :billing_address => {
178
- :street_address => street_address,
179
- :extended_address => extended_address,
180
- :locality => locality,
181
- :region => region,
182
- :postal_code => postal_code,
183
- :country_name => country_name
184
- }
169
+ def credit_card_attributes
170
+ if plan.billed?
171
+ card_attributes = { :cardholder_name => cardholder_name,
172
+ :number => card_number,
173
+ :expiration_month => expiration_month,
174
+ :expiration_year => expiration_year,
175
+ :cvv => verification_code,
176
+ :billing_address => {
177
+ :street_address => street_address,
178
+ :extended_address => extended_address,
179
+ :locality => locality,
180
+ :region => region,
181
+ :postal_code => postal_code,
182
+ :country_name => country_name
185
183
  }
186
- if credit_card
187
- card_attributes.merge!(:options => credit_card_options)
188
- end
189
- card_attributes
190
- else
191
- {}
184
+ }
185
+ if credit_card
186
+ card_attributes.merge!(:options => credit_card_options)
192
187
  end
188
+ card_attributes
189
+ else
190
+ {}
193
191
  end
192
+ end
194
193
 
195
- def credit_card_options
196
- if customer && customer.credit_cards.any?
197
- { :update_existing_token => credit_card.token }
198
- else
199
- {}
200
- end
194
+ def credit_card_options
195
+ if customer && customer.credit_cards.any?
196
+ { :update_existing_token => credit_card.token }
197
+ else
198
+ {}
201
199
  end
200
+ end
202
201
 
203
- def create_customer
204
- result = Braintree::Customer.create(customer_attributes)
205
- handle_customer_result(result)
206
- end
202
+ def create_customer
203
+ result = Braintree::Customer.create(customer_attributes)
204
+ handle_customer_result(result)
205
+ end
207
206
 
208
- def destroy_customer
209
- Braintree::Customer.delete(customer_token)
210
- end
207
+ def destroy_customer
208
+ Braintree::Customer.delete(customer_token)
209
+ end
211
210
 
212
- def handle_customer_result(result)
213
- if result.success?
214
- self.customer_token = result.customer.id
215
- flush_cache :customer
216
- else
217
- handle_errors(result.credit_card_verification, result.errors)
218
- end
219
- result.success?
211
+ def handle_customer_result(result)
212
+ if result.success?
213
+ self.customer_token = result.customer.id
214
+ flush_cache :customer
215
+ else
216
+ handle_errors(result.credit_card_verification, result.errors)
220
217
  end
218
+ result.success?
219
+ end
221
220
 
222
- def handle_errors(result, remote_errors)
223
- Airbrake.notify(nil,
224
- :error_class => "handle_errors",
225
- :error_message => "handle_errors",
226
- :parameters => { :result => result.inspect, :remote_errors => remote_errors.inspect }
227
- )
228
- if result && result.status == "processor_declined"
229
- errors[:card_number] << "was denied by the payment processor with the message: #{result.processor_response_text}"
230
- elsif result && result.status == "gateway_rejected"
231
- errors[:verification_code] << "did not match"
232
- elsif remote_errors.any?
233
- remote_errors.each do |error|
234
- if error.attribute == "number"
235
- errors[:card_number] << error.message.gsub("Credit card number ", "")
236
- elsif error.attribute == "CVV"
237
- errors[:verification_code] << error.message.gsub("CVV ", "")
238
- elsif error.attribute == "expiration_month"
239
- errors[:expiration_month] << error.message.gsub("Expiration month ", "")
240
- elsif error.attribute == "expiration_year"
241
- errors[:expiration_year] << error.message.gsub("Expiration year ", "")
242
- else
243
- errors[:card_number] << error.message
244
- end
221
+ def handle_errors(result, remote_errors)
222
+ Airbrake.notify(nil,
223
+ :error_class => "handle_errors",
224
+ :error_message => "handle_errors",
225
+ :parameters => { :result => result.inspect, :remote_errors => remote_errors.inspect }
226
+ )
227
+ if result && result.status == "processor_declined"
228
+ errors[:card_number] << "was denied by the payment processor with the message: #{result.processor_response_text}"
229
+ elsif result && result.status == "gateway_rejected"
230
+ errors[:verification_code] << "did not match"
231
+ elsif remote_errors.any?
232
+ remote_errors.each do |error|
233
+ if error.attribute == "number"
234
+ errors[:card_number] << error.message.gsub("Credit card number ", "")
235
+ elsif error.attribute == "CVV"
236
+ errors[:verification_code] << error.message.gsub("CVV ", "")
237
+ elsif error.attribute == "expiration_month"
238
+ errors[:expiration_month] << error.message.gsub("Expiration month ", "")
239
+ elsif error.attribute == "expiration_year"
240
+ errors[:expiration_year] << error.message.gsub("Expiration year ", "")
241
+ else
242
+ errors[:card_number] << error.message
245
243
  end
246
- else
247
- errors[:card_number] << "there was an unknown status"
248
244
  end
245
+ else
246
+ errors[:card_number] << "there was an unknown status"
249
247
  end
248
+ end
250
249
 
251
- def create_subscription
252
- result = Braintree::Subscription.create(subscription_attributes)
253
- if result.success?
254
- zone = ActiveSupport::TimeZone[Saucy::Configuration.merchant_account_time_zone]
255
- self.subscription_token = result.subscription.id
256
- self.next_billing_date = zone.parse(result.subscription.next_billing_date)
257
- self.subscription_status = result.subscription.status
258
- else
259
- Airbrake.notify(nil,
260
- :error_class => "Subscription creation",
261
- :error_message => "Subscription creation failed",
262
- :parameters => subscription_attributes
263
- )
264
- false
265
- end
250
+ def create_subscription
251
+ result = Braintree::Subscription.create(subscription_attributes)
252
+ if result.success?
253
+ zone = ActiveSupport::TimeZone[Saucy::Configuration.merchant_account_time_zone]
254
+ self.subscription_token = result.subscription.id
255
+ self.next_billing_date = zone.parse(result.subscription.next_billing_date)
256
+ self.subscription_status = result.subscription.status
257
+ else
258
+ Airbrake.notify(nil,
259
+ :error_class => "Subscription creation",
260
+ :error_message => "Subscription creation failed",
261
+ :parameters => subscription_attributes
262
+ )
263
+ false
266
264
  end
265
+ end
267
266
 
268
- def subscription_attributes
269
- {
270
- :payment_method_token => credit_card.token,
271
- :plan_id => plan_id,
272
- :merchant_account_id => Saucy::Configuration.merchant_account_id
273
- }.tap do |attributes|
274
- attributes.reject! { |key, value| value.nil? }
275
- end
267
+ def subscription_attributes
268
+ {
269
+ :payment_method_token => credit_card.token,
270
+ :plan_id => plan_id,
271
+ :merchant_account_id => Saucy::Configuration.merchant_account_id
272
+ }.tap do |attributes|
273
+ attributes.reject! { |key, value| value.nil? }
276
274
  end
275
+ end
277
276
 
278
- def switching_to_billed?
279
- plan_id && plan.billed? && subscription_token.blank?
280
- end
277
+ def switching_to_billed?
278
+ plan_id && plan.billed? && subscription_token.blank?
281
279
  end
282
280
 
283
281
  module ClassMethods