Skip to content

Commit ba7a28a

Browse files
authored
Merge pull request #17 from indexdata/ID-CIRC-2415-set-expiration-date
CIRC-2415 hold shelf exp date, use-at-location
2 parents 1864c16 + 2b1dd73 commit ba7a28a

File tree

6 files changed

+51
-9
lines changed

6 files changed

+51
-9
lines changed

src/main/java/org/folio/circulation/domain/Loan.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import static org.folio.circulation.domain.representations.LoanProperties.ACTION_COMMENT;
2222
import static org.folio.circulation.domain.representations.LoanProperties.AGED_TO_LOST_DATE;
2323
import static org.folio.circulation.domain.representations.LoanProperties.AGED_TO_LOST_DELAYED_BILLING;
24+
import static org.folio.circulation.domain.representations.LoanProperties.AT_LOCATION_USE_EXPIRY_DATE;
2425
import static org.folio.circulation.domain.representations.LoanProperties.AT_LOCATION_USE_STATUS;
2526
import static org.folio.circulation.domain.representations.LoanProperties.AT_LOCATION_USE_STATUS_DATE;
2627
import static org.folio.circulation.domain.representations.LoanProperties.BILL_DATE;
@@ -46,6 +47,7 @@
4647
import static org.folio.circulation.domain.representations.LoanProperties.STATUS;
4748
import static org.folio.circulation.domain.representations.LoanProperties.SYSTEM_RETURN_DATE;
4849
import static org.folio.circulation.domain.representations.LoanProperties.UPDATED_BY_USER_ID;
50+
import static org.folio.circulation.domain.representations.LoanProperties.USAGE_STATUS_HELD;
4951
import static org.folio.circulation.domain.representations.LoanProperties.USER_ID;
5052
import static org.folio.circulation.support.ValidationErrorFailure.failedValidation;
5153
import static org.folio.circulation.support.json.JsonPropertyFetcher.getBooleanProperty;
@@ -79,6 +81,7 @@
7981
import org.apache.logging.log4j.Logger;
8082
import org.folio.circulation.domain.policy.LoanPolicy;
8183
import org.folio.circulation.domain.policy.OverdueFinePolicy;
84+
import org.folio.circulation.domain.policy.Period;
8285
import org.folio.circulation.domain.policy.RemindersPolicy;
8386
import org.folio.circulation.domain.policy.lostitem.LostItemPolicy;
8487
import org.folio.circulation.domain.representations.LoanProperties;
@@ -211,9 +214,19 @@ public String getAction() {
211214
}
212215

213216
public Loan changeStatusOfUsageAtLocation(String usageStatus) {
214-
log.debug("changeStatusOfUsageAtLocation:: parameters usageStatus: {}", usageStatus);
217+
log.info("changeStatusOfUsageAtLocation:: parameters usageStatus: {}", usageStatus);
215218
writeByPath(representation, usageStatus, FOR_USE_AT_LOCATION, AT_LOCATION_USE_STATUS);
216219
writeByPath(representation, ClockUtil.getZonedDateTime().toString(), FOR_USE_AT_LOCATION, AT_LOCATION_USE_STATUS_DATE);
220+
if (usageStatus.equals(USAGE_STATUS_HELD)) {
221+
Period expiry = getLoanPolicy().getHoldShelfExpiryPeriodForUseAtLocation();
222+
if (expiry == null) {
223+
log.warn("No hold shelf expiry period for use at location defined in loan policy {}", getLoanPolicy().getName());
224+
} else {
225+
writeByPath(representation, expiry.plusDate(ClockUtil.getZonedDateTime()), FOR_USE_AT_LOCATION, AT_LOCATION_USE_EXPIRY_DATE);
226+
return this;
227+
}
228+
}
229+
remove(representation.getJsonObject(FOR_USE_AT_LOCATION), AT_LOCATION_USE_EXPIRY_DATE);
217230
return this;
218231
}
219232

src/main/java/org/folio/circulation/domain/policy/LoanPolicy.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ private boolean isAlternatePeriod(RequestQueue requestQueue, String itemId) {
216216
(!request.hasItem() || itemId.equals(request.getItemId())));
217217
}
218218

219-
private JsonObject getLoansPolicy() {
219+
public JsonObject getLoansPolicy() {
220220
return representation.getJsonObject(LOANS_POLICY_KEY);
221221
}
222222

@@ -350,6 +350,16 @@ public boolean isForUseAtLocation() {
350350
return getBooleanProperty(getLoansPolicy(), FOR_USE_AT_LOCATION);
351351
}
352352

353+
public Period getHoldShelfExpiryPeriodForUseAtLocation() {
354+
if (isForUseAtLocation()) {
355+
JsonObject holdShelfExpiryPeriod = getObjectProperty(getLoansPolicy(), "holdShelfExpiryPeriodForUseAtLocation");
356+
if (holdShelfExpiryPeriod != null) {
357+
return Period.from(holdShelfExpiryPeriod);
358+
}
359+
}
360+
return null;
361+
}
362+
353363
public DueDateManagement getDueDateManagement() {
354364
JsonObject loansPolicyObj = getLoansPolicy();
355365
if (Objects.isNull(loansPolicyObj)) {

src/main/java/org/folio/circulation/domain/representations/LoanProperties.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ private LoanProperties() { }
3737
public static final String FOR_USE_AT_LOCATION = "forUseAtLocation";
3838
public static final String AT_LOCATION_USE_STATUS = "status";
3939
public static final String AT_LOCATION_USE_STATUS_DATE = "statusDate";
40+
public static final String AT_LOCATION_USE_EXPIRY_DATE = "holdShelfExpirationDate";
4041
public static final String USAGE_STATUS_IN_USE = "In use";
4142
public static final String USAGE_STATUS_HELD = "Held";
4243
public static final String USAGE_STATUS_RETURNED = "Returned";

src/main/java/org/folio/circulation/resources/foruseatlocation/HoldByBarcodeResource.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.folio.circulation.domain.LoanAction;
1111
import org.folio.circulation.domain.representations.logs.LogEventType;
1212
import org.folio.circulation.infrastructure.storage.inventory.ItemRepository;
13+
import org.folio.circulation.infrastructure.storage.loans.LoanPolicyRepository;
1314
import org.folio.circulation.infrastructure.storage.loans.LoanRepository;
1415
import org.folio.circulation.infrastructure.storage.users.UserRepository;
1516
import org.folio.circulation.resources.Resource;
@@ -58,6 +59,7 @@ private void markHeld(RoutingContext routingContext) {
5859
final var itemRepository = new ItemRepository(clients);
5960
final var userRepository = new UserRepository(clients);
6061
final var loanRepository = new LoanRepository(clients, itemRepository, userRepository);
62+
final var loanPolicyRepository = new LoanPolicyRepository(clients);
6163
final EventPublisher eventPublisher = new EventPublisher(webContext,clients);
6264

6365
JsonObject requestBodyAsJson = routingContext.body().asJsonObject();
@@ -67,6 +69,7 @@ private void markHeld(RoutingContext routingContext) {
6769
.after(request -> findLoan(request, loanRepository, itemRepository, userRepository, errorHandler))
6870
.thenApply(loan -> failWhenOpenLoanNotFoundForItem(loan, requestResult.value()))
6971
.thenApply(loan -> failWhenOpenLoanIsNotForUseAtLocation(loan, requestResult.value()))
72+
.thenCompose(loanPolicyRepository::findPolicyForLoan)
7073
.thenApply(loanResult -> loanResult.map(loan -> loan.changeStatusOfUsageAtLocation(USAGE_STATUS_HELD)))
7174
.thenApply(loanResult -> loanResult.map(loan -> loan.withAction(LoanAction.HELD_FOR_USE_AT_LOCATION)))
7275
.thenCompose(loanResult -> loanResult.after(

src/test/java/api/loans/LoansForUseAtLocationTests.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static api.support.fixtures.ItemExamples.basedUponSmallAngryPlanet;
1919
import static org.hamcrest.CoreMatchers.notNullValue;
2020
import static org.hamcrest.MatcherAssert.assertThat;
21+
import static org.hamcrest.CoreMatchers.nullValue;
2122

2223
public class LoansForUseAtLocationTests extends APITests {
2324
private ItemResource item;
@@ -77,7 +78,8 @@ void willMarkItemHeldByBarcode() {
7778
.withName("Reading room loans")
7879
.withDescription("Policy for items to be used at location")
7980
.rolling(Period.days(30))
80-
.withForUseAtLocation(true);
81+
.withForUseAtLocation(true)
82+
.withHoldShelfExpiryPeriodForUseAtLocation(Period.from(5, "DAYS"));
8183

8284
use(forUseAtLocationPolicyBuilder);
8385

@@ -91,10 +93,13 @@ void willMarkItemHeldByBarcode() {
9193
new HoldByBarcodeRequestBuilder(item.getBarcode()));
9294

9395
JsonObject forUseAtLocation = holdResponse.getJson().getJsonObject("forUseAtLocation");
96+
9497
assertThat("loan.forUseAtLocation",
9598
forUseAtLocation, notNullValue());
9699
assertThat("loan.forUseAtLocation.status",
97100
forUseAtLocation.getString("status"), Is.is("Held"));
101+
assertThat("loan.forUseAtLocation.holdShelfExpirationDate",
102+
forUseAtLocation.getString("holdShelfExpirationDate"), notNullValue());
98103
}
99104

100105
@Test
@@ -103,7 +108,8 @@ void holdWillFailWithDifferentItem() {
103108
.withName("Reading room loans")
104109
.withDescription("Policy for items to be used at location")
105110
.rolling(Period.days(30))
106-
.withForUseAtLocation(true);
111+
.withForUseAtLocation(true)
112+
.withHoldShelfExpiryPeriodForUseAtLocation(Period.from(5, "DAYS"));
107113

108114
use(forUseAtLocationPolicyBuilder);
109115

@@ -142,7 +148,8 @@ void holdWillFailWithIncompleteRequest() {
142148
.withName("Reading room loans")
143149
.withDescription("Policy for items to be used at location")
144150
.rolling(Period.days(30))
145-
.withForUseAtLocation(true);
151+
.withForUseAtLocation(true)
152+
.withHoldShelfExpiryPeriodForUseAtLocation(Period.from(5, "DAYS"));
146153

147154
use(forUseAtLocationPolicyBuilder);
148155

@@ -163,7 +170,8 @@ void willMarkItemInUseByBarcode() {
163170
.withName("Reading room loans")
164171
.withDescription("Policy for items to be used at location")
165172
.rolling(Period.days(30))
166-
.withForUseAtLocation(true);
173+
.withForUseAtLocation(true)
174+
.withHoldShelfExpiryPeriodForUseAtLocation(Period.from(5, "DAYS"));
167175

168176
use(forUseAtLocationPolicyBuilder);
169177

@@ -213,7 +221,8 @@ void pickupWillFailWithIncompleteRequestObject() {
213221
.withName("Reading room loans")
214222
.withDescription("Policy for items to be used at location")
215223
.rolling(Period.days(30))
216-
.withForUseAtLocation(true);
224+
.withForUseAtLocation(true)
225+
.withHoldShelfExpiryPeriodForUseAtLocation(Period.from(5, "DAYS"));
217226

218227
use(forUseAtLocationPolicyBuilder);
219228

@@ -255,7 +264,8 @@ void willSetAtLocationUsageStatusToReturnedOnCheckIn() {
255264
.withName("Reading room loans")
256265
.withDescription("Policy for items to be used at location")
257266
.rolling(Period.days(30))
258-
.withForUseAtLocation(true);
267+
.withForUseAtLocation(true)
268+
.withHoldShelfExpiryPeriodForUseAtLocation(Period.from(5, "DAYS"));
259269

260270
use(forUseAtLocationPolicyBuilder);
261271

@@ -275,6 +285,8 @@ void willSetAtLocationUsageStatusToReturnedOnCheckIn() {
275285
forUseAtLocation, notNullValue());
276286
assertThat("loan.forUseAtLocation.status",
277287
forUseAtLocation.getString("status"), Is.is("Returned"));
288+
assertThat("loan.forUseAtLocation.holdShelfExpirationDate",
289+
forUseAtLocation.getString("holdShelfExpirationDate"), nullValue());
278290
}
279291

280292
}

src/test/java/api/support/builders/LoanPolicyBuilder.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public class LoanPolicyBuilder extends JsonBuilder implements Builder {
4141
private final Integer itemLimit;
4242
private final Period gracePeriod;
4343
private final boolean forUseAtLocation;
44+
private final Period holdShelfExpiryPeriodForUseAtLocation;
4445

4546
public LoanPolicyBuilder() {
4647
this(UUID.randomUUID(),
@@ -67,7 +68,8 @@ public LoanPolicyBuilder() {
6768
null,
6869
null,
6970
null,
70-
false
71+
false,
72+
null
7173
);
7274
}
7375

@@ -91,6 +93,7 @@ public JsonObject create() {
9193
put(loansPolicy, "itemLimit", itemLimit);
9294
putIfNotNull(loansPolicy, "gracePeriod", gracePeriod, Period::asJson);
9395
put(loansPolicy, "forUseAtLocation", forUseAtLocation);
96+
putIfNotNull(loansPolicy, "holdShelfExpiryPeriodForUseAtLocation", holdShelfExpiryPeriodForUseAtLocation, Period::asJson);
9497

9598
//TODO: Replace with sub-builders
9699
if(Objects.equals(loansProfile, "Rolling")) {

0 commit comments

Comments
 (0)