diff --git a/ramls/dereferenceditem-without-pub-period.json b/ramls/dereferenceditem-without-pub-period.json new file mode 100644 index 000000000..58b6789ac --- /dev/null +++ b/ramls/dereferenceditem-without-pub-period.json @@ -0,0 +1,416 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "An item record with related record data", + "type": "object", + "javaType": "org.folio.rest.jaxrs.model.DereferencedItemWithoutPubPeriod", + "properties": { + "id": { + "type": "string", + "description": "Unique ID of the item record" + }, + "instanceRecord":{ + "type": "object", + "description" : "Parent instance record without the publicationPeriod.", + "$ref": "instance-without-pub-period.json" + }, + "_version": { + "type": "integer", + "description": "Record version for optimistic locking" + }, + "hrid": { + "type": "string", + "description": "The human readable ID, also called eye readable ID. A system-assigned sequential alternate ID" + }, + "holdingsRecord": { + "type": "object", + "description": "Holdings record the item is a member of.", + "$ref": "holdings-storage/holdingsRecord.json" + }, + "formerIds": { + "type": "array", + "description": "Previous identifiers assigned to the item", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "discoverySuppress": { + "type": "boolean", + "description": "Records the fact that the record should not be displayed in a discovery system" + }, + "accessionNumber": { + "type": "string", + "description": "Also called inventar number" + }, + "barcode": { + "type": "string", + "description": "Unique inventory control number for physical resources, used largely for circulation purposes" + }, + "effectiveShelvingOrder": { + "type": "string", + "description": "A system generated normalization of the call number that allows for call number sorting in reports and search results", + "readonly": true + }, + "itemLevelCallNumber": { + "type": "string", + "description": "Call Number is an identifier assigned to an item, usually printed on a label attached to the item. The call number is used to determine the items physical position in a shelving sequence, e.g. K1 .M44. The Item level call number, is the call number on item level." + }, + "itemLevelCallNumberPrefix": { + "type": "string", + "description": "Prefix of the call number on the item level." + }, + "itemLevelCallNumberSuffix": { + "type": "string", + "description": "Suffix of the call number on the item level." + }, + "itemLevelCallNumberTypeId": { + "type": "string", + "description": "Identifies the source of the call number, e.g., LCC, Dewey, NLM, etc." + }, + "effectiveCallNumberComponents": { + "type": "object", + "description": "Elements of a full call number generated from the item or holding", + "properties": { + "callNumber": { + "type": "string", + "description": "Effective Call Number is an identifier assigned to an item or its holding and associated with the item.", + "readonly": true + }, + "prefix": { + "type": "string", + "description": "Effective Call Number Prefix is the prefix of the identifier assigned to an item or its holding and associated with the item.", + "readonly": true + }, + "suffix": { + "type": "string", + "description": "Effective Call Number Suffix is the suffix of the identifier assigned to an item or its holding and associated with the item.", + "readonly": true + }, + "typeId": { + "type": "string", + "description": "Effective Call Number Type Id is the call number type id of the item, if available, otherwise that of the holding.", + "$ref": "uuid.json", + "readonly": true + } + }, + "additionalProperties": false + }, + "volume": { + "type": "string", + "description": "Volume is intended for monographs when a multipart monograph (e.g. a biography of George Bernard Shaw in three volumes)." + }, + "enumeration": { + "type": "string", + "description": "Enumeration is the descriptive information for the numbering scheme of a serial." + }, + "chronology": { + "type": "string", + "description": "Chronology is the descriptive information for the dating scheme of a serial." + }, + "yearCaption": { + "type": "array", + "description": "In multipart monographs, a caption is a character(s) used to label a level of chronology, e.g., year 1985.", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "itemIdentifier": { + "type": "string", + "description": "Item identifier number, e.g. imported from the union catalogue (read only)." + }, + "copyNumber": { + "type": "string", + "description": "Copy number is the piece identifier. The copy number reflects if the library has a copy of a single-volume monograph; one copy of a multi-volume, (e.g. Copy 1, or C.7.)" + }, + "numberOfPieces": { + "type": "string", + "description": "Number of pieces. Used when an item is checked out or returned to verify that all parts are present (e.g. 7 CDs in a set)." + }, + "descriptionOfPieces": { + "description": "Description of item pieces.", + "type": "string" + }, + "numberOfMissingPieces": { + "type": "string", + "description": "Number of missing pieces." + }, + "missingPieces": { + "type": "string", + "description": "Description of the missing pieces. " + }, + "missingPiecesDate": { + "type": "string", + "description": "Date when the piece(s) went missing." + }, + "itemDamagedStatusId": { + "description": "Item dame status id identifier.", + "type": "string" + }, + "itemDamagedStatusDate": { + "description": "Date and time when the item was damaged.", + "type": "string" + }, + "administrativeNotes":{ + "type": "array", + "description": "Administrative notes", + "minItems": 0, + "items": { + "type": "string" + } + }, + "notes": { + "type": "array", + "description": "Notes about action, copy, binding etc.", + "items": { + "type": "object", + "properties": { + "itemNoteTypeId": { + "type": "string", + "description": "ID of the type of note" + }, + "itemNoteType": { + "description": "Type of item's note", + "type": "object", + "folio:$ref": "itemnotetype.json", + "javaType": "org.folio.rest.jaxrs.model.itemNoteTypeVirtual", + "readonly": true, + "folio:isVirtual": true, + "folio:linkBase": "item-note-types", + "folio:linkFromField": "itemNoteTypeId", + "folio:linkToField": "id", + "folio:includedElement": "itemNoteTypes.0" + }, + "note": { + "type": "string", + "description": "Text content of the note" + }, + "staffOnly": { + "type": "boolean", + "description": "If true, determines that the note should not be visible for others than staff", + "default": false + } + } + } + }, + "circulationNotes": { + "type": "array", + "description": "Notes to be displayed in circulation processes", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "The id of the circulation note" + }, + "noteType": { + "type": "string", + "description": "Type of circulation process that the note applies to", + "enum": ["Check in", "Check out"] + }, + "note": { + "type": "string", + "description": "Text to display" + }, + "source": { + "type": "object", + "description": "The user who added/updated the note. The property is generated by the server and needed to support sorting. Points to /users/{id} resource.", + "properties": { + "id": { + "type": "string", + "description": "The id of the user who added/updated the note. The user information is generated by the server and needed to support sorting. Points to /users/{id} resource." + }, + "personal": { + "type": "object", + "description": "Personal information about the user", + "properties": { + "lastName": { + "description": "The user's last name", + "type": "string" + }, + "firstName": { + "description": "The user's first name", + "type": "string" + } + } + } + } + }, + "date": { + "type": "string", + "description": "Date and time the record is added/updated. The property is generated by the server and needed to support sorting." + }, + "staffOnly": { + "type": "boolean", + "description": "Flag to restrict display of this note", + "default": false + } + }, + "additionalProperties": false + } + }, + "status": { + "description": "The status of the item", + "type": "object", + "properties": { + "name": { + "description": "Name of the status e.g. Available, Checked out, In transit", + "type": "string", + "enum": [ + "Aged to lost", + "Available", + "Awaiting pickup", + "Awaiting delivery", + "Checked out", + "Claimed returned", + "Declared lost", + "In process", + "In process (non-requestable)", + "In transit", + "Intellectual item", + "Long missing", + "Lost and paid", + "Missing", + "On order", + "Paged", + "Restricted", + "Order closed", + "Unavailable", + "Unknown", + "Withdrawn" + ] + }, + "date": { + "description": "Date and time when the status was last changed", + "type": "string", + "format": "date-time", + "readonly": true + } + }, + "required": ["name"], + "additionalProperties": false + }, + "materialType": { + "description": "Item's material type", + "type": "object", + "$ref": "materialtype.json" + }, + "permanentLoanType": { + "type": "object", + "description": "The permanent loan type, is the default loan type for a given item. Loan types are tenant-defined.", + "$ref":"loantype.json" + }, + "temporaryLoanType": { + "type": "object", + "description": "Temporary loan type, is the temporary loan type for a given item.", + "$ref":"loantype.json" + }, + "permanentLocation": { + "type": "object", + "description": "Permanent item location is the default location, shelving location, or holding which is a physical place where items are stored, or an Online location.", + "$ref": "locations/location.json" + }, + "temporaryLocation": { + "type": "object", + "description": "Temporary item location is the temporarily location, shelving location, or holding which is a physical place where items are stored, or an Online location.", + "$ref": "locations/location.json" + }, + "effectiveLocation": { + "type": "object", + "description": "Read only current home location for the item.", + "$ref": "locations/location.json", + "readonly": true + }, + "electronicAccess": { + "type": "array", + "description": "References for accessing the item by URL.", + "items": { + "type": "object", + "properties": { + "uri": { + "type": "string", + "description": "uniform resource identifier (URI) is a string of characters designed for unambiguous identification of resources" + }, + "linkText": { + "type": "string", + "description": "the value of the MARC tag field 856 2nd indicator, where the values are: no information provided, resource, version of resource, related resource, no display constant generated" + }, + "materialsSpecification": { + "type": "string", + "description": "materials specified is used to specify to what portion or aspect of the resource the electronic location and access information applies (e.g. a portion or subset of the item is electronic, or a related electronic resource is being linked to the record)" + }, + "publicNote": { + "type": "string", + "description": "URL public note to be displayed in the discovery" + }, + "relationshipId": { + "type": "string", + "description": "relationship between the electronic resource at the location identified and the item described in the record as a whole" + } + }, + "additionalProperties": false, + "required": [ + "uri" + ] + } + }, + "inTransitDestinationServicePointId": { + "description": "Service point an item is intended to be transited to (should only be present when in transit)", + "type": "string", + "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$" + }, + "statisticalCodeIds": { + "type": "array", + "description": "List of statistical code IDs", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "purchaseOrderLineIdentifier": { + "type": "string", + "description": "ID referencing a remote purchase order object related to this item" + }, + "tags": { + "description": "arbitrary tags associated with this item", + "id": "tags", + "type": "object", + "$ref": "raml-util/schemas/tags.schema" + }, + "metadata": { + "type": "object", + "$ref": "raml-util/schemas/metadata.schema", + "readonly": true + }, + "lastCheckIn": { + "type": "object", + "additionalProperties": false, + "description": "Information about when an item was last scanned in the Inventory app.", + "properties": { + "dateTime": { + "type": "string", + "description": "Date and time of the last check in of the item.", + "format": "date-time" + }, + "servicePointId": { + "type": "string", + "description": "Service point ID being used by a staff member when item was scanned in Check in app.", + "$ref": "uuid.json" + }, + "staffMemberId": { + "type": "string", + "description": "ID a staff member who scanned the item", + "$ref": "uuid.json" + } + } + } + }, + "additionalProperties": false, + "required": [ + "materialType", + "instanceRecord", + "permanentLoanType", + "holdingsRecord", + "status" + ] +} diff --git a/ramls/dereferenceditem.json b/ramls/dereferenceditem.json index e28c05c63..2a93352b6 100644 --- a/ramls/dereferenceditem.json +++ b/ramls/dereferenceditem.json @@ -9,8 +9,8 @@ }, "instanceRecord":{ "type": "object", - "description" : "Parent instance record without the publicationPeriod.", - "$ref": "instance-without-pub-period.json" + "description" : "Parent instance record.", + "$ref": "instance.json" }, "_version": { "type": "integer", diff --git a/ramls/dereferenceditems-without-pub-period.json b/ramls/dereferenceditems-without-pub-period.json new file mode 100644 index 000000000..bf5365257 --- /dev/null +++ b/ramls/dereferenceditems-without-pub-period.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "A collection of dereferenced item records", + "type": "object", + "properties": { + "dereferencedItems": { + "description": "List of dereferenced item records", + "id": "items", + "type": "array", + "items": { + "type": "object", + "$ref": "dereferenceditem-without-pub-period.json" + } + }, + "totalRecords": { + "description": "Estimated or exact total number of records", + "type": "integer" + } + }, + "required": [ + "dereferencedItems", + "totalRecords" + ] +} diff --git a/ramls/examples/instance_get.json b/ramls/examples/instance_get.json index a4c007c2c..086356896 100644 --- a/ramls/examples/instance_get.json +++ b/ramls/examples/instance_get.json @@ -19,10 +19,6 @@ "value": "1" } ], - "publicationPeriod": { - "start": 1999, - "end": 2001 - }, "instanceTypeId": "2b94c631-fca9-4892-a730-03ee529ffe2c", "tags" : { "tagList" : [ diff --git a/ramls/examples/instances_get.json b/ramls/examples/instances_get.json index 27c0c9a07..1d948b250 100644 --- a/ramls/examples/instances_get.json +++ b/ramls/examples/instances_get.json @@ -21,10 +21,6 @@ "value": "1" } ], - "publicationPeriod": { - "start": 1999, - "end": 2001 - }, "instanceTypeId": "2b94c631-fca9-4892-a730-03ee529ffe2c", "tags" : { "tagList" : [ diff --git a/ramls/examples/instanceswithoutpubperiod_get.json b/ramls/examples/instanceswithoutpubperiod_get.json deleted file mode 100644 index 1d948b250..000000000 --- a/ramls/examples/instanceswithoutpubperiod_get.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "instances": [ - { - "id": "601a8dc4-dee7-48eb-b03f-d02fdf0debd0", - "title": "ADVANCING LIBRARY EDUCATION: TECHNOLOGICAL INNOVATION AND INSTRUCTIONAL DESIGN", - "source": "Local: MARC", - "contributors": [ - { - "name": "Sigal, Ari", - "contributorNameTypeId": "2b94c631-fca9-4892-a730-03ee529ffe2a", - "primary": true - } - ], - "identifiers": [ - { - "identifierTypeId": "2e48e713-17f3-4c13-a9f8-23845bb210af", - "value": "9781466636897" - }, - { - "identifierTypeId": "6051f95c-028e-4c6a-8a9e-ee689dd51453", - "value": "1" - } - ], - "instanceTypeId": "2b94c631-fca9-4892-a730-03ee529ffe2c", - "tags" : { - "tagList" : [ - "important" - ] - } - }, - { - "id": "f31a36de-fcf8-44f9-87ef-a55d06ad21ae", - "title": "ADVANCING RESEARCH METHODS WITH NEW TECHNOLOGIES.", - "source": "Local: MARC", - "contributors": [ - { - "name": "Sappleton, Natalie", - "contributorNameTypeId": "2b94c631-fca9-4892-a730-03ee529ffe2a", - "primary": true - } - ], - "identifiers": [ - { - "identifierTypeId": "2e48e713-17f3-4c13-a9f8-23845bb210af", - "value": "9781466639195" - }, - { - "identifierTypeId": "6051f95c-028e-4c6a-8a9e-ee689dd51453", - "value": "2" - } - ], - "instanceTypeId": "2b94c631-fca9-4892-a730-03ee529ffe2c" - } - ], - "totalRecords": 2 -} diff --git a/ramls/examples/instancewithoutpubperiod_get.json b/ramls/examples/instancewithoutpubperiod_get.json deleted file mode 100644 index 086356896..000000000 --- a/ramls/examples/instancewithoutpubperiod_get.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "id": "601a8dc4-dee7-48eb-b03f-d02fdf0debd0", - "source": "Local: MARC", - "title": "ADVANCING LIBRARY EDUCATION: TECHNOLOGICAL INNOVATION AND INSTRUCTIONAL DESIGN", - "contributors": [ - { - "name": "Sigal, Ari", - "contributorNameTypeId": "2b94c631-fca9-4892-a730-03ee529ffe2a", - "primary": true - } - ], - "identifiers": [ - { - "identifierTypeId": "2e48e713-17f3-4c13-a9f8-23845bb210af", - "value": "9781466636897" - }, - { - "identifierTypeId": "6051f95c-028e-4c6a-8a9e-ee689dd51453", - "value": "1" - } - ], - "instanceTypeId": "2b94c631-fca9-4892-a730-03ee529ffe2c", - "tags" : { - "tagList" : [ - "important" - ] - } -} diff --git a/ramls/instance-storage-batch.raml b/ramls/instance-storage-batch.raml index 6d637e8bd..1ff19a968 100644 --- a/ramls/instance-storage-batch.raml +++ b/ramls/instance-storage-batch.raml @@ -22,7 +22,7 @@ types: application/json: type: instancesWithoutPubPeriod example: - value: !include examples/instanceswithoutpubperiod_get.json + value: !include examples/instances_get.json responses: 201: description: "At least one Instance from the list was created" diff --git a/ramls/instance-storage.raml b/ramls/instance-storage.raml index b1d2f8539..42e16acfc 100644 --- a/ramls/instance-storage.raml +++ b/ramls/instance-storage.raml @@ -62,10 +62,10 @@ resourceTypes: displayName: Instances type: collection: - exampleCollection: !include examples/instanceswithoutpubperiod_get.json + exampleCollection: !include examples/instances_get.json schemaCollection: instancesWithoutPubPeriod schemaItem: instanceWithoutPubPeriod - exampleItem: !include examples/instancewithoutpubperiod_get.json + exampleItem: !include examples/instance_get.json get: is: [pageable, searchable: {description: "by title (using CQL)", @@ -91,7 +91,7 @@ resourceTypes: /{instanceId}: type: collection-item: - exampleItem: !include examples/instancewithoutpubperiod_get.json + exampleItem: !include examples/instance_get.json schema: instanceWithoutPubPeriod get: responses: diff --git a/ramls/item-storage-dereferenced.raml b/ramls/item-storage-dereferenced.raml index ed618e597..1ba83dbad 100644 --- a/ramls/item-storage-dereferenced.raml +++ b/ramls/item-storage-dereferenced.raml @@ -11,6 +11,9 @@ documentation: types: dereferencedItem: !include dereferenceditem.json dereferencedItems: !include dereferenceditems.json + dereferencedItemWithoutPubPeriod: !include dereferenceditem-without-pub-period.json + dereferencedItemsWithoutPubPeriod: !include dereferenceditems-without-pub-period.json + errors: !include raml-util/schemas/errors.schema traits: @@ -27,7 +30,7 @@ resourceTypes: type: collection: exampleCollection: !include examples/items_dereferenced_get.json - schemaCollection: dereferencedItems + schemaCollection: dereferencedItemsWithoutPubPeriod get: is: [pageable, searchable: {description: "using CQL (indexes for item and material type)", @@ -37,5 +40,5 @@ resourceTypes: type: collection-item: exampleItem: !include examples/item_dereferenced_get.json - schema: dereferencedItem + schema: dereferencedItemWithoutPubPeriod get: diff --git a/src/main/java/org/folio/rest/impl/ItemStorageDereferencedApi.java b/src/main/java/org/folio/rest/impl/ItemStorageDereferencedApi.java index 0f6eb5f8d..6b3fb0685 100644 --- a/src/main/java/org/folio/rest/impl/ItemStorageDereferencedApi.java +++ b/src/main/java/org/folio/rest/impl/ItemStorageDereferencedApi.java @@ -17,12 +17,15 @@ import org.folio.cql2pgjson.CQL2PgJSON; import org.folio.rest.annotations.Validate; import org.folio.rest.jaxrs.model.DereferencedItem; +import org.folio.rest.jaxrs.model.DereferencedItemWithoutPubPeriod; import org.folio.rest.jaxrs.model.DereferencedItems; +import org.folio.rest.jaxrs.model.DereferencedItemsWithoutPubPeriod; import org.folio.rest.jaxrs.resource.ItemStorageDereferenced; import org.folio.rest.persist.PgUtil; import org.folio.rest.persist.PostgresClient; import org.folio.rest.persist.cql.CQLWrapper; import org.folio.util.UuidUtil; +import org.folio.utils.ObjectConverterUtils; /** * CRUD for Dereferenced Items. @@ -109,8 +112,11 @@ public void getItemStorageDereferencedItems(String totalRecords, int offset, int itemCollection.setDereferencedItems(mappedResults); itemCollection.setTotalRecords(mappedResults.size()); + var dereferencedItemsWithoutPubPeriod = ObjectConverterUtils.convertObject( + itemCollection, DereferencedItemsWithoutPubPeriod.class); asyncResultHandler.handle(Future.succeededFuture( - GetItemStorageDereferencedItemsResponse.respond200WithApplicationJson(itemCollection))); + GetItemStorageDereferencedItemsResponse.respond200WithApplicationJson( + dereferencedItemsWithoutPubPeriod))); }); } @@ -138,8 +144,12 @@ public void getItemStorageDereferencedItemsByItemId( Row row = asyncResult.result().iterator().next(); DereferencedItem item = mapToDereferencedItem(row); + var dereferencedItemWithoutPubPeriod = ObjectConverterUtils.convertObject( + item, DereferencedItemWithoutPubPeriod.class); + asyncResultHandler.handle(Future.succeededFuture( - GetItemStorageDereferencedItemsByItemIdResponse.respond200WithApplicationJson(item))); + GetItemStorageDereferencedItemsByItemIdResponse.respond200WithApplicationJson( + dereferencedItemWithoutPubPeriod))); }); } diff --git a/src/main/java/org/folio/rest/support/EndpointHandler.java b/src/main/java/org/folio/rest/support/EndpointHandler.java index 94a6b070c..d6edf8ef0 100644 --- a/src/main/java/org/folio/rest/support/EndpointHandler.java +++ b/src/main/java/org/folio/rest/support/EndpointHandler.java @@ -5,7 +5,7 @@ import io.vertx.core.AsyncResult; import io.vertx.core.Handler; import javax.ws.rs.core.Response; -import org.folio.rest.jaxrs.model.Instances; +import org.folio.HttpStatus; import org.folio.rest.jaxrs.model.InstancesWithoutPubPeriod; import org.folio.rest.jaxrs.resource.InstanceStorage; import org.folio.utils.ObjectConverterUtils; @@ -30,17 +30,22 @@ public static Handler> handle(Handler> handleInstances(Handler> asyncResultHandler) { return result -> { - if (result.succeeded() && result.result().getStatus() == 200) { - Instances instances = (Instances) result.result().getEntity(); - var instancesWithoutPubPeriod = ObjectConverterUtils.convertObject(instances, InstancesWithoutPubPeriod.class); - - asyncResultHandler.handle(succeededFuture( - InstanceStorage.GetInstanceStorageInstancesResponse.respond200WithApplicationJson( - instancesWithoutPubPeriod))); + if (result.succeeded()) { + handleSuccess(asyncResultHandler, result.result()); } else { - asyncResultHandler.handle(succeededFuture( - InstanceStorage.GetInstanceStorageInstancesResponse.respond500WithTextPlain(result.cause()))); + EndpointFailureHandler.handleFailure(asyncResultHandler).handle(result.cause()); } }; } + + private static void handleSuccess(Handler> asyncResultHandler, Response result) { + if (result.getStatus() == HttpStatus.HTTP_OK.toInt()) { + var instances = result.getEntity(); + var instancesWithoutPubPeriod = ObjectConverterUtils.convertObject(instances, InstancesWithoutPubPeriod.class); + asyncResultHandler.handle(succeededFuture( + InstanceStorage.GetInstanceStorageInstancesResponse.respond200WithApplicationJson(instancesWithoutPubPeriod))); + } else { + asyncResultHandler.handle(succeededFuture(result)); + } + } }