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
@@ -1,38 +1,30 @@
1
- unless Gem::Version.new(EffectiveDatatables::VERSION) < Gem::Version.new('3.0')
2
- class EffectiveCustomersDatatable < Effective::Datatable
3
- datatable do
4
- order :email
1
+ class EffectiveCustomersDatatable < Effective::Datatable
2
+ datatable do
5
3
 
6
- col :id, visible: false
7
- col :email, sql_column: 'users.email' do |user|
8
- mail_to user.email, user.email
9
- end
4
+ col :id, visible: false
5
+ #col 'user.email'
10
6
 
11
- if EffectiveOrders.stripe_enabled
12
- col :stripe_customer_id
13
- col :stripe_active_card
14
- end
15
-
16
- if EffectiveOrders.stripe_connect_enabled
17
- col :stripe_connect_access_token
18
- end
19
-
20
- col :subscription_types, sql_column: 'subscription_types'
7
+ if EffectiveOrders.stripe_enabled
8
+ col :stripe_customer_id
9
+ col :active_card
10
+ end
21
11
 
22
- actions_col partial: 'admin/customers/actions', partial_as: :customer
12
+ if EffectiveOrders.stripe_connect_enabled
13
+ col :stripe_connect_access_token
23
14
  end
24
15
 
25
- collection do
26
- Effective::Customer.customers.distinct
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')
16
+ actions_col do |customer|
17
+ link_to('Manage', "https://dashboard.stripe.com/#{'test/' if Rails.env.development?}customers/#{customer.stripe_customer_id}")
31
18
  end
32
19
 
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
20
  end
21
+
22
+ collection do
23
+ Effective::Customer.joins(:user).all
24
+ end
25
+
26
+ # def search_column(collection, table_column, search_term)
27
+ # return collection.where('subscriptions.stripe_plan_id ILIKE ?', "%#{search_term}%") if table_column[:name] == 'subscription_types'
28
+ # super
29
+ # end
38
30
  end
@@ -1,101 +1,99 @@
1
- unless Gem::Version.new(EffectiveDatatables::VERSION) < Gem::Version.new('3.0')
2
- class EffectiveOrderItemsDatatable < Effective::Datatable
3
- datatable do
4
- order :purchased_at, :desc
1
+ class EffectiveOrderItemsDatatable < Effective::Datatable
2
+ datatable do
3
+ order :purchased_at, :desc
5
4
 
6
- col(:purchased_at, sql_column: 'orders.purchased_at') do |order_item|
7
- Time.at(order_item[:purchased_at]).in_time_zone if order_item[:purchased_at].present?
8
- end
5
+ col(:purchased_at, sql_column: 'orders.purchased_at') do |order_item|
6
+ Time.at(order_item[:purchased_at]).in_time_zone if order_item[:purchased_at].present?
7
+ end
9
8
 
10
- col :id, visible: false
11
-
12
- col :order
13
-
14
- # if effectiveorders.obfuscate_order_ids
15
- # col(:order, type: :obfuscated_id) 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
- # col(:order) 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
- unless attributes[:user_id]
26
- col :email, sql_column: 'users.email', label: 'Buyer Email' do |order_item|
27
- link_to order_item[:email], (edit_admin_user_path(order_item[:user_id]) rescue admin_user_path(order_item[:user_id]) rescue '#')
28
- end
29
- end
9
+ col :id, visible: false
30
10
 
31
- if EffectiveOrders.require_billing_address && attributes[:user_id].blank?
32
- col :buyer_name, sort: false, label: 'Buyer Name' do |order_item|
33
- (order_item[:buyer_name] || '').split('!!SEP!!').find(&:present?)
34
- end
35
- end
11
+ col :order
12
+
13
+ # if effectiveorders.obfuscate_order_ids
14
+ # col(:order, type: :obfuscated_id) do |order_item|
15
+ # obfuscated_id = effective::order.obfuscate(order_item[:order_id])
16
+ # link_to(obfuscated_id, (datatables_admin_path? ? effective_orders.admin_order_path(obfuscated_id) : effective_orders.order_path(obfuscated_id)))
17
+ # end
18
+ # else
19
+ # col(:order) do |order_item|
20
+ # 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)))
21
+ # end
22
+ # end
36
23
 
