disco_app 0.8.7 → 0.8.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/disco_app/admin/concerns/plans_controller.rb +51 -0
  3. data/app/controllers/disco_app/admin/plans_controller.rb +3 -0
  4. data/app/controllers/disco_app/charges_controller.rb +37 -20
  5. data/app/controllers/disco_app/concerns/app_proxy_controller.rb +1 -1
  6. data/app/controllers/disco_app/concerns/authenticated_controller.rb +26 -12
  7. data/app/controllers/disco_app/concerns/carrier_request_controller.rb +1 -1
  8. data/app/controllers/disco_app/install_controller.rb +20 -19
  9. data/app/controllers/disco_app/subscriptions_controller.rb +40 -0
  10. data/app/controllers/disco_app/webhooks_controller.rb +1 -1
  11. data/app/controllers/sessions_controller.rb +22 -0
  12. data/app/jobs/disco_app/concerns/app_installed_job.rb +21 -4
  13. data/app/jobs/disco_app/concerns/app_uninstalled_job.rb +2 -5
  14. data/app/jobs/disco_app/concerns/subscription_changed_job.rb +7 -0
  15. data/app/jobs/disco_app/subscription_changed_job.rb +3 -0
  16. data/app/models/disco_app/application_charge.rb +18 -0
  17. data/app/models/disco_app/concerns/plan.rb +13 -1
  18. data/app/models/disco_app/concerns/plan_code.rb +15 -0
  19. data/app/models/disco_app/concerns/shop.rb +10 -9
  20. data/app/models/disco_app/concerns/subscription.rb +36 -2
  21. data/app/models/disco_app/plan_code.rb +3 -0
  22. data/app/models/disco_app/recurring_application_charge.rb +18 -0
  23. data/app/services/disco_app/charges_service.rb +66 -58
  24. data/app/services/disco_app/subscription_service.rb +27 -15
  25. data/app/views/disco_app/admin/plans/_form.html.erb +27 -0
  26. data/app/views/disco_app/admin/plans/edit.html.erb +7 -0
  27. data/app/views/disco_app/admin/plans/index.html.erb +32 -0
  28. data/app/views/disco_app/admin/plans/new.html.erb +7 -0
  29. data/app/views/disco_app/charges/new.html.erb +9 -42
  30. data/app/views/disco_app/subscriptions/new.html.erb +25 -0
  31. data/app/views/layouts/admin/_navbar.html.erb +1 -0
  32. data/config/routes.rb +8 -5
  33. data/db/migrate/20160301223215_update_plans.rb +22 -0
  34. data/db/migrate/20160301224558_update_subscriptions.rb +13 -0
  35. data/db/migrate/20160302104816_create_disco_app_recurring_application_charges.rb +14 -0
  36. data/db/migrate/20160302105259_create_disco_app_application_charges.rb +14 -0
  37. data/db/migrate/20160302134728_drop_charge_status_from_shops.rb +5 -0
  38. data/db/migrate/20160302142941_add_shopify_attributes_to_charges.rb +8 -0
  39. data/db/migrate/20160331093148_create_disco_app_plan_codes.rb +14 -0
  40. data/db/migrate/20160401044420_add_status_to_plan_codes.rb +5 -0
  41. data/db/migrate/20160401045551_add_amount_and_plan_code_to_disco_app_subscriptions.rb +7 -0
  42. data/lib/disco_app/configuration.rb +6 -0
  43. data/lib/disco_app/version.rb +1 -1
  44. data/lib/generators/disco_app/reactify/reactify_generator.rb +1 -1
  45. data/lib/generators/disco_app/templates/initializers/disco_app.rb +9 -4
  46. data/test/controllers/disco_app/charges_controller_test.rb +91 -0
  47. data/test/controllers/disco_app/subscriptions_controller_test.rb +73 -0
  48. data/test/controllers/home_controller_test.rb +37 -6
  49. data/test/dummy/app/jobs/disco_app/app_installed_job.rb +16 -0
  50. data/test/dummy/config/initializers/disco_app.rb +9 -4
  51. data/test/dummy/db/schema.rb +54 -14
  52. data/test/fixtures/api/widget_store/charges/activate_application_charge_request.json +16 -0
  53. data/test/fixtures/api/widget_store/charges/activate_application_charge_response.json +1 -0
  54. data/test/fixtures/api/widget_store/charges/activate_recurring_application_charge_request.json +20 -0
  55. data/test/fixtures/api/widget_store/charges/activate_recurring_application_charge_response.json +1 -0
  56. data/test/fixtures/api/widget_store/charges/create_application_charge_request.json +9 -0
  57. data/test/fixtures/api/widget_store/charges/create_application_charge_response.json +16 -0
  58. data/test/fixtures/api/widget_store/charges/create_recurring_application_charge_request.json +9 -0
  59. data/test/fixtures/api/widget_store/charges/create_recurring_application_charge_response.json +20 -0
  60. data/test/fixtures/api/widget_store/charges/create_second_recurring_application_charge_request.json +9 -0
  61. data/test/fixtures/api/widget_store/charges/create_second_recurring_application_charge_response.json +20 -0
  62. data/test/fixtures/api/widget_store/charges/get_accepted_application_charge_response.json +16 -0
  63. data/test/fixtures/api/widget_store/charges/get_accepted_recurring_application_charge_response.json +20 -0
  64. data/test/fixtures/api/widget_store/charges/get_declined_application_charge_response.json +16 -0
  65. data/test/fixtures/api/widget_store/charges/get_declined_recurring_application_charge_response.json +20 -0
  66. data/test/fixtures/api/widget_store/charges/get_pending_application_charge_response.json +16 -0
  67. data/test/fixtures/api/widget_store/charges/get_pending_recurring_application_charge_response.json +20 -0
  68. data/test/fixtures/disco_app/application_charges.yml +11 -0
  69. data/test/fixtures/disco_app/plan_codes.yml +6 -0
  70. data/test/fixtures/disco_app/plans.yml +23 -18
  71. data/test/fixtures/disco_app/recurring_application_charges.yml +11 -0
  72. data/test/fixtures/disco_app/subscriptions.yml +12 -17
  73. data/test/jobs/disco_app/app_installed_job_test.rb +17 -5
  74. data/test/jobs/disco_app/app_uninstalled_job_test.rb +0 -2
  75. data/test/models/disco_app/shop_test.rb +3 -2
  76. data/test/services/disco_app/charges_service_test.rb +104 -0
  77. data/test/services/disco_app/subscription_service_test.rb +39 -8
  78. data/test/support/test_file_fixtures.rb +1 -1
  79. data/test/support/test_shopify_api.rb +16 -0
  80. data/test/test_helper.rb +1 -0
  81. metadata +73 -3
  82. data/test/models/disco_app/subscription_test.rb +0 -6
