effective_orders 4.5.0

Sign up to get free protection for your applications and to get access to all the features.
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