usps-imis-api 0.1.3 → 0.2.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/Gemfile.lock +1 -1
- data/Readme.md +33 -3
- data/lib/imis/api.rb +37 -8
- data/lib/imis/mapper.rb +4 -4
- data/lib/imis/panel/vsc.rb +126 -0
- data/lib/usps-imis-api.rb +1 -0
- data/spec/lib/imis/api_spec.rb +4 -2
- data/spec/lib/imis/panel/vsc_spec.rb +38 -0
- data/usps-imis-api.gemspec +1 -1
- 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: 596057339ef96ddfa1bc884107307bae2bedfa3ef28610f1293218362daa53ad
|
4
|
+
data.tar.gz: 304f7b47a0923b08646266b71365049074235d24983abaa78fac615f0b02e5cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec4ec8cedb9966992b4e6d86b34e2a219c3f6cc28d4c01622d460e1f1f7c44fdfa8c6aa76f3aad1fb97b2e44f75366eb7060f9685b83c1bca21937c8b778414f
|
7
|
+
data.tar.gz: 412e3f664b0384330956c11eee3ce11f0c6bb77a3154d24fb4c671e34d919628fb58f7780a92b5a164cb987de8f43893308a7de9f892580a3f6478515d861b3b
|
data/Gemfile.lock
CHANGED
data/Readme.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# USPS iMIS API for Ruby
|
2
2
|
|
3
|
-

