spree_advanced_reporting 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.gitignore +1 -0
  2. data/Gemfile +5 -0
  3. data/README.md +23 -0
  4. data/Rakefile +20 -0
  5. data/TODO.txt +3 -0
  6. data/app/assets/images/admin/advanced_reporting/asc.gif +0 -0
  7. data/app/assets/images/admin/advanced_reporting/barchart.png +0 -0
  8. data/app/assets/images/admin/advanced_reporting/bg.gif +0 -0
  9. data/app/assets/images/admin/advanced_reporting/close.png +0 -0
  10. data/app/assets/images/admin/advanced_reporting/desc.gif +0 -0
  11. data/app/assets/images/admin/advanced_reporting/menu-current-opposite.png +0 -0
  12. data/app/assets/images/admin/advanced_reporting/open.png +0 -0
  13. data/app/assets/images/admin/advanced_reporting/save.png +0 -0
  14. data/app/assets/images/admin/advanced_reporting/search.png +0 -0
  15. data/app/assets/images/admin/advanced_reporting/usa.png +0 -0
  16. data/app/assets/images/admin/advanced_reporting/world.png +0 -0
  17. data/app/assets/javascripts/admin/advanced_reporting/advanced_reporting.js +46 -0
  18. data/app/assets/javascripts/admin/advanced_reporting/jquery.tablesorter.min.js +4 -0
  19. data/app/assets/stylesheets/admin/advanced_reporting/advanced_reporting.css.erb +18 -0
  20. data/app/assets/stylesheets/pdf.css +15 -0
  21. data/app/controllers/spree/admin/advanced_report_overview_controller.rb +21 -0
  22. data/app/controllers/spree/admin/reports_controller_decorator.rb +127 -0
  23. data/app/helpers/advanced_report_helper.rb +13 -0
  24. data/app/models/ruport/formatter/html_decorator.rb +29 -0
  25. data/app/models/ruport/formatter/wicked_pdf_decorator.rb +12 -0
  26. data/app/views/spree/admin/advanced_report_overview/index.html.erb +117 -0
  27. data/app/views/spree/admin/reports/_advanced_report_criteria.html.erb +64 -0
  28. data/app/views/spree/admin/reports/geo_base.html.erb +61 -0
  29. data/app/views/spree/admin/reports/increment_base.html.erb +63 -0
  30. data/app/views/spree/admin/reports/outstanding.html.erb +16 -0
  31. data/app/views/spree/admin/reports/top_base.html.erb +17 -0
  32. data/config/locales/en.yml +96 -0
  33. data/config/locales/pt-BR.yml +92 -0
  34. data/config/routes.rb +37 -0
  35. data/lib/spree/advanced_report.rb +225 -0
  36. data/lib/spree/advanced_report/geo_report.rb +2 -0
  37. data/lib/spree/advanced_report/geo_report/geo_profit.rb +44 -0
  38. data/lib/spree/advanced_report/geo_report/geo_revenue.rb +44 -0
  39. data/lib/spree/advanced_report/geo_report/geo_units.rb +42 -0
  40. data/lib/spree/advanced_report/increment_report.rb +78 -0
  41. data/lib/spree/advanced_report/increment_report/count.rb +33 -0
  42. data/lib/spree/advanced_report/increment_report/profit.rb +41 -0
  43. data/lib/spree/advanced_report/increment_report/revenue.rb +40 -0
  44. data/lib/spree/advanced_report/increment_report/units.rb +33 -0
  45. data/lib/spree/advanced_report/top_report.rb +2 -0
  46. data/lib/spree/advanced_report/top_report/top_customers.rb +32 -0
  47. data/lib/spree/advanced_report/top_report/top_products.rb +35 -0
  48. data/lib/spree/advanced_report/transaction_report.rb +79 -0
  49. data/lib/spree_advanced_reporting.rb +25 -0
  50. data/spree_advanced_reporting.gemspec +22 -0
  51. metadata +133 -0
@@ -0,0 +1,41 @@
1
+ class Spree::AdvancedReport::IncrementReport::Profit < Spree::AdvancedReport::IncrementReport
2
+ def name
3
+ I18n.t("adv_report.increment_report.profit.name")
4
+ "Profit"
5
+ end
6
+
7
+ def column
8
+ I18n.t("adv_report.increment_report.profit.column")
9
+ "Profit"
10
+ end
11
+
12
+ def description
13
+ I18n.t("adv_report.increment_report.profit.description")
14
+ end
15
+
16
+ def initialize(params)
17
+ super(params)
18
+ self.total = 0
19
+ self.orders.each do |order|
20
+ date = {}
21
+ INCREMENTS.each do |type|
22
+ date[type] = get_bucket(type, order.completed_at || order.updated_at)
23
+ data[type][date[type]] ||= {
24
+ :value => 0,
25
+ :display => get_display(type, order.completed_at || order.updated_at),
26
+ }
27
+ end
28
+ profit = profit(order)
29
+ INCREMENTS.each { |type| data[type][date[type]][:value] += profit }
30
+ self.total += profit
31
+ end
32
+
33
+ generate_ruport_data
34
+
35
+ INCREMENTS.each { |type| ruportdata[type].replace_column(name) { |r| "$%0.2f" % r[name] } }
36
+ end
37
+
38
+ def format_total
39
+ '$' + ((self.total*100).round.to_f / 100).to_s
40
+ end
41
+ end
@@ -0,0 +1,40 @@
1
+ class Spree::AdvancedReport::IncrementReport::Revenue < Spree::AdvancedReport::IncrementReport
2
+ def name
3
+ I18n.t("adv_report.increment_report.revenue.name")
4
+ end
5
+
6
+ def column
7
+ I18n.t("adv_report.increment_report.revenue.column")
8
+ end
9
+
10
+ def description
11
+ I18n.t("adv_report.increment_report.revenue.description")
12
+ end
13
+
14
+ def initialize(params)
15
+ super(params)
16
+ self.total = 0
17
+
18
+ self.orders.each do |order|
19
+ date = {}
20
+ INCREMENTS.each do |type|
21
+ date[type] = get_bucket(type, (order.completed_at || order.updated_at))
22
+ data[type][date[type]] ||= {
23
+ :value => 0,
24
+ :display => get_display(type, (order.completed_at || order.updated_at)),
25
+ }
26
+ end
27
+ rev = revenue(order)
28
+ INCREMENTS.each { |type| data[type][date[type]][:value] += rev }
29
+ self.total += rev
30
+ end
31
+
32
+ generate_ruport_data
33
+
34
+ INCREMENTS.each { |type| ruportdata[type].replace_column(name) { |r| "$%0.2f" % r[name] } }
35
+ end
36
+
37
+ def format_total
38
+ '$' + ((self.total*100).round.to_f / 100).to_s
39
+ end
40
+ end
@@ -0,0 +1,33 @@
1
+ class Spree::AdvancedReport::IncrementReport::Units < Spree::AdvancedReport::IncrementReport
2
+ def name
3
+ I18n.t("adv_report.increment_report.units.name")
4
+ end
5
+
6
+ def column
7
+ I18n.t("adv_report.increment_report.units.column")
8
+ end
9
+
10
+ def description
11
+ I18n.t("adv_report.increment_report.units.description")
12
+ end
13
+
14
+ def initialize(params)
15
+ super(params)
16
+ self.total = 0
17
+ self.orders.each do |order|
18
+ date = {}
19
+ INCREMENTS.each do |type|
20
+ date[type] = get_bucket(type, order.completed_at)
21
+ data[type][date[type]] ||= {
22
+ :value => 0,
23
+ :display => get_display(type, order.completed_at),
24
+ }
25
+ end
26
+ units = units(order)
27
+ INCREMENTS.each { |type| data[type][date[type]][:value] += units }
28
+ self.total += units
29
+ end
30
+
31
+ generate_ruport_data
32
+ end
33
+ end
@@ -0,0 +1,2 @@
1
+ class Spree::AdvancedReport::TopReport < Spree::AdvancedReport
2
+ end
@@ -0,0 +1,32 @@
1
+ class Spree::AdvancedReport::TopReport::TopCustomers < Spree::AdvancedReport::TopReport
2
+ def name
3
+ I18n.t("adv_report.top_report.top_customers.name")
4
+ end
5
+
6
+ def description
7
+ I18n.t("adv_report.top_report.top_customers.description")
8
+ end
9
+
10
+ def initialize(params, limit)
11
+ super(params)
12
+
13
+ orders.each do |order|
14
+ if order.user
15
+ data[order.user.id] ||= {
16
+ :email => order.user.email,
17
+ :revenue => 0,
18
+ :units => 0
19
+ }
20
+ data[order.user.id][:revenue] += revenue(order)
21
+ data[order.user.id][:units] += units(order)
22
+ end
23
+ end
24
+
25
+ self.ruportdata = Table(I18n.t("adv_report.top_report.top_customers.table"))
26
+ data.inject({}) { |h, (k, v) | h[k] = v[:revenue]; h }.sort { |a, b| a[1] <=> b [1] }.reverse[0..4].each do |k, v|
27
+ ruportdata << { "email" => data[k][:email], I18n.t("adv_report.units") => data[k][:units], I18n.t("adv_report.revenue") => data[k][:revenue] }
28
+ end
29
+ ruportdata.replace_column(I18n.t("adv_report.revenue")) { |r| "$%0.2f" % r.send(I18n.t("adv_report.revenue")) }
30
+ ruportdata.rename_column("email", I18n.t("adv_report.top_report.top_customers.customer_email"))
31
+ end
32
+ end
@@ -0,0 +1,35 @@
1
+ class Spree::AdvancedReport::TopReport::TopProducts < Spree::AdvancedReport::TopReport
2
+ def name
3
+ I18n.t("adv_report.top_report.top_products.name")
4
+ end
5
+
6
+ def description
7
+ I18n.t("adv_report.top_report.top_products.description")
8
+ end
9
+
10
+ def initialize(params, limit)
11
+ super(params)
12
+
13
+ orders.each do |order|
14
+ order.line_items.each do |li|
15
+ if !li.product.nil?
16
+ data[li.product.id] ||= {
17
+ :name => li.product.name.to_s,
18
+ :revenue => 0,
19
+ :units => 0
20
+ }
21
+ data[li.product.id][:revenue] += li.quantity*li.price
22
+ data[li.product.id][:units] += li.quantity
23
+ end
24
+ end
25
+ end
26
+
27
+ self.ruportdata = Table(I18n.t("adv_report.top_report.top_products.table"))
28
+ data.inject({}) { |h, (k, v) | h[k] = v[:revenue]; h }.sort { |a, b| a[1] <=> b [1] }.reverse[0..limit].each do |k, v|
29
+ ruportdata << { "name" => data[k][:name], I18n.t("adv_report.units") => data[k][:units], I18n.t("adv_report.revenue") => data[k][:revenue] }
30
+ end
31
+
32
+ ruportdata.replace_column(I18n.t("adv_report.revenue")) { |r| "$%0.2f" % r.send(I18n.t("adv_report.revenue")) }
33
+ ruportdata.rename_column("name", I18n.t("adv_report.top_report.top_products.product_name"))
34
+ end
35
+ end
@@ -0,0 +1,79 @@
1
+ class Spree::AdvancedReport::TransactionReport < Spree::AdvancedReport
2
+ include ActionView::Helpers::NumberHelper
3
+ include ActionView::Helpers::UrlHelper
4
+
5
+ def name
6
+ "Transaction Report"
7
+ end
8
+
9
+ def description
10
+ "Top purchasing customers, calculated by revenue"
11
+ end
12
+
13
+ def initialize(params)
14
+ super(params)
15
+
16
+ self.ruportdata = Ruport::Data::Group.new({
17
+ :name => "#{self.name} #{self.date_range}",
18
+ :column_names => %w[date type id total state]
19
+ })
20
+
21
+ card_listing = {}
22
+
23
+ orders.each do |order|
24
+ order.payments.each do |payment|
25
+ # create a direct link for easy inspection
26
+ gateway_link = payment.response_code
27
+
28
+ if payment.payment_method.type == "Spree::Gateway::AuthorizeNetCim" and payment.response_code.present?
29
+ gateway_link = link_to(payment.response_code, "https://account.authorize.net/UI/themes/anet/transaction/transactiondetail.aspx?transID=#{payment.response_code}", target: '_blank')
30
+ end
31
+
32
+ if payment.source.class == Spree::Creditcard
33
+ credit_cart_type = payment.source.cc_type
34
+ else
35
+ # it seems as though a previous payment can be used a payment type
36
+ # links to the previous payment's credit card
37
+ credit_cart_type = payment.source.source.cc_type
38
+ end
39
+
40
+ (card_listing[credit_cart_type] ||= []) << {
41
+ "date" => payment.source.created_at.to_formatted_s(:db),
42
+ "type" => credit_cart_type.humanize.titlecase,
43
+ "id" => gateway_link,
44
+ "total" => payment.amount,
45
+ "state" => payment.state,
46
+ }
47
+ end
48
+ end
49
+
50
+ @sales_total = 0
51
+
52
+ card_listing.keys.sort.each do |card_name|
53
+ card_total = card_listing[card_name].map { |c| c["total"] * (c["state"] == 'void' ? 0 : 1) }.sum
54
+ @sales_total += card_total
55
+
56
+ ruportdata << {
57
+ "date" => "<b>#{card_name.humanize.titlecase} (#{card_listing[card_name].count}): #{number_to_currency(card_total)}</b>"
58
+ }
59
+
60
+ card_listing[card_name].each do |transaction|
61
+ transaction["total"] = number_to_currency(transaction["total"])
62
+ ruportdata << transaction
63
+ end
64
+ end
65
+
66
+ ruportdata << { "date" => "<b>Sales Total: #{number_to_currency(@sales_total)}</b>" }
67
+
68
+ # spaces don't seem to work in column names (ruport is old...)
69
+ ruportdata.rename_column("date", "Transaction Date")
70
+ ruportdata.rename_column("type", "Card Type")
71
+ ruportdata.rename_column("id", "Transaction ID")
72
+ ruportdata.rename_column("total", "Payment Total")
73
+ ruportdata.rename_column("state", "Payment State")
74
+ end
75
+
76
+ def sales_total
77
+ @sales_total
78
+ end
79
+ end
@@ -0,0 +1,25 @@
1
+ require "ruport"
2
+ require 'wicked_pdf'
3
+
4
+ module Spree
5
+ module AdvancedReporting
6
+ class Engine < Rails::Engine
7
+ engine_name "spree_advanced_reporting"
8
+
9
+ config.autoload_paths += %W(#{config.root}/lib)
10
+
11
+ initializer :assets do |config|
12
+ Rails.application.config.assets.precompile += %w( admin/advanced_reporting/advanced_reporting.css )
13
+ end
14
+
15
+ def self.activate
16
+ Dir.glob(File.join(File.dirname(__FILE__), "../app/**/*_decorator.rb")).each do |c|
17
+ Rails.env.production? ? require(c) : load(c)
18
+ end
19
+ end
20
+
21
+ config.to_prepare &method(:activate).to_proc
22
+ end
23
+ end
24
+ end
25
+
@@ -0,0 +1,22 @@
1
+ Gem::Specification.new do |s|
2
+ s.platform = Gem::Platform::RUBY
3
+ s.name = 'spree_advanced_reporting'
4
+ s.version = '2.1.0'
5
+ s.summary = 'Advanced Reporting for Spree'
6
+ s.description = 'Adds many useful reports, with PDF and CSV output, to Spree'
7
+ s.homepage = 'https://github.com/iloveitaly/spree_advanced_reporting'
8
+ s.authors = ['Steph Skardal', 'Michael Bianco']
9
+ s.email = ['steph@endpoint.com', 'info@cliffsidedev.com']
10
+ s.required_ruby_version = '>= 1.8.7'
11
+
12
+ s.files = `git ls-files`.split("\n")
13
+ s.require_path = 'lib'
14
+ s.requirements << 'none'
15
+
16
+ s.has_rdoc = true
17
+
18
+ s.add_dependency 'spree_core', '>= 1.1.2'
19
+
20
+ # use https://github.com/iloveitaly/ruport/tree/wicked-pdf
21
+ s.add_dependency 'ruport', '>= 1.8'
22
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spree_advanced_reporting
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Steph Skardal
9
+ - Michael Bianco
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-12-04 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: spree_core
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: 1.1.2
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: 1.1.2
31
+ - !ruby/object:Gem::Dependency
32
+ name: ruport
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '1.8'
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '1.8'
47
+ description: Adds many useful reports, with PDF and CSV output, to Spree
48
+ email:
49
+ - steph@endpoint.com
50
+ - info@cliffsidedev.com
51
+ executables: []
52
+ extensions: []
53
+ extra_rdoc_files: []
54
+ files:
55
+ - .gitignore
56
+ - Gemfile
57
+ - README.md
58
+ - Rakefile
59
+ - TODO.txt
60
+ - app/assets/images/admin/advanced_reporting/asc.gif
61
+ - app/assets/images/admin/advanced_reporting/barchart.png
62
+ - app/assets/images/admin/advanced_reporting/bg.gif
63
+ - app/assets/images/admin/advanced_reporting/close.png
64
+ - app/assets/images/admin/advanced_reporting/desc.gif
65
+ - app/assets/images/admin/advanced_reporting/menu-current-opposite.png
66
+ - app/assets/images/admin/advanced_reporting/open.png
67
+ - app/assets/images/admin/advanced_reporting/save.png
68
+ - app/assets/images/admin/advanced_reporting/search.png
69
+ - app/assets/images/admin/advanced_reporting/usa.png
70
+ - app/assets/images/admin/advanced_reporting/world.png
71
+ - app/assets/javascripts/.DS_Store
72
+ - app/assets/javascripts/admin/.DS_Store
73
+ - app/assets/javascripts/admin/advanced_reporting/advanced_reporting.js
74
+ - app/assets/javascripts/admin/advanced_reporting/jquery.tablesorter.min.js
75
+ - app/assets/stylesheets/admin/.DS_Store
76
+ - app/assets/stylesheets/admin/advanced_reporting/advanced_reporting.css.erb
77
+ - app/assets/stylesheets/pdf.css
78
+ - app/controllers/spree/admin/advanced_report_overview_controller.rb
79
+ - app/controllers/spree/admin/reports_controller_decorator.rb
80
+ - app/helpers/advanced_report_helper.rb
81
+ - app/models/ruport/formatter/html_decorator.rb
82
+ - app/models/ruport/formatter/wicked_pdf_decorator.rb
83
+ - app/views/spree/admin/advanced_report_overview/index.html.erb
84
+ - app/views/spree/admin/reports/_advanced_report_criteria.html.erb
85
+ - app/views/spree/admin/reports/geo_base.html.erb
86
+ - app/views/spree/admin/reports/increment_base.html.erb
87
+ - app/views/spree/admin/reports/outstanding.html.erb
88
+ - app/views/spree/admin/reports/top_base.html.erb
89
+ - config/locales/en.yml
90
+ - config/locales/pt-BR.yml
91
+ - config/routes.rb
92
+ - lib/spree/advanced_report.rb
93
+ - lib/spree/advanced_report/geo_report.rb
94
+ - lib/spree/advanced_report/geo_report/geo_profit.rb
95
+ - lib/spree/advanced_report/geo_report/geo_revenue.rb
96
+ - lib/spree/advanced_report/geo_report/geo_units.rb
97
+ - lib/spree/advanced_report/increment_report.rb
98
+ - lib/spree/advanced_report/increment_report/count.rb
99
+ - lib/spree/advanced_report/increment_report/profit.rb
100
+ - lib/spree/advanced_report/increment_report/revenue.rb
101
+ - lib/spree/advanced_report/increment_report/units.rb
102
+ - lib/spree/advanced_report/top_report.rb
103
+ - lib/spree/advanced_report/top_report/top_customers.rb
104
+ - lib/spree/advanced_report/top_report/top_products.rb
105
+ - lib/spree/advanced_report/transaction_report.rb
106
+ - lib/spree_advanced_reporting.rb
107
+ - spree_advanced_reporting.gemspec
108
+ homepage: https://github.com/iloveitaly/spree_advanced_reporting
109
+ licenses: []
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: 1.8.7
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements:
127
+ - none
128
+ rubyforge_project:
129
+ rubygems_version: 1.8.24
130
+ signing_key:
131
+ specification_version: 3
132
+ summary: Advanced Reporting for Spree
133
+ test_files: []