effective_orders 4.6.3 → 5.0.4

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +14 -86
  4. data/app/controllers/admin/customers_controller.rb +5 -16
  5. data/app/controllers/admin/order_items_controller.rb +6 -9
  6. data/app/controllers/admin/orders_controller.rb +18 -82
  7. data/app/controllers/effective/carts_controller.rb +10 -6
  8. data/app/controllers/effective/concerns/purchase.rb +12 -19
  9. data/app/controllers/effective/customers_controller.rb +4 -2
  10. data/app/controllers/effective/orders_controller.rb +26 -23
  11. data/app/controllers/effective/providers/cheque.rb +3 -1
  12. data/app/controllers/effective/providers/free.rb +3 -2
  13. data/app/controllers/effective/providers/mark_as_paid.rb +5 -4
  14. data/app/controllers/effective/providers/moneris.rb +3 -1
  15. data/app/controllers/effective/providers/paypal.rb +3 -2
  16. data/app/controllers/effective/providers/phone.rb +3 -1
  17. data/app/controllers/effective/providers/pretend.rb +4 -3
  18. data/app/controllers/effective/providers/refund.rb +4 -3
  19. data/app/controllers/effective/providers/stripe.rb +4 -3
  20. data/app/controllers/effective/subscripter_controller.rb +4 -2
  21. data/app/controllers/effective/webhooks_controller.rb +12 -3
  22. data/app/datatables/admin/effective_customers_datatable.rb +7 -3
  23. data/app/datatables/admin/effective_orders_datatable.rb +4 -7
  24. data/app/datatables/effective_orders_datatable.rb +3 -7
  25. data/app/helpers/effective_orders_helper.rb +1 -7
  26. data/app/mailers/effective/orders_mailer.rb +131 -96
  27. data/app/models/concerns/acts_as_purchasable.rb +0 -11
  28. data/app/models/concerns/acts_as_subscribable.rb +0 -6
  29. data/app/models/effective/cart.rb +7 -5
  30. data/app/models/effective/cart_item.rb +7 -4
  31. data/app/models/effective/customer.rb +7 -6
  32. data/app/models/effective/order.rb +58 -61
  33. data/app/models/effective/order_item.rb +20 -8
  34. data/app/models/effective/product.rb +11 -6
  35. data/app/models/effective/subscription.rb +13 -12
  36. data/app/views/admin/orders/_form.html.haml +5 -9
  37. data/app/views/admin/orders/_order_item_fields.html.haml +8 -12
  38. data/app/views/effective/orders/_checkout_step2.html.haml +1 -2
  39. data/app/views/effective/orders/_order_actions.html.haml +2 -2
  40. data/app/views/effective/orders/show.html.haml +4 -0
  41. data/config/effective_orders.rb +8 -32
  42. data/config/routes.rb +16 -17
  43. data/db/migrate/01_create_effective_orders.rb.erb +4 -0
  44. data/lib/effective_orders.rb +34 -76
  45. data/lib/effective_orders/engine.rb +0 -7
  46. data/lib/effective_orders/version.rb +1 -1
  47. data/lib/generators/templates/effective_orders_mailer_preview.rb +13 -13
  48. data/lib/tasks/effective_orders_tasks.rake +2 -2
  49. metadata +2 -3
  50. data/app/models/effective/access_denied.rb +0 -17
@@ -107,13 +107,7 @@ module EffectiveOrdersHelper
107
107
  end
108
108
  end
109
109
 
110
- def render_orders(obj, opts = {})
111
- orders = Array(obj.kind_of?(User) ? Effective::Order.purchased_by(obj) : obj)
112
-
113
- if orders.any? { |order| order.kind_of?(Effective::Order) == false }
114
- raise 'expected a User or Effective::Order'
115
- end
116
-
110
+ def render_orders(orders, opts = {})
117
111
  render(partial: 'effective/orders/orders_table', locals: { orders: orders }.merge(opts))
118
112
  end
119
113
 
@@ -1,183 +1,218 @@
1
1
  module Effective
2
2
  class OrdersMailer < ActionMailer::Base
3
- default from: EffectiveOrders.mailer[:default_from]
3
+ default from: -> { EffectiveOrders.mailer[:default_from] }
4
+ layout -> { EffectiveOrders.mailer[:layout].presence || 'effective_orders_mailer_layout' }
4
5
 
