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
@@ -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
|