37
- col :purchase_state, sql_column: 'orders.purchase_state', search: { collection: [%w(abandoned abandoned), [EffectiveOrders::PURCHASED, EffectiveOrders::PURCHASED], [EffectiveOrders::DECLINED, EffectiveOrders::DECLINED]], selected: EffectiveOrders::PURCHASED } do |order_item|
38
- order_item[:purchase_state] || 'abandoned'
24
+ unless attributes[:user_id]
25
+ col :email, sql_column: 'users.email', label: 'Buyer Email' 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 '#')
39
27
  end
28
+ end
40
29
 
41
- col :title do |order_item|
42
- order_item.quantity == 1 ? order_item.title : "#{order_item.title} (#{order_item.quantity} purchased)"
30
+ if EffectiveOrders.require_billing_address && attributes[:user_id].blank?
31
+ col :buyer_name, sort: false, label: 'Buyer Name' do |order_item|
32
+ (order_item[:buyer_name] || '').split('!!SEP!!').find(&:present?)
43
33
  end
34
+ end
44
35
 
45
- # col :subtotal, as: :price
46
- # col :tax, as: :price
47
- # col :total, as: :price
36
+ col :purchase_state, sql_column: 'orders.purchase_state', search: { collection: [%w(abandoned abandoned), [EffectiveOrders::PURCHASED, EffectiveOrders::PURCHASED], [EffectiveOrders::DECLINED, EffectiveOrders::DECLINED]], selected: EffectiveOrders::PURCHASED } do |order_item|
37
+ order_item[:purchase_state] || 'abandoned'
38
+ end
48
39
 
49
- col :created_at, visible: false
50
- col :updated_at, visible: false
40
+ col :title do |order_item|
41
+ order_item.quantity == 1 ? order_item.title : "#{order_item.title} (#{order_item.quantity} purchased)"
51
42
  end
52
43
 
53
- collection do
54
- collection = Effective::OrderItem.unscoped
55
- .joins(order: :user)
56
- .select('order_items.*, orders.*, users.email AS email')
57
- .select("#{query_subtotal} AS subtotal, #{query_tax} AS tax, #{query_total} AS total")
58
- .group('order_items.id, orders.id, users.email')
44
+ # col :subtotal, as: :price
45
+ # col :tax, as: :price
46
+ # col :total, as: :price
59
47
 
60
- if EffectiveOrders.require_billing_address && defined?(EffectiveAddresses)
61
- addresses_tbl = EffectiveAddresses.addresses_table_name
48
+ col :created_at, visible: false
49
+ col :updated_at, visible: false
50
+ end
62
51
 
63
- collection = collection
64
- .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")
65
- .group("#{addresses_tbl}.buyer_name")
66
- .select("#{addresses_tbl}.buyer_name AS buyer_name")
67
- end
52
+ collection do
53
+ collection = Effective::OrderItem.unscoped
54
+ .joins(order: :user)
55
+ .select('order_items.*, orders.*, users.email AS email')
56
+ .select("#{query_subtotal} AS subtotal, #{query_tax} AS tax, #{query_total} AS total")
57
+ .group('order_items.id, orders.id, users.email')
68
58
 
69
- attributes[:user_id].present? ? collection.where("#{EffectiveOrders.orders_table_name.to_s}.user_id = ?", attributes[:user_id]) : collection
70
- end
59
+ if EffectiveOrders.require_billing_address && defined?(EffectiveAddresses)
60
+ addresses_tbl = EffectiveAddresses.addresses_table_name
71
61
 
72
- def query_subtotal
73
- 'SUM(price * quantity)'
62
+ collection = collection
63
+ .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")
64
+ .group("#{addresses_tbl}.buyer_name")
65
+ .select("#{addresses_tbl}.buyer_name AS buyer_name")
74
66
  end
75
67
 
76
- def query_total
77
- 'SUM((price * quantity) + (CASE tax_exempt WHEN true THEN 0 ELSE ((price * quantity) * tax_rate) END))'
78
- end
68
+ attributes[:user_id].present? ? collection.where("#{EffectiveOrders.orders_table_name.to_s}.user_id = ?", attributes[:user_id]) : collection
69
+ end
79
70
 
