Skip to content

Commit

Permalink
Merge branch 'b24.2' into tmp-release-24.2.4
Browse files Browse the repository at this point in the history
  • Loading branch information
nielserik committed Apr 23, 2024
2 parents 9c0f03b + 88a80c0 commit 0fbea7e
Show file tree
Hide file tree
Showing 5 changed files with 258 additions and 39 deletions.
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 24.2.3 2024-04-23

* Keep due date when it is within recall return interval (CIRC-2043)

## 24.2.2 2024-04-19

* Fix alternate loan period applying when multiple requests in fulfillment in progress (CIRC-2026)
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>mod-circulation</artifactId>
<groupId>org.folio</groupId>
<version>24.2.3-SNAPSHOT</version>
<version>24.2.4-SNAPSHOT</version>
<licenses>
<license>
<name>Apache License 2.0</name>
Expand Down
37 changes: 31 additions & 6 deletions src/main/java/org/folio/circulation/domain/policy/LoanPolicy.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
import static org.folio.circulation.support.json.JsonPropertyFetcher.getProperty;
import static org.folio.circulation.support.results.Result.succeeded;
import static org.folio.circulation.support.utils.DateTimeUtil.isAfterMillis;
import static org.folio.circulation.support.utils.LogUtil.resultAsString;

import java.lang.invoke.MethodHandles;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Collections;
Expand All @@ -20,6 +22,8 @@
import java.util.Optional;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.folio.circulation.domain.Loan;
import org.folio.circulation.domain.RequestQueue;
import org.folio.circulation.domain.RequestStatus;
Expand All @@ -36,6 +40,8 @@

