diff --git a/src/main/java/org/folio/circulation/domain/CallNumberComponents.java b/src/main/java/org/folio/circulation/domain/CallNumberComponents.java index ba19547e74..d23c59a5e4 100644 --- a/src/main/java/org/folio/circulation/domain/CallNumberComponents.java +++ b/src/main/java/org/folio/circulation/domain/CallNumberComponents.java @@ -5,11 +5,17 @@ import java.util.Optional; import io.vertx.core.json.JsonObject; +import lombok.Value; +@Value public class CallNumberComponents { - private final String callNumber; - private final String prefix; - private final String suffix; + String callNumber; + String prefix; + String suffix; + + public static CallNumberComponents unknown() { + return new CallNumberComponents(null, null, null); + } private CallNumberComponents(String callNumber, String prefix, String suffix) { this.callNumber = callNumber; @@ -17,24 +23,11 @@ private CallNumberComponents(String callNumber, String prefix, String suffix) { this.suffix = suffix; } - public String getCallNumber() { - return callNumber; - } - - public String getPrefix() { - return prefix; - } - - public String getSuffix() { - return suffix; - } - private static CallNumberComponents fromJson(JsonObject callNumberComponents) { return new CallNumberComponents( getProperty(callNumberComponents, "callNumber"), getProperty(callNumberComponents, "prefix"), - getProperty(callNumberComponents, "suffix") - ); + getProperty(callNumberComponents, "suffix")); } /** @@ -45,11 +38,11 @@ private static CallNumberComponents fromJson(JsonObject callNumberComponents) { */ public static CallNumberComponents fromItemJson(JsonObject itemJson) { if (itemJson == null) { - return null; + return unknown(); } return Optional.ofNullable(itemJson.getJsonObject("effectiveCallNumberComponents")) .map(CallNumberComponents::fromJson) - .orElse(null); + .orElse(unknown()); } } diff --git a/src/main/java/org/folio/circulation/domain/CheckInContext.java b/src/main/java/org/folio/circulation/domain/CheckInContext.java index d12f76e76c..e9d3b8dc7d 100644 --- a/src/main/java/org/folio/circulation/domain/CheckInContext.java +++ b/src/main/java/org/folio/circulation/domain/CheckInContext.java @@ -9,6 +9,7 @@ import org.folio.circulation.support.utils.ClockUtil; import lombok.AllArgsConstructor; +import lombok.NonNull; /** * The loan captures a snapshot of the item status @@ -54,7 +55,7 @@ public CheckInContext withTlrSettings(TlrSettingsConfiguration tlrSettingsConfig this.itemStatusBeforeCheckIn); } - public CheckInContext withItem(Item item) { + public CheckInContext withItem(@NonNull Item item) { //When the item is updated, also update the item for the loan, //as they should be the same diff --git a/src/main/java/org/folio/circulation/domain/Item.java b/src/main/java/org/folio/circulation/domain/Item.java index 604691eeb9..5ac6103b68 100644 --- a/src/main/java/org/folio/circulation/domain/Item.java +++ b/src/main/java/org/folio/circulation/domain/Item.java @@ -1,17 +1,14 @@ package org.folio.circulation.domain; import static org.apache.commons.lang3.StringUtils.firstNonBlank; -import static org.folio.circulation.domain.ItemStatus.AVAILABLE; -import static org.folio.circulation.domain.ItemStatus.AWAITING_PICKUP; -import static org.folio.circulation.domain.ItemStatus.CHECKED_OUT; -import static org.folio.circulation.domain.ItemStatus.CLAIMED_RETURNED; -import static org.folio.circulation.domain.ItemStatus.DECLARED_LOST; -import static org.folio.circulation.domain.ItemStatus.IN_TRANSIT; -import static org.folio.circulation.domain.ItemStatus.MISSING; -import static org.folio.circulation.domain.ItemStatus.PAGED; -import static org.folio.circulation.domain.representations.ItemProperties.STATUS_PROPERTY; -import static org.folio.circulation.support.json.JsonPropertyFetcher.getNestedStringProperty; -import static org.folio.circulation.support.json.JsonPropertyWriter.write; +import static org.folio.circulation.domain.ItemStatusName.AVAILABLE; +import static org.folio.circulation.domain.ItemStatusName.AWAITING_PICKUP; +import static org.folio.circulation.domain.ItemStatusName.CHECKED_OUT; +import static org.folio.circulation.domain.ItemStatusName.CLAIMED_RETURNED; +import static org.folio.circulation.domain.ItemStatusName.DECLARED_LOST; +import static org.folio.circulation.domain.ItemStatusName.IN_TRANSIT; +import static org.folio.circulation.domain.ItemStatusName.MISSING; +import static org.folio.circulation.domain.ItemStatusName.PAGED; import java.util.Collection; import java.util.Optional; @@ -21,50 +18,41 @@ import org.folio.circulation.storage.mappers.ItemMapper; import io.vertx.core.json.JsonObject; +import lombok.AllArgsConstructor; import lombok.NonNull; +@AllArgsConstructor public class Item { private final String id; - private final JsonObject itemRepresentation; @NonNull private final Location location; private final LastCheckIn lastCheckIn; private final CallNumberComponents callNumberComponents; @NonNull private final Location permanentLocation; private final ServicePoint inTransitDestinationServicePoint; - - private boolean changed; - + private final boolean changed; @NonNull private final Holdings holdings; @NonNull private final Instance instance; @NonNull private final MaterialType materialType; @NonNull private final LoanType loanType; @NonNull private final ItemDescription description; + @NonNull private final ItemStatus status; - public static Item from(JsonObject representation) { - return new ItemMapper().toDomain(representation); + public static Item unknown() { + return unknown(null); } - public Item(String id, JsonObject itemRepresentation, Location effectiveLocation, - LastCheckIn lastCheckIn, CallNumberComponents callNumberComponents, - Location permanentLocation, ServicePoint inTransitDestinationServicePoint, - boolean changed, Holdings holdings, Instance instance, - MaterialType materialType, LoanType loanType, - ItemDescription description) { - - this.id = id; - this.itemRepresentation = itemRepresentation; - this.location = effectiveLocation; - this.lastCheckIn = lastCheckIn; - this.callNumberComponents = callNumberComponents; - this.permanentLocation = permanentLocation; - this.inTransitDestinationServicePoint = inTransitDestinationServicePoint; - this.changed = changed; - this.holdings = holdings; - this.instance = instance; - this.materialType = materialType; - this.loanType = loanType; - this.description = description; + + public static Item unknown(String id) { + return new Item(id, Location.unknown(), LastCheckIn.unknown(), + CallNumberComponents.unknown(), Location.unknown(), ServicePoint.unknown(), + false, Holdings.unknown(), Instance.unknown(), + MaterialType.unknown(), LoanType.unknown(), ItemDescription.unknown(), + ItemStatus.unknown()); } + public static Item from(JsonObject representation) { + return new ItemMapper().toDomain(representation); + } + public boolean isCheckedOut() { return isInStatus(CHECKED_OUT); } @@ -89,24 +77,16 @@ public boolean isAvailable() { return isInStatus(AVAILABLE); } - private boolean isInTransit() { - return isInStatus(IN_TRANSIT); - } - public boolean isDeclaredLost() { return isInStatus(DECLARED_LOST); } - boolean isNotSameStatus(ItemStatus prospectiveStatus) { - return !isInStatus(prospectiveStatus); + public boolean isInStatus(ItemStatusName status) { + return getStatus().is(status); } - public boolean isInStatus(ItemStatus status) { - return getStatus().equals(status); - } - - public boolean isNotInStatus(ItemStatus status) { - return !isInStatus(status); + public boolean isNotInStatus(ItemStatusName status) { + return !getStatus().is(status); } public boolean hasChanged() { @@ -166,15 +146,11 @@ public CallNumberComponents getCallNumberComponents() { } public ItemStatus getStatus() { - return ItemStatus.from(getStatusName(), getStatusDate()); + return status; } public String getStatusName() { - return getNestedStringProperty(itemRepresentation, STATUS_PROPERTY, "name"); - } - - private String getStatusDate() { - return getNestedStringProperty(itemRepresentation, STATUS_PROPERTY, "date"); + return status.getName().getName(); } public Location getLocation() { @@ -261,25 +237,22 @@ public String getPermanentLocationName() { return ""; } - public Item changeStatus(ItemStatus newStatus) { - if (isNotSameStatus(newStatus)) { - changed = true; - } + public Item changeStatus(ItemStatusName newStatus) { + final var newChanged = isNotInStatus(newStatus); - write(itemRepresentation, STATUS_PROPERTY, - new JsonObject().put("name", newStatus.getValue())); + final var destinationServicePoint = newStatus == IN_TRANSIT + ? this.inTransitDestinationServicePoint + : null; - //TODO: Remove this hack to remove destination service point - // needs refactoring of how in transit for pickup is done - if(!isInTransit()) { - return removeDestination(); - } - else { - return this; - } + // The previous code did not change the item status date + // that behaviour has been preserved even though it is confusing + return new Item(this.id, this.location, this.lastCheckIn, + this.callNumberComponents, this.permanentLocation, + destinationServicePoint, newChanged, this.holdings, + this.instance, this.materialType, this.loanType, this.description, + new ItemStatus(newStatus, status.getDate())); } - Item available() { return changeStatus(AVAILABLE) .removeDestination(); @@ -320,7 +293,10 @@ public boolean isNotFound() { } public boolean isFound() { - return itemRepresentation != null; + // this relies on items that are completely unknown are defined without an ID + // this might not represent the case where an item's ID is known yet that + // record could not be found / fetched + return id != null; } public LastCheckIn getLastCheckIn() { @@ -331,59 +307,66 @@ public String getPermanentLocationId() { return firstNonBlank(permanentLocation.getId(), holdings.getPermanentLocationId()); } - public Item withLocation(Location newLocation) { - return new Item(this.id, this.itemRepresentation, newLocation, - this.lastCheckIn, this.callNumberComponents, this.permanentLocation, + public Item withLocation(@NonNull Location newLocation) { + return new Item(this.id, newLocation, this.lastCheckIn, + this.callNumberComponents, this.permanentLocation, this.inTransitDestinationServicePoint, this.changed, this.holdings, - this.instance, this.materialType, this.loanType, description); + this.instance, this.materialType, this.loanType, this.description, + this.status); } public Item withMaterialType(@NonNull MaterialType materialType) { - return new Item(this.id, this.itemRepresentation, this.location, - this.lastCheckIn, this.callNumberComponents, this.permanentLocation, + return new Item(this.id, this.location, this.lastCheckIn, + this.callNumberComponents, this.permanentLocation, this.inTransitDestinationServicePoint, this.changed, this.holdings, - this.instance, materialType, this.loanType, this.description); + this.instance, materialType, this.loanType, this.description, + this.status); } public Item withHoldings(@NonNull Holdings holdings) { - return new Item(this.id, this.itemRepresentation, this.location, - this.lastCheckIn, this.callNumberComponents, this.permanentLocation, + return new Item(this.id, this.location, this.lastCheckIn, + this.callNumberComponents, this.permanentLocation, this.inTransitDestinationServicePoint, this.changed, holdings, - this.instance, this.materialType, this.loanType, this.description); + this.instance, this.materialType, this.loanType, this.description, + this.status); } public Item withInstance(@NonNull Instance instance) { - return new Item(this.id, this.itemRepresentation, this.location, - this.lastCheckIn, this.callNumberComponents, this.permanentLocation, + return new Item(this.id, this.location, this.lastCheckIn, + this.callNumberComponents, this.permanentLocation, this.inTransitDestinationServicePoint, this.changed, this.holdings, - instance, this.materialType, this.loanType, this.description); + instance, this.materialType, this.loanType, this.description, + this.status); } public Item withLoanType(@NonNull LoanType loanType) { - return new Item(this.id, this.itemRepresentation, this.location, - this.lastCheckIn, this.callNumberComponents, this.permanentLocation, + return new Item(this.id, this.location, this.lastCheckIn, + this.callNumberComponents, this.permanentLocation, this.inTransitDestinationServicePoint, this.changed, this.holdings, - this.instance, this.materialType, loanType, this.description); + this.instance, this.materialType, loanType, this.description, + this.status); } public Item withLastCheckIn(@NonNull LastCheckIn lastCheckIn) { - return new Item(this.id, this.itemRepresentation, this.location, - lastCheckIn, this.callNumberComponents, this.permanentLocation, + return new Item(this.id, this.location, lastCheckIn, + this.callNumberComponents, this.permanentLocation, this.inTransitDestinationServicePoint, this.changed, this.holdings, - this.instance, this.materialType, this.loanType, this.description); + this.instance, this.materialType, this.loanType, this.description, + this.status); } - public Item withPermanentLocation(Location permanentLocation) { - return new Item(this.id, this.itemRepresentation, this.location, - this.lastCheckIn, this.callNumberComponents, permanentLocation, + public Item withPermanentLocation(@NonNull Location permanentLocation) { + return new Item(this.id, this.location, this.lastCheckIn, + this.callNumberComponents, permanentLocation, this.inTransitDestinationServicePoint, this.changed, this.holdings, - this.instance, this.materialType, this.loanType, this.description); + this.instance, this.materialType, this.loanType, this.description, + this.status); } public Item withInTransitDestinationServicePoint(ServicePoint servicePoint) { - return new Item(this.id, this.itemRepresentation, this.location, - this.lastCheckIn, this.callNumberComponents, this.permanentLocation, + return new Item(this.id, this.location, this.lastCheckIn, + this.callNumberComponents, this.permanentLocation, servicePoint, this.changed, this.holdings, this.instance, - this.materialType, this.loanType, this.description); + this.materialType, this.loanType, this.description, this.status); } } diff --git a/src/main/java/org/folio/circulation/domain/ItemStatus.java b/src/main/java/org/folio/circulation/domain/ItemStatus.java index 59b011d315..83dc370962 100644 --- a/src/main/java/org/folio/circulation/domain/ItemStatus.java +++ b/src/main/java/org/folio/circulation/domain/ItemStatus.java @@ -1,74 +1,25 @@ package org.folio.circulation.domain; -import static org.apache.commons.lang3.StringUtils.equalsIgnoreCase; +import lombok.Value; -import java.util.Arrays; - -public enum ItemStatus { - NONE(""), - AVAILABLE("Available"), - AWAITING_PICKUP("Awaiting pickup"), - AWAITING_DELIVERY("Awaiting delivery"), - CHECKED_OUT("Checked out"), - IN_TRANSIT("In transit"), - MISSING("Missing"), - PAGED("Paged"), - ON_ORDER("On order"), - IN_PROCESS("In process"), - DECLARED_LOST("Declared lost"), - CLAIMED_RETURNED("Claimed returned"), - WITHDRAWN("Withdrawn"), - LOST_AND_PAID("Lost and paid"), - INTELLECTUAL_ITEM("Intellectual item"), - IN_PROCESS_NON_REQUESTABLE("In process (non-requestable)"), - LONG_MISSING("Long missing"), - UNAVAILABLE("Unavailable"), - UNKNOWN("Unknown"), - RESTRICTED("Restricted"), - AGED_TO_LOST("Aged to lost"); - - public static ItemStatus from(String value) { - return Arrays.stream(values()) - .filter(status -> status.valueMatches(value)) - .findFirst() - .orElse(NONE); +@Value +public class ItemStatus { + public static ItemStatus unknown() { + return new ItemStatus(ItemStatusName.NONE, null); } - public static ItemStatus from(String value, String date) { - return Arrays.stream(values()) - .filter(status -> status.valueMatches(value)) - .findFirst().map(status -> { - status.setDate(date); - return status; - }) - .orElse(NONE); - } - - private final String value; - // FIXME: Enum constants are singletons, date must not be associated with it - private String date; - - ItemStatus(String value) { - this.value = value; - } + ItemStatusName name; + String date; public String getValue() { - return value; - } - - public String getDate() { - return date; - } - - void setDate(String date) { - this.date = date; + return name.getName(); } - private boolean valueMatches(String value) { - return equalsIgnoreCase(getValue(), value); + public boolean is(ItemStatusName name) { + return this.name.equals(name); } public boolean isLostNotResolved() { - return this == DECLARED_LOST || this == AGED_TO_LOST; + return getName().isLostNotResolved(); } } diff --git a/src/main/java/org/folio/circulation/domain/ItemStatusName.java b/src/main/java/org/folio/circulation/domain/ItemStatusName.java new file mode 100644 index 0000000000..c4a4e9c6fd --- /dev/null +++ b/src/main/java/org/folio/circulation/domain/ItemStatusName.java @@ -0,0 +1,50 @@ +package org.folio.circulation.domain; + +import static org.apache.commons.lang3.StringUtils.equalsIgnoreCase; + +import java.util.Arrays; + +public enum ItemStatusName { + NONE(""), + AVAILABLE("Available"), + AWAITING_PICKUP("Awaiting pickup"), + AWAITING_DELIVERY("Awaiting delivery"), + CHECKED_OUT("Checked out"), + IN_TRANSIT("In transit"), + MISSING("Missing"), + PAGED("Paged"), + ON_ORDER("On order"), + IN_PROCESS("In process"), + DECLARED_LOST("Declared lost"), + CLAIMED_RETURNED("Claimed returned"), + WITHDRAWN("Withdrawn"), + LOST_AND_PAID("Lost and paid"), + INTELLECTUAL_ITEM("Intellectual item"), + IN_PROCESS_NON_REQUESTABLE("In process (non-requestable)"), + LONG_MISSING("Long missing"), + UNAVAILABLE("Unavailable"), + UNKNOWN("Unknown"), + RESTRICTED("Restricted"), + AGED_TO_LOST("Aged to lost"); + + public static ItemStatusName from(String value) { + return Arrays.stream(values()) + .filter(status -> equalsIgnoreCase(status.name, value)) + .findFirst() + .orElse(NONE); + } + + private final String name; + + ItemStatusName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public boolean isLostNotResolved() { + return this == DECLARED_LOST || this == AGED_TO_LOST; + } +} diff --git a/src/main/java/org/folio/circulation/domain/LastCheckIn.java b/src/main/java/org/folio/circulation/domain/LastCheckIn.java index f0e3f7da70..633b22a0c5 100644 --- a/src/main/java/org/folio/circulation/domain/LastCheckIn.java +++ b/src/main/java/org/folio/circulation/domain/LastCheckIn.java @@ -19,6 +19,10 @@ public class LastCheckIn { private final String staffMemberId; private ServicePoint servicePoint; + public static LastCheckIn unknown() { + return new LastCheckIn(null, null, null); + } + public LastCheckIn(ZonedDateTime dateTime, UUID servicePointId, String staffMemberId) { this.dateTime = dateTime; this.servicePointId = servicePointId; diff --git a/src/main/java/org/folio/circulation/domain/Loan.java b/src/main/java/org/folio/circulation/domain/Loan.java index e9fd96f457..62a8f8460c 100644 --- a/src/main/java/org/folio/circulation/domain/Loan.java +++ b/src/main/java/org/folio/circulation/domain/Loan.java @@ -1,7 +1,7 @@ package org.folio.circulation.domain; -import static java.lang.Boolean.TRUE; import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; import static java.time.ZoneOffset.UTC; import static java.util.Collections.emptyList; import static java.util.Objects.nonNull; @@ -10,7 +10,6 @@ import static org.folio.circulation.domain.FeeAmount.noFeeAmount; import static org.folio.circulation.domain.LoanAction.CHECKED_IN; import static org.folio.circulation.domain.LoanAction.CHECKED_OUT; -import static org.folio.circulation.domain.LoanAction.CLAIMED_RETURNED; import static org.folio.circulation.domain.LoanAction.CLOSED_LOAN; import static org.folio.circulation.domain.LoanAction.DECLARED_LOST; import static org.folio.circulation.domain.LoanAction.ITEM_AGED_TO_LOST; @@ -28,7 +27,6 @@ import static org.folio.circulation.domain.representations.LoanProperties.DECLARED_LOST_DATE; import static org.folio.circulation.domain.representations.LoanProperties.DUE_DATE; import static org.folio.circulation.domain.representations.LoanProperties.ITEM_LOCATION_ID_AT_CHECKOUT; -import static org.folio.circulation.domain.representations.LoanProperties.ITEM_STATUS; import static org.folio.circulation.domain.representations.LoanProperties.LOAN_POLICY_ID; import static org.folio.circulation.domain.representations.LoanProperties.LOST_ITEM_HAS_BEEN_BILLED; import static org.folio.circulation.domain.representations.LoanProperties.LOST_ITEM_POLICY_ID; @@ -51,7 +49,6 @@ import static org.folio.circulation.support.json.JsonPropertyWriter.writeByPath; import static org.folio.circulation.support.results.CommonFailures.failedDueToServerError; import static org.folio.circulation.support.results.Result.succeeded; -import static org.folio.circulation.support.utils.CommonUtils.executeIfNotNull; import static org.folio.circulation.support.utils.DateTimeUtil.isBeforeMillis; import static org.folio.circulation.support.utils.DateTimeUtil.isSameMillis; import static org.folio.circulation.support.utils.DateTimeUtil.mostRecentDate; @@ -72,20 +69,18 @@ import io.vertx.core.json.JsonObject; import lombok.AllArgsConstructor; +import lombok.NonNull; @AllArgsConstructor(access = PRIVATE) public class Loan implements ItemRelatedRecord, UserRelatedRecord { private final JsonObject representation; - private final Item item; + @NonNull private final Item item; private final User user; private final User proxy; - private final ServicePoint checkinServicePoint; private final ServicePoint checkoutServicePoint; - private final ZonedDateTime originalDueDate; - private ZonedDateTime previousDueDate; - + private final ZonedDateTime previousDueDate; private final Policies policies; private final Collection accounts; @@ -98,7 +93,8 @@ public static Loan from(JsonObject representation) { final LostItemPolicy lostItemPolicy = LostItemPolicy.unknown( getProperty(representation, LOST_ITEM_POLICY_ID)); - return new Loan(representation, null, null, null, null, null, + return new Loan(representation, Item.unknown(getProperty(representation, "itemId")), + null, null, null, null, getDateTimeProperty(representation, DUE_DATE), getDateTimeProperty(representation, DUE_DATE), new Policies(loanPolicy, overdueFinePolicy, lostItemPolicy), emptyList()); } @@ -122,66 +118,68 @@ public Loan changeDueDate(ZonedDateTime newDueDate) { } public Loan setDueDateChangedByRecall() { - write(representation, "dueDateChangedByRecall", TRUE); - - return this; + return setDueDateChangedByRecall(TRUE); } public Loan unsetDueDateChangedByRecall() { - write(representation, "dueDateChangedByRecall", FALSE); + return setDueDateChangedByRecall(FALSE); + } + + public Loan setDueDateChangedByRecall(Boolean value) { + write(representation, "dueDateChangedByRecall", value); return this; } - private void changeReturnDate(ZonedDateTime returnDate) { + private Loan changeReturnDate(ZonedDateTime returnDate) { write(representation, RETURN_DATE, returnDate); + + return this; } - private void changeSystemReturnDate(ZonedDateTime systemReturnDate) { + private Loan changeSystemReturnDate(ZonedDateTime systemReturnDate) { write(representation, SYSTEM_RETURN_DATE, systemReturnDate); - } - public void changeAction(LoanAction action) { - changeAction(action.getValue()); + return this; } - public void changeAction(String action) { - write(representation, LoanProperties.ACTION, action); + public Loan changeAction(LoanAction action) { + write(representation, LoanProperties.ACTION, action.getValue()); + + return this; } public String getAction() { return getProperty(representation, ACTION); } - private void changeCheckInServicePointId(UUID servicePointId) { + private Loan changeCheckInServicePointId(UUID servicePointId) { write(representation, "checkinServicePointId", servicePointId); - } - - public Loan changeItemStatusForItemAndLoan(ItemStatus itemStatus) { - Item itemToChange = getItem(); - - executeIfNotNull(itemToChange, f -> f.changeStatus(itemStatus)); - - changeItemStatus(itemStatus.getValue()); return this; } - private void changeStatus(LoanStatus status) { - representation.put(STATUS, new JsonObject().put("name", status.getValue())); + public Loan changeItemStatusForItemAndLoan(ItemStatusName itemStatus) { + return changeItemStatus(itemStatus.getName()) + .withItem(item.changeStatus(itemStatus)); } public Loan changeItemEffectiveLocationIdAtCheckOut(String locationId) { representation.put(ITEM_LOCATION_ID_AT_CHECKOUT, locationId); + return this; } - public void changeActionComment(String comment) { + public Loan changeActionComment(String comment) { representation.put(ACTION_COMMENT, comment); + + return this; } - public void removeActionComment() { + public Loan removeActionComment() { representation.remove(ACTION_COMMENT); + + return this; } public String getActionComment() { @@ -275,10 +273,10 @@ public Loan replaceRepresentation(JsonObject newRepresentation) { checkoutServicePoint, originalDueDate, previousDueDate, policies, accounts); } - public Loan withItem(Item newItem) { + public Loan withItem(@NonNull Item newItem) { JsonObject newRepresentation = representation.copy(); - if (newItem != null && newItem.isFound()) { + if (newItem.isFound()) { newRepresentation.put("itemId", newItem.getItemId()); } @@ -310,6 +308,7 @@ public Loan withPatronGroupAtCheckout(PatronGroup patronGroup) { write(representation, LoanProperties.PATRON_GROUP_AT_CHECKOUT, patronGroupAtCheckout); } + return this; } @@ -391,10 +390,12 @@ public LostItemPolicy getLostItemPolicy() { return policies.getLostItemPolicy(); } - private void setLoanPolicyId(String newLoanPolicyId) { + private Loan setLoanPolicyId(String newLoanPolicyId) { if (newLoanPolicyId != null) { representation.put("loanPolicyId", newLoanPolicyId); } + + return this; } public ServicePoint getCheckinServicePoint() { @@ -410,36 +411,30 @@ public String getPatronGroupIdAtCheckout() { } public Loan renew(ZonedDateTime dueDate, String basedUponLoanPolicyId) { - changeAction(RENEWED); - removeActionComment(); - setLoanPolicyId(basedUponLoanPolicyId); - changeDueDate(dueDate); - incrementRenewalCount(); - - return this; + return changeAction(RENEWED) + .removeActionComment() + .setLoanPolicyId(basedUponLoanPolicyId) + .changeDueDate(dueDate) + .incrementRenewalCount(); } - public Loan overrideRenewal(ZonedDateTime dueDate, - String basedUponLoanPolicyId, - String actionComment) { - changeAction(RENEWED_THROUGH_OVERRIDE); - setLoanPolicyId(basedUponLoanPolicyId); - changeDueDate(dueDate); - incrementRenewalCount(); - changeActionComment(actionComment); + public Loan overrideRenewal(ZonedDateTime dueDate, String basedUponLoanPolicyId, + String actionComment) { - return this; + return changeAction(RENEWED_THROUGH_OVERRIDE) + .setLoanPolicyId(basedUponLoanPolicyId) + .changeDueDate(dueDate) + .incrementRenewalCount() + .changeActionComment(actionComment); } private Loan checkIn(LoanAction action, ZonedDateTime returnDateTime, ZonedDateTime systemReturnDateTime, UUID servicePointId) { - closeLoan(action); - changeReturnDate(returnDateTime); - changeSystemReturnDate(systemReturnDateTime); - changeCheckInServicePointId(servicePointId); - - return this; + return closeLoan(action) + .changeReturnDate(returnDateTime) + .changeSystemReturnDate(systemReturnDateTime) + .changeCheckInServicePointId(servicePointId); } Loan checkIn(ZonedDateTime returnDateTime, ZonedDateTime systemReturnDateTime, UUID servicePointId) { @@ -448,26 +443,26 @@ Loan checkIn(ZonedDateTime returnDateTime, ZonedDateTime systemReturnDateTime, U } Loan resolveClaimedReturned(LoanAction resolveAction, - ZonedDateTime returnDateTime, ZonedDateTime systemReturnDateTime, UUID servicePointId) { + ZonedDateTime returnDateTime, ZonedDateTime systemReturnDateTime, + UUID servicePointId) { return checkIn(resolveAction, returnDateTime, systemReturnDateTime, servicePointId); } public Loan declareItemLost(String comment, ZonedDateTime dateTime) { - changeAction(DECLARED_LOST); - changeActionComment(comment); - changeItemStatusForItemAndLoan(ItemStatus.DECLARED_LOST); - changeDeclaredLostDateTime(dateTime); - return this; + return changeAction(DECLARED_LOST) + .changeActionComment(comment) + .changeItemStatusForItemAndLoan(ItemStatusName.DECLARED_LOST) + .changeDeclaredLostDateTime(dateTime); } public boolean isDeclaredLost() { - return hasItemWithStatus(ItemStatus.DECLARED_LOST); + return hasItemWithStatus(ItemStatusName.DECLARED_LOST); } public boolean isAgedToLost() { - return hasItemWithStatus(ItemStatus.AGED_TO_LOST); + return hasItemWithStatus(ItemStatusName.AGED_TO_LOST); } public boolean isItemLost() { @@ -475,7 +470,7 @@ public boolean isItemLost() { } public boolean isClaimedReturned() { - return hasItemWithStatus(ItemStatus.CLAIMED_RETURNED); + return hasItemWithStatus(ItemStatusName.CLAIMED_RETURNED); } public boolean isRenewed() { @@ -487,16 +482,18 @@ public boolean isRenewed() { return false; } - public boolean hasItemWithStatus(ItemStatus itemStatus) { + public boolean hasItemWithStatus(ItemStatusName itemStatus) { return hasItemWithAnyStatus(itemStatus); } - public boolean hasItemWithAnyStatus(ItemStatus... itemStatuses) { - return item != null && Stream.of(itemStatuses).anyMatch(item::isInStatus); + public boolean hasItemWithAnyStatus(ItemStatusName... itemStatuses) { + return Stream.of(itemStatuses).anyMatch(item::isInStatus); } - private void incrementRenewalCount() { + private Loan incrementRenewalCount() { write(representation, "renewalCount", getRenewalCount() + 1); + + return this; } public Integer getRenewalCount() { @@ -537,12 +534,16 @@ public ZonedDateTime getReturnDate() { return getDateTimeProperty(representation, RETURN_DATE); } - public void changeItemStatus(String itemStatus) { + public Loan changeItemStatus(String itemStatus) { representation.put(LoanProperties.ITEM_STATUS, itemStatus); + + return this; } - public void changeDeclaredLostDateTime(ZonedDateTime dateTime) { + public Loan changeDeclaredLostDateTime(ZonedDateTime dateTime) { write(representation, DECLARED_LOST_DATE, dateTime); + + return this; } public ZonedDateTime getDeclareLostDateTime() { @@ -566,43 +567,44 @@ public boolean isOverdue(ZonedDateTime systemTime) { } public Loan claimItemReturned(String comment, ZonedDateTime claimedReturnedDate) { - changeAction(CLAIMED_RETURNED); - if (StringUtils.isNotBlank(comment)) { - changeActionComment(comment); - } + final Loan newLoan = StringUtils.isNotBlank(comment) + ? changeActionComment(comment) + : this; - changeItemStatusForItemAndLoan(ItemStatus.CLAIMED_RETURNED); - changeClaimedReturnedDate(claimedReturnedDate); - - return this; + return newLoan + .changeAction(LoanAction.CLAIMED_RETURNED) + .changeItemStatusForItemAndLoan(ItemStatusName.CLAIMED_RETURNED) + .changeClaimedReturnedDate(claimedReturnedDate); } - private void changeClaimedReturnedDate(ZonedDateTime claimedReturnedDate) { + private Loan changeClaimedReturnedDate(ZonedDateTime claimedReturnedDate) { write(representation, CLAIMED_RETURNED_DATE, claimedReturnedDate); + + return this; } public Loan closeLoan(LoanAction action) { - changeStatus(LoanStatus.CLOSED); - - changeAction(action); - removeActionComment(); - - return this; + return closeLoan() + .changeAction(action) + .removeActionComment(); } public Loan closeLoan(LoanAction action, String comment) { - changeStatus(LoanStatus.CLOSED); + return closeLoan() + .changeAction(action) + .changeActionComment(comment); + } - changeAction(action); - changeActionComment(comment); + private Loan closeLoan() { + representation.put(STATUS, + new JsonObject().put("name", LoanStatus.CLOSED.getValue())); return this; } public Loan markItemMissing(String comment) { - changeItemStatusForItemAndLoan(ItemStatus.MISSING); - - return closeLoan(MISSING, comment); + return changeItemStatusForItemAndLoan(ItemStatusName.MISSING) + .closeLoan(MISSING, comment); } public FeeAmount getRemainingFeeFineAmount() { @@ -617,24 +619,23 @@ public FeeAmount getRemainingFeeFineAmount() { .orElse(noFeeAmount()); } - public void closeLoanAsLostAndPaid() { - closeLoan(CLOSED_LOAN); - changeItemStatusForItemAndLoan(ItemStatus.LOST_AND_PAID); + public Loan closeLoanAsLostAndPaid() { + return closeLoan(CLOSED_LOAN) + .changeItemStatusForItemAndLoan(ItemStatusName.LOST_AND_PAID); } public Loan copy() { final JsonObject representationCopy = representation.copy(); + return new Loan(representationCopy, item, user, proxy, checkinServicePoint, checkoutServicePoint, originalDueDate, previousDueDate, policies, accounts); } public Loan ageOverdueItemToLost(ZonedDateTime ageToLostDate) { - changeAction(ITEM_AGED_TO_LOST); - removeActionComment(); - changeItemStatusForItemAndLoan(ItemStatus.AGED_TO_LOST); - setAgedToLostDate(ageToLostDate); - - return this; + return changeAction(ITEM_AGED_TO_LOST) + .removeActionComment() + .changeItemStatusForItemAndLoan(ItemStatusName.AGED_TO_LOST) + .setAgedToLostDate(ageToLostDate); } public void setAgedToLostDelayedBilling(boolean hasBeenBilled, ZonedDateTime whenToBill) { @@ -651,21 +652,26 @@ public Loan setLostItemHasBeenBilled() { return this; } - public void removeAgedToLostBillingInfo() { + public Loan removeAgedToLostBillingInfo() { final JsonObject billingInfo = representation .getJsonObject(AGED_TO_LOST_DELAYED_BILLING); remove(billingInfo, LOST_ITEM_HAS_BEEN_BILLED); remove(billingInfo, DATE_LOST_ITEM_SHOULD_BE_BILLED); + + return this; } - private void setAgedToLostDate(ZonedDateTime agedToLostDate) { + private Loan setAgedToLostDate(ZonedDateTime agedToLostDate) { writeByPath(representation, agedToLostDate, AGED_TO_LOST_DELAYED_BILLING, AGED_TO_LOST_DATE); + + return this; } public Loan removePreviousAction() { representation.put(LoanProperties.ACTION, ""); + return this; } @@ -677,32 +683,20 @@ public String getUpdatedByUserId() { return getNestedStringProperty(representation, METADATA, UPDATED_BY_USER_ID); } - public ZonedDateTime getOriginalDueDate() { - return originalDueDate; - } - - public Loan setPreviousDueDate(ZonedDateTime previousDateTime) { - this.previousDueDate = previousDateTime; - return this; + public Loan setPreviousDueDate(ZonedDateTime previousDueDate) { + return new Loan(representation, item, user, proxy, checkinServicePoint, + checkoutServicePoint, originalDueDate, previousDueDate, policies, accounts); } public ZonedDateTime getPreviousDueDate() { return previousDueDate; } - public ItemStatus getItemStatus() { - if (item != null) { - return item.getStatus(); - } - - return ItemStatus.from(getItemStatusName()); + public ItemStatusName getItemStatus() { + return item.getStatus().getName(); } public String getItemStatusName() { - if (item != null) { - return item.getStatusName(); - } - - return getProperty(representation, ITEM_STATUS); + return item.getStatusName(); } } diff --git a/src/main/java/org/folio/circulation/domain/LoanAndRelatedRecords.java b/src/main/java/org/folio/circulation/domain/LoanAndRelatedRecords.java index 4c57c9fa74..80dce5bc14 100644 --- a/src/main/java/org/folio/circulation/domain/LoanAndRelatedRecords.java +++ b/src/main/java/org/folio/circulation/domain/LoanAndRelatedRecords.java @@ -9,6 +9,7 @@ import io.vertx.core.json.JsonObject; import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NonNull; import lombok.With; @AllArgsConstructor @@ -42,7 +43,7 @@ public LoanAndRelatedRecords(Loan loan, ZoneId timeZone) { this(loan, null, null, timeZone, new JsonObject(), null, null, null); } - public LoanAndRelatedRecords changeItemStatus(ItemStatus status) { + public LoanAndRelatedRecords changeItemStatus(ItemStatusName status) { return withItem(getItem().changeStatus(status)); } @@ -54,7 +55,7 @@ public LoanAndRelatedRecords withProxyingUser(User newProxy) { return withLoan(loan.withProxy(newProxy)); } - public LoanAndRelatedRecords withItem(Item newItem) { + public LoanAndRelatedRecords withItem(@NonNull Item newItem) { return withLoan(loan.withItem(newItem)); } diff --git a/src/main/java/org/folio/circulation/domain/LoanCheckInService.java b/src/main/java/org/folio/circulation/domain/LoanCheckInService.java index 5450a2583a..b3434fe929 100644 --- a/src/main/java/org/folio/circulation/domain/LoanCheckInService.java +++ b/src/main/java/org/folio/circulation/domain/LoanCheckInService.java @@ -27,11 +27,11 @@ public Result checkIn(Loan loan, ZonedDateTime systemDateTime, systemDateTime, request.getServicePointId())); } - if (loan.isAgedToLost()) { - loan.removeAgedToLostBillingInfo(); - } + final Loan changedLoan = loan.isAgedToLost() + ? loan.removeAgedToLostBillingInfo() + : loan; - return succeeded(loan.checkIn(request.getCheckInDate(), systemDateTime, + return succeeded(changedLoan.checkIn(request.getCheckInDate(), systemDateTime, request.getServicePointId())); } diff --git a/src/main/java/org/folio/circulation/domain/MoveRequestService.java b/src/main/java/org/folio/circulation/domain/MoveRequestService.java index ffed3f354c..b777d9e86b 100644 --- a/src/main/java/org/folio/circulation/domain/MoveRequestService.java +++ b/src/main/java/org/folio/circulation/domain/MoveRequestService.java @@ -1,5 +1,6 @@ package org.folio.circulation.domain; +import static org.folio.circulation.domain.ItemStatusName.AVAILABLE; import static org.folio.circulation.domain.representations.logs.LogEventType.REQUEST_MOVED; import static org.folio.circulation.support.results.Result.of; @@ -75,7 +76,7 @@ private RequestAndRelatedRecords pagedRequestIfDestinationItemAvailable( Item item = requestAndRelatedRecords.getRequest().getItem(); - if (item.getStatus().equals(ItemStatus.AVAILABLE)) { + if (item.getStatus().is(AVAILABLE)) { return requestAndRelatedRecords.withRequestType(RequestType.PAGE); } diff --git a/src/main/java/org/folio/circulation/domain/Request.java b/src/main/java/org/folio/circulation/domain/Request.java index 8772a53b19..1eb0921032 100644 --- a/src/main/java/org/folio/circulation/domain/Request.java +++ b/src/main/java/org/folio/circulation/domain/Request.java @@ -43,6 +43,7 @@ import io.vertx.core.json.JsonObject; import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NonNull; import lombok.With; @AllArgsConstructor @@ -66,6 +67,7 @@ public class Request implements ItemRelatedRecord, UserRelatedRecord { @With private final Collection instanceItems; + @NonNull private final Item item; @With @@ -91,15 +93,17 @@ public class Request implements ItemRelatedRecord, UserRelatedRecord { public static Request from(JsonObject representation) { // TODO: make sure that operation and TLR settings don't matter for all processes calling // this constructor - return new Request(null, null, representation, null, null, new ArrayList<>(), null, null, null, - null, null, null, false, null, false); + return new Request(null, null, representation, null, null, + new ArrayList<>(), Item.unknown(), null, null, null, null, null, false, + null, false); } public static Request from(TlrSettingsConfiguration tlrSettingsConfiguration, Operation operation, JsonObject representation) { return new Request(tlrSettingsConfiguration, operation, representation, null, null, - new ArrayList<>(), null, null, null, null, null, null, false, null, false); + new ArrayList<>(), Item.unknown(), null, null, null, null, null, false, + null, false); } public JsonObject asJson() { @@ -109,7 +113,7 @@ public JsonObject asJson() { boolean isFulfillable() { return getFulfilmentPreference() == HOLD_SHELF || getFulfilmentPreference() == DELIVERY; } - + public boolean isPage() { return getRequestType() == RequestType.PAGE; } @@ -183,9 +187,8 @@ public String getHoldingsRecordId() { return requestRepresentation.getString(HOLDINGS_RECORD_ID); } - public Request withItem(Item newItem) { - // NOTE: this is null in RequestsAPIUpdatingTests.replacingAnExistingRequestRemovesItemInformationWhenItemDoesNotExist test - if (newItem != null && newItem.getItemId() != null && newItem.getHoldingsRecordId() != null) { + public Request withItem(@NonNull Item newItem) { + if (newItem.getItemId() != null && newItem.getHoldingsRecordId() != null) { requestRepresentation.put(ITEM_ID, newItem.getItemId()); requestRepresentation.put(HOLDINGS_RECORD_ID, newItem.getHoldingsRecordId()); } @@ -227,7 +230,8 @@ public RequestType getRequestType() { } boolean allowedForItem() { - return RequestTypeItemStatusWhiteList.canCreateRequestForItem(getItem().getStatus(), getRequestType()); + return RequestTypeItemStatusWhiteList.canCreateRequestForItem( + getItem().getStatus().getName(), getRequestType()); } LoanAction actionOnCreateOrUpdate() { @@ -289,7 +293,7 @@ public boolean hasChangedPosition() { return changedPosition; } - ItemStatus checkedInItemStatus() { + ItemStatusName checkedInItemStatus() { return getFulfilmentPreference().toCheckedInItemStatus(); } diff --git a/src/main/java/org/folio/circulation/domain/RequestAndRelatedRecords.java b/src/main/java/org/folio/circulation/domain/RequestAndRelatedRecords.java index cc1ebf15e5..ef3f654c79 100644 --- a/src/main/java/org/folio/circulation/domain/RequestAndRelatedRecords.java +++ b/src/main/java/org/folio/circulation/domain/RequestAndRelatedRecords.java @@ -44,9 +44,8 @@ public boolean isTlrFeatureEnabled() { } public RequestAndRelatedRecords withRequest(Request newRequest) { - Item item = this.request.getItem(); return new RequestAndRelatedRecords( - newRequest.withItem(item == null ? newRequest.getItem() : item), + newRequest, this.requestQueue, null, this.moveRequestRecord, diff --git a/src/main/java/org/folio/circulation/domain/RequestFulfilmentPreference.java b/src/main/java/org/folio/circulation/domain/RequestFulfilmentPreference.java index 9a5ceb6ad4..422a3d1e96 100644 --- a/src/main/java/org/folio/circulation/domain/RequestFulfilmentPreference.java +++ b/src/main/java/org/folio/circulation/domain/RequestFulfilmentPreference.java @@ -1,8 +1,8 @@ package org.folio.circulation.domain; import static org.apache.commons.lang3.StringUtils.equalsIgnoreCase; -import static org.folio.circulation.domain.ItemStatus.AWAITING_DELIVERY; -import static org.folio.circulation.domain.ItemStatus.AWAITING_PICKUP; +import static org.folio.circulation.domain.ItemStatusName.AWAITING_DELIVERY; +import static org.folio.circulation.domain.ItemStatusName.AWAITING_PICKUP; import java.util.Arrays; import java.util.List; @@ -35,7 +35,7 @@ public static RequestFulfilmentPreference from(String value) { .orElse(NONE); } - ItemStatus toCheckedInItemStatus() { + ItemStatusName toCheckedInItemStatus() { switch(this) { case HOLD_SHELF: return AWAITING_PICKUP; @@ -44,7 +44,7 @@ ItemStatus toCheckedInItemStatus() { return AWAITING_DELIVERY; default: - return ItemStatus.NONE; + return ItemStatusName.NONE; } } diff --git a/src/main/java/org/folio/circulation/domain/RequestQueue.java b/src/main/java/org/folio/circulation/domain/RequestQueue.java index 67b3dbe5ed..0c34b29e64 100644 --- a/src/main/java/org/folio/circulation/domain/RequestQueue.java +++ b/src/main/java/org/folio/circulation/domain/RequestQueue.java @@ -5,7 +5,6 @@ import static java.util.stream.Collectors.counting; import static java.util.stream.Collectors.groupingBy; import static java.util.stream.Collectors.toList; -import static org.folio.circulation.domain.ItemStatus.AVAILABLE; import java.util.ArrayList; import java.util.Collection; @@ -45,14 +44,10 @@ public RequestQueue filter(Predicate predicate) { .collect(toList())); } - ItemStatus checkedInItemStatus(Item item) { + ItemStatusName checkedInItemStatus(Item item) { return hasOutstandingRequestsFulfillableByItem(item) ? getHighestPriorityRequestFulfillableByItem(item).checkedInItemStatus() - : AVAILABLE; - } - - boolean hasOutstandingFulfillableRequests() { - return !fulfillableRequests().isEmpty(); + : ItemStatusName.AVAILABLE; } boolean hasOutstandingRequestsFulfillableByItem(Item item) { diff --git a/src/main/java/org/folio/circulation/domain/RequestRepresentation.java b/src/main/java/org/folio/circulation/domain/RequestRepresentation.java index 4b36b0544a..083f481c10 100644 --- a/src/main/java/org/folio/circulation/domain/RequestRepresentation.java +++ b/src/main/java/org/folio/circulation/domain/RequestRepresentation.java @@ -81,8 +81,7 @@ private static void addItemProperties(JsonObject request, Item item) { ItemStatus status = item.getStatus(); if (status != null) { - String statusValue = status.getValue(); - itemSummary.put("status", statusValue); + write(itemSummary, "status", status.getValue()); } write(itemSummary, "callNumber", item.getCallNumber()); diff --git a/src/main/java/org/folio/circulation/domain/RequestTypeItemStatusWhiteList.java b/src/main/java/org/folio/circulation/domain/RequestTypeItemStatusWhiteList.java index 768d321cd2..f7f00875d3 100644 --- a/src/main/java/org/folio/circulation/domain/RequestTypeItemStatusWhiteList.java +++ b/src/main/java/org/folio/circulation/domain/RequestTypeItemStatusWhiteList.java @@ -1,35 +1,35 @@ package org.folio.circulation.domain; -import static org.folio.circulation.domain.ItemStatus.AGED_TO_LOST; -import static org.folio.circulation.domain.ItemStatus.AVAILABLE; -import static org.folio.circulation.domain.ItemStatus.AWAITING_DELIVERY; -import static org.folio.circulation.domain.ItemStatus.AWAITING_PICKUP; -import static org.folio.circulation.domain.ItemStatus.CHECKED_OUT; -import static org.folio.circulation.domain.ItemStatus.CLAIMED_RETURNED; -import static org.folio.circulation.domain.ItemStatus.DECLARED_LOST; -import static org.folio.circulation.domain.ItemStatus.INTELLECTUAL_ITEM; -import static org.folio.circulation.domain.ItemStatus.IN_PROCESS; -import static org.folio.circulation.domain.ItemStatus.IN_PROCESS_NON_REQUESTABLE; -import static org.folio.circulation.domain.ItemStatus.IN_TRANSIT; -import static org.folio.circulation.domain.ItemStatus.LONG_MISSING; -import static org.folio.circulation.domain.ItemStatus.LOST_AND_PAID; -import static org.folio.circulation.domain.ItemStatus.MISSING; -import static org.folio.circulation.domain.ItemStatus.NONE; -import static org.folio.circulation.domain.ItemStatus.ON_ORDER; -import static org.folio.circulation.domain.ItemStatus.PAGED; -import static org.folio.circulation.domain.ItemStatus.RESTRICTED; -import static org.folio.circulation.domain.ItemStatus.UNAVAILABLE; -import static org.folio.circulation.domain.ItemStatus.UNKNOWN; -import static org.folio.circulation.domain.ItemStatus.WITHDRAWN; +import static org.folio.circulation.domain.ItemStatusName.AGED_TO_LOST; +import static org.folio.circulation.domain.ItemStatusName.AVAILABLE; +import static org.folio.circulation.domain.ItemStatusName.AWAITING_DELIVERY; +import static org.folio.circulation.domain.ItemStatusName.AWAITING_PICKUP; +import static org.folio.circulation.domain.ItemStatusName.CHECKED_OUT; +import static org.folio.circulation.domain.ItemStatusName.CLAIMED_RETURNED; +import static org.folio.circulation.domain.ItemStatusName.DECLARED_LOST; +import static org.folio.circulation.domain.ItemStatusName.INTELLECTUAL_ITEM; +import static org.folio.circulation.domain.ItemStatusName.IN_PROCESS; +import static org.folio.circulation.domain.ItemStatusName.IN_PROCESS_NON_REQUESTABLE; +import static org.folio.circulation.domain.ItemStatusName.IN_TRANSIT; +import static org.folio.circulation.domain.ItemStatusName.LONG_MISSING; +import static org.folio.circulation.domain.ItemStatusName.LOST_AND_PAID; +import static org.folio.circulation.domain.ItemStatusName.MISSING; +import static org.folio.circulation.domain.ItemStatusName.NONE; +import static org.folio.circulation.domain.ItemStatusName.ON_ORDER; +import static org.folio.circulation.domain.ItemStatusName.PAGED; +import static org.folio.circulation.domain.ItemStatusName.RESTRICTED; +import static org.folio.circulation.domain.ItemStatusName.UNAVAILABLE; +import static org.folio.circulation.domain.ItemStatusName.UNKNOWN; +import static org.folio.circulation.domain.ItemStatusName.WITHDRAWN; import java.util.EnumMap; public class RequestTypeItemStatusWhiteList { - private static EnumMap recallRules; - private static EnumMap holdRules; - private static EnumMap pageRules; - private static EnumMap noneRules; - private static EnumMap> requestsRulesMap; + private static EnumMap recallRules; + private static EnumMap holdRules; + private static EnumMap pageRules; + private static EnumMap noneRules; + private static EnumMap> requestsRulesMap; static { initRecallRules(); @@ -44,7 +44,7 @@ private RequestTypeItemStatusWhiteList() { } private static void initRecallRules() { - recallRules = new EnumMap<>(ItemStatus.class); + recallRules = new EnumMap<>(ItemStatusName.class); recallRules.put(CHECKED_OUT, true); recallRules.put(AVAILABLE, false); recallRules.put(AWAITING_PICKUP, true); @@ -69,7 +69,7 @@ private static void initRecallRules() { } private static void initHoldRules() { - holdRules = new EnumMap<>(ItemStatus.class); + holdRules = new EnumMap<>(ItemStatusName.class); holdRules.put(CHECKED_OUT, true); holdRules.put(AVAILABLE, false); holdRules.put(AWAITING_PICKUP, true); @@ -94,7 +94,7 @@ private static void initHoldRules() { } private static void initPageRules() { - pageRules = new EnumMap<>(ItemStatus.class); + pageRules = new EnumMap<>(ItemStatusName.class); pageRules.put(CHECKED_OUT, false); pageRules.put(AVAILABLE, true); pageRules.put(RESTRICTED, true); @@ -119,7 +119,7 @@ private static void initPageRules() { } private static void initNoneRules() { - noneRules = new EnumMap<>(ItemStatus.class); + noneRules = new EnumMap<>(ItemStatusName.class); noneRules.put(CHECKED_OUT, false); noneRules.put(AVAILABLE, false); noneRules.put(AWAITING_PICKUP, false); @@ -150,7 +150,7 @@ private static void initRequestRulesMap() { requestsRulesMap.put(RequestType.NONE, noneRules); } - public static boolean canCreateRequestForItem(ItemStatus itemStatus, RequestType requestType) { + public static boolean canCreateRequestForItem(ItemStatusName itemStatus, RequestType requestType) { return requestsRulesMap.get(requestType).get(itemStatus); } } diff --git a/src/main/java/org/folio/circulation/domain/UpdateItem.java b/src/main/java/org/folio/circulation/domain/UpdateItem.java index 62877ead73..91fce1db99 100644 --- a/src/main/java/org/folio/circulation/domain/UpdateItem.java +++ b/src/main/java/org/folio/circulation/domain/UpdateItem.java @@ -1,9 +1,10 @@ package org.folio.circulation.domain; import static java.util.concurrent.CompletableFuture.completedFuture; -import static org.folio.circulation.domain.ItemStatus.AVAILABLE; -import static org.folio.circulation.domain.ItemStatus.CHECKED_OUT; -import static org.folio.circulation.domain.ItemStatus.PAGED; +import static org.folio.circulation.domain.ItemStatusName.AVAILABLE; +import static org.folio.circulation.domain.ItemStatusName.CHECKED_OUT; +import static org.folio.circulation.domain.ItemStatusName.DECLARED_LOST; +import static org.folio.circulation.domain.ItemStatusName.PAGED; import static org.folio.circulation.support.ValidationErrorFailure.failedValidation; import static org.folio.circulation.support.results.MappingFunctions.when; import static org.folio.circulation.support.results.Result.of; @@ -117,8 +118,7 @@ public CompletableFuture> onLoanUpdate( .thenApply(itemResult -> itemResult.map(loanAndRelatedRecords::withItem)); } - private CompletableFuture> onLoanUpdate( - Loan loan, + private CompletableFuture> onLoanUpdate(Loan loan, RequestQueue requestQueue) { return of(() -> itemStatusOnLoanUpdate(loan, requestQueue)) @@ -144,13 +144,10 @@ private CompletableFuture> updateItemStatusOnCheck } private CompletableFuture> updateItemWhenNotSameStatus( - ItemStatus prospectiveStatus, - Item item) { - - if(item.isNotSameStatus(prospectiveStatus)) { - item.changeStatus(prospectiveStatus); + ItemStatusName prospectiveStatus, Item item) { - return storeItem(item); + if (item.isNotInStatus(prospectiveStatus)) { + return storeItem(item.changeStatus(prospectiveStatus)); } else { return completedFuture(succeeded(item)); @@ -171,7 +168,7 @@ private static CompletableFuture> skip(T previousResult) { return completedFuture(succeeded(previousResult)); } - private ItemStatus itemStatusOnRequestCreateOrUpdate( + private ItemStatusName itemStatusOnRequestCreateOrUpdate( RequestAndRelatedRecords requestAndRelatedRecords) { RequestType type = requestAndRelatedRecords.getRequest().getRequestType(); @@ -193,23 +190,23 @@ private boolean queueContainsNoRequestsForItem(RequestAndRelatedRecords requestA : requestQueue.isEmpty(); } - private ItemStatus pagedWhenRequested(RequestType type, Item item) { + private ItemStatusName pagedWhenRequested(RequestType type, Item item) { return (item.isAvailable() && type.isPage()) ? PAGED - : item.getStatus(); + : ItemStatusName.from(item.getStatus().getValue()); } - private ItemStatus itemStatusOnLoanUpdate(Loan loan, RequestQueue requestQueue) { - if(loan.isClosed()) { + private ItemStatusName itemStatusOnLoanUpdate(Loan loan, RequestQueue requestQueue) { + if (loan.isClosed()) { return itemStatusOnCheckIn(requestQueue, loan.getItem()); } - else if(loan.getItem().isDeclaredLost()) { - return loan.getItem().getStatus(); + else if (loan.getItem().isDeclaredLost()) { + return DECLARED_LOST; } return CHECKED_OUT; } - private ItemStatus itemStatusOnCheckIn(RequestQueue requestQueue, Item item) { + private ItemStatusName itemStatusOnCheckIn(RequestQueue requestQueue, Item item) { return requestQueue.checkedInItemStatus(item); } } diff --git a/src/main/java/org/folio/circulation/domain/notice/schedule/LoanScheduledNoticeHandler.java b/src/main/java/org/folio/circulation/domain/notice/schedule/LoanScheduledNoticeHandler.java index 9105acf4bc..7dc4cbd07d 100644 --- a/src/main/java/org/folio/circulation/domain/notice/schedule/LoanScheduledNoticeHandler.java +++ b/src/main/java/org/folio/circulation/domain/notice/schedule/LoanScheduledNoticeHandler.java @@ -3,8 +3,8 @@ import static java.util.Collections.singletonList; import static org.apache.commons.lang3.StringUtils.isEmpty; import static org.folio.circulation.domain.FeeFine.lostItemFeeTypes; -import static org.folio.circulation.domain.ItemStatus.CLAIMED_RETURNED; -import static org.folio.circulation.domain.ItemStatus.DECLARED_LOST; +import static org.folio.circulation.domain.ItemStatusName.CLAIMED_RETURNED; +import static org.folio.circulation.domain.ItemStatusName.DECLARED_LOST; import static org.folio.circulation.domain.notice.NoticeTiming.BEFORE; import static org.folio.circulation.domain.notice.TemplateContextUtil.createLoanNoticeContext; import static org.folio.circulation.domain.notice.schedule.TriggeringEvent.AGED_TO_LOST; @@ -22,7 +22,7 @@ import java.util.concurrent.CompletableFuture; import org.apache.commons.collections.CollectionUtils; -import org.folio.circulation.domain.ItemStatus; +import org.folio.circulation.domain.ItemStatusName; import org.folio.circulation.domain.Loan; import org.folio.circulation.domain.representations.logs.NoticeLogContext; import org.folio.circulation.domain.representations.logs.NoticeLogContextItem; @@ -154,9 +154,11 @@ private boolean dueDateNoticeIsNotRelevant(ScheduledNoticeContext context) { if (noticeConfig.hasBeforeTiming() && isBeforeMillis(dueDate, systemTime)) { logMessages.add("Loan is overdue"); } - if (loan.hasItemWithAnyStatus(DECLARED_LOST, ItemStatus.AGED_TO_LOST, CLAIMED_RETURNED)) { + if (loan.hasItemWithAnyStatus(DECLARED_LOST, + ItemStatusName.AGED_TO_LOST, CLAIMED_RETURNED)) { + logMessages.add(String.format("Recurring overdue notice for item in status \"%s\"", - loan.getItemStatus())); + loan.getItemStatusName())); } if (logMessages.isEmpty()) { @@ -178,7 +180,7 @@ private boolean agedToLostNoticeIsNotRelevant(ScheduledNoticeContext context) { if (loan.hasItemWithAnyStatus(DECLARED_LOST, CLAIMED_RETURNED)) { logMessages.add( - String.format("Recurring notice for item in status \"%s\"", loan.getItemStatus())); + String.format("Recurring notice for item in status \"%s\"", loan.getItemStatusName())); } if (loan.isRenewed()) { logMessages.add("Loan was renewed"); diff --git a/src/main/java/org/folio/circulation/domain/policy/LoanPolicy.java b/src/main/java/org/folio/circulation/domain/policy/LoanPolicy.java index 1a8124fa72..6cb66d0aa3 100644 --- a/src/main/java/org/folio/circulation/domain/policy/LoanPolicy.java +++ b/src/main/java/org/folio/circulation/domain/policy/LoanPolicy.java @@ -481,8 +481,8 @@ private Result determineDueDate(Result minimumGuar private Loan changeDueDate(ZonedDateTime dueDate, Loan loan) { if (!loan.wasDueDateChangedByRecall()) { - loan.changeDueDate(dueDate); - loan.setDueDateChangedByRecall(); + return loan.changeDueDate(dueDate) + .setDueDateChangedByRecall(); } return loan; diff --git a/src/main/java/org/folio/circulation/domain/representations/ItemProperties.java b/src/main/java/org/folio/circulation/domain/representations/ItemProperties.java index af02f78728..26c6065eff 100644 --- a/src/main/java/org/folio/circulation/domain/representations/ItemProperties.java +++ b/src/main/java/org/folio/circulation/domain/representations/ItemProperties.java @@ -3,7 +3,5 @@ public class ItemProperties { private ItemProperties() { } - public static final String STATUS_PROPERTY = "status"; - public static final String LAST_CHECK_IN = "lastCheckIn"; public static final String CALL_NUMBER_COMPONENTS = "callNumberComponents"; } diff --git a/src/main/java/org/folio/circulation/domain/representations/ItemSummaryRepresentation.java b/src/main/java/org/folio/circulation/domain/representations/ItemSummaryRepresentation.java index e51522647d..ec14c7c464 100644 --- a/src/main/java/org/folio/circulation/domain/representations/ItemSummaryRepresentation.java +++ b/src/main/java/org/folio/circulation/domain/representations/ItemSummaryRepresentation.java @@ -43,7 +43,7 @@ public JsonObject createItemSummary(Item item) { status.put("date", item.getStatus().getDate()); } - write(itemSummary, ItemProperties.STATUS_PROPERTY, status); + write(itemSummary, "status", status); write(itemSummary, "inTransitDestinationServicePointId", item.getInTransitDestinationServicePointId()); diff --git a/src/main/java/org/folio/circulation/domain/validation/CheckInValidators.java b/src/main/java/org/folio/circulation/domain/validation/CheckInValidators.java index 90e92050d6..3f53a00f3e 100644 --- a/src/main/java/org/folio/circulation/domain/validation/CheckInValidators.java +++ b/src/main/java/org/folio/circulation/domain/validation/CheckInValidators.java @@ -1,6 +1,6 @@ package org.folio.circulation.domain.validation; -import static org.folio.circulation.domain.ItemStatus.INTELLECTUAL_ITEM; +import static org.folio.circulation.domain.ItemStatusName.INTELLECTUAL_ITEM; import static org.folio.circulation.domain.representations.CheckInByBarcodeRequest.CLAIMED_RETURNED_RESOLUTION; import static org.folio.circulation.support.ValidationErrorFailure.singleValidationError; import static org.folio.circulation.support.results.Result.succeeded; diff --git a/src/main/java/org/folio/circulation/domain/validation/ItemStatusValidator.java b/src/main/java/org/folio/circulation/domain/validation/ItemStatusValidator.java index 22d3dcabcb..2a9312e1ab 100644 --- a/src/main/java/org/folio/circulation/domain/validation/ItemStatusValidator.java +++ b/src/main/java/org/folio/circulation/domain/validation/ItemStatusValidator.java @@ -1,19 +1,19 @@ package org.folio.circulation.domain.validation; -import static org.folio.circulation.domain.ItemStatus.AGED_TO_LOST; -import static org.folio.circulation.domain.ItemStatus.CLAIMED_RETURNED; -import static org.folio.circulation.domain.ItemStatus.DECLARED_LOST; -import static org.folio.circulation.domain.ItemStatus.INTELLECTUAL_ITEM; -import static org.folio.circulation.domain.ItemStatus.MISSING; +import static org.folio.circulation.domain.ItemStatusName.AGED_TO_LOST; +import static org.folio.circulation.domain.ItemStatusName.CLAIMED_RETURNED; +import static org.folio.circulation.domain.ItemStatusName.DECLARED_LOST; +import static org.folio.circulation.domain.ItemStatusName.INTELLECTUAL_ITEM; +import static org.folio.circulation.domain.ItemStatusName.MISSING; import static org.folio.circulation.support.results.Result.succeeded; import java.util.function.Function; import org.folio.circulation.domain.Item; -import org.folio.circulation.domain.ItemStatus; +import org.folio.circulation.domain.ItemStatusName; import org.folio.circulation.domain.LoanAndRelatedRecords; -import org.folio.circulation.support.results.Result; import org.folio.circulation.support.ValidationErrorFailure; +import org.folio.circulation.support.results.Result; public class ItemStatusValidator { private final Function itemStatusErrorFunction; @@ -23,7 +23,7 @@ public ItemStatusValidator(Function itemStatusErro } private Result refuseWhenItemIs( - Result loanAndRelatedRecords, ItemStatus status) { + Result loanAndRelatedRecords, ItemStatusName status) { return loanAndRelatedRecords.failWhen( records -> succeeded(records.getLoan().getItem().isInStatus(status)), diff --git a/src/main/java/org/folio/circulation/domain/validation/NotInItemStatusValidator.java b/src/main/java/org/folio/circulation/domain/validation/NotInItemStatusValidator.java index 59cc1e5607..cbda94a777 100644 --- a/src/main/java/org/folio/circulation/domain/validation/NotInItemStatusValidator.java +++ b/src/main/java/org/folio/circulation/domain/validation/NotInItemStatusValidator.java @@ -1,10 +1,10 @@ package org.folio.circulation.domain.validation; -import static org.folio.circulation.domain.ItemStatus.CLAIMED_RETURNED; -import static org.folio.circulation.support.results.Result.succeeded; +import static org.folio.circulation.domain.ItemStatusName.CLAIMED_RETURNED; import static org.folio.circulation.support.ValidationErrorFailure.singleValidationError; +import static org.folio.circulation.support.results.Result.succeeded; -import org.folio.circulation.domain.ItemStatus; +import org.folio.circulation.domain.ItemStatusName; import org.folio.circulation.domain.Loan; import org.folio.circulation.support.results.Result; @@ -20,11 +20,11 @@ public static Result refuseWhenItemIsNotClaimedReturned( } private static Result refuseWhenItemIsNotInStatus( - Result loanResult, ItemStatus status) { + Result loanResult, ItemStatusName status) { return loanResult.failWhen( records -> succeeded(loanResult.value().getItem().isNotInStatus(status)), loan -> singleValidationError(String.format("Item is not %s", - status.getValue()), "itemId", loanResult.value().getItem().getItemId())); + status.getName()), "itemId", loanResult.value().getItem().getItemId())); } } diff --git a/src/main/java/org/folio/circulation/infrastructure/storage/inventory/ItemRepository.java b/src/main/java/org/folio/circulation/infrastructure/storage/inventory/ItemRepository.java index 609ba1d0a3..93b0ed4250 100644 --- a/src/main/java/org/folio/circulation/infrastructure/storage/inventory/ItemRepository.java +++ b/src/main/java/org/folio/circulation/infrastructure/storage/inventory/ItemRepository.java @@ -2,10 +2,7 @@ import static java.util.concurrent.CompletableFuture.completedFuture; import static java.util.function.Function.identity; -import static org.folio.circulation.domain.ItemStatus.AVAILABLE; import static org.folio.circulation.domain.MultipleRecords.CombinationMatchers.matchRecordsById; -import static org.folio.circulation.domain.representations.ItemProperties.LAST_CHECK_IN; -import static org.folio.circulation.domain.representations.ItemProperties.STATUS_PROPERTY; import static org.folio.circulation.support.fetching.MultipleCqlIndexValuesCriteria.byIndex; import static org.folio.circulation.support.http.CommonResponseInterpreters.noContentRecordInterpreter; import static org.folio.circulation.support.http.client.CqlQuery.exactMatch; @@ -31,6 +28,7 @@ import org.folio.circulation.domain.Instance; import org.folio.circulation.domain.Item; import org.folio.circulation.domain.ItemRelatedRecord; +import org.folio.circulation.domain.LastCheckIn; import org.folio.circulation.domain.LoanType; import org.folio.circulation.domain.Location; import org.folio.circulation.domain.MaterialType; @@ -93,7 +91,7 @@ public CompletableFuture> updateItem(Item item) { final var updatedItemRepresentation = identityMap.get(item.getItemId()); - write(updatedItemRepresentation, STATUS_PROPERTY, + write(updatedItemRepresentation, "status", new JsonObject().put("name", item.getStatus().getValue())); remove(updatedItemRepresentation, IN_TRANSIT_DESTINATION_SERVICE_POINT_ID); @@ -102,33 +100,22 @@ public CompletableFuture> updateItem(Item item) { final var lastCheckIn = item.getLastCheckIn(); - if (lastCheckIn == null) { - remove(updatedItemRepresentation, LAST_CHECK_IN); - } - else { - write(updatedItemRepresentation, LAST_CHECK_IN, lastCheckIn.toJson()); - } + setLastCheckIn(updatedItemRepresentation, lastCheckIn); return itemsClient.put(item.getItemId(), updatedItemRepresentation) .thenApply(noContentRecordInterpreter(item)::flatMap) .thenCompose(x -> ofAsync(() -> item)); } - public CompletableFuture> getFirstAvailableItemByInstanceId(String instanceId) { - return holdingsRepository.fetchByInstanceId(instanceId) - .thenCompose(r -> r.after(this::getAvailableItem)); - } - - private CompletableFuture> getAvailableItem( - MultipleRecords holdingsRecords) { + private void setLastCheckIn(JsonObject representation, LastCheckIn lastCheckIn) { + final var LAST_CHECK_IN_PROPERTY = "lastCheckIn"; - if (holdingsRecords == null || holdingsRecords.isEmpty()) { - return ofAsync(() -> Item.from(null)); + if (lastCheckIn == null) { + remove(representation, LAST_CHECK_IN_PROPERTY); + } + else { + write(representation, LAST_CHECK_IN_PROPERTY, lastCheckIn.toJson()); } - - return findByIndexNameAndQuery(holdingsRecords.toKeys(Holdings::getId), - "holdingsRecordId", exactMatch("status.name", AVAILABLE.getValue())) - .thenApply(mapResult(MultipleRecords::firstOrNull)); } public CompletableFuture> fetchByBarcode(String barcode) { @@ -147,9 +134,9 @@ private CompletableFuture>> fetchLocations( return result.combineAfter(this::fetchLocations, (items, locations) -> items .combineRecords(locations, matchRecordsById(Item::getPermanentLocationId, Location::getId), - Item::withPermanentLocation, null) + Item::withPermanentLocation, Location.unknown()) .combineRecords(locations, matchRecordsById(Item::getEffectiveLocationId, Location::getId), - Item::withLocation, null)); + Item::withLocation, Location.unknown())); } private CompletableFuture>> fetchLocations( diff --git a/src/main/java/org/folio/circulation/infrastructure/storage/loans/LoanRepository.java b/src/main/java/org/folio/circulation/infrastructure/storage/loans/LoanRepository.java index 555df80332..ce4faac512 100644 --- a/src/main/java/org/folio/circulation/infrastructure/storage/loans/LoanRepository.java +++ b/src/main/java/org/folio/circulation/infrastructure/storage/loans/LoanRepository.java @@ -3,7 +3,7 @@ import static java.lang.String.format; import static java.util.Objects.nonNull; import static java.util.concurrent.CompletableFuture.completedFuture; -import static org.folio.circulation.domain.ItemStatus.IN_TRANSIT; +import static org.folio.circulation.domain.ItemStatusName.IN_TRANSIT; import static org.folio.circulation.domain.representations.LoanProperties.BORROWER; import static org.folio.circulation.domain.representations.LoanProperties.DUE_DATE; import static org.folio.circulation.domain.representations.LoanProperties.FEESANDFINES; @@ -67,6 +67,7 @@ import org.folio.circulation.support.results.Result; import io.vertx.core.json.JsonObject; +import lombok.NonNull; public class LoanRepository implements GetManyRecordsRepository { private static final String RECORDS_PROPERTY_NAME = "loans"; @@ -143,13 +144,13 @@ public CompletableFuture> findOpenLoanForRequest(Request request) { * success with null if the no open loan is found, * failure if more than one open loan for the item found */ - public CompletableFuture> findOpenLoanForItem(Item item) { + public CompletableFuture> findOpenLoanForItem(@NonNull Item item) { return findOpenLoans(item.getItemId()) .thenApply(loansResult -> loansResult.next(loans -> { if (loans.getTotalRecords() == 0) { return succeeded(null); } - else if(loans.getTotalRecords() == 1) { + else if (loans.getTotalRecords() == 1) { final Optional firstLoan = loans.getRecords().stream().findFirst(); return firstLoan @@ -235,7 +236,7 @@ public CompletableFuture>> findByIds(Collection>> findByItemIds( Collection itemIds) { - Result statusQuery = exactMatch(ITEM_STATUS, IN_TRANSIT.getValue()); + Result statusQuery = exactMatch(ITEM_STATUS, IN_TRANSIT.getName()); FindWithMultipleCqlIndexValues fetcher = findWithMultipleCqlIndexValues( loansStorageClient, RECORDS_PROPERTY_NAME, Loan::from); diff --git a/src/main/java/org/folio/circulation/resources/CheckOutByBarcodeResource.java b/src/main/java/org/folio/circulation/resources/CheckOutByBarcodeResource.java index ff67d9d301..56c62845bf 100644 --- a/src/main/java/org/folio/circulation/resources/CheckOutByBarcodeResource.java +++ b/src/main/java/org/folio/circulation/resources/CheckOutByBarcodeResource.java @@ -1,7 +1,6 @@ package org.folio.circulation.resources; import static java.util.concurrent.CompletableFuture.completedFuture; -import static org.folio.circulation.domain.ItemStatus.CHECKED_OUT; import static org.folio.circulation.domain.LoanAction.CHECKED_OUT_THROUGH_OVERRIDE; import static org.folio.circulation.resources.handlers.error.CirculationErrorType.FAILED_TO_FETCH_ITEM; import static org.folio.circulation.resources.handlers.error.CirculationErrorType.FAILED_TO_FETCH_PROXY_USER; @@ -16,6 +15,7 @@ import java.time.ZonedDateTime; import java.util.concurrent.CompletableFuture; +import org.folio.circulation.domain.ItemStatusName; import org.folio.circulation.domain.Loan; import org.folio.circulation.domain.LoanAndRelatedRecords; import org.folio.circulation.domain.LoanRepresentation; @@ -206,7 +206,7 @@ private CompletableFuture> updateItem( } private LoanAndRelatedRecords checkOutItem(LoanAndRelatedRecords loanAndRelatedRecords) { - return loanAndRelatedRecords.changeItemStatus(CHECKED_OUT); + return loanAndRelatedRecords.changeItemStatus(ItemStatusName.CHECKED_OUT); } private Result createdLoanFrom(Result result, diff --git a/src/main/java/org/folio/circulation/resources/PickSlipsResource.java b/src/main/java/org/folio/circulation/resources/PickSlipsResource.java index c80b2987e7..eb3d6dae60 100644 --- a/src/main/java/org/folio/circulation/resources/PickSlipsResource.java +++ b/src/main/java/org/folio/circulation/resources/PickSlipsResource.java @@ -5,6 +5,7 @@ import static java.util.function.Function.identity; import static java.util.stream.Collectors.toMap; import static java.util.stream.Collectors.toSet; +import static org.folio.circulation.domain.ItemStatusName.PAGED; import static org.folio.circulation.support.fetching.MultipleCqlIndexValuesCriteria.byIndex; import static org.folio.circulation.support.fetching.RecordFetching.findWithCqlQuery; import static org.folio.circulation.support.fetching.RecordFetching.findWithMultipleCqlIndexValues; @@ -22,7 +23,6 @@ import org.apache.commons.lang3.StringUtils; import org.folio.circulation.domain.Item; -import org.folio.circulation.domain.ItemStatus; import org.folio.circulation.domain.Location; import org.folio.circulation.domain.MultipleRecords; import org.folio.circulation.domain.Request; @@ -122,7 +122,7 @@ private CompletableFuture>> fetchPagedItemsForLocations( return completedFuture(succeeded(emptyList())); } - Result statusQuery = exactMatch(STATUS_NAME_KEY, ItemStatus.PAGED.getValue()); + Result statusQuery = exactMatch(STATUS_NAME_KEY, PAGED.getName()); return itemRepository.findByIndexNameAndQuery(locationIds, EFFECTIVE_LOCATION_ID_KEY, statusQuery) .thenComposeAsync(r -> r.after(items -> fetchLocationDetailsForItems(items, locations, diff --git a/src/main/java/org/folio/circulation/resources/RequestFromRepresentationService.java b/src/main/java/org/folio/circulation/resources/RequestFromRepresentationService.java index 4e6d6cc43d..e8d05c3480 100644 --- a/src/main/java/org/folio/circulation/resources/RequestFromRepresentationService.java +++ b/src/main/java/org/folio/circulation/resources/RequestFromRepresentationService.java @@ -5,9 +5,10 @@ import static java.util.stream.Collectors.toList; import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank; -import static org.folio.circulation.domain.ItemStatus.AWAITING_DELIVERY; -import static org.folio.circulation.domain.ItemStatus.AWAITING_PICKUP; -import static org.folio.circulation.domain.ItemStatus.PAGED; +import static org.folio.circulation.domain.ItemStatusName.AVAILABLE; +import static org.folio.circulation.domain.ItemStatusName.AWAITING_DELIVERY; +import static org.folio.circulation.domain.ItemStatusName.AWAITING_PICKUP; +import static org.folio.circulation.domain.ItemStatusName.PAGED; import static org.folio.circulation.domain.RequestLevel.ITEM; import static org.folio.circulation.domain.RequestLevel.TITLE; import static org.folio.circulation.domain.representations.RequestProperties.HOLDINGS_RECORD_ID; @@ -51,7 +52,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.folio.circulation.domain.Item; -import org.folio.circulation.domain.ItemStatus; +import org.folio.circulation.domain.ItemStatusName; import org.folio.circulation.domain.Loan; import org.folio.circulation.domain.MultipleRecords; import org.folio.circulation.domain.Request; @@ -85,7 +86,7 @@ class RequestFromRepresentationService { private static final Logger log = LogManager.getLogger(MethodHandles.lookup().lookupClass()); private static final PageLimit LOANS_PAGE_LIMIT = limit(10000); - private static final Set RECALLABLE_ITEM_STATUSES = + private static final Set RECALLABLE_ITEM_STATUSES = Set.of(PAGED, AWAITING_PICKUP, AWAITING_DELIVERY); private final Request.Operation operation; private final InstanceRepository instanceRepository; @@ -317,7 +318,7 @@ private CompletableFuture> findItemForRecall(Request request) { private Result findRecallableItemOrFail(Request request) { return request.getInstanceItems() .stream() - .filter(item -> RECALLABLE_ITEM_STATUSES.contains(item.getStatus())) + .filter(item -> RECALLABLE_ITEM_STATUSES.contains(item.getStatus().getName())) .findFirst() .map(request::withItem) .map(Result::succeeded) diff --git a/src/main/java/org/folio/circulation/resources/RequestHoldShelfClearanceResource.java b/src/main/java/org/folio/circulation/resources/RequestHoldShelfClearanceResource.java index eb2774b81b..a46c7392bd 100644 --- a/src/main/java/org/folio/circulation/resources/RequestHoldShelfClearanceResource.java +++ b/src/main/java/org/folio/circulation/resources/RequestHoldShelfClearanceResource.java @@ -1,6 +1,6 @@ package org.folio.circulation.resources; -import static org.folio.circulation.domain.ItemStatus.AWAITING_PICKUP; +import static org.folio.circulation.domain.ItemStatusName.AWAITING_PICKUP; import static org.folio.circulation.domain.RequestStatus.CLOSED_CANCELLED; import static org.folio.circulation.domain.RequestStatus.CLOSED_PICKUP_EXPIRED; import static org.folio.circulation.domain.RequestStatus.OPEN_AWAITING_PICKUP; @@ -92,7 +92,7 @@ private void getMany(RoutingContext routingContext) { final String servicePointId = routingContext.request().getParam(SERVICE_POINT_ID_PARAM); - itemReportRepository.getAllItemsByField(STATUS_NAME_KEY, AWAITING_PICKUP.getValue()) + itemReportRepository.getAllItemsByField(STATUS_NAME_KEY, AWAITING_PICKUP.getName()) .thenComposeAsync(r -> r.after(this::mapContextToItemIdList)) .thenComposeAsync(r -> r.after(this::mapItemIdsInBatchItemIds)) .thenComposeAsync(r -> findAwaitingPickupRequestsByItemsIds(requestsStorage, r.value())) diff --git a/src/main/java/org/folio/circulation/resources/handlers/LoanRelatedFeeFineClosedHandlerResource.java b/src/main/java/org/folio/circulation/resources/handlers/LoanRelatedFeeFineClosedHandlerResource.java index 2742ae6495..7f9dc657ee 100644 --- a/src/main/java/org/folio/circulation/resources/handlers/LoanRelatedFeeFineClosedHandlerResource.java +++ b/src/main/java/org/folio/circulation/resources/handlers/LoanRelatedFeeFineClosedHandlerResource.java @@ -112,9 +112,12 @@ public CompletableFuture> closeLoanAndUpdateItem(Loan loan, } boolean wasLoanOpen = loan.isOpen(); - loan.closeLoanAsLostAndPaid(); - return new StoreLoanAndItem(loanRepository, itemRepository).updateLoanAndItemInStorage(loan) + final var changedLoan = loan.closeLoanAsLostAndPaid(); + + final var storeLoanAndItem = new StoreLoanAndItem(loanRepository, itemRepository); + + return storeLoanAndItem.updateLoanAndItemInStorage(changedLoan) .thenCompose(r -> r.after(l -> publishLoanClosedEvent(l, wasLoanOpen, eventPublisher))); } diff --git a/src/main/java/org/folio/circulation/resources/renewal/RenewByIdResource.java b/src/main/java/org/folio/circulation/resources/renewal/RenewByIdResource.java index 14d2b2a1ad..0b2d084643 100644 --- a/src/main/java/org/folio/circulation/resources/renewal/RenewByIdResource.java +++ b/src/main/java/org/folio/circulation/resources/renewal/RenewByIdResource.java @@ -61,7 +61,7 @@ private CompletableFuture> lookupItem(ItemByIdInStorageFinder itemF String itemId, CirculationErrorHandler errorHandler) { return itemFinder.findItemById(itemId) - .thenApply(r -> errorHandler.handleValidationResult(r, ITEM_DOES_NOT_EXIST, (Item) null)); + .thenApply(r -> errorHandler.handleValidationResult(r, ITEM_DOES_NOT_EXIST, Item.unknown())); } private CompletableFuture> lookupLoan( diff --git a/src/main/java/org/folio/circulation/resources/renewal/RenewalResource.java b/src/main/java/org/folio/circulation/resources/renewal/RenewalResource.java index 0fef2631da..8ccc02fb72 100644 --- a/src/main/java/org/folio/circulation/resources/renewal/RenewalResource.java +++ b/src/main/java/org/folio/circulation/resources/renewal/RenewalResource.java @@ -1,10 +1,10 @@ package org.folio.circulation.resources.renewal; import static java.util.concurrent.CompletableFuture.completedFuture; -import static org.folio.circulation.domain.ItemStatus.AGED_TO_LOST; -import static org.folio.circulation.domain.ItemStatus.CHECKED_OUT; -import static org.folio.circulation.domain.ItemStatus.CLAIMED_RETURNED; -import static org.folio.circulation.domain.ItemStatus.DECLARED_LOST; +import static org.folio.circulation.domain.ItemStatusName.AGED_TO_LOST; +import static org.folio.circulation.domain.ItemStatusName.CHECKED_OUT; +import static org.folio.circulation.domain.ItemStatusName.CLAIMED_RETURNED; +import static org.folio.circulation.domain.ItemStatusName.DECLARED_LOST; import static org.folio.circulation.domain.RequestType.HOLD; import static org.folio.circulation.domain.RequestType.RECALL; import static org.folio.circulation.domain.override.OverridableBlockType.PATRON_BLOCK; @@ -48,7 +48,7 @@ import org.apache.commons.lang3.StringUtils; import org.folio.circulation.StoreLoanAndItem; -import org.folio.circulation.domain.ItemStatus; +import org.folio.circulation.domain.ItemStatusName; import org.folio.circulation.domain.Loan; import org.folio.circulation.domain.LoanRepresentation; import org.folio.circulation.domain.OverdueFineService; @@ -111,9 +111,9 @@ public abstract class RenewalResource extends Resource { private static final String DUE_DATE = "dueDate"; private static final String OVERRIDE_BLOCKS = "overrideBlocks"; private static final String RENEWAL_DUE_DATE_REQUIRED_OVERRIDE_BLOCK = "renewalDueDateRequiredBlock"; - private static final EnumSet ITEM_STATUSES_DISALLOWED_FOR_RENEW = EnumSet.of( + private static final EnumSet ITEM_STATUSES_DISALLOWED_FOR_RENEW = EnumSet.of( AGED_TO_LOST, DECLARED_LOST); - private static final EnumSet ITEM_STATUSES_NOT_POSSIBLE_TO_RENEW = EnumSet.of( + private static final EnumSet ITEM_STATUSES_NOT_POSSIBLE_TO_RENEW = EnumSet.of( CLAIMED_RETURNED); private boolean isRenewalBlockOverrideRequested; @@ -462,11 +462,11 @@ private Result processRenewal(Result calculatedDueDate, Loa } private Loan overrideRenewLoan(ZonedDateTime dueDate, Loan loan, String comment) { - if (loan.isAgedToLost()) { - loan.removeAgedToLostBillingInfo(); - } + final Loan changedLoan = loan.isAgedToLost() + ? loan.removeAgedToLostBillingInfo() + : loan; - return loan.overrideRenewal(dueDate, loan.getLoanPolicyId(), comment) + return changedLoan.overrideRenewal(dueDate, loan.getLoanPolicyId(), comment) .changeItemStatusForItemAndLoan(CHECKED_OUT); } diff --git a/src/main/java/org/folio/circulation/services/EventPublisher.java b/src/main/java/org/folio/circulation/services/EventPublisher.java index e5d3534157..3a520a1a68 100644 --- a/src/main/java/org/folio/circulation/services/EventPublisher.java +++ b/src/main/java/org/folio/circulation/services/EventPublisher.java @@ -190,10 +190,11 @@ public CompletableFuture> publishLoanClosedEvent(Loan loan) { } private CompletableFuture> publishDueDateChangedEvent(Loan loan, RequestAndRelatedRecords records) { - if (records.getRecalledLoanPreviousDueDate() != null) { - loan.setPreviousDueDate(records.getRecalledLoanPreviousDueDate()); - } - return publishDueDateChangedEvent(loan, records.getRequest().getRequester(), false); + final var loanWithPreviousDueDate = records.getRecalledLoanPreviousDueDate() != null + ? loan.setPreviousDueDate(records.getRecalledLoanPreviousDueDate()) + : loan; + + return publishDueDateChangedEvent(loanWithPreviousDueDate, records.getRequest().getRequester(), false); } private CompletableFuture> publishDueDateChangedEvent(Loan loan, User user, boolean renewalContext) { @@ -258,12 +259,13 @@ public CompletableFuture> publishAgedToLostEvents(Loan loan) { .thenCompose(r -> r.after(v -> publishStatusChangeEvent(ITEM_AGED_TO_LOST, loan))); } - public CompletableFuture> publishClosedLoanEvent(Loan loan) { + public CompletableFuture> publishClosedLoanEvent(Loan loan) { if (!CHECKED_IN.getValue().equalsIgnoreCase(loan.getAction())) { return publishLogRecord(LoanLogContext.from(loan) - .withServicePointId(loan.getCheckoutServicePointId()).asJson(), LOAN); + .withServicePointId(loan.getCheckoutServicePointId()).asJson(), LOAN) + .thenApply(r -> r.map(x -> loan)); } - return CompletableFuture.completedFuture(succeeded(null)); + return CompletableFuture.completedFuture(succeeded(loan)); } public CompletableFuture> publishMarkedAsMissingLoanEvent(Loan loan) { diff --git a/src/main/java/org/folio/circulation/services/ItemForPageTlrService.java b/src/main/java/org/folio/circulation/services/ItemForPageTlrService.java index aa2b93e095..54e66823d7 100644 --- a/src/main/java/org/folio/circulation/services/ItemForPageTlrService.java +++ b/src/main/java/org/folio/circulation/services/ItemForPageTlrService.java @@ -4,6 +4,7 @@ import static java.util.stream.Collectors.groupingBy; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toSet; +import static org.folio.circulation.domain.ItemStatusName.AVAILABLE; import static org.folio.circulation.domain.representations.RequestProperties.INSTANCE_ID; import static org.folio.circulation.support.ValidationErrorFailure.failedValidation; @@ -17,7 +18,6 @@ import java.util.function.Function; import org.folio.circulation.domain.Item; -import org.folio.circulation.domain.ItemStatus; import org.folio.circulation.domain.Location; import org.folio.circulation.domain.Request; import org.folio.circulation.infrastructure.storage.inventory.LocationRepository; @@ -38,7 +38,7 @@ public static ItemForPageTlrService using(Clients clients) { public CompletableFuture> findItem(Request request) { List availableItems = request.getInstanceItems() .stream() - .filter(item -> ItemStatus.AVAILABLE == item.getStatus()) + .filter(item -> item.getStatus().is(AVAILABLE)) .collect(toList()); if (availableItems.isEmpty()) { diff --git a/src/main/java/org/folio/circulation/services/ItemsInTransitReportService.java b/src/main/java/org/folio/circulation/services/ItemsInTransitReportService.java index 3716922dc0..2ebe6b5124 100644 --- a/src/main/java/org/folio/circulation/services/ItemsInTransitReportService.java +++ b/src/main/java/org/folio/circulation/services/ItemsInTransitReportService.java @@ -3,7 +3,7 @@ import static java.util.concurrent.CompletableFuture.completedFuture; import static java.util.function.Function.identity; import static java.util.stream.Collectors.toSet; -import static org.folio.circulation.domain.ItemStatus.IN_TRANSIT; +import static org.folio.circulation.domain.ItemStatusName.IN_TRANSIT; import static org.folio.circulation.support.results.Result.combineAll; import static org.folio.circulation.support.results.Result.ofAsync; import static org.folio.circulation.support.results.Result.succeeded; @@ -87,7 +87,7 @@ public CompletableFuture> buildReport() { private CompletableFuture> fetchItems( ItemsInTransitReportContext context) { - return itemReportRepository.getAllItemsByField("status.name", IN_TRANSIT.getValue()) + return itemReportRepository.getAllItemsByField("status.name", IN_TRANSIT.getName()) .thenApply(r -> r.next(itemsReportFetcher -> combineAll(itemsReportFetcher.getResultListOfItems()) .map(listOfPages -> listOfPages.stream() diff --git a/src/main/java/org/folio/circulation/services/LostItemFeeChargingService.java b/src/main/java/org/folio/circulation/services/LostItemFeeChargingService.java index 3938e5939d..75782439db 100644 --- a/src/main/java/org/folio/circulation/services/LostItemFeeChargingService.java +++ b/src/main/java/org/folio/circulation/services/LostItemFeeChargingService.java @@ -150,8 +150,7 @@ private CompletableFuture> removeAndRefundFees( private CompletableFuture> closeLoanAsLostAndPaidAndPublishEvent(Loan loan) { return closeLoanAsLostAndPaidAndUpdateInStorage(loan) - .thenCompose(r -> r.after(eventPublisher::publishClosedLoanEvent)) - .thenApply(r -> r.map(v -> loan)); + .thenCompose(r -> r.after(eventPublisher::publishClosedLoanEvent)); } private Boolean isOpenLostItemFee(Account account) { @@ -160,12 +159,11 @@ private Boolean isOpenLostItemFee(Account account) { } private Boolean hasLostItemFees(Loan loan) { - return loan.getAccounts().stream().anyMatch(account -> isOpenLostItemFee(account)); + return loan.getAccounts().stream().anyMatch(this::isOpenLostItemFee); } private CompletableFuture> closeLoanAsLostAndPaidAndUpdateInStorage(Loan loan) { - loan.closeLoanAsLostAndPaid(); - return storeLoanAndItem.updateLoanAndItemInStorage(loan); + return storeLoanAndItem.updateLoanAndItemInStorage(loan.closeLoanAsLostAndPaid()); } private boolean shouldCloseLoan(LostItemPolicy policy) { diff --git a/src/main/java/org/folio/circulation/services/LostItemFeeRefundContext.java b/src/main/java/org/folio/circulation/services/LostItemFeeRefundContext.java index 213bc0f063..c52f028f0b 100644 --- a/src/main/java/org/folio/circulation/services/LostItemFeeRefundContext.java +++ b/src/main/java/org/folio/circulation/services/LostItemFeeRefundContext.java @@ -3,7 +3,7 @@ import static org.folio.circulation.domain.AccountCancelReason.CANCELLED_ITEM_RENEWED; import static org.folio.circulation.domain.AccountCancelReason.CANCELLED_ITEM_RETURNED; import static org.folio.circulation.domain.AccountRefundReason.LOST_ITEM_FOUND; -import static org.folio.circulation.domain.ItemStatus.LOST_AND_PAID; +import static org.folio.circulation.domain.ItemStatusName.LOST_AND_PAID; import java.time.ZonedDateTime; import java.util.Collection; @@ -59,7 +59,8 @@ ZonedDateTime getItemLostDate() { } boolean shouldRefundFeesForItem() { - return initialItemStatus.isLostNotResolved() || initialItemStatus == LOST_AND_PAID; + return initialItemStatus.isLostNotResolved() + || initialItemStatus.getName() == LOST_AND_PAID; } boolean hasLoan() { diff --git a/src/main/java/org/folio/circulation/services/agedtolost/ChargeLostFeesWhenAgedToLostService.java b/src/main/java/org/folio/circulation/services/agedtolost/ChargeLostFeesWhenAgedToLostService.java index fdc88c70d6..0a598c9c1a 100644 --- a/src/main/java/org/folio/circulation/services/agedtolost/ChargeLostFeesWhenAgedToLostService.java +++ b/src/main/java/org/folio/circulation/services/agedtolost/ChargeLostFeesWhenAgedToLostService.java @@ -4,7 +4,7 @@ import static org.folio.circulation.domain.FeeFine.LOST_ITEM_FEE_TYPE; import static org.folio.circulation.domain.FeeFine.LOST_ITEM_PROCESSING_FEE_TYPE; import static org.folio.circulation.domain.FeeFine.lostItemFeeTypes; -import static org.folio.circulation.domain.ItemStatus.AGED_TO_LOST; +import static org.folio.circulation.domain.ItemStatusName.AGED_TO_LOST; import static org.folio.circulation.domain.representations.LoanProperties.AGED_TO_LOST_DELAYED_BILLING; import static org.folio.circulation.domain.representations.LoanProperties.DATE_LOST_ITEM_SHOULD_BE_BILLED; import static org.folio.circulation.domain.representations.LoanProperties.ITEM_STATUS; @@ -129,13 +129,13 @@ private CompletableFuture> chargeLostFeesForLoans( .thenApply(Result::mapEmpty); } - private CompletableFuture> processLoan(LoanToChargeFees loan) { + private CompletableFuture> processLoan(LoanToChargeFees loan) { return loan.shouldCloseLoanWhenActualCostUsed() - ? closeLoanAsLostAndPaid(loan).thenApply(Result::mapEmpty) + ? closeLoanAsLostAndPaid(loan) : chargeLostFees(loan); } - private CompletableFuture> chargeLostFees( + private CompletableFuture> chargeLostFees( LoanToChargeFees loanToChargeFees) { return ofAsync(() -> loanToChargeFees) @@ -146,7 +146,7 @@ private CompletableFuture> chargeLostFees( .exceptionally(t -> handleFailure(loanToChargeFees, t.getMessage())); } - private static Result handleFailure(LoanToChargeFees loan, String errorMessage) { + private static Result handleFailure(LoanToChargeFees loan, String errorMessage) { log.error("Failed to charge lost item fee(s) for loan {}: {}", loan.getLoanId(), errorMessage); return succeeded(null); } @@ -272,7 +272,7 @@ private Result loanFetchQuery() { final ZonedDateTime currentDate = getZonedDateTime(); final Result billingDateQuery = lessThanOrEqualTo(billingDateProperty, currentDate); - final Result agedToLostQuery = exactMatch(ITEM_STATUS, AGED_TO_LOST.getValue()); + final Result agedToLostQuery = exactMatch(ITEM_STATUS, AGED_TO_LOST.getName()); final Result hasNotBeenBilledQuery = exactMatch( lostItemHasBeenBilled, "false"); @@ -324,9 +324,9 @@ private CompletableFuture> updateLoanBillingInfo(LoanToChargeFees l private CompletableFuture> closeLoanAsLostAndPaid(LoanToChargeFees loanToChargeFees) { final Loan loan = loanToChargeFees.getLoan(); - loan.setLostItemHasBeenBilled(); - loan.closeLoanAsLostAndPaid(); + final var changedLoan = loan.setLostItemHasBeenBilled() + .closeLoanAsLostAndPaid(); - return storeLoanAndItem.updateLoanAndItemInStorage(loan); + return storeLoanAndItem.updateLoanAndItemInStorage(changedLoan); } } diff --git a/src/main/java/org/folio/circulation/services/agedtolost/MarkOverdueLoansAsAgedLostService.java b/src/main/java/org/folio/circulation/services/agedtolost/MarkOverdueLoansAsAgedLostService.java index 4ca2cb9b9b..101b31c497 100644 --- a/src/main/java/org/folio/circulation/services/agedtolost/MarkOverdueLoansAsAgedLostService.java +++ b/src/main/java/org/folio/circulation/services/agedtolost/MarkOverdueLoansAsAgedLostService.java @@ -1,8 +1,8 @@ package org.folio.circulation.services.agedtolost; -import static org.folio.circulation.domain.ItemStatus.AGED_TO_LOST; -import static org.folio.circulation.domain.ItemStatus.CLAIMED_RETURNED; -import static org.folio.circulation.domain.ItemStatus.DECLARED_LOST; +import static org.folio.circulation.domain.ItemStatusName.AGED_TO_LOST; +import static org.folio.circulation.domain.ItemStatusName.CLAIMED_RETURNED; +import static org.folio.circulation.domain.ItemStatusName.DECLARED_LOST; import static org.folio.circulation.support.AsyncCoordinationUtil.allOf; import static org.folio.circulation.support.CqlSortBy.ascending; import static org.folio.circulation.support.http.client.CqlQuery.exactMatch; @@ -141,9 +141,9 @@ private boolean shouldAgeLoanToLost(Loan loan) { private Result loanFetchQuery() { final Result statusQuery = exactMatch("status.name", "Open"); final Result dueDateQuery = lessThan("dueDate", formatDateTime(ClockUtil.getZonedDateTime())); - final Result claimedReturnedQuery = notEqual("itemStatus", CLAIMED_RETURNED.getValue()); - final Result agedToLostQuery = notEqual("itemStatus", AGED_TO_LOST.getValue()); - final Result declaredLostQuery = notEqual("itemStatus", DECLARED_LOST.getValue()); + final Result claimedReturnedQuery = notEqual("itemStatus", CLAIMED_RETURNED.getName()); + final Result agedToLostQuery = notEqual("itemStatus", AGED_TO_LOST.getName()); + final Result declaredLostQuery = notEqual("itemStatus", DECLARED_LOST.getName()); return statusQuery.combine(dueDateQuery, CqlQuery::and) .combine(claimedReturnedQuery, CqlQuery::and) diff --git a/src/main/java/org/folio/circulation/storage/mappers/ItemMapper.java b/src/main/java/org/folio/circulation/storage/mappers/ItemMapper.java index 78f1ce14bf..da3893d5e4 100644 --- a/src/main/java/org/folio/circulation/storage/mappers/ItemMapper.java +++ b/src/main/java/org/folio/circulation/storage/mappers/ItemMapper.java @@ -1,6 +1,7 @@ package org.folio.circulation.storage.mappers; import static org.apache.commons.lang3.StringUtils.firstNonBlank; +import static org.folio.circulation.support.json.JsonPropertyFetcher.getNestedStringProperty; import static org.folio.circulation.support.json.JsonPropertyFetcher.getProperty; import static org.folio.circulation.support.json.JsonStringArrayPropertyFetcher.toStream; @@ -11,6 +12,8 @@ import org.folio.circulation.domain.Instance; import org.folio.circulation.domain.Item; import org.folio.circulation.domain.ItemDescription; +import org.folio.circulation.domain.ItemStatus; +import org.folio.circulation.domain.ItemStatusName; import org.folio.circulation.domain.LastCheckIn; import org.folio.circulation.domain.LoanType; import org.folio.circulation.domain.Location; @@ -21,7 +24,7 @@ public class ItemMapper { public Item toDomain(JsonObject representation) { - return new Item(getProperty(representation, "id"), representation, + return new Item(getProperty(representation, "id"), Location.unknown(getProperty(representation, "effectiveLocationId")), LastCheckIn.fromItemJson(representation), CallNumberComponents.fromItemJson(representation), @@ -30,7 +33,8 @@ public Item toDomain(JsonObject representation) { Holdings.unknown(getProperty(representation, "holdingsRecordId")), Instance.unknown(), MaterialType.unknown(getProperty(representation, "materialTypeId")), - LoanType.unknown(getLoanTypeId(representation)), getDescription(representation)); + LoanType.unknown(getLoanTypeId(representation)), getDescription(representation), + getItemStatus(representation)); } private ItemDescription getDescription(JsonObject representation) { @@ -46,6 +50,14 @@ private ItemDescription getDescription(JsonObject representation) { .collect(Collectors.toList())); } + private ItemStatus getItemStatus(JsonObject representation) { + final String STATUS_PROPERTY = "status"; + + return new ItemStatus(ItemStatusName + .from(getNestedStringProperty(representation, STATUS_PROPERTY, "name")), + getNestedStringProperty(representation, STATUS_PROPERTY, "date")); + } + private ServicePoint getInTransitServicePoint(JsonObject representation) { final var inTransitDestinationServicePointId = getProperty(representation, "inTransitDestinationServicePointId"); diff --git a/src/main/java/org/folio/circulation/support/json/JsonPropertyWriter.java b/src/main/java/org/folio/circulation/support/json/JsonPropertyWriter.java index 9a7594336f..af517517fe 100644 --- a/src/main/java/org/folio/circulation/support/json/JsonPropertyWriter.java +++ b/src/main/java/org/folio/circulation/support/json/JsonPropertyWriter.java @@ -49,12 +49,8 @@ public static void write(JsonObject to, String propertyName, Collection v } } - public static void write( - JsonObject to, - String propertyName, - JsonObject value) { - - if(value != null) { + public static void write(JsonObject to, String propertyName, JsonObject value) { + if (to != null && value != null) { to.put(propertyName, value); } } diff --git a/src/test/java/api/loans/CheckInByBarcodeTests.java b/src/test/java/api/loans/CheckInByBarcodeTests.java index 09f67551de..0493e01b62 100644 --- a/src/test/java/api/loans/CheckInByBarcodeTests.java +++ b/src/test/java/api/loans/CheckInByBarcodeTests.java @@ -36,6 +36,7 @@ import static org.awaitility.Awaitility.waitAtMost; import static org.folio.HttpStatus.HTTP_UNPROCESSABLE_ENTITY; import static org.folio.circulation.domain.EventType.ITEM_CHECKED_IN; +import static org.folio.circulation.domain.ItemStatusName.AWAITING_PICKUP; import static org.folio.circulation.domain.RequestStatus.CLOSED_CANCELLED; import static org.folio.circulation.domain.RequestStatus.CLOSED_PICKUP_EXPIRED; import static org.folio.circulation.domain.RequestStatus.CLOSED_UNFILLED; @@ -66,7 +67,7 @@ import java.util.Map; import java.util.UUID; -import org.folio.circulation.domain.ItemStatus; +import org.folio.circulation.domain.ItemStatusName; import org.folio.circulation.domain.Request; import org.folio.circulation.domain.RequestStatus; import org.folio.circulation.domain.User; @@ -870,7 +871,7 @@ private void patronNoticeIsSentForRequestAwaitingPickupWhenPreviousRequestWasClo // check that both item and first request are awaiting pickup - assertThatItemStatusIs(item.getId(), ItemStatus.AWAITING_PICKUP); + assertThatItemStatusIs(item.getId(), AWAITING_PICKUP); assertThatRequestStatusIs(firstRequest.getId(), RequestStatus.OPEN_AWAITING_PICKUP); // verify that Request Awaiting Pickup notice was sent for first request @@ -913,7 +914,7 @@ private void patronNoticeIsSentForRequestAwaitingPickupWhenPreviousRequestWasClo // verify that first request was closed, and that item is still awaiting pickup - assertThatItemStatusIs(item.getId(), ItemStatus.AWAITING_PICKUP); + assertThatItemStatusIs(item.getId(), AWAITING_PICKUP); assertThatRequestStatusIs(firstRequest.getId(), firstRequestUpdateStatus); // check the item in again @@ -922,7 +923,7 @@ private void patronNoticeIsSentForRequestAwaitingPickupWhenPreviousRequestWasClo // verify that item is still awaiting pickup, and that second request is now awaiting pickup - assertThatItemStatusIs(item.getId(), ItemStatus.AWAITING_PICKUP); + assertThatItemStatusIs(item.getId(), AWAITING_PICKUP); assertThatRequestStatusIs(secondRequest.getId(), RequestStatus.OPEN_AWAITING_PICKUP); // verify that Request Awaiting Pickup notice was sent to second requester @@ -1757,10 +1758,10 @@ private LocalDate toLocalDate(ZonedDateTime dateTime) { return LocalDate.of(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth()); } - private void assertThatItemStatusIs(UUID itemId, ItemStatus status) { + private void assertThatItemStatusIs(UUID itemId, ItemStatusName status) { final var item = itemsFixture.getById(itemId); - assertThat(item.getStatusName(), is(status.getValue())); + assertThat(item.getStatusName(), is(status.getName())); } private void assertThatRequestStatusIs(UUID requestId, RequestStatus status) { diff --git a/src/test/java/api/loans/OverrideRenewByBarcodeTests.java b/src/test/java/api/loans/OverrideRenewByBarcodeTests.java index c6b1f241d9..8f8e2c8ce1 100644 --- a/src/test/java/api/loans/OverrideRenewByBarcodeTests.java +++ b/src/test/java/api/loans/OverrideRenewByBarcodeTests.java @@ -22,7 +22,7 @@ import static api.support.utl.PatronNoticeTestHelper.verifyNumberOfSentNotices; import static java.time.ZoneOffset.UTC; import static org.apache.commons.lang3.StringUtils.EMPTY; -import static org.folio.circulation.domain.ItemStatus.CHECKED_OUT; +import static org.folio.circulation.domain.ItemStatusName.CHECKED_OUT; import static org.folio.circulation.domain.representations.logs.LogEventType.NOTICE; import static org.folio.circulation.domain.representations.logs.LogEventType.NOTICE_ERROR; import static org.folio.circulation.support.utils.DateFormatUtil.formatDateTime; @@ -40,6 +40,7 @@ import java.util.Map; import java.util.UUID; +import org.folio.circulation.domain.ItemStatusName; import org.folio.circulation.domain.policy.Period; import org.folio.circulation.support.http.client.Response; import org.folio.circulation.support.http.server.ValidationError; @@ -462,7 +463,7 @@ void canOverrideRenewalWhenItemIsDeclaredLost() { assertThat("item status should be changed", renewedLoan.getJsonObject("item").getJsonObject("status").getString("name"), - is(CHECKED_OUT.getValue())); + is(CHECKED_OUT.getName())); ZonedDateTime expectedDueDate = loanDate.plusWeeks(2); assertThat("due date should be 2 weeks later", diff --git a/src/test/java/api/requests/InstanceRequestsAPICreationTests.java b/src/test/java/api/requests/InstanceRequestsAPICreationTests.java index 009fb0bba9..173b4948ed 100644 --- a/src/test/java/api/requests/InstanceRequestsAPICreationTests.java +++ b/src/test/java/api/requests/InstanceRequestsAPICreationTests.java @@ -13,6 +13,7 @@ import static api.support.utl.PatronNoticeTestHelper.verifyNumberOfSentNotices; import static java.time.ZoneOffset.UTC; import static org.folio.HttpStatus.HTTP_CREATED; +import static org.folio.circulation.domain.ItemStatusName.CHECKED_OUT; import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; @@ -29,7 +30,6 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; -import org.folio.circulation.domain.ItemStatus; import org.folio.circulation.domain.RequestLevel; import org.folio.circulation.domain.RequestStatus; import org.folio.circulation.domain.RequestType; @@ -1045,7 +1045,7 @@ private void placeHoldRequest(IndividualResource instance, IndividualResource it ? holdRequest.getJson().getJsonObject("item") : new JsonObject(); assertThat(requestedItem.getString("status"), - is(ItemStatus.CHECKED_OUT.getValue())); + is(CHECKED_OUT.getName())); } } diff --git a/src/test/java/api/requests/ItemsInTransitReportTests.java b/src/test/java/api/requests/ItemsInTransitReportTests.java index 7a2ad6fcfd..fc78d67b39 100644 --- a/src/test/java/api/requests/ItemsInTransitReportTests.java +++ b/src/test/java/api/requests/ItemsInTransitReportTests.java @@ -1,6 +1,7 @@ package api.requests; import static api.support.JsonCollectionAssistant.getRecordById; +import static api.support.builders.ItemBuilder.IN_TRANSIT; import static api.support.matchers.TextDateTimeMatcher.isEquivalentTo; import static java.time.ZoneOffset.UTC; import static org.folio.circulation.support.StreamToListMapper.toList; @@ -19,7 +20,6 @@ import java.util.List; import java.util.UUID; -import org.folio.circulation.domain.ItemStatus; import org.folio.circulation.support.json.JsonPropertyFetcher; import org.folio.circulation.support.utils.ClockUtil; import org.junit.jupiter.api.AfterEach; @@ -490,8 +490,7 @@ private void verifyItem(JsonObject itemJson, ItemResource item, UUID secondServicePointId) { assertThat(itemJson.getString(BARCODE_KEY), is(item.getBarcode())); - assertThat(itemJson.getJsonObject(STATUS_KEY).getMap().get(NAME), - is(ItemStatus.IN_TRANSIT.getValue())); + assertThat(itemJson.getJsonObject(STATUS_KEY).getMap().get(NAME), is(IN_TRANSIT)); assertThat(itemJson.getString(DESTINATION_SERVICE_POINT), is(secondServicePointId.toString())); diff --git a/src/test/java/api/requests/PickSlipsTests.java b/src/test/java/api/requests/PickSlipsTests.java index 9af9331a24..558af31f54 100644 --- a/src/test/java/api/requests/PickSlipsTests.java +++ b/src/test/java/api/requests/PickSlipsTests.java @@ -1,5 +1,6 @@ package api.requests; +import static api.support.builders.ItemBuilder.PAGED; import static api.support.matchers.TextDateTimeMatcher.isEquivalentTo; import static java.net.HttpURLConnection.HTTP_OK; import static java.time.ZoneOffset.UTC; @@ -22,7 +23,6 @@ import org.folio.circulation.domain.CallNumberComponents; import org.folio.circulation.domain.Item; -import org.folio.circulation.domain.ItemStatus; import org.folio.circulation.domain.Location; import org.folio.circulation.domain.RequestStatus; import org.folio.circulation.domain.User; @@ -35,6 +35,7 @@ import api.support.APITests; import api.support.builders.Address; +import api.support.builders.ItemBuilder; import api.support.builders.RequestBuilder; import api.support.fixtures.AddressExamples; import api.support.http.IndividualResource; @@ -184,7 +185,7 @@ void responseContainsPickSlipWithAllAvailableTokens() { assertEquals(item.getTitle(), itemContext.getString("title")); assertEquals(item.getBarcode(), itemContext.getString("barcode")); - assertEquals(ItemStatus.PAGED.getValue(), itemContext.getString("status")); + assertEquals(PAGED, itemContext.getString("status")); assertEquals(item.getPrimaryContributorName(), itemContext.getString("primaryContributor")); assertEquals(contributorNames, itemContext.getString("allContributors")); assertEquals(item.getEnumeration(), itemContext.getString("enumeration")); diff --git a/src/test/java/api/requests/RequestsAPICreationTests.java b/src/test/java/api/requests/RequestsAPICreationTests.java index 00a25744ab..72fcc86fc2 100644 --- a/src/test/java/api/requests/RequestsAPICreationTests.java +++ b/src/test/java/api/requests/RequestsAPICreationTests.java @@ -1,6 +1,12 @@ package api.requests; import static api.support.PubsubPublisherTestUtils.assertThatPublishedNoticeLogRecordEventsAreValid; +import static api.support.builders.ItemBuilder.AVAILABLE; +import static api.support.builders.ItemBuilder.AWAITING_PICKUP; +import static api.support.builders.ItemBuilder.CHECKED_OUT; +import static api.support.builders.ItemBuilder.IN_TRANSIT; +import static api.support.builders.ItemBuilder.MISSING; +import static api.support.builders.ItemBuilder.PAGED; import static api.support.builders.RequestBuilder.OPEN_AWAITING_PICKUP; import static api.support.builders.RequestBuilder.OPEN_NOT_YET_FILLED; import static api.support.fakes.FakePubSub.getPublishedEventsAsList; @@ -13,6 +19,7 @@ import static api.support.http.Limit.limit; import static api.support.http.Offset.noOffset; import static api.support.matchers.EventMatchers.isValidLoanDueDateChangedEvent; +import static api.support.matchers.ItemStatusCodeMatcher.hasItemStatus; import static api.support.matchers.JsonObjectMatcher.hasJsonPath; import static api.support.matchers.JsonObjectMatcher.hasNoJsonPath; import static api.support.matchers.PatronNoticeMatcher.hasEmailNoticeProperties; @@ -38,8 +45,6 @@ import static org.folio.HttpStatus.HTTP_BAD_REQUEST; import static org.folio.HttpStatus.HTTP_CREATED; import static org.folio.HttpStatus.HTTP_UNPROCESSABLE_ENTITY; -import static org.folio.circulation.domain.ItemStatus.AVAILABLE; -import static org.folio.circulation.domain.ItemStatus.PAGED; import static org.folio.circulation.domain.RequestType.HOLD; import static org.folio.circulation.domain.RequestType.RECALL; import static org.folio.circulation.domain.policy.Period.hours; @@ -80,7 +85,6 @@ import org.apache.http.HttpStatus; import org.awaitility.Awaitility; -import org.folio.circulation.domain.ItemStatus; import org.folio.circulation.domain.MultipleRecords; import org.folio.circulation.domain.RequestLevel; import org.folio.circulation.domain.RequestStatus; @@ -1283,10 +1287,8 @@ void cannotCreateARequestWithUnknownPickupLocationServicePoint() { @Test void canCreatePagedRequestWhenItemStatusIsAvailable() { - //Set up the item's initial status to be AVAILABLE - final IndividualResource smallAngryPlanet = itemsFixture.basedUponSmallAngryPlanet(); - final String itemInitialStatus = smallAngryPlanet.getResponse().getJson().getJsonObject("status").getString("name"); - assertThat(itemInitialStatus, is(ItemStatus.AVAILABLE.getValue())); + final var smallAngryPlanet = itemsFixture.basedUponSmallAngryPlanet(); + assertThat(smallAngryPlanet, hasItemStatus(AVAILABLE)); //Attempt to create a page request on it. Final expected status is PAGED final IndividualResource servicePoint = servicePointsFixture.cd1(); @@ -1299,7 +1301,7 @@ void canCreatePagedRequestWhenItemStatusIsAvailable() { String finalStatus = pagedRequest.getResponse().getJson().getJsonObject("item").getString("status"); assertThat(pagedRequest.getJson().getString("requestType"), is(RequestType.PAGE.getValue())); assertThat(pagedRequest.getResponse(), hasStatus(HTTP_CREATED)); - assertThat(finalStatus, is(ItemStatus.PAGED.getValue())); + assertThat(finalStatus, is(PAGED)); } @Test @@ -1384,8 +1386,7 @@ void canCreateTitleLevelPagedRequest() { assertThat(json.getString("itemId"), is(item.getId())); assertThat(json.getString("instanceId"), is(instanceId)); assertThat(pagedRequest.getResponse(), hasStatus(HTTP_CREATED)); - assertThat(json.getJsonObject("item") - .getString("status"), is(ItemStatus.PAGED.getValue())); + assertThat(json.getJsonObject("item").getString("status"), is(PAGED)); assertThat(json.getString("requestLevel"), is(RequestLevel.TITLE.getValue())); } @@ -1584,7 +1585,7 @@ void canCreateRecallRequestWhenItemIsCheckedOut() { JsonObject requestedItem = recallRequest.getJson().getJsonObject("item"); assertThat(recallRequest.getJson().getString("requestType"), is(RequestType.RECALL.getValue())); - assertThat(requestedItem.getString("status"), is(ItemStatus.CHECKED_OUT.getValue())); + assertThat(requestedItem.getString("status"), is(CHECKED_OUT)); assertThat(recallRequest.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); } @@ -1770,7 +1771,8 @@ void canCreateRecallRequestWhenItemIsAwaitingPickup() { .by(usersFixture.steve())); assertThat(recallRequest.getJson().getString("requestType"), is(RequestType.RECALL.getValue())); - assertThat(recallRequest.getJson().getJsonObject("item").getString("status"), is(ItemStatus.AWAITING_PICKUP.getValue())); + assertThat(recallRequest.getJson().getJsonObject("item").getString("status"), + is(AWAITING_PICKUP)); assertThat(recallRequest.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); } @@ -1791,7 +1793,7 @@ void canCreateRecallRequestWhenItemIsInTransit() { JsonObject requestItem = recallRequest.getJson().getJsonObject("item"); assertThat(recallRequest.getJson().getString("requestType"), is(RequestType.RECALL.getValue())); - assertThat(requestItem.getString("status"), is(ItemStatus.IN_TRANSIT.getValue())); + assertThat(requestItem.getString("status"), is(IN_TRANSIT)); assertThat(recallRequest.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); } @@ -1843,7 +1845,7 @@ void canCreateRecallRequestWhenItemIsPaged() { .by(usersFixture.jessica())); assertThat(recallResponse.getJson().getString("requestType"), is(RECALL.getValue())); - assertThat(pagedItem.getResponse().getJson().getJsonObject("status").getString("name"), is(PAGED.getValue())); + assertThat(pagedItem, hasItemStatus(PAGED)); assertThat(recallResponse.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); } @@ -1863,8 +1865,9 @@ void canCreateHoldRequestWhenItemIsCheckedOut() { JsonObject requestedItem = holdRequest.getJson().getJsonObject("item"); assertThat(holdRequest.getJson().getString("requestType"), is(HOLD.getValue())); - assertThat(requestedItem.getString("status"), is(ItemStatus.CHECKED_OUT.getValue())); + assertThat(requestedItem.getString("status"), is(CHECKED_OUT)); assertThat(holdRequest.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); + var publishedEvents = Awaitility.await() .atMost(1, TimeUnit.SECONDS) .until(FakePubSub::getPublishedEvents, hasSize(5)); @@ -1885,7 +1888,8 @@ void canCreateHoldRequestWhenItemIsAwaitingPickup() { .by(usersFixture.steve())); assertThat(holdRequest.getJson().getString("requestType"), is(HOLD.getValue())); - assertThat(holdRequest.getJson().getJsonObject("item").getString("status"), is(ItemStatus.AWAITING_PICKUP.getValue())); + assertThat(holdRequest.getJson().getJsonObject("item").getString("status"), + is(AWAITING_PICKUP)); assertThat(holdRequest.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); } @@ -1907,7 +1911,7 @@ void canCreateHoldRequestWhenItemIsInTransit() { JsonObject requestedItem = holdRequest.getJson().getJsonObject("item"); assertThat(holdRequest.getJson().getString("requestType"), is(HOLD.getValue())); - assertThat(requestedItem.getString("status"), is(ItemStatus.IN_TRANSIT.getValue())); + assertThat(requestedItem.getString("status"), is(IN_TRANSIT)); assertThat(holdRequest.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); } @@ -1925,7 +1929,7 @@ void canCreateHoldRequestWhenItemIsMissing() { JsonObject requestedItem = holdRequest.getJson().getJsonObject("item"); assertThat(holdRequest.getJson().getString("requestType"), is(HOLD.getValue())); - assertThat(requestedItem.getString("status"), is(ItemStatus.MISSING.getValue())); + assertThat(requestedItem.getString("status"), is(MISSING)); assertThat(holdRequest.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); } @@ -1959,7 +1963,7 @@ void canCreateHoldRequestWhenItemIsPaged() { .by(usersFixture.steve())); assertThat(holdRequest.getJson().getString("requestType"), is(HOLD.getValue())); - assertThat(holdRequest.getJson().getJsonObject("item").getString("status"), is(ItemStatus.PAGED.getValue())); + assertThat(holdRequest.getJson().getJsonObject("item").getString("status"), is(PAGED)); assertThat(holdRequest.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); } @@ -2484,10 +2488,8 @@ void recallNoticeToLoanOwnerIsSendWhenDueDateIsNotChanged() { @Test void canCreatePagedRequestWithNullProxyUser() { - //Set up the item's initial status to be AVAILABLE final IndividualResource smallAngryPlanet = itemsFixture.basedUponSmallAngryPlanet(); - final String itemInitialStatus = smallAngryPlanet.getResponse().getJson().getJsonObject("status").getString("name"); - assertThat(itemInitialStatus, is(ItemStatus.AVAILABLE.getValue())); + assertThat(smallAngryPlanet, hasItemStatus(AVAILABLE)); //Attempt to create a page request on it. Final expected status is PAGED final IndividualResource servicePoint = servicePointsFixture.cd1(); @@ -2501,7 +2503,7 @@ void canCreatePagedRequestWithNullProxyUser() { String finalStatus = pagedRequest.getResponse().getJson().getJsonObject("item").getString("status"); assertThat(pagedRequest.getJson().getString("requestType"), is(RequestType.PAGE.getValue())); assertThat(pagedRequest.getResponse(), hasStatus(HTTP_CREATED)); - assertThat(finalStatus, is(ItemStatus.PAGED.getValue())); + assertThat(finalStatus, is(PAGED)); } @Test @@ -3253,8 +3255,7 @@ void pageRequestShouldNotChangeItemStatusIfFailsWithoutRequestDate() { hasMessage("Cannot create a request with no requestDate"), hasParameter("requestDate", null)))); var itemById = itemsFixture.getById(item.getId()); - assertThat(itemById.getResponse().getJson().getJsonObject("status").getString("name"), - is(AVAILABLE.getValue())); + assertThat(itemById, hasItemStatus(AVAILABLE)); } @ParameterizedTest @@ -3282,8 +3283,7 @@ void pageRequestShouldNotBeCreatedIfFulfilmentPreferenceIsNotValid(String fulfil hasMessage("fulfilmentPreference must be one of the following: Hold Shelf, Delivery"), hasParameter("fulfilmentPreference", fulfilmentPreference)))); var itemById = itemsFixture.getById(item.getId()); - assertThat(itemById.getResponse().getJson().getJsonObject("status").getString("name"), - is(AVAILABLE.getValue())); + assertThat(itemById, hasItemStatus(AVAILABLE)); } @Test @@ -3601,7 +3601,7 @@ private void validateNoticeLogContextItem(JsonObject noticeLogContextItem, ItemR } private boolean isNotPaged(IndividualResource item) { - return !PAGED.getValue().equals(item.getJson().getJsonObject("status").getString("name")); + return !PAGED.equals(item.getJson().getJsonObject("status").getString("name")); } private RequestBuilder buildPageRequest(UUID instanceId, UUID pickupServicePointId, @@ -3730,7 +3730,7 @@ public static ItemResource setupPagedItem(IndividualResource requestPickupServic .by(usersFixture.james())); JsonObject requestedItem = pagedRequest.getJson().getJsonObject("item"); - assertThat(requestedItem.getString("status"), is(ItemStatus.PAGED.getValue())); + assertThat(requestedItem.getString("status"), is(PAGED)); return smallAngryPlanet; } @@ -3751,8 +3751,8 @@ public static IndividualResource setupItemAwaitingPickup( checkInFixture.checkInByBarcode(smallAngryPlanet, ClockUtil.getZonedDateTime(), requestPickupServicePoint.getId()); - Response pagedRequestRecord = itemsClient.getById(smallAngryPlanet.getId()); - assertThat(pagedRequestRecord.getJson().getJsonObject("status").getString("name"), is(ItemStatus.AWAITING_PICKUP.getValue())); + final var pagedItem = itemsFixture.getById(smallAngryPlanet.getId()); + assertThat(pagedItem, hasItemStatus(AWAITING_PICKUP)); return smallAngryPlanet; } @@ -3772,7 +3772,7 @@ public static IndividualResource setupItemInTransit(IndividualResource requestPi .by(usersFixture.james())); JsonObject requestItem = firstRequest.getJson().getJsonObject("item"); - assertThat(requestItem.getString("status"), is(ItemStatus.PAGED.getValue())); + assertThat(requestItem.getString("status"), is(PAGED)); assertThat(firstRequest.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); //check it it at the "wrong" or unintended pickup location @@ -3781,7 +3781,8 @@ public static IndividualResource setupItemInTransit(IndividualResource requestPi MultipleRecords requests = requestsFixture.getQueueFor(smallAngryPlanet); JsonObject pagedRequestRecord = requests.getRecords().iterator().next(); - assertThat(pagedRequestRecord.getJsonObject("item").getString("status"), is(ItemStatus.IN_TRANSIT.getValue())); + assertThat(pagedRequestRecord.getJsonObject("item").getString("status"), + is(IN_TRANSIT)); assertThat(pagedRequestRecord.getString("status"), is(RequestStatus.OPEN_IN_TRANSIT.getValue())); return smallAngryPlanet; @@ -3789,7 +3790,7 @@ public static IndividualResource setupItemInTransit(IndividualResource requestPi public static IndividualResource setupMissingItem(ItemsFixture itemsFixture) { IndividualResource missingItem = itemsFixture.basedUponSmallAngryPlanet(ItemBuilder::missing); - assertThat(missingItem.getResponse().getJson().getJsonObject("status").getString("name"), is(ItemStatus.MISSING.getValue())); + assertThat(missingItem, hasItemStatus(MISSING)); return missingItem; } diff --git a/src/test/java/api/requests/scenarios/MoveRequestTests.java b/src/test/java/api/requests/scenarios/MoveRequestTests.java index a3d5602c39..6b183f673e 100644 --- a/src/test/java/api/requests/scenarios/MoveRequestTests.java +++ b/src/test/java/api/requests/scenarios/MoveRequestTests.java @@ -1,6 +1,7 @@ package api.requests.scenarios; import static api.support.builders.ItemBuilder.AVAILABLE; +import static api.support.builders.ItemBuilder.CHECKED_OUT; import static api.support.builders.ItemBuilder.PAGED; import static api.support.builders.RequestBuilder.OPEN_AWAITING_PICKUP; import static api.support.fixtures.ConfigurationExample.timezoneConfigurationFor; @@ -41,7 +42,6 @@ import java.util.concurrent.TimeUnit; import org.awaitility.Awaitility; -import org.folio.circulation.domain.ItemStatus; import org.folio.circulation.domain.MultipleRecords; import org.folio.circulation.domain.Request; import org.folio.circulation.domain.RequestStatus; @@ -53,6 +53,7 @@ import org.junit.jupiter.api.Test; import api.support.APITests; +import api.support.builders.ItemBuilder; import api.support.builders.LoanPolicyBuilder; import api.support.builders.MoveRequestBuilder; import api.support.builders.RequestBuilder; @@ -109,15 +110,15 @@ void canMoveRequestFromOneItemCopyToAnother() { IndividualResource steve = usersFixture.steve(); IndividualResource charlotte = usersFixture.charlotte(); - assertThat(itemCopyA.getJson().getJsonObject("status").getString("name"), is(ItemStatus.AVAILABLE.getValue())); - assertThat(itemCopyB.getJson().getJsonObject("status").getString("name"), is(ItemStatus.AVAILABLE.getValue())); + assertThat(itemCopyA, hasItemStatus(AVAILABLE)); + assertThat(itemCopyB, hasItemStatus(AVAILABLE)); IndividualResource itemCopyALoan = checkOutFixture.checkOutByBarcode(itemCopyA, james, getZonedDateTime()); assertThat(itemCopyALoan.getJson().getString("userId"), is(james.getId().toString())); assertThat(itemCopyALoan.getJson().getString("itemId"), is(itemCopyA.getId().toString())); - assertThat(itemsClient.get(itemCopyA).getJson().getJsonObject("status").getString("name"), is(ItemStatus.CHECKED_OUT.getValue())); + assertThat(itemsClient.get(itemCopyA), hasItemStatus(CHECKED_OUT)); IndividualResource pageRequestForItemCopyB = requestsFixture.placeItemLevelHoldShelfRequest( itemCopyB, jessica, getZonedDateTime().minusHours(3), RequestType.PAGE.getValue()); @@ -132,13 +133,14 @@ void canMoveRequestFromOneItemCopyToAnother() { assertThat(requestsFixture.getQueueFor(itemCopyB).getTotalRecords(), is(2)); assertThat(pageRequestForItemCopyB.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); - assertThat(pageRequestForItemCopyB.getJson().getJsonObject("item").getString("status"), is(ItemStatus.PAGED.getValue())); + assertThat(pageRequestForItemCopyB.getJson().getJsonObject("item").getString("status"), is(ItemBuilder.PAGED)); assertThat(recallRequestForItemCopyB.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); - assertThat(recallRequestForItemCopyB.getJson().getJsonObject("item").getString("status"), is(ItemStatus.PAGED.getValue())); + assertThat(recallRequestForItemCopyB.getJson().getJsonObject("item").getString("status"), is(ItemBuilder.PAGED)); assertThat(holdRequestForItemCopyA.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); - assertThat(holdRequestForItemCopyA.getJson().getJsonObject("item").getString("status"), is(ItemStatus.CHECKED_OUT.getValue())); + assertThat(holdRequestForItemCopyA.getJson().getJsonObject("item").getString("status"), + is(CHECKED_OUT)); IndividualResource moveRecallRequestToItemCopyA = requestsFixture.move(new MoveRequestBuilder( recallRequestForItemCopyB.getId(), @@ -151,7 +153,8 @@ void canMoveRequestFromOneItemCopyToAnother() { assertThat(moveRecallRequestToItemCopyA.getJson().getString("itemId"), is(itemCopyA.getId().toString())); assertThat(moveRecallRequestToItemCopyA.getJson().getString("requesterId"), is(steve.getId().toString())); assertThat(moveRecallRequestToItemCopyA.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); - assertThat(moveRecallRequestToItemCopyA.getJson().getJsonObject("item").getString("status"), is(ItemStatus.CHECKED_OUT.getValue())); + assertThat(moveRecallRequestToItemCopyA.getJson().getJsonObject("item").getString("status"), + is(CHECKED_OUT)); assertThat(moveRecallRequestToItemCopyA.getJson().getInteger("position"), is(2)); retainsStoredSummaries(moveRecallRequestToItemCopyA); @@ -159,7 +162,8 @@ void canMoveRequestFromOneItemCopyToAnother() { assertThat(holdRequestForItemCopyA.getJson().getString("itemId"), is(itemCopyA.getId().toString())); assertThat(holdRequestForItemCopyA.getJson().getString("requesterId"), is(charlotte.getId().toString())); assertThat(holdRequestForItemCopyA.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); - assertThat(holdRequestForItemCopyA.getJson().getJsonObject("item").getString("status"), is(ItemStatus.CHECKED_OUT.getValue())); + assertThat(holdRequestForItemCopyA.getJson().getJsonObject("item").getString("status"), + is(CHECKED_OUT)); assertThat(holdRequestForItemCopyA.getJson().getInteger("position"), is(1)); retainsStoredSummaries(holdRequestForItemCopyA); @@ -167,7 +171,8 @@ void canMoveRequestFromOneItemCopyToAnother() { assertThat(pageRequestForItemCopyB.getJson().getString("itemId"), is(itemCopyB.getId().toString())); assertThat(pageRequestForItemCopyB.getJson().getString("requesterId"), is(jessica.getId().toString())); assertThat(pageRequestForItemCopyB.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); - assertThat(pageRequestForItemCopyB.getJson().getJsonObject("item").getString("status"), is(ItemStatus.PAGED.getValue())); + assertThat(pageRequestForItemCopyB.getJson().getJsonObject("item").getString("status"), + is(PAGED)); assertThat(pageRequestForItemCopyB.getJson().getInteger("position"), is(1)); retainsStoredSummaries(pageRequestForItemCopyB); @@ -175,9 +180,8 @@ void canMoveRequestFromOneItemCopyToAnother() { assertThat(itemCopyALoan.getJson().getString("userId"), is(james.getId().toString())); assertThat(itemCopyALoan.getJson().getString("itemId"), is(itemCopyA.getId().toString())); - assertThat(itemsClient.get(itemCopyA).getJson().getJsonObject("status").getString("name"), is(ItemStatus.CHECKED_OUT.getValue())); - - assertThat(itemsClient.get(itemCopyB).getJson().getJsonObject("status").getString("name"), is(ItemStatus.PAGED.getValue())); + assertThat(itemsClient.get(itemCopyA), hasItemStatus(CHECKED_OUT)); + assertThat(itemsClient.get(itemCopyB), hasItemStatus(ItemBuilder.PAGED)); } @Test @@ -197,11 +201,11 @@ void itemShouldRemainPagedIfHoldCreatedAfterRequestHasBeenMovedToAnotherItem() { requestsFixture.move(new MoveRequestBuilder(pageIlrForFirstItem.getId(), secondItem.getId(), RequestType.HOLD.value)); - assertThat(itemsClient.get(firstItem), hasItemStatus(PAGED)); + assertThat(itemsClient.get(firstItem), hasItemStatus(ItemBuilder.PAGED)); requestsFixture.placeItemLevelHoldShelfRequest(firstItem, jessica); - assertThat(itemsClient.get(firstItem), hasItemStatus(PAGED)); + assertThat(itemsClient.get(firstItem), hasItemStatus(ItemBuilder.PAGED)); } @Test @@ -493,7 +497,7 @@ void canMoveAShelfHoldRequestToAnAvailableItem() { requestByJessica = requestsClient.get(requestByJessica); assertThat(requestByJessica.getJson().getString(REQUEST_TYPE), is(RequestType.PAGE.getValue())); - assertThat(requestByJessica.getJson().getJsonObject("item").getString("status"), is(ItemStatus.PAGED.getValue())); + assertThat(requestByJessica.getJson().getJsonObject("item").getString("status"), is(ItemBuilder.PAGED)); assertThat(requestByJessica.getJson().getInteger("position"), is(1)); assertThat(requestByJessica.getJson().getString("itemId"), is(itemToMoveTo.getId().toString())); assertThat(requestByJessica.getJson().getString("patronComments"), @@ -1042,7 +1046,8 @@ void cannotDisplacePagedRequest() { assertThat(stevesRequest.getJson().getInteger("position"), is(1)); assertThat(stevesRequest.getJson().getJsonObject("item").getString("barcode"), is(itemCopyA.getBarcode())); - assertThat(stevesRequest.getJson().getJsonObject("item").getString("status"), is(ItemStatus.CHECKED_OUT.getValue())); + assertThat(stevesRequest.getJson().getJsonObject("item").getString("status"), + is(CHECKED_OUT)); assertThat(stevesRequest.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); // Jessica requests Item Copy B @@ -1052,7 +1057,7 @@ void cannotDisplacePagedRequest() { // Confirm Jessica's request is first on Item Copy B and is a paged request assertThat(jessicasRequest.getJson().getInteger("position"), is(1)); assertThat(jessicasRequest.getJson().getJsonObject("item").getString("barcode"), is(itemCopyB.getBarcode())); - assertThat(jessicasRequest.getJson().getJsonObject("item").getString("status"), is(ItemStatus.PAGED.getValue())); + assertThat(jessicasRequest.getJson().getJsonObject("item").getString("status"), is(ItemBuilder.PAGED)); assertThat(jessicasRequest.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); // Move recallRequestForItemCopyA to Item Copy B @@ -1062,13 +1067,13 @@ void cannotDisplacePagedRequest() { jessicasRequest = requestsClient.get(jessicasRequest); assertThat(jessicasRequest.getJson().getInteger("position"), is(1)); assertThat(jessicasRequest.getJson().getJsonObject("item").getString("barcode"), is(itemCopyB.getBarcode())); - assertThat(jessicasRequest.getJson().getJsonObject("item").getString("status"), is(ItemStatus.PAGED.getValue())); + assertThat(jessicasRequest.getJson().getJsonObject("item").getString("status"), is(ItemBuilder.PAGED)); // Confirm Steves's request is second on Item Copy B and (is not a paged request (?)) stevesRequest = requestsClient.get(stevesRequest); assertThat(stevesRequest.getJson().getInteger("position"), is(2)); assertThat(stevesRequest.getJson().getJsonObject("item").getString("barcode"), is(itemCopyB.getBarcode())); - assertThat(stevesRequest.getJson().getJsonObject("item").getString("status"), is(ItemStatus.PAGED.getValue())); + assertThat(stevesRequest.getJson().getJsonObject("item").getString("status"), is(ItemBuilder.PAGED)); } @@ -1106,8 +1111,8 @@ void checkoutItemStatusDoesNotChangeOnPagedRequest() { .withNoTemporaryLocation() .withBarcode("90806050402")); - assertThat(itemCopyA.getJson().getJsonObject("status").getString("name"), is(ItemStatus.AVAILABLE.getValue())); - assertThat(itemCopyB.getJson().getJsonObject("status").getString("name"), is(ItemStatus.AVAILABLE.getValue())); + assertThat(itemCopyA, hasItemStatus(AVAILABLE)); + assertThat(itemCopyB, hasItemStatus(AVAILABLE)); IndividualResource james = usersFixture.james(); //cate IndividualResource steve = usersFixture.steve(); //walker @@ -1115,13 +1120,13 @@ void checkoutItemStatusDoesNotChangeOnPagedRequest() { checkOutFixture.checkOutByBarcode(itemCopyA, james, getZonedDateTime()); - assertThat(itemsClient.get(itemCopyA).getJson().getJsonObject("status").getString("name"), is(ItemStatus.CHECKED_OUT.getValue())); + assertThat(itemsClient.get(itemCopyA), hasItemStatus(CHECKED_OUT)); // Steve requests Item Copy B IndividualResource stevesRequest = requestsFixture.placeItemLevelHoldShelfRequest( itemCopyB, steve, getZonedDateTime().minusHours(2), RequestType.PAGE.getValue()); - assertThat(itemsClient.get(itemCopyB).getJson().getJsonObject("status").getString("name"), is(ItemStatus.PAGED.getValue())); + assertThat(itemsClient.get(itemCopyB), hasItemStatus(ItemBuilder.PAGED)); // Jessica requests Item Copy A IndividualResource jessicasRequest = requestsFixture.placeItemLevelHoldShelfRequest( @@ -1132,12 +1137,11 @@ void checkoutItemStatusDoesNotChangeOnPagedRequest() { stevesRequest = requestsClient.get(stevesRequest); assertThat(stevesRequest.getJson().getInteger("position"), is(2)); - assertThat(itemsClient.get(itemCopyB).getJson().getJsonObject("status").getString("name"), is(ItemStatus.AVAILABLE.getValue())); + assertThat(itemsClient.get(itemCopyB), hasItemStatus(AVAILABLE)); requestsFixture.move(new MoveRequestBuilder(jessicasRequest.getId(), itemCopyB.getId())); - // Ensure that itemCopyA is still CHECKED_OUT - assertThat(itemsClient.get(itemCopyA).getJson().getJsonObject("status").getString("name"), is(ItemStatus.CHECKED_OUT.getValue())); + assertThat(itemsClient.get(itemCopyA), hasItemStatus(CHECKED_OUT)); } /** diff --git a/src/test/java/api/requests/scenarios/RequestPolicyTests.java b/src/test/java/api/requests/scenarios/RequestPolicyTests.java index c82da978c3..43493c51fa 100644 --- a/src/test/java/api/requests/scenarios/RequestPolicyTests.java +++ b/src/test/java/api/requests/scenarios/RequestPolicyTests.java @@ -1,5 +1,6 @@ package api.requests.scenarios; +import static api.support.builders.ItemBuilder.PAGED; import static api.support.matchers.ResponseStatusCodeMatcher.hasStatus; import static api.support.matchers.ValidationErrorMatchers.hasErrorWith; import static api.support.matchers.ValidationErrorMatchers.hasMessage; @@ -12,13 +13,13 @@ import java.util.ArrayList; -import org.folio.circulation.domain.ItemStatus; import org.folio.circulation.domain.RequestStatus; import org.folio.circulation.domain.RequestType; import org.folio.circulation.support.http.client.Response; import org.junit.jupiter.api.Test; import api.support.APITests; +import api.support.builders.ItemBuilder; import api.support.builders.RequestBuilder; import api.support.http.IndividualResource; import io.vertx.core.json.JsonObject; @@ -67,7 +68,7 @@ void canCreateRecallRequestsWithRequestPolicyAllowingRecalls() { JsonObject requestedItem = recallRequest.getJson().getJsonObject("item"); assertThat(recallRequest.getJson().getString("requestType"), is(RequestType.RECALL.getValue())); - assertThat(requestedItem.getString("status"), is(ItemStatus.CHECKED_OUT.getValue())); + assertThat(requestedItem.getString("status"), is(ItemBuilder.CHECKED_OUT)); assertThat(recallRequest.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); } @@ -149,7 +150,7 @@ void canCreateHoldRequestsWithRequestWithReqestPolicyAllowingHolds() { JsonObject requestedItem = recallRequest.getJson().getJsonObject("item"); assertThat(recallRequest.getJson().getString("requestType"), is(RequestType.HOLD.getValue())); - assertThat(requestedItem.getString("status"), is(ItemStatus.CHECKED_OUT.getValue())); + assertThat(requestedItem.getString("status"), is(ItemBuilder.CHECKED_OUT)); assertThat(recallRequest.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); } @@ -223,7 +224,7 @@ void canCreatePageRequestsWithRequestPolicyAllowingPageRequests() { JsonObject requestedItem = recallRequest.getJson().getJsonObject("item"); assertThat(recallRequest.getJson().getString("requestType"), is(RequestType.PAGE.getValue())); - assertThat(requestedItem.getString("status"), is(ItemStatus.PAGED.getValue())); + assertThat(requestedItem.getString("status"), is(PAGED)); assertThat(recallRequest.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); } @@ -295,7 +296,7 @@ void canCreateRecallRequestsWithRequestPolicyUsingFallbackRules() { JsonObject requestedItem = recallRequest.getJson().getJsonObject("item"); assertThat(recallRequest.getJson().getString("requestType"), is(RequestType.RECALL.getValue())); - assertThat(requestedItem.getString("status"), is(ItemStatus.CHECKED_OUT.getValue())); + assertThat(requestedItem.getString("status"), is(ItemBuilder.CHECKED_OUT)); assertThat(recallRequest.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); } diff --git a/src/test/java/api/requests/scenarios/RequestsServicePointsTests.java b/src/test/java/api/requests/scenarios/RequestsServicePointsTests.java index a488984943..01753d30d4 100644 --- a/src/test/java/api/requests/scenarios/RequestsServicePointsTests.java +++ b/src/test/java/api/requests/scenarios/RequestsServicePointsTests.java @@ -1,5 +1,8 @@ package api.requests.scenarios; +import static api.support.builders.ItemBuilder.AWAITING_PICKUP; +import static api.support.builders.ItemBuilder.IN_TRANSIT; +import static api.support.builders.ItemBuilder.PAGED; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; @@ -7,7 +10,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.folio.circulation.domain.ItemStatus; import org.folio.circulation.domain.MultipleRecords; import org.folio.circulation.domain.RequestStatus; import org.folio.circulation.support.utils.ClockUtil; @@ -36,7 +38,7 @@ void pagedRequestCheckedInAtIntendedServicePointTest() { .by(usersFixture.james())); JsonObject requestItem = firstRequest.getJson().getJsonObject("item"); - assertThat(requestItem.getString("status"), is(ItemStatus.PAGED.getValue())); + assertThat(requestItem.getString("status"), is(PAGED)); assertThat(firstRequest.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); checkInFixture.checkInByBarcode(smallAngryPlanet, ClockUtil.getZonedDateTime(), servicePoint.getId()); @@ -44,7 +46,8 @@ void pagedRequestCheckedInAtIntendedServicePointTest() { MultipleRecords requests = requestsFixture.getQueueFor(smallAngryPlanet); JsonObject pagedRequestRecord = requests.getRecords().iterator().next(); - assertThat(pagedRequestRecord.getJsonObject("item").getString("status"), is(ItemStatus.AWAITING_PICKUP.getValue())); + assertThat(pagedRequestRecord.getJsonObject("item").getString("status"), + is(AWAITING_PICKUP)); assertThat(pagedRequestRecord.getString("status"), is(RequestStatus.OPEN_AWAITING_PICKUP.getValue())); } @@ -63,7 +66,8 @@ void pagedRequestForItemWithIntransitStatusCheckedInAtIntendedServicePointTest() MultipleRecords requests = requestsFixture.getQueueFor(inTransitItem); JsonObject pagedRequestRecord = requests.getRecords().iterator().next(); - assertThat(pagedRequestRecord.getJsonObject("item").getString("status"), is(ItemStatus.AWAITING_PICKUP.getValue())); + assertThat(pagedRequestRecord.getJsonObject("item").getString("status"), + is(AWAITING_PICKUP)); assertThat(pagedRequestRecord.getString("status"), is(RequestStatus.OPEN_AWAITING_PICKUP.getValue())); } @@ -81,7 +85,7 @@ void pagedRequestCheckedInAtUnIntendedServicePointTest() { .by(usersFixture.james())); JsonObject requestItem = firstRequest.getJson().getJsonObject("item"); - assertThat(requestItem.getString("status"), is(ItemStatus.PAGED.getValue())); + assertThat(requestItem.getString("status"), is(PAGED)); assertThat(firstRequest.getJson().getString("status"), is(RequestStatus.OPEN_NOT_YET_FILLED.getValue())); log.info("requestServicePoint" + requestPickupServicePoint.getId()); @@ -92,7 +96,8 @@ void pagedRequestCheckedInAtUnIntendedServicePointTest() { MultipleRecords requests = requestsFixture.getQueueFor(smallAngryPlanet); JsonObject pagedRequestRecord = requests.getRecords().iterator().next(); - assertThat(pagedRequestRecord.getJsonObject("item").getString("status"), is(ItemStatus.IN_TRANSIT.getValue())); + assertThat(pagedRequestRecord.getJsonObject("item").getString("status"), + is(IN_TRANSIT)); assertThat(pagedRequestRecord.getString("status"), is(RequestStatus.OPEN_IN_TRANSIT.getValue())); } } diff --git a/src/test/java/api/support/fixtures/ItemsFixture.java b/src/test/java/api/support/fixtures/ItemsFixture.java index 3a3017a6b7..d89b01637e 100644 --- a/src/test/java/api/support/fixtures/ItemsFixture.java +++ b/src/test/java/api/support/fixtures/ItemsFixture.java @@ -1,9 +1,10 @@ package api.support.fixtures; +import static api.support.builders.ItemBuilder.DECLARED_LOST; +import static api.support.matchers.ItemStatusCodeMatcher.hasItemStatus; import static java.util.function.Function.identity; import static org.folio.circulation.support.json.JsonPropertyFetcher.getProperty; import static org.folio.circulation.support.json.JsonPropertyWriter.write; -import static org.hamcrest.core.Is.is; import static org.hamcrest.MatcherAssert.assertThat; import java.util.ArrayList; @@ -14,12 +15,10 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; -import org.folio.circulation.domain.ItemStatus; -import api.support.http.IndividualResource; - import api.support.builders.HoldingBuilder; import api.support.builders.InstanceBuilder; import api.support.builders.ItemBuilder; +import api.support.http.IndividualResource; import api.support.http.ItemResource; import api.support.http.ResourceClient; import io.vertx.core.json.JsonObject; @@ -318,7 +317,7 @@ public HoldingBuilder thirdFloorHoldings() { public IndividualResource setupDeclaredLostItem() { IndividualResource declaredLostItem = basedUponSmallAngryPlanet(ItemBuilder::declaredLost); - assertThat(declaredLostItem.getResponse().getJson().getJsonObject("status").getString("name"), is(ItemStatus.DECLARED_LOST.getValue())); + assertThat(declaredLostItem, hasItemStatus(DECLARED_LOST)); return declaredLostItem; } diff --git a/src/test/java/org/folio/circulation/domain/RequestQueueTests.java b/src/test/java/org/folio/circulation/domain/RequestQueueTests.java index 291da7e2fd..05583d15b4 100644 --- a/src/test/java/org/folio/circulation/domain/RequestQueueTests.java +++ b/src/test/java/org/folio/circulation/domain/RequestQueueTests.java @@ -83,7 +83,8 @@ private static Request buildRequest(int position, RequestStatus status, String r .put("status", status.getValue()) .put("position", position); - return new Request(null, null, json, null, null, null, null, null, null, null, null, null, false, null, false); + return new Request(null, null, json, null, null, null, Item.unknown(), + null, null, null, null, null, false, null, false); } private static String randomId() { diff --git a/src/test/java/org/folio/circulation/domain/RequestTypeItemStatusWhiteListTests.java b/src/test/java/org/folio/circulation/domain/RequestTypeItemStatusWhiteListTests.java index 4bba35da78..86f68854c3 100644 --- a/src/test/java/org/folio/circulation/domain/RequestTypeItemStatusWhiteListTests.java +++ b/src/test/java/org/folio/circulation/domain/RequestTypeItemStatusWhiteListTests.java @@ -2,23 +2,24 @@ import static junit.framework.TestCase.assertFalse; import static junit.framework.TestCase.assertTrue; -import static org.folio.circulation.domain.ItemStatus.AGED_TO_LOST; -import static org.folio.circulation.domain.ItemStatus.AVAILABLE; -import static org.folio.circulation.domain.ItemStatus.AWAITING_DELIVERY; -import static org.folio.circulation.domain.ItemStatus.CHECKED_OUT; -import static org.folio.circulation.domain.ItemStatus.CLAIMED_RETURNED; -import static org.folio.circulation.domain.ItemStatus.DECLARED_LOST; -import static org.folio.circulation.domain.ItemStatus.INTELLECTUAL_ITEM; -import static org.folio.circulation.domain.ItemStatus.IN_PROCESS; -import static org.folio.circulation.domain.ItemStatus.IN_PROCESS_NON_REQUESTABLE; -import static org.folio.circulation.domain.ItemStatus.LONG_MISSING; -import static org.folio.circulation.domain.ItemStatus.LOST_AND_PAID; -import static org.folio.circulation.domain.ItemStatus.ON_ORDER; -import static org.folio.circulation.domain.ItemStatus.PAGED; -import static org.folio.circulation.domain.ItemStatus.RESTRICTED; -import static org.folio.circulation.domain.ItemStatus.UNAVAILABLE; -import static org.folio.circulation.domain.ItemStatus.UNKNOWN; -import static org.folio.circulation.domain.ItemStatus.WITHDRAWN; +import static org.folio.circulation.domain.ItemStatusName.AGED_TO_LOST; +import static org.folio.circulation.domain.ItemStatusName.AVAILABLE; +import static org.folio.circulation.domain.ItemStatusName.AWAITING_DELIVERY; +import static org.folio.circulation.domain.ItemStatusName.CHECKED_OUT; +import static org.folio.circulation.domain.ItemStatusName.CLAIMED_RETURNED; +import static org.folio.circulation.domain.ItemStatusName.DECLARED_LOST; +import static org.folio.circulation.domain.ItemStatusName.INTELLECTUAL_ITEM; +import static org.folio.circulation.domain.ItemStatusName.IN_PROCESS; +import static org.folio.circulation.domain.ItemStatusName.IN_PROCESS_NON_REQUESTABLE; +import static org.folio.circulation.domain.ItemStatusName.LONG_MISSING; +import static org.folio.circulation.domain.ItemStatusName.LOST_AND_PAID; +import static org.folio.circulation.domain.ItemStatusName.NONE; +import static org.folio.circulation.domain.ItemStatusName.ON_ORDER; +import static org.folio.circulation.domain.ItemStatusName.PAGED; +import static org.folio.circulation.domain.ItemStatusName.RESTRICTED; +import static org.folio.circulation.domain.ItemStatusName.UNAVAILABLE; +import static org.folio.circulation.domain.ItemStatusName.UNKNOWN; +import static org.folio.circulation.domain.ItemStatusName.WITHDRAWN; import static org.folio.circulation.domain.RequestType.HOLD; import static org.folio.circulation.domain.RequestType.PAGE; import static org.folio.circulation.domain.RequestType.RECALL; @@ -89,7 +90,7 @@ void canCreateRecallRequestWhenItemStatusPaged() { @Test void cannotCreatePagedRequestWhenItemStatusIsNone() { - assertFalse(canCreateRequestForItem(ItemStatus.NONE, PAGE)); + assertFalse(canCreateRequestForItem(NONE, PAGE)); } @Test diff --git a/src/test/java/org/folio/circulation/infrastructure/storage/inventory/ItemRepositoryTests.java b/src/test/java/org/folio/circulation/infrastructure/storage/inventory/ItemRepositoryTests.java index 46207a613f..7f340810f0 100644 --- a/src/test/java/org/folio/circulation/infrastructure/storage/inventory/ItemRepositoryTests.java +++ b/src/test/java/org/folio/circulation/infrastructure/storage/inventory/ItemRepositoryTests.java @@ -21,6 +21,7 @@ import org.folio.circulation.domain.Instance; import org.folio.circulation.domain.Item; import org.folio.circulation.domain.ItemDescription; +import org.folio.circulation.domain.ItemStatus; import org.folio.circulation.domain.LoanType; import org.folio.circulation.domain.Location; import org.folio.circulation.domain.MaterialType; @@ -112,9 +113,10 @@ private ItemRepository createRepository(CollectionResourceClient itemsClient) { } private Item dummyItem() { - return new Item(null, null, null, null, null, null, null, false, - Holdings.unknown(), Instance.unknown(), MaterialType.unknown(), - LoanType.unknown(), ItemDescription.unknown()); + return new Item(null, Location.unknown(), null, null, + Location.unknown(), null, false, Holdings.unknown(), + Instance.unknown(), MaterialType.unknown(), LoanType.unknown(), + ItemDescription.unknown(), ItemStatus.unknown()); } @SneakyThrows diff --git a/src/test/java/org/folio/circulation/resources/renewal/OverrideRenewalTest.java b/src/test/java/org/folio/circulation/resources/renewal/OverrideRenewalTest.java index 53eec289c9..d2e80e7ef6 100644 --- a/src/test/java/org/folio/circulation/resources/renewal/OverrideRenewalTest.java +++ b/src/test/java/org/folio/circulation/resources/renewal/OverrideRenewalTest.java @@ -8,7 +8,7 @@ import static api.support.matchers.ValidationErrorMatchers.hasMessageContaining; import static java.util.Collections.emptyList; import static java.util.Collections.singleton; -import static org.folio.circulation.domain.ItemStatus.CHECKED_OUT; +import static org.folio.circulation.domain.ItemStatusName.CHECKED_OUT; import static org.folio.circulation.domain.policy.Period.weeks; import static org.folio.circulation.support.json.JsonPropertyWriter.write; import static org.folio.circulation.support.json.JsonPropertyWriter.writeByPath; @@ -48,7 +48,7 @@ void shouldUseOverrideDateWhenLoanIsNotLoanable() { final Result renewedLoan = renew(LoanPolicy.from(loanPolicyJson), overrideDate); assertDueDate(overrideDate, renewedLoan); - assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus()); + assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus().getName()); } @Test @@ -61,7 +61,7 @@ void shouldUseOverrideDateWhenLoanIsNotRenewable() { final Result renewedLoan = renew(LoanPolicy.from(loanPolicyJson), overrideDate); assertDueDate(overrideDate, renewedLoan); - assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus()); + assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus().getName()); } @Test @@ -97,7 +97,7 @@ void shouldUseOverrideDateWhenUnableToCalculateCalculatedDueDate() { final Result renewedLoan = renew(LoanPolicy.from(loanPolicyJson), overrideDate); assertDueDate(overrideDate, renewedLoan); - assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus()); + assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus().getName()); } @Test @@ -126,7 +126,7 @@ void shouldUseOverrideDateWhenReachedNumberOfRenewalsAndNewDueDateBeforeCurrent( final Result renewedLoan = renew(loan, overrideDueDate); assertDueDate(overrideDueDate, renewedLoan); - assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus()); + assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus().getName()); } @Test @@ -143,7 +143,7 @@ void shouldUseCalculatedDueDateWhenReachedNumberOfRenewalsAndNewDueDateAfterCurr final Result renewedLoan = renew(loan, null); assertDueDateWithinOneSecondAfter(estimatedDueDate, renewedLoan); - assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus()); + assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus().getName()); } @Test @@ -168,7 +168,7 @@ void shouldUseOverrideDateWhenRecallRequestedAndNewDateIsBeforeCurrent() { final Result renewedLoan = renewWithRecall(loan, overrideDueDate); assertDueDate(overrideDueDate, renewedLoan); - assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus()); + assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus().getName()); } @Test @@ -188,7 +188,7 @@ void shouldUseCalculatedDateWhenRecallRequestedAndNewDateIsAfterCurrent() { final Result renewedLoan = renewWithRecall(loan, null); assertDueDateWithinOneSecondAfter(estimatedDueDate, renewedLoan); - assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus()); + assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus().getName()); } @Test @@ -201,7 +201,7 @@ void shouldUseOverrideDateWhenItemLostAndNewDateIsBeforeCurrent() { final Result renewedLoan = renew(loan, overrideDueDate); assertDueDate(overrideDueDate, renewedLoan); - assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus()); + assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus().getName()); } @Test @@ -223,7 +223,7 @@ void shouldUseCalculatedDateWhenItemLostAndNewDateIsAfterCurrent() { final Result renewedLoan = renew(loan, null); assertDueDateWithinOneSecondAfter(estimatedDueDate, renewedLoan); - assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus()); + assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus().getName()); } @Test @@ -234,7 +234,7 @@ void canOverrideLoanWhenCurrentDueDateIsAfterCalculated() { final Result renewedLoan = renew(loan, overrideDate); assertDueDate(overrideDate, renewedLoan); - assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus()); + assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus().getName()); } @Test @@ -285,7 +285,7 @@ void nonLoanableAgedToLostItemShouldBeProperlyRenewed() { final Result renewedLoan = renew(loan, newDueDate); assertDueDate(newDueDate, renewedLoan); - assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus()); + assertEquals(CHECKED_OUT, renewedLoan.value().getItem().getStatus().getName()); assertThat(renewedLoan.value().asJson(), allOf( hasNoJsonPath("agedToLostDelayedBilling.lostItemHasBeenBilled"), diff --git a/src/test/java/org/folio/circulation/resources/renewal/RegularRenewalTest.java b/src/test/java/org/folio/circulation/resources/renewal/RegularRenewalTest.java index 0ad1246ae0..6600fea78f 100644 --- a/src/test/java/org/folio/circulation/resources/renewal/RegularRenewalTest.java +++ b/src/test/java/org/folio/circulation/resources/renewal/RegularRenewalTest.java @@ -2,7 +2,7 @@ import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; -import static org.folio.circulation.domain.ItemStatus.AGED_TO_LOST; +import static org.folio.circulation.domain.ItemStatusName.AGED_TO_LOST; import static org.folio.circulation.domain.policy.Period.days; import static org.folio.circulation.support.utils.ClockUtil.getZonedDateTime; import static org.hamcrest.CoreMatchers.is; @@ -12,8 +12,9 @@ import static org.mockito.Mockito.spy; import java.util.UUID; +import java.util.stream.Collectors; -import org.folio.circulation.domain.ItemStatus; +import org.folio.circulation.domain.ItemStatusName; import org.folio.circulation.domain.Loan; import org.folio.circulation.domain.Request; import org.folio.circulation.domain.RequestQueue; @@ -23,6 +24,9 @@ import org.folio.circulation.resources.handlers.error.OverridingErrorHandler; import org.folio.circulation.support.ValidationErrorFailure; import org.folio.circulation.support.results.Result; +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeDiagnosingMatcher; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; @@ -86,10 +90,9 @@ void cannotRenewWhenRecallRequestedAndPolicyNorLoanableAndItemLost() { renew(loan, recallRequest, errorHandler); assertEquals(3, errorHandler.getErrors().size()); - assertTrue(matchErrorReason(errorHandler, - ITEMS_CANNOT_BE_RENEWED_WHEN_THERE_IS_AN_ACTIVE_RECALL_REQUEST)); - assertTrue(matchErrorReason(errorHandler, ITEM_IS_NOT_LOANABLE)); - assertTrue(matchErrorReason(errorHandler, ITEM_IS_AGED_TO_LOST)); + assertThat(errorHandler, hasError(ITEMS_CANNOT_BE_RENEWED_WHEN_THERE_IS_AN_ACTIVE_RECALL_REQUEST)); + assertThat(errorHandler, hasError(ITEM_IS_NOT_LOANABLE)); + assertThat(errorHandler, hasError(ITEM_IS_AGED_TO_LOST)); } @Test @@ -179,12 +182,12 @@ void cannotRenewItemsWithDisallowedStatuses(String itemStatus) { final var loanPolicy = new LoanPolicyBuilder().asDomainObject(); final var loan = new LoanBuilder().asDomainObject() .withLoanPolicy(loanPolicy) - .changeItemStatusForItemAndLoan(ItemStatus.from(itemStatus)); + .changeItemStatusForItemAndLoan(ItemStatusName.from(itemStatus)); CirculationErrorHandler errorHandler = new OverridingErrorHandler(null); renew(loan, errorHandler); - assertTrue(matchErrorReason(errorHandler, "item is " + itemStatus)); + assertThat(errorHandler, hasError("item is " + itemStatus)); } @Test @@ -292,4 +295,37 @@ private boolean matchErrorReason(CirculationErrorHandler errorHandler, String ex .map(ValidationErrorFailure.class::cast) .anyMatch(httpFailure -> httpFailure.hasErrorWithReason(expectedReason)); } + private Matcher hasError(String expectedReason) { + return new TypeSafeDiagnosingMatcher<>() { + @Override + public void describeTo(Description description) { + description.appendText(String.format( + "a validation error with: %s", expectedReason)); + } + + @Override + protected boolean matchesSafely(CirculationErrorHandler errorHandler, + Description description) { + + final var validationErrors = errorHandler.getErrors().keySet().stream() + .map(ValidationErrorFailure.class::cast); + + if (errorHandler.getErrors().isEmpty()) { + description.appendText("but there are no errors"); + return false; + } else if (validationErrors.anyMatch(httpFailure -> httpFailure.hasErrorWithReason(expectedReason))) { + return true; + } else { + final var errorDescriptions = errorHandler.getErrors().keySet() + .stream() + .map(ValidationErrorFailure.class::cast) + .map(ValidationErrorFailure::toString) + .collect(Collectors.joining(";")); + + description.appendText("was not found. Failures are: " + errorDescriptions); + return false; + } + } + }; + } }