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.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +124 -84
  4. data/app/assets/javascripts/effective_orders/customers.js.coffee +39 -0
  5. data/app/assets/javascripts/effective_orders/providers/{stripe_charges.js.coffee → stripe.js.coffee} +15 -13
  6. data/app/assets/javascripts/effective_orders/subscriptions.js.coffee +73 -0
  7. data/app/assets/stylesheets/effective_orders.scss +2 -1
  8. data/app/assets/stylesheets/effective_orders/_order.scss +16 -8
  9. data/app/assets/stylesheets/effective_orders/_subscriptions.scss +14 -0
  10. data/app/controllers/admin/customers_controller.rb +11 -8
  11. data/app/controllers/admin/order_items_controller.rb +4 -8
  12. data/app/controllers/admin/orders_controller.rb +133 -87
  13. data/app/controllers/effective/carts_controller.rb +18 -8
  14. data/app/controllers/effective/concerns/purchase.rb +39 -0
  15. data/app/controllers/effective/customers_controller.rb +43 -0
  16. data/app/controllers/effective/orders_controller.rb +73 -119
  17. data/app/controllers/effective/providers/app_checkout.rb +3 -1
  18. data/app/controllers/effective/providers/ccbill.rb +4 -6
  19. data/app/controllers/effective/providers/cheque.rb +20 -11
  20. data/app/controllers/effective/providers/free.rb +33 -0
  21. data/app/controllers/effective/providers/mark_as_paid.rb +33 -0
  22. data/app/controllers/effective/providers/moneris.rb +9 -17
  23. data/app/controllers/effective/providers/paypal.rb +4 -6
  24. data/app/controllers/effective/providers/pretend.rb +4 -4
  25. data/app/controllers/effective/providers/refund.rb +39 -0
  26. data/app/controllers/effective/providers/stripe.rb +19 -40
  27. data/app/controllers/effective/providers/stripe_connect.rb +2 -6
  28. data/app/controllers/effective/webhooks_controller.rb +44 -95
  29. data/app/datatables/effective_customers_datatable.rb +21 -29
  30. data/app/datatables/effective_order_items_datatable.rb +77 -79
  31. data/app/datatables/effective_orders_datatable.rb +67 -57
  32. data/app/helpers/effective_carts_helper.rb +17 -14
  33. data/app/helpers/effective_orders_helper.rb +40 -56
  34. data/app/helpers/effective_paypal_helper.rb +3 -3
  35. data/app/helpers/effective_stripe_helper.rb +47 -18
  36. data/app/helpers/effective_subscriptions_helper.rb +79 -0
  37. data/app/mailers/effective/orders_mailer.rb +125 -2
  38. data/app/models/concerns/acts_as_purchasable.rb +23 -33
  39. data/app/models/concerns/acts_as_subscribable.rb +68 -0
  40. data/app/models/concerns/acts_as_subscribable_buyer.rb +22 -0
  41. data/app/models/effective/cart.rb +53 -24
  42. data/app/models/effective/cart_item.rb +6 -12
  43. data/app/models/effective/customer.rb +51 -54
  44. data/app/models/effective/order.rb +160 -147
  45. data/app/models/effective/order_item.rb +18 -21
  46. data/app/models/effective/product.rb +7 -7
  47. data/app/models/effective/providers/ccbill_postback.rb +1 -1
  48. data/app/models/effective/providers/stripe_charge.rb +8 -19
  49. data/app/models/effective/subscripter.rb +230 -0
  50. data/app/models/effective/subscription.rb +27 -76
  51. data/app/models/effective/tax_rate_calculator.rb +10 -7
  52. data/app/views/admin/customers/_actions.html.haml +1 -2
  53. data/app/views/admin/customers/index.html.haml +1 -1
  54. data/app/views/admin/customers/show.html.haml +6 -0
  55. data/app/views/admin/orders/_actions.html.haml +9 -7
  56. data/app/views/admin/orders/_form.html.haml +11 -7
  57. data/app/views/admin/orders/_order_actions.html.haml +2 -1
  58. data/app/views/admin/orders/_order_item_fields.html.haml +1 -1
  59. data/app/views/admin/orders/edit.html.haml +4 -0
  60. data/app/views/admin/orders/index.html.haml +1 -4
  61. data/app/views/admin/orders/new.html.haml +1 -1
  62. data/app/views/admin/orders/show.html.haml +5 -6
  63. data/app/views/effective/carts/_cart.html.haml +2 -2
  64. data/app/views/effective/carts/show.html.haml +2 -2
  65. data/app/views/effective/customers/_customer.html.haml +152 -0
  66. data/app/views/effective/customers/_fields.html.haml +12 -0
  67. data/app/views/effective/customers/_form.html.haml +13 -0
  68. data/app/views/effective/customers/edit.html.haml +3 -0
  69. data/app/views/effective/orders/_checkout_step1.html.haml +8 -15
  70. data/app/views/effective/orders/_checkout_step2.html.haml +34 -21
  71. data/app/views/effective/orders/_order.html.haml +8 -9
  72. data/app/views/effective/orders/_order_actions.html.haml +7 -8
  73. data/app/views/effective/orders/_order_header.html.haml +1 -1
  74. data/app/views/effective/orders/_order_items.html.haml +11 -5
  75. data/app/views/effective/orders/_order_note.html.haml +4 -7
  76. data/app/views/effective/orders/_orders_table.html.haml +26 -26
  77. data/app/views/effective/orders/app_checkout/_form.html.haml +2 -2
  78. data/app/views/effective/orders/ccbill/_form.html.haml +1 -1
  79. data/app/views/effective/orders/cheque/_form.html.haml +3 -1
  80. data/app/views/effective/orders/declined.html.haml +1 -1
  81. data/app/views/effective/orders/{checkout_step1.html.haml → edit.html.haml} +0 -0
  82. data/app/views/effective/orders/free/_form.html.haml +4 -0
  83. data/app/views/effective/orders/index.html.haml +2 -4
  84. data/app/views/effective/orders/mark_as_paid/_form.html.haml +32 -0
  85. data/app/views/effective/orders/moneris/_form.html.haml +6 -6
  86. data/app/views/effective/orders/{checkout_step2.html.haml → new.html.haml} +1 -1
  87. data/app/views/effective/orders/paypal/_form.html.haml +2 -2
  88. data/app/views/effective/orders/pretend/_form.html.haml +2 -2
  89. data/app/views/effective/orders/purchased.html.haml +3 -0
  90. data/app/views/effective/orders/refund/_form.html.haml +32 -0
  91. data/app/views/effective/orders/show.html.haml +4 -1
  92. data/app/views/effective/orders/stripe/_form.html.haml +5 -5
  93. data/app/views/effective/orders_mailer/subscription_canceled.html.haml +9 -0
  94. data/app/views/effective/orders_mailer/subscription_payment_failed.html.haml +9 -0
  95. data/app/views/effective/orders_mailer/subscription_payment_succeeded.html.haml +9 -0
  96. data/app/views/effective/orders_mailer/subscription_trial_expired.html.haml +5 -0
  97. data/app/views/effective/orders_mailer/subscription_trial_expiring.html.haml +7 -0
  98. data/app/views/effective/subscriptions/_fields.html.haml +16 -0
  99. data/app/views/effective/subscriptions/_plan.html.haml +21 -0
  100. data/app/views/layouts/effective_orders_mailer_layout.html.haml +6 -8
  101. data/config/effective_orders.rb +41 -20
  102. data/config/routes.rb +48 -48
  103. data/db/migrate/01_create_effective_orders.rb.erb +19 -5
  104. data/lib/effective_orders.rb +78 -42
  105. data/lib/effective_orders/engine.rb +36 -82
  106. data/lib/effective_orders/version.rb +1 -1
  107. data/lib/generators/effective_orders/install_generator.rb +2 -2
  108. data/lib/generators/templates/effective_orders_mailer_preview.rb +39 -4
  109. data/lib/tasks/effective_orders_tasks.rake +42 -0
  110. data/spec/controllers/carts_controller_spec.rb +1 -1
  111. data/spec/controllers/moneris_orders_controller_spec.rb +4 -4
  112. data/spec/controllers/orders_controller_spec.rb +4 -4
  113. data/spec/controllers/stripe_orders_controller_spec.rb +2 -2
  114. data/spec/controllers/webhooks_controller_spec.rb +1 -1
  115. data/spec/dummy/config/initializers/effective_orders.rb +1 -7
  116. data/spec/dummy/db/schema.rb +1 -0
  117. data/spec/dummy/db/test.sqlite3 +0 -0
  118. data/spec/dummy/log/test.log +3 -0
  119. data/spec/models/acts_as_purchasable_spec.rb +0 -56
  120. data/spec/models/customer_spec.rb +3 -3
  121. data/spec/models/order_spec.rb +2 -2
  122. data/spec/spec_helper.rb +1 -1
  123. data/spec/support/factories.rb +2 -1
  124. metadata +37 -49
  125. data/active_admin/effective_carts.rb +0 -14
  126. data/active_admin/effective_orders.rb +0 -112
  127. data/app/assets/javascripts/effective_orders/providers/stripe_subscriptions.js.coffee +0 -28
  128. data/app/controllers/concerns/acts_as_active_admin_controller.rb +0 -69
  129. data/app/controllers/effective/subscriptions_controller.rb +0 -126
  130. data/app/models/effective/datatables/customers.rb +0 -40
  131. data/app/models/effective/datatables/order_items.rb +0 -101
  132. data/app/models/effective/datatables/orders.rb +0 -91
  133. data/app/models/inputs/price_field.rb +0 -63
  134. data/app/models/inputs/price_form_input.rb +0 -7
  135. data/app/models/inputs/price_formtastic_input.rb +0 -9
  136. data/app/models/inputs/price_input.rb +0 -19
  137. data/app/models/inputs/price_simple_form_input.rb +0 -8
  138. data/app/views/admin/orders/_form_mark_as_paid.html.haml +0 -33
  139. data/app/views/admin/orders/_order_payment_details.html.haml +0 -5
  140. data/app/views/admin/orders/mark_as_paid.html.haml +0 -7
  141. data/app/views/effective/orders/stripe/_subscription_fields.html.haml +0 -7
  142. data/app/views/effective/subscriptions/index.html.haml +0 -22
  143. data/app/views/effective/subscriptions/new.html.haml +0 -9
  144. data/app/views/effective/subscriptions/show.html.haml +0 -49
  145. data/db/upgrade/02_upgrade_effective_orders_from03x.rb.erb +0 -29
  146. data/db/upgrade/03_upgrade_effective_orders_from1x.rb.erb +0 -98
  147. data/db/upgrade/upgrade_price_column_on_table.rb.erb +0 -17
  148. data/lib/generators/effective_orders/upgrade_from03x_generator.rb +0 -31
  149. data/lib/generators/effective_orders/upgrade_from1x_generator.rb +0 -27
  150. 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
