diff --git a/NEWS.md b/NEWS.md index a087e81952..ca649b1d18 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,7 @@ +## 24.2.1 2024-03-29 + +* Fix item details not fully populated when response contains more than 50 loans (CIRC-2059) + ## 24.2.0 2024-03-21 * Update `feesfines` interface version to 19.0 (CIRC-1914) diff --git a/pom.xml b/pom.xml index bb6da6be23..b5f9a652f2 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 mod-circulation org.folio - 24.3.0-SNAPSHOT + 24.2.2-SNAPSHOT Apache License 2.0 diff --git a/src/main/java/org/folio/circulation/domain/Loan.java b/src/main/java/org/folio/circulation/domain/Loan.java index f90b11d7a5..d89ac21eb5 100644 --- a/src/main/java/org/folio/circulation/domain/Loan.java +++ b/src/main/java/org/folio/circulation/domain/Loan.java @@ -501,6 +501,7 @@ public Loan overrideRenewal(ZonedDateTime dueDate, String basedUponLoanPolicyId, changeDueDate(dueDate); incrementRenewalCount(); changeActionComment(actionComment); + resetReminders(); return this; } diff --git a/src/main/java/org/folio/circulation/domain/LoanRepresentation.java b/src/main/java/org/folio/circulation/domain/LoanRepresentation.java index a1cd823d34..05ea36fccb 100644 --- a/src/main/java/org/folio/circulation/domain/LoanRepresentation.java +++ b/src/main/java/org/folio/circulation/domain/LoanRepresentation.java @@ -1,11 +1,7 @@ package org.folio.circulation.domain; import static java.util.Objects.isNull; -import static org.folio.circulation.domain.representations.LoanProperties.BORROWER; -import static org.folio.circulation.domain.representations.LoanProperties.LOAN_POLICY; -import static org.folio.circulation.domain.representations.LoanProperties.LOST_ITEM_POLICY; -import static org.folio.circulation.domain.representations.LoanProperties.OVERDUE_FINE_POLICY; -import static org.folio.circulation.domain.representations.LoanProperties.PATRON_GROUP_ID_AT_CHECKOUT; +import static org.folio.circulation.domain.representations.LoanProperties.*; import static org.folio.circulation.support.json.JsonPropertyWriter.write; import java.lang.invoke.MethodHandles; @@ -13,6 +9,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.folio.circulation.domain.policy.Policy; +import org.folio.circulation.domain.policy.RemindersPolicy; import org.folio.circulation.domain.representations.ItemSummaryRepresentation; import org.folio.circulation.domain.representations.LoanProperties; import org.folio.circulation.resources.context.RenewalContext; @@ -59,6 +56,13 @@ public JsonObject extendedLoan(Loan loan) { extendedRepresentation.remove(BORROWER); } + if (loan.getOverdueFinePolicy().isReminderFeesPolicy() + && loan.getLastReminderFeeBilledNumber() != null) { + extendedRepresentation.getJsonObject(REMINDERS).put( + "renewalBlocked", + !loan.getOverdueFinePolicy().getRemindersPolicy().getAllowRenewalOfItemsWithReminderFees()); + } + addPolicy(extendedRepresentation, loan.getLoanPolicy(), LOAN_POLICY); addPolicy(extendedRepresentation, loan.getOverdueFinePolicy(), OVERDUE_FINE_POLICY); addPolicy(extendedRepresentation, loan.getLostItemPolicy(), LOST_ITEM_POLICY); diff --git a/src/main/java/org/folio/circulation/domain/validation/RenewalOfItemsWithReminderFeesValidator.java b/src/main/java/org/folio/circulation/domain/validation/RenewalOfItemsWithReminderFeesValidator.java index 24eaffb509..410debac04 100644 --- a/src/main/java/org/folio/circulation/domain/validation/RenewalOfItemsWithReminderFeesValidator.java +++ b/src/main/java/org/folio/circulation/domain/validation/RenewalOfItemsWithReminderFeesValidator.java @@ -3,6 +3,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.folio.circulation.domain.Loan; +import org.folio.circulation.domain.override.BlockOverrides; import org.folio.circulation.domain.policy.OverdueFinePolicy; import org.folio.circulation.resources.context.RenewalContext; import org.folio.circulation.support.HttpFailure; @@ -14,6 +15,7 @@ import static java.util.concurrent.CompletableFuture.completedFuture; import static org.folio.circulation.support.ValidationErrorFailure.singleValidationError; +import static org.folio.circulation.support.json.JsonPropertyFetcher.getObjectProperty; import static org.folio.circulation.support.results.Result.failed; import static org.folio.circulation.support.results.Result.succeeded; @@ -27,13 +29,12 @@ public CompletableFuture> blockRenewalIfReminderFeesExist Result blockRenewalIfRuledByRemindersFeePolicy(RenewalContext renewalContext) { log.debug("blockRenewalIfRuledByRemindersFeePolicy:: parameters: renewalContext: {}", renewalContext); - - Loan loan = renewalContext.getLoan(); - Integer lastFeeBilledCount = loan.getLastReminderFeeBilledNumber(); - OverdueFinePolicy overdueFinePolicy = loan.getOverdueFinePolicy(); - Boolean allowRenewalWithReminders = overdueFinePolicy.getRemindersPolicy().getAllowRenewalOfItemsWithReminderFees(); - - if ((lastFeeBilledCount != null && lastFeeBilledCount > 0) && Boolean.FALSE.equals(allowRenewalWithReminders)) { + BlockOverrides overrides = BlockOverrides.from(getObjectProperty(renewalContext.getRenewalRequest(), "overrideBlocks")); + final boolean overrideRenewalBlock = overrides.getRenewalBlockOverride().isRequested(); + final boolean overrideRenewalBlockDueDateRequired = overrides.getRenewalDueDateRequiredBlockOverride().isRequested(); + if (overrideRenewalBlock || overrideRenewalBlockDueDateRequired) { + return succeeded(renewalContext); + } else if (renewalBlockedDueToReminders(renewalContext)) { String reason = "Renewals not allowed for loans with reminders."; log.info("createBlockedRenewalDueToReminderFeesPolicyError:: {}", reason); return failed(createBlockedRenewalDueToReminderFeesPolicyError("Renewals not allowed for loans with reminders.", reason)); @@ -48,4 +49,19 @@ private HttpFailure createBlockedRenewalDueToReminderFeesPolicyError(String mess return singleValidationError(new ValidationError(message, "reason", reason)); } + + private static boolean renewalBlockedDueToReminders(RenewalContext renewalContext) { + Loan loan = renewalContext.getLoan(); + return loanHasReminders(loan) && policyBlocksRenewalWithReminders(loan); + } + + private static Boolean loanHasReminders(Loan loan) { + return loan.getLastReminderFeeBilledNumber() != null && loan.getLastReminderFeeBilledNumber() > 0; + } + + private static boolean policyBlocksRenewalWithReminders (Loan loan) { + OverdueFinePolicy overdueFinePolicy = loan.getOverdueFinePolicy(); + Boolean allowRenewalWithReminders = overdueFinePolicy.getRemindersPolicy().getAllowRenewalOfItemsWithReminderFees(); + return Boolean.FALSE.equals(allowRenewalWithReminders); + } } diff --git a/src/main/java/org/folio/circulation/resources/RenewalValidator.java b/src/main/java/org/folio/circulation/resources/RenewalValidator.java index 6b4e583f88..f7bede794e 100644 --- a/src/main/java/org/folio/circulation/resources/RenewalValidator.java +++ b/src/main/java/org/folio/circulation/resources/RenewalValidator.java @@ -103,7 +103,8 @@ public static ValidationError errorForNotMatchingOverrideCases(LoanPolicy loanPo "renewal date falls outside of the date ranges in the loan policy, " + "items cannot be renewed when there is an active recall request, " + DECLARED_LOST_ITEM_RENEWED_ERROR + ", item is Aged to lost, " + - "renewal would not change the due date"; + "renewal would not change the due date, " + + "loan has reminder fees"; return loanPolicyValidationError(loanPolicy, reason); } 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 7d8cecef34..d3780208da 100644 --- a/src/main/java/org/folio/circulation/resources/renewal/RenewalResource.java +++ b/src/main/java/org/folio/circulation/resources/renewal/RenewalResource.java @@ -492,6 +492,10 @@ private Result overrideRenewal(Loan loan, ZonedDateTime systemDate, return processRenewal(newDueDateResult, loan, comment); } + if (loan.getLastReminderFeeBilledNumber() != null && loan.getLastReminderFeeBilledNumber()>0) { + return processRenewal(newDueDateResult, loan, comment); + } + return failedValidation(errorForNotMatchingOverrideCases(loanPolicy)); } catch (Exception e) { diff --git a/src/test/java/api/loans/OverrideRenewByBarcodeTests.java b/src/test/java/api/loans/OverrideRenewByBarcodeTests.java index eb8b2bd95b..b6d4f0b1f1 100644 --- a/src/test/java/api/loans/OverrideRenewByBarcodeTests.java +++ b/src/test/java/api/loans/OverrideRenewByBarcodeTests.java @@ -521,7 +521,8 @@ void cannotOverrideRenewalWhenLoanDoesNotMatchAnyOfOverrideCases() { "renewal date falls outside of the date ranges in the loan policy, " + "items cannot be renewed when there is an active recall request, " + "item is Declared lost, item is Aged to lost, " + - "renewal would not change the due date")))); + "renewal would not change the due date, " + + "loan has reminder fees")))); } @Test diff --git a/src/test/java/api/requests/RequestsAPILoanRenewalTests.java b/src/test/java/api/requests/RequestsAPILoanRenewalTests.java index 1071b1cd0b..20434ac2be 100644 --- a/src/test/java/api/requests/RequestsAPILoanRenewalTests.java +++ b/src/test/java/api/requests/RequestsAPILoanRenewalTests.java @@ -592,7 +592,8 @@ void forbidRenewalOverrideWhenRecallIsForDifferentItemOfSameInstance() { "renewal date falls outside of the date ranges in the loan policy, " + "items cannot be renewed when there is an active recall request, " + "item is Declared lost, item is Aged to lost, " + - "renewal would not change the due date")))); + "renewal would not change the due date, " + + "loan has reminder fees")))); } @Test @@ -623,7 +624,8 @@ void forbidRenewalOverrideWhenTitleLevelRecallRequestExistsForDifferentItemOfSam "renewal date falls outside of the date ranges in the loan policy, " + "items cannot be renewed when there is an active recall request, " + "item is Declared lost, item is Aged to lost, " + - "renewal would not change the due date")))); + "renewal would not change the due date, " + + "loan has reminder fees")))); } @Test