5
6
  helper EffectiveOrdersHelper
6
- layout EffectiveOrders.mailer[:layout].presence || 'effective_orders_mailer_layout'
7
7
 
8
- def order_receipt_to_admin(order_param)
9
- return true unless EffectiveOrders.mailer[:send_order_receipt_to_admin]
8
+ def order_receipt_to_admin(order_param, atts = {})
9
+ around_mail_action(:order_receipt_to_admin, order_param, atts) do
10
+ return true unless EffectiveOrders.mailer[:send_order_receipt_to_admin]
10
11
 
11
- @order = (order_param.kind_of?(Effective::Order) ? order_param : Effective::Order.find(order_param))
12
- @user = @order.user
12
+ @order = (order_param.kind_of?(Effective::Order) ? order_param : Effective::Order.find(order_param))
13
+ @user = @order.user
13
14
 
14
- @subject = subject_for(@order, :order_receipt_to_admin, "Order Receipt: ##{@order.to_param}")
15
+ @subject = subject_for(@order, :order_receipt_to_admin, "Order Receipt: ##{@order.to_param}")
15
16
 
16
- mail(to: EffectiveOrders.mailer[:admin_email], from: EffectiveOrders.mailer[:default_from], subject: @subject)
17
+ mail(to: EffectiveOrders.mailer[:admin_email], subject: @subject)
18
+ end
17
19
  end
18
20
 
19
- def order_receipt_to_buyer(order_param) # Buyer
20
- return true unless EffectiveOrders.mailer[:send_order_receipt_to_buyer]
21
+ def order_receipt_to_buyer(order_param, atts = {}) # Buyer
22
+ around_mail_action(:order_receipt_to_buyer, order_param, atts) do
23
+ return true unless EffectiveOrders.mailer[:send_order_receipt_to_buyer]
21
24
 
22
- @order = (order_param.kind_of?(Effective::Order) ? order_param : Effective::Order.find(order_param))
23
- @user = @order.user
25
+ @order = (order_param.kind_of?(Effective::Order) ? order_param : Effective::Order.find(order_param))
26
+ @user = @order.user
24
27
 
25
- @subject = subject_for(@order, :order_receipt_to_buyer, "Order Receipt: ##{@order.to_param}")
28
+ @subject = subject_for(@order, :order_receipt_to_buyer, "Order Receipt: ##{@order.to_param}")
26
29
 
27
- mail(to: @order.email, cc: @order.cc, subject: @subject)
30
+ mail(to: @order.email, cc: @order.cc, subject: @subject)
31
+ end
28
32
  end
29
33
 
30
34
  # This is sent when an admin creates a new order or /admin/orders/new
31
35
  # Or when Pay by Cheque or Pay by Phone (deferred payments)
32
36
  # Or uses the order action Send Payment Request
33
- def payment_request_to_buyer(order_param)
34
- return true unless EffectiveOrders.mailer[:send_payment_request_to_buyer]
37
+ def payment_request_to_buyer(order_param, atts = {})
38
+ around_mail_action(:payment_request_to_buyer, order_param, atts) do
39
+ return true unless EffectiveOrders.mailer[:send_payment_request_to_buyer]
35
40
 
36
- @order = (order_param.kind_of?(Effective::Order) ? order_param : Effective::Order.find(order_param))
37
- @user = @order.user
41
+ @order = (order_param.kind_of?(Effective::Order) ? order_param : Effective::Order.find(order_param))
42
+ @user = @order.user
38
43
 
39
- @subject = subject_for(@order, :payment_request_to_buyer, "Request for Payment: Invoice ##{@order.to_param}")
44
+ @subject = subject_for(@order, :payment_request_to_buyer, "Request for Payment: Invoice ##{@order.to_param}")
40
45
 
41
- mail(to: @order.email, cc: @order.cc, subject: @subject)
46
+ mail(to: @order.email, cc: @order.cc, subject: @subject)
47
+ end
42
48
  end
43
49
 
50
+
44
51
  # This is sent when someone chooses to Pay by Cheque
