order2cb 0.0.1
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 +7 -0
- data/.gitignore +23 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/LICENSE.txt +22 -0
- data/README.md +39 -0
- data/Rakefile +2 -0
- data/bin/order2cb +9 -0
- data/lib/order2cb/caseblocks.rb +36 -0
- data/lib/order2cb/order.rb +180 -0
- data/lib/order2cb/version.rb +3 -0
- data/lib/order2cb.rb +122 -0
- data/order2cb.gemspec +34 -0
- data/test/lib/order2cb/order_test.rb +20 -0
- data/test/lib/order2cb/version_test.rb +7 -0
- data/test/lib/order2cb_test.rb +25 -0
- data/test/test_helper.rb +3 -0
- metadata +193 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 235c77174039472238256e63b6949440d6154bfc
|
4
|
+
data.tar.gz: 9544a9b1effcb5654e0b77482e379ef755fa1d9a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8f0a8fe67514cbf9bff1bc4abb9796da6c9ef5a0d2586c4cd53b7c38d54721ed4e30e656c3df375be09d734aae855bc60b1d4941abfaeb566bac0a342cc73fef
|
7
|
+
data.tar.gz: 43659ba64b45622946ae804ac866ecdec9512ee7405514403d1e24c983d95ba89fc79e4448fe609db97b3716f90f8e67c847e3041a7b1acc0845fcb416e7db8f
|
data/.gitignore
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
23
|
+
*.swp
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
order2cb
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.2.2
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 EmergeAdapt
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Ijonas Kisselbach
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Order2cb
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'order2cb'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install order2cb
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Ensure the following environment variables are set:
|
22
|
+
|
23
|
+
AWS_ACCESS_KEY=...
|
24
|
+
AWS_SECRET_ACCESS_KEY=...
|
25
|
+
CB_QUEUE=https://sqs.<region>.amazonaws.com/<account-id>/<caseblocks-queue>
|
26
|
+
CB_API_ENDPOINT=https://<subdomain>.caseblocks.com
|
27
|
+
CB_API_TOKEN=...
|
28
|
+
|
29
|
+
And run the daemon from the CLI
|
30
|
+
|
31
|
+
order2cb
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
1. Fork it ( https://github.com/[my-github-username]/order2cb/fork )
|
36
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
37
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
38
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
39
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/bin/order2cb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
module Order2cb
|
2
|
+
class Caseblocks
|
3
|
+
|
4
|
+
def initialize(logger)
|
5
|
+
@logger = logger
|
6
|
+
end
|
7
|
+
|
8
|
+
def completed_orders(start_time = Time.now.utc - 4200, end_time = Time.now.utc)
|
9
|
+
results = $client.query("SELECT number, state, payment_state, card_type, pp_payment_id, completed_at, title, first_name, surname, email, total FROM exp_spree_orders WHERE completed_at > '#{start_time.strftime("%Y-%m-%d %H-%M-%S")}' and completed_at < '#{end_time.strftime("%Y-%m-%d %H-%M-%S")}'")
|
10
|
+
results
|
11
|
+
rescue => e
|
12
|
+
@logger.error e.message
|
13
|
+
@logger.error e.backtrace.join('\n')
|
14
|
+
false
|
15
|
+
end
|
16
|
+
|
17
|
+
def order_exists?(order_no)
|
18
|
+
response = RestClient.get "#{ENV['CB_API_ENDPOINT']}/case_blocks/search.json?auth_token=#{ENV['CB_API_TOKEN']}&case_type_id=#{ENV['CB_TS_TYPE_ID']}&query=order_number:#{order_no}"
|
19
|
+
response.code==200 && JSON.parse(response.body).count > 0
|
20
|
+
rescue => e
|
21
|
+
@logger.error e.message
|
22
|
+
@logger.error e.backtrace.join('\n')
|
23
|
+
raise e
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_order(order)
|
27
|
+
response = RestClient.post "#{ENV['CB_API_ENDPOINT']}/case_blocks/cases?auth_token=#{ENV['CB_API_TOKEN']}", order.to_json, :content_type => :json, :accept => :json
|
28
|
+
response.code==201 && JSON.parse(response.body).count > 0
|
29
|
+
rescue => e
|
30
|
+
@logger.error e.message
|
31
|
+
@logger.error e.backtrace.join('\n')
|
32
|
+
false
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
module Order2cb
|
2
|
+
class Order
|
3
|
+
|
4
|
+
def self.find(order_number)
|
5
|
+
sql = "SELECT * FROM exp_spree_orders where number = '#{order_number}';"
|
6
|
+
data = $db_client.query(sql)
|
7
|
+
return Order.new(data.first)
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(data)
|
11
|
+
@data = data
|
12
|
+
end
|
13
|
+
|
14
|
+
def number
|
15
|
+
@data['number']
|
16
|
+
end
|
17
|
+
|
18
|
+
def current_state
|
19
|
+
if high_risk?
|
20
|
+
return "Requiring action Risk"
|
21
|
+
elsif fitting_centre['mobile_fitting']
|
22
|
+
return "Ready for mobile fitting"
|
23
|
+
else
|
24
|
+
return "Ready for dataflex"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def high_risk?
|
29
|
+
@data["risk_score"] >= 22 || @data["worldpay_risk_score"] >= 40
|
30
|
+
end
|
31
|
+
|
32
|
+
def customer
|
33
|
+
[@data['title'], @data['first_name'], @data['surname']].reject{|s| s.strip.empty?}.join(" ")
|
34
|
+
end
|
35
|
+
|
36
|
+
def market_opt_in
|
37
|
+
@data['accept_marketing'] == true
|
38
|
+
end
|
39
|
+
|
40
|
+
def payment_type
|
41
|
+
@data['card_type'].to_s.strip == "" ? "PayPal" : "Creditcard"
|
42
|
+
end
|
43
|
+
|
44
|
+
def payment_reference
|
45
|
+
@data['card_type'].to_s.strip == "" ? @data['pp_payment_id'] : @data['number']
|
46
|
+
end
|
47
|
+
|
48
|
+
def order_details
|
49
|
+
{
|
50
|
+
'title' => @data['number'],
|
51
|
+
'case_type_id' => ENV['CB_CASE_TYPE_ID'],
|
52
|
+
'case_type' => 'tyre-shopper-order',
|
53
|
+
'current_state' => current_state,
|
54
|
+
'order_number' => @data['number'],
|
55
|
+
'order_date' => DateTime.now,
|
56
|
+
'customer' => customer,
|
57
|
+
'vrn' => @data['vehicle_registration'],
|
58
|
+
'address1' => @data['address1'],
|
59
|
+
'address2' => @data['address2'],
|
60
|
+
'address3' => @data['town'],
|
61
|
+
'postcode' => @data['postcode'],
|
62
|
+
'daytime_telephone' => @data['daytime_telephone'],
|
63
|
+
'evening_telephone' => @data['evening_telephone'],
|
64
|
+
'email' => @data['email'],
|
65
|
+
'market_opt_in' => market_opt_in,
|
66
|
+
'payment_type' => payment_type,
|
67
|
+
'transaction_reference' => payment_reference,
|
68
|
+
'card_number' => @data['card_last_digits'],
|
69
|
+
'account_holder' => @data['card_holder_name'],
|
70
|
+
'streamline_risk_assessment' => @data['worldpay_risk_score'],
|
71
|
+
'tyre_shopper_risk_assessment' => @data['risk_score'],
|
72
|
+
'tyre_shopper_risk_assessment_notes' => @data['risk_score_reasons'],
|
73
|
+
'order_source' => 'TyreShopper',
|
74
|
+
# set time to + 5 hours
|
75
|
+
'fitting_date' => @data['fitting_date'] + 5.hours,
|
76
|
+
'am_pm' => @data['fitting_day_part'],
|
77
|
+
'stock_check' => true,
|
78
|
+
'original_total' => @data['total']
|
79
|
+
}
|
80
|
+
end
|
81
|
+
|
82
|
+
def fitting_centre
|
83
|
+
channel_fields = $db_client.query("SELECT exp_channel_fields.* FROM exp_channel_fields JOIN exp_channels on exp_channels.channel_id = exp_channel_fields.group_id WHERE exp_channels.channel_name = 'branches'")
|
84
|
+
data_field_id = $db_client.query("SELECT exp_channel_fields.field_id FROM exp_channel_fields JOIN exp_channels on exp_channels.channel_id = exp_channel_fields.group_id WHERE exp_channels.channel_name = 'branches' and exp_channel_fields.field_name = 'dataflex_id'").first["field_id"]
|
85
|
+
fitting_centre_fields = $db_client.query("SELECT * FROM exp_channel_data WHERE field_id_#{data_field_id} = '#{@data['fitting_centre_id']}'")
|
86
|
+
|
87
|
+
fitting_centre_hash = {}
|
88
|
+
channel_fields.map{|f| fitting_centre_hash[f['field_name']] = fitting_centre_fields.first["field_id_#{f['field_id']}"]}
|
89
|
+
|
90
|
+
is_mobile_fitting = fitting_centre_hash['is_mobile_fitting'].upcase == "YES"
|
91
|
+
details = {
|
92
|
+
'phone_number' => fitting_centre_hash['phone_number'],
|
93
|
+
'branch_number' => fitting_centre_hash['dataflex_id'],
|
94
|
+
'mobile_fitting' => is_mobile_fitting
|
95
|
+
}
|
96
|
+
if is_mobile_fitting
|
97
|
+
|
98
|
+
address_components = [fitting_centre_hash['street'], fitting_centre_hash['street2'], fitting_centre_hash['town'], fitting_centre_hash['postcode']]
|
99
|
+
address = address_components.reject{|comp| comp.strip.empty?}.join(", ")
|
100
|
+
|
101
|
+
details['mobile_fitter'] = fitting_centre_hash['name']
|
102
|
+
details['customer_contact_name'] = 'Unknown'
|
103
|
+
details['fitting_address'] = address
|
104
|
+
else
|
105
|
+
details['name'] = fitting_centre_hash['name']
|
106
|
+
end
|
107
|
+
|
108
|
+
details
|
109
|
+
end
|
110
|
+
|
111
|
+
def line_items
|
112
|
+
line_items_results = []
|
113
|
+
@operational_stock_order = true
|
114
|
+
|
115
|
+
get_line_items.each do |line_item_row|
|
116
|
+
if @operational_stock_order && !line_item_row['is_operational_stock']
|
117
|
+
@operational_stock_order = false
|
118
|
+
end
|
119
|
+
line_items_results << {
|
120
|
+
'qty' => line_item_row['quantity'],
|
121
|
+
'sku' => line_item_row['sku'],
|
122
|
+
'price' => exvat(line_item_price(line_item_row)),
|
123
|
+
'size' => line_item_row['tyre_size'],
|
124
|
+
'speed_rating' => line_item_row['speed_rating'],
|
125
|
+
'load_index' => line_item_row['load_index'].to_i,
|
126
|
+
'description' => line_item_row['sku_description']
|
127
|
+
}
|
128
|
+
end
|
129
|
+
line_items_results
|
130
|
+
end
|
131
|
+
|
132
|
+
def db_adjustments_by_order
|
133
|
+
$db_client.query("SELECT * FROM exp_spree_adjustments WHERE source_id = '#{@data['id']}' ORDER BY id ASC")
|
134
|
+
end
|
135
|
+
|
136
|
+
def adjustments
|
137
|
+
line_items_results = []
|
138
|
+
db_adjustments_by_order.each do |adj|
|
139
|
+
line_items_results << {
|
140
|
+
'qty' => 1,
|
141
|
+
'sku' => adj['coupon_code'],
|
142
|
+
'price' => exvat(adj['amount']),
|
143
|
+
'size' => nil,
|
144
|
+
'speed_rating' => nil,
|
145
|
+
'load_index' => nil,
|
146
|
+
'description' => 'Promotion'
|
147
|
+
}
|
148
|
+
end
|
149
|
+
line_items_results
|
150
|
+
end
|
151
|
+
|
152
|
+
def get_line_items
|
153
|
+
$db_client.query("SELECT * FROM exp_remote_line_items WHERE order_id = #{@data['id']} ORDER BY id ASC;")
|
154
|
+
end
|
155
|
+
def exvat(with_vat_amount)
|
156
|
+
(with_vat_amount / 120) * 100
|
157
|
+
end
|
158
|
+
|
159
|
+
def line_item_price(line_item_row)
|
160
|
+
line_item_row['prices'].to_s.split(",")[0].to_s.to_f
|
161
|
+
end
|
162
|
+
|
163
|
+
def to_hash
|
164
|
+
order = order_details.merge(fitting_centre)
|
165
|
+
|
166
|
+
order['line_items'] = []
|
167
|
+
order['line_items'] += line_items
|
168
|
+
order['line_items'] += adjustments
|
169
|
+
|
170
|
+
order['operational_stock'] = @operational_stock_order
|
171
|
+
|
172
|
+
return {'case' => order}
|
173
|
+
end
|
174
|
+
|
175
|
+
def to_json
|
176
|
+
self.to_hash.to_json
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
end
|
data/lib/order2cb.rb
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
require_relative "order2cb/version"
|
2
|
+
require_relative "order2cb/order"
|
3
|
+
require_relative "order2cb/caseblocks"
|
4
|
+
require 'aws-sdk-v1'
|
5
|
+
require 'json'
|
6
|
+
require 'rest_client'
|
7
|
+
require 'logger'
|
8
|
+
require 'mysql2'
|
9
|
+
require 'active_support/all'
|
10
|
+
require 'action_view'
|
11
|
+
require 'awesome_print'
|
12
|
+
|
13
|
+
include ActionView::Helpers::DateHelper
|
14
|
+
|
15
|
+
module Order2cb
|
16
|
+
class OrderHandler
|
17
|
+
def initialize
|
18
|
+
@caseBlocksAPIEndpoint = ENV['CB_API_ENDPOINT']
|
19
|
+
@caseBlocksAPIToken = ENV['CB_API_TOKEN']
|
20
|
+
@caseBlocksQueue = ENV['CB_QUEUE']
|
21
|
+
@caseBlocksCaseTypeID = ENV['CB_CASE_TYPE_ID']
|
22
|
+
|
23
|
+
@tyreshopperDatabaseHost = ENV['DB_HOST']
|
24
|
+
@tyreshopperDatabaseUser = ENV['DB_USER']
|
25
|
+
@tyreshopperDatabasePassword = ENV['DB_PASSWORD']
|
26
|
+
@tyreshopperDatabaseName = ENV['DB_NAME']
|
27
|
+
|
28
|
+
@interval = ENV['CHECK_INTERVAL'] ? ENV['CHECK_INTERVAL'] : 60
|
29
|
+
|
30
|
+
@usePatchCommand = (@caseBlocksQueue =~ /patch/)
|
31
|
+
logfile = ENV['ORDER2CB_LOGFILE_PATH'].nil? ? STDOUT : File.open(ENV['ORDER2CB_LOGFILE_PATH'], 'a')
|
32
|
+
logfile.sync = true
|
33
|
+
@logger = Logger.new logfile
|
34
|
+
@stop = false
|
35
|
+
@orders_sent_to_caseblocks = []
|
36
|
+
|
37
|
+
@options = {:use_patch_command => @usePatchCommand, :case_blocks_api_endpoint => @caseBlocksAPIEndpoint, :caseblocks_api_token => @caseBlocksAPIToken}
|
38
|
+
|
39
|
+
raise RuntimeError, "Please ensure CB_API_ENDPOINT is set." if @caseBlocksAPIEndpoint.nil? or @caseBlocksAPIEndpoint.empty?
|
40
|
+
raise RuntimeError, "Please ensure CB_API_TOKEN is set." if @caseBlocksAPIToken.nil? or @caseBlocksAPIToken.empty?
|
41
|
+
raise RuntimeError, "Please ensure DB_HOST is set." if @tyreshopperDatabaseHost.nil? or @tyreshopperDatabaseHost.empty?
|
42
|
+
raise RuntimeError, "Please ensure DB_USER is set." if @tyreshopperDatabaseUser.nil? or @tyreshopperDatabaseUser.empty?
|
43
|
+
raise RuntimeError, "Please ensure DB_PASSWORD is set." if @tyreshopperDatabasePassword.nil?
|
44
|
+
raise RuntimeError, "Please ensure DB_NAME is set." if @tyreshopperDatabaseName .nil? or @tyreshopperDatabaseName.empty?
|
45
|
+
raise RuntimeError, "Please ensure CB_CASE_TYPE_ID is set." if @caseBlocksCaseTypeID.nil? or @caseBlocksCaseTypeID.empty?
|
46
|
+
|
47
|
+
@logger.info "MessageHandler ready to transfer messages."
|
48
|
+
end
|
49
|
+
|
50
|
+
def run
|
51
|
+
@logger.info "Starting processing orders from tyreshopper to caseblocks"
|
52
|
+
until @stop
|
53
|
+
begin
|
54
|
+
$db_client = Mysql2::Client.new(:host => @tyreshopperDatabaseHost, :username => @tyreshopperDatabaseUser, :password => @tyreshopperDatabasePassword, :database => @tyreshopperDatabaseName)
|
55
|
+
process_orders
|
56
|
+
$db_client.close
|
57
|
+
@logger.debug "Waiting for #{@interval} seconds..."
|
58
|
+
rescue => e
|
59
|
+
@logger.error e.message
|
60
|
+
@logger.error e.backtrace.join('\n')
|
61
|
+
end
|
62
|
+
sleep @interval
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def stop
|
67
|
+
@stop = true
|
68
|
+
end
|
69
|
+
|
70
|
+
def process_orders
|
71
|
+
@logger.debug "Checking for orders"
|
72
|
+
caseblocks = Caseblocks.new(@logger)
|
73
|
+
orders_to_process.each do |order|
|
74
|
+
begin
|
75
|
+
order = ::Order2cb::Order.find(order['number'])
|
76
|
+
unless caseblocks.order_exists?(order.number)
|
77
|
+
@logger.debug "#{order.number} doesn't exist in caseblocks, sending it now"
|
78
|
+
if caseblocks.create_order(order)
|
79
|
+
@logger.info "Sent #{order.number} to caseblocks."
|
80
|
+
else
|
81
|
+
@logger.error "Failed to send #{order.number} to caseblocks."
|
82
|
+
end
|
83
|
+
else
|
84
|
+
@logger.debug "#{order.number} already exists in caseblocks... skipping."
|
85
|
+
end
|
86
|
+
rescue => e
|
87
|
+
@logger.error e.message
|
88
|
+
@logger.error e.backtrace.join('\n')
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
def orders_to_process(start_time = DateTime.parse(6.hours.ago.to_s))
|
95
|
+
results = $db_client.query("SELECT * from exp_spree_orders where completed_at > '#{start_time}';")
|
96
|
+
@logger.debug "Found #{results.count} completed orders in the last #{time_ago_in_words(start_time)} to be processed"
|
97
|
+
results
|
98
|
+
end
|
99
|
+
|
100
|
+
def order_exists_in_casebocks
|
101
|
+
RestClient.get 'https://login.caseblocks/com/search', {:params => {:auth_token => @caseBlocksAPIToken, 'foo' => 'bar'}}
|
102
|
+
return false
|
103
|
+
end
|
104
|
+
|
105
|
+
def send_to_caseblocks(msgHash)
|
106
|
+
@logger.debug "Sending to CaseBlocks"
|
107
|
+
|
108
|
+
response = RestClient.post(add_auth(Uri.parse("#{@caseBlocksAPIEndpoint}/case_blocks/cases")), msgHash.to_json,
|
109
|
+
:content_type => :json,
|
110
|
+
:accept => :json,
|
111
|
+
"AUTH_TOKEN" => @caseBlocksAPIToken)
|
112
|
+
@logger.info "Received #{response.code} Location: #{response.headers[:location]}"
|
113
|
+
rescue RestClient::ExceptionWithResponse => ex
|
114
|
+
if ex.response.nil?
|
115
|
+
@logger.error "Received a bad response (null) from CaseBlocks. Re-raising."
|
116
|
+
raise ex
|
117
|
+
else
|
118
|
+
@logger.error "Received #{ex.response.code} bad response: #{ex.response.body}"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
data/order2cb.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'order2cb/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "order2cb"
|
8
|
+
spec.version = Order2cb::VERSION
|
9
|
+
spec.authors = ["EmergeAdapt"]
|
10
|
+
spec.email = ["development@emergeadapt.com"]
|
11
|
+
spec.summary = %q{Grabs orders from Tyreshopper and posts them to SQS.}
|
12
|
+
spec.description = %q{Basic WIP.}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "awesome_print"
|
24
|
+
|
25
|
+
spec.add_dependency 'aws-sdk-v1', "~> 1.60.2"
|
26
|
+
spec.add_dependency 'rest-client', "~> 1.7.2"
|
27
|
+
spec.add_dependency 'mysql2', "~> 0.4.0"
|
28
|
+
spec.add_dependency 'activesupport', "~> 4.2.1"
|
29
|
+
spec.add_dependency 'actionview', "~> 4.2.1"
|
30
|
+
spec.add_dependency 'caseblocks_api'
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
|
3
|
+
class TestOrder < Minitest::Test
|
4
|
+
def setup
|
5
|
+
@sample = {}
|
6
|
+
@order = Order.new(@sample)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_that_kitty_can_eat
|
10
|
+
assert_equal "OHAI!", @meme.i_can_has_cheezburger?
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_that_it_will_not_blend
|
14
|
+
refute_match /^no/i, @meme.will_it_blend?
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_that_will_be_skipped
|
18
|
+
skip "test this later"
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
class MessageHandlerTest < MiniTest::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
ENV['CB_API_ENDPOINT'] = 'https://cb.local/'
|
6
|
+
ENV['CB_API_TOKEN'] = '1234'
|
7
|
+
end
|
8
|
+
def test_invalid_construction
|
9
|
+
ENV['AWS_ACCESS_KEY'] = nil
|
10
|
+
ENV['AWS_SECRET_ACCESS_KEY'] = nil
|
11
|
+
ENV['CB_API_ENDPOINT'] = nil
|
12
|
+
ENV['CB_API_TOKEN'] = nil
|
13
|
+
assert_raises(RuntimeError) { Order2cb::OrderHandler.new }
|
14
|
+
end
|
15
|
+
def test_valid_construction
|
16
|
+
ENV['AWS_ACCESS_KEY'] = 'access'
|
17
|
+
ENV['AWS_SECRET_ACCESS_KEY'] = 'secret'
|
18
|
+
refute_nil Order2cb::OrderHandler.new
|
19
|
+
end
|
20
|
+
def test_basic_sqs_connectivity
|
21
|
+
oh = Order2cb::OrderHandler.new
|
22
|
+
result = oh.send_orders
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: order2cb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- EmergeAdapt
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-09-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: awesome_print
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: aws-sdk-v1
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.60.2
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.60.2
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rest-client
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.7.2
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.7.2
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: mysql2
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.4.0
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.4.0
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: activesupport
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 4.2.1
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 4.2.1
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: actionview
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 4.2.1
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 4.2.1
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: caseblocks_api
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description: Basic WIP.
|
140
|
+
email:
|
141
|
+
- development@emergeadapt.com
|
142
|
+
executables:
|
143
|
+
- order2cb
|
144
|
+
extensions: []
|
145
|
+
extra_rdoc_files: []
|
146
|
+
files:
|
147
|
+
- ".gitignore"
|
148
|
+
- ".ruby-gemset"
|
149
|
+
- ".ruby-version"
|
150
|
+
- Gemfile
|
151
|
+
- LICENSE
|
152
|
+
- LICENSE.txt
|
153
|
+
- README.md
|
154
|
+
- Rakefile
|
155
|
+
- bin/order2cb
|
156
|
+
- lib/order2cb.rb
|
157
|
+
- lib/order2cb/caseblocks.rb
|
158
|
+
- lib/order2cb/order.rb
|
159
|
+
- lib/order2cb/version.rb
|
160
|
+
- order2cb.gemspec
|
161
|
+
- test/lib/order2cb/order_test.rb
|
162
|
+
- test/lib/order2cb/version_test.rb
|
163
|
+
- test/lib/order2cb_test.rb
|
164
|
+
- test/test_helper.rb
|
165
|
+
homepage: ''
|
166
|
+
licenses:
|
167
|
+
- MIT
|
168
|
+
metadata: {}
|
169
|
+
post_install_message:
|
170
|
+
rdoc_options: []
|
171
|
+
require_paths:
|
172
|
+
- lib
|
173
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
174
|
+
requirements:
|
175
|
+
- - ">="
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
178
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - ">="
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: '0'
|
183
|
+
requirements: []
|
184
|
+
rubyforge_project:
|
185
|
+
rubygems_version: 2.4.8
|
186
|
+
signing_key:
|
187
|
+
specification_version: 4
|
188
|
+
summary: Grabs orders from Tyreshopper and posts them to SQS.
|
189
|
+
test_files:
|
190
|
+
- test/lib/order2cb/order_test.rb
|
191
|
+
- test/lib/order2cb/version_test.rb
|
192
|
+
- test/lib/order2cb_test.rb
|
193
|
+
- test/test_helper.rb
|