use of com.forgerock.openbanking.common.model.openbanking.persistence.account.FRStandingOrder in project openbanking-aspsp by OpenBankingToolkit.
the class StandingOrdersApiController method getAccountStandingOrders.
@Override
public ResponseEntity<OBReadStandingOrder1> getAccountStandingOrders(@PathVariable("AccountId") String accountId, @RequestParam(value = "page", defaultValue = "0") int page, @RequestHeader(value = "x-fapi-financial-id", required = true) String xFapiFinancialId, @RequestHeader(value = "Authorization", required = true) String authorization, @RequestHeader(value = "x-fapi-customer-last-logged-time", required = false) @DateTimeFormat(pattern = HTTP_DATE_FORMAT) DateTime xFapiCustomerLastLoggedTime, @RequestHeader(value = "x-fapi-customer-ip-address", required = false) String xFapiCustomerIpAddress, @RequestHeader(value = "x-fapi-interaction-id", required = false) String xFapiInteractionId, @RequestHeader(value = "x-customer-user-agent", required = false) String xCustomerUserAgent, @RequestHeader(value = "x-ob-permissions", required = true) List<OBExternalPermissions1Code> permissions, @RequestHeader(value = "x-ob-url", required = true) String httpUrl) {
LOGGER.info("Read standing orders for account {} with minimumPermissions {}", accountId, permissions);
Page<FRStandingOrder> standingOrdersResponse = frStandingOrderRepository.byAccountIdWithPermissions(accountId, toFRExternalPermissionsCodeList(permissions), PageRequest.of(page, PAGE_LIMIT_STANDING_ORDERS));
List<OBStandingOrder1> standingOrders = standingOrdersResponse.stream().map(so -> toOBStandingOrder1(so.getStandingOrder())).collect(Collectors.toList());
int totalPages = standingOrdersResponse.getTotalPages();
return ResponseEntity.ok(new OBReadStandingOrder1().data(new OBReadDataStandingOrder1().standingOrder(standingOrders)).links(PaginationUtil.generateLinks(httpUrl, page, totalPages)).meta(PaginationUtil.generateMetaData(totalPages)));
}
use of com.forgerock.openbanking.common.model.openbanking.persistence.account.FRStandingOrder in project openbanking-aspsp by OpenBankingToolkit.
the class StandingOrderService method createStandingOrder.
public FRStandingOrder createStandingOrder(FRStandingOrderData standingOrder, String pispId) {
log.debug("Create a standing order in the store. {}", standingOrder);
FRStandingOrder frStandingOrder = FRStandingOrder.builder().standingOrder(standingOrder).accountId(standingOrder.getAccountId()).id(standingOrder.getStandingOrderId()).status(StandingOrderStatus.PENDING).pispId(pispId).build();
return restTemplate.postForObject(rsStoreRoot + BASE_RESOURCE_PATH, frStandingOrder, FRStandingOrder.class);
}
use of com.forgerock.openbanking.common.model.openbanking.persistence.account.FRStandingOrder in project openbanking-aspsp by OpenBankingToolkit.
the class StandingOrderService method getActiveStandingOrders.
public Collection<FRStandingOrder> getActiveStandingOrders() {
log.debug("Get active standing orders in the store. {}");
ParameterizedTypeReference<List<FRStandingOrder>> ptr = new ParameterizedTypeReference<List<FRStandingOrder>>() {
};
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(rsStoreRoot + BASE_RESOURCE_PATH + "search/active");
URI uri = builder.build().encode().toUri();
ResponseEntity<List<FRStandingOrder>> entity = restTemplate.exchange(uri, HttpMethod.GET, null, ptr);
return entity.getBody();
}
use of com.forgerock.openbanking.common.model.openbanking.persistence.account.FRStandingOrder in project openbanking-aspsp by OpenBankingToolkit.
the class AcceptDueStandingOrderTask method payDueStandingOrders.
@Scheduled(fixedRate = 60 * 1000)
@SchedulerLock(name = "payDueStandingOrders")
public void payDueStandingOrders() {
log.info("Standing order payment task waking up. The time is now {}.", format.print(DateTime.now()));
final DateTime now = DateTime.now();
for (FRStandingOrder frStandingOrder : standingOrderService.getActiveStandingOrders()) {
FRStandingOrderData obStandingOrder = frStandingOrder.getStandingOrder();
// Check the OB status code has an ACTIVE status (because standing orders could be imported on /data endpoint with INACTIVE status).
if (FRStandingOrderData.FRStandingOrderStatus.ACTIVE != obStandingOrder.getStandingOrderStatusCode()) {
log.warn("Standing Order: '{}' has been given an OBExternalStandingOrderStatus1Code of {} and will not be processed.", frStandingOrder, obStandingOrder.getStandingOrderStatusCode());
continue;
}
log.info("Processing standing order {}", obStandingOrder);
try {
boolean isFirstPaymentDue = obStandingOrder.getFirstPaymentDateTime().isBefore(now);
boolean isFinalPaymentDue = obStandingOrder.getFinalPaymentDateTime().isBefore(now);
boolean isNextRecurringPaymentDue = obStandingOrder.getNextPaymentDateTime().isBefore(now);
boolean isBeforeFinalPayment = obStandingOrder.getNextPaymentDateTime().isBefore(obStandingOrder.getFinalPaymentDateTime());
log.debug("Standing order '{}', status: '{}', isFirstPaymentDue {} , isFinalPaymentDue {} , isNextPaymentDue: {}, isBeforeFinalPayment: {}", frStandingOrder.getId(), frStandingOrder.getStatus(), isFirstPaymentDue, isFinalPaymentDue, isNextRecurringPaymentDue, isBeforeFinalPayment);
if (StandingOrderStatus.ACTIVE == frStandingOrder.getStatus() && isNextRecurringPaymentDue && isBeforeFinalPayment) {
log.info("Active standing order '{}' has passed recurring payment date but not reached final payment date - make payment and calculate next recurring payment", frStandingOrder.getId());
doCreditAndDebitPayment(frStandingOrder, obStandingOrder.getNextPaymentAmount());
frStandingOrder.getStandingOrder().setNextPaymentDateTime(frequencyService.getNextDateTime(obStandingOrder.getNextPaymentDateTime(), obStandingOrder.getFrequency()));
} else if (StandingOrderStatus.ACTIVE == frStandingOrder.getStatus() && isFinalPaymentDue) {
log.info("Active standing order '{}' has passed final payment date - make final payment and set to COMPLETE", frStandingOrder.getId());
doCreditAndDebitPayment(frStandingOrder, obStandingOrder.getFinalPaymentAmount());
frStandingOrder.setStatus(StandingOrderStatus.COMPLETED);
} else if (StandingOrderStatus.PENDING == frStandingOrder.getStatus() && isFirstPaymentDue) {
log.info("Pending standing order '{}' has passed start payment date - make first payment and set to active", frStandingOrder.getId());
doCreditAndDebitPayment(frStandingOrder, obStandingOrder.getFirstPaymentAmount());
frStandingOrder.setStatus(StandingOrderStatus.ACTIVE);
} else {
log.debug("Active standing order '{}' is not due for payment", frStandingOrder.getId());
}
} catch (CurrencyConverterException e) {
log.error("Can't convert amount in the right currency", e);
log.error("Update payment status to rejected");
frStandingOrder.setRejectionReason("Can't convert amount in the right currency: " + e.getMessage());
frStandingOrder.setStatus(StandingOrderStatus.REJECTED);
log.info("Rejected payment {}", obStandingOrder);
} catch (Exception e) {
log.error("Couldn't pay standing order payment.", e);
log.error("Update payment status to rejected");
frStandingOrder.setRejectionReason("Failed to execute payment: " + e.getMessage());
frStandingOrder.setStatus(StandingOrderStatus.REJECTED);
log.info("Rejected payment {}", obStandingOrder);
} finally {
standingOrderService.updateStandingOrder(frStandingOrder);
paymentNotificationService.paymentStatusChanged(frStandingOrder);
}
}
log.info("All due standing order payments are now completed. The time is now {}.", format.print(DateTime.now()));
}
use of com.forgerock.openbanking.common.model.openbanking.persistence.account.FRStandingOrder in project openbanking-aspsp by OpenBankingToolkit.
the class AcceptDomesticStandingOrderTaskTest method shouldRejectPaymentWhenAnyException.
@Test
public void shouldRejectPaymentWhenAnyException() throws CurrencyConverterException {
// Given
FRStandingOrder payment = defaultPayment(StandingOrderStatus.PENDING);
given(paymentsService.getActiveStandingOrders()).willReturn(Collections.singletonList(payment));
FRAccount account = defaultAccount(DEBIT_ACCOUNT);
given(account2StoreService.getAccount(DEBIT_ACCOUNT)).willReturn(account);
doThrow(new RuntimeException("Simulated failure")).when(moneyService).moveMoney(any(), any(), any(), any(), any());
// When
acceptDueStandingOrderTask.payDueStandingOrders();
// Then
verify(moneyService).moveMoney(eq(account), any(), eq(FRCreditDebitIndicator.DEBIT), eq(payment), any());
verify(paymentsService).updateStandingOrder(argThat(p -> p.getStatus().equals(StandingOrderStatus.REJECTED)));
assertThat(payment.getRejectionReason()).isEqualTo("Failed to execute payment: Simulated failure");
}
Aggregations