45
- def pending_order_invoice_to_buyer(order_param)
46
- return true unless EffectiveOrders.mailer[:send_pending_order_invoice_to_buyer]
52
+ def pending_order_invoice_to_buyer(order_param, atts = {})
53
+ around_mail_action(:pending_order_invoice_to_buyer, order_param, atts) do
54
+ return true unless EffectiveOrders.mailer[:send_pending_order_invoice_to_buyer]
47
55
 
48
- @order = (order_param.kind_of?(Effective::Order) ? order_param : Effective::Order.find(order_param))
49
- @user = @order.user
56
+ @order = (order_param.kind_of?(Effective::Order) ? order_param : Effective::Order.find(order_param))
57
+ @user = @order.user
50
58
 
51
- @subject = subject_for(@order, :pending_order_invoice_to_buyer, "Pending Order: ##{@order.to_param}")
59
+ @subject = subject_for(@order, :pending_order_invoice_to_buyer, "Pending Order: ##{@order.to_param}")
52
60
 
53
- mail(to: @order.email, cc: @order.cc, subject: @subject)
61
+ mail(to: @order.email, cc: @order.cc, subject: @subject)
62
+ end
54
63
  end
55
64
 
56
65
  # This is sent to admin when someone Accepts Refund
57
- def refund_notification_to_admin(order_param)
58
- @order = (order_param.kind_of?(Effective::Order) ? order_param : Effective::Order.find(order_param))
59
- @user = @order.user
66
+ def refund_notification_to_admin(order_param, atts = {})
67
+ around_mail_action(:refund_notification_to_admin, order_param, atts) do
68
+ @order = (order_param.kind_of?(Effective::Order) ? order_param : Effective::Order.find(order_param))
69
+ @user = @order.user
60
70
 
61
- @subject = subject_for(@order, :refund_notification_to_admin, "New Refund: ##{@order.to_param}")
71
+ @subject = subject_for(@order, :refund_notification_to_admin, "New Refund: ##{@order.to_param}")
62
72
 
63
- mail(to: EffectiveOrders.mailer[:admin_email], subject: @subject)
73
+ mail(to: EffectiveOrders.mailer[:admin_email], subject: @subject)
74
+ end
64
75
  end
65
76
 
66
77
  # Sent by the invoice.payment_succeeded webhook event
67
- def subscription_payment_succeeded(customer_param)
68
- return true unless EffectiveOrders.mailer[:send_subscription_payment_succeeded]
78
+ def subscription_payment_succeeded(customer_param, atts = {})
79
+ around_mail_action(:subscription_payment_succeeded, customer_param, atts) do
80
+ return true unless EffectiveOrders.mailer[:send_subscription_payment_succeeded]
69
81
 
70
- @customer = (customer_param.kind_of?(Effective::Customer) ? customer_param : Effective::Customer.find(customer_param))
71
- @subscriptions = @customer.subscriptions
72
- @user = @customer.user
82
+ @customer = (customer_param.kind_of?(Effective::Customer) ? customer_param : Effective::Customer.find(customer_param))
83
+ @subscriptions = @customer.subscriptions
84
+ @user = @customer.user
73
85
 
74
- @subject = subject_for(@customer, :subscription_payment_succeeded, 'Thank you for your payment')
86
+ @subject = subject_for(@customer, :subscription_payment_succeeded, 'Thank you for your payment')
75
87
 
76
- mail(to: @customer.user.email, subject: @subject)
88
+ mail(to: @customer.user.email, subject: @subject)
89
+ end
77
90
  end
78
91
 
79
92
  # Sent by the invoice.payment_failed webhook event
80
- def subscription_payment_failed(customer_param)
81
- return true unless EffectiveOrders.mailer[:send_subscription_payment_failed]
93
+ def subscription_payment_failed(customer_param, atts = {})
94
+ around_mail_action(:subscription_payment_failed, customer_param, atts) do
95
+ return true unless EffectiveOrders.mailer[:send_subscription_payment_failed]
82
96
 
83
- @customer = (customer_param.kind_of?(Effective::Customer) ? customer_param : Effective::Customer.find(customer_param))
84
- @subscriptions = @customer.subscriptions
85
- @user = @customer.user
97
+ @customer = (customer_param.kind_of?(Effective::Customer) ? customer_param : Effective::Customer.find(customer_param))
98
+ @subscriptions = @customer.subscriptions
99
+ @user = @customer.user
86
100
 
