killbill-uncached
Changes
Details
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
index be1cbf9..c947853 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
@@ -187,6 +187,183 @@ public class TestOverdueIntegration extends TestOverdueBase {
assertEquals(invoiceUserApi.getAccountBalance(account.getId(), callContext).compareTo(new BigDecimal("-11.79")), 0);
}
+
+
+
+ // We set the the property killbill.payment.retry.days=8,8,8,8,8,8,8,8 so that Payment retry logic does not end with an ABORTED state
+ // preventing final instant payment to succeed.
+ @Test(groups = "slow")
+ public void testSingleRepareeOnOverdueState() throws Exception {
+ clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
+
+ // Set next invoice to fail and create subscription
+ paymentPlugin.makeAllInvoicesFailWithError(true);
+ final Subscription baseSubscription = createSubscriptionAndCheckForCompletion(bundle.getId(), productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.INVOICE);
+
+ invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
+ invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 5, 1), callContext);
+
+ // 2012, 5, 31 => DAY 30 have to get out of trial {I0, P0}
+ addDaysAndCheckForCompletion(30, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR);
+
+ invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
+ invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 6, 30), callContext);
+
+ // 2012, 6, 8 => Retry P0
+ addDaysAndCheckForCompletion(8, NextEvent.PAYMENT_ERROR);
+ checkODState(DefaultBlockingState.CLEAR_STATE_NAME);
+
+ // 2012, 6, 16 => Retry P0
+ addDaysAndCheckForCompletion(8, NextEvent.PAYMENT_ERROR);
+ checkODState(DefaultBlockingState.CLEAR_STATE_NAME);
+
+ // 2012, 6, 24 => Retry P0
+ addDaysAndCheckForCompletion(8, NextEvent.PAYMENT_ERROR);
+ checkODState(DefaultBlockingState.CLEAR_STATE_NAME);
+
+ // 2012, 6, 31 => P1 (We se 6/31 instead of 6/30 because invoice might happen later in that day)
+ addDaysAndCheckForCompletion(7, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR);
+ checkODState("OD1");
+ checkChangePlanWithOverdueState(baseSubscription, true);
+ invoiceChecker.checkInvoice(account.getId(), 3, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
+ invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 7, 31), callContext);
+
+ // 2012, 7, 2 => Retry P0
+ addDaysAndCheckForCompletion(1, NextEvent.PAYMENT_ERROR);
+ checkODState("OD1");
+
+ // 2012, 7, 9 => Retry P1
+ addDaysAndCheckForCompletion(7, NextEvent.PAYMENT_ERROR);
+ checkODState("OD1");
+
+ // 2012, 7, 10 => Retry P0
+ addDaysAndCheckForCompletion(1, NextEvent.PAYMENT_ERROR);
+ checkODState("OD2");
+
+ // 2012, 7, 17 => Retry P1
+ addDaysAndCheckForCompletion(7, NextEvent.PAYMENT_ERROR);
+ checkODState("OD2");
+
+ // 2012, 7, 18 => Retry P0
+ addDaysAndCheckForCompletion(1, NextEvent.PAYMENT_ERROR);
+ checkODState("OD2");
+
+ // 2012, 7, 23 => Should be 20 but notficationQ event occurs on 23...
+ addDaysAndCheckForCompletion(5);
+ checkODState("OD3");
+
+
+ paymentPlugin.makeAllInvoicesFailWithError(false);
+ final Collection<Invoice> invoices = invoiceUserApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday(), callContext);
+ for (final Invoice invoice : invoices) {
+ if (invoice.getBalance().compareTo(BigDecimal.ZERO) > 0) {
+ createPaymentAndCheckForCompletion(account, invoice, NextEvent.PAYMENT);
+ }
+ }
+ checkODState(DefaultBlockingState.CLEAR_STATE_NAME);
+
+
+ // Add 10 days to generate next invoice
+ addDaysAndCheckForCompletion(10, NextEvent.INVOICE, NextEvent.INVOICE_ADJUSTMENT, NextEvent.PAYMENT);
+
+ invoiceChecker.checkRepairedInvoice(account.getId(), 3,
+ callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 30), new LocalDate(2012, 7, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")),
+ // We paid up to 07-31, hence the adjustment
+ new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 10), new LocalDate(2012, 7, 23), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-102.13")),
+ new ExpectedInvoiceItemCheck(new LocalDate(2012, 8, 2), new LocalDate(2012, 8, 2), InvoiceItemType.CBA_ADJ, new BigDecimal("102.13")));
+
+ invoiceChecker.checkInvoice(account.getId(), 4, callContext,
+ // Item for the upgraded recurring plan
+ new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 31), new LocalDate(2012, 8, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")),
+ // Credits consumed
+ new ExpectedInvoiceItemCheck(new LocalDate(2012, 8, 2), new LocalDate(2012, 8, 2), InvoiceItemType.CBA_ADJ, new BigDecimal("-102.13")));
+ invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 8, 31), callContext);
+
+ // Verify the account balance: 249.95 - 74.99 - 154.85
+ assertEquals(invoiceUserApi.getAccountBalance(account.getId(), callContext).compareTo(BigDecimal.ZERO), 0);
+ }
+
+
+ // We set the the property killbill.payment.retry.days=8,8,8,8,8,8,8,8 so that Payment retry logic does not end with an ABORTED state
+ // preventing final instant payment to succeed.
+ @Test(groups = "slow")
+ public void testMultipleRepareeOnOverdueState() throws Exception {
+ clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
+
+ // Set next invoice to fail and create subscription
+ paymentPlugin.makeAllInvoicesFailWithError(true);
+ final Subscription baseSubscription = createSubscriptionAndCheckForCompletion(bundle.getId(), productName, ProductCategory.BASE, BillingPeriod.ANNUAL, NextEvent.CREATE, NextEvent.INVOICE);
+
+ invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
+ invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 5, 1), callContext);
+
+ // 2012, 5, 31 => DAY 30 have to get out of trial {I0, P0}
+ addDaysAndCheckForCompletion(30, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR);
+
+ invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2013, 5, 31), InvoiceItemType.RECURRING, new BigDecimal("2399.95")));
+ invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2013, 5, 31), callContext);
+
+ // 2012, 6, 8 => Retry P0
+ addDaysAndCheckForCompletion(8, NextEvent.PAYMENT_ERROR);
+ checkODState(DefaultBlockingState.CLEAR_STATE_NAME);
+
+ // 2012, 6, 16 => Retry P0
+ addDaysAndCheckForCompletion(8, NextEvent.PAYMENT_ERROR);
+ checkODState(DefaultBlockingState.CLEAR_STATE_NAME);
+
+ // 2012, 6, 24 => Retry P0
+ addDaysAndCheckForCompletion(8, NextEvent.PAYMENT_ERROR);
+ checkODState(DefaultBlockingState.CLEAR_STATE_NAME);
+
+ // 2012, 7, 2 => Retry P0
+ addDaysAndCheckForCompletion(8, NextEvent.PAYMENT_ERROR);
+ checkODState("OD1");
+
+ // 2012, 7, 10 => Retry P0
+ addDaysAndCheckForCompletion(8, NextEvent.PAYMENT_ERROR);
+ checkODState("OD2");
+
+ // 2012, 7, 18 => Retry P0
+ addDaysAndCheckForCompletion(8, NextEvent.PAYMENT_ERROR);
+ checkODState("OD2");
+
+ // 2012, 7, 23 => Should be 20 but notficationQ event occurs on 23...
+ addDaysAndCheckForCompletion(5);
+ checkODState("OD3");
+
+
+ paymentPlugin.makeAllInvoicesFailWithError(false);
+ final Collection<Invoice> invoices = invoiceUserApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday(), callContext);
+ for (final Invoice invoice : invoices) {
+ if (invoice.getBalance().compareTo(BigDecimal.ZERO) > 0) {
+ createPaymentAndCheckForCompletion(account, invoice, NextEvent.PAYMENT);
+ }
+ }
+ checkODState(DefaultBlockingState.CLEAR_STATE_NAME);
+
+ // Move to 2012, 7, 31 and Make a change of plan
+ addDaysAndCheckForCompletion(8);
+
+ checkChangePlanWithOverdueState(baseSubscription, false);
+
+
+ invoiceChecker.checkRepairedInvoice(account.getId(), 2,
+ callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2013, 5, 31), InvoiceItemType.RECURRING, new BigDecimal("2399.95")),
+ new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 10), new LocalDate(2012, 7, 23), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-85.4588")),
+ new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 31), new LocalDate(2013, 5, 31), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-1998.9012")),
+ new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 31), new LocalDate(2012, 7, 31), InvoiceItemType.CBA_ADJ, new BigDecimal("2084.36")));
+
+ invoiceChecker.checkInvoice(account.getId(), 3, callContext,
+ // Item for the upgraded recurring plan
+ new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 31), new LocalDate(2012, 8, 31), InvoiceItemType.RECURRING, new BigDecimal("599.95")),
+ // Credits consumed
+ new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 31), new LocalDate(2012, 7, 31), InvoiceItemType.CBA_ADJ, new BigDecimal("-599.95")));
+ invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 8, 31), callContext);
+
+ assertEquals(invoiceUserApi.getAccountBalance(account.getId(), callContext).compareTo(new BigDecimal("-1484.41")), 0);
+ }
+
+
@Test(groups = "slow")
public void testOverdueStateIfNoPaymentMethod() throws Exception {
// This test is similar to the previous one - but there is no default payment method on the account, so there
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 9cde6fa..b690e7d 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
@@ -16,15 +16,19 @@
package com.ning.billing.invoice.generator;
+import java.awt.image.DataBufferUShort;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import javax.annotation.Nullable;
+import org.joda.time.Days;
import org.joda.time.LocalDate;
import org.joda.time.Months;
import org.slf4j.Logger;
@@ -177,34 +181,76 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
/**
* Add the repair item for the (yet to be) repairedItem. It will merge the candidateRepairItem with reparee item
*
+ *
+ *
* @param repairedItem the item being repaired
* @param candidateRepairItem the repair item we would have if we were to repair the full period
* @param proposedItems the list of proposed items
*/
void addRepairItem(final InvoiceItem repairedItem, final RepairAdjInvoiceItem candidateRepairItem, final List<InvoiceItem> proposedItems) {
- InvoiceItem repareeItem = null;
+
+
+ int nbTotalRepaireeDays = 0;
+
+ // totalRepareeItemAmount is negative and represents the portion left after we removed the adjustments for the total period for all the reparees combined
+ BigDecimal totalRepareeItemAmount = candidateRepairItem.getAmount();
+ final List<InvoiceItem> reparees = new ArrayList<InvoiceItem>();
for (final InvoiceItem cur : proposedItems) {
if (isRepareeItemForRepairedItem(repairedItem, cur)) {
- if (repareeItem == null) {
- repareeItem = cur;
- } else {
- log.warn("Found multiple reparee item for repaired invoice item " + repairedItem.getId());
- }
+ nbTotalRepaireeDays += Days.daysBetween(cur.getStartDate(), cur.getEndDate()).getDays();
+ reparees.add(cur);
+ totalRepareeItemAmount = totalRepareeItemAmount.add(cur.getAmount());
}
}
+ int nbTotalRepairedDays = Days.daysBetween(candidateRepairItem.getStartDate(), candidateRepairItem.getEndDate()).getDays() - nbTotalRepaireeDays;
+
// If we repaired the full period there is no repairee item
- if (repareeItem == null) {
+ if (reparees.size() == 0) {
proposedItems.add(candidateRepairItem);
return;
}
- final BigDecimal partialRepairAmount = candidateRepairItem.getAmount().add(repareeItem.getAmount());
- if (partialRepairAmount.compareTo(BigDecimal.ZERO) < 0) {
- final RepairAdjInvoiceItem repairItem = new RepairAdjInvoiceItem(candidateRepairItem.getInvoiceId(), candidateRepairItem.getAccountId(), repareeItem.getEndDate(), candidateRepairItem.getEndDate(), partialRepairAmount, candidateRepairItem.getCurrency(), candidateRepairItem.getLinkedItemId());
- proposedItems.remove(repareeItem);
- proposedItems.add(repairItem);
+ // Sort the reparees based on startDate in order to create the repair items -- based on the endDate (previous repairee) -> startDate (next reparee)
+ Collections.sort(reparees, new Comparator<InvoiceItem>() {
+ @Override
+ public int compare(final InvoiceItem o1, final InvoiceItem o2) {
+ return o1.getStartDate().compareTo(o2.getStartDate());
+ }
+ });
+
+ //Build the reparees
+ BigDecimal totalRepairItemAmount = BigDecimal.ZERO;
+ List<InvoiceItem> repairedItems = new ArrayList<InvoiceItem>();
+ InvoiceItem prevReparee = null;
+ final Iterator<InvoiceItem> it = reparees.iterator();
+ while (it.hasNext()) {
+ final InvoiceItem nextReparee = it.next();
+ if (prevReparee != null) {
+ // repairItemAmount is an approximation of the exact amount by simply prorating totalRepareeItemAmount in the repair period; we make sure last item is calculated based
+ // on what is left so the sum of all repairs amount is exactly correct
+ final BigDecimal repairItemAmount = (nextReparee.getEndDate().compareTo(candidateRepairItem.getEndDate()) != 0) ?
+ InvoiceDateUtils.calculateProrationBetweenDates(prevReparee.getEndDate(), nextReparee.getStartDate(), nbTotalRepairedDays).multiply(totalRepareeItemAmount) :
+ totalRepareeItemAmount.subtract(totalRepairItemAmount);
+ totalRepairItemAmount = totalRepairItemAmount.add(repairItemAmount);
+ final RepairAdjInvoiceItem repairItem = new RepairAdjInvoiceItem(candidateRepairItem.getInvoiceId(), candidateRepairItem.getAccountId(), prevReparee.getEndDate(), nextReparee.getStartDate(), repairItemAmount, candidateRepairItem.getCurrency(), repairedItem.getId());
+ repairedItems.add(repairItem);
+ }
+ prevReparee = nextReparee;
}
+
+ // In case we end up with a repair up to the service endDate we need to add this extra item-- this is the 'classic' case with one repairee/repair item
+ if (prevReparee.getEndDate().compareTo(candidateRepairItem.getEndDate()) != 0) {
+ final BigDecimal repairItemAmount = totalRepareeItemAmount.subtract(totalRepairItemAmount);
+ final RepairAdjInvoiceItem repairItem = new RepairAdjInvoiceItem(candidateRepairItem.getInvoiceId(), candidateRepairItem.getAccountId(), prevReparee.getEndDate(), candidateRepairItem.getEndDate(), repairItemAmount, candidateRepairItem.getCurrency(), repairedItem.getId());
+ repairedItems.add(repairItem);
+ }
+
+ // Finally remove all reparees from the proposed items and add all repaired items in the invoice
+ for (InvoiceItem reparee : reparees) {
+ proposedItems.remove(reparee);
+ }
+ proposedItems.addAll(repairedItems);
}
/**
@@ -221,13 +267,13 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
// We assume the items are correctly created, so that the subscription id check implicitly
// verifies that account id and bundle id matches
repairedInvoiceItem.getSubscriptionId().equals(invoiceItem.getSubscriptionId()) &&
- // The reparee item is the "portion used" of the repaired item, hence it will have the same start date
- repairedInvoiceItem.getStartDate().compareTo(invoiceItem.getStartDate()) == 0 &&
+ // service period for reparee should be included in service period of repaired-- true for startDate and endDate
+ repairedInvoiceItem.getStartDate().compareTo(invoiceItem.getStartDate()) <= 0 &&
// Similarly, check the "portion used" is less than the original service end date. The check
// is strict, otherwise there wouldn't be anything to repair
((repairedInvoiceItem.getEndDate() == null && invoiceItem.getEndDate() == null) ||
(repairedInvoiceItem.getEndDate() != null && invoiceItem.getEndDate() != null &&
- repairedInvoiceItem.getEndDate().isAfter(invoiceItem.getEndDate()))) &&
+ repairedInvoiceItem.getEndDate().compareTo(invoiceItem.getEndDate()) >= 0)) &&
// Finally, for the tricky part... In case of complete repairs, the new item will always meet all of the
// following conditions: same type, subscription, start date. Depending on the catalog configuration, the end
// date check could also match (e.g. repair from annual to monthly). For that scenario, we need to default
diff --git a/invoice/src/main/java/com/ning/billing/invoice/generator/InvoiceDateUtils.java b/invoice/src/main/java/com/ning/billing/invoice/generator/InvoiceDateUtils.java
index 2b5f8dd..ff1591c 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/generator/InvoiceDateUtils.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/generator/InvoiceDateUtils.java
@@ -33,21 +33,41 @@ public class InvoiceDateUtils {
private static final int ROUNDING_METHOD = InvoicingConfiguration.getRoundingMode();
private static final int NUMBER_OF_DECIMALS = InvoicingConfiguration.getNumberOfDecimals();
- public static BigDecimal calculateProRationBeforeFirstBillingPeriod(final LocalDate startDate, final LocalDate nextBillingCycleDate,
- final BillingPeriod billingPeriod) {
- final LocalDate previousBillingCycleDate = nextBillingCycleDate.plusMonths(-billingPeriod.getNumberOfMonths());
+ /**
+ *
+ * Called internally to calculate proration or when we recalculate approximate repair amount
+ *
+ * @param startDate start date of the prorated interval
+ * @param endDate end date of the prorated interval
+ * @param previousBillingCycleDate start date of the period
+ * @param nextBillingCycleDate end date of the period
+ * @return
+ */
+ public static BigDecimal calculateProrationBetweenDates(final LocalDate startDate, final LocalDate endDate, final LocalDate previousBillingCycleDate, final LocalDate nextBillingCycleDate) {
final int daysBetween = Days.daysBetween(previousBillingCycleDate, nextBillingCycleDate).getDays();
+ return calculateProrationBetweenDates(startDate, endDate, daysBetween);
+ }
+
+ public static BigDecimal calculateProrationBetweenDates(final LocalDate startDate, final LocalDate endDate, int daysBetween) {
if (daysBetween <= 0) {
return BigDecimal.ZERO;
}
final BigDecimal daysInPeriod = new BigDecimal(daysBetween);
- final BigDecimal days = new BigDecimal(Days.daysBetween(startDate, nextBillingCycleDate).getDays());
+ final BigDecimal days = new BigDecimal(Days.daysBetween(startDate, endDate).getDays());
return days.divide(daysInPeriod, 2 * NUMBER_OF_DECIMALS, ROUNDING_METHOD);
}
+
+ public static BigDecimal calculateProRationBeforeFirstBillingPeriod(final LocalDate startDate, final LocalDate nextBillingCycleDate,
+ final BillingPeriod billingPeriod) {
+ final LocalDate previousBillingCycleDate = nextBillingCycleDate.plusMonths(-billingPeriod.getNumberOfMonths());
+
+ return calculateProrationBetweenDates(startDate, nextBillingCycleDate, previousBillingCycleDate, nextBillingCycleDate);
+ }
+
public static int calculateNumberOfWholeBillingPeriods(final LocalDate startDate, final LocalDate endDate, final BillingPeriod billingPeriod) {
final int numberOfMonths = Months.monthsBetween(startDate, endDate).getMonths();
final int numberOfMonthsInPeriod = billingPeriod.getNumberOfMonths();
@@ -129,15 +149,12 @@ public class InvoiceDateUtils {
}
}
+
public static BigDecimal calculateProRationAfterLastBillingCycleDate(final LocalDate endDate, final LocalDate previousBillThroughDate,
final BillingPeriod billingPeriod) {
// Note: assumption is that previousBillThroughDate is correctly aligned with the billing cycle day
final LocalDate nextBillThroughDate = previousBillThroughDate.plusMonths(billingPeriod.getNumberOfMonths());
- final BigDecimal daysInPeriod = new BigDecimal(Days.daysBetween(previousBillThroughDate, nextBillThroughDate).getDays());
-
- final BigDecimal days = new BigDecimal(Days.daysBetween(previousBillThroughDate, endDate).getDays());
-
- return days.divide(daysInPeriod, 2 * NUMBER_OF_DECIMALS, ROUNDING_METHOD);
+ return calculateProrationBetweenDates(previousBillThroughDate, endDate, previousBillThroughDate, nextBillThroughDate);
}
/*
diff --git a/payment/src/test/java/com/ning/billing/payment/provider/TestExternalPaymentProviderPlugin.java b/payment/src/test/java/com/ning/billing/payment/provider/TestExternalPaymentProviderPlugin.java
index 71929c7..e1eaec2 100644
--- a/payment/src/test/java/com/ning/billing/payment/provider/TestExternalPaymentProviderPlugin.java
+++ b/payment/src/test/java/com/ning/billing/payment/provider/TestExternalPaymentProviderPlugin.java
@@ -57,8 +57,6 @@ public class TestExternalPaymentProviderPlugin extends PaymentTestSuiteNoDB {
final PaymentInfoPlugin paymentInfoPlugin = plugin.processPayment(accountId, paymentId, paymentMethodId, amount, Currency.BRL, callContext);
Assert.assertEquals(paymentInfoPlugin.getAmount(), amount);
- Assert.assertEquals(Seconds.secondsBetween(paymentInfoPlugin.getCreatedDate(), clock.getUTCNow()).getSeconds(), 0);
- Assert.assertEquals(Seconds.secondsBetween(paymentInfoPlugin.getEffectiveDate(), clock.getUTCNow()).getSeconds(), 0);
Assert.assertNull(paymentInfoPlugin.getGatewayError());
Assert.assertNull(paymentInfoPlugin.getGatewayErrorCode());
Assert.assertEquals(paymentInfoPlugin.getStatus(), PaymentPluginStatus.PROCESSED);