Details
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
index 5136b19..aad1c94 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
@@ -498,24 +498,6 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB {
}, events);
}
- protected Payment refundPaymentWithAdjustmentAndCheckForCompletion(final Account account, final Payment payment, final NextEvent... events) {
- return doCallAndCheckForCompletion(new Function<Void, Payment>() {
- @Override
- public Payment apply(@Nullable final Void input) {
-
- final List<PluginProperty> properties = new ArrayList<PluginProperty>();
- final PluginProperty prop1 = new PluginProperty(InvoicePaymentControlPluginApi.PROP_IPCD_REFUND_WITH_ADJUSTMENTS, "true", false);
- properties.add(prop1);
- try {
- return paymentApi.createRefundWithPaymentControl(account, payment.getId(), payment.getPurchasedAmount(), payment.getCurrency(), UUID.randomUUID().toString(),
- properties, PAYMENT_OPTIONS, callContext);
- } catch (final PaymentApiException e) {
- fail(e.toString());
- return null;
- }
- }
- }, events);
- }
protected Payment refundPaymentWithInvoiceItemAdjAndCheckForCompletion(final Account account, final Payment payment, final Map<UUID, BigDecimal> iias, final NextEvent... events) {
return refundPaymentWithInvoiceItemAdjAndCheckForCompletion(account, payment, payment.getPurchasedAmount(), payment.getCurrency(), iias, events);
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPaymentRefund.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPaymentRefund.java
index cd0ef09..81d7a94 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPaymentRefund.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPaymentRefund.java
@@ -19,8 +19,10 @@
package org.killbill.billing.beatrix.integration;
import java.math.BigDecimal;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
@@ -29,6 +31,7 @@ import javax.annotation.Nullable;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
+import org.killbill.billing.ErrorCode;
import org.killbill.billing.account.api.Account;
import org.killbill.billing.api.TestApiListener.NextEvent;
import org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck;
@@ -42,7 +45,11 @@ import org.killbill.billing.invoice.api.Invoice;
import org.killbill.billing.invoice.api.InvoiceItem;
import org.killbill.billing.invoice.api.InvoiceItemType;
import org.killbill.billing.payment.api.Payment;
+import org.killbill.billing.payment.api.PaymentApiException;
+import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.payment.api.TransactionStatus;
+import org.killbill.billing.payment.invoice.InvoicePaymentControlPluginApi;
+import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -51,6 +58,7 @@ import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.fail;
public class TestPaymentRefund extends TestIntegrationBase {
@@ -92,14 +100,20 @@ public class TestPaymentRefund extends TestIntegrationBase {
}
@Test(groups = "slow")
- public void testRefundWithInvoiceAdjustment() throws Exception {
- refundPaymentWithAdjustmentAndCheckForCompletion(account, payment, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT, NextEvent.INVOICE_ADJUSTMENT);
- refundChecker.checkRefund(payment.getId(), callContext, new ExpectedRefundCheck(payment.getId(), true, new BigDecimal("233.82"), Currency.USD, initialCreationDate.toLocalDate()));
- invoice = invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext,
- new ExpectedInvoiceItemCheck(new LocalDate(2012, 3, 2),
- new LocalDate(2012, 3, 31), InvoiceItemType.RECURRING, new BigDecimal("233.82")),
- new ExpectedInvoiceItemCheck(InvoiceItemType.REFUND_ADJ, new BigDecimal("-233.82"))
- );
+ public void testFailedRefundWithInvoiceAdjustment() throws Exception {
+
+ final List<PluginProperty> properties = new ArrayList<PluginProperty>();
+ final PluginProperty prop1 = new PluginProperty(InvoicePaymentControlPluginApi.PROP_IPCD_REFUND_WITH_ADJUSTMENTS, "true", false);
+ properties.add(prop1);
+ try {
+ paymentApi.createRefundWithPaymentControl(account, payment.getId(), payment.getPurchasedAmount(), payment.getCurrency(), UUID.randomUUID().toString(),
+ properties, PAYMENT_OPTIONS, callContext);
+ fail("Refund with invoice adjustment should now throw an Exception");
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCause(), null);
+ // Unfortunately we lose the original error code : INVOICE_ITEMS_ADJUSTMENT_MISSING
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_PLUGIN_EXCEPTION.getCode());
+ }
}
private void setupRefundTest() throws Exception {
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java b/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
index 56565d2..9d978ce 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
@@ -155,6 +155,10 @@ public class DefaultInvoiceInternalApi implements InvoiceInternalApi {
@Override
public Map<UUID, BigDecimal> validateInvoiceItemAdjustments(final UUID paymentId, final Map<UUID, BigDecimal> idWithAmount, final InternalTenantContext context) throws InvoiceApiException {
+ // We want to validate that only refund with invoice *item* adjustments are allowed (as opposed to refund with invoice adjustment)
+ if (idWithAmount.size() == 0) {
+ throw new InvoiceApiException(ErrorCode.INVOICE_ITEMS_ADJUSTMENT_MISSING);
+ }
final InvoicePayment invoicePayment = getInvoicePayment(paymentId, InvoicePaymentType.ATTEMPT, context);
return dao.computeItemAdjustments(invoicePayment.getInvoiceId().toString(), idWithAmount, context);
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
index 58d0fa2..10aeb7a 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
@@ -434,7 +434,11 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
public InvoicePaymentModelDao createRefund(final UUID paymentId, final BigDecimal requestedRefundAmount, final boolean isInvoiceAdjusted,
final Map<UUID, BigDecimal> invoiceItemIdsWithNullAmounts, final String transactionExternalKey,
final InternalCallContext context) throws InvoiceApiException {
- final boolean isInvoiceItemAdjusted = isInvoiceAdjusted && invoiceItemIdsWithNullAmounts.size() > 0;
+
+
+ if (isInvoiceAdjusted && invoiceItemIdsWithNullAmounts.size() == 0) {
+ throw new InvoiceApiException(ErrorCode.INVOICE_ITEMS_ADJUSTMENT_MISSING);
+ }
return transactionalSqlDao.execute(InvoiceApiException.class, new EntitySqlDaoTransactionWrapper<InvoicePaymentModelDao>() {
@Override
@@ -487,18 +491,7 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
// At this point, we created the refund which made the invoice balance positive and applied any existing
// available CBA to that invoice.
// We now need to adjust the invoice and/or invoice items if needed and specified.
- if (isInvoiceAdjusted && !isInvoiceItemAdjusted) {
- // Invoice adjustment
- final BigDecimal maxBalanceToAdjust = (invoiceBalanceAfterRefund.compareTo(BigDecimal.ZERO) <= 0) ? BigDecimal.ZERO : invoiceBalanceAfterRefund;
- final BigDecimal requestedPositiveAmountToAdjust = requestedPositiveAmount.compareTo(maxBalanceToAdjust) > 0 ? maxBalanceToAdjust : requestedPositiveAmount;
- if (requestedPositiveAmountToAdjust.compareTo(BigDecimal.ZERO) > 0) {
- final InvoiceItemModelDao adjItem = new InvoiceItemModelDao(context.getCreatedDate(), InvoiceItemType.REFUND_ADJ, invoice.getId(), invoice.getAccountId(),
- null, null, null, null, null, null, context.getCreatedDate().toLocalDate(), null,
- requestedPositiveAmountToAdjust.negate(), null, invoice.getCurrency(), null);
- createInvoiceItemFromTransaction(transInvoiceItemDao, adjItem, context);
- invoice.addInvoiceItem(adjItem);
- }
- } else if (isInvoiceAdjusted) {
+ if (isInvoiceAdjusted) {
// Invoice item adjustment
for (final UUID invoiceItemId : invoiceItemIdsWithAmounts.keySet()) {
final BigDecimal adjAmount = invoiceItemIdsWithAmounts.get(invoiceItemId);
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/RefundAdjInvoiceItem.java b/invoice/src/main/java/org/killbill/billing/invoice/model/RefundAdjInvoiceItem.java
index a0e4dd4..3f2ff23 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/RefundAdjInvoiceItem.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/RefundAdjInvoiceItem.java
@@ -31,6 +31,9 @@ import org.killbill.billing.util.UUIDs;
import com.google.common.base.Objects;
+// See killbill/killbill#30
+// At some point we want to remove all code related to invoice adjustment
+@Deprecated()
public class RefundAdjInvoiceItem extends AdjInvoiceItem {
public RefundAdjInvoiceItem(final UUID invoiceId, final UUID accountId, final LocalDate date,