spree_dash 0.70.7 → 1.0.0.rc1
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.
- data/LICENSE +2 -2
- data/README.md +1 -1
- data/app/assets/images/analytics_dashboard_preview.png +0 -0
- data/app/controllers/spree/admin/overview_controller.rb +15 -0
- data/app/controllers/spree/base_controller_decorator.rb +3 -0
- data/app/helpers/spree/analytics_helper.rb +69 -0
- data/app/models/spree/dash_configuration.rb +11 -0
- data/app/overrides/analytics_header.rb +4 -0
- data/app/views/spree/admin/overview/_form.html.erb +23 -0
- data/app/views/spree/admin/overview/index.html.erb +37 -0
- data/app/views/spree/analytics/_header.html.erb +12 -0
- data/config/locales/en.yml +1 -0
- data/config/routes.rb +2 -2
- data/lib/spree/dash.rb +9 -0
- data/lib/spree/dash/engine.rb +24 -0
- data/lib/spree_dash.rb +1 -7
- metadata +33 -32
- data/app/assets/javascripts/admin/dashboard.js +0 -144
- data/app/assets/javascripts/admin/spree_dash.js +0 -15
- data/app/assets/javascripts/store/spree_dash.js +0 -1
- data/app/assets/stylesheets/admin/dashboard.css.erb +0 -143
- data/app/assets/stylesheets/admin/spree_dash.css +0 -4
- data/app/assets/stylesheets/store/spree_dash.css +0 -3
- data/app/controllers/admin/overview_controller.rb +0 -152
- data/app/views/admin/overview/index.html.erb +0 -164
- data/vendor/assets/javascripts/jqPlot/excanvas.min.js +0 -1
- data/vendor/assets/javascripts/jqPlot/jquery.jqplot.min.js +0 -14
- data/vendor/assets/javascripts/jqPlot/plugins/jqplot.canvasAxisLabelRenderer.min.js +0 -14
- data/vendor/assets/javascripts/jqPlot/plugins/jqplot.canvasAxisTickRenderer.min.js +0 -14
- data/vendor/assets/javascripts/jqPlot/plugins/jqplot.canvasTextRenderer.min.js +0 -14
- data/vendor/assets/javascripts/jqPlot/plugins/jqplot.categoryAxisRenderer.min.js +0 -14
- data/vendor/assets/javascripts/jqPlot/plugins/jqplot.dateAxisRenderer.min.js +0 -14
- data/vendor/assets/javascripts/jqPlot/plugins/jqplot.highlighter.min.js +0 -14
- data/vendor/assets/javascripts/jqPlot/plugins/jqplot.pieRenderer.min.js +0 -14
@@ -1,15 +0,0 @@
|
|
1
|
-
// This is a manifest file that'll be compiled into including all the files listed below.
|
2
|
-
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
|
3
|
-
// be included in the compiled file accessible from http://example.com/assets/application.js
|
4
|
-
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
5
|
-
// the compiled file.
|
6
|
-
//
|
7
|
-
//= require_tree .
|
8
|
-
//= require admin/spree_core
|
9
|
-
//= require jqPlot/jquery.jqplot.min
|
10
|
-
//= require jqPlot/plugins/jqplot.dateAxisRenderer.min
|
11
|
-
//= require jqPlot/plugins/jqplot.highlighter.min
|
12
|
-
//= require jqPlot/plugins/jqplot.canvasAxisTickRenderer.min
|
13
|
-
//= require jqPlot/plugins/jqplot.canvasTextRenderer.min
|
14
|
-
//= require jqPlot/plugins/jqplot.canvasAxisLabelRenderer.min
|
15
|
-
//= require jqPlot/plugins/jqplot.pieRenderer.min
|
@@ -1 +0,0 @@
|
|
1
|
-
//= require store/spree_core
|
@@ -1,143 +0,0 @@
|
|
1
|
-
.dashboard h2{
|
2
|
-
padding-bottom:5px;
|
3
|
-
color: #476D9B;
|
4
|
-
clear:both;
|
5
|
-
}
|
6
|
-
|
7
|
-
.dashboard_left{
|
8
|
-
width:25%;
|
9
|
-
float:left;
|
10
|
-
}
|
11
|
-
|
12
|
-
.dashboard_main{
|
13
|
-
width:55%;
|
14
|
-
float:left;
|
15
|
-
}
|
16
|
-
|
17
|
-
.dashboard_main #orders_by_day_options{
|
18
|
-
background-color:#0095DA;
|
19
|
-
-moz-border-radius-bottomleft:10px;
|
20
|
-
-moz-border-radius-bottomright:10px;
|
21
|
-
-moz-border-radius-topleft:10px;
|
22
|
-
-moz-border-radius-topright:10px;
|
23
|
-
-webkit-border-bottom-left-radius: 10px 10px;
|
24
|
-
-webkit-border-bottom-right-radius: 10px 10px;
|
25
|
-
-webkit-border-top-left-radius: 10px 10px;
|
26
|
-
-webkit-border-top-right-radius: 10px 10px;
|
27
|
-
color:#fff;
|
28
|
-
margin-top:10px;
|
29
|
-
padding:5px;
|
30
|
-
text-align:center;
|
31
|
-
}
|
32
|
-
|
33
|
-
#order_by_day_title{
|
34
|
-
padding-bottom:5px;
|
35
|
-
color: #476D9B;
|
36
|
-
clear:both;
|
37
|
-
}
|
38
|
-
|
39
|
-
#order_totals{
|
40
|
-
background:#154E8C url(<%= asset_path("admin/bg/admin_tab_back.png") %>) repeat-x scroll left top;
|
41
|
-
-moz-border-radius-bottomleft:10px;
|
42
|
-
-moz-border-radius-bottomright:10px;
|
43
|
-
-moz-border-radius-topleft:10px;
|
44
|
-
-moz-border-radius-topright:10px;
|
45
|
-
-webkit-border-bottom-left-radius: 10px 10px;
|
46
|
-
-webkit-border-bottom-right-radius: 10px 10px;
|
47
|
-
-webkit-border-top-left-radius: 10px 10px;
|
48
|
-
-webkit-border-top-right-radius: 10px 10px;
|
49
|
-
color:#fff;
|
50
|
-
height:62px;
|
51
|
-
padding:0 10px;
|
52
|
-
margin-bottom:20px;
|
53
|
-
}
|
54
|
-
|
55
|
-
#order_totals hr{
|
56
|
-
background-color:#fff;
|
57
|
-
clear:none;
|
58
|
-
float:left;
|
59
|
-
height:80%;
|
60
|
-
margin-top:6px;
|
61
|
-
width:3px;
|
62
|
-
}
|
63
|
-
|
64
|
-
#order_totals .spacer{
|
65
|
-
padding: 0px 10px;
|
66
|
-
font-size: 50px;
|
67
|
-
line-height: 60px;
|
68
|
-
color: #476D9B;
|
69
|
-
}
|
70
|
-
|
71
|
-
#order_totals p{
|
72
|
-
float:left;
|
73
|
-
font-size:420%;
|
74
|
-
font-weight:bold;
|
75
|
-
line-height:60px;
|
76
|
-
margin:0 5px 0 0;
|
77
|
-
}
|
78
|
-
|
79
|
-
#order_totals label{
|
80
|
-
font-size:200%;
|
81
|
-
line-height:50px;
|
82
|
-
}
|
83
|
-
|
84
|
-
#order_totals span{
|
85
|
-
display:block;
|
86
|
-
font-size:90%;
|
87
|
-
font-weight:bold;
|
88
|
-
margin-top: -10px;
|
89
|
-
}
|
90
|
-
|
91
|
-
.dashboard_main #orders_by_day_options label{
|
92
|
-
padding: 0px 10px;
|
93
|
-
}
|
94
|
-
|
95
|
-
.dashboard_right{
|
96
|
-
width:20%;
|
97
|
-
float:left;
|
98
|
-
}
|
99
|
-
|
100
|
-
.dashboard table th{
|
101
|
-
background-color: #0095DA;
|
102
|
-
color: #fff;
|
103
|
-
}
|
104
|
-
|
105
|
-
.dashboard_small_wrapper{
|
106
|
-
padding: 0px 20px 0px 0px;
|
107
|
-
}
|
108
|
-
|
109
|
-
.dashboard_main_wrapper{
|
110
|
-
padding: 0px 30px 10px 30px;
|
111
|
-
margin-left: auto;
|
112
|
-
margin-right: auto;
|
113
|
-
}
|
114
|
-
|
115
|
-
#pie_legend{
|
116
|
-
width:50%;
|
117
|
-
float:left;
|
118
|
-
font-size: 80%;
|
119
|
-
}
|
120
|
-
|
121
|
-
#pie_legend span{
|
122
|
-
line-height:15px;
|
123
|
-
width:15px;
|
124
|
-
float:left;
|
125
|
-
}
|
126
|
-
|
127
|
-
#pie_legend label{
|
128
|
-
margin-left:5px;
|
129
|
-
float:left;
|
130
|
-
}
|
131
|
-
|
132
|
-
#pie_legend div{
|
133
|
-
clear:both;
|
134
|
-
text-align:right;
|
135
|
-
}
|
136
|
-
|
137
|
-
.text-right{
|
138
|
-
text-align:right;
|
139
|
-
}
|
140
|
-
|
141
|
-
.jqplot-table-legend{
|
142
|
-
width:60px;
|
143
|
-
}
|
@@ -1,152 +0,0 @@
|
|
1
|
-
# this clas was inspired (heavily) from the mephisto admin architecture
|
2
|
-
|
3
|
-
class Admin::OverviewController < Admin::BaseController
|
4
|
-
before_filter :check_json_authenticity, :only => :get_report_data
|
5
|
-
#todo, add rss feed of information that is happening
|
6
|
-
|
7
|
-
def index
|
8
|
-
@show_dashboard = show_dashboard
|
9
|
-
return unless @show_dashboard
|
10
|
-
|
11
|
-
p = {:from => (Time.new().to_date - 1.week).to_s(:db), :value => "Count"}
|
12
|
-
@orders_by_day = orders_by_day(p)
|
13
|
-
@orders_line_total = orders_line_total(p)
|
14
|
-
@orders_total = orders_total(p)
|
15
|
-
@orders_adjustment_total = orders_adjustment_total(p)
|
16
|
-
@orders_credit_total = orders_credit_total(p)
|
17
|
-
|
18
|
-
@best_selling_variants = best_selling_variants
|
19
|
-
@top_grossing_variants = top_grossing_variants
|
20
|
-
@last_five_orders = last_five_orders
|
21
|
-
@biggest_spenders = biggest_spenders
|
22
|
-
@out_of_stock_products = out_of_stock_products
|
23
|
-
@best_selling_taxons = best_selling_taxons
|
24
|
-
|
25
|
-
@pie_colors = [ "#0093DA", "#FF3500", "#92DB00", "#1AB3FF", "#FFB800"]
|
26
|
-
end
|
27
|
-
|
28
|
-
def get_report_data
|
29
|
-
opts = case params[:name]
|
30
|
-
when "7_days" then {:from => (Time.new().to_date - 1.week).to_s(:db)}
|
31
|
-
when "14_days" then {:from => (Time.new().to_date - 2.week).to_s(:db)}
|
32
|
-
when "this_month" then {:from => Date.new(Time.now.year, Time.now.month, 1).to_s(:db), :to => Date.new(Time.now.year, Time.now.month, -1).to_s(:db)}
|
33
|
-
when "last_month" then {:from => (Date.new(Time.now.year, Time.now.month, 1) - 1.month).to_s(:db), :to => (Date.new(Time.now.year, Time.now.month, -1) - 1.month).to_s(:db)}
|
34
|
-
when "this_year" then {:from => Date.new(Time.now.year, 1, 1).to_s(:db)}
|
35
|
-
when "last_year" then {:from => Date.new(Time.now.year - 1, 1, 1).to_s(:db), :to => Date.new(Time.now.year - 1, 12, -1).to_s(:db)}
|
36
|
-
end
|
37
|
-
|
38
|
-
case params[:report]
|
39
|
-
when "orders_by_day"
|
40
|
-
opts[:value] = params[:value]
|
41
|
-
|
42
|
-
render :js => "[[" + orders_by_day(opts).map { |day| "['#{day[0]}',#{day[1]}]" }.join(",") + "]]"
|
43
|
-
when "orders_totals"
|
44
|
-
render :js => [:orders_total => orders_total(opts).to_i, :orders_line_total => orders_line_total(opts).to_i,
|
45
|
-
:orders_adjustment_total => orders_adjustment_total(opts).to_i, :orders_credit_total => orders_credit_total(opts).to_i ].to_json
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
private
|
50
|
-
def show_dashboard
|
51
|
-
Order.count > 50
|
52
|
-
end
|
53
|
-
|
54
|
-
def conditions(params)
|
55
|
-
if params.key? :to
|
56
|
-
["completed_at >= ? AND completed_at <= ? AND state <> 'canceled'", params[:from], params[:to]]
|
57
|
-
else
|
58
|
-
["completed_at >= ? AND state <> 'canceled'", params[:from]]
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def fill_empty_entries(orders, params)
|
63
|
-
from_date = params[:from].to_date
|
64
|
-
to_date = (params[:to] || Time.now).to_date
|
65
|
-
(from_date..to_date).each do |date|
|
66
|
-
orders[date] ||= []
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def orders_by_day(params)
|
71
|
-
|
72
|
-
if params[:value] == "Count"
|
73
|
-
orders = Order.select(:created_at).where(conditions(params))
|
74
|
-
orders = orders.group_by { |o| o.created_at.to_date }
|
75
|
-
fill_empty_entries(orders, params)
|
76
|
-
orders.keys.sort.map {|key| [key.strftime('%Y-%m-%d'), orders[key].size ]}
|
77
|
-
else
|
78
|
-
orders = Order.select([:created_at, :total]).where(conditions(params))
|
79
|
-
orders = orders.group_by { |o| o.created_at.to_date }
|
80
|
-
fill_empty_entries(orders, params)
|
81
|
-
orders.keys.sort.map {|key| [key.strftime('%Y-%m-%d'), orders[key].inject(0){|s,o| s += o.total} ]}
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def orders_line_total(params)
|
86
|
-
Order.sum(:item_total, :conditions => conditions(params))
|
87
|
-
end
|
88
|
-
|
89
|
-
def orders_total(params)
|
90
|
-
Order.sum(:total, :conditions => conditions(params))
|
91
|
-
end
|
92
|
-
|
93
|
-
def orders_adjustment_total(params)
|
94
|
-
Order.sum(:adjustment_total, :conditions => conditions(params))
|
95
|
-
end
|
96
|
-
|
97
|
-
def orders_credit_total(params)
|
98
|
-
Order.sum(:credit_total, :conditions => conditions(params))
|
99
|
-
end
|
100
|
-
|
101
|
-
def best_selling_variants
|
102
|
-
li = LineItem.includes(:order).where("orders.state = 'complete'").sum(:quantity, :group => :variant_id, :order => 'sum(quantity) desc', :limit => 5)
|
103
|
-
variants = li.map do |v|
|
104
|
-
variant = Variant.find(v[0])
|
105
|
-
[variant.name, v[1] ]
|
106
|
-
end
|
107
|
-
variants.sort { |x,y| y[1] <=> x[1] }
|
108
|
-
end
|
109
|
-
|
110
|
-
def top_grossing_variants
|
111
|
-
prices = LineItem.includes(:order).where("orders.state = 'complete'").sum(:price, :group => :variant_id, :order => 'sum(price) desc', :limit => 5)
|
112
|
-
variants = prices.map do |v|
|
113
|
-
variant = Variant.find(v[0])
|
114
|
-
[variant.name, v[1] * prices[v[0]]]
|
115
|
-
end
|
116
|
-
|
117
|
-
variants.sort { |x,y| y[1] <=> x[1] }
|
118
|
-
end
|
119
|
-
|
120
|
-
def best_selling_taxons
|
121
|
-
taxonomy = Taxonomy.last
|
122
|
-
taxons = Taxon.connection.select_rows("select t.name, count(li.quantity) from line_items li inner join variants v on
|
123
|
-
li.variant_id = v.id inner join products p on v.product_id = p.id inner join products_taxons pt on p.id = pt.product_id
|
124
|
-
inner join taxons t on pt.taxon_id = t.id where t.taxonomy_id = #{taxonomy.id} group by t.name order by count(li.quantity) desc limit 5;")
|
125
|
-
end
|
126
|
-
|
127
|
-
def last_five_orders
|
128
|
-
orders = Order.includes(:line_items).where("completed_at IS NOT NULL AND state <> 'canceled'").order("completed_at DESC").limit(5)
|
129
|
-
orders.map do |o|
|
130
|
-
qty = o.line_items.inject(0) {|sum,li| sum + li.quantity}
|
131
|
-
|
132
|
-
[o.email, qty, o.total]
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
def biggest_spenders
|
137
|
-
spenders = Order.sum(:total, :group => :user_id, :limit => 5, :order => "sum(total) desc", :conditions => "completed_at is not null and state <> 'canceled' and user_id is not null")
|
138
|
-
spenders = spenders.map do |o|
|
139
|
-
orders = User.find(o[0]).orders
|
140
|
-
qty = orders.size
|
141
|
-
|
142
|
-
[orders.first.email, qty, o[1]]
|
143
|
-
|
144
|
-
end
|
145
|
-
|
146
|
-
spenders.sort { |x,y| y[2] <=> x[2] }
|
147
|
-
end
|
148
|
-
|
149
|
-
def out_of_stock_products
|
150
|
-
Product.where(:count_on_hand => 0).limit(5)
|
151
|
-
end
|
152
|
-
end
|
@@ -1,164 +0,0 @@
|
|
1
|
-
<h1><%= t(:overview) %></h1>
|
2
|
-
|
3
|
-
<div data-hook="admin_dashboard">
|
4
|
-
<% if @show_dashboard %>
|
5
|
-
<div class="dashboard">
|
6
|
-
<div class="dashboard_left">
|
7
|
-
<div data-hook="admin_dashboard_left">
|
8
|
-
<div class="dashboard_small_wrapper">
|
9
|
-
<h2><%= t(:best_selling_products) %></h2>
|
10
|
-
<div id="best_selling_products" style="width:50%; height:170px; float:left;"></div>
|
11
|
-
<div id="pie_legend">
|
12
|
-
<% @best_selling_variants.each_with_index do |v,i| %>
|
13
|
-
<span style="background-color:<%= @pie_colors[i] %>"> </span>
|
14
|
-
<label><%= truncate v[0], :length => 27 %></label>
|
15
|
-
<div><%= number_with_delimiter v[1] %> <%= t(:units) %></div>
|
16
|
-
<% end %>
|
17
|
-
</div>
|
18
|
-
|
19
|
-
<h2><%= t(:top_grossing_products) %></h2>
|
20
|
-
<div id="top_grossing_products" style="width:50%; height:170px; float:left;"></div>
|
21
|
-
<div id="pie_legend">
|
22
|
-
<% @top_grossing_variants.each_with_index do |v,i| %>
|
23
|
-
<span style="background-color:<%= @pie_colors[i] %>"> </span>
|
24
|
-
<label><%= truncate v[0], :length => 27 %></label>
|
25
|
-
<div><%= number_to_currency v[1], :precision => 0 %></div>
|
26
|
-
<% end %>
|
27
|
-
</div>
|
28
|
-
|
29
|
-
<h2><%= t(:best_selling_taxons) %></h2>
|
30
|
-
<div id="best_selling_taxons" style="width:50%; height:170px; float:left;"></div>
|
31
|
-
<div id="pie_legend">
|
32
|
-
<% @best_selling_taxons.each_with_index do |t,i| %>
|
33
|
-
<span style="background-color:<%= @pie_colors[i] %>"> </span>
|
34
|
-
<label><%= truncate t[0], :length => 27 %></label>
|
35
|
-
<div><%= number_with_delimiter t[1] %> <%= t(:units) %></div>
|
36
|
-
<% end %>
|
37
|
-
</div>
|
38
|
-
|
39
|
-
</div>
|
40
|
-
</div>
|
41
|
-
</div>
|
42
|
-
<div data-hook="admin_dashboard_center">
|
43
|
-
<div class="dashboard_main">
|
44
|
-
<div class="dashboard_main_wrapper">
|
45
|
-
<h2 id="order_by_day_title"><%= t('orders') %> <%= t('count') %> <%= t('by_day') %> (<%= t('last_7_days') %>)</h2>
|
46
|
-
|
47
|
-
<table id="order_totals">
|
48
|
-
<tr>
|
49
|
-
<td style="width:23%;">
|
50
|
-
<p><%= t("number.currency.format.unit") %></p>
|
51
|
-
<label id="orders_total"><%= number_with_delimiter @orders_total.to_i %></label>
|
52
|
-
<span><%= t('order') %> <%= t('total') %></span>
|
53
|
-
</td>
|
54
|
-
<td class="spacer">|</td>
|
55
|
-
<td style="width:23%;">
|
56
|
-
<p><%= t("number.currency.format.unit") %></p>
|
57
|
-
<label id="orders_line_total"><%= number_with_delimiter @orders_line_total.to_i %></label>
|
58
|
-
<span><%= t('item') %> <%= t('total') %></span>
|
59
|
-
</td>
|
60
|
-
<td class="spacer">|</td>
|
61
|
-
<td style="width:23%;">
|
62
|
-
<p><%= t("number.currency.format.unit") %></p>
|
63
|
-
<label id="orders_adjustment_total"><%= number_with_delimiter @orders_adjustment_total.to_i %></label>
|
64
|
-
<span><%= t('adjustments') %></span>
|
65
|
-
</td>
|
66
|
-
<td class="spacer">|</td>
|
67
|
-
<td style="width:22%">
|
68
|
-
<p><%= t("number.currency.format.unit") %></p>
|
69
|
-
<label id="orders_adjustment_total"><%= number_with_delimiter @orders_credit_total.to_i %></label>
|
70
|
-
<span><%= t('credits') %></span>
|
71
|
-
</td>
|
72
|
-
</tr>
|
73
|
-
</table>
|
74
|
-
|
75
|
-
<div id="orders_by_day" style="width:100%;height:240px;"></div>
|
76
|
-
|
77
|
-
<div id="orders_by_day_options">
|
78
|
-
<label><%= t('range') %>:</label>
|
79
|
-
<%= select_tag "orders_by_day_reports", options_for_select([[t('last_7_days'), "7_days"], [t('last_14_days'), "14_days"], [t('this_month'), "this_month"],
|
80
|
-
[t('last_month'), "last_month"], [t('this_year'), "this_year"], [t('last_year'), "last_year"] ], "7_days") %>
|
81
|
-
<label><%= t('value') %>:</label>
|
82
|
-
<%= select_tag "orders_by_day_value", options_for_select({t('count') => 'Count', t('value') => 'Value'}, 'Count') %>
|
83
|
-
</div>
|
84
|
-
</div>
|
85
|
-
</div>
|
86
|
-
</div>
|
87
|
-
<div data-hook="admin_dashboard_right">
|
88
|
-
<div class="dashboard_right">
|
89
|
-
<h2><%= t('last_5_orders') %></h2>
|
90
|
-
<table>
|
91
|
-
<thead>
|
92
|
-
<tr>
|
93
|
-
<th><%= t('name') %></th>
|
94
|
-
<th class="text-right"><%= t('items') %></th>
|
95
|
-
<th class="text-right"><%= t('total') %></th>
|
96
|
-
</tr>
|
97
|
-
</thead>
|
98
|
-
<% @last_five_orders.each do |order| %>
|
99
|
-
<tr>
|
100
|
-
<td><%= truncate order[0], :length => 18 %></td>
|
101
|
-
<td class="text-right"><%= order[1] %></td>
|
102
|
-
<td class="text-right"><%= number_to_currency order[2] %></td>
|
103
|
-
</tr>
|
104
|
-
<% end %>
|
105
|
-
</table>
|
106
|
-
|
107
|
-
<h2><%= t('5_biggest_spenders') %></h2>
|
108
|
-
<table>
|
109
|
-
<thead>
|
110
|
-
<tr>
|
111
|
-
<th><%= t('name') %></th>
|
112
|
-
<th class="text-right"><%= t('ord_qty') %></th>
|
113
|
-
<th class="text-right"><%= t('ord_total') %></th>
|
114
|
-
</tr>
|
115
|
-
</thead>
|
116
|
-
<% @biggest_spenders.each do |order| %>
|
117
|
-
<tr>
|
118
|
-
<td><%= truncate order[0], :length => 18 %></td>
|
119
|
-
<td class="text-right"><%= order[1] %></td>
|
120
|
-
<td class="text-right"><%= number_to_currency order[2] %></td>
|
121
|
-
</tr>
|
122
|
-
<% end %>
|
123
|
-
</table>
|
124
|
-
|
125
|
-
<h2><%= t('out_of_stock_products') %></h2>
|
126
|
-
<table>
|
127
|
-
<thead>
|
128
|
-
<tr>
|
129
|
-
<th><%= t('name') %></th>
|
130
|
-
</tr>
|
131
|
-
</thead>
|
132
|
-
<% @out_of_stock_products.each do |product| %>
|
133
|
-
<tr>
|
134
|
-
<td><%= product.name %></td>
|
135
|
-
</tr>
|
136
|
-
<% end %>
|
137
|
-
</table>
|
138
|
-
</div>
|
139
|
-
</div>
|
140
|
-
</div>
|
141
|
-
<p style="clear:both;"> </p>
|
142
|
-
<% else %>
|
143
|
-
<div data-hook="admin_dashboard_welcome">
|
144
|
-
<%== t('overview_welcome') %>
|
145
|
-
</div>
|
146
|
-
<% end %>
|
147
|
-
</div>
|
148
|
-
|
149
|
-
<% content_for :head do %>
|
150
|
-
<% if @show_dashboard %>
|
151
|
-
<%= javascript_tag do -%>
|
152
|
-
var orders_by_day_points = [[<%== @orders_by_day.map { |day| "[\"#{day[0]}\",#{day[1]}]" }.join(",") %>]];
|
153
|
-
var best_selling_variants_points = [<%== @best_selling_variants.map { |v| "[\"#{h(v[0])}\",#{v[1]}]" }.join(",") %>];
|
154
|
-
var top_grossing_variants_points = [<%== @top_grossing_variants.map { |v| "[\"#{h(v[0])}\",#{v[1]}]" }.join(",") %>];
|
155
|
-
var best_selling_taxons_points = [<%== @best_selling_taxons.map { |t| "[\"#{h(t[0])}\",#{t[1]}]" }.join(",") %>];
|
156
|
-
|
157
|
-
var orders = "<%= t(:orders) %>";
|
158
|
-
var by_day = "<%= t(:by_day) %>";
|
159
|
-
|
160
|
-
var pie_colors = [<%== @pie_colors.map{|c| "'#{c}'"}.join(",") %>];
|
161
|
-
<% end -%>
|
162
|
-
<!--[if IE]><%= javascript_include_tag 'jqPlot/excanvas.min.js' %><![endif]-->
|
163
|
-
<% end %>
|
164
|
-
<% end %>
|