killbill-memoizeit
Changes
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessAccountDao.java 79(+9 -70)
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessAnalyticsDaoBase.java 11(+2 -9)
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessBundleSummaryDao.java 91(+1 -90)
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessFieldDao.java 39(+6 -33)
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessInvoiceAndInvoicePaymentDao.java 58(+36 -22)
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessInvoiceDao.java 587(+15 -572)
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessInvoicePaymentDao.java 103(+13 -90)
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessOverdueStatusDao.java 63(+8 -55)
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessSubscriptionTransitionDao.java 126(+20 -106)
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessTagDao.java 45(+9 -36)
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessAccountFactory.java 101(+101 -0)
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessBundleSummaryFactory.java 123(+123 -0)
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessFactoryBase.java 29(+29 -0)
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessFieldFactory.java 66(+66 -0)
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessInvoiceFactory.java 592(+592 -0)
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessInvoiceItemFactory.java 28(+28 -0)
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessInvoicePaymentFactory.java 109(+109 -0)
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessOverdueStatusFactory.java 95(+95 -0)
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessSubscriptionTransitionFactory.java 126(+126 -0)
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessTagFactory.java 69(+69 -0)
osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/factory/TestBusinessBundleSummaryFactory.java 8(+4 -4)
Details
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessAccountDao.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessAccountDao.java
index 2f31a3b..e54a01c 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessAccountDao.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessAccountDao.java
@@ -16,24 +16,14 @@
package com.ning.billing.osgi.bundles.analytics.dao;
-import java.math.BigDecimal;
-import java.util.Collection;
-import java.util.List;
import java.util.UUID;
import org.skife.jdbi.v2.Transaction;
import org.skife.jdbi.v2.TransactionStatus;
-import com.ning.billing.account.api.Account;
-import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.entitlement.api.user.Subscription;
-import com.ning.billing.entitlement.api.user.SubscriptionBundle;
-import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
+import com.ning.billing.osgi.bundles.analytics.dao.factory.BusinessAccountFactory;
import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessAccountModelDao;
-import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessModelDaoBase.ReportGroup;
-import com.ning.billing.payment.api.Payment;
-import com.ning.billing.util.audit.AuditLog;
import com.ning.billing.util.callcontext.CallContext;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillDataSource;
@@ -41,17 +31,18 @@ import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
public class BusinessAccountDao extends BusinessAnalyticsDaoBase {
+ private final BusinessAccountFactory bacFactory;
+
public BusinessAccountDao(final OSGIKillbillLogService logService,
final OSGIKillbillAPI osgiKillbillAPI,
final OSGIKillbillDataSource osgiKillbillDataSource) {
- super(logService, osgiKillbillAPI, osgiKillbillDataSource);
+ super(osgiKillbillDataSource);
+ bacFactory = new BusinessAccountFactory(logService, osgiKillbillAPI);
}
public void update(final UUID accountId, final CallContext context) throws AnalyticsRefreshException {
- final Account account = getAccount(accountId, context);
-
// Recompute the account record
- final BusinessAccountModelDao bac = createBusinessAccount(account, context);
+ final BusinessAccountModelDao bac = bacFactory.createBusinessAccount(accountId, context);
sqlDao.inTransaction(new Transaction<Void, BusinessAnalyticsSqlDao>() {
@Override
@@ -63,62 +54,10 @@ public class BusinessAccountDao extends BusinessAnalyticsDaoBase {
}
// Note: computing the BusinessAccountModelDao object is fairly expensive, hence should be done outside of the transaction
- public void updateInTransaction(final BusinessAccountModelDao bac, final BusinessAnalyticsSqlDao transactional, final CallContext context) {
+ public void updateInTransaction(final BusinessAccountModelDao bac,
+ final BusinessAnalyticsSqlDao transactional,
+ final CallContext context) {
transactional.deleteByAccountRecordId(bac.getTableName(), bac.getAccountRecordId(), bac.getTenantRecordId(), context);
transactional.create(bac.getTableName(), bac, context);
}
-
- public BusinessAccountModelDao createBusinessAccount(final Account account, final CallContext context) throws AnalyticsRefreshException {
- // Retrieve the account creation audit log
- final AuditLog creationAuditLog = getAccountCreationAuditLog(account.getId(), context);
-
- // Retrieve the account balance
- // Note: since we retrieve the invoices below, we could compute it ourselves and avoid fetching the invoices
- // twice, but that way the computation logic is owned by invoice
- final BigDecimal accountBalance = getAccountBalance(account.getId(), context);
-
- // Retrieve invoices information
- Invoice lastInvoice = null;
- final Collection<Invoice> invoices = getInvoicesByAccountId(account.getId(), context);
- for (final Invoice invoice : invoices) {
- if (lastInvoice == null || invoice.getInvoiceDate().isAfter(lastInvoice.getInvoiceDate())) {
- lastInvoice = invoice;
- }
- }
-
- // Retrieve payments information
- Payment lastPayment = null;
- final Collection<Payment> payments = getPaymentsByAccountId(account.getId(), context);
- for (final Payment payment : payments) {
- if (lastPayment == null || payment.getEffectiveDate().isAfter(lastPayment.getEffectiveDate())) {
- lastPayment = payment;
- }
- }
-
- final List<SubscriptionBundle> bundles = getSubscriptionBundlesForAccount(account.getId(), context);
- int nbActiveBundles = 0;
- for (final SubscriptionBundle bundle : bundles) {
- final Collection<Subscription> subscriptionsForBundle = getSubscriptionsForBundle(bundle.getId(), context);
- for (final Subscription subscription : subscriptionsForBundle) {
- if (ProductCategory.BASE.equals(subscription.getCategory()) &&
- !(subscription.getEndDate() != null && !subscription.getEndDate().isAfterNow())) {
- nbActiveBundles++;
- }
- }
- }
-
- final Long accountRecordId = getAccountRecordId(account.getId(), context);
- final Long tenantRecordId = getTenantRecordId(context);
- final ReportGroup reportGroup = getReportGroup(account.getId(), context);
-
- return new BusinessAccountModelDao(account,
- accountRecordId,
- accountBalance,
- lastInvoice,
- lastPayment,
- nbActiveBundles,
- creationAuditLog,
- tenantRecordId,
- reportGroup);
- }
}
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessAnalyticsDaoBase.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessAnalyticsDaoBase.java
index 9395500..f676281 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessAnalyticsDaoBase.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessAnalyticsDaoBase.java
@@ -18,20 +18,13 @@ package com.ning.billing.osgi.bundles.analytics.dao;
import org.skife.jdbi.v2.DBI;
-import com.ning.billing.osgi.bundles.analytics.BusinessAnalyticsBase;
-import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillDataSource;
-import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
-public class BusinessAnalyticsDaoBase extends BusinessAnalyticsBase {
+public class BusinessAnalyticsDaoBase {
protected final BusinessAnalyticsSqlDao sqlDao;
- public BusinessAnalyticsDaoBase(final OSGIKillbillLogService logService,
- final OSGIKillbillAPI osgiKillbillAPI,
- final OSGIKillbillDataSource osgiKillbillDataSource) {
- super(logService, osgiKillbillAPI);
-
+ public BusinessAnalyticsDaoBase(final OSGIKillbillDataSource osgiKillbillDataSource) {
final DBI dbi = BusinessDBIProvider.get(osgiKillbillDataSource.getDataSource());
sqlDao = dbi.onDemand(BusinessAnalyticsSqlDao.class);
}
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessBundleSummaryDao.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessBundleSummaryDao.java
index e49a686..75b5bdc 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessBundleSummaryDao.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessBundleSummaryDao.java
@@ -17,36 +17,19 @@
package com.ning.billing.osgi.bundles.analytics.dao;
import java.util.Collection;
-import java.util.Comparator;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.UUID;
-import com.ning.billing.account.api.Account;
-import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.entitlement.api.user.SubscriptionBundle;
-import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessBundleSummaryModelDao;
-import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessModelDaoBase.ReportGroup;
-import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscriptionTransitionModelDao;
-import com.ning.billing.util.audit.AuditLog;
import com.ning.billing.util.callcontext.CallContext;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillDataSource;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Ordering;
-
public class BusinessBundleSummaryDao extends BusinessAnalyticsDaoBase {
public BusinessBundleSummaryDao(final OSGIKillbillLogService logService,
final OSGIKillbillAPI osgiKillbillAPI,
final OSGIKillbillDataSource osgiKillbillDataSource) {
- super(logService, osgiKillbillAPI, osgiKillbillDataSource);
+ super(osgiKillbillDataSource);
}
public void updateInTransaction(final Collection<BusinessBundleSummaryModelDao> bbss,
@@ -65,76 +48,4 @@ public class BusinessBundleSummaryDao extends BusinessAnalyticsDaoBase {
// The update of summary columns in BAC will be done via BST
}
-
- public Collection<BusinessBundleSummaryModelDao> createBusinessBundleSummaries(final Account account,
- final Long accountRecordId,
- final Collection<BusinessSubscriptionTransitionModelDao> bsts,
- final Long tenantRecordId,
- final ReportGroup reportGroup,
- final CallContext context) throws AnalyticsRefreshException {
- final Map<UUID, Integer> rankForBundle = new LinkedHashMap<UUID, Integer>();
- final Map<UUID, BusinessSubscriptionTransitionModelDao> bstForBundle = new LinkedHashMap<UUID, BusinessSubscriptionTransitionModelDao>();
- filterBstsForBasePlans(bsts, rankForBundle, bstForBundle);
-
- final Collection<BusinessBundleSummaryModelDao> bbss = new LinkedList<BusinessBundleSummaryModelDao>();
- for (final BusinessSubscriptionTransitionModelDao bst : bstForBundle.values()) {
- final BusinessBundleSummaryModelDao bbs = buildBBS(account,
- accountRecordId,
- bst,
- rankForBundle.get(bst.getBundleId()),
- tenantRecordId,
- reportGroup,
- context);
- bbss.add(bbs);
- }
- return bbss;
- }
-
- @VisibleForTesting
- void filterBstsForBasePlans(final Collection<BusinessSubscriptionTransitionModelDao> bsts, final Map<UUID, Integer> rankForBundle, final Map<UUID, BusinessSubscriptionTransitionModelDao> bstForBundle) {// Find bsts for BASE subscriptions only and sort them using the next start date
- final Collection<BusinessSubscriptionTransitionModelDao> sortedBundlesBst = Ordering.from(new Comparator<BusinessSubscriptionTransitionModelDao>() {
- @Override
- public int compare(final BusinessSubscriptionTransitionModelDao o1, final BusinessSubscriptionTransitionModelDao o2) {
- return o1.getNextStartDate().compareTo(o2.getNextStartDate());
- }
- }).sortedCopy(Iterables.filter(bsts, new Predicate<BusinessSubscriptionTransitionModelDao>() {
- @Override
- public boolean apply(final BusinessSubscriptionTransitionModelDao input) {
- return ProductCategory.BASE.toString().equals(input.getNextProductCategory());
- }
- }));
-
- UUID lastBundleId = null;
- Integer lastBundleRank = 0;
- for (final BusinessSubscriptionTransitionModelDao bst : sortedBundlesBst) {
- // Note that sortedBundlesBst is not ordered bundle by bundle, i.e. we may have:
- // bundleId1 CREATE, bundleId2 CREATE, bundleId1 PHASE, bundleId3 CREATE bundleId2 PHASE
- if (lastBundleId == null || (!lastBundleId.equals(bst.getBundleId()) && rankForBundle.get(bst.getBundleId()) == null)) {
- lastBundleRank++;
- lastBundleId = bst.getBundleId();
- rankForBundle.put(lastBundleId, lastBundleRank);
- }
-
- if (bstForBundle.get(bst.getBundleId()) == null ||
- bstForBundle.get(bst.getBundleId()).getNextStartDate().isBefore(bst.getNextStartDate())) {
- bstForBundle.put(bst.getBundleId(), bst);
- }
- }
- }
-
- private BusinessBundleSummaryModelDao buildBBS(final Account account, final Long accountRecordId, final BusinessSubscriptionTransitionModelDao bst, final Integer bundleAccountRank, final Long tenantRecordId, final ReportGroup reportGroup, final CallContext context) throws AnalyticsRefreshException {
- final SubscriptionBundle bundle = getSubscriptionBundle(bst.getBundleId(), context);
- final Long bundleRecordId = getBundleRecordId(bundle.getId(), context);
- final AuditLog creationAuditLog = getBundleCreationAuditLog(bundle.getId(), context);
-
- return new BusinessBundleSummaryModelDao(account,
- accountRecordId,
- bundle,
- bundleRecordId,
- bundleAccountRank,
- bst,
- creationAuditLog,
- tenantRecordId,
- reportGroup);
- }
}
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessFieldDao.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessFieldDao.java
index d1b330e..c205a88 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessFieldDao.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessFieldDao.java
@@ -17,35 +17,32 @@
package com.ning.billing.osgi.bundles.analytics.dao;
import java.util.Collection;
-import java.util.LinkedList;
import java.util.UUID;
import org.skife.jdbi.v2.Transaction;
import org.skife.jdbi.v2.TransactionStatus;
-import com.ning.billing.account.api.Account;
import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
+import com.ning.billing.osgi.bundles.analytics.dao.factory.BusinessFieldFactory;
import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessFieldModelDao;
-import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessModelDaoBase.ReportGroup;
-import com.ning.billing.util.audit.AuditLog;
import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.customfield.CustomField;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillDataSource;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
public class BusinessFieldDao extends BusinessAnalyticsDaoBase {
+ private final BusinessFieldFactory bFieldFactory;
+
public BusinessFieldDao(final OSGIKillbillLogService logService,
final OSGIKillbillAPI osgiKillbillAPI,
final OSGIKillbillDataSource osgiKillbillDataSource) {
- super(logService, osgiKillbillAPI, osgiKillbillDataSource);
+ super(osgiKillbillDataSource);
+ bFieldFactory = new BusinessFieldFactory(logService, osgiKillbillAPI);
}
public void update(final UUID accountId, final CallContext context) throws AnalyticsRefreshException {
- final Account account = getAccount(accountId, context);
-
- final Collection<BusinessFieldModelDao> fieldModelDaos = createBusinessFields(account, context);
+ final Collection<BusinessFieldModelDao> fieldModelDaos = bFieldFactory.createBusinessFields(accountId, context);
sqlDao.inTransaction(new Transaction<Void, BusinessAnalyticsSqlDao>() {
@Override
@@ -69,28 +66,4 @@ public class BusinessFieldDao extends BusinessAnalyticsDaoBase {
transactional.create(fieldModelDao.getTableName(), fieldModelDao, context);
}
}
-
- private Collection<BusinessFieldModelDao> createBusinessFields(final Account account, final CallContext context) throws AnalyticsRefreshException {
- final Long accountRecordId = getAccountRecordId(account.getId(), context);
- final Long tenantRecordId = getTenantRecordId(context);
- final ReportGroup reportGroup = getReportGroup(account.getId(), context);
-
- final Collection<CustomField> fields = getFieldsForAccount(account.getId(), context);
-
- final Collection<BusinessFieldModelDao> fieldModelDaos = new LinkedList<BusinessFieldModelDao>();
- for (final CustomField field : fields) {
- final Long customFieldRecordId = getFieldRecordId(field.getId(), context);
- final AuditLog creationAuditLog = getFieldCreationAuditLog(field.getId(), context);
- final BusinessFieldModelDao fieldModelDao = BusinessFieldModelDao.create(account,
- accountRecordId,
- field,
- customFieldRecordId,
- creationAuditLog,
- tenantRecordId,
- reportGroup);
- fieldModelDaos.add(fieldModelDao);
- }
-
- return fieldModelDaos;
- }
}
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessInvoiceAndInvoicePaymentDao.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessInvoiceAndInvoicePaymentDao.java
index d41d613..5a77d36 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessInvoiceAndInvoicePaymentDao.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessInvoiceAndInvoicePaymentDao.java
@@ -26,8 +26,10 @@ import java.util.UUID;
import org.skife.jdbi.v2.Transaction;
import org.skife.jdbi.v2.TransactionStatus;
-import com.ning.billing.account.api.Account;
import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
+import com.ning.billing.osgi.bundles.analytics.dao.factory.BusinessAccountFactory;
+import com.ning.billing.osgi.bundles.analytics.dao.factory.BusinessInvoiceFactory;
+import com.ning.billing.osgi.bundles.analytics.dao.factory.BusinessInvoicePaymentFactory;
import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessAccountModelDao;
import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceItemBaseModelDao;
import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceModelDao;
@@ -39,40 +41,47 @@ import com.ning.killbill.osgi.libs.killbill.OSGIKillbillDataSource;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Iterables;
/**
* Wrapper around BusinessInvoiceDao and BusinessInvoicePaymentDao.
* <p/>
- * These two should always be updated together as invoice and payment information is denormalized across tables.
+ * These two should always be updated together as invoice and payment information is denormalized across
+ * bot sets of tables.
*/
public class BusinessInvoiceAndInvoicePaymentDao extends BusinessAnalyticsDaoBase {
private final BusinessAccountDao businessAccountDao;
private final BusinessInvoiceDao businessInvoiceDao;
private final BusinessInvoicePaymentDao businessInvoicePaymentDao;
+ private final BusinessAccountFactory bacFactory;
+ private final BusinessInvoiceFactory binFactory;
+ private final BusinessInvoicePaymentFactory bipFactory;
public BusinessInvoiceAndInvoicePaymentDao(final OSGIKillbillLogService logService,
final OSGIKillbillAPI osgiKillbillAPI,
final OSGIKillbillDataSource osgiKillbillDataSource,
final BusinessAccountDao businessAccountDao) {
- super(logService, osgiKillbillAPI, osgiKillbillDataSource);
+ super(osgiKillbillDataSource);
this.businessAccountDao = businessAccountDao;
- this.businessInvoiceDao = new BusinessInvoiceDao(logService, osgiKillbillAPI, osgiKillbillDataSource);
- this.businessInvoicePaymentDao = new BusinessInvoicePaymentDao(logService, osgiKillbillAPI, osgiKillbillDataSource);
+ this.businessInvoiceDao = new BusinessInvoiceDao(osgiKillbillDataSource);
+ this.businessInvoicePaymentDao = new BusinessInvoicePaymentDao(osgiKillbillDataSource);
+ bacFactory = new BusinessAccountFactory(logService, osgiKillbillAPI);
+ binFactory = new BusinessInvoiceFactory(logService, osgiKillbillAPI);
+ bipFactory = new BusinessInvoicePaymentFactory(logService, osgiKillbillAPI);
}
public void update(final UUID accountId, final CallContext context) throws AnalyticsRefreshException {
- final Account account = getAccount(accountId, context);
-
// Recompute the account record
- final BusinessAccountModelDao bac = businessAccountDao.createBusinessAccount(account, context);
+ final BusinessAccountModelDao bac = bacFactory.createBusinessAccount(accountId, context);
+ // Recompute invoice, invoice items and invoice payments records
final Map<UUID, BusinessInvoiceModelDao> invoices = new HashMap<UUID, BusinessInvoiceModelDao>();
final Map<UUID, Collection<BusinessInvoiceItemBaseModelDao>> invoiceItems = new HashMap<UUID, Collection<BusinessInvoiceItemBaseModelDao>>();
final Map<UUID, Collection<BusinessInvoicePaymentBaseModelDao>> invoicePayments = new HashMap<UUID, Collection<BusinessInvoicePaymentBaseModelDao>>();
- createBusinessPojos(account, invoices, invoiceItems, invoicePayments, context);
+ createBusinessPojos(accountId, invoices, invoiceItems, invoicePayments, context);
- // Delete and recreate invoice and invoice items in the transaction
+ // Delete and recreate all items in the transaction
sqlDao.inTransaction(new Transaction<Void, BusinessAnalyticsSqlDao>() {
@Override
public Void inTransaction(final BusinessAnalyticsSqlDao transactional, final TransactionStatus status) throws Exception {
@@ -83,17 +92,17 @@ public class BusinessInvoiceAndInvoicePaymentDao extends BusinessAnalyticsDaoBas
}
@VisibleForTesting
- void createBusinessPojos(final Account account,
+ void createBusinessPojos(final UUID accountId,
final Map<UUID, BusinessInvoiceModelDao> invoices,
final Map<UUID, Collection<BusinessInvoiceItemBaseModelDao>> invoiceItems,
final Map<UUID, Collection<BusinessInvoicePaymentBaseModelDao>> invoicePayments,
final CallContext context) throws AnalyticsRefreshException {
// Recompute all invoices and invoice items. Invoices will have their denormalized payment fields missing,
// and items won't have neither invoice nor payment denormalized fields populated
- final Map<BusinessInvoiceModelDao, Collection<BusinessInvoiceItemBaseModelDao>> businessInvoices = businessInvoiceDao.createBusinessInvoicesAndInvoiceItems(account, context);
+ final Map<BusinessInvoiceModelDao, Collection<BusinessInvoiceItemBaseModelDao>> businessInvoices = binFactory.createBusinessInvoicesAndInvoiceItems(accountId, context);
// Recompute all invoice payments (without denormalized payment fields populated)
- final Collection<BusinessInvoicePaymentBaseModelDao> businessInvoicePayments = businessInvoicePaymentDao.createBusinessInvoicePayments(account, businessInvoices, context);
+ final Collection<BusinessInvoicePaymentBaseModelDao> businessInvoicePayments = bipFactory.createBusinessInvoicePayments(accountId, businessInvoices, context);
// Transform the results
for (final BusinessInvoiceModelDao businessInvoice : businessInvoices.keySet()) {
@@ -150,24 +159,29 @@ public class BusinessInvoiceAndInvoicePaymentDao extends BusinessAnalyticsDaoBas
}
}
+ /**
+ * Refresh the records. This does not perform any logic but simply deletes existing records and inserts the current ones.
+ *
+ * @param bac current, fully populated, BusinessAccountModelDao record
+ * @param invoices current, fully populated, mapping of invoice id -> BusinessInvoiceModelDao records
+ * @param invoiceItems current, fully populated, mapping of invoice id -> BusinessInvoiceItemBaseModelDao records
+ * @param invoicePayments current, fully populated, mapping of invoice id -> BusinessInvoicePaymentBaseModelDao records
+ * @param transactional current transaction
+ * @param context call context
+ */
private void updateInTransaction(final BusinessAccountModelDao bac,
final Map<UUID, BusinessInvoiceModelDao> invoices,
final Map<UUID, Collection<BusinessInvoiceItemBaseModelDao>> invoiceItems,
final Map<UUID, Collection<BusinessInvoicePaymentBaseModelDao>> invoicePayments,
final BusinessAnalyticsSqlDao transactional,
- final CallContext context) throws AnalyticsRefreshException {
- // Update invoice tables
+ final CallContext context) {
+ // Update invoice and invoice items tables
businessInvoiceDao.updateInTransaction(bac, invoices, invoiceItems, transactional, context);
// Update invoice payment tables
- // TODO flatten function?
- final Collection<BusinessInvoicePaymentBaseModelDao> flattenedInvoicePayments = new LinkedList<BusinessInvoicePaymentBaseModelDao>();
- for (final UUID invoiceId : invoicePayments.keySet()) {
- flattenedInvoicePayments.addAll(invoicePayments.get(invoiceId));
- }
- businessInvoicePaymentDao.updateInTransaction(bac, flattenedInvoicePayments, transactional, context);
+ businessInvoicePaymentDao.updateInTransaction(bac, Iterables.<BusinessInvoicePaymentBaseModelDao>concat(invoicePayments.values()), transactional, context);
- // Update invoice and payment details in BAC
+ // Update denormalized invoice and payment details in BAC
businessAccountDao.updateInTransaction(bac, transactional, context);
}
}
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 ee396ab..fe3f936 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
@@ -16,78 +16,37 @@
package com.ning.billing.osgi.bundles.analytics.dao;
-import java.math.BigDecimal;
import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
import java.util.Map;
-import java.util.Set;
import java.util.UUID;
-import javax.annotation.Nullable;
-
-import org.joda.time.DateTime;
-import org.joda.time.LocalDate;
-import org.osgi.service.log.LogService;
-
-import com.ning.billing.account.api.Account;
-import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.catalog.api.Plan;
-import com.ning.billing.catalog.api.PlanPhase;
-import com.ning.billing.entitlement.api.user.SubscriptionBundle;
-import com.ning.billing.invoice.api.Invoice;
-import com.ning.billing.invoice.api.InvoiceItem;
-import com.ning.billing.invoice.api.InvoiceItemType;
-import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessAccountModelDao;
import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceItemBaseModelDao;
-import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceItemBaseModelDao.BusinessInvoiceItemType;
import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceModelDao;
-import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessModelDaoBase.ReportGroup;
-import com.ning.billing.osgi.bundles.analytics.utils.BusinessInvoiceUtils;
-import com.ning.billing.util.audit.AuditLog;
import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.TenantContext;
-import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillDataSource;
-import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Predicate;
-import com.google.common.base.Strings;
-import com.google.common.collect.Collections2;
-
-import static com.ning.billing.osgi.bundles.analytics.utils.BusinessInvoiceUtils.isAccountCreditItem;
-import static com.ning.billing.osgi.bundles.analytics.utils.BusinessInvoiceUtils.isCharge;
-import static com.ning.billing.osgi.bundles.analytics.utils.BusinessInvoiceUtils.isInvoiceAdjustmentItem;
-import static com.ning.billing.osgi.bundles.analytics.utils.BusinessInvoiceUtils.isInvoiceItemAdjustmentItem;
-import static com.ning.billing.osgi.bundles.analytics.utils.BusinessInvoiceUtils.isRevenueRecognizable;
public class BusinessInvoiceDao extends BusinessAnalyticsDaoBase {
- public BusinessInvoiceDao(final OSGIKillbillLogService logService,
- final OSGIKillbillAPI osgiKillbillAPI,
- final OSGIKillbillDataSource osgiKillbillDataSource) {
- super(logService, osgiKillbillAPI, osgiKillbillDataSource);
+ public BusinessInvoiceDao(final OSGIKillbillDataSource osgiKillbillDataSource) {
+ super(osgiKillbillDataSource);
}
+ /**
+ * Delete all invoice and invoice item records and insert the specified ones as current.
+ *
+ * @param bac current, fully populated, BusinessAccountModelDao record
+ * @param businessInvoices current, fully populated, mapping of invoice id -> BusinessInvoiceModelDao records
+ * @param businessInvoiceItems current, fully populated, mapping of invoice id -> BusinessInvoiceItemBaseModelDao records
+ * @param transactional current transaction
+ * @param context call context
+ */
public void updateInTransaction(final BusinessAccountModelDao bac,
final Map<UUID, BusinessInvoiceModelDao> businessInvoices,
final Map<UUID, Collection<BusinessInvoiceItemBaseModelDao>> businessInvoiceItems,
final BusinessAnalyticsSqlDao transactional,
- final CallContext context) throws AnalyticsRefreshException {
- rebuildInvoicesForAccountInTransaction(bac, businessInvoices, businessInvoiceItems, transactional, context);
- // Invoice and payment details in BAC will be updated by BusinessInvoiceAndInvoicePaymentDao
- }
-
- private void rebuildInvoicesForAccountInTransaction(final BusinessAccountModelDao account,
- final Map<UUID, BusinessInvoiceModelDao> businessInvoices,
- final Map<UUID, Collection<BusinessInvoiceItemBaseModelDao>> businessInvoiceItems,
- final BusinessAnalyticsSqlDao transactional,
- final CallContext context) {
- deleteInvoicesAndInvoiceItemsForAccountInTransaction(transactional, account.getAccountRecordId(), account.getTenantRecordId(), context);
+ final CallContext context) {
+ deleteInvoicesAndInvoiceItemsForAccountInTransaction(transactional, bac.getAccountRecordId(), bac.getTenantRecordId(), context);
for (final BusinessInvoiceModelDao businessInvoice : businessInvoices.values()) {
final Collection<BusinessInvoiceItemBaseModelDao> invoiceItems = businessInvoiceItems.get(businessInvoice.getInvoiceId());
@@ -95,6 +54,8 @@ public class BusinessInvoiceDao extends BusinessAnalyticsDaoBase {
createInvoiceInTransaction(transactional, businessInvoice, invoiceItems, context);
}
}
+
+ // Invoice and payment details in BAC will be updated by BusinessInvoiceAndInvoicePaymentDao
}
private void deleteInvoicesAndInvoiceItemsForAccountInTransaction(final BusinessAnalyticsSqlDao transactional,
@@ -122,522 +83,4 @@ public class BusinessInvoiceDao extends BusinessAnalyticsDaoBase {
transactional.create(invoiceItem.getTableName(), invoiceItem, context);
}
}
-
- /**
- * Create business invoices and invoice items to record. Note that these POJOs are incomplete
- * (denormalized payment fields have not yet been populated)
- *
- * @param account current account refreshed
- * @param context call context
- * @return all business invoice and invoice items to create
- * @throws AnalyticsRefreshException
- */
- public Map<BusinessInvoiceModelDao, Collection<BusinessInvoiceItemBaseModelDao>> createBusinessInvoicesAndInvoiceItems(final Account account,
- final CallContext context) throws AnalyticsRefreshException {
- final Long accountRecordId = getAccountRecordId(account.getId(), context);
- final Long tenantRecordId = getTenantRecordId(context);
- final ReportGroup reportGroup = getReportGroup(account.getId(), context);
-
- // Lookup the invoices for that account
- final Collection<Invoice> invoices = getInvoicesByAccountId(account.getId(), context);
-
- // All invoice items across all invoices for that accounr (we need to be able to reference items across multiple invoices)
- final Collection<InvoiceItem> allInvoiceItems = new LinkedList<InvoiceItem>();
- // Convenient mapping invoice_id -> invoice
- final Map<UUID, Invoice> invoiceIdToInvoiceMappings = new LinkedHashMap<UUID, Invoice>();
- for (final Invoice invoice : invoices) {
- invoiceIdToInvoiceMappings.put(invoice.getId(), invoice);
- allInvoiceItems.addAll(invoice.getInvoiceItems());
- }
-
- // Sanitize (cherry-pick, merge) the items
- final Collection<InvoiceItem> sanitizedInvoiceItems = sanitizeInvoiceItems(allInvoiceItems);
-
- // Create the business invoice items. These are incomplete (the denormalized invoice fields haven't been computed yet)
- final Map<UUID, Collection<BusinessInvoiceItemBaseModelDao>> businessInvoiceItemsForInvoiceId = new HashMap<UUID, Collection<BusinessInvoiceItemBaseModelDao>>();
- for (final InvoiceItem invoiceItem : sanitizedInvoiceItems) {
- final Invoice invoice = invoiceIdToInvoiceMappings.get(invoiceItem.getInvoiceId());
- final BusinessInvoiceItemBaseModelDao businessInvoiceItem = createBusinessInvoiceItem(account,
- invoice,
- invoiceItem,
- Collections2.filter(sanitizedInvoiceItems,
- new Predicate<InvoiceItem>() {
- @Override
- public boolean apply(final InvoiceItem input) {
- return !input.getId().equals(invoiceItem.getId());
- }
- }),
- accountRecordId,
- tenantRecordId,
- reportGroup,
- context);
- if (businessInvoiceItem != null) {
- if (businessInvoiceItemsForInvoiceId.get(invoice.getId()) == null) {
- businessInvoiceItemsForInvoiceId.put(invoice.getId(), new LinkedList<BusinessInvoiceItemBaseModelDao>());
- }
- businessInvoiceItemsForInvoiceId.get(invoice.getId()).add(businessInvoiceItem);
- }
- }
-
- // Now, create the business invoices
- final Map<BusinessInvoiceModelDao, Collection<BusinessInvoiceItemBaseModelDao>> businessRecords = new HashMap<BusinessInvoiceModelDao, Collection<BusinessInvoiceItemBaseModelDao>>();
- for (final Invoice invoice : invoices) {
- final Collection<BusinessInvoiceItemBaseModelDao> businessInvoiceItems = businessInvoiceItemsForInvoiceId.get(invoice.getId());
- if (businessInvoiceItems == null) {
- continue;
- }
-
- final BusinessInvoiceModelDao businessInvoice = createBusinessInvoice(account, invoice, businessInvoiceItems, accountRecordId, tenantRecordId, reportGroup, context);
- businessRecords.put(businessInvoice, businessInvoiceItems);
- }
-
- return businessRecords;
- }
-
- private BusinessInvoiceModelDao createBusinessInvoice(final Account account,
- final Invoice invoice,
- final Collection<BusinessInvoiceItemBaseModelDao> businessInvoiceItems,
- final Long accountRecordId,
- final Long tenantRecordId,
- @Nullable final ReportGroup reportGroup,
- final CallContext context) throws AnalyticsRefreshException {
- final Long invoiceRecordId = getInvoiceRecordId(invoice.getId(), context);
- final AuditLog creationAuditLog = getInvoiceCreationAuditLog(invoice.getId(), context);
-
- final BigDecimal amountCharged = BusinessInvoiceUtils.computeInvoiceAmountCharged(businessInvoiceItems);
- final BigDecimal originalAmountCharged = BusinessInvoiceUtils.computeInvoiceOriginalAmountCharged(businessInvoiceItems);
- final BigDecimal amountCredited = BusinessInvoiceUtils.computeInvoiceAmountCredited(businessInvoiceItems);
-
- return new BusinessInvoiceModelDao(account,
- accountRecordId,
- invoice,
- amountCharged,
- originalAmountCharged,
- amountCredited,
- invoiceRecordId,
- creationAuditLog,
- tenantRecordId,
- reportGroup);
- }
-
- private BusinessInvoiceItemBaseModelDao createBusinessInvoiceItem(final Account account,
- final Invoice invoice,
- final InvoiceItem invoiceItem,
- final Collection<InvoiceItem> otherInvoiceItems,
- final Long accountRecordId,
- final Long tenantRecordId,
- @Nullable final ReportGroup reportGroup,
- final TenantContext context) throws AnalyticsRefreshException {
- SubscriptionBundle bundle = null;
- // Subscription and bundle could be null for e.g. credits or adjustments
- if (invoiceItem.getBundleId() != null) {
- bundle = getSubscriptionBundle(invoiceItem.getBundleId(), context);
- }
-
- Plan plan = null;
- if (Strings.emptyToNull(invoiceItem.getPlanName()) != null) {
- plan = getPlanFromInvoiceItem(invoiceItem, context);
- }
-
- PlanPhase planPhase = null;
- if (invoiceItem.getSubscriptionId() != null && Strings.emptyToNull(invoiceItem.getPhaseName()) != null) {
- planPhase = getPlanPhaseFromInvoiceItem(invoiceItem, context);
- }
-
- final Long invoiceItemRecordId = getInvoiceItemRecordId(invoiceItem.getId(), context);
- final AuditLog creationAuditLog = getInvoiceItemCreationAuditLog(invoiceItem.getId(), context);
-
- return createBusinessInvoiceItem(account,
- invoice,
- invoiceItem,
- otherInvoiceItems,
- bundle,
- plan,
- planPhase,
- invoiceItemRecordId,
- creationAuditLog,
- accountRecordId,
- tenantRecordId,
- reportGroup,
- context);
- }
-
- @VisibleForTesting
- BusinessInvoiceItemBaseModelDao createBusinessInvoiceItem(final Account account,
- final Invoice invoice,
- final InvoiceItem invoiceItem,
- final Collection<InvoiceItem> otherInvoiceItems,
- @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;
- } else if (isAccountCreditItem(invoiceItem)) {
- businessInvoiceItemType = BusinessInvoiceItemType.ACCOUNT_CREDIT;
- } else if (isInvoiceItemAdjustmentItem(invoiceItem)) {
- businessInvoiceItemType = BusinessInvoiceItemType.INVOICE_ITEM_ADJUSTMENT;
- } else if (isInvoiceAdjustmentItem(invoiceItem, otherInvoiceItems)) {
- businessInvoiceItemType = BusinessInvoiceItemType.INVOICE_ADJUSTMENT;
- } else {
- // We don't care
- return null;
- }
-
- final Boolean revenueRecognizable = isRevenueRecognizable(invoiceItem, otherInvoiceItems);
-
- final Long secondInvoiceItemRecordId;
- if (invoiceItem instanceof AdjustmentInvoiceItemForRepair) {
- secondInvoiceItemRecordId = getInvoiceItemRecordId(((AdjustmentInvoiceItemForRepair) invoiceItem).getSecondId(), context);
- } else {
- secondInvoiceItemRecordId = null;
- }
-
- return BusinessInvoiceItemBaseModelDao.create(account,
- accountRecordId,
- invoice,
- invoiceItem,
- revenueRecognizable,
- businessInvoiceItemType,
- invoiceItemRecordId,
- secondInvoiceItemRecordId,
- bundle,
- plan,
- planPhase,
- creationAuditLog,
- tenantRecordId,
- reportGroup);
- }
-
- /**
- * Filter and transform the original invoice items for Analytics purposes. We mainly
- * merge REPAIR_ADJ items with reparation items (reparees) to create item adjustments.
- *
- * @param allInvoiceItems all items for the current account
- * @return invoice items interesting for Analytics purposes
- */
- @VisibleForTesting
- Collection<InvoiceItem> sanitizeInvoiceItems(final Collection<InvoiceItem> allInvoiceItems) {
- // Build a convenience mapping between items -> repair_adj items (inverse of linkedItemId)
- final Map<UUID, InvoiceItem> repairedInvoiceItemIdToRepairInvoiceItemMappings = new HashMap<UUID, InvoiceItem>();
- for (final InvoiceItem invoiceItem : allInvoiceItems) {
- if (InvoiceItemType.REPAIR_ADJ.equals(invoiceItem.getInvoiceItemType())) {
- repairedInvoiceItemIdToRepairInvoiceItemMappings.put(invoiceItem.getLinkedItemId(), invoiceItem);
- }
- }
-
- // Now find the "reparation" items, i.e. the ones which correspond to the repaired items
- final Map<UUID, InvoiceItem> reparationInvoiceItemIdToRepairItemMappings = new LinkedHashMap<UUID, InvoiceItem>();
- for (final InvoiceItem repairedInvoiceItem : allInvoiceItems) {
- // Skip non-repaired items
- if (!repairedInvoiceItemIdToRepairInvoiceItemMappings.keySet().contains(repairedInvoiceItem.getId())) {
- continue;
- }
-
- InvoiceItem reparationItem = null;
- for (final InvoiceItem invoiceItem : allInvoiceItems) {
- // Try to find the matching "reparation" item
- if (repairedInvoiceItem.getInvoiceItemType().equals(invoiceItem.getInvoiceItemType()) &&
- repairedInvoiceItem.getSubscriptionId().equals(invoiceItem.getSubscriptionId()) &&
- repairedInvoiceItem.getStartDate().compareTo(invoiceItem.getStartDate()) == 0 &&
- // FIXED items have a null end date
- ((repairedInvoiceItem.getEndDate() == null && invoiceItem.getEndDate() == null) ||
- (repairedInvoiceItem.getEndDate() != null && invoiceItem.getEndDate() != null && !repairedInvoiceItem.getEndDate().isBefore(invoiceItem.getEndDate()))) &&
- !repairedInvoiceItem.getId().equals(invoiceItem.getId())) {
- if (reparationItem == null) {
- reparationItem = invoiceItem;
- } else {
- logService.log(LogService.LOG_ERROR, "Found multiple reparation items matching the repair item id " + repairedInvoiceItem.getId() + " - this should never happen!");
- }
- }
- }
-
- if (reparationItem != null) {
- reparationInvoiceItemIdToRepairItemMappings.put(reparationItem.getId(), repairedInvoiceItemIdToRepairInvoiceItemMappings.get(repairedInvoiceItem.getId()));
- } else {
- logService.log(LogService.LOG_ERROR, "Could not find the reparation item for the repair item id " + repairedInvoiceItem.getId() + " - this should never happen!");
- }
- }
-
- // We now need to adjust the CBA_ADJ for the repair items
- final Set<UUID> cbasToIgnore = new HashSet<UUID>();
- final Collection<AdjustedCBAInvoiceItem> newCbasToAdd = new LinkedList<AdjustedCBAInvoiceItem>();
- for (final InvoiceItem cbaInvoiceItem : allInvoiceItems) {
- if (!InvoiceItemType.CBA_ADJ.equals(cbaInvoiceItem.getInvoiceItemType())) {
- continue;
- }
-
- for (final InvoiceItem invoiceItem : allInvoiceItems) {
- if (reparationInvoiceItemIdToRepairItemMappings.keySet().contains(invoiceItem.getId())) {
- final InvoiceItem repairInvoiceItem = reparationInvoiceItemIdToRepairItemMappings.get(invoiceItem.getId());
- final InvoiceItem reparationInvoiceItem = invoiceItem;
- // Au petit bonheur la chance... There is nothing else against to compare
- if (repairInvoiceItem.getAmount().negate().compareTo(cbaInvoiceItem.getAmount()) == 0) {
- cbasToIgnore.add(cbaInvoiceItem.getId());
- newCbasToAdd.add(new AdjustedCBAInvoiceItem(cbaInvoiceItem, cbaInvoiceItem.getAmount().add(reparationInvoiceItem.getAmount().negate()), reparationInvoiceItem.getId()));
-
- // Now, fiddle with the CBA used on the reparation invoice
- for (final InvoiceItem cbaUsedOnNextInvoiceItem : allInvoiceItems) {
- if (!InvoiceItemType.CBA_ADJ.equals(cbaUsedOnNextInvoiceItem.getInvoiceItemType()) ||
- !cbaUsedOnNextInvoiceItem.getInvoiceId().equals(reparationInvoiceItem.getInvoiceId())) {
- continue;
- }
-
- // Au petit bonheur la chance... There is nothing else against to compare. Take the first one again?
- cbasToIgnore.add(cbaUsedOnNextInvoiceItem.getId());
- newCbasToAdd.add(new AdjustedCBAInvoiceItem(cbaUsedOnNextInvoiceItem, cbaUsedOnNextInvoiceItem.getAmount().add(reparationInvoiceItem.getAmount()), reparationInvoiceItem.getId()));
- break;
- }
-
- // Break from the inner loop only
- break;
- }
- }
- }
- }
-
-
- // Filter the invoice items for analytics
- final Collection<InvoiceItem> invoiceItemsForAnalytics = new LinkedList<InvoiceItem>();
- for (final InvoiceItem invoiceItem : allInvoiceItems) {
- if (cbasToIgnore.contains(invoiceItem.getId())) {
- // We don't care
- } else if (InvoiceItemType.REPAIR_ADJ.equals(invoiceItem.getInvoiceItemType())) {
- // We don't care, we'll create a special item for it below
- } else if (reparationInvoiceItemIdToRepairItemMappings.keySet().contains(invoiceItem.getId())) {
- // We do care - this is a reparation item. Create an item adjustment for it
- final InvoiceItem repairInvoiceItem = reparationInvoiceItemIdToRepairItemMappings.get(invoiceItem.getId());
- final InvoiceItem reparationInvoiceItem = invoiceItem;
- invoiceItemsForAnalytics.add(new AdjustmentInvoiceItemForRepair(repairInvoiceItem, reparationInvoiceItem));
- } else {
- invoiceItemsForAnalytics.add(invoiceItem);
- }
- }
- invoiceItemsForAnalytics.addAll(newCbasToAdd);
-
- return invoiceItemsForAnalytics;
- }
-
- private class AdjustedCBAInvoiceItem implements InvoiceItem {
-
- private final InvoiceItem cbaInvoiceItem;
- private final BigDecimal amount;
- private final UUID reparationItemId;
-
- private AdjustedCBAInvoiceItem(final InvoiceItem cbaInvoiceItem,
- final BigDecimal amount,
- final UUID reparationItemId) {
- this.cbaInvoiceItem = cbaInvoiceItem;
- this.amount = amount;
- this.reparationItemId = reparationItemId;
- }
-
- @Override
- public InvoiceItemType getInvoiceItemType() {
- return InvoiceItemType.CBA_ADJ;
- }
-
- @Override
- public UUID getInvoiceId() {
- return cbaInvoiceItem.getInvoiceId();
- }
-
- @Override
- public UUID getAccountId() {
- return cbaInvoiceItem.getAccountId();
- }
-
- @Override
- public LocalDate getStartDate() {
- return cbaInvoiceItem.getStartDate();
- }
-
- @Override
- public LocalDate getEndDate() {
- return cbaInvoiceItem.getStartDate();
- }
-
- @Override
- public BigDecimal getAmount() {
- return amount;
- }
-
- @Override
- public Currency getCurrency() {
- return cbaInvoiceItem.getCurrency();
- }
-
- @Override
- public String getDescription() {
- return cbaInvoiceItem.getDescription();
- }
-
- @Override
- public UUID getBundleId() {
- return cbaInvoiceItem.getBundleId();
- }
-
- @Override
- public UUID getSubscriptionId() {
- return cbaInvoiceItem.getSubscriptionId();
- }
-
- @Override
- public String getPlanName() {
- return cbaInvoiceItem.getPlanName();
- }
-
- @Override
- public String getPhaseName() {
- return cbaInvoiceItem.getPhaseName();
- }
-
- @Override
- public BigDecimal getRate() {
- return cbaInvoiceItem.getRate();
- }
-
- @Override
- public UUID getLinkedItemId() {
- return cbaInvoiceItem.getLinkedItemId();
- }
-
- @Override
- public boolean matches(final Object other) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public UUID getId() {
- return cbaInvoiceItem.getId();
- }
-
- public UUID getSecondId() {
- return reparationItemId;
- }
-
- @Override
- public DateTime getCreatedDate() {
- return cbaInvoiceItem.getCreatedDate();
- }
-
- @Override
- public DateTime getUpdatedDate() {
- return cbaInvoiceItem.getUpdatedDate();
- }
- }
-
- private class AdjustmentInvoiceItemForRepair implements InvoiceItem {
-
- private final InvoiceItem repairInvoiceItem;
- private final InvoiceItem reparationInvoiceItem;
-
- private AdjustmentInvoiceItemForRepair(final InvoiceItem repairInvoiceItem,
- final InvoiceItem reparationInvoiceItem) {
- this.repairInvoiceItem = repairInvoiceItem;
- this.reparationInvoiceItem = reparationInvoiceItem;
- }
-
- @Override
- public InvoiceItemType getInvoiceItemType() {
- return InvoiceItemType.ITEM_ADJ;
- }
-
- @Override
- public UUID getInvoiceId() {
- return repairInvoiceItem.getInvoiceId();
- }
-
- @Override
- public UUID getAccountId() {
- return repairInvoiceItem.getAccountId();
- }
-
- @Override
- public LocalDate getStartDate() {
- return repairInvoiceItem.getStartDate();
- }
-
- @Override
- public LocalDate getEndDate() {
- return repairInvoiceItem.getStartDate();
- }
-
- @Override
- public BigDecimal getAmount() {
- return reparationInvoiceItem.getAmount().add(repairInvoiceItem.getAmount());
- }
-
- @Override
- public Currency getCurrency() {
- return repairInvoiceItem.getCurrency();
- }
-
- @Override
- public String getDescription() {
- return null;
- }
-
- @Override
- public UUID getBundleId() {
- return null;
- }
-
- @Override
- public UUID getSubscriptionId() {
- return null;
- }
-
- @Override
- public String getPlanName() {
- return null;
- }
-
- @Override
- public String getPhaseName() {
- return null;
- }
-
- @Override
- public BigDecimal getRate() {
- return null;
- }
-
- @Override
- public UUID getLinkedItemId() {
- return repairInvoiceItem.getLinkedItemId();
- }
-
- @Override
- public boolean matches(final Object other) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public UUID getId() {
- // We pretend to be the repair, the reparation item record id
- // will be available as secondId
- return repairInvoiceItem.getId();
- }
-
- public UUID getSecondId() {
- return reparationInvoiceItem.getId();
- }
-
- @Override
- public DateTime getCreatedDate() {
- return repairInvoiceItem.getCreatedDate();
- }
-
- @Override
- public DateTime getUpdatedDate() {
- return repairInvoiceItem.getUpdatedDate();
- }
- }
}
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessInvoicePaymentDao.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessInvoicePaymentDao.java
index 423024c..a3b4276 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessInvoicePaymentDao.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessInvoicePaymentDao.java
@@ -16,50 +16,29 @@
package com.ning.billing.osgi.bundles.analytics.dao;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.Map;
-
-import javax.annotation.Nullable;
-
-import com.ning.billing.account.api.Account;
-import com.ning.billing.invoice.api.Invoice;
-import com.ning.billing.invoice.api.InvoicePayment;
-import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessAccountModelDao;
-import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceItemBaseModelDao;
-import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceModelDao;
import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoicePaymentBaseModelDao;
-import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessModelDaoBase.ReportGroup;
-import com.ning.billing.payment.api.Payment;
-import com.ning.billing.payment.api.PaymentMethod;
-import com.ning.billing.payment.api.Refund;
-import com.ning.billing.util.audit.AuditLog;
import com.ning.billing.util.callcontext.CallContext;
-import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillDataSource;
-import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
public class BusinessInvoicePaymentDao extends BusinessAnalyticsDaoBase {
- public BusinessInvoicePaymentDao(final OSGIKillbillLogService logService,
- final OSGIKillbillAPI osgiKillbillAPI,
- final OSGIKillbillDataSource osgiKillbillDataSource) {
- super(logService, osgiKillbillAPI, osgiKillbillDataSource);
+ public BusinessInvoicePaymentDao(final OSGIKillbillDataSource osgiKillbillDataSource) {
+ super(osgiKillbillDataSource);
}
+ /**
+ * Delete all invoice payment records and insert the specified ones as current.
+ *
+ * @param bac current, fully populated, BusinessAccountModelDao record
+ * @param businessInvoicePayments current, fully populated, mapping of invoice id -> BusinessInvoicePaymentBaseModelDao records
+ * @param transactional current transaction
+ * @param context call context
+ */
public void updateInTransaction(final BusinessAccountModelDao bac,
- final Collection<BusinessInvoicePaymentBaseModelDao> businessInvoicePayments,
+ final Iterable<BusinessInvoicePaymentBaseModelDao> businessInvoicePayments,
final BusinessAnalyticsSqlDao transactional,
- final CallContext context) throws AnalyticsRefreshException {
- rebuildInvoicePaymentsForAccountInTransaction(bac, businessInvoicePayments, transactional, context);
- // Invoice and payment details in BAC will be updated by BusinessInvoiceAndInvoicePaymentDao
- }
-
- private void rebuildInvoicePaymentsForAccountInTransaction(final BusinessAccountModelDao bac,
- final Collection<BusinessInvoicePaymentBaseModelDao> businessInvoicePayments,
- final BusinessAnalyticsSqlDao transactional,
- final CallContext context) throws AnalyticsRefreshException {
+ final CallContext context) {
for (final String tableName : BusinessInvoicePaymentBaseModelDao.ALL_INVOICE_PAYMENTS_TABLE_NAMES) {
transactional.deleteByAccountRecordId(tableName, bac.getAccountRecordId(), bac.getTenantRecordId(), context);
}
@@ -67,63 +46,7 @@ public class BusinessInvoicePaymentDao extends BusinessAnalyticsDaoBase {
for (final BusinessInvoicePaymentBaseModelDao invoicePayment : businessInvoicePayments) {
transactional.create(invoicePayment.getTableName(), invoicePayment, context);
}
- }
-
- public Collection<BusinessInvoicePaymentBaseModelDao> createBusinessInvoicePayments(final Account account,
- final Map<BusinessInvoiceModelDao, Collection<BusinessInvoiceItemBaseModelDao>> businessInvoices,
- final CallContext context) throws AnalyticsRefreshException {
- final Collection<BusinessInvoicePaymentBaseModelDao> businessInvoicePayments = new LinkedList<BusinessInvoicePaymentBaseModelDao>();
- final Long accountRecordId = getAccountRecordId(account.getId(), context);
- final Long tenantRecordId = getTenantRecordId(context);
- final ReportGroup reportGroup = getReportGroup(account.getId(), context);
-
- final Collection<InvoicePayment> invoicePayments = getAccountInvoicePayments(account.getId(), context);
- for (final InvoicePayment invoicePayment : invoicePayments) {
- final BusinessInvoicePaymentBaseModelDao businessInvoicePayment = createBusinessInvoicePayment(account,
- invoicePayment,
- businessInvoices,
- accountRecordId,
- tenantRecordId,
- reportGroup,
- context);
- if (businessInvoicePayment != null) {
- businessInvoicePayments.add(businessInvoicePayment);
- }
- }
-
- return businessInvoicePayments;
- }
-
- private BusinessInvoicePaymentBaseModelDao createBusinessInvoicePayment(final Account account,
- final InvoicePayment invoicePayment,
- final Map<BusinessInvoiceModelDao, Collection<BusinessInvoiceItemBaseModelDao>> businessInvoices,
- final Long accountRecordId,
- final Long tenantRecordId,
- @Nullable final ReportGroup reportGroup,
- final CallContext context) throws AnalyticsRefreshException {
- final Long invoicePaymentRecordId = getInvoicePaymentRecordId(invoicePayment.getId(), context);
-
- final Payment payment = getPaymentWithPluginInfo(invoicePayment.getPaymentId(), context);
- Refund refund = null;
- if (invoicePayment.getPaymentCookieId() != null) {
- refund = getRefundWithPluginInfo(invoicePayment.getPaymentCookieId(), context);
- }
-
- final Invoice invoice = getInvoice(invoicePayment.getInvoiceId(), context);
- final PaymentMethod paymentMethod = getPaymentMethod(payment.getPaymentMethodId(), context);
- final AuditLog creationAuditLog = getInvoicePaymentCreationAuditLog(invoicePayment.getId(), context);
-
- return BusinessInvoicePaymentBaseModelDao.create(account,
- accountRecordId,
- invoice,
- invoicePayment,
- invoicePaymentRecordId,
- payment,
- refund,
- paymentMethod,
- creationAuditLog,
- tenantRecordId,
- reportGroup);
+ // Invoice and payment details in BAC will be updated by BusinessInvoiceAndInvoicePaymentDao
}
}
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessOverdueStatusDao.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessOverdueStatusDao.java
index 9812140..27352ed 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessOverdueStatusDao.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessOverdueStatusDao.java
@@ -17,37 +17,32 @@
package com.ning.billing.osgi.bundles.analytics.dao;
import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
import java.util.UUID;
-import org.joda.time.DateTime;
import org.osgi.service.log.LogService;
import org.skife.jdbi.v2.Transaction;
import org.skife.jdbi.v2.TransactionStatus;
import com.ning.billing.ObjectType;
-import com.ning.billing.account.api.Account;
-import com.ning.billing.entitlement.api.user.SubscriptionBundle;
-import com.ning.billing.junction.api.BlockingState;
import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
-import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessModelDaoBase.ReportGroup;
+import com.ning.billing.osgi.bundles.analytics.dao.factory.BusinessOverdueStatusFactory;
import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessOverdueStatusModelDao;
-import com.ning.billing.util.audit.AuditLog;
import com.ning.billing.util.callcontext.CallContext;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillDataSource;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-
public class BusinessOverdueStatusDao extends BusinessAnalyticsDaoBase {
+ private final LogService logService;
+ private final BusinessOverdueStatusFactory bosFactory;
+
public BusinessOverdueStatusDao(final OSGIKillbillLogService logService,
final OSGIKillbillAPI osgiKillbillAPI,
final OSGIKillbillDataSource osgiKillbillDataSource) {
- super(logService, osgiKillbillAPI, osgiKillbillDataSource);
+ super(osgiKillbillDataSource);
+ this.logService = logService;
+ bosFactory = new BusinessOverdueStatusFactory(logService, osgiKillbillAPI);
}
public void update(final UUID accountId, final ObjectType objectType, final CallContext context) throws AnalyticsRefreshException {
@@ -59,14 +54,7 @@ public class BusinessOverdueStatusDao extends BusinessAnalyticsDaoBase {
}
private void updateForBundle(final UUID accountId, final CallContext context) throws AnalyticsRefreshException {
- final Account account = getAccount(accountId, context);
-
- final Collection<SubscriptionBundle> bundles = getSubscriptionBundlesForAccount(accountId, context);
- final Collection<BusinessOverdueStatusModelDao> businessOverdueStatuses = new LinkedList<BusinessOverdueStatusModelDao>();
- for (final SubscriptionBundle bundle : bundles) {
- // Recompute all blocking states for that bundle
- businessOverdueStatuses.addAll(createBusinessOverdueStatuses(account, bundle, context));
- }
+ final Collection<BusinessOverdueStatusModelDao> businessOverdueStatuses = bosFactory.createBusinessOverdueStatuses(accountId, context);
sqlDao.inTransaction(new Transaction<Void, BusinessAnalyticsSqlDao>() {
@Override
@@ -89,39 +77,4 @@ public class BusinessOverdueStatusDao extends BusinessAnalyticsDaoBase {
transactional.create(bst.getTableName(), bst, context);
}
}
-
- private Collection<BusinessOverdueStatusModelDao> createBusinessOverdueStatuses(final Account account,
- final SubscriptionBundle subscriptionBundle,
- final CallContext context) throws AnalyticsRefreshException {
- final Collection<BusinessOverdueStatusModelDao> businessOverdueStatuses = new LinkedList<BusinessOverdueStatusModelDao>();
-
- final List<BlockingState> blockingStatesOrdered = getBlockingHistory(subscriptionBundle.getId(), context);
- if (blockingStatesOrdered.size() == 0) {
- return businessOverdueStatuses;
- }
-
- final Long accountRecordId = getAccountRecordId(account.getId(), context);
- final Long tenantRecordId = getTenantRecordId(context);
- final ReportGroup reportGroup = getReportGroup(account.getId(), context);
-
- final List<BlockingState> blockingStates = Lists.reverse(ImmutableList.<BlockingState>copyOf(blockingStatesOrdered));
- DateTime previousStartDate = null;
- for (final BlockingState state : blockingStates) {
- final Long blockingStateRecordId = getBlockingStateRecordId(state.getId(), context);
- final AuditLog creationAuditLog = getBlockingStateCreationAuditLog(state.getId(), context);
- final BusinessOverdueStatusModelDao overdueStatus = new BusinessOverdueStatusModelDao(account,
- accountRecordId,
- subscriptionBundle,
- state,
- blockingStateRecordId,
- previousStartDate,
- creationAuditLog,
- tenantRecordId,
- reportGroup);
- businessOverdueStatuses.add(overdueStatus);
- previousStartDate = state.getTimestamp();
- }
-
- return businessOverdueStatuses;
- }
}
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessSubscriptionTransitionDao.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessSubscriptionTransitionDao.java
index b3fda1c..8f5dcf0 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessSubscriptionTransitionDao.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessSubscriptionTransitionDao.java
@@ -17,27 +17,18 @@
package com.ning.billing.osgi.bundles.analytics.dao;
import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
import java.util.UUID;
-import javax.annotation.Nullable;
-
import org.skife.jdbi.v2.Transaction;
import org.skife.jdbi.v2.TransactionStatus;
-import com.ning.billing.account.api.Account;
-import com.ning.billing.entitlement.api.user.Subscription;
-import com.ning.billing.entitlement.api.user.SubscriptionBundle;
-import com.ning.billing.entitlement.api.user.SubscriptionTransition;
import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
+import com.ning.billing.osgi.bundles.analytics.dao.factory.BusinessAccountFactory;
+import com.ning.billing.osgi.bundles.analytics.dao.factory.BusinessBundleSummaryFactory;
+import com.ning.billing.osgi.bundles.analytics.dao.factory.BusinessSubscriptionTransitionFactory;
import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessAccountModelDao;
import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessBundleSummaryModelDao;
-import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessModelDaoBase.ReportGroup;
-import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscription;
-import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscriptionEvent;
import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscriptionTransitionModelDao;
-import com.ning.billing.util.audit.AuditLog;
import com.ning.billing.util.callcontext.CallContext;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillDataSource;
@@ -47,37 +38,38 @@ public class BusinessSubscriptionTransitionDao extends BusinessAnalyticsDaoBase
private final BusinessAccountDao businessAccountDao;
private final BusinessBundleSummaryDao businessBundleSummaryDao;
+ private final BusinessAccountFactory bacFactory;
+ private final BusinessBundleSummaryFactory bbsFactory;
+ private final BusinessSubscriptionTransitionFactory bstFactory;
public BusinessSubscriptionTransitionDao(final OSGIKillbillLogService logService,
final OSGIKillbillAPI osgiKillbillAPI,
final OSGIKillbillDataSource osgiKillbillDataSource,
final BusinessAccountDao businessAccountDao) {
- super(logService, osgiKillbillAPI, osgiKillbillDataSource);
+ super(osgiKillbillDataSource);
this.businessAccountDao = businessAccountDao;
this.businessBundleSummaryDao = new BusinessBundleSummaryDao(logService, osgiKillbillAPI, osgiKillbillDataSource);
+ bacFactory = new BusinessAccountFactory(logService, osgiKillbillAPI);
+ bbsFactory = new BusinessBundleSummaryFactory(logService, osgiKillbillAPI);
+ bstFactory = new BusinessSubscriptionTransitionFactory(logService, osgiKillbillAPI);
}
public void update(final UUID accountId, final CallContext context) throws AnalyticsRefreshException {
- final Account account = getAccount(accountId, context);
- final ReportGroup reportGroup = getReportGroup(account.getId(), context);
-
// Recompute the account record
- final BusinessAccountModelDao bac = businessAccountDao.createBusinessAccount(account, context);
+ final BusinessAccountModelDao bac = bacFactory.createBusinessAccount(accountId, context);
// Recompute all invoices and invoice items
- final Collection<BusinessSubscriptionTransitionModelDao> bsts = createBusinessSubscriptionTransitions(account,
- bac.getAccountRecordId(),
- bac.getTenantRecordId(),
- reportGroup,
- context);
+ final Collection<BusinessSubscriptionTransitionModelDao> bsts = bstFactory.createBusinessSubscriptionTransitions(accountId,
+ bac.getAccountRecordId(),
+ bac.getTenantRecordId(),
+ context);
// Recompute the bundle summary records
- final Collection<BusinessBundleSummaryModelDao> bbss = businessBundleSummaryDao.createBusinessBundleSummaries(account,
- bac.getAccountRecordId(),
- bsts,
- bac.getTenantRecordId(),
- reportGroup,
- context);
+ final Collection<BusinessBundleSummaryModelDao> bbss = bbsFactory.createBusinessBundleSummaries(accountId,
+ bac.getAccountRecordId(),
+ bsts,
+ bac.getTenantRecordId(),
+ context);
sqlDao.inTransaction(new Transaction<Void, BusinessAnalyticsSqlDao>() {
@Override
public Void inTransaction(final BusinessAnalyticsSqlDao transactional, final TransactionStatus status) throws Exception {
@@ -112,82 +104,4 @@ public class BusinessSubscriptionTransitionDao extends BusinessAnalyticsDaoBase
// Update BAC
businessAccountDao.updateInTransaction(bac, transactional, context);
}
-
- private Collection<BusinessSubscriptionTransitionModelDao> createBusinessSubscriptionTransitions(final Account account,
- final Long accountRecordId,
- final Long tenantRecordId,
- @Nullable final ReportGroup reportGroup,
- final CallContext context) throws AnalyticsRefreshException {
- final Collection<BusinessSubscriptionTransitionModelDao> bsts = new LinkedList<BusinessSubscriptionTransitionModelDao>();
-
- final List<SubscriptionBundle> bundles = getSubscriptionBundlesForAccount(account.getId(), context);
- for (final SubscriptionBundle bundle : bundles) {
- final Collection<Subscription> subscriptions = getSubscriptionsForBundle(bundle.getId(), context);
- for (final Subscription subscription : subscriptions) {
- final List<SubscriptionTransition> transitions = subscription.getAllTransitions();
-
- BusinessSubscription prevNextSubscription = null;
-
- // Ordered for us by entitlement
- for (final SubscriptionTransition transition : transitions) {
- final BusinessSubscription nextSubscription = getBusinessSubscriptionFromTransition(account, transition);
- final BusinessSubscriptionTransitionModelDao bst = createBusinessSubscriptionTransition(account,
- accountRecordId,
- bundle,
- transition,
- prevNextSubscription,
- nextSubscription,
- tenantRecordId,
- reportGroup,
- context);
- if (bst != null) {
- bsts.add(bst);
- prevNextSubscription = nextSubscription;
- }
- }
- }
- }
-
- return bsts;
- }
-
- private BusinessSubscriptionTransitionModelDao createBusinessSubscriptionTransition(final Account account,
- final Long accountRecordId,
- final SubscriptionBundle subscriptionBundle,
- final SubscriptionTransition subscriptionTransition,
- @Nullable final BusinessSubscription prevNextSubscription,
- final BusinessSubscription nextSubscription,
- final Long tenantRecordId,
- @Nullable final ReportGroup reportGroup,
- final CallContext context) throws AnalyticsRefreshException {
- final BusinessSubscriptionEvent businessEvent = BusinessSubscriptionEvent.fromTransition(subscriptionTransition);
- if (businessEvent == null) {
- return null;
- }
-
- final Long subscriptionEventRecordId = getSubscriptionEventRecordId(subscriptionTransition.getNextEventId(), context);
- final AuditLog creationAuditLog = getSubscriptionEventCreationAuditLog(subscriptionTransition.getNextEventId(), context);
-
- return new BusinessSubscriptionTransitionModelDao(account,
- accountRecordId,
- subscriptionBundle,
- subscriptionTransition,
- subscriptionEventRecordId,
- subscriptionTransition.getRequestedTransitionTime(),
- businessEvent,
- prevNextSubscription,
- nextSubscription,
- creationAuditLog,
- tenantRecordId,
- reportGroup);
- }
-
- private BusinessSubscription getBusinessSubscriptionFromTransition(final Account account, final SubscriptionTransition subscriptionTransition) {
- return new BusinessSubscription(subscriptionTransition.getNextPlan(),
- subscriptionTransition.getNextPhase(),
- subscriptionTransition.getNextPriceList(),
- account.getCurrency(),
- subscriptionTransition.getEffectiveTransitionTime(),
- subscriptionTransition.getNextState());
- }
}
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessTagDao.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessTagDao.java
index 5b843a0..4516b65 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessTagDao.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessTagDao.java
@@ -17,36 +17,35 @@
package com.ning.billing.osgi.bundles.analytics.dao;
import java.util.Collection;
-import java.util.LinkedList;
import java.util.UUID;
import org.skife.jdbi.v2.Transaction;
import org.skife.jdbi.v2.TransactionStatus;
-import com.ning.billing.account.api.Account;
import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
-import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessModelDaoBase.ReportGroup;
+import com.ning.billing.osgi.bundles.analytics.dao.factory.BusinessAccountFactory;
+import com.ning.billing.osgi.bundles.analytics.dao.factory.BusinessTagFactory;
import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessTagModelDao;
-import com.ning.billing.util.audit.AuditLog;
import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.tag.Tag;
-import com.ning.billing.util.tag.TagDefinition;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillDataSource;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
public class BusinessTagDao extends BusinessAnalyticsDaoBase {
+ private final BusinessAccountFactory bacFactory;
+ private final BusinessTagFactory bTagFactory;
+
public BusinessTagDao(final OSGIKillbillLogService logService,
final OSGIKillbillAPI osgiKillbillAPI,
final OSGIKillbillDataSource osgiKillbillDataSource) {
- super(logService, osgiKillbillAPI, osgiKillbillDataSource);
+ super(osgiKillbillDataSource);
+ bacFactory = new BusinessAccountFactory(logService, osgiKillbillAPI);
+ bTagFactory = new BusinessTagFactory(logService, osgiKillbillAPI);
}
public void update(final UUID accountId, final CallContext context) throws AnalyticsRefreshException {
- final Account account = getAccount(accountId, context);
-
- final Collection<BusinessTagModelDao> tagModelDaos = createBusinessTags(account, context);
+ final Collection<BusinessTagModelDao> tagModelDaos = bTagFactory.createBusinessTags(accountId, context);
sqlDao.inTransaction(new Transaction<Void, BusinessAnalyticsSqlDao>() {
@Override
@@ -70,30 +69,4 @@ public class BusinessTagDao extends BusinessAnalyticsDaoBase {
transactional.create(tagModelDao.getTableName(), tagModelDao, context);
}
}
-
- private Collection<BusinessTagModelDao> createBusinessTags(final Account account, final CallContext context) throws AnalyticsRefreshException {
- final Long accountRecordId = getAccountRecordId(account.getId(), context);
- final Long tenantRecordId = getTenantRecordId(context);
- final ReportGroup reportGroup = getReportGroup(account.getId(), context);
-
- final Collection<Tag> tags = getTagsForAccount(account.getId(), context);
-
- final Collection<BusinessTagModelDao> tagModelDaos = new LinkedList<BusinessTagModelDao>();
- for (final Tag tag : tags) {
- final Long tagRecordId = getTagRecordId(tag.getId(), context);
- final TagDefinition tagDefinition = getTagDefinition(tag.getTagDefinitionId(), context);
- final AuditLog creationAuditLog = getTagCreationAuditLog(tag.getId(), context);
- final BusinessTagModelDao tagModelDao = BusinessTagModelDao.create(account,
- accountRecordId,
- tag,
- tagRecordId,
- tagDefinition,
- creationAuditLog,
- tenantRecordId,
- reportGroup);
- tagModelDaos.add(tagModelDao);
- }
-
- return tagModelDaos;
- }
}
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessAccountFactory.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessAccountFactory.java
new file mode 100644
index 0000000..3154362
--- /dev/null
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessAccountFactory.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.osgi.bundles.analytics.dao.factory;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessAccountModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessModelDaoBase.ReportGroup;
+import com.ning.billing.payment.api.Payment;
+import com.ning.billing.util.audit.AuditLog;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
+
+public class BusinessAccountFactory extends BusinessFactoryBase {
+
+ public BusinessAccountFactory(final OSGIKillbillLogService logService,
+ final OSGIKillbillAPI osgiKillbillAPI) {
+ super(logService, osgiKillbillAPI);
+ }
+
+ public BusinessAccountModelDao createBusinessAccount(final UUID accountId,
+ final CallContext context) throws AnalyticsRefreshException {
+ final Account account = getAccount(accountId, context);
+
+ // Retrieve the account creation audit log
+ final AuditLog creationAuditLog = getAccountCreationAuditLog(account.getId(), context);
+
+ // Retrieve the account balance
+ // Note: since we retrieve the invoices below, we could compute it ourselves and avoid fetching the invoices
+ // twice, but that way the computation logic is owned by invoice
+ final BigDecimal accountBalance = getAccountBalance(account.getId(), context);
+
+ // Retrieve invoices information
+ Invoice lastInvoice = null;
+ final Collection<Invoice> invoices = getInvoicesByAccountId(account.getId(), context);
+ for (final Invoice invoice : invoices) {
+ if (lastInvoice == null || invoice.getInvoiceDate().isAfter(lastInvoice.getInvoiceDate())) {
+ lastInvoice = invoice;
+ }
+ }
+
+ // Retrieve payments information
+ Payment lastPayment = null;
+ final Collection<Payment> payments = getPaymentsByAccountId(account.getId(), context);
+ for (final Payment payment : payments) {
+ if (lastPayment == null || payment.getEffectiveDate().isAfter(lastPayment.getEffectiveDate())) {
+ lastPayment = payment;
+ }
+ }
+
+ final List<SubscriptionBundle> bundles = getSubscriptionBundlesForAccount(account.getId(), context);
+ int nbActiveBundles = 0;
+ for (final SubscriptionBundle bundle : bundles) {
+ final Collection<Subscription> subscriptionsForBundle = getSubscriptionsForBundle(bundle.getId(), context);
+ for (final Subscription subscription : subscriptionsForBundle) {
+ if (ProductCategory.BASE.equals(subscription.getCategory()) &&
+ !(subscription.getEndDate() != null && !subscription.getEndDate().isAfterNow())) {
+ nbActiveBundles++;
+ }
+ }
+ }
+
+ final Long accountRecordId = getAccountRecordId(account.getId(), context);
+ final Long tenantRecordId = getTenantRecordId(context);
+ final ReportGroup reportGroup = getReportGroup(account.getId(), context);
+
+ return new BusinessAccountModelDao(account,
+ accountRecordId,
+ accountBalance,
+ lastInvoice,
+ lastPayment,
+ nbActiveBundles,
+ creationAuditLog,
+ tenantRecordId,
+ reportGroup);
+ }
+}
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessBundleSummaryFactory.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessBundleSummaryFactory.java
new file mode 100644
index 0000000..57a7599
--- /dev/null
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessBundleSummaryFactory.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.osgi.bundles.analytics.dao.factory;
+
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.UUID;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessBundleSummaryModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessModelDaoBase.ReportGroup;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscriptionTransitionModelDao;
+import com.ning.billing.util.audit.AuditLog;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Ordering;
+
+public class BusinessBundleSummaryFactory extends BusinessFactoryBase {
+
+ public BusinessBundleSummaryFactory(final OSGIKillbillLogService logService,
+ final OSGIKillbillAPI osgiKillbillAPI) {
+ super(logService, osgiKillbillAPI);
+ }
+
+ public Collection<BusinessBundleSummaryModelDao> createBusinessBundleSummaries(final UUID accountId,
+ final Long accountRecordId,
+ final Collection<BusinessSubscriptionTransitionModelDao> bsts,
+ final Long tenantRecordId,
+ final CallContext context) throws AnalyticsRefreshException {
+ final Account account = getAccount(accountId, context);
+ final ReportGroup reportGroup = getReportGroup(account.getId(), context);
+
+ final Map<UUID, Integer> rankForBundle = new LinkedHashMap<UUID, Integer>();
+ final Map<UUID, BusinessSubscriptionTransitionModelDao> bstForBundle = new LinkedHashMap<UUID, BusinessSubscriptionTransitionModelDao>();
+ filterBstsForBasePlans(bsts, rankForBundle, bstForBundle);
+
+ final Collection<BusinessBundleSummaryModelDao> bbss = new LinkedList<BusinessBundleSummaryModelDao>();
+ for (final BusinessSubscriptionTransitionModelDao bst : bstForBundle.values()) {
+ final BusinessBundleSummaryModelDao bbs = buildBBS(account,
+ accountRecordId,
+ bst,
+ rankForBundle.get(bst.getBundleId()),
+ tenantRecordId,
+ reportGroup,
+ context);
+ bbss.add(bbs);
+ }
+ return bbss;
+ }
+
+ @VisibleForTesting
+ void filterBstsForBasePlans(final Collection<BusinessSubscriptionTransitionModelDao> bsts, final Map<UUID, Integer> rankForBundle, final Map<UUID, BusinessSubscriptionTransitionModelDao> bstForBundle) {// Find bsts for BASE subscriptions only and sort them using the next start date
+ final Collection<BusinessSubscriptionTransitionModelDao> sortedBundlesBst = Ordering.from(new Comparator<BusinessSubscriptionTransitionModelDao>() {
+ @Override
+ public int compare(final BusinessSubscriptionTransitionModelDao o1, final BusinessSubscriptionTransitionModelDao o2) {
+ return o1.getNextStartDate().compareTo(o2.getNextStartDate());
+ }
+ }).sortedCopy(Iterables.filter(bsts, new Predicate<BusinessSubscriptionTransitionModelDao>() {
+ @Override
+ public boolean apply(final BusinessSubscriptionTransitionModelDao input) {
+ return ProductCategory.BASE.toString().equals(input.getNextProductCategory());
+ }
+ }));
+
+ UUID lastBundleId = null;
+ Integer lastBundleRank = 0;
+ for (final BusinessSubscriptionTransitionModelDao bst : sortedBundlesBst) {
+ // Note that sortedBundlesBst is not ordered bundle by bundle, i.e. we may have:
+ // bundleId1 CREATE, bundleId2 CREATE, bundleId1 PHASE, bundleId3 CREATE bundleId2 PHASE
+ if (lastBundleId == null || (!lastBundleId.equals(bst.getBundleId()) && rankForBundle.get(bst.getBundleId()) == null)) {
+ lastBundleRank++;
+ lastBundleId = bst.getBundleId();
+ rankForBundle.put(lastBundleId, lastBundleRank);
+ }
+
+ if (bstForBundle.get(bst.getBundleId()) == null ||
+ bstForBundle.get(bst.getBundleId()).getNextStartDate().isBefore(bst.getNextStartDate())) {
+ bstForBundle.put(bst.getBundleId(), bst);
+ }
+ }
+ }
+
+ private BusinessBundleSummaryModelDao buildBBS(final Account account, final Long accountRecordId, final BusinessSubscriptionTransitionModelDao bst, final Integer bundleAccountRank, final Long tenantRecordId, final ReportGroup reportGroup, final CallContext context) throws AnalyticsRefreshException {
+ final SubscriptionBundle bundle = getSubscriptionBundle(bst.getBundleId(), context);
+ final Long bundleRecordId = getBundleRecordId(bundle.getId(), context);
+ final AuditLog creationAuditLog = getBundleCreationAuditLog(bundle.getId(), context);
+
+ return new BusinessBundleSummaryModelDao(account,
+ accountRecordId,
+ bundle,
+ bundleRecordId,
+ bundleAccountRank,
+ bst,
+ creationAuditLog,
+ tenantRecordId,
+ reportGroup);
+ }
+}
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessFactoryBase.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessFactoryBase.java
new file mode 100644
index 0000000..77f0969
--- /dev/null
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessFactoryBase.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.osgi.bundles.analytics.dao.factory;
+
+import com.ning.billing.osgi.bundles.analytics.BusinessAnalyticsBase;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
+
+public class BusinessFactoryBase extends BusinessAnalyticsBase {
+
+ public BusinessFactoryBase(final OSGIKillbillLogService logService,
+ final OSGIKillbillAPI osgiKillbillAPI) {
+ super(logService, osgiKillbillAPI);
+ }
+}
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessFieldFactory.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessFieldFactory.java
new file mode 100644
index 0000000..ce8adab
--- /dev/null
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessFieldFactory.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.osgi.bundles.analytics.dao.factory;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.UUID;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessFieldModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessModelDaoBase.ReportGroup;
+import com.ning.billing.util.audit.AuditLog;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.customfield.CustomField;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
+
+public class BusinessFieldFactory extends BusinessFactoryBase {
+
+ public BusinessFieldFactory(final OSGIKillbillLogService logService,
+ final OSGIKillbillAPI osgiKillbillAPI) {
+ super(logService, osgiKillbillAPI);
+ }
+
+ public Collection<BusinessFieldModelDao> createBusinessFields(final UUID accountId,
+ final CallContext context) throws AnalyticsRefreshException {
+ final Account account = getAccount(accountId, context);
+
+ final Long accountRecordId = getAccountRecordId(account.getId(), context);
+ final Long tenantRecordId = getTenantRecordId(context);
+ final ReportGroup reportGroup = getReportGroup(account.getId(), context);
+
+ final Collection<CustomField> fields = getFieldsForAccount(account.getId(), context);
+
+ final Collection<BusinessFieldModelDao> fieldModelDaos = new LinkedList<BusinessFieldModelDao>();
+ for (final CustomField field : fields) {
+ final Long customFieldRecordId = getFieldRecordId(field.getId(), context);
+ final AuditLog creationAuditLog = getFieldCreationAuditLog(field.getId(), context);
+ final BusinessFieldModelDao fieldModelDao = BusinessFieldModelDao.create(account,
+ accountRecordId,
+ field,
+ customFieldRecordId,
+ creationAuditLog,
+ tenantRecordId,
+ reportGroup);
+ fieldModelDaos.add(fieldModelDao);
+ }
+
+ return fieldModelDaos;
+ }
+}
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessInvoiceFactory.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessInvoiceFactory.java
new file mode 100644
index 0000000..4f8a46b
--- /dev/null
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessInvoiceFactory.java
@@ -0,0 +1,592 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.osgi.bundles.analytics.dao.factory;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+import org.joda.time.DateTime;
+import org.joda.time.LocalDate;
+import org.osgi.service.log.LogService;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.catalog.api.Plan;
+import com.ning.billing.catalog.api.PlanPhase;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.invoice.api.InvoiceItem;
+import com.ning.billing.invoice.api.InvoiceItemType;
+import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceItemBaseModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceItemBaseModelDao.BusinessInvoiceItemType;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessModelDaoBase.ReportGroup;
+import com.ning.billing.osgi.bundles.analytics.utils.BusinessInvoiceUtils;
+import com.ning.billing.util.audit.AuditLog;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Predicate;
+import com.google.common.base.Strings;
+import com.google.common.collect.Collections2;
+
+import static com.ning.billing.osgi.bundles.analytics.utils.BusinessInvoiceUtils.isAccountCreditItem;
+import static com.ning.billing.osgi.bundles.analytics.utils.BusinessInvoiceUtils.isCharge;
+import static com.ning.billing.osgi.bundles.analytics.utils.BusinessInvoiceUtils.isInvoiceAdjustmentItem;
+import static com.ning.billing.osgi.bundles.analytics.utils.BusinessInvoiceUtils.isInvoiceItemAdjustmentItem;
+import static com.ning.billing.osgi.bundles.analytics.utils.BusinessInvoiceUtils.isRevenueRecognizable;
+
+public class BusinessInvoiceFactory extends BusinessFactoryBase {
+
+ public BusinessInvoiceFactory(final OSGIKillbillLogService logService,
+ final OSGIKillbillAPI osgiKillbillAPI) {
+ super(logService, osgiKillbillAPI);
+ }
+
+ /**
+ * Create business invoices and invoice items to record. Note that these POJOs are incomplete
+ * (denormalized payment fields have not yet been populated)
+ *
+ * @param accountId current accountId refreshed
+ * @param context call context
+ * @return all business invoice and invoice items to create
+ * @throws com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException
+ *
+ */
+ public Map<BusinessInvoiceModelDao, Collection<BusinessInvoiceItemBaseModelDao>> createBusinessInvoicesAndInvoiceItems(final UUID accountId,
+ final CallContext context) throws AnalyticsRefreshException {
+ final Account account = getAccount(accountId, context);
+ final Long accountRecordId = getAccountRecordId(account.getId(), context);
+ final Long tenantRecordId = getTenantRecordId(context);
+ final ReportGroup reportGroup = getReportGroup(account.getId(), context);
+
+ // Lookup the invoices for that account
+ final Collection<Invoice> invoices = getInvoicesByAccountId(account.getId(), context);
+
+ // All invoice items across all invoices for that accounr (we need to be able to reference items across multiple invoices)
+ final Collection<InvoiceItem> allInvoiceItems = new LinkedList<InvoiceItem>();
+ // Convenient mapping invoice_id -> invoice
+ final Map<UUID, Invoice> invoiceIdToInvoiceMappings = new LinkedHashMap<UUID, Invoice>();
+ for (final Invoice invoice : invoices) {
+ invoiceIdToInvoiceMappings.put(invoice.getId(), invoice);
+ allInvoiceItems.addAll(invoice.getInvoiceItems());
+ }
+
+ // Sanitize (cherry-pick, merge) the items
+ final Collection<InvoiceItem> sanitizedInvoiceItems = sanitizeInvoiceItems(allInvoiceItems);
+
+ // Create the business invoice items. These are incomplete (the denormalized invoice fields haven't been computed yet)
+ final Map<UUID, Collection<BusinessInvoiceItemBaseModelDao>> businessInvoiceItemsForInvoiceId = new HashMap<UUID, Collection<BusinessInvoiceItemBaseModelDao>>();
+ for (final InvoiceItem invoiceItem : sanitizedInvoiceItems) {
+ final Invoice invoice = invoiceIdToInvoiceMappings.get(invoiceItem.getInvoiceId());
+ final BusinessInvoiceItemBaseModelDao businessInvoiceItem = createBusinessInvoiceItem(account,
+ invoice,
+ invoiceItem,
+ Collections2.filter(sanitizedInvoiceItems,
+ new Predicate<InvoiceItem>() {
+ @Override
+ public boolean apply(final InvoiceItem input) {
+ return !input.getId().equals(invoiceItem.getId());
+ }
+ }),
+ accountRecordId,
+ tenantRecordId,
+ reportGroup,
+ context);
+ if (businessInvoiceItem != null) {
+ if (businessInvoiceItemsForInvoiceId.get(invoice.getId()) == null) {
+ businessInvoiceItemsForInvoiceId.put(invoice.getId(), new LinkedList<BusinessInvoiceItemBaseModelDao>());
+ }
+ businessInvoiceItemsForInvoiceId.get(invoice.getId()).add(businessInvoiceItem);
+ }
+ }
+
+ // Now, create the business invoices
+ final Map<BusinessInvoiceModelDao, Collection<BusinessInvoiceItemBaseModelDao>> businessRecords = new HashMap<BusinessInvoiceModelDao, Collection<BusinessInvoiceItemBaseModelDao>>();
+ for (final Invoice invoice : invoices) {
+ final Collection<BusinessInvoiceItemBaseModelDao> businessInvoiceItems = businessInvoiceItemsForInvoiceId.get(invoice.getId());
+ if (businessInvoiceItems == null) {
+ continue;
+ }
+
+ final BusinessInvoiceModelDao businessInvoice = createBusinessInvoice(account, invoice, businessInvoiceItems, accountRecordId, tenantRecordId, reportGroup, context);
+ businessRecords.put(businessInvoice, businessInvoiceItems);
+ }
+
+ return businessRecords;
+ }
+
+ private BusinessInvoiceModelDao createBusinessInvoice(final Account account,
+ final Invoice invoice,
+ final Collection<BusinessInvoiceItemBaseModelDao> businessInvoiceItems,
+ final Long accountRecordId,
+ final Long tenantRecordId,
+ @Nullable final ReportGroup reportGroup,
+ final CallContext context) throws AnalyticsRefreshException {
+ final Long invoiceRecordId = getInvoiceRecordId(invoice.getId(), context);
+ final AuditLog creationAuditLog = getInvoiceCreationAuditLog(invoice.getId(), context);
+
+ final BigDecimal amountCharged = BusinessInvoiceUtils.computeInvoiceAmountCharged(businessInvoiceItems);
+ final BigDecimal originalAmountCharged = BusinessInvoiceUtils.computeInvoiceOriginalAmountCharged(businessInvoiceItems);
+ final BigDecimal amountCredited = BusinessInvoiceUtils.computeInvoiceAmountCredited(businessInvoiceItems);
+
+ return new BusinessInvoiceModelDao(account,
+ accountRecordId,
+ invoice,
+ amountCharged,
+ originalAmountCharged,
+ amountCredited,
+ invoiceRecordId,
+ creationAuditLog,
+ tenantRecordId,
+ reportGroup);
+ }
+
+ private BusinessInvoiceItemBaseModelDao createBusinessInvoiceItem(final Account account,
+ final Invoice invoice,
+ final InvoiceItem invoiceItem,
+ final Collection<InvoiceItem> otherInvoiceItems,
+ final Long accountRecordId,
+ final Long tenantRecordId,
+ @Nullable final ReportGroup reportGroup,
+ final TenantContext context) throws AnalyticsRefreshException {
+ SubscriptionBundle bundle = null;
+ // Subscription and bundle could be null for e.g. credits or adjustments
+ if (invoiceItem.getBundleId() != null) {
+ bundle = getSubscriptionBundle(invoiceItem.getBundleId(), context);
+ }
+
+ Plan plan = null;
+ if (Strings.emptyToNull(invoiceItem.getPlanName()) != null) {
+ plan = getPlanFromInvoiceItem(invoiceItem, context);
+ }
+
+ PlanPhase planPhase = null;
+ if (invoiceItem.getSubscriptionId() != null && Strings.emptyToNull(invoiceItem.getPhaseName()) != null) {
+ planPhase = getPlanPhaseFromInvoiceItem(invoiceItem, context);
+ }
+
+ final Long invoiceItemRecordId = getInvoiceItemRecordId(invoiceItem.getId(), context);
+ final AuditLog creationAuditLog = getInvoiceItemCreationAuditLog(invoiceItem.getId(), context);
+
+ return createBusinessInvoiceItem(account,
+ invoice,
+ invoiceItem,
+ otherInvoiceItems,
+ bundle,
+ plan,
+ planPhase,
+ invoiceItemRecordId,
+ creationAuditLog,
+ accountRecordId,
+ tenantRecordId,
+ reportGroup,
+ context);
+ }
+
+ @VisibleForTesting
+ BusinessInvoiceItemBaseModelDao createBusinessInvoiceItem(final Account account,
+ final Invoice invoice,
+ final InvoiceItem invoiceItem,
+ final Collection<InvoiceItem> otherInvoiceItems,
+ @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;
+ } else if (isAccountCreditItem(invoiceItem)) {
+ businessInvoiceItemType = BusinessInvoiceItemType.ACCOUNT_CREDIT;
+ } else if (isInvoiceItemAdjustmentItem(invoiceItem)) {
+ businessInvoiceItemType = BusinessInvoiceItemType.INVOICE_ITEM_ADJUSTMENT;
+ } else if (isInvoiceAdjustmentItem(invoiceItem, otherInvoiceItems)) {
+ businessInvoiceItemType = BusinessInvoiceItemType.INVOICE_ADJUSTMENT;
+ } else {
+ // We don't care
+ return null;
+ }
+
+ final Boolean revenueRecognizable = isRevenueRecognizable(invoiceItem, otherInvoiceItems);
+
+ final Long secondInvoiceItemRecordId;
+ if (invoiceItem instanceof AdjustmentInvoiceItemForRepair) {
+ secondInvoiceItemRecordId = getInvoiceItemRecordId(((AdjustmentInvoiceItemForRepair) invoiceItem).getSecondId(), context);
+ } else {
+ secondInvoiceItemRecordId = null;
+ }
+
+ return BusinessInvoiceItemBaseModelDao.create(account,
+ accountRecordId,
+ invoice,
+ invoiceItem,
+ revenueRecognizable,
+ businessInvoiceItemType,
+ invoiceItemRecordId,
+ secondInvoiceItemRecordId,
+ bundle,
+ plan,
+ planPhase,
+ creationAuditLog,
+ tenantRecordId,
+ reportGroup);
+ }
+
+ /**
+ * Filter and transform the original invoice items for Analytics purposes. We mainly
+ * merge REPAIR_ADJ items with reparation items (reparees) to create item adjustments.
+ *
+ * @param allInvoiceItems all items for the current account
+ * @return invoice items interesting for Analytics purposes
+ */
+ @VisibleForTesting
+ Collection<InvoiceItem> sanitizeInvoiceItems(final Collection<InvoiceItem> allInvoiceItems) {
+ // Build a convenience mapping between items -> repair_adj items (inverse of linkedItemId)
+ final Map<UUID, InvoiceItem> repairedInvoiceItemIdToRepairInvoiceItemMappings = new HashMap<UUID, InvoiceItem>();
+ for (final InvoiceItem invoiceItem : allInvoiceItems) {
+ if (InvoiceItemType.REPAIR_ADJ.equals(invoiceItem.getInvoiceItemType())) {
+ repairedInvoiceItemIdToRepairInvoiceItemMappings.put(invoiceItem.getLinkedItemId(), invoiceItem);
+ }
+ }
+
+ // Now find the "reparation" items, i.e. the ones which correspond to the repaired items
+ final Map<UUID, InvoiceItem> reparationInvoiceItemIdToRepairItemMappings = new LinkedHashMap<UUID, InvoiceItem>();
+ for (final InvoiceItem repairedInvoiceItem : allInvoiceItems) {
+ // Skip non-repaired items
+ if (!repairedInvoiceItemIdToRepairInvoiceItemMappings.keySet().contains(repairedInvoiceItem.getId())) {
+ continue;
+ }
+
+ InvoiceItem reparationItem = null;
+ for (final InvoiceItem invoiceItem : allInvoiceItems) {
+ // Try to find the matching "reparation" item
+ if (repairedInvoiceItem.getInvoiceItemType().equals(invoiceItem.getInvoiceItemType()) &&
+ repairedInvoiceItem.getSubscriptionId().equals(invoiceItem.getSubscriptionId()) &&
+ repairedInvoiceItem.getStartDate().compareTo(invoiceItem.getStartDate()) == 0 &&
+ // FIXED items have a null end date
+ ((repairedInvoiceItem.getEndDate() == null && invoiceItem.getEndDate() == null) ||
+ (repairedInvoiceItem.getEndDate() != null && invoiceItem.getEndDate() != null && !repairedInvoiceItem.getEndDate().isBefore(invoiceItem.getEndDate()))) &&
+ !repairedInvoiceItem.getId().equals(invoiceItem.getId())) {
+ if (reparationItem == null) {
+ reparationItem = invoiceItem;
+ } else {
+ logService.log(LogService.LOG_ERROR, "Found multiple reparation items matching the repair item id " + repairedInvoiceItem.getId() + " - this should never happen!");
+ }
+ }
+ }
+
+ if (reparationItem != null) {
+ reparationInvoiceItemIdToRepairItemMappings.put(reparationItem.getId(), repairedInvoiceItemIdToRepairInvoiceItemMappings.get(repairedInvoiceItem.getId()));
+ } else {
+ logService.log(LogService.LOG_ERROR, "Could not find the reparation item for the repair item id " + repairedInvoiceItem.getId() + " - this should never happen!");
+ }
+ }
+
+ // We now need to adjust the CBA_ADJ for the repair items
+ final Set<UUID> cbasToIgnore = new HashSet<UUID>();
+ final Collection<AdjustedCBAInvoiceItem> newCbasToAdd = new LinkedList<AdjustedCBAInvoiceItem>();
+ for (final InvoiceItem cbaInvoiceItem : allInvoiceItems) {
+ if (!InvoiceItemType.CBA_ADJ.equals(cbaInvoiceItem.getInvoiceItemType())) {
+ continue;
+ }
+
+ for (final InvoiceItem invoiceItem : allInvoiceItems) {
+ if (reparationInvoiceItemIdToRepairItemMappings.keySet().contains(invoiceItem.getId())) {
+ final InvoiceItem repairInvoiceItem = reparationInvoiceItemIdToRepairItemMappings.get(invoiceItem.getId());
+ final InvoiceItem reparationInvoiceItem = invoiceItem;
+ // Au petit bonheur la chance... There is nothing else against to compare
+ if (repairInvoiceItem.getAmount().negate().compareTo(cbaInvoiceItem.getAmount()) == 0) {
+ cbasToIgnore.add(cbaInvoiceItem.getId());
+ newCbasToAdd.add(new AdjustedCBAInvoiceItem(cbaInvoiceItem, cbaInvoiceItem.getAmount().add(reparationInvoiceItem.getAmount().negate()), reparationInvoiceItem.getId()));
+
+ // Now, fiddle with the CBA used on the reparation invoice
+ for (final InvoiceItem cbaUsedOnNextInvoiceItem : allInvoiceItems) {
+ if (!InvoiceItemType.CBA_ADJ.equals(cbaUsedOnNextInvoiceItem.getInvoiceItemType()) ||
+ !cbaUsedOnNextInvoiceItem.getInvoiceId().equals(reparationInvoiceItem.getInvoiceId())) {
+ continue;
+ }
+
+ // Au petit bonheur la chance... There is nothing else against to compare. Take the first one again?
+ cbasToIgnore.add(cbaUsedOnNextInvoiceItem.getId());
+ newCbasToAdd.add(new AdjustedCBAInvoiceItem(cbaUsedOnNextInvoiceItem, cbaUsedOnNextInvoiceItem.getAmount().add(reparationInvoiceItem.getAmount()), reparationInvoiceItem.getId()));
+ break;
+ }
+
+ // Break from the inner loop only
+ break;
+ }
+ }
+ }
+ }
+
+
+ // Filter the invoice items for analytics
+ final Collection<InvoiceItem> invoiceItemsForAnalytics = new LinkedList<InvoiceItem>();
+ for (final InvoiceItem invoiceItem : allInvoiceItems) {
+ if (cbasToIgnore.contains(invoiceItem.getId())) {
+ // We don't care
+ } else if (InvoiceItemType.REPAIR_ADJ.equals(invoiceItem.getInvoiceItemType())) {
+ // We don't care, we'll create a special item for it below
+ } else if (reparationInvoiceItemIdToRepairItemMappings.keySet().contains(invoiceItem.getId())) {
+ // We do care - this is a reparation item. Create an item adjustment for it
+ final InvoiceItem repairInvoiceItem = reparationInvoiceItemIdToRepairItemMappings.get(invoiceItem.getId());
+ final InvoiceItem reparationInvoiceItem = invoiceItem;
+ invoiceItemsForAnalytics.add(new AdjustmentInvoiceItemForRepair(repairInvoiceItem, reparationInvoiceItem));
+ } else {
+ invoiceItemsForAnalytics.add(invoiceItem);
+ }
+ }
+ invoiceItemsForAnalytics.addAll(newCbasToAdd);
+
+ return invoiceItemsForAnalytics;
+ }
+
+ private class AdjustedCBAInvoiceItem implements InvoiceItem {
+
+ private final InvoiceItem cbaInvoiceItem;
+ private final BigDecimal amount;
+ private final UUID reparationItemId;
+
+ private AdjustedCBAInvoiceItem(final InvoiceItem cbaInvoiceItem,
+ final BigDecimal amount,
+ final UUID reparationItemId) {
+ this.cbaInvoiceItem = cbaInvoiceItem;
+ this.amount = amount;
+ this.reparationItemId = reparationItemId;
+ }
+
+ @Override
+ public InvoiceItemType getInvoiceItemType() {
+ return InvoiceItemType.CBA_ADJ;
+ }
+
+ @Override
+ public UUID getInvoiceId() {
+ return cbaInvoiceItem.getInvoiceId();
+ }
+
+ @Override
+ public UUID getAccountId() {
+ return cbaInvoiceItem.getAccountId();
+ }
+
+ @Override
+ public LocalDate getStartDate() {
+ return cbaInvoiceItem.getStartDate();
+ }
+
+ @Override
+ public LocalDate getEndDate() {
+ return cbaInvoiceItem.getStartDate();
+ }
+
+ @Override
+ public BigDecimal getAmount() {
+ return amount;
+ }
+
+ @Override
+ public Currency getCurrency() {
+ return cbaInvoiceItem.getCurrency();
+ }
+
+ @Override
+ public String getDescription() {
+ return cbaInvoiceItem.getDescription();
+ }
+
+ @Override
+ public UUID getBundleId() {
+ return cbaInvoiceItem.getBundleId();
+ }
+
+ @Override
+ public UUID getSubscriptionId() {
+ return cbaInvoiceItem.getSubscriptionId();
+ }
+
+ @Override
+ public String getPlanName() {
+ return cbaInvoiceItem.getPlanName();
+ }
+
+ @Override
+ public String getPhaseName() {
+ return cbaInvoiceItem.getPhaseName();
+ }
+
+ @Override
+ public BigDecimal getRate() {
+ return cbaInvoiceItem.getRate();
+ }
+
+ @Override
+ public UUID getLinkedItemId() {
+ return cbaInvoiceItem.getLinkedItemId();
+ }
+
+ @Override
+ public boolean matches(final Object other) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public UUID getId() {
+ return cbaInvoiceItem.getId();
+ }
+
+ public UUID getSecondId() {
+ return reparationItemId;
+ }
+
+ @Override
+ public DateTime getCreatedDate() {
+ return cbaInvoiceItem.getCreatedDate();
+ }
+
+ @Override
+ public DateTime getUpdatedDate() {
+ return cbaInvoiceItem.getUpdatedDate();
+ }
+ }
+
+ private class AdjustmentInvoiceItemForRepair implements InvoiceItem {
+
+ private final InvoiceItem repairInvoiceItem;
+ private final InvoiceItem reparationInvoiceItem;
+
+ private AdjustmentInvoiceItemForRepair(final InvoiceItem repairInvoiceItem,
+ final InvoiceItem reparationInvoiceItem) {
+ this.repairInvoiceItem = repairInvoiceItem;
+ this.reparationInvoiceItem = reparationInvoiceItem;
+ }
+
+ @Override
+ public InvoiceItemType getInvoiceItemType() {
+ return InvoiceItemType.ITEM_ADJ;
+ }
+
+ @Override
+ public UUID getInvoiceId() {
+ return repairInvoiceItem.getInvoiceId();
+ }
+
+ @Override
+ public UUID getAccountId() {
+ return repairInvoiceItem.getAccountId();
+ }
+
+ @Override
+ public LocalDate getStartDate() {
+ return repairInvoiceItem.getStartDate();
+ }
+
+ @Override
+ public LocalDate getEndDate() {
+ return repairInvoiceItem.getStartDate();
+ }
+
+ @Override
+ public BigDecimal getAmount() {
+ return reparationInvoiceItem.getAmount().add(repairInvoiceItem.getAmount());
+ }
+
+ @Override
+ public Currency getCurrency() {
+ return repairInvoiceItem.getCurrency();
+ }
+
+ @Override
+ public String getDescription() {
+ return null;
+ }
+
+ @Override
+ public UUID getBundleId() {
+ return null;
+ }
+
+ @Override
+ public UUID getSubscriptionId() {
+ return null;
+ }
+
+ @Override
+ public String getPlanName() {
+ return null;
+ }
+
+ @Override
+ public String getPhaseName() {
+ return null;
+ }
+
+ @Override
+ public BigDecimal getRate() {
+ return null;
+ }
+
+ @Override
+ public UUID getLinkedItemId() {
+ return repairInvoiceItem.getLinkedItemId();
+ }
+
+ @Override
+ public boolean matches(final Object other) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public UUID getId() {
+ // We pretend to be the repair, the reparation item record id
+ // will be available as secondId
+ return repairInvoiceItem.getId();
+ }
+
+ public UUID getSecondId() {
+ return reparationInvoiceItem.getId();
+ }
+
+ @Override
+ public DateTime getCreatedDate() {
+ return repairInvoiceItem.getCreatedDate();
+ }
+
+ @Override
+ public DateTime getUpdatedDate() {
+ return repairInvoiceItem.getUpdatedDate();
+ }
+ }
+}
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessInvoiceItemFactory.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessInvoiceItemFactory.java
new file mode 100644
index 0000000..89b4f55
--- /dev/null
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessInvoiceItemFactory.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.osgi.bundles.analytics.dao.factory;
+
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
+
+public class BusinessInvoiceItemFactory extends BusinessFactoryBase {
+
+ public BusinessInvoiceItemFactory(final OSGIKillbillLogService logService,
+ final OSGIKillbillAPI osgiKillbillAPI) {
+ super(logService, osgiKillbillAPI);
+ }
+}
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessInvoicePaymentFactory.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessInvoicePaymentFactory.java
new file mode 100644
index 0000000..11856f2
--- /dev/null
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessInvoicePaymentFactory.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.osgi.bundles.analytics.dao.factory;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.invoice.api.InvoicePayment;
+import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceItemBaseModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoicePaymentBaseModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessModelDaoBase.ReportGroup;
+import com.ning.billing.payment.api.Payment;
+import com.ning.billing.payment.api.PaymentMethod;
+import com.ning.billing.payment.api.Refund;
+import com.ning.billing.util.audit.AuditLog;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
+
+public class BusinessInvoicePaymentFactory extends BusinessFactoryBase {
+
+ public BusinessInvoicePaymentFactory(final OSGIKillbillLogService logService,
+ final OSGIKillbillAPI osgiKillbillAPI) {
+ super(logService, osgiKillbillAPI);
+ }
+
+
+ public Collection<BusinessInvoicePaymentBaseModelDao> createBusinessInvoicePayments(final UUID accountId,
+ final Map<BusinessInvoiceModelDao, Collection<BusinessInvoiceItemBaseModelDao>> businessInvoices,
+ final CallContext context) throws AnalyticsRefreshException {
+ final Account account = getAccount(accountId, context);
+
+ final Collection<BusinessInvoicePaymentBaseModelDao> businessInvoicePayments = new LinkedList<BusinessInvoicePaymentBaseModelDao>();
+
+ final Long accountRecordId = getAccountRecordId(account.getId(), context);
+ final Long tenantRecordId = getTenantRecordId(context);
+ final ReportGroup reportGroup = getReportGroup(account.getId(), context);
+
+ final Collection<InvoicePayment> invoicePayments = getAccountInvoicePayments(account.getId(), context);
+ for (final InvoicePayment invoicePayment : invoicePayments) {
+ final BusinessInvoicePaymentBaseModelDao businessInvoicePayment = createBusinessInvoicePayment(account,
+ invoicePayment,
+ businessInvoices,
+ accountRecordId,
+ tenantRecordId,
+ reportGroup,
+ context);
+ if (businessInvoicePayment != null) {
+ businessInvoicePayments.add(businessInvoicePayment);
+ }
+ }
+
+ return businessInvoicePayments;
+ }
+
+ private BusinessInvoicePaymentBaseModelDao createBusinessInvoicePayment(final Account account,
+ final InvoicePayment invoicePayment,
+ final Map<BusinessInvoiceModelDao, Collection<BusinessInvoiceItemBaseModelDao>> businessInvoices,
+ final Long accountRecordId,
+ final Long tenantRecordId,
+ @Nullable final ReportGroup reportGroup,
+ final CallContext context) throws AnalyticsRefreshException {
+ final Long invoicePaymentRecordId = getInvoicePaymentRecordId(invoicePayment.getId(), context);
+
+ final Payment payment = getPaymentWithPluginInfo(invoicePayment.getPaymentId(), context);
+ Refund refund = null;
+ if (invoicePayment.getPaymentCookieId() != null) {
+ refund = getRefundWithPluginInfo(invoicePayment.getPaymentCookieId(), context);
+ }
+
+ final Invoice invoice = getInvoice(invoicePayment.getInvoiceId(), context);
+ final PaymentMethod paymentMethod = getPaymentMethod(payment.getPaymentMethodId(), context);
+ final AuditLog creationAuditLog = getInvoicePaymentCreationAuditLog(invoicePayment.getId(), context);
+
+ return BusinessInvoicePaymentBaseModelDao.create(account,
+ accountRecordId,
+ invoice,
+ invoicePayment,
+ invoicePaymentRecordId,
+ payment,
+ refund,
+ paymentMethod,
+ creationAuditLog,
+ tenantRecordId,
+ reportGroup);
+ }
+}
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessOverdueStatusFactory.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessOverdueStatusFactory.java
new file mode 100644
index 0000000..d346cc1
--- /dev/null
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessOverdueStatusFactory.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.osgi.bundles.analytics.dao.factory;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.junction.api.BlockingState;
+import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessModelDaoBase.ReportGroup;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessOverdueStatusModelDao;
+import com.ning.billing.util.audit.AuditLog;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+public class BusinessOverdueStatusFactory extends BusinessFactoryBase {
+
+ public BusinessOverdueStatusFactory(final OSGIKillbillLogService logService,
+ final OSGIKillbillAPI osgiKillbillAPI) {
+ super(logService, osgiKillbillAPI);
+ }
+
+ public Collection<BusinessOverdueStatusModelDao> createBusinessOverdueStatuses(final UUID accountId,
+ final CallContext context) throws AnalyticsRefreshException {
+ final Collection<SubscriptionBundle> bundles = getSubscriptionBundlesForAccount(accountId, context);
+ final Collection<BusinessOverdueStatusModelDao> businessOverdueStatuses = new LinkedList<BusinessOverdueStatusModelDao>();
+ for (final SubscriptionBundle bundle : bundles) {
+ // Recompute all blocking states for that bundle
+ businessOverdueStatuses.addAll(createBusinessOverdueStatusesForBundle(accountId, bundle, context));
+ }
+
+ return businessOverdueStatuses;
+ }
+
+ private Collection<BusinessOverdueStatusModelDao> createBusinessOverdueStatusesForBundle(final UUID accountId,
+ final SubscriptionBundle subscriptionBundle,
+ final CallContext context) throws AnalyticsRefreshException {
+ final Account account = getAccount(accountId, context);
+
+ final Collection<BusinessOverdueStatusModelDao> businessOverdueStatuses = new LinkedList<BusinessOverdueStatusModelDao>();
+
+ final List<BlockingState> blockingStatesOrdered = getBlockingHistory(subscriptionBundle.getId(), context);
+ if (blockingStatesOrdered.size() == 0) {
+ return businessOverdueStatuses;
+ }
+
+ final Long accountRecordId = getAccountRecordId(account.getId(), context);
+ final Long tenantRecordId = getTenantRecordId(context);
+ final ReportGroup reportGroup = getReportGroup(account.getId(), context);
+
+ final List<BlockingState> blockingStates = Lists.reverse(ImmutableList.<BlockingState>copyOf(blockingStatesOrdered));
+ DateTime previousStartDate = null;
+ for (final BlockingState state : blockingStates) {
+ final Long blockingStateRecordId = getBlockingStateRecordId(state.getId(), context);
+ final AuditLog creationAuditLog = getBlockingStateCreationAuditLog(state.getId(), context);
+ final BusinessOverdueStatusModelDao overdueStatus = new BusinessOverdueStatusModelDao(account,
+ accountRecordId,
+ subscriptionBundle,
+ state,
+ blockingStateRecordId,
+ previousStartDate,
+ creationAuditLog,
+ tenantRecordId,
+ reportGroup);
+ businessOverdueStatuses.add(overdueStatus);
+ previousStartDate = state.getTimestamp();
+ }
+
+ return businessOverdueStatuses;
+ }
+}
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessSubscriptionTransitionFactory.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessSubscriptionTransitionFactory.java
new file mode 100644
index 0000000..7cbc5f4
--- /dev/null
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessSubscriptionTransitionFactory.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.osgi.bundles.analytics.dao.factory;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.entitlement.api.user.SubscriptionTransition;
+import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessModelDaoBase.ReportGroup;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscription;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscriptionEvent;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscriptionTransitionModelDao;
+import com.ning.billing.util.audit.AuditLog;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
+
+public class BusinessSubscriptionTransitionFactory extends BusinessFactoryBase {
+
+ public BusinessSubscriptionTransitionFactory(final OSGIKillbillLogService logService,
+ final OSGIKillbillAPI osgiKillbillAPI) {
+ super(logService, osgiKillbillAPI);
+ }
+
+ public Collection<BusinessSubscriptionTransitionModelDao> createBusinessSubscriptionTransitions(final UUID accountId,
+ final Long accountRecordId,
+ final Long tenantRecordId,
+ final CallContext context) throws AnalyticsRefreshException {
+ final Account account = getAccount(accountId, context);
+ final ReportGroup reportGroup = getReportGroup(account.getId(), context);
+
+ final Collection<BusinessSubscriptionTransitionModelDao> bsts = new LinkedList<BusinessSubscriptionTransitionModelDao>();
+
+ final List<SubscriptionBundle> bundles = getSubscriptionBundlesForAccount(account.getId(), context);
+ for (final SubscriptionBundle bundle : bundles) {
+ final Collection<Subscription> subscriptions = getSubscriptionsForBundle(bundle.getId(), context);
+ for (final Subscription subscription : subscriptions) {
+ final List<SubscriptionTransition> transitions = subscription.getAllTransitions();
+
+ BusinessSubscription prevNextSubscription = null;
+
+ // Ordered for us by entitlement
+ for (final SubscriptionTransition transition : transitions) {
+ final BusinessSubscription nextSubscription = getBusinessSubscriptionFromTransition(account, transition);
+ final BusinessSubscriptionTransitionModelDao bst = createBusinessSubscriptionTransition(account,
+ accountRecordId,
+ bundle,
+ transition,
+ prevNextSubscription,
+ nextSubscription,
+ tenantRecordId,
+ reportGroup,
+ context);
+ if (bst != null) {
+ bsts.add(bst);
+ prevNextSubscription = nextSubscription;
+ }
+ }
+ }
+ }
+
+ return bsts;
+ }
+
+ private BusinessSubscriptionTransitionModelDao createBusinessSubscriptionTransition(final Account account,
+ final Long accountRecordId,
+ final SubscriptionBundle subscriptionBundle,
+ final SubscriptionTransition subscriptionTransition,
+ @Nullable final BusinessSubscription prevNextSubscription,
+ final BusinessSubscription nextSubscription,
+ final Long tenantRecordId,
+ @Nullable final ReportGroup reportGroup,
+ final CallContext context) throws AnalyticsRefreshException {
+ final BusinessSubscriptionEvent businessEvent = BusinessSubscriptionEvent.fromTransition(subscriptionTransition);
+ if (businessEvent == null) {
+ return null;
+ }
+
+ final Long subscriptionEventRecordId = getSubscriptionEventRecordId(subscriptionTransition.getNextEventId(), context);
+ final AuditLog creationAuditLog = getSubscriptionEventCreationAuditLog(subscriptionTransition.getNextEventId(), context);
+
+ return new BusinessSubscriptionTransitionModelDao(account,
+ accountRecordId,
+ subscriptionBundle,
+ subscriptionTransition,
+ subscriptionEventRecordId,
+ subscriptionTransition.getRequestedTransitionTime(),
+ businessEvent,
+ prevNextSubscription,
+ nextSubscription,
+ creationAuditLog,
+ tenantRecordId,
+ reportGroup);
+ }
+
+ private BusinessSubscription getBusinessSubscriptionFromTransition(final Account account, final SubscriptionTransition subscriptionTransition) {
+ return new BusinessSubscription(subscriptionTransition.getNextPlan(),
+ subscriptionTransition.getNextPhase(),
+ subscriptionTransition.getNextPriceList(),
+ account.getCurrency(),
+ subscriptionTransition.getEffectiveTransitionTime(),
+ subscriptionTransition.getNextState());
+ }
+}
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessTagFactory.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessTagFactory.java
new file mode 100644
index 0000000..1df645d
--- /dev/null
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/factory/BusinessTagFactory.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.osgi.bundles.analytics.dao.factory;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.UUID;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessModelDaoBase.ReportGroup;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessTagModelDao;
+import com.ning.billing.util.audit.AuditLog;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.tag.Tag;
+import com.ning.billing.util.tag.TagDefinition;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
+
+public class BusinessTagFactory extends BusinessFactoryBase {
+
+ public BusinessTagFactory(final OSGIKillbillLogService logService,
+ final OSGIKillbillAPI osgiKillbillAPI) {
+ super(logService, osgiKillbillAPI);
+ }
+
+ public Collection<BusinessTagModelDao> createBusinessTags(final UUID accountId,
+ final CallContext context) throws AnalyticsRefreshException {
+ final Account account = getAccount(accountId, context);
+
+ final Long accountRecordId = getAccountRecordId(account.getId(), context);
+ final Long tenantRecordId = getTenantRecordId(context);
+ final ReportGroup reportGroup = getReportGroup(account.getId(), context);
+
+ final Collection<Tag> tags = getTagsForAccount(account.getId(), context);
+
+ final Collection<BusinessTagModelDao> tagModelDaos = new LinkedList<BusinessTagModelDao>();
+ for (final Tag tag : tags) {
+ final Long tagRecordId = getTagRecordId(tag.getId(), context);
+ final TagDefinition tagDefinition = getTagDefinition(tag.getTagDefinitionId(), context);
+ final AuditLog creationAuditLog = getTagCreationAuditLog(tag.getId(), context);
+ final BusinessTagModelDao tagModelDao = BusinessTagModelDao.create(account,
+ accountRecordId,
+ tag,
+ tagRecordId,
+ tagDefinition,
+ creationAuditLog,
+ tenantRecordId,
+ reportGroup);
+ tagModelDaos.add(tagModelDao);
+ }
+
+ return tagModelDaos;
+ }
+}
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceAndInvoicePaymentDao.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceAndInvoicePaymentDao.java
index 60f46e9..b13f3a7 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceAndInvoicePaymentDao.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceAndInvoicePaymentDao.java
@@ -125,6 +125,7 @@ public class TestBusinessInvoiceAndInvoicePaymentDao extends AnalyticsTestSuiteN
// Setup the mocks
// TODO this is really fragile - we need to extract a mock library for testing Kill Bill
+ Mockito.when(osgiKillbillApi.getAccountUserApi().getAccountById(account.getId(), callContext)).thenReturn(account);
Mockito.when(osgiKillbillApi.getInvoiceUserApi().getInvoicesByAccount(account.getId(), callContext)).thenReturn(ImmutableList.<Invoice>of(invoice349, invoice570));
Mockito.when(osgiKillbillApi.getInvoiceUserApi().getInvoice(invoice349Id, callContext)).thenReturn(invoice349);
Mockito.when(osgiKillbillApi.getInvoiceUserApi().getInvoice(invoice570Id, callContext)).thenReturn(invoice570);
@@ -140,7 +141,7 @@ public class TestBusinessInvoiceAndInvoicePaymentDao extends AnalyticsTestSuiteN
final Map<UUID, BusinessInvoiceModelDao> invoices = new HashMap<UUID, BusinessInvoiceModelDao>();
final Map<UUID, Collection<BusinessInvoiceItemBaseModelDao>> invoiceItems = new HashMap<UUID, Collection<BusinessInvoiceItemBaseModelDao>>();
final Map<UUID, Collection<BusinessInvoicePaymentBaseModelDao>> invoicePayments = new HashMap<UUID, Collection<BusinessInvoicePaymentBaseModelDao>>();
- dao.createBusinessPojos(account, invoices, invoiceItems, invoicePayments, callContext);
+ dao.createBusinessPojos(account.getId(), invoices, invoiceItems, invoicePayments, callContext);
/*
* Expected Business invoice 349: