use of api.support.builders.NoticeConfigurationBuilder in project mod-circulation by folio-org.
the class ChangeDueDateAPITests method changeDueDateNoticeIsSentWhenPolicyIsDefined.
@Test
void changeDueDateNoticeIsSentWhenPolicyIsDefined() {
UUID templateId = UUID.randomUUID();
JsonObject changeNoticeConfiguration = new NoticeConfigurationBuilder().withTemplateId(templateId).withManualDueDateChangeEvent().create();
JsonObject checkInNoticeConfiguration = new NoticeConfigurationBuilder().withTemplateId(UUID.randomUUID()).withCheckInEvent().create();
IndividualResource noticePolicy = noticePoliciesFixture.create(new NoticePolicyBuilder().withName("Policy with manual due date change notice").withLoanNotices(Arrays.asList(changeNoticeConfiguration, checkInNoticeConfiguration)));
int renewalLimit = 3;
IndividualResource policyWithLimitedRenewals = loanPoliciesFixture.create(new LoanPolicyBuilder().withName("Limited renewals loan policy").rolling(months(1)).limitedRenewals(renewalLimit));
useFallbackPolicies(policyWithLimitedRenewals.getId(), requestPoliciesFixture.allowAllRequestPolicy().getId(), noticePolicy.getId(), overdueFinePoliciesFixture.facultyStandard().getId(), lostItemFeePoliciesFixture.facultyStandard().getId());
ItemBuilder itemBuilder = ItemExamples.basedUponSmallAngryPlanet(materialTypesFixture.book().getId(), loanTypesFixture.canCirculate().getId(), EMPTY, "ItemPrefix", "ItemSuffix", "");
ItemResource smallAngryPlanet = itemsFixture.basedUponSmallAngryPlanet(itemBuilder, itemsFixture.thirdFloorHoldings());
IndividualResource steve = usersFixture.steve();
IndividualResource loan = checkOutFixture.checkOutByBarcode(smallAngryPlanet, steve);
ZonedDateTime newDueDate = dueDate.plusWeeks(2);
changeDueDateFixture.changeDueDate(new ChangeDueDateRequestBuilder().forLoan(loan.getId()).withDueDate(newDueDate));
IndividualResource loanAfterUpdate = loansClient.get(loan);
verifyNumberOfSentNotices(1);
verifyNumberOfPublishedEvents(NOTICE, 1);
verifyNumberOfPublishedEvents(NOTICE_ERROR, 0);
Map<String, Matcher<String>> matchers = new HashMap<>();
matchers.putAll(getUserContextMatchers(steve));
matchers.putAll(getItemContextMatchers(smallAngryPlanet, true));
matchers.putAll(getLoanContextMatchers(loanAfterUpdate));
matchers.putAll(getLoanPolicyContextMatchers(renewalLimit, renewalLimit));
assertThat(FakeModNotify.getSentPatronNotices(), hasItems(hasEmailNoticeProperties(steve.getId(), templateId, matchers)));
}
use of api.support.builders.NoticeConfigurationBuilder in project mod-circulation by folio-org.
the class ChangeDueDateByReplacingLoanTests method manualDueDateChangeNoticeIsSentWhenPolicyDefinesManualDueDateChangeNoticeConfiguration.
@Test
void manualDueDateChangeNoticeIsSentWhenPolicyDefinesManualDueDateChangeNoticeConfiguration() {
UUID manualDueDateChangeTemplateId = UUID.randomUUID();
JsonObject manualDueDateChangeNoticeConfiguration = new NoticeConfigurationBuilder().withTemplateId(manualDueDateChangeTemplateId).withManualDueDateChangeEvent().create();
JsonObject checkInNoticeConfiguration = new NoticeConfigurationBuilder().withTemplateId(UUID.randomUUID()).withCheckInEvent().create();
IndividualResource noticePolicy = noticePoliciesFixture.create(new NoticePolicyBuilder().withName("Policy with manual due date change notice").withLoanNotices(Arrays.asList(manualDueDateChangeNoticeConfiguration, checkInNoticeConfiguration)));
int renewalLimit = 3;
IndividualResource loanPolicyWithLimitedRenewals = loanPoliciesFixture.create(new LoanPolicyBuilder().withName("Limited renewals loan policy").rolling(org.folio.circulation.domain.policy.Period.months(1)).limitedRenewals(renewalLimit));
useFallbackPolicies(loanPolicyWithLimitedRenewals.getId(), requestPoliciesFixture.allowAllRequestPolicy().getId(), noticePolicy.getId(), overdueFinePoliciesFixture.facultyStandard().getId(), lostItemFeePoliciesFixture.facultyStandard().getId());
ItemBuilder itemBuilder = ItemExamples.basedUponSmallAngryPlanet(materialTypesFixture.book().getId(), loanTypesFixture.canCirculate().getId(), EMPTY, "ItemPrefix", "ItemSuffix", "");
ItemResource smallAngryPlanet = itemsFixture.basedUponSmallAngryPlanet(itemBuilder, itemsFixture.thirdFloorHoldings());
IndividualResource steve = usersFixture.steve();
IndividualResource loan = checkOutFixture.checkOutByBarcode(smallAngryPlanet, steve);
JsonObject loanToChange = loan.getJson().copy();
ZonedDateTime dueDate = parseDateTime(loanToChange.getString("dueDate"));
ZonedDateTime newDueDate = dueDate.plusWeeks(2);
write(loanToChange, "dueDate", newDueDate);
loansClient.replace(loan.getId(), loanToChange);
IndividualResource loanAfterUpdate = loansClient.get(loan);
verifyNumberOfSentNotices(1);
verifyNumberOfPublishedEvents(NOTICE, 1);
verifyNumberOfPublishedEvents(NOTICE_ERROR, 0);
Map<String, Matcher<String>> noticeContextMatchers = new HashMap<>();
noticeContextMatchers.putAll(TemplateContextMatchers.getUserContextMatchers(steve));
noticeContextMatchers.putAll(TemplateContextMatchers.getItemContextMatchers(smallAngryPlanet, true));
noticeContextMatchers.putAll(TemplateContextMatchers.getLoanContextMatchers(loanAfterUpdate));
noticeContextMatchers.putAll(TemplateContextMatchers.getLoanPolicyContextMatchers(renewalLimit, renewalLimit));
assertThat(FakeModNotify.getSentPatronNotices(), hasItems(hasEmailNoticeProperties(steve.getId(), manualDueDateChangeTemplateId, noticeContextMatchers)));
}
use of api.support.builders.NoticeConfigurationBuilder in project mod-circulation by folio-org.
the class AgedToLostScheduledNoticesProcessingTests method patronNoticeForAdjustmentOfFullyPaidLostItemFeeIsCreatedAndProcessed.
@Test
void patronNoticeForAdjustmentOfFullyPaidLostItemFeeIsCreatedAndProcessed() {
LostItemFeePolicyBuilder lostItemFeePolicyBuilder = lostItemFeePoliciesFixture.ageToLostAfterOneMinutePolicy().withSetCost(LOST_ITEM_FEE_AMOUNT).withLostItemProcessingFee(PROCESSING_FEE_AMOUNT);
AgeToLostResult agedToLostLoan = ageToLostFixture.createLoanAgeToLostAndChargeFees(lostItemFeePolicyBuilder, new NoticePolicyBuilder().active().withName("Aged to lost notice policy").withFeeFineNotices(List.of(new NoticeConfigurationBuilder().withAgedToLostReturnedEvent().withTemplateId(UPON_AT_TEMPLATE_ID).withUponAtTiming().create())));
final UUID loanId = agedToLostLoan.getLoanId();
final UUID userId = agedToLostLoan.getUser().getId();
final List<JsonObject> existingAccounts = accountsClient.getAll();
assertThat(existingAccounts, allOf(iterableWithSize(2), hasItems(isAccount(LOST_ITEM_FEE_AMOUNT, LOST_ITEM_FEE_AMOUNT, ACCOUNT_STATUS_OPEN, PAYMENT_STATUS_OUTSTANDING, LOST_ITEM_FEE, agedToLostLoan.getUser().getId()), isAccount(PROCESSING_FEE_AMOUNT, PROCESSING_FEE_AMOUNT, ACCOUNT_STATUS_OPEN, PAYMENT_STATUS_OUTSTANDING, LOST_ITEM_PROCESSING_FEE, agedToLostLoan.getUser().getId()))));
// one "charge" action per account
assertThat(feeFineActionsClient.getAll(), hasSize(2));
final List<Account> accounts = existingAccounts.stream().map(Account::from).collect(toList());
assertThat(accounts, hasSize(2));
final Account firstAccount = accounts.get(0);
final Account secondAccount = accounts.get(1);
feeFineAccountFixture.pay(firstAccount.getId(), firstAccount.getAmount().toDouble());
feeFineAccountFixture.transfer(secondAccount.getId(), secondAccount.getAmount().toDouble());
// 2 charges + 1 payment + 1 transfer
assertThat(feeFineActionsClient.getAll(), hasSize(4));
// closing a loan-related fee/fine should close the loan
eventSubscribersFixture.publishLoanRelatedFeeFineClosedEvent(loanId);
assertThat(loansFixture.getLoanById(agedToLostLoan.getLoanId()).getJson(), isClosed());
// check-in should refund both fees, no cancellations since both were paid/transferred fully
checkInFixture.checkInByBarcode(agedToLostLoan.getItem());
assertThat(itemsFixture.getById(agedToLostLoan.getItemId()).getJson(), isAvailable());
assertThat(loansFixture.getLoanById(agedToLostLoan.getLoanId()).getJson(), isClosed());
// 2 charges + 1 payment + 1 transfer + 2 credits + 2 refunds
assertThat(feeFineActionsClient.getAll(), hasSize(8));
final JsonObject lostItemFeeRefundAction = findFeeFineAction(ACTION_TYPE_REFUNDED_FULLY, LOST_ITEM_FEE_AMOUNT);
final JsonObject processingFeeRefundAction = findFeeFineAction(ACTION_TYPE_REFUNDED_FULLY, PROCESSING_FEE_AMOUNT);
final UUID refundLostItemFeeActionId = getId(lostItemFeeRefundAction);
final UUID refundProcessingFeeActionId = getId(processingFeeRefundAction);
final ZonedDateTime refundLostItemFeeActionDate = getActionDate(lostItemFeeRefundAction);
final ZonedDateTime refundProcessingFeeActionDate = getActionDate(processingFeeRefundAction);
verifyNumberOfSentNotices(0);
assertThat(scheduledNoticesClient.getAll(), allOf(iterableWithSize(2), hasItems(hasScheduledFeeFineNotice(refundLostItemFeeActionId, loanId, userId, UPON_AT_TEMPLATE_ID, AGED_TO_LOST_RETURNED, refundLostItemFeeActionDate, UPON_AT, null, true), hasScheduledFeeFineNotice(refundProcessingFeeActionId, loanId, userId, UPON_AT_TEMPLATE_ID, AGED_TO_LOST_RETURNED, refundProcessingFeeActionDate, UPON_AT, null, true))));
ZonedDateTime maxActionDate = Stream.of(refundLostItemFeeActionDate, refundProcessingFeeActionDate).max(ZonedDateTime::compareTo).orElseThrow();
scheduledNoticeProcessingClient.runFeeFineNoticesProcessing(maxActionDate.plusSeconds(1));
checkSentFeeFineNotices(agedToLostLoan, Map.of(lostItemFeeRefundAction, UPON_AT_TEMPLATE_ID, processingFeeRefundAction, UPON_AT_TEMPLATE_ID));
verifyNumberOfScheduledNotices(0);
verifyNumberOfPublishedEvents(NOTICE, 2);
verifyNumberOfPublishedEvents(NOTICE_ERROR, 0);
}
use of api.support.builders.NoticeConfigurationBuilder in project mod-circulation by folio-org.
the class CheckInByBarcodeTests method requestAwaitingPickupNoticeIsNotSentWhenUserWasNotFound.
@Test
void requestAwaitingPickupNoticeIsNotSentWhenUserWasNotFound() {
JsonObject availableNoticeConfig = new NoticeConfigurationBuilder().withTemplateId(UUID.randomUUID()).withAvailableEvent().create();
NoticePolicyBuilder noticePolicy = new NoticePolicyBuilder().withName("Policy with available notice").withLoanNotices(Collections.singletonList(availableNoticeConfig));
use(noticePolicy);
ItemResource requestedItem = itemsFixture.basedUponNod();
UUID pickupServicePointId = servicePointsFixture.cd1().getId();
ZonedDateTime requestDate = ZonedDateTime.of(2019, 10, 9, 10, 0, 0, 0, UTC);
UserResource steve = usersFixture.steve();
requestsFixture.place(new RequestBuilder().page().forItem(requestedItem).by(steve).withPickupServicePointId(pickupServicePointId).withRequestDate(requestDate));
ZonedDateTime checkInDate = ZonedDateTime.of(2019, 10, 10, 12, 30, 0, 0, UTC);
usersClient.delete(steve);
checkInFixture.checkInByBarcode(requestedItem, checkInDate, pickupServicePointId);
verifyNumberOfSentNotices(0);
verifyNumberOfPublishedEvents(NOTICE, 0);
verifyNumberOfPublishedEvents(NOTICE_ERROR, 1);
}
use of api.support.builders.NoticeConfigurationBuilder in project mod-circulation by folio-org.
the class CheckInByBarcodeTests method patronNoticeOnCheckInIsNotSentWhenCheckInLoanNoticeIsDefinedAndLoanExists.
@Test
void patronNoticeOnCheckInIsNotSentWhenCheckInLoanNoticeIsDefinedAndLoanExists() {
UUID checkInTemplateId = UUID.randomUUID();
JsonObject checkOutNoticeConfiguration = new NoticeConfigurationBuilder().withTemplateId(checkInTemplateId).withCheckInEvent().create();
JsonObject renewNoticeConfiguration = new NoticeConfigurationBuilder().withTemplateId(UUID.randomUUID()).withEventType("Renew").create();
NoticePolicyBuilder noticePolicy = new NoticePolicyBuilder().withName("Policy with checkout notice").withLoanNotices(Arrays.asList(checkOutNoticeConfiguration, renewNoticeConfiguration));
use(noticePolicy);
ZonedDateTime loanDate = ZonedDateTime.of(2018, 3, 1, 13, 25, 46, 0, UTC);
final IndividualResource james = usersFixture.james();
final UUID checkInServicePointId = servicePointsFixture.cd1().getId();
final IndividualResource homeLocation = locationsFixture.basedUponExampleLocation(builder -> builder.withPrimaryServicePoint(checkInServicePointId));
final ItemResource nod = itemsFixture.basedUponNod(builder -> builder.withTemporaryLocation(homeLocation.getId()));
checkOutFixture.checkOutByBarcode(nod, james, loanDate);
ZonedDateTime checkInDate = ZonedDateTime.of(2018, 3, 5, 14, 23, 41, 0, UTC);
final CheckInByBarcodeResponse checkInResponse = checkInFixture.checkInByBarcode(new CheckInByBarcodeRequestBuilder().forItem(nod).on(checkInDate).at(checkInServicePointId));
JsonObject loanRepresentation = checkInResponse.getLoan();
assertThat("Closed loan should be present", loanRepresentation, notNullValue());
verifyNumberOfSentNotices(0);
verifyNumberOfPublishedEvents(NOTICE, 0);
verifyNumberOfPublishedEvents(NOTICE_ERROR, 0);
}
Aggregations