- %thead{style: 'width: 100%;'}
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
@@ -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: {class: 'form-horizontal'},
141
- # wrapper: :horizontal_form,
142
- # wrapper_mappings: {
143
- # boolean: :horizontal_boolean,
144
- # check_boxes: :horizontal_radio_and_checkboxes,
145
- # radio_buttons: :horizontal_radio_and_checkboxes
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
- send_order_receipts_when_mark_as_paid_by_admin: false,
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.stripe_subscriptions_enabled = false # https://stripe.com/docs/subscriptions
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
- match 'orders/(:id)/purchased', to: 'orders#purchased', as: 'order_purchased', via: :get
11
- match 'orders/:id/declined', to: 'orders#declined', as: 'order_declined', via: :get
12
- match 'orders/:id/resend_buyer_receipt', to: 'orders#resend_buyer_receipt', via: :get, as: 'resend_buyer_receipt'
13
- match 'orders/my_purchases', to: 'orders#my_purchases', as: 'my_purchases', via: :get
14
-
15
- if EffectiveOrders.cheque_enabled
16
- match 'orders/:id/pay_by_cheque', to: 'orders#pay_by_cheque', via: :post, as: 'pay_by_cheque'
17
- end
18
-
19
- if EffectiveOrders.paypal_enabled
20
- match 'orders/paypal_postback', to: 'orders#paypal_postback', as: 'paypal_postback', via: :post
21
- end
22
-
23
- if EffectiveOrders.moneris_enabled
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
- if EffectiveOrders.stripe_subscriptions_enabled
32
- resources :subscriptions, only: [:index, :show, :new, :create, :destroy]
33
- end
25
+ collection do
26
+ get :my_purchases
27
+ post :bulk_send_buyer_receipt
34
28
 
