paid_up 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/README.md +28 -20
  4. data/VERSION +1 -1
  5. data/app/helpers/paid_up/features_helper.rb +3 -3
  6. data/app/models/paid_up/ability.rb +29 -11
  7. data/app/models/paid_up/feature.rb +70 -8
  8. data/app/models/paid_up/features_plan.rb +1 -2
  9. data/app/models/paid_up/plan.rb +9 -13
  10. data/app/models/paid_up/unlimited.rb +15 -0
  11. data/app/views/paid_up/features/_abilities_table.html.haml +13 -4
  12. data/app/views/paid_up/subscriptions/new.html.haml +20 -20
  13. data/bin/rails +8 -1
  14. data/config/locales/en.yml +4 -1
  15. data/coverage/.last_run.json +1 -1
  16. data/coverage/.resultset.json +291 -145
  17. data/db/migrate/20150407105900_create_paid_up_features_plans_table.rb +1 -1
  18. data/lib/generators/paid_up/install/install_generator.rb +6 -0
  19. data/lib/generators/paid_up/install/templates/initializer.rb +21 -1
  20. data/lib/paid_up/{integer.rb → extensions/integer.rb} +2 -4
  21. data/lib/paid_up/{stripe_extensions.rb → extensions/stripe.rb} +3 -6
  22. data/lib/paid_up/mixins/paid_for.rb +24 -0
  23. data/lib/paid_up/{mixins.rb → mixins/subscriber.rb} +28 -22
  24. data/lib/paid_up/validators/rolify_rows.rb +9 -0
  25. data/lib/paid_up/{table_validator.rb → validators/table_rows.rb} +2 -2
  26. data/lib/paid_up.rb +27 -7
  27. data/paid_up.gemspec +26 -16
  28. data/spec/dummy/app/models/ability.rb +0 -1
  29. data/spec/dummy/app/models/doodad.rb +3 -0
  30. data/spec/dummy/app/models/group.rb +1 -1
  31. data/spec/dummy/app/models/role.rb +10 -0
  32. data/spec/dummy/app/models/user.rb +2 -3
  33. data/spec/dummy/bin/rspec +3 -0
  34. data/spec/dummy/config/application.rb +0 -1
  35. data/spec/dummy/config/initializers/paid_up.rb +21 -1
  36. data/spec/dummy/config/initializers/rolify.rb +7 -0
  37. data/spec/dummy/config/routes.rb +10 -0
  38. data/spec/dummy/db/development.sqlite3 +0 -0
  39. data/spec/dummy/db/migrate/20150517175135_create_groups_table.rb +0 -1
  40. data/spec/dummy/db/migrate/20150517175136_create_doodads_table.rb +9 -0
  41. data/spec/dummy/db/migrate/{20150518000915_add_devise_to_users.rb → 20150523010827_add_devise_to_users.rb} +0 -0
  42. data/spec/dummy/db/migrate/20150523010837_rolify_create_roles.rb +19 -0
  43. data/spec/dummy/db/migrate/{20150518000917_create_paid_up_features_plans_table.paid_up.rb → 20150523010838_create_paid_up_features_plans_table.paid_up.rb} +1 -1
  44. data/spec/dummy/db/migrate/{20150518000919_create_paid_up_plans_table.paid_up.rb → 20150523010839_create_paid_up_plans_table.paid_up.rb} +0 -0
  45. data/spec/dummy/db/migrate/{20150519164355_add_stripe_id_column_to_users.paid_up.rb → 20150523010840_add_stripe_id_column_to_users.paid_up.rb} +0 -0
  46. data/spec/dummy/db/schema.rb +29 -15
  47. data/spec/dummy/db/seeds/features_plans.seeds.rb +9 -9
  48. data/spec/dummy/db/test.sqlite3 +0 -0
  49. data/spec/dummy/log/development.log +932 -108863
  50. data/spec/models/paid_up/feature_spec.rb +23 -5
  51. data/spec/models/paid_up/features_plan_spec.rb +2 -1
  52. data/spec/models/paid_up/plan_spec.rb +8 -32
  53. data/spec/models/user_spec.rb +110 -37
  54. data/spec/rails_helper.rb +1 -0
  55. data/spec/support/plans_and_features.rb +16 -62
  56. data/spec/views/paid_up/subscriptions_spec.rb +1 -1
  57. metadata +47 -15
  58. data/db/migrate/20150407110100_create_paid_up_features_table.rb +0 -11
  59. data/lib/paid_up/unlimited.rb +0 -17
  60. data/spec/dummy/db/migrate/20150518000918_create_paid_up_features_table.paid_up.rb +0 -12
  61. data/spec/dummy/db/seeds/features.seeds.rb +0 -19
  62. data/spec/dummy/test/controllers/plans_controller_controller_test.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1e99f660fe6ef9bb9d9afd0ed0335084916ceb65
4
- data.tar.gz: c1d31256b8769576aa47b8c8c9d277ecc52a6d8c
3
+ metadata.gz: da81f695f2094574cefed7cb6aaaffdd15bb9326
4
+ data.tar.gz: e3c4755cf8c29caea0bde253637001751d1d096a
5
5
  SHA512:
6
- metadata.gz: 419a3f9468e4e9e91be0b9a1fc1b7183057aa974bde6dc6f1d2a4795f02ec72d1c5668dd716a0da01beccc2330f0ada633fafd5d5f65153a3848d04ea251e683
7
- data.tar.gz: b939fe5c9760a1fc9f5bfb8a48e4c2fa68e0466e25073c746354947882355c426ac7d3cfeb274c840952b732e091b186650c6727d6d988e2504de1a42fe44852
6
+ metadata.gz: 19f7b0cf4a1db0adc4f18272c5f32087887e95631a73986d501498f16ee7b8175749cdb8f37f22ed11e414cacc605f191dfbf0025289a4ff0a8252e3c764305d
7
+ data.tar.gz: 3f64aa28876b80c9623142b8efca71e0671be455e668aae14caf1eaeb6250d268ba1b11dcc0466abb2a975f6f7df03d70e9669e8ba28a5b0ffb0817e98a189b2
data/Gemfile CHANGED
@@ -15,6 +15,7 @@ gem 'money', '~> 6.5'
15
15
 
16
16
  gem 'devise', '~> 3.4'
17
17
  gem 'cancan', '~> 1.6'
18
+ gem 'rolify', '~> 4'
18
19
  gem 'stripe', '~> 1.21'
19
20
 
20
21
  group :test, :development do
@@ -22,9 +23,11 @@ group :test, :development do
22
23
  gem 'forgery', '~> 0.6'
23
24
  gem 'bootstrap-sass', '~> 3.3'
24
25
  gem 'sass-rails', '~> 5.0'
26
+ gem 'high_voltage', '~> 2.3'
25
27
  end
26
28
 
27
29
  group :test do
30
+ gem 'capybara', '~> 2.4'
28
31
  gem 'rspec-rails', '~> 3.2'
29
32
  gem 'database_cleaner', '~> 1.4'
30
33
  gem 'rspec-collection_matchers', '~> 1.1'
data/README.md CHANGED
@@ -1,5 +1,4 @@
1
- Paid Up
2
- ===========
1
+ # Paid Up
3
2
 
4
3
  [![GitHub version](https://badge.fury.io/gh/gemvein%2Fpaid_up.svg)](http://badge.fury.io/gh/gemvein%2Fpaid_up)
5
4
  [![Build Status](https://travis-ci.org/gemvein/paid_up.svg)](https://travis-ci.org/gemvein/paid_up)
@@ -13,8 +12,8 @@ Paid Up is a start-to-finish Stripe subscription engine. You set up the plans yo
13
12
  * Subscription by Stripe
14
13
  * Assumes you will be using some variety of Bootstrap, and designed to be quite responsive out of the box, but included views can be overridden with custom views.
15
14
 
16
- Installation
17
- ----------------------------
15
+ ## Installation
16
+
18
17
  First, add paid_up to your `Gemfile`:
19
18
 
20
19
  gem 'paid_up'
@@ -29,37 +28,44 @@ Next, install PaidUp for your user model by executing these commands:
29
28
  rails g paid_up:install
30
29
  rake db:migrate
31
30
 
32
- Configuration
33
- ----------------------------
31
+ ## Configuration
32
+
34
33
 
35
34
  Edit your config file at `config/initializers/paid_up.rb` to set up some other key details.
36
35
 
37
36
  Set your environment variables with your STRIPE_PUBLISHABLE_KEY and your STRIPE_SECRET_KEY. (Check your operating system or IDE's documentation for details)
38
37
 
39
- Stripe Setup
40
- ----------------------------
38
+ ## Stripe Setup
41
39
 
42
40
  Using your own code or Stripe's convenient web interface, add the plans you intend to offer. Each will also need a record in your own database, so for each `Stripe::Plan` you create, note the `id` and use it as the `stripe_id` in the corresponding `PaidUp::Plan`. At a minimum, you will need an anonymous plan, a free plan, both with a cost amount of `0`; and also at least one paid plan.
43
41
 
44
42
  Next, add a `Stripe::Customer` to serve as the Anonymous User, and subscribe that customer to the anonymous plan. Note the customer's `id` and copy that into your stripe configuration file.
45
43
 
46
- Features Setup
47
- ----------------------------
44
+ ## Features Setup
45
+
46
+ Set up each `PaidUp::Feature` using the config file. (A config file is used rather than using records in an `ActiveRecord::Base` model because relationships cannot be created at runtime.) Associate the features with the corresponding plans using the `PaidUp::FeaturesPlan` model. For an example, check out the seeds files in [`spec/dummy/db/seeds/`](spec/dummy/db/seeds/)
48
47
 
49
- Set up each `PaidUp::Feature` using your own admin, the console, or seed data. Associate the features with the corresponding plans using the `PaidUp::FeaturesPlan` joining table model. For example, check out the seeds files in [`spec/dummy/db/seeds/`](spec/dummy/db/seeds/)
48
+ Possible `:setting_type` values are: `boolean`, `table_rows`, `rolify_rows`. The latter two require that a table corresponding to the feature's `:name` value.
50
49
 
51
- Enabling Javascript
52
- ----------------------------
50
+ #### Setting Type: Table Rows
53
51
 
54
- In order for PaidUp's AJAX functionality to work, you will need to add this to your layout file, preferably at the very end of the <body> element (for speed reasons):
52
+ In the `table_rows` case, the table and its model must exist. the table should have a `:user_id` column, and from there the appropriate `has_many` and `belongs_to` relationships will be created for you.
53
+
54
+ #### Setting Type: Rolify Rows
55
+
56
+ In the `rolify_rows` case, the table and its model must also exist. Once that is done and the corresponding `PaidUp::Feature` is created, the resource model will run the `resourcify` method, and the User method will have had the `rolify` method added to it during install, so no further setup is required.
57
+
58
+ ## Enabling Javascript
59
+
60
+ In order for PaidUp's AJAX functionality to work (which is required because Stripe uses AJAX), you will need to add this to your layout file, preferably near the end of the <body> element (for speed reasons):
55
61
 
56
62
  = render_footer_javascript
57
63
 
58
- Abilities
59
- -----------------------------
64
+ ## Abilities
60
65
 
61
- Abilities corresponding to features you have defined will be generated automatically for you if you include the PaidUp::Ability module and use the `initialize_paid_up(user)` command, like this:
66
+ Abilities corresponding to features you have defined will be generated automatically, as an `:own` ability on the specified tables, if you include the PaidUp::Ability module and use the `initialize_paid_up(user)` command, like this:
62
67
 
68
+ # /app/models/ability.rb
63
69
  class Ability
64
70
  include CanCan::Ability
65
71
  include PaidUp::Ability
@@ -74,8 +80,10 @@ Abilities corresponding to features you have defined will be generated automatic
74
80
  end
75
81
  end
76
82
 
77
- Contributing to Paid Up
78
- ----------------------------
83
+ Note that you will probably need to set up `:manage` and `:read` , according to your business rules.
84
+
85
+ ## Contributing to Paid Up
86
+
79
87
 
80
88
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
81
89
  * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
@@ -85,7 +93,7 @@ Contributing to Paid Up
85
93
  * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
86
94
  * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
87
95
 
88
- Copyright
96
+ ## Copyright
89
97
  ---------
90
98
 
91
99
  Copyright (c) 2015 Gem Vein. See LICENSE.txt for further details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.4
1
+ 0.3.0
@@ -15,15 +15,15 @@ module PaidUp
15
15
 
16
16
  def feature_display(feature, plan)
17
17
  if feature.setting_type == 'boolean'
18
- if plan.feature_setting(feature.id)
18
+ if plan.feature_setting(feature.slug)
19
19
  icon 'ok'
20
20
  else
21
21
  icon 'remove'
22
22
  end
23
- elsif plan.feature_unlimited?(feature.id)
23
+ elsif plan.feature_unlimited?(feature.slug)
24
24
  :unlimited.l
25
25
  else
26
- plan.feature_setting(feature.id)
26
+ plan.feature_setting(feature.slug)
27
27
  end
28
28
  end
29
29
 
@@ -4,23 +4,41 @@ module PaidUp
4
4
 
5
5
  def initialize_paid_up(user)
6
6
  features = PaidUp::Feature.all
7
-
8
7
  for feature in features
9
-
10
8
  case feature.setting_type
11
9
  when 'table_rows'
12
- model = feature.name.classify.constantize
13
- if user.table_rows_allowed(feature.name) > 0 || user.table_rows_allowed(feature.name) == -1
14
- can :manage, model, :user => user
15
- can :own, model
16
- unless user.table_rows_remaining(feature.name) > 0
17
- cannot :create, model
10
+ can :read, feature.feature_model
11
+ if user.table_rows_allowed(feature.slug) > 0 || user.table_rows_unlimited?(feature.slug)
12
+ can :manage, feature.feature_model, :user => user
13
+ can :own, feature.feature_model
14
+ unless user.table_rows_remaining(feature.slug) > 0
15
+ cannot :create, feature.feature_model
16
+ end
17
+ else
18
+ cannot :delete, feature.feature_model
19
+ cannot :update, feature.feature_model
20
+ cannot :own, feature.feature_model
21
+ cannot :create, feature.feature_model
22
+ end
23
+ when 'rolify_rows'
24
+ can :read, feature.feature_model
25
+ if user.rolify_rows_allowed(feature.slug) > 0 || user.rolify_rows_unlimited?(feature.slug)
26
+ can :manage, feature.feature_model do |record|
27
+ user.has_role? :owner, record
28
+ end
29
+ can :own, feature.feature_model
30
+ unless user.rolify_rows_remaining(feature.slug) > 0
31
+ cannot :create, feature.feature_model
18
32
  end
33
+ else
34
+ cannot :delete, feature.feature_model
35
+ cannot :update, feature.feature_model
36
+ cannot :own, feature.feature_model
37
+ cannot :create, feature.feature_model
19
38
  end
20
- can :read, model
21
39
  when 'boolean'
22
- if user.plan.feature_setting feature.id
23
- can :use, feature.name.to_sym
40
+ if user.plan.feature_setting feature.slug
41
+ can :use, feature.slug.to_sym
24
42
  end
25
43
  else
26
44
  raise(:unknown_feature_type.l)
@@ -1,19 +1,81 @@
1
- class PaidUp::Feature < ActiveRecord::Base
2
- has_many :features_plans, class_name: 'PaidUp::FeaturesPlan'
3
- has_many :plans, :through => :features_plans, class_name: 'PaidUp::Plan'
1
+ class PaidUp::Feature
2
+ include ActiveModel::Model
3
+ include ActiveModel::AttributeMethods
4
4
 
5
- validates_presence_of :name, :title, :setting_type
5
+ @@instance_collector = {}
6
6
 
7
- validates_with PaidUp::TableValidator, field: 'setting_type', comparison: 'table_rows', found_in: 'name'
7
+ attr_accessor :slug, :title, :setting_type, :description
8
+
9
+ validates_presence_of :slug, :title, :setting_type
10
+ validates :setting_type, inclusion: { in: %w(boolean table_rows rolify_rows) }
11
+ validates_with PaidUp::Validators::TableRows, field: 'setting_type', comparison: 'table_rows', found_in: 'slug'
12
+ validates_with PaidUp::Validators::RolifyRows, field: 'setting_type', comparison: 'rolify_rows', found_in: 'slug'
13
+
14
+ def initialize(attributes = {})
15
+ super attributes
16
+ if self.slug.present?
17
+ @@instance_collector[self.slug.to_sym] = self
18
+ end
19
+ end
20
+
21
+ def to_s
22
+ slug
23
+ end
8
24
 
9
25
  def feature_model_name
10
- if setting_type != 'table_rows'
11
- raise :no_conversion_of_type_features_to_table_rows.l type: setting_type
26
+ acceptable_setting_types = ['table_rows', 'rolify_rows']
27
+ unless acceptable_setting_types.include? setting_type
28
+ raise :no_implicit_conversion_of_type_features.l(type: setting_type)
12
29
  end
13
- name.classify
30
+ slug.classify
14
31
  end
15
32
 
16
33
  def feature_model
17
34
  feature_model_name.constantize
18
35
  end
36
+
37
+ def self.all
38
+ @@instance_collector.values
39
+ end
40
+
41
+ def self.find_by_slug(slug)
42
+ @@instance_collector[slug.to_sym]
43
+ end
44
+
45
+ def self.find_all(**conditions)
46
+ collection = []
47
+ for feature in all
48
+ qualifies = true
49
+ conditions.each do |key, value|
50
+ unless feature.send(key) == value
51
+ qualifies = false
52
+ end
53
+ end
54
+ if qualifies
55
+ collection << feature
56
+ end
57
+ end
58
+ collection
59
+ end
60
+
61
+ def self.find(**conditions)
62
+ find_all(conditions).first
63
+ end
64
+
65
+ # Define on self, since it's a class method
66
+ def self.method_missing(method_sym, *arguments, &block)
67
+ # the first argument is a Symbol, so you need to_s it if you want to pattern match
68
+ if method_sym.to_s =~ /^find_by_(.*)$/
69
+ self.find($1.to_sym => arguments.first)
70
+ elsif method_sym.to_s =~ /^find_all_by_(.*)$/
71
+ self.find_all($1.to_sym => arguments.first)
72
+ else
73
+ super
74
+ end
75
+ end
76
+
77
+ def self.respond_to_missing?(method_name, include_private = false)
78
+ method_name.to_s.start_with?('find_') || super
79
+ end
80
+
19
81
  end
@@ -1,7 +1,6 @@
1
1
  class PaidUp::FeaturesPlan < ActiveRecord::Base
2
2
  belongs_to :plan, class_name: 'PaidUp::Plan'
3
- belongs_to :feature, class_name: 'PaidUp::Feature'
4
- validates_presence_of :setting
3
+ validates_presence_of :setting, :plan, :feature
5
4
 
6
5
  after_initialize :catch_unlimited_in_setting
7
6
 
@@ -1,13 +1,14 @@
1
1
  class PaidUp::Plan < ActiveRecord::Base
2
2
  has_many :features_plans, class_name: 'PaidUp::FeaturesPlan'
3
3
  has_many :features, :through => :features_plans, class_name: 'PaidUp::Feature'
4
-
5
- validates_presence_of :description, :name
4
+ has_many :subscribers, :through => :subscriptions, :source => :subscriber, :source_type => 'User'
6
5
 
7
6
  after_initialize :load_stripe_data
8
7
 
9
8
  attr_accessor :stripe_data
10
9
 
10
+ validates_presence_of :name, :stripe_id
11
+
11
12
  default_scope { order('sort_order ASC') }
12
13
  scope :subscribable, -> { where('sort_order >= ?', 0) }
13
14
  scope :free, -> { find_by_stripe_id(PaidUp.configuration.free_plan_stripe_id) }
@@ -18,14 +19,9 @@ class PaidUp::Plan < ActiveRecord::Base
18
19
  self
19
20
  end
20
21
 
21
- def feature_setting_by_name(feature_name)
22
- feature = PaidUp::Feature.find_by_name(feature_name) || raise(:feature_not_found.l)
23
- feature_setting(feature.id)
24
- end
25
-
26
- def feature_setting(feature_id)
27
- feature = PaidUp::Feature.find(feature_id) || raise(:feature_not_found.l)
28
- raw = features_plans.where(feature_id: feature_id)
22
+ def feature_setting(feature_name)
23
+ feature = PaidUp::Feature.find_by_slug(feature_name) || raise(:feature_not_found.l)
24
+ raw = features_plans.where(feature: feature_name)
29
25
  case feature.setting_type
30
26
  when 'boolean'
31
27
  if raw.empty?
@@ -33,7 +29,7 @@ class PaidUp::Plan < ActiveRecord::Base
33
29
  else
34
30
  raw.first.setting != 0
35
31
  end
36
- when 'table_rows'
32
+ when 'table_rows', 'rolify_rows'
37
33
  if raw.empty?
38
34
  0
39
35
  else
@@ -44,8 +40,8 @@ class PaidUp::Plan < ActiveRecord::Base
44
40
  end
45
41
  end
46
42
 
47
- def feature_unlimited?(feature_id)
48
- feature_setting(feature_id) == PaidUp::Unlimited.to_i
43
+ def feature_unlimited?(feature_name)
44
+ feature_setting(feature_name) == PaidUp::Unlimited.to_i
49
45
  end
50
46
 
51
47
  def interval
@@ -0,0 +1,15 @@
1
+ module PaidUp::Unlimited
2
+ def self.initialize
3
+ 999999999
4
+ end
5
+ def self.to_i(format = :default)
6
+ if format == :db
7
+ -1
8
+ else
9
+ 999999999
10
+ end
11
+ end
12
+ def self.to_s
13
+ :unlimited.l
14
+ end
15
+ end
@@ -1,11 +1,11 @@
1
1
  %table.abilities.table.table-bordered{ html_options }
2
2
  - for feature in features
3
- %tr{ id: feature.name + '_ability'}
3
+ %tr{ id: feature.slug + '_ability'}
4
4
  %th= feature.title
5
5
  %td
6
6
  - case feature.setting_type
7
7
  - when 'boolean'
8
- - if can? :use, feature.name.to_sym
8
+ - if can? :use, feature.slug.to_sym
9
9
  = icon 'ok'
10
10
  - else
11
11
  = icon 'remove'
@@ -14,9 +14,18 @@
14
14
  = icon 'ok'
15
15
  - else
16
16
  = icon 'remove'
17
- - if current_user.table_rows_unlimited?(feature.name)
17
+ - if current_user.table_rows_unlimited?(feature.slug)
18
18
  = :unlimited.l
19
19
  - else
20
- = :x_of_y_remaining.l x: current_user.table_rows_remaining(feature.name), y: current_user.table_rows_allowed(feature.name)
20
+ = :x_of_y_remaining.l x: current_user.table_rows_remaining(feature.slug), y: current_user.table_rows_allowed(feature.slug)
21
+ - when 'rolify_rows'
22
+ - if can? :own, feature.feature_model
23
+ = icon 'ok'
24
+ - else
25
+ = icon 'remove'
26
+ - if current_user.rolify_rows_unlimited?(feature.slug)
27
+ = :unlimited.l
28
+ - else
29
+ = :x_of_y_remaining.l x: current_user.rolify_rows_remaining(feature.slug), y: current_user.rolify_rows_allowed(feature.slug)
21
30
  - else
22
31
  = :error.l
@@ -11,26 +11,26 @@
11
11
  %script{ src: 'https://js.stripe.com/v2/' }
12
12
  %input{ name: 'plan_id', value: @plan.id, type: 'hidden' }
13
13
  .payment-errors
14
- .form-group
15
- %label.control-label.col-xs-2= :card.l
16
- .col-md-10
17
- .group
18
- - if current_user.cards.count > 0
19
- - current_user.cards.each_with_index do |card, index|
20
- .radio
21
- %label
22
- - if index == 0
23
- %input{ type: :radio, name: 'card', value: card.id, checked: 'checked' }
24
- - else
25
- %input{ type: :radio, name: 'card', value: card.id }
26
- = :card_ending_with.l brand: card.brand, last4: card.last4
27
- .radio
28
- %label
29
- - if current_user.cards.count == 0
30
- %input{ type: :radio, name: 'card', value: 'stripeToken', checked: 'checked' }
31
- - else
32
- %input{ type: :radio, name: 'card', value: 'stripeToken' }
33
- = :enter_new_card.l
14
+ .form-group
15
+ %label.control-label.col-xs-2= :card.l
16
+ .col-md-10
17
+ .group
18
+ - if current_user.cards.count > 0
19
+ - current_user.cards.each_with_index do |card, index|
20
+ .radio
21
+ %label
22
+ - if index == 0
23
+ %input{ type: :radio, name: 'card', value: card.id, checked: 'checked' }
24
+ - else
25
+ %input{ type: :radio, name: 'card', value: card.id }
26
+ = :card_ending_with.l brand: card.brand, last4: card.last4
27
+ .radio
28
+ %label
29
+ - if current_user.cards.count == 0
30
+ %input{ type: :radio, name: 'card', value: 'stripeToken', checked: 'checked' }
31
+ - else
32
+ %input{ type: :radio, name: 'card', value: 'stripeToken' }
33
+ = :enter_new_card.l
34
34
  #new-card
35
35
  .form-group
36
36
  %label.control-label.col-xs-2{for: 'number'}= :card_number.l
data/bin/rails CHANGED
@@ -8,5 +8,12 @@ ENGINE_PATH = File.expand_path('../../lib/paid_up/engine', __FILE__)
8
8
  ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
9
9
  require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
10
10
 
11
- require 'rails/all'
11
+ # require 'rails/all'
12
+
13
+ require "active_record/railtie"
14
+ require "action_controller/railtie"
15
+ require "action_mailer/railtie"
16
+ require "action_view/railtie"
17
+ require "sprockets/railtie"
18
+
12
19
  require 'rails/engine/commands'
@@ -48,12 +48,13 @@ en:
48
48
  expiration: 'Expiration'
49
49
  features: 'Features'
50
50
  feature_not_found: "Feature Not Found"
51
+ feature_not_found_feature: "Feature Not Found: %{feature}"
51
52
  forgot_your_password: 'Forgot your password?'
52
53
  leave_blank_if_you_dont_want_to_change_it: "(leave blank if you don't want to change it)"
53
54
  length_characters_minimum: "(%{length} characters minimum)"
54
55
  my_subscription: 'My Subscription'
55
56
  my_subscription_information: 'My Subscription Information'
56
- no_conversion_of_type_features_to_table_rows: 'No conversion of %{type} Features to table_rows'
57
+ no_implicit_conversion_of_type_features: 'No implicit conversion of %{type} Features'
57
58
  or_sign_in: "Or, Sign In"
58
59
  or_sign_up: "Or, Sign Up"
59
60
  paid_thru: "Paid Thru"
@@ -78,8 +79,10 @@ en:
78
79
  unknown_feature_type: 'Unknown Feature Type'
79
80
  unlimited: 'Unlimited'
80
81
  update_account: 'Update Account'
82
+ value_is_not_a_valid_setting_type: "%{value} is not a valid setting_type. Must be one of: boolean, table_rows, rolify_rows"
81
83
  we_need_your_current_password_to_confirm_your_changes: '(we need your current password to confirm your changes)'
82
84
  when_using_table_rows_table_must_exist: 'When using table_rows, the table must exist.'
85
+ when_using_rolify_rows_table_must_exist: 'When using rolify_rows, the table must exist.'
83
86
  x_of_y_remaining: '%{x} of %{y} remaining'
84
87
  you_are_now_subscribed_to_the_plan: "You are now subscribed to the %{plan_name} Plan"
85
88
  you_will_be_charged: "You will be charged %{charge_amount}."
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "result": {
3
- "covered_percent": 78.66
3
+ "covered_percent": 78.17
4
4
  }
5
5
  }