From 7782fc5998a4cd7a54336ae169e3fea954181d14 Mon Sep 17 00:00:00 2001 From: amihaiemil Date: Fri, 5 Mar 2021 17:58:34 +0200 Subject: [PATCH] #1034 Wallet.pay(...) returns the registered Payment --- .../main/java/com/selfxdsd/api/Wallet.java | 11 ++- .../selfxdsd/core/projects/FakeWallet.java | 7 +- .../selfxdsd/core/projects/StripeWallet.java | 80 +++++++++---------- .../core/projects/FakeWalletTestCase.java | 8 +- .../projects/StripePaymentMethodTestCase.java | 2 +- 5 files changed, 53 insertions(+), 55 deletions(-) diff --git a/self-api/src/main/java/com/selfxdsd/api/Wallet.java b/self-api/src/main/java/com/selfxdsd/api/Wallet.java index 49304b7c..3492f8c3 100644 --- a/self-api/src/main/java/com/selfxdsd/api/Wallet.java +++ b/self-api/src/main/java/com/selfxdsd/api/Wallet.java @@ -63,11 +63,14 @@ default BigDecimal debt() { * Pay an invoice. * @param invoice The Invoice to be paid. * @return Wallet having cash deducted with Invoice amount. - * - * @todo #1026:180min Modify method pay(...) to return the Payment created - * by Invoices.registerAsPai(...). + * @todo #1034:90min Write a Wallet decorator which will perform all the + * required pre-checks before making a payment (invoice is not paid, the + * cash limit is not exceeded etc). + * @todo #1034:90min Write a Wallet decorator which will catch any + * WalletPaymentException or IllegalStateException thrown from this method + * and register a failed Payment for it. */ - Wallet pay(final Invoice invoice); + Payment pay(final Invoice invoice); /** * Type of this wallet. diff --git a/self-core-impl/src/main/java/com/selfxdsd/core/projects/FakeWallet.java b/self-core-impl/src/main/java/com/selfxdsd/core/projects/FakeWallet.java index 25d90454..c1fd8573 100644 --- a/self-core-impl/src/main/java/com/selfxdsd/core/projects/FakeWallet.java +++ b/self-core-impl/src/main/java/com/selfxdsd/core/projects/FakeWallet.java @@ -108,7 +108,7 @@ public BigDecimal cash() { } @Override - public Wallet pay(final Invoice invoice) { + public Payment pay(final Invoice invoice) { if (!this.project.equals(invoice.contract().project())) { throw new InvoiceException.NotPartOfProjectContract(invoice, this.project); @@ -132,7 +132,7 @@ public Wallet pay(final Invoice invoice) { + "..." ); final String uuid = UUID.randomUUID().toString().replace("-", ""); - this.storage + final Payment payment = this.storage .invoices() .registerAsPaid( new StoredInvoice( @@ -151,7 +151,8 @@ public Wallet pay(final Invoice invoice) { BigDecimal.valueOf(0), BigDecimal.valueOf(0) ); - return this.updateCash(newCash); + this.updateCash(newCash); + return payment; } @Override diff --git a/self-core-impl/src/main/java/com/selfxdsd/core/projects/StripeWallet.java b/self-core-impl/src/main/java/com/selfxdsd/core/projects/StripeWallet.java index 1cded7e3..0e515c90 100644 --- a/self-core-impl/src/main/java/com/selfxdsd/core/projects/StripeWallet.java +++ b/self-core-impl/src/main/java/com/selfxdsd/core/projects/StripeWallet.java @@ -149,9 +149,11 @@ public BigDecimal cash() { * @see docs * @param invoice The Invoice to be paid. * @return Wallet with the updated cash limit. + * @checkstyle CyclomaticComplexity (200 lines) + * @checkstyle MethodLength (200 lines) */ @Override - public Wallet pay(final Invoice invoice) { + public Payment pay(final Invoice invoice) { final Contract contract = invoice.contract(); LOG.debug( "[STRIPE] Trying to pay Invoice #" + invoice.invoiceId() + " of " @@ -258,7 +260,7 @@ public Wallet pay(final Invoice invoice) { .ofEpochSecond(paymentIntent.getCreated(), 0, OffsetDateTime.now().getOffset()); final BigDecimal eurToRon = new XmlBnr().euroToRon(); - this.storage.invoices() + final Payment payment = this.storage.invoices() .registerAsPaid( new StoredInvoice( invoice.invoiceId(), @@ -276,6 +278,8 @@ public Wallet pay(final Invoice invoice) { vat, eurToRon ); + this.updateCash(newLimit); + return payment; } else { LOG.error("[STRIPE] PaymentIntent status: " + status); LOG.error("[STRIPE] Cancelling PaymentIntent..."); @@ -287,9 +291,37 @@ public Wallet pay(final Invoice invoice) { ); } } catch (final StripeException ex) { - this.rethrowStripeException(ex, invoice.invoiceId()); + final int invoiceId = invoice.invoiceId(); + final String code = ex.getCode(); + LOG.error( + String.format( + "[STRIPE] StripeException (code %s, request id %s) " + + "while trying to pay Invoice #%s.", + code, + ex.getRequestId(), + invoiceId + ), + ex + ); + if("authentication_required".equalsIgnoreCase(code)) { + throw new WalletPaymentException( + "Payment cannot be made because the card " + + "requires authentication." + ); + } + if("card_declined".equalsIgnoreCase(code)) { + final String message = ex.getMessage(); + throw new WalletPaymentException( + "Payment cannot be made: " + + message.substring(0, message.indexOf(';')) + ); + } + throw new IllegalStateException( + "Stripe threw an exception when trying execute PaymentIntent" + + " for invoice #" + invoiceId + ": " + ex.getMessage(), + ex + ); } - return this.updateCash(newLimit); } /** @@ -466,46 +498,6 @@ public int hashCode() { return Objects.hash(this.project); } - /** - * Rethrow the StripeException. - * @param exception StripeException. - * @param invoiceId Invoice ID. - */ - private void rethrowStripeException( - final StripeException exception, - final int invoiceId - ) { - final String code = exception.getCode(); - LOG.error( - String.format( - "[STRIPE] StripeException (code %s, request id %s) " - + "while trying to pay Invoice #%s.", - code, - exception.getRequestId(), - invoiceId - ), - exception - ); - if("authentication_required".equalsIgnoreCase(code)) { - throw new WalletPaymentException( - "Payment cannot be made because the card " - + "requires authentication." - ); - } - if("card_declined".equalsIgnoreCase(code)) { - final String message = exception.getMessage(); - throw new WalletPaymentException( - "Payment cannot be made: " - + message.substring(0, message.indexOf(';')) - ); - } - throw new IllegalStateException( - "Stripe threw an exception when trying execute PaymentIntent" - + " for invoice #" + invoiceId + ": " + exception.getMessage(), - exception - ); - } - /** * Calculate the VAT for Self's commission.

* diff --git a/self-core-impl/src/test/java/com/selfxdsd/core/projects/FakeWalletTestCase.java b/self-core-impl/src/test/java/com/selfxdsd/core/projects/FakeWalletTestCase.java index eed3f291..1a12fc26 100644 --- a/self-core-impl/src/test/java/com/selfxdsd/core/projects/FakeWalletTestCase.java +++ b/self-core-impl/src/test/java/com/selfxdsd/core/projects/FakeWalletTestCase.java @@ -404,7 +404,7 @@ public void canPayInvoice() { ) ).thenReturn(payment); - final Wallet updated = new FakeWallet( + final Payment successful = new FakeWallet( storage, project, BigDecimal.TEN, @@ -412,8 +412,10 @@ public void canPayInvoice() { true ).pay(invoice); - MatcherAssert.assertThat(updated.cash(), - Matchers.equalTo(BigDecimal.ZERO)); + MatcherAssert.assertThat( + payment, + Matchers.is(successful) + ); final ArgumentCaptor paidInvoiceCapture = ArgumentCaptor .forClass(Invoice.class); diff --git a/self-core-impl/src/test/java/com/selfxdsd/core/projects/StripePaymentMethodTestCase.java b/self-core-impl/src/test/java/com/selfxdsd/core/projects/StripePaymentMethodTestCase.java index 253a4225..f38af83d 100644 --- a/self-core-impl/src/test/java/com/selfxdsd/core/projects/StripePaymentMethodTestCase.java +++ b/self-core-impl/src/test/java/com/selfxdsd/core/projects/StripePaymentMethodTestCase.java @@ -181,7 +181,7 @@ public BigDecimal cash() { } @Override - public Wallet pay(final Invoice invoice) { + public Payment pay(final Invoice invoice) { throw new UnsupportedOperationException(); }