effective_orders 1.2.13 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 101d33deb56c39e2cb0805f69c46cdae7b11df2f
4
- data.tar.gz: 164d3ac6fcef01e5c36fecafa3758df40791cf7b
3
+ metadata.gz: d9d3799addd53c68bed28726c22a3b9d45be94f1
4
+ data.tar.gz: 1af44c4052ea662a756483459449b16b08ff9e13
5
5
  SHA512:
6
- metadata.gz: 8b53c1a55398129ef3d432b424735c368950f470984423cf1da2ff2201d2e64585c4d172105e726fc52fa10d65332a9604c0a82bd1d213b94b603e519baa25f0
7
- data.tar.gz: 44699ee1eb34067dc7b3ace224c31ded9faa93351e1f96a19faf073af2c2eab36890d72c460861a3f57a4e8df382c5737eaf127ad3730454973da476b963aae6
6
+ metadata.gz: d029f7d0bfc198f91f8acd375bccf1b461451ac50250e4964d53dfe8fecae78631325b3cb774d003bed6d699901aedec82a5eb3acd7247284815231ea78ac495
7
+ data.tar.gz: 70a36698cc25ed54f732525e2d5d1e12be127b2aede2e8fa450aab84159032d462967d3a96cce9b5efdef24dc85b04ad24b6e42e81c54226be20cc7dc3f57199
@@ -26,5 +26,13 @@
26
26
  min-width: 200px;
27
27
  }
28
28
  }
29
+ }
30
+
31
+ .effective-order-purchase-actions {
32
+ text-align: right;
33
+
34
+ > * {
35
+ display: inline-block;
36
+ }
29
37
 
30
38
  }