@@ -1,73 +1,81 @@
1
- module DiscoApp
2
- class ChargesService
1
+ class DiscoApp::ChargesService
3
2
 
4
- # Create a new charge for the given Shop using the Shopify API.
5
- #
6
- # The attributes of the charge are fetched using the shop's `new_charge_attributes` method, which can be overriden
7
- # to provide custom charge types for individual shops.
8
- #
9
- # Returns the new Shopify charge model on success, nil otherwise.
10
- def self.create(shop)
11
- shopify_charge = shop.temp {
12
- self.charge_api_class(shop).create(self.new_charge_attributes(shop))
13
- }
3
+ # Create the appropriate type of Shopify charge for the given subscription
4
+ # (either one-time or recurring) and return.
5
+ def self.create(shop, subscription)
6
+ # Create the charge object locally first.
7
+ charge = subscription.charge_class.create!(
8
+ shop: shop,
9
+ subscription: subscription,
10
+ )
14
11
 
15
- # If the charge was successfully created, update the charge status on the shop.
16
- shop.update_charge_status(shopify_charge) if shopify_charge
12
+ # Create the charge object on Shopify.
13
+ shopify_charge = shop.temp {
14
+ subscription.shopify_charge_class.create(
15
+ name: subscription.plan.name,
16
+ price: '%.2f' % (subscription.amount.to_f / 100.0),
17
+ trial_days: subscription.plan.has_trial? ? subscription.plan.trial_period_days : nil,
18
+ return_url: charge.activate_url,
19
+ test: !DiscoApp.configuration.real_charges?
20
+ )
21
+ }
17
22
 
18
- # Return the charge.
19
- shopify_charge
23
+ # If we couldn't create the charge on Shopify, return nil.
24
+ if shopify_charge.nil?
25
+ return nil
20
26
  end
21
27
 
