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.
- checksums.yaml +4 -4
- data/.rubocop.yml +16 -0
- data/.travis.yml +6 -0
- data/Gemfile.lock +99 -35
- data/README.md +16 -7
- data/Rakefile +13 -0
- data/bin/shopify_dashboard_plus.rb +1 -1
- data/config.ru +4 -0
- data/lib/shopify_dashboard_plus.rb +40 -52
- data/lib/shopify_dashboard_plus/currency.rb +31 -0
- data/lib/shopify_dashboard_plus/discount_report.rb +36 -0
- data/lib/shopify_dashboard_plus/helpers.rb +65 -51
- data/lib/shopify_dashboard_plus/report.rb +4 -196
- data/lib/shopify_dashboard_plus/revenue_report.rb +55 -0
- data/lib/shopify_dashboard_plus/sales_report.rb +86 -0
- data/lib/shopify_dashboard_plus/traffic_report.rb +65 -0
- data/lib/shopify_dashboard_plus/version.rb +3 -1
- data/shopify_dashboard_plus.gemspec +17 -7
- data/test/fixtures/vcr_cassettes/.gitkeep +0 -0
- data/test/fixtures/vcr_cassettes/authenticate.yml +88 -0
- data/test/fixtures/vcr_cassettes/multiple_pages_orders.yml +1544 -0
- data/test/fixtures/vcr_cassettes/orders_from_2010_01_01.yml +815 -0
- data/test/fixtures/vcr_cassettes/orders_from_2010_01_01_to_2015_01_01.yml +566 -0
- data/test/fixtures/vcr_cassettes/orders_no_paramaters.yml +81 -0
- data/test/fixtures/vcr_cassettes/orders_none.yml +77 -0
- data/test/fixtures/vcr_cassettes/orders_to_2015-06-26.yml +81 -0
- data/test/resources/anonymizer.rb +125 -0
- data/test/resources/modify_data.rb +110 -0
- data/test/strip_sensitive_data.rb +79 -0
- data/test/test_app.rb +60 -0
- data/test/test_frontend.rb +76 -0
- data/test/test_mockdata.rb +237 -0
- data/views/connect.erb +6 -6
- data/views/layout.erb +2 -3
- data/views/report.erb +1 -1
- metadata +190 -59
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 368458584f187d4a84965649cdef6626a22b9d2b
|
4
|
+
data.tar.gz: b5bee8a64a3565bd2ba4cc647a0c448616ef9cf1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '06321384b8a0c88ed08f3acaeef748686720b36ba00edbc7642769ad290ad0a895e494644bc5e05be684d3ab8d4d3556c94ee1c94898a479e8352c7ed57d8575'
|
7
|
+
data.tar.gz: 607ea7132f9ba3252c153105d574687951949a71e2fa5b265771f64365436eb53d1241fc0f6b33e8af32544f37969d69a4e0c82e0200a673b498594ebaeb768a
|
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
data/Gemfile.lock
CHANGED
@@ -1,58 +1,122 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
shopify_dashboard_plus (0.0
|
5
|
-
chartkick (~>
|
6
|
-
shopify_api (
|
7
|
-
sinatra (~>
|
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 (
|
15
|
-
activesupport (=
|
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 (
|
18
|
-
activemodel (
|
19
|
-
|
20
|
-
|
21
|
-
activesupport (
|
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
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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 (
|
42
|
-
|
43
|
-
rack
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
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.
|
57
|
-
|
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
|
-
##
|
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
|
-
|
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
|
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
|
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
|
data/Rakefile
ADDED
@@ -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
|
data/config.ru
ADDED
@@ -1,96 +1,81 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'sinatra'
|
4
|
-
require 'tilt/
|
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/
|
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
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
29
|
-
PASSWORD
|
39
|
+
API_KEY = ENV["SHP_KEY"]
|
40
|
+
PASSWORD = ENV["SHP_PWD"]
|
30
41
|
SHOP_NAME = ENV["SHP_NAME"]
|
31
42
|
|
32
43
|
begin
|
33
|
-
|
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
|
39
|
-
puts "\nFailed to connect using provided credentials
|
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
|
76
|
-
|
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
|
87
|
-
to
|
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
|
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
|