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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: be16a91ca6be18e6cb0138bf54bcd3d48e3e25c2
4
- data.tar.gz: 39eea999d39a96ed273f18f7548b58a89884f594
3
+ metadata.gz: cff962d702de6839c46b2fc005d001a0fbcd5127
4
+ data.tar.gz: 1797dcdbbe5646e02ff4d9c0758dace32f5f4c2b
5
5
  SHA512:
6
- metadata.gz: 2a2b3ef7b917d84e4048f4334b7dcd2d46e196e34984784fce5dd5cc919d698f36b62d97c822a8ab927ea6dbdb5c37632a5401b5d4080a5d061201af20a0d75c
7
- data.tar.gz: b0559a4206f01a1faec59e2dc2abefd67752ca5d70c4abfe8ed9d83e1adca871fc2124aaf8ae0884efb3051680f71d7357fb57c3e428ddcafbaf90b458d20f32
6
+ metadata.gz: da9e42a533c48fed2528b87b618b1772dde32704a768263bc236147a90923a1f0271af19fd596866f42d3ac6eb0c56139795e80f6e5fa7aff3791b1c8ff0f04d
7
+ data.tar.gz: 99ed585f27028a60f3aed0bb1384c898596916fe5a6c23748b158002f5cf337cfa3df1a169883bd8b6b29da253735da24da0172d9f4d81cf5baababac223a9e9
data/.gitignore CHANGED
@@ -20,3 +20,4 @@ tmp
20
20
  *.o
21
21
  *.a
22
22
  mkmf.log
23
+ log
File without changes
@@ -1,3 +1,3 @@
1
1
  module TyreshopperSqs2cb
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -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
- response = post("#{@caseBlocksAPIEndpoint}/case_blocks/customers", msgHash.to_json, :content_type => :json, :accept => :json, "AUTH_TOKEN" => @caseBlocksAPIToken)
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
- @logger.info "Received #{response.code} Location: #{response.headers[:location]}"
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
- customer_case_type = get("/case_blocks/people_types")["people_types"].select{|type| type["code"] == "customer" }.first
82
+ order_details = options["case"]
70
83
 
71
84
  # if user was signed in then use member_id else use email
72
- if options["signed_in"]
73
- case_type_matches = get("/case_blocks/search", {"query" => "member_id%3A#{options["member"]["member_id"]}"}).detect{|type| type["case_type_id"] == customer_case_type["id"]}
74
-
75
- if case_type_matches.nil?
76
-
77
- customer = {:customer => {
78
- :case_type_id => customer_case_type["id"],
79
- :people_type_id => customer_case_type["id"],
80
- :address_1 => options["member"]["address1"],
81
- :address_2 => options["member"]["address2"],
82
- :county => options["member"]["county"],
83
- :prefix => options["member"]["prefix"],
84
- :first_name => options["member"]["first_name"],
85
- :surname => options["member"]["surname"],
86
- :postcode => options["member"]["postcode"],
87
- :town => options["member"]["town"]
88
- }}
89
-
90
- # create customer
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 case_type_matches.first
125
+ return cb_customer
93
126
  end
94
127
  else
95
- case_type_matches = get("/case_blocks/search", {"query" => "email%3A#{options["email"]}"}).detect{|type| type["case_type_id"] == customer_case_type["id"]}
128
+ puts "Searching for customer on email #{order_details["email"]}..."
96
129
 
97
- if case_type_matches.nil?
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
- return case_type_matches.first
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 = Uri.parse("#{@caseBlocksAPIEndpoint}#{path}")
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
- return RestClient.get(uri.to_s, :content_type => :json, :accept => :json, "AUTH_TOKEN" => @caseBlocksAPIToken)
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(uri, data)
118
- uri = Uri.parse("#{@caseBlocksAPIEndpoint}#{path}")
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
- return RestClient.get(uri.to_s, data.to_json, :content_type => :json, :accept => :json, "AUTH_TOKEN" => @caseBlocksAPIToken)
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
@@ -23,4 +23,5 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "bundler", "~> 1.6"
24
24
  spec.add_development_dependency "rake"
25
25
  spec.add_development_dependency "rspec"
26
+ spec.add_development_dependency "awesome_print"
26
27
  end
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.1
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-24 00:00:00.000000000 Z
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