87
- @subject = subject_for(@customer, :subscription_payment_failed, 'Payment failed - please update your card details')
101
+ @subject = subject_for(@customer, :subscription_payment_failed, 'Payment failed - please update your card details')
88
102
 
89
- mail(to: @customer.user.email, subject: @subject)
103
+ mail(to: @customer.user.email, subject: @subject)
104
+ end
90
105
  end
91
106
 
92
107
  # Sent by the customer.subscription.created webhook event
93
- def subscription_created(customer_param)
94
- return true unless EffectiveOrders.mailer[:send_subscription_created]
108
+ def subscription_created(customer_param, atts = {})
109
+ around_mail_action(:subscription_created, customer_param, atts) do
110
+ return true unless EffectiveOrders.mailer[:send_subscription_created]
95
111
 
96
- @customer = (customer_param.kind_of?(Effective::Customer) ? customer_param : Effective::Customer.find(customer_param))
97
- @subscriptions = @customer.subscriptions
98
- @user = @customer.user
112
+ @customer = (customer_param.kind_of?(Effective::Customer) ? customer_param : Effective::Customer.find(customer_param))
113
+ @subscriptions = @customer.subscriptions
114
+ @user = @customer.user
99
115
 
100
- @subject = subject_for(@customer, :subscription_created, 'New Subscription')
116
+ @subject = subject_for(@customer, :subscription_created, 'New Subscription')
101
117
 
102
- mail(to: @customer.user.email, subject: @subject)
118
+ mail(to: @customer.user.email, subject: @subject)
119
+ end
103
120
  end
104
121
 
105
122
  # Sent by the customer.subscription.updated webhook event
106
- def subscription_updated(customer_param)
107
- return true unless EffectiveOrders.mailer[:send_subscription_updated]
123
+ def subscription_updated(customer_param, atts = {})
124
+ around_mail_action(:subscription_updated, customer_param, atts) do
125
+ return true unless EffectiveOrders.mailer[:send_subscription_updated]
108
126
 
109
- @customer = (customer_param.kind_of?(Effective::Customer) ? customer_param : Effective::Customer.find(customer_param))
110
- @subscriptions = @customer.subscriptions
111
- @user = @customer.user
127
+ @customer = (customer_param.kind_of?(Effective::Customer) ? customer_param : Effective::Customer.find(customer_param))
128
+ @subscriptions = @customer.subscriptions
129
+ @user = @customer.user
112
130
 
113
- @subject = subject_for(@customer, :subscription_updated, 'Subscription Changed')
131
+ @subject = subject_for(@customer, :subscription_updated, 'Subscription Changed')
114
132
 
115
- mail(to: @customer.user.email, subject: @subject)
133
+ mail(to: @customer.user.email, subject: @subject)
134
+ end
116
135
  end
117
136
 
118
137
  # Sent by the invoice.payment_failed webhook event
119
- def subscription_canceled(customer_param)
120
- return true unless EffectiveOrders.mailer[:send_subscription_canceled]
138
+ def subscription_canceled(customer_param, atts = {})
139
+ around_mail_action(:subscription_canceled, customer_param, atts) do
140
+ return true unless EffectiveOrders.mailer[:send_subscription_canceled]
121
141
 
122
- @customer = (customer_param.kind_of?(Effective::Customer) ? customer_param : Effective::Customer.find(customer_param))
123
- @subscriptions = @customer.subscriptions
124
- @user = @customer.user
142
+ @customer = (customer_param.kind_of?(Effective::Customer) ? customer_param : Effective::Customer.find(customer_param))
143
+ @subscriptions = @customer.subscriptions
144
+ @user = @customer.user
125
145
 
126
- @subject = subject_for(@customer, :subscription_canceled, 'Subscription canceled')
146
+ @subject = subject_for(@customer, :subscription_canceled, 'Subscription canceled')
127
147
 
128
- mail(to: @customer.user.email, subject: @subject)
148
+ mail(to: @customer.user.email, subject: @subject)
149
+ end
129
150
  end
130
151
 
131
152
  # Sent by the effective_orders:notify_trial_users rake task.
132
- def subscription_trialing(subscribable)
133
- return true unless EffectiveOrders.mailer[:send_subscription_trialing]
153
+ def subscription_trialing(subscribable, atts = {})
154
+ around_mail_action(:subscription_trialing, subscribable, atts) do
155
+ return true unless EffectiveOrders.mailer[:send_subscription_trialing]
134
156
 