@ToString(onlyExplicitlyIncluded = true)
public class LoanPolicy extends Policy {
private static final Logger log = LogManager.getLogger(MethodHandles.lookup().lookupClass());

private static final String LOANS_POLICY_KEY = "loansPolicy";
private static final String PERIOD_KEY = "period";

Expand Down Expand Up @@ -461,16 +467,35 @@ private Result<ZonedDateTime> determineDueDate(Result<ZonedDateTime> minimumGuar

return minimumGuaranteedDueDateResult.combine(recallDueDateResult,
(minimumGuaranteedDueDate, recallDueDate) -> {
if (loan.isOverdue() && !allowRecallsToExtendOverdueLoans()) {
log.debug("determineDueDate:: parameters minimumGuaranteedDueDateResult: {}, " +
"recallDueDateResult: {}, loan: {}", () -> resultAsString(minimumGuaranteedDueDateResult),
() -> resultAsString(recallDueDateResult), () -> loan);

return loan.getDueDate();
ZonedDateTime currentDueDate = loan.getDueDate();

if (loan.isOverdue() && !allowRecallsToExtendOverdueLoans()) {
log.info("determineDueDate:: loan is overdue and allowRecallsToExtendOverdueLoans is " +
"disabled - keeping current due date");
return currentDueDate;
}

if (minimumGuaranteedDueDate == null ||
isAfterMillis(recallDueDate, minimumGuaranteedDueDate)) {
return recallDueDate;
if (isAfterMillis(recallDueDate, currentDueDate) && !allowRecallsToExtendOverdueLoans()) {
log.info("determineDueDate:: current due date is before recall due date and " +
"allowRecallsToExtendOverdueLoans is disabled - keeping current due date");
return currentDueDate;
} else {
return minimumGuaranteedDueDate;
if (minimumGuaranteedDueDate == null ||
isAfterMillis(recallDueDate, minimumGuaranteedDueDate)) {

log.info("determineDueDate:: minimum guaranteed period doesn't exist or recall due " +
"date is after minimum guaranteed due date - changing due date to recall due date");
return recallDueDate;
} else {
log.info("determineDueDate:: minimum guaranteed period exists and recall due " +
"date is before minimum guaranteed due date - changing due date to minimum " +
"guaranteed due date");
return minimumGuaranteedDueDate;
}
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ void recallRequestWithNoPolicyValuesChangesDueDateToSystemDate() {
}

@Test
void recallRequestWithMGDAndRDValuesChangesDueDateToRD() {
void recallRequestWithMGDAndRDValuesShouldNotChangeDueDateToRD() {
final IndividualResource smallAngryPlanet = itemsFixture.basedUponSmallAngryPlanet();
final IndividualResource requestServicePoint = servicePointsFixture.cd1();
final IndividualResource steve = usersFixture.steve();
Expand All @@ -143,12 +143,12 @@ void recallRequestWithMGDAndRDValuesChangesDueDateToRD() {

final JsonObject storedLoan = loansStorageClient.getById(loan.getId()).getJson();

assertThat("due date should not be the original date",
storedLoan.getString("dueDate"), not(originalDueDate));
assertThat("due date should be the original date", storedLoan.getString("dueDate"),
is(originalDueDate));

final String expectedDueDate = formatDateTime(getZonedDateTime().plusMonths(2));
assertThat("due date should be in 2 months",
storedLoan.getString("dueDate"), is(expectedDueDate));
final String expectedDueDate = formatDateTime(getZonedDateTime().plusWeeks(3));
assertThat("due date should be in 3 weeks", storedLoan.getString("dueDate"),
is(expectedDueDate));
}

@Test
Expand Down Expand Up @@ -367,7 +367,7 @@ void loanPolicyWithInvalidMGDOrRDPeriodValuesReturnsErrorOnRecallCreation(
}

@Test
void initialLoanDueDateOnCreateWithPrexistingRequests() {
void initialLoanDueDateOnCreateWithPrexistingRequestsIsBeforeRecallInterval() {

final IndividualResource smallAngryPlanet = itemsFixture.basedUponSmallAngryPlanet();
final IndividualResource requestServicePoint = servicePointsFixture.cd1();
Expand Down Expand Up @@ -403,12 +403,12 @@ void initialLoanDueDateOnCreateWithPrexistingRequests() {

final JsonObject storedLoan = loansStorageClient.getById(loan.getId()).getJson();

final String expectedDueDate = formatDateTime(ZonedDateTime
.of(getZonedDateTime().plusMonths(2).toLocalDate(),
LocalTime.MIDNIGHT.minusSeconds(1),getZoneId()));
final String expectedDueDate = formatDateTime(ZonedDateTime.of(
getZonedDateTime().plusWeeks(3).toLocalDate(), LocalTime.MIDNIGHT.minusSeconds(1),
getZoneId()));

assertThat("due date should be in 2 months (recall return interval)",
storedLoan.getString("dueDate"), is(expectedDueDate));
assertThat("due date should be in 3 weeks (loan period) since it is before the recall " +
"return interval", storedLoan.getString("dueDate"), is(expectedDueDate));
}

@Test
Expand Down Expand Up @@ -674,11 +674,11 @@ void secondRecallRequestWithRDTruncationInPlaceDoesNotChangeDueDate() {
JsonObject storedLoan = loansStorageClient.getById(loan.getId()).getJson();

final String recalledDueDate = storedLoan.getString("dueDate");
assertThat("due date after recall should not be the original date",
recalledDueDate, not(originalDueDate));
assertThat("due date after recall should be the original date",
recalledDueDate, is(originalDueDate));

final String expectedDueDate = formatDateTime(getZonedDateTime().plusMonths(2));
assertThat("due date after recall should be in 2 months",
final String expectedDueDate = formatDateTime(getZonedDateTime().plusWeeks(3));
assertThat("due date after recall should be in 3 weeks",
storedLoan.getString("dueDate"), is(expectedDueDate));

setClock(Clock.offset(getClock(), Duration.ofDays(7)));
Expand All @@ -687,7 +687,7 @@ void secondRecallRequestWithRDTruncationInPlaceDoesNotChangeDueDate() {
getZonedDateTime(), requestServicePoint.getId(), "Recall");

storedLoan = loansStorageClient.getById(loan.getId()).getJson();
assertThat("second recall should not change the due date (2 months)",
assertThat("second recall should not change the due date (3 weeks)",
storedLoan.getString("dueDate"), is(recalledDueDate));
}

Expand All @@ -702,11 +702,12 @@ void secondRecallRequestWithRDTruncationInPlaceAndLoanOverdueDoesNotChangeDueDat
final LoanPolicyBuilder canCirculateRollingPolicy = new LoanPolicyBuilder()
.withName("Can Circulate Rolling With Recalls")
.withDescription("Can circulate item With Recalls")
.rolling(Period.weeks(3))
.rolling(Period.days(65))
.unlimitedRenewals()
.renewFromSystemDate()
.withRecallsMinimumGuaranteedLoanPeriod(Period.weeks(2))
.withRecallsRecallReturnInterval(Period.months(2));
.withAllowRecallsToExtendOverdueLoans(false)
.withRecallsMinimumGuaranteedLoanPeriod(Period.days(15))
.withRecallsRecallReturnInterval(Period.days(60));

setFallbackPolicies(canCirculateRollingPolicy);

Expand All @@ -724,8 +725,8 @@ void secondRecallRequestWithRDTruncationInPlaceAndLoanOverdueDoesNotChangeDueDat
assertThat("due date after recall should not be the original date",
recalledDueDate, not(originalDueDate));

final String expectedDueDate = formatDateTime(getZonedDateTime().plusMonths(2));
assertThat("due date after recall should be in 2 months",
final String expectedDueDate = formatDateTime(getZonedDateTime().plusDays(60));
assertThat("due date after recall should be in 60 days",
storedLoan.getString("dueDate"), is(expectedDueDate));

// Move the fixed clock so that the loan is now overdue
Expand All @@ -735,7 +736,7 @@ void secondRecallRequestWithRDTruncationInPlaceAndLoanOverdueDoesNotChangeDueDat
getZonedDateTime(), requestServicePoint.getId(), "Recall");

storedLoan = loansStorageClient.getById(loan.getId()).getJson();
assertThat("second recall should not change the due date (2 months)",
assertThat("second recall should not change the due date (60 days)",
storedLoan.getString("dueDate"), is(recalledDueDate));
}

Expand Down Expand Up @@ -861,7 +862,6 @@ void shouldExtendLoanDueDateByAlternatePeriodWhenOverdueLoanIsRecalledAndPolicyA
.forItem(smallAngryPlanet)
.fulfillToHoldShelf()
.by(usersFixture.jessica())
.fulfillToHoldShelf()
.withPickupServicePointId(servicePointsFixture.cd1().getId()));

final JsonObject storedLoan = loansStorageClient.getById(loan.getId()).getJson();
Expand All @@ -876,6 +876,40 @@ void shouldExtendLoanDueDateByAlternatePeriodWhenOverdueLoanIsRecalledAndPolicyA
verifyLogEventDueDateChangedMessage(publishedLoanLogEvents.get(1), loan, expectedLoanDueDate);
}

@Test
void shouldNotExtendLoanDueDateWhenCurrentDueDateIsBeforeRecallDueDate() {
final IndividualResource smallAngryPlanet = itemsFixture.basedUponSmallAngryPlanet();

final Period loanPeriod = Period.days(2);
setFallbackPolicies(new LoanPolicyBuilder()
.withName("Can Circulate Rolling With Recalls")
.withDescription("Can circulate item With Recalls")
.rolling(loanPeriod)
.unlimitedRenewals()
.renewFromSystemDate()
.withRecallsMinimumGuaranteedLoanPeriod(Period.days(10))
.withRecallsRecallReturnInterval(Period.days(5)));

final ZonedDateTime loanCreateDate = getZonedDateTime().minusDays(1);
final ZonedDateTime expectedLoanDueDate = loanPeriod.plusDate(loanCreateDate);

final IndividualResource loan = checkOutFixture.checkOutByBarcode(
smallAngryPlanet, usersFixture.steve(), loanCreateDate);

requestsFixture.place(new RequestBuilder()
.recall()
.forItem(smallAngryPlanet)
.fulfillToHoldShelf()
.by(usersFixture.jessica())
.withPickupServicePointId(servicePointsFixture.cd1().getId()));

final var updatedLoan = loansStorageClient.getById(loan.getId());

// verify that loan due date hasn't changed
assertThat(updatedLoan.getJson(),
hasJsonPath("dueDate", isEquivalentTo(expectedLoanDueDate)));
}

private void verifyLogEventDueDateChangedMessage(JsonObject eventLogJsonObject,
IndividualResource loan, ZonedDateTime expectedLoanDueDate) {

Expand Down
Loading

0 comments on commit 0fbea7e

Please sign in to comment.