effective_orders 2.2.4 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +124 -84
  4. data/app/assets/javascripts/effective_orders/customers.js.coffee +39 -0
  5. data/app/assets/javascripts/effective_orders/providers/{stripe_charges.js.coffee → stripe.js.coffee} +15 -13
  6. data/app/assets/javascripts/effective_orders/subscriptions.js.coffee +73 -0
  7. data/app/assets/stylesheets/effective_orders.scss +2 -1
  8. data/app/assets/stylesheets/effective_orders/_order.scss +16 -8
  9. data/app/assets/stylesheets/effective_orders/_subscriptions.scss +14 -0
  10. data/app/controllers/admin/customers_controller.rb +11 -8
  11. data/app/controllers/admin/order_items_controller.rb +4 -8
  12. data/app/controllers/admin/orders_controller.rb +133 -87
  13. data/app/controllers/effective/carts_controller.rb +18 -8
  14. data/app/controllers/effective/concerns/purchase.rb +39 -0
  15. data/app/controllers/effective/customers_controller.rb +43 -0
  16. data/app/controllers/effective/orders_controller.rb +73 -119
  17. data/app/controllers/effective/providers/app_checkout.rb +3 -1
  18. data/app/controllers/effective/providers/ccbill.rb +4 -6
  19. data/app/controllers/effective/providers/cheque.rb +20 -11
  20. data/app/controllers/effective/providers/free.rb +33 -0
  21. data/app/controllers/effective/providers/mark_as_paid.rb +33 -0
  22. data/app/controllers/effective/providers/moneris.rb +9 -17
  23. data/app/controllers/effective/providers/paypal.rb +4 -6
  24. data/app/controllers/effective/providers/pretend.rb +4 -4
  25. data/app/controllers/effective/providers/refund.rb +39 -0
  26. data/app/controllers/effective/providers/stripe.rb +19 -40
  27. data/app/controllers/effective/providers/stripe_connect.rb +2 -6
  28. data/app/controllers/effective/webhooks_controller.rb +44 -95
  29. data/app/datatables/effective_customers_datatable.rb +21 -29
  30. data/app/datatables/effective_order_items_datatable.rb +77 -79
  31. data/app/datatables/effective_orders_datatable.rb +67 -57
  32. data/app/helpers/effective_carts_helper.rb +17 -14
  33. data/app/helpers/effective_orders_helper.rb +40 -56
  34. data/app/helpers/effective_paypal_helper.rb +3 -3
  35. data/app/helpers/effective_stripe_helper.rb +47 -18
  36. data/app/helpers/effective_subscriptions_helper.rb +79 -0
  37. data/app/mailers/effective/orders_mailer.rb +125 -2
  38. data/app/models/concerns/acts_as_purchasable.rb +23 -33
  39. data/app/models/concerns/acts_as_subscribable.rb +68 -0
  40. data/app/models/concerns/acts_as_subscribable_buyer.rb +22 -0
  41. data/app/models/effective/cart.rb +53 -24
  42. data/app/models/effective/cart_item.rb +6 -12
  43. data/app/models/effective/customer.rb +51 -54
  44. data/app/models/effective/order.rb +160 -147
  45. data/app/models/effective/order_item.rb +18 -21
  46. data/app/models/effective/product.rb +7 -7
  47. data/app/models/effective/providers/ccbill_postback.rb +1 -1
  48. data/app/models/effective/providers/stripe_charge.rb +8 -19
  49. data/app/models/effective/subscripter.rb +230 -0
  50. data/app/models/effective/subscription.rb +27 -76
  51. data/app/models/effective/tax_rate_calculator.rb +10 -7
  52. data/app/views/admin/customers/_actions.html.haml +1 -2
  53. data/app/views/admin/customers/index.html.haml +1 -1
  54. data/app/views/admin/customers/show.html.haml +6 -0
  55. data/app/views/admin/orders/_actions.html.haml +9 -7
  56. data/app/views/admin/orders/_form.html.haml +11 -7
  57. data/app/views/admin/orders/_order_actions.html.haml +2 -1
  58. data/app/views/admin/orders/_order_item_fields.html.haml +1 -1
  59. data/app/views/admin/orders/edit.html.haml +4 -0
  60. data/app/views/admin/orders/index.html.haml +1 -4
  61. data/app/views/admin/orders/new.html.haml +1 -1
  62. data/app/views/admin/orders/show.html.haml +5 -6
  63. data/app/views/effective/carts/_cart.html.haml +2 -2
  64. data/app/views/effective/carts/show.html.haml +2 -2
  65. data/app/views/effective/customers/_customer.html.haml +152 -0
  66. data/app/views/effective/customers/_fields.html.haml +12 -0
  67. data/app/views/effective/customers/_form.html.haml +13 -0
  68. data/app/views/effective/customers/edit.html.haml +3 -0
  69. data/app/views/effective/orders/_checkout_step1.html.haml +8 -15
  70. data/app/views/effective/orders/_checkout_step2.html.haml +34 -21
  71. data/app/views/effective/orders/_order.html.haml +8 -9
  72. data/app/views/effective/orders/_order_actions.html.haml +7 -8
  73. data/app/views/effective/orders/_order_header.html.haml +1 -1
  74. data/app/views/effective/orders/_order_items.html.haml +11 -5
  75. data/app/views/effective/orders/_order_note.html.haml +4 -7
  76. data/app/views/effective/orders/_orders_table.html.haml +26 -26
  77. data/app/views/effective/orders/app_checkout/_form.html.haml +2 -2
  78. data/app/views/effective/orders/ccbill/_form.html.haml +1 -1
  79. data/app/views/effective/orders/cheque/_form.html.haml +3 -1
  80. data/app/views/effective/orders/declined.html.haml +1 -1
  81. data/app/views/effective/orders/{checkout_step1.html.haml → edit.html.haml} +0 -0
  82. data/app/views/effective/orders/free/_form.html.haml +4 -0
  83. data/app/views/effective/orders/index.html.haml +2 -4
  84. data/app/views/effective/orders/mark_as_paid/_form.html.haml +32 -0
  85. data/app/views/effective/orders/moneris/_form.html.haml +6 -6
  86. data/app/views/effective/orders/{checkout_step2.html.haml → new.html.haml} +1 -1
  87. data/app/views/effective/orders/paypal/_form.html.haml +2 -2
  88. data/app/views/effective/orders/pretend/_form.html.haml +2 -2
  89. data/app/views/effective/orders/purchased.html.haml +3 -0
  90. data/app/views/effective/orders/refund/_form.html.haml +32 -0
  91. data/app/views/effective/orders/show.html.haml +4 -1
  92. data/app/views/effective/orders/stripe/_form.html.haml +5 -5
  93. data/app/views/effective/orders_mailer/subscription_canceled.html.haml +9 -0
  94. data/app/views/effective/orders_mailer/subscription_payment_failed.html.haml +9 -0
  95. data/app/views/effective/orders_mailer/subscription_payment_succeeded.html.haml +9 -0
  96. data/app/views/effective/orders_mailer/subscription_trial_expired.html.haml +5 -0
  97. data/app/views/effective/orders_mailer/subscription_trial_expiring.html.haml +7 -0
  98. data/app/views/effective/subscriptions/_fields.html.haml +16 -0
  99. data/app/views/effective/subscriptions/_plan.html.haml +21 -0
  100. data/app/views/layouts/effective_orders_mailer_layout.html.haml +6 -8
  101. data/config/effective_orders.rb +41 -20
  102. data/config/routes.rb +48 -48
  103. data/db/migrate/01_create_effective_orders.rb.erb +19 -5
  104. data/lib/effective_orders.rb +78 -42
  105. data/lib/effective_orders/engine.rb +36 -82
  106. data/lib/effective_orders/version.rb +1 -1
  107. data/lib/generators/effective_orders/install_generator.rb +2 -2
  108. data/lib/generators/templates/effective_orders_mailer_preview.rb +39 -4
  109. data/lib/tasks/effective_orders_tasks.rake +42 -0
  110. data/spec/controllers/carts_controller_spec.rb +1 -1
  111. data/spec/controllers/moneris_orders_controller_spec.rb +4 -4
  112. data/spec/controllers/orders_controller_spec.rb +4 -4
  113. data/spec/controllers/stripe_orders_controller_spec.rb +2 -2
  114. data/spec/controllers/webhooks_controller_spec.rb +1 -1
  115. data/spec/dummy/config/initializers/effective_orders.rb +1 -7
  116. data/spec/dummy/db/schema.rb +1 -0
  117. data/spec/dummy/db/test.sqlite3 +0 -0
  118. data/spec/dummy/log/test.log +3 -0
  119. data/spec/models/acts_as_purchasable_spec.rb +0 -56
  120. data/spec/models/customer_spec.rb +3 -3
  121. data/spec/models/order_spec.rb +2 -2
  122. data/spec/spec_helper.rb +1 -1
  123. data/spec/support/factories.rb +2 -1
  124. metadata +37 -49
  125. data/active_admin/effective_carts.rb +0 -14
  126. data/active_admin/effective_orders.rb +0 -112
  127. data/app/assets/javascripts/effective_orders/providers/stripe_subscriptions.js.coffee +0 -28
  128. data/app/controllers/concerns/acts_as_active_admin_controller.rb +0 -69
  129. data/app/controllers/effective/subscriptions_controller.rb +0 -126
  130. data/app/models/effective/datatables/customers.rb +0 -40
  131. data/app/models/effective/datatables/order_items.rb +0 -101
  132. data/app/models/effective/datatables/orders.rb +0 -91
  133. data/app/models/inputs/price_field.rb +0 -63
  134. data/app/models/inputs/price_form_input.rb +0 -7
  135. data/app/models/inputs/price_formtastic_input.rb +0 -9
  136. data/app/models/inputs/price_input.rb +0 -19
  137. data/app/models/inputs/price_simple_form_input.rb +0 -8
  138. data/app/views/admin/orders/_form_mark_as_paid.html.haml +0 -33
  139. data/app/views/admin/orders/_order_payment_details.html.haml +0 -5
  140. data/app/views/admin/orders/mark_as_paid.html.haml +0 -7
  141. data/app/views/effective/orders/stripe/_subscription_fields.html.haml +0 -7
  142. data/app/views/effective/subscriptions/index.html.haml +0 -22
  143. data/app/views/effective/subscriptions/new.html.haml +0 -9
  144. data/app/views/effective/subscriptions/show.html.haml +0 -49
  145. data/db/upgrade/02_upgrade_effective_orders_from03x.rb.erb +0 -29
  146. data/db/upgrade/03_upgrade_effective_orders_from1x.rb.erb +0 -98
  147. data/db/upgrade/upgrade_price_column_on_table.rb.erb +0 -17
  148. data/lib/generators/effective_orders/upgrade_from03x_generator.rb +0 -31
  149. data/lib/generators/effective_orders/upgrade_from1x_generator.rb +0 -27
  150. data/lib/generators/effective_orders/upgrade_price_column_generator.rb +0 -30
@@ -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