tyreshopper_sqs2cb 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|