killbill-uncached
Changes
account/pom.xml 2(+1 -1)
analytics/pom.xml 2(+1 -1)
api/pom.xml 2(+1 -1)
beatrix/pom.xml 2(+1 -1)
catalog/pom.xml 2(+1 -1)
entitlement/pom.xml 2(+1 -1)
invoice/pom.xml 2(+1 -1)
invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java 10(+3 -7)
jaxrs/pom.xml 2(+1 -1)
junction/pom.xml 2(+1 -1)
overdue/pom.xml 2(+1 -1)
payment/pom.xml 2(+1 -1)
pom.xml 14(+13 -1)
server/pom.xml 2(+1 -1)
usage/pom.xml 2(+1 -1)
util/pom.xml 2(+1 -1)
Details
account/pom.xml 2(+1 -1)
diff --git a/account/pom.xml b/account/pom.xml
index 8247e9d..d21272b 100644
--- a/account/pom.xml
+++ b/account/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.30-SNAPSHOT</version>
+ <version>0.1.31-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-account</artifactId>
analytics/pom.xml 2(+1 -1)
diff --git a/analytics/pom.xml b/analytics/pom.xml
index 78c11e2..5c029c2 100644
--- a/analytics/pom.xml
+++ b/analytics/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.30-SNAPSHOT</version>
+ <version>0.1.31-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-analytics</artifactId>
api/pom.xml 2(+1 -1)
diff --git a/api/pom.xml b/api/pom.xml
index a4123c4..a923e0e 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.30-SNAPSHOT</version>
+ <version>0.1.31-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-api</artifactId>
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java b/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
index 545e04d..b65cf34 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
@@ -34,9 +34,9 @@ public interface InvoicePaymentApi {
*/
public List<Invoice> getAllInvoicesByAccount(UUID accountId);
- public Invoice getInvoice(UUID invoiceId);
+ public Invoice getInvoice(UUID invoiceId) throws InvoiceApiException;
- public Invoice getInvoiceForPaymentId(UUID paymentId);
+ public Invoice getInvoiceForPaymentId(UUID paymentId) throws InvoiceApiException;
public List<InvoicePayment> getInvoicePayments(UUID paymentId);
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java b/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
index 3b78afe..fa58913 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
@@ -62,7 +62,7 @@ public interface InvoiceUserApi {
* @param invoiceId invoice id
* @return the invoice
*/
- public Invoice getInvoice(UUID invoiceId);
+ public Invoice getInvoice(UUID invoiceId) throws InvoiceApiException;
/**
* Retrieve an invoice by invoice number.
@@ -70,7 +70,7 @@ public interface InvoiceUserApi {
* @param number invoice number
* @return the invoice
*/
- public Invoice getInvoiceByNumber(Integer number);
+ public Invoice getInvoiceByNumber(Integer number) throws InvoiceApiException;
/**
* Record a payment for an invoice.
beatrix/pom.xml 2(+1 -1)
diff --git a/beatrix/pom.xml b/beatrix/pom.xml
index 99eb803..ae42097 100644
--- a/beatrix/pom.xml
+++ b/beatrix/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.30-SNAPSHOT</version>
+ <version>0.1.31-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-beatrix</artifactId>
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/util/InvoiceChecker.java b/beatrix/src/test/java/com/ning/billing/beatrix/util/InvoiceChecker.java
index 1cc24d8..e3cca6f 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/util/InvoiceChecker.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/util/InvoiceChecker.java
@@ -16,6 +16,11 @@
package com.ning.billing.beatrix.util;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;
@@ -28,22 +33,17 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
+import com.google.common.collect.ImmutableList;
+import com.google.inject.Inject;
import com.ning.billing.entitlement.api.user.EntitlementUserApi;
import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
import com.ning.billing.entitlement.api.user.Subscription;
import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.invoice.api.InvoiceApiException;
import com.ning.billing.invoice.api.InvoiceItem;
import com.ning.billing.invoice.api.InvoiceItemType;
import com.ning.billing.invoice.api.InvoiceUserApi;
-import com.google.common.collect.ImmutableList;
-import com.google.inject.Inject;
-
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
public class InvoiceChecker {
private static final Logger log = LoggerFactory.getLogger(InvoiceChecker.class);
@@ -57,29 +57,29 @@ public class InvoiceChecker {
this.entitlementApi = entitlementApi;
}
- public void checkInvoice(final UUID accountId, final int invoiceOrderingNumber, final ExpectedItemCheck... expected) {
+ public void checkInvoice(final UUID accountId, final int invoiceOrderingNumber, final ExpectedItemCheck... expected) throws InvoiceApiException {
checkInvoice(accountId, invoiceOrderingNumber, ImmutableList.<ExpectedItemCheck>copyOf(expected));
}
- public void checkInvoice(final UUID accountId, final int invoiceOrderingNumber, final List<ExpectedItemCheck> expected) {
+ public void checkInvoice(final UUID accountId, final int invoiceOrderingNumber, final List<ExpectedItemCheck> expected) throws InvoiceApiException {
final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(accountId);
Assert.assertEquals(invoices.size(), invoiceOrderingNumber);
final Invoice invoice = invoices.get(invoiceOrderingNumber - 1);
checkInvoice(invoice.getId(), expected);
}
- public void checkRepairedInvoice(final UUID accountId, final int invoiceNb, final ExpectedItemCheck... expected) {
+ public void checkRepairedInvoice(final UUID accountId, final int invoiceNb, final ExpectedItemCheck... expected) throws InvoiceApiException {
checkRepairedInvoice(accountId, invoiceNb, ImmutableList.<ExpectedItemCheck>copyOf(expected));
}
- public void checkRepairedInvoice(final UUID accountId, final int invoiceNb, final List<ExpectedItemCheck> expected) {
+ public void checkRepairedInvoice(final UUID accountId, final int invoiceNb, final List<ExpectedItemCheck> expected) throws InvoiceApiException {
final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(accountId);
Assert.assertTrue(invoices.size() > invoiceNb);
final Invoice invoice = invoices.get(invoiceNb - 1);
checkInvoice(invoice.getId(), expected);
}
- public void checkInvoice(final UUID invoiceId, final List<ExpectedItemCheck> expected) {
+ public void checkInvoice(final UUID invoiceId, final List<ExpectedItemCheck> expected) throws InvoiceApiException {
final Invoice invoice = invoiceUserApi.getInvoice(invoiceId);
Assert.assertNotNull(invoice);
catalog/pom.xml 2(+1 -1)
diff --git a/catalog/pom.xml b/catalog/pom.xml
index c7ae798..12580bf 100644
--- a/catalog/pom.xml
+++ b/catalog/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.30-SNAPSHOT</version>
+ <version>0.1.31-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-catalog</artifactId>
entitlement/pom.xml 2(+1 -1)
diff --git a/entitlement/pom.xml b/entitlement/pom.xml
index a9b7295..826233a 100644
--- a/entitlement/pom.xml
+++ b/entitlement/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.30-SNAPSHOT</version>
+ <version>0.1.31-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-entitlement</artifactId>
invoice/pom.xml 2(+1 -1)
diff --git a/invoice/pom.xml b/invoice/pom.xml
index 1534393..f59f789 100644
--- a/invoice/pom.xml
+++ b/invoice/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.30-SNAPSHOT</version>
+ <version>0.1.31-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-invoice</artifactId>
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
index e6bb878..ab7cccc 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
@@ -18,7 +18,6 @@
package com.ning.billing.invoice.api.invoice;
import java.math.BigDecimal;
-import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -26,6 +25,9 @@ import java.util.UUID;
import org.joda.time.DateTime;
import org.skife.jdbi.v2.exceptions.TransactionFailedException;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.inject.Inject;
import com.ning.billing.ErrorCode;
import com.ning.billing.catalog.api.Currency;
import com.ning.billing.invoice.api.Invoice;
@@ -37,10 +39,6 @@ import com.ning.billing.invoice.dao.InvoiceDao;
import com.ning.billing.invoice.model.DefaultInvoicePayment;
import com.ning.billing.util.callcontext.CallContext;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.inject.Inject;
-
public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
private static final WithInvoiceApiException<InvoicePayment> invoicePaymentWithException = new WithInvoiceApiException<InvoicePayment>();
@@ -63,12 +61,12 @@ public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
}
@Override
- public Invoice getInvoice(final UUID invoiceId) {
+ public Invoice getInvoice(final UUID invoiceId) throws InvoiceApiException {
return dao.getById(invoiceId);
}
@Override
- public Invoice getInvoiceForPaymentId(final UUID paymentId) {
+ public Invoice getInvoiceForPaymentId(final UUID paymentId) throws InvoiceApiException {
final UUID invoiceIdStr = dao.getInvoiceIdByPaymentId(paymentId);
return invoiceIdStr == null ? null : dao.getById(invoiceIdStr);
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
index bd524b2..11efa03 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
@@ -27,6 +27,7 @@ import javax.annotation.Nullable;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
+import com.google.inject.Inject;
import com.ning.billing.ErrorCode;
import com.ning.billing.account.api.Account;
import com.ning.billing.account.api.AccountApiException;
@@ -49,8 +50,6 @@ import com.ning.billing.util.dao.ObjectType;
import com.ning.billing.util.tag.ControlTagType;
import com.ning.billing.util.tag.Tag;
-import com.google.inject.Inject;
-
public class DefaultInvoiceUserApi implements InvoiceUserApi {
private final InvoiceDao dao;
@@ -91,12 +90,12 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
}
@Override
- public Invoice getInvoice(final UUID invoiceId) {
+ public Invoice getInvoice(final UUID invoiceId) throws InvoiceApiException {
return dao.getById(invoiceId);
}
@Override
- public Invoice getInvoiceByNumber(final Integer number) {
+ public Invoice getInvoiceByNumber(final Integer number) throws InvoiceApiException {
return dao.getByNumber(number);
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/AuditedInvoiceDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/AuditedInvoiceDao.java
index ba3ec0c..b03626e 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/AuditedInvoiceDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/AuditedInvoiceDao.java
@@ -30,10 +30,17 @@ import org.joda.time.LocalDate;
import org.skife.jdbi.v2.IDBI;
import org.skife.jdbi.v2.Transaction;
import org.skife.jdbi.v2.TransactionStatus;
+import org.skife.jdbi.v2.exceptions.TransactionFailedException;
import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Objects;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableMap.Builder;
+import com.google.inject.Inject;
import com.ning.billing.ErrorCode;
import com.ning.billing.catalog.api.Currency;
import com.ning.billing.invoice.api.Invoice;
@@ -65,13 +72,6 @@ import com.ning.billing.util.dao.ObjectType;
import com.ning.billing.util.dao.TableName;
import com.ning.billing.util.tag.ControlTagType;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableMap.Builder;
-import com.google.inject.Inject;
-
public class AuditedInvoiceDao implements InvoiceDao {
private static final Logger log = LoggerFactory.getLogger(AuditedInvoiceDao.class);
@@ -150,25 +150,36 @@ public class AuditedInvoiceDao implements InvoiceDao {
}
@Override
- public Invoice getById(final UUID invoiceId) {
- return invoiceSqlDao.inTransaction(new Transaction<Invoice, InvoiceSqlDao>() {
- @Override
- public Invoice inTransaction(final InvoiceSqlDao invoiceDao, final TransactionStatus status) throws Exception {
- final Invoice invoice = invoiceDao.getById(invoiceId.toString());
-
- if (invoice != null) {
+ public Invoice getById(final UUID invoiceId) throws InvoiceApiException {
+ try {
+ return invoiceSqlDao.inTransaction(new Transaction<Invoice, InvoiceSqlDao>() {
+ @Override
+ public Invoice inTransaction(final InvoiceSqlDao invoiceDao, final TransactionStatus status) throws Exception {
+ final Invoice invoice = invoiceDao.getById(invoiceId.toString());
+ if (invoice == null) {
+ throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND, invoiceId);
+ }
populateChildren(invoice, invoiceDao);
+ return invoice;
}
-
- return invoice;
+ });
+ } catch (TransactionFailedException e) {
+ if (e.getCause() instanceof InvoiceApiException) {
+ throw (InvoiceApiException) e.getCause();
+ } else {
+ throw e;
}
- });
+ }
}
@Override
- public Invoice getByNumber(final Integer number) {
+ public Invoice getByNumber(final Integer number) throws InvoiceApiException {
// The invoice number is just the record id
- return invoiceSqlDao.getByRecordId(number.longValue());
+ final Invoice result = invoiceSqlDao.getByRecordId(number.longValue());
+ if (result == null) {
+ throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND, number);
+ }
+ return result;
}
@Override
@@ -576,7 +587,8 @@ public class AuditedInvoiceDao implements InvoiceDao {
@Override
public InvoiceItem insertExternalCharge(final UUID accountId, @Nullable final UUID invoiceId, @Nullable final UUID bundleId, final String description,
- final BigDecimal amount, final LocalDate effectiveDate, final Currency currency, final CallContext context) {
+ final BigDecimal amount, final LocalDate effectiveDate, final Currency currency, final CallContext context)
+ throws InvoiceApiException {
return invoiceSqlDao.inTransaction(new Transaction<InvoiceItem, InvoiceSqlDao>() {
@Override
public InvoiceItem inTransaction(final InvoiceSqlDao transactional, final TransactionStatus status) throws Exception {
@@ -595,9 +607,22 @@ public class AuditedInvoiceDao implements InvoiceDao {
final InvoiceItemSqlDao transInvoiceItemDao = transactional.become(InvoiceItemSqlDao.class);
transInvoiceItemDao.create(externalCharge, context);
+ // At this point, reread the invoice and figure out if we need to consume some of the CBA
+ final Invoice invoice = transactional.getById(invoiceIdForExternalCharge.toString());
+ if (invoice == null) {
+ throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND, invoiceIdForExternalCharge);
+ }
+ populateChildren(invoice, transactional);
+
+ final BigDecimal accountCbaAvailable = getAccountCBAFromTransaction(invoice.getAccountId(), transactional);
+ if (accountCbaAvailable.compareTo(BigDecimal.ZERO) > 0 && invoice.getBalance().compareTo(BigDecimal.ZERO) > 0) {
+ final BigDecimal cbaAmountToConsume = accountCbaAvailable.compareTo(invoice.getBalance()) > 0 ? invoice.getBalance().negate() : accountCbaAvailable.negate();
+ final InvoiceItem cbaAdjItem = new CreditBalanceAdjInvoiceItem(invoice.getId(), invoice.getAccountId(), context.getCreatedDate().toLocalDate(), cbaAmountToConsume, invoice.getCurrency());
+ transInvoiceItemDao.create(cbaAdjItem, context);
+ }
+
// Notify the bus since the balance of the invoice changed
notifyBusOfInvoiceAdjustment(transactional, invoiceId, accountId, context.getUserToken());
-
return externalCharge;
}
});
@@ -742,7 +767,6 @@ public class AuditedInvoiceDao implements InvoiceDao {
for (final Invoice cur : invoices) {
cba = cba.add(cur.getCBAAmount());
}
-
return cba;
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
index dbf2edb..207c1de 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
@@ -37,9 +37,9 @@ public interface InvoiceDao {
void create(final Invoice invoice, final int billCycleDayUTC, final boolean isRealInvoice, final CallContext context);
- Invoice getById(final UUID id);
+ Invoice getById(final UUID id) throws InvoiceApiException;
- Invoice getByNumber(final Integer number);
+ Invoice getByNumber(final Integer number) throws InvoiceApiException;
List<Invoice> get();
@@ -119,7 +119,7 @@ public interface InvoiceDao {
* @return the newly created external charge invoice item
*/
InvoiceItem insertExternalCharge(final UUID accountId, @Nullable final UUID invoiceId, @Nullable final UUID bundleId, @Nullable final String description,
- final BigDecimal amount, final LocalDate effectiveDate, final Currency currency, final CallContext context);
+ final BigDecimal amount, final LocalDate effectiveDate, final Currency currency, final CallContext context) throws InvoiceApiException;
/**
* Retrieve a credit by id.
diff --git a/invoice/src/main/java/com/ning/billing/invoice/generator/DefaultInvoiceGenerator.java b/invoice/src/main/java/com/ning/billing/invoice/generator/DefaultInvoiceGenerator.java
index 43a1d70..c1e3140 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/generator/DefaultInvoiceGenerator.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/generator/DefaultInvoiceGenerator.java
@@ -18,6 +18,7 @@ package com.ning.billing.invoice.generator;
import java.math.BigDecimal;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
@@ -56,6 +57,9 @@ import com.ning.billing.invoice.model.RepairAdjInvoiceItem;
import com.ning.billing.junction.api.BillingEventSet;
import com.ning.billing.util.clock.Clock;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
import com.google.inject.Inject;
public class DefaultInvoiceGenerator implements InvoiceGenerator {
@@ -78,9 +82,9 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
*/
@Override
public Invoice generateInvoice(final UUID accountId, @Nullable final BillingEventSet events,
- @Nullable final List<Invoice> existingInvoices,
- final LocalDate targetDate, final DateTimeZone accountTimeZone,
- final Currency targetCurrency) throws InvoiceApiException {
+ @Nullable final List<Invoice> existingInvoices,
+ final LocalDate targetDate, final DateTimeZone accountTimeZone,
+ final Currency targetCurrency) throws InvoiceApiException {
if ((events == null) || (events.size() == 0) || events.isAccountAutoInvoiceOff()) {
return null;
}
@@ -94,8 +98,8 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
for (final Invoice invoice : existingInvoices) {
for (final InvoiceItem item : invoice.getInvoiceItems()) {
if (item.getSubscriptionId() == null || // Always include migration invoices, credits, external charges etc.
- !events.getSubscriptionIdsWithAutoInvoiceOff()
- .contains(item.getSubscriptionId())) { //don't add items with auto_invoice_off tag
+ !events.getSubscriptionIdsWithAutoInvoiceOff()
+ .contains(item.getSubscriptionId())) { //don't add items with auto_invoice_off tag
existingItems.add(item);
}
}
@@ -127,7 +131,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
}
void generateCBAForExistingInvoices(final UUID accountId, final List<Invoice> existingInvoices,
- final List<InvoiceItem> proposedItems, final Currency currency) {
+ final List<InvoiceItem> proposedItems, final Currency currency) {
// Determine most accurate invoice balances up to this point
final Map<UUID, BigDecimal> amountOwedByInvoice = new HashMap<UUID, BigDecimal>();
@@ -159,16 +163,48 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
void addRepairedItems(final List<InvoiceItem> existingItems, final List<InvoiceItem> proposedItems) {
for (final InvoiceItem existingItem : existingItems) {
if (existingItem.getInvoiceItemType() == InvoiceItemType.RECURRING ||
- existingItem.getInvoiceItemType() == InvoiceItemType.FIXED) {
- final BigDecimal amountNegated = existingItem.getAmount() == null ? null : existingItem.getAmount().negate();
- final RepairAdjInvoiceItem repairItem = new RepairAdjInvoiceItem(existingItem.getInvoiceId(), existingItem.getAccountId(), existingItem.getStartDate(), existingItem.getEndDate(), amountNegated, existingItem.getCurrency(), existingItem.getId());
- proposedItems.add(repairItem);
+ existingItem.getInvoiceItemType() == InvoiceItemType.FIXED) {
+ final BigDecimal existingAdjustedPositiveAmount = getAdjustedPositiveAmount(existingItems, existingItem.getId());
+ final BigDecimal amountNegated = existingItem.getAmount() == null ? null : existingItem.getAmount().subtract(existingAdjustedPositiveAmount).negate();
+ if (amountNegated.compareTo(BigDecimal.ZERO) < 0) {
+ final RepairAdjInvoiceItem repairItem = new RepairAdjInvoiceItem(existingItem.getInvoiceId(), existingItem.getAccountId(), existingItem.getStartDate(), existingItem.getEndDate(), amountNegated, existingItem.getCurrency(), existingItem.getId());
+ proposedItems.add(repairItem);
+ }
}
}
+
+ }
+
+
+ // We check to see if there are any adjustments that point to the item we are trying to repair
+ // If we did any CREDIT_ADJ or REFUND_ADJ, then we unfortunately we can't know what is the intent
+ // was as it applies to the full Invoice, so we ignore it. That might result in an extra positive CBA
+ // that would have to be corrected manually. This is the best we can do, and administrators should always
+ // use ITEM_ADJUSTEMNT rather than CREDIT_ADJ or REFUND_ADJ when possible.
+ //
+ BigDecimal getAdjustedPositiveAmount(final List<InvoiceItem> existingItems, final UUID linkedItemId) {
+ BigDecimal totalAdjustedOnItem = BigDecimal.ZERO;
+ final Collection<InvoiceItem> c = Collections2.filter(existingItems, new Predicate<InvoiceItem>() {
+ @Override
+ public boolean apply(InvoiceItem item) {
+ if (item.getInvoiceItemType() == InvoiceItemType.ITEM_ADJ &&
+ item.getLinkedItemId() != null && item.getLinkedItemId().equals(linkedItemId)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ });
+
+ final Iterator<InvoiceItem> it = c.iterator();
+ while (it.hasNext()) {
+ totalAdjustedOnItem = totalAdjustedOnItem.add(it.next().getAmount());
+ }
+ return totalAdjustedOnItem.negate();
}
void consumeExistingCredit(final UUID invoiceId, final UUID accountId, final List<InvoiceItem> existingItems,
- final List<InvoiceItem> proposedItems, final Currency targetCurrency) {
+ final List<InvoiceItem> proposedItems, final Currency targetCurrency) {
BigDecimal totalUnusedCreditAmount = BigDecimal.ZERO;
BigDecimal totalAmountOwed = BigDecimal.ZERO;
@@ -230,7 +266,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
* Removes all matching items from both submitted collections
*/
void removeDuplicatedInvoiceItems(final List<InvoiceItem> proposedItems,
- final List<InvoiceItem> existingInvoiceItems) {
+ final List<InvoiceItem> existingInvoiceItems) {
// We can't just use sets here as order matters (we want to keep duplicated in existingInvoiceItems)
final Iterator<InvoiceItem> proposedItemIterator = proposedItems.iterator();
while (proposedItemIterator.hasNext()) {
@@ -269,7 +305,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
}
private List<InvoiceItem> generateInvoiceItems(final UUID invoiceId, final UUID accountId, final BillingEventSet events,
- final LocalDate targetDate, final DateTimeZone accountTimeZone, final Currency currency) throws InvoiceApiException {
+ final LocalDate targetDate, final DateTimeZone accountTimeZone, final Currency currency) throws InvoiceApiException {
final List<InvoiceItem> items = new ArrayList<InvoiceItem>();
if (events.size() == 0) {
@@ -307,7 +343,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
// Turn a set of events into a list of invoice items. Note that the dates on the invoice items will be rounded (granularity of a day)
private List<InvoiceItem> processEvents(final UUID invoiceId, final UUID accountId, final BillingEvent thisEvent, @Nullable final BillingEvent nextEvent,
- final LocalDate targetDate, final DateTimeZone accountTimeZone, final Currency currency) throws InvoiceApiException {
+ final LocalDate targetDate, final DateTimeZone accountTimeZone, final Currency currency) throws InvoiceApiException {
final List<InvoiceItem> items = new ArrayList<InvoiceItem>();
// Handle fixed price items
@@ -341,13 +377,13 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
final BigDecimal amount = itemDatum.getNumberOfCycles().multiply(rate).setScale(NUMBER_OF_DECIMALS, ROUNDING_MODE);
final RecurringInvoiceItem recurringItem = new RecurringInvoiceItem(invoiceId,
- accountId,
- thisEvent.getSubscription().getBundleId(),
- thisEvent.getSubscription().getId(),
- thisEvent.getPlan().getName(),
- thisEvent.getPlanPhase().getName(),
- itemDatum.getStartDate(), itemDatum.getEndDate(),
- amount, rate, currency);
+ accountId,
+ thisEvent.getSubscription().getBundleId(),
+ thisEvent.getSubscription().getId(),
+ thisEvent.getPlan().getName(),
+ thisEvent.getPlanPhase().getName(),
+ itemDatum.getStartDate(), itemDatum.getEndDate(),
+ amount, rate, currency);
items.add(recurringItem);
}
}
@@ -360,15 +396,15 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
private BillingMode instantiateBillingMode(final BillingModeType billingMode) {
switch (billingMode) {
- case IN_ADVANCE:
- return new InAdvanceBillingMode();
- default:
- throw new UnsupportedOperationException();
+ case IN_ADVANCE:
+ return new InAdvanceBillingMode();
+ default:
+ throw new UnsupportedOperationException();
}
}
InvoiceItem generateFixedPriceItem(final UUID invoiceId, final UUID accountId, final BillingEvent thisEvent,
- final LocalDate targetDate, final Currency currency) {
+ final LocalDate targetDate, final Currency currency) {
final LocalDate roundedStartDate = new LocalDate(thisEvent.getEffectiveDate(), thisEvent.getTimeZone());
if (roundedStartDate.isAfter(targetDate)) {
@@ -378,9 +414,9 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
if (fixedPrice != null) {
return new FixedPriceInvoiceItem(invoiceId, accountId, thisEvent.getSubscription().getBundleId(),
- thisEvent.getSubscription().getId(),
- thisEvent.getPlan().getName(), thisEvent.getPlanPhase().getName(),
- roundedStartDate, fixedPrice, currency);
+ thisEvent.getSubscription().getId(),
+ thisEvent.getPlan().getName(), thisEvent.getPlanPhase().getName(),
+ roundedStartDate, fixedPrice, currency);
} else {
return null;
}
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java b/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java
index 007f2f6..bb65134 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java
@@ -32,11 +32,7 @@ import org.testng.annotations.Test;
import com.ning.billing.account.api.Account;
import com.ning.billing.catalog.api.Currency;
import com.ning.billing.invoice.api.Invoice;
-import com.ning.billing.invoice.api.InvoiceMigrationApi;
-import com.ning.billing.invoice.api.InvoicePaymentApi;
-import com.ning.billing.invoice.api.InvoiceUserApi;
-
-import com.google.inject.Inject;
+import com.ning.billing.invoice.api.InvoiceApiException;
public class TestDefaultInvoiceMigrationApi extends InvoiceApiTestBase {
@@ -63,7 +59,7 @@ public class TestDefaultInvoiceMigrationApi extends InvoiceApiTestBase {
regularInvoiceId = generateRegularInvoice(account, date_regular);
}
- private UUID createAndCheckMigrationInvoice(final UUID accountId) {
+ private UUID createAndCheckMigrationInvoice(final UUID accountId) throws InvoiceApiException {
final UUID migrationInvoiceId = migrationApi.createMigrationInvoice(accountId, date_migrated, MIGRATION_INVOICE_AMOUNT, MIGRATION_INVOICE_CURRENCY);
Assert.assertNotNull(migrationInvoiceId);
//Double check it was created and values are correct
@@ -108,7 +104,7 @@ public class TestDefaultInvoiceMigrationApi extends InvoiceApiTestBase {
// ACCOUNT balance should reflect total of migration and non-migration invoices
@Test(groups = "slow")
- public void testBalance() {
+ public void testBalance() throws InvoiceApiException{
final Invoice migrationInvoice = invoiceDao.getById(migrationInvoiceId);
final Invoice regularInvoice = invoiceDao.getById(regularInvoiceId);
final BigDecimal balanceOfAllInvoices = migrationInvoice.getBalance().add(regularInvoice.getBalance());
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/user/TestDefaultInvoiceUserApi.java b/invoice/src/test/java/com/ning/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
index 39ee3ec..c245e29 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
@@ -78,7 +78,7 @@ public class TestDefaultInvoiceUserApi extends InvoiceApiTestBase {
}
private void verifyExternalChargeOnNewInvoice(final BigDecimal initialAccountBalance, @Nullable final UUID bundleId,
- final BigDecimal externalChargeAmount, final InvoiceItem externalChargeInvoiceItem) {
+ final BigDecimal externalChargeAmount, final InvoiceItem externalChargeInvoiceItem) throws InvoiceApiException {
Assert.assertNotNull(externalChargeInvoiceItem.getInvoiceId());
Assert.assertNotEquals(externalChargeInvoiceItem.getInvoiceId(), invoiceId);
Assert.assertEquals(externalChargeInvoiceItem.getBundleId(), bundleId);
@@ -135,7 +135,7 @@ public class TestDefaultInvoiceUserApi extends InvoiceApiTestBase {
}
private void verifyExternalChargeOnExistingInvoice(final BigDecimal initialInvoiceBalance, @Nullable final UUID bundleId,
- final BigDecimal externalChargeAmount, final InvoiceItem externalChargeInvoiceItem) {
+ final BigDecimal externalChargeAmount, final InvoiceItem externalChargeInvoiceItem) throws InvoiceApiException {
Assert.assertEquals(externalChargeInvoiceItem.getInvoiceId(), invoiceId);
Assert.assertEquals(externalChargeInvoiceItem.getBundleId(), bundleId);
Assert.assertEquals(externalChargeInvoiceItem.getInvoiceItemType(), InvoiceItemType.EXTERNAL_CHARGE);
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/TestDefaultInvoiceDao.java b/invoice/src/test/java/com/ning/billing/invoice/dao/TestDefaultInvoiceDao.java
index ab3b14d..0427972 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/TestDefaultInvoiceDao.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/TestDefaultInvoiceDao.java
@@ -29,6 +29,7 @@ import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import com.google.common.collect.ImmutableMap;
import com.ning.billing.ErrorCode;
import com.ning.billing.invoice.InvoiceTestSuite;
import com.ning.billing.invoice.api.Invoice;
@@ -48,8 +49,6 @@ import com.ning.billing.util.tag.dao.MockTagDefinitionDao;
import com.ning.billing.util.tag.dao.TagDao;
import com.ning.billing.util.tag.dao.TagDefinitionDao;
-import com.google.common.collect.ImmutableMap;
-
public class TestDefaultInvoiceDao extends InvoiceTestSuite {
private InvoiceSqlDao invoiceSqlDao;
@@ -63,6 +62,7 @@ public class TestDefaultInvoiceDao extends InvoiceTestSuite {
Mockito.when(idbi.onDemand(InvoiceSqlDao.class)).thenReturn(invoiceSqlDao);
Mockito.when(invoiceSqlDao.getById(Mockito.anyString())).thenReturn(Mockito.mock(Invoice.class));
Mockito.when(invoiceSqlDao.inTransaction(Mockito.<Transaction<Void, InvoiceSqlDao>>any())).thenAnswer(new Answer() {
+ @Override
public Object answer(final InvocationOnMock invocation) {
final Object[] args = invocation.getArguments();
try {
@@ -125,7 +125,11 @@ public class TestDefaultInvoiceDao extends InvoiceTestSuite {
Mockito.when(invoiceSqlDao.getByRecordId(number.longValue())).thenReturn(invoice);
Assert.assertEquals(dao.getByNumber(number), invoice);
- Assert.assertNull(dao.getByNumber(Integer.MIN_VALUE));
+ try {
+ dao.getByNumber(Integer.MIN_VALUE);
+ Assert.fail();
+ } catch (InvoiceApiException e) {
+ }
}
@Test(groups = "fast")
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java b/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java
index 55a2e61..f7ba009 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java
@@ -16,9 +16,15 @@
package com.ning.billing.invoice.dao;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -27,8 +33,11 @@ import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
import org.mockito.Mockito;
+import org.testng.Assert;
import org.testng.annotations.Test;
+import com.google.common.collect.ImmutableMap;
+import com.ning.billing.ErrorCode;
import com.ning.billing.catalog.DefaultPrice;
import com.ning.billing.catalog.MockInternationalPrice;
import com.ning.billing.catalog.MockPlan;
@@ -59,19 +68,13 @@ import com.ning.billing.invoice.model.RecurringInvoiceItem;
import com.ning.billing.invoice.model.RepairAdjInvoiceItem;
import com.ning.billing.junction.api.BillingEventSet;
import com.ning.billing.util.api.TagApiException;
+import com.ning.billing.util.clock.ClockMock;
import com.ning.billing.util.dao.ObjectType;
import com.ning.billing.util.tag.ControlTagType;
import com.ning.billing.util.tag.Tag;
import com.ning.billing.util.tag.dao.AuditedTagDao;
import com.ning.billing.util.tag.dao.TagDao;
-import com.google.common.collect.ImmutableMap;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-
public class TestInvoiceDao extends InvoiceDaoTestBase {
@Test(groups = "slow")
@@ -94,7 +97,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
}
@Test(groups = "slow")
- public void testInvoicePayment() {
+ public void testInvoicePayment() throws InvoiceApiException {
final UUID accountId = UUID.randomUUID();
final Invoice invoice = new DefaultInvoice(accountId, clock.getUTCToday(), clock.getUTCToday(), Currency.USD);
final UUID invoiceId = invoice.getId();
@@ -103,7 +106,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
final LocalDate startDate = new LocalDate(2010, 1, 1);
final LocalDate endDate = new LocalDate(2010, 4, 1);
final InvoiceItem invoiceItem = new RecurringInvoiceItem(invoiceId, accountId, bundleId, subscriptionId, "test plan", "test phase", startDate, endDate,
- new BigDecimal("21.00"), new BigDecimal("7.00"), Currency.USD);
+ new BigDecimal("21.00"), new BigDecimal("7.00"), Currency.USD);
invoice.addInvoiceItem(invoiceItem);
invoiceDao.create(invoice, invoice.getTargetDate().getDayOfMonth(), true, context);
@@ -128,9 +131,15 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
}
@Test(groups = "slow")
- public void testRetrievalForNonExistentInvoiceId() {
- final Invoice invoice = invoiceDao.getById(UUID.randomUUID());
- assertNull(invoice);
+ public void testRetrievalForNonExistentInvoiceId() throws InvoiceApiException {
+ try {
+ invoiceDao.getById(UUID.randomUUID());
+ Assert.fail();
+ } catch (InvoiceApiException e) {
+ if (e.getCode() != ErrorCode.INVOICE_NOT_FOUND.getCode()) {
+ Assert.fail();
+ }
+ }
}
@Test(groups = "slow")
@@ -159,19 +168,19 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
LocalDate endDate = startDate.plusMonths(1);
final RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId1, "test plan", "test A", startDate, endDate,
- rate1, rate1, Currency.USD);
+ rate1, rate1, Currency.USD);
invoiceItemSqlDao.create(item1, context);
final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId2, "test plan", "test B", startDate, endDate,
- rate2, rate2, Currency.USD);
+ rate2, rate2, Currency.USD);
invoiceItemSqlDao.create(item2, context);
final RecurringInvoiceItem item3 = new RecurringInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId3, "test plan", "test C", startDate, endDate,
- rate3, rate3, Currency.USD);
+ rate3, rate3, Currency.USD);
invoiceItemSqlDao.create(item3, context);
final RecurringInvoiceItem item4 = new RecurringInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId4, "test plan", "test D", startDate, endDate,
- rate4, rate4, Currency.USD);
+ rate4, rate4, Currency.USD);
invoiceItemSqlDao.create(item4, context);
// Create invoice 2 (subscriptions 1-3)
@@ -184,15 +193,15 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
endDate = startDate.plusMonths(1);
final RecurringInvoiceItem item5 = new RecurringInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId1, "test plan", "test phase A", startDate, endDate,
- rate1, rate1, Currency.USD);
+ rate1, rate1, Currency.USD);
invoiceItemSqlDao.create(item5, context);
final RecurringInvoiceItem item6 = new RecurringInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId2, "test plan", "test phase B", startDate, endDate,
- rate2, rate2, Currency.USD);
+ rate2, rate2, Currency.USD);
invoiceItemSqlDao.create(item6, context);
final RecurringInvoiceItem item7 = new RecurringInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId3, "test plan", "test phase C", startDate, endDate,
- rate3, rate3, Currency.USD);
+ rate3, rate3, Currency.USD);
invoiceItemSqlDao.create(item7, context);
// Check that each subscription returns the correct number of invoices
@@ -235,19 +244,19 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
LocalDate endDate = startDate.plusMonths(1);
final FixedPriceInvoiceItem item1 = new FixedPriceInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId1, "test plan", "test A", startDate,
- rate1, Currency.USD);
+ rate1, Currency.USD);
invoiceItemSqlDao.create(item1, context);
final FixedPriceInvoiceItem item2 = new FixedPriceInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId2, "test plan", "test B", startDate,
- rate2, Currency.USD);
+ rate2, Currency.USD);
invoiceItemSqlDao.create(item2, context);
final FixedPriceInvoiceItem item3 = new FixedPriceInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId3, "test plan", "test C", startDate,
- rate3, Currency.USD);
+ rate3, Currency.USD);
invoiceItemSqlDao.create(item3, context);
final FixedPriceInvoiceItem item4 = new FixedPriceInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId4, "test plan", "test D", startDate,
- rate4, Currency.USD);
+ rate4, Currency.USD);
invoiceItemSqlDao.create(item4, context);
// create invoice 2 (subscriptions 1-3)
@@ -260,15 +269,15 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
endDate = startDate.plusMonths(1);
final FixedPriceInvoiceItem item5 = new FixedPriceInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId1, "test plan", "test phase A", startDate,
- rate1, Currency.USD);
+ rate1, Currency.USD);
invoiceItemSqlDao.create(item5, context);
final FixedPriceInvoiceItem item6 = new FixedPriceInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId2, "test plan", "test phase B", startDate,
- rate2, Currency.USD);
+ rate2, Currency.USD);
invoiceItemSqlDao.create(item6, context);
final FixedPriceInvoiceItem item7 = new FixedPriceInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId3, "test plan", "test phase C", startDate,
- rate3, Currency.USD);
+ rate3, Currency.USD);
invoiceItemSqlDao.create(item7, context);
// check that each subscription returns the correct number of invoices
@@ -311,35 +320,35 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
LocalDate endDate = startDate.plusMonths(1);
final RecurringInvoiceItem recurringItem1 = new RecurringInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId1, "test plan", "test A", startDate, endDate,
- rate1, rate1, Currency.USD);
+ rate1, rate1, Currency.USD);
invoiceItemSqlDao.create(recurringItem1, context);
final RecurringInvoiceItem recurringItem2 = new RecurringInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId2, "test plan", "test B", startDate, endDate,
- rate2, rate2, Currency.USD);
+ rate2, rate2, Currency.USD);
invoiceItemSqlDao.create(recurringItem2, context);
final RecurringInvoiceItem recurringItem3 = new RecurringInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId3, "test plan", "test C", startDate, endDate,
- rate3, rate3, Currency.USD);
+ rate3, rate3, Currency.USD);
invoiceItemSqlDao.create(recurringItem3, context);
final RecurringInvoiceItem recurringItem4 = new RecurringInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId4, "test plan", "test D", startDate, endDate,
- rate4, rate4, Currency.USD);
+ rate4, rate4, Currency.USD);
invoiceItemSqlDao.create(recurringItem4, context);
final FixedPriceInvoiceItem fixedItem1 = new FixedPriceInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId1, "test plan", "test A", startDate,
- rate1, Currency.USD);
+ rate1, Currency.USD);
invoiceItemSqlDao.create(fixedItem1, context);
final FixedPriceInvoiceItem fixedItem2 = new FixedPriceInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId2, "test plan", "test B", startDate,
- rate2, Currency.USD);
+ rate2, Currency.USD);
invoiceItemSqlDao.create(fixedItem2, context);
final FixedPriceInvoiceItem fixedItem3 = new FixedPriceInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId3, "test plan", "test C", startDate,
- rate3, Currency.USD);
+ rate3, Currency.USD);
invoiceItemSqlDao.create(fixedItem3, context);
final FixedPriceInvoiceItem fixedItem4 = new FixedPriceInvoiceItem(invoiceId1, accountId, bundleId, subscriptionId4, "test plan", "test D", startDate,
- rate4, Currency.USD);
+ rate4, Currency.USD);
invoiceItemSqlDao.create(fixedItem4, context);
// create invoice 2 (subscriptions 1-3)
@@ -352,26 +361,26 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
endDate = startDate.plusMonths(1);
final RecurringInvoiceItem recurringItem5 = new RecurringInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId1, "test plan", "test phase A", startDate, endDate,
- rate1, rate1, Currency.USD);
+ rate1, rate1, Currency.USD);
invoiceItemSqlDao.create(recurringItem5, context);
final RecurringInvoiceItem recurringItem6 = new RecurringInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId2, "test plan", "test phase B", startDate, endDate,
- rate2, rate2, Currency.USD);
+ rate2, rate2, Currency.USD);
invoiceItemSqlDao.create(recurringItem6, context);
final RecurringInvoiceItem recurringItem7 = new RecurringInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId3, "test plan", "test phase C", startDate, endDate,
- rate3, rate3, Currency.USD);
+ rate3, rate3, Currency.USD);
invoiceItemSqlDao.create(recurringItem7, context);
final FixedPriceInvoiceItem fixedItem5 = new FixedPriceInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId1, "test plan", "test phase A", startDate,
- rate1, Currency.USD);
+ rate1, Currency.USD);
invoiceItemSqlDao.create(fixedItem5, context);
final FixedPriceInvoiceItem fixedItem6 = new FixedPriceInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId2, "test plan", "test phase B", startDate,
- rate2, Currency.USD);
+ rate2, Currency.USD);
invoiceItemSqlDao.create(fixedItem6, context);
final FixedPriceInvoiceItem fixedItem7 = new FixedPriceInvoiceItem(invoiceId2, accountId, bundleId, subscriptionId3, "test plan", "test phase C", startDate,
- rate3, Currency.USD);
+ rate3, Currency.USD);
invoiceItemSqlDao.create(fixedItem7, context);
// check that each subscription returns the correct number of invoices
@@ -431,11 +440,11 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
final BigDecimal rate2 = new BigDecimal("42.0");
final RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase A", startDate,
- endDate, rate1, rate1, Currency.USD);
+ endDate, rate1, rate1, Currency.USD);
invoiceItemSqlDao.create(item1, context);
final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate,
- endDate, rate2, rate2, Currency.USD);
+ endDate, rate2, rate2, Currency.USD);
invoiceItemSqlDao.create(item2, context);
final BigDecimal payment1 = new BigDecimal("48.0");
@@ -460,7 +469,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
final BigDecimal rate1 = new BigDecimal("17.0");
final RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase A", startDate,
- endDate, rate1, rate1, Currency.USD);
+ endDate, rate1, rate1, Currency.USD);
invoiceItemSqlDao.create(item1, context);
final CreditAdjInvoiceItem creditItem = new CreditAdjInvoiceItem(invoice1.getId(), accountId, new LocalDate(), rate1.negate(), Currency.USD);
@@ -485,11 +494,11 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
final BigDecimal rate2 = new BigDecimal("42.0");
final RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase A", startDate, endDate,
- rate1, rate1, Currency.USD);
+ rate1, rate1, Currency.USD);
invoiceItemSqlDao.create(item1, context);
final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate, endDate,
- rate2, rate2, Currency.USD);
+ rate2, rate2, Currency.USD);
invoiceItemSqlDao.create(item2, context);
final BigDecimal balance = invoiceDao.getAccountBalance(accountId);
@@ -538,7 +547,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
// Recurring item
final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate,
- endDate, rate1, rate1, Currency.USD);
+ endDate, rate1, rate1, Currency.USD);
invoiceItemSqlDao.create(item2, context);
BigDecimal balance = invoiceDao.getAccountBalance(accountId);
assertEquals(balance.compareTo(new BigDecimal("20.00")), 0);
@@ -604,7 +613,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
// Fixed Item
final FixedPriceInvoiceItem item1 = new FixedPriceInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase A", startDate,
- amount1, Currency.USD);
+ amount1, Currency.USD);
invoiceItemSqlDao.create(item1, context);
BigDecimal balance = invoiceDao.getAccountBalance(accountId);
@@ -612,7 +621,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
// Recurring item
final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate,
- endDate, rate1, rate1, Currency.USD);
+ endDate, rate1, rate1, Currency.USD);
invoiceItemSqlDao.create(item2, context);
balance = invoiceDao.getAccountBalance(accountId);
assertEquals(balance.compareTo(new BigDecimal("25.00")), 0);
@@ -628,7 +637,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
// Repair previous item with rate 2
final RepairAdjInvoiceItem item2Repair = new RepairAdjInvoiceItem(invoice1.getId(), accountId, startDate, endDate, rate1.negate(), Currency.USD, item2.getId());
final RecurringInvoiceItem item2Replace = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate,
- endDate, rate2, rate2, Currency.USD);
+ endDate, rate2, rate2, Currency.USD);
invoiceItemSqlDao.create(item2Repair, context);
invoiceItemSqlDao.create(item2Replace, context);
balance = invoiceDao.getAccountBalance(accountId);
@@ -655,6 +664,33 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
}
@Test(groups = "slow")
+ public void testExternalChargeWithCBA() throws InvoiceApiException {
+
+ final UUID accountId = UUID.randomUUID();
+ final UUID bundleId = UUID.randomUUID();
+ final LocalDate targetDate1 = new LocalDate(2011, 10, 6);
+ final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate1, Currency.USD);
+ invoiceDao.create(invoice1, invoice1.getTargetDate().getDayOfMonth(), true, context);
+
+ // CREATE INVOICE WITH A (just) CBA. Should not happen, but that does not matter for that test
+ final CreditBalanceAdjInvoiceItem cbaItem = new CreditBalanceAdjInvoiceItem(invoice1.getId(), accountId, new LocalDate(), new BigDecimal("20.0"), Currency.USD);
+ invoiceItemSqlDao.create(cbaItem, context);
+
+ final InvoiceItem charge = invoiceDao.insertExternalCharge(accountId, null, bundleId, "bla", new BigDecimal("15.0"), clock.getUTCNow().toLocalDate(), Currency.USD, context);
+
+ final Invoice newInvoice = invoiceDao.getById(charge.getInvoiceId());
+ List<InvoiceItem> items = newInvoice.getInvoiceItems();
+ assertEquals(items.size(), 2);
+ for (InvoiceItem cur : items) {
+ if (!cur.getId().equals(charge.getId())) {
+ assertEquals(cur.getInvoiceItemType(), InvoiceItemType.CBA_ADJ);
+ assertTrue(cur.getAmount().compareTo(new BigDecimal("-15.00")) == 0);
+ break;
+ }
+ }
+ }
+
+ @Test(groups = "slow")
public void testAccountBalanceWithAllSortsOfThings() {
final UUID accountId = UUID.randomUUID();
final UUID bundleId = UUID.randomUUID();
@@ -671,7 +707,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
// Fixed Item
final FixedPriceInvoiceItem item1 = new FixedPriceInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase A", startDate,
- amount1, Currency.USD);
+ amount1, Currency.USD);
invoiceItemSqlDao.create(item1, context);
BigDecimal balance = invoiceDao.getAccountBalance(accountId);
@@ -679,7 +715,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
// Recurring item
final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate,
- endDate, rate1, rate1, Currency.USD);
+ endDate, rate1, rate1, Currency.USD);
invoiceItemSqlDao.create(item2, context);
balance = invoiceDao.getAccountBalance(accountId);
assertEquals(balance.compareTo(new BigDecimal("25.00")), 0);
@@ -694,7 +730,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
// Repair previous item with rate 2
final RepairAdjInvoiceItem item2Repair = new RepairAdjInvoiceItem(invoice1.getId(), accountId, startDate, endDate, rate1.negate(), Currency.USD, item2.getId());
final RecurringInvoiceItem item2Replace = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate,
- endDate, rate2, rate2, Currency.USD);
+ endDate, rate2, rate2, Currency.USD);
invoiceItemSqlDao.create(item2Repair, context);
invoiceItemSqlDao.create(item2Replace, context);
balance = invoiceDao.getAccountBalance(accountId);
@@ -725,7 +761,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, context);
final RecurringInvoiceItem nextItem = new RecurringInvoiceItem(invoice2.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test bla", startDate.plusMonths(1),
- endDate.plusMonths(1), rate2, rate2, Currency.USD);
+ endDate.plusMonths(1), rate2, rate2, Currency.USD);
invoiceItemSqlDao.create(nextItem, context);
balance = invoiceDao.getAccountBalance(accountId);
assertEquals(balance.compareTo(new BigDecimal("10.00")), 0);
@@ -818,7 +854,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
// Fixed Item
final FixedPriceInvoiceItem item1 = new FixedPriceInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase A", startDate,
- amount1, Currency.USD);
+ amount1, Currency.USD);
invoiceItemSqlDao.create(item1, context);
// Create the credit item
@@ -862,11 +898,11 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
final BigDecimal rate2 = new BigDecimal("42.0");
final RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase A", startDate, endDate,
- rate1, rate1, Currency.USD);
+ rate1, rate1, Currency.USD);
invoiceItemSqlDao.create(item1, context);
final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate, endDate,
- rate2, rate2, Currency.USD);
+ rate2, rate2, Currency.USD);
invoiceItemSqlDao.create(item2, context);
LocalDate upToDate;
@@ -890,7 +926,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
final BigDecimal rate3 = new BigDecimal("21.0");
final RecurringInvoiceItem item3 = new RecurringInvoiceItem(invoice2.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase C", startDate2, endDate2,
- rate3, rate3, Currency.USD);
+ rate3, rate3, Currency.USD);
invoiceItemSqlDao.create(item3, context);
upToDate = new LocalDate(2011, 1, 1);
@@ -924,8 +960,8 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
final DateTime effectiveDate1 = new DateTime(2011, 2, 1, 0, 0, 0);
final BillingEvent event1 = createMockBillingEvent(null, subscription, effectiveDate1, plan1, phase1, null,
- recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
- "testEvent1", 1L, SubscriptionTransitionType.CREATE);
+ recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+ "testEvent1", 1L, SubscriptionTransitionType.CREATE);
final BillingEventSet events = new MockBillingEventSet();
events.add(event1);
@@ -942,8 +978,8 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
final DateTime effectiveDate2 = new DateTime(2011, 2, 15, 0, 0, 0);
final BillingEvent event2 = createMockBillingEvent(null, subscription, effectiveDate2, plan2, phase2, null,
- recurringPrice2.getPrice(currency), currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
- "testEvent2", 2L, SubscriptionTransitionType.CREATE);
+ recurringPrice2.getPrice(currency), currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+ "testEvent2", 2L, SubscriptionTransitionType.CREATE);
events.add(event2);
// second invoice should be for one half (14/28 days) the difference between the rate plans
@@ -974,8 +1010,8 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
final DateTime effectiveDate = buildDate(2011, 1, 1).toDateTimeAtStartOfDay();
final BillingEvent event = createMockBillingEvent(null, subscription, effectiveDate, plan, phase, null,
- recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 15, BillingModeType.IN_ADVANCE,
- "testEvent", 1L, SubscriptionTransitionType.CREATE);
+ recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 15, BillingModeType.IN_ADVANCE,
+ "testEvent", 1L, SubscriptionTransitionType.CREATE);
final BillingEventSet events = new MockBillingEventSet();
events.add(event);
@@ -1013,8 +1049,8 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
final DateTime effectiveDate1 = buildDate(2011, 1, 1).toDateTimeAtStartOfDay();
final BillingEvent event1 = createMockBillingEvent(null, subscription, effectiveDate1, plan, phase1, fixedPrice.getPrice(currency),
- null, currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
- "testEvent1", 1L, SubscriptionTransitionType.CREATE);
+ null, currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+ "testEvent1", 1L, SubscriptionTransitionType.CREATE);
final BillingEventSet events = new MockBillingEventSet();
events.add(event1);
@@ -1031,8 +1067,8 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
final DateTime effectiveDate2 = effectiveDate1.plusDays(30);
final BillingEvent event2 = createMockBillingEvent(null, subscription, effectiveDate2, plan, phase2, null,
- recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
- "testEvent2", 2L, SubscriptionTransitionType.PHASE);
+ recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+ "testEvent2", 2L, SubscriptionTransitionType.PHASE);
events.add(event2);
final Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, new LocalDate(effectiveDate2), DateTimeZone.UTC, Currency.USD);
@@ -1078,16 +1114,16 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
final DateTime effectiveDate1 = buildDate(2011, 1, 1).toDateTimeAtStartOfDay();
final BillingEvent event1 = createMockBillingEvent(null, subscription, effectiveDate1, plan, phase1,
- fixedPrice.getPrice(currency), null, currency,
- BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
- "testEvent1", 1L, SubscriptionTransitionType.CREATE);
+ fixedPrice.getPrice(currency), null, currency,
+ BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+ "testEvent1", 1L, SubscriptionTransitionType.CREATE);
final BillingEventSet events = new MockBillingEventSet();
events.add(event1);
final DateTime effectiveDate2 = effectiveDate1.plusDays(30);
final BillingEvent event2 = createMockBillingEvent(null, subscription, effectiveDate2, plan, phase2, null,
- recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
- "testEvent2", 2L, SubscriptionTransitionType.CHANGE);
+ recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+ "testEvent2", 2L, SubscriptionTransitionType.CHANGE);
events.add(event2);
final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, new LocalDate(effectiveDate2), DateTimeZone.UTC, Currency.USD);
@@ -1103,6 +1139,81 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
assertEquals(savedInvoice.getBalance().compareTo(cheapAmount), 0);
}
+
+ @Test(groups = "slow")
+ public void testRefundedInvoiceWithInvoiceItemAdjustmentWithRepair() throws InvoiceApiException {
+
+ final UUID accountId = UUID.randomUUID();
+ final UUID subscriptionId = UUID.randomUUID();
+ final UUID bundleId = UUID.randomUUID();
+ final LocalDate startDate = new LocalDate(2010, 1, 1);
+
+ ((ClockMock) clock).setDay(startDate);
+
+ final LocalDate recuringStartDate = clock.getUTCNow().plusDays(30).toLocalDate();
+ final LocalDate recuringEndDate = clock.getUTCNow().plusDays(30).toLocalDate();
+ final LocalDate targetDate = recuringStartDate.plusDays(1);
+
+
+ // FIRST CREATE INITIAL INVOICE WITH ONE RECURRING ITEM
+ final Invoice invoice = new DefaultInvoice(accountId, targetDate, targetDate, Currency.USD);
+ final UUID invoiceId = invoice.getId();
+
+ final InvoiceItem invoiceItem = new RecurringInvoiceItem(invoiceId, accountId, bundleId, subscriptionId, "test-plan", "test-phase-rec",
+ recuringStartDate, recuringEndDate, new BigDecimal("239.00"), new BigDecimal("239.00"), Currency.USD);
+
+
+ invoice.addInvoiceItem(invoiceItem);
+ invoiceDao.create(invoice, invoice.getTargetDate().getDayOfMonth(), true, context);
+
+
+ ((ClockMock) clock).addDays(1);
+
+ // SECOND CREATE THE PAYMENT
+ final BigDecimal paymentAmount = new BigDecimal("239.00");
+ final UUID paymentId = UUID.randomUUID();
+ invoiceDao.notifyOfPayment(new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentId, invoiceId, clock.getUTCNow(), paymentAmount, Currency.USD), context);
+
+ // AND THEN THIRD THE REFUND
+ Map<UUID, BigDecimal> invoiceItemMap = new HashMap<UUID, BigDecimal>();
+ invoiceItemMap.put(invoiceItem.getId(), new BigDecimal("239.00"));
+ invoiceDao.createRefund(paymentId, paymentAmount, true, invoiceItemMap, UUID.randomUUID(), context);
+
+ final Invoice savedInvoice = invoiceDao.getById(invoiceId);
+ assertNotNull(savedInvoice);
+ assertEquals(savedInvoice.getInvoiceItems().size(), 2);
+
+ final List<Invoice> invoices = new ArrayList<Invoice>();
+ invoices.add(savedInvoice);
+
+
+ // NOW COMPUTE A DIFFERENT ITEM TO TRIGGER REPAIR
+ final BillingEventSet events = new MockBillingEventSet();
+ final Subscription subscription = getZombieSubscription();
+
+ final Plan plan = Mockito.mock(Plan.class);
+ Mockito.when(plan.getName()).thenReturn("plan");
+
+ final PlanPhase phase1 = Mockito.mock(PlanPhase.class);
+ Mockito.when(phase1.getName()).thenReturn("plan-phase1");
+
+ final PlanPhase phase2 = Mockito.mock(PlanPhase.class);
+ Mockito.when(phase2.getName()).thenReturn("plan-phase2");
+
+ final BillingEvent event1 = createMockBillingEvent(null, subscription, recuringStartDate.toDateTimeAtStartOfDay(), plan, phase1, null,
+ TEN, Currency.USD,
+ BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+ "new-event", 1L, SubscriptionTransitionType.CREATE);
+ events.add(event1);
+ Invoice newInvoice = generator.generateInvoice(UUID.randomUUID(), events, invoices, targetDate, DateTimeZone.UTC, Currency.USD);
+ invoiceDao.create(newInvoice, newInvoice.getTargetDate().getDayOfMonth(), true, context);
+
+ // VERIFY THAT WE STILL HAVE ONLY 2 ITEMS, MENAING THERE WERE NO REPAIR AND NO CBA GENERATED
+ final Invoice firstInvoice = invoiceDao.getById(invoiceId);
+ assertNotNull(firstInvoice);
+ assertEquals(firstInvoice.getInvoiceItems().size(), 2);
+ }
+
@Test(groups = "slow")
public void testInvoiceNumber() throws InvoiceApiException {
final Currency currency = Currency.USD;
@@ -1124,9 +1235,9 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
final List<Invoice> invoices = new ArrayList<Invoice>();
final BillingEvent event1 = createMockBillingEvent(null, subscription, targetDate1, plan, phase1, null,
- TEN, currency,
- BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
- "testEvent1", 1L, SubscriptionTransitionType.CHANGE);
+ TEN, currency,
+ BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+ "testEvent1", 1L, SubscriptionTransitionType.CHANGE);
events.add(event1);
Invoice invoice1 = generator.generateInvoice(UUID.randomUUID(), events, invoices, new LocalDate(targetDate1), DateTimeZone.UTC, Currency.USD);
@@ -1136,9 +1247,9 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
assertNotNull(invoice1.getInvoiceNumber());
final BillingEvent event2 = createMockBillingEvent(null, subscription, targetDate1, plan, phase2, null,
- TWENTY, currency,
- BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
- "testEvent2", 2L, SubscriptionTransitionType.CHANGE);
+ TWENTY, currency,
+ BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+ "testEvent2", 2L, SubscriptionTransitionType.CHANGE);
events.add(event2);
Invoice invoice2 = generator.generateInvoice(UUID.randomUUID(), events, invoices, new LocalDate(targetDate2), DateTimeZone.UTC, Currency.USD);
invoiceDao.create(invoice2, invoice2.getTargetDate().getDayOfMonth(), true, context);
@@ -1161,9 +1272,9 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
// create pseudo-random invoice
final BillingEvent event1 = createMockBillingEvent(null, subscription, targetDate1, plan, phase1, null,
- TEN, currency,
- BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
- "testEvent1", 1L, SubscriptionTransitionType.CHANGE);
+ TEN, currency,
+ BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+ "testEvent1", 1L, SubscriptionTransitionType.CHANGE);
final BillingEventSet events = new MockBillingEventSet();
events.add(event1);
@@ -1192,9 +1303,9 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
// create pseudo-random invoice
final BillingEvent event1 = createMockBillingEvent(null, subscription, targetDate1, plan, phase1, null,
- TEN, currency,
- BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
- "testEvent1", 1L, SubscriptionTransitionType.CHANGE);
+ TEN, currency,
+ BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+ "testEvent1", 1L, SubscriptionTransitionType.CHANGE);
final BillingEventSet events = new MockBillingEventSet();
events.add(event1);
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDaoForItemAdjustment.java b/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDaoForItemAdjustment.java
index e76e890..1fac6f7 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDaoForItemAdjustment.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDaoForItemAdjustment.java
@@ -101,7 +101,7 @@ public class TestInvoiceDaoForItemAdjustment extends InvoiceDaoTestBase {
Assert.assertEquals(adjustedInvoiceItem.getAmount().compareTo(BigDecimal.TEN.negate()), 0);
}
- private InvoiceItem createAndCheckAdjustment(final Invoice invoice, final InvoiceItem invoiceItem, final BigDecimal amount) {
+ private InvoiceItem createAndCheckAdjustment(final Invoice invoice, final InvoiceItem invoiceItem, final BigDecimal amount) throws InvoiceApiException {
final LocalDate effectiveDate = new LocalDate(2010, 1, 1);
final InvoiceItem adjustedInvoiceItem = invoiceDao.insertInvoiceItemAdjustment(invoice.getAccountId(), invoice.getId(), invoiceItem.getId(),
effectiveDate, amount, null, context);
jaxrs/pom.xml 2(+1 -1)
diff --git a/jaxrs/pom.xml b/jaxrs/pom.xml
index acdb6d7..67a0511 100644
--- a/jaxrs/pom.xml
+++ b/jaxrs/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.30-SNAPSHOT</version>
+ <version>0.1.31-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-jaxrs</artifactId>
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
index 97eb58c..dbf22b2 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
@@ -144,7 +144,7 @@ public class InvoiceResource extends JaxRsResourceBase {
@QueryParam(QUERY_INVOICE_WITH_ITEMS) @DefaultValue("false") final boolean withItems) throws InvoiceApiException {
final Invoice invoice = invoiceApi.getInvoice(UUID.fromString(invoiceId));
if (invoice == null) {
- throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND);
+ throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND, invoiceId);
} else {
final InvoiceJsonSimple json = withItems ? new InvoiceJsonWithItems(invoice) : new InvoiceJsonSimple(invoice);
return Response.status(Status.OK).entity(json).build();
junction/pom.xml 2(+1 -1)
diff --git a/junction/pom.xml b/junction/pom.xml
index 1db0204..1b1d475 100644
--- a/junction/pom.xml
+++ b/junction/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.30-SNAPSHOT</version>
+ <version>0.1.31-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-junction</artifactId>
overdue/pom.xml 2(+1 -1)
diff --git a/overdue/pom.xml b/overdue/pom.xml
index 8c58169..c0336d2 100644
--- a/overdue/pom.xml
+++ b/overdue/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.30-SNAPSHOT</version>
+ <version>0.1.31-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-overdue</artifactId>
payment/pom.xml 2(+1 -1)
diff --git a/payment/pom.xml b/payment/pom.xml
index 52bc21b..96765f3 100644
--- a/payment/pom.xml
+++ b/payment/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.30-SNAPSHOT</version>
+ <version>0.1.31-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-payment</artifactId>
diff --git a/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java b/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
index 55b852f..241027b 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
@@ -15,24 +15,24 @@
*/
package com.ning.billing.payment.core;
-import javax.annotation.Nullable;
-import javax.inject.Inject;
+import static com.ning.billing.payment.glue.PaymentModule.PLUGIN_EXECUTOR_NAMED;
+
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeoutException;
+import javax.annotation.Nullable;
+import javax.inject.Inject;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.inject.name.Named;
@@ -42,6 +42,7 @@ import com.ning.billing.account.api.AccountApiException;
import com.ning.billing.account.api.AccountUserApi;
import com.ning.billing.config.PaymentConfig;
import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.invoice.api.InvoiceApiException;
import com.ning.billing.invoice.api.InvoicePaymentApi;
import com.ning.billing.payment.api.DefaultPayment;
import com.ning.billing.payment.api.DefaultPaymentErrorEvent;
@@ -53,7 +54,6 @@ import com.ning.billing.payment.api.PaymentStatus;
import com.ning.billing.payment.dao.PaymentAttemptModelDao;
import com.ning.billing.payment.dao.PaymentDao;
import com.ning.billing.payment.dao.PaymentModelDao;
-import com.ning.billing.payment.dao.PaymentSqlDao;
import com.ning.billing.payment.dao.RefundModelDao;
import com.ning.billing.payment.dispatcher.PluginDispatcher;
import com.ning.billing.payment.plugin.api.PaymentInfoPlugin;
@@ -63,7 +63,6 @@ import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
import com.ning.billing.payment.retry.AutoPayRetryService.AutoPayRetryServiceScheduler;
import com.ning.billing.payment.retry.FailedPaymentRetryService.FailedPaymentRetryServiceScheduler;
import com.ning.billing.payment.retry.PluginFailureRetryService.PluginFailureRetryServiceScheduler;
-import com.ning.billing.util.api.TagApiException;
import com.ning.billing.util.api.TagUserApi;
import com.ning.billing.util.bus.Bus;
import com.ning.billing.util.bus.BusEvent;
@@ -72,12 +71,7 @@ import com.ning.billing.util.callcontext.CallContextFactory;
import com.ning.billing.util.callcontext.CallOrigin;
import com.ning.billing.util.callcontext.UserType;
import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.dao.ObjectType;
import com.ning.billing.util.globallocker.GlobalLocker;
-import com.ning.billing.util.tag.ControlTagType;
-import com.ning.billing.util.tag.Tag;
-
-import static com.ning.billing.payment.glue.PaymentModule.PLUGIN_EXECUTOR_NAMED;
public class PaymentProcessor extends ProcessorBase {
@@ -237,21 +231,25 @@ public class PaymentProcessor extends ProcessorBase {
public Payment doOperation() throws PaymentApiException {
- final Invoice invoice = invoicePaymentApi.getInvoice(invoiceId);
+ try {
+ final Invoice invoice = invoicePaymentApi.getInvoice(invoiceId);
- if (invoice.isMigrationInvoice()) {
- log.error("Received invoice for payment that is a migration invoice - don't know how to handle those yet: {}", invoice);
- return null;
- }
+ if (invoice.isMigrationInvoice()) {
+ log.error("Received invoice for payment that is a migration invoice - don't know how to handle those yet: {}", invoice);
+ return null;
+ }
- final boolean isAccountAutoPayOff = isAccountAutoPayOff(account.getId());
- setUnsaneAccount_AUTO_PAY_OFFWithAccountLock(account.getId(), paymentMethodId, isAccountAutoPayOff, context, isInstantPayment);
+ final boolean isAccountAutoPayOff = isAccountAutoPayOff(account.getId());
+ setUnsaneAccount_AUTO_PAY_OFFWithAccountLock(account.getId(), paymentMethodId, isAccountAutoPayOff, context, isInstantPayment);
- final BigDecimal requestedAmount = getAndValidatePaymentAmount(invoice, inputAmount, isInstantPayment);
- if (!isInstantPayment && isAccountAutoPayOff) {
- return processNewPaymentForAutoPayOffWithAccountLocked(paymentMethodId, account, invoice, requestedAmount, context);
- } else {
- return processNewPaymentWithAccountLocked(paymentMethodId, plugin, account, invoice, requestedAmount, isInstantPayment, context);
+ final BigDecimal requestedAmount = getAndValidatePaymentAmount(invoice, inputAmount, isInstantPayment);
+ if (!isInstantPayment && isAccountAutoPayOff) {
+ return processNewPaymentForAutoPayOffWithAccountLocked(paymentMethodId, account, invoice, requestedAmount, context);
+ } else {
+ return processNewPaymentWithAccountLocked(paymentMethodId, plugin, account, invoice, requestedAmount, isInstantPayment, context);
+ }
+ } catch (InvoiceApiException e) {
+ throw new PaymentApiException(e);
}
}
}));
@@ -269,10 +267,6 @@ public class PaymentProcessor extends ProcessorBase {
}
}
-
-
-
-
private void setUnsaneAccount_AUTO_PAY_OFFWithAccountLock(final UUID accountId, final UUID paymentMethodId, final boolean isAccountAutoPayOff, final CallContext context, final boolean isInstantPayment)
throws PaymentApiException {
@@ -347,32 +341,34 @@ public class PaymentProcessor extends ProcessorBase {
@Override
public Void doOperation() throws PaymentApiException {
-
- // Fetch again with account lock this time
- final PaymentModelDao payment = paymentDao.getPayment(paymentId);
- boolean foundExpectedState = false;
- for (final PaymentStatus cur : expectedPaymentStates) {
- if (payment.getPaymentStatus() == cur) {
- foundExpectedState = true;
- break;
+ try {
+ // Fetch again with account lock this time
+ final PaymentModelDao payment = paymentDao.getPayment(paymentId);
+ boolean foundExpectedState = false;
+ for (final PaymentStatus cur : expectedPaymentStates) {
+ if (payment.getPaymentStatus() == cur) {
+ foundExpectedState = true;
+ break;
+ }
+ }
+ if (!foundExpectedState) {
+ log.info("Aborted retry for payment {} because it is {} state", paymentId, payment.getPaymentStatus());
+ return null;
}
- }
- if (!foundExpectedState) {
- log.info("Aborted retry for payment {} because it is {} state", paymentId, payment.getPaymentStatus());
- return null;
- }
- final Invoice invoice = invoicePaymentApi.getInvoice(payment.getInvoiceId());
- if (invoice.isMigrationInvoice()) {
- return null;
- }
- if (invoice.getBalance().compareTo(BigDecimal.ZERO) <= 0) {
- log.info("Aborted retry for payment {} because invoice has been paid", paymentId);
+ final Invoice invoice = invoicePaymentApi.getInvoice(payment.getInvoiceId());
+ if (invoice.isMigrationInvoice()) {
+ return null;
+ }
+ if (invoice.getBalance().compareTo(BigDecimal.ZERO) <= 0) {
+ log.info("Aborted retry for payment {} because invoice has been paid", paymentId);
+ return null;
+ }
+ processRetryPaymentWithAccountLocked(plugin, account, invoice, payment, invoice.getBalance(), context);
return null;
+ } catch (InvoiceApiException e) {
+ throw new PaymentApiException(e);
}
- processRetryPaymentWithAccountLocked(plugin, account, invoice, payment, invoice.getBalance(), context);
- return null;
-
}
}));
} catch (AccountApiException e) {
diff --git a/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java b/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java
index a254ff2..3184081 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java
@@ -16,6 +16,8 @@
package com.ning.billing.payment.core;
+import static com.ning.billing.payment.glue.PaymentModule.PLUGIN_EXECUTOR_NAMED;
+
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
@@ -31,6 +33,12 @@ import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableMap;
+import com.google.inject.name.Named;
import com.ning.billing.ErrorCode;
import com.ning.billing.account.api.Account;
import com.ning.billing.account.api.AccountApiException;
@@ -56,15 +64,6 @@ import com.ning.billing.util.callcontext.CallOrigin;
import com.ning.billing.util.callcontext.UserType;
import com.ning.billing.util.globallocker.GlobalLocker;
-import com.google.common.base.Function;
-import com.google.common.base.Objects;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableMap;
-import com.google.inject.name.Named;
-
-import static com.ning.billing.payment.glue.PaymentModule.PLUGIN_EXECUTOR_NAMED;
-
public class RefundProcessor extends ProcessorBase {
private static final Logger log = LoggerFactory.getLogger(RefundProcessor.class);
@@ -188,21 +187,26 @@ public class RefundProcessor extends ProcessorBase {
* @param invoiceItemIdsWithAmounts invoice item ids and associated amounts to adjust
* @return the refund amount
*/
- private BigDecimal computeRefundAmount(final UUID paymentId, @Nullable final BigDecimal specifiedRefundAmount, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts) {
- final List<InvoiceItem> items = invoicePaymentApi.getInvoiceForPaymentId(paymentId).getInvoiceItems();
+ private BigDecimal computeRefundAmount(final UUID paymentId, @Nullable final BigDecimal specifiedRefundAmount, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts)
+ throws PaymentApiException {
+ try {
+ final List<InvoiceItem> items = invoicePaymentApi.getInvoiceForPaymentId(paymentId).getInvoiceItems();
- BigDecimal amountFromItems = BigDecimal.ZERO;
- for (final UUID itemId : invoiceItemIdsWithAmounts.keySet()) {
- amountFromItems = amountFromItems.add(Objects.firstNonNull(invoiceItemIdsWithAmounts.get(itemId),
- getAmountFromItem(items, itemId)));
- }
+ BigDecimal amountFromItems = BigDecimal.ZERO;
+ for (final UUID itemId : invoiceItemIdsWithAmounts.keySet()) {
+ amountFromItems = amountFromItems.add(Objects.firstNonNull(invoiceItemIdsWithAmounts.get(itemId),
+ getAmountFromItem(items, itemId)));
+ }
- // Sanity check: if some items were specified, then the sum should be equal to specified refund amount, if specified
- if (amountFromItems.compareTo(BigDecimal.ZERO) != 0 && specifiedRefundAmount != null && specifiedRefundAmount.compareTo(amountFromItems) != 0) {
- throw new IllegalArgumentException("You can't specify a refund amount that doesn't match the invoice items amounts");
- }
+ // Sanity check: if some items were specified, then the sum should be equal to specified refund amount, if specified
+ if (amountFromItems.compareTo(BigDecimal.ZERO) != 0 && specifiedRefundAmount != null && specifiedRefundAmount.compareTo(amountFromItems) != 0) {
+ throw new IllegalArgumentException("You can't specify a refund amount that doesn't match the invoice items amounts");
+ }
- return Objects.firstNonNull(specifiedRefundAmount, amountFromItems);
+ return Objects.firstNonNull(specifiedRefundAmount, amountFromItems);
+ } catch (InvoiceApiException e) {
+ throw new PaymentApiException(e);
+ }
}
private BigDecimal getAmountFromItem(final List<InvoiceItem> items, final UUID itemId) {
diff --git a/payment/src/test/java/com/ning/billing/payment/TestHelper.java b/payment/src/test/java/com/ning/billing/payment/TestHelper.java
index ed4c905..568e45d 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestHelper.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestHelper.java
@@ -18,7 +18,6 @@ package com.ning.billing.payment;
import java.util.UUID;
-import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.mockito.Mockito;
@@ -27,6 +26,7 @@ import com.ning.billing.account.api.Account;
import com.ning.billing.account.api.AccountUserApi;
import com.ning.billing.catalog.api.Currency;
import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.invoice.api.InvoiceApiException;
import com.ning.billing.invoice.api.InvoiceCreationEvent;
import com.ning.billing.invoice.api.InvoiceItem;
import com.ning.billing.invoice.api.InvoicePaymentApi;
@@ -65,7 +65,7 @@ public class TestHelper {
public Invoice createTestInvoice(final Account account,
final LocalDate targetDate,
final Currency currency,
- final InvoiceItem... items) throws EventBusException {
+ final InvoiceItem... items) throws EventBusException, InvoiceApiException {
final Invoice invoice = new MockInvoice(account.getId(), clock.getUTCToday(), targetDate, currency);
for (final InvoiceItem item : items) {
pom.xml 14(+13 -1)
diff --git a/pom.xml b/pom.xml
index e4a5911..f10764c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,7 +17,7 @@
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
<packaging>pom</packaging>
- <version>0.1.30-SNAPSHOT</version>
+ <version>0.1.31-SNAPSHOT</version>
<name>killbill</name>
<description>Library for managing recurring subscriptions and the associated billing</description>
<url>http://github.com/ning/killbill</url>
@@ -625,6 +625,18 @@
</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.11</version>
+ <configuration>
+ <groups>fast</groups>
+ <systemPropertyVariables>
+ <file.encoding>UTF-8</file.encoding>
+ <user.timezone>GMT</user.timezone>
+ </systemPropertyVariables>
+ </configuration>
+ </plugin>
</plugins>
</build>
</profile>
server/pom.xml 2(+1 -1)
diff --git a/server/pom.xml b/server/pom.xml
index 06bce5a..fdc002c 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.30-SNAPSHOT</version>
+ <version>0.1.31-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-server</artifactId>
usage/pom.xml 2(+1 -1)
diff --git a/usage/pom.xml b/usage/pom.xml
index c69dae9..db9f947 100644
--- a/usage/pom.xml
+++ b/usage/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.30-SNAPSHOT</version>
+ <version>0.1.31-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-usage</artifactId>
util/pom.xml 2(+1 -1)
diff --git a/util/pom.xml b/util/pom.xml
index 79fba48..bf97252 100644
--- a/util/pom.xml
+++ b/util/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.30-SNAPSHOT</version>
+ <version>0.1.31-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-util</artifactId>