effective_orders 2.2.4 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +124 -84
- data/app/assets/javascripts/effective_orders/customers.js.coffee +39 -0
- data/app/assets/javascripts/effective_orders/providers/{stripe_charges.js.coffee → stripe.js.coffee} +15 -13
- data/app/assets/javascripts/effective_orders/subscriptions.js.coffee +73 -0
- data/app/assets/stylesheets/effective_orders.scss +2 -1
- data/app/assets/stylesheets/effective_orders/_order.scss +16 -8
- data/app/assets/stylesheets/effective_orders/_subscriptions.scss +14 -0
- data/app/controllers/admin/customers_controller.rb +11 -8
- data/app/controllers/admin/order_items_controller.rb +4 -8
- data/app/controllers/admin/orders_controller.rb +133 -87
- data/app/controllers/effective/carts_controller.rb +18 -8
- data/app/controllers/effective/concerns/purchase.rb +39 -0
- data/app/controllers/effective/customers_controller.rb +43 -0
- data/app/controllers/effective/orders_controller.rb +73 -119
- data/app/controllers/effective/providers/app_checkout.rb +3 -1
- data/app/controllers/effective/providers/ccbill.rb +4 -6
- data/app/controllers/effective/providers/cheque.rb +20 -11
- data/app/controllers/effective/providers/free.rb +33 -0
- data/app/controllers/effective/providers/mark_as_paid.rb +33 -0
- data/app/controllers/effective/providers/moneris.rb +9 -17
- data/app/controllers/effective/providers/paypal.rb +4 -6
- data/app/controllers/effective/providers/pretend.rb +4 -4
- data/app/controllers/effective/providers/refund.rb +39 -0
- data/app/controllers/effective/providers/stripe.rb +19 -40
- data/app/controllers/effective/providers/stripe_connect.rb +2 -6
- data/app/controllers/effective/webhooks_controller.rb +44 -95
- data/app/datatables/effective_customers_datatable.rb +21 -29
- data/app/datatables/effective_order_items_datatable.rb +77 -79
- data/app/datatables/effective_orders_datatable.rb +67 -57
- data/app/helpers/effective_carts_helper.rb +17 -14
- data/app/helpers/effective_orders_helper.rb +40 -56
- data/app/helpers/effective_paypal_helper.rb +3 -3
- data/app/helpers/effective_stripe_helper.rb +47 -18
- data/app/helpers/effective_subscriptions_helper.rb +79 -0
- data/app/mailers/effective/orders_mailer.rb +125 -2
- data/app/models/concerns/acts_as_purchasable.rb +23 -33
- data/app/models/concerns/acts_as_subscribable.rb +68 -0
- data/app/models/concerns/acts_as_subscribable_buyer.rb +22 -0
- data/app/models/effective/cart.rb +53 -24
- data/app/models/effective/cart_item.rb +6 -12
- data/app/models/effective/customer.rb +51 -54
- data/app/models/effective/order.rb +160 -147
- data/app/models/effective/order_item.rb +18 -21
- data/app/models/effective/product.rb +7 -7
- data/app/models/effective/providers/ccbill_postback.rb +1 -1
- data/app/models/effective/providers/stripe_charge.rb +8 -19
- data/app/models/effective/subscripter.rb +230 -0
- data/app/models/effective/subscription.rb +27 -76
- data/app/models/effective/tax_rate_calculator.rb +10 -7
- data/app/views/admin/customers/_actions.html.haml +1 -2
- data/app/views/admin/customers/index.html.haml +1 -1
- data/app/views/admin/customers/show.html.haml +6 -0
- data/app/views/admin/orders/_actions.html.haml +9 -7
- data/app/views/admin/orders/_form.html.haml +11 -7
- data/app/views/admin/orders/_order_actions.html.haml +2 -1
- data/app/views/admin/orders/_order_item_fields.html.haml +1 -1
- data/app/views/admin/orders/edit.html.haml +4 -0
- data/app/views/admin/orders/index.html.haml +1 -4
- data/app/views/admin/orders/new.html.haml +1 -1
- data/app/views/admin/orders/show.html.haml +5 -6
- data/app/views/effective/carts/_cart.html.haml +2 -2
- data/app/views/effective/carts/show.html.haml +2 -2
- data/app/views/effective/customers/_customer.html.haml +152 -0
- data/app/views/effective/customers/_fields.html.haml +12 -0
- data/app/views/effective/customers/_form.html.haml +13 -0
- data/app/views/effective/customers/edit.html.haml +3 -0
- data/app/views/effective/orders/_checkout_step1.html.haml +8 -15
- data/app/views/effective/orders/_checkout_step2.html.haml +34 -21
- data/app/views/effective/orders/_order.html.haml +8 -9
- data/app/views/effective/orders/_order_actions.html.haml +7 -8
- data/app/views/effective/orders/_order_header.html.haml +1 -1
- data/app/views/effective/orders/_order_items.html.haml +11 -5
- data/app/views/effective/orders/_order_note.html.haml +4 -7
- data/app/views/effective/orders/_orders_table.html.haml +26 -26
- data/app/views/effective/orders/app_checkout/_form.html.haml +2 -2
- data/app/views/effective/orders/ccbill/_form.html.haml +1 -1
- data/app/views/effective/orders/cheque/_form.html.haml +3 -1
- data/app/views/effective/orders/declined.html.haml +1 -1
- data/app/views/effective/orders/{checkout_step1.html.haml → edit.html.haml} +0 -0
- data/app/views/effective/orders/free/_form.html.haml +4 -0
- data/app/views/effective/orders/index.html.haml +2 -4
- data/app/views/effective/orders/mark_as_paid/_form.html.haml +32 -0
- data/app/views/effective/orders/moneris/_form.html.haml +6 -6
- data/app/views/effective/orders/{checkout_step2.html.haml → new.html.haml} +1 -1
- data/app/views/effective/orders/paypal/_form.html.haml +2 -2
- data/app/views/effective/orders/pretend/_form.html.haml +2 -2
- data/app/views/effective/orders/purchased.html.haml +3 -0
- data/app/views/effective/orders/refund/_form.html.haml +32 -0
- data/app/views/effective/orders/show.html.haml +4 -1
- data/app/views/effective/orders/stripe/_form.html.haml +5 -5
- data/app/views/effective/orders_mailer/subscription_canceled.html.haml +9 -0
- data/app/views/effective/orders_mailer/subscription_payment_failed.html.haml +9 -0
- data/app/views/effective/orders_mailer/subscription_payment_succeeded.html.haml +9 -0
- data/app/views/effective/orders_mailer/subscription_trial_expired.html.haml +5 -0
- data/app/views/effective/orders_mailer/subscription_trial_expiring.html.haml +7 -0
- data/app/views/effective/subscriptions/_fields.html.haml +16 -0
- data/app/views/effective/subscriptions/_plan.html.haml +21 -0
- data/app/views/layouts/effective_orders_mailer_layout.html.haml +6 -8
- data/config/effective_orders.rb +41 -20
- data/config/routes.rb +48 -48
- data/db/migrate/01_create_effective_orders.rb.erb +19 -5
- data/lib/effective_orders.rb +78 -42
- data/lib/effective_orders/engine.rb +36 -82
- data/lib/effective_orders/version.rb +1 -1
- data/lib/generators/effective_orders/install_generator.rb +2 -2
- data/lib/generators/templates/effective_orders_mailer_preview.rb +39 -4
- data/lib/tasks/effective_orders_tasks.rake +42 -0
- data/spec/controllers/carts_controller_spec.rb +1 -1
- data/spec/controllers/moneris_orders_controller_spec.rb +4 -4
- data/spec/controllers/orders_controller_spec.rb +4 -4
- data/spec/controllers/stripe_orders_controller_spec.rb +2 -2
- data/spec/controllers/webhooks_controller_spec.rb +1 -1
- data/spec/dummy/config/initializers/effective_orders.rb +1 -7
- data/spec/dummy/db/schema.rb +1 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/test.log +3 -0
- data/spec/models/acts_as_purchasable_spec.rb +0 -56
- data/spec/models/customer_spec.rb +3 -3
- data/spec/models/order_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -1
- data/spec/support/factories.rb +2 -1
- metadata +37 -49
- data/active_admin/effective_carts.rb +0 -14
- data/active_admin/effective_orders.rb +0 -112
- data/app/assets/javascripts/effective_orders/providers/stripe_subscriptions.js.coffee +0 -28
- data/app/controllers/concerns/acts_as_active_admin_controller.rb +0 -69
- data/app/controllers/effective/subscriptions_controller.rb +0 -126
- data/app/models/effective/datatables/customers.rb +0 -40
- data/app/models/effective/datatables/order_items.rb +0 -101
- data/app/models/effective/datatables/orders.rb +0 -91
- data/app/models/inputs/price_field.rb +0 -63
- data/app/models/inputs/price_form_input.rb +0 -7
- data/app/models/inputs/price_formtastic_input.rb +0 -9
- data/app/models/inputs/price_input.rb +0 -19
- data/app/models/inputs/price_simple_form_input.rb +0 -8
- data/app/views/admin/orders/_form_mark_as_paid.html.haml +0 -33
- data/app/views/admin/orders/_order_payment_details.html.haml +0 -5
- data/app/views/admin/orders/mark_as_paid.html.haml +0 -7
- data/app/views/effective/orders/stripe/_subscription_fields.html.haml +0 -7
- data/app/views/effective/subscriptions/index.html.haml +0 -22
- data/app/views/effective/subscriptions/new.html.haml +0 -9
- data/app/views/effective/subscriptions/show.html.haml +0 -49
- data/db/upgrade/02_upgrade_effective_orders_from03x.rb.erb +0 -29
- data/db/upgrade/03_upgrade_effective_orders_from1x.rb.erb +0 -98
- data/db/upgrade/upgrade_price_column_on_table.rb.erb +0 -17
- data/lib/generators/effective_orders/upgrade_from03x_generator.rb +0 -31
- data/lib/generators/effective_orders/upgrade_from1x_generator.rb +0 -27
- data/lib/generators/effective_orders/upgrade_price_column_generator.rb +0 -30
@@ -2,26 +2,24 @@
|
|
2
2
|
%html{style: 'background: #fff;'}
|
3
3
|
%head
|
4
4
|
%meta{:content => 'text/html; charset=UTF-8', 'http-equiv' => 'Content-Type'}
|
5
|
+
|
5
6
|
:css
|
6
|
-
.effective-order table.table { min-width: 650px; }
|
7
|
+
.effective-order table.table { min-width: 650px; vertical-align: top; border: 0; }
|
8
|
+
.effective-order table.table td { border: 0; vertical-align: top; }
|
7
9
|
.effective-order { text-align: left; }
|
8
10
|
.effective-order .price { text-align: right; }
|
9
11
|
.effective-order tfoot th { text-align: right; }
|
10
12
|
.effective-order tfoot tr:first-child td { padding-top: 24px; }
|
11
13
|
.effective-order tfoot tr:first-child th { padding-top: 24px; }
|
12
14
|
.effective-order-shipping { padding-top: 12px; padding-bottom: 12px; }
|
15
|
+
.effective-order-header h1 { margin: 0; }
|
16
|
+
@media print { .effective-page-break { page-break-inside: avoid; page-break-after: always; min-height: 1px; } }
|
13
17
|
|
14
18
|
%body{style: 'background: #fff;'}
|
15
19
|
%table{style: 'width: 100%;'}
|
16
20
|
%tr
|
17
21
|
%td
|
18
22
|
%table{style: 'max-width: 650px; margin: 4px auto 30px;'}
|
19
|
-
%
|
20
|
-
%tr
|
21
|
-
%th
|
22
|
-
%tbody{style: 'width: 100%'}
|
23
|
+
%tbody{style: 'width: 100%;'}
|
23
24
|
%tr
|
24
25
|
%td= yield
|
25
|
-
%tfoot{style: 'width: 100%;'}
|
26
|
-
%tr
|
27
|
-
%th
|
data/config/effective_orders.rb
CHANGED
@@ -10,7 +10,6 @@ EffectiveOrders.setup do |config|
|
|
10
10
|
config.subscriptions_table_name = :subscriptions
|
11
11
|
config.products_table_name = :products
|
12
12
|
|
13
|
-
|
14
13
|
# Authorization Method
|
15
14
|
#
|
16
15
|
# This method is called by all controller actions with the appropriate action and resource
|
@@ -38,18 +37,9 @@ EffectiveOrders.setup do |config|
|
|
38
37
|
# Filter the @orders on admin/orders#index screen
|
39
38
|
# config.orders_collection_scope = Proc.new { |scope| scope.where(...) }
|
40
39
|
|
41
|
-
# Register Effective::Order with ActiveAdmin if ActiveAdmin is present
|
42
|
-
# You must have authorization to authorized?(:manage, Effective::Order)
|
43
|
-
# For the activeadmin menu to item to show up
|
44
|
-
config.use_active_admin = true
|
45
|
-
config.active_admin_namespace = :admin # Passed internally to ActiveAdmin.register
|
46
|
-
|
47
40
|
# Use effective_obfuscation gem to change order.id into a seemingly random 10-digit number
|
48
41
|
config.obfuscate_order_ids = false
|
49
42
|
|
50
|
-
# Silence the price deprecation warnings
|
51
|
-
config.silence_deprecation_warnings = false
|
52
|
-
|
53
43
|
# Require these addresses when creating a new Order. Works with effective_addresses gem
|
54
44
|
config.require_billing_address = true
|
55
45
|
config.require_shipping_address = false
|
@@ -95,10 +85,15 @@ EffectiveOrders.setup do |config|
|
|
95
85
|
|
96
86
|
# Free Orders
|
97
87
|
# Allow orders with a total of 0.00 to be purchased (regardless of the minimum charge setting)
|
98
|
-
# When enabled, the checkout process will skip the paypal/stripe/purchasing step
|
99
88
|
# and just display the 'Thank You' after checkout is clicked
|
100
89
|
config.allow_free_orders = true
|
101
90
|
|
91
|
+
# Refunds
|
92
|
+
# Allow admins to create orders with a negative total
|
93
|
+
# Refunds don't perform any kind of refund action with the payment processor.
|
94
|
+
# This just changes the validations
|
95
|
+
config.allow_refunds = false
|
96
|
+
|
102
97
|
# Display a 'Purchase order' button on the Checkout screen allowing the user
|
103
98
|
# to purchase an Order without going through the payment processor
|
104
99
|
config.allow_pretend_purchase_in_development = true
|
@@ -137,12 +132,12 @@ EffectiveOrders.setup do |config|
|
|
137
132
|
config.admin_simple_form_options = {} # For the /admin/orders/new form
|
138
133
|
|
139
134
|
# config.simple_form_options = {
|
140
|
-
# html
|
141
|
-
# wrapper
|
142
|
-
# wrapper_mappings
|
143
|
-
# boolean
|
144
|
-
# check_boxes
|
145
|
-
# radio_buttons
|
135
|
+
# :html => {:class => ['form-horizontal']},
|
136
|
+
# :wrapper => :horizontal_form,
|
137
|
+
# :wrapper_mappings => {
|
138
|
+
# :boolean => :horizontal_boolean,
|
139
|
+
# :check_boxes => :horizontal_radio_and_checkboxes,
|
140
|
+
# :radio_buttons => :horizontal_radio_and_checkboxes
|
146
141
|
# }
|
147
142
|
# }
|
148
143
|
|
@@ -169,28 +164,45 @@ EffectiveOrders.setup do |config|
|
|
169
164
|
send_order_receipt_to_seller: true, # Only applies to StripeConnect
|
170
165
|
send_payment_request_to_buyer: true,
|
171
166
|
send_pending_order_invoice_to_buyer: true,
|
172
|
-
|
167
|
+
send_order_receipts_when_mark_as_paid: false,
|
168
|
+
|
169
|
+
send_subscription_payment_succeeded: true,
|
170
|
+
send_subscription_payment_failed: true,
|
171
|
+
send_subscription_canceled: true,
|
172
|
+
send_subscription_trial_expiring: true, # Only if you schedule the rake task to run
|
173
|
+
send_subscription_trial_expired: true, # Only if you schedule the rake task to run
|
173
174
|
|
174
175
|
subject_prefix: '[example]',
|
176
|
+
|
175
177
|
subject_for_order_receipt_to_admin: '',
|
176
178
|
subject_for_order_receipt_to_buyer: '',
|
177
179
|
subject_for_order_receipt_to_seller: '',
|
178
180
|
subject_for_pending_order_invoice_to_buyer: '',
|
179
181
|
subject_for_payment_request_to_buyer: '',
|
180
182
|
|
183
|
+
subject_for_subscription_payment_succeeded: '',
|
184
|
+
subject_for_subscription_payment_failed: '',
|
185
|
+
subject_for_subscription_canceled: '',
|
186
|
+
subject_for_subscription_trial_expiring: '',
|
187
|
+
subject_for_subscription_trial_expired: '',
|
188
|
+
|
181
189
|
layout: 'effective_orders_mailer_layout',
|
182
190
|
|
183
191
|
default_from: 'info@example.com',
|
184
192
|
admin_email: 'admin@example.com',
|
185
193
|
|
186
194
|
deliver_method: nil, # :deliver (rails < 4.2), :deliver_now (rails >= 4.2) or :deliver_later
|
187
|
-
delayed_job_deliver: false
|
195
|
+
delayed_job_deliver: false # Use the oldschool pre-ActiveJob delayed_job way of sending email
|
188
196
|
}
|
189
197
|
|
190
198
|
#######################################
|
191
199
|
### Payment Provider specific options
|
192
200
|
#######################################
|
193
201
|
|
202
|
+
# Mark an order as paid without going through a processor
|
203
|
+
# This is accessed via the admin screens only. Must have can?(:admin, :effective_orders)
|
204
|
+
config.mark_as_paid_enabled = false
|
205
|
+
|
194
206
|
# Moneris configuration
|
195
207
|
config.moneris_enabled = false
|
196
208
|
|
@@ -239,10 +251,19 @@ EffectiveOrders.setup do |config|
|
|
239
251
|
|
240
252
|
# Stripe configuration
|
241
253
|
config.stripe_enabled = false
|
242
|
-
config.
|
254
|
+
config.subscriptions_enabled = false # https://stripe.com/docs/subscriptions
|
255
|
+
|
243
256
|
config.stripe_connect_enabled = false # https://stripe.com/docs/connect
|
244
257
|
config.stripe_connect_application_fee_method = Proc.new { |order_item| order_item.total * 0.10 } # 10 percent
|
245
258
|
|
259
|
+
config.subscription = {
|
260
|
+
trial_name: 'Free Trial',
|
261
|
+
trial_description: '45-Day Free Trial',
|
262
|
+
trial_period: 45.days,
|
263
|
+
trial_remind_at: [1.day, 3.days, 7.days], # Send email notification to trialing users 1, 3 and 7 days before expiring. false to disable.
|
264
|
+
webhook_secret: 'whsec_1234567890'
|
265
|
+
}
|
266
|
+
|
246
267
|
if Rails.env.production?
|
247
268
|
config.stripe = {
|
248
269
|
secret_key: '',
|
data/config/routes.rb
CHANGED
@@ -7,71 +7,71 @@ end
|
|
7
7
|
EffectiveOrders::Engine.routes.draw do
|
8
8
|
scope module: 'effective' do
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
match 'orders/moneris_postback', to: 'orders#moneris_postback', as: 'moneris_postback', via: :post
|
25
|
-
end
|
26
|
-
|
27
|
-
if EffectiveOrders.stripe_enabled
|
28
|
-
match 'orders/stripe_charge', to: 'orders#stripe_charge', as: 'stripe_charges', via: :post
|
29
|
-
end
|
10
|
+
resources :orders, except: [:destroy] do
|
11
|
+
member do
|
12
|
+
get :purchased
|
13
|
+
get :declined
|
14
|
+
get :send_buyer_receipt
|
15
|
+
|
16
|
+
post :app_checkout if EffectiveOrders.app_checkout_enabled
|
17
|
+
post :free if EffectiveOrders.allow_free_orders
|
18
|
+
post :mark_as_paid if EffectiveOrders.mark_as_paid_enabled
|
19
|
+
post :pay_by_cheque if EffectiveOrders.cheque_enabled
|
20
|
+
post :pretend if EffectiveOrders.allow_pretend_purchase_in_production && Rails.env.production?
|
21
|
+
post :pretend if EffectiveOrders.allow_pretend_purchase_in_development && !Rails.env.production?
|
22
|
+
post :refund if EffectiveOrders.allow_refunds
|
23
|
+
end
|
30
24
|
|
31
|
-
|
32
|
-
|
33
|
-
|
25
|
+
collection do
|
26
|
+
get :my_purchases
|
27
|
+
post :bulk_send_buyer_receipt
|
34
28
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
29
|
+
if EffectiveOrders.stripe_connect_enabled
|
30
|
+
get :stripe_connect_redirect_uri # oAuth2
|
31
|
+
get :my_sales
|
32
|
+
end
|
39
33
|
|
40
|
-
|
41
|
-
|
34
|
+
post :ccbill_postback if EffectiveOrders.ccbill_enabled
|
35
|
+
post :moneris_postback if EffectiveOrders.moneris_enabled
|
36
|
+
post :paypal_postback if EffectiveOrders.paypal_enabled
|
37
|
+
post :stripe_charge if EffectiveOrders.stripe_enabled
|
38
|
+
end
|
42
39
|
end
|
43
40
|
|
44
|
-
|
45
|
-
match 'orders/:id/app_checkout', to: 'orders#app_checkout', as: 'app_checkout', via: :post
|
46
|
-
end
|
41
|
+
post 'orders/:id', to: 'orders#update'
|
47
42
|
|
48
|
-
if
|
49
|
-
match '
|
43
|
+
if EffectiveOrders.subscriptions_enabled
|
44
|
+
match 'customer/settings', to: 'customers#edit', as: :customer_settings, via: [:get]
|
45
|
+
match 'customer/settings', to: 'customers#update', via: [:patch, :put]
|
46
|
+
match 'webhooks/stripe', to: 'webhooks#stripe', via: [:post, :put]
|
50
47
|
end
|
51
48
|
|
52
|
-
resources :orders, except: [:destroy]
|
53
|
-
|
54
49
|
match 'cart', to: 'carts#show', as: 'cart', via: :get
|
55
50
|
match 'cart', to: 'carts#destroy', via: :delete
|
56
51
|
|
57
52
|
# If you Tweak this route, please update EffectiveOrdersHelper too
|
58
53
|
match 'cart/:purchasable_type/:purchasable_id', to: 'carts#add_to_cart', via: [:get, :post], as: 'add_to_cart'
|
59
54
|
match 'cart/:id', to: 'carts#remove_from_cart', via: [:delete], as: 'remove_from_cart'
|
60
|
-
|
61
|
-
match 'webhooks/stripe', to: 'webhooks#stripe', via: [:post, :put]
|
62
55
|
end
|
63
56
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
post :send_payment_request
|
72
|
-
end
|
57
|
+
namespace :admin do
|
58
|
+
resources :customers, only: [:index, :show]
|
59
|
+
resources :orders do
|
60
|
+
member do
|
61
|
+
post :send_payment_request
|
62
|
+
post :checkout
|
63
|
+
patch :checkout
|
73
64
|
end
|
74
|
-
|
65
|
+
|
66
|
+
collection do
|
67
|
+
post :bulk_send_payment_request
|
68
|
+
end
|
69
|
+
|
75
70
|
end
|
71
|
+
|
72
|
+
post 'orders/:id', to: 'orders#update'
|
73
|
+
|
74
|
+
resources :order_items, only: [:index]
|
76
75
|
end
|
76
|
+
|
77
77
|
end
|
@@ -47,6 +47,7 @@ class CreateEffectiveOrders < ActiveRecord::Migration[4.2]
|
|
47
47
|
|
48
48
|
create_table <%= @carts_table_name %> do |t|
|
49
49
|
t.integer :user_id
|
50
|
+
t.integer :cart_items_count, :default => 0
|
50
51
|
t.timestamps
|
51
52
|
end
|
52
53
|
|
@@ -57,6 +58,7 @@ class CreateEffectiveOrders < ActiveRecord::Migration[4.2]
|
|
57
58
|
t.string :purchasable_type
|
58
59
|
t.integer :purchasable_id
|
59
60
|
|
61
|
+
t.string :unique
|
60
62
|
t.integer :quantity
|
61
63
|
|
62
64
|
t.timestamps
|
@@ -68,10 +70,17 @@ class CreateEffectiveOrders < ActiveRecord::Migration[4.2]
|
|
68
70
|
|
69
71
|
create_table <%= @customers_table_name %> do |t|
|
70
72
|
t.integer :user_id
|
73
|
+
|
71
74
|
t.string :stripe_customer_id
|
72
|
-
t.string :
|
75
|
+
t.string :active_card
|
76
|
+
|
77
|
+
t.string :stripe_subscription_id
|
78
|
+
t.string :status
|
79
|
+
|
73
80
|
t.string :stripe_connect_access_token
|
74
81
|
|
82
|
+
t.integer :subscriptions_count, :default => 0
|
83
|
+
|
75
84
|
t.timestamps
|
76
85
|
end
|
77
86
|
|
@@ -79,17 +88,22 @@ class CreateEffectiveOrders < ActiveRecord::Migration[4.2]
|
|
79
88
|
|
80
89
|
create_table <%= @subscriptions_table_name %> do |t|
|
81
90
|
t.integer :customer_id
|
91
|
+
|
92
|
+
t.integer :subscribable_id
|
93
|
+
t.string :subscribable_type
|
94
|
+
|
82
95
|
t.string :stripe_plan_id
|
83
|
-
t.string :
|
84
|
-
|
85
|
-
t.string :
|
96
|
+
t.string :status
|
97
|
+
|
98
|
+
t.string :name
|
86
99
|
t.integer :price, :default => 0
|
87
100
|
|
88
101
|
t.timestamps
|
89
102
|
end
|
90
103
|
|
91
104
|
add_index <%= @subscriptions_table_name %>, :customer_id
|
92
|
-
add_index <%= @subscriptions_table_name %>, :
|
105
|
+
add_index <%= @subscriptions_table_name %>, :subscribable_id
|
106
|
+
add_index <%= @subscriptions_table_name %>, [:subscribable_type, :subscribable_id]
|
93
107
|
|
94
108
|
create_table <%= @products_table_name %> do |t|
|
95
109
|
t.string :title
|
data/lib/effective_orders.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'simple_form'
|
2
1
|
require 'effective_addresses'
|
3
2
|
require 'effective_orders/engine'
|
4
3
|
require 'effective_orders/version'
|
@@ -10,6 +9,8 @@ module EffectiveOrders
|
|
10
9
|
DECLINED = 'declined'
|
11
10
|
PENDING = 'pending'
|
12
11
|
|
12
|
+
PURCHASE_STATES = { nil => ABANDONED, PURCHASED => PURCHASED, DECLINED => DECLINED, PENDING => PENDING }
|
13
|
+
|
13
14
|
# The following are all valid config keys
|
14
15
|
mattr_accessor :orders_table_name
|
15
16
|
mattr_accessor :order_items_table_name
|
@@ -29,12 +30,9 @@ module EffectiveOrders
|
|
29
30
|
mattr_accessor :layout
|
30
31
|
mattr_accessor :simple_form_options
|
31
32
|
mattr_accessor :admin_simple_form_options
|
32
|
-
|
33
|
-
mattr_accessor :use_active_admin
|
34
|
-
mattr_accessor :active_admin_namespace
|
33
|
+
mattr_accessor :show_order_history_button
|
35
34
|
|
36
35
|
mattr_accessor :obfuscate_order_ids
|
37
|
-
mattr_accessor :silence_deprecation_warnings
|
38
36
|
|
39
37
|
mattr_accessor :allow_pretend_purchase_in_development
|
40
38
|
mattr_accessor :allow_pretend_purchase_in_production
|
@@ -56,73 +54,63 @@ module EffectiveOrders
|
|
56
54
|
|
57
55
|
mattr_accessor :minimum_charge
|
58
56
|
mattr_accessor :allow_free_orders
|
59
|
-
mattr_accessor :
|
57
|
+
mattr_accessor :allow_refunds
|
60
58
|
|
59
|
+
mattr_accessor :app_checkout_enabled
|
60
|
+
mattr_accessor :ccbill_enabled
|
61
61
|
mattr_accessor :cheque_enabled
|
62
|
-
mattr_accessor :
|
62
|
+
mattr_accessor :mark_as_paid_enabled
|
63
63
|
mattr_accessor :moneris_enabled
|
64
|
-
mattr_accessor :
|
65
|
-
mattr_accessor :app_checkout_enabled
|
64
|
+
mattr_accessor :paypal_enabled
|
66
65
|
|
67
66
|
mattr_accessor :stripe_enabled
|
68
|
-
mattr_accessor :stripe_subscriptions_enabled
|
69
67
|
mattr_accessor :stripe_connect_enabled
|
70
68
|
|
69
|
+
mattr_accessor :subscriptions_enabled
|
70
|
+
|
71
71
|
# application fee is required if stripe_connect_enabled is true
|
72
72
|
mattr_accessor :stripe_connect_application_fee_method
|
73
73
|
|
74
74
|
# These are hashes of configs
|
75
|
+
mattr_accessor :app_checkout
|
76
|
+
mattr_accessor :ccbill
|
77
|
+
mattr_accessor :cheque
|
75
78
|
mattr_accessor :mailer
|
76
|
-
mattr_accessor :paypal
|
77
79
|
mattr_accessor :moneris
|
80
|
+
mattr_accessor :paypal
|
78
81
|
mattr_accessor :stripe
|
79
|
-
mattr_accessor :
|
80
|
-
mattr_accessor :app_checkout
|
81
|
-
mattr_accessor :cheque
|
82
|
+
mattr_accessor :subscription
|
82
83
|
|
83
84
|
mattr_accessor :deliver_method
|
84
85
|
|
85
86
|
def self.setup
|
86
87
|
yield self
|
87
|
-
|
88
|
-
if EffectiveOrders.stripe_enabled
|
89
|
-
begin
|
90
|
-
require 'stripe'
|
91
|
-
rescue Exception
|
92
|
-
raise "unable to load stripe. Plese add gem 'stripe' to your Gemfile and then 'bundle install'"
|
93
|
-
end
|
94
|
-
|
95
|
-
::Stripe.api_key = stripe[:secret_key]
|
96
|
-
end
|
97
88
|
end
|
98
89
|
|
99
90
|
def self.authorized?(controller, action, resource)
|
100
|
-
if
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
end
|
91
|
+
@_exceptions ||= [Effective::AccessDenied, (CanCan::AccessDenied if defined?(CanCan)), (Pundit::NotAuthorizedError if defined?(Pundit))].compact
|
92
|
+
|
93
|
+
return !!authorization_method unless authorization_method.respond_to?(:call)
|
94
|
+
controller = controller.controller if controller.respond_to?(:controller)
|
105
95
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
ActiveSupport::Deprecation.warn('EffectiveOrders.minimum_charge config option is a non-integer. It should be an Integer representing the number of cents. Continuing with (price * 100.0).round(0).to_i conversion') unless EffectiveOrders.silence_deprecation_warnings
|
111
|
-
((@@minimum_charge * 100.0).round(0).to_i rescue nil)
|
96
|
+
begin
|
97
|
+
!!(controller || self).instance_exec((controller || self), action, resource, &authorization_method)
|
98
|
+
rescue *@_exceptions
|
99
|
+
false
|
112
100
|
end
|
113
101
|
end
|
114
102
|
|
115
|
-
def self.
|
116
|
-
|
103
|
+
def self.authorize!(controller, action, resource)
|
104
|
+
raise Effective::AccessDenied unless authorized?(controller, action, resource)
|
117
105
|
end
|
118
106
|
|
119
107
|
def self.permitted_params
|
120
108
|
[
|
121
|
-
:note, :
|
109
|
+
:note, :terms_and_conditions,
|
122
110
|
billing_address: EffectiveAddresses.permitted_params,
|
123
111
|
shipping_address: EffectiveAddresses.permitted_params,
|
124
112
|
user_attributes: (EffectiveOrders.collect_user_fields || []),
|
125
|
-
|
113
|
+
subscripter: [:stripe_plan_id, :stripe_token]
|
126
114
|
]
|
127
115
|
end
|
128
116
|
|
@@ -152,15 +140,63 @@ module EffectiveOrders
|
|
152
140
|
].compact
|
153
141
|
end
|
154
142
|
|
143
|
+
# One of these is used when Admin marks as paid
|
155
144
|
def self.other_payment_providers
|
156
145
|
['credit card', 'none', 'other']
|
157
146
|
end
|
158
147
|
|
159
|
-
def self.
|
160
|
-
|
148
|
+
def self.can_skip_checkout_step1?
|
149
|
+
return false if require_billing_address
|
150
|
+
return false if require_shipping_address
|
151
|
+
return false if collect_note
|
152
|
+
return false if terms_and_conditions
|
153
|
+
return false if collect_user_fields.present?
|
154
|
+
|
155
|
+
true
|
156
|
+
end
|
157
|
+
|
158
|
+
def self.stripe_plans
|
159
|
+
return {} unless (stripe_enabled && subscriptions_enabled)
|
160
|
+
|
161
|
+
@stripe_plans ||= (
|
162
|
+
plans = Stripe::Plan.all.inject({}) do |h, plan|
|
163
|
+
occurrence = case plan.interval
|
164
|
+
when 'daily' ; '/day'
|
165
|
+
when 'weekly' ; '/week'
|
166
|
+
when 'monthly' ; '/month'
|
167
|
+
when 'yearly' ; '/year'
|
168
|
+
when 'day' ; plan.interval_count == 1 ? '/day' : " every #{plan.interval_count} days"
|
169
|
+
when 'week' ; plan.interval_count == 1 ? '/week' : " every #{plan.interval_count} weeks"
|
170
|
+
when 'month' ; plan.interval_count == 1 ? '/month' : " every #{plan.interval_count} months"
|
171
|
+
when 'year' ; plan.interval_count == 1 ? '/year' : " every #{plan.interval_count} years"
|
172
|
+
else ; plan.interval
|
173
|
+
end
|
174
|
+
|
175
|
+
h[plan.id] = {
|
176
|
+
id: plan.id,
|
177
|
+
name: plan.name,
|
178
|
+
amount: plan.amount,
|
179
|
+
currency: plan.currency,
|
180
|
+
description: "$#{'%0.2f' % (plan.amount / 100.0)} #{plan.currency.upcase}#{occurrence}",
|
181
|
+
occurrence: "#{occurrence}",
|
182
|
+
interval: plan.interval,
|
183
|
+
interval_count: plan.interval_count
|
184
|
+
}; h
|
185
|
+
end
|
186
|
+
|
187
|
+
if subscription.kind_of?(Hash)
|
188
|
+
plans['trial'] = {
|
189
|
+
id: 'trial',
|
190
|
+
amount: 0,
|
191
|
+
name: (subscription[:trial_name] || 'Free Trial'),
|
192
|
+
description: (subscription[:trial_description] || 'Free Trial')
|
193
|
+
}
|
194
|
+
end
|
195
|
+
|
196
|
+
plans
|
197
|
+
)
|
161
198
|
end
|
162
199
|
|
163
200
|
class SoldOutException < Exception; end
|
164
201
|
class AlreadyPurchasedException < Exception; end
|
165
|
-
|
166
202
|
end
|