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
@@ -1,28 +0,0 @@
1
- stripeCheckoutHandler = (key, form) ->
2
- StripeCheckout.configure
3
- key: key
4
- token: (token, args) ->
5
- if token.error
6
- form.find("input[type='submit']").removeAttr('disabled')
7
- alert("An error ocurred when contacting Stripe. Your card has not been charged. Please refresh the page and try again. #{token.error.message}")
8
- else
9
- form.find("input[type='submit']").prop('disabled', true)
10
- form.find('input#effective_providers_stripe_subscription_token').val('' + token['id'])
11
- form.submit()
12
-
13
- $(document).on 'click', "#effective-orders-new-subscription-form form input[type='submit']", (event) ->
14
- event.preventDefault()
15
-
16
- obj = $('#effective-orders-new-subscription-form')
17
- form = obj.find('form').first()
18
- plan = form.find('option:selected')
19
-
20
- if plan.length > 0
21
- form.find("input[type='submit']").prop('disabled', true)
22
-
23
- stripeCheckoutHandler(obj.data('stripe-publishable-key'), form).open
24
- name: obj.data('site-title')
25
- email: obj.data('user-email')
26
- description: plan.text()
27
- panelLabel: 'Start Subscription'
28
- closed: -> form.find("input[type='submit']").removeAttr('disabled')
@@ -1,69 +0,0 @@
1
- module ActsAsActiveAdminController
2
- extend ActiveSupport::Concern
3
-
4
- module ActionController
5
- def acts_as_active_admin_controller(element_lookup_key)
6
- @active_admin_resource_element_lookup_key = element_lookup_key
7
- include ::ActsAsActiveAdminController
8
- end
9
- end
10
-
11
- included do
12
- include ActiveAdmin::BaseController::Menu
13
- include ActiveAdmin::BaseController::Authorization
14
-
15
- helper ActiveAdmin::ViewHelpers
16
- helper_method :active_admin_config, :active_admin_namespace, :current_active_admin_user, :current_active_admin_user?, :env
17
-
18
- resource_key = @active_admin_resource_element_lookup_key.to_s
19
- self.send(:define_method, :active_admin_resource_element_key) { resource_key }
20
-
21
- resource_ivar = '@' + resource_key.singularize
22
- self.send(:define_method, :resource) { instance_variable_get(resource_ivar) }
23
-
24
- resource_path = "effective_orders.#{resource_key.singularize}_path"
25
-
26
- if resource_path == 'effective_orders.cart_path'
27
- self.send(:define_method, :resource_path) { |resource| effective_orders.cart_path }
28
- else
29
- self.send(:define_method, :resource_path) { |resource| public_send(resource_path, resource) }
30
- self.send(:define_method, :edit_resource_path) { |resource| effective_orders.edit_order_path(resource) }
31
- end
32
-
33
- helper_method :resource, :resource_path, :edit_resource_path
34
- end
35
-
36
- module ClassMethods
37
- end
38
-
39
- def active_admin_namespace
40
- ActiveAdmin.application.namespaces[EffectiveOrders.active_admin_namespace || :root]
41
- end
42
-
43
- def active_admin_config
44
- active_admin_namespace.resources[active_admin_resource_key]
45
- end
46
-
47
- def active_admin_resource_key
48
- @active_admin_resource_key ||= begin
49
- namespace = ActiveAdmin.application.namespaces[EffectiveOrders.active_admin_namespace || :root]
50
- namespace.resources.keys.find { |resource| resource.element == active_admin_resource_element_key }
51
- end
52
- end
53
-
54
- # Calls the authentication method as defined in ActiveAdmin.authentication_method
55
- def authenticate_active_admin_user
56
- send(active_admin_namespace.authentication_method) if active_admin_namespace.authentication_method
57
- end
58
-
59
- def current_active_admin_user
60
- send(active_admin_namespace.current_user_method) if active_admin_namespace.current_user_method
61
- end
62
-
63
- def current_active_admin_user?
64
- !!current_active_admin_user
65
- end
66
-
67
-
68
- end
69
-
@@ -1,126 +0,0 @@
1
- module Effective
2
- class SubscriptionsController < ApplicationController
3
- include EffectiveCartsHelper
4
- include EffectiveStripeHelper
5
-
6
- layout (EffectiveOrders.layout.kind_of?(Hash) ? EffectiveOrders.layout[:subscriptions] : EffectiveOrders.layout)
7
-
8
- respond_to?(:before_action) ? before_action(:authenticate_user!) : before_filter(:authenticate_user!) # Devise
9
- respond_to?(:before_action) ? before_action(:assign_customer) : before_filter(:assign_customer)
10
-
11
- # This is a 'My Subscriptions' page
12
- def index
13
- @page_title ||= 'My Subscriptions'
14
-
15
- @subscriptions = @customer.subscriptions.purchased
16
- @active_stripe_subscription = @subscriptions.map(&:stripe_subscription).find do |subscription|
17
- subscription.present? && subscription.status == 'active' && subscription.current_period_end > Time.zone.now.to_i
18
- end
19
-
20
- EffectiveOrders.authorized?(self, :index, Effective::Subscription)
21
- end
22
-
23
- def new
24
- @page_title ||= 'New Subscription'
25
-
26
- @subscription = @customer.subscriptions.new()
27
-
28
- purchased_plans = @customer.subscriptions.purchased.map(&:stripe_plan_id)
29
- @plans = Stripe::Plan.all.reject { |stripe_plan| purchased_plans.include?(stripe_plan.id) }
30
-
31
- EffectiveOrders.authorized?(self, :new, @subscription)
32
- end
33
-
34
- def create
35
- @page_title ||= 'New Subscription'
36
-
37
- # Don't let the user create another Subscription object if it's already created
38
- @subscription = @customer.subscriptions.where(:stripe_plan_id => subscription_params[:stripe_plan_id]).first_or_initialize
39
-
40
- EffectiveOrders.authorized?(self, :create, @subscription)
41
-
42
- if @subscription.update_attributes(subscription_params) && (current_cart.find(@subscription).present? || current_cart.add(@subscription))
43
- flash[:success] = "Successfully added subscription to cart."
44
- redirect_to effective_orders.new_order_path
45
- else
46
- purchased_plans = @customer.subscriptions.purchased.map(&:stripe_plan_id)
47
- @plans = Stripe::Plan.all.reject { |stripe_plan| purchased_plans.include?(stripe_plan.id) }
48
-
49
- flash[:danger] ||= 'Unable to add subscription to cart. Please try again.'
50
- render :action => :new
51
- end
52
- end
53
-
54
- def show
55
- @plan = Stripe::Plan.retrieve(params[:id])
56
-
57
- unless @plan.present?
58
- flash[:danger] = "Unrecognized Stripe Plan: #{params[:id]}"
59
- raise ActiveRecord::RecordNotFound
60
- end
61
-
62
- @subscription = @customer.subscriptions.find { |subscription| subscription.stripe_plan_id == params[:id] }
63
-
64
- unless @subscription.present?
65
- flash[:danger] = "Unable to find Customer Subscription for plan: #{params[:id]}"
66
- raise ActiveRecord::RecordNotFound
67
- end
68
-
69
- @stripe_subscription = @subscription.try(:stripe_subscription)
70
-
71
- unless @stripe_subscription.present?
72
- flash[:danger] = "Unable to find Stripe Subscription for plan: #{params[:id]}"
73
- raise ActiveRecord::RecordNotFound
74
- end
75
-
76
- EffectiveOrders.authorized?(self, :show, @subscription)
77
-
78
- @invoices = @customer.stripe_customer.invoices.all.select do |invoice|
79
- invoice.lines.any? { |line| line.id == @stripe_subscription.id }
80
- end
81
-
82
- @page_title ||= "#{@plan.name}"
83
- end
84
-
85
- def destroy
86
- @plan = Stripe::Plan.retrieve(params[:id])
87
- raise ActiveRecord::RecordNotFound unless @plan.present?
88
-
89
- @subscription = @customer.subscriptions.find { |subscription| subscription.stripe_plan_id == params[:id] }
90
- @stripe_subscription = @subscription.try(:stripe_subscription)
91
- raise ActiveRecord::RecordNotFound unless @subscription.present?
92
-
93
- EffectiveOrders.authorized?(self, :destroy, @subscription)
94
-
95
- if @subscription.present?
96
- begin
97
- @stripe_subscription.delete if @stripe_subscription
98
- @subscription.destroy
99
- flash[:success] = "Successfully unsubscribed from #{params[:id]}"
100
- rescue => e
101
- flash[:danger] = "Unable to unsubscribe. Message: \"#{e.message}\"."
102
- end
103
- else
104
- flash[:danger] = "Unable to find stripe subscription for #{params[:id]}" unless @subscription.present?
105
- end
106
-
107
- redirect_to effective_orders.subscriptions_path
108
- end
109
-
110
- private
111
-
112
- def assign_customer
113
- @customer ||= Customer.for_user(current_user)
114
- end
115
-
116
- # StrongParameters
117
- def subscription_params
118
- begin
119
- params.require(:effective_subscription).permit(:stripe_plan_id, :stripe_coupon_id)
120
- rescue => e
121
- params[:effective_subscription]
122
- end
123
- end
124
-
125
- end
126
- end
@@ -1,40 +0,0 @@
1
- if Gem::Version.new(EffectiveDatatables::VERSION) < Gem::Version.new('3.0')
2
- module Effective
3
- module Datatables
4
- class Customers < Effective::Datatable
5
- datatable do
6
- default_order :email, :asc
7
-
8
- table_column :id, visible: false
9
- table_column(:email, column: 'users.email') { |user| mail_to user.email, user.email }
10
-
11
- if EffectiveOrders.stripe_enabled
12
- table_column :stripe_customer_id
13
- table_column :stripe_active_card
14
- end
15
-
16
- if EffectiveOrders.stripe_connect_enabled
17
- table_column :stripe_connect_access_token
18
- end
19
-
20
- table_column :subscription_types, column: 'subscription_types'
21
-
22
- actions_column partial: 'admin/customers/actions'
23
- end
24
-
25
- def collection
26
- Effective::Customer.customers.uniq
27
- .joins(:user, :subscriptions)
28
- .select('customers.*, users.email AS email')
29
- .select("array_to_string(array(#{Effective::Subscription.purchased.select('subscriptions.stripe_plan_id').where('subscriptions.customer_id = customers.id').to_sql}), ' ,') AS subscription_types")
30
- .group('customers.id, subscriptions.stripe_plan_id, users.email')
31
- end
32
-
33
- def search_column(collection, table_column, search_term)
34
- return collection.where('subscriptions.stripe_plan_id ILIKE ?', "%#{search_term}%") if table_column[:name] == 'subscription_types'
35
- super
36
- end
37
- end
38
- end
39
- end
40
- end
@@ -1,101 +0,0 @@
1
- if Gem::Version.new(EffectiveDatatables::VERSION) < Gem::Version.new('3.0')
2
- module Effective
3
- module Datatables
4
- class OrderItems < Effective::Datatable
5
- datatable do
6
- default_order :purchased_at, :desc
7
-
8
- table_column(:purchased_at, type: :datetime, column: 'orders.purchased_at') do |order_item|
9
- Time.at(order_item[:purchased_at]).in_time_zone if order_item[:purchased_at].present?
10
- end
11
-
12
- table_column :id, visible: false
13
-
14
- if EffectiveOrders.obfuscate_order_ids
15
- table_column(:order, type: :obfuscated_id, sortable: false) do |order_item|
16
- obfuscated_id = Effective::Order.obfuscate(order_item[:order_id])
17
- link_to(obfuscated_id, (datatables_admin_path? ? effective_orders.admin_order_path(obfuscated_id) : effective_orders.order_path(obfuscated_id)))
18
- end
19
- else
20
- table_column(:order, sortable: false) do |order_item|
21
- link_to(order_item.to_param, (datatables_admin_path? ? effective_orders.admin_order_path(order_item.to_param) : effective_orders.order_path(order_item.to_param)))
22
- end
23
- end
24
-
25
- table_column :email, column: 'users.email', label: 'Buyer Email', if: proc { attributes[:user_id].blank? } do |order_item|
26
- link_to order_item[:email], (edit_admin_user_path(order_item[:user_id]) rescue admin_user_path(order_item[:user_id]) rescue '#')
27
- end
28
-
29
- if EffectiveOrders.require_billing_address
30
- table_column :buyer_name, sortable: false, label: 'Buyer Name', if: proc { attributes[:user_id].blank? } do |order_item|
31
- (order_item[:buyer_name] || '').split('!!SEP!!').find(&:present?)
32
- end
33
- end
34
-
35
- table_column :purchase_state, column: 'orders.purchase_state', filter: { type: :select, values: [%w(abandoned abandoned), [EffectiveOrders::PURCHASED, EffectiveOrders::PURCHASED], [EffectiveOrders::DECLINED, EffectiveOrders::DECLINED]], selected: EffectiveOrders::PURCHASED } do |order_item|
36
- order_item[:purchase_state] || 'abandoned'
37
- end
38
-
39
- table_column :title do |order_item|
40
- order_item.quantity == 1 ? order_item.title : "#{order_item.title} (#{order_item.quantity} purchased)"
41
- end
42
-
43
- table_column(:subtotal) { |order_item| price_to_currency(order_item[:subtotal].to_i) }
44
- table_column(:tax) { |order_item| price_to_currency(order_item[:tax].to_i) }
45
- table_column(:total) { |order_item| price_to_currency(order_item[:total].to_i) }
46
-
47
- table_column :created_at, visible: false
48
- table_column :updated_at, visible: false
49
- end
50
-
51
- def collection
52
- collection = Effective::OrderItem.unscoped
53
- .joins(order: :user)
54
- .select('order_items.*, orders.*, users.email AS email')
55
- .select("#{query_subtotal} AS subtotal, #{query_tax} AS tax, #{query_total} AS total")
56
- .group('order_items.id, orders.id, users.email')
57
-
58
- if EffectiveOrders.require_billing_address && defined?(EffectiveAddresses)
59
- addresses_tbl = EffectiveAddresses.addresses_table_name
60
-
61
- collection = collection
62
- .joins("LEFT JOIN (SELECT addressable_id, string_agg(#{addresses_tbl}.full_name, '!!SEP!!') AS buyer_name FROM #{addresses_tbl} WHERE #{addresses_tbl}.category = 'billing' AND #{addresses_tbl}.addressable_type = 'Effective::Order' GROUP BY #{addresses_tbl}.addressable_id) #{addresses_tbl} ON orders.id = #{addresses_tbl}.addressable_id")
63
- .group("#{addresses_tbl}.buyer_name")
64
- .select("#{addresses_tbl}.buyer_name AS buyer_name")
65
- end
66
-
67
- attributes[:user_id].present? ? collection.where("#{EffectiveOrders.orders_table_name.to_s}.user_id = ?", attributes[:user_id]) : collection
68
- end
69
-
70
- def query_subtotal
71
- 'SUM(price * quantity)'
72
- end
73
-
74
- def query_total
75
- 'SUM((price * quantity) + (CASE tax_exempt WHEN true THEN 0 ELSE ((price * quantity) * tax_rate) END))'
76
- end
77
-
78
- def query_tax
79
- '(CASE tax_exempt WHEN true THEN 0 ELSE ((price * quantity) * tax_rate) END)'
80
- end
81
-
82
- def search_column(collection, table_column, search_term)
83
- if table_column[:name] == 'order'
84
- collection.where("#{EffectiveOrders.order_items_table_name.to_s}.order_id = ?", Effective::Order.deobfuscate(search_term))
85
- elsif table_column[:name] == 'purchase_state' && search_term == 'abandoned'
86
- collection.where("#{EffectiveOrders.orders_table_name.to_s}.purchase_state IS NULL")
87
- elsif table_column[:name] == 'subtotal'
88
- collection.having("#{query_subtotal} = ?", (search_term.gsub(/[^0-9.]/, '').to_f * 100.0).to_i)
89
- elsif table_column[:name] == 'tax'
90
- collection.having("#{query_tax} = ?", (search_term.gsub(/[^0-9.]/, '').to_f * 100.0).to_i)
91
- elsif table_column[:name] == 'total'
92
- collection.having("#{query_total} = ?", (search_term.gsub(/[^0-9.]/, '').to_f * 100.0).to_i)
93
- else
94
- super
95
- end
96
- end
97
-
98
- end
99
- end
100
- end
101
- end
@@ -1,91 +0,0 @@
1
- module Effective
2
- module Datatables
3
- class Orders < Effective::Datatable
4
- datatable do
5
- default_order :created_at, :desc
6
-
7
- table_column :purchased_at
8
-
9
- table_column :id, label: 'ID' do |order|
10
- link_to order.to_param, effective_orders.admin_order_path(order)
11
- end
12
-
13
- # Don't display email or buyer_name column if this is for a specific user
14
- if attributes[:user_id].blank?
15
- table_column :email, column: 'users.email', label: 'Buyer Email' do |order|
16
- link_to order.user.email, (edit_admin_user_path(order.user) rescue admin_user_path(order.user) rescue '#')
17
- end
18
-
19
- if EffectiveOrders.use_address_full_name
20
- table_column :buyer_name, column: 'addresses.full_name' do |order|
21
- order.billing_address.try(:full_name)
22
- end
23
-
24
- elsif # Not using address full name
25
- table_column :buyer_name, column: 'users.*' do |order|
26
- order.user.to_s
27
- end
28
- end
29
- end
30
-
31
- if EffectiveOrders.require_billing_address
32
- table_column :billing_address
33
- end
34
-
35
- if EffectiveOrders.require_shipping_address
36
- table_column :shipping_address
37
- end
38
-
39
- table_column :purchase_state, label: 'State', filter: { values: purchase_state_filter_values } do |order|
40
- order.purchase_state || 'abandoned'
41
- end
42
-
43
- table_column :order_items, column: 'order_items.title', filter: :string
44
-
45
- table_column :subtotal, as: :price
46
- table_column :tax, as: :price
47
-
48
- table_column :tax_rate, visible: false do |order|
49
- tax_rate_to_percentage(order.tax_rate)
50
- end
51
-
52
- table_column :total, as: :price
53
-
54
- table_column :payment_provider, label: 'Provider', visible: false, filter: { values: ['nil'] + (EffectiveOrders.payment_providers + EffectiveOrders.other_payment_providers).sort }
55
- table_column :payment_card, label: 'Card'
56
-
57
- table_column :note, visible: false
58
- table_column :note_to_buyer, visible: false
59
- table_column :note_internal, visible: false
60
-
61
- table_column :created_at, visible: false
62
- table_column :updated_at, visible: false
63
-
64
- actions_column partial: 'admin/orders/actions'
65
- end
66
-
67
- def collection
68
- collection = Effective::Order.unscoped
69
- .joins(:user)
70
- .includes(:addresses)
71
- .includes(:user)
72
- .includes(:order_items)
73
-
74
- if EffectiveOrders.orders_collection_scope.respond_to?(:call)
75
- collection = EffectiveOrders.orders_collection_scope.call(collection)
76
- end
77
-
78
- attributes[:user_id].present? ? collection.where(user_id: attributes[:user_id]) : collection
79
- end
80
-
81
- def purchase_state_filter_values
82
- [
83
- %w(abandoned nil),
84
- [EffectiveOrders::PURCHASED, EffectiveOrders::PURCHASED],
85
- [EffectiveOrders::DECLINED, EffectiveOrders::DECLINED],
86
- [EffectiveOrders::PENDING, EffectiveOrders::PENDING]
87
- ]
88
- end
89
- end
90
- end
91
- end