shopify_dashboard_plus 0.0.7 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +16 -0
  3. data/.travis.yml +6 -0
  4. data/Gemfile.lock +99 -35
  5. data/README.md +16 -7
  6. data/Rakefile +13 -0
  7. data/bin/shopify_dashboard_plus.rb +1 -1
  8. data/config.ru +4 -0
  9. data/lib/shopify_dashboard_plus.rb +40 -52
  10. data/lib/shopify_dashboard_plus/currency.rb +31 -0
  11. data/lib/shopify_dashboard_plus/discount_report.rb +36 -0
  12. data/lib/shopify_dashboard_plus/helpers.rb +65 -51
  13. data/lib/shopify_dashboard_plus/report.rb +4 -196
  14. data/lib/shopify_dashboard_plus/revenue_report.rb +55 -0
  15. data/lib/shopify_dashboard_plus/sales_report.rb +86 -0
  16. data/lib/shopify_dashboard_plus/traffic_report.rb +65 -0
  17. data/lib/shopify_dashboard_plus/version.rb +3 -1
  18. data/shopify_dashboard_plus.gemspec +17 -7
  19. data/test/fixtures/vcr_cassettes/.gitkeep +0 -0
  20. data/test/fixtures/vcr_cassettes/authenticate.yml +88 -0
  21. data/test/fixtures/vcr_cassettes/multiple_pages_orders.yml +1544 -0
  22. data/test/fixtures/vcr_cassettes/orders_from_2010_01_01.yml +815 -0
  23. data/test/fixtures/vcr_cassettes/orders_from_2010_01_01_to_2015_01_01.yml +566 -0
  24. data/test/fixtures/vcr_cassettes/orders_no_paramaters.yml +81 -0
  25. data/test/fixtures/vcr_cassettes/orders_none.yml +77 -0
  26. data/test/fixtures/vcr_cassettes/orders_to_2015-06-26.yml +81 -0
  27. data/test/resources/anonymizer.rb +125 -0
  28. data/test/resources/modify_data.rb +110 -0
  29. data/test/strip_sensitive_data.rb +79 -0
  30. data/test/test_app.rb +60 -0
  31. data/test/test_frontend.rb +76 -0
  32. data/test/test_mockdata.rb +237 -0
  33. data/views/connect.erb +6 -6
  34. data/views/layout.erb +2 -3
  35. data/views/report.erb +1 -1
  36. metadata +190 -59
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9fdfd548de3a3601bf7e6b95a270e47cf5ceaa27
4
- data.tar.gz: a1d785b1ac756ff95eafd897167ae39ed0035429
3
+ metadata.gz: 368458584f187d4a84965649cdef6626a22b9d2b
4
+ data.tar.gz: b5bee8a64a3565bd2ba4cc647a0c448616ef9cf1
5
5
  SHA512:
6
- metadata.gz: 2024bcd98be9ced7b9c41a68fdeecf114c0556d7f7a13b2d9dfbe8d39dea0e8bfa2565ef0da7c359332812b3a72d6cab3fbefc10bc9b3052aa4b8f5f204c8ec2
7
- data.tar.gz: bd114f9ed38cc8ad8f71241835518977db22e486839db4f8ef38a031e64b1bceb94493c59b77ee058349e64af043267221c4bf91aaec6bbc7aee649829736bf5
6
+ metadata.gz: '06321384b8a0c88ed08f3acaeef748686720b36ba00edbc7642769ad290ad0a895e494644bc5e05be684d3ab8d4d3556c94ee1c94898a479e8352c7ed57d8575'
7
+ data.tar.gz: 607ea7132f9ba3252c153105d574687951949a71e2fa5b265771f64365436eb53d1241fc0f6b33e8af32544f37969d69a4e0c82e0200a673b498594ebaeb768a
@@ -0,0 +1,16 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.3
3
+ Exclude:
4
+ - Gemfile
5
+ - shopify_dashboard_plus.gemspec
6
+
7
+ Metrics/LineLength:
8
+ Exclude:
9
+ - test/**/*
10
+ Max: 120
11
+
12
+ Style/HashSyntax:
13
+ Enabled: false
14
+
15
+ Style/StringLiterals:
16
+ Enabled: false
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.6
4
+ - 2.4.3
5
+ - 2.5.0
6
+ script: bundle exec xvfb-run rake
@@ -1,58 +1,122 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shopify_dashboard_plus (0.0.1)
5
- chartkick (~> 1.3, >= 1.3.2)
6
- shopify_api (~> 4.0, >= 4.0.3)
7
- sinatra (~> 1.4, >= 1.4.5)
8
- tilt
4
+ shopify_dashboard_plus (1.0.0)
5
+ chartkick (~> 2.3)
6
+ shopify_api (= 4.9.1)
7
+ sinatra (~> 2.0)
9
8
  vegas (~> 0.1, >= 0.1.11)