35
- if EffectiveOrders.stripe_connect_enabled
36
- match 'orders/stripe_connect_redirect_uri', to: 'orders#stripe_connect_redirect_uri', as: 'stripe_connect_redirect_uri', via: :get
37
- match 'orders/my_sales', to: 'orders#my_sales', as: 'my_sales', via: :get
38
- end
29
+ if EffectiveOrders.stripe_connect_enabled
30
+ get :stripe_connect_redirect_uri # oAuth2
31
+ get :my_sales
32
+ end
39
33
 
40
- if EffectiveOrders.ccbill_enabled
41
- match 'orders/ccbill_postback', to: 'orders#ccbill_postback', as: 'ccbill_postback', via: :post
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
- if EffectiveOrders.app_checkout_enabled
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 (Rails.env.development? || Rails.env.test?) || EffectiveOrders.allow_pretend_purchase_in_production
49
- match 'orders/:id/pretend_purchase', to: 'orders#pretend_purchase', as: 'pretend_purchase', via: [:get, :post]
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
- if !EffectiveOrders.use_active_admin? || Rails.env.test?
65
- namespace :admin do
66
- resources :customers, only: [:index]
67
- resources :orders, except: [:edit] do
68
- member do
69
- get :mark_as_paid
70
- post :mark_as_paid
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
- resources :order_items, only: [:index]
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 :stripe_active_card
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 :stripe_subscription_id
84
- t.string :stripe_coupon_id
85
- t.string :title
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 %>, :stripe_subscription_id
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
@@ -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 :show_order_history_button
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 :paypal_enabled
62
+ mattr_accessor :mark_as_paid_enabled
63
63
  mattr_accessor :moneris_enabled
64
- mattr_accessor :ccbill_enabled
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 :ccbill
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 authorization_method.respond_to?(:call) || authorization_method.kind_of?(Symbol)
101
- raise Effective::AccessDenied.new() unless (controller || self).instance_exec(controller, action, resource, &authorization_method)
102
- end
103
- true
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
- def self.minimum_charge
107
- if @@minimum_charge.nil? || @@minimum_charge.kind_of?(Integer)
108
- @@minimum_charge
109
- else
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.use_active_admin?
116
- use_active_admin && defined?(ActiveAdmin)
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, :save_billing_address, :save_shipping_address, :terms_and_conditions,
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
- order_items_attributes: [:stripe_coupon_id, :class, :id]
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.tax_rate_method=(*args)
160
- raise 'EffectiveOrders.tax_rate_method has been removed and renamed to EffectiveOrders.order_tax_rate_method. Its expected value is now different too. Return 5.25 for 5.25% tax. Please refer to the readme for more info.'
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