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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9a699891bdb0679741aafb3754e7939bfcd7f854b51e6cab76c25f6d9fc69995
4
- data.tar.gz: 97ff09a0b7d9c1981b9170c96e3885e57f82465e08fa8a8be4c1b20cf7c8f822
3
+ metadata.gz: b058c2109e980f6706a58b10847ec6d68c943b44c6de7d5c6dbf44d00b5095e9
4
+ data.tar.gz: 4b49c8c39e215e09add71b36d68e86a3a3b6b6f10f999010c9d858787feaa1cc
5
5
  SHA512:
6
- metadata.gz: 49f73bb0e65581cb15cb8004170ed22963e025693e8fb62f33a09b6c2afa5ca548a9a37354867679a9562205ff752a18b812bcca085b1b575c3c5bc48ec45564
7
- data.tar.gz: 5f455a1a8a0231e08d6b83297ebcfcfea0c423dc6396ae4e1ec312d6da52e111b6a25babc978f232631242ac86da14499cfc2d6ac246c90779e41be6049b3fb7
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
- ### iMIS ID
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Usps
4
4
  module Imis
5
- VERSION = '0.10.3'
5
+ VERSION = '0.10.4'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: usps-imis-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.3
4
+ version: 0.10.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julian Fiander