usps-imis-api 0.10.3 → 0.10.4
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/Readme.md +1 -372
- data/lib/usps/imis/business_object.rb +12 -0
- data/lib/usps/imis/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b058c2109e980f6706a58b10847ec6d68c943b44c6de7d5c6dbf44d00b5095e9
|
|
4
|
+
data.tar.gz: 4b49c8c39e215e09add71b36d68e86a3a3b6b6f10f999010c9d858787feaa1cc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e646b741b55e2f25395004da9ca74c3bed8a44d7a645e8a0434ec74d38315f0d9e91bbfd17c53111069627ef0ff946eb5f0075df35d375e69cc9ebdc3edfcc7e
|
|
7
|
+
data.tar.gz: 42650930b35cdef5a05bc361796d2665ff16ca50a005a268551220d2ba6dd2983d451dfa3dd3ebb00886229224078a6ba44eeabf27aad03e5a32d52e4e8ea417
|
data/Readme.md
CHANGED
|
@@ -39,380 +39,9 @@ Usps::Imis.configure do |config|
|
|
|
39
39
|
end
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
When using `bin/console`, this configuration will be run by default.
|
|
43
|
-
|
|
44
|
-
Instantiate the API object:
|
|
45
|
-
|
|
46
|
-
```ruby
|
|
47
|
-
api = Usps::Imis::Api.new
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
If you already have an iMIS ID to work with, you can pass that in immediately:
|
|
51
|
-
|
|
52
|
-
```ruby
|
|
53
|
-
api = Usps::Imis::Api.new(imis_id: imis_id)
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
### Authentication
|
|
57
|
-
|
|
58
|
-
If a token is not available, this will automatically fetch one when needed. As long as that token
|
|
59
|
-
should still be valid, it will reuse the same token. If the token should expire, this will
|
|
60
|
-
automatically request a new token.
|
|
61
|
-
|
|
62
42
|
## Usage
|
|
63
43
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
To act on member data, you need to have the iMIS ID. If you already have access to that from the
|
|
67
|
-
database, you can skip this step.
|
|
68
|
-
|
|
69
|
-
To convert a member's certificate number into their iMIS ID, run the following method:
|
|
70
|
-
|
|
71
|
-
```ruby
|
|
72
|
-
api.imis_id_for(certificate)
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
This will both return the ID, and store it for use with other requests. If you need to change which
|
|
76
|
-
member you are working with, just run this method again with the new certificate number.
|
|
77
|
-
|
|
78
|
-
You can also manually set the current ID, if you already have it for a given member
|
|
79
|
-
|
|
80
|
-
```ruby
|
|
81
|
-
api.imis_id = imis_id
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
#### Without an iMIS ID
|
|
85
|
-
|
|
86
|
-
Running requests without an iMIS ID set will raise an exception.
|
|
87
|
-
|
|
88
|
-
If you want to query the entire Business Object, use the query interface instead:
|
|
89
|
-
|
|
90
|
-
```ruby
|
|
91
|
-
api = Usps::Imis::Api.new # No iMIS ID set
|
|
92
|
-
|
|
93
|
-
# These requests are identical:
|
|
94
|
-
|
|
95
|
-
Usps::Imis::Query.new(api, 'ABC_ASC_Individual_Demog')
|
|
96
|
-
|
|
97
|
-
api.on('ABC_ASC_Individual_Demog').query
|
|
98
|
-
|
|
99
|
-
api.query('ABC_ASC_Individual_Demog')
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### Business Object and Panel Actions
|
|
103
|
-
|
|
104
|
-
Business Objects and Panels support the following actions.
|
|
105
|
-
|
|
106
|
-
Panels require passing in the ordinal identifier as an argument, except for `POST`.
|
|
107
|
-
|
|
108
|
-
#### GET
|
|
109
|
-
|
|
110
|
-
To fetch member data, run e.g.:
|
|
111
|
-
|
|
112
|
-
```ruby
|
|
113
|
-
data = api.on('ABC_ASC_Individual_Demog').get
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
You can also pass in specific field names to filter the returned member data, e.g.:
|
|
117
|
-
|
|
118
|
-
```ruby
|
|
119
|
-
data = api.on('ABC_ASC_Individual_Demog').get('TotMMS', 'MMS_Updated')
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
The response from `get` behaves like a Hash, but directly accesses property values by name.
|
|
123
|
-
If you need to access the rest of the underlying data, use the `raw` method:
|
|
124
|
-
|
|
125
|
-
```ruby
|
|
126
|
-
data = api.on('ABC_ASC_Individual_Demog').get
|
|
127
|
-
data['TotMMS']
|
|
128
|
-
data.raw['EntityTypeName']
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
Alias: `read`
|
|
132
|
-
|
|
133
|
-
#### GET Field
|
|
134
|
-
|
|
135
|
-
To fetch a specific field from member data, run e.g.:
|
|
136
|
-
|
|
137
|
-
```ruby
|
|
138
|
-
tot_mms = api.on('ABC_ASC_Individual_Demog').get_field('TotMMS')
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
You can also access fields directly on the Business Object or Panel like a Hash:
|
|
142
|
-
|
|
143
|
-
```ruby
|
|
144
|
-
tot_mms = api.on('ABC_ASC_Individual_Demog')['TotMMS']
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
Alias: `fetch`
|
|
148
|
-
|
|
149
|
-
#### GET Fields
|
|
150
|
-
|
|
151
|
-
To fetch multiple specific fields from member data, run e.g.:
|
|
152
|
-
|
|
153
|
-
```ruby
|
|
154
|
-
data = api.on('ABC_ASC_Individual_Demog').get_fields('TotMMS', 'MMS_Updated')
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
Alias: `fetch_all`
|
|
158
|
-
|
|
159
|
-
#### PUT Fields
|
|
160
|
-
|
|
161
|
-
To update member data, run e.g.:
|
|
162
|
-
|
|
163
|
-
```ruby
|
|
164
|
-
data = { 'MMS_Updated' => Time.now.strftime('%Y-%m-%dT%H:%M:%S'), 'TotMMS' => new_total }
|
|
165
|
-
update = api.on('ABC_ASC_Individual_Demog').put_fields(data)
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
This method fetches the current data structure, and filters it down to just what you want to
|
|
169
|
-
update, to reduce the likelihood of update collisions or type validation failures.
|
|
170
|
-
|
|
171
|
-
Alias: `patch`
|
|
172
|
-
|
|
173
|
-
#### PUT
|
|
174
|
-
|
|
175
|
-
To update member data, run e.g.:
|
|
176
|
-
|
|
177
|
-
```ruby
|
|
178
|
-
update = api.on('ABC_ASC_Individual_Demog').put(complete_imis_object)
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
This method requires a complete iMIS data structure. However, any properties not included will be
|
|
182
|
-
left unmodified (meaning this also effectively handles `PATCH`, though iMIS does not accept that
|
|
183
|
-
HTTP verb).
|
|
184
|
-
|
|
185
|
-
Alias: `update`
|
|
186
|
-
|
|
187
|
-
#### POST
|
|
188
|
-
|
|
189
|
-
To create new member data, run e.g.:
|
|
190
|
-
|
|
191
|
-
```ruby
|
|
192
|
-
created = api.on('ABC_ASC_Individual_Demog').post(complete_imis_object)
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
This method requires a complete iMIS data structure.
|
|
196
|
-
|
|
197
|
-
Alias: `create`
|
|
198
|
-
|
|
199
|
-
#### DELETE
|
|
200
|
-
|
|
201
|
-
To remove member data, run e.g.:
|
|
202
|
-
|
|
203
|
-
```ruby
|
|
204
|
-
api.on('ABC_ASC_Individual_Demog').delete
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
Alias: `destroy`
|
|
208
|
-
|
|
209
|
-
### QUERY
|
|
210
|
-
|
|
211
|
-
Run an IQA Query
|
|
212
|
-
|
|
213
|
-
`query_params` is a hash of shape: `{ param_name => param_value }`
|
|
214
|
-
|
|
215
|
-
```ruby
|
|
216
|
-
query = api.query(query_name, query_params)
|
|
217
|
-
|
|
218
|
-
query.each do |item|
|
|
219
|
-
# Download all pages of the query, then iterate on the results
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
query.find_each do |item|
|
|
223
|
-
# Iterate one page at a time, fetching new pages automatically
|
|
224
|
-
end
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
### Field Mapper
|
|
228
|
-
|
|
229
|
-
For fields that have already been mapped between the ITCom database and iMIS, you can use the
|
|
230
|
-
Mapper class to further simplify the `fetch` / `update` interfaces:
|
|
231
|
-
|
|
232
|
-
```ruby
|
|
233
|
-
mm = api.mapper.fetch(:mm)
|
|
234
|
-
mm = api.mapper[:mm]
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
```ruby
|
|
238
|
-
api.mapper.update(mm: 15)
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
For simplicity, you can also call `fetch` (or simply use Hash access syntax) and `update` on the
|
|
242
|
-
`Api` class directly:
|
|
243
|
-
|
|
244
|
-
```ruby
|
|
245
|
-
api.fetch(:mm)
|
|
246
|
-
api[:mm]
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
```ruby
|
|
250
|
-
api.update(mm: 15)
|
|
251
|
-
api[:mm] = 15
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
If there is no known mapping for the requested field, the Mapper will give up, but will provide
|
|
255
|
-
you with the standard API call syntax, and will suggest you inform ITCom leadership of the new
|
|
256
|
-
mapping you need.
|
|
257
|
-
|
|
258
|
-
### Panels
|
|
259
|
-
|
|
260
|
-
For supported panels (usually, business objects with composite identity keys), you can interact
|
|
261
|
-
with them in the same general way:
|
|
262
|
-
|
|
263
|
-
```ruby
|
|
264
|
-
vsc = Usps::Imis::Panels::Vsc.new(imis_id: 6374)
|
|
265
|
-
|
|
266
|
-
vsc.get(1417)
|
|
267
|
-
|
|
268
|
-
# All of these options are identical
|
|
269
|
-
#
|
|
270
|
-
vsc.get(1417, 'Quantity').first
|
|
271
|
-
vsc.get(1417)['Quantity']
|
|
272
|
-
vsc[1417, 'Quantity']
|
|
273
|
-
vsc.get(1417).raw['Properties']['$values'].find { it['Name'] == 'Quantity' }['Value']['$value']
|
|
274
|
-
vsc.get_field(1417, 'Quantity')
|
|
275
|
-
|
|
276
|
-
created = vsc.create(certificate: 'E136924', year: 2024, count: 42)
|
|
277
|
-
|
|
278
|
-
# Get the Ordinal identifier from the response
|
|
279
|
-
#
|
|
280
|
-
# All of these options are identical
|
|
281
|
-
#
|
|
282
|
-
ordinal = created.ordinal
|
|
283
|
-
ordinal = created['Ordinal']
|
|
284
|
-
ordinal = created.raw['Properties']['$values'].find { it['Name'] == 'Ordinal' }['Value']['$value']
|
|
285
|
-
ordinal = created.raw['Identity']['IdentityElements']['$values'][1].to_i # Value is duplicated here
|
|
286
|
-
|
|
287
|
-
vsc.update(certificate: 'E136924', year: 2024, count: 43, ordinal: ordinal)
|
|
288
|
-
|
|
289
|
-
vsc.put_fields(ordinal, 'Quantity' => 44)
|
|
290
|
-
vsc[ordinal, 'Quantity'] = 44
|
|
291
|
-
|
|
292
|
-
vsc.destroy(ordinal)
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
If you already have an iMIS ID to work with, you can pass that in immediately:
|
|
296
|
-
|
|
297
|
-
```ruby
|
|
298
|
-
vsc = Usps::Imis::Panels::Vsc.new(imis_id: imis_id)
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
Panels are also accessible directly from the API object:
|
|
302
|
-
|
|
303
|
-
```ruby
|
|
304
|
-
api.panels.vsc.get(1417)
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
### DSL Mode
|
|
308
|
-
|
|
309
|
-
Instead of manually setting the current iMIS ID, then running individual queries, you can instead
|
|
310
|
-
run queries in DSL mode. This specifies the iMIS ID for the scope of the block, then reverts to the
|
|
311
|
-
previous value.
|
|
312
|
-
|
|
313
|
-
```ruby
|
|
314
|
-
api.with(31092) do
|
|
315
|
-
# These requests are identical:
|
|
316
|
-
|
|
317
|
-
on('ABC_ASC_Individual_Demog') { put_fields('TotMMS' => 15) }
|
|
318
|
-
|
|
319
|
-
on('ABC_ASC_Individual_Demog').put_fields('TotMMS' => 15)
|
|
320
|
-
|
|
321
|
-
mapper.update(mm: 15)
|
|
322
|
-
|
|
323
|
-
update(mm: 15)
|
|
324
|
-
|
|
325
|
-
mapper[:mm] = 15
|
|
326
|
-
end
|
|
327
|
-
|
|
328
|
-
# This request fetches the same data, but leaves the iMIS ID selected
|
|
329
|
-
api.with(31092)[:mm] = 15
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
```ruby
|
|
333
|
-
api.with(6374) do
|
|
334
|
-
panels.vsc.get(1417)
|
|
335
|
-
end
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
```ruby
|
|
339
|
-
api.with(31092) do
|
|
340
|
-
# These requests are identical:
|
|
341
|
-
|
|
342
|
-
on('ABC_ASC_Individual_Demog') do
|
|
343
|
-
get.raw['Properties']['$values'].find { it['Name'] == 'TotMMS' }['Value']['$value']
|
|
344
|
-
|
|
345
|
-
get['TotMMS']
|
|
346
|
-
|
|
347
|
-
get_field('TotMMS')
|
|
348
|
-
|
|
349
|
-
get_fields('TotMMS').first
|
|
350
|
-
end
|
|
351
|
-
|
|
352
|
-
on('ABC_ASC_Individual_Demog').get_field('TotMMS')
|
|
353
|
-
|
|
354
|
-
on('ABC_ASC_Individual_Demog')['TotMMS']
|
|
355
|
-
end
|
|
356
|
-
|
|
357
|
-
# These requests fetch the same data, but leave the iMIS ID selected
|
|
358
|
-
api.with(31092).on('ABC_ASC_Individual_Demog').get_field('TotMMS')
|
|
359
|
-
api.with(31092).on('ABC_ASC_Individual_Demog')['TotMMS']
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
### Data Methods
|
|
363
|
-
|
|
364
|
-
Data responses from the API can be handled as a standard Hash using the `raw` method.
|
|
365
|
-
|
|
366
|
-
If you need to access all of the property values, you can use the `properties` method.
|
|
367
|
-
By default, this will exclude the `ID` and `Ordinal` properties; they can be included with
|
|
368
|
-
`properties(include_ids: true)`.
|
|
369
|
-
|
|
370
|
-
## Test Data Mocking
|
|
371
|
-
|
|
372
|
-
You can use the provided Business Object Mock to generate stub data for rspec:
|
|
373
|
-
|
|
374
|
-
```ruby
|
|
375
|
-
allow(api).to(
|
|
376
|
-
receive(:on).with('ABC_ASC_Individual_Demog').and_return(
|
|
377
|
-
Usps::Imis::Mocks::BusinessObject.new(TotMMS: 2)
|
|
378
|
-
)
|
|
379
|
-
)
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
### VCR
|
|
383
|
-
|
|
384
|
-
If you would like to use the included VCR config, make sure your Gemfile includes the required gems:
|
|
385
|
-
|
|
386
|
-
```ruby
|
|
387
|
-
gem 'cgi' # 2025-10-27 - Currently required for Ruby 3.5
|
|
388
|
-
gem 'vcr'
|
|
389
|
-
gem 'webmock'
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
In `spec_helper.rb`, add the following:
|
|
393
|
-
|
|
394
|
-
```ruby
|
|
395
|
-
require 'usps/vcr'
|
|
396
|
-
Usps::Vcr::Config.configure!
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
You can also pass additional VCR config options through:
|
|
400
|
-
|
|
401
|
-
```ruby
|
|
402
|
-
Usps::Vcr::Config.configure! do |config|
|
|
403
|
-
config.ignore_localhost = true
|
|
404
|
-
end
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
If you have any tests that are dependent on ordering to (re-)generate cassettes, a helper is also
|
|
408
|
-
available to support adding example metadata, which will use a fixed order when the environment
|
|
409
|
-
varialbe `VCR=all` is set:
|
|
410
|
-
|
|
411
|
-
```ruby
|
|
412
|
-
describe 'examples that care about order', order: Usps::Vcr::Config.vcr_record_ordered do
|
|
413
|
-
# ...
|
|
414
|
-
end
|
|
415
|
-
```
|
|
44
|
+
For more details and examples, refer to the [Wiki](https://github.com/unitedstatespowersquadrons/imis-api-ruby/wiki).
|
|
416
45
|
|
|
417
46
|
## Exception Handling
|
|
418
47
|
|
|
@@ -39,6 +39,18 @@ module Usps
|
|
|
39
39
|
#
|
|
40
40
|
def query = api.query(business_object_name)
|
|
41
41
|
|
|
42
|
+
# Support passthrough for Api#with
|
|
43
|
+
#
|
|
44
|
+
def with(imis_id, &)
|
|
45
|
+
# Bring into local scope
|
|
46
|
+
wrapper_business_object_name = business_object_name
|
|
47
|
+
wrapper_ordinal = ordinal
|
|
48
|
+
|
|
49
|
+
api.with(imis_id) do
|
|
50
|
+
on(wrapper_business_object_name, ordinal: wrapper_ordinal, &)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
42
54
|
# Get a business object for the current member
|
|
43
55
|
#
|
|
44
56
|
# If +fields+ is provided, will return only those field values
|
data/lib/usps/imis/version.rb
CHANGED