saucy 0.2.4.1 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +2 -0
- data/app/views/billings/show.html.erb +18 -0
- data/lib/generators/saucy/features/templates/features/manage_billing.feature +17 -0
- data/lib/generators/saucy/features/templates/step_definitions/braintree_steps.rb +13 -0
- data/lib/saucy/account.rb +2 -0
- data/lib/saucy/engine.rb +4 -0
- data/lib/saucy/fake_braintree.rb +1 -1
- data/spec/models/account_spec.rb +3 -0
- metadata +3 -4
data/README.md
CHANGED
@@ -34,6 +34,8 @@ Saucy::Configuration.mailer_sender = "billingemail@example.com"
|
|
34
34
|
|
35
35
|
In addition, there are a number of string such as application name, support url, etc. that are provided and customized with i18n translations. You can customize these in your app, and you can see what they are by looking at config/locales/en.yml in saucy.
|
36
36
|
|
37
|
+
There is a `saucy:update_subscriptions` rake task which should be run on a regular basis to send receipts and payment processing problem emails.
|
38
|
+
|
37
39
|
Development environment
|
38
40
|
-----------------------
|
39
41
|
|
@@ -2,4 +2,22 @@
|
|
2
2
|
<div class="current_credit_card">
|
3
3
|
We're currently charging the credit card ending in <%= current_account.credit_card.last_4 %>. <%= link_to "Change", edit_account_billing_path(current_account) %>
|
4
4
|
</div>
|
5
|
+
<div class="billing_history">
|
6
|
+
<h3>Your Invoices</h3>
|
7
|
+
<% if current_account.subscription.transactions.any? -%>
|
8
|
+
<table>
|
9
|
+
<tr>
|
10
|
+
<th>Date</th>
|
11
|
+
<th>Amount</th>
|
12
|
+
</tr>
|
13
|
+
<% current_account.subscription.transactions.each do |transaction| -%>
|
14
|
+
<tr>
|
15
|
+
<td><%= transaction.created_at.to_s(:short_date) %></td> <td><%= number_to_currency transaction.amount %></td>
|
16
|
+
</tr>
|
17
|
+
<% end -%>
|
18
|
+
</table>
|
19
|
+
<% else -%>
|
20
|
+
There have been no invoices yet.
|
21
|
+
<% end -%>
|
22
|
+
</div>
|
5
23
|
<% end -%>
|
@@ -12,6 +12,7 @@ Feature: Manage Billing
|
|
12
12
|
And "joe@example.com" is an admin of the "Test" account
|
13
13
|
When I go to the billing page for the "Test" account
|
14
14
|
Then I should see "card ending in 5555"
|
15
|
+
And I should see "There have been no invoices yet."
|
15
16
|
And I follow "Change" within ".current_credit_card"
|
16
17
|
|
17
18
|
Then the "Cardholder name" field should contain "Joe Smith"
|
@@ -62,3 +63,19 @@ Feature: Manage Billing
|
|
62
63
|
When I go to the accounts page
|
63
64
|
Then I should see "There was an issue processing the credit card on file for this account. Please have an administrator on the account update the credit card information."
|
64
65
|
Then I should be on the billing page for the "Test" account
|
66
|
+
|
67
|
+
Scenario: View past credit card charges
|
68
|
+
Given a paid plan exists with a name of "Paid"
|
69
|
+
And the following account exists:
|
70
|
+
| name | keyword | plan | cardholder_name | billing_email | card_number | verification_code | expiration_month | expiration_year |
|
71
|
+
| Test | test | name: Paid | Joe Smith | jsmith@example.com | 4111111111115555 | 122 | 01 | 2015 |
|
72
|
+
And the following transaction exist for the "Test" account:
|
73
|
+
| status | amount | created_at |
|
74
|
+
| Settled | 20.00 | July 1, 2010 |
|
75
|
+
| Settled | 5.00 | August 1, 2010 |
|
76
|
+
And I have signed in with "joe@example.com/test"
|
77
|
+
And "joe@example.com" is an admin of the "Test" account
|
78
|
+
When I go to the billing page for the "Test" account
|
79
|
+
Then I should see "Your Invoices"
|
80
|
+
And I should see "07/01/10 $20"
|
81
|
+
And I should see "08/01/10 $5"
|
@@ -10,3 +10,16 @@ Given /^the "([^"]*)" account is past due$/ do |account_name|
|
|
10
10
|
account = Account.find_by_name!(account_name)
|
11
11
|
account.update_attribute(:subscription_status, Braintree::Subscription::Status::PastDue)
|
12
12
|
end
|
13
|
+
|
14
|
+
Given /^the following transaction exist for the "([^"]*)" account:$/ do |account_name, table|
|
15
|
+
account = Account.find_by_name!(account_name)
|
16
|
+
subscription = FakeBraintree.subscriptions[account.subscription_token]
|
17
|
+
subscription["transactions"] = []
|
18
|
+
table.hashes.each do |transaction|
|
19
|
+
FakeBraintree.transaction = { :status => transaction["status"],
|
20
|
+
:amount => transaction["amount"],
|
21
|
+
:created_at => Time.parse(transaction["created_at"]),
|
22
|
+
:subscription_id => account.subscription_token }
|
23
|
+
subscription["transactions"] << FakeBraintree.generated_transaction
|
24
|
+
end
|
25
|
+
end
|
data/lib/saucy/account.rb
CHANGED
@@ -40,6 +40,7 @@ module Saucy
|
|
40
40
|
before_create :create_subscription, :if => :billed?
|
41
41
|
|
42
42
|
memoize :customer
|
43
|
+
memoize :subscription
|
43
44
|
end
|
44
45
|
|
45
46
|
module InstanceMethods
|
@@ -96,6 +97,7 @@ module Saucy
|
|
96
97
|
else
|
97
98
|
create_subscription
|
98
99
|
end
|
100
|
+
flush_cache :subscription
|
99
101
|
end
|
100
102
|
successful && save
|
101
103
|
end
|
data/lib/saucy/engine.rb
CHANGED
data/lib/saucy/fake_braintree.rb
CHANGED
@@ -33,7 +33,7 @@ class FakeBraintree
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def self.generated_transaction
|
36
|
-
{"status_history"=>[{"timestamp"=>Time.now, "amount"=>
|
36
|
+
{"status_history"=>[{"timestamp"=>Time.now, "amount"=>FakeBraintree.transaction[:amount], "transaction_source"=>"CP", "user"=>"copycopter", "status"=>"authorized"}, {"timestamp"=>Time.now, "amount"=>FakeBraintree.transaction[:amount], "transaction_source"=>"CP", "user"=>"copycopter", "status"=>FakeBraintree.transaction[:status]}], "created_at"=>(FakeBraintree.transaction[:created_at] || Time.now), "currency_iso_code"=>"USD", "settlement_batch_id"=>nil, "processor_authorization_code"=>"ZKB4VJ", "avs_postal_code_response_code"=>"I", "order_id"=>nil, "updated_at"=>Time.now, "refunded_transaction_id"=>nil, "amount"=>FakeBraintree.transaction[:amount], "credit_card"=>{"last_4"=>"1111", "card_type"=>"Visa", "token"=>"8yq7", "customer_location"=>"US", "expiration_year"=>"2013", "expiration_month"=>"02", "bin"=>"411111", "cardholder_name"=>"Chad Lee Pytel"}, "refund_id"=>nil, "add_ons"=>[], "shipping"=>{"region"=>nil, "company"=>nil, "country_name"=>nil, "extended_address"=>nil, "postal_code"=>nil, "id"=>nil, "street_address"=>nil, "country_code_numeric"=>nil, "last_name"=>nil, "locality"=>nil, "country_code_alpha2"=>nil, "country_code_alpha3"=>nil, "first_name"=>nil}, "id"=>"49sbx6", "merchant_account_id"=>"Thoughtbot", "type"=>"sale", "cvv_response_code"=>"I", "subscription_id"=>FakeBraintree.transaction[:subscription_id], "custom_fields"=>"\n ", "discounts"=>[], "billing"=>{"region"=>nil, "company"=>nil, "country_name"=>nil, "extended_address"=>nil, "postal_code"=>nil, "id"=>nil, "street_address"=>nil, "country_code_numeric"=>nil, "last_name"=>nil, "locality"=>nil, "country_code_alpha2"=>nil, "country_code_alpha3"=>nil, "first_name"=>nil}, "processor_response_code"=>"1000", "refund_ids"=>[], "customer"=>{"company"=>nil, "id"=>"108427", "last_name"=>nil, "fax"=>nil, "phone"=>nil, "website"=>nil, "first_name"=>nil, "email"=>"cpytel@thoughtbot.com"}, "avs_error_response_code"=>nil, "processor_response_text"=>"Approved", "avs_street_address_response_code"=>"I", "status"=>FakeBraintree.transaction[:status], "gateway_rejection_reason"=>nil}
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
data/spec/models/account_spec.rb
CHANGED
@@ -289,6 +289,9 @@ describe Account, "with a paid subscription" do
|
|
289
289
|
subscription = FakeBraintree.subscriptions[subject.subscription_token]
|
290
290
|
subscription["status"] = Braintree::Subscription::Status::Active
|
291
291
|
subscription["next_billing_date"] = 2.months.from_now
|
292
|
+
FakeBraintree.transaction = { :status => Braintree::Transaction::Status::Settled,
|
293
|
+
:subscription_id => subject.subscription_token }
|
294
|
+
subscription["transactions"] = [FakeBraintree.generated_transaction]
|
292
295
|
|
293
296
|
Timecop.travel(subject.next_billing_date + 1.day) do
|
294
297
|
Account.update_subscriptions!
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: saucy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 29
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
|
11
|
-
version: 0.2.4.1
|
9
|
+
- 5
|
10
|
+
version: 0.2.5
|
12
11
|
platform: ruby
|
13
12
|
authors:
|
14
13
|
- thoughtbot, inc.
|