killbill-memoizeit
Changes
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")