@@ -0,0 +1,14 @@
1
+ module Admin
2
+ class OrderItemsController < ApplicationController
3
+ before_filter :authenticate_user! # This is devise, ensure we're logged in.
4
+
5
+ layout (EffectiveOrders.layout.kind_of?(Hash) ? EffectiveOrders.layout[:admin_orders] : EffectiveOrders.layout)
6
+
7
+ def index
8
+ @datatable = Effective::Datatables::OrderItems.new() if defined?(EffectiveDatatables)
9
+ @page_title = 'Order Items'
10
+
11
+ EffectiveOrders.authorized?(self, :index, Effective::OrderItem)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,93 @@
1
+ if defined?(EffectiveDatatables)
2
+ module Effective
3
+ module Datatables
4
+ class OrderItems < Effective::Datatable
5
+ default_order :purchased_at, :desc
6
+
7
+ table_column(:purchased_at, :type => :datetime, :column => 'orders.purchased_at') do |order_item|
8
+ Time.at(order_item[:purchased_at]).in_time_zone if order_item[:purchased_at].present?
9
+ end
10
+
11
+ table_column :id, :visible => false
12
+
13
+ table_column(:order, :type => :obfuscated_id, :sortable => false) do |order_item|
14
+ obfuscated_id = Effective::Order.obfuscate(order_item[:order_id])
15
+ link_to(obfuscated_id, (datatables_admin_path? ? effective_orders.admin_order_path(obfuscated_id) : effective_orders.order_path(obfuscated_id)))
16
+ end
17
+
18
+ table_column :email, column: 'users.email', label: 'Buyer Email', if: proc { attributes[:user_id].blank? } do |order_item|
19
+ link_to order_item[:email], (edit_admin_user_path(order_item[:user_id]) rescue admin_user_path(order_item[:user_id]) rescue '#')
20
+ end
21
+
22
+ if EffectiveOrders.require_billing_address
23
+ table_column :buyer_name, sortable: false, label: 'Buyer Name', if: proc { attributes[:user_id].blank? } do |order_item|
24
+ (order_item[:buyer_name] || '').split('!!SEP!!').find(&:present?)
25
+ end
26
+ end
27
+
28
+ 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|
29
+ order_item[:purchase_state] || 'abandoned'
30
+ end
31
+
32
+ table_column :title do |order_item|
33
+ order_item.quantity == 1 ? order_item.title : "#{order_item.title} (#{order_item.quantity} purchased)"
34
+ end
35
+
36
+ table_column(:subtotal) { |order_item| price_to_currency(order_item[:subtotal].to_i) }
37
+ table_column(:tax) { |order_item| price_to_currency(order_item[:tax].to_i) }
38
+ table_column(:total) { |order_item| price_to_currency(order_item[:total].to_i) }
39
+
40
+ table_column :created_at, :visible => false
41
+ table_column :updated_at, :visible => false
42
+
43
+ def collection
44
+ collection = Effective::OrderItem.unscoped
45
+ .joins(:order => :user)
46
+ .select('order_items.*, orders.*, users.email AS email')
47
+ .select("#{query_subtotal} AS subtotal, #{query_tax} AS tax, #{query_total} AS total")
48
+ .group('order_items.id, orders.id, users.email')
49
+
50
+ if EffectiveOrders.require_billing_address && defined?(EffectiveAddresses)
51
+ addresses_tbl = EffectiveAddresses.addresses_table_name
52
+
53
+ collection = collection
54
+ .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")
55
+ .group("#{addresses_tbl}.buyer_name")
56
+ .select("#{addresses_tbl}.buyer_name AS buyer_name")
57
+ end
58
+
59
+ attributes[:user_id].present? ? collection.where("#{EffectiveOrders.orders_table_name.to_s}.user_id = ?", attributes[:user_id]) : collection
60
+ end
61
+
62
+ def query_subtotal
63
+ 'SUM(price * quantity)'
64
+ end
65
+
66
+ def query_total
67
+ 'SUM((price * quantity) + (CASE tax_exempt WHEN true THEN 0 ELSE ((price * quantity) * tax_rate) END))'
68
+ end
69
+
70
+ def query_tax
71
+ '(CASE tax_exempt WHEN true THEN 0 ELSE ((price * quantity) * tax_rate) END)'
72
+ end
73
+
74
+ def search_column(collection, table_column, search_term)
75
+ if table_column[:name] == 'order'
76
+ collection.where("#{EffectiveOrders.order_items_table_name.to_s}.order_id = ?", Effective::Order.deobfuscate(search_term))
77
+ elsif table_column[:name] == 'purchase_state' && search_term == 'abandoned'
78
+ collection.where("#{EffectiveOrders.orders_table_name.to_s}.purchase_state IS NULL")
79
+ elsif table_column[:name] == 'subtotal'
80
+ collection.having("#{query_subtotal} = ?", (search_term.gsub(/[^0-9.]/, '').to_f * 100.0).to_i)
81
+ elsif table_column[:name] == 'tax'
82
+ collection.having("#{query_tax} = ?", (search_term.gsub(/[^0-9.]/, '').to_f * 100.0).to_i)
83
+ elsif table_column[:name] == 'total'
84
+ collection.having("#{query_total} = ?", (search_term.gsub(/[^0-9.]/, '').to_f * 100.0).to_i)
85
+ else
86
+ super
87
+ end
88
+ end
89
+
90
+ end
91
+ end
92
+ end
93
+ end
@@ -4,7 +4,7 @@ if defined?(EffectiveDatatables)
4
4
  class Orders < Effective::Datatable
5
5
  default_order :purchased_at, :desc
6
6
 
7
- table_column(:purchased_at) { |order| order.purchased_at.try(:strftime, '%Y-%m-%d %H:%M') }
7
+ table_column :purchased_at
8
8
  table_column :id
9
9
 
10
10
  table_column :email, column: 'users.email', label: 'Buyer Email', if: proc { attributes[:user_id].blank? } do |order|
@@ -27,9 +27,12 @@ if defined?(EffectiveDatatables)
27
27
  end
28
28
  end
29
29
 
30
+ table_column(:subtotal) { |order| price_to_currency(order[:subtotal].to_i) }
31
+ table_column(:tax) { |order| price_to_currency(order[:tax].to_i) }
30
32
  table_column(:total) { |order| price_to_currency(order[:total].to_i) }
31
- table_column(:created_at, visible: false) { |order| order.updated_at.strftime('%Y-%m-%d %H:%M') }
32
- table_column(:updated_at, visible: false) { |order| order.updated_at.strftime('%Y-%m-%d %H:%M') }
33
+
34
+ table_column :created_at, :visible => false
35
+ table_column :updated_at, :visible => false
33
36
 
34
37
  table_column :actions, sortable: false, filter: false do |order|
35
38
  link_to('View', (datatables_admin_path? ? effective_orders.admin_order_path(order) : effective_orders.order_path(order)))
@@ -37,30 +40,42 @@ if defined?(EffectiveDatatables)
37
40
 
38
41
  def collection
39
42
  collection = Effective::Order.unscoped
40
- .joins(:user, :order_items)
41
- .group('users.email, orders.id')
42
- .select('orders.*, users.email AS email')
43
- .select("#{query_total} AS total")
44
- .select("string_agg(order_items.title, '!!SEP!!') AS order_items")
43
+ .joins(:user, :order_items)
44
+ .group('users.email, orders.id')
45
+ .select('orders.*, users.email AS email')
46
+ .select("#{query_subtotal} AS subtotal, #{query_tax} AS tax, #{query_total} AS total")
47
+ .select("string_agg(order_items.title, '!!SEP!!') AS order_items")
45
48
 
46
49
  if EffectiveOrders.require_billing_address && defined?(EffectiveAddresses)
47
50
  addresses_tbl = EffectiveAddresses.addresses_table_name
48
51
 
49
52
  collection = collection
50
- .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")
51
- .group("#{addresses_tbl}.buyer_name")
52
- .select("#{addresses_tbl}.buyer_name AS buyer_name")
53
+ .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")
54
+ .group("#{addresses_tbl}.buyer_name")
55
+ .select("#{addresses_tbl}.buyer_name AS buyer_name")
53
56
  end
54
57
 
55
58
  attributes[:user_id].present? ? collection.where(user_id: attributes[:user_id]) : collection
56
59
  end
57
60
 
61
+ def query_subtotal
62
+ 'SUM(order_items.price * order_items.quantity)'
63
+ end
64
+
65
+ def query_tax
66
+ 'SUM(CASE order_items.tax_exempt WHEN true THEN 0 ELSE ((order_items.price * order_items.quantity) * order_items.tax_rate) END)'
67
+ end
68
+
58
69
  def query_total
59
70
  'SUM((order_items.price * order_items.quantity) + (CASE order_items.tax_exempt WHEN true THEN 0 ELSE ((order_items.price * order_items.quantity) * order_items.tax_rate) END))'
60
71
  end
61
72
 
62
73
  def search_column(collection, table_column, search_term)
63
- if table_column[:name] == 'total'
74
+ if table_column[:name] == 'subtotal'
75
+ collection.having("#{query_subtotal} = ?", (search_term.gsub(/[^0-9.]/, '').to_f * 100.0).to_i)
76
+ elsif table_column[:name] == 'tax'
77
+ collection.having("#{query_tax} = ?", (search_term.gsub(/[^0-9.]/, '').to_f * 100.0).to_i)
78
+ elsif table_column[:name] == 'total'
64
79
  collection.having("#{query_total} = ?", (search_term.gsub(/[^0-9.]/, '').to_f * 100.0).to_i)
65
80
  elsif table_column[:name] == 'purchase_state' && search_term == 'abandoned'
66
81
  collection.where(purchase_state: nil)
@@ -0,0 +1,7 @@
1
+ %h2 Order Items
2
+
3
+ - unless @datatable.collection.length > 0
4
+ %p
5
+ There are no order items
6
+ - else
7
+ = render_datatable @datatable
@@ -34,10 +34,10 @@
34
34
 
35
35
  = f.input :shipping_address_same_as_billing, :as => :boolean, :label => 'My Shipping address is the same as my Billing address'
36
36
 
37
- %hr
38
37
  = link_to_current_cart :label => 'Change Items', :class => 'btn btn-default'
39
38
 
