-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update HostAPI models to reflect newest changes to the system
- Loading branch information
1 parent
addd3db
commit 69787f9
Showing
6 changed files
with
269 additions
and
10 deletions.
There are no files selected for viewing
130 changes: 130 additions & 0 deletions
130
src/main/kotlin/no/nb/mlt/wls/application/hostapi/item/ApiCreateItemPayload.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
package no.nb.mlt.wls.application.hostapi.item | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema | ||
import no.nb.mlt.wls.domain.model.Environment | ||
import no.nb.mlt.wls.domain.model.HostName | ||
import no.nb.mlt.wls.domain.model.Item | ||
import no.nb.mlt.wls.domain.model.ItemCategory | ||
import no.nb.mlt.wls.domain.model.Packaging | ||
import no.nb.mlt.wls.domain.ports.inbound.ItemMetadata | ||
import no.nb.mlt.wls.domain.ports.inbound.ValidationException | ||
import org.apache.commons.validator.routines.UrlValidator | ||
|
||
@Schema( | ||
description = """Payload for registering an item in Hermes WLS, and appropriate storage systems.""", | ||
example = """ | ||
{ | ||
"hostId": "mlt-12345", | ||
"hostName": "AXIELL", | ||
"description": "Tyven, tyven skal du hete", | ||
"itemCategory": "PAPER", | ||
"preferredEnvironment": "NONE", | ||
"packaging": "NONE", | ||
"callbackUrl": "https://callback-wls.no/item" | ||
} | ||
""" | ||
) | ||
data class ApiCreateItemPayload( | ||
@Schema( | ||
description = """The item ID from the host system, usually a barcode or an equivalent ID.""", | ||
example = "mlt-12345" | ||
) | ||
val hostId: String, | ||
@Schema( | ||
description = """Name of the host system which the item originates from. | ||
Host system is usually the catalogue that the item is registered in.""", | ||
examples = [ "AXIELL", "ALMA", "ASTA", "BIBLIOFIL" ] | ||
) | ||
val hostName: HostName, | ||
@Schema( | ||
description = """Description of the item for easy identification in the warehouse system. | ||
Usually an item title/name, e.g. book title, film name, etc. or contents description.""", | ||
examples = ["Tyven, tyven skal du hete", "Avisa Hemnes", "Kill Buljo"] | ||
) | ||
val description: String, | ||
@Schema( | ||
description = """Item's category, same category indicates that the items can be stored together without any preservation issues. | ||
For example: books, magazines, newspapers, etc. are of type PAPER, and can be stored together without damaging each other.""", | ||
examples = ["PAPER", "DISC", "FILM", "PHOTO", "EQUIPMENT", "BULK_ITEMS", "MAGNETIC_TAPE"] | ||
) | ||
val itemCategory: ItemCategory, | ||
@Schema( | ||
description = """What kind of environment the item should be stored in. | ||
"NONE" is for normal storage for the item category, "FRYS" is for frozen storage, etc. | ||
NOTE: This is not a guarantee that the item will be stored in the preferred environment. | ||
In cases where storage space is limited, the item may be stored in a different environment.""", | ||
examples = ["NONE", "FRYS"] | ||
) | ||
val preferredEnvironment: Environment, | ||
@Schema( | ||
description = """Whether the item is a single object or a container with other items inside. | ||
"NONE" is for single objects, "ABOX" is for archival boxes, etc. | ||
NOTE: It is up to the catalogue to keep track of the items inside a container.""", | ||
examples = ["NONE", "BOX", "ABOX", "CRATE"] | ||
) | ||
val packaging: Packaging, | ||
@Schema( | ||
description = """Callback URL to use for sending item updates to the host system. | ||
For example when item moves or changes quantity in storage.""", | ||
example = "https://callback-wls.no/item" | ||
) | ||
val callbackUrl: String? | ||
) { | ||
fun toItem(): Item = | ||
Item( | ||
hostId = hostId, | ||
hostName = hostName, | ||
description = description, | ||
itemCategory = itemCategory, | ||
preferredEnvironment = preferredEnvironment, | ||
packaging = packaging, | ||
callbackUrl = callbackUrl, | ||
location = "UNKNOWN", | ||
quantity = 0 | ||
) | ||
|
||
fun toItemMetadata(): ItemMetadata = | ||
ItemMetadata( | ||
hostId = hostId, | ||
hostName = hostName, | ||
description = description, | ||
itemCategory = itemCategory, | ||
preferredEnvironment = preferredEnvironment, | ||
packaging = packaging, | ||
callbackUrl = callbackUrl | ||
) | ||
|
||
@Throws(ValidationException::class) | ||
fun validate() { | ||
if (hostId.isBlank()) { | ||
throw ValidationException("The item's 'hostId' is required, and it cannot be blank") | ||
} | ||
|
||
if (description.isBlank()) { | ||
throw ValidationException("The item's 'description' is required, and it cannot be blank") | ||
} | ||
|
||
if (callbackUrl != null && !isValidUrl(callbackUrl)) { | ||
throw ValidationException("The item's 'callback URL' must be valid if set") | ||
} | ||
} | ||
|
||
private fun isValidUrl(url: String): Boolean { | ||
// Yes I am aware that this function is duplicated in three places | ||
// But I prefer readability to DRY in cases like this | ||
|
||
val validator = UrlValidator(arrayOf("http", "https")) // Allow only HTTP/HTTPS | ||
return validator.isValid(url) | ||
} | ||
} | ||
|
||
fun Item.toCreateApiPayload() = | ||
ApiCreateItemPayload( | ||
hostId = hostId, | ||
hostName = hostName, | ||
description = description, | ||
itemCategory = itemCategory, | ||
preferredEnvironment = preferredEnvironment, | ||
packaging = packaging, | ||
callbackUrl = callbackUrl | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
135 changes: 135 additions & 0 deletions
135
src/main/kotlin/no/nb/mlt/wls/application/hostapi/order/ApiCreateOrderPayload.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
package no.nb.mlt.wls.application.hostapi.order | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema | ||
import io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_ONLY | ||
import no.nb.mlt.wls.domain.model.HostName | ||
import no.nb.mlt.wls.domain.model.Order | ||
import no.nb.mlt.wls.domain.ports.inbound.CreateOrderDTO | ||
import no.nb.mlt.wls.domain.ports.inbound.ValidationException | ||
import org.apache.commons.validator.routines.UrlValidator | ||
|
||
@Schema( | ||
description = """Payload for creating orders in Hermes WLS, and appropriate storage system(s).""", | ||
example = """ | ||
{ | ||
"hostName": "AXIELL", | ||
"hostOrderId": "mlt-12345-order", | ||
"orderLine": [ | ||
{ | ||
"hostId": "mlt-12345", | ||
"status": "NOT_STARTED" | ||
} | ||
], | ||
"orderType": "LOAN", | ||
"contactPerson": "Dr. Heinz Doofenshmirtz", | ||
"address": { | ||
"recipient": "Doug Dimmadome", | ||
"addressLine1": "Dimmsdale Dimmadome", | ||
"addressLine2": "21st Texan Ave.", | ||
"city": "Dimmsdale", | ||
"country": "United States", | ||
"region": "California", | ||
"postcode": "CA-55415" | ||
}, | ||
"note": "Handle with care", | ||
"callbackUrl": "https://callback-wls.no/order" | ||
} | ||
""" | ||
) | ||
data class ApiCreateOrderPayload( | ||
@Schema( | ||
description = """Name of the host system which made the order.""", | ||
examples = ["AXIELL", "ALMA", "ASTA", "BIBLIOFIL"] | ||
) | ||
val hostName: HostName, | ||
@Schema( | ||
description = """ID for the order, preferably the same ID as the one in the host system.""", | ||
example = "mlt-12345-order" | ||
) | ||
val hostOrderId: String, | ||
@Schema( | ||
description = """List of items in the order, also called order lines.""", | ||
accessMode = READ_ONLY | ||
) | ||
val orderLine: List<OrderLine>, | ||
@Schema( | ||
description = """Describes what type of order this is. | ||
"LOAN" means that the order is for borrowing items to external or internal users, | ||
usually meaning the items will be viewed, inspected, etc. | ||
"DIGITIZATION" means that the order is specifically for digitizing items, | ||
usually meaning that the order will be delivered to digitization workstation.""", | ||
examples = ["LOAN", "DIGITIZATION"] | ||
) | ||
val orderType: Order.Type, | ||
@Schema( | ||
description = """Who to contact in relation to the order if case of any problems/issues/questions.""", | ||
example = "Dr. Heinz Doofenshmirtz" | ||
) | ||
val contactPerson: String, | ||
@Schema( | ||
description = """Address for the order, used in cases where storage operator sends out the order directly.""", | ||
example = "{...}" | ||
) | ||
val address: Order.Address?, | ||
@Schema( | ||
description = """Notes regarding the order, such as delivery instructions, special requests, etc.""", | ||
example = "I need this order in four weeks, not right now." | ||
) | ||
val note: String?, | ||
@Schema( | ||
description = """Callback URL to use for sending order updates to the host system. | ||
For example when order items get picked or the order is cancelled.""", | ||
example = "https://callback-wls.no/order" | ||
) | ||
val callbackUrl: String | ||
) { | ||
fun toCreateOrderDTO() = | ||
CreateOrderDTO( | ||
hostName = hostName, | ||
hostOrderId = hostOrderId, | ||
orderLine = orderLine.map { it.toCreateOrderItem() }, | ||
orderType = orderType, | ||
address = address, | ||
contactPerson = contactPerson, | ||
note = note, | ||
callbackUrl = callbackUrl | ||
) | ||
|
||
@Throws(ValidationException::class) | ||
fun validate() { | ||
if (hostOrderId.isBlank()) { | ||
throw ValidationException("The order's hostOrderId is required, and can not be blank") | ||
} | ||
|
||
if (orderLine.isEmpty()) { | ||
throw ValidationException("The order must have at least one order line") | ||
} | ||
|
||
if (!isValidUrl(callbackUrl)) { | ||
throw ValidationException("The order's callback URL is required, and must be a valid URL") | ||
} | ||
|
||
orderLine.forEach(OrderLine::validate) | ||
address?.validate() | ||
} | ||
|
||
private fun isValidUrl(url: String): Boolean { | ||
// Yes I am aware that this function is duplicated in three places | ||
// But I prefer readability over DRY in cases like this | ||
|
||
val validator = UrlValidator(arrayOf("http", "https")) // Allow only HTTP/HTTPS | ||
return validator.isValid(url) | ||
} | ||
} | ||
|
||
fun Order.toCreateApiOrderPayload() = | ||
ApiCreateOrderPayload( | ||
hostName = hostName, | ||
hostOrderId = hostOrderId, | ||
orderLine = orderLine.map { it.toApiOrderLine() }, | ||
orderType = orderType, | ||
contactPerson = contactPerson, | ||
address = address, | ||
note = note, | ||
callbackUrl = callbackUrl | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters