thumbjive-koudoku 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +198 -0
  4. data/Rakefile +10 -0
  5. data/app/assets/javascripts/koudoku/application.js +15 -0
  6. data/app/assets/stylesheets/koudoku/application.css +13 -0
  7. data/app/assets/stylesheets/koudoku/pricing-table.scss +78 -0
  8. data/app/concerns/koudoku/coupon.rb +7 -0
  9. data/app/concerns/koudoku/plan.rb +14 -0
  10. data/app/concerns/koudoku/subscription.rb +255 -0
  11. data/app/controllers/koudoku/application_controller.rb +7 -0
  12. data/app/controllers/koudoku/subscriptions_controller.rb +181 -0
  13. data/app/helpers/koudoku/application_helper.rb +20 -0
  14. data/app/views/koudoku/subscriptions/_card.html.erb +99 -0
  15. data/app/views/koudoku/subscriptions/_pricing_table.html.erb +40 -0
  16. data/app/views/koudoku/subscriptions/_social_proof.html.erb +11 -0
  17. data/app/views/koudoku/subscriptions/_stripe_js.html.erb +0 -0
  18. data/app/views/koudoku/subscriptions/edit.html.erb +7 -0
  19. data/app/views/koudoku/subscriptions/index.html.erb +2 -0
  20. data/app/views/koudoku/subscriptions/new.html.erb +1 -0
  21. data/app/views/koudoku/subscriptions/show.html.erb +15 -0
  22. data/app/views/koudoku/subscriptions/unauthorized.html.erb +1 -0
  23. data/app/views/layouts/koudoku/application.html.erb +14 -0
  24. data/config/environment.rb +0 -0
  25. data/config/initializers/stripe_event.rb +27 -0
  26. data/config/locales/en.yml +58 -0
  27. data/config/locales/pt-BR.yml +57 -0
  28. data/config/routes.rb +14 -0
  29. data/lib/generators/koudoku/install_generator.rb +74 -0
  30. data/lib/generators/koudoku/templates/app/models/coupon.rb +5 -0
  31. data/lib/generators/koudoku/templates/app/models/plan.rb +6 -0
  32. data/lib/generators/koudoku/templates/app/models/subscription.rb +8 -0
  33. data/lib/generators/koudoku/templates/config/initializers/koudoku.rb +18 -0
  34. data/lib/generators/koudoku/views_generator.rb +31 -0
  35. data/lib/koudoku-tj.rb +0 -0
  36. data/lib/koudoku.rb +84 -0
  37. data/lib/koudoku/engine.rb +20 -0
  38. data/lib/koudoku/errors.rb +4 -0
  39. data/lib/koudoku/version.rb +3 -0
  40. data/lib/tasks/koudoku_tasks.rake +12 -0
  41. data/spec/concerns/koudoku/plan_spec.rb +39 -0
  42. data/spec/concerns/koudoku/subscription_spec.rb +0 -0
  43. data/spec/controllers/koudoku/subscriptions_controller.rb +21 -0
  44. data/spec/dummy/README.rdoc +261 -0
  45. data/spec/dummy/Rakefile +7 -0
  46. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  47. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  48. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  49. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  50. data/spec/dummy/app/models/coupon.rb +3 -0
  51. data/spec/dummy/app/models/customer.rb +6 -0
  52. data/spec/dummy/app/models/plan.rb +8 -0
  53. data/spec/dummy/app/models/subscription.rb +7 -0
  54. data/spec/dummy/app/views/koudoku/subscriptions/_social_proof.html.erb +11 -0
  55. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  56. data/spec/dummy/config.ru +4 -0
  57. data/spec/dummy/config/application.rb +55 -0
  58. data/spec/dummy/config/boot.rb +10 -0
  59. data/spec/dummy/config/database.yml +25 -0
  60. data/spec/dummy/config/environment.rb +5 -0
  61. data/spec/dummy/config/environments/development.rb +32 -0
  62. data/spec/dummy/config/environments/production.rb +69 -0
  63. data/spec/dummy/config/environments/test.rb +36 -0
  64. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  65. data/spec/dummy/config/initializers/devise.rb +0 -0
  66. data/spec/dummy/config/initializers/inflections.rb +15 -0
  67. data/spec/dummy/config/initializers/koudoku.rb +7 -0
  68. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  69. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  70. data/spec/dummy/config/initializers/session_store.rb +8 -0
  71. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  72. data/spec/dummy/config/locales/devise.en.yml +59 -0
  73. data/spec/dummy/config/locales/en.yml +5 -0
  74. data/spec/dummy/config/routes.rb +6 -0
  75. data/spec/dummy/db/migrate/20130318201927_create_customers.rb +8 -0
  76. data/spec/dummy/db/migrate/20130318204455_create_subscriptions.rb +16 -0
  77. data/spec/dummy/db/migrate/20130318204458_create_plans.rb +14 -0
  78. data/spec/dummy/db/migrate/20130318204502_create_coupons.rb +10 -0
  79. data/spec/dummy/db/migrate/20130520163946_add_interval_to_plan.rb +5 -0
  80. data/spec/dummy/db/schema.rb +53 -0
  81. data/spec/dummy/db/test.sqlite3 +0 -0
  82. data/spec/dummy/log/test.log +80 -0
  83. data/spec/dummy/public/404.html +26 -0
  84. data/spec/dummy/public/422.html +26 -0
  85. data/spec/dummy/public/500.html +25 -0
  86. data/spec/dummy/public/favicon.ico +0 -0
  87. data/spec/dummy/script/rails +6 -0
  88. data/spec/dummy/test/fixtures/customers.yml +7 -0
  89. data/spec/dummy/test/unit/customer_test.rb +7 -0
  90. data/spec/helpers/koudoku/application_helper_spec.rb +29 -0
  91. data/spec/spec_helper.rb +30 -0
  92. metadata +332 -0
