effective_orders 2.2.4 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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