10
9
 
11
10
  GEM
12
11
  remote: https://rubygems.org/
13
12
  specs:
14
- activemodel (4.2.1)
15
- activesupport (= 4.2.1)
13
+ activemodel (5.1.5)
14
+ activesupport (= 5.1.5)
15
+ activemodel-serializers-xml (1.0.2)
16
+ activemodel (> 5.x)
17
+ activesupport (> 5.x)
16
18
  builder (~> 3.1)
17
- activeresource (4.0.0)
18
- activemodel (~> 4.0)
19
- activesupport (~> 4.0)
20
- rails-observers (~> 0.1.1)
21
- activesupport (4.2.1)
19
+ activeresource (5.0.0)
20
+ activemodel (>= 5.0, < 6)
21
+ activemodel-serializers-xml (~> 1.0)
22
+ activesupport (>= 5.0, < 6)
23
+ activesupport (5.1.5)
24
+ concurrent-ruby (~> 1.0, >= 1.0.2)
22
25
  i18n (~> 0.7)
23
- json (~> 1.7, >= 1.7.7)
24
26
  minitest (~> 5.1)
25
- thread_safe (~> 0.3, >= 0.3.4)
26
27
  tzinfo (~> 1.1)
27
- builder (3.2.2)
28
- chartkick (1.3.2)
29
- i18n (0.7.0)
30
- json (1.8.2)
31
- minitest (5.6.1)
32
- rack (1.6.1)
33
- rack-protection (1.5.3)
28
+ addressable (2.5.2)
29
+ public_suffix (>= 2.0.2, < 4.0)
30
+ ast (2.4.0)
31
+ builder (3.2.3)
32
+ byebug (10.0.0)
33
+ capybara (2.18.0)
34
+ addressable
35
+ mini_mime (>= 0.1.3)
36
+ nokogiri (>= 1.3.3)
37
+ rack (>= 1.0.0)
38
+ rack-test (>= 0.5.4)
39
+ xpath (>= 2.0, < 4.0)
40
+ capybara-webkit (1.15.0)
41
+ capybara (>= 2.3, < 4.0)
42
+ json
43
+ chartkick (2.3.2)
44
+ concurrent-ruby (1.0.5)
45
+ crack (0.4.3)
46
+ safe_yaml (~> 1.0.0)
47
+ faker (1.8.7)
48
+ i18n (>= 0.7)
49
+ hashdiff (0.3.7)
50
+ i18n (0.9.5)
51
+ concurrent-ruby (~> 1.0)
52
+ json (2.1.0)
53
+ mini_mime (1.0.0)
54
+ mini_portile2 (2.3.0)
55
+ minitest (5.11.3)
56
+ mustermann (1.0.2)
57
+ nokogiri (1.8.2)
58
+ mini_portile2 (~> 2.3.0)
59
+ parallel (1.12.1)
60
+ parser (2.5.0.3)
61
+ ast (~> 2.4.0)
62
+ powerpack (0.1.1)
63
+ public_suffix (3.0.2)
64
+ rack (2.0.4)
65
+ rack-protection (2.0.1)
34
66
  rack
35
- rails-observers (0.1.2)
36
- activemodel (~> 4.0)
37
- rake (10.4.2)
38
- shopify_api (4.0.3)
39
- activeresource
67
+ rack-test (0.8.3)
68
+ rack (>= 1.0, < 3)
69
+ rainbow (3.0.0)
70
+ rake (12.3.0)
71
+ rubocop (0.53.0)
72
+ parallel (~> 1.10)
73
+ parser (>= 2.5)
74
+ powerpack (~> 0.1)
75
+ rainbow (>= 2.2.2, < 4.0)
76
+ ruby-progressbar (~> 1.7)
77
+ unicode-display_width (~> 1.0, >= 1.0.1)
78
+ ruby-progressbar (1.9.0)
79
+ safe_yaml (1.0.4)
80
+ shopify_api (4.9.1)
81
+ activeresource (>= 3.0.0)
40
82
  rack
41
- sinatra (1.4.6)
42
- rack (~> 1.4)
43
- rack-protection (~> 1.4)
44
- tilt (>= 1.3, < 3)
45
- thread_safe (0.3.5)
46
- tilt (2.0.1)
47
- tzinfo (1.2.2)
83
+ sinatra (2.0.1)
84
+ mustermann (~> 1.0)
85
+ rack (~> 2.0)
86
+ rack-protection (= 2.0.1)
87
+ tilt (~> 2.0)
88
+ thread_safe (0.3.6)
89
+ tilt (2.0.8)
90
+ tzinfo (1.2.5)
48
91
  thread_safe (~> 0.1)
92
+ unicode-display_width (1.3.0)
93
+ vcr (3.0.3)
49
94
  vegas (0.1.11)
50
95
  rack (>= 1.0.0)
96
+ webmock (3.3.0)
97
+ addressable (>= 2.3.6)
98
+ crack (>= 0.3.2)
99
+ hashdiff
100
+ xpath (3.0.0)
101
+ nokogiri (~> 1.8)
51
102
 
52
103
  PLATFORMS
53
104
  ruby
54
105
 
55
106
  DEPENDENCIES
56
- bundler (~> 1.7)
57
- rake (~> 10.0)
107
+ bundler (~> 1.16)
108
+ byebug (~> 10.0)
109
+ capybara (~> 2.18)
110
+ capybara-webkit (~> 1.15)
111
+ faker (~> 1.8)
112
+ minitest (~> 5.11)
113
+ rack-test (~> 0.8)
114
+ rake (~> 12.3)
115
+ rubocop (~> 0.53.0)
58
116
  shopify_dashboard_plus!
117
+ tilt (~> 2.0)
118
+ vcr (~> 3.0)
119
+ webmock (~> 3.3)
120
+
121
+ BUNDLED WITH
122
+ 1.16.1
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Shopify_Dashboard_Plus [![Gem Version](https://badge.fury.io/rb/shopify_dashboard_plus.svg)](http://badge.fury.io/rb/shopify_dashboard_plus)
1
+ # Shopify_Dashboard_Plus [![Gem Version](https://badge.fury.io/rb/shopify_dashboard_plus.svg)](http://badge.fury.io/rb/shopify_dashboard_plus) [![Build Status](https://travis-ci.org/at1as/Shopify_Dashboard_Plus.svg?branch=master)](https://travis-ci.org/at1as/Shopify_Dashboard_Plus) <a href="https://codeclimate.com/github/at1as/Shopify_Dashboard_Plus"><img src="https://codeclimate.com/github/at1as/Shopify_Dashboard_Plus/badges/gpa.svg" /></a>
2
2
  Pretty Dashboard for Shopify Admin with lots of graphs.
3
3
 
4
4
  ## Screenshots
@@ -38,17 +38,26 @@ Choose the interval over which to get data and see it displayed as:
38
38
  * Revenue Per Referral Site
39
39
  * Revenue Per Specific Referral Site Page
40
40
 
41
- ## Usage
41
+ ## Installation
42
42
  * To install manually:
43
43
  * `git clone https://github.com/at1as/Shopify_Dashboard_Plus.git`
44
44
  * To install using the gem:
45
45
  * `gem install shopify_dashboard_plus`
46
- * `shopify_dashboard_plus.rb`
46
+ * Or, if you just want to try it out, head over to [Heroku](https://shopifydashboardplus.herokuapp.com/)
47
+ * Generally it's unwise to pass your API key & password through some hosted website. The code run on Heroku is taken automatically from this repo and you can check the source to see that the keys aren't being saved, but if you're in doubt, either create new credentials for this app and then revoke them after you're finished, or just install run locally with either option listed above instead.
48
+
49
+ ## Usage
47
50
  * Retrieve `API Key`, `Password` and `Shop Name` for your store from Shopify Admin
48
- * Run (key, password & name can be passed as environment variables, or later thorugh the UI):
49
- * `SHP_KEY="API KEY" SHP_PWD="PASSWORD" SHP_NAME="SHOP NAME" ./lib/shopify_dashboard_plus.rb`
51
+ * Run with environment variables
52
+ * `SHP_KEY="API KEY" SHP_PWD="PASSWORD" SHP_NAME="SHOP NAME" ./lib/shopify_dashboard_plus.rb` [manual installation]
53
+ * `SHP_KEY="API KEY" SHP_PWD="PASSWORD" SHP_NAME="SHOP NAME" shopify_dashboard_plus.rb` [Gem]
54
+ * Run without environment variables (and pass these later thorugh the UI)
55
+ * `./lib/shopify_dashboard_plus.rb`
56
+ * `shopify_dashboard_plus.rb`
50
57
 
51
58
  ## Notes
52
- * Tested and developed with Ruby 2.0.0, 2.1.2, 2.2.0 on Mac OS 10.10
59
+ * Tested with:
60
+ * Ruby 2.3.6, 2.4.3, 2.5.0 on Mac OS 10.10 (Locally)
61
+ * Ruby 2.3.6, 2.4.3, 2.5.0 on Ubuntu Linux (TravisCI)
62
+ * Support for unmaintained versions of Ruby have been dropped. This gem requires >= Ruby 2.3.0
53
63
  * Tested against [Learning Photography](http://learning.photography)
54
- * Requires >= Ruby 2.0.0
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs << 'test'
8
+ t.test_files = FileList['test/test*.rb']
9
+ t.verbose = true
10
+ end
11
+
12
+ desc "Run all tests..."
13
+ task :default => :test
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require File.expand_path('../../lib/shopify_dashboard_plus.rb', __FILE__)
4
5
  require 'vegas'
5
6
 
6
7
  Vegas::Runner.new(Sinatra::Application, 'shopify_dashboard_plus')
7
-
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require './lib/shopify_dashboard_plus.rb'
4
+ run Sinatra::Application
@@ -1,96 +1,81 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'sinatra'
4
- require 'tilt/erubis'
5
+ require 'tilt/erb'
5
6
  require 'shopify_api'
6
7
  require 'uri'
7
8
  require 'chartkick'
9
+ require_relative 'shopify_dashboard_plus/currency'
8
10
  require_relative 'shopify_dashboard_plus/helpers'
9
- require_relative 'shopify_dashboard_plus/report'
11
+ require_relative 'shopify_dashboard_plus/discount_report'
12
+ require_relative 'shopify_dashboard_plus/revenue_report'
13
+ require_relative 'shopify_dashboard_plus/sales_report'
14
+ require_relative 'shopify_dashboard_plus/traffic_report'
10
15
  require_relative 'shopify_dashboard_plus/version'
11
16
 
12
- configure do
13
- set :public_dir, "#{__dir__}/../public"
14
- set :views, "#{__dir__}/../views"
15
17
 
16
- $connected ||= false
17
- $metrics ||= false
18
- $flash ||= nil
18
+ HELP = <<-USAGE
19
+ Set global variables through the WebUI or call with the correct ENV variables:
20
+
21
+ Example:
22
+
23
+ SHP_KEY="<shop_key>" SHP_PWD="<shop_password>" SHP_NAME="<shop_name>" ./lib/shopify-dashboard.rb
24
+ USAGE
25
+
19
26
 
20
- HELP = <<-END
21
- Set global variables through the WebUI or call with the correct ENV variables:
22
- Example: SHP_KEY=\"<shop_key>\" SHP_PWD=\"<shop_password>\" SHP_NAME=\"<shop_name>\" ./lib/shopify-dashboard.rb
23
- END
27
+ configure do
28
+ enable :sessions
29
+
30
+ set :public_dir, Proc.new { File.join(root, "../public") }
31
+ set :views, Proc.new { File.join(root, "../views") }
32
+
33
+ $connected ||= false
34
+ $flash ||= nil
24
35
 
25
- # If Environment variables were set connect to Shopify Admin immediately
36
+ # If Environment variables were set, connect to Shopify Admin immediately
26
37
  # Refuse to start server if variables are passed but incorrect
27
38
  if ENV["SHP_KEY"] && ENV["SHP_PWD"] && ENV["SHP_NAME"]
28
- API_KEY = ENV["SHP_KEY"]
29
- PASSWORD = ENV["SHP_PWD"]
39
+ API_KEY = ENV["SHP_KEY"]
40
+ PASSWORD = ENV["SHP_PWD"]
30
41
  SHOP_NAME = ENV["SHP_NAME"]
31
42
 
32
43
  begin
33
- shop_url = "https://#{API_KEY}:#{PASSWORD}@#{SHOP_NAME}.myshopify.com/admin"
34
- ShopifyAPI::Base.site = shop_url
44
+ ShopifyAPI::Base.site = "https://#{API_KEY}:#{PASSWORD}@#{SHOP_NAME}.myshopify.com/admin"
35
45
  shop = ShopifyAPI::Shop.current
46
+
36
47
  $shop_name = SHOP_NAME
48
+ $currency = shop.money_with_currency_format
37
49
  $connected = true
38
- rescue Exception => e
39
- puts "\nFailed to connect using provided credentials...(Exception: #{e})\n #{HELP}"
50
+ rescue URI::InvalidURIError, ActiveResource::ResourceNotFound => e
51
+ puts "\nFailed to connect using provided credentials for API KEY #{API_KEY} : #{e})\n #{HELP}"
40
52
  exit
41
53
  end
42
54
  end
43
-
44
-
45
- # When adding 44.95.round(2) + 940.6.round(2) the precision of the result will be 985.5500000000001
46
- # In a sample of 100_000_000_000 entries, the precision will round up cents
47
- # Since all numbers are currency, the plus method will trim to two decimals
48
- # Numbers returned as: 44, 44.5, or 44.51
49
- class Fixnum
50
- def plus(amount)
51
- result = self + (amount.to_f rescue 0)
52
- result.round(2)
53
- end
54
- end
55
-
56
- class Float
57
- def plus(amount)
58
- result = self + (amount.to_f rescue 0)
59
- result.round(2)
60
- end
61
- end
62
-
63
- # For < Ruby 2.1 Compatability
64
- class Array
65
- def to_h
66
- Hash[*self.flatten]
67
- end
68
- end
69
55
  end
70
56
 
71
57
  helpers ApplicationHelpers
72
58
 
73
59
 
74
60
  before do
75
- $flash = nil
76
- $metrics = false
61
+ $flash = ''
62
+ @metrics = false
77
63
  end
78
64
 
79
65
 
80
66
  get '/' do
81
- redirect '/connect' unless connected?
67
+ redirect '/connect' unless connected? && authenticated?
82
68
 
83
69
  # If no start date is set, default to match end date
84
70
  # If no date parameters are set, default both to today
85
71
  @today = date_today
86
- from = (params[:from] if not params[:from].empty? rescue nil) || (params[:to] if not params[:to].empty? rescue nil) || @today
87
- to = (params[:to] if not params[:to].empty? rescue nil) || @today
72
+ from = (params[:from] unless params[:from].empty? rescue nil) || (params[:to] unless params[:to].empty? rescue nil) || @today
73
+ to = (params[:to] unless params[:to].empty? rescue nil) || @today
88
74
 
89
75
  to = @today if to > @today
90
76
 
91
77
  if date_range_valid?(from, to)
92
78
  @metrics = get_detailed_revenue_metrics(from, to)
93
- $metrics = true
94
79
  else
95
80
  $flash = "Invalid Dates. Please use format YYYY-MM-DD"
96
81
  end
@@ -114,7 +99,9 @@ post '/connect' do
114
99
  end
115
100
 
116
101
  post '/disconnect' do
117
- API_KEY, API_PWD, SHP_NAME = "", "", ""
102
+ API_KEY = ''
103
+ API_PWD = ''
104
+ SHP_NAME = ''
118
105
  close_connection
119
106
 
120
107
  erb :connect
@@ -129,3 +116,4 @@ after '/quit' do
129
116
  puts "\nExiting..."
130
117
  exit!
131
118
  end
119
+
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ # When adding 44.95.round(2) + 940.6.round(2) the precision of the result will be 985.5500000000001
4
+ # In a sample of 100_000_000_000 entries, the precision will round up cents
5
+ # Since all numbers are currency, the plus method will trim to two decimals
6
+ # Numbers returned as: 44, 44.5, or 44.51
7
+ # Note that Numbers are class Fixnum in Ruby < 2.4 and Integer from 2.4 onwards
8
+ module Currency
9
+ if 0.class.to_s == "Fixnum"
10
+ refine Fixnum do
11
+ def plus(amount)
12
+ result = self + (amount.to_f rescue 0)
13
+ result.round(2)
14
+ end
15
+ end
16
+ else
17
+ refine Integer do
18
+ def plus(amount)
19
+ result = self + (amount.to_f rescue 0)
20
+ result.round(2)
21
+ end
22
+ end
23
+ end
24
+
25
+ refine Float do
26
+ def plus(amount)
27
+ result = self + (amount.to_f rescue 0)
28
+ result.round(2)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'currency'
4
+ require_relative 'helpers'
5
+ require_relative 'report'
6
+
7
+ module ShopifyDashboardPlus
8
+ class DiscountReport < Report
9
+ using Currency
10
+
11
+ def discount_usage
12
+ discount_value = Hash.new(0.0)
13
+ discount_used = Hash.new(0)
14
+
15
+ @orders.each do |order|
16
+ next unless order.attributes['discount_codes']
17
+
18
+ order.discount_codes.each do |discount_code|
19
+ discount_value[discount_code.code] = discount_value[discount_code.code].plus(discount_code.amount)
20
+ discount_used[discount_code.code] += 1
21
+ end
22
+ end
23
+
24
+ {
25
+ :discount_savings => discount_value,
26
+ :top_discount_savings => discount_value.sort_by { |_, v| v }.last,
27
+ :discount_quantity => discount_used,
28
+ :most_used_discount_code => discount_used.sort_by { |_, v| v }.last
29
+ }
30
+ end
31
+
32
+ def to_h
33
+ discount_usage
34
+ end
35
+ end
36
+ end