vng 0.1.18 → 0.1.20

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: a5a0ac30382d544a23cf237ceaed3b8d1ca72a91c1886126d007475bf8b5ee2b
4
- data.tar.gz: 62843a64cc58e6b21788d5fc87969fad1335e89740cd564247920df83620058c
3
+ metadata.gz: 0b49dda09b2542875760b7b2cdd3c4ab50d548458400e7dda9586edafd5c18b2
4
+ data.tar.gz: 0e86208199aebd2f79914bfd5e6c5ec330682bcebbe4d154bd808bb3bb4a64f7
5
5
  SHA512:
6
- metadata.gz: e516c0ab8fa41d444e923227ac3c2c4393a1451710e8ff10ac02dd2444c67c0423b3125471b290aa6b68b8a5e63c618c323df8ba41272e48361bf8e9c66151c2
7
- data.tar.gz: 8b236c7ad8f41302f1d5ff6de2ed222e1780217942c4bbdfdc441ecc3cbf2d43ed4ed8014946a7b200eef9e612affd77bfff4d3358211905eef3dd6caae8dd15
6
+ metadata.gz: 751d1a4eb1774f508106113b6cdc21988b6515ae8d965be322b205670b716214668ae72c67828e2a05fcb127a6c525fa741704c72244e8d9c52ad5e33fc55e43
7
+ data.tar.gz: 552dcc79f28b148d54559849f04052b5348e552c7fbecc2dbba81dc46a07744db9b83b90b4ff740e48893b1aedede0e3db31d05fcccb043bf6620a3c8af276ee
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.20] - 2024-11-20
4
+
5
+ - Adds Franchise.find
6
+
7
+ ## [0.1.19] - 2024-11-19
8
+
9
+ - Adds Route
10
+
3
11
  ## [0.1.18] - 2024-11-19
4
12
 
5
13
  - Ensure a plus sign in the email is not translated into a space
data/README.md CHANGED
@@ -84,6 +84,8 @@ To run tests:
84
84
  rspec
85
85
  ```
86
86
 
87
+ Set `VNG_MOCK=1` to test against HTTP mocks.
88
+
87
89
  How to release new versions
88
90
  ===========================
89
91
 
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Vng
2
- VERSION = '0.1.18'
2
+ VERSION = '0.1.20'
3
3
  end
@@ -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.18
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-19 00:00:00.000000000 Z
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