40
- - if order.total == 0 && EffectiveOrders.allow_free_orders
41
- = f.submit 'Checkout', :class => 'btn btn-primary pull-right', :rel => :nofollow, 'data-disable-with' => 'Continuing...'
42
- - else
43
- = f.submit 'Continue to Checkout Confirmation', :class => 'btn btn-primary pull-right', :rel => :nofollow, 'data-disable-with' => 'Continuing...'
39
+ .text-right
40
+ - if order.total == 0 && EffectiveOrders.allow_free_orders
41
+ = f.submit 'Checkout', :class => 'btn btn-primary pull-right', :rel => :nofollow, 'data-disable-with' => 'Continuing...'
42
+ - else
43
+ = f.submit 'Continue to Checkout Confirmation', :class => 'btn btn-primary pull-right', :rel => :nofollow, 'data-disable-with' => 'Continuing...'
@@ -1,17 +1,18 @@
1
1
  = render order
2
2
 
3
- - if EffectiveOrders.moneris_enabled
4
- = render :partial => '/effective/orders/moneris/form', :locals => {:order => order, :purchased_redirect_url => purchased_redirect_url, :declined_redirect_url => declined_redirect_url}
3
+ .effective-order.effective-order-purchase-actions
4
+ - if EffectiveOrders.moneris_enabled
5
+ = render :partial => '/effective/orders/moneris/form', :locals => {:order => order, :purchased_redirect_url => purchased_redirect_url, :declined_redirect_url => declined_redirect_url}
5
6
 
6
- - if EffectiveOrders.paypal_enabled
7
- = render :partial => '/effective/orders/paypal/form', :locals => {:order => order}
7
+ - if EffectiveOrders.paypal_enabled
8
+ = render :partial => '/effective/orders/paypal/form', :locals => {:order => order}
8
9
 
9
- - if EffectiveOrders.stripe_enabled
10
- = render :partial => '/effective/orders/stripe/form', :locals => {:order => order}
10
+ - if EffectiveOrders.stripe_enabled
11
+ = render :partial => '/effective/orders/stripe/form', :locals => {:order => order}
11
12
 
12
- - if EffectiveOrders.allow_pretend_purchase_in_production
13
- = link_to 'Process Order', effective_orders.pretend_purchase_path(order, :purchased_redirect_url => purchased_redirect_url, :declined_redirect_url => declined_redirect_url), :class => 'btn btn-primary'
14
- %p= EffectiveOrders.allow_pretend_purchase_in_production_message
15
- - elsif Rails.env.development?
16
- = link_to 'Process Order (development only)', effective_orders.pretend_purchase_path(order, :purchased_redirect_url => purchased_redirect_url, :declined_redirect_url => declined_redirect_url), :class => 'btn btn-primary'
13
+ - if EffectiveOrders.allow_pretend_purchase_in_production
14
+ = link_to 'Process Order', effective_orders.pretend_purchase_path(order, :purchased_redirect_url => purchased_redirect_url, :declined_redirect_url => declined_redirect_url), :class => 'btn btn-primary'
15
+ %p= EffectiveOrders.allow_pretend_purchase_in_production_message
16
+ - elsif Rails.env.development?
17
+ = link_to 'Process Order (development only)', effective_orders.pretend_purchase_path(order, :purchased_redirect_url => purchased_redirect_url, :declined_redirect_url => declined_redirect_url), :class => 'btn btn-primary'
17
18
 
@@ -34,4 +34,4 @@
34
34
  = hidden_field_tag(:bill_postal_code, address.postal_code)
35
35
  = hidden_field_tag(:bill_country, address.country)
36
36
 
37
- %p= submit_tag 'Checkout with Moneris', :class => 'btn btn-primary'
37
+ = submit_tag 'Checkout with Moneris', :class => 'btn btn-primary'
@@ -2,4 +2,4 @@
2
2
  = hidden_field_tag :cmd, '_s-xclick'
3
3
  = hidden_field_tag :encrypted, paypal_encrypted_payload(order)
4
4
 
5
- %p= submit_tag 'Checkout with PayPal', :class => 'btn btn-primary'
5
+ = submit_tag 'Checkout with PayPal', :class => 'btn btn-primary'
@@ -4,14 +4,13 @@
4
4
  %h2 Order
