effective_orders 1.2.13 → 1.3.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.
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