killbill-memoizeit

analytics: fix isRevenueRecognizable implementation Signed-off-by:

4/12/2013 7:33:45 PM

Details

diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessInvoiceDao.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessInvoiceDao.java
index 68d5182..0809d51 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessInvoiceDao.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessInvoiceDao.java
@@ -26,6 +26,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
+import javax.annotation.Nullable;
+
 import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
 import org.osgi.service.log.LogService;
@@ -212,6 +214,35 @@ public class BusinessInvoiceDao extends BusinessAnalyticsDaoBase {
         final Long tenantRecordId = getTenantRecordId(context);
         final ReportGroup reportGroup = getReportGroup(account.getId(), context);
 
+        return createBusinessInvoiceItem(account,
+                                         invoice,
+                                         invoiceItem,
+                                         otherInvoiceItemsOnInvoice,
+                                         bundle,
+                                         plan,
+                                         planPhase,
+                                         invoiceItemRecordId,
+                                         creationAuditLog,
+                                         accountRecordId,
+                                         tenantRecordId,
+                                         reportGroup,
+                                         context);
+    }
+
+    @VisibleForTesting
+    BusinessInvoiceItemBaseModelDao createBusinessInvoiceItem(final Account account,
+                                                              final Invoice invoice,
+                                                              final InvoiceItem invoiceItem,
+                                                              final Collection<InvoiceItem> otherInvoiceItemsOnInvoice,
+                                                              @Nullable final SubscriptionBundle bundle,
+                                                              @Nullable final Plan plan,
+                                                              @Nullable final PlanPhase planPhase,
+                                                              final Long invoiceItemRecordId,
+                                                              final AuditLog creationAuditLog,
+                                                              final Long accountRecordId,
+                                                              final Long tenantRecordId,
+                                                              final ReportGroup reportGroup,
+                                                              final TenantContext context) throws AnalyticsRefreshException {
         final BusinessInvoiceItemType businessInvoiceItemType;
         if (isCharge(invoiceItem)) {
             businessInvoiceItemType = BusinessInvoiceItemType.CHARGE;
@@ -226,7 +257,7 @@ public class BusinessInvoiceDao extends BusinessAnalyticsDaoBase {
             return null;
         }
 
-        final Boolean revenueRecognizable = isRevenueRecognizable(invoiceItem);
+        final Boolean revenueRecognizable = isRevenueRecognizable(invoiceItem, otherInvoiceItemsOnInvoice);
 
         final Long secondInvoiceItemRecordId;
         if (invoiceItem instanceof AdjustmentInvoiceItemForRepair) {
@@ -251,10 +282,12 @@ public class BusinessInvoiceDao extends BusinessAnalyticsDaoBase {
                                                       reportGroup);
     }
 
-    @VisibleForTesting
-    Boolean isRevenueRecognizable(final InvoiceItem invoiceItem) {
-        // REFUND_ADJ are recognizable because associated with a payment
-        return !InvoiceItemType.CREDIT_ADJ.equals(invoiceItem.getInvoiceItemType());
+    private Boolean isRevenueRecognizable(final InvoiceItem invoiceItem, final Collection<InvoiceItem> otherInvoiceItemsOnInvoice) {
+        // All items are recognizable except user generated credit (CBA_ADJ and CREDIT_ADJ on their own invoice)
+        return !(InvoiceItemType.CBA_ADJ.equals(invoiceItem.getInvoiceItemType()) &&
+                 (otherInvoiceItemsOnInvoice.size() == 1 &&
+                  InvoiceItemType.CREDIT_ADJ.equals(otherInvoiceItemsOnInvoice.iterator().next().getInvoiceItemType()) &&
+                  otherInvoiceItemsOnInvoice.iterator().next().getAmount().compareTo(invoiceItem.getAmount().negate()) == 0));
     }
 
     // Invoice adjustments
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceDao.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceDao.java
index 60faf8d..9c776f8 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceDao.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceDao.java
@@ -38,6 +38,7 @@ import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoiceItemType;
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteNoDB;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceItemBaseModelDao;
 import com.ning.killbill.osgi.libs.killbill.OSGIKillbillDataSource;
 import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
 
@@ -74,12 +75,120 @@ public class TestBusinessInvoiceDao extends AnalyticsTestSuiteNoDB {
     }
 
     @Test(groups = "fast")
-    public void testRevenueRecognizable() throws Exception {
-        // All items but CREDIT_ADJ are recognizable by default
-        Assert.assertTrue(invoiceDao.isRevenueRecognizable(createInvoiceItem(InvoiceItemType.RECURRING)
-                                                          ));
-        Assert.assertFalse(invoiceDao.isRevenueRecognizable(createInvoiceItem(InvoiceItemType.CREDIT_ADJ)
-                                                           ));
+    public void testRevenueRecognizableClassicAccountCredit() throws Exception {
+        // Classic account credit ($10), from the perspective of the CREDIT_ADJ item
+        final BusinessInvoiceItemBaseModelDao businessCreditAdjItem = invoiceDao.createBusinessInvoiceItem(account,
+                                                                                                           invoice,
+                                                                                                           createInvoiceItem(InvoiceItemType.CREDIT_ADJ, new BigDecimal("-10")),
+                                                                                                           ImmutableList.<InvoiceItem>of(createInvoiceItem(InvoiceItemType.CBA_ADJ, new BigDecimal("10"))),
+                                                                                                           null,
+                                                                                                           null,
+                                                                                                           null,
+                                                                                                           invoiceItemRecordId,
+                                                                                                           auditLog,
+                                                                                                           accountRecordId,
+                                                                                                           tenantRecordId,
+                                                                                                           reportGroup,
+                                                                                                           callContext);
+        // We ignore these
+        Assert.assertNull(businessCreditAdjItem);
+
+        // Classic account credit ($10), from the perspective of the CBA_ADJ item
+        final BusinessInvoiceItemBaseModelDao businessCreditItem = invoiceDao.createBusinessInvoiceItem(account,
+                                                                                                        invoice,
+                                                                                                        createInvoiceItem(InvoiceItemType.CBA_ADJ, new BigDecimal("10")),
+                                                                                                        ImmutableList.<InvoiceItem>of(createInvoiceItem(InvoiceItemType.CREDIT_ADJ, new BigDecimal("-10"))),
+                                                                                                        null,
+                                                                                                        null,
+                                                                                                        null,
+                                                                                                        invoiceItemRecordId,
+                                                                                                        auditLog,
+                                                                                                        accountRecordId,
+                                                                                                        tenantRecordId,
+                                                                                                        reportGroup,
+                                                                                                        callContext);
+        // We treat these as NOT recognizable account credits
+        Assert.assertEquals(businessCreditItem.getAmount().compareTo(new BigDecimal("10")), 0);
+        Assert.assertEquals(businessCreditItem.getItemType(), InvoiceItemType.CBA_ADJ.toString());
+        Assert.assertFalse(businessCreditItem.getRevenueRecognizable());
+
+        // Invoice adjustment, not to be mixed with credits!
+        final BusinessInvoiceItemBaseModelDao businessInvoiceAdjustmentItem = invoiceDao.createBusinessInvoiceItem(account,
+                                                                                                                   invoice,
+                                                                                                                   createInvoiceItem(InvoiceItemType.CREDIT_ADJ, new BigDecimal("-10")),
+                                                                                                                   ImmutableList.<InvoiceItem>of(createInvoiceItem(InvoiceItemType.RECURRING, new BigDecimal("10"))),
+                                                                                                                   null,
+                                                                                                                   null,
+                                                                                                                   null,
+                                                                                                                   invoiceItemRecordId,
+                                                                                                                   auditLog,
+                                                                                                                   accountRecordId,
+                                                                                                                   tenantRecordId,
+                                                                                                                   reportGroup,
+                                                                                                                   callContext);
+        Assert.assertEquals(businessInvoiceAdjustmentItem.getAmount().compareTo(new BigDecimal("-10")), 0);
+        Assert.assertEquals(businessInvoiceAdjustmentItem.getItemType(), InvoiceItemType.CREDIT_ADJ.toString());
+        // Recognizable by default
+        Assert.assertTrue(businessInvoiceAdjustmentItem.getRevenueRecognizable());
+
+        // Invoice adjustment via refund
+        final BusinessInvoiceItemBaseModelDao businessRefundInvoiceAdjustmentItem = invoiceDao.createBusinessInvoiceItem(account,
+                                                                                                                         invoice,
+                                                                                                                         createInvoiceItem(InvoiceItemType.REFUND_ADJ, new BigDecimal("-10")),
+                                                                                                                         ImmutableList.<InvoiceItem>of(createInvoiceItem(InvoiceItemType.RECURRING, new BigDecimal("10"))),
+                                                                                                                         null,
+                                                                                                                         null,
+                                                                                                                         null,
+                                                                                                                         invoiceItemRecordId,
+                                                                                                                         auditLog,
+                                                                                                                         accountRecordId,
+                                                                                                                         tenantRecordId,
+                                                                                                                         reportGroup,
+                                                                                                                         callContext);
+        Assert.assertEquals(businessRefundInvoiceAdjustmentItem.getAmount().compareTo(new BigDecimal("-10")), 0);
+        Assert.assertEquals(businessRefundInvoiceAdjustmentItem.getItemType(), InvoiceItemType.REFUND_ADJ.toString());
+        // Recognizable by default
+        Assert.assertTrue(businessRefundInvoiceAdjustmentItem.getRevenueRecognizable());
+
+        // Item adjustment
+        final BusinessInvoiceItemBaseModelDao businessInvoiceItemAdjustmentItem = invoiceDao.createBusinessInvoiceItem(account,
+                                                                                                                       invoice,
+                                                                                                                       createInvoiceItem(InvoiceItemType.ITEM_ADJ, new BigDecimal("-10")),
+                                                                                                                       ImmutableList.<InvoiceItem>of(createInvoiceItem(InvoiceItemType.RECURRING, new BigDecimal("10"))),
+                                                                                                                       null,
+                                                                                                                       null,
+                                                                                                                       null,
+                                                                                                                       invoiceItemRecordId,
+                                                                                                                       auditLog,
+                                                                                                                       accountRecordId,
+                                                                                                                       tenantRecordId,
+                                                                                                                       reportGroup,
+                                                                                                                       callContext);
+        Assert.assertEquals(businessInvoiceItemAdjustmentItem.getAmount().compareTo(new BigDecimal("-10")), 0);
+        Assert.assertEquals(businessInvoiceItemAdjustmentItem.getItemType(), InvoiceItemType.ITEM_ADJ.toString());
+        // Recognizable by default
+        Assert.assertTrue(businessInvoiceItemAdjustmentItem.getRevenueRecognizable());
+
+        // System generated account credit
+        final BusinessInvoiceItemBaseModelDao businessCBAItem = invoiceDao.createBusinessInvoiceItem(account,
+                                                                                                     invoice,
+                                                                                                     createInvoiceItem(InvoiceItemType.CBA_ADJ, new BigDecimal("10")),
+                                                                                                     ImmutableList.<InvoiceItem>of(createInvoiceItem(InvoiceItemType.RECURRING, new BigDecimal("30")),
+                                                                                                                                   createInvoiceItem(InvoiceItemType.REPAIR_ADJ, new BigDecimal("-30")),
+                                                                                                                                   createInvoiceItem(InvoiceItemType.RECURRING, new BigDecimal("20"))),
+                                                                                                     null,
+                                                                                                     null,
+                                                                                                     null,
+                                                                                                     invoiceItemRecordId,
+                                                                                                     auditLog,
+                                                                                                     accountRecordId,
+                                                                                                     tenantRecordId,
+                                                                                                     reportGroup,
+                                                                                                     callContext);
+        Assert.assertEquals(businessCBAItem.getAmount().compareTo(new BigDecimal("10")), 0);
+        Assert.assertEquals(businessCBAItem.getItemType(), InvoiceItemType.CBA_ADJ.toString());
+        // Recognizable by default
+        Assert.assertTrue(businessCBAItem.getRevenueRecognizable());
     }
 
     @Test(groups = "fast")