big_machines 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 ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MzAxYWIzMjQ1YWViZjdiZDk5YjMzMjhlMWU0OGJjZGY1ODhiMGUyYw==
5
+ data.tar.gz: !binary |-
6
+ MmNkZGQ1M2QyZmU1MjRiNWFiM2I3MTE0MzhmZWEyMGVjNzBlNTI0Mg==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ MzNhOTM4MzAwYjZiYjM0NzYzYTY4OTlhMDkyM2VhM2Y3OTM1MzJkYTk5NTMz
10
+ NzcwMmQ5NGJmMTMxZjMwNGZmNjA4YzM5OTA5MjU4ZTc2YTZhYTRkOTlkZDAx
11
+ MWQzNGRmOWZiNjM2MDliNDgzNWY3ZjgxMTU3OTE5ZWEzZDljMzE=
12
+ data.tar.gz: !binary |-
13
+ OTYyMWM4OGQ4NzRkNGZjZmRjZWFhODdjNTM4NDFlN2MxNzI0YTVlNmE0MTJh
14
+ NGUxYzhlZjQ1MjZiYTU5MzlhYjRmMDA4MDk4NTNlNWIwNTBkZTE5OTFlNmE3
15
+ MWU4N2M2OTAyYTE1YmVlMjIxNjAzYzc2MWI4ZGE3YzIyOTAwZDc=
data/.gitignore ADDED
@@ -0,0 +1,18 @@
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
+ vendor
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ notifications:
5
+ email:
6
+ recipients:
7
+ - joeheth@gmail.com
8
+ on_success: never
9
+ on_failure: always
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in big_machines.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Joe Heth
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,96 @@
1
+ # BigMachines
2
+
3
+ [![Build Status](https://travis-ci.org/TinderBox/big_machines.png)](https://travis-ci.org/TinderBox/big_machines)
4
+
5
+ Ruby gem for the undocumented BigMachines SOAP API
6
+
7
+ ### Implemented Operations
8
+
9
+ * Security API - login, logout, getUserInfo, setSessionCurrency
10
+ * Commerce API - getTransaction, updateTransaction (partial)
11
+
12
+ ### Services Not Implemented
13
+
14
+ * Configuration, Parts, Data Tables, Users, Groups, Exchange Rates
15
+
16
+
17
+ ## Installation
18
+
19
+ Add this line to your application's Gemfile:
20
+
21
+ gem 'big_machines'
22
+
23
+ And then execute:
24
+
25
+ $ bundle
26
+
27
+ Or install it yourself as:
28
+
29
+ $ gem install big_machines
30
+
31
+ ## Usage
32
+
33
+
34
+ #### Create Client
35
+
36
+ ```ruby
37
+ client = BigMachines::Client.new('subdomain')
38
+ ```
39
+
40
+ ```ruby
41
+ # Specify process name
42
+ client = BigMachines::Client.new('subdomain', process_name: 'quotes_process')
43
+ ```
44
+
45
+
46
+ #### Authenticate
47
+
48
+ ```ruby
49
+ client.login(:username => 'foo', :password => 'password')
50
+ ```
51
+
52
+ ### set_session_currency
53
+
54
+ ```ruby
55
+ client.set_session_currency('USD')
56
+ # => Hash[:status]
57
+ ```
58
+
59
+ ### get_user_info
60
+
61
+ ```ruby
62
+ client.get_user_info
63
+ # => Hash[:user_info]
64
+ ```
65
+
66
+ ### get_transaction
67
+
68
+ ```ruby
69
+ # Find transaction by id
70
+ client.get_transaction(id)
71
+ # => BigMachines::Transaction
72
+ ```
73
+
74
+ ### update_transaction
75
+
76
+ ```ruby
77
+ # Update transaction
78
+ client.update_transaction(id, data={})
79
+ # => Hash[:status]
80
+ ```
81
+
82
+
83
+ ### logout
84
+
85
+ ```ruby
86
+ client.logout
87
+ ```
88
+
89
+
90
+ ## Contributing
91
+
92
+ 1. Fork it ( http://github.com/TinderBox/big_machines/fork )
93
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
94
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
95
+ 4. Push to the branch (`git push origin my-new-feature`)
96
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'big_machines/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "big_machines"
8
+ spec.version = BigMachines::VERSION
9
+ spec.authors = ["Joe Heth"]
10
+ spec.email = ["joeheth@gmail.com"]
11
+ spec.summary = %q{Communicate with BigMachine's SOAP API}
12
+ spec.description = %q{BigMachine's SOAP API Implementation}
13
+ spec.homepage = "https://github.com/TinderBox/big_machines"
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_dependency 'savon', '~> 2.3.0', '>= 2.3.0'
22
+ spec.add_development_dependency 'bundler', '~> 1.5'
23
+ spec.add_development_dependency 'rake', '~> 0'
24
+
25
+ spec.add_development_dependency 'rspec', '~> 2.14.0', '>= 2.14.0'
26
+ spec.add_development_dependency 'webmock', '~> 1.13.0', '>= 1.13.0'
27
+ spec.add_development_dependency 'simplecov', '~> 0.7.1', '>= 0.7.1'
28
+ end
@@ -0,0 +1,238 @@
1
+ module BigMachines
2
+ class Client
3
+
4
+ attr_reader :client
5
+ attr_reader :headers
6
+
7
+ # The partner.wsdl is used by default but can be changed by passing in a new :wsdl option.
8
+ # A client_id can be
9
+ def initialize(site_name, options={})
10
+ @site_name = site_name
11
+ raise "Valid Site Name must be provided" if @site_name.nil? || @site_name.empty?
12
+ @process_var_name = options[:process_name] || "quotes_process"
13
+
14
+ @namespaces = {
15
+ "xmlns:bm" => "urn:soap.bigmachines.com"
16
+ }
17
+
18
+ @security_wsdl = File.dirname(__FILE__) + "/../../resources/security.wsdl.xml"
19
+ @commerce_wsdl = File.dirname(__FILE__) + "/../../resources/commerce.wsdl.xml"
20
+
21
+ @endpoint = "https://#{@site_name}.bigmachines.com/v1_0/receiver"
22
+
23
+ @client = Savon.client(
24
+ wsdl: @security_wsdl,
25
+ endpoint: @endpoint,
26
+ soap_header: headers(:security),
27
+ convert_request_keys_to: :none,
28
+ pretty_print_xml: true
29
+ )
30
+ end
31
+
32
+ def headers(type=:security)
33
+ if type == :security
34
+ category = "Security"
35
+ schema = "https://#{@site_name}.bigmachines.com/bmfsweb/#{@site_name}/schema/v1_0/security/Security.xsd"
36
+ else
37
+ category = "Commerce"
38
+ schema = "https://#{@site_name}.bigmachines.com/bmfsweb/#{@site_name}/schema/v1_0/commerce/#{@process_var_name}.xsd"
39
+ end
40
+
41
+ @headers = ''
42
+ if @session_id
43
+ @headers << %Q{<bm:userInfo xmlns:bm="urn:soap.bigmachines.com">
44
+ <bm:sessionId>#{@session_id}</bm:sessionId>
45
+ </bm:userInfo>}
46
+ end
47
+
48
+ @headers << %Q{
49
+ <bm:category xmlns:bm="urn:soap.bigmachines.com">#{category}</bm:category>
50
+ <bm:xsdInfo xmlns:bm="urn:soap.bigmachines.com">
51
+ <bm:schemaLocation>#{schema}</bm:schemaLocation>
52
+ </bm:xsdInfo>}.gsub(/\n/, '')
53
+
54
+ @headers
55
+ end
56
+
57
+ # Public: Get the names of all wsdl operations.
58
+ # List all available operations from the partner.wsdl
59
+ def operations
60
+ @client.operations
61
+ end
62
+
63
+ # Public: Get the names of all wsdl operations.
64
+ #
65
+ # Supports a username/password (with token) combination or session_id/server_url pair.
66
+ #
67
+ # Examples
68
+ #
69
+ # client.login(username: 'test', password: 'password_and_token')
70
+ # # => {...}
71
+ #
72
+ # client.login(session_id: 'abcd1234', server_url: 'https://na1.salesforce.com/')
73
+ # # => {...}
74
+ #
75
+ # Returns Hash of login response and user info
76
+ def login(options={})
77
+ result = nil
78
+ if options[:username] && options[:password]
79
+ message = {userInfo: {username: options[:username], password: options[:password]}}
80
+ response = self.security_call(:login, message)
81
+
82
+ userInfo = response[:user_info]
83
+
84
+ @session_id = userInfo[:session_id]
85
+ else
86
+ raise ArgumentError.new("Must provide username/password or session_id/server_url.")
87
+ end
88
+
89
+ @security_client = Savon.client(
90
+ wsdl: @security_wsdl,
91
+ endpoint: @endpoint,
92
+ soap_header: headers(:security),
93
+ convert_request_keys_to: :none,
94
+ pretty_print_xml: true
95
+ )
96
+
97
+ # If a session_id/server_url were passed in then invoke get_user_info for confirmation.
98
+ # Method missing to call_soap_api
99
+ result = self.get_user_info if options[:session_id]
100
+
101
+ result
102
+ end
103
+ alias_method :authenticate, :login
104
+
105
+ def set_session_currency(currency)
106
+ security_call(:set_session_currency, sessionCurrency: currency)
107
+ end
108
+
109
+ # Commerce API
110
+ #
111
+ # <bm:getTransaction xmlns:bm="urn:soap.bigmachines.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
112
+ # <bm:transaction>
113
+ # <bm:id/>
114
+ # <bm:return_specific_attributes>
115
+ # <bm:documents>
116
+ # <bm:document>
117
+ # <bm:var_name>quote_process</bm:var_name>
118
+ # <bm:attributes>
119
+ # <bm:attribute>_document_number</bm:attribute>
120
+ # </bm:attributes>
121
+ # </bm:document>
122
+ # </bm:documents>
123
+ # </bm:return_specific_attributes>
124
+ # </bm:transaction>
125
+ # </bm:getTransaction>
126
+ def get_transaction(id)
127
+ transaction = {
128
+ transaction: {
129
+ id: id,
130
+ return_specific_attributes: {
131
+ documents: {
132
+ document: {
133
+ var_name: "quote_process"
134
+ }
135
+ }
136
+ }
137
+ }
138
+ }
139
+
140
+ result = commerce_call(:get_transaction, transaction)
141
+ BigMachines::Transaction.new(result)
142
+ end
143
+
144
+ # <bm:updateTransaction xmlns:bm="urn:soap.bigmachines.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
145
+ # <bm:transaction>
146
+ # <bm:id>26539349</bm:id>
147
+ # <bm:data_xml>
148
+ # <bm:quote_process bm:bs_id="26539349" bm:data_type="0" bm:document_number="1">
149
+ # <bm:opportunityName_quote>Test Oppty Auto Approval TinderBox</bm:opportunityName_quote>
150
+ # <bm:siteName_quote>MY DUMMY SITE</bm:siteName_quote>
151
+ # </bm:quote_process>
152
+ # </bm:data_xml>
153
+ # <bm:action_data>
154
+ # <bm:action_var_name>_update_line_items</bm:action_var_name>
155
+ # </bm:action_data>
156
+ # </bm:transaction>
157
+ # </bm:updateTransaction>
158
+ def update_transaction(id, data={})
159
+ transaction = {
160
+ transaction: {
161
+ id: id,
162
+ data_xml: {
163
+ quote_process: {
164
+ :"@bs_id" => id,
165
+ :"@data_type" => 0,
166
+ :"@document_number" => 1,
167
+ :opportunityName_quote => 'Test Oppty Auto Approval TinderBox 12',
168
+ :siteName_quote => 'My Dummy Site'
169
+ }
170
+ },
171
+ action_data: {
172
+ action_var_name: '_update_line_items'
173
+ }
174
+ }
175
+ }
176
+
177
+ commerce_call(:update_transaction, transaction)
178
+ end
179
+
180
+ # Supports the following No Argument methods:
181
+ # get_user_info
182
+ # logout
183
+ def method_missing(method, *args)
184
+ if [:get_user_info, :logout].include?(method)
185
+ call_soap_api(security_client, method, *args)
186
+ else
187
+ super
188
+ end
189
+ end
190
+
191
+ protected
192
+
193
+ def commerce_client
194
+ @commerce_client ||= client_api(@commerce_wsdl)
195
+ end
196
+
197
+ def security_client
198
+ @security_client ||= client_api(@security_wsdl)
199
+ end
200
+
201
+ def client_api(wsdl)
202
+ category = wsdl.include?('security') ? :security : :commerce
203
+
204
+ client = Savon.client(
205
+ wsdl: wsdl,
206
+ endpoint: @endpoint,
207
+ soap_header: headers(category),
208
+ convert_request_keys_to: :none,
209
+ pretty_print_xml: true
210
+ )
211
+ end
212
+
213
+ def security_call(method, message_hash={})
214
+ call_soap_api(security_client, method, message_hash)
215
+ end
216
+
217
+ def commerce_call(method, message_hash={})
218
+ call_soap_api(commerce_client, method, message_hash)
219
+ end
220
+
221
+ def call_soap_api(client, method, message={})
222
+ response = client.call(method.to_sym, message: message)
223
+ # Convert SOAP XML to Hash
224
+ response = response.to_hash
225
+
226
+ # Get Response Body
227
+ response = response["#{method}_response".to_sym]
228
+
229
+ # Raise error when response contains errors
230
+ if response.is_a?(Hash) && response[:status] && response[:status][:success] == false
231
+ raise Savon::Error.new(response[:status][:message])
232
+ end
233
+
234
+ return response
235
+ end
236
+
237
+ end
238
+ end
@@ -0,0 +1,28 @@
1
+ module BigMachines
2
+ class Transaction
3
+ attr_reader :raw_transaction
4
+
5
+ def initialize(response)
6
+ @raw_transaction = response
7
+ # Metadata
8
+ @transaction = response[:transaction]
9
+ # Quote
10
+ @quote_process = @transaction[:data_xml][:quote_process]
11
+ # Quote Line Items
12
+ @line_process = @quote_process[:sub_documents][:line_process]
13
+ end
14
+
15
+ def method_missing(method, *args)
16
+ @transaction[method]
17
+ end
18
+
19
+ def quote
20
+ @quote_process
21
+ end
22
+
23
+ def quote_line_items
24
+ @line_process
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ module BigMachines
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,9 @@
1
+ require "big_machines/version"
2
+
3
+ require 'savon'
4
+ require "big_machines/client"
5
+ require "big_machines/transaction"
6
+
7
+ module BigMachines
8
+ # Your code goes here...
9
+ end