80
- def query_tax
81
- '(CASE tax_exempt WHEN true THEN 0 ELSE ((price * quantity) * tax_rate) END)'
82
- end
71
+ def query_subtotal
72
+ 'SUM(price * quantity)'
73
+ end
83
74
 
84
- # def search_column(collection, table_column, search_term)
85
- # if table_column[:name] == 'order'
86
- # collection.where("#{EffectiveOrders.order_items_table_name.to_s}.order_id = ?", Effective::Order.deobfuscate(search_term))
87
- # elsif table_column[:name] == 'purchase_state' && search_term == 'abandoned'
88
- # collection.where("#{EffectiveOrders.orders_table_name.to_s}.purchase_state IS NULL")
89
- # elsif table_column[:name] == 'subtotal'
90
- # collection.having("#{query_subtotal} = ?", (search_term.gsub(/[^0-9.]/, '').to_f * 100.0).to_i)
91
- # elsif table_column[:name] == 'tax'
92
- # collection.having("#{query_tax} = ?", (search_term.gsub(/[^0-9.]/, '').to_f * 100.0).to_i)
93
- # elsif table_column[:name] == 'total'
94
- # collection.having("#{query_total} = ?", (search_term.gsub(/[^0-9.]/, '').to_f * 100.0).to_i)
95
- # else
96
- # super
97
- # end
98
- # end
75
+ def query_total
76
+ 'SUM((price * quantity) + (CASE tax_exempt WHEN true THEN 0 ELSE ((price * quantity) * tax_rate) END))'
77
+ end
99
78
 
79
+ def query_tax
80
+ '(CASE tax_exempt WHEN true THEN 0 ELSE ((price * quantity) * tax_rate) END)'
100
81
  end
82
+
83
+ # def search_column(collection, table_column, search_term)
84
+ # if table_column[:name] == 'order'
85
+ # collection.where("#{EffectiveOrders.order_items_table_name.to_s}.order_id = ?", Effective::Order.deobfuscate(search_term))
86
+ # elsif table_column[:name] == 'purchase_state' && search_term == 'abandoned'
87
+ # collection.where("#{EffectiveOrders.orders_table_name.to_s}.purchase_state IS NULL")
88
+ # elsif table_column[:name] == 'subtotal'
89
+ # collection.having("#{query_subtotal} = ?", (search_term.gsub(/[^0-9.]/, '').to_f * 100.0).to_i)
90
+ # elsif table_column[:name] == 'tax'
91
+ # collection.having("#{query_tax} = ?", (search_term.gsub(/[^0-9.]/, '').to_f * 100.0).to_i)
92
+ # elsif table_column[:name] == 'total'
93
+ # collection.having("#{query_total} = ?", (search_term.gsub(/[^0-9.]/, '').to_f * 100.0).to_i)
94
+ # else
95
+ # super
96
+ # end
97
+ # end
98
+
101
99
  end
@@ -1,81 +1,91 @@
1
- unless Gem::Version.new(EffectiveDatatables::VERSION) < Gem::Version.new('3.0')
2
- class EffectiveOrdersDatatable < Effective::Datatable
3
- datatable do
4
- order :created_at, :desc
1
+ class EffectiveOrdersDatatable < Effective::Datatable
2
+ bulk_actions do
3
+ if EffectiveOrders.authorized?(view.controller, :admin, :effective_orders)
4
+ bulk_action(
5
+ 'Send payment request email to selected pending orders',
6
+ effective_orders.bulk_send_payment_request_admin_orders_path,
7
+ data: { confirm: 'Send payment request emails to pending orders?' }
8
+ )
9
+ end
5
10
 
6
- col :purchased_at
11
+ bulk_action(
12
+ 'Send receipt email to selected purchased orders',
13
+ effective_orders.bulk_send_buyer_receipt_orders_path,
14
+ data: { confirm: 'Send receipt emails to purchased orders?' }
15
+ )
16
+ end
7
17
 
8
- col :id
18
+ datatable do
19
+ order :created_at, :desc
9
20
 
10
- if attributes[:user_id].blank?
11
- col :user, label: 'Buyer', search: :string, sort: :email do |order|
12
- link_to order.user.email, (edit_admin_user_path(order.user) rescue admin_user_path(order.user) rescue '#')
13
- end
21
+ bulk_actions_col
14
22
 
15
- if EffectiveOrders.require_billing_address && EffectiveOrders.use_address_full_name
16
- val :buyer_name, visible: false do |order|
17
- order.billing_address.try(:full_name)
18
- end
19
- else
20
- val :buyer_name, visible: false do |order|
21
- order.user.to_s
22
- end
23
- end
24
- end
23
+ col :purchased_at
25
24
 
26
- if EffectiveOrders.require_billing_address
27
- col :billing_address
28
- end
25
+ col :id
29
26
 
30
- if EffectiveOrders.require_shipping_address
31
- col :shipping_address
27
+ if attributes[:user_id].blank?
28
+ col :user, label: 'Buyer', search: :string, sort: :email do |order|
29
+ link_to order.user.email, (edit_admin_user_path(order.user) rescue admin_user_path(order.user) rescue '#')
32
30
  end
33
31
 
34
- col :purchase_state, label: 'State', search: { collection: purchase_state_filter_values } do |order|
35
- order.purchase_state || EffectiveOrders::ABANDONED
32
+ if EffectiveOrders.require_billing_address && EffectiveOrders.use_address_full_name
33
+ val :buyer_name, visible: false do |order|
34
+ order.billing_address.try(:full_name)
35
+ end
36
+ else
37
+ val :buyer_name, visible: false do |order|
38
+ order.user.to_s
39
+ end
36
40
  end
41
+ end
42
+
43
+ if EffectiveOrders.require_billing_address
44
+ col :billing_address
45
+ end
37
46
 
38
- col :order_items
47
+ if EffectiveOrders.require_shipping_address
48
+ col :shipping_address
49
+ end
39
50
 
40
- col :subtotal, as: :price
41
- col :tax, as: :price
51
+ col :purchase_state, label: 'State', search: { collection: EffectiveOrders::PURCHASE_STATES.invert } do |order|
52
+ EffectiveOrders::PURCHASE_STATES[order.purchase_state]
53
+ end
42
54
 
43
- col :tax_rate, visible: false do |order|
44
- tax_rate_to_percentage(order.tax_rate)
45
- end
55
+ col :order_items, search: { as: :string }
46
56
 
47
- col :total, as: :price
57
+ col :subtotal, as: :price
58
+ col :tax, as: :price
48
59
 
49
- col :payment_provider, label: 'Provider', visible: false, search: { collection: ['nil'] + (EffectiveOrders.payment_providers + EffectiveOrders.other_payment_providers).sort }
50
- col :payment_card, label: 'Card'
60
+ col :tax_rate, visible: false do |order|
61
+ tax_rate_to_percentage(order.tax_rate)
62
+ end
51
63
 
52
- col :note, visible: false
53
- col :note_to_buyer, visible: false
54
- col :note_internal, visible: false
64
+ col :total, as: :price
55
65
 
56
- col :created_at, visible: false
57
- col :updated_at, visible: false
66
+ col :payment_provider, label: 'Provider', visible: false, search: { collection: ['nil'] + (EffectiveOrders.payment_providers + EffectiveOrders.other_payment_providers).sort }
67
+ col :payment_card, label: 'Card'
58
68
 
59
- actions_col partial: 'admin/orders/actions', partial_as: :order
60
- end
69
+ col :note, visible: false
70
+ col :note_to_buyer, visible: false
71
+ col :note_internal, visible: false
61
72
 
62
- collection do
63
- scope = Effective::Order.unscoped.includes(:addresses, :order_items, :user)
73
+ col :created_at, visible: false
74
+ col :updated_at, visible: false
64
75
 
65
- if EffectiveOrders.orders_collection_scope.respond_to?(:call)
66
- scope = EffectiveOrders.orders_collection_scope.call(scope)
67
- end
76
+ actions_col partial: 'admin/orders/actions', partial_as: :order
68
77
 
69
- attributes[:user_id].present? ? scope.where(user_id: attributes[:user_id]) : scope
70
- end
78
+ aggregate :total
79
+ end
80
+
81
+ collection do
82
+ scope = Effective::Order.unscoped.includes(:addresses, :order_items, :user)
71
83
 
72
- def purchase_state_filter_values
73
- [
74
- [EffectiveOrders::ABANDONED, nil],
75
- [EffectiveOrders::PURCHASED, EffectiveOrders::PURCHASED],
76
- [EffectiveOrders::DECLINED, EffectiveOrders::DECLINED],
77
- [EffectiveOrders::PENDING, EffectiveOrders::PENDING]
78
- ]
84
+ if EffectiveOrders.orders_collection_scope.respond_to?(:call)
85
+ scope = EffectiveOrders.orders_collection_scope.call(scope)
79
86
  end
87
+
88
+ attributes[:user_id].present? ? scope.where(user_id: attributes[:user_id]) : scope
80
89
  end
90
+
81
91
  end
@@ -1,24 +1,27 @@
1
1
  module EffectiveCartsHelper
2
+ # TODO: Consider unique
2
3
  def current_cart(for_user = nil)
3
4
  @cart ||= (
4
5
  user = for_user || (current_user rescue nil) # rescue protects me against Devise not being installed
5
6
 
6
7
  if user.present?
7
- Effective::Cart.where(user_id: user.id).first_or_create.tap do |user_cart|
8
- if session[:cart].present?
9
- session_cart = Effective::Cart.where('user_id IS NULL').where(id: session[:cart]).first
8
+ user_cart = Effective::Cart.where(user: user).first_or_create
10
9
 
11
- if session_cart.present?
12
- session_cart.cart_items.update_all(cart_id: user_cart.id)
13
- session_cart.destroy
14
- user_cart.reload
15
- end
10
+ # Merge session cart into user cart.
11
+ if session[:cart].present?
12
+ session_cart = Effective::Cart.where(user: nil).where(id: session[:cart]).first
16
13
 
17
- session[:cart] = nil
14
+ if session_cart
15
+ session_cart.cart_items.each { |i| user_cart.add(i.purchasable, quantity: i.quantity, unique: i.unique) }
16
+ session_cart.destroy
18
17
  end
18
+
19
+ session[:cart] = nil
19
20
  end
21
+
22
+ user_cart
20
23
  elsif session[:cart].present?
21
- Effective::Cart.where('user_id IS NULL').where(id: session[:cart]).first_or_create
24
+ Effective::Cart.where(user_id: nil).where(id: session[:cart]).first_or_create
22
25
  else
23
26
  cart = Effective::Cart.create!
24
27
  session[:cart] = cart.id
@@ -42,7 +45,7 @@ module EffectiveCartsHelper
42
45
  end
43
46
 
44
47
  def link_to_add_to_cart(purchasable, opts = {})
45
- raise ArgumentError.new('expecting an acts_as_purchasable object') unless purchasable.kind_of?(ActsAsPurchasable)
48
+ raise 'expecting an acts_as_purchasable object' unless purchasable.kind_of?(ActsAsPurchasable)
46
49
 
47
50
  options = {
48
51
  label: 'Add to Cart',
@@ -60,7 +63,7 @@ module EffectiveCartsHelper
60
63
  end
61
64
 
62
65
  def link_to_remove_from_cart(cart_item, opts = {})
63
- raise ArgumentError.new('expecting an Effective::CartItem object') unless cart_item.kind_of?(Effective::CartItem)
66
+ raise 'expecting an Effective::CartItem object' unless cart_item.kind_of?(Effective::CartItem)
64
67
 
65
68
  options = {
66
69
  label: 'Remove',
@@ -120,11 +123,11 @@ module EffectiveCartsHelper
120
123
 
121
124
  def render_cart(cart = nil)
122
125
  cart ||= current_cart
123
- render(partial: 'effective/carts/cart', locals: {cart: cart})
126
+ render(partial: 'effective/carts/cart', locals: { cart: cart })
124
127
  end
125
128
 
126
129
  def render_purchasables(*purchasables)
127
- render(partial: 'effective/orders/order_items', locals: {order: Effective::Order.new(purchasables)})
130
+ render(partial: 'effective/orders/order_items', locals: { order: Effective::Order.new(purchasables) })
128
131
  end
129
132
 
130
133
  end