effective_orders 1.8.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +150 -60
- data/Rakefile +0 -3
- data/active_admin/effective_orders.rb +14 -9
- data/app/assets/javascripts/effective_orders.js +2 -0
- data/app/assets/javascripts/effective_orders/{stripe_charges.js.coffee → providers/stripe_charges.js.coffee} +1 -1
- data/app/assets/javascripts/effective_orders/{stripe_subscriptions.js.coffee → providers/stripe_subscriptions.js.coffee} +1 -1
- data/app/assets/stylesheets/effective_orders/_order.scss +9 -3
- data/app/controllers/admin/orders_controller.rb +87 -3
- data/app/controllers/concerns/acts_as_active_admin_controller.rb +2 -1
- data/app/controllers/effective/carts_controller.rb +4 -2
- data/app/controllers/effective/orders_controller.rb +101 -60
- data/app/controllers/effective/providers/app_checkout.rb +10 -2
- data/app/controllers/effective/providers/ccbill.rb +34 -0
- data/app/controllers/effective/providers/cheque.rb +30 -0
- data/app/controllers/effective/providers/moneris.rb +7 -7
- data/app/controllers/effective/providers/paypal.rb +7 -5
- data/app/controllers/effective/providers/pretend.rb +22 -0
- data/app/controllers/effective/providers/stripe.rb +26 -24
- data/app/controllers/effective/webhooks_controller.rb +1 -1
- data/app/helpers/effective_carts_helper.rb +59 -29
- data/app/helpers/effective_ccbill_helper.rb +25 -0
- data/app/helpers/effective_orders_helper.rb +50 -41
- data/app/helpers/effective_paypal_helper.rb +11 -11
- data/app/mailers/effective/orders_mailer.rb +95 -20
- data/app/models/concerns/acts_as_purchasable.rb +14 -22
- data/app/models/effective/cart.rb +9 -15
- data/app/models/effective/cart_item.rb +15 -13
- data/app/models/effective/customer.rb +9 -9
- data/app/models/effective/datatables/order_items.rb +14 -8
- data/app/models/effective/datatables/orders.rb +56 -69
- data/app/models/effective/order.rb +250 -139
- data/app/models/effective/order_item.rb +23 -16
- data/app/models/effective/product.rb +23 -0
- data/app/models/effective/providers/ccbill_postback.rb +85 -0
- data/app/models/effective/{stripe_charge.rb → providers/stripe_charge.rb} +1 -1
- data/app/models/effective/subscription.rb +16 -12
- data/app/models/effective/tax_rate_calculator.rb +45 -0
- data/app/views/admin/customers/index.html.haml +2 -5
- data/app/views/admin/order_items/index.html.haml +2 -5
- data/app/views/admin/orders/_actions.html.haml +2 -0
- data/app/views/admin/orders/_form.html.haml +28 -0
- data/app/views/admin/orders/_order_item_fields.html.haml +9 -0
- data/app/views/admin/orders/index.html.haml +9 -5
- data/app/views/admin/orders/new.html.haml +3 -0
- data/app/views/effective/carts/_cart.html.haml +3 -12
- data/app/views/effective/carts/_cart_actions.html.haml +4 -0
- data/app/views/effective/carts/show.html.haml +10 -12
- data/app/views/effective/orders/_checkout_step1.html.haml +46 -0
- data/app/views/effective/orders/_checkout_step2.html.haml +33 -0
- data/app/views/effective/orders/_order.html.haml +2 -0
- data/app/views/effective/orders/_order_actions.html.haml +10 -5
- data/app/views/effective/orders/_order_footer.html.haml +1 -0
- data/app/views/effective/orders/_order_items.html.haml +11 -9
- data/app/views/effective/orders/_order_note.html.haml +8 -0
- data/app/views/effective/orders/_order_note_fields.html.haml +5 -0
- data/app/views/effective/orders/_order_shipping.html.haml +4 -4
- data/app/views/effective/orders/_order_user_fields.html.haml +1 -0
- data/app/views/effective/orders/_orders_table.html.haml +27 -0
- data/app/views/effective/orders/ccbill/_form.html.haml +24 -0
- data/app/views/effective/orders/checkout_step1.html.haml +3 -0
- data/app/views/effective/orders/checkout_step2.html.haml +3 -0
- data/app/views/effective/orders/cheque/_form.html.haml +2 -0
- data/app/views/effective/orders/cheque/pay_by_cheque.html.haml +9 -0
- data/app/views/effective/orders/declined.html.haml +4 -2
- data/app/views/effective/orders/my_purchases.html.haml +1 -1
- data/app/views/effective/orders/my_sales.html.haml +1 -1
- data/app/views/effective/orders/purchased.html.haml +3 -2
- data/app/views/effective/orders/show.html.haml +1 -1
- data/app/views/effective/orders/stripe/_form.html.haml +5 -5
- data/app/views/effective/orders_mailer/order_error.html.haml +11 -0
- data/app/views/effective/orders_mailer/payment_request_to_buyer.html.haml +13 -0
- data/app/views/effective/orders_mailer/pending_order_invoice_to_buyer.html.haml +13 -0
- data/app/views/layouts/effective_orders_mailer_layout.html.haml +7 -7
- data/config/routes.rb +39 -24
- data/db/migrate/01_create_effective_orders.rb.erb +20 -1
- data/db/upgrade/03_upgrade_effective_orders_from1x.rb.erb +95 -0
- data/lib/effective_orders.rb +67 -9
- data/lib/effective_orders/app_checkout_service.rb +1 -2
- data/lib/effective_orders/engine.rb +46 -14
- data/lib/effective_orders/version.rb +1 -1
- data/lib/generators/effective_orders/install_generator.rb +1 -0
- data/lib/generators/effective_orders/upgrade_from03x_generator.rb +1 -0
- data/lib/generators/effective_orders/upgrade_from1x_generator.rb +31 -0
- data/lib/generators/templates/effective_orders.rb +131 -66
- data/lib/generators/templates/effective_orders_mailer_preview.rb +28 -13
- data/spec/controllers/admin/orders_controller_spec.rb +242 -0
- data/spec/controllers/ccbill_orders_controller_spec.rb +103 -0
- data/spec/controllers/moneris_orders_controller_spec.rb +23 -23
- data/spec/controllers/orders_controller_spec.rb +167 -79
- data/spec/controllers/stripe_orders_controller_spec.rb +7 -7
- data/spec/dummy/app/models/product.rb +0 -8
- data/spec/dummy/app/models/product_with_float_price.rb +0 -8
- data/spec/dummy/app/models/user.rb +2 -19
- data/spec/dummy/config/application.rb +2 -1
- data/spec/dummy/config/environments/test.rb +1 -0
- data/spec/dummy/config/initializers/effective_orders.rb +109 -64
- data/spec/dummy/db/schema.rb +15 -2
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/test.log +0 -258
- data/spec/models/acts_as_purchasable_spec.rb +8 -6
- data/spec/models/factories_spec.rb +7 -1
- data/spec/models/order_item_spec.rb +1 -1
- data/spec/models/order_spec.rb +165 -46
- data/spec/models/stripe_charge_spec.rb +5 -5
- data/spec/spec_helper.rb +2 -0
- data/spec/support/factories.rb +49 -33
- metadata +47 -64
- data/app/views/effective/orders/_checkout_step_1.html.haml +0 -43
- data/app/views/effective/orders/_checkout_step_2.html.haml +0 -25
- data/app/views/effective/orders/_my_purchases.html.haml +0 -17
- data/app/views/effective/orders/checkout.html.haml +0 -3
- data/app/views/effective/orders/new.html.haml +0 -4
- data/spec/dummy/log/development.log +0 -82
@@ -8,6 +8,8 @@ EffectiveOrders.setup do |config|
|
|
8
8
|
config.cart_items_table_name = :cart_items
|
9
9
|
config.customers_table_name = :customers
|
10
10
|
config.subscriptions_table_name = :subscriptions
|
11
|
+
config.products_table_name = :products
|
12
|
+
|
11
13
|
|
12
14
|
# Authorization Method
|
13
15
|
#
|
@@ -30,6 +32,12 @@ EffectiveOrders.setup do |config|
|
|
30
32
|
# config.authorization_method = false
|
31
33
|
config.authorization_method = Proc.new { |controller, action, resource| true }
|
32
34
|
|
35
|
+
# Skip automatically mounting the EffectiveOrders engine
|
36
|
+
config.skip_mount_engine = false
|
37
|
+
|
38
|
+
# Filter the @orders on admin/orders#index screen
|
39
|
+
# config.orders_collection_scope = Proc.new { |scope| scope.where(...) }
|
40
|
+
|
33
41
|
# Register Effective::Order with ActiveAdmin if ActiveAdmin is present
|
34
42
|
# You must have authorization to authorized?(:manage, Effective::Order)
|
35
43
|
# For the activeadmin menu to item to show up
|
@@ -50,7 +58,7 @@ EffectiveOrders.setup do |config|
|
|
50
58
|
# Works with effective_addresses gem
|
51
59
|
config.use_address_full_name = true
|
52
60
|
|
53
|
-
# If set, the orders#new screen will render effective/orders/
|
61
|
+
# If set, the orders#new screen will render effective/orders/_order_user_fields to capture this User Info
|
54
62
|
# The partial can be overridden to customize the form, but the following fields are also fed into strong_paramters
|
55
63
|
config.collect_user_fields = []
|
56
64
|
#config.collect_user_fields = [:salutation, :first_name, :last_name] # Must be valid fields on the User object
|
@@ -58,8 +66,13 @@ EffectiveOrders.setup do |config|
|
|
58
66
|
# Don't validate_associated :user when saving an Order
|
59
67
|
config.skip_user_validation = false
|
60
68
|
|
69
|
+
# If set, the orders#new screen will render effective/orders/_order_note_fields to capture any Note info
|
70
|
+
config.collect_note = false
|
71
|
+
config.collect_note_required = false # just required for the form, not a true Order model validation
|
72
|
+
config.collect_note_message = ''
|
73
|
+
|
61
74
|
# Tax Calculation Method
|
62
|
-
config.
|
75
|
+
config.order_tax_rate_method = Proc.new { |order| Effective::TaxRateCalculator.new(order: order).tax_rate }
|
63
76
|
|
64
77
|
# Minimum Charge
|
65
78
|
# Prevent orders less than this value from being purchased
|
@@ -99,24 +112,25 @@ EffectiveOrders.setup do |config|
|
|
99
112
|
|
100
113
|
# config.layout = 'application' # All EffectiveOrders controllers will use this layout
|
101
114
|
config.layout = {
|
102
|
-
:
|
103
|
-
:
|
104
|
-
:
|
105
|
-
:
|
106
|
-
:
|
115
|
+
carts: 'application',
|
116
|
+
orders: 'application',
|
117
|
+
subscriptions: 'application',
|
118
|
+
admin_customers: 'application',
|
119
|
+
admin_orders: 'application'
|
107
120
|
}
|
108
121
|
|
109
122
|
# SimpleForm Options
|
110
|
-
# This Hash of options will be passed into any simple_form_for() calls
|
123
|
+
# This Hash of options will be passed into any client facing simple_form_for() calls
|
111
124
|
config.simple_form_options = {}
|
125
|
+
config.admin_simple_form_options = {} # For the /admin/orders/new form
|
112
126
|
|
113
127
|
# config.simple_form_options = {
|
114
|
-
# :
|
115
|
-
# :
|
116
|
-
# :
|
117
|
-
# :
|
118
|
-
# :
|
119
|
-
# :
|
128
|
+
# html: {class: 'form-horizontal'},
|
129
|
+
# wrapper: :horizontal_form,
|
130
|
+
# wrapper_mappings: {
|
131
|
+
# boolean: :horizontal_boolean,
|
132
|
+
# check_boxes: :horizontal_radio_and_checkboxes,
|
133
|
+
# radio_buttons: :horizontal_radio_and_checkboxes
|
120
134
|
# }
|
121
135
|
# }
|
122
136
|
|
@@ -124,48 +138,63 @@ EffectiveOrders.setup do |config|
|
|
124
138
|
# effective_orders will send out receipts to the buyer, seller and admins.
|
125
139
|
# For all the emails, the same :subject_prefix will be prefixed. Leave as nil / empty string if you don't want any prefix
|
126
140
|
#
|
127
|
-
# The subject_for_admin_receipt, subject_for_buyer_receipt and
|
141
|
+
# The subject_for_admin_receipt, subject_for_buyer_receipt, subject_for_payment_request and
|
142
|
+
# subject_for_seller_receipt can be one of:
|
128
143
|
# - nil / empty string to use the built in defaults
|
129
144
|
# - A string with the full subject line for this email
|
130
145
|
# - A Proc to create the subject line based on the email
|
131
146
|
# In all three of these cases, the subject_prefix will still be used.
|
132
147
|
|
133
148
|
# The Procs are the same for admin & buyer receipt, the seller Proc is different
|
134
|
-
# :
|
135
|
-
# :
|
136
|
-
# :
|
149
|
+
# subject_for_order_receipt_to_admin: Proc.new { |order| "Order #{order.to_param} has been purchased"}
|
150
|
+
# subject_for_order_receipt_to_buyer: Proc.new { |order| "Order #{order.to_param} has been purchased"}
|
151
|
+
# subject_for_payment_request_to_buyer: Proc.new { |order| "Pending Order #{order.to_param}"}
|
152
|
+
# subject_for_order_receipt_to_seller: Proc.new { |order, order_items, seller| "Order #{order.to_param} has been purchased"}
|
137
153
|
|
138
154
|
config.mailer = {
|
139
|
-
:
|
140
|
-
:
|
141
|
-
:
|
142
|
-
:
|
143
|
-
:
|
144
|
-
:
|
145
|
-
|
146
|
-
:
|
147
|
-
:
|
148
|
-
:
|
149
|
-
:
|
150
|
-
:
|
155
|
+
send_order_receipt_to_admin: true,
|
156
|
+
send_order_receipt_to_buyer: true,
|
157
|
+
send_order_receipt_to_seller: true, # Only applies to StripeConnect
|
158
|
+
send_payment_request_to_buyer: true,
|
159
|
+
send_pending_order_invoice_to_buyer: true,
|
160
|
+
send_order_receipts_when_marked_paid_by_admin: false,
|
161
|
+
|
162
|
+
subject_prefix: '[example]',
|
163
|
+
subject_for_order_receipt_to_admin: '',
|
164
|
+
subject_for_order_receipt_to_buyer: '',
|
165
|
+
subject_for_order_receipt_to_seller: '',
|
166
|
+
subject_for_pending_order_invoice_to_buyer: '',
|
167
|
+
subject_for_payment_request_to_buyer: '',
|
168
|
+
|
169
|
+
layout: 'effective_orders_mailer_layout',
|
170
|
+
|
171
|
+
default_from: 'info@example.com',
|
172
|
+
admin_email: 'admin@example.com',
|
173
|
+
|
174
|
+
deliver_method: nil, # :deliver (rails < 4.2), :deliver_now (rails >= 4.2) or :deliver_later
|
175
|
+
delayed_job_deliver: false
|
151
176
|
}
|
152
177
|
|
178
|
+
#######################################
|
179
|
+
### Payment Provider specific options
|
180
|
+
#######################################
|
181
|
+
|
153
182
|
# Moneris configuration
|
154
183
|
config.moneris_enabled = false
|
155
184
|
|
156
185
|
if Rails.env.production?
|
157
186
|
config.moneris = {
|
158
|
-
:
|
159
|
-
:
|
160
|
-
:
|
161
|
-
:
|
187
|
+
ps_store_id: '',
|
188
|
+
hpp_key: '',
|
189
|
+
hpp_url: 'https://www3.moneris.com/HPPDP/index.php',
|
190
|
+
verify_url: 'https://www3.moneris.com/HPPDP/verifyTxn.php'
|
162
191
|
}
|
163
192
|
else
|
164
193
|
config.moneris = {
|
165
|
-
:
|
166
|
-
:
|
167
|
-
:
|
168
|
-
:
|
194
|
+
ps_store_id: '',
|
195
|
+
hpp_key: '',
|
196
|
+
hpp_url: 'https://esqa.moneris.com/HPPDP/index.php',
|
197
|
+
verify_url: 'https://esqa.moneris.com/HPPDP/verifyTxn.php'
|
169
198
|
}
|
170
199
|
end
|
171
200
|
|
@@ -174,25 +203,25 @@ EffectiveOrders.setup do |config|
|
|
174
203
|
|
175
204
|
if Rails.env.production?
|
176
205
|
config.paypal = {
|
177
|
-
:
|
178
|
-
:
|
179
|
-
:
|
180
|
-
:
|
181
|
-
:
|
182
|
-
:
|
183
|
-
:
|
184
|
-
:
|
206
|
+
seller_email: '',
|
207
|
+
secret: '',
|
208
|
+
cert_id: '',
|
209
|
+
paypal_url: 'https://www.paypal.com/cgi-bin/webscr',
|
210
|
+
currency: 'CAD',
|
211
|
+
paypal_cert: "#{Rails.root}/config/paypalcerts/production/paypal_cert.pem",
|
212
|
+
app_cert: "#{Rails.root}/config/paypalcerts/production/app_cert.pem",
|
213
|
+
app_key: "#{Rails.root}/config/paypalcerts/production/app_key.pem"
|
185
214
|
}
|
186
215
|
else
|
187
216
|
config.paypal = {
|
188
|
-
:
|
189
|
-
:
|
190
|
-
:
|
191
|
-
:
|
192
|
-
:
|
193
|
-
:
|
194
|
-
:
|
195
|
-
:
|
217
|
+
seller_email: '',
|
218
|
+
secret: '',
|
219
|
+
cert_id: '',
|
220
|
+
paypal_url: 'https://www.sandbox.paypal.com/cgi-bin/webscr',
|
221
|
+
currency: 'CAD',
|
222
|
+
paypal_cert: "#{Rails.root}/config/paypalcerts/#{Rails.env}/paypal_cert.pem",
|
223
|
+
app_cert: "#{Rails.root}/config/paypalcerts/#{Rails.env}/app_cert.pem",
|
224
|
+
app_key: "#{Rails.root}/config/paypalcerts/#{Rails.env}/app_key.pem"
|
196
225
|
}
|
197
226
|
end
|
198
227
|
|
@@ -204,21 +233,48 @@ EffectiveOrders.setup do |config|
|
|
204
233
|
|
205
234
|
if Rails.env.production?
|
206
235
|
config.stripe = {
|
207
|
-
:
|
208
|
-
:
|
209
|
-
:
|
210
|
-
:
|
211
|
-
:
|
212
|
-
:
|
236
|
+
secret_key: '',
|
237
|
+
publishable_key: '',
|
238
|
+
currency: 'usd',
|
239
|
+
site_title: 'My Site',
|
240
|
+
site_image: '', # A relative URL pointing to a square image of your brand or product. The recommended minimum size is 128x128px.
|
241
|
+
connect_client_id: ''
|
213
242
|
}
|
214
243
|
else
|
215
244
|
config.stripe = {
|
216
|
-
:
|
217
|
-
:
|
218
|
-
:
|
219
|
-
:
|
220
|
-
:
|
221
|
-
:
|
245
|
+
secret_key: '',
|
246
|
+
publishable_key: '',
|
247
|
+
currency: 'usd',
|
248
|
+
site_title: 'My Development Site', # Displayed on the Embedded Stripe Form
|
249
|
+
site_image: '', # A relative URL pointing to a square image of your brand or product. The recommended minimum size is 128x128px.
|
250
|
+
connect_client_id: ''
|
251
|
+
}
|
252
|
+
end
|
253
|
+
|
254
|
+
# CCBill configuration
|
255
|
+
config.ccbill_enabled = false
|
256
|
+
|
257
|
+
# CCBill Dynamic Pricing documentation describes these variables:
|
258
|
+
# https://www.ccbill.com/cs/wiki/tiki-index.php?page=Dynamic+Pricing+User+Guide
|
259
|
+
if Rails.env.production?
|
260
|
+
config.ccbill = {
|
261
|
+
client_accnum: '',
|
262
|
+
client_subacc: '0000', # initial sub account
|
263
|
+
# Get this from CCBill Admin dashboard after setting up a form
|
264
|
+
form_name: '211cc', # default credit card form
|
265
|
+
# https://www.ccbill.com/cs/wiki/tiki-index.php?page=Webhooks+User+Guide#Appendix_A:_Currency_Codes
|
266
|
+
currency_code: '840', # USD
|
267
|
+
# You'll need to get this salt after having CCBill tech support set up dynamic pricing
|
268
|
+
# https://www.ccbill.com/cs/wiki/tiki-index.php?page=Dynamic+Pricing+User+Guide#Generating_the_MD5_Hash
|
269
|
+
dynamic_pricing_salt: ''
|
270
|
+
}
|
271
|
+
else
|
272
|
+
config.ccbill = {
|
273
|
+
client_accnum: '',
|
274
|
+
client_subacc: '0000',
|
275
|
+
form_name: '211cc',
|
276
|
+
currency_code: '840',
|
277
|
+
dynamic_pricing_salt: ''
|
222
278
|
}
|
223
279
|
end
|
224
280
|
|
@@ -230,4 +286,13 @@ EffectiveOrders.setup do |config|
|
|
230
286
|
service: nil, # an EffectiveOrders::AppCheckout type object
|
231
287
|
declined_flash: "Payment was unsuccessful. Please try again."
|
232
288
|
}
|
289
|
+
|
290
|
+
|
291
|
+
# Pay by Cheque configuration
|
292
|
+
config.cheque_enabled = false
|
293
|
+
|
294
|
+
config.cheque = {
|
295
|
+
confirm: 'Your order will not be considered purchased until we receive your cheque. Proceed with pay by cheque?'
|
296
|
+
}
|
297
|
+
|
233
298
|
end
|
@@ -3,42 +3,56 @@
|
|
3
3
|
# to see a preview of the following 3 emails:
|
4
4
|
|
5
5
|
class EffectiveOrdersMailerPreview < ActionMailer::Preview
|
6
|
-
def order_receipt_to_buyer
|
7
|
-
Effective::OrdersMailer.order_receipt_to_buyer(build_preview_order)
|
8
|
-
end
|
9
|
-
|
10
6
|
def order_receipt_to_admin
|
11
7
|
Effective::OrdersMailer.order_receipt_to_admin(build_preview_order)
|
12
8
|
end
|
13
9
|
|
10
|
+
def order_receipt_to_buyer
|
11
|
+
Effective::OrdersMailer.order_receipt_to_buyer(build_preview_order)
|
12
|
+
end
|
13
|
+
|
14
14
|
# This email is only sent to sellers having sold items via StripeConnect
|
15
15
|
def order_receipt_to_seller
|
16
16
|
order = build_preview_order
|
17
17
|
Effective::OrdersMailer.order_receipt_to_seller(order, preview_customer, order.order_items)
|
18
18
|
end
|
19
19
|
|
20
|
+
def payment_request_to_buyer
|
21
|
+
Effective::OrdersMailer.payment_request_to_buyer(build_preview_order)
|
22
|
+
end
|
23
|
+
|
24
|
+
def pending_order_invoice_to_buyer
|
25
|
+
Effective::OrdersMailer.pending_order_invoice_to_buyer(build_preview_order)
|
26
|
+
end
|
27
|
+
|
28
|
+
def order_error
|
29
|
+
Effective::OrdersMailer.order_error(order: build_preview_order, error: "Something didn't work out")
|
30
|
+
end
|
31
|
+
|
20
32
|
protected
|
21
33
|
|
22
34
|
def build_preview_order
|
23
|
-
order = Effective::Order.new
|
35
|
+
order = Effective::Order.new
|
24
36
|
order.user = preview_user
|
25
37
|
preview_order_items.each { |atts| order.order_items.build(atts) }
|
38
|
+
order.valid?
|
26
39
|
order
|
27
40
|
end
|
28
41
|
|
42
|
+
def build_address
|
43
|
+
Effective::Address.new(category: 'billing', full_name: 'Valued Customer', address1: '1234 Fake Street', address2: 'Suite 200', city: 'Edmonton', state_code: 'AB', country_code: 'CA', postal_code: 'T5T 2T1')
|
44
|
+
end
|
45
|
+
|
29
46
|
private
|
30
47
|
|
31
48
|
# We're building Effective::OrderItems directly rather than creating acts_as_purchasable objects
|
32
49
|
# so that this mailer will not have to guess at your app's acts_as_purchasable objects
|
33
50
|
def preview_order_items
|
34
|
-
tax_rate = (EffectiveOrders.tax_rate_method.call(Object.new()) rescue -1)
|
35
|
-
tax_rate = 0.05 if tax_rate < 0.0
|
36
|
-
|
37
51
|
[
|
38
|
-
{title: 'Item One', quantity: 2, price: 999, tax_exempt: false
|
39
|
-
{title: 'Item Two', quantity: 1, price: 25000, tax_exempt: false
|
40
|
-
{title: 'Item Three', quantity: 1, price: 8999, tax_exempt: false
|
41
|
-
{title: 'Item Four', quantity: 1, price: 100000, tax_exempt: false
|
52
|
+
{title: 'Item One', quantity: 2, price: 999, tax_exempt: false},
|
53
|
+
{title: 'Item Two', quantity: 1, price: 25000, tax_exempt: false},
|
54
|
+
{title: 'Item Three', quantity: 1, price: 8999, tax_exempt: false},
|
55
|
+
{title: 'Item Four', quantity: 1, price: 100000, tax_exempt: false}
|
42
56
|
]
|
43
57
|
end
|
44
58
|
|
@@ -51,11 +65,12 @@ class EffectiveOrdersMailerPreview < ActionMailer::Preview
|
|
51
65
|
user.first_name = 'Valued'
|
52
66
|
user.last_name = 'Customer'
|
53
67
|
end
|
68
|
+
|
69
|
+
user.billing_address = build_address if user.respond_to?(:billing_address=)
|
54
70
|
end
|
55
71
|
end
|
56
72
|
|
57
73
|
def preview_customer
|
58
74
|
Effective::Customer.new(user: preview_user)
|
59
75
|
end
|
60
|
-
|
61
76
|
end
|
@@ -0,0 +1,242 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Admin::OrdersController, type: :controller do
|
4
|
+
routes { EffectiveOrders::Engine.routes }
|
5
|
+
|
6
|
+
let!(:user1) { FactoryGirl.create(:user, email: 'bbb@example.com') }
|
7
|
+
let!(:user2) { FactoryGirl.create(:user, email: 'ccc@example.com') }
|
8
|
+
let!(:user3) { FactoryGirl.create(:user, email: 'aaa@example.com') }
|
9
|
+
let(:cart) { FactoryGirl.create(:cart, user: user1) }
|
10
|
+
|
11
|
+
before { sign_in cart.user }
|
12
|
+
|
13
|
+
describe 'GET #new' do
|
14
|
+
it 'should render admin new order page successfully' do
|
15
|
+
get :new
|
16
|
+
|
17
|
+
expect(response).to be_successful
|
18
|
+
expect(response).to render_template :new
|
19
|
+
expect(assigns(:order)).to be_an Effective::Order
|
20
|
+
expect(assigns(:order)).to be_new_record
|
21
|
+
expect(assigns(:page_title)).to eq 'New Order'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'POST #create' do
|
26
|
+
let(:user1) { FactoryGirl.create(:user, email: 'bbb@example.com', billing_address: FactoryGirl.create(:address), shipping_address: FactoryGirl.create(:address)) }
|
27
|
+
|
28
|
+
context 'when success' do
|
29
|
+
let(:order_params) { { effective_order: { user_id: user1.id, order_items_attributes: { '0' => { purchasable_attributes: { title: 'test product 1', price: '10000', tax_exempt: '1' }, quantity: '2', '_destroy' => 'false' }, '1' => { purchasable_attributes: { title: 'test product 2', price: '30000', tax_exempt: '0' }, quantity: '3', '_destroy' => 'false' } }, send_payment_request_to_buyer: '1' } } }
|
30
|
+
|
31
|
+
shared_context 'creates objects in db correctly' do
|
32
|
+
it 'should create new custom order with pending state' do
|
33
|
+
expect { post :create, order_params.merge(commit: button_pressed) }.to change { Effective::Order.count }.from(0).to(1)
|
34
|
+
|
35
|
+
expect(assigns(:order)).to be_persisted
|
36
|
+
expect(assigns(:order).pending?).to be_truthy
|
37
|
+
expect(assigns(:order).user).to eq user1
|
38
|
+
expect(assigns(:order).billing_address).to eq user1.billing_address
|
39
|
+
expect(assigns(:order).shipping_address).to eq user1.shipping_address
|
40
|
+
|
41
|
+
expect(assigns(:order).order_items.count).to eq 2
|
42
|
+
|
43
|
+
first_item = assigns(:order).order_items.sort.first
|
44
|
+
expect(first_item).to be_persisted
|
45
|
+
expect(first_item.title).to eq 'test product 1'
|
46
|
+
expect(first_item.quantity).to eq 2
|
47
|
+
expect(first_item.price).to eq 10000
|
48
|
+
expect(first_item.tax_exempt).to be_truthy
|
49
|
+
|
50
|
+
second_item = assigns(:order).order_items.sort.last
|
51
|
+
expect(second_item).to be_persisted
|
52
|
+
expect(second_item.title).to eq 'test product 2'
|
53
|
+
expect(second_item.quantity).to eq 3
|
54
|
+
expect(second_item.price).to eq 30000
|
55
|
+
expect(second_item.tax_exempt).to be_falsey
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should create new effective products' do
|
59
|
+
expect { post :create, order_params.merge(commit: button_pressed) }.to change { Effective::Product.count }.from(0).to(2)
|
60
|
+
|
61
|
+
first_product = Effective::Product.all.sort.first
|
62
|
+
expect(first_product.title).to eq 'test product 1'
|
63
|
+
expect(first_product.price).to eq 10000
|
64
|
+
|
65
|
+
second_product = Effective::Product.all.sort.last
|
66
|
+
expect(second_product.title).to eq 'test product 2'
|
67
|
+
expect(second_product.price).to eq 30000
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when "Save" button is pressed' do
|
72
|
+
let(:button_pressed) { 'Save' }
|
73
|
+
|
74
|
+
it_should_behave_like 'creates objects in db correctly'
|
75
|
+
|
76
|
+
it 'should redirect to admin orders index page with success message' do
|
77
|
+
post :create, order_params.merge(commit: button_pressed)
|
78
|
+
|
79
|
+
expect(response).to be_redirect
|
80
|
+
expect(response).to redirect_to EffectiveOrders::Engine.routes.url_helpers.admin_order_path(assigns(:order))
|
81
|
+
expect(flash[:success]).to eq "Successfully created order. #{assigns(:order).user.email} has been sent a request for payment."
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'when "Save and Add New" button is pressed' do
|
86
|
+
let(:button_pressed) { 'Save and Add New' }
|
87
|
+
|
88
|
+
it_should_behave_like 'creates objects in db correctly'
|
89
|
+
|
90
|
+
it 'should redirect to admin new order page with success message' do
|
91
|
+
post :create, order_params.merge(commit: button_pressed)
|
92
|
+
|
93
|
+
expect(response).to be_redirect
|
94
|
+
expect(response).to redirect_to EffectiveOrders::Engine.routes.url_helpers.new_admin_order_path
|
95
|
+
expect(flash[:success]).to eq "Successfully created order. #{assigns(:order).user.email} has been sent a request for payment."
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'when failed' do
|
101
|
+
let(:order_params) { { effective_order: { user_id: user1.id, order_items_attributes: { '0' => { purchasable_attributes: { title: 'test product 1', price: '0', tax_exempt: '1' }, quantity: '2', '_destroy' => 'false' } } } } }
|
102
|
+
|
103
|
+
shared_context 'does not create objects in db and redirects to admin new order page with danger message' do
|
104
|
+
it 'should not create order' do
|
105
|
+
expect { post :create, order_params.merge(commit: button_pressed) }.not_to change { Effective::Order.count }
|
106
|
+
|
107
|
+
expect(assigns(:order)).to be_new_record
|
108
|
+
expect(assigns(:order).valid?).to be_falsey
|
109
|
+
expect(assigns(:order).pending?).to be_truthy
|
110
|
+
expect(assigns(:order).user).to eq user1
|
111
|
+
expect(assigns(:order).billing_address).to eq user1.billing_address
|
112
|
+
expect(assigns(:order).shipping_address).to eq user1.shipping_address
|
113
|
+
|
114
|
+
expect(assigns(:order).order_items.to_a.count).to eq 1
|
115
|
+
|
116
|
+
item = assigns(:order).order_items.first
|
117
|
+
expect(item).to be_new_record
|
118
|
+
expect(item.valid?).to be_falsey
|
119
|
+
expect(item.title).to eq 'test product 1'
|
120
|
+
expect(item.quantity).to eq 2
|
121
|
+
expect(item.price).to eq 0
|
122
|
+
expect(item.tax_exempt).to be_truthy
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should not create product' do
|
126
|
+
expect { post :create, order_params.merge(commit: button_pressed) }.not_to change { Effective::Product.count }
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should render admin new order page with danger message' do
|
130
|
+
post :create, order_params.merge(commit: button_pressed)
|
131
|
+
|
132
|
+
expect(response).to be_successful
|
133
|
+
expect(response).to render_template :new
|
134
|
+
expect(assigns(:page_title)).to eq 'New Order'
|
135
|
+
expect(flash[:danger]).to eq 'Unable to create order'
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context 'when "Save" button is pressed' do
|
140
|
+
let(:button_pressed) { 'Save' }
|
141
|
+
|
142
|
+
it_should_behave_like 'does not create objects in db and redirects to admin new order page with danger message'
|
143
|
+
end
|
144
|
+
|
145
|
+
context 'when "Save and Add New" button is pressed' do
|
146
|
+
let(:button_pressed) { 'Save and Add New' }
|
147
|
+
|
148
|
+
it_should_behave_like 'does not create objects in db and redirects to admin new order page with danger message'
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe 'POST #mark_as_paid' do
|
154
|
+
let(:order) { FactoryGirl.create(:pending_order) }
|
155
|
+
|
156
|
+
before { request.env['HTTP_REFERER'] = 'where_i_came_from' }
|
157
|
+
|
158
|
+
context 'when success' do
|
159
|
+
it 'should update order state and redirect to orders admin index page with success message' do
|
160
|
+
post :mark_as_paid, id: order.to_param
|
161
|
+
|
162
|
+
expect(response).to be_redirect
|
163
|
+
expect(response).to redirect_to EffectiveOrders::Engine.routes.url_helpers.admin_order_path(assigns(:order))
|
164
|
+
expect(assigns(:order)).to eq order
|
165
|
+
expect(assigns(:order).purchased?).to be_truthy
|
166
|
+
expect(assigns(:order).payment).to eq(details: 'Marked as paid by admin')
|
167
|
+
expect(flash[:success]).to eq 'Order marked as paid successfully'
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
context 'when failed' do
|
172
|
+
before { Effective::Order.any_instance.stub(:purchase!).and_return(false) }
|
173
|
+
|
174
|
+
it 'should redirect back with danger message' do
|
175
|
+
post :mark_as_paid, id: order.to_param
|
176
|
+
|
177
|
+
expect(response).to be_redirect
|
178
|
+
expect(response).to redirect_to 'where_i_came_from'
|
179
|
+
expect(assigns(:order)).to eq order
|
180
|
+
expect(assigns(:order).purchased?).to be_falsey
|
181
|
+
expect(flash[:danger]).to eq 'Unable to mark order as paid'
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe 'POST #send_payment_request' do
|
187
|
+
let(:user) { FactoryGirl.create(:user, email: 'user@example.com') }
|
188
|
+
let(:order) { FactoryGirl.create(:order, user: user) }
|
189
|
+
|
190
|
+
context 'when success' do
|
191
|
+
before { Effective::Order.any_instance.should_receive(:send_payment_request_to_buyer!).once.and_return(true) }
|
192
|
+
|
193
|
+
context 'when referrer page is present' do
|
194
|
+
before { request.env['HTTP_REFERER'] = 'where_i_came_from' }
|
195
|
+
|
196
|
+
it 'should redirect to previous page with success message' do
|
197
|
+
post :send_payment_request, id: order.to_param
|
198
|
+
|
199
|
+
expect(response).to be_redirect
|
200
|
+
expect(response).to redirect_to 'where_i_came_from'
|
201
|
+
expect(flash[:success]).to eq 'Successfully sent payment request to user@example.com'
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
context 'when referrer page is not present' do
|
206
|
+
it 'should redirect to admin order show page with success message' do
|
207
|
+
post :send_payment_request, id: order.to_param
|
208
|
+
|
209
|
+
expect(response).to be_redirect
|
210
|
+
expect(response).to redirect_to EffectiveOrders::Engine.routes.url_helpers.admin_order_path(order)
|
211
|
+
expect(flash[:success]).to eq 'Successfully sent payment request to user@example.com'
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
context 'when failed' do
|
217
|
+
before { Effective::Order.any_instance.should_receive(:send_payment_request_to_buyer!).once.and_return(false) }
|
218
|
+
|
219
|
+
context 'when referrer page is present' do
|
220
|
+
before { request.env['HTTP_REFERER'] = 'where_i_came_from' }
|
221
|
+
|
222
|
+
it 'should redirect to previous page with danger message' do
|
223
|
+
post :send_payment_request, id: order.to_param
|
224
|
+
|
225
|
+
expect(response).to be_redirect
|
226
|
+
expect(response).to redirect_to 'where_i_came_from'
|
227
|
+
expect(flash[:danger]).to eq 'Unable to send payment request'
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
context 'when referrer page is not present' do
|
232
|
+
it 'should redirect to admin order show page with danger message' do
|
233
|
+
post :send_payment_request, id: order.to_param
|
234
|
+
|
235
|
+
expect(response).to be_redirect
|
236
|
+
expect(response).to redirect_to EffectiveOrders::Engine.routes.url_helpers.admin_order_path(order)
|
237
|
+
expect(flash[:danger]).to eq 'Unable to send payment request'
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|