vng 1.2.0 → 1.3.0
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 +4 -4
- data/CHANGELOG.md +5 -1
- data/README.md +8 -1
- data/lib/vng/availability.rb +1 -0
- data/lib/vng/franchise.rb +1 -1
- data/lib/vng/http_request.rb +95 -0
- data/lib/vng/lock.rb +1 -1
- data/lib/vng/mock_request.rb +130 -0
- data/lib/vng/resource.rb +14 -32
- data/lib/vng/security_token.rb +3 -2
- data/lib/vng/version.rb +1 -1
- data/lib/vng.rb +4 -5
- metadata +4 -3
- data/lib/vng/mock_resource.rb +0 -107
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d55841e2ab8e3e620c5bd29d8c994cbbb441a327ab3006ee262c3c44f207fda1
|
4
|
+
data.tar.gz: d4fb1cd2865d72faa464711cd03d61974a991d53e766310523ee5adc0353ba1e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f118bbfc089a69e924fdcc0948de07dbb20217d4b5556a0e80abea896734f545199f27afdf1edf7c6d1c3ffec2ee9a6a04497a7629527e1623c44ba5ea75e894
|
7
|
+
data.tar.gz: fce28eb9405e05bc3620e67a53942ae901ec0f655dca7e640755ac231c975b262329596ec5dbd6a5e0dfa6180ebd5b2edc9d95503b3e8f09db0f670c97618920
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -84,7 +84,14 @@ To run tests:
|
|
84
84
|
rspec
|
85
85
|
```
|
86
86
|
|
87
|
-
|
87
|
+
By default, tests are run with real HTTP calls to Vonigo that must be
|
88
|
+
set with the environment variables specified above.
|
89
|
+
|
90
|
+
If you do not have access to Vonigo, you can still run the tests mocked:
|
91
|
+
|
92
|
+
```bash
|
93
|
+
VNG_MOCK=1 rspec
|
94
|
+
```
|
88
95
|
|
89
96
|
How to release new versions
|
90
97
|
===========================
|
data/lib/vng/availability.rb
CHANGED
data/lib/vng/franchise.rb
CHANGED
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
require 'vng/connection_error'
|
5
|
+
require 'vng/error'
|
6
|
+
|
7
|
+
module Vng
|
8
|
+
# A wrapper around +Net::HTTP+ to send HTTP requests to the Vonigo API and
|
9
|
+
# return their result or raise an error if the result is unexpected.
|
10
|
+
# The basic way to use HTTPRequest is by calling +run+ on an instance.
|
11
|
+
# @example List the species of all breeds.
|
12
|
+
# host = ''subdomain.vonigo.com'
|
13
|
+
# path = '/api/v1/resources/breeds/'
|
14
|
+
# body = {securityToken: security_token}
|
15
|
+
# response = Vng::HTTPRequest.new(path: path, body: body).run
|
16
|
+
# response['Breeds'].map{|breed| breed['species']}
|
17
|
+
# @api private
|
18
|
+
class Request
|
19
|
+
# Initializes an HTTPRequest object.
|
20
|
+
# @param [Hash] options the options for the request.
|
21
|
+
# @option options [String] :host The host of the request URI.
|
22
|
+
# @option options [String] :path The path of the request URI.
|
23
|
+
# @option options [Hash] :query ({}) The params to use as the query
|
24
|
+
# component of the request URI, for instance the Hash +{a: 1, b: 2}+
|
25
|
+
# corresponds to the query parameters +"a=1&b=2"+.
|
26
|
+
# @option options [Hash] :body The body of the request.
|
27
|
+
def initialize(options = {})
|
28
|
+
@host = options[:host]
|
29
|
+
@path = options[:path]
|
30
|
+
@body = options[:body]
|
31
|
+
@query = options.fetch :query, {}
|
32
|
+
end
|
33
|
+
|
34
|
+
# Sends the request and returns the body parsed from the JSON response.
|
35
|
+
# @return [Hash] the body parsed from the JSON response.
|
36
|
+
# @raise [Vng::ConnectionError] if the request fails.
|
37
|
+
# @raise [Vng::Error] if parsed body includes errors.
|
38
|
+
def run
|
39
|
+
return {} if response.body.empty?
|
40
|
+
JSON(response.body).tap do |data|
|
41
|
+
raise Error, "#{data['errMsg']} #{data['Errors']}" unless data['errNo'].zero?
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
# Run the request and memoize the response or the server error received.
|
48
|
+
def response
|
49
|
+
@response ||= Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
|
50
|
+
http.request http_request
|
51
|
+
end
|
52
|
+
rescue *server_errors => e
|
53
|
+
raise ConnectionError, e.message
|
54
|
+
end
|
55
|
+
|
56
|
+
# @return [URI::HTTPS] the (memoized) URI of the request.
|
57
|
+
def uri
|
58
|
+
attributes = { host: @host, path: @path, query: URI.encode_www_form(@query) }
|
59
|
+
@uri ||= URI::HTTPS.build attributes
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return [Net::HTTPRequest] the full HTTP request object,
|
63
|
+
# inclusive of headers of request body.
|
64
|
+
def http_request
|
65
|
+
http_class = @query.any? ? Net::HTTP::Get : Net::HTTP::Post
|
66
|
+
|
67
|
+
@http_request ||= http_class.new(uri.request_uri).tap do |request|
|
68
|
+
set_request_body! request
|
69
|
+
set_request_headers! request
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Adds the request headers to the request in the appropriate format.
|
74
|
+
# The User-Agent header is also set to recognize the request.
|
75
|
+
def set_request_headers!(request)
|
76
|
+
request.initialize_http_header 'Content-Type' => 'application/json'
|
77
|
+
request.add_field 'User-Agent', 'Vng::HTTPRequest'
|
78
|
+
end
|
79
|
+
|
80
|
+
# Adds the request body to the request in the appropriate format.
|
81
|
+
def set_request_body!(request)
|
82
|
+
request.body = @body.to_json if @body
|
83
|
+
end
|
84
|
+
|
85
|
+
# Returns the list of server errors worth retrying the request once.
|
86
|
+
def server_errors
|
87
|
+
[
|
88
|
+
Errno::ECONNRESET, Errno::EHOSTUNREACH, Errno::ENETUNREACH,
|
89
|
+
Errno::ETIMEDOUT, Errno::ECONNREFUSED, Net::HTTPServerError,
|
90
|
+
OpenSSL::SSL::SSLError, OpenSSL::SSL::SSLErrorWaitReadable,
|
91
|
+
Net::OpenTimeout, SocketError,
|
92
|
+
]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/lib/vng/lock.rb
CHANGED
@@ -0,0 +1,130 @@
|
|
1
|
+
module Vng
|
2
|
+
# A mock version of HTTPRequest which returns pre-built responses.
|
3
|
+
# @example List the species of all breeds.
|
4
|
+
# host = ''subdomain.vonigo.com'
|
5
|
+
# path = '/api/v1/resources/breeds/'
|
6
|
+
# body = {securityToken: security_token}
|
7
|
+
# response = Vng::Request.new(path: path, body: body).run
|
8
|
+
# response['Breeds'].map{|breed| breed['species']}
|
9
|
+
# @api private
|
10
|
+
class Request
|
11
|
+
# Initializes an MockRequest object.
|
12
|
+
# @param [Hash] options the options for the request.
|
13
|
+
# @option options [String] :host The host of the request URI.
|
14
|
+
# @option options [String] :path The path of the request URI.
|
15
|
+
# @option options [Hash] :query ({}) The params to use as the query
|
16
|
+
# component of the request URI, for instance the Hash +{a: 1, b: 2}+
|
17
|
+
# corresponds to the query parameters +"a=1&b=2"+.
|
18
|
+
# @option options [Hash] :body The body of the request.
|
19
|
+
def initialize(options = {})
|
20
|
+
@host = options[:host]
|
21
|
+
@path = options[:path]
|
22
|
+
@body = options[:body]
|
23
|
+
@query = options.fetch :query, {}
|
24
|
+
end
|
25
|
+
|
26
|
+
ROUTE_ID = 1630
|
27
|
+
@@logged_out = false
|
28
|
+
|
29
|
+
# Sends the request and returns the body parsed from the JSON response.
|
30
|
+
# @return [Hash] the body parsed from the JSON response.
|
31
|
+
# @raise [Vng::ConnectionError] if the request fails.
|
32
|
+
# @raise [Vng::Error] if parsed body includes errors.
|
33
|
+
def run
|
34
|
+
case @path
|
35
|
+
when '/api/v1/security/session/'
|
36
|
+
raise Error.new 'Same franchise ID supplied.'
|
37
|
+
when '/api/v1/security/login/'
|
38
|
+
if @host == 'invalid-host'
|
39
|
+
raise ConnectionError.new 'Failed to open connection'
|
40
|
+
else
|
41
|
+
{ "securityToken"=>"1234567" }
|
42
|
+
end
|
43
|
+
when '/api/v1/security/logout/'
|
44
|
+
if @@logged_out
|
45
|
+
raise Error.new 'Session expired. '
|
46
|
+
else
|
47
|
+
@@logged_out = true
|
48
|
+
{}
|
49
|
+
end
|
50
|
+
when '/api/v1/resources/zips/'
|
51
|
+
{ "Zips"=>[{ "zip"=>"21765", "zoneName"=>"Brentwood", "state"=>"MD" }] }
|
52
|
+
when '/api/v1/resources/franchises/'
|
53
|
+
if @body.key?(:objectID)
|
54
|
+
{ "Franchise"=>{ "objectID"=>"2201007" }, "Fields"=>[
|
55
|
+
{ "fieldID"=>9, "fieldValue"=>"vng@example.com" },
|
56
|
+
] }
|
57
|
+
else
|
58
|
+
{ "Franchises"=>[
|
59
|
+
{ "franchiseID"=>106, "franchiseName"=>"Mississauga", "gmtOffsetFranchise"=>-300, "isActive"=>false },
|
60
|
+
{ "franchiseID"=>107, "franchiseName"=>"Boise", "gmtOffsetFranchise"=>-420, "isActive"=>true },
|
61
|
+
] }
|
62
|
+
end
|
63
|
+
when '/api/v1/resources/availability/'
|
64
|
+
if @body.key?(:zip)
|
65
|
+
{ "Ids"=>{ "franchiseID"=>"172" } }
|
66
|
+
elsif @body[:method] == '2'
|
67
|
+
{ "Ids"=>{ "lockID"=>"1406328" } }
|
68
|
+
else
|
69
|
+
{ "Availability"=> [
|
70
|
+
{ "dayID"=>"20281119", "routeID"=>"#{ROUTE_ID}", "startTime"=>"1080" },
|
71
|
+
{ "dayID"=>"20281119", "routeID"=>"#{ROUTE_ID}", "startTime"=>"1110" },
|
72
|
+
] }
|
73
|
+
end
|
74
|
+
when '/api/v1/resources/breeds/'
|
75
|
+
{ "Breeds"=>[{ "breedID"=>2, "breed"=>"Bulldog", "species"=>"Dog", "optionID"=>303, "breedLowWeight"=>30, "breedHighWeight"=>50 }] }
|
76
|
+
when '/api/v1/data/Leads/'
|
77
|
+
{ "Client"=>{ "objectID"=>"916347" }, "Fields"=> [
|
78
|
+
{ "fieldID"=>126, "fieldValue"=>"Vng Example" },
|
79
|
+
{ "fieldID"=>238, "fieldValue"=>"vng@example.com" },
|
80
|
+
{ "fieldID"=>1024, "fieldValue"=>"8648648640" },
|
81
|
+
] }
|
82
|
+
when '/api/v1/data/Contacts/'
|
83
|
+
{ "Contact"=>{ "objectID"=>"2201007" }, "Fields"=>[
|
84
|
+
{ "fieldID"=>127, "fieldValue"=>"Vng" },
|
85
|
+
{ "fieldID"=>128, "fieldValue"=>"Example" },
|
86
|
+
{ "fieldID"=>97, "fieldValue"=>"vng@example.com" },
|
87
|
+
{ "fieldID"=>96, "fieldValue"=>"8648648640" },
|
88
|
+
] }
|
89
|
+
when '/api/v1/data/Locations/'
|
90
|
+
{ "Location"=>{ "objectID"=>"995681" } }
|
91
|
+
when '/api/v1/data/Assets/'
|
92
|
+
if @body[:method].eql? '3'
|
93
|
+
{ "Asset"=>{ "objectID"=>"2201008" } }
|
94
|
+
elsif @body[:method].eql? '4'
|
95
|
+
{}
|
96
|
+
end
|
97
|
+
when '/api/v1/data/priceLists/'
|
98
|
+
{ "PriceItems"=>[
|
99
|
+
{ "priceItemID"=>275111, "priceItem"=>"15 Step SPA Grooming", "value"=>85.0, "taxID"=>256, "durationPerUnit"=>45.0, "serviceBadge"=>"Required", "serviceCategory"=>"15 Step Spa", "isOnline"=>true, "isActive"=>true },
|
100
|
+
{ "priceItemID"=>275300, "priceItem"=>"De-Matting - Light", "value"=>10.0, "taxID"=>256, "durationPerUnit"=>15.0, "serviceBadge"=>nil, "serviceCategory"=>"De-Shed", "isOnline"=>true, "isActive"=>true },
|
101
|
+
{ "priceItemID"=>275301, "priceItem"=>"De-Shedding Treatment", "value"=>20.0, "taxID"=>256, "durationPerUnit"=>15.0, "serviceBadge"=>nil, "serviceCategory"=>"De-Shed", "isOnline"=>true, "isActive"=>false },
|
102
|
+
] }
|
103
|
+
when '/api/v1/resources/serviceTypes/'
|
104
|
+
if @body.key?(:zip)
|
105
|
+
{"ServiceTypes" => [
|
106
|
+
{"serviceTypeID" => 14, "serviceType" => "Pet Grooming (name)", "duration" => 45,"isActive" => true},
|
107
|
+
{"serviceTypeID" => 16, "serviceType" => "Pet Grooming (name)", "duration" => 45,"isActive" => false},
|
108
|
+
]}
|
109
|
+
else
|
110
|
+
{ "ServiceTypes"=>[
|
111
|
+
{ "serviceTypeID"=>14, "serviceType"=>"Pet Grooming", "duration"=>90, "isActive"=>true },
|
112
|
+
] }
|
113
|
+
end
|
114
|
+
when '/api/v1/resources/Routes/'
|
115
|
+
{"Routes" => [
|
116
|
+
{"routeID" => ROUTE_ID, "routeName" => "Route 1", "isActive" => true},
|
117
|
+
{"routeID" => 2, "routeName" => "Inactive", "isActive" => false},
|
118
|
+
]}
|
119
|
+
when '/api/v1/data/WorkOrders/'
|
120
|
+
{ "WorkOrder"=>{ "objectID"=>"4138030" } }
|
121
|
+
when '/api/v1/data/Cases/'
|
122
|
+
if @body[:method].eql? '3'
|
123
|
+
{"Case" => {"objectID" => "28503"}}
|
124
|
+
elsif @body[:method].eql? '4'
|
125
|
+
{}
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
data/lib/vng/resource.rb
CHANGED
@@ -1,42 +1,18 @@
|
|
1
|
-
require 'vng/
|
2
|
-
require 'vng/error'
|
1
|
+
require ENV['VNG_MOCK'] ? 'vng/mock_request' : 'vng/http_request'
|
3
2
|
|
4
3
|
module Vng
|
5
4
|
# Provides an abstract class for every Vonigo resource.
|
6
5
|
class Resource
|
7
6
|
private
|
8
|
-
def self.request(path:, body: {}, query: {}, include_security_token: true)
|
9
|
-
uri = URI::HTTPS.build host: host, path: path
|
10
|
-
uri.query = URI.encode_www_form(query) if query.any?
|
11
|
-
|
12
|
-
method = query.any? ? Net::HTTP::Get : Net::HTTP::Post
|
13
|
-
request = method.new uri.request_uri
|
14
|
-
request.initialize_http_header 'Content-Type' => 'application/json'
|
15
|
-
|
16
|
-
if query.none?
|
17
|
-
body = body.merge(securityToken: security_token) if include_security_token
|
18
|
-
request.body = body.to_json
|
19
|
-
end
|
20
7
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
8
|
+
def self.request(path:, body: {}, query: {}, include_security_token: true)
|
9
|
+
if query.none? && include_security_token
|
10
|
+
body = body.merge securityToken: Vng.configuration.security_token
|
25
11
|
end
|
26
12
|
|
27
|
-
|
28
|
-
|
13
|
+
instrument do |data|
|
14
|
+
Request.new(host: host, path: path, query: query, body: body).run
|
29
15
|
end
|
30
|
-
rescue Errno::ECONNREFUSED, SocketError => e
|
31
|
-
raise Vng::ConnectionError, e.message
|
32
|
-
end
|
33
|
-
|
34
|
-
def self.host
|
35
|
-
Vng.configuration.host
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.security_token
|
39
|
-
Vng.configuration.security_token
|
40
16
|
end
|
41
17
|
|
42
18
|
def self.value_for_field(data, field_id)
|
@@ -44,12 +20,18 @@ module Vng
|
|
44
20
|
field['fieldValue'] if field
|
45
21
|
end
|
46
22
|
|
23
|
+
# @return [String] the Vonigo API host.
|
24
|
+
def self.host
|
25
|
+
Vng.configuration.host
|
26
|
+
end
|
27
|
+
|
28
|
+
# Provides instrumentation to ActiveSupport listeners
|
47
29
|
def self.instrument(&block)
|
48
|
-
data = {class_name: name}
|
30
|
+
data = { class_name: name }
|
49
31
|
if defined?(ActiveSupport::Notifications)
|
50
32
|
ActiveSupport::Notifications.instrument 'Vng.request', data, &block
|
51
33
|
else
|
52
|
-
block.call
|
34
|
+
block.call data
|
53
35
|
end
|
54
36
|
end
|
55
37
|
end
|
data/lib/vng/security_token.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'digest/md5'
|
1
2
|
require 'vng/resource'
|
2
3
|
|
3
4
|
module Vng
|
@@ -32,14 +33,14 @@ module Vng
|
|
32
33
|
}
|
33
34
|
|
34
35
|
self.class.request path: '/api/v1/security/session/', body: body, include_security_token: false
|
35
|
-
rescue
|
36
|
+
rescue Error => e
|
36
37
|
raise unless e.message.include? 'Same franchise ID supplied'
|
37
38
|
end
|
38
39
|
|
39
40
|
def destroy
|
40
41
|
query = { securityToken: @token }
|
41
42
|
self.class.request path: '/api/v1/security/logout/', query: query
|
42
|
-
rescue
|
43
|
+
rescue Error => e
|
43
44
|
raise unless e.message.include?('Session expired') || e.message.include?('Session does not exist')
|
44
45
|
end
|
45
46
|
end
|
data/lib/vng/version.rb
CHANGED
data/lib/vng.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
|
-
|
2
|
-
require 'digest/md5'
|
3
|
-
require 'json'
|
4
|
-
require 'net/http'
|
1
|
+
# Used by multiple resources
|
5
2
|
require 'uri'
|
3
|
+
require_relative 'vng/error'
|
4
|
+
require_relative 'vng/config'
|
6
5
|
|
6
|
+
# Individual resources
|
7
7
|
require_relative 'vng/asset'
|
8
8
|
require_relative 'vng/availability'
|
9
9
|
require_relative 'vng/breed'
|
10
10
|
require_relative 'vng/case'
|
11
|
-
require_relative 'vng/config'
|
12
11
|
require_relative 'vng/connection_error'
|
13
12
|
require_relative 'vng/contact'
|
14
13
|
require_relative 'vng/franchise'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vng
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- claudiob
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11-
|
11
|
+
date: 2024-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: simplecov
|
@@ -76,10 +76,11 @@ files:
|
|
76
76
|
- lib/vng/contact.rb
|
77
77
|
- lib/vng/error.rb
|
78
78
|
- lib/vng/franchise.rb
|
79
|
+
- lib/vng/http_request.rb
|
79
80
|
- lib/vng/lead.rb
|
80
81
|
- lib/vng/location.rb
|
81
82
|
- lib/vng/lock.rb
|
82
|
-
- lib/vng/
|
83
|
+
- lib/vng/mock_request.rb
|
83
84
|
- lib/vng/price_item.rb
|
84
85
|
- lib/vng/resource.rb
|
85
86
|
- lib/vng/route.rb
|
data/lib/vng/mock_resource.rb
DELETED
@@ -1,107 +0,0 @@
|
|
1
|
-
require 'vng/connection_error'
|
2
|
-
require 'vng/error'
|
3
|
-
|
4
|
-
module Vng
|
5
|
-
# Provides an abstract class for every Vonigo resource.
|
6
|
-
class Resource
|
7
|
-
private
|
8
|
-
def self.request(path:, body: {}, query: {}, include_security_token: true)
|
9
|
-
if Vng.configuration.mock
|
10
|
-
mock_request(path:, body:, query:)
|
11
|
-
else
|
12
|
-
http_request(path:, body:, query:, include_security_token:)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.mock_request(path:, body:, query:)
|
17
|
-
case path
|
18
|
-
when '/api/v1/security/login/'
|
19
|
-
{ "securityToken"=>"1234567" }
|
20
|
-
when '/api/v1/resources/zips/'
|
21
|
-
{ "Zips"=>[{ "zip"=>"21765", "zoneName"=>"Brentwood", "state"=>"MD" }] }
|
22
|
-
when '/api/v1/resources/franchises/'
|
23
|
-
{ "Franchises"=>[
|
24
|
-
{ "franchiseID"=>106, "franchiseName"=>"Mississauga", "gmtOffsetFranchise"=>-300, "isActive"=>false },
|
25
|
-
{ "franchiseID"=>107, "franchiseName"=>"Boise", "gmtOffsetFranchise"=>-420, "isActive"=>true },
|
26
|
-
] }
|
27
|
-
when '/api/v1/resources/availability/'
|
28
|
-
if body.key?(:zip)
|
29
|
-
{ "Ids"=>{ "franchiseID"=>"172" } }
|
30
|
-
elsif body[:method] == '2'
|
31
|
-
{ "Ids"=>{ "lockID"=>"1406328" } }
|
32
|
-
else
|
33
|
-
{ "Availability"=> [
|
34
|
-
{ "dayID"=>"20241119", "routeID"=>"8949", "startTime"=>"1080" },
|
35
|
-
{ "dayID"=>"20241119", "routeID"=>"8949", "startTime"=>"1110" },
|
36
|
-
] }
|
37
|
-
end
|
38
|
-
when '/api/v1/resources/breeds/'
|
39
|
-
{ "Breeds"=>[{ "breedID"=>2, "breed"=>"Bulldog", "species"=>"Dog", "optionID"=>303, "breedLowWeight"=>30, "breedHighWeight"=>50 }] }
|
40
|
-
when '/api/v1/data/Leads/'
|
41
|
-
{ "Client"=>{ "objectID"=>"916347" }, "Fields"=> [
|
42
|
-
{ "fieldID"=>126, "fieldValue"=>"Vng Example" },
|
43
|
-
{ "fieldID"=>238, "fieldValue"=>"vng@example.com" },
|
44
|
-
{ "fieldID"=>1024, "fieldValue"=>"8648648640" },
|
45
|
-
] }
|
46
|
-
when '/api/v1/data/Contacts/'
|
47
|
-
{ "Contact"=>{ "objectID"=>"2201007" }, "Fields"=>[
|
48
|
-
{ "fieldID"=>127, "fieldValue"=>"Vng" },
|
49
|
-
{ "fieldID"=>128, "fieldValue"=>"Example" },
|
50
|
-
{ "fieldID"=>97, "fieldValue"=>"vng@example.com" },
|
51
|
-
{ "fieldID"=>96, "fieldValue"=>"8648648640" },
|
52
|
-
] }
|
53
|
-
when '/api/v1/data/Locations/'
|
54
|
-
{ "Location"=>{ "objectID"=>"995681" } }
|
55
|
-
when '/api/v1/data/Assets/'
|
56
|
-
{ "Asset"=>{ "objectID"=>"2201008" } }
|
57
|
-
when '/api/v1/data/priceLists/'
|
58
|
-
{ "PriceItems"=>[
|
59
|
-
{ "priceItemID"=>275111, "priceItem"=>"15 Step SPA Grooming", "value"=>85.0, "taxID"=>256, "durationPerUnit"=>45.0, "serviceBadge"=>"Required", "serviceCategory"=>"15 Step Spa", "isOnline"=>true, "isActive"=>true },
|
60
|
-
{ "priceItemID"=>275300, "priceItem"=>"De-Shedding Treatment", "value"=>20.0, "taxID"=>256, "durationPerUnit"=>15.0, "serviceBadge"=>nil, "serviceCategory"=>"De-Shed", "isOnline"=>true, "isActive"=>false },
|
61
|
-
] }
|
62
|
-
when '/api/v1/resources/serviceTypes/'
|
63
|
-
{ "ServiceTypes"=>[
|
64
|
-
{ "serviceTypeID"=>14, "serviceType"=>"Pet Grooming", "duration"=>90, "isActive"=>true },
|
65
|
-
] }
|
66
|
-
when '/api/v1/data/WorkOrders/'
|
67
|
-
{ "WorkOrder"=>{ "objectID"=>"4138030" } }
|
68
|
-
when '/api/v1/data/Cases/'
|
69
|
-
{ "Case"=>{ "objectID"=>"28460" } }
|
70
|
-
else
|
71
|
-
{}
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def self.http_request(path:, body:, query:, include_security_token: true)
|
76
|
-
uri = URI::HTTPS.build host: host, path: path
|
77
|
-
uri.query = URI.encode_www_form(query) if query.any?
|
78
|
-
|
79
|
-
method = query.any? ? Net::HTTP::Get : Net::HTTP::Post
|
80
|
-
request = method.new uri.request_uri
|
81
|
-
request.initialize_http_header 'Content-Type' => 'application/json'
|
82
|
-
|
83
|
-
if query.none?
|
84
|
-
body = body.merge(securityToken: security_token) if include_security_token
|
85
|
-
request.body = body.to_json
|
86
|
-
end
|
87
|
-
|
88
|
-
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
|
89
|
-
http.request request
|
90
|
-
end
|
91
|
-
|
92
|
-
JSON(response.body).tap do |data|
|
93
|
-
raise Vng::Error, "#{data['errMsg']} #{data['Errors']}" unless data['errNo'].zero?
|
94
|
-
end
|
95
|
-
rescue Errno::ECONNREFUSED, SocketError => e
|
96
|
-
raise Vng::ConnectionError, e.message
|
97
|
-
end
|
98
|
-
|
99
|
-
def self.host
|
100
|
-
Vng.configuration.host
|
101
|
-
end
|
102
|
-
|
103
|
-
def self.security_token
|
104
|
-
Vng.configuration.security_token
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|