135
- @subscribable = subscribable
136
- @user = @subscribable.subscribable_buyer
157
+ @subscribable = subscribable
158
+ @user = @subscribable.subscribable_buyer
137
159
 
138
- @subject = subject_for(@customer, :subscription_trialing, 'Trial is active')
160
+ @subject = subject_for(@customer, :subscription_trialing, 'Trial is active')
139
161
 
140
- mail(to: @subscribable.subscribable_buyer.email, subject: @subject)
162
+ mail(to: @subscribable.subscribable_buyer.email, subject: @subject)
163
+ end
141
164
  end
142
165
 
143
166
  # Sent by the effective_orders:notify_trial_users rake task.
144
- def subscription_trial_expired(subscribable)
145
- return true unless EffectiveOrders.mailer[:send_subscription_trial_expired]
167
+ def subscription_trial_expired(subscribable, atts = {})
168
+ around_mail_action(:subscription_trial_expired, subscribable, atts) do
169
+ return true unless EffectiveOrders.mailer[:send_subscription_trial_expired]
146
170
 
147
- @subscribable = subscribable
148
- @user = @subscribable.subscribable_buyer
171
+ @subscribable = subscribable
172
+ @user = @subscribable.subscribable_buyer
149
173
 
150
- @subject = subject_for(@customer, :subscription_trial_expired, 'Trial expired')
174
+ @subject = subject_for(@customer, :subscription_trial_expired, 'Trial expired')
151
175
 
152
- mail(to: @subscribable.subscribable_buyer.email, subject: @subject)
176
+ mail(to: @subscribable.subscribable_buyer.email, subject: @subject)
177
+ end
153
178
  end
154
179
 
155
- def subscription_event_to_admin(event, customer_param)
156
- return true unless EffectiveOrders.mailer[:send_subscription_event_to_admin]
180
+ def subscription_event_to_admin(event, customer_param, atts = {})
181
+ around_mail_action(:subscription_event_to_admin, event, atts) do
182
+ return true unless EffectiveOrders.mailer[:send_subscription_event_to_admin]
157
183
 
158
- @customer = (customer_param.kind_of?(Effective::Customer) ? customer_param : Effective::Customer.find(customer_param))
159
- @subscriptions = @customer.subscriptions
160
- @user = @customer.user
161
- @event = event.to_s
184
+ @customer = (customer_param.kind_of?(Effective::Customer) ? customer_param : Effective::Customer.find(customer_param))
185
+ @subscriptions = @customer.subscriptions
186
+ @user = @customer.user
187
+ @event = event.to_s
162
188
 
163
- @subject = subject_for(@customer, :subscription_event_to_admin, "Subscription event - @event - @customer").gsub('@event', @event.to_s).gsub('@customer', @customer.to_s)
189
+ @subject = subject_for(@customer, :subscription_event_to_admin, "Subscription event - @event - @customer").gsub('@event', @event.to_s).gsub('@customer', @customer.to_s)
164
190
 
165
- mail(to: EffectiveOrders.mailer[:admin_email], subject: @subject)
191
+ mail(to: EffectiveOrders.mailer[:admin_email], subject: @subject)
192
+ end
166
193
  end
167
194
 
168
195
  def order_error(order: nil, error: nil, to: nil, from: nil, subject: nil, template: 'order_error')
169
- @order = (order.kind_of?(Effective::Order) ? order : Effective::Order.find(order))
170
- @error = error.to_s
196
+ around_mail_action(:order_error, order, {error: error, to: to, from: from, subject: subject, template: template}) do
197
+ @order = (order.kind_of?(Effective::Order) ? order : Effective::Order.find(order))
198
+ @error = error.to_s
199
+
200
+ @subject = subject_for(@order, :error, "An error occurred with order: ##{@order.try(:to_param)}")
201
+
202
+ mail(
203
+ to: (to || EffectiveOrders.mailer[:admin_email]),
204
+ from: (from || EffectiveOrders.mailer[:default_from]),
205
+ subject: (subject || @subject)
206
+ ) do |format|
207
+ format.html { render(template) }
208
+ end
209
+ end
210
+ end
171
211
 
