nzbn-ruby 0.1.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 +7 -0
- data/CHANGELOG.md +26 -0
- data/Gemfile +5 -0
- data/LICENSE +21 -0
- data/README.md +239 -0
- data/Rakefile +8 -0
- data/lib/nzbn/api/addresses.rb +61 -0
- data/lib/nzbn/api/company_details.rb +32 -0
- data/lib/nzbn/api/email_addresses.rb +35 -0
- data/lib/nzbn/api/entities.rb +120 -0
- data/lib/nzbn/api/history.rb +81 -0
- data/lib/nzbn/api/industry_classifications.rb +35 -0
- data/lib/nzbn/api/organisation_parts.rb +92 -0
- data/lib/nzbn/api/phone_numbers.rb +35 -0
- data/lib/nzbn/api/privacy_settings.rb +33 -0
- data/lib/nzbn/api/roles.rb +53 -0
- data/lib/nzbn/api/trading_names.rb +35 -0
- data/lib/nzbn/api/watchlists.rb +120 -0
- data/lib/nzbn/api/websites.rb +35 -0
- data/lib/nzbn/client.rb +180 -0
- data/lib/nzbn/configuration.rb +28 -0
- data/lib/nzbn/error.rb +62 -0
- data/lib/nzbn/models/address.rb +12 -0
- data/lib/nzbn/models/base.rb +59 -0
- data/lib/nzbn/models/company.rb +20 -0
- data/lib/nzbn/models/email_address.rb +11 -0
- data/lib/nzbn/models/entity.rb +14 -0
- data/lib/nzbn/models/error_response.rb +19 -0
- data/lib/nzbn/models/full_entity.rb +50 -0
- data/lib/nzbn/models/industry_classification.rb +10 -0
- data/lib/nzbn/models/organisation_part.rb +14 -0
- data/lib/nzbn/models/phone_number.rb +16 -0
- data/lib/nzbn/models/privacy_settings.rb +26 -0
- data/lib/nzbn/models/role.rb +27 -0
- data/lib/nzbn/models/search_entity.rb +32 -0
- data/lib/nzbn/models/search_response.rb +50 -0
- data/lib/nzbn/models/trading_name.rb +10 -0
- data/lib/nzbn/models/watchlist.rb +14 -0
- data/lib/nzbn/models/website.rb +10 -0
- data/lib/nzbn/version.rb +5 -0
- data/lib/nzbn.rb +67 -0
- data/nzbn-ruby.gemspec +35 -0
- metadata +175 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nzbn
|
|
4
|
+
module Api
|
|
5
|
+
# Organisation Parts API (OPN/GLN management)
|
|
6
|
+
class OrganisationParts
|
|
7
|
+
def initialize(client)
|
|
8
|
+
@client = client
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Search organisation parts
|
|
12
|
+
#
|
|
13
|
+
# @param nzbn [String] Parent NZBN to search within
|
|
14
|
+
# @param opn [String] OPN to search for
|
|
15
|
+
# @param name [String] Name filter
|
|
16
|
+
# @param function [String] Function filter (FUNCTION, PHYSICAL_LOCATION, DIGITAL_LOCATION)
|
|
17
|
+
# @param status [String] Status filter (ACTIVE, INACTIVE)
|
|
18
|
+
# @param page [Integer] Page number
|
|
19
|
+
# @param page_size [Integer] Results per page
|
|
20
|
+
# @return [Models::SearchResponse] Paginated results
|
|
21
|
+
#
|
|
22
|
+
def search(nzbn: nil, opn: nil, name: nil, function: nil, status: nil, page: nil, page_size: nil)
|
|
23
|
+
params = {}
|
|
24
|
+
params['nzbn'] = nzbn if nzbn
|
|
25
|
+
params['opn'] = opn if opn
|
|
26
|
+
params['name'] = name if name
|
|
27
|
+
params['function'] = function if function
|
|
28
|
+
params['status'] = status if status
|
|
29
|
+
params['page'] = page if page
|
|
30
|
+
params['page-size'] = page_size if page_size
|
|
31
|
+
|
|
32
|
+
response = @client.get('/entities/organisation-parts', params)
|
|
33
|
+
Models::SearchResponse.new(response, item_class: Models::OrganisationPart)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# List organisation parts for an entity
|
|
37
|
+
#
|
|
38
|
+
# @param nzbn [String] 13-digit NZBN
|
|
39
|
+
# @return [Array<Models::OrganisationPart>] List of organisation parts
|
|
40
|
+
#
|
|
41
|
+
def list(nzbn:)
|
|
42
|
+
response = @client.get("/entities/#{nzbn}/organisation-parts")
|
|
43
|
+
return [] unless response.is_a?(Array)
|
|
44
|
+
|
|
45
|
+
response.map { |op| Models::OrganisationPart.new(op) }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Get an organisation part
|
|
49
|
+
#
|
|
50
|
+
# @param nzbn [String] 13-digit NZBN
|
|
51
|
+
# @param opn [String] Organisation part number
|
|
52
|
+
# @return [Models::OrganisationPart] Organisation part details
|
|
53
|
+
#
|
|
54
|
+
def get(nzbn:, opn:)
|
|
55
|
+
response = @client.get("/entities/#{nzbn}/organisation-parts/#{opn}")
|
|
56
|
+
Models::OrganisationPart.new(response)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Create an organisation part
|
|
60
|
+
#
|
|
61
|
+
# @param nzbn [String] 13-digit NZBN
|
|
62
|
+
# @param organisation_part [Hash] Organisation part attributes
|
|
63
|
+
# @return [Models::OrganisationPart] Created organisation part
|
|
64
|
+
#
|
|
65
|
+
def create(nzbn:, organisation_part:)
|
|
66
|
+
response = @client.post("/entities/#{nzbn}/organisation-parts", organisation_part)
|
|
67
|
+
Models::OrganisationPart.new(response)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Update an organisation part
|
|
71
|
+
#
|
|
72
|
+
# @param nzbn [String] 13-digit NZBN
|
|
73
|
+
# @param opn [String] Organisation part number
|
|
74
|
+
# @param organisation_part [Hash] Updated attributes
|
|
75
|
+
# @return [Models::OrganisationPart] Updated organisation part
|
|
76
|
+
#
|
|
77
|
+
def update(nzbn:, opn:, organisation_part:)
|
|
78
|
+
response = @client.put("/entities/#{nzbn}/organisation-parts/#{opn}", organisation_part)
|
|
79
|
+
Models::OrganisationPart.new(response)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Get GLN allocation summary for an entity
|
|
83
|
+
#
|
|
84
|
+
# @param nzbn [String] 13-digit NZBN
|
|
85
|
+
# @return [Hash] Allocation summary
|
|
86
|
+
#
|
|
87
|
+
def gln_allocation(nzbn:)
|
|
88
|
+
@client.get("/entities/#{nzbn}/organisation-parts/allocation")
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nzbn
|
|
4
|
+
module Api
|
|
5
|
+
# Phone Numbers API
|
|
6
|
+
class PhoneNumbers
|
|
7
|
+
def initialize(client)
|
|
8
|
+
@client = client
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# List phone numbers for an entity
|
|
12
|
+
#
|
|
13
|
+
# @param nzbn [String] 13-digit NZBN
|
|
14
|
+
# @return [Array<Models::PhoneNumber>] List of phone numbers
|
|
15
|
+
#
|
|
16
|
+
def list(nzbn:)
|
|
17
|
+
response = @client.get("/entities/#{nzbn}/phone-numbers")
|
|
18
|
+
return [] unless response.is_a?(Array)
|
|
19
|
+
|
|
20
|
+
response.map { |pn| Models::PhoneNumber.new(pn) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Add a phone number
|
|
24
|
+
#
|
|
25
|
+
# @param nzbn [String] 13-digit NZBN
|
|
26
|
+
# @param phone [Hash] Phone number attributes
|
|
27
|
+
# @return [Models::PhoneNumber] Created phone number
|
|
28
|
+
#
|
|
29
|
+
def create(nzbn:, phone:)
|
|
30
|
+
response = @client.post("/entities/#{nzbn}/phone-numbers", phone)
|
|
31
|
+
Models::PhoneNumber.new(response)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nzbn
|
|
4
|
+
module Api
|
|
5
|
+
# Privacy Settings API
|
|
6
|
+
class PrivacySettings
|
|
7
|
+
def initialize(client)
|
|
8
|
+
@client = client
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Get privacy settings for an entity
|
|
12
|
+
#
|
|
13
|
+
# @param nzbn [String] 13-digit NZBN
|
|
14
|
+
# @return [Models::PrivacySettings] Privacy settings
|
|
15
|
+
#
|
|
16
|
+
def get(nzbn:)
|
|
17
|
+
response = @client.get("/entities/#{nzbn}/privacy-settings")
|
|
18
|
+
Models::PrivacySettings.new(response)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Update privacy settings
|
|
22
|
+
#
|
|
23
|
+
# @param nzbn [String] 13-digit NZBN
|
|
24
|
+
# @param settings [Hash] Privacy settings to update
|
|
25
|
+
# @return [Models::PrivacySettings] Updated settings
|
|
26
|
+
#
|
|
27
|
+
def update(nzbn:, settings:)
|
|
28
|
+
response = @client.put("/entities/#{nzbn}/privacy-settings", settings)
|
|
29
|
+
Models::PrivacySettings.new(response)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nzbn
|
|
4
|
+
module Api
|
|
5
|
+
# Roles API - Manage entity roles (directors, partners, etc.)
|
|
6
|
+
class Roles
|
|
7
|
+
def initialize(client)
|
|
8
|
+
@client = client
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# List roles for an entity
|
|
12
|
+
#
|
|
13
|
+
# @param nzbn [String] 13-digit NZBN
|
|
14
|
+
# @return [Array<Models::Role>] List of roles
|
|
15
|
+
#
|
|
16
|
+
def list(nzbn:)
|
|
17
|
+
response = @client.get("/entities/#{nzbn}/roles")
|
|
18
|
+
return [] unless response.is_a?(Array)
|
|
19
|
+
|
|
20
|
+
response.map { |role| Models::Role.new(role) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Add a role to an entity
|
|
24
|
+
#
|
|
25
|
+
# @param nzbn [String] 13-digit NZBN
|
|
26
|
+
# @param role [Hash] Role attributes including roleType, rolePerson, etc.
|
|
27
|
+
# @return [Models::Role] Created role
|
|
28
|
+
#
|
|
29
|
+
# @example
|
|
30
|
+
# client.roles.create(nzbn: '9429041925676', role: {
|
|
31
|
+
# roleType: 'PARTNER_INDIVIDUAL',
|
|
32
|
+
# rolePerson: { firstName: 'John', lastName: 'Doe' },
|
|
33
|
+
# startDate: '2024-01-01'
|
|
34
|
+
# })
|
|
35
|
+
#
|
|
36
|
+
def create(nzbn:, role:)
|
|
37
|
+
response = @client.post("/entities/#{nzbn}/roles", role)
|
|
38
|
+
Models::Role.new(response)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Update a role
|
|
42
|
+
#
|
|
43
|
+
# @param nzbn [String] 13-digit NZBN
|
|
44
|
+
# @param role [Hash] Updated role attributes
|
|
45
|
+
# @return [Models::Role] Updated role
|
|
46
|
+
#
|
|
47
|
+
def update(nzbn:, role:)
|
|
48
|
+
response = @client.put("/entities/#{nzbn}/roles", role)
|
|
49
|
+
Models::Role.new(response)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nzbn
|
|
4
|
+
module Api
|
|
5
|
+
# Trading Names API
|
|
6
|
+
class TradingNames
|
|
7
|
+
def initialize(client)
|
|
8
|
+
@client = client
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# List trading names for an entity
|
|
12
|
+
#
|
|
13
|
+
# @param nzbn [String] 13-digit NZBN
|
|
14
|
+
# @return [Array<Models::TradingName>] List of trading names
|
|
15
|
+
#
|
|
16
|
+
def list(nzbn:)
|
|
17
|
+
response = @client.get("/entities/#{nzbn}/trading-names")
|
|
18
|
+
return [] unless response.is_a?(Array)
|
|
19
|
+
|
|
20
|
+
response.map { |tn| Models::TradingName.new(tn) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Add a trading name
|
|
24
|
+
#
|
|
25
|
+
# @param nzbn [String] 13-digit NZBN
|
|
26
|
+
# @param trading_name [Hash] Trading name attributes
|
|
27
|
+
# @return [Models::TradingName] Created trading name
|
|
28
|
+
#
|
|
29
|
+
def create(nzbn:, trading_name:)
|
|
30
|
+
response = @client.post("/entities/#{nzbn}/trading-names", trading_name)
|
|
31
|
+
Models::TradingName.new(response)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nzbn
|
|
4
|
+
module Api
|
|
5
|
+
# Watchlists API - Manage change notification watchlists
|
|
6
|
+
class Watchlists
|
|
7
|
+
def initialize(client)
|
|
8
|
+
@client = client
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# List watchlists
|
|
12
|
+
#
|
|
13
|
+
# @param name [String] Filter by name (partial match)
|
|
14
|
+
# @param organisation_id [String] Filter by organisation ID
|
|
15
|
+
# @param page [Integer] Page number
|
|
16
|
+
# @param page_size [Integer] Results per page
|
|
17
|
+
# @param sort_by [String] Sort field
|
|
18
|
+
# @param sort_order [String] ASC or DESC
|
|
19
|
+
# @param change_event_types [String] Filter by change event types
|
|
20
|
+
# @return [Models::SearchResponse] Paginated watchlist results
|
|
21
|
+
#
|
|
22
|
+
def list(name: nil, organisation_id: nil, page: nil, page_size: nil,
|
|
23
|
+
sort_by: nil, sort_order: nil, change_event_types: nil)
|
|
24
|
+
params = {}
|
|
25
|
+
params['name'] = name if name
|
|
26
|
+
params['organisation-id'] = organisation_id if organisation_id
|
|
27
|
+
params['page'] = page if page
|
|
28
|
+
params['page-size'] = page_size if page_size
|
|
29
|
+
params['sort-by'] = sort_by if sort_by
|
|
30
|
+
params['sortorder'] = sort_order if sort_order
|
|
31
|
+
params['change-event-types'] = change_event_types if change_event_types
|
|
32
|
+
|
|
33
|
+
response = @client.get('/watchlists', params)
|
|
34
|
+
Models::SearchResponse.new(response, item_class: Models::Watchlist)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Get a watchlist by ID
|
|
38
|
+
#
|
|
39
|
+
# @param watchlist_id [String] Watchlist ID
|
|
40
|
+
# @return [Models::Watchlist] Watchlist details
|
|
41
|
+
#
|
|
42
|
+
def get(watchlist_id:)
|
|
43
|
+
response = @client.get("/watchlists/#{watchlist_id}")
|
|
44
|
+
Models::Watchlist.new(response)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Create a new watchlist
|
|
48
|
+
#
|
|
49
|
+
# @param watchlist [Hash] Watchlist attributes
|
|
50
|
+
# @return [Models::Watchlist] Created watchlist
|
|
51
|
+
#
|
|
52
|
+
# @example
|
|
53
|
+
# client.watchlists.create(watchlist: {
|
|
54
|
+
# name: 'My Watchlist',
|
|
55
|
+
# channel: 'EMAIL',
|
|
56
|
+
# frequency: 'DAILY',
|
|
57
|
+
# changeEventTypes: 'ALL',
|
|
58
|
+
# adminEmailAddress: 'admin@example.com'
|
|
59
|
+
# })
|
|
60
|
+
#
|
|
61
|
+
def create(watchlist:)
|
|
62
|
+
response = @client.post('/watchlists', watchlist)
|
|
63
|
+
Models::Watchlist.new(response)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Update a watchlist
|
|
67
|
+
#
|
|
68
|
+
# @param watchlist_id [String] Watchlist ID
|
|
69
|
+
# @param watchlist [Hash] Updated watchlist attributes
|
|
70
|
+
# @return [Models::Watchlist] Updated watchlist
|
|
71
|
+
#
|
|
72
|
+
def update(watchlist_id:, watchlist:)
|
|
73
|
+
response = @client.put("/watchlists/#{watchlist_id}", watchlist)
|
|
74
|
+
Models::Watchlist.new(response)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Delete a watchlist
|
|
78
|
+
#
|
|
79
|
+
# @param watchlist_id [String] Watchlist ID
|
|
80
|
+
# @return [Boolean] True if successful
|
|
81
|
+
#
|
|
82
|
+
def delete(watchlist_id:)
|
|
83
|
+
@client.delete("/watchlists/#{watchlist_id}")
|
|
84
|
+
true
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# List NZBNs in a watchlist
|
|
88
|
+
#
|
|
89
|
+
# @param watchlist_id [String] Watchlist ID
|
|
90
|
+
# @return [Array<String>] List of NZBNs
|
|
91
|
+
#
|
|
92
|
+
def list_nzbns(watchlist_id:)
|
|
93
|
+
response = @client.get("/watchlists/#{watchlist_id}/nzbns")
|
|
94
|
+
response['nzbns'] || []
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Add NZBNs to a watchlist
|
|
98
|
+
#
|
|
99
|
+
# @param watchlist_id [String] Watchlist ID
|
|
100
|
+
# @param nzbns [Array<String>] NZBNs to add
|
|
101
|
+
# @return [Boolean] True if successful
|
|
102
|
+
#
|
|
103
|
+
def add_nzbns(watchlist_id:, nzbns:)
|
|
104
|
+
@client.post("/watchlists/#{watchlist_id}/nzbns", { nzbns: nzbns })
|
|
105
|
+
true
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Remove NZBNs from a watchlist
|
|
109
|
+
#
|
|
110
|
+
# @param watchlist_id [String] Watchlist ID
|
|
111
|
+
# @param nzbns [Array<String>] NZBNs to remove
|
|
112
|
+
# @return [Boolean] True if successful
|
|
113
|
+
#
|
|
114
|
+
def remove_nzbns(watchlist_id:, nzbns:)
|
|
115
|
+
@client.delete("/watchlists/#{watchlist_id}/nzbns", { nzbns: nzbns })
|
|
116
|
+
true
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nzbn
|
|
4
|
+
module Api
|
|
5
|
+
# Websites API
|
|
6
|
+
class Websites
|
|
7
|
+
def initialize(client)
|
|
8
|
+
@client = client
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# List websites for an entity
|
|
12
|
+
#
|
|
13
|
+
# @param nzbn [String] 13-digit NZBN
|
|
14
|
+
# @return [Array<Models::Website>] List of websites
|
|
15
|
+
#
|
|
16
|
+
def list(nzbn:)
|
|
17
|
+
response = @client.get("/entities/#{nzbn}/websites")
|
|
18
|
+
return [] unless response.is_a?(Array)
|
|
19
|
+
|
|
20
|
+
response.map { |ws| Models::Website.new(ws) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Add a website
|
|
24
|
+
#
|
|
25
|
+
# @param nzbn [String] 13-digit NZBN
|
|
26
|
+
# @param website [Hash] Website attributes
|
|
27
|
+
# @return [Models::Website] Created website
|
|
28
|
+
#
|
|
29
|
+
def create(nzbn:, website:)
|
|
30
|
+
response = @client.post("/entities/#{nzbn}/websites", website)
|
|
31
|
+
Models::Website.new(response)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
data/lib/nzbn/client.rb
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'faraday'
|
|
4
|
+
require 'faraday/multipart'
|
|
5
|
+
require 'json'
|
|
6
|
+
require 'securerandom'
|
|
7
|
+
|
|
8
|
+
module Nzbn
|
|
9
|
+
# Main HTTP client for NZBN API
|
|
10
|
+
#
|
|
11
|
+
# @example
|
|
12
|
+
# client = Nzbn::Client.new
|
|
13
|
+
# client.entities.search(search_term: 'Company Name')
|
|
14
|
+
#
|
|
15
|
+
class Client
|
|
16
|
+
attr_reader :configuration
|
|
17
|
+
|
|
18
|
+
def initialize(api_key: nil, base_url: nil, timeout: nil)
|
|
19
|
+
@configuration = Nzbn.configuration&.dup || Configuration.new
|
|
20
|
+
@configuration.api_key = api_key if api_key
|
|
21
|
+
@configuration.base_url = base_url if base_url
|
|
22
|
+
@configuration.timeout = timeout if timeout
|
|
23
|
+
|
|
24
|
+
validate_configuration!
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# API Resource Accessors
|
|
28
|
+
|
|
29
|
+
def entities
|
|
30
|
+
@entities ||= Api::Entities.new(self)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def addresses
|
|
34
|
+
@addresses ||= Api::Addresses.new(self)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def roles
|
|
38
|
+
@roles ||= Api::Roles.new(self)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def trading_names
|
|
42
|
+
@trading_names ||= Api::TradingNames.new(self)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def phone_numbers
|
|
46
|
+
@phone_numbers ||= Api::PhoneNumbers.new(self)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def email_addresses
|
|
50
|
+
@email_addresses ||= Api::EmailAddresses.new(self)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def websites
|
|
54
|
+
@websites ||= Api::Websites.new(self)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def industry_classifications
|
|
58
|
+
@industry_classifications ||= Api::IndustryClassifications.new(self)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def privacy_settings
|
|
62
|
+
@privacy_settings ||= Api::PrivacySettings.new(self)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def company_details
|
|
66
|
+
@company_details ||= Api::CompanyDetails.new(self)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def watchlists
|
|
70
|
+
@watchlists ||= Api::Watchlists.new(self)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def organisation_parts
|
|
74
|
+
@organisation_parts ||= Api::OrganisationParts.new(self)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def history
|
|
78
|
+
@history ||= Api::History.new(self)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# HTTP Methods
|
|
82
|
+
|
|
83
|
+
def get(path, params = {}, headers = {})
|
|
84
|
+
request(:get, path, params, headers)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def post(path, body = {}, headers = {})
|
|
88
|
+
request(:post, path, body, headers)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def put(path, body = {}, headers = {})
|
|
92
|
+
request(:put, path, body, headers)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def patch(path, body = {}, headers = {})
|
|
96
|
+
request(:patch, path, body, headers)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def delete(path, params = {}, headers = {})
|
|
100
|
+
request(:delete, path, params, headers)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
private
|
|
104
|
+
|
|
105
|
+
def validate_configuration!
|
|
106
|
+
return if configuration.valid?
|
|
107
|
+
|
|
108
|
+
raise ConfigurationError, 'API key is required. Configure with Nzbn.configure or pass api_key to Client.new'
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def connection
|
|
112
|
+
@connection ||= Faraday.new(url: configuration.base_url) do |conn|
|
|
113
|
+
conn.request :json
|
|
114
|
+
conn.response :json, content_type: /\bjson$/
|
|
115
|
+
conn.adapter Faraday.default_adapter
|
|
116
|
+
|
|
117
|
+
conn.options.timeout = configuration.timeout
|
|
118
|
+
conn.options.open_timeout = configuration.open_timeout
|
|
119
|
+
|
|
120
|
+
if configuration.logger
|
|
121
|
+
conn.response :logger, configuration.logger
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def request(method, path, data, headers)
|
|
127
|
+
request_id = SecureRandom.uuid
|
|
128
|
+
|
|
129
|
+
merged_headers = default_headers(request_id).merge(headers)
|
|
130
|
+
|
|
131
|
+
response = connection.public_send(method) do |req|
|
|
132
|
+
req.url path
|
|
133
|
+
req.headers = merged_headers
|
|
134
|
+
|
|
135
|
+
case method
|
|
136
|
+
when :get, :delete
|
|
137
|
+
req.params = data unless data.empty?
|
|
138
|
+
else
|
|
139
|
+
req.body = data
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
handle_response(response)
|
|
144
|
+
rescue Faraday::TimeoutError => e
|
|
145
|
+
raise TimeoutError, "Request timed out: #{e.message}"
|
|
146
|
+
rescue Faraday::ConnectionFailed => e
|
|
147
|
+
raise ConnectionError, "Connection failed: #{e.message}"
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def default_headers(request_id)
|
|
151
|
+
{
|
|
152
|
+
'Ocp-Apim-Subscription-Key' => configuration.api_key,
|
|
153
|
+
'api-business-govt-nz-Request-Id' => request_id,
|
|
154
|
+
'Accept' => 'application/json',
|
|
155
|
+
'Content-Type' => 'application/json'
|
|
156
|
+
}
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def handle_response(response)
|
|
160
|
+
case response.status
|
|
161
|
+
when 200..299
|
|
162
|
+
response.body
|
|
163
|
+
when 400
|
|
164
|
+
raise ValidationError.new(response: response.body, status: response.status)
|
|
165
|
+
when 401
|
|
166
|
+
raise AuthenticationError.new('Authentication failed', response: response.body, status: response.status)
|
|
167
|
+
when 403
|
|
168
|
+
raise AuthorizationError.new('Authorization denied', response: response.body, status: response.status)
|
|
169
|
+
when 404
|
|
170
|
+
raise NotFoundError.new('Resource not found', response: response.body, status: response.status)
|
|
171
|
+
when 412
|
|
172
|
+
raise PreconditionFailedError.new('Precondition failed', response: response.body, status: response.status)
|
|
173
|
+
when 500..599
|
|
174
|
+
raise ServerError.new('Server error', response: response.body, status: response.status)
|
|
175
|
+
else
|
|
176
|
+
raise ApiError.new("Unexpected response: #{response.status}", response: response.body, status: response.status)
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nzbn
|
|
4
|
+
# Configuration class for NZBN client settings
|
|
5
|
+
#
|
|
6
|
+
# @example
|
|
7
|
+
# Nzbn.configure do |config|
|
|
8
|
+
# config.api_key = 'your-api-key'
|
|
9
|
+
# config.base_url = 'https://api.business.govt.nz/gateway/nzbn/v5'
|
|
10
|
+
# config.timeout = 30
|
|
11
|
+
# end
|
|
12
|
+
#
|
|
13
|
+
class Configuration
|
|
14
|
+
attr_accessor :api_key, :base_url, :timeout, :open_timeout, :logger
|
|
15
|
+
|
|
16
|
+
def initialize
|
|
17
|
+
@api_key = nil
|
|
18
|
+
@base_url = Nzbn::DEFAULT_BASE_URL
|
|
19
|
+
@timeout = 30
|
|
20
|
+
@open_timeout = 10
|
|
21
|
+
@logger = nil
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def valid?
|
|
25
|
+
!api_key.nil? && !api_key.empty?
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
data/lib/nzbn/error.rb
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nzbn
|
|
4
|
+
# Base error class for NZBN client
|
|
5
|
+
class Error < StandardError
|
|
6
|
+
attr_reader :response, :code
|
|
7
|
+
|
|
8
|
+
def initialize(message = nil, response: nil, code: nil)
|
|
9
|
+
@response = response
|
|
10
|
+
@code = code
|
|
11
|
+
super(message)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# API error with status code and response body
|
|
16
|
+
class ApiError < Error
|
|
17
|
+
attr_reader :status, :error_code, :error_description, :errors
|
|
18
|
+
|
|
19
|
+
def initialize(message = nil, response: nil, status: nil)
|
|
20
|
+
@status = status
|
|
21
|
+
parse_response(response) if response
|
|
22
|
+
super(message || @error_description || 'API Error', response: response, code: @error_code)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def parse_response(response)
|
|
28
|
+
return unless response.is_a?(Hash)
|
|
29
|
+
|
|
30
|
+
@error_code = response['errorCode']
|
|
31
|
+
@error_description = response['errorDescription']
|
|
32
|
+
@errors = response['list'] || []
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# 400 Bad Request - Validation errors
|
|
37
|
+
class ValidationError < ApiError; end
|
|
38
|
+
|
|
39
|
+
# 401 Unauthorized - Authentication required
|
|
40
|
+
class AuthenticationError < ApiError; end
|
|
41
|
+
|
|
42
|
+
# 403 Forbidden - Authorization denied
|
|
43
|
+
class AuthorizationError < ApiError; end
|
|
44
|
+
|
|
45
|
+
# 404 Not Found
|
|
46
|
+
class NotFoundError < ApiError; end
|
|
47
|
+
|
|
48
|
+
# 412 Precondition Failed - ETag mismatch
|
|
49
|
+
class PreconditionFailedError < ApiError; end
|
|
50
|
+
|
|
51
|
+
# 500 Internal Server Error
|
|
52
|
+
class ServerError < ApiError; end
|
|
53
|
+
|
|
54
|
+
# Connection/network errors
|
|
55
|
+
class ConnectionError < Error; end
|
|
56
|
+
|
|
57
|
+
# Timeout errors
|
|
58
|
+
class TimeoutError < Error; end
|
|
59
|
+
|
|
60
|
+
# Configuration errors
|
|
61
|
+
class ConfigurationError < Error; end
|
|
62
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nzbn
|
|
4
|
+
module Models
|
|
5
|
+
# Address model
|
|
6
|
+
class Address < Base
|
|
7
|
+
attr_accessor :unique_identifier, :start_date, :end_date,
|
|
8
|
+
:care_of, :address1, :address2, :address3, :address4,
|
|
9
|
+
:post_code, :country_code, :address_type, :paf_id, :description
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|