22
- # Fetch the specified charge for the given Shop using the Shopify API and check that it has been actioned (either
23
- # accepted or declined). Updates the shop object's charge status, then returns the charge if it was accepted or
24
- # nil otherwise.
25
- def self.get_accepted_charge(shop, charge_id)
26
- begin
27
- shopify_charge = shop.temp {
28
- self.charge_api_class(shop).find(charge_id)
29
- }
28
+ # Update the local record of the charge from Shopify's created charge, then
29
+ # return it.
30
+ charge.update(
31
+ shopify_id: shopify_charge.id,
32
+ confirmation_url: shopify_charge.confirmation_url
33
+ )
34
+ charge
35
+ end
30
36
 
31
- # If the charge was successfully fetched, update the status for the shop accordingly.
32
- shop.update_charge_status(shopify_charge) if shopify_charge
37
+ # Attempt to activate the given Shopify charge for the given Shop using the
38
+ # Shopify API. Returns true on successful activation, false otherwise.
39
+ def self.activate(shop, charge)
40
+ begin
41
+ # Start by fetching the Shopify charge to check that it was accepted.
42
+ shopify_charge = shop.temp {
43
+ charge.subscription.shopify_charge_class.find(charge.shopify_id)
44
+ }
33
45
 
34
- shopify_charge
35
- rescue
36
- nil
37
- end
38
- end
46
+ # Update the status of the local charge based on the Shopify charge.
47
+ charge.send("#{shopify_charge.status}!") if charge.respond_to? "#{shopify_charge.status}!"
39
48
 
40
- # Attempt to activate the given Shopify charge for the given Shop using the Shopify API.
41
- # Returns true on successful activation, false otherwise.
42
- def self.activate(shop, shopify_charge)
43
- begin
44
- shop.temp {
45
- shopify_charge.activate
46
- }
47
- shop.charge_active!
48
- true
49
- rescue
50
- false
51
- end
52
- end
49
+ # If the charge wasn't accepted, fail and return.
50
+ return false unless charge.accepted?
53
51
 
54
- # Merge the new_charge_attributes returned by the given shop model and merge them with some application-level
55
- # charge attributes.
56
- def self.new_charge_attributes(shop)
57
- shop.new_charge_attributes.merge(
58
- return_url: DiscoApp::Engine.routes.url_helpers.activate_charge_url,
59
- test: !Rails.configuration.x.shopify_charges_real,
60
- )
61
- end
52
+ # If the charge was indeed accepted, activate it via Shopify.
53
+ charge.shop.temp {
54
+ shopify_charge.activate
55
+ }
62
56
 
63
- # Get the appropriate Shopify API class for the given shop (either ApplicationCharge or RecurringApplicationCharge).
64
- def self.charge_api_class(shop)
65
- if shop.new_charge_attributes[:type] == :one_time
66
- ShopifyAPI::ApplicationCharge
67
- else
68
- ShopifyAPI::RecurringApplicationCharge
57
+ # If the charge was recurring, make sure that all other local recurring
58
+ # charges are marked inactive.
59
+ if charge.recurring?
60
+ self.cancel_recurring_charges(shop, charge)
69
61
  end
62
+
63
+ charge.active!
64
+
65
+ true
66
+ rescue
67
+ false
70
68
  end
69
+ end
71
70
 
71
+ # Cancel all recurring charges for the given shop. If the optional charge
72
+ # parameter is given, it will be excluded from the cancellation.
73
+ def self.cancel_recurring_charges(shop, charge = nil)
74
+ charges = DiscoApp::RecurringApplicationCharge.where(shop: shop)
75
+ if charge.present?
76
+ charges = charges.where.not(id: charge)
77
+ end
78
+ charges.update_all(status: DiscoApp::RecurringApplicationCharge.statuses[:cancelled])
72
79
  end
80
+
73
81
  end
@@ -1,25 +1,37 @@
1
1
  class DiscoApp::SubscriptionService
2
2
 