172
- @subject = subject_for(@order, :error, "An error occurred with order: ##{@order.try(:to_param)}")
212
+ protected
173
213
 
174
- mail(
175
- to: (to || EffectiveOrders.mailer[:admin_email]),
176
- from: (from || EffectiveOrders.mailer[:default_from]),
177
- subject: (subject || @subject)
178
- ) do |format|
179
- format.html { render(template) }
180
- end
214
+ def around_mail_action(name, param, atts = {}, &block)
215
+ yield
181
216
  end
182
217
 
183
218
  private
@@ -4,17 +4,6 @@ module ActsAsPurchasable
4
4
  module Base
5
5
  def acts_as_purchasable(*options)
6
6
  @acts_as_purchasable = options || []
7
-
8
- # if table_exists?
9
- # instance = new()
10
- # raise 'must respond_to price' unless instance.respond_to?(:price)
11
- # raise 'must respond_to purchased_order_id' unless instance.respond_to?(:purchased_order_id)
12
-
13
- # if defined?(EffectiveQbSync)
14
- # raise 'must respond to qb_item_name' unless instance.respond_to?(:qb_item_name)
15
- # end
16
- # end
17
-
18
7
  include ::ActsAsPurchasable
19
8
  end
20
9
  end
@@ -7,12 +7,6 @@ module ActsAsSubscribable
7
7
  def acts_as_subscribable(*options)
8
8
  @acts_as_subscribable = options || []
9
9
 
10
- # if table_exists?
11
- # instance = new()
12
- # raise 'must respond to trialing_until' unless instance.respond_to?(:trialing_until) || !EffectiveOrders.trial?
13
- # raise 'must respond to subscription_status' unless instance.respond_to?(:subscription_status)
14
- # end
15
-
16
10
  include ::ActsAsSubscribable
17
11
  (ActsAsSubscribable.descendants ||= []) << self
18
12
  end
@@ -2,14 +2,16 @@ module Effective
2
2
  class Cart < ActiveRecord::Base
3
3
  self.table_name = EffectiveOrders.carts_table_name.to_s
4
4
 
5
- belongs_to :user, optional: true # Optional. We want non-logged-in users to have carts too.
6
- has_many :cart_items, -> { order(:id) }, dependent: :delete_all, class_name: 'Effective::CartItem'
5
+ belongs_to :user, polymorphic: true, optional: true # Optional. We want non-logged-in users to have carts too.
7
6
 
7
+ has_many :cart_items, -> { order(:id) }, inverse_of: :cart, dependent: :delete_all
8
8
  accepts_nested_attributes_for :cart_items
9
9
 
10
- # Attributes
11
- # cart_items_count :integer
12
- # timestamps
10
+ effective_resource do
11
+ cart_items_count :integer
12
+
13
+ timestamps
14
+ end
13
15
 
14
16
  scope :deep, -> { includes(cart_items: :purchasable) }
15
17
 
@@ -2,12 +2,15 @@ module Effective
2
2
  class CartItem < ActiveRecord::Base
3
3
  self.table_name = EffectiveOrders.cart_items_table_name.to_s
4
4
 
5
- belongs_to :cart, counter_cache: true, class_name: 'Effective::Cart'
5
+ belongs_to :cart, counter_cache: true
6
6
  belongs_to :purchasable, polymorphic: true
7
7
 
8
- # Attributes
9
- # quantity :integer
10
- # timestamps
8
+ effective_resource do
9
+ unique :string
10
+ quantity :integer
11
+
12
+ timestamps
13
+ end
11
14
 
12
15
  validates :purchasable, presence: true
13
16
  validates :quantity, presence: true
@@ -4,16 +4,17 @@ module Effective
4
4
 
5
5
  attr_accessor :stripe_customer
6
6
 
7
- belongs_to :user
7
+ belongs_to :user, polymorphic: true
8
8
  has_many :subscriptions, -> { includes(:subscribable) }, class_name: 'Effective::Subscription', foreign_key: 'customer_id'
9
9
  accepts_nested_attributes_for :subscriptions
10
10
 
