vng 0.1.18 → 0.1.20
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 +8 -0
- data/README.md +2 -0
- data/lib/vng/configuration.rb +4 -0
- data/lib/vng/contact.rb +0 -10
- data/lib/vng/franchise.rb +16 -2
- data/lib/vng/lead.rb +0 -11
- data/lib/vng/location.rb +0 -10
- data/lib/vng/mock_resource.rb +107 -0
- data/lib/vng/route.rb +29 -0
- data/lib/vng/version.rb +1 -1
- data/lib/vng/work_order.rb +0 -10
- data/lib/vng.rb +1 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b49dda09b2542875760b7b2cdd3c4ab50d548458400e7dda9586edafd5c18b2
|
4
|
+
data.tar.gz: 0e86208199aebd2f79914bfd5e6c5ec330682bcebbe4d154bd808bb3bb4a64f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 751d1a4eb1774f508106113b6cdc21988b6515ae8d965be322b205670b716214668ae72c67828e2a05fcb127a6c525fa741704c72244e8d9c52ad5e33fc55e43
|
7
|
+
data.tar.gz: 552dcc79f28b148d54559849f04052b5348e552c7fbecc2dbba81dc46a07744db9b83b90b4ff740e48893b1aedede0e3db31d05fcccb043bf6620a3c8af276ee
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
data/lib/vng/configuration.rb
CHANGED
@@ -40,12 +40,16 @@ module Vng
|
|
40
40
|
# @return [String] the password for the API calls.
|
41
41
|
attr_accessor :password
|
42
42
|
|
43
|
+
# @return [Boolean] whether to mock the HTTP calls to Vonigo
|
44
|
+
attr_accessor :mock
|
45
|
+
|
43
46
|
# Initialize the global configuration settings, using the values of
|
44
47
|
# the specified following environment variables by default.
|
45
48
|
def initialize
|
46
49
|
@host = ENV['VNG_HOST']
|
47
50
|
@username = ENV['VNG_USERNAME']
|
48
51
|
@password = ENV['VNG_PASSWORD']
|
52
|
+
@mock = ENV['VNG_MOCK'] == '1'
|
49
53
|
end
|
50
54
|
end
|
51
55
|
end
|
data/lib/vng/contact.rb
CHANGED
@@ -37,16 +37,6 @@ module Vng
|
|
37
37
|
|
38
38
|
new id: id, first_name: first_name, last_name: last_name, email: email, phone: phone
|
39
39
|
end
|
40
|
-
|
41
|
-
# Data validation failed. [{"fieldID"=>0, "fieldName"=>nil, "errNo"=>-1408, "errMsg"=>"Primary contact cannot be deleted."}]
|
42
|
-
# def destroy
|
43
|
-
# body = {
|
44
|
-
# method: '4',
|
45
|
-
# objectID: id,
|
46
|
-
# }
|
47
|
-
#
|
48
|
-
# self.class.request path: PATH, body: body
|
49
|
-
# end
|
50
40
|
end
|
51
41
|
end
|
52
42
|
|
data/lib/vng/franchise.rb
CHANGED
@@ -5,12 +5,13 @@ module Vng
|
|
5
5
|
class Franchise < Resource
|
6
6
|
PATH = '/api/v1/resources/franchises/'
|
7
7
|
|
8
|
-
attr_reader :id, :name, :gmt_offset
|
8
|
+
attr_reader :id, :name, :gmt_offset, :email
|
9
9
|
|
10
|
-
def initialize(id:, name: nil, gmt_offset: nil)
|
10
|
+
def initialize(id:, name: nil, gmt_offset: nil, email: nil)
|
11
11
|
@id = id
|
12
12
|
@name = name
|
13
13
|
@gmt_offset = gmt_offset
|
14
|
+
@email = email
|
14
15
|
end
|
15
16
|
|
16
17
|
|
@@ -26,6 +27,19 @@ module Vng
|
|
26
27
|
new(id: franchise_id) unless franchise_id == '0'
|
27
28
|
end
|
28
29
|
|
30
|
+
def self.find(franchise_id)
|
31
|
+
body = {
|
32
|
+
method: '1',
|
33
|
+
objectID: franchise_id,
|
34
|
+
}
|
35
|
+
|
36
|
+
data = request path: PATH, body: body
|
37
|
+
|
38
|
+
email_field = data['Fields'].find{|field| field['fieldID'] == 9}
|
39
|
+
email = email_field['fieldValue'] if email_field
|
40
|
+
new id: franchise_id, email: email
|
41
|
+
end
|
42
|
+
|
29
43
|
def self.all
|
30
44
|
data = request path: PATH
|
31
45
|
|
data/lib/vng/lead.rb
CHANGED
@@ -34,16 +34,5 @@ module Vng
|
|
34
34
|
|
35
35
|
new id: id, name: name, email: email, phone: phone
|
36
36
|
end
|
37
|
-
|
38
|
-
# Data validation failed. [{"fieldID"=>0, "fieldName"=>nil, "errNo"=>-1201, "errMsg"=>"Lead ID does not exist."}]
|
39
|
-
# TODO: has become an account meanwhile!! so this doesn't work
|
40
|
-
# def destroy
|
41
|
-
# body = {
|
42
|
-
# method: '4',
|
43
|
-
# objectID: id,
|
44
|
-
# }
|
45
|
-
#
|
46
|
-
# self.class.request path: PATH, body: body
|
47
|
-
# end
|
48
37
|
end
|
49
38
|
end
|
data/lib/vng/location.rb
CHANGED
@@ -40,16 +40,6 @@ module Vng
|
|
40
40
|
|
41
41
|
new id: data['Location']['objectID']
|
42
42
|
end
|
43
|
-
|
44
|
-
# Data validation failed. [{"fieldID"=>0, "fieldName"=>"", "errNo"=>-1809, "errMsg"=>"Primary location cannot be deleted."}]
|
45
|
-
# def destroy
|
46
|
-
# body = {
|
47
|
-
# method: '4',
|
48
|
-
# objectID: id,
|
49
|
-
# }
|
50
|
-
#
|
51
|
-
# self.class.request path: PATH, body: body
|
52
|
-
# end
|
53
43
|
end
|
54
44
|
end
|
55
45
|
|
@@ -0,0 +1,107 @@
|
|
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
|
data/lib/vng/route.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'vng/resource'
|
2
|
+
|
3
|
+
module Vng
|
4
|
+
# Provides methods to interact with Vonigo ZIP routes.
|
5
|
+
class Route < Resource
|
6
|
+
PATH = '/api/v1/resources/Routes/'
|
7
|
+
|
8
|
+
attr_reader :id, :name
|
9
|
+
|
10
|
+
def initialize(id:, name:)
|
11
|
+
@id = id
|
12
|
+
@name = name
|
13
|
+
end
|
14
|
+
|
15
|
+
# TODO: Needs pagination
|
16
|
+
def self.all
|
17
|
+
data = request path: PATH
|
18
|
+
|
19
|
+
data['Routes'].filter do |route|
|
20
|
+
route['isActive']
|
21
|
+
end.map do |body|
|
22
|
+
id = body['routeID']
|
23
|
+
name = body['routeName']
|
24
|
+
|
25
|
+
new id: id, name: name
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/vng/version.rb
CHANGED
data/lib/vng/work_order.rb
CHANGED
@@ -32,16 +32,6 @@ module Vng
|
|
32
32
|
new id: data['WorkOrder']['objectID']
|
33
33
|
end
|
34
34
|
|
35
|
-
# TODO: This moves to "archived". actual cancelation is different
|
36
|
-
# def destroy
|
37
|
-
# body = {
|
38
|
-
# method: '8',
|
39
|
-
# objectID: id,
|
40
|
-
# }
|
41
|
-
#
|
42
|
-
# data = self.class.request path: PATH, body: body
|
43
|
-
# end
|
44
|
-
|
45
35
|
private
|
46
36
|
|
47
37
|
def self.charges_for(line_items)
|
data/lib/vng.rb
CHANGED
@@ -16,6 +16,7 @@ require_relative 'vng/lead'
|
|
16
16
|
require_relative 'vng/location'
|
17
17
|
require_relative 'vng/lock'
|
18
18
|
require_relative 'vng/price_item'
|
19
|
+
require_relative 'vng/route'
|
19
20
|
require_relative 'vng/security_token'
|
20
21
|
require_relative 'vng/service_type'
|
21
22
|
require_relative 'vng/version'
|
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: 0.1.
|
4
|
+
version: 0.1.20
|
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-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: simplecov
|
@@ -50,8 +50,10 @@ files:
|
|
50
50
|
- lib/vng/lead.rb
|
51
51
|
- lib/vng/location.rb
|
52
52
|
- lib/vng/lock.rb
|
53
|
+
- lib/vng/mock_resource.rb
|
53
54
|
- lib/vng/price_item.rb
|
54
55
|
- lib/vng/resource.rb
|
56
|
+
- lib/vng/route.rb
|
55
57
|
- lib/vng/security_token.rb
|
56
58
|
- lib/vng/service_type.rb
|
57
59
|
- lib/vng/version.rb
|