vng 0.1.13 → 0.1.14

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3cff4f73336138d9e2386b1273fd4e398c8d3e8e9c52fb60ba4f47fb7b98e3bf
4
- data.tar.gz: 6dbfa0fdad71e5fe35b113071e451a27e0150cde5ccffc7bc0676f191d433486
3
+ metadata.gz: de1ec03096db648933db7f9886eaa72b6c4af73e614e475bc0ad26126f35015e
4
+ data.tar.gz: 0adb9f129d030b78ec726f6a2a1cedd61ebc37c88a88df524aca23ff4d2583ca
5
5
  SHA512:
6
- metadata.gz: d76586e4271dc06bfe12ab3784f9534373f82e1953084c012ca79522ffbad4744486f55f66076b735bcafe7bddddc1465ef624f2af001aa0c183106a4403f0c4
7
- data.tar.gz: 5bb9df92265cf90e2e10a88efc2e5cbd4de6d0b4e80e38dc2faf597780ea9b759e951fe331ae453db38253df4c93a58bd04d8a6c299318f475a5c04f6b5d08c1
6
+ metadata.gz: ce83ddaea6c34121333fdaf15b5600b2486e51c2803b82a71826ca464b7c18f79f1c5d39e0837a0483ecda73512abae325fda7aea0b6ec7b4f8fac3ebcc201c4
7
+ data.tar.gz: 7efd6a2bc16eae79b5ecde44d85ec4ce4de4366a9c735bebc99350d1c743ccc4a6320d47a834e84a92205524761222d07e43a02b06878ff413ca5ff8219e7962
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.14] - 2024-11-17
4
+
5
+ - Adds Vng::Error
6
+
3
7
  ## [0.1.13] - 2024-11-15
4
8
 
5
9
  - Enable Vng.configuration.security_token
data/README.md CHANGED
@@ -5,8 +5,11 @@ Vng helps you write apps that need to interact with Vonigo.
5
5
 