11
- # Attributes
12
- # stripe_customer_id :string # cus_xja7acoa03
13
- # payment_method_id :string # Last payment method used
14
- # active_card :string # **** **** **** 4242 Visa 05/12
11
+ effective_resource do
12
+ stripe_customer_id :string # cus_xja7acoa03
13
+ payment_method_id :string # Last payment method used
14
+ active_card :string # **** **** **** 4242 Visa 05/12
15
15
 
16
- # timestamps
16
+ timestamps
17
+ end
17
18
 
18
19
  scope :deep, -> { includes(subscriptions: :subscribable) }
19
20
 
@@ -31,35 +31,37 @@ module Effective
31
31
  # If we want to use orders in a has_many way
32
32
  belongs_to :parent, polymorphic: true, optional: true
33
33
 
34
- belongs_to :user, validate: false # This is the buyer/user of the order. We validate it below.
35
- has_many :order_items, -> { order(:id) }, inverse_of: :order, class_name: 'Effective::OrderItem', dependent: :delete_all
34
+ belongs_to :user, polymorphic: true, validate: false # This is the buyer/user of the order. We validate it below.
35
+ has_many :order_items, -> { order(:id) }, inverse_of: :order, dependent: :delete_all
36
36
 
37
37
  accepts_nested_attributes_for :order_items, allow_destroy: false, reject_if: :all_blank
38
38
  accepts_nested_attributes_for :user, allow_destroy: false, update_only: true
39
39
 
40
40
  # Attributes
41
- # state :string
42
- # purchased_at :datetime
43
- #
44
- # note :text # From buyer to admin
45
- # note_to_buyer :text # From admin to buyer
46
- # note_internal :text # Internal admin only
47
- #
48
- # billing_name :string # name of buyer
49
- # email :string # same as user.email
50
- # cc :string # can be set by admin
51
- #
52
- # payment :text # serialized hash containing all the payment details.
53
- # payment_provider :string
54
- # payment_card :string
55
- #
56
- # tax_rate :decimal, precision: 6, scale: 3
57
- #
58
- # subtotal :integer
59
- # tax :integer
60
- # total :integer
61
- #
62
- # timestamps
41
+ effective_resource do
42
+ state :string
43
+ purchased_at :datetime
44
+
45
+ note :text # From buyer to admin
46
+ note_to_buyer :text # From admin to buyer
47
+ note_internal :text # Internal admin only
48
+
49
+ billing_name :string # name of buyer
50
+ email :string # same as user.email
51
+ cc :string # can be set by admin
52
+
53
+ payment :text # serialized hash containing all the payment details.
54
+ payment_provider :string
55
+ payment_card :string
56
+
57
+ tax_rate :decimal, precision: 6, scale: 3
58
+
59
+ subtotal :integer
60
+ tax :integer
61
+ total :integer
62
+
63
+ timestamps
64
+ end
63
65
 
64
66
  serialize :payment, Hash
65
67
 
@@ -135,7 +137,7 @@ module Effective
135
137
  validates :payment_provider, presence: true, inclusion: { in: EffectiveOrders.deferred_providers }
136
138
  end
137
139
 
138
- scope :deep, -> { includes(:user, order_items: :purchasable) }
140
+ scope :deep, -> { includes(:addresses, :user, order_items: :purchasable) }
139
141
  scope :sorted, -> { order(:id) }
140
142
 
141
143
  scope :purchased, -> { where(state: EffectiveOrders::PURCHASED) }
@@ -314,15 +316,15 @@ module Effective
314
316
  end
315
317
 
316
318
  def send_payment_request_to_buyer?
317
- truthy?(send_payment_request_to_buyer) && !free? && !refund?
319
+ EffectiveResources.truthy?(send_payment_request_to_buyer) && !free? && !refund?
318
320
  end
319
321
 
320
322
  def send_mark_as_paid_email_to_buyer?
321
- truthy?(send_mark_as_paid_email_to_buyer)
323
+ EffectiveResources.truthy?(send_mark_as_paid_email_to_buyer)
322
324
  end
323
325
 
324
326
  def skip_buyer_validations?
325
- truthy?(skip_buyer_validations)
327
+ EffectiveResources.truthy?(skip_buyer_validations)
326
328
  end
327
329
 
328
330
  # This is called from admin/orders#create
@@ -360,38 +362,31 @@ module Effective
360
362
 
361
363
  # Effective::Order.new(items: Product.first, user: User.first).purchase!(email: false)
