Skip to content

Commit 52db533

Browse files
committed
MDS Integration
0 parents  commit 52db533

29 files changed

+1314
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.DS_Store
2+
.bundle/

.rspec

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
--color
2+
--format d
3+
--order rand

Gemfile

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
source 'https://rubygems.org'
2+
3+
gem 'sinatra'
4+
gem 'tilt', '~> 1.4.1'
5+
gem 'tilt-jbuilder', require: 'sinatra/jbuilder'
6+
gem 'endpoint_base', github: 'spree/endpoint_base'
7+
gem 'foreman'
8+
gem 'unicorn'
9+
gem 'nokogiri'
10+
gem 'httparty'
11+
gem 'simplecov'
12+
13+
group :development do
14+
gem 'pry'
15+
gem 'shotgun'
16+
end
17+
18+
group :development, :test do
19+
gem 'pry-byebug'
20+
end
21+
22+
group :test do
23+
gem 'rspec'
24+
gem 'rack-test'
25+
gem 'vcr'
26+
gem 'webmock'
27+
end
28+

Gemfile.lock

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
GIT
2+
remote: git://github.com/spree/endpoint_base.git
3+
revision: f6c1859af1175bd4e29aa36823c8b02a2bb722c2
4+
specs:
5+
endpoint_base (0.3)
6+
activesupport
7+
jbuilder
8+
json
9+
10+
GEM
11+
remote: https://rubygems.org/
12+
specs:
13+
activesupport (4.1.0)
14+
i18n (~> 0.6, >= 0.6.9)
15+
json (~> 1.7, >= 1.7.7)
16+
minitest (~> 5.1)
17+
thread_safe (~> 0.1)
18+
tzinfo (~> 1.1)
19+
addressable (2.3.6)
20+
byebug (2.7.0)
21+
columnize (~> 0.3)
22+
debugger-linecache (~> 1.2)
23+
coderay (1.1.0)
24+
columnize (0.8.9)
25+
crack (0.4.2)
26+
safe_yaml (~> 1.0.0)
27+
debugger-linecache (1.2.0)
28+
diff-lcs (1.2.5)
29+
docile (1.1.5)
30+
dotenv (0.10.0)
31+
foreman (0.63.0)
32+
dotenv (>= 0.7)
33+
thor (>= 0.13.6)
34+
httparty (0.13.1)
35+
json (~> 1.8)
36+
multi_xml (>= 0.5.2)
37+
i18n (0.6.9)
38+
jbuilder (2.0.6)
39+
activesupport (>= 3.0.0, < 5)
40+
multi_json (~> 1.2)
41+
json (1.8.1)
42+
kgio (2.9.2)
43+
method_source (0.8.2)
44+
mini_portile (0.5.2)
45+
minitest (5.3.2)
46+
multi_json (1.9.2)
47+
multi_xml (0.5.5)
48+
nokogiri (1.6.1)
49+
mini_portile (~> 0.5.0)
50+
pry (0.9.12.6)
51+
coderay (~> 1.0)
52+
method_source (~> 0.8)
53+
slop (~> 3.4)
54+
pry-byebug (1.3.2)
55+
byebug (~> 2.7)
56+
pry (~> 0.9.12)
57+
rack (1.5.2)
58+
rack-protection (1.5.2)
59+
rack
60+
rack-test (0.6.2)
61+
rack (>= 1.0)
62+
raindrops (0.13.0)
63+
rspec (2.14.1)
64+
rspec-core (~> 2.14.0)
65+
rspec-expectations (~> 2.14.0)
66+
rspec-mocks (~> 2.14.0)
67+
rspec-core (2.14.8)
68+
rspec-expectations (2.14.5)
69+
diff-lcs (>= 1.1.3, < 2.0)
70+
rspec-mocks (2.14.6)
71+
safe_yaml (1.0.3)
72+
shotgun (0.9)
73+
rack (>= 1.0)
74+
simplecov (0.9.0)
75+
docile (~> 1.1.0)
76+
multi_json
77+
simplecov-html (~> 0.8.0)
78+
simplecov-html (0.8.0)
79+
sinatra (1.4.4)
80+
rack (~> 1.4)
81+
rack-protection (~> 1.4)
82+
tilt (~> 1.3, >= 1.3.4)
83+
slop (3.5.0)
84+
thor (0.18.1)
85+
thread_safe (0.3.3)
86+
tilt (1.4.1)
87+
tilt-jbuilder (0.5.2)
88+
jbuilder
89+
tilt
90+
tzinfo (1.1.0)
91+
thread_safe (~> 0.1)
92+
unicorn (4.8.2)
93+
kgio (~> 2.6)
94+
rack
95+
raindrops (~> 0.7)
96+
vcr (2.6.0)
97+
webmock (1.18.0)
98+
addressable (>= 2.3.6)
99+
crack (>= 0.3.2)
100+
101+
PLATFORMS
102+
ruby
103+
104+
DEPENDENCIES
105+
endpoint_base!
106+
foreman
107+
httparty
108+
nokogiri
109+
pry
110+
pry-byebug
111+
rack-test
112+
rspec
113+
shotgun
114+
simplecov
115+
sinatra
116+
tilt (~> 1.4.1)
117+
tilt-jbuilder
118+
unicorn
119+
vcr
120+
webmock

