Details
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/api/InvoiceApiHelper.java b/invoice/src/main/java/org/killbill/billing/invoice/api/InvoiceApiHelper.java
index cb7dfcb..047f073 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/api/InvoiceApiHelper.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/api/InvoiceApiHelper.java
@@ -151,6 +151,11 @@ public class InvoiceApiHelper {
final Map<UUID, BigDecimal> output = dao.computeItemAdjustments(invoiceToBeAdjusted.getId().toString(), input, context);
+ // Nothing to adjust
+ if (output.get(invoiceItemId) == null) {
+ return null;
+ }
+
// If we pass that stage, it means the validation succeeded so we just need to extract resulting amount and negate the result.
final BigDecimal amountToAdjust = output.get(invoiceItemId).negate();
// Finally, create the adjustment
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java b/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
index c19bb7c..4079b53 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
@@ -419,7 +419,9 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
effectiveDate,
description,
internalCallContextFactory.createInternalCallContext(accountId, context));
- invoice.addInvoiceItem(adjustmentItem);
+ if (adjustmentItem != null) {
+ invoice.addInvoiceItem(adjustmentItem);
+ }
return ImmutableList.<Invoice>of(invoice);
}
@@ -432,9 +434,9 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
return InvoiceItemType.ITEM_ADJ.equals(invoiceItem.getInvoiceItemType());
}
});
- Preconditions.checkState(adjustmentInvoiceItems.size() == 1, "Should have created a single adjustment item: " + adjustmentInvoiceItems);
+ Preconditions.checkState(adjustmentInvoiceItems.size() <= 1, "Should have created a single adjustment item: " + adjustmentInvoiceItems);
- return adjustmentInvoiceItems.iterator().next();
+ return adjustmentInvoiceItems.iterator().hasNext() ? adjustmentInvoiceItems.iterator().next() : null;
}
@Override
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java b/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
index 98fc4b3..7daf146 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
@@ -262,6 +262,9 @@ public class TestDefaultInvoiceUserApi extends InvoiceTestSuiteWithEmbeddedDB {
// Verify the adjusted account balance
final BigDecimal adjustedAccountBalance = invoiceUserApi.getAccountBalance(accountId, callContext);
Assert.assertEquals(adjustedAccountBalance, adjustedInvoiceBalance);
+
+ // Verify idempotency
+ Assert.assertNull(invoiceUserApi.insertInvoiceItemAdjustment(accountId, invoiceId, invoiceItem.getId(), clock.getUTCToday(), null, callContext));
}
@Test(groups = "slow")
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
index cd70288..ac5a0fe 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
@@ -474,7 +474,11 @@ public class InvoiceResource extends JaxRsResourceBase {
callContext);
}
- return uriBuilder.buildResponse(uriInfo, InvoiceResource.class, "getInvoice", adjustmentItem.getInvoiceId(), request);
+ if (adjustmentItem == null) {
+ return Response.status(Status.NOT_FOUND).build();
+ } else {
+ return uriBuilder.buildResponse(uriInfo, InvoiceResource.class, "getInvoice", adjustmentItem.getInvoiceId(), request);
+ }
}
@TimedResource