tyreshopper_sqs2cb 0.0.1 → 0.0.2
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/.gitignore +1 -0
- data/bin/tyreshopper_sqs2cb +0 -0
- data/lib/tyreshopper_sqs2cb/version.rb +1 -1
- data/lib/tyreshopper_sqs2cb.rb +171 -34
- data/spec/lib/tyreshopper_sqs2cb/message_handler_spec.rb +41 -0
- data/spec/spec_helper.rb +0 -8
- data/tyreshopper_sqs2cb.gemspec +1 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cff962d702de6839c46b2fc005d001a0fbcd5127
|
4
|
+
data.tar.gz: 1797dcdbbe5646e02ff4d9c0758dace32f5f4c2b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: da9e42a533c48fed2528b87b618b1772dde32704a768263bc236147a90923a1f0271af19fd596866f42d3ac6eb0c56139795e80f6e5fa7aff3791b1c8ff0f04d
|
7
|
+
data.tar.gz: 99ed585f27028a60f3aed0bb1384c898596916fe5a6c23748b158002f5cf337cfa3df1a169883bd8b6b29da253735da24da0172d9f4d81cf5baababac223a9e9
|
data/.gitignore
CHANGED
data/bin/tyreshopper_sqs2cb
CHANGED
File without changes
|
data/lib/tyreshopper_sqs2cb.rb
CHANGED
@@ -4,12 +4,15 @@ require 'json'
|
|
4
4
|
require 'rest_client'
|
5
5
|
require 'logger'
|
6
6
|
require 'sqs2cb'
|
7
|
+
require 'ap'
|
8
|
+
require 'uri'
|
7
9
|
|
8
10
|
module TyreshopperSqs2cb
|
9
11
|
class MessageHandler
|
10
12
|
def initialize
|
11
13
|
|
12
14
|
logfile = ENV['TYRESHOPPER_SQS2CB_LOGFILE_PATH'].nil? ? STDOUT : File.open(ENV['TYRESHOPPER_SQS2CB_LOGFILE_PATH'], 'a')
|
15
|
+
logfile = STDOUT
|
13
16
|
@logger = Logger.new logfile
|
14
17
|
|
15
18
|
|
@@ -31,6 +34,11 @@ module TyreshopperSqs2cb
|
|
31
34
|
@options = options
|
32
35
|
@logger.info "Tyreshopper Message received."
|
33
36
|
@logger.debug message.body
|
37
|
+
puts "Sending..."
|
38
|
+
|
39
|
+
@caseBlocksAPIEndpoint = options[:case_blocks_api_endpoint]
|
40
|
+
@caseBlocksAPIToken = options[:caseblocks_api_token]
|
41
|
+
|
34
42
|
send_to_caseblocks(JSON.parse(message.body))
|
35
43
|
|
36
44
|
rescue JSON::ParserError => ex
|
@@ -46,13 +54,18 @@ module TyreshopperSqs2cb
|
|
46
54
|
def send_to_caseblocks(msgHash)
|
47
55
|
@logger.info "Sending to CaseBlocks"
|
48
56
|
|
57
|
+
puts "Sending order #{msgHash["case"]["title"]} to caseblocks..."
|
58
|
+
|
59
|
+
puts "Looking for customer..."
|
49
60
|
customer = find_or_create_customer(msgHash)
|
50
|
-
msgHash["customer_ref"] = customer["customer_ref"]
|
51
|
-
msgHash["user_signed_in"] = msgHash["signed_in"]
|
52
61
|
|
53
|
-
|
62
|
+
msgHash["case"]["customer_ref"] = customer["customer_ref"]
|
63
|
+
|
64
|
+
puts "Creating order in caseblocks..."
|
65
|
+
response = post("/case_blocks/tyre_shopper_orders", msgHash)
|
54
66
|
|
55
|
-
|
67
|
+
puts "Done."
|
68
|
+
@logger.info "Received #{response}"
|
56
69
|
rescue RestClient::ExceptionWithResponse => ex
|
57
70
|
if ex.response.nil?
|
58
71
|
@logger.error "Received a bad response (null) from CaseBlocks. Re-raising."
|
@@ -66,59 +79,183 @@ module TyreshopperSqs2cb
|
|
66
79
|
def find_or_create_customer(options)
|
67
80
|
|
68
81
|
# find customer case type id
|
69
|
-
|
82
|
+
order_details = options["case"]
|
70
83
|
|
71
84
|
# if user was signed in then use member_id else use email
|
72
|
-
if
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
85
|
+
if order_details["signed_in"]
|
86
|
+
|
87
|
+
puts "Searching for customer on member_id #{order_details["member"]["member_id"]}..."
|
88
|
+
|
89
|
+
customer = {
|
90
|
+
"case_type_id" => customer_case_type_id,
|
91
|
+
"people_type_id" => customer_case_type_id,
|
92
|
+
"address_1" => order_details["member"]["address1"],
|
93
|
+
"address_2" => order_details["member"]["address2"],
|
94
|
+
"county" => order_details["member"]["county"],
|
95
|
+
"prefix" => order_details["member"]["prefix"],
|
96
|
+
"first_name" => order_details["member"]["first_name"],
|
97
|
+
"surname" => order_details["member"]["surname"],
|
98
|
+
"postcode" => order_details["member"]["postcode"],
|
99
|
+
"town" => order_details["member"]["town"],
|
100
|
+
"email" => order_details["member"]["email"],
|
101
|
+
"member_id" => order_details["member"]["member_id"].to_i,
|
102
|
+
}
|
103
|
+
|
104
|
+
cb_customer = find_customer(:member_id => order_details["member"]["member_id"])
|
105
|
+
if cb_customer.nil?
|
106
|
+
puts "Can't find customer by member_id, checking if the email is there..."
|
107
|
+
|
108
|
+
cb_customer = find_customer(:email => order_details["email"])
|
109
|
+
|
110
|
+
if cb_customer
|
111
|
+
puts "Found customer, need to update member_id and data"
|
112
|
+
|
113
|
+
cb_customer = ensure_taskslists_are_populated(cb_customer)
|
114
|
+
put("/case_blocks/customer/#{cb_customer["_id"]}", {"customer" => customer})
|
115
|
+
|
116
|
+
return cb_customer
|
117
|
+
else
|
118
|
+
puts "Unable to find customer"
|
119
|
+
puts "Creating new customer from member details..."
|
120
|
+
|
121
|
+
result = post("/case_blocks/customer", customer)["case"]
|
122
|
+
return result
|
123
|
+
end
|
91
124
|
else
|
92
|
-
return
|
125
|
+
return cb_customer
|
93
126
|
end
|
94
127
|
else
|
95
|
-
|
128
|
+
puts "Searching for customer on email #{order_details["email"]}..."
|
96
129
|
|
97
|
-
|
98
|
-
# create customer
|
130
|
+
cb_customer = find_customer(:email => order_details["email"])
|
99
131
|
|
132
|
+
if cb_customer
|
133
|
+
puts "Found customer"
|
134
|
+
return cb_customer
|
100
135
|
else
|
101
|
-
|
136
|
+
puts "Unable to find customer"
|
137
|
+
|
138
|
+
name_parts = parse_name(order_details["customer"])
|
139
|
+
|
140
|
+
customer = {
|
141
|
+
:case_type_id => customer_case_type_id,
|
142
|
+
:people_type_id => customer_case_type_id,
|
143
|
+
:address_1 => order_details["address1"],
|
144
|
+
:address_2 => order_details["address2"],
|
145
|
+
:town => order_details["address3"],
|
146
|
+
:postcode => order_details["postcode"],
|
147
|
+
|
148
|
+
:prefix => name_parts[:prefix],
|
149
|
+
:first_name => name_parts[:first_name],
|
150
|
+
:surname => name_parts[:surname],
|
151
|
+
:email => order_details["email"],
|
152
|
+
|
153
|
+
}
|
154
|
+
|
155
|
+
puts "Creating new customer from order details..."
|
156
|
+
return post("/case_blocks/customer", customer)["case"]
|
102
157
|
end
|
103
158
|
end
|
159
|
+
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
def customer_case_type_id
|
164
|
+
@customer_case_type_id ||= get("/case_blocks/people_types")["people_types"].select{|type| type["code"] == "customer" }.first["id"]
|
165
|
+
end
|
166
|
+
|
167
|
+
def find_customer(query)
|
168
|
+
|
169
|
+
result = get("/case_blocks/search", {"query" => query.map{|k,v| "#{k}%3A#{v}"}.join(" AND ")})
|
170
|
+
matches = result.detect{|type| type["case_type_id"] == customer_case_type_id}
|
171
|
+
|
172
|
+
if !matches.nil? && matches["cases"].count > 0
|
173
|
+
return matches["cases"].first
|
174
|
+
else
|
175
|
+
return nil
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
def ensure_taskslists_are_populated(customer)
|
181
|
+
ap customer
|
182
|
+
# populate tasklists
|
183
|
+
tasklists = []
|
184
|
+
customer["tasklists"].each do |tasklist_id|
|
185
|
+
tasklists << get("/case_blocks/tasklists/#{tasklist_id}")
|
186
|
+
end
|
187
|
+
|
188
|
+
customer["tasklists"] = tasklists
|
189
|
+
|
190
|
+
return customer
|
191
|
+
end
|
192
|
+
|
193
|
+
def parse_name(full_name)
|
194
|
+
valid_prefix = %w(dr miss mr mrs ms professor sir)
|
195
|
+
|
196
|
+
parts = full_name.split(" ")
|
197
|
+
|
198
|
+
result = {:prefix => "", :first_name => "", :last_name => ""}
|
199
|
+
|
200
|
+
if valid_prefix.include?(parts[0].downcase)
|
201
|
+
result[:prefix] = titleize(parts.delete_at(0))
|
202
|
+
end
|
104
203
|
|
204
|
+
result[:first_name] = parts.delete_at(0)
|
205
|
+
|
206
|
+
result[:surname] = parts.join(" ")
|
207
|
+
|
208
|
+
return result
|
209
|
+
end
|
210
|
+
def titleize(str)
|
211
|
+
return str[0].upcase + str[1..-1].downcase
|
105
212
|
end
|
106
213
|
|
107
214
|
def get(path, query={})
|
108
|
-
uri =
|
215
|
+
uri = URI.parse("#{@caseBlocksAPIEndpoint}#{path}")
|
109
216
|
|
110
217
|
query.each do |k, v|
|
111
218
|
uri.query = [uri.query, "#{k}=#{v}"].compact.join('&')
|
112
219
|
end
|
113
220
|
uri.query = [uri.query, "auth_token=#{@caseBlocksAPIToken}"].compact.join('&')
|
114
|
-
|
221
|
+
ap " === GETing to #{uri.to_s} ==="
|
222
|
+
return JSON.parse(RestClient.get(uri.to_s, :content_type => :json, :accept => :json, "AUTH_TOKEN" => @caseBlocksAPIToken))
|
115
223
|
end
|
116
224
|
|
117
|
-
def post(
|
118
|
-
uri =
|
225
|
+
def post(path, data, options={})
|
226
|
+
uri = URI.parse("#{@caseBlocksAPIEndpoint}#{path}")
|
227
|
+
|
228
|
+
options = {:content_type => :json, :accept => :json, "AUTH_TOKEN" => @caseBlocksAPIToken}.merge(options)
|
229
|
+
|
230
|
+
uri.query = [uri.query, "auth_token=#{@caseBlocksAPIToken}"].compact.join('&')
|
231
|
+
ap " === POSTing to #{uri.to_s} ==="
|
232
|
+
#ap data
|
233
|
+
return JSON.parse(RestClient.post(uri.to_s, data.to_json, options))
|
234
|
+
end
|
235
|
+
|
236
|
+
def put(path, data, options={})
|
237
|
+
uri = URI.parse("#{@caseBlocksAPIEndpoint}#{path}")
|
238
|
+
|
239
|
+
options = {:content_type => :json, :accept => :json, "AUTH_TOKEN" => @caseBlocksAPIToken}.merge(options)
|
240
|
+
|
241
|
+
uri.query = [uri.query, "auth_token=#{@caseBlocksAPIToken}"].compact.join('&')
|
242
|
+
ap " === PUTing to #{uri.to_s} ==="
|
243
|
+
#ap data
|
244
|
+
return JSON.parse(RestClient.put(uri.to_s, data.to_json, options))
|
245
|
+
end
|
246
|
+
|
247
|
+
def patch(path, data, options={})
|
248
|
+
uri = URI.parse("#{@caseBlocksAPIEndpoint}#{path}")
|
249
|
+
|
250
|
+
options = {:content_type => :json, :accept => :json, "AUTH_TOKEN" => @caseBlocksAPIToken}.merge(options)
|
119
251
|
|
120
252
|
uri.query = [uri.query, "auth_token=#{@caseBlocksAPIToken}"].compact.join('&')
|
121
|
-
|
253
|
+
ap " === PATCHing to #{uri.to_s} ==="
|
254
|
+
#ap data
|
255
|
+
return JSON.parse(RestClient.patch(uri.to_s, data.to_json, options))
|
122
256
|
end
|
257
|
+
|
258
|
+
|
259
|
+
|
123
260
|
end
|
124
261
|
end
|
@@ -7,5 +7,46 @@ describe TyreshopperSqs2cb::MessageHandler do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
context "handling message" do
|
10
|
+
before(:each) do
|
11
|
+
@awsAccessKeyId = ENV['AWS_ACCESS_KEY']
|
12
|
+
@awsSecretAccessKey = ENV['AWS_SECRET_ACCESS_KEY']
|
13
|
+
@caseBlocksAPIEndpoint = ENV['CB_API_ENDPOINT']
|
14
|
+
@caseBlocksAPIToken = ENV['CB_API_TOKEN']
|
15
|
+
@caseBlocksQueue = ENV['CB_QUEUE']
|
16
|
+
@usePatchCommand = (@caseBlocksQueue =~ /patch/)
|
17
|
+
@stop = false
|
18
|
+
|
19
|
+
@options = {:use_patch_command => @usePatchCommand, :case_blocks_api_endpoint => @caseBlocksAPIEndpoint, :caseblocks_api_token => @caseBlocksAPIToken}
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when signed out" do
|
23
|
+
before(:each) do
|
24
|
+
@json = '{"case":{"signed_in":false,"member":{"email": "stewart@rockwellcottage.com"},"title":"TZ672449","case_type_id":1,"case_type":"tyre-shopper-order","current_state":"Requiring action Risk","order_number":"TZ672449","order_date":"2015-02-24T16:02:44Z","customer":"Mr Stewart McKee","vrn":"YT55 NFO","address1":"Rockwell Cottage","address2":"Main Road","address3":"Cardross","postcode":"G82 5PA","daytime_telephone":"+447968115250","evening_telephone":"+447968115250","email":"stewart@rockwellcottage.com","market_opt_in":false,"payment_type":"Creditcard","transaction_reference":"TZ672449","card_number":"1111","account_holder":"Stewart","streamline_risk_assessment":"0","tyre_shopper_risk_assessment":"37","tyre_shopper_risk_assessment_notes":"Customer name isn''t an exact match of the Streamline cardholder name\nEmail is Hotmail, Yahoo or Gmail\nEmail used in last 6 months\nVRN used in last 6 months\nNumber used in last 6 months\nAlternative phone number used in last 6 months\n","order_source":"TyreShopper","fitting_date":"2015-02-27T00:00:00Z","am_pm":"PM","stock_check":true,"phone_number":"01625 424461","branch_number":"050","mobile_fitting":false,"name":"Macclesfield","line_items":[{"qty":"1","sku":"2055516BU1WX2","price":36.575,"size":"2055516","speed_rating":"W","load_index":94,"description":"WESTLAKE SA05 94W XL"},{"qty":"1","sku":"free_tyre_guarantee","price":0,"size":null,"speed_rating":null,"load_index":0,"description":"Free tyre guarantee"}],"operational_stock":true}}'
|
25
|
+
end
|
26
|
+
it "does what it says on the tin" do
|
27
|
+
|
28
|
+
message = OpenStruct.new(:body => @json)
|
29
|
+
|
30
|
+
handler = TyreshopperSqs2cb::MessageHandler.new
|
31
|
+
|
32
|
+
puts "handling message...."
|
33
|
+
handler.handle_received_message(message, @options);
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when signed in" do
|
38
|
+
before(:each) do
|
39
|
+
@json = '{"case":{"title":"TZ362794","case_type_id":1,"case_type":"tyre-shopper-order","current_state":"Ready for dataflex","order_number":"TZ362794","order_date":"2015-02-26T09:52:47Z","customer":"Mr Stewart McKee","vrn":"YT55 NFO","address1":"Rockwell Cottage","address2":"Main Road","address3":"Cardross","postcode":"G82 5PA","daytime_telephone":"+447968115250","evening_telephone":"+447968115250","email":"stewart@rockwellcottage.com","market_opt_in":false,"payment_type":"PayPal","transaction_reference":null,"card_number":null,"account_holder":null,"streamline_risk_assessment":"0","tyre_shopper_risk_assessment":"0","tyre_shopper_risk_assessment_notes":null,"order_source":"TyreShopper","fitting_date":"2015-02-28T00:00:00Z","am_pm":"PM","stock_check":true,"signed_in":true,"member":{"member_id":"20","group_id":"8","username":"stewart@rockwellcottage.com","screen_name":"stewart@rockwellcottage.com","email":"stewart@rockwellcottage.com","url":"","location":"","occupation":null,"interests":null,"last_visit":"1424703620","last_activity":"1424944270","join_date":"1424700057","first_name":"Stewart","surname":"McKee","opt_in":"","address1":"Rockwell Cottage","address2":"Main Road","town":"Cardross","county":"","daytime_telephone":"+447968115250","postcode":"G82 5PA","evening_telephone":"+447968115250","prefix":"Mr"},"phone_number":"0141 551 8244","branch_number":"102","mobile_fitting":false,"name":"Alexandra Parade","line_items":[{"qty":"1","sku":"2055516BU1WX2","price":36.575,"size":"2055516","speed_rating":"W","load_index":94,"description":"WESTLAKE SA05 94W XL"},{"qty":"1","sku":"free_tyre_guarantee","price":0,"size":null,"speed_rating":null,"load_index":0,"description":"Free tyre guarantee"}],"operational_stock":true}}'
|
40
|
+
end
|
41
|
+
it "does what it says on the tin" do
|
42
|
+
|
43
|
+
message = OpenStruct.new(:body => @json)
|
44
|
+
|
45
|
+
handler = TyreshopperSqs2cb::MessageHandler.new
|
46
|
+
|
47
|
+
puts "handling message...."
|
48
|
+
handler.handle_received_message(message, @options);
|
49
|
+
end
|
50
|
+
end
|
10
51
|
end
|
11
52
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -3,14 +3,6 @@ Bundler.setup
|
|
3
3
|
|
4
4
|
require 'tyreshopper_sqs2cb' # and any other gems you need
|
5
5
|
|
6
|
-
ENV['AWS_ACCESS_KEY'] = "access_key"
|
7
|
-
ENV['AWS_SECRET_ACCESS_KEY'] = "secret_key"
|
8
|
-
ENV['CB_API_ENDPOINT'] = "http://localhost:8888/"
|
9
|
-
ENV['CB_API_TOKEN'] = "token"
|
10
|
-
ENV['CB_QUEUE'] = "cb_queue"
|
11
|
-
ENV['SQS2CB_LOGFILE_PATH'] = "log/sqs2cb.log"
|
12
|
-
ENV['TYRESHOPPER_SQS2CB_LOGFILE_PATH'] = "log/tyreshopper_sqs2cb.log"
|
13
|
-
|
14
6
|
RSpec.configure do |config|
|
15
7
|
# some (optional) config here
|
16
8
|
end
|
data/tyreshopper_sqs2cb.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tyreshopper_sqs2cb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stewart McKee
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-02-
|
11
|
+
date: 2015-02-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sqs2cb
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: awesome_print
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
description: Tyreshopper specific handling of data to send to CaseBlocks
|
70
84
|
email:
|
71
85
|
- stewart@theizone.co.uk
|