3
- # Subscribe the given shop to the given plan.
4
- def self.subscribe(shop, plan)
5
- # Mark all existing active subscriptions as replaced.
6
- shop.subscriptions.active.update_all(status: DiscoApp::Subscription.statuses[:replaced])
3
+ # Subscribe the given shop to the given plan, optionally using the given plan
4
+ # code.
5
+ def self.subscribe(shop, plan, plan_code = nil)
6
+ # Cancel any existing current subscriptions.
7
+ shop.subscriptions.current.update_all(
8
+ status: DiscoApp::Subscription.statuses[:cancelled],
9
+ cancelled_at: Time.now
10
+ )
11
+
12
+ # Get the amount that should be charged for the subscription.
13
+ subscription_amount = plan_code.present? ? plan_code.amount : plan.amount
14
+
15
+ # Get the date the subscription trial should end.
16
+ subscription_trial_end_at = plan.has_trial? ? (plan_code.present? ? plan_code.trial_period_days: plan.trial_period_days).days.from_now : nil
7
17
 
8
- # Add the new subscription.
9
- DiscoApp::Subscription.create!(
18
+ # Create the new subscription.
19
+ new_subscription = DiscoApp::Subscription.create!(
10
20
  shop: shop,
11
21
  plan: plan,
12
- status: DiscoApp::Subscription.statuses[:active],
13
- name: plan.name,
14
- charge_type: plan.charge_type,
15
- price: plan.default_price,
16
- trial_days: plan.default_trial_days
22
+ plan_code: plan_code,
23
+ status: DiscoApp::Subscription.statuses[plan.has_trial? ? :trial : :active],
24
+ subscription_type: plan.plan_type,
25
+ amount: subscription_amount,
26
+ trial_start_at: plan.has_trial? ? Time.now : nil,
27
+ trial_end_at: plan.has_trial? ? subscription_trial_end_at : nil
17
28
  )
18
- end
19
29
 
20
- # Cancel any active subscription for the given shop.
21
- def self.cancel(shop)
22
- shop.subscriptions.active.update_all(status: DiscoApp::Subscription.statuses[:cancelled])
30
+ # Enqueue the subscription changed background job.
31
+ DiscoApp::SubscriptionChangedJob.perform_later(shop.shopify_domain, new_subscription)
32
+
33
+ # Return the new subscription.
34
+ new_subscription
23
35
  end
24
36
 
25
37
  end
@@ -0,0 +1,27 @@
1
+ <%= f.label(:name, 'Name') %>
2
+ <%= f.text_field(:name) %>
3
+
4
+ <%= f.label(:status, 'Status') %>
5
+ <%= f.select(:status, DiscoApp::Plan.statuses.map { |s| [s.first.humanize, s.first] }) %>
6
+
7
+ <%= f.label(:plan_type, 'Plan Type') %>
8
+ <%= f.select(:plan_type, DiscoApp::Plan.plan_types.map { |s| [s.first.humanize, s.first] }) %>
9
+
10
+ <%= f.label(:trial_period_days, 'Trial Period Days') %>
11
+ <%= f.number_field(:trial_period_days) %>
12
+
13
+ <%= f.label(:amount, 'Amount') %>
14
+ <%= f.number_field(:amount) %>
15
+
16
+ <%= f.fields_for :plan_codes do |plan_code| %>
17
+ <%= plan_code.label(:code, 'Code') %>
18
+ <%= plan_code.text_field(:code) %>
19
+
20
+ <%= plan_code.label(:trial_period_days, 'Trial Period Days') %>
21
+ <%= plan_code.number_field(:trial_period_days) %>
22
+
23
+ <%= plan_code.label(:amount, 'Amount') %>
24
+ <%= plan_code.number_field(:amount) %>
25
+ <% end %>
26
+
27
+ <%= f.submit %>
@@ -0,0 +1,7 @@
1
+ <% provide(:title, 'Edit Plan') %>
2
+
3
+ <%= form_for(@plan, url: admin_plan_path(@plan)) do |f| %>
4
+ <%= render 'form', f: f %>
5
+ <% end %>
6
+
7
+ <%= link_to 'Back', admin_plans_path %>
@@ -0,0 +1,32 @@
1
+ <% provide(:title, 'Plans') %>
2
+
3
+ <table class="table">
4
+ <thead>
5
+ <tr>
6
+ <th>Name</th>
7
+ <th>Status</th>
8
+ <th>Plan Type</th>
9
+ <th>Trial Period</th>
10
+ <th>Amount</th>
11
+ <th>Currency</th>
12
+ <th>Interval</th>
13
+ <th>Interval Count</th>
14
+ </tr>
15
+ </thead>
16
+ <tbody>
17
+ <% @plans.each do |plan| %>
18
+ <tr>
19
+ <td><%= link_to(plan.name, edit_admin_plan_path(plan)) %></td>
20
+ <td><%= plan.status %></td>
21
+ <td><%= plan.plan_type %></td>
22
+ <td><%= plan.trial_period_days %></td>
23
+ <td><%= plan.amount %></td>
24
+ <td><%= plan.currency %></td>
25
+ <td><%= plan.interval %></td>
26
+ <td><%= plan.interval_count %></td>
27
+ </tr>
28
+ <% end %>
29
+ </tbody>
30
+ </table>
31
+
32
+ <%= link_to 'Create new plan', new_admin_plan_path %>
@@ -0,0 +1,7 @@
1
+ <% provide(:title, 'New Plan') %>
2
+
3
+ <%= form_for(@plan, url: admin_plans_path) do |f| %>
4
+ <%= render 'form', f: f %>
5
+ <% end %>
6
+
7
+ <%= link_to 'Back', admin_plans_path %>
@@ -1,45 +1,12 @@
1
1
  <% provide(:title, 'Thankyou') %>
2
2
 
3
- <div class="row">
4
- <% if @shop.charge_declined? %>
5
- <div class="alert alert-warning">
6
- <p>
7
- Oops! Looks like you declined the charge.
8
- Unfortunately, you'll have to accept the charge on the next screen in order to continue installing the application.
9
- </p>
10
- </div>
11
- <% elsif @shop.charge_cancelled? %>
12
- <div class="alert alert-warning">
13
- <p>
14
- Your authorized charge for this application has expired.
15
- This could have occurred if:
16
- </p>
17
- <ul>
18
- <li>You uninstalled and reinstalled the application; or</li>
19
- <li>Your plan level has changed.</li>
20
- </ul>
21
- <p>
22
- In either case, it's no problem!
23
- Simply click okay and you'll be asked to authorize a new charge.
24
- Don't worry - you *wont'* be billed twice.
25
- </p>
26
- </div>
27
- <% else %>
28
- <div class="alert alert-success">
29
- <p>
30
- Thanks for installing <%= DiscoApp.configuration.app_name %>!
31
- </p>
32
- <p>
33
- Before we start setting things up, we need you to authorize a charge for the application.
34
- </p>
35
- </div>
36
- <% end %>
37
- </div>
3
+ <p>
4
+ Thanks for installing <%= DiscoApp.configuration.app_name %>!
5
+ </p>
6
+ <p>
7
+ Before we start setting things up, we need you to authorize a charge for the application.
8
+ </p>
38
9
 
39
- <div class="row">
40
- <%= form_tag disco_app.create_charge_path, method: 'POST', target: '_parent' do %>
41
- <div class="form-group">
42
- <%= submit_tag 'Okay', class: 'form-input' %>
43
- </div>
44
- <% end %>
45
- </div>
10
+ <%= form_tag disco_app.subscription_charges_path(@subscription), method: 'POST', target: '_parent' do %>
11
+ <%= submit_tag 'Okay', class: 'form-input' %>
12
+ <% end %>
@@ -0,0 +1,25 @@
1
+ <% if @shop.current_subscription? %>
2
+ <p>
3
+ You are currently on the <%= @shop.current_subscription.plan.name %> plan.
4
+ </p>
5
+ <p>
6
+ Choose a new plan:
7
+ </p>
8
+ <% else %>
9
+ <p>
10
+ Welcome!
11
+ </p>
12
+ <p>
13
+ Choose a plan below to get started:
14
+ </p>
15
+ <% end %>
16
+
17
+ <% for plan in DiscoApp::Plan.available %>
18
+
19
+ <h2><%= plan.name %></h2>
20
+ <%= form_for(@subscription) do |f| %>
21
+ <%= f.hidden_field :plan, value: plan.id %>
22
+ <%= f.submit %>
23
+ <% end %>
24
+
25
+ <% end %>
@@ -16,6 +16,7 @@
16
16
  <div class="collapse navbar-collapse">
17
17
  <ul class="nav navbar-nav">
18
18
  <%= active_link_to 'Shops', admin_shops_path, wrap_tag: :li %>
19
+ <%= active_link_to 'Plans', admin_plans_path, wrap_tag: :li %>
19
20
  <%= active_link_to 'Settings', edit_admin_app_settings_path, wrap_tag: :li %>
20
21
  </ul>
21
22
  </div>
data/config/routes.rb CHANGED
@@ -4,10 +4,12 @@ DiscoApp::Engine.routes.draw do
4
4
  post 'webhooks' => :process_webhook, as: :webhooks
5
5
  end
6
6
 
7
- controller :charges do
8
- get 'charges/new' => :new, as: :new_charge
9
- post 'charges/create' => :create, as: :create_charge
10
- get 'charges/activate' => :activate, as: :activate_charge
7
+ resources :subscriptions, only: [:new, :create] do
8
+ resources :charges, only: [:new, :create] do
9
+ member do
10
+ get 'activate'
11
+ end
12
+ end
11
13
  end
12
14
 
13
15
  controller :install do
@@ -22,7 +24,8 @@ DiscoApp::Engine.routes.draw do
22
24
  end
23
25
 
24
26
  namespace :admin do
25
- resources :shops, path: '/shops', only: [:index, :edit, :update]
27
+ resources :shops, only: [:index, :edit, :update]
28
+ resources :plans
26
29
  resource :app_settings, only: [:edit, :update]
27
30
 
28
31
  # JSON-API resources for admins."
@@ -0,0 +1,22 @@
1
+ class UpdatePlans < ActiveRecord::Migration
2
+ def change
3
+ remove_column :disco_app_plans, :default_price, :decimal
4
+ rename_column :disco_app_plans, :default_trial_days, :trial_period_days
5
+ rename_column :disco_app_plans, :charge_type, :plan_type
6
+ add_column :disco_app_plans, :amount, :integer, default: 0
7
+ add_column :disco_app_plans, :currency, :string, default: 'USD'
8
+ add_column :disco_app_plans, :interval, :integer, default: 0
9
+ add_column :disco_app_plans, :interval_count, :integer, default: 1
10
+
11
+ reversible do |direction|
12
+ direction.up do
13
+ change_column :disco_app_plans, :plan_type, :integer, default: 0
14
+ change_column :disco_app_plans, :status, :integer, default: 0
15
+ end
16
+ direction.down do
17
+ change_column :disco_app_plans, :plan_type, :integer
18
+ change_column :disco_app_plans, :status, :integer
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,13 @@
1
+ class UpdateSubscriptions < ActiveRecord::Migration
2
+ def change
3
+ remove_column :disco_app_subscriptions, :name, :string
4
+ remove_column :disco_app_subscriptions, :price, :decimal
5
+ remove_column :disco_app_subscriptions, :trial_days, :integer
6
+
7
+ rename_column :disco_app_subscriptions, :charge_type, :subscription_type
8
+
9
+ add_column :disco_app_subscriptions, :trial_start_at, :datetime, null: true
10
+ add_column :disco_app_subscriptions, :trial_end_at, :datetime, null: true
11
+ add_column :disco_app_subscriptions, :cancelled_at, :datetime, null: true
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ class CreateDiscoAppRecurringApplicationCharges < ActiveRecord::Migration
2
+ def change
3
+ create_table :disco_app_recurring_application_charges do |t|
4
+ t.integer :shop_id, limit: 8
5
+ t.integer :subscription_id, limit: 8
6
+ t.integer :status, default: 0
7
+
8
+ t.timestamps null: false
9
+ end
10
+
11
+ add_foreign_key :disco_app_recurring_application_charges, :disco_app_shops, column: :shop_id
12
+ add_foreign_key :disco_app_recurring_application_charges, :disco_app_subscriptions, column: :subscription_id
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ class CreateDiscoAppApplicationCharges < ActiveRecord::Migration
2
+ def change
3
+ create_table :disco_app_application_charges do |t|
4
+ t.integer :shop_id, limit: 8
5
+ t.integer :subscription_id, limit: 8
6
+ t.integer :status, default: 0
7
+
8
+ t.timestamps null: false
9
+ end
10
+
11
+ add_foreign_key :disco_app_application_charges, :disco_app_shops, column: :shop_id
12
+ add_foreign_key :disco_app_application_charges, :disco_app_subscriptions, column: :subscription_id
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ class DropChargeStatusFromShops < ActiveRecord::Migration
2
+ def change
3
+ remove_column :disco_app_shops, :charge_status, :integer, default: 0
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ class AddShopifyAttributesToCharges < ActiveRecord::Migration
2
+ def change
3
+ add_column :disco_app_application_charges, :shopify_id, :integer, limit: 8, null: true
4
+ add_column :disco_app_recurring_application_charges, :shopify_id, :integer, limit: 8, null: true
5
+ add_column :disco_app_application_charges, :confirmation_url, :string, null: true
6
+ add_column :disco_app_recurring_application_charges, :confirmation_url, :string, null: true
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ class CreateDiscoAppPlanCodes < ActiveRecord::Migration
2
+ def change
3
+ create_table :disco_app_plan_codes do |t|
4
+ t.integer :plan_id, limit: 8
5
+ t.string :code
6
+ t.integer :trial_period_days
7
+ t.integer :amount
8
+
9
+ t.timestamps null: false
10
+ end
11
+
12
+ add_foreign_key :disco_app_plan_codes, :disco_app_plans, column: :plan_id
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ class AddStatusToPlanCodes < ActiveRecord::Migration
2
+ def change
3
+ add_column :disco_app_plan_codes, :status, :integer, default: 0
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ class AddAmountAndPlanCodeToDiscoAppSubscriptions < ActiveRecord::Migration
2
+ def change
3
+ add_column :disco_app_subscriptions, :amount, :integer, default: 0
4
+ add_column :disco_app_subscriptions, :plan_code_id, :integer, limit: 8
5
+ add_foreign_key :disco_app_subscriptions, :disco_app_plan_codes, column: :plan_code_id
6
+ end
7
+ end
@@ -8,6 +8,10 @@ module DiscoApp
8
8
  # Set the below if using an application proxy.
9
9
  attr_accessor :app_proxy_prefix
10
10
 
11
+ # Set the below to create real Shopify charges.
12
+ attr_accessor :real_charges
13
+ alias_method :real_charges?, :real_charges
14
+
11
15
  # Optional configuration, usually useful for development environments.
12
16
  attr_accessor :skip_proxy_verification
13
17
  alias_method :skip_proxy_verification?, :skip_proxy_verification
@@ -15,6 +19,8 @@ module DiscoApp
15
19
  alias_method :skip_webhook_verification?, :skip_webhook_verification
16
20
  attr_accessor :skip_carrier_request_verification
17
21
  alias_method :skip_carrier_request_verification?, :skip_carrier_request_verification
22
+ attr_accessor :skip_oauth
23
+ alias_method :skip_oauth?, :skip_oauth
18
24
 
19
25
  end
20
26
 
@@ -1,3 +1,3 @@
1
1
  module DiscoApp
2
- VERSION = '0.8.7'
2
+ VERSION = '0.8.8'
3
3
  end
@@ -7,7 +7,7 @@ module DiscoApp
7
7
  # Install the react-rails gem and run its setup.
8
8
  def install_gem
9
9
  # Add gem to Gemfile
10
- gem 'react-rails', '~> 1.5.0'
10
+ gem 'react-rails', '~> 1.6.0'
11
11
 
12
12
  # Install gem.
13
13
  Bundler.with_clean_env do
@@ -7,8 +7,13 @@ DiscoApp.configure do |config|
7
7
  # Set the below if using an application proxy.
8
8
  config.app_proxy_prefix = ENV['SHOPIFY_APP_PROXY_PREFIX']
9
9
 
10
- # Optional configuration, usually useful for development environments.
11
- config.skip_proxy_verification = ENV['SKIP_PROXY_VERIFICATION']
12
- config.skip_webhook_verification = ENV['SKIP_WEBHOOK_VERIFICATION']
13
- config.skip_carrier_request_verification = ENV['SKIP_CARRIER_REQUEST_VERIFICATION']
10
+ # Set the below to create real Shopify charges.
11
+ config.real_charges = ENV['SHOPIFY_REAL_CHARGES'] === 'true'
12
+
13
+ # Optional configuration. These flags are only respected in the development
14
+ # environment and will have no effect in production.
15
+ config.skip_proxy_verification = ENV['SKIP_PROXY_VERIFICATION'] == 'true'
16
+ config.skip_webhook_verification = ENV['SKIP_WEBHOOK_VERIFICATION'] == 'true'
17
+ config.skip_carrier_request_verification = ENV['SKIP_CARRIER_REQUEST_VERIFICATION'] == 'true'
18
+ config.skip_oauth = ENV['SKIP_OAUTH'] == 'true'
14
19
  end