|
3
|
+
[](https://rubygems.org/gems/usps-imis-api)
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -112,7 +112,7 @@ Update only specific fields on a business object for the current member
|
|
112
112
|
`fields` is a hash of shape: `{ field_name => new_value }`
|
113
113
|
|
114
114
|
```ruby
|
115
|
-
api.
|
115
|
+
api.put_fields(business_object_name, fields)
|
116
116
|
```
|
117
117
|
|
118
118
|
Run an IQA Query
|
@@ -132,10 +132,36 @@ Mapper class to further simplify the update interface:
|
|
132
132
|
api.mapper.update(mm: 15)
|
133
133
|
```
|
134
134
|
|
135
|
+
For simplicity, you can also call `update` on the `Api` class directly:
|
136
|
+
|
137
|
+
```ruby
|
138
|
+
api.update(mm: 15)
|
139
|
+
```
|
140
|
+
|
135
141
|
If there is no known mapping for the requested field, the Mapper will give up, but will provide
|
136
142
|
you with the standard API call syntax, and will suggest you inform ITCom leadership of the new
|
137
143
|
mapping you need.
|
138
144
|
|
145
|
+
### Panels
|
146
|
+
|
147
|
+
For supported panels (usually, business objects with composite identity keys), you can interact
|
148
|
+
with them in the same general way:
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
vsc = Imis::Panel::Vsc.new
|
152
|
+
|
153
|
+
vsc.api.imis_id = 6374
|
154
|
+
|
155
|
+
vsc.get(1417)
|
156
|
+
|
157
|
+
created = vsc.create(certificate: 'E136924', year: 2024, count: 42)
|
158
|
+
ordinal = created['Properties']['$values'][1]['Value']['$value']
|
159
|
+
|
160
|
+
vsc.update(certificate: 'E136924', year: 2024, count: 43, ordinal: ordinal)
|
161
|
+
|
162
|
+
vsc.destroy(ordinal)
|
163
|
+
```
|
164
|
+
|
139
165
|
### DSL Mode
|
140
166
|
|
141
167
|
Instead of manually setting the current iMIS ID, then running individual queries, you can instead
|
@@ -144,9 +170,13 @@ previous value.
|
|
144
170
|
|
145
171
|
```ruby
|
146
172
|
api.with(31092) do
|
147
|
-
# These
|
173
|
+
# These three requests are identical:
|
174
|
+
|
148
175
|
put('ABC_ASC_Individual_Demog', { 'TotMMS' => 15 })
|
176
|
+
|
149
177
|
mapper.update(mm: 15)
|
178
|
+
|
179
|
+
update(mm: 15)
|
150
180
|
end
|
151
181
|
```
|
152
182
|
|
data/lib/imis/api.rb
CHANGED
@@ -39,8 +39,8 @@ module Imis
|
|
39
39
|
|
40
40
|
# Get a business object for the current member
|
41
41
|
#
|
42
|
-
def get(business_object_name)
|
43
|
-
uri = uri_for(business_object_name)
|
42
|
+
def get(business_object_name, url_id: nil)
|
43
|
+
uri = uri_for(business_object_name, url_id: url_id)
|
44
44
|
request = Net::HTTP::Get.new(uri)
|
45
45
|
result = submit(uri, authorize(request))
|
46
46
|
JSON.parse(result.body)
|
@@ -50,15 +50,42 @@ module Imis
|
|
50
50
|
#
|
51
51
|
# fields - hash of shape: { field_name => new_value }
|
52
52
|
#
|
53
|
-
def
|
54
|
-
uri = uri_for(business_object_name)
|
55
|
-
request = Net::HTTP::Put.new(uri)
|
53
|
+
def put_fields(business_object_name, fields, url_id: nil)
|
56
54
|
updated = filter_fields(business_object_name, fields)
|
57
|
-
|
55
|
+
put(business_object_name, updated, url_id: url_id)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Update a business object for the current member
|
59
|
+
#
|
60
|
+
def put(business_object_name, body, url_id: nil)
|
61
|
+
uri = uri_for(business_object_name, url_id: url_id)
|
62
|
+
request = Net::HTTP::Put.new(uri)
|
63
|
+
request.body = JSON.dump(body)
|
58
64
|
result = submit(uri, authorize(request))
|
59
65
|
JSON.parse(result.body)
|
60
66
|
end
|
61
67
|
|
68
|
+
# Create a business object for the current member
|
69
|
+
#
|
70
|
+
def post(business_object_name, body, url_id: nil)
|
71
|
+
uri = uri_for(business_object_name, url_id: url_id)
|
72
|
+
request = Net::HTTP::Post.new(uri)
|
73
|
+
request.body = JSON.dump(body)
|
74
|
+
result = submit(uri, authorize(request))
|
75
|
+
JSON.parse(result.body)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Remove a business object for the current member
|
79
|
+
#
|
80
|
+
# Returns empty string on success
|
81
|
+
#
|
82
|
+
def delete(business_object_name, url_id: nil)
|
83
|
+
uri = uri_for(business_object_name, url_id: url_id)
|
84
|
+
request = Net::HTTP::Delete.new(uri)
|
85
|
+
result = submit(uri, authorize(request))
|
86
|
+
result.body
|
87
|
+
end
|
88
|
+
|
62
89
|
# Run an IQA Query
|
63
90
|
#
|
64
91
|
# query_name - the full path of the query in IQA, e.g. `$/_ABC/Fiander/iMIS_ID`
|
@@ -105,8 +132,10 @@ module Imis
|
|
105
132
|
|
106
133
|
# Construct a business object API endpoint address
|
107
134
|
#
|
108
|
-
def uri_for(business_object_name)
|
109
|
-
|
135
|
+
def uri_for(business_object_name, url_id: nil)
|
136
|
+
url_id ||= imis_id
|
137
|
+
url_id = CGI.escape(url_id)
|
138
|
+
URI(File.join(imis_hostname, "#{API_PATH}/#{business_object_name}/#{url_id}"))
|
110
139
|
end
|
111
140
|
|
112
141
|
def submit(uri, request)
|
data/lib/imis/mapper.rb
CHANGED
@@ -10,8 +10,8 @@ module Imis
|
|
10
10
|
|
11
11
|
attr_reader :api
|
12
12
|
|
13
|
-
def initialize(api)
|
14
|
-
@api = api
|
13
|
+
def initialize(api = nil)
|
14
|
+
@api = api || Api.new
|
15
15
|
end
|
16
16
|
|
17
17
|
# Update a member's data on multiple affected business objects by arbitrary field names
|
@@ -30,7 +30,7 @@ module Imis
|
|
30
30
|
end
|
31
31
|
|
32
32
|
updates.map do |business_object_name, field_updates|
|
33
|
-
api.
|
33
|
+
api.put_fields(business_object_name, field_updates)
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -49,7 +49,7 @@ module Imis
|
|
49
49
|
unless ENV['TESTING']
|
50
50
|
warn(
|
51
51
|
"Mapper does not know how to handle field \"#{field_name}\".\n\n" \
|
52
|
-
'You can use api.
|
52
|
+
'You can use api.put_fields(business_object_name, { field_name => value }) ' \
|
53
53
|
"if you know the business object and iMIS-specific field name.\n\n"
|
54
54
|
)
|
55
55
|
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Imis
|
4
|
+
module Panel
|
5
|
+
class Vsc
|
6
|
+
BUSINESS_OBJECT = 'ABC_ASC_Vessel_Safety_Checks'
|
7
|
+
|
8
|
+
attr_reader :api
|
9
|
+
|
10
|
+
def initialize(api = nil)
|
11
|
+
@api = api || Api.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def get(ordinal)
|
15
|
+
api.get(BUSINESS_OBJECT, url_id: "~#{api.imis_id}|#{ordinal}")
|
16
|
+
end
|
17
|
+
|
18
|
+
def create(data)
|
19
|
+
api.post(BUSINESS_OBJECT, payload(data), url_id: '')
|
20
|
+
end
|
21
|
+
|
22
|
+
def update(data)
|
23
|
+
api.put(BUSINESS_OBJECT, payload(data), url_id: "~#{api.imis_id}|#{data[:ordinal]}")
|
24
|
+
end
|
25
|
+
|
26
|
+
def destroy(ordinal)
|
27
|
+
api.delete(BUSINESS_OBJECT, url_id: "~#{api.imis_id}|#{ordinal}")
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
# rubocop:disable Metrics/MethodLength
|
33
|
+
def payload(data)
|
34
|
+
{
|
35
|
+
'$type' => 'Asi.Soa.Core.DataContracts.GenericEntityData, Asi.Contracts',
|
36
|
+
'EntityTypeName' => 'ABC_ASC_Vessel_Safety_Checks',
|
37
|
+
'PrimaryParentEntityTypeName' => 'Party',
|
38
|
+
'Identity' => {
|
39
|
+
'$type' => 'Asi.Soa.Core.DataContracts.IdentityData, Asi.Contracts',
|
40
|
+
'EntityTypeName' => 'ABC_ASC_Vessel_Safety_Checks',
|
41
|
+
'IdentityElements' => {
|
42
|
+
'$type' =>
|
43
|
+
'System.Collections.ObjectModel.Collection`1[[System.String, mscorlib]], mscorlib',
|
44
|
+
'$values' => [api.imis_id]
|
45
|
+
}
|
46
|
+
},
|
47
|
+
'PrimaryParentIdentity' => {
|
48
|
+
'$type' => 'Asi.Soa.Core.DataContracts.IdentityData, Asi.Contracts',
|
49
|
+
'EntityTypeName' => 'Party',
|
50
|
+
'IdentityElements' => {
|
51
|
+
'$type' =>
|
52
|
+
'System.Collections.ObjectModel.Collection`1[[System.String, mscorlib]], mscorlib',
|
53
|
+
'$values' => [api.imis_id]
|
54
|
+
}
|
55
|
+
},
|
56
|
+
'Properties' => {
|
57
|
+
'$type' => 'Asi.Soa.Core.DataContracts.GenericPropertyDataCollection, Asi.Contracts',
|
58
|
+
'$values' => [
|
59
|
+
{
|
60
|
+
'$type' => 'Asi.Soa.Core.DataContracts.GenericPropertyData, Asi.Contracts',
|
61
|
+
'Name' => 'ID',
|
62
|
+
'Value' => api.imis_id
|
63
|
+
},
|
64
|
+
(
|
65
|
+
if data[:ordinal]
|
66
|
+
{
|
67
|
+
'$type' => 'Asi.Soa.Core.DataContracts.GenericPropertyData, Asi.Contracts',
|
68
|
+
'Name' => 'Ordinal',
|
69
|
+
'Value' => {
|
70
|
+
'$type' => 'System.Int32',
|
71
|
+
'$value' => data[:ordinal]
|
72
|
+
}
|
73
|
+
}
|
74
|
+
end
|
75
|
+
),
|
76
|
+
{
|
77
|
+
'$type' => 'Asi.Soa.Core.DataContracts.GenericPropertyData, Asi.Contracts',
|
78
|
+
'Name' => 'Source_System',
|
79
|
+
'Value' => 'Manual ITCom Entry'
|
80
|
+
},
|
81
|
+
{
|
82
|
+
'$type' => 'Asi.Soa.Core.DataContracts.GenericPropertyData, Asi.Contracts',
|
83
|
+
'Name' => 'ABC_ECertificate',
|
84
|
+
'Value' => data[:certificate]
|
85
|
+
},
|
86
|
+
{
|
87
|
+
'$type' => 'Asi.Soa.Core.DataContracts.GenericPropertyData, Asi.Contracts',
|
88
|
+
'Name' => 'Activity_Type',
|
89
|
+
'Value' => 'VSC'
|
90
|
+
},
|
91
|
+
{
|
92
|
+
'$type' => 'Asi.Soa.Core.DataContracts.GenericPropertyData, Asi.Contracts',
|
93
|
+
'Name' => 'Description',
|
94
|
+
'Value' => 'Vessel Safety Checks'
|
95
|
+
},
|
96
|
+
{
|
97
|
+
'$type' => 'Asi.Soa.Core.DataContracts.GenericPropertyData, Asi.Contracts',
|
98
|
+
'Name' => 'Effective_Date',
|
99
|
+
'Value' => "#{data[:year]}-12-01T00:00:00"
|
100
|
+
},
|
101
|
+
{
|
102
|
+
'$type' => 'Asi.Soa.Core.DataContracts.GenericPropertyData, Asi.Contracts',
|
103
|
+
'Name' => 'Quantity',
|
104
|
+
'Value' => {
|
105
|
+
'$type' => 'System.Int32',
|
106
|
+
'$value' => data[:count]
|
107
|
+
}
|
108
|
+
},
|
109
|
+
{
|
110
|
+
'$type' => 'Asi.Soa.Core.DataContracts.GenericPropertyData, Asi.Contracts',
|
111
|
+
'Name' => 'Thru_Date',
|
112
|
+
'Value' => "#{data[:year]}-12-31T00:00:00"
|
113
|
+
},
|
114
|
+
{
|
115
|
+
'$type' => 'Asi.Soa.Core.DataContracts.GenericPropertyData, Asi.Contracts',
|
116
|
+
'Name' => 'Transaction_Date',
|
117
|
+
'Value' => Time.now.strftime('%Y-%m-%dT%H:%M:%S')
|
118
|
+
}
|
119
|
+
].compact
|
120
|
+
}
|
121
|
+
}
|
122
|
+
end
|
123
|
+
# rubocop:enable Metrics/MethodLength
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
data/lib/usps-imis-api.rb
CHANGED
data/spec/lib/imis/api_spec.rb
CHANGED
@@ -15,13 +15,15 @@ describe Imis::Api do
|
|
15
15
|
before { api.imis_id = 31092 }
|
16
16
|
|
17
17
|
it 'sends an update' do
|
18
|
-
expect(api.
|
18
|
+
expect(api.put_fields('ABC_ASC_Individual_Demog', { 'TotMMS' => 15 })).to be_a(Hash)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
describe '#with' do
|
23
23
|
it 'sends an update from put' do
|
24
|
-
expect(
|
24
|
+
expect(
|
25
|
+
api.with(31092) { put_fields('ABC_ASC_Individual_Demog', { 'TotMMS' => 15 }) }
|
26
|
+
).to be_a(Hash)
|
25
27
|
end
|
26
28
|
|
27
29
|
it 'sends an update from update' do
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Imis::Panel::Vsc do
|
6
|
+
let(:vsc) { described_class.new }
|
7
|
+
|
8
|
+
let(:details) do
|
9
|
+
{
|
10
|
+
certificate: 'E136924',
|
11
|
+
year: 2024,
|
12
|
+
count: 42
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
before { vsc.api.imis_id = 6374 }
|
17
|
+
|
18
|
+
describe '#get' do
|
19
|
+
it 'loads a specific object' do
|
20
|
+
expect(vsc.get(1433)).to be_a(Hash)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# rubocop:disable RSpec/ExampleLength
|
25
|
+
it 'handles new records correctly', :aggregate_failures do
|
26
|
+
new_record = vsc.create(details)
|
27
|
+
expect(new_record).to be_a(Hash)
|
28
|
+
|
29
|
+
ordinal = new_record['Properties']['$values'][1]['Value']['$value']
|
30
|
+
|
31
|
+
update_result = vsc.update(details.merge(count: 43, ordinal: ordinal))
|
32
|
+
updated = update_result['Properties']['$values'].find { |v| v['Name'] == 'Quantity' }
|
33
|
+
expect(updated['Value']['$value']).to eq(43)
|
34
|
+
|
35
|
+
expect(vsc.destroy(ordinal)).to eq('')
|
36
|
+
end
|
37
|
+
# rubocop:enable RSpec/ExampleLength
|
38
|
+
end
|
data/usps-imis-api.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: usps-imis-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julian Fiander
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-10-
|
11
|
+
date: 2024-10-30 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A wrapper for the iMIS API.
|
14
14
|
email: jsfiander@gmail.com
|
@@ -30,9 +30,11 @@ files:
|
|
30
30
|
- lib/imis/error/api.rb
|
31
31
|
- lib/imis/error/mapper.rb
|
32
32
|
- lib/imis/mapper.rb
|
33
|
+
- lib/imis/panel/vsc.rb
|
33
34
|
- lib/usps-imis-api.rb
|
34
35
|
- spec/lib/imis/api_spec.rb
|
35
36
|
- spec/lib/imis/mapper_spec.rb
|
37
|
+
- spec/lib/imis/panel/vsc_spec.rb
|
36
38
|
- spec/spec_helper.rb
|
37
39
|
- usps-imis-api.gemspec
|
38
40
|
homepage: http://rubygems.org/gems/usps-imis-api
|