@@ -0,0 +1,58 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ koudoku:
6
+ confirmations:
7
+ feature_depends_on_devise: "This feature depends on Devise for authentication."
8
+ subscription_cancelled: "You've successfully cancelled your subscription."
9
+ subscription_updated: "You've successfully updated your subscription."
10
+ subscription_upgraded: "You've been successfully upgraded."
11
+ failure:
12
+ problem_processing_transaction: "There was a problem processing this transaction."
13
+ unauthorized: "Unauthorized"
14
+ plan_intervals:
15
+ month: "month"
16
+ year: "year"
17
+ week: "week"
18
+ 6month: "half-year"
19
+ 3month: "quarter"
20
+ plan_difference:
21
+ downgrade: "Downgrade"
22
+ selected: "Selected"
23
+ start_trial: "Start Trial"
24
+ upgrade: "Upgrade"
25
+ payment:
26
+ cancel: "Cancel"
27
+ card_number: "Card Number"
28
+ card_on_file_with_last_four: "The card on file for your account ends with %{last_four}."
29
+ cvc: "CVC"
30
+ expiration: "Expiration (MM/YYYY)"
31
+ payment_information: "Payment Information"
32
+ save_billing_info: "Save Billing Information"
33
+ upgrade_account: "Upgrade Your Account"
34
+ update_payment_information: "Update Your Payment Information"
35
+ social_proof:
36
+ testimonial1:
37
+ person: "Person at Place"
38
+ quote: "\"Some Great Quote\""
39
+ testimonial2:
40
+ person: "Person at Place"
41
+ quote: "\"This is a great service and you've been the best ever! Thanks!\""
42
+ testimonial3:
43
+ person: "Person at Place"
44
+ quote: "\"I love you guys and you're the best! You're the best!\""
45
+ subscriptions:
46
+ cancel_your_subscription: "cancel your subscription"
47
+ cancel_your_subscription_note_html: "You can also %{link}."
48
+ choose_other_plan: "Choose Another Plan"
49
+ choose_plan: "Choose A Plan"
50
+ free_trial_for_days: "%{days}-day Free Trial"
51
+ no_subscription: "No Subscription"
52
+ not_subscribed_to_plan: "You are not subscribed to a paid plan."
53
+ sign_up: "Sign up"
54
+ start_trial: "Start Your Free Trial"
55
+ subscribed: "You're Subscribed!"
56
+ subscribed_to_plan: "You're currently subscribed to the %{plan} plan."
57
+ upgrade_your_account: "Upgrade Your Account"
58
+ which_plan_is_best: "What Plan Is Best For You?"
@@ -0,0 +1,57 @@
1
+ # Translation by Lauro Becker (http://www.organicadigital.com)
2
+
3
+ pt-BR:
4
+ koudoku:
5
+ confirmations:
6
+ feature_depends_on_devise: "Esta funcionalidade necessita do Devise para autenticação."
7
+ subscription_cancelled: "Você cancelou sua subscrição com sucesso."
8
+ subscription_updated: "Você atualizou sua subscrição com sucesso."
9
+ subscription_upgraded: "Upgrade feito com sucesso."
10
+ failure:
11
+ problem_processing_transaction: "Ocorreu um problema processando a transação."
12
+ unauthorized: "Não autorizado"
13
+ plan_intervals:
14
+ month: "mês"
15
+ year: "ano"
16
+ week: "semana"
17
+ 6month: "6 meses"
18
+ 3month: "3 meses"
19
+ plan_difference:
20
+ downgrade: "Diminuir"
21
+ selected: "Selecionado"
22
+ start_trial: "Iniciar teste"
23
+ upgrade: "Upgrade"
24
+ payment:
25
+ cancel: "Cancelar"
26
+ card_number: "Número do Cartão"
27
+ card_on_file_with_last_four: "O cartão de sua conta termina com %{last_four}."
28
+ cvc: "CVC"
29
+ expiration: "Expiração (MM/YYYY)"
30
+ payment_information: "Informações de Pagamento"
31
+ save_billing_info: "Salvar Informações de Cobrança"
32
+ upgrade_account: "Upgrade de Sua Conta"
33
+ update_payment_information: "Atualizar suas Informações de Pagamento"
34
+ social_proof:
35
+ testimonial1:
36
+ person: "Person at Place"
37
+ quote: "\"Some Great Quote\""
38
+ testimonial2:
39
+ person: "Person at Place"
40
+ quote: "\"This is a great service and you've been the best ever! Thanks!\""
41
+ testimonial3:
42
+ person: "Person at Place"
43
+ quote: "\"I love you guys and you're the best! You're the best!\""
44
+ subscriptions:
45
+ cancel_your_subscription: "cancelar sua subscrição"
46
+ cancel_your_subscription_note_html: "Você também pode %{link}."
47
+ choose_other_plan: "Escolher Outro Plano"
48
+ choose_plan: "Escolha Um Plano"
49
+ free_trial_for_days: "%{days} dias de teste"
50
+ no_subscription: "Nenhuma Subscrição"
51
+ not_subscribed_to_plan: "Você não está subscrito em um plano pago."
52
+ sign_up: "Cadastrar-se"
53
+ start_trial: "Iniciar seu período de testes"
54
+ subscribed: "Você está subscrito!"
55
+ subscribed_to_plan: "Você está atualmente subscrito ao plano %{plan}."
56
+ upgrade_your_account: "Upgrade de Sua Conta"
57
+ which_plan_is_best: "Qual é o melhor plano para você?"
data/config/routes.rb ADDED
@@ -0,0 +1,14 @@
1
+ Koudoku::Engine.routes.draw do
2
+ # e.g. :users
3
+ resources :subscriptions, only: [:new]
4
+ resources Koudoku.owner_resource, as: :owner do
5
+ resources :subscriptions do
6
+ member do
7
+ post :cancel
8
+ end
9
+ end
10
+ end
11
+
12
+ mount StripeEvent::Engine => '/webhooks'
13
+
14
+ end
@@ -0,0 +1,74 @@
1
+ # this generator based on rails_admin's install generator.
2
+ # https://www.github.com/sferik/rails_admin/master/lib/generators/rails_admin/install_generator.rb
3
+
4
+ require 'rails/generators'
5
+
6
+ # http://guides.rubyonrails.org/generators.html
7
+ # http://rdoc.info/github/wycats/thor/master/Thor/Actions.html
8
+
9
+ module Koudoku
10
+ class InstallGenerator < Rails::Generators::Base
11
+
12
+ def self.source_paths
13
+ [Koudoku::Engine.root, File.expand_path("../templates", __FILE__)]
14
+ end
15
+
16
+ include Rails::Generators::Migration
17
+
18
+ argument :subscription_owner_model, :type => :string, :required => true, :desc => "Owner of the subscription"
19
+ desc "Koudoku installation generator"
20
+
21
+ # Override the attr_accessor generated by 'argument' so that
22
+ # subscription_owner_model is always returned lowercase.
23
+ def subscription_owner_model
24
+ @subscription_owner_model.downcase
25
+ end
26
+
27
+
28
+ def install
29
+
30
+ unless defined?(Koudoku)
31
+ gem("koudoku")
32
+ end
33
+
34
+ require "securerandom"
35
+ template "config/initializers/koudoku.rb"
36
+
37
+ # Generate subscription.
38
+ generate("model", "subscription stripe_id:string plan_id:integer last_four:string coupon_id:integer card_type:string current_price:float #{subscription_owner_model}_id:integer")
39
+ template "app/models/subscription.rb"
40
+
41
+ # Add the plans.
42
+ generate("model", "plan name:string stripe_id:string price:float interval:string features:text highlight:boolean display_order:integer")
43
+ template "app/models/plan.rb"
44
+
45
+ # Add coupons.
46
+ generate("model coupon code:string free_trial_length:string")
47
+ template "app/models/coupon.rb"
48
+
49
+ # Update the owner relationship.
50
+ inject_into_class "app/models/#{subscription_owner_model}.rb", subscription_owner_model.camelize.constantize,
51
+ "# Added by Koudoku.\n has_one :subscription\n\n"
52
+
53
+ # Install the pricing table.
54
+ copy_file "app/views/koudoku/subscriptions/_social_proof.html.erb"
55
+
56
+ # Add webhooks to the route.
57
+
58
+ route <<-RUBY
59
+
60
+ # Added by Koudoku.
61
+ mount Koudoku::Engine, at: 'koudoku'
62
+ scope module: 'koudoku' do
63
+ get 'pricing' => 'subscriptions#index', as: 'pricing'
64
+ end
65
+
66
+ RUBY
67
+
68
+ # Show the user the API key we generated.
69
+ say "\nTo enable support for Stripe webhooks, point it to \"/koudoku/events\"."
70
+
71
+ end
72
+
73
+ end
74
+ end
@@ -0,0 +1,5 @@
1
+ class Coupon < ActiveRecord::Base
2
+
3
+ has_many :subscriptions
4
+
5
+ end
@@ -0,0 +1,6 @@
1
+ class Plan < ActiveRecord::Base
2
+ has_many :subscriptions
3
+
4
+ include Koudoku::Plan
5
+ <%= "attr_accessible :display_order, :features, :highlight, :interval, :name, :price, :stripe_id" if Rails::VERSION::MAJOR == 3 %>
6
+ end
@@ -0,0 +1,8 @@
1
+ class Subscription < ActiveRecord::Base
2
+ include Koudoku::Subscription
3
+
4
+ <%= "attr_accessible :credit_card_token" if Rails::VERSION::MAJOR == 3 %>
5
+ belongs_to :<%= subscription_owner_model %>
6
+ belongs_to :coupon
7
+
8
+ end
@@ -0,0 +1,18 @@
1
+ Koudoku.setup do |config|
2
+ config.subscriptions_owned_by = :<%= subscription_owner_model %>
3
+ config.stripe_publishable_key = ENV['STRIPE_PUBLISHABLE_KEY']
4
+ config.stripe_secret_key = ENV['STRIPE_SECRET_KEY']
5
+
6
+ Stripe.api_version = '2015-01-11' #Making sure the API version used is compatible.
7
+ # config.prorate = false # Default is true, set to false to disable prorating subscriptions
8
+ # config.free_trial_length = 30
9
+
10
+ # Specify layout you want to use for the subscription pages, default is application
11
+ config.layout = 'application'
12
+
13
+ # you can subscribe to additional webhooks here
14
+ # we use stripe_event under the hood and you can subscribe using the
15
+ # stripe_event syntax on the config object:
16
+ # config.subscribe 'charge.failed', Koudoku::ChargeFailed
17
+
18
+ end
@@ -0,0 +1,31 @@
1
+ # this generator based on rails_admin's install generator.
2
+ # https://www.github.com/sferik/rails_admin/master/lib/generators/rails_admin/install_generator.rb
3
+
4
+ require 'rails/generators'
5
+
6
+ # http://guides.rubyonrails.org/generators.html
7
+ # http://rdoc.info/github/wycats/thor/master/Thor/Actions.html
8
+
9
+ module Koudoku
10
+ class ViewsGenerator < Rails::Generators::Base
11
+
12
+ # Not sure what this does.
13
+ source_root "#{Koudoku::Engine.root}/app/views/koudoku/subscriptions"
14
+
15
+ include Rails::Generators::Migration
16
+
17
+ desc "Koudoku installation generator"
18
+
19
+ def install
20
+
21
+ # all entries in app/views/koudoku/subscriptions without . and ..
22
+ # ==> all FILES in the directory
23
+ files_to_copy = Dir.entries("#{Koudoku::Engine.root}/app/views/koudoku/subscriptions") - %w[. ..]
24
+ files_to_copy.each do |file|
25
+ copy_file file, "app/views/koudoku/subscriptions/#{file}"
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+ end
data/lib/koudoku-tj.rb ADDED
File without changes
data/lib/koudoku.rb ADDED
@@ -0,0 +1,84 @@
1
+ require "koudoku/engine"
2
+ require "generators/koudoku/install_generator"
3
+ require "generators/koudoku/views_generator"
4
+ require 'stripe_event'
5
+
6
+ module Koudoku
7
+ mattr_accessor :subscriptions_owned_by
8
+ @@subscriptions_owned_by = nil
9
+
10
+ mattr_accessor :stripe_publishable_key
11
+ @@stripe_publishable_key = nil
12
+
13
+ mattr_accessor :stripe_secret_key
14
+ @@stripe_secret_key = nil
15
+
16
+ mattr_accessor :free_trial_length
17
+ @@free_trial_length = nil
18
+
19
+ mattr_accessor :prorate
20
+ @@prorate = true
21
+
22
+
23
+ @@layout = nil
24
+
25
+ def self.layout
26
+ @@layout || 'application'
27
+ end
28
+
29
+ def self.layout=(layout)
30
+ @@layout = layout
31
+ end
32
+
33
+ def self.webhooks_api_key=(key)
34
+ raise "Koudoku no longer uses an API key to secure webhooks, please delete the line from \"config/initializers/koudoku.rb\""
35
+ end
36
+
37
+ def self.setup
38
+ yield self
39
+
40
+ # Configure the Stripe gem.
41
+ Stripe.api_key = stripe_secret_key
42
+ end
43
+
44
+ # e.g. :users
45
+ def self.owner_resource
46
+ subscriptions_owned_by.to_s.pluralize.to_sym
47
+ end
48
+
49
+ # e.g. :user_id
50
+ def self.owner_id_sym
51
+ :"#{Koudoku.subscriptions_owned_by}_id"
52
+ end
53
+
54
+ # e.g. :user=
55
+ def self.owner_assignment_sym
56
+ :"#{Koudoku.subscriptions_owned_by}="
57
+ end
58
+
59
+ # e.g. User
60
+ def self.owner_class
61
+ Koudoku.subscriptions_owned_by.to_s.classify.constantize
62
+ end
63
+
64
+ def self.free_trial?
65
+ free_trial_length.to_i > 0
66
+ end
67
+
68
+
69
+ #
70
+ # STRIPE_EVENT section
71
+ #
72
+ def self.subscribe(name, callable = Proc.new)
73
+ StripeEvent.subscribe(name, callable)
74
+ end
75
+
76
+ def self.instrument(name, object)
77
+ StripeEvent.backend.instrument(StripeEvent.namespace.call(name), object)
78
+ end
79
+
80
+ def self.all(callable = Proc.new)
81
+ StripeEvent.all(callable)
82
+ end
83
+
84
+ end
@@ -0,0 +1,20 @@
1
+ require 'stripe'
2
+ require 'bluecloth'
3
+ module Koudoku
4
+ class Engine < ::Rails::Engine
5
+ isolate_namespace Koudoku
6
+ config.generators do |g|
7
+ g.test_framework :rspec, :fixture => false
8
+ g.fixture_replacement :factory_girl, :dir => 'spec/factories'
9
+ g.assets false
10
+ g.helper false
11
+ end
12
+
13
+ initializer 'koudoku.action_controller' do |app|
14
+ ActiveSupport.on_load :action_controller do
15
+ include Koudoku::ApplicationHelper
16
+ end
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,4 @@
1
+ module Koudoku
2
+ class Error < StandardError; end
3
+ class NilCardToken < Error; end
4
+ end
@@ -0,0 +1,3 @@
1
+ module Koudoku
2
+ VERSION = "1.5.0"
3
+ end
@@ -0,0 +1,12 @@
1
+ namespace :koudoku do
2
+ desc "Install koudoku"
3
+ task :install do
4
+ system 'rails g koudoku:install'
5
+ end
6
+
7
+ desc "Install koudoku views for application-specific modification"
8
+ task :views do
9
+ system 'rails g koudoku:views'
10
+ end
11
+ end
12
+
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe Koudoku::Plan do
4
+ describe '#is_upgrade_from?' do
5
+
6
+ class FakePlan
7
+ attr_accessor :price
8
+ include Koudoku::Plan
9
+ end
10
+
11
+ it 'returns true if the price is higher' do
12
+ plan = FakePlan.new
13
+ plan.price = 123.23
14
+ cheaper_plan = FakePlan.new
15
+ cheaper_plan.price = 61.61
16
+ expect(plan.is_upgrade_from?(cheaper_plan)).to eq(true)
17
+ end
18
+ it 'returns true if the price is the same' do
19
+ plan = FakePlan.new
20
+ plan.price = 123.23
21
+ expect(plan.is_upgrade_from?(plan)).to eq(true)
22
+ end
23
+ it 'returns false if the price is the same or higher' do
24
+ plan = FakePlan.new
25
+ plan.price = 61.61
26
+ more_expensive_plan = FakePlan.new
27
+ more_expensive_plan.price = 123.23
28
+ expect(plan.is_upgrade_from?(more_expensive_plan)).to eq(false)
29
+ end
30
+ it 'handles a nil value gracefully' do
31
+ plan = FakePlan.new
32
+ plan.price = 123.23
33
+ cheaper_plan = FakePlan.new
34
+ expect {
35
+ expect(plan.is_upgrade_from?(cheaper_plan)).to eq(true)
36
+ }.not_to raise_error
37
+ end
38
+ end
39
+ end