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