362
364
  def purchase!(payment: 'none', provider: 'none', card: 'none', email: true, skip_buyer_validations: false)
363
- return false if purchased?
364
- error = nil
365
-
366
- assign_attributes(
367
- state: EffectiveOrders::PURCHASED,
368
- payment: payment_to_h(payment),
369
- payment_provider: provider,
370
- payment_card: (card.presence || 'none'),
371
- skip_buyer_validations: skip_buyer_validations
372
- )
365
+ # Assign attributes
366
+ self.state = EffectiveOrders::PURCHASED
367
+ self.skip_buyer_validations = skip_buyer_validations
373
368
 
369
+ self.payment_provider ||= provider
370
+ self.payment_card ||= (card.presence || 'none')
374
371
  self.purchased_at ||= Time.zone.now
372
+ self.payment = payment_to_h(payment) if self.payment.blank?
375
373
 
376
- Effective::Order.transaction do
377
- begin
374
+ begin
375
+ Effective::Order.transaction do
378
376
  run_purchasable_callbacks(:before_purchase)
379
377
  save!
380
378
  update_purchasables_purchased_order!
381
- rescue => e
382
- self.state = state_was
383
- self.purchased_at = nil
384
-
385
- error = e.message
386
- raise ::ActiveRecord::Rollback
387
379
  end
388
- end
380
+ rescue => e
381
+ Effective::Order.transaction do
382
+ save!(validate: false)
383
+ update_purchasables_purchased_order!
384
+ end
389
385
 
390
- raise "Failed to purchase order: #{error || errors.full_messages.to_sentence}" unless error.nil?
386
+ raise(e)
387
+ end
391
388
 
392
389
  run_purchasable_callbacks(:after_purchase)
393
-
394
- send_refund_notification! if email && refund?
395
390
  send_order_receipts! if email
396
391
 
397
392
  true
@@ -454,6 +449,7 @@ module Effective
454
449
  def send_order_receipts!
455
450
  send_order_receipt_to_admin! if EffectiveOrders.mailer[:send_order_receipt_to_admin]
456
451
  send_order_receipt_to_buyer! if EffectiveOrders.mailer[:send_order_receipt_to_buyer]
452
+ send_refund_notification! if refund?
457
453
  end
458
454
 
459
455
  def send_order_receipt_to_admin!
@@ -477,7 +473,7 @@ module Effective
477
473
  end
478
474
 
479
475
  def skip_qb_sync!
480
- defined?(EffectiveQbSync) ? EffectiveQbSync.skip_order!(self) : true
476
+ EffectiveOrders.use_effective_qb_sync ? EffectiveQbSync.skip_order!(self) : true
481
477
  end
482
478
 
483
479
  protected
@@ -544,22 +540,23 @@ module Effective
544
540
  order_items.each { |oi| oi.purchasable.public_send(name, self, oi) if oi.purchasable.respond_to?(name) }
545
541
  end
546
542
 
547
- def send_email(email, *mailer_args)
543
+ def send_email(email, *args)
544
+ raise('expected args to be an Array') unless args.kind_of?(Array)
545
+
546
+ if defined?(Tenant)
547
+ tenant = Tenant.current || raise('expected a current tenant')
548
+ args << { tenant: tenant }
549
+ end
550
+
551
+ deliver_method = EffectiveOrders.mailer[:deliver_method] || EffectiveResources.deliver_method
552
+
548
553
  begin
549
- Effective::OrdersMailer.public_send(email, *mailer_args).public_send(EffectiveOrders.mailer[:deliver_method])
554
+ EffectiveOrders.mailer_klass.send(email, *args).send(deliver_method)
550
555
  rescue => e
551
556
  raise if Rails.env.development? || Rails.env.test?
552
557
  end
553
558
  end
554
559
 
555
- def truthy?(value)
556
- if defined?(::ActiveRecord::ConnectionAdapters::Column::TRUE_VALUES) # Rails <5
557
- ::ActiveRecord::ConnectionAdapters::Column::TRUE_VALUES.include?(value)
558
- else
559
- ::ActiveRecord::Type::Boolean.new.cast(value)
560
- end
561
- end
562
-
563
560
  def payment_to_h(payment)
564
561
  if payment.respond_to?(:to_unsafe_h)
565
562
  payment.to_unsafe_h.to_h