killbill-aplcache

analytics: fix mrr computation We need to look at the billing

10/22/2012 4:26:43 PM

Details

diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessSubscription.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessSubscription.java
index 18d85cc..91e4023 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessSubscription.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessSubscription.java
@@ -24,15 +24,14 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.ning.billing.analytics.utils.Rounder;
+import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.Catalog;
 import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.catalog.api.Duration;
 import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.PlanPhase;
 import com.ning.billing.catalog.api.Product;
 import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.catalog.api.TimeUnit;
 import com.ning.billing.entitlement.api.user.Subscription;
 
 import static com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
@@ -44,8 +43,6 @@ public class BusinessSubscription {
 
     private static final Logger log = LoggerFactory.getLogger(BusinessSubscription.class);
 
-    private static final BigDecimal DAYS_IN_MONTH = BigDecimal.valueOf(30);
-    private static final BigDecimal MONTHS_IN_YEAR = BigDecimal.valueOf(12);
     private static final Currency USD = Currency.valueOf("USD");
 
     private final String productName;
@@ -145,7 +142,7 @@ public class BusinessSubscription {
                     tmpPrice = new BigDecimal(0);
                 }
                 price = tmpPrice;
-                mrr = getMrrFromISubscription(thePhase.getDuration(), price);
+                mrr = getMrrFromBillingPeriod(thePhase.getBillingPeriod(), price);
             } else {
                 price = BigDecimal.ZERO;
                 mrr = BigDecimal.ZERO;
@@ -210,7 +207,7 @@ public class BusinessSubscription {
                     tmpPrice = new BigDecimal(0);
                 }
                 price = tmpPrice;
-                mrr = getMrrFromISubscription(currentPhase.getDuration(), price);
+                mrr = getMrrFromBillingPeriod(currentPhase.getBillingPeriod(), price);
             } else {
                 price = BigDecimal.ZERO;
                 mrr = BigDecimal.ZERO;
@@ -289,23 +286,12 @@ public class BusinessSubscription {
         return state;
     }
 
-    static BigDecimal getMrrFromISubscription(final Duration duration, final BigDecimal price) {
-        if (duration == null || duration.getUnit() == null || duration.getNumber() == 0) {
+    static BigDecimal getMrrFromBillingPeriod(final BillingPeriod period, final BigDecimal price) {
+        if (period == null || period.getNumberOfMonths() == 0) {
             return BigDecimal.ZERO;
         }
 
-        if (duration.getUnit().equals(TimeUnit.UNLIMITED)) {
-            return BigDecimal.ZERO;
-        } else if (duration.getUnit().equals(TimeUnit.DAYS)) {
-            return price.multiply(DAYS_IN_MONTH).multiply(BigDecimal.valueOf(duration.getNumber()));
-        } else if (duration.getUnit().equals(TimeUnit.MONTHS)) {
-            return price.divide(BigDecimal.valueOf(duration.getNumber()), Rounder.SCALE, BigDecimal.ROUND_HALF_UP);
-        } else if (duration.getUnit().equals(TimeUnit.YEARS)) {
-            return price.divide(BigDecimal.valueOf(duration.getNumber()), Rounder.SCALE, RoundingMode.HALF_UP).divide(MONTHS_IN_YEAR, Rounder.SCALE, RoundingMode.HALF_UP);
-        } else {
-            log.error("Unknown duration [" + duration + "], can't compute mrr");
-            return null;
-        }
+        return price.divide(BigDecimal.valueOf(period.getNumberOfMonths()), Rounder.SCALE, RoundingMode.HALF_UP);
     }
 
     @Override
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockDuration.java b/analytics/src/test/java/com/ning/billing/analytics/MockDuration.java
index 6810e0e..2167156 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockDuration.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockDuration.java
@@ -23,53 +23,6 @@ import com.ning.billing.catalog.api.Duration;
 import com.ning.billing.catalog.api.TimeUnit;
 
 public class MockDuration {
-    public static Duration MONHTLY() {
-        return new Duration() {
-            @Override
-            public TimeUnit getUnit() {
-                return TimeUnit.MONTHS;
-            }
-
-            @Override
-            public int getNumber() {
-                return 1;
-            }
-
-            @Override
-            public DateTime addToDateTime(final DateTime dateTime) {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public Period toJodaPeriod() {
-                throw new UnsupportedOperationException();
-            }
-        };
-    }
-
-    public static Duration YEARLY() {
-        return new Duration() {
-            @Override
-            public TimeUnit getUnit() {
-                return TimeUnit.YEARS;
-            }
-
-            @Override
-            public int getNumber() {
-                return 1;
-            }
-
-            @Override
-            public DateTime addToDateTime(final DateTime dateTime) {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public Period toJodaPeriod() {
-                throw new UnsupportedOperationException();
-            }
-        };
-    }
 
     public static Duration UNLIMITED() {
         return new Duration() {
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscription.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscription.java
index 7a2cbd7..604d511 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscription.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscription.java
@@ -28,9 +28,9 @@ import com.ning.billing.analytics.AnalyticsTestSuite;
 import com.ning.billing.analytics.MockDuration;
 import com.ning.billing.analytics.MockPhase;
 import com.ning.billing.analytics.MockProduct;
+import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.Catalog;
 import com.ning.billing.catalog.api.CatalogService;
-import com.ning.billing.catalog.api.Duration;
 import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.PlanPhase;
@@ -43,19 +43,71 @@ import com.ning.billing.mock.MockSubscription;
 import static com.ning.billing.catalog.api.Currency.USD;
 
 public class TestBusinessSubscription extends AnalyticsTestSuite {
-    private final Duration MONTHLY = MockDuration.MONHTLY();
-    private final Duration YEARLY = MockDuration.YEARLY();
+
     final Object[][] catalogMapping = {
-            {MONTHLY, 229.0000, 229.0000},
-            {MONTHLY, 19.9500, 19.9500},
-            {MONTHLY, 14.9500, 14.9500},
-            {MONTHLY, 12.9500, 12.9500},
-            {YEARLY, 19.9500, 1.6625},
-            {YEARLY, 399.0000, 33.2500},
-            {YEARLY, 29.9500, 2.4958},
-            {YEARLY, 59.0000, 4.9167},
-            {YEARLY, 18.2900, 1.5242},
-            {YEARLY, 49.0000, 4.0833}};
+            {BillingPeriod.NO_BILLING_PERIOD, 369.9500, 0.0000},
+            {BillingPeriod.NO_BILLING_PERIOD, 429.9500, 0.0000},
+            {BillingPeriod.NO_BILLING_PERIOD, 999.9500, 0.0000},
+            {BillingPeriod.NO_BILLING_PERIOD, 2300.0000, 0.0000},
+            {BillingPeriod.MONTHLY, 2.9500, 2.9500},
+            {BillingPeriod.MONTHLY, 3.9500, 3.9500},
+            {BillingPeriod.MONTHLY, 6.9500, 6.9500},
+            {BillingPeriod.MONTHLY, 7.0000, 7.0000},
+            {BillingPeriod.MONTHLY, 7.9500, 7.9500},
+            {BillingPeriod.MONTHLY, 9.0000, 9.0000},
+            {BillingPeriod.MONTHLY, 9.9500, 9.9500},
+            {BillingPeriod.MONTHLY, 11.9500, 11.9500},
+            {BillingPeriod.MONTHLY, 12.4500, 12.4500},
+            {BillingPeriod.MONTHLY, 12.9500, 12.9500},
+            {BillingPeriod.MONTHLY, 14.9500, 14.9500},
+            {BillingPeriod.MONTHLY, 15.0000, 15.0000},
+            {BillingPeriod.MONTHLY, 16.9500, 16.9500},
+            {BillingPeriod.MONTHLY, 19.0000, 19.0000},
+            {BillingPeriod.MONTHLY, 19.9500, 19.9500},
+            {BillingPeriod.MONTHLY, 24.9500, 24.9500},
+            {BillingPeriod.MONTHLY, 29.0000, 29.0000},
+            {BillingPeriod.MONTHLY, 29.9500, 29.9500},
+            {BillingPeriod.MONTHLY, 31.0000, 31.0000},
+            {BillingPeriod.MONTHLY, 34.9500, 34.9500},
+            {BillingPeriod.MONTHLY, 39.0000, 39.0000},
+            {BillingPeriod.MONTHLY, 39.9500, 39.9500},
+            {BillingPeriod.MONTHLY, 49.0000, 49.0000},
+            {BillingPeriod.MONTHLY, 49.9500, 49.9500},
+            {BillingPeriod.MONTHLY, 59.9500, 59.9500},
+            {BillingPeriod.MONTHLY, 79.0000, 79.0000},
+            {BillingPeriod.MONTHLY, 99.0000, 99.0000},
+            {BillingPeriod.MONTHLY, 139.0000, 139.0000},
+            {BillingPeriod.MONTHLY, 209.0000, 209.0000},
+            {BillingPeriod.MONTHLY, 229.0000, 229.0000},
+            {BillingPeriod.MONTHLY, 274.5000, 274.5000},
+            {BillingPeriod.MONTHLY, 549.0000, 549.0000},
+            {BillingPeriod.ANNUAL, 18.2900, 1.5242},
+            {BillingPeriod.ANNUAL, 19.9500, 1.6625},
+            {BillingPeriod.ANNUAL, 29.9500, 2.4958},
+            {BillingPeriod.ANNUAL, 49.0000, 4.0833},
+            {BillingPeriod.ANNUAL, 59.0000, 4.9167},
+            {BillingPeriod.ANNUAL, 149.9500, 12.4958},
+            {BillingPeriod.ANNUAL, 159.9500, 13.3292},
+            {BillingPeriod.ANNUAL, 169.9500, 14.1625},
+            {BillingPeriod.ANNUAL, 183.2900, 15.2742},
+            {BillingPeriod.ANNUAL, 199.9500, 16.6625},
+            {BillingPeriod.ANNUAL, 219.9500, 18.3292},
+            {BillingPeriod.ANNUAL, 239.9000, 19.9917},
+            {BillingPeriod.ANNUAL, 249.9500, 20.8292},
+            {BillingPeriod.ANNUAL, 319.0000, 26.5833},
+            {BillingPeriod.ANNUAL, 349.9500, 29.1625},
+            {BillingPeriod.ANNUAL, 399.0000, 33.2500},
+            {BillingPeriod.ANNUAL, 399.9500, 33.3292},
+            {BillingPeriod.ANNUAL, 458.2900, 38.1908},
+            {BillingPeriod.ANNUAL, 499.9500, 41.6625},
+            {BillingPeriod.ANNUAL, 549.9500, 45.8292},
+            {BillingPeriod.ANNUAL, 599.9000, 49.9917},
+            {BillingPeriod.ANNUAL, 599.9500, 49.9958},
+            {BillingPeriod.ANNUAL, 624.9500, 52.0792},
+            {BillingPeriod.ANNUAL, 799.0000, 66.5833},
+            {BillingPeriod.ANNUAL, 999.0000, 83.2500},
+            {BillingPeriod.ANNUAL, 2299.0000, 191.5833},
+            {BillingPeriod.ANNUAL, 5499.0000, 458.2500}};
 
     private Product product;
     private Plan plan;
@@ -85,11 +137,11 @@ public class TestBusinessSubscription extends AnalyticsTestSuite {
     public void testMrrComputation() throws Exception {
         int i = 0;
         for (final Object[] object : catalogMapping) {
-            final Duration duration = (Duration) object[0];
+            final BillingPeriod billingPeriod = (BillingPeriod) object[0];
             final double price = (Double) object[1];
             final double expectedMrr = (Double) object[2];
 
-            final BigDecimal computedMrr = BusinessSubscription.getMrrFromISubscription(duration, BigDecimal.valueOf(price));
+            final BigDecimal computedMrr = BusinessSubscription.getMrrFromBillingPeriod(billingPeriod, BigDecimal.valueOf(price));
             Assert.assertEquals(computedMrr.doubleValue(), expectedMrr, "Invalid mrr for product #" + i);
             i++;
         }