6
6
  The **source code** is available on [GitHub](https://github.com/HouseAccountEng/vng) and the **documentation** on [RubyDoc](http://www.rubydoc.info/gems/vng/frames).
7
7
 
8
+ [![Code Climate](https://codeclimate.com/github/HouseAccountEng/vng.png)](https://codeclimate.com/github/HouseAccountEng/vng)
9
+
8
10
  After [registering your app](#configuring-your-app), you can run commands like:
9
11
 
12
+
10
13
  ```ruby
11
14
  Vng::Zip.all
12
15
  Vng::Franchise.all
@@ -42,15 +45,6 @@ indicating the full version in your Gemfile (~> *major*.*minor*.*patch*)
42
45
  guarantees that your project won’t occur in any error when you `bundle update`
43
46
  and a new version of Vng is released.
44
47
 
45
- Available resources
46
- ===================
47
-
48
- Vng::Zip
49
- -------
50
-
51
- TODO
52
-
53
-
54
48
  Configuring your app
55
49
  ====================
56
50
 
@@ -95,8 +89,8 @@ How to release new versions
95
89
 
96
90
  If you are a manager of this project, remember to upgrade the [Vng gem](http://rubygems.org/gems/vng)
97
91
  whenever a new feature is added or a bug gets fixed.
98
- Make sure all the tests are passing ,
99
- document the changes in CHANGELOG.md and README.md, bump the version, then run
92
+ Make sure all the tests are passing and the code is 100% test-covered.
93
+ Document the changes in CHANGELOG.md and README.md, bump the version, then run:
100
94
 
101
95
  rake release
102
96
 
data/lib/vng/asset.rb CHANGED
@@ -1,6 +1,10 @@
1
+ require 'vng/resource'
2
+
1
3
  module Vng
2
4
  # Provides methods to interact with Vonigo assets.
3
- class Asset
5
+ class Asset < Resource
6
+ PATH = '/api/v1/data/Assets/'
7
+
4
8
  attr_reader :id
5
9
 
6
10
  def initialize(id:)
@@ -9,7 +13,6 @@ module Vng
9
13
 
10
14
  def self.create(name:, weight:, breed_option_id:, client_id:)
11
15
  body = {
12
- securityToken: Vng.configuration.security_token,
13
16
  method: '3',
14
17
  clientID: client_id,
15
18
  Fields: [
@@ -19,15 +22,7 @@ module Vng
19
22
  ]
20
23
  }
21
24
 
22
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/data/Assets/'
23
-
24
- request = Net::HTTP::Post.new(uri.request_uri)
25
- request.initialize_http_header 'Content-Type' => 'application/json'
26
- request.body = body.to_json
27
-
28
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
29
- http.request request
30
- end
25
+ data = request path: PATH, body: body
31
26
 
32
27
  # curl = 'curl'.tap do |curl|
33
28
  # curl << ' -X POST'
@@ -37,25 +32,16 @@ module Vng
37
32
  # end
38
33
  # puts curl
39
34
 
40
- new id: JSON(response.body)['Asset']['objectID']
35
+ new id: data['Asset']['objectID']
41
36
  end
42
37
 
43
38
  def destroy
44
39
  body = {
45
- securityToken: Vng.configuration.security_token,
46
40
  method: '4',
47
41
  objectID: id,
48
42
  }
49
43
 
50
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/data/Assets/'
51
-
52
- request = Net::HTTP::Post.new(uri.request_uri)
53
- request.initialize_http_header 'Content-Type' => 'application/json'
54
- request.body = body.to_json
55
-
56
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
57
- http.request request
58
- end
44
+ data = self.class.request path: PATH, body: body
59
45
  end
60
46
  end
61
47
  end
@@ -1,6 +1,10 @@
1
+ require 'vng/resource'
2
+
1
3
  module Vng
2
4
  # Provides methods to interact with Vonigo availabilities.
3
- class Availability
5
+ class Availability < Resource
6
+ PATH = '/api/v1/resources/availability/'
7
+
4
8
  attr_reader :route_id, :date, :minutes
5
9
 
6
10
  def initialize(route_id:, date:, minutes:)
@@ -11,29 +15,20 @@ module Vng
11
15
 
12
16
  def self.where(location_id:, duration:, from_time:, to_time:)
13
17
  body = {
14
- securityToken: Vng.configuration.security_token,
15
18
  method: '0',
16
19
  serviceTypeID: '14', # only return items of serviceType 'Pet Grooming'
17
20
  locationID: location_id,
18
- duration: duration.to_i,
21
+ duration: [duration.to_i, 30].max, # or 'duration is not provided'
19
22
  dateStart: from_time.to_i,
20
23
  dateEnd: to_time.to_i,
21
24
  }
22
25
 
23
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/resources/availability/'
24
-
25
- request = Net::HTTP::Post.new(uri.request_uri)
26
- request.initialize_http_header 'Content-Type' => 'application/json'
27
- request.body = body.to_json
28
-
29
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
30
- http.request request
31
- end
26
+ data = request path: PATH, body: body
32
27
 
33
- JSON(response.body)['Availability'].map do |body|
34
- route_id = body['routeID']
35
- date = Date.strptime body['dayID'], '%Y%m%d'
36
- minutes = body['startTime'].to_i
28
+ data['Availability'].map do |availability|
29
+ route_id = availability['routeID']
30
+ date = Date.strptime availability['dayID'], '%Y%m%d'
31
+ minutes = availability['startTime'].to_i
37
32
 
38
33
  new route_id: route_id, date: date, minutes: minutes
39
34
  end
data/lib/vng/breed.rb CHANGED
@@ -1,6 +1,10 @@
1
+ require 'vng/resource'
2
+
1
3
  module Vng
2
4
  # Provides methods to interact with Vonigo breeds.
3
- class Breed
5
+ class Breed < Resource
6
+ PATH = '/api/v1/resources/breeds/'
7
+
4
8
  attr_reader :id, :name, :species, :option_id, :low_weight, :high_weight
5
9
 
6
10
  def initialize(id:, name:, species:, option_id:, low_weight:, high_weight:)
@@ -14,27 +18,15 @@ module Vng
14
18
 
15
19
  # TODO: Needs pagination
16
20
  def self.all
17
- body = {
18
- securityToken: Vng.configuration.security_token,
19
- }
20
-
21
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/resources/breeds/'
22
-
23
- request = Net::HTTP::Post.new(uri.request_uri)
24
- request.initialize_http_header 'Content-Type' => 'application/json'
25
- request.body = body.to_json
26
-
27
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
28
- http.request request
29
- end
21
+ data = request path: PATH
30
22
 
31
- JSON(response.body)['Breeds'].map do |body|
32
- id = body['breedID']
33
- name = body['breed']
34
- species = body['species']
35
- option_id = body['optionID']
36
- low_weight = body['breedLowWeight']
37
- high_weight = body['breedHighWeight']
23
+ data['Breeds'].map do |breed|
24
+ id = breed['breedID']
25
+ name = breed['breed']
26
+ species = breed['species']
27
+ option_id = breed['optionID']
28
+ low_weight = breed['breedLowWeight']
29
+ high_weight = breed['breedHighWeight']
38
30
 
39
31
  new id: id, name: name, species: species, option_id: option_id, low_weight: low_weight, high_weight: high_weight
40
32
  end
data/lib/vng/case.rb CHANGED
@@ -1,53 +1,44 @@
1
+ require 'vng/resource'
2
+
1
3
  module Vng
2
4
  # Provides methods to interact with Vonigo cases.
3
- class Case
5
+ class Case < Resource
6
+ PATH = '/api/v1/data/Cases/'
7
+
4
8
  attr_reader :id
5
9
 
6
10
  def initialize(id:)
7
11
  @id = id
8
12
  end
9
13
 
10
- def self.create(client_id:, summary:, comments:)
14
+ def self.create(client_id:, summary:, comments:, phone:, email:, zip:)
11
15
  body = {
12
- securityToken: Vng.configuration.security_token,
13
16
  method: '3',
14
- objectID: client_id,
17
+ clientID: client_id,
15
18
  Fields: [
16
19
  {fieldID: 219, optionID: 239}, # Status: open
17
- {fieldID: 220, fieldValue: summary},
18
- {fieldID: 230, fieldValue: comments},
20
+ {fieldID: 220, fieldValue: summary}, # Summary:
21
+ {fieldID: 230, fieldValue: comments}, # Comments:
22
+ {fieldID: 226, optionID: 227}, # Type: 'General request'
23
+ {fieldID: 227, optionID: 232}, # Preferred Contact Method: 'Phone'
24
+ {fieldID: 228, fieldValue: phone}, # Phone Me Back at:
25
+ {fieldID: 229, fieldValue: email}, # Email:
26
+ {fieldID: 1023, fieldValue: zip}, # Zip Code:
19
27
  ]
20
28
  }
21
29
 
22
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/data/Cases/'
23
-
24
- request = Net::HTTP::Post.new(uri.request_uri)
25
- request.initialize_http_header 'Content-Type' => 'application/json'
26
- request.body = body.to_json
30
+ data = request path: PATH, body: body
27
31
 
28
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
29
- http.request request
30
- end
31
-
32
- new id: JSON(response.body)['Case']['objectID']
32
+ new id: data['Case']['objectID']
33
33
  end
34
34
 
35
35
  def destroy
36
36
  body = {
37
- securityToken: Vng.configuration.security_token,
38
37
  method: '4',
39
38
  objectID: id,
40
39
  }
41
40
 
42
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/data/Cases/'
43
-
44
- request = Net::HTTP::Post.new(uri.request_uri)
45
- request.initialize_http_header 'Content-Type' => 'application/json'
46
- request.body = body.to_json
47
-
48
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
49
- http.request request
50
- end
41
+ self.class.request path: PATH, body: body
51
42
  end
52
43
  end
53
44
  end
@@ -0,0 +1,5 @@
1
+ module Vng
2
+ # A wrapper around StandardError.
3
+ class ConnectionError < StandardError
4
+ end
5
+ end
data/lib/vng/contact.rb CHANGED
@@ -1,6 +1,10 @@
1
+ require 'vng/resource'
2
+
1
3
  module Vng
2
4
  # Provides methods to interact with Vonigo contacts.
3
- class Contact
5
+ class Contact < Resource
6
+ PATH = '/api/v1/data/Contacts/'
7
+
4
8
  attr_reader :id, :first_name, :last_name, :email, :phone
5
9
 
6
10
  def initialize(id:, first_name:, last_name:, email:, phone:)
@@ -13,7 +17,6 @@ module Vng
13
17
 
14
18
  def self.create(first_name:, last_name:, email:, phone:, client_id:)
15
19
  body = {
16
- securityToken: Vng.configuration.security_token,
17
20
  method: '3',
18
21
  clientID: client_id,
19
22
  Fields: [
@@ -24,44 +27,26 @@ module Vng
24
27
  ]
25
28
  }
26
29
 
27
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/data/Contacts/'
28
-
29
- request = Net::HTTP::Post.new(uri.request_uri)
30
- request.initialize_http_header 'Content-Type' => 'application/json'
31
- request.body = body.to_json
30
+ data = request path: PATH, body: body
32
31
 
33
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
34
- http.request request
35
- end
36
-
37
- body = JSON response.body
38
-
39
- id = body['Contact']['objectID']
40
- first_name = body['Fields'].find{|field| field['fieldID'] == 127}['fieldValue']
41
- last_name = body['Fields'].find{|field| field['fieldID'] == 128}['fieldValue']
42
- email = body['Fields'].find{|field| field['fieldID'] == 97}['fieldValue']
43
- phone = body['Fields'].find{|field| field['fieldID'] == 96}['fieldValue']
32
+ id = data['Contact']['objectID']
33
+ first_name = data['Fields'].find{|field| field['fieldID'] == 127}['fieldValue']
34
+ last_name = data['Fields'].find{|field| field['fieldID'] == 128}['fieldValue']
35
+ email = data['Fields'].find{|field| field['fieldID'] == 97}['fieldValue']
36
+ phone = data['Fields'].find{|field| field['fieldID'] == 96}['fieldValue']
44
37
 
45
38
  new id: id, first_name: first_name, last_name: last_name, email: email, phone: phone
46
39
  end
47
40
 
48
- def destroy
49
- body = {
50
- securityToken: Vng.configuration.security_token,
51
- method: '4',
52
- objectID: id,
53
- }
54
-
55
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/data/Contacts/'
56
-
57
- request = Net::HTTP::Post.new(uri.request_uri)
58
- request.initialize_http_header 'Content-Type' => 'application/json'
59
- request.body = body.to_json
60
-
61
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
62
- http.request request
63
- end
64
- end
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
65
50
  end
66
51
  end
67
52
 
data/lib/vng/error.rb ADDED
@@ -0,0 +1,5 @@
1
+ module Vng
2
+ # A wrapper around StandardError.
3
+ class Error < StandardError
4
+ end
5
+ end
data/lib/vng/franchise.rb CHANGED
@@ -1,6 +1,10 @@
1
+ require 'vng/availability'
2
+
1
3
  module Vng
2
4
  # Provides methods to interact with Vonigo franchises.
3
- class Franchise
5
+ class Franchise < Resource
6
+ PATH = '/api/v1/resources/franchises/'
7
+
4
8
  attr_reader :id, :name, :gmt_offset
5
9
 
6
10
  def initialize(id:, name: nil, gmt_offset: nil)
@@ -12,46 +16,25 @@ module Vng
12
16
 
13
17
  def self.find_by(zip:)
14
18
  body = {
15
- securityToken: Vng.configuration.security_token,
16
19
  method: '1',
17
20
  zip: zip,
18
21
  }
19
22
 
20
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/resources/availability/'
21
-
22
- request = Net::HTTP::Post.new(uri.request_uri)
23
- request.initialize_http_header 'Content-Type' => 'application/json'
24
- request.body = body.to_json
23
+ data = request path: Vng::Availability::PATH, body: body
25
24
 
26
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
27
- http.request request
28
- end
29
-
30
- franchise_id = JSON(response.body)['Ids']['franchiseID']
25
+ franchise_id = data['Ids']['franchiseID']
31
26
  new(id: franchise_id) unless franchise_id == '0'
32
27
  end
33
28
 
34
29
  def self.all
35
- body = {
36
- securityToken: Vng.configuration.security_token,
37
- }
38
-
39
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/resources/franchises/'
40
-
41
- request = Net::HTTP::Post.new(uri.request_uri)
42
- request.initialize_http_header 'Content-Type' => 'application/json'
43
- request.body = body.to_json
44
-
45
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
46
- http.request request
47
- end
48
-
49
- JSON(response.body)['Franchises'].filter do |body|
50
- body['isActive']
51
- end.map do |body|
52
- id = body['franchiseID']
53
- name = body['franchiseName']
54
- gmt_offset = body['gmtOffsetFranchise']
30
+ data = request path: PATH
31
+
32
+ data['Franchises'].filter do |franchise|
33
+ franchise['isActive']
34
+ end.map do |franchise|
35
+ id = franchise['franchiseID']
36
+ name = franchise['franchiseName']
37
+ gmt_offset = franchise['gmtOffsetFranchise']
55
38
 
56
39
  new id: id, name: name, gmt_offset: gmt_offset
57
40
  end
data/lib/vng/lead.rb CHANGED
@@ -1,6 +1,10 @@
1
+ require 'vng/resource'
2
+
1
3
  module Vng
2
4
  # Provides methods to interact with Vonigo leads.
3
- class Lead
5
+ class Lead < Resource
6
+ PATH = '/api/v1/data/Leads/'
7
+
4
8
  attr_reader :id, :name, :email, :phone
5
9
 
6
10
  def initialize(id:, name:, email:, phone:)
@@ -12,7 +16,6 @@ module Vng
12
16
 
13
17
  def self.create(name:, email:, phone:)
14
18
  body = {
15
- securityToken: Vng.configuration.security_token,
16
19
  method: '3',
17
20
  Fields: [
18
21
  {fieldID: 121, optionID: '59'},
@@ -22,51 +25,25 @@ module Vng
22
25
  ]
23
26
  }
24
27
 
25
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/data/Leads/'
26
-
27
- request = Net::HTTP::Post.new(uri.request_uri)
28
- request.initialize_http_header 'Content-Type' => 'application/json'
29
- request.body = body.to_json
30
-
31
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
32
- http.request request
33
- end
34
-
35
- body = JSON response.body
36
-
37
- if body['errNo']
38
- # 'errNo'=>-600,
39
- # 'errMsg'=>'Data validation failed.',
40
- # 'dateNow'=>'1731342482',
41
- # 'Errors'=>[{"fieldID"=>1024, "fieldName"=>"Phone # to Reach You", "errNo"=>-602, "errMsg"=>"Field data is in incorrect format."}]}
42
-
43
- # raise Vng::Error
44
- end
28
+ data = request path: PATH, body: body
45
29
 
46
- id = body['Client']['objectID']
47
- name = body['Fields'].find{|field| field['fieldID'] == 126}['fieldValue']
48
- email = body['Fields'].find{|field| field['fieldID'] == 238}['fieldValue']
49
- phone = body['Fields'].find{|field| field['fieldID'] == 1024}['fieldValue']
30
+ id = data['Client']['objectID']
31
+ name = data['Fields'].find{|field| field['fieldID'] == 126}['fieldValue']
32
+ email = data['Fields'].find{|field| field['fieldID'] == 238}['fieldValue']
33
+ phone = data['Fields'].find{|field| field['fieldID'] == 1024}['fieldValue']
50
34
 
51
35
  new id: id, name: name, email: email, phone: phone
52
36
  end
53
37
 
54
- def destroy
55
- body = {
56
- securityToken: Vng.configuration.security_token,
57
- method: '4',
58
- objectID: id,
59
- }
60
-
61
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/data/Leads/'
62
-
63
- request = Net::HTTP::Post.new(uri.request_uri)
64
- request.initialize_http_header 'Content-Type' => 'application/json'
65
- request.body = body.to_json
66
-
67
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
68
- http.request request
69
- end
70
- end
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
71
48
  end
72
49
  end
data/lib/vng/location.rb CHANGED
@@ -1,6 +1,10 @@
1
+ require 'vng/resource'
2
+
1
3
  module Vng
2
4
  # Provides methods to interact with Vonigo locations.
3
- class Location
5
+ class Location < Resource
6
+ PATH = '/api/v1/data/Locations/'
7
+
4
8
  # TODO: fetch from /system/objects/ method: 1, objectID: 20
5
9
  STATES_OPTION_ID = {
6
10
  AK: 9879, AL: 9878, AR: 9877, AZ: 9880, CA: 9883, CO: 9876, CT: 9875,
@@ -21,7 +25,6 @@ module Vng
21
25
 
22
26
  def self.create(address:, city:, zip:, state:, client_id:)
23
27
  body = {
24
- securityToken: Vng.configuration.security_token,
25
28
  method: '3',
26
29
  clientID: client_id,
27
30
  Fields: [
@@ -33,36 +36,20 @@ module Vng
33
36
  ]
34
37
  }
35
38
 
36
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/data/Locations/'
37
-
38
- request = Net::HTTP::Post.new(uri.request_uri)
39
- request.initialize_http_header 'Content-Type' => 'application/json'
40
- request.body = body.to_json
39
+ data = request path: PATH, body: body
41
40
 
42
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
43
- http.request request
44
- end
45
-
46
- new id: JSON(response.body)['Location']['objectID']
41
+ new id: data['Location']['objectID']
47
42
  end
48
43
 
49
- def destroy
50
- body = {
51
- securityToken: Vng.configuration.security_token,
52
- method: '4',
53
- objectID: id,
54
- }
55
-
56
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/data/Locations/'
57
-
58
- request = Net::HTTP::Post.new(uri.request_uri)
59
- request.initialize_http_header 'Content-Type' => 'application/json'
60
- request.body = body.to_json
61
-
62
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
63
- http.request request
64
- end
65
- end
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
66
53
  end
67
54
  end
68
55
 
data/lib/vng/lock.rb CHANGED
@@ -1,6 +1,10 @@
1
+ require 'vng/availability'
2
+
1
3
  module Vng
2
4
  # Provides methods to interact with Vonigo locks.
3
- class Lock
5
+ class Lock < Resource
6
+ PATH = '/api/v1/resources/availability/'
7
+
4
8
  attr_reader :id
5
9
 
6
10
  def initialize(id:)
@@ -9,7 +13,6 @@ module Vng
9
13
 
10
14
  def self.create(duration:, location_id:, date:, minutes:, route_id:)
11
15
  body = {
12
- securityToken: Vng.configuration.security_token,
13
16
  method: '2',
14
17
  serviceTypeID: '14', # only create items of serviceType 'Pet Grooming'
15
18
  duration: duration.to_i,
@@ -19,36 +22,18 @@ module Vng
19
22
  startTime: minutes,
20
23
  }
21
24
 
22
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/resources/availability/'
23
-
24
- request = Net::HTTP::Post.new(uri.request_uri)
25
- request.initialize_http_header 'Content-Type' => 'application/json'
26
- request.body = body.to_json
25
+ data = request path: Vng::Availability::PATH, body: body
27
26
 
28
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
29
- http.request request
30
- end
31
-
32
- id = JSON(response.body)['Ids']['lockID']
33
- new id: id
27
+ new id: data['Ids']['lockID']
34
28
  end
35
29
 
36
- def destroy
37
- body = {
38
- securityToken: Vng.configuration.security_token,
39
- method: '4',
40
- objectID: id,
41
- }
42
-
43
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/resources/availability/'
44
-
45
- request = Net::HTTP::Post.new(uri.request_uri)
46
- request.initialize_http_header 'Content-Type' => 'application/json'
47
- request.body = body.to_json
48
-
49
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
50
- http.request request
51
- end
52
- end
30
+ # def destroy
31
+ # body = {
32
+ # method: '4',
33
+ # lockID: id,
34
+ # }
35
+ #
36
+ # self.class.request path: PATH, body: body
37
+ # end
53
38
  end
54
39
  end
@@ -1,6 +1,10 @@
1
+ require 'vng/resource'
2
+
1
3
  module Vng
2
4
  # Provides methods to interact with Vonigo price items.
3
- class PriceItem
5
+ class PriceItem < Resource
6
+ PATH = '/api/v1/data/priceLists/'
7
+
4
8
  attr_reader :id, :price_item, :value, :tax_id, :duration_per_unit, :service_badge, :service_category
5
9
 
6
10
  def initialize(id:, price_item:, value:, tax_id:, duration_per_unit:, service_badge:, service_category:)
@@ -15,25 +19,15 @@ module Vng
15
19
 
16
20
  def self.where(location_id:, asset_id:)
17
21
  body = {
18
- securityToken: Vng.configuration.security_token,
19
22
  method: '2',
20
23
  serviceTypeID: '14', # only return items of serviceType 'Pet Grooming'
21
24
  locationID: location_id,
22
25
  assetID: asset_id,
23
26
  }
24
27
 
25
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/data/priceLists/'
26
-
27
- request = Net::HTTP::Post.new(uri.request_uri)
28
- request.initialize_http_header 'Content-Type' => 'application/json'
29
- request.body = body.to_json
30
-
31
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
32
- http.request request
33
- end
28
+ data = request path: PATH, body: body
34
29
 
35
- JSON(response.body)['PriceItems'].filter do |body|
36
- # TODO: body['serviceBadge'] != 'Not Offered'
30
+ data['PriceItems'].filter do |body|
37
31
  body['isOnline'] && body['isActive']
38
32
  end.map do |body|
39
33
  id = body['priceItemID']
@@ -0,0 +1,40 @@
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
+ 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
+
21
+ response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
22
+ http.request request
23
+ end
24
+
25
+ JSON(response.body).tap do |data|
26
+ raise Vng::Error, "#{data['errMsg']} #{data['Errors']}" unless data['errNo'].zero?
27
+ end
28
+ rescue Errno::ECONNREFUSED, SocketError => e
29
+ raise Vng::ConnectionError, e.message
30
+ end
31
+
32
+ def self.host
33
+ Vng.configuration.host
34
+ end
35
+
36
+ def self.security_token
37
+ Vng.configuration.security_token
38
+ end
39
+ end
40
+ end
@@ -1,51 +1,51 @@
1
+ require 'vng/resource'
2
+
1
3
  module Vng
2
4
  # Provides methods to interact with Vonigo work security tokens.
3
- class SecurityToken
5
+ class SecurityToken < Resource
6
+ PATH = '/api/v1/security/login/'
7
+
4
8
  attr_reader :token
5
9
 
6
- def initialize(token:, host:)
10
+ def initialize(token:)
7
11
  @token = token
8
- @host = host
9
12
  end
10
13
 
11
- def self.create(host:, username:, password:)
14
+ def self.create
12
15
  body = {
13
16
  app_version: '1',
14
17
  company: 'Vonigo',
15
- host: host,
16
- password: Digest::MD5.hexdigest(password),
17
- username: username,
18
+ username: Vng.configuration.username,
19
+ password: Digest::MD5.hexdigest(Vng.configuration.password),
18
20
  }
19
21
 
20
- uri = URI::HTTPS.build host: host, path: '/api/v1/security/login/'
21
-
22
- request = Net::HTTP::Get.new(uri.request_uri)
23
- request.initialize_http_header 'Content-Type' => 'application/json; charset=utf-8'
24
- request.body = body.to_json
25
-
26
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
27
- http.request request
28
- end
29
-
30
- token = JSON(response.body)['securityToken']
22
+ data = request path: PATH, body: body, include_security_token: false
31
23
 
32
- new token: token, host: host
24
+ new token: data['securityToken']
33
25
  end
34
26
 
35
- def destroy
27
+ # TODO: Check if it's not the correct one already or catch
28
+ # Data validation failed. [{"fieldID"=>0, "fieldName"=>nil, "errNo"=>-5213, "errMsg"=>"Same franchise ID supplied."}]
29
+ def assign_to(franchise_id:)
36
30
  body = {
37
31
  securityToken: @token,
32
+ method: "2",
33
+ franchiseID: franchise_id,
38
34
  }
39
35
 
40
- uri = URI::HTTPS.build host: @host, path: '/api/v1/security/login/'
41
-
42
- request = Net::HTTP::Post.new(uri.request_uri)
43
- request.initialize_http_header 'Content-Type' => 'application/json'
44
- request.body = body.to_json
36
+ self.class.request path: '/api/v1/security/session/', body: body, include_security_token: false
37
+ rescue Vng::Error => e
38
+ # TODO: improve: ignore if the token was already assigned to the franchise
39
+ raise unless e.message.include? 'Same franchise ID supplied'
40
+ end
45
41
 
46
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
47
- http.request request
48
- end
42
+ def destroy
43
+ query = { securityToken: @token }
44
+ self.class.request path: '/api/v1/security/logout/', query: query
45
+ rescue Vng::Error => e
46
+ p "Vng:Error! #{e}"
47
+ # TODO: improve: ignore if the token was already destroyed
48
+ raise unless e.message.include?('Session expired') || e.message.include?('Session does not exist')
49
49
  end
50
50
  end
51
51
  end
@@ -1,6 +1,10 @@
1
+ require 'vng/resource'
2
+
1
3
  module Vng
2
4
  # Provides methods to interact with Vonigo service types.
3
- class ServiceType
5
+ class ServiceType < Resource
6
+ PATH = '/api/v1/resources/serviceTypes/'
7
+
4
8
  attr_reader :id, :type, :duration
5
9
 
6
10
  def initialize(id:, type:, duration:)
@@ -11,21 +15,9 @@ module Vng
11
15
 
12
16
  # TODO: Needs pagination
13
17
  def self.all
14
- body = {
15
- securityToken: Vng.configuration.security_token,
16
- }
17
-
18
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/resources/serviceTypes/'
19
-
20
- request = Net::HTTP::Post.new(uri.request_uri)
21
- request.initialize_http_header 'Content-Type' => 'application/json'
22
- request.body = body.to_json
18
+ data = request path: PATH
23
19
 
24
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
25
- http.request request
26
- end
27
-
28
- JSON(response.body)['ServiceTypes'].map do |body|
20
+ data['ServiceTypes'].map do |body|
29
21
  id = body['serviceTypeID']
30
22
  type = body['serviceType']
31
23
  duration = body['duration']
@@ -36,21 +28,12 @@ module Vng
36
28
 
37
29
  def self.where(zip:)
38
30
  body = {
39
- securityToken: Vng.configuration.security_token,
40
31
  zip: zip,
41
32
  }
42
33
 
43
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/resources/serviceTypes/'
44
-
45
- request = Net::HTTP::Post.new(uri.request_uri)
46
- request.initialize_http_header 'Content-Type' => 'application/json'
47
- request.body = body.to_json
48
-
49
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
50
- http.request request
51
- end
34
+ data = request path: PATH, body: body
52
35
 
53
- JSON(response.body)['ServiceTypes'].filter do |body|
36
+ data.fetch('ServiceTypes', []).filter do |body|
54
37
  body['isActive']
55
38
  end.map do |body|
56
39
  id = body['serviceTypeID']
data/lib/vng/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Vng
2
- VERSION = '0.1.13'
2
+ VERSION = '0.1.14'
3
3
  end
@@ -1,6 +1,10 @@
1
+ require 'vng/resource'
2
+
1
3
  module Vng
2
4
  # Provides methods to interact with Vonigo work orders.
3
- class WorkOrder
5
+ class WorkOrder < Resource
6
+ PATH = '/api/v1/data/WorkOrders/'
7
+
4
8
  attr_reader :id
5
9
 
6
10
  def initialize(id:)
@@ -8,20 +12,7 @@ module Vng
8
12
  end
9
13
 
10
14
  def self.create(lock_id:, client_id:, contact_id:, location_id:, duration:, summary:, line_items:)
11
- charges = line_items.map do |line_item|
12
- {
13
- priceItemID: line_item[:price_item_id],
14
- taxID: line_item[:tax_id],
15
- assetID: line_item[:asset_id],
16
- Fields: [
17
- {fieldID: 9289, fieldValue: line_item[:description]},
18
- {fieldID: 9287, fieldValue: line_item[:price]}
19
- ]
20
- }
21
- end
22
-
23
15
  body = {
24
- securityToken: Vng.configuration.security_token,
25
16
  method: '3',
26
17
  serviceTypeID: '14', # only return items of serviceType 'Pet Grooming'
27
18
  lockID: lock_id,
@@ -33,39 +24,47 @@ module Vng
33
24
  {fieldID: 186, fieldValue: duration.to_i},
34
25
  {fieldID: 201, optionID: '9537'} # label: Online Tentative
35
26
  ],
36
- Charges: charges
27
+ Charges: charges_for(line_items)
37
28
  }
38
29
 
39
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/data/WorkOrders/'
40
-
41
- request = Net::HTTP::Post.new(uri.request_uri)
42
- request.initialize_http_header 'Content-Type' => 'application/json'
43
- request.body = body.to_json
44
-
45
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
46
- http.request request
47
- end
30
+ data = request path: PATH, body: body
48
31
 
49
- id = JSON(response.body)['WorkOrder']['objectID']
50
- new id: id
32
+ new id: data['WorkOrder']['objectID']
51
33
  end
52
34
 
53
- def destroy
54
- body = {
55
- securityToken: Vng.configuration.security_token,
56
- method: '4',
57
- objectID: id,
58
- }
59
-
60
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/data/WorkOrders/'
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
61
44
 
62
- request = Net::HTTP::Post.new(uri.request_uri)
63
- request.initialize_http_header 'Content-Type' => 'application/json'
64
- request.body = body.to_json
45
+ private
65
46
 
66
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
67
- http.request request
47
+ def self.charges_for(line_items)
48
+ line_items.map do |line_item|
49
+ {
50
+ priceItemID: line_item[:price_item_id],
51
+ taxID: line_item[:tax_id],
52
+ assetID: line_item[:asset_id],
53
+ Fields: charge_fields_for(line_item)
54
+ }
68
55
  end
69
56
  end
57
+
58
+ def self.charge_fields_for(line_item)
59
+ [
60
+ {fieldID: 9289, fieldValue: line_item[:description]},
61
+ {fieldID: 9287, fieldValue: line_item[:price]}, # Unit price
62
+ {fieldID: 8673, fieldValue: line_item[:price]}, # Price item
63
+ {fieldID: 813, fieldValue: line_item[:price]}, # Price
64
+ {fieldID: 9286, fieldValue: line_item[:price]}, # Subtotal
65
+ {fieldID: 9283, fieldValue: line_item[:price]}, # Total
66
+ {fieldID: 9288, fieldValue: 1}, # Qty
67
+ ]
68
+ end
70
69
  end
71
70
  end
data/lib/vng/zip.rb CHANGED
@@ -1,6 +1,10 @@
1
+ require 'vng/resource'
2
+
1
3
  module Vng
2
4
  # Provides methods to interact with Vonigo ZIP codes.
3
- class Zip
5
+ class Zip < Resource
6
+ PATH = '/api/v1/resources/zips/'
7
+
4
8
  attr_reader :zip, :state, :zone_name
5
9
 
6
10
  def initialize(zip:, state:, zone_name:)
@@ -11,21 +15,9 @@ module Vng
11
15
 
12
16
  # TODO: Needs pagination
13
17
  def self.all
14
- body = {
15
- securityToken: Vng.configuration.security_token,
16
- }
17
-
18
- uri = URI::HTTPS.build host: 'aussiepetmobileusatraining2.vonigo.com', path: '/api/v1/resources/zips/'
19
-
20
- request = Net::HTTP::Post.new(uri.request_uri)
21
- request.initialize_http_header 'Content-Type' => 'application/json'
22
- request.body = body.to_json
23
-
24
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
25
- http.request request
26
- end
18
+ data = request path: PATH
27
19
 
28
- JSON(response.body)['Zips'].map do |body|
20
+ data['Zips'].map do |body|
29
21
  zip = body['zip']
30
22
  state = body['state']
31
23
  zone_name = body['zoneName']
data/lib/vng.rb CHANGED
@@ -9,6 +9,7 @@ require_relative 'vng/availability'
9
9
  require_relative 'vng/breed'
10
10
  require_relative 'vng/case'
11
11
  require_relative 'vng/config'
12
+ require_relative 'vng/connection_error'
12
13
  require_relative 'vng/contact'
13
14
  require_relative 'vng/franchise'
14
15
  require_relative 'vng/lead'
@@ -20,8 +21,3 @@ require_relative 'vng/service_type'
20
21
  require_relative 'vng/version'
21
22
  require_relative 'vng/work_order'
22
23
  require_relative 'vng/zip'
23
-
24
- module Vng
25
- class Error < StandardError; end
26
- # Your code goes here...
27
- end
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.13
4
+ version: 0.1.14
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-16 00:00:00.000000000 Z
11
+ date: 2024-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: simplecov
@@ -43,12 +43,15 @@ files:
43
43
  - lib/vng/case.rb
44
44
  - lib/vng/config.rb
45
45
  - lib/vng/configuration.rb
46
+ - lib/vng/connection_error.rb
46
47
  - lib/vng/contact.rb
48
+ - lib/vng/error.rb
47
49
  - lib/vng/franchise.rb
48
50
  - lib/vng/lead.rb
49
51
  - lib/vng/location.rb
50
52
  - lib/vng/lock.rb
51
53
  - lib/vng/price_item.rb
54
+ - lib/vng/resource.rb
52
55
  - lib/vng/security_token.rb
53
56
  - lib/vng/service_type.rb
54
57
  - lib/vng/version.rb