Skip to content

Commit

Permalink
MODDCB-173: The GET status API extended with renewal count and renewa…
Browse files Browse the repository at this point in the history
…l maximum number in the borrowing or borrowing-pickup role and ITEM_CHECKED_OUT.
  • Loading branch information
kapil-epam committed Feb 10, 2025
1 parent 5c3e61d commit 069e0c0
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 3 deletions.
4 changes: 4 additions & 0 deletions descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
"id": "circulation",
"version": "14.4"
},
{
"id": "loan-policy-storage",
"version": "2.3"
},
{
"id": "users",
"version": "16.3"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
import org.folio.dcb.domain.dto.CheckInRequest;
import org.folio.dcb.domain.dto.CheckOutRequest;
import org.folio.dcb.domain.dto.CirculationRequest;
import org.folio.dcb.domain.dto.LoanCollection;
import org.folio.spring.config.FeignClientConfiguration;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(name = "circulation", configuration = FeignClientConfiguration.class)
public interface CirculationClient {
Expand All @@ -24,4 +27,7 @@ public interface CirculationClient {
@PutMapping("/requests/{requestId}")
CirculationRequest updateRequest(@PathVariable("requestId") String requestId,
@RequestBody CirculationRequest circulationRequest);

@GetMapping("/loans")
LoanCollection fetchLoanByQuery(@RequestParam("query") String query);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.folio.dcb.client.feign;

import org.folio.dcb.domain.dto.LoanPolicyCollection;
import org.folio.spring.config.FeignClientConfiguration;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(name = "loan-policy-storage", configuration = FeignClientConfiguration.class)
public interface CirculationLoanPolicyStorageClient {
@GetMapping("/loan-policies")
LoanPolicyCollection fetchLoanPolicyByQuery(@RequestParam("query") String query);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@

import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.folio.dcb.client.feign.CirculationClient;
import org.folio.dcb.client.feign.CirculationLoanPolicyStorageClient;
import org.folio.dcb.domain.dto.DcbItem;
import org.folio.dcb.domain.dto.DcbTransaction;
import org.folio.dcb.domain.dto.DcbUpdateTransaction;
import org.folio.dcb.domain.dto.LoanCollection;
import org.folio.dcb.domain.dto.LoanPolicyCollection;
import org.folio.dcb.domain.dto.RenewalPolicy;
import org.folio.dcb.domain.dto.TransactionStatus;
import org.folio.dcb.domain.dto.TransactionStatusResponse;
import org.folio.dcb.domain.dto.TransactionStatusResponseCollection;
Expand All @@ -17,17 +23,23 @@
import org.folio.dcb.service.StatusProcessorService;
import org.folio.dcb.service.TransactionsService;
import org.folio.spring.exception.NotFoundException;
import org.folio.util.PercentCodec;
import org.folio.util.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.time.OffsetDateTime;
import java.util.Optional;

@Service
@RequiredArgsConstructor
@Log4j2
public class TransactionsServiceImpl implements TransactionsService {

private static final String CQL_AND = " AND ";
@Qualifier("lendingLibraryService")
private final LibraryService lendingLibraryService;
@Qualifier("borrowingPickupLibraryService")
Expand All @@ -41,6 +53,8 @@ public class TransactionsServiceImpl implements TransactionsService {
private final TransactionMapper transactionMapper;
private final TransactionAuditRepository transactionAuditRepository;
private final BaseLibraryService baseLibraryService;
private final CirculationClient circulationClient;
private final CirculationLoanPolicyStorageClient circulationLoanPolicyStorageClient;

@Override
public TransactionStatusResponse createCirculationRequest(String dcbTransactionId, DcbTransaction dcbTransaction) {
Expand Down Expand Up @@ -89,9 +103,46 @@ public TransactionStatusResponse getTransactionStatusById(String dcbTransactionI
log.debug("getTransactionStatusById:: id {} ", dcbTransactionId);
TransactionEntity transactionEntity = getTransactionEntityOrThrow(dcbTransactionId);

return generateTransactionStatusResponseFromTransactionEntity(transactionEntity);
Optional<LoanRenewalDetails> loanRenewalDetails = getLoanRenewalDetails(transactionEntity);
return generateTransactionStatusResponseFromTransactionEntity(transactionEntity, loanRenewalDetails);
}

private Optional<LoanRenewalDetails> getLoanRenewalDetails(TransactionEntity transactionEntity) {
if (transactionEntity.getStatus() == TransactionStatus.StatusEnum.ITEM_CHECKED_OUT
&& (transactionEntity.getRole() == DcbTransaction.RoleEnum.BORROWING_PICKUP
|| transactionEntity.getRole() == DcbTransaction.RoleEnum.BORROWER)) {
String loanQuery = buildLoanQuery(transactionEntity);
LoanCollection loanCollection = circulationClient.fetchLoanByQuery(loanQuery);
if (loanCollection.getLoans().isEmpty()) {
return Optional.empty();
}

Integer loanRenewalCount = Integer.valueOf(loanCollection.getLoans().get(0).getRenewalCount());

String loanPolicyIdQuery = "id==" + StringUtil.cqlEncode(loanCollection.getLoans().get(0).getLoanPolicyId());
LoanPolicyCollection loanPolicyCollection =
circulationLoanPolicyStorageClient.fetchLoanPolicyByQuery(PercentCodec.encode(loanPolicyIdQuery).toString());

Boolean isUnlimited = loanPolicyCollection.getLoanPolicies().get(0).getRenewalsPolicy().getUnlimited();
Integer renewalMaxCount = Boolean.TRUE.equals(isUnlimited) ? -1 :
loanPolicyCollection.getLoanPolicies().get(0).getRenewalsPolicy().getNumberAllowed();

return Optional.of(new LoanRenewalDetails(loanRenewalCount, renewalMaxCount));
} else {
return Optional.empty();
}
}

private static @NotNull String buildLoanQuery(TransactionEntity transactionEntity) {
String itemId = "itemId==" + StringUtil.cqlEncode(transactionEntity.getItemId());
String statusOpen = "status.name==" + StringUtil.cqlEncode("OPEN");
String isDCB = "isDcb==" + StringUtil.cqlEncode("true");
String userId = "itemId==" + StringUtil.cqlEncode(transactionEntity.getPatronId());
return PercentCodec.encode(itemId + CQL_AND + statusOpen + CQL_AND + isDCB + CQL_AND + userId).toString();
}

private record LoanRenewalDetails(Integer loanRenewalCount, Integer renewalMaxCount) {}

@Override
public TransactionStatusResponseCollection getTransactionStatusList(OffsetDateTime fromDate, OffsetDateTime toDate, Integer pageNumber, Integer pageSize) {
log.info("getTransactionStatusList:: fromDate {}, toDate {}, pageNumber {}, pageSize {}",
Expand Down Expand Up @@ -124,13 +175,19 @@ public void updateTransactionDetails(String dcbTransactionId, DcbUpdateTransacti
baseLibraryService.updateTransactionDetails(transactionEntity, dcbUpdateTransaction.getItem());
}

private TransactionStatusResponse generateTransactionStatusResponseFromTransactionEntity(TransactionEntity transactionEntity) {
private TransactionStatusResponse generateTransactionStatusResponseFromTransactionEntity(TransactionEntity transactionEntity, Optional<LoanRenewalDetails> loanRenewalDetails) {
TransactionStatus.StatusEnum transactionStatus = transactionEntity.getStatus();
TransactionStatusResponse.StatusEnum transactionStatusResponseStatusEnum = TransactionStatusResponse.StatusEnum.fromValue(transactionStatus.getValue());
DcbTransaction.RoleEnum transactionRole = transactionEntity.getRole();

DcbItem dcbItem = loanRenewalDetails.map(loanDetails-> DcbItem.builder()
.renewalPolicy(RenewalPolicy.builder()
.renewalCount(loanDetails.loanRenewalCount())
.renewalMaxCount(loanDetails.renewalMaxCount())
.build())
.build()).orElse(null);
return TransactionStatusResponse.builder()
.status(transactionStatusResponseStatusEnum)
.item(dcbItem)
.role((TransactionStatusResponse.RoleEnum.fromValue(transactionRole.getValue())))
.build();
}
Expand Down
4 changes: 4 additions & 0 deletions src/main/resources/swagger.api/dcb_transaction.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,10 @@ components:
$ref: 'schemas/UserGroup.yaml#/UserGroupCollection'
UserCollection:
$ref: 'schemas/User.yaml#/UserCollection'
LoanCollection:
$ref: 'schemas/Loan.yaml#/LoanCollection'
LoanPolicyCollection:
$ref: 'schemas/LoanPolicy.yaml#/LoanPolicyCollection'
CirculationRequest:
$ref: 'schemas/CirculationRequest.yaml#/CirculationRequest'
CheckInRequest:
Expand Down
42 changes: 42 additions & 0 deletions src/main/resources/swagger.api/schemas/Loan.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
Loan:
type: object
title: Loan
properties:
id:
description: A globally unique (UUID) identifier for the Loan
type: string
userId:
description: A globally unique (UUID) identifier for the user
type: string
itemId:
description: A globally unique (UUID) identifier for the item
type: string
renewalCount:
description: renewalCount of the loan
type: string
loanPolicyId:
description: A unique name belonging to a user. Typically used for login
type: string
status:
"$ref": "Loan.yaml#/status"
status:
type: object
properties:
name:
description: loan status
type: string

LoanCollection:
type: object
properties:
loans:
type: array
description: "Loan collection"
items:
$ref: "Loan.yaml#/Loan"
totalRecords:
type: integer
additionalProperties: false
required:
- loans
- totalRecords
36 changes: 36 additions & 0 deletions src/main/resources/swagger.api/schemas/LoanPolicy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
LoanPolicy:
type: object
title: LoanPolicy
properties:
id:
description: A globally unique (UUID) identifier for the LoanPolicy
type: string
name:
description: Policy Name
type: string
renewalsPolicy:
"$ref": "LoanPolicy.yaml#/renewalsPolicy"
renewalsPolicy:
type: object
properties:
unlimited:
description: unlimited
type: boolean
numberAllowed:
description: numberAllowed
type: integer

LoanPolicyCollection:
type: object
properties:
loanPolicies:
type: array
description: "LoanPolicy collection"
items:
$ref: "LoanPolicy.yaml#/LoanPolicy"
totalRecords:
type: integer
additionalProperties: false
required:
- loanPolicies
- totalRecords
12 changes: 12 additions & 0 deletions src/main/resources/swagger.api/schemas/dcbItem.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,15 @@ DcbItem:
lendingLibraryCode:
description: The code which identifies the lending library
type: string
renewalPolicy:
"$ref": "dcbItem.yaml#/renewalPolicy"

renewalPolicy:
type: object
properties:
renewalCount:
description: renewalCount of the loan
type: integer
renewalMaxCount:
description: renewalMaxCount of loan as per the loan policy configuration
type: integer

0 comments on commit 069e0c0

Please sign in to comment.