5
5
  %hr
6
6
 
7
- %a.btn.btn-default.pull-right{'data-role' => 'print-button', :class => 'print-button', :onClick => "window.print(); false;"} Print
7
+ %p.pull-right
8
+ %a.btn.btn-default{'data-role' => 'print-button', :class => 'print-button', :onClick => "window.print(); false;"} Print
9
+ - if @order.purchased?
10
+ = link_to 'Resend Receipt', effective_orders.resend_buyer_receipt_path(@order), 'data-confirm' => 'This action will email you a copy of the original email receipt. Send receipt now?', :class => 'btn btn-default'
8
11
 
9
12
  = render @order
10
13
 
11
- %hr
12
14
  = link_to 'Back', :back, :class => 'btn btn-primary'
13
- - if @order.purchased?
14
- = '-'
15
- = link_to 'Resend Receipt', effective_orders.resend_buyer_receipt_path(@order), 'data-confirm' => 'This action will email you a copy of the original email receipt. Send receipt now?', :class => 'btn btn-default'
16
15
 
17
16
 
data/config/routes.rb CHANGED
@@ -52,6 +52,7 @@ EffectiveOrders::Engine.routes.draw do
52
52
  namespace :admin do
53
53
  resources :customers, :only => [:index]
54
54
  resources :orders, :only => [:index, :show]
55
+ resources :order_items, :only => [:index]
55
56
  end
56
57
  end
57
58
  end
@@ -1,3 +1,3 @@
1
1
  module EffectiveOrders
2
- VERSION = '1.2.13'.freeze
2
+ VERSION = '1.3.0'.freeze
3
3
  end
@@ -232,7 +232,6 @@ describe Effective::OrdersController do
232
232
  }
233
233
 
234
234
  (assigns(:order).valid? && assigns(:order).persisted?).should eq false
235
- assigns(:order).errors[:addresses].present?.should eq true
236
235
  assigns(:order).errors[:shipping_address].present?.should eq true
237
236
 
238
237
  response.should render_template(:new)
@@ -170,3 +170,6 @@
170
170
   (0.2ms) SELECT MAX("orders"."id") FROM "orders"
171
171
   (0.2ms) SELECT MAX("orders"."id") FROM "orders"
172
172
   (0.2ms) SELECT MAX("orders"."id") FROM "orders"
173
+  (0.4ms) SELECT MAX("orders"."id") FROM "orders"
174
+  (0.2ms) SELECT MAX("orders"."id") FROM "orders"
175
+  (0.3ms) SELECT MAX("orders"."id") FROM "orders"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_orders
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.13
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-20 00:00:00.000000000 Z
11
+ date: 2015-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -323,6 +323,7 @@ files:
323
323
  - app/assets/stylesheets/effective_orders.scss
324
324
  - app/assets/stylesheets/effective_orders/_order.scss
325
325
  - app/controllers/admin/customers_controller.rb
326
+ - app/controllers/admin/order_items_controller.rb
326
327
  - app/controllers/admin/orders_controller.rb
327
328
  - app/controllers/effective/carts_controller.rb
328
329
  - app/controllers/effective/orders_controller.rb
@@ -343,6 +344,7 @@ files:
343
344
  - app/models/effective/cart_item.rb
344
345
  - app/models/effective/customer.rb
345
346
  - app/models/effective/datatables/customers.rb
347
+ - app/models/effective/datatables/order_items.rb
346
348
  - app/models/effective/datatables/orders.rb
347
349
  - app/models/effective/order.rb
348
350
  - app/models/effective/order_item.rb
@@ -357,6 +359,7 @@ files:
357
359
  - app/views/active_admin/effective_orders/orders/_show.html.haml
358
360
  - app/views/admin/customers/_actions.html.haml
359
361
  - app/views/admin/customers/index.html.haml
362
+ - app/views/admin/order_items/index.html.haml
360
363
  - app/views/admin/orders/index.html.haml
361
364
  - app/views/admin/orders/show.html.haml
362
365
  - app/views/effective/carts/_cart.html.haml