Details
diff --git a/api/src/main/java/com/ning/billing/ErrorCode.java b/api/src/main/java/com/ning/billing/ErrorCode.java
index c081e57..b62ab79 100644
--- a/api/src/main/java/com/ning/billing/ErrorCode.java
+++ b/api/src/main/java/com/ning/billing/ErrorCode.java
@@ -60,7 +60,7 @@ public enum ErrorCode {
ENT_GET_INVALID_BUNDLE_ID(1081, "Could not find a bundle matching id %s"),
ENT_INVALID_SUBSCRIPTION_ID(1082, "Unknown subscription %s"),
ENT_GET_INVALID_BUNDLE_KEY(1083, "Could not find a bundle matching key %s"),
- ENT_GET_NO_SUCH_BASE_SUBSCRIPTION(1084, "Could not base subscription for bundle %s"),
+ ENT_GET_NO_SUCH_BASE_SUBSCRIPTION(1084, "Could not find base subscription for bundle %s"),
/* Repair */
ENT_REPAIR_INVALID_DELETE_SET(1091, "Event %s is not deleted for subscription %s but prior events were"),
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/migration/DefaultEntitlementMigrationApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/migration/DefaultEntitlementMigrationApi.java
index f08e351..e836d59 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/migration/DefaultEntitlementMigrationApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/migration/DefaultEntitlementMigrationApi.java
@@ -170,10 +170,13 @@ public class DefaultEntitlementMigrationApi implements EntitlementMigrationApi {
private List<EntitlementEvent> toEvents(final SubscriptionData subscriptionData, final DateTime now, final DateTime ctd, final TimedMigration[] migrationEvents, final CallContext context) {
ApiEventMigrateEntitlement creationEvent = null;
final List<EntitlementEvent> events = new ArrayList<EntitlementEvent>(migrationEvents.length);
- DateTime subsciptionCancelledDate = null;
+
+ // The first event date after the MIGRATE_ENTITLEMENT event
+ DateTime nextEventDate = null;
for (final TimedMigration cur : migrationEvents) {
if (cur.getEventType() == EventType.PHASE) {
+ nextEventDate = nextEventDate != null && nextEventDate.compareTo(cur.getEventTime()) < 0 ? nextEventDate : cur.getEventTime();
final PhaseEvent nextPhaseEvent = PhaseEventData.createNextPhaseEvent(cur.getPhase().getName(), subscriptionData, now, cur.getEventTime());
events.add(nextPhaseEvent);
@@ -198,10 +201,11 @@ public class DefaultEntitlementMigrationApi implements EntitlementMigrationApi {
break;
case CHANGE:
+ nextEventDate = nextEventDate != null && nextEventDate.compareTo(cur.getEventTime()) < 0 ? nextEventDate : cur.getEventTime();
events.add(new ApiEventChange(builder));
break;
case CANCEL:
- subsciptionCancelledDate = cur.getEventTime();
+ nextEventDate = nextEventDate != null && nextEventDate.compareTo(cur.getEventTime()) < 0 ? nextEventDate : cur.getEventTime();
events.add(new ApiEventCancel(builder));
break;
default:
@@ -214,7 +218,8 @@ public class DefaultEntitlementMigrationApi implements EntitlementMigrationApi {
if (creationEvent == null || ctd == null) {
throw new EntitlementError(String.format("Could not create migration billing event ctd = %s", ctd));
}
- if (subsciptionCancelledDate == null || subsciptionCancelledDate.isAfter(ctd)) {
+ // Only add the MIGRATE_BILLING event if there is no event prior to that that will trigger the first invoice.
+ if (nextEventDate == null || nextEventDate.isAfter(ctd)) {
events.add(new ApiEventMigrateBilling(creationEvent, ctd));
}
Collections.sort(events, new Comparator<EntitlementEvent>() {
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigration.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigration.java
index ccdc80a..aefdfbe 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigration.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigration.java
@@ -192,7 +192,6 @@ public abstract class TestMigration extends TestApiBase {
assertEquals(subscription.getCurrentPlan().getName(), "assault-rifle-monthly");
assertEquals(subscription.getChargedThroughDate(), trialDate.plusDays(30));
- testListener.pushExpectedEvent(NextEvent.MIGRATE_BILLING);
testListener.pushExpectedEvent(NextEvent.PHASE);
final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(30));
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 4934889..226ef40 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
@@ -24,6 +24,7 @@ import java.util.UUID;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
+import com.ning.billing.ErrorCode;
import com.ning.billing.account.api.Account;
import com.ning.billing.account.api.AccountApiException;
import com.ning.billing.catalog.api.BillingPeriod;
@@ -60,13 +61,14 @@ public class BillingStateCalculatorBundle extends BillingStateCalculator<Subscri
this.accountApi = accountApi;
}
+
@Override
public BillingStateBundle calculateBillingState(final SubscriptionBundle bundle, final InternalTenantContext context) throws OverdueException {
try {
final Account account = accountApi.getAccountById(bundle.getAccountId(), context);
final SortedSet<Invoice> unpaidInvoices = unpaidInvoicesForBundle(bundle.getId(), bundle.getAccountId(), account.getTimeZone(), context);
- final Subscription basePlan = entitlementApi.getBaseSubscription(bundle.getId(), context);
+ final Subscription basePlan = getBasePlanIfExist(bundle.getId(), context);
final UUID id = bundle.getId();
final int numberOfUnpaidInvoices = unpaidInvoices.size();
@@ -131,6 +133,19 @@ public class BillingStateCalculatorBundle extends BillingStateCalculator<Subscri
return result;
}
+ private Subscription getBasePlanIfExist(UUID bundleId, final InternalTenantContext context) throws EntitlementUserApiException {
+ try {
+ final Subscription basePlan = entitlementApi.getBaseSubscription(bundleId, context);
+ return basePlan;
+ } catch (EntitlementUserApiException e) {
+ if (e.getCode() == ErrorCode.ENT_GET_NO_SUCH_BASE_SUBSCRIPTION.getCode()) {
+ // No base plan probably a STANDALONE subscription in a bundle
+ return null;
+ }
+ throw e;
+ }
+ }
+
private boolean invoiceHasAnItemFromBundle(final Invoice invoice, final UUID bundleId) {
for (final InvoiceItem item : invoice.getInvoiceItems()) {
if (item.getBundleId() != null && item.getBundleId().equals(bundleId)) {
@@ -139,6 +154,4 @@ public class BillingStateCalculatorBundle extends BillingStateCalculator<Subscri
}
return false;
}
-
-
}