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
@@ -0,0 +1,73 @@
1
+ stripeSubscriptionHandler = (key, form) ->
2
+ StripeCheckout.configure
3
+ key: key
4
+ closed: ->
5
+ form.find("input[type='submit']").removeAttr('disabled')
6
+ $('input[data-disable-with]').each -> try $.rails.enableFormElement($(this))
7
+ token: (token, args) ->
8
+ if token.error
9
+ form.find("input[type='submit']").removeAttr('disabled')
10
+ $('input[data-disable-with]').each -> try $.rails.enableFormElement($(this))
11
+
12
+ alert("An error ocurred when contacting Stripe. Your card has not been charged. Your subscription has not changed. Please refresh the page and try again. #{token.error.message}")
13
+ else
14
+ form.find("input[name$='[stripe_token]']").val('' + token['id'])
15
+
16
+ form.find("input[type='submit']").prop('disabled', true)
17
+ $('input[data-disable-with]').each -> try $.rails.disableFormElement($(this))
18
+ form.submit()
19
+
20
+ $(document).on 'click', "input[type='submit'].effective-orders-subscripter-token-required", (event) ->
21
+ event.preventDefault()
22
+
23
+ $submit = $(event.currentTarget)
24
+ $form = $submit.closest('form')
25
+
26
+ # Disable the form
27
+ $submit.prop('disabled', true)
28
+ $('input[data-disable-with]').each -> try $.rails.disableFormElement($(this))
29
+
30
+ # Get the stripe data
31
+ $plans = $form.find('.effective-orders-stripe-plans').first()
32
+ selected_plan_id = $plans.find("input[name$='[subscripter][stripe_plan_id]']:checked").val()
33
+
34
+ stripe = $plans.data('stripe')
35
+ plan = stripe.plans.find (plan, _) => plan.id == selected_plan_id
36
+
37
+ stripeSubscriptionHandler(stripe.key, $form).open
38
+ image: stripe.image
39
+ name: stripe.name
40
+ description: plan.name
41
+ email: stripe.email
42
+ amount: plan.amount
43
+ panelLabel: "{{amount}}#{plan.occurrence} Go!"
44
+
45
+ # When a plan is selected, toggle the selected-class on each plan.
46
+ # Set the submit button's class if a customer token is required
47
+ $(document).on 'change', "input[name$='[subscripter][stripe_plan_id]']", (event) ->
48
+ $plan = $(event.currentTarget)
49
+ return unless $plan.is(':checked')
50
+
51
+ $plans = $plan.closest('.effective-orders-stripe-plans').first()
52
+ selected_class = $plans.data('selected-class')
53
+ selected_plan_id = $plan.val()
54
+
55
+ $plans.find("input[name$='[subscripter][stripe_plan_id]']").each (_, item) =>
56
+ if $(item).is(':checked')
57
+ $(item).siblings('.panel').addClass(selected_class)
58
+ else
59
+ $(item).siblings('.panel').removeClass(selected_class)
60
+
61
+ plan = $plans.data('stripe').plans.find (plan, _) => plan.id == selected_plan_id
62
+ token_required = $plans.data('stripe').token_required
63
+
64
+ if (plan.amount || 0) > 0 && token_required
65
+ $plans.closest('form').find("input[type='submit']").addClass('effective-orders-subscripter-token-required')
66
+ else
67
+ $plans.closest('form').find("input[type='submit']").removeClass('effective-orders-subscripter-token-required')
68
+
69
+ # When the 'Select' button is clicked, set the radio button input
70
+ $(document).on 'click', '.effective-orders-stripe-plan .btn-select-plan', (event) ->
71
+ val = $(event.currentTarget).closest('.effective-orders-stripe-plan').find('input:radio').val()
72
+ $(event.currentTarget).closest('.effective-orders-stripe-plans').find('input:radio').val([val]).trigger('change')
73
+ false
@@ -1 +1,2 @@
1
- @import "effective_orders/order";
1
+ @import 'effective_orders/order';
2
+ @import 'effective_orders/subscriptions';
@@ -23,16 +23,15 @@
23
23
  }
24
24
 
25
25
  .price { text-align: right; }
26
+ }
26
27
 
27
- .effective-stripe-subscription {
28
- input {
29
- margin-top: 5px;
30
- width: 30%;
31
- min-width: 200px;
32
- }
33
- }
28
+ // Print - Resend Receipt. Ontop of order.
29
+ .effective-order-actions {
30
+ text-align: right;
31
+ margin-bottom: 10px;
34
32
  }
35
33
 
34
+ // Checkout buttons. Bottom of order.
36
35
  .effective-order-purchase-actions {
37
36
  text-align: right;
38
37
 
@@ -41,6 +40,10 @@
41
40
  }
42
41
  }
43
42
 
43
+ .effective-order-admin-purchase-actions {
44
+ margin-top: 10px;
45
+ }
46
+
44
47
  form.new_effective_order {
45
48
  .checkbox { margin-top: 30px; }
46
49
  .remove-nested-fields { margin-top: 30px; }
@@ -48,8 +51,13 @@ form.new_effective_order {
48
51
  }
49
52
 
50
53
  @media print {
51
- .effective-orders-page-title { display: none; }
52
54
  .effective-orders-page-content { display: none; }
55
+
53
56
  .effective-order-actions { display: none; }
54
57
  .effective-order-purchase-actions { display: none; }
58
+ .effective-order-admin-purchase-actions { display: none; }
59
+
60
+ .effective-heading { display: none; }
61
+ .effective-admin-heading { display: none; }
62
+ .effective-order-internal-note-form { display: none; }
55
63
  }
@@ -0,0 +1,14 @@
1
+ // This is the radio button form input
2
+ .effective-orders-stripe-plans {
3
+ input { display: none; }
4
+ label { width: 100%; padding-left: 0px; }
5
+ .radio + .radio { margin-top: 10px; }
6
+
7
+ .visible-when-selected { display: none; }
8
+ .visible-when-unselected { display: block; }
9
+
10
+ label > .selected {
11
+ .visible-when-selected { display: block; }
12
+ .visible-when-unselected { display: none; }
13
+ }
14
+ }
@@ -1,20 +1,23 @@
1
1
  module Admin
2
2
  class CustomersController < ApplicationController
3
- respond_to?(:before_action) ? before_action(:authenticate_user!) : before_filter(:authenticate_user!) # Devise
3
+ before_action :authenticate_user!
4
4
 
5
5
  layout (EffectiveOrders.layout.kind_of?(Hash) ? EffectiveOrders.layout[:admin_customers] : EffectiveOrders.layout)
6
6
 
7
7
  def index
8
- if Gem::Version.new(EffectiveDatatables::VERSION) < Gem::Version.new('3.0')
9
- @datatable = Effective::Datatables::Customers.new()
10
- else
11
- @datatable = EffectiveCustomersDatatable.new(self)
12
- end
8
+ @datatable = EffectiveCustomersDatatable.new(self)
13
9
 
14
10
  @page_title = 'Customers'
15
11
 
16
- EffectiveOrders.authorized?(self, :admin, :effective_orders)
17
- EffectiveOrders.authorized?(self, :index, Effective::Customer)
12
+ EffectiveOrders.authorize!(self, :admin, :effective_orders)
13
+ EffectiveOrders.authorize!(self, :index, Effective::Customer)
14
+ end
15
+
16
+ def show
17
+ @customer = Effective::Customer.find(params[:id])
18
+
19
+ @page_title ||= @customer.to_s
20
+ EffectiveOrders.authorize!(self, :show, Effective::Customer)
18
21
  end
19
22
 
20
23
  end
@@ -1,20 +1,16 @@
1
1
  module Admin
2
2
  class OrderItemsController < ApplicationController
3
- respond_to?(:before_action) ? before_action(:authenticate_user!) : before_filter(:authenticate_user!) # Devise
3
+ before_action :authenticate_user!
4
4
 
5
5
  layout (EffectiveOrders.layout.kind_of?(Hash) ? EffectiveOrders.layout[:admin_orders] : EffectiveOrders.layout)
6
6
 
7
7
  def index
8
- if Gem::Version.new(EffectiveDatatables::VERSION) < Gem::Version.new('3.0')
9
- @datatable = Effective::Datatables::OrderItems.new()
10
- else
11
- @datatable = EffectiveOrderItemsDatatable.new(self)
12
- end
8
+ @datatable = EffectiveOrderItemsDatatable.new(self)
13
9
 
14
10
  @page_title = 'Order Items'
15
11
 
16
- EffectiveOrders.authorized?(self, :admin, :effective_orders)
17
- EffectiveOrders.authorized?(self, :index, Effective::OrderItem)
12
+ EffectiveOrders.authorize!(self, :admin, :effective_orders)
13
+ EffectiveOrders.authorize!(self, :index, Effective::OrderItem)
18
14
  end
19
15
  end
20
16
  end
@@ -1,81 +1,132 @@
1
1
  module Admin
2
2
  class OrdersController < ApplicationController
3
- respond_to?(:before_action) ? before_action(:authenticate_user!) : before_filter(:authenticate_user!) # Devise
3
+ before_action :authenticate_user!
4
4
 
5
5
  layout (EffectiveOrders.layout.kind_of?(Hash) ? EffectiveOrders.layout[:admin_orders] : EffectiveOrders.layout)
6
6
 
7
- def index
8
- if Gem::Version.new(EffectiveDatatables::VERSION) < Gem::Version.new('3.0')
9
- @datatable = Effective::Datatables::Orders.new()
10
- else
11
- @datatable = EffectiveOrdersDatatable.new(self)
7
+ def new
8
+ @order = Effective::Order.new
9
+
10
+ if params[:user_id]
11
+ @order.user = User.where(id: params[:user_id]).first
12
12
  end
13
13
 
14
- @page_title = 'Orders'
14
+ if params[:duplicate_id]
15
+ @duplicate = Effective::Order.deep.find(params[:duplicate_id])
16
+ EffectiveOrders.authorize!(self, :show, @duplicate)
17
+
18
+ @order.add(@duplicate)
19
+ end
20
+
21
+ @page_title = 'New Order'
22
+
23
+ raise 'please install cocoon gem to use this page' unless defined?(Cocoon)
15
24
 
16
25
  authorize_effective_order!
17
26
  end
18
27
 
19
- # We use the show action as an edit screen too
20
- def show
28
+ def create
29
+ @user = User.find_by_id(order_params[:user_id])
30
+ @order = Effective::Order.new(user: @user)
31
+
32
+ authorize_effective_order!
33
+ error = nil
34
+
35
+ Effective::Order.transaction do
36
+ begin
37
+ (order_params[:order_items_attributes] || {}).each do |_, item_attrs|
38
+ purchasable = Effective::Product.new(item_attrs[:purchasable_attributes])
39
+ @order.add(purchasable, quantity: item_attrs[:quantity])
40
+ end
41
+
42
+ @order.attributes = order_params.except(:order_items_attributes, :user_id)
43
+
44
+ @order.create_as_pending!
45
+
46
+ message = 'Successfully created order'
47
+ message << ". A request for payment has been sent to #{@order.user.email}" if @order.send_payment_request_to_buyer?
48
+ flash[:success] = message
49
+
50
+ redirect_to(admin_redirect_path) and return
51
+ rescue => e
52
+ error = e.message
53
+ raise ActiveRecord::Rollback
54
+ end
55
+ end
56
+
57
+ @page_title = 'New Order'
58
+ flash.now[:danger] = "Unable to create order: #{error || @order.errors.full_messages.to_sentence}"
59
+ render :new
60
+ end
61
+
62
+ def edit
21
63
  @order = Effective::Order.find(params[:id])
22
- @page_title = "Order ##{@order.to_param}"
64
+ @page_title ||= @order.to_s
23
65
 
24
66
  authorize_effective_order!
25
67
  end
26
68
 
27
69
  def update
28
70
  @order = Effective::Order.find(params[:id])
29
- @page_title = "Order ##{@order.to_param}"
71
+ @order.skip_minimum_charge_validation = true if @order.refund?
72
+
73
+ @page_title ||= @order.to_s
30
74
 
31
75
  authorize_effective_order!
32
76
 
33
- if @order.update_attributes(order_params)
34
- if params[:commit].to_s.downcase == 'save internal note'
35
- flash[:success] = 'Successfully updated internal note'
36
- else
37
- flash[:success] = 'Successfully updated order'
77
+ Effective::Order.transaction do
78
+ begin
79
+ @order.assign_attributes(order_params)
80
+ @order.save!
81
+ redirect_to(admin_redirect_path) and return
82
+ rescue => e
83
+ raise ActiveRecord::Rollback
38
84
  end
39
-
40
- redirect_to(admin_redirect_path)
41
- else
42
- flash.now[:danger] = "Unable to update order: #{@order.errors.full_messages.to_sentence}"
43
- render action: :show
44
85
  end
86
+
87
+ flash.now[:danger] = "Unable to update order: #{@order.errors.full_messages.to_sentence}"
88
+ render :edit
45
89
  end
46
90
 
47
- def new
48
- @order = Effective::Order.new
49
- @order.user = (User.find(params[:user_id]) rescue nil) if params[:user_id]
91
+ def show
92
+ @order = Effective::Order.find(params[:id])
93
+ @order.skip_minimum_charge_validation = true if @order.refund?
50
94
 
51
- @page_title = 'New Order'
95
+ @page_title ||= @order.to_s
52
96
 
53
97
  authorize_effective_order!
54
98
  end
55
99
 
56
- def create
57
- @user = User.find_by_id(order_params[:user_id])
58
- @order = Effective::Order.new(user: @user)
100
+ # The show page posts to this action
101
+ # See Effective::OrdersController checkout
102
+ def checkout
103
+ @order = Effective::Order.find(params[:id])
104
+ @order.skip_minimum_charge_validation = true if @order.refund?
105
+
106
+ @page_title ||= 'Checkout'
59
107
 
60
108
  authorize_effective_order!
61
109
 
62
- (order_params[:order_items_attributes] || {}).each do |_, item_attrs|
63
- purchasable = Effective::Product.new(item_attrs[:purchasable_attributes])
64
- @order.add(purchasable, quantity: item_attrs[:quantity])
110
+ Effective::Order.transaction do
111
+ begin
112
+ @order.assign_attributes(checkout_params)
113
+ @order.save!
114
+ redirect_to(effective_orders.admin_order_path(@order)) and return
115
+ rescue => e
116
+ raise ActiveRecord::Rollback
117
+ end
65
118
  end
66
119
 
67
- @order.attributes = order_params.except(:order_items_attributes, :user_id)
120
+ flash.now[:danger] = "Unable to save order: #{@order.errors.full_messages.to_sentence}. Please try again."
121
+ render :show
122
+ end
68
123
 
69
- if @order.create_as_pending
70
- message = 'Successfully created order'
71
- message << ". #{@order.user.email} has been sent a request for payment." if @order.send_payment_request_to_buyer?
72
- flash[:success] = message
73
- redirect_to(admin_redirect_path)
74
- else
75
- @page_title = 'New Order'
76
- flash.now[:danger] = "Unable to create order: #{@order.errors.full_messages.to_sentence}"
77
- render :new
78
- end
124
+ def index
125
+ @datatable = EffectiveOrdersDatatable.new(self)
126
+
127
+ @page_title = 'Orders'
128
+
129
+ authorize_effective_order!
79
130
  end
80
131
 
81
132
  def destroy
@@ -92,50 +143,36 @@ module Admin
92
143
  redirect_to(effective_orders.admin_orders_path)
93
144
  end
94
145
 
95
- def mark_as_paid
96
- @order = Effective::Order.find(params[:id])
97
- @page_title = 'Mark as Paid'
98
-
99
- authorize_effective_order!
100
-
101
- if request.patch? || request.post? # They are submitting the form to mark an order as paid
102
- purchased = false
103
-
104
- @order.attributes = order_params.except(:payment, :payment_provider, :payment_card)
105
-
106
- begin
107
- purchased = @order.purchase!(
108
- details: order_params[:payment],
109
- provider: order_params[:payment_provider],
110
- card: order_params[:payment_card],
111
- email: @order.send_mark_as_paid_email_to_buyer?,
112
- skip_buyer_validations: true
113
- )
114
- rescue => e
115
- purchased = false
116
- end
117
-
118
- if purchased
119
- flash[:success] = 'Order marked as paid successfully'
120
- redirect_to(admin_redirect_path)
121
- else
122
- flash.now[:danger] = "Unable to mark order as paid: #{@order.errors.full_messages.to_sentence}"
123
- render action: :mark_as_paid
124
- end
125
- end
126
- end
127
-
128
146
  def send_payment_request
129
- @order = Effective::Order.find(params[:id])
147
+ @order = Effective::Order.pending.find(params[:id])
130
148
  authorize_effective_order!
131
149
 
132
150
  if @order.send_payment_request_to_buyer!
133
- flash[:success] = "Successfully sent payment request to #{@order.user.email}"
151
+ flash[:success] = "A request for payment has been sent to #{@order.user.email}"
134
152
  else
135
153
  flash[:danger] = 'Unable to send payment request'
136
154
  end
137
155
 
138
- request.referrer ? (redirect_to :back) : (redirect_to effective_orders.admin_order_path(@order))
156
+ if respond_to?(:redirect_back)
157
+ redirect_back(fallback_location: effective_orders.admin_order_path(@order))
158
+ elsif request.referrer.present?
159
+ redirect_to :back
160
+ else
161
+ redirect_to effective_orders.admin_order_path(@order)
162
+ end
163
+ end
164
+
165
+ def bulk_send_payment_request
166
+ @orders = Effective::Order.pending.where(id: params[:ids])
167
+
168
+ begin
169
+ authorize_effective_order!
170
+
171
+ @orders.each { |order| order.send_payment_request_to_buyer! }
172
+ render json: { status: 200, message: "Successfully sent #{@orders.length} payment request emails"}
173
+ rescue => e
174
+ render json: { status: 500, message: "Bulk send payment request error: #{e.message}" }
175
+ end
139
176
  end
140
177
 
141
178
  private
@@ -152,9 +189,13 @@ module Admin
152
189
  )
153
190
  end
154
191
 
192
+ def checkout_params
193
+ params.require(:effective_order).permit(EffectiveOrders.permitted_params)
194
+ end
195
+
155
196
  def authorize_effective_order!
156
- EffectiveOrders.authorized?(self, :admin, :effective_orders)
157
- EffectiveOrders.authorized?(self, action_name.to_sym, @order || Effective::Order)
197
+ EffectiveOrders.authorize!(self, :admin, :effective_orders)
198
+ EffectiveOrders.authorize!(self, action_name.to_sym, @order || Effective::Order)
158
199
  end
159
200
 
160
201
  def admin_redirect_path
@@ -165,13 +206,18 @@ module Admin
165
206
 
166
207
  return path if path.present?
167
208
 
168
- case params[:commit]
169
- when 'Save and Add New'
170
- effective_orders.new_admin_order_path(user_id: @order.user.try(:to_param))
171
- when 'Save and Mark as Paid'
172
- effective_orders.mark_as_paid_admin_order_path(@order)
173
- else
174
- effective_orders.admin_order_path(@order)
209
+ case params[:commit].to_s
210
+ when 'Save' ; effective_orders.admin_order_path(@order)
211
+
212
+ when 'Save and Continue' ; effective_orders.admin_orders_path
213
+ when 'Save and Add New' ; effective_orders.new_admin_order_path(user_id: @order.user.try(:to_param))
214
+ when 'Save and Duplicate' ; effective_orders.new_admin_order_path(duplicate_id: @order.to_param)
215
+
216
+ when 'Continue' ; effective_orders.admin_orders_path
217
+ when 'Add New' ; effective_orders.new_admin_order_path(user_id: @order.user.try(:to_param))
218
+ when 'Duplicate' ; effective_orders.new_admin_order_path(duplicate_id: @order.to_param)
219
+
220
+ else effective_orders.admin_order_path(@order)
175
221
  end
176
222
  end
177
223