Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 65 additions & 9 deletions src/main/java/org/folio/circulation/domain/OverdueFineService.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,14 @@ public CompletableFuture<Result<RenewalContext>> createOverdueFineIfNecessary(
log.debug("createOverdueFineIfNecessary:: parameters context: {}", () -> context);
final String loggedInUserId = context.getLoggedInUserId();
final Loan loanBeforeRenewal = context.getLoanBeforeRenewal();
final String loanBeforeRenewalId = loanBeforeRenewal != null ? loanBeforeRenewal.getId() : null;

log.info("createOverdueFineIfNecessary:: loanBeforeRenewalId: {}, loggedInUserId: {}",
() -> loanBeforeRenewalId, () -> loggedInUserId);

if (!shouldChargeOverdueFineOnRenewal(context)) {
log.info("createOverdueFineIfNecessary:: loan on renewal should not be charged");
log.info("createOverdueFineIfNecessary:: Loan {} should not be charged",
() -> loanBeforeRenewalId);
return completedFuture(succeeded(context));
}

Expand All @@ -70,14 +75,26 @@ public CompletableFuture<Result<RenewalContext>> createOverdueFineIfNecessary(

private boolean shouldChargeOverdueFineOnRenewal(RenewalContext renewalContext) {
final Loan loanBeforeRenewal = renewalContext.getLoanBeforeRenewal();
if (loanBeforeRenewal == null || !loanBeforeRenewal.isOverdue()) {

if (loanBeforeRenewal == null) {
log.info("shouldChargeOverdueFineOnRenewal:: Loan is null");
return false;
}

if (!loanBeforeRenewal.isOverdue()) {
log.info("shouldChargeOverdueFineOnRenewal:: Loan {} is not overdue",
loanBeforeRenewal::getId);
return false;
}

if (itemWasLost(renewalContext.getItemStatusBeforeRenewal())) {
log.info("shouldChargeOverdueFineOnRenewal:: Item was lost for loan {}",
loanBeforeRenewal::getId);
return shouldChargeOverdueFineForLostItem(renewalContext.getLoan());
}

log.info("shouldChargeOverdueFineOnRenewal:: Should charge overdue fine for loanBeforeRenewal ID: {}",
loanBeforeRenewal::getId);
return true;
}

Expand All @@ -86,8 +103,10 @@ public CompletableFuture<Result<FeeFineAction>> createOverdueFineIfNecessary(

log.debug("createOverdueFineIfNecessary:: parameters context: {}, userId: {}",
() -> context, () -> userId);


if (!shouldChargeOverdueFineOnCheckIn(context)) {
log.info("createOverdueFineIfNecessary:: loan on check in should not be charged");
log.info("createOverdueFineIfNecessary:: Loan on check in should not be charged");
return completedFuture(succeeded(null));
}

Expand All @@ -96,65 +115,94 @@ public CompletableFuture<Result<FeeFineAction>> createOverdueFineIfNecessary(

private boolean shouldChargeOverdueFineOnCheckIn(CheckInContext context) {
final Loan loan = context.getLoan();
log.info("shouldChargeOverdueFineOnCheckIn:: loan ID: {}", loan::getId);

if (loan == null || !loan.isOverdue(loan.getReturnDate())) {
log.info("shouldChargeOverdueFineOnCheckIn:: Loan {} is null or not overdue", loan::getId);
return false;
}

if(context.getCheckInRequest().getClaimedReturnedResolution() != null
&& context.getCheckInRequest().getClaimedReturnedResolution().equals(FOUND_BY_LIBRARY)) {
log.info("shouldChargeOverdueFineOnCheckIn:: Loan {} was claimed returned and found by " +
"library", loan::getId);
return false;
}

if (itemWasLost(context.getItemStatusBeforeCheckIn())) {
log.info("shouldChargeOverdueFineOnCheckIn:: Item was lost, loan {}", loan::getId);
return shouldChargeOverdueFineForLostItem(loan);
}

log.info("shouldChargeOverdueFineOnCheckIn:: Should charge overdue fine for loan {}",
loan::getId);
return true;
}

private boolean shouldChargeOverdueFineForLostItem(Loan loan) {
log.info("shouldChargeOverdueFineForLostItem:: loan ID: {}", loan::getId);

if (!loan.getLostItemPolicy().shouldChargeOverdueFee()) {
log.info("shouldChargeOverdueFineForLostItem:: Overdue fine for loan: {} should not be " +
"charged", loan::getId);
return false;
}

if (!loan.getLostItemPolicy().shouldRefundFees(loan.getLostDate())) {
// if the refund period has passed, do not charge fines.
log.info("shouldChargeOverdueFineForLostItem:: Refund period has passed for loan: {}, " +
"should not charge fines", loan::getId);
return false;
}

log.info("shouldChargeOverdueFineForLostItem:: Overdue fine should be charged for loan: {}",
loan::getId);
return true;
}

private CompletableFuture<Result<FeeFineAction>> createOverdueFineIfNecessary(Loan loan,
Scenario scenario, String loggedInUserId, ZoneId zoneId) {

log.debug("createOverdueFineIfNecessary:: parameters loan: {}, scenario: {}, " +
"loggedInUserId: {}", () -> loan, () -> scenario, () -> loggedInUserId);
"loggedInUserId: {}, zoneId: {}", () -> loan, () -> scenario, () -> loggedInUserId,
zoneId::getId);
log.info("createOverdueFineIfNecessary:: parameters loan ID: {}, scenario: {}, " +
"loggedInUserId: {}, zoneId: {}", loan::getId, () -> scenario, () -> loggedInUserId,
zoneId::getId);

if (loan.getOverdueFinePolicy().isUnknown()) {
log.info("createOverdueFineIfNecessary:: Overdue policy for loan {} is unknown", loan::getId);
return overdueFinePolicyRepository.findOverdueFinePolicyForLoan(succeeded(loan))
.thenCompose(r -> r.after(l -> createOverdueFineIfNecessary(l, scenario, loggedInUserId,
l.getOverdueFinePolicy(), zoneId)));
} else {
return createOverdueFineIfNecessary(loan, scenario, loggedInUserId, loan.getOverdueFinePolicy(), zoneId);
log.info("createOverdueFineIfNecessary:: Overdue policy for loan {} is {}", loan::getId,
loan::getOverdueFinePolicyId);
return createOverdueFineIfNecessary(loan, scenario, loggedInUserId,
loan.getOverdueFinePolicy(), zoneId);
}
}

private CompletableFuture<Result<FeeFineAction>> createOverdueFineIfNecessary(Loan loan,
Scenario scenario, String loggedInUserId, OverdueFinePolicy overdueFinePolicy, ZoneId zoneId) {

log.debug("createOverdueFineIfNecessary:: parameters loan: {}, scenario: {}, " +
"loggedInUserId: {}, overdueFinePolicy: {}", () -> loan, () -> scenario, () -> loggedInUserId,
() -> overdueFinePolicy);
"loggedInUserId: {}, overdueFinePolicy: {}, zoneId: {}", () -> loan, () -> scenario,
() -> loggedInUserId, () -> overdueFinePolicy, zoneId::getId);
log.info("createOverdueFineIfNecessary:: parameters loan ID: {}, scenario: {}, " +
"loggedInUserId: {}, overdueFinePolicy ID: {}, zoneId: {}", loan::getId, () -> scenario,
() -> loggedInUserId, overdueFinePolicy::getId, zoneId::getId);

return scenario.shouldCreateFine(overdueFinePolicy)
? createOverdueFine(loan, loggedInUserId, zoneId)
: completedFuture(succeeded(null));
}

private CompletableFuture<Result<FeeFineAction>> createOverdueFine(Loan loan, String loggedInUserId, ZoneId zoneId) {
log.debug("createOverdueFine:: parameters loan: {}, loggedInUserId: {}",
() -> loan, () -> loggedInUserId);
log.debug("createOverdueFine:: parameters loan: {}, loggedInUserId: {}, zoneId: {}",
() -> loan, () -> loggedInUserId, zoneId::getId);
log.info("createOverdueFine:: parameters loan ID: {}, loggedInUserId: {}, zoneId: {}",
loan::getId, () -> loggedInUserId, zoneId::getId);

return getOverdueMinutes(loan, zoneId)
.thenCompose(r -> r.after(minutes -> calculateOverdueFine(loan, minutes)))
Expand Down Expand Up @@ -207,9 +255,12 @@ private CompletableFuture<Result<CalculationParameters>> lookupItemRelatedRecord

log.debug("lookupItemRelatedRecords:: parameters params: {}", () -> params);
if (params.feeFine == null) {
log.info("lookupItemRelatedRecords:: params.feeFine is null");
return completedFuture(succeeded(params));
}

log.info("lookupItemRelatedRecords:: Fetching item related records for item {}",
params.loan::getItemId);
return itemRepository.fetchItemRelatedRecords(succeeded(params.loan.getItem()))
.thenApply(mapResult(params::withItem));
}
Expand Down Expand Up @@ -242,6 +293,8 @@ private CompletableFuture<Result<FeeFineAction>> createFeeFineRecord(Loan loan,

log.debug("createFeeFineRecord:: parameters loan: {}, fineAmount: {}, loggedInUserId: {}",
() -> loan, () -> fineAmount, () -> loggedInUserId);
log.info("createFeeFineRecord:: parameters loan ID: {}, fineAmount: {}, loggedInUserId: {}",
loan::getId, () -> fineAmount, () -> loggedInUserId);

if (fineAmount.compareTo(BigDecimal.ZERO) <= 0) {
log.info("createFeeFineRecord:: fineAmount is 0");
Expand Down Expand Up @@ -278,6 +331,9 @@ private CompletableFuture<Result<FeeFineAction>> createAccount(CalculationParame
.withLostItemFeePolicyId(params.loan.getLostItemPolicyId())
.build();

log.info("createAccount:: Creating account record for loan {}, item {} by user {} " +
"with amount {}", params.loan.getId(), params.item == null ? null : params.item.getItemId(),
params.loggedInUserId, params.fineAmount);
return feeFineFacade.createAccount(createAccountCommand);
}

Expand Down