killbill-aplcache
Changes
entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java 12(+7 -5)
junction/pom.xml 14(+8 -6)
junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingEntitlementUserApi.java 6(+4 -2)
Details
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoiceRecorder.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoiceRecorder.java
index 30baa4a..554ee50 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoiceRecorder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoiceRecorder.java
@@ -16,11 +16,12 @@
package com.ning.billing.analytics;
-import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
+import javax.inject.Inject;
+
import org.skife.jdbi.v2.Transaction;
import org.skife.jdbi.v2.TransactionStatus;
import org.slf4j.Logger;
@@ -89,14 +90,14 @@ public class BusinessInvoiceRecorder {
return;
}
- log.info("Started rebuilding transitions for account id {}", accountId);
+ log.info("Started rebuilding invoices for account id {}", accountId);
deleteInvoicesAndInvoiceItemsForAccountInTransaction(transactional, accountId);
for (final Invoice invoice : invoiceApi.getInvoicesByAccount(accountId)) {
createInvoiceInTransaction(transactional, accountKey, invoice);
}
- log.info("Finished rebuilding transitions for account id {}", accountId);
+ log.info("Finished rebuilding invoices for account id {}", accountId);
}
private void deleteInvoicesAndInvoiceItemsForAccountInTransaction(final BusinessInvoiceSqlDao transactional, final UUID accountId) {
@@ -107,10 +108,12 @@ public class BusinessInvoiceRecorder {
for (final BusinessInvoice businessInvoice : invoicesToDelete) {
final List<BusinessInvoiceItem> invoiceItemsForInvoice = invoiceItemSqlDao.getInvoiceItemsForInvoice(businessInvoice.getInvoiceId().toString());
for (final BusinessInvoiceItem invoiceItemToDelete : invoiceItemsForInvoice) {
+ log.info("Deleting invoice item {}", invoiceItemToDelete.getItemId());
invoiceItemSqlDao.deleteInvoiceItem(invoiceItemToDelete.getItemId().toString());
}
}
+ log.info("Deleting invoices for account {}", accountId);
transactional.deleteInvoicesForAccount(accountId.toString());
}
@@ -153,6 +156,7 @@ public class BusinessInvoiceRecorder {
account.setLastInvoiceDate(invoice.getInvoiceDate());
account.setTotalInvoiceBalance(account.getTotalInvoiceBalance().add(invoice.getBalance()));
account.setUpdatedDt(clock.getUTCNow());
+ log.info("Updating account {}", account);
accountSqlDao.saveAccount(account);
}
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java b/api/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
index 3757319..0ea8cea 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
@@ -19,6 +19,8 @@ package com.ning.billing.entitlement.api.user;
import java.util.List;
import java.util.UUID;
+import javax.annotation.Nullable;
+
import org.joda.time.DateTime;
import com.ning.billing.catalog.api.PlanPhaseSpecifier;
@@ -47,7 +49,7 @@ public interface EntitlementUserApi {
public Subscription createSubscription(UUID bundleId, PlanPhaseSpecifier spec, DateTime requestedDate, CallContext context)
throws EntitlementUserApiException;
- public List<SubscriptionStatusDryRun> getDryRunChangePlanStatus(UUID subscriptionId, String productName, DateTime requestedDate)
+ public List<SubscriptionStatusDryRun> getDryRunChangePlanStatus(UUID subscriptionId, @Nullable String productName, DateTime requestedDate)
throws EntitlementUserApiException;
public DateTime getNextBillingDate(UUID account);
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java
index ce96066..b8aba53 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java
@@ -20,6 +20,8 @@ import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
+import javax.annotation.Nullable;
+
import org.joda.time.DateTime;
import com.google.inject.Inject;
@@ -213,9 +215,8 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
}
@Override
- public List<SubscriptionStatusDryRun> getDryRunChangePlanStatus(final UUID subscriptionId, final String baseProductName, final DateTime requestedDate)
+ public List<SubscriptionStatusDryRun> getDryRunChangePlanStatus(final UUID subscriptionId, @Nullable final String baseProductName, final DateTime requestedDate)
throws EntitlementUserApiException {
-
final Subscription subscription = dao.getSubscriptionFromId(subscriptionFactory, subscriptionId);
if (subscription == null) {
throw new EntitlementUserApiException(ErrorCode.ENT_INVALID_SUBSCRIPTION_ID, subscriptionId);
@@ -232,10 +233,11 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
continue;
}
- DryRunChangeReason reason = null;
- if (addonUtils.isAddonIncludedFromProdName(baseProductName, requestedDate, cur.getCurrentPlan())) {
+ final DryRunChangeReason reason;
+ // If baseProductName is null, it's a cancellation dry-run. In this case, return all addons, so they are cancelled
+ if (baseProductName != null && addonUtils.isAddonIncludedFromProdName(baseProductName, requestedDate, cur.getCurrentPlan())) {
reason = DryRunChangeReason.AO_INCLUDED_IN_NEW_PLAN;
- } else if (addonUtils.isAddonAvailableFromProdName(baseProductName, requestedDate, cur.getCurrentPlan())) {
+ } else if (baseProductName != null && addonUtils.isAddonAvailableFromProdName(baseProductName, requestedDate, cur.getCurrentPlan())) {
reason = DryRunChangeReason.AO_AVAILABLE_IN_NEW_PLAN;
} else {
reason = DryRunChangeReason.AO_NOT_AVAILABLE_IN_NEW_PLAN;
junction/pom.xml 14(+8 -6)
diff --git a/junction/pom.xml b/junction/pom.xml
index 5ced827..e7a9373 100644
--- a/junction/pom.xml
+++ b/junction/pom.xml
@@ -29,6 +29,14 @@
<artifactId>killbill-util</artifactId>
</dependency>
<dependency>
+ <!-- We don't really need Guava - we need jsr305. Guava uses the com.google.code.findbugs
+ implementation, so let's use the same one. But since we don't explicitly depend on it elsewhere
+ (this should be fixed), let's depend on it transitively for now -->
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<scope>provided</scope>
@@ -93,12 +101,6 @@
<artifactId>mysql-connector-mxj-db-files</artifactId>
<scope>test</scope>
</dependency>
- <!-- Strangely this is needed in order to run the tests in local db mode -->
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- <scope>test</scope>
- </dependency>
</dependencies>
<build>
<plugins>
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingEntitlementUserApi.java b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingEntitlementUserApi.java
index 0b15824..a2bd036 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingEntitlementUserApi.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingEntitlementUserApi.java
@@ -20,9 +20,12 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
+import javax.annotation.Nullable;
+
import org.joda.time.DateTime;
import com.google.inject.Inject;
+
import com.ning.billing.catalog.api.PlanPhaseSpecifier;
import com.ning.billing.entitlement.api.user.EntitlementUserApi;
import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
@@ -97,8 +100,7 @@ public class BlockingEntitlementUserApi implements EntitlementUserApi {
}
@Override
- public List<SubscriptionStatusDryRun> getDryRunChangePlanStatus(
- final UUID subscriptionId, final String productName, final DateTime requestedDate)
+ public List<SubscriptionStatusDryRun> getDryRunChangePlanStatus(final UUID subscriptionId, @Nullable final String productName, final DateTime requestedDate)
throws EntitlementUserApiException {
return entitlementUserApi.getDryRunChangePlanStatus(subscriptionId, productName, requestedDate);
}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java
index 64a3968..0bde914 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java
@@ -70,28 +70,38 @@ public class BillingStateCalculatorBundle extends BillingStateCalculator<Subscri
}
final PaymentResponse responseForLastFailedPayment = PaymentResponse.INSUFFICIENT_FUNDS; //TODO MDW
final Tag[] tags = new Tag[]{}; //TODO MDW
- final Product basePlanProduct = basePlan.getCurrentPlan().getProduct();
- final BillingPeriod basePlanBillingPeriod = basePlan.getCurrentPlan().getBillingPeriod();
- final PriceList basePlanPriceList = basePlan.getCurrentPriceList();
- final PhaseType basePlanPhaseType = basePlan.getCurrentPhase().getPhaseType();
-
-
- return new BillingStateBundle(
- id,
- numberOfUnpaidInvoices,
- unpaidInvoiceBalance,
- dateOfEarliestUnpaidInvoice,
- idOfEarliestUnpaidInvoice,
- responseForLastFailedPayment,
- tags,
- basePlanProduct,
- basePlanBillingPeriod,
- basePlanPriceList,
- basePlanPhaseType);
+
+ final Product basePlanProduct;
+ final BillingPeriod basePlanBillingPeriod;
+ final PriceList basePlanPriceList;
+ final PhaseType basePlanPhaseType;
+ if (basePlan.getCurrentPlan() == null) {
+ // The subscription has been cancelled since
+ basePlanProduct = null;
+ basePlanBillingPeriod = null;
+ basePlanPriceList = null;
+ basePlanPhaseType = null;
+ } else {
+ basePlanProduct = basePlan.getCurrentPlan().getProduct();
+ basePlanBillingPeriod = basePlan.getCurrentPlan().getBillingPeriod();
+ basePlanPriceList = basePlan.getCurrentPriceList();
+ basePlanPhaseType = basePlan.getCurrentPhase().getPhaseType();
+ }
+
+ return new BillingStateBundle(id,
+ numberOfUnpaidInvoices,
+ unpaidInvoiceBalance,
+ dateOfEarliestUnpaidInvoice,
+ idOfEarliestUnpaidInvoice,
+ responseForLastFailedPayment,
+ tags,
+ basePlanProduct,
+ basePlanBillingPeriod,
+ basePlanPriceList,
+ basePlanPhaseType);
} catch (EntitlementUserApiException e) {
throw new OverdueError(e);
}
-
}
public SortedSet<Invoice> unpaidInvoicesForBundle(final UUID bundleId, final UUID accountId) {
diff --git a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
index 419e089..ed4bd61 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
@@ -53,10 +53,9 @@ public class OverdueWrapper<T extends Blockable> {
return overdueStateSet.getClearState();
}
- final OverdueState<T> nextOverdueState;
final BillingState<T> billingState = billingState();
final String previousOverdueStateName = api.getBlockingStateFor(overdueable).getStateName();
- nextOverdueState = overdueStateSet.calculateOverdueState(billingState, clock.getUTCNow());
+ final OverdueState<T> nextOverdueState = overdueStateSet.calculateOverdueState(billingState, clock.getUTCNow());
if (nextOverdueState != null && !previousOverdueStateName.equals(nextOverdueState.getName())) {
overdueStateApplicator.apply(overdueable, previousOverdueStateName, nextOverdueState);
diff --git a/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculatorBundle.java b/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculatorBundle.java
index 67b63ab..bb07af4 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculatorBundle.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculatorBundle.java
@@ -30,6 +30,8 @@ import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+
import com.ning.billing.catalog.MockPlan;
import com.ning.billing.catalog.MockPriceList;
import com.ning.billing.catalog.api.Plan;
@@ -57,6 +59,26 @@ public class TestBillingStateCalculatorBundle extends TestBillingStateCalculator
}
@Test(groups = "fast")
+ public void testBillingStateAfterCancellation() throws Exception {
+ Mockito.when(invoiceApi.getUnpaidInvoicesByAccountId(Mockito.<UUID>any(), Mockito.<DateTime>any())).thenReturn(ImmutableList.<Invoice>of());
+
+ final UUID bundleId = UUID.randomUUID();
+ final SubscriptionBundle bundle = Mockito.mock(SubscriptionBundle.class);
+ Mockito.when(bundle.getId()).thenReturn(bundleId);
+
+ final EntitlementUserApi entitlementApi = Mockito.mock(EntitlementUserApi.class);
+ final Subscription subscription = Mockito.mock(Subscription.class);
+ Mockito.when(entitlementApi.getBaseSubscription(bundleId)).thenReturn(subscription);
+
+ final BillingStateCalculatorBundle calc = new BillingStateCalculatorBundle(entitlementApi, invoiceApi, clock);
+ final BillingStateBundle billingStateBundle = calc.calculateBillingState(bundle);
+ Assert.assertNull(billingStateBundle.getBasePlanBillingPeriod());
+ Assert.assertNull(billingStateBundle.getBasePlanPhaseType());
+ Assert.assertNull(billingStateBundle.getBasePlanPriceList());
+ Assert.assertNull(billingStateBundle.getBasePlanProduct());
+ }
+
+ @Test(groups = "fast")
public void testUnpaidInvoiceForBundle() {
final UUID thisBundleId = new UUID(0L, 0L);
final UUID thatBundleId = new UUID(0L, 1L);