shopify_dashboard_plus 0.0.7 → 1.0.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 +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
@@ -0,0 +1,81 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://<API_KEY>:<API_PWD>@<SHOP_NAME>.myshopify.com/admin/orders.json?created_at_max=<%= today %>%2023:59:59&created_at_min==<%= today %>%200:00&fields%5B%5D=billing_address&fields%5B%5D=created_at&fields%5B%5D=currency&fields%5B%5D=customer&fields%5B%5D=discount_codes&fields%5B%5D=line_items&fields%5B%5D=referring_site&fields%5B%5D=total_price&limit=250&page=1
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- application/json
|
12
|
+
User-Agent:
|
13
|
+
- ShopifyAPI/4.0.4 ActiveResource/4.0.0 Ruby/2.1.2
|
14
|
+
Accept-Encoding:
|
15
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
16
|
+
response:
|
17
|
+
status:
|
18
|
+
code: 200
|
19
|
+
message: OK
|
20
|
+
headers:
|
21
|
+
Server:
|
22
|
+
- nginx
|
23
|
+
Date:
|
24
|
+
- Sat, 27 Jun 2015 03:02:01 GMT
|
25
|
+
Content-Type:
|
26
|
+
- application/json; charset=utf-8
|
27
|
+
Transfer-Encoding:
|
28
|
+
- chunked
|
29
|
+
Connection:
|
30
|
+
- keep-alive
|
31
|
+
X-Sorting-Hat-Podid:
|
32
|
+
- '3'
|
33
|
+
X-Sorting-Hat-Shopid:
|
34
|
+
- '4500785'
|
35
|
+
X-Sorting-Hat-Podid-Cached:
|
36
|
+
- '1'
|
37
|
+
X-Sorting-Hat-Shopid-Cached:
|
38
|
+
- '1'
|
39
|
+
Vary:
|
40
|
+
- Accept-Encoding
|
41
|
+
Status:
|
42
|
+
- 200 OK
|
43
|
+
X-Xss-Protection:
|
44
|
+
- 1; mode=block; report=/xss-report/0a457a06-1849-408f-bc0f-57f4edc59f89?source%5Baction%5D=index&source%5Bcontroller%5D=admin%2Forders&source%5Bsection%5D=admin
|
45
|
+
X-Content-Type-Options:
|
46
|
+
- nosniff
|
47
|
+
- nosniff
|
48
|
+
X-Frame-Options:
|
49
|
+
- DENY
|
50
|
+
X-Shopid:
|
51
|
+
- '4500785'
|
52
|
+
X-Shardid:
|
53
|
+
- '3'
|
54
|
+
X-Shopify-Shop-Api-Call-Limit:
|
55
|
+
- 1/40
|
56
|
+
Http-X-Shopify-Shop-Api-Call-Limit:
|
57
|
+
- 1/40
|
58
|
+
X-Stats-Userid:
|
59
|
+
- '0'
|
60
|
+
X-Stats-Apiclientid:
|
61
|
+
- '860030'
|
62
|
+
X-Stats-Apipermissionid:
|
63
|
+
- '11578246'
|
64
|
+
Set-Cookie:
|
65
|
+
- request_method=GET; path=/
|
66
|
+
X-Request-Id:
|
67
|
+
- 0a457a06-1849-408f-bc0f-57f4edc59f89
|
68
|
+
P3p:
|
69
|
+
- CP="NOI DSP COR NID ADMa OPTa OUR NOR"
|
70
|
+
X-Dc:
|
71
|
+
- ash
|
72
|
+
body:
|
73
|
+
encoding: UTF-8
|
74
|
+
string: '{"orders":[{"created_at":"<%= today %>T20:06:43-04:00","currency":"CAD","referring_site":"http://thielhodkiewicz.ca/caandra","total_price":"281.37","discount_codes":[],"line_items":[{"product_id":"08314615","price":76.97,"title":"Ergonomic
|
75
|
+
Wooden Gloves","variant_id":"4564472289","vendor":"Jewelery","name":"Sleek
|
76
|
+
Concrete Car"}],"billing_address":{"address1":"9875 Bogan Grove","address2":"Suite
|
77
|
+
328","city":"Modestoport","country":"Canada","company":"Leannon-Veum","first_name":"Conner","last_name":"Grimes","latitude":"18.212338163213815","longitude":"70.88552439133932","phone":"300-733-7915
|
78
|
+
x4220","zip":"A5Q1V5","name":"ConnerGrimes"},"customer":{"id":"41185198","email":"frances@lubowitz.com","first_name":"Ephraim","last_name":"Baumbach"}}]}'
|
79
|
+
http_version:
|
80
|
+
recorded_at: Sat, 27 Jun 2015 03:03:11 GMT
|
81
|
+
recorded_with: VCR 2.9.3
|
@@ -0,0 +1,77 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://<API_KEY>:<API_PWD>@<SHOP_NAME>.myshopify.com/admin/orders.json?created_at_max=2015-06-27%2023:59:59&created_at_min=2015-06-27%200:00&fields%5B%5D=billing_address&fields%5B%5D=created_at&fields%5B%5D=currency&fields%5B%5D=customer&fields%5B%5D=discount_codes&fields%5B%5D=line_items&fields%5B%5D=referring_site&fields%5B%5D=total_price&limit=250&page=1
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- application/json
|
12
|
+
User-Agent:
|
13
|
+
- ShopifyAPI/4.0.4 ActiveResource/4.0.0 Ruby/2.1.2
|
14
|
+
Accept-Encoding:
|
15
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
16
|
+
response:
|
17
|
+
status:
|
18
|
+
code: 200
|
19
|
+
message: OK
|
20
|
+
headers:
|
21
|
+
Server:
|
22
|
+
- nginx
|
23
|
+
Date:
|
24
|
+
- Sat, 27 Jun 2015 05:19:23 GMT
|
25
|
+
Content-Type:
|
26
|
+
- application/json; charset=utf-8
|
27
|
+
Transfer-Encoding:
|
28
|
+
- chunked
|
29
|
+
Connection:
|
30
|
+
- keep-alive
|
31
|
+
X-Sorting-Hat-Podid:
|
32
|
+
- '3'
|
33
|
+
X-Sorting-Hat-Shopid:
|
34
|
+
- '4500785'
|
35
|
+
X-Sorting-Hat-Podid-Cached:
|
36
|
+
- '0'
|
37
|
+
X-Sorting-Hat-Shopid-Cached:
|
38
|
+
- '0'
|
39
|
+
Vary:
|
40
|
+
- Accept-Encoding
|
41
|
+
Status:
|
42
|
+
- 200 OK
|
43
|
+
X-Xss-Protection:
|
44
|
+
- 1; mode=block; report=/xss-report/89d0344f-7536-411e-96ea-965119e394ff?source%5Baction%5D=index&source%5Bcontroller%5D=admin%2Forders&source%5Bsection%5D=admin
|
45
|
+
X-Content-Type-Options:
|
46
|
+
- nosniff
|
47
|
+
- nosniff
|
48
|
+
X-Frame-Options:
|
49
|
+
- DENY
|
50
|
+
X-Shopid:
|
51
|
+
- '4500785'
|
52
|
+
X-Shardid:
|
53
|
+
- '3'
|
54
|
+
X-Shopify-Shop-Api-Call-Limit:
|
55
|
+
- 1/40
|
56
|
+
Http-X-Shopify-Shop-Api-Call-Limit:
|
57
|
+
- 1/40
|
58
|
+
X-Stats-Userid:
|
59
|
+
- '0'
|
60
|
+
X-Stats-Apiclientid:
|
61
|
+
- '860030'
|
62
|
+
X-Stats-Apipermissionid:
|
63
|
+
- '11578246'
|
64
|
+
Set-Cookie:
|
65
|
+
- request_method=GET; path=/
|
66
|
+
X-Request-Id:
|
67
|
+
- 89d0344f-7536-411e-96ea-965119e394ff
|
68
|
+
P3p:
|
69
|
+
- CP="NOI DSP COR NID ADMa OPTa OUR NOR"
|
70
|
+
X-Dc:
|
71
|
+
- ash
|
72
|
+
body:
|
73
|
+
encoding: UTF-8
|
74
|
+
string: '{"orders":[]}'
|
75
|
+
http_version:
|
76
|
+
recorded_at: Sat, 27 Jun 2015 05:20:33 GMT
|
77
|
+
recorded_with: VCR 2.9.3
|
@@ -0,0 +1,81 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://<API_KEY>:<API_PWD>@<SHOP_NAME>.myshopify.com/admin/orders.json?created_at_max=2015-06-26%2023:59:59&created_at_min=2015-06-26%200:00&fields%5B%5D=billing_address&fields%5B%5D=created_at&fields%5B%5D=currency&fields%5B%5D=customer&fields%5B%5D=discount_codes&fields%5B%5D=line_items&fields%5B%5D=referring_site&fields%5B%5D=total_price&limit=250&page=1
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- application/json
|
12
|
+
User-Agent:
|
13
|
+
- ShopifyAPI/4.0.4 ActiveResource/4.0.0 Ruby/2.1.2
|
14
|
+
Accept-Encoding:
|
15
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
16
|
+
response:
|
17
|
+
status:
|
18
|
+
code: 200
|
19
|
+
message: OK
|
20
|
+
headers:
|
21
|
+
Server:
|
22
|
+
- nginx
|
23
|
+
Date:
|
24
|
+
- Sat, 27 Jun 2015 03:02:01 GMT
|
25
|
+
Content-Type:
|
26
|
+
- application/json; charset=utf-8
|
27
|
+
Transfer-Encoding:
|
28
|
+
- chunked
|
29
|
+
Connection:
|
30
|
+
- keep-alive
|
31
|
+
X-Sorting-Hat-Podid:
|
32
|
+
- '3'
|
33
|
+
X-Sorting-Hat-Shopid:
|
34
|
+
- '4500785'
|
35
|
+
X-Sorting-Hat-Podid-Cached:
|
36
|
+
- '1'
|
37
|
+
X-Sorting-Hat-Shopid-Cached:
|
38
|
+
- '1'
|
39
|
+
Vary:
|
40
|
+
- Accept-Encoding
|
41
|
+
Status:
|
42
|
+
- 200 OK
|
43
|
+
X-Xss-Protection:
|
44
|
+
- 1; mode=block; report=/xss-report/db2dd2d8-eb26-4650-8bc4-588a41b866ef?source%5Baction%5D=index&source%5Bcontroller%5D=admin%2Forders&source%5Bsection%5D=admin
|
45
|
+
X-Content-Type-Options:
|
46
|
+
- nosniff
|
47
|
+
- nosniff
|
48
|
+
X-Frame-Options:
|
49
|
+
- DENY
|
50
|
+
X-Shopid:
|
51
|
+
- '4500785'
|
52
|
+
X-Shardid:
|
53
|
+
- '3'
|
54
|
+
X-Shopify-Shop-Api-Call-Limit:
|
55
|
+
- 1/40
|
56
|
+
Http-X-Shopify-Shop-Api-Call-Limit:
|
57
|
+
- 1/40
|
58
|
+
X-Stats-Userid:
|
59
|
+
- '0'
|
60
|
+
X-Stats-Apiclientid:
|
61
|
+
- '860030'
|
62
|
+
X-Stats-Apipermissionid:
|
63
|
+
- '11578246'
|
64
|
+
Set-Cookie:
|
65
|
+
- request_method=GET; path=/
|
66
|
+
X-Request-Id:
|
67
|
+
- db2dd2d8-eb26-4650-8bc4-588a41b866ef
|
68
|
+
P3p:
|
69
|
+
- CP="NOI DSP COR NID ADMa OPTa OUR NOR"
|
70
|
+
X-Dc:
|
71
|
+
- ash
|
72
|
+
body:
|
73
|
+
encoding: UTF-8
|
74
|
+
string: '{"orders":[{"created_at":"2015-06-26T20:06:43-04:00","currency":"CAD","referring_site":"http://bartell.com/alvis","total_price":"281.37","discount_codes":[],"line_items":[{"product_id":"63864731","price":"95.11","title":"Gorgeous
|
75
|
+
Rubber Pants","variant_id":"7654546673","vendor":"Automotive","name":"Incredible
|
76
|
+
Cotton Gloves"}],"billing_address":{"address1":"72886 Emmanuelle Manors","address2":"Suite
|
77
|
+
813","city":"Connhaven","country":"Canada","company":"Collins LLC","first_name":"Chelsea","last_name":"Thiel","latitude":"69.41862661206804","longitude":"82.43290958920517","phone":"1-244-410-9707
|
78
|
+
x716","zip":"M1I9E7","name":"ChelseaThiel"},"customer":{"id":"29327241","email":"emmalee_goodwin@cronagottlieb.com","first_name":"Sarina","last_name":"Abshire"}}]}'
|
79
|
+
http_version:
|
80
|
+
recorded_at: Sat, 27 Jun 2015 03:03:11 GMT
|
81
|
+
recorded_with: VCR 2.9.3
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Anonymizer
|
4
|
+
|
5
|
+
# Strip discount information and replace with fake data
|
6
|
+
def anonymize_discounts(orders)
|
7
|
+
discount_code_replacement = {}
|
8
|
+
|
9
|
+
orders.each_with_index do |order, index|
|
10
|
+
order['discount_codes'].each_with_index do |dc, inner_index|
|
11
|
+
next if dc.nil? || dc.empty?
|
12
|
+
|
13
|
+
old_code = order['discount_codes'][inner_index]['code']
|
14
|
+
|
15
|
+
unless discount_code_replacement[old_code]
|
16
|
+
discount_code_replacement[old_code] = Faker::Internet.slug
|
17
|
+
end
|
18
|
+
|
19
|
+
orders[index]['discount_codes'][inner_index]['code'] = discount_code_replacement[old_code]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
orders
|
24
|
+
end
|
25
|
+
|
26
|
+
# Strip referral information and replace with fake data
|
27
|
+
def anonymize_referrals(orders)
|
28
|
+
referring_site_replacement = {}
|
29
|
+
|
30
|
+
orders.each_with_index do |order, index|
|
31
|
+
next if order['referring_site'].nil? || order['referring_site'].empty?
|
32
|
+
|
33
|
+
old_site = order['referring_site']
|
34
|
+
|
35
|
+
unless referring_site_replacement[old_site]
|
36
|
+
referring_site_replacement[old_site] = Faker::Internet.url
|
37
|
+
end
|
38
|
+
|
39
|
+
orders[index]['referring_site'] = referring_site_replacement[old_site]
|
40
|
+
end
|
41
|
+
|
42
|
+
orders
|
43
|
+
end
|
44
|
+
|
45
|
+
# Strip billing address informatino and replace with fake data
|
46
|
+
def anonymize_billing_address(orders)
|
47
|
+
billing_address_replacement = Hash.new { |hash, key| hash[key] = {} }
|
48
|
+
|
49
|
+
orders.each_with_index do |order, index|
|
50
|
+
next if order['billing_address'].nil? || order['billing_address'].empty?
|
51
|
+
|
52
|
+
old_address = order['billing_address']['address1']
|
53
|
+
|
54
|
+
if billing_address_replacement[old_address].empty?
|
55
|
+
billing_address_replacement[old_address]['address1'] = Faker::Address.street_address
|
56
|
+
billing_address_replacement[old_address]['address2'] = Faker::Address.secondary_address
|
57
|
+
billing_address_replacement[old_address]['city'] = Faker::Address.city
|
58
|
+
billing_address_replacement[old_address]['country'] = 'Canada'
|
59
|
+
billing_address_replacement[old_address]['company'] = Faker::Company.name
|
60
|
+
billing_address_replacement[old_address]['first_name'] = Faker::Name.first_name
|
61
|
+
billing_address_replacement[old_address]['last_name'] = Faker::Name.last_name
|
62
|
+
billing_address_replacement[old_address]['latitude'] = Faker::Address.latitude
|
63
|
+
billing_address_replacement[old_address]['longitude'] = Faker::Address.longitude
|
64
|
+
billing_address_replacement[old_address]['phone'] = Faker::PhoneNumber.phone_number
|
65
|
+
billing_address_replacement[old_address]['zip'] = Faker::Address.zip_code
|
66
|
+
billing_address_replacement[old_address]['name'] = billing_address_replacement[old_address]['first_name'] + billing_address_replacement[old_address]['last_name']
|
67
|
+
end
|
68
|
+
|
69
|
+
orders[index]['billing_address'] = billing_address_replacement[old_address]
|
70
|
+
end
|
71
|
+
|
72
|
+
orders
|
73
|
+
end
|
74
|
+
|
75
|
+
# Strip line item information and replace with fake data
|
76
|
+
def anonymize_line_items(orders)
|
77
|
+
line_items_replacement = Hash.new { |hash, key| hash[key] = {} }
|
78
|
+
|
79
|
+
orders.each_with_index do |order, index|
|
80
|
+
order['line_items'].each_with_index do |item, inner_index|
|
81
|
+
next if item.empty?
|
82
|
+
old_item = order['line_items'][inner_index]['product_id']
|
83
|
+
|
84
|
+
if line_items_replacement[old_item].empty?
|
85
|
+
line_items_replacement[old_item]['product_id'] = Faker::Number.number(8)
|
86
|
+
line_items_replacement[old_item]['price'] = Faker::Commerce.price.to_s
|
87
|
+
line_items_replacement[old_item]['title'] = Faker::Commerce.product_name
|
88
|
+
line_items_replacement[old_item]['variant_id'] = Faker::Number.number(10)
|
89
|
+
line_items_replacement[old_item]['vendor'] = Faker::Commerce.department
|
90
|
+
line_items_replacement[old_item]['name'] = Faker::Commerce.product_name
|
91
|
+
end
|
92
|
+
|
93
|
+
orders[index]['line_items'][inner_index] = line_items_replacement[old_item]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
orders
|
98
|
+
end
|
99
|
+
|
100
|
+
# Strip customer data and replace with fake data
|
101
|
+
def anonymize_customers(orders)
|
102
|
+
customer_replacement = Hash.new { |hash, key| hash[key] = {} }
|
103
|
+
|
104
|
+
orders.each_with_index do |order, index|
|
105
|
+
next if order['customer'].empty?
|
106
|
+
|
107
|
+
old_customer = order['customer']['id']
|
108
|
+
|
109
|
+
if customer_replacement[old_customer].empty?
|
110
|
+
customer_replacement[old_customer]['id'] = Faker::Number.number(8)
|
111
|
+
customer_replacement[old_customer]['email'] = Faker::Internet.email
|
112
|
+
customer_replacement[old_customer]['first_name'] = Faker::Name.first_name
|
113
|
+
customer_replacement[old_customer]['last_name'] = Faker::Name.last_name
|
114
|
+
|
115
|
+
# TODO: Take billing_address parameter to fill in:
|
116
|
+
# customer_replacement[customer[:id]][:default_address]
|
117
|
+
end
|
118
|
+
|
119
|
+
orders[index]['customer'] = customer_replacement[old_customer]
|
120
|
+
end
|
121
|
+
|
122
|
+
orders
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ModifyData
|
4
|
+
Faker::Config.locale = :"en-CA"
|
5
|
+
|
6
|
+
# Replace the shop data from real stores with randomly generated data
|
7
|
+
def self.anonymize_shop(raw_store_data)
|
8
|
+
|
9
|
+
store_data = JSON.parse(raw_store_data).fetch('shop') rescue (return raw_store_data)
|
10
|
+
|
11
|
+
# Store Details
|
12
|
+
store_data['id'] = Faker::Number.number(8) if store_data['id']
|
13
|
+
store_data['name'] = Faker::Company.name if store_data['name']
|
14
|
+
store_data['domain'] = Faker::Internet.url if store_data['domain']
|
15
|
+
|
16
|
+
# Owner
|
17
|
+
store_data['shop_owner'] = Faker::Name.name if store_data['shop_owner']
|
18
|
+
store_data['phone'] = Faker::PhoneNumber.phone_number if store_data['phone']
|
19
|
+
store_data['email'] = Faker::Internet.email if store_data['email']
|
20
|
+
store_data['customer_email'] = Faker::Internet.email if store_data['customer_email']
|
21
|
+
|
22
|
+
# Address
|
23
|
+
store_data['city'] = Faker::Address.city if store_data['city']
|
24
|
+
store_data['address1'] = Faker::Address.street_address if store_data['address1']
|
25
|
+
store_data['longitude'] = Faker::Address.longitude if store_data['longitude']
|
26
|
+
store_data['latitude'] = Faker::Address.latitude if store_data['latitude']
|
27
|
+
store_data['zip'] = Faker::Address.zip if store_data['zip']
|
28
|
+
|
29
|
+
# Set data back under the json 'shop' key and return as JSON
|
30
|
+
updated_store_data = JSON.parse('{}')
|
31
|
+
updated_store_data['shop'] = store_data
|
32
|
+
updated_store_data.to_json
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
# Intercept Shopify Orders and replace data with generated mock data
|
37
|
+
# Ensure predictable replacements of data
|
38
|
+
# e.g. If a real order from John Galt is replaced with a fake name, Jane Smith,
|
39
|
+
# every instance of John Galt should be replaced with the same data.
|
40
|
+
def self.anonymize_orders(raw_order_data)
|
41
|
+
|
42
|
+
order_data = JSON.parse(raw_order_data).fetch('orders') rescue (return raw_order_data)
|
43
|
+
|
44
|
+
order_data = anonymize_discounts(order_data)
|
45
|
+
order_data = anonymize_referrals(order_data)
|
46
|
+
order_data = anonymize_billing_address(order_data)
|
47
|
+
order_data = anonymize_line_items(order_data)
|
48
|
+
order_data = anonymize_customers(order_data)
|
49
|
+
|
50
|
+
# Set data back under the json 'orders' key and return as JSON
|
51
|
+
updated_order_data = JSON.parse('{}')
|
52
|
+
updated_order_data['orders'] = order_data
|
53
|
+
updated_order_data.to_json
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
# Traverse through orders and return a new array with each order <multiplier_constant> times
|
58
|
+
def self.duplicate_orders(raw_order_data, multiplier_constant:)
|
59
|
+
begin
|
60
|
+
order_data = JSON.parse(raw_order_data).fetch('orders')
|
61
|
+
rescue
|
62
|
+
return raw_order_data
|
63
|
+
end
|
64
|
+
|
65
|
+
duplicated_order_data = []
|
66
|
+
|
67
|
+
order_data.each do |order|
|
68
|
+
multiplier_constant.to_i.times { duplicated_order_data << order }
|
69
|
+
end
|
70
|
+
|
71
|
+
# Set data back under the json 'orders' key and return as JSON
|
72
|
+
returned_order_data = JSON.parse('{}')
|
73
|
+
returned_order_data['orders'] = duplicated_order_data
|
74
|
+
returned_order_data.to_json
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
# Ensure at least <floor> orders exist, or otherwise continually append the last order until enough orders exist
|
79
|
+
def self.number_of_orders_floor(raw_order_data, floor:)
|
80
|
+
order_data = JSON.parse(raw_order_data).fetch('orders') rescue (return raw_order_data)
|
81
|
+
|
82
|
+
order_delta = order_data.length - floor
|
83
|
+
return raw_order_data if order_delta >= 0
|
84
|
+
|
85
|
+
order_delta.to_i.times { new_order_data << order_data.last }
|
86
|
+
|
87
|
+
# Set data back under the json 'orders' key and return as JSON
|
88
|
+
returned_order_data = JSON.parse('{}')
|
89
|
+
returned_order_data['orders'] = new_order_data
|
90
|
+
returned_order_data.to_json
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
# Ensure no more than <ceiling> orders exist, or otherwise clip the array at <ceiling>
|
95
|
+
def self.number_of_orders_ceiling(raw_order_data, ceiling:)
|
96
|
+
order_data = JSON.parse(raw_order_data).fetch('orders') rescue (return raw_order_data)
|
97
|
+
trimmed_order_data = []
|
98
|
+
|
99
|
+
order_delta = ceiling - order_data.length
|
100
|
+
return raw_order_data if order_delta >= 0
|
101
|
+
|
102
|
+
ceiling.to_i.times { |i| trimmed_order_data << order_data[i] }
|
103
|
+
|
104
|
+
# Set data back under the json 'orders' key and return as JSON
|
105
|
+
returned_order_data = JSON.parse('{}')
|
106
|
+
returned_order_data['orders'] = trimmed_order_data
|
107
|
+
returned_order_data.to_json
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|