Procfile

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb

README.md

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# MDS Fulfillment Integration
2+
3+
This integration is designed to integrate Wombat with
4+
[MDS Fulfillment](http://www.mdsfulfillment.com/) API.
5+
6+
This is a fully hosted and supported integration for use with the [Wombat](http://wombat.co)
7+
product. With this integration you can perform the following functions:
8+
9+
* Push Orders to MDS Fulfillment
10+
* Get Inventory stock / status from MDS Fulfillment
11+
* Get Orders / Shipment updates from MDS Fulfillment
12+
13+
[Wombat](http://wombat.co) allows you to connect to your own custom integrations.
14+
Feel free to modify the source code and host your own version of the integration
15+
or better yet, help to make the official integration better by submitting a pull request!
16+
17+
![Wombat Logo](http://spreecommerce.com/images/wombat_logo.png)
18+
19+
This integration is 100% open source an licensed under the terms of the New BSD License.
20+

config.ru

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
require 'rubygems'
2+
require 'bundler/setup'
3+
4+
Bundler.require(:default)
5+
require './mds_integration'
6+
run MDSIntegration

config/unicorn.rb

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
worker_processes ENV.fetch('WORKER_PROCESSES', 5).to_i
2+
timeout 180
3+
4+
preload_app true
5+
6+
GC.respond_to?(:copy_on_write_friendly=) and GC.copy_on_write_friendly = true
7+
8+
before_fork do |server, worker|
9+
defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
10+
11+
# kills old children after zero downtime deploy
12+
old_pid = "#{server.config[:pid]}.oldbin"
13+
if old_pid != server.pid
14+
begin
15+
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
16+
Process.kill(sig, File.read(old_pid).to_i)
17+
rescue Errno::ENOENT, Errno::ESRCH
18+
end
19+
end
20+
21+
sleep 1
22+
end
23+
24+
after_fork do |server, worker|
25+
defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
26+
27+
defined?(Rails) and Rails.cache.respond_to?(:reconnect) and Rails.cache.reconnect
28+
end

lib/mds/mds.rb

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# services
2+
require_relative 'services/base'
3+
require_relative 'services/full_inventory'
4+
require_relative 'services/submit_order'
5+
require_relative 'services/shipping_status/tracking'
6+
7+
# responses
8+
require_relative 'responses/cust_order_ack'
9+
require_relative 'responses/sku_full_ack'
10+
require_relative 'responses/shipping_sku_ack'

lib/mds/responses/cust_order_ack.rb

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
module MDS
2+
module Responses
3+
class CUSTOrderAck
4+
attr_accessor :body
5+
6+
def initialize(body)
7+
@body = body
8+
end
9+
10+
def success?
11+
body["OrderAck"]["Result"] == "1"
12+
end
13+
14+
def message
15+
if success?
16+
"#{body["OrderAck"]["OrderID"]} was received by MDS Fulfillment."
17+
else
18+
body["OrderAck"]["Message"]
19+
end
20+
end
21+
end
22+
end
23+
end

lib/mds/responses/shipping_sku_ack.rb

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module MDS
2+
module Responses
3+
class ShippingSKUAck
4+
attr_accessor :body
5+
6+
def initialize(body)
7+
@body = body.to_h
8+
end
9+
10+
def success?
11+
true
12+
end
13+
14+
def message
15+
"#{objects.size} shipments were received."
16+
end
17+
18+
def objects
19+
Array(body["Order"]).map do |order|
20+
{
21+
id: order["OrderID"],
22+
status: "shipped",
23+
tracking: order["TrackingNumber"],
24+
shipped_at: DateTime.parse(order["OrderShipDate"])
25+
}
26+
end
27+
end
28+
end
29+
end
30+
end

lib/mds/responses/sku_full_ack.rb

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
module MDS
2+
module Responses
3+
class SKUFullAck
4+
attr_accessor :body
5+
6+
def initialize(body)
7+
@body = body.to_h
8+
end
9+
10+
def success?
11+
true
12+
end
13+
14+
def message
15+
"Inventory for #{objects.size} products was received."
16+
end
17+
18+
def objects
19+
sku_lines.map do |sku_line|
20+
{
21+
id: sku_line["SKU"],
22+
location: "MDS",
23+
product_id: sku_line["SKU"],
24+
quantity: sku_line["OnHand"].to_i
25+
}
26+
end
27+
end
28+
29+
private
30+
def sku_lines
31+
Array(body["SKULine"]).reject {|sku_line| sku_line["Active"] != "Y"}
32+
end
33+
end
34+
end
35+
end

lib/mds/services/base.rb

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
module MDS
2+
module Services
3+
module Base
4+
def self.included(base)
5+
base.send(:extend, ClassMethods)
6+
end
7+
8+
module ClassMethods
9+
attr_reader :url_package, :xml_root
10+
11+
def set_url_package(package)
12+
@url_package = package
13+
end
14+
15+
def set_xml_root(xml_root)
16+
@xml_root = xml_root
17+
end
18+
end
19+
20+
def initialize(credentials)
21+
@client_code = credentials.fetch(:client_code)
22+
@client_signature = credentials.fetch(:client_signature)
23+
end
24+
25+
def query(object = {})
26+
puts payload = builder(object).to_xml
27+
puts '-' * 77
28+
puts xml_response = HTTParty.get("http://webservice-dev.mdsfulfillment.com/#{self.class.url_package}/ReceiveXML.aspx?xml=" + URI.encode(payload))
29+
build_response_instance(xml_response)
30+
end
31+
32+
def build_response_instance(xml_response)
33+
response = Hash.from_xml(xml_response)
34+
klass = response.keys[0]
35+
body = response[klass]
36+
37+
MDS::Responses.const_get(klass).new(body)
38+
end
39+
40+
def xml_builder
41+
Nokogiri::XML::Builder.new do |xml|
42+
xml.send(self.class.xml_root, 'xml:lang' => 'en-US') do
43+
xml.ClientCode @client_code
44+
xml.ClientSignature @client_signature
45+
yield(xml)
46+
end
47+
end
48+
end
49+
end
50+
end
51+
end

lib/mds/services/full_inventory.rb

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module MDS
2+
module Services
3+
class FullInventory
4+
include Base
5+
6+
set_xml_root 'MDSFullSKU'
7+
set_url_package 'mds.full.inventory'
8+
9+
def builder(_)
10+
xml_builder do |xml|
11+
xml.SKUDetail 'True'
12+
end
13+
end
14+
end
15+
end
16+
end

0 commit comments

Comments
 (0)