diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java
index beb7246..7b6b8da 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java
@@ -46,13 +46,16 @@ import org.killbill.billing.invoice.api.InvoiceItem;
import org.killbill.billing.invoice.api.InvoiceItemType;
import org.killbill.billing.invoice.api.InvoicePayment;
import org.killbill.billing.invoice.model.ExternalChargeInvoiceItem;
+import org.killbill.billing.overdue.config.DefaultOverdueConfig;
import org.killbill.billing.overdue.wrapper.OverdueWrapper;
import org.killbill.billing.payment.api.Payment;
import org.killbill.billing.payment.api.PluginProperty;
+import org.killbill.xmlloader.XMLLoader;
import org.testng.Assert;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
+import com.google.common.io.Resources;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
@@ -949,6 +952,151 @@ public class TestOverdueIntegration extends TestOverdueBase {
checkODState(OverdueWrapper.CLEAR_STATE_NAME);
}
+ @Test(groups = "slow", description = "Test overdue state with number of unpaid invoices condition")
+ public void testOverdueStateWithNumberOfUnpaidInvoicesCondition() throws Exception {
+ // 2012-05-01T00:03:42.000Z
+ clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
+
+ final DefaultOverdueConfig config = XMLLoader.getObjectFromString(Resources.getResource("overdueWithNumberOfUnpaidInvoicesCondition.xml").toExternalForm(), DefaultOverdueConfig.class);
+ overdueConfigCache.loadDefaultOverdueConfig(config);
+
+ setupAccount();
+
+ paymentPlugin.makeAllInvoicesFailWithError(true);
+
+ createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", productName, ProductCategory.BASE,
+ term, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
+
+ // 2012-05-31 => DAY 30 have to get out of trial before first payment
+ addMonthsAndCheckForCompletion(1, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
+ // Verify that number of unpaid invoices is 1
+ Assert.assertEquals(invoiceUserApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday(), callContext).size(), 1);
+ // Should still be in clear state
+ checkODState(OverdueWrapper.CLEAR_STATE_NAME);
+
+ // Add 1 month
+ addMonthsAndCheckForCompletion(1, NextEvent.INVOICE, NextEvent.BLOCK, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
+ // Verify that number of unpaid invoices is 2
+ Assert.assertEquals(invoiceUserApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday(), callContext).size(), 2);
+ // Now we should be in OD1
+ checkODState("OD1");
+
+ // Add 1 month
+ addMonthsAndCheckForCompletion(1, NextEvent.INVOICE, NextEvent.BLOCK, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR,
+ NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR,
+ NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
+ // Verify that number of unpaid invoices is 3
+ Assert.assertEquals(invoiceUserApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday(), callContext).size(), 3);
+ // Now we should be in OD2
+ checkODState("OD2");
+
+ // Add 1 month
+ addMonthsAndCheckForCompletion(1, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR,
+ NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR,
+ NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR,
+ NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
+ // Verify that number of unpaid invoices is 4
+ Assert.assertEquals(invoiceUserApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday(), callContext).size(), 4);
+ // We should still be in OD2
+ checkODState("OD2");
+
+ // Add 1 month
+ addMonthsAndCheckForCompletion(1, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR,
+ NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR,
+ NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR,
+ NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR,
+ NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR, NextEvent.TAG, NextEvent.BLOCK);
+ // Verify that number of unpaid invoices is 5
+ Assert.assertEquals(invoiceUserApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday(), callContext).size(), 5);
+ // Now we should be in OD3
+ checkODState("OD3");
+
+ // Get all unpaid invoices and pay them to clear the overdue state
+ paymentPlugin.makeAllInvoicesFailWithError(false);
+ List<Invoice> unpaidInvoices = getUnpaidInvoicesOrderFromRecent();
+ createPaymentAndCheckForCompletion(account, unpaidInvoices.get(0), NextEvent.BLOCK, NextEvent.TAG, NextEvent.NULL_INVOICE, NextEvent.NULL_INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
+ createPaymentAndCheckForCompletion(account, unpaidInvoices.get(1), NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
+ createPaymentAndCheckForCompletion(account, unpaidInvoices.get(2), NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT, NextEvent.BLOCK);
+ createPaymentAndCheckForCompletion(account, unpaidInvoices.get(3), NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT, NextEvent.BLOCK);
+ createPaymentAndCheckForCompletion(account, unpaidInvoices.get(4), NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
+
+ // We should be clear now
+ checkODState(OverdueWrapper.CLEAR_STATE_NAME);
+ }
+
+ @Test(groups = "slow", description = "Test overdue state with total unpaid invoice balance condition")
+ public void testOverdueStateWithTotalUnpaidInvoiceBalanceCondition() throws Exception {
+ // 2012-05-01T00:03:42.000Z
+ clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
+
+ final DefaultOverdueConfig config = XMLLoader.getObjectFromString(Resources.getResource("overdueWithTotalUnpaidInvoiceBalanceCondition.xml").toExternalForm(), DefaultOverdueConfig.class);
+ overdueConfigCache.loadDefaultOverdueConfig(config);
+
+ setupAccount();
+
+ paymentPlugin.makeAllInvoicesFailWithError(true);
+
+ createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", productName, ProductCategory.BASE,
+ term, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
+
+ // 2012-05-31 => DAY 30 have to get out of trial before first payment
+ addMonthsAndCheckForCompletion(1, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
+
+ // Amount balance should be USD 249.95
+ assertEquals(invoiceUserApi.getAccountBalance(account.getId(), callContext).compareTo(BigDecimal.valueOf(249.95)), 0);
+ // Should still be in clear state
+ checkODState(OverdueWrapper.CLEAR_STATE_NAME);
+
+ // Add 1 month
+ addMonthsAndCheckForCompletion(1, NextEvent.INVOICE, NextEvent.BLOCK, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
+ // Amount balance should be USD 499.90
+ assertEquals(invoiceUserApi.getAccountBalance(account.getId(), callContext).compareTo(BigDecimal.valueOf(499.90)), 0);
+ // Now we should be in OD1
+ checkODState("OD1");
+
+ // Add 1 month
+ addMonthsAndCheckForCompletion(1, NextEvent.INVOICE, NextEvent.BLOCK, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR,
+ NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR,
+ NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
+ // Amount balance should be USD 749.85
+ assertEquals(invoiceUserApi.getAccountBalance(account.getId(), callContext).compareTo(BigDecimal.valueOf(749.85)), 0);
+ // Now we should be in OD2
+ checkODState("OD2");
+
+ // Add 1 month
+ addMonthsAndCheckForCompletion(1, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR,
+ NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR,
+ NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR,
+ NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
+ // Amount balance should be USD 999.80
+ assertEquals(invoiceUserApi.getAccountBalance(account.getId(), callContext).compareTo(BigDecimal.valueOf(999.80)), 0);
+ // We should still be in OD2
+ checkODState("OD2");
+
+ // Add 1 month
+ addMonthsAndCheckForCompletion(1, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR,
+ NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR,
+ NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR,
+ NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR,
+ NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR, NextEvent.TAG, NextEvent.BLOCK);
+ // Amount balance should be USD 1249.75
+ assertEquals(invoiceUserApi.getAccountBalance(account.getId(), callContext).compareTo(BigDecimal.valueOf(1249.75)), 0);
+ // Now we should be in OD3
+ checkODState("OD3");
+
+ // Get all unpaid invoices and pay them to clear the overdue state
+ paymentPlugin.makeAllInvoicesFailWithError(false);
+ List<Invoice> unpaidInvoices = getUnpaidInvoicesOrderFromRecent();
+ createPaymentAndCheckForCompletion(account, unpaidInvoices.get(0), NextEvent.BLOCK, NextEvent.TAG, NextEvent.NULL_INVOICE, NextEvent.NULL_INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
+ createPaymentAndCheckForCompletion(account, unpaidInvoices.get(1), NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
+ createPaymentAndCheckForCompletion(account, unpaidInvoices.get(2), NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT, NextEvent.BLOCK);
+ createPaymentAndCheckForCompletion(account, unpaidInvoices.get(3), NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT, NextEvent.BLOCK);
+ createPaymentAndCheckForCompletion(account, unpaidInvoices.get(4), NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
+
+ // We should be clear now
+ checkODState(OverdueWrapper.CLEAR_STATE_NAME);
+ }
+
private void allowPaymentsAndResetOverdueToClearByPayingAllUnpaidInvoices(final boolean extraPayment) {
// Reset plugin so payments should now succeed
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestOverdue.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestOverdue.java
index f2f8f2c..6b13996 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestOverdue.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestOverdue.java
@@ -22,11 +22,11 @@ import java.math.BigDecimal;
import java.util.Comparator;
import java.util.List;
+import org.killbill.billing.client.KillBillClientException;
import org.killbill.billing.client.model.Account;
import org.killbill.billing.client.model.Invoice;
import org.killbill.billing.client.model.InvoicePayment;
import org.killbill.billing.client.model.Invoices;
-import org.killbill.billing.client.model.Payment;
import org.killbill.billing.client.model.Tags;
import org.killbill.billing.util.tag.ControlTagType;
import org.testng.Assert;
@@ -42,9 +42,9 @@ public class TestOverdue extends TestJaxrsBase {
@Test(groups = "slow", description = "Upload and retrieve a per tenant overdue config")
public void testMultiTenantOverdueConfig() throws Exception {
final String overdueConfigPath = Resources.getResource("overdue.xml").getPath();
- killBillClient.uploadXMLOverdueConfig(overdueConfigPath, createdBy, reason, comment);
+ killBillClient.uploadXMLOverdueConfig(overdueConfigPath, requestOptions);
- final String overdueConfig = killBillClient.getXMLOverdueConfig();
+ final String overdueConfig = killBillClient.getXMLOverdueConfig(requestOptions);
Assert.assertNotNull(overdueConfig);
}
@@ -54,29 +54,29 @@ public class TestOverdue extends TestJaxrsBase {
final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
// Get the invoices
- final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId());
+ final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions);
// 2 invoices but look for the non zero dollar one
assertEquals(invoices.size(), 2);
// We're still clear - see the configuration
- Assert.assertTrue(killBillClient.getOverdueStateForAccount(accountJson.getAccountId()).getIsClearState());
+ Assert.assertTrue(killBillClient.getOverdueStateForAccount(accountJson.getAccountId(), requestOptions).getIsClearState());
clock.addDays(30);
crappyWaitForLackOfProperSynchonization();
- Assert.assertEquals(killBillClient.getOverdueStateForAccount(accountJson.getAccountId()).getName(), "OD1");
+ Assert.assertEquals(killBillClient.getOverdueStateForAccount(accountJson.getAccountId(), requestOptions).getName(), "OD1");
clock.addDays(10);
crappyWaitForLackOfProperSynchonization();
- Assert.assertEquals(killBillClient.getOverdueStateForAccount(accountJson.getAccountId()).getName(), "OD2");
+ Assert.assertEquals(killBillClient.getOverdueStateForAccount(accountJson.getAccountId(), requestOptions).getName(), "OD2");
clock.addDays(10);
crappyWaitForLackOfProperSynchonization();
- Assert.assertEquals(killBillClient.getOverdueStateForAccount(accountJson.getAccountId()).getName(), "OD3");
+ Assert.assertEquals(killBillClient.getOverdueStateForAccount(accountJson.getAccountId(), requestOptions).getName(), "OD3");
// Post external payments, paying the most recent invoice first: this is to avoid a race condition where
// a refresh overdue notification kicks in after the first payment, which makes the account goes CLEAR and
// triggers an AUTO_INVOICE_OFF tag removal (hence adjustment of the other invoices balance).
- final Invoices invoicesForAccount = killBillClient.getInvoicesForAccount(accountJson.getAccountId());
+ final Invoices invoicesForAccount = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions);
final List<Invoice> mostRecentInvoiceFirst = Ordering.<Invoice>from(new Comparator<Invoice>() {
@Override
public int compare(final Invoice invoice1, final Invoice invoice2) {
@@ -90,7 +90,7 @@ public class TestOverdue extends TestJaxrsBase {
invoicePayment.setPurchasedAmount(invoice.getAmount());
invoicePayment.setAccountId(accountJson.getAccountId());
invoicePayment.setTargetInvoiceId(invoice.getInvoiceId());
- killBillClient.createInvoicePayment(invoicePayment, true, createdBy, reason, comment);
+ killBillClient.createInvoicePayment(invoicePayment, true, requestOptions);
}
}
@@ -98,7 +98,7 @@ public class TestOverdue extends TestJaxrsBase {
crappyWaitForLackOfProperSynchonization();
// Verify we're in clear state
- Assert.assertTrue(killBillClient.getOverdueStateForAccount(accountJson.getAccountId()).getIsClearState());
+ Assert.assertTrue(killBillClient.getOverdueStateForAccount(accountJson.getAccountId(), requestOptions).getIsClearState());
}
@Test(groups = "slow", description = "Allow overdue condition by control tag defined in overdue config xml file")