diff --git a/descriptors/ModuleDescriptor-template.json b/descriptors/ModuleDescriptor-template.json index 7c3518710b..b41b0ffe80 100644 --- a/descriptors/ModuleDescriptor-template.json +++ b/descriptors/ModuleDescriptor-template.json @@ -1130,7 +1130,7 @@ "requires": [ { "id": "loan-storage", - "version": "7.1" + "version": "7.3" }, { "id": "circulation-rules-storage", diff --git a/ramls/loan.json b/ramls/loan.json index 125f2d1798..80125978c9 100644 --- a/ramls/loan.json +++ b/ramls/loan.json @@ -370,6 +370,10 @@ "type": "string", "format": "date-time" }, + "isDcb": { + "description": "Indicates whether or not this loan is associated for DCB use case", + "type": "boolean" + }, "metadata": { "description": "Metadata about creation and changes to loan, provided by the server (client should not provide)", "type": "object", diff --git a/src/main/java/org/folio/circulation/infrastructure/storage/loans/LoanRepository.java b/src/main/java/org/folio/circulation/infrastructure/storage/loans/LoanRepository.java index da995e2a69..d804634fd9 100644 --- a/src/main/java/org/folio/circulation/infrastructure/storage/loans/LoanRepository.java +++ b/src/main/java/org/folio/circulation/infrastructure/storage/loans/LoanRepository.java @@ -88,6 +88,9 @@ public class LoanRepository implements GetManyRecordsRepository { private static final String ID = "id"; private static final String USER_ID = "userId"; + private static final String IS_DCB = "isDcb"; + private static final String DCB_USER_LASTNAME = "DcbSystem"; + public LoanRepository(Clients clients, ItemRepository itemRepository, UserRepository userRepository) { @@ -294,6 +297,15 @@ private Result> mapResponseToLoans(Response response) { return MultipleRecords.from(response, Loan::from, RECORDS_PROPERTY_NAME); } + private static void addIsDcbProperty(Loan loan, Item item, JsonObject storageLoan) { + write(storageLoan, IS_DCB, isDcbLoan(loan, item)); + } + + private static boolean isDcbLoan(Loan loan, Item item) { + return item.isDcbItem() || (nonNull(loan.getUser()) && nonNull(loan.getUser().getLastName()) + && loan.getUser().getLastName().equalsIgnoreCase(DCB_USER_LASTNAME)); + } + private static JsonObject mapToStorageRepresentation(Loan loan, Item item) { log.debug("mapToStorageRepresentation:: parameters loan: {}, item: {}", loan, item); JsonObject storageLoan = loan.asJson(); @@ -307,7 +319,7 @@ private static JsonObject mapToStorageRepresentation(Loan loan, Item item) { removeProperty(storageLoan, FEESANDFINES); removeProperty(storageLoan, OVERDUE_FINE_POLICY); removeProperty(storageLoan, LOST_ITEM_POLICY); - + addIsDcbProperty(loan, item, storageLoan); updatePolicy(storageLoan, loan.getLoanPolicy(), "loanPolicyId"); updatePolicy(storageLoan, loan.getOverdueFinePolicy(), "overdueFinePolicyId"); updatePolicy(storageLoan, loan.getLostItemPolicy(), "lostItemPolicyId"); diff --git a/src/test/java/api/loans/LoanAPITests.java b/src/test/java/api/loans/LoanAPITests.java index faa2b5abdb..4d4f43131c 100644 --- a/src/test/java/api/loans/LoanAPITests.java +++ b/src/test/java/api/loans/LoanAPITests.java @@ -199,8 +199,61 @@ void canCreateALoan() { assertThat("has item volume", item.getString("volume"), is("testVolume")); + assertThat("isDcb should be false", + loan.getString("isDcb"), is("false")); + loanHasExpectedProperties(loan, user); } + @Test + void createLoanForDcbItem() { + IndividualResource instance = instancesFixture.basedUponDunkirk(); + IndividualResource holdings = holdingsFixture.defaultWithHoldings(instance.getId()); + var instanceTitle = "virtual Title"; + + IndividualResource locationsResource = locationsFixture.mainFloor(); + final IndividualResource circulationItem = circulationItemsFixture.createCirculationItem( + "100002222", holdings.getId(), locationsResource.getId(), instanceTitle); + + loansFixture.createLoan(circulationItem, usersFixture.jessica()); + JsonObject loan = loansFixture.getLoans().getFirst(); + + assertThat("isDcb should be true", + loan.getString("isDcb"), is("true")); + } + + @Test + void createLoanForDcbUser() { + IndividualResource instance = instancesFixture.basedUponDunkirk(); + IndividualResource holdings = holdingsFixture.defaultWithHoldings(instance.getId()); + var instanceTitle = "title"; + + IndividualResource locationsResource = locationsFixture.mainFloor(); + final IndividualResource circulationItem = circulationItemsFixture.createCirculationItemForDcb( + "100002222", holdings.getId(), locationsResource.getId(), instanceTitle, false); + + loansFixture.createLoan(circulationItem, usersFixture.groot()); + JsonObject loan = loansFixture.getLoans().getFirst(); + + assertThat("isDcb should be true", + loan.getString("isDcb"), is("true")); + } + + @Test + void createLoanForDcbUserAndDcbItem() { + IndividualResource instance = instancesFixture.basedUponDunkirk(); + IndividualResource holdings = holdingsFixture.defaultWithHoldings(instance.getId()); + var instanceTitle = "virtual Title"; + + IndividualResource locationsResource = locationsFixture.mainFloor(); + final IndividualResource circulationItem = circulationItemsFixture.createCirculationItem( + "100002222", holdings.getId(), locationsResource.getId(), instanceTitle); + + loansFixture.createLoan(circulationItem, usersFixture.groot()); + JsonObject loan = loansFixture.getLoans().getFirst(); + + assertThat("isDcb should be true", + loan.getString("isDcb"), is("true")); + } @Test void canGetLoanWithoutOpenFeesFines() { diff --git a/src/test/java/api/support/builders/CirculationItemsBuilder.java b/src/test/java/api/support/builders/CirculationItemsBuilder.java index 1ec177ec60..6d31c5ce00 100644 --- a/src/test/java/api/support/builders/CirculationItemsBuilder.java +++ b/src/test/java/api/support/builders/CirculationItemsBuilder.java @@ -170,4 +170,17 @@ public CirculationItemsBuilder withInstanceTitle(String instanceTitle) { instanceTitle); } + public CirculationItemsBuilder withDcb(boolean isDcb) { + return new CirculationItemsBuilder( + this.itemId, + this.barcode, + this.holdingId, + this.locationId, + this.materialTypeId, + this.loanTypeId, + isDcb, + this.lendingLibraryCode, + this.instanceTitle); + } + } diff --git a/src/test/java/api/support/fakes/StorageSchema.java b/src/test/java/api/support/fakes/StorageSchema.java index 9f00695474..87aa34eac9 100644 --- a/src/test/java/api/support/fakes/StorageSchema.java +++ b/src/test/java/api/support/fakes/StorageSchema.java @@ -12,7 +12,7 @@ public static JsonSchemaValidator validatorForStorageItemSchema() throws IOExcep } public static JsonSchemaValidator validatorForStorageLoanSchema() throws IOException { - return JsonSchemaValidator.fromResource("/storage-loan-7-2.json"); + return JsonSchemaValidator.fromResource("/storage-loan-7-3.json"); } public static JsonSchemaValidator validatorForLocationInstSchema() throws IOException { diff --git a/src/test/java/api/support/fixtures/CirculationItemsFixture.java b/src/test/java/api/support/fixtures/CirculationItemsFixture.java index 10e69d57f4..2444d9d89e 100644 --- a/src/test/java/api/support/fixtures/CirculationItemsFixture.java +++ b/src/test/java/api/support/fixtures/CirculationItemsFixture.java @@ -27,6 +27,20 @@ public IndividualResource createCirculationItem(String barcode, UUID holdingId, return circulationItemClient.create(circulationItemsBuilder); } + public IndividualResource createCirculationItemForDcb(String barcode, UUID holdingId, UUID locationId, + String instanceTitle, boolean isDcb) { + CirculationItemsBuilder circulationItemsBuilder = new CirculationItemsBuilder() + .withBarcode(barcode) + .withHoldingId(holdingId) + .withLoanType(loanTypesFixture.canCirculate().getId()) + .withMaterialType(materialTypesFixture.book().getId()) + .withLocationId(locationId) + .withInstanceTitle(instanceTitle) + .withDcb(isDcb); + + return circulationItemClient.create(circulationItemsBuilder); + } + public IndividualResource createCirculationItemWithLendingLibrary(String barcode, UUID holdingId, UUID locationId, String lendingLibrary) { CirculationItemsBuilder circulationItemsBuilder = new CirculationItemsBuilder().withBarcode(barcode).withHoldingId(holdingId) .withLoanType(loanTypesFixture.canCirculate().getId()).withMaterialType(materialTypesFixture.book().getId()) diff --git a/src/test/java/api/support/fixtures/UserExamples.java b/src/test/java/api/support/fixtures/UserExamples.java index 0ec213a826..b44bd89f96 100644 --- a/src/test/java/api/support/fixtures/UserExamples.java +++ b/src/test/java/api/support/fixtures/UserExamples.java @@ -32,6 +32,13 @@ static UserBuilder basedUponJamesRodwell() { } + static UserBuilder basedUponGroot() { + return new UserBuilder() + .withName("DcbSystem", "dcb") + .withBarcode("6430530304") + .withActive(true); + } + static UserBuilder basedUponCharlotteBroadwell() { return new UserBuilder() .withName("Broadwell", "Charlotte") diff --git a/src/test/java/api/support/fixtures/UsersFixture.java b/src/test/java/api/support/fixtures/UsersFixture.java index bc322a72d7..d442941d6d 100644 --- a/src/test/java/api/support/fixtures/UsersFixture.java +++ b/src/test/java/api/support/fixtures/UsersFixture.java @@ -2,6 +2,7 @@ import static api.support.fixtures.UserExamples.basedUponBobbyBibbin; import static api.support.fixtures.UserExamples.basedUponCharlotteBroadwell; +import static api.support.fixtures.UserExamples.basedUponGroot; import static api.support.fixtures.UserExamples.basedUponHenryHanks; import static api.support.fixtures.UserExamples.basedUponJamesRodwell; import static api.support.fixtures.UserExamples.basedUponJessicaPontefract; @@ -34,6 +35,11 @@ public UserResource jessica() { .inGroupFor(patronGroupsFixture.regular())); } + public UserResource groot() { + return createIfAbsent(basedUponGroot() + .inGroupFor(patronGroupsFixture.regular())); + } + public UserResource james() { return createIfAbsent(basedUponJamesRodwell() .inGroupFor(patronGroupsFixture.regular())); diff --git a/src/test/resources/storage-loan-7-2.json b/src/test/resources/storage-loan-7-3.json similarity index 97% rename from src/test/resources/storage-loan-7-2.json rename to src/test/resources/storage-loan-7-3.json index a721809f4a..136137f8af 100644 --- a/src/test/resources/storage-loan-7-2.json +++ b/src/test/resources/storage-loan-7-3.json @@ -93,6 +93,10 @@ "description": "Indicates whether or not this loan had its due date modified by a recall on the loaned item", "type": "boolean" }, + "isDcb": { + "description": "Indicates whether or not this loan is associated for DCB use case", + "type": "boolean" + }, "declaredLostDate" : { "description": "Date and time the item was declared lost during this loan", "type": "string",