effective_orders 4.5.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 (135) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +1004 -0
  4. data/app/assets/images/effective_orders/stripe.png +0 -0
  5. data/app/assets/javascripts/effective_orders.js +6 -0
  6. data/app/assets/javascripts/effective_orders/customers.js.coffee +32 -0
  7. data/app/assets/javascripts/effective_orders/providers/stripe.js.coffee +77 -0
  8. data/app/assets/javascripts/effective_orders/subscriptions.js.coffee +81 -0
  9. data/app/assets/stylesheets/effective_orders.scss +2 -0
  10. data/app/assets/stylesheets/effective_orders/_cart.scss +4 -0
  11. data/app/assets/stylesheets/effective_orders/_order.scss +58 -0
  12. data/app/controllers/admin/customers_controller.rb +24 -0
  13. data/app/controllers/admin/order_items_controller.rb +16 -0
  14. data/app/controllers/admin/orders_controller.rb +223 -0
  15. data/app/controllers/effective/carts_controller.rb +85 -0
  16. data/app/controllers/effective/concerns/purchase.rb +62 -0
  17. data/app/controllers/effective/customers_controller.rb +20 -0
  18. data/app/controllers/effective/orders_controller.rb +162 -0
  19. data/app/controllers/effective/providers/cheque.rb +22 -0
  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 +60 -0
  23. data/app/controllers/effective/providers/paypal.rb +33 -0
  24. data/app/controllers/effective/providers/phone.rb +22 -0
  25. data/app/controllers/effective/providers/pretend.rb +26 -0
  26. data/app/controllers/effective/providers/refund.rb +33 -0
  27. data/app/controllers/effective/providers/stripe.rb +72 -0
  28. data/app/controllers/effective/subscripter_controller.rb +18 -0
  29. data/app/controllers/effective/webhooks_controller.rb +109 -0
  30. data/app/datatables/admin/effective_customers_datatable.rb +22 -0
  31. data/app/datatables/admin/effective_orders_datatable.rb +100 -0
  32. data/app/datatables/effective_orders_datatable.rb +79 -0
  33. data/app/helpers/effective_carts_helper.rb +113 -0
  34. data/app/helpers/effective_orders_helper.rb +143 -0
  35. data/app/helpers/effective_paypal_helper.rb +49 -0
  36. data/app/helpers/effective_stripe_helper.rb +85 -0
  37. data/app/helpers/effective_subscriptions_helper.rb +34 -0
  38. data/app/mailers/effective/orders_mailer.rb +196 -0
  39. data/app/models/concerns/acts_as_purchasable.rb +118 -0
  40. data/app/models/concerns/acts_as_subscribable.rb +90 -0
  41. data/app/models/concerns/acts_as_subscribable_buyer.rb +49 -0
  42. data/app/models/effective/access_denied.rb +17 -0
  43. data/app/models/effective/cart.rb +88 -0
  44. data/app/models/effective/cart_item.rb +40 -0
  45. data/app/models/effective/customer.rb +92 -0
  46. data/app/models/effective/order.rb +541 -0
  47. data/app/models/effective/order_item.rb +63 -0
  48. data/app/models/effective/product.rb +23 -0
  49. data/app/models/effective/sold_out_validator.rb +7 -0
  50. data/app/models/effective/subscripter.rb +185 -0
  51. data/app/models/effective/subscription.rb +95 -0
  52. data/app/models/effective/tax_rate_calculator.rb +48 -0
  53. data/app/views/admin/customers/_actions.html.haml +2 -0
  54. data/app/views/admin/customers/index.html.haml +6 -0
  55. data/app/views/admin/customers/show.html.haml +6 -0
  56. data/app/views/admin/order_items/index.html.haml +3 -0
  57. data/app/views/admin/orders/_datatable_actions.html.haml +18 -0
  58. data/app/views/admin/orders/_form.html.haml +35 -0
  59. data/app/views/admin/orders/_form_note_internal.html.haml +7 -0
  60. data/app/views/admin/orders/_order_actions.html.haml +9 -0
  61. data/app/views/admin/orders/_order_item_fields.html.haml +14 -0
  62. data/app/views/admin/orders/checkout.html.haml +3 -0
  63. data/app/views/admin/orders/edit.html.haml +6 -0
  64. data/app/views/admin/orders/index.html.haml +6 -0
  65. data/app/views/admin/orders/new.html.haml +4 -0
  66. data/app/views/admin/orders/show.html.haml +4 -0
  67. data/app/views/effective/carts/_cart.html.haml +28 -0
  68. data/app/views/effective/carts/_cart_actions.html.haml +3 -0
  69. data/app/views/effective/carts/show.html.haml +17 -0
  70. data/app/views/effective/customers/_customer.html.haml +72 -0
  71. data/app/views/effective/customers/_form.html.haml +21 -0
  72. data/app/views/effective/customers/edit.html.haml +4 -0
  73. data/app/views/effective/customers/update.js.erb +5 -0
  74. data/app/views/effective/orders/_checkout_actions.html.haml +3 -0
  75. data/app/views/effective/orders/_checkout_step1.html.haml +4 -0
  76. data/app/views/effective/orders/_checkout_step2.html.haml +37 -0
  77. data/app/views/effective/orders/_datatable_actions.html.haml +2 -0
  78. data/app/views/effective/orders/_fields.html.haml +31 -0
  79. data/app/views/effective/orders/_fields_note.html.haml +7 -0
  80. data/app/views/effective/orders/_fields_terms.html.haml +8 -0
  81. data/app/views/effective/orders/_order.html.haml +11 -0
  82. data/app/views/effective/orders/_order_actions.html.haml +18 -0
  83. data/app/views/effective/orders/_order_deferred.html.haml +9 -0
  84. data/app/views/effective/orders/_order_footer.html.haml +1 -0
  85. data/app/views/effective/orders/_order_header.html.haml +23 -0
  86. data/app/views/effective/orders/_order_items.html.haml +72 -0
  87. data/app/views/effective/orders/_order_notes.html.haml +17 -0
  88. data/app/views/effective/orders/_order_payment.html.haml +24 -0
  89. data/app/views/effective/orders/_order_shipping.html.haml +30 -0
  90. data/app/views/effective/orders/_orders_table.html.haml +23 -0
  91. data/app/views/effective/orders/cheque/_form.html.haml +4 -0
  92. data/app/views/effective/orders/declined.html.haml +12 -0
  93. data/app/views/effective/orders/deferred.html.haml +13 -0
  94. data/app/views/effective/orders/deferred/_form.html.haml +16 -0
  95. data/app/views/effective/orders/edit.html.haml +3 -0
  96. data/app/views/effective/orders/free/_form.html.haml +5 -0
  97. data/app/views/effective/orders/index.html.haml +3 -0
  98. data/app/views/effective/orders/mark_as_paid/_form.html.haml +23 -0
  99. data/app/views/effective/orders/moneris/_form.html.haml +47 -0
  100. data/app/views/effective/orders/new.html.haml +3 -0
  101. data/app/views/effective/orders/paypal/_form.html.haml +5 -0
  102. data/app/views/effective/orders/phone/_form.html.haml +4 -0
  103. data/app/views/effective/orders/pretend/_form.html.haml +8 -0
  104. data/app/views/effective/orders/purchased.html.haml +11 -0
  105. data/app/views/effective/orders/refund/_form.html.haml +5 -0
  106. data/app/views/effective/orders/show.html.haml +6 -0
  107. data/app/views/effective/orders/stripe/_element.html.haml +8 -0
  108. data/app/views/effective/orders/stripe/_form.html.haml +31 -0
  109. data/app/views/effective/orders_mailer/order_error.html.haml +11 -0
  110. data/app/views/effective/orders_mailer/order_receipt_to_admin.html.haml +2 -0
  111. data/app/views/effective/orders_mailer/order_receipt_to_buyer.html.haml +2 -0
  112. data/app/views/effective/orders_mailer/payment_request_to_buyer.html.haml +13 -0
  113. data/app/views/effective/orders_mailer/pending_order_invoice_to_buyer.html.haml +13 -0
  114. data/app/views/effective/orders_mailer/refund_notification_to_admin.html.haml +15 -0
  115. data/app/views/effective/orders_mailer/subscription_canceled.html.haml +9 -0
  116. data/app/views/effective/orders_mailer/subscription_created.html.haml +13 -0
  117. data/app/views/effective/orders_mailer/subscription_event_to_admin.html.haml +13 -0
  118. data/app/views/effective/orders_mailer/subscription_payment_failed.html.haml +9 -0
  119. data/app/views/effective/orders_mailer/subscription_payment_succeeded.html.haml +9 -0
  120. data/app/views/effective/orders_mailer/subscription_trial_expired.html.haml +5 -0
  121. data/app/views/effective/orders_mailer/subscription_trialing.html.haml +7 -0
  122. data/app/views/effective/orders_mailer/subscription_updated.html.haml +13 -0
  123. data/app/views/effective/subscripter/_form.html.haml +60 -0
  124. data/app/views/effective/subscripter/_plan.html.haml +23 -0
  125. data/app/views/layouts/effective_orders_mailer_layout.html.haml +25 -0
  126. data/config/effective_orders.rb +279 -0
  127. data/config/routes.rb +70 -0
  128. data/db/migrate/01_create_effective_orders.rb.erb +137 -0
  129. data/lib/effective_orders.rb +243 -0
  130. data/lib/effective_orders/engine.rb +60 -0
  131. data/lib/effective_orders/version.rb +3 -0
  132. data/lib/generators/effective_orders/install_generator.rb +63 -0
  133. data/lib/generators/templates/effective_orders_mailer_preview.rb +120 -0
  134. data/lib/tasks/effective_orders_tasks.rake +69 -0
  135. metadata +276 -0
@@ -0,0 +1,33 @@
1
+ module Effective
2
+ module Providers
3
+ module Paypal
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ skip_before_action :verify_authenticity_token, only: [:paypal_postback]
8
+ end
9
+
10
+ # TODO: Make paypal postback work with admin checkout workflow
11
+
12
+ def paypal_postback
13
+ @order ||= Effective::Order.where(id: (params[:invoice].to_i rescue 0)).first
14
+
15
+ (EffectiveOrders.authorize!(self, :update, @order) rescue false)
16
+
17
+ if @order.present?
18
+ if @order.purchased?
19
+ order_purchased(payment: params, provider: 'paypal', card: params[:payment_type])
20
+ elsif (params[:payment_status] == 'Completed' && params[:custom] == EffectiveOrders.paypal[:secret])
21
+ order_purchased(payment: params, provider: 'paypal', card: params[:payment_type])
22
+ else
23
+ order_declined(payment: params, provider: 'paypal', card: params[:payment_type])
24
+ end
25
+ end
26
+
27
+ head(:ok)
28
+ end
29
+
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,22 @@
1
+ module Effective
2
+ module Providers
3
+ module Phone
4
+ extend ActiveSupport::Concern
5
+
6
+ def phone
7
+ @order ||= Order.find(params[:id])
8
+
9
+ EffectiveOrders.authorize!(self, :update, @order)
10
+
11
+ flash[:success] = EffectiveOrders.phone[:success]
12
+
13
+ order_deferred(provider: 'phone', deferred_url: phone_params[:deferred_url])
14
+ end
15
+
16
+ def phone_params
17
+ params.require(:phone).permit(:deferred_url)
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,26 @@
1
+ module Effective
2
+ module Providers
3
+ module Pretend
4
+ extend ActiveSupport::Concern
5
+
6
+ def pretend
7
+ @order ||= Order.find(params[:id])
8
+
9
+ EffectiveOrders.authorize!(self, :update, @order)
10
+
11
+ order_purchased(
12
+ payment: 'for pretend',
13
+ provider: 'pretend',
14
+ card: 'none',
15
+ purchased_url: pretend_params[:purchased_url],
16
+ declined_url: pretend_params[:declined_url]
17
+ )
18
+ end
19
+
20
+ def pretend_params
21
+ params.require(:pretend).permit(:purchased_url, :declined_url)
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,33 @@
1
+ module Effective
2
+ module Providers
3
+ module Refund
4
+ extend ActiveSupport::Concern
5
+
6
+ def refund
7
+ @order ||= Order.find(params[:id])
8
+
9
+ EffectiveOrders.authorize!(self, :update, @order)
10
+
11
+ unless @order.refund?
12
+ flash[:danger] = 'Unable to process refund order with a positive total'
13
+ redirect_to effective_orders.order_path(@order)
14
+ return
15
+ end
16
+
17
+ flash[:success] = EffectiveOrders.refund[:success].presence
18
+
19
+ order_purchased(
20
+ payment: 'refund. no payment required.',
21
+ provider: 'refund',
22
+ purchased_url: refund_params[:purchased_url],
23
+ declined_url: refund_params[:declined_url]
24
+ )
25
+ end
26
+
27
+ def refund_params
28
+ params.require(:refund).permit(:purchased_url, :declined_url)
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,72 @@
1
+ module Effective
2
+ module Providers
3
+ module Stripe
4
+ extend ActiveSupport::Concern
5
+
6
+ def stripe
7
+ @order = Order.find(params[:id])
8
+ @customer = Effective::Customer.for_user(@order.user)
9
+
10
+ EffectiveOrders.authorize!(self, :update, @order)
11
+
12
+ payment = validate_stripe_payment(stripe_params[:payment_intent_id])
13
+
14
+ if payment.blank? || !payment.kind_of?(Hash)
15
+ return order_declined(payment: payment, provider: 'stripe', declined_url: stripe_params[:declined_url])
16
+ end
17
+
18
+ # Update the customer payment fields
19
+ if payment[:payment_method_id].present?
20
+ @customer.update!(payment.slice(:payment_method_id, :active_card))
21
+ end
22
+
23
+ order_purchased(
24
+ payment: payment,
25
+ provider: 'stripe',
26
+ card: payment[:card],
27
+ purchased_url: stripe_params[:purchased_url],
28
+ declined_url: stripe_params[:declined_url]
29
+ )
30
+ end
31
+
32
+ private
33
+
34
+ def stripe_params
35
+ params.require(:stripe).permit(:payment_intent_id, :purchased_url, :declined_url)
36
+ end
37
+
38
+ def validate_stripe_payment(payment_intent_id)
39
+ begin
40
+ intent = ::Stripe::PaymentIntent.retrieve(payment_intent_id)
41
+ raise('status is not succeeded') unless intent.status == 'succeeded'
42
+ raise('charges are not present') unless intent.charges.present?
43
+
44
+ charge = intent.charges.data.first
45
+ raise('charge not succeeded') unless charge.status == 'succeeded'
46
+
47
+ card = charge.payment_method_details.try(:card) || {}
48
+ active_card = "**** **** **** #{card['last4']} #{card['brand']} #{card['exp_month']}/#{card['exp_year']}" if card.present?
49
+
50
+ {
51
+ charge_id: charge.id,
52
+ payment_method_id: charge.payment_method,
53
+ payment_intent_id: intent.id,
54
+
55
+ active_card: active_card,
56
+ card: card['brand'],
57
+
58
+ amount: charge.amount,
59
+ created: charge.created,
60
+ currency: charge.currency,
61
+ customer: charge.customer,
62
+ status: charge.status
63
+ }.compact
64
+
65
+ rescue => e
66
+ e.message
67
+ end
68
+ end
69
+
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,18 @@
1
+ module Effective
2
+ class SubscripterController < ApplicationController
3
+ layout (EffectiveOrders.layout.kind_of?(Hash) ? EffectiveOrders.layout[:subscriptions] : EffectiveOrders.layout)
4
+
5
+ include Effective::CrudController
6
+
7
+ submit :save, 'Save', redirect: :back, success: -> { 'Successfully updated plan.' }
8
+
9
+ def resource
10
+ @subscripter ||= Effective::Subscripter.new(current_user: current_user)
11
+ end
12
+
13
+ # StrongParameters
14
+ def subscripter_params
15
+ params.require(:effective_subscripter).permit!
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,109 @@
1
+ # New workflow is:
2
+ # customer.updated
3
+ # customer.created
4
+ # customer.subscription.created
5
+ # customer.updated
6
+ # customer.source.created
7
+ # charge.succeeded
8
+ # invoice.created
9
+ # invoice.payment_succeeded
10
+
11
+ module Effective
12
+ class WebhooksController < ApplicationController
13
+ protect_from_forgery except: [:stripe]
14
+ skip_authorization_check if defined?(CanCan)
15
+
16
+ after_action :run_subscribable_buyer_callbacks!
17
+
18
+ def stripe
19
+ @event = (Stripe::Webhook.construct_event(request.body.read, request.env['HTTP_STRIPE_SIGNATURE'], EffectiveOrders.subscriptions[:webhook_secret]) rescue nil)
20
+ (head(:ok) and return) if request.get? && @event.blank?
21
+ (head(:bad_request) and return) unless @event
22
+
23
+ unless EffectiveOrders.subscriptions[:ignore_livemode]
24
+ (head(:bad_request) and return) if (params[:livemode] == false && Rails.env.production?)
25
+ end
26
+
27
+ Rails.logger.info "[STRIPE] webhook received: #{@event.type} for #{customer || 'no customer'}"
28
+
29
+ Effective::Customer.transaction do
30
+ case @event.type
31
+ # when 'customer.created'
32
+ # when 'customer.updated'
33
+ # when 'customer.source.created'
34
+ # when 'customer.source.deleted'
35
+ # when 'customer.subscription.created'
36
+ # when 'customer.subscription.updated'
37
+ # when 'invoice.created'
38
+ # when 'invoice.payment_succeeded'
39
+ # when 'invoiceitem.created'
40
+ # when 'invoiceitem.updated'
41
+ # when 'charge.succeeded'
42
+ # when 'charge.failed' # Card declined. 4000 0000 0000 0341
43
+
44
+ when 'invoice.payment_succeeded'
45
+ subscriptions.each { |subscription| subscription.update!(status: EffectiveOrders::ACTIVE) }
46
+ send_email(:subscription_payment_succeeded, customer)
47
+ when 'invoice.payment_failed'
48
+ subscriptions.each { |subscription| subscription.update!(status: EffectiveOrders::PAST_DUE) }
49
+ send_email(:subscription_payment_failed, customer)
50
+ when 'customer.subscription.deleted'
51
+ subscriptions.each { |subscription| subscription.destroy! }
52
+ send_email(:subscription_canceled, customer)
53
+ when 'customer.subscription.created'
54
+ send_email(:subscription_created, customer)
55
+ when 'customer.subscription.updated'
56
+ send_email(:subscription_updated, customer)
57
+ else
58
+ Rails.logger.info "[STRIPE] successful event: #{@event.type}. Nothing to do."
59
+ end
60
+ end
61
+
62
+ head(:ok)
63
+ end
64
+
65
+ private
66
+
67
+ def customer
68
+ return unless @event.respond_to?(:data)
69
+
70
+ @customer ||= (
71
+ stripe_customer_id = @event.data.object.customer if @event.data.object.respond_to?(:customer)
72
+ stripe_customer_id = @event.data.object.id if @event.data.object.object == 'customer'
73
+
74
+ Effective::Customer.where(stripe_customer_id: stripe_customer_id || 'none').first
75
+ )
76
+ end
77
+
78
+ def subscriptions
79
+ customer.subscriptions.select { |subscription| stripe_plan_ids.include?(subscription.stripe_plan_id) }
80
+ end
81
+
82
+ def stripe_plan_ids
83
+ return unless @event.respond_to?(:data)
84
+
85
+ @stripe_plan_ids ||= begin
86
+ object = @event.data.object
87
+ lines = object.respond_to?(:lines) ? object.lines : object.items
88
+ lines.map { |line| line.plan.id }
89
+ end
90
+ end
91
+
92
+ def send_email(email, *mailer_args)
93
+ Effective::OrdersMailer.public_send(email, *mailer_args).public_send(EffectiveOrders.mailer[:deliver_method])
94
+ Effective::OrdersMailer.public_send(:subscription_event_to_admin, email.to_s, *mailer_args).public_send(EffectiveOrders.mailer[:deliver_method])
95
+ end
96
+
97
+ def run_subscribable_buyer_callbacks!
98
+ return true if (@event.blank? || @customer.blank?)
99
+
100
+ name = ('after_' + @event.type.to_s.gsub('.', '_')).to_sym
101
+ buyer = @customer.user
102
+
103
+ buyer.public_send(name, @event) if buyer.respond_to?(name)
104
+
105
+ true
106
+ end
107
+
108
+ end
109
+ end
@@ -0,0 +1,22 @@
1
+ class Admin::EffectiveCustomersDatatable < Effective::Datatable
2
+ datatable do
3
+
4
+ col :id, visible: false
5
+ col :user
6
+ col 'user.email'
7
+
8
+ if EffectiveOrders.stripe?
9
+ col :stripe_customer_id
10
+ col :active_card
11
+ end
12
+
13
+ actions_col do |customer|
14
+ link_to('Manage', "https://dashboard.stripe.com/#{'test/' if Rails.env.development?}customers/#{customer.stripe_customer_id}")
15
+ end
16
+
17
+ end
18
+
19
+ collection do
20
+ Effective::Customer.joins(:user).all
21
+ end
22
+ end
@@ -0,0 +1,100 @@
1
+ class Admin::EffectiveOrdersDatatable < Effective::Datatable
2
+ bulk_actions do
3
+ bulk_action(
4
+ 'Send payment request email to selected orders',
5
+ effective_orders.bulk_send_payment_request_admin_orders_path,
6
+ data: { confirm: 'Send payment request emails?' }
7
+ )
8
+
9
+ bulk_action(
10
+ 'Send receipt email to selected purchased orders',
11
+ effective_orders.bulk_send_buyer_receipt_orders_path,
12
+ data: { confirm: 'Send receipt emails?' }
13
+ )
14
+ end
15
+
16
+ filters do
17
+ scope :purchased, default: true
18
+ scope :deferred
19
+ scope :refunds
20
+ scope :not_purchased
21
+ scope :all
22
+ end
23
+
24
+ datatable do
25
+ order :id, :desc
26
+
27
+ bulk_actions_col
28
+
29
+ col :created_at, visible: false
30
+ col :updated_at, visible: false
31
+
32
+ col :id, label: 'Number' do |order|
33
+ '#' + order.to_param
34
+ end
35
+
36
+ col :purchased_at do |order|
37
+ order.purchased_at&.strftime('%F %H:%M') || 'not purchased'
38
+ end
39
+
40
+ if attributes[:user_id].blank?
41
+ col :user
42
+ col :billing_name, visible: false
43
+ col :email, visible: false
44
+ end
45
+
46
+ col :cc, visible: false
47
+
48
+ if EffectiveOrders.billing_address
49
+ col :billing_address, visible: false
50
+ end
51
+
52
+ if EffectiveOrders.shipping_address
53
+ col :shipping_address, visible: false
54
+ end
55
+
56
+ col :order_items, search: { as: :string }
57
+
58
+ col :subtotal, as: :price, visible: false
59
+ col :tax, as: :price, visible: false
60
+
61
+ col :tax_rate, visible: false do |order|
62
+ tax_rate_to_percentage(order.tax_rate)
63
+ end
64
+
65
+ col :total, as: :price
66
+
67
+ col :payment_provider, label: 'Provider', visible: false, search: { collection: EffectiveOrders.payment_providers }
68
+ col :payment_card, label: 'Card', visible: false
69
+
70
+ if EffectiveOrders.collect_note
71
+ col :note, visible: false
72
+ end
73
+
74
+ col :note_to_buyer, visible: false
75
+ col :note_internal, visible: false
76
+
77
+ actions_col partial: 'admin/orders/datatable_actions', partial_as: :order
78
+
79
+ aggregate :total
80
+ end
81
+
82
+ collection do
83
+ scope = Effective::Order.all.includes(:addresses, :order_items, :user)
84
+
85
+ if EffectiveOrders.orders_collection_scope.respond_to?(:call)
86
+ scope = EffectiveOrders.orders_collection_scope.call(scope)
87
+ end
88
+
89
+ if attributes[:user_id].present?
90
+ scope = scope.where(user: user)
91
+ end
92
+
93
+ scope
94
+ end
95
+
96
+ def user
97
+ @user ||= User.find(attributes[:user_id])
98
+ end
99
+
100
+ end
@@ -0,0 +1,79 @@
1
+ # This is a user specific EffectiveOrdersDatatable
2
+
3
+ class EffectiveOrdersDatatable < Effective::Datatable
4
+ filters do
5
+ unless attributes[:not_purchased]
6
+ scope :purchased, default: true
7
+ scope :deferred
8
+ scope :refunds
9
+ scope :not_purchased
10
+ scope :all
11
+ end
12
+ end
13
+
14
+ datatable do
15
+ order :id, :desc
16
+
17
+ col :created_at, visible: false
18
+ col :updated_at, visible: false
19
+
20
+ col :id, label: 'Number' do |order|
21
+ '#' + order.to_param
22
+ end
23
+
24
+ unless attributes[:not_purchased]
25
+ col :purchased_at do |order|
26
+ order.purchased_at&.strftime('%F %H:%M') || 'not purchased'
27
+ end
28
+ end
29
+
30
+ if EffectiveOrders.billing_address
31
+ col :billing_address, visible: false
32
+ end
33
+
34
+ if EffectiveOrders.shipping_address
35
+ col :shipping_address, visible: false
36
+ end
37
+
38
+ col :order_items, search: { as: :string }
39
+
40
+ col :subtotal, as: :price, visible: false
41
+ col :tax, as: :price, visible: false
42
+
43
+ col :tax_rate, visible: false do |order|
44
+ tax_rate_to_percentage(order.tax_rate)
45
+ end
46
+
47
+ col :total, as: :price
48
+
49
+ col :payment_provider, label: 'Provider', visible: false, search: { collection: EffectiveOrders.payment_providers }
50
+ col :payment_card, label: 'Card', visible: false
51
+
52
+ if EffectiveOrders.collect_note
53
+ col :note
54
+ end
55
+
56
+ col :note_to_buyer
57
+
58
+ actions_col partial: 'effective/orders/datatable_actions', partial_as: :order
59
+ end
60
+
61
+ collection do
62
+ scope = Effective::Order.all.where(user: user).includes(:addresses, :order_items, :user)
63
+
64
+ if EffectiveOrders.orders_collection_scope.respond_to?(:call)
65
+ scope = EffectiveOrders.orders_collection_scope.call(scope)
66
+ end
67
+
68
+ if attributes[:not_purchased]
69
+ scope = scope.not_purchased
70
+ end
71
+
72
+ scope
73
+ end
74
+
75
+ def user
76
+ @user ||= User.find(attributes[:user_id])
77
+ end
78
+
79
+ end