killbill-aplcache

analytics: import new model The DAO for the new tables hasn't

6/20/2012 4:20:58 PM

Changes

Details

diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessAccount.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessAccount.java
index bfc2da0..a4c31bf 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessAccount.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessAccount.java
@@ -31,8 +31,8 @@ public class BusinessAccount {
     private DateTime updatedDt = null;
 
     private final String key;
+    private String name;
     private BigDecimal balance;
-    private List<Tag> tags;
     private DateTime lastInvoiceDate;
     private BigDecimal totalInvoiceBalance;
     private String lastPaymentStatus;
@@ -40,15 +40,15 @@ public class BusinessAccount {
     private String creditCardType;
     private String billingAddressCountry;
 
-    public BusinessAccount(final String key, final BigDecimal balance, final List<Tag> tags, final DateTime lastInvoiceDate, final BigDecimal totalInvoiceBalance, final String lastPaymentStatus, final String paymentMethod, final String creditCardType, final String billingAddressCountry) {
+    public BusinessAccount(final String key, final String name, final BigDecimal balance, final DateTime lastInvoiceDate, final BigDecimal totalInvoiceBalance, final String lastPaymentStatus, final String paymentMethod, final String creditCardType, final String billingAddressCountry) {
         this.key = key;
         this.balance = balance;
         this.billingAddressCountry = billingAddressCountry;
         this.creditCardType = creditCardType;
         this.lastInvoiceDate = lastInvoiceDate;
         this.lastPaymentStatus = lastPaymentStatus;
+        this.name = name;
         this.paymentMethod = paymentMethod;
-        this.tags = tags;
         this.totalInvoiceBalance = totalInvoiceBalance;
     }
 
@@ -108,20 +108,20 @@ public class BusinessAccount {
         this.lastPaymentStatus = lastPaymentStatus;
     }
 
-    public String getPaymentMethod() {
-        return paymentMethod;
+    public String getName() {
+        return name;
     }
 
-    public void setPaymentMethod(final String paymentMethod) {
-        this.paymentMethod = paymentMethod;
+    public void setName(final String name) {
+        this.name = name;
     }
 
-    public List<Tag> getTags() {
-        return tags;
+    public String getPaymentMethod() {
+        return paymentMethod;
     }
 
-    public void setTags(final List<Tag> tags) {
-        this.tags = tags;
+    public void setPaymentMethod(final String paymentMethod) {
+        this.paymentMethod = paymentMethod;
     }
 
     public BigDecimal getTotalInvoiceBalance() {
@@ -152,9 +152,7 @@ public class BusinessAccount {
         sb.append(", createdDt=").append(createdDt);
         sb.append(", updatedDt=").append(updatedDt);
         sb.append(", key='").append(key).append('\'');
-        sb.append(", tags=");
-        final Joiner joiner = Joiner.on(";").skipNulls();
-        sb.append(joiner.join(tags));
+        sb.append(", name='").append(name).append('\'');
         sb.append(", lastInvoiceDate=").append(lastInvoiceDate);
         sb.append(", totalInvoiceBalance=").append(totalInvoiceBalance);
         sb.append(", lastPaymentStatus='").append(lastPaymentStatus).append('\'');
@@ -197,10 +195,10 @@ public class BusinessAccount {
         if (lastPaymentStatus != null ? !lastPaymentStatus.equals(that.lastPaymentStatus) : that.lastPaymentStatus != null) {
             return false;
         }
-        if (paymentMethod != null ? !paymentMethod.equals(that.paymentMethod) : that.paymentMethod != null) {
+        if (name != null ? !name.equals(that.name) : that.name != null) {
             return false;
         }
-        if (tags != null ? !tags.toString().equals(that.tags.toString()) : that.tags != null) {
+        if (paymentMethod != null ? !paymentMethod.equals(that.paymentMethod) : that.paymentMethod != null) {
             return false;
         }
         if (totalInvoiceBalance == null ? that.totalInvoiceBalance != null : totalInvoiceBalance.compareTo(that.totalInvoiceBalance) != 0) {
@@ -218,8 +216,8 @@ public class BusinessAccount {
         int result = createdDt != null ? createdDt.hashCode() : 0;
         result = 31 * result + (updatedDt != null ? updatedDt.hashCode() : 0);
         result = 31 * result + (key != null ? key.hashCode() : 0);
+        result = 31 * result + (name != null ? name.hashCode() : 0);
         result = 31 * result + (balance != null ? balance.hashCode() : 0);
-        result = 31 * result + (tags != null ? tags.hashCode() : 0);
         result = 31 * result + (lastInvoiceDate != null ? lastInvoiceDate.hashCode() : 0);
         result = 31 * result + (totalInvoiceBalance != null ? totalInvoiceBalance.hashCode() : 0);
         result = 31 * result + (lastPaymentStatus != null ? lastPaymentStatus.hashCode() : 0);
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java
index 0877ae4..eeec61e 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java
@@ -136,8 +136,8 @@ public class BusinessAccountRecorder {
     private BusinessAccount createBusinessAccountFromAccount(final Account account, final List<Tag> tags) {
         final BusinessAccount bac = new BusinessAccount(
                 account.getExternalKey(),
+                account.getName(),
                 invoiceUserApi.getAccountBalance(account.getId()),
-                tags,
                 // These fields will be updated below
                 null,
                 null,
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransition.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransition.java
index 6749260..c163a2a 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransition.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransition.java
@@ -16,8 +16,6 @@
 
 package com.ning.billing.analytics;
 
-import java.util.UUID;
-
 import org.joda.time.DateTime;
 
 /**
@@ -26,20 +24,20 @@ import org.joda.time.DateTime;
  * The key is unique identifier that ties sets of subscriptions together.
  */
 public class BusinessSubscriptionTransition {
-    private final UUID id;
-    private final String key;
+    private final long totalOrdering;
+    private final String externalKey;
     private final String accountKey;
     private final DateTime requestedTimestamp;
     private final BusinessSubscriptionEvent event;
     private final BusinessSubscription previousSubscription;
     private final BusinessSubscription nextSubscription;
 
-    public BusinessSubscriptionTransition(final UUID id, final String key, final String accountKey, final DateTime requestedTimestamp, final BusinessSubscriptionEvent event, final BusinessSubscription previousSubscription, final BusinessSubscription nextSubscription) {
-        if (id == null) {
-            throw new IllegalArgumentException("An event must have an id");
+    public BusinessSubscriptionTransition(final Long totalOrdering, final String externalKey, final String accountKey, final DateTime requestedTimestamp, final BusinessSubscriptionEvent event, final BusinessSubscription previousSubscription, final BusinessSubscription nextSubscription) {
+        if (totalOrdering == null) {
+            throw new IllegalArgumentException("An event must have a total ordering");
         }
-        if (key == null) {
-            throw new IllegalArgumentException("An event must have an key");
+        if (externalKey == null) {
+            throw new IllegalArgumentException("An event must have an external key");
         }
         if (accountKey == null) {
             throw new IllegalArgumentException("An event must have an account key");
@@ -51,8 +49,8 @@ public class BusinessSubscriptionTransition {
             throw new IllegalArgumentException("No event specified");
         }
 
-        this.id = id;
-        this.key = key;
+        this.totalOrdering = totalOrdering;
+        this.externalKey = externalKey;
         this.accountKey = accountKey;
         this.requestedTimestamp = requestedTimestamp;
         this.event = event;
@@ -60,16 +58,16 @@ public class BusinessSubscriptionTransition {
         this.nextSubscription = nextSubscription;
     }
 
-    public UUID getId() {
-        return id;
+    public long getTotalOrdering() {
+        return totalOrdering;
     }
 
     public BusinessSubscriptionEvent getEvent() {
         return event;
     }
 
-    public String getKey() {
-        return key;
+    public String getExternalKey() {
+        return externalKey;
     }
 
     public String getAccountKey() {
@@ -93,8 +91,8 @@ public class BusinessSubscriptionTransition {
         final StringBuilder sb = new StringBuilder();
         sb.append("BusinessSubscriptionTransition");
         sb.append("{accountKey='").append(accountKey).append('\'');
-        sb.append(", id=").append(id);
-        sb.append(", key='").append(key).append('\'');
+        sb.append(", totalOrdering=").append(totalOrdering);
+        sb.append(", key='").append(externalKey).append('\'');
         sb.append(", requestedTimestamp=").append(requestedTimestamp);
         sb.append(", event=").append(event);
         sb.append(", previousSubscription=").append(previousSubscription);
@@ -120,10 +118,10 @@ public class BusinessSubscriptionTransition {
         if (event != null ? !event.equals(that.event) : that.event != null) {
             return false;
         }
-        if (id != null ? !id.equals(that.id) : that.id != null) {
+        if (totalOrdering != that.totalOrdering) {
             return false;
         }
-        if (key != null ? !key.equals(that.key) : that.key != null) {
+        if (externalKey != null ? !externalKey.equals(that.externalKey) : that.externalKey != null) {
             return false;
         }
         if (nextSubscription != null ? !nextSubscription.equals(that.nextSubscription) : that.nextSubscription != null) {
@@ -141,8 +139,8 @@ public class BusinessSubscriptionTransition {
 
     @Override
     public int hashCode() {
-        int result = id != null ? id.hashCode() : 0;
-        result = 31 * result + (key != null ? key.hashCode() : 0);
+        int result = (int) (totalOrdering ^ (totalOrdering >>> 32));
+        result = 31 * result + (externalKey != null ? externalKey.hashCode() : 0);
         result = 31 * result + (accountKey != null ? accountKey.hashCode() : 0);
         result = 31 * result + (requestedTimestamp != null ? requestedTimestamp.hashCode() : 0);
         result = 31 * result + (event != null ? event.hashCode() : 0);
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionRecorder.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionRecorder.java
index 80db909..f15b760 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionRecorder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionRecorder.java
@@ -84,13 +84,13 @@ public class BusinessSubscriptionTransitionRecorder {
     void recordTransition(final BusinessSubscriptionEvent event, final SubscriptionEvent transition)
             throws AccountApiException, EntitlementUserApiException {
         Currency currency = null;
-        String transitionKey = null;
+        String externalKey = null;
         String accountKey = null;
 
         // Retrieve key and currency via the bundle
         final SubscriptionBundle bundle = entitlementApi.getBundleFromId(transition.getBundleId());
         if (bundle != null) {
-            transitionKey = bundle.getKey();
+            externalKey = bundle.getKey();
 
             final Account account = accountApi.getAccountById(bundle.getAccountId());
             if (account != null) {
@@ -104,7 +104,7 @@ public class BusinessSubscriptionTransitionRecorder {
         DateTime previousEffectiveTransitionTime = null;
         // For creation events, the prev subscription will always be null
         if (event.getEventType() != BusinessSubscriptionEvent.EventType.ADD) {
-            final List<BusinessSubscriptionTransition> transitions = dao.getTransitions(transitionKey);
+            final List<BusinessSubscriptionTransition> transitions = dao.getTransitions(externalKey);
             if (transitions != null && transitions.size() > 0) {
                 final BusinessSubscriptionTransition lastTransition = transitions.get(transitions.size() - 1);
                 if (lastTransition != null && lastTransition.getNextSubscription() != null) {
@@ -129,14 +129,14 @@ public class BusinessSubscriptionTransitionRecorder {
             nextSubscription = new BusinessSubscription(transition.getNextPriceList(), transition.getNextPlan(), transition.getNextPhase(), currency, transition.getEffectiveTransitionTime(), transition.getNextState(), transition.getSubscriptionId(), transition.getBundleId(), catalogService.getFullCatalog());
         }
 
-        record(transition.getId(), transitionKey, accountKey, transition.getRequestedTransitionTime(), event, prevSubscription, nextSubscription);
+        record(transition.getTotalOrdering(), externalKey, accountKey, transition.getRequestedTransitionTime(), event, prevSubscription, nextSubscription);
     }
 
     // Public for internal reasons
-    public void record(final UUID id, final String key, final String accountKey, final DateTime requestedDateTime, final BusinessSubscriptionEvent event, final BusinessSubscription prevSubscription, final BusinessSubscription nextSubscription) {
+    public void record(final Long totalOrdering, final String externalKey, final String accountKey, final DateTime requestedDateTime, final BusinessSubscriptionEvent event, final BusinessSubscription prevSubscription, final BusinessSubscription nextSubscription) {
         final BusinessSubscriptionTransition transition = new BusinessSubscriptionTransition(
-                id,
-                key,
+                totalOrdering,
+                externalKey,
                 accountKey,
                 requestedDateTime,
                 event,
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountBinder.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountBinder.java
index 234e543..d17e9c7 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountBinder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountBinder.java
@@ -54,7 +54,7 @@ public @interface BusinessAccountBinder {
 
                     q.bind("account_key", account.getKey());
                     q.bind("balance", account.getRoundedBalance());
-                    q.bind("tags", joiner.join(account.getTags()));
+                    q.bind("name", account.getName());
                     if (account.getLastInvoiceDate() != null) {
                         q.bind("last_invoice_date", account.getLastInvoiceDate().getMillis());
                     } else {
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountMapper.java
index 366bb3b..8c94e32 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountMapper.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountMapper.java
@@ -19,54 +19,21 @@ package com.ning.billing.analytics.dao;
 import java.math.BigDecimal;
 import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
 
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import com.google.common.base.Splitter;
-import com.google.common.collect.Iterables;
 import com.ning.billing.analytics.BusinessAccount;
-import com.ning.billing.util.tag.Tag;
 
 public class BusinessAccountMapper implements ResultSetMapper<BusinessAccount> {
-    private final Splitter splitter = Splitter.on(";").trimResults().omitEmptyStrings();
-
     @Override
     public BusinessAccount map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
-        final List<String> tagNames = new ArrayList<String>();
-        Iterables.addAll(tagNames, splitter.split(r.getString(5)));
-
-        final List<Tag> tags = new ArrayList<Tag>();
-        for (final String tagName : tagNames) {
-            tags.add(new Tag() {
-                private final UUID id = UUID.randomUUID();
-
-                @Override
-                public String getTagDefinitionName() {
-                    return tagName;
-                }
-
-                @Override
-                public UUID getId() {
-                    return id;
-                }
-
-                @Override
-                public String toString() {
-                    return tagName;
-                }
-            });
-        }
-
         final BusinessAccount account = new BusinessAccount(
                 r.getString(1),
+                r.getString(5),
                 BigDecimal.valueOf(r.getDouble(4)),
-                tags,
                 new DateTime(r.getLong(6), DateTimeZone.UTC),
                 BigDecimal.valueOf(r.getDouble(7)),
                 r.getString(8),
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionBinder.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionBinder.java
index 2a04c8e..fc2cd40 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionBinder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionBinder.java
@@ -39,8 +39,8 @@ public @interface BusinessSubscriptionTransitionBinder {
         public Binder build(final Annotation annotation) {
             return new Binder<BusinessSubscriptionTransitionBinder, BusinessSubscriptionTransition>() {
                 public void bind(final SQLStatement q, final BusinessSubscriptionTransitionBinder bind, final BusinessSubscriptionTransition arg) {
-                    q.bind("event_id", arg.getId().toString());
-                    q.bind("event_key", arg.getKey());
+                    q.bind("total_ordering", arg.getTotalOrdering());
+                    q.bind("external_key", arg.getExternalKey());
                     q.bind("account_key", arg.getAccountKey());
                     q.bind("requested_timestamp", arg.getRequestedTimestamp().getMillis());
                     q.bind("event", arg.getEvent().toString());
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionDao.java
index a05aeca..82b35fe 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionDao.java
@@ -30,7 +30,7 @@ import com.ning.billing.analytics.BusinessSubscriptionTransition;
 @RegisterMapper(BusinessSubscriptionTransitionMapper.class)
 public interface BusinessSubscriptionTransitionDao {
     @SqlQuery
-    List<BusinessSubscriptionTransition> getTransitions(@Bind("event_key") final String key);
+    List<BusinessSubscriptionTransition> getTransitions(@Bind("external_key") final String externalKey);
 
     @SqlUpdate
     int createTransition(@BusinessSubscriptionTransitionBinder final BusinessSubscriptionTransition transition);
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionMapper.java
index ac38463..3ff9b1e 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionMapper.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionMapper.java
@@ -83,7 +83,7 @@ public class BusinessSubscriptionTransitionMapper implements ResultSetMapper<Bus
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.valueOf(r.getString(5));
 
         return new BusinessSubscriptionTransition(
-                UUID.fromString(r.getString(1)),
+                r.getLong(1),
                 r.getString(2),
                 r.getString(3),
                 new DateTime(r.getLong(4), DateTimeZone.UTC),
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountDao.sql.stg
index 10f27b8..e4cfa8d 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountDao.sql.stg
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountDao.sql.stg
@@ -6,7 +6,7 @@ getAccount(account_key) ::= <<
   , created_date
   , updated_date
   , balance
-  , tags
+  , name
   , last_invoice_date
   , total_invoice_balance
   , last_payment_status
@@ -25,7 +25,7 @@ createAccount() ::= <<
   , created_date
   , updated_date
   , balance
-  , tags
+  , name
   , last_invoice_date
   , total_invoice_balance
   , last_payment_status
@@ -37,7 +37,7 @@ createAccount() ::= <<
   , :created_date
   , :updated_date
   , :balance
-  , :tags
+  , :name
   , :last_invoice_date
   , :total_invoice_balance
   , :last_payment_status
@@ -51,7 +51,7 @@ saveAccount() ::= <<
   update bac set
     updated_date=:updated_date
   , balance=:balance
-  , tags=:tags
+  , name=:name
   , last_invoice_date=:last_invoice_date
   , total_invoice_balance=:total_invoice_balance
   , last_payment_status=:last_payment_status
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionDao.sql.stg
index de6076e..c80b6b5 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionDao.sql.stg
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionDao.sql.stg
@@ -1,9 +1,9 @@
 group BusinessSubscriptionTransition;
 
-getTransitions(event_key) ::= <<
+getTransitions(external_key) ::= <<
   select
-    event_id
-  , event_key
+    total_ordering
+  , external_key
   , account_key
   , requested_timestamp
   , event
@@ -36,15 +36,15 @@ getTransitions(event_key) ::= <<
   , next_subscription_id
   , next_bundle_id
   from bst
-  where event_key=:event_key
+  where external_key=:external_key
   order by requested_timestamp asc
   ;
 >>
 
 createTransition() ::= <<
   insert ignore into bst(
-    event_id
-  , event_key
+    total_ordering
+  , external_key
   , account_key
   , requested_timestamp
   , event
@@ -77,8 +77,8 @@ createTransition() ::= <<
   , next_subscription_id
   , next_bundle_id
   ) values (
-    :event_id
-  , :event_key
+    :total_ordering
+  , :external_key
   , :account_key
   , :requested_timestamp
   , :event
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/ddl.sql b/analytics/src/main/resources/com/ning/billing/analytics/ddl.sql
index 7240236..69393c2 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/ddl.sql
+++ b/analytics/src/main/resources/com/ning/billing/analytics/ddl.sql
@@ -1,8 +1,8 @@
 drop table if exists bst;
 create table bst (
-  event_id char(36) not null
-, event_key varchar(50) not null
-, account_key varchar(50) not null
+  total_ordering bigint default 0
+, external_key varchar(50) not null comment 'Bundle external key'
+, account_key varchar(50) not null comment 'Account external key'
 , requested_timestamp bigint not null
 , event varchar(50) not null
 , prev_product_name varchar(32) default null
@@ -33,22 +33,143 @@ create table bst (
 , next_state varchar(32) default null
 , next_subscription_id varchar(100) default null
 , next_bundle_id varchar(100) default null
-, primary key(event_id)
-) engine=innodb;
-create index bst_key_index on bst (event_key, requested_timestamp asc);
+, primary key(total_ordering)
+) engine=innodb comment 'Business Subscription Transitions, describe the lifecycle of the bundles';
+create index bst_key_index on bst (external_key, requested_timestamp asc);
 
 drop table if exists bac;
 create table bac (
   account_key varchar(50) not null
+, name varchar(100) not null
 , created_date bigint not null
 , updated_date bigint not null
 , balance numeric(10, 4) default 0
-, tags varchar(500) default null
 , last_invoice_date bigint default null
 , total_invoice_balance numeric(10, 4) default 0
 , last_payment_status varchar(100) default null
 , payment_method varchar(100) default null
 , credit_card_type varchar(32) default null
 , billing_address_country varchar(100) default null
-) engine=innodb;
-create unique index bac_key_index on bac (account_key);
\ No newline at end of file
+, currency char(3) default null
+) engine=innodb comment 'Business ACcounts, keep a record of all accounts';
+create unique index bac_key_index on bac (account_key);
+
+drop table if exists bin;
+create table bin (
+  invoice_id char(36) not null
+, created_date bigint not null
+, updated_date bigint not null
+, account_key varchar(50) not null
+, invoice_date bigint not null
+, target_date bigint not null
+, currency char(3) not null
+, balance numeric(10, 4) default 0 comment 'amount_charged - amount_paid - amount_credited'
+, amount_paid numeric(10, 4) default 0 comment 'Sums of the successful payments made for this invoice minus the refunds associated with this invoice'
+, amount_charged numeric(10, 4) default 0 comment 'Sums of the invoice items amount'
+, amount_credited numeric(10, 4) default 0 comment 'Sums of the credit items'
+) engine=innodb comment 'Business INvoices, keep a record of generated invoices';
+create unique index bin_key_index on bin (invoice_id);
+
+drop table if exists bii;
+create table bii (
+  item_id char(36) not null
+, created_date bigint not null
+, updated_date bigint not null
+, invoice_id char(36) not null
+, item_type char(20) not null comment 'e.g. FIXED or RECURRING'
+, external_key varchar(50) not null comment 'Bundle external key'
+, product_name varchar(32) default null
+, product_type varchar(32) default null
+, product_category varchar(32) default null
+, slug varchar(50) default null comment 'foo'
+, phase varchar(32) default null
+, billing_period varchar(32) default null
+, start_date bigint default null
+, end_date bigint default null
+, amount numeric(10, 4) default 0
+, currency char(3) default null
+) engine=innodb comment 'Business Invoice Items, keep a record of generated invoice items';
+create unique index bii_key_index on bii (item_id);
+
+drop table if exists bip;
+create table bip (
+  payment_id char(36) not null
+, created_date bigint not null
+, updated_date bigint not null
+, attempt_id char(36) not null
+, account_key varchar(50) not null comment 'Account external key'
+, invoice_id char(36) not null
+, effective_date bigint default null
+, amount numeric(10, 4) default 0
+, currency char(3) default null
+, payment_error varchar(256) default null
+, processing_status varchar(50) default null
+, requested_amount numeric(10, 4) default 0
+, plugin_name varchar(20) default null
+, payment_type varchar(20) default null
+, payment_method varchar(20) default null
+, card_type varchar(20) default null
+, card_country varchar(20) default null
+) engine=innodb comment 'Business Invoice Payments, keep a record of all payment attempts';
+create unique index bip_key_index on bip (attempt_id);
+
+drop table if exists bos;
+create table bos (
+  external_key varchar(50) not null comment 'Bundle external key'
+, status varchar(50) not null
+, start_date bigint default null
+, end_date bigint default null
+) engine=innodb comment 'Business Overdue Status, describe the historical overdue status of the bundles';
+create unique index bos_key_index on bos (external_key, status);
+
+drop table if exists bac_tags;
+create table bac_tags (
+  account_key varchar(50) not null comment 'Account external key'
+, name varchar(20) not null
+) engine=innodb comment 'Tags associated to accounts';
+
+drop table if exists bac_fields;
+create table bac_fields (
+  account_key varchar(50) not null comment 'Account external key'
+, name varchar(30) not null
+, value varchar(255) default null
+) engine=innodb comment 'Custom fields associated to accounts';
+
+drop table if exists bst_tags;
+create table bst_tags (
+  external_key varchar(50) not null comment 'Bundle external key'
+, name varchar(20) not null
+) engine=innodb comment 'Tags associated to bundles';
+
+drop table if exists bst_fields;
+create table bst_fields (
+  external_key varchar(50) not null comment 'Bundle external key'
+, name varchar(30) not null
+, value varchar(255) default null
+) engine=innodb comment 'Custom fields associated to bundles';
+
+drop table if exists bin_tags;
+create table bin_tags (
+  invoice_id char(36) not null
+, name varchar(20) not null
+) engine=innodb comment 'Tags associated to invoices';
+
+drop table if exists bin_fields;
+create table bin_fields (
+  invoice_id char(36) not null
+, name varchar(30) not null
+, value varchar(255) default null
+) engine=innodb comment 'Custom fields associated to invoices';
+
+drop table if exists bip_tags;
+create table bip_tags (
+  payment_id char(36) not null
+, name varchar(20) not null
+) engine=innodb comment 'Tags associated to payments';
+
+drop table if exists bip_fields;
+create table bip_fields (
+  payment_id char(36) not null
+, name varchar(30) not null
+, value varchar(255) default null
+) engine=innodb comment 'Custom fields associated to payments';
diff --git a/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java b/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
index 0094ca4..0f7a554 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
@@ -94,8 +94,8 @@ public class TestAnalyticsService extends TestWithEmbeddedDB {
     final Plan plan = new MockPlan("platinum-monthly", product);
     final PlanPhase phase = new MockPhase(PhaseType.EVERGREEN, plan, MockDuration.UNLIMITED(), 25.95);
 
-    private static final UUID ID = UUID.randomUUID();
-    private static final String KEY = "12345";
+    private static final Long TOTAL_ORDERING = 11L;
+    private static final String EXTERNAL_KEY = "12345";
     private static final String ACCOUNT_KEY = "pierre-12345";
     private static final Currency ACCOUNT_CURRENCY = Currency.EUR;
     private static final BigDecimal INVOICE_AMOUNT = BigDecimal.valueOf(1243.11);
@@ -165,11 +165,11 @@ public class TestAnalyticsService extends TestWithEmbeddedDB {
     }
 
     private void createSubscriptionTransitionEvent(final Account account) throws EntitlementUserApiException {
-        final SubscriptionBundle bundle = entitlementApi.createBundleForAccount(account.getId(), KEY, context);
+        final SubscriptionBundle bundle = entitlementApi.createBundleForAccount(account.getId(), EXTERNAL_KEY, context);
 
         // Verify we correctly initialized the account subsystem
         Assert.assertNotNull(bundle);
-        Assert.assertEquals(bundle.getKey(), KEY);
+        Assert.assertEquals(bundle.getKey(), EXTERNAL_KEY);
 
         // Create a subscription transition event
         final UUID subscriptionId = UUID.randomUUID();
@@ -179,7 +179,7 @@ public class TestAnalyticsService extends TestWithEmbeddedDB {
 
 
         transition = new DefaultSubscriptionEvent(new SubscriptionTransitionData(
-                ID,
+                UUID.randomUUID(),
                 subscriptionId,
                 bundle.getId(),
                 EntitlementEvent.EventType.API_USER,
@@ -194,12 +194,12 @@ public class TestAnalyticsService extends TestWithEmbeddedDB {
                 plan,
                 phase,
                 priceList,
-                1L,
+                TOTAL_ORDERING,
                 null,
                 true), null);
         expectedTransition = new BusinessSubscriptionTransition(
-                ID,
-                KEY,
+                TOTAL_ORDERING,
+                EXTERNAL_KEY,
                 ACCOUNT_KEY,
                 requestedTransitionTime,
                 BusinessSubscriptionEvent.subscriptionCreated(plan.getName(), catalog, new DateTime(), new DateTime()),
@@ -268,8 +268,8 @@ public class TestAnalyticsService extends TestWithEmbeddedDB {
         bus.post(accountCreationNotification);
         Thread.sleep(5000);
 
-        Assert.assertEquals(subscriptionDao.getTransitions(KEY).size(), 1);
-        Assert.assertEquals(subscriptionDao.getTransitions(KEY).get(0), expectedTransition);
+        Assert.assertEquals(subscriptionDao.getTransitions(EXTERNAL_KEY).size(), 1);
+        Assert.assertEquals(subscriptionDao.getTransitions(EXTERNAL_KEY).get(0), expectedTransition);
 
         // Test invoice integration - the account creation notification has triggered a BAC update
         Assert.assertTrue(accountDao.getAccount(ACCOUNT_KEY).getTotalInvoiceBalance().compareTo(INVOICE_AMOUNT) == 0);
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java
index c9c31be..73fcf87 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java
@@ -19,7 +19,6 @@ package com.ning.billing.analytics.dao;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.sql.SQLException;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
@@ -51,11 +50,10 @@ import com.ning.billing.catalog.api.PlanPhase;
 import com.ning.billing.catalog.api.Product;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.entitlement.api.user.Subscription;
-import com.ning.billing.util.tag.Tag;
 
 public class TestAnalyticsDao extends TestWithEmbeddedDB {
-    private static final UUID EVENT_ID = UUID.randomUUID();
-    private static final String EVENT_KEY = "23456";
+    private static final Long TOTAL_ORDERING = 1L;
+    private static final String EXTERNAL_KEY = "23456";
     private static final String ACCOUNT_KEY = "pierre-143343-vcc";
 
     private final Product product = new MockProduct("platinium", "subscription", ProductCategory.BASE);
@@ -87,7 +85,7 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
         final BusinessSubscription nextSubscription = new BusinessSubscription(null, plan.getName(), phase.getName(), Currency.USD, new DateTime(DateTimeZone.UTC), Subscription.SubscriptionState.CANCELLED, UUID.randomUUID(), UUID.randomUUID(), catalog);
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionCancelled(plan.getName(), catalog, requestedTimestamp, requestedTimestamp);
 
-        transition = new BusinessSubscriptionTransition(EVENT_ID, EVENT_KEY, ACCOUNT_KEY, requestedTimestamp, event, prevSubscription, nextSubscription);
+        transition = new BusinessSubscriptionTransition(TOTAL_ORDERING, EXTERNAL_KEY, ACCOUNT_KEY, requestedTimestamp, event, prevSubscription, nextSubscription);
 
         final IDBI dbi = helper.getDBI();
         businessSubscriptionTransitionDao = dbi.onDemand(BusinessSubscriptionTransitionDao.class);
@@ -101,10 +99,7 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
     }
 
     private void setupBusinessAccount() {
-        final List<Tag> tags = new ArrayList<Tag>();
-        tags.add(getMockTag("batch1"));
-        tags.add(getMockTag("great,guy"));
-        account = new BusinessAccount(ACCOUNT_KEY, BigDecimal.ONE, tags, new DateTime(DateTimeZone.UTC), BigDecimal.TEN, "ERROR_NOT_ENOUGH_FUNDS", "CreditCard", "Visa", "FRANCE");
+        account = new BusinessAccount(ACCOUNT_KEY, UUID.randomUUID().toString(), BigDecimal.ONE, new DateTime(DateTimeZone.UTC), BigDecimal.TEN, "ERROR_NOT_ENOUGH_FUNDS", "CreditCard", "Visa", "FRANCE");
 
         final IDBI dbi = helper.getDBI();
         businessAccountDao = dbi.onDemand(BusinessAccountDao.class);
@@ -117,18 +112,11 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
         }
     }
 
-    private Tag getMockTag(final String tagDefinitionName) {
-        final Tag tag = Mockito.mock(Tag.class);
-        Mockito.when(tag.getTagDefinitionName()).thenReturn(tagDefinitionName);
-        Mockito.when(tag.toString()).thenReturn(tagDefinitionName);
-        return tag;
-    }
-
     @Test(groups = "slow")
     public void testHandleDuplicatedEvents() {
         final BusinessSubscriptionTransition transitionWithNullPrev = new BusinessSubscriptionTransition(
-                transition.getId(),
-                transition.getKey(),
+                transition.getTotalOrdering(),
+                transition.getExternalKey(),
                 transition.getAccountKey(),
                 transition.getRequestedTimestamp(),
                 transition.getEvent(),
@@ -137,19 +125,19 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
         );
 
         businessSubscriptionTransitionDao.createTransition(transitionWithNullPrev);
-        List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EVENT_KEY);
+        List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EXTERNAL_KEY);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0), transitionWithNullPrev);
         // Try to add the same transition, with the same UUID - we should only store one though
         businessSubscriptionTransitionDao.createTransition(transitionWithNullPrev);
-        transitions = businessSubscriptionTransitionDao.getTransitions(EVENT_KEY);
+        transitions = businessSubscriptionTransitionDao.getTransitions(EXTERNAL_KEY);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0), transitionWithNullPrev);
 
         // Try now to store a look-alike transition (same fields except UUID) - we should store it this time
         final BusinessSubscriptionTransition secondTransitionWithNullPrev = new BusinessSubscriptionTransition(
-                UUID.randomUUID(),
-                transition.getKey(),
+                12L,
+                transition.getExternalKey(),
                 transition.getAccountKey(),
                 transition.getRequestedTimestamp(),
                 transition.getEvent(),
@@ -157,7 +145,7 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
                 transition.getNextSubscription()
         );
         businessSubscriptionTransitionDao.createTransition(secondTransitionWithNullPrev);
-        transitions = businessSubscriptionTransitionDao.getTransitions(EVENT_KEY);
+        transitions = businessSubscriptionTransitionDao.getTransitions(EXTERNAL_KEY);
         Assert.assertEquals(transitions.size(), 2);
         Assert.assertTrue(transitions.contains(transitionWithNullPrev));
         Assert.assertTrue(transitions.contains(secondTransitionWithNullPrev));
@@ -166,8 +154,8 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
     @Test(groups = "slow")
     public void testTransitionsWithNullPrevSubscription() {
         final BusinessSubscriptionTransition transitionWithNullPrev = new BusinessSubscriptionTransition(
-                transition.getId(),
-                transition.getKey(),
+                transition.getTotalOrdering(),
+                transition.getExternalKey(),
                 transition.getAccountKey(),
                 transition.getRequestedTimestamp(),
                 transition.getEvent(),
@@ -176,7 +164,7 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
         );
         businessSubscriptionTransitionDao.createTransition(transitionWithNullPrev);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EVENT_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EXTERNAL_KEY);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0), transitionWithNullPrev);
     }
@@ -184,8 +172,8 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
     @Test(groups = "slow")
     public void testTransitionsWithNullNextSubscription() {
         final BusinessSubscriptionTransition transitionWithNullNext = new BusinessSubscriptionTransition(
-                transition.getId(),
-                transition.getKey(),
+                transition.getTotalOrdering(),
+                transition.getExternalKey(),
                 transition.getAccountKey(),
                 transition.getRequestedTimestamp(),
                 transition.getEvent(),
@@ -194,7 +182,7 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
         );
         businessSubscriptionTransitionDao.createTransition(transitionWithNullNext);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EVENT_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EXTERNAL_KEY);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0), transitionWithNullNext);
     }
@@ -203,8 +191,8 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
     public void testTransitionsWithNullFieldsInSubscription() {
         final BusinessSubscription subscriptionWithNullFields = new BusinessSubscription(null, plan.getName(), phase.getName(), Currency.USD, null, null, null, null, catalog);
         final BusinessSubscriptionTransition transitionWithNullFields = new BusinessSubscriptionTransition(
-                transition.getId(),
-                transition.getKey(),
+                transition.getTotalOrdering(),
+                transition.getExternalKey(),
                 transition.getAccountKey(),
                 transition.getRequestedTimestamp(),
                 transition.getEvent(),
@@ -213,7 +201,7 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
         );
         businessSubscriptionTransitionDao.createTransition(transitionWithNullFields);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EVENT_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EXTERNAL_KEY);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0), transitionWithNullFields);
     }
@@ -222,8 +210,8 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
     public void testTransitionsWithNullPlanAndPhase() throws Exception {
         final BusinessSubscription subscriptionWithNullPlanAndPhase = new BusinessSubscription(null, null, null, Currency.USD, null, null, null, null, catalog);
         final BusinessSubscriptionTransition transitionWithNullPlanAndPhase = new BusinessSubscriptionTransition(
-                transition.getId(),
-                transition.getKey(),
+                transition.getTotalOrdering(),
+                transition.getExternalKey(),
                 transition.getAccountKey(),
                 transition.getRequestedTimestamp(),
                 transition.getEvent(),
@@ -232,9 +220,9 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
         );
         businessSubscriptionTransitionDao.createTransition(transitionWithNullPlanAndPhase);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EVENT_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EXTERNAL_KEY);
         Assert.assertEquals(transitions.size(), 1);
-        Assert.assertEquals(transitions.get(0).getKey(), transition.getKey());
+        Assert.assertEquals(transitions.get(0).getExternalKey(), transition.getExternalKey());
         Assert.assertEquals(transitions.get(0).getRequestedTimestamp(), transition.getRequestedTimestamp());
         Assert.assertEquals(transitions.get(0).getEvent(), transition.getEvent());
         Assert.assertNull(transitions.get(0).getPreviousSubscription());
@@ -245,8 +233,8 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
     public void testTransitionsWithNullPlan() throws Exception {
         final BusinessSubscription subscriptionWithNullPlan = new BusinessSubscription(null, null, phase.getName(), Currency.USD, null, null, null, null, catalog);
         final BusinessSubscriptionTransition transitionWithNullPlan = new BusinessSubscriptionTransition(
-                transition.getId(),
-                transition.getKey(),
+                transition.getTotalOrdering(),
+                transition.getExternalKey(),
                 transition.getAccountKey(),
                 transition.getRequestedTimestamp(),
                 transition.getEvent(),
@@ -255,7 +243,7 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
         );
         businessSubscriptionTransitionDao.createTransition(transitionWithNullPlan);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EVENT_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EXTERNAL_KEY);
         Assert.assertEquals(transitions.size(), 1);
         // Null Plan but Phase - we don't turn the subscription into a null
         Assert.assertEquals(transitions.get(0), transitionWithNullPlan);
@@ -265,8 +253,8 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
     public void testTransitionsWithNullPhase() throws Exception {
         final BusinessSubscription subscriptionWithNullPhase = new BusinessSubscription(null, plan.getName(), null, Currency.USD, null, null, null, null, catalog);
         final BusinessSubscriptionTransition transitionWithNullPhase = new BusinessSubscriptionTransition(
-                transition.getId(),
-                transition.getKey(),
+                transition.getTotalOrdering(),
+                transition.getExternalKey(),
                 transition.getAccountKey(),
                 transition.getRequestedTimestamp(),
                 transition.getEvent(),
@@ -275,9 +263,9 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
         );
         businessSubscriptionTransitionDao.createTransition(transitionWithNullPhase);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EVENT_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EXTERNAL_KEY);
         Assert.assertEquals(transitions.size(), 1);
-        Assert.assertEquals(transitions.get(0).getKey(), transition.getKey());
+        Assert.assertEquals(transitions.get(0).getExternalKey(), transition.getExternalKey());
         Assert.assertEquals(transitions.get(0).getRequestedTimestamp(), transition.getRequestedTimestamp());
         Assert.assertEquals(transitions.get(0).getEvent(), transition.getEvent());
 
@@ -291,7 +279,7 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
     public void testCreateAndRetrieveTransitions() {
         businessSubscriptionTransitionDao.createTransition(transition);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EVENT_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EXTERNAL_KEY);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0), transition);
 
@@ -305,10 +293,6 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
         final BusinessAccount foundAccount = businessAccountDao.getAccount(ACCOUNT_KEY);
         Assert.assertNotNull(foundAccount.getCreatedDt());
         Assert.assertEquals(foundAccount.getCreatedDt(), foundAccount.getUpdatedDt());
-        // Verify the joiner stuff
-        Assert.assertEquals(foundAccount.getTags().size(), 2);
-        Assert.assertEquals(foundAccount.getTags().get(0).getTagDefinitionName(), "batch1");
-        Assert.assertEquals(foundAccount.getTags().get(1).getTagDefinitionName(), "great,guy");
         // Verify the dates by backfilling them
         account.setCreatedDt(foundAccount.getCreatedDt());
         account.setUpdatedDt(foundAccount.getUpdatedDt());
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockBusinessSubscriptionTransitionDao.java b/analytics/src/test/java/com/ning/billing/analytics/MockBusinessSubscriptionTransitionDao.java
index 68012eb..bab24cb 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockBusinessSubscriptionTransitionDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockBusinessSubscriptionTransitionDao.java
@@ -36,10 +36,10 @@ public class MockBusinessSubscriptionTransitionDao implements BusinessSubscripti
 
     @Override
     public int createTransition(@BusinessSubscriptionTransitionBinder final BusinessSubscriptionTransition transition) {
-        if (content.get(transition.getKey()) == null) {
-            content.put(transition.getKey(), new ArrayList<BusinessSubscriptionTransition>());
+        if (content.get(transition.getExternalKey()) == null) {
+            content.put(transition.getExternalKey(), new ArrayList<BusinessSubscriptionTransition>());
         }
-        content.get(transition.getKey()).add(transition);
+        content.get(transition.getExternalKey()).add(transition);
         return 1;
     }
 
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestAnalyticsListener.java b/analytics/src/test/java/com/ning/billing/analytics/TestAnalyticsListener.java
index 6a03abc..dfec125 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestAnalyticsListener.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestAnalyticsListener.java
@@ -44,7 +44,7 @@ import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.events.user.ApiEventType;
 
 public class TestAnalyticsListener extends AnalyticsTestSuite {
-    private static final String KEY = "1234";
+    private static final String EXTERNAL_KEY = "1234";
     private static final String ACCOUNT_KEY = "pierre-1234";
     private final Currency CURRENCY = Currency.BRL;
 
@@ -70,7 +70,7 @@ public class TestAnalyticsListener extends AnalyticsTestSuite {
 
     @BeforeMethod(groups = "fast")
     public void setUp() throws Exception {
-        final BusinessSubscriptionTransitionRecorder recorder = new BusinessSubscriptionTransitionRecorder(dao, catalogService, new MockEntitlementUserApi(bundleUUID, KEY), new MockAccountUserApi(ACCOUNT_KEY, CURRENCY));
+        final BusinessSubscriptionTransitionRecorder recorder = new BusinessSubscriptionTransitionRecorder(dao, catalogService, new MockEntitlementUserApi(bundleUUID, EXTERNAL_KEY), new MockAccountUserApi(ACCOUNT_KEY, CURRENCY));
         listener = new AnalyticsListener(recorder, null);
     }
 
@@ -80,59 +80,59 @@ public class TestAnalyticsListener extends AnalyticsTestSuite {
         final DateTime effectiveTransitionTime = new DateTime(DateTimeZone.UTC);
         final DateTime requestedTransitionTime = effectiveTransitionTime;
         final SubscriptionTransitionData firstTransition = createFirstSubscriptionTransition(requestedTransitionTime, effectiveTransitionTime);
-        final BusinessSubscriptionTransition firstBST = createExpectedFirstBST(firstTransition.getId(), requestedTransitionTime, effectiveTransitionTime);
+        final BusinessSubscriptionTransition firstBST = createExpectedFirstBST(firstTransition.getTotalOrdering(), requestedTransitionTime, effectiveTransitionTime);
         listener.handleSubscriptionTransitionChange(new DefaultSubscriptionEvent(firstTransition, effectiveTransitionTime));
-        Assert.assertEquals(dao.getTransitions(KEY).size(), 1);
-        Assert.assertEquals(dao.getTransitions(KEY).get(0), firstBST);
+        Assert.assertEquals(dao.getTransitions(EXTERNAL_KEY).size(), 1);
+        Assert.assertEquals(dao.getTransitions(EXTERNAL_KEY).get(0), firstBST);
 
         // Cancel it
         final DateTime effectiveCancelTransitionTime = new DateTime(DateTimeZone.UTC);
         final DateTime requestedCancelTransitionTime = effectiveCancelTransitionTime;
         final SubscriptionTransitionData cancelledSubscriptionTransition = createCancelSubscriptionTransition(requestedCancelTransitionTime, effectiveCancelTransitionTime, firstTransition.getNextState());
-        final BusinessSubscriptionTransition cancelledBST = createExpectedCancelledBST(cancelledSubscriptionTransition.getId(), requestedCancelTransitionTime, effectiveCancelTransitionTime, firstBST.getNextSubscription());
+        final BusinessSubscriptionTransition cancelledBST = createExpectedCancelledBST(cancelledSubscriptionTransition.getTotalOrdering(), requestedCancelTransitionTime, effectiveCancelTransitionTime, firstBST.getNextSubscription());
         listener.handleSubscriptionTransitionChange(new DefaultSubscriptionEvent(cancelledSubscriptionTransition, effectiveTransitionTime));
-        Assert.assertEquals(dao.getTransitions(KEY).size(), 2);
-        Assert.assertEquals(dao.getTransitions(KEY).get(1), cancelledBST);
+        Assert.assertEquals(dao.getTransitions(EXTERNAL_KEY).size(), 2);
+        Assert.assertEquals(dao.getTransitions(EXTERNAL_KEY).get(1), cancelledBST);
 
         // Recreate it
         final DateTime effectiveRecreatedTransitionTime = new DateTime(DateTimeZone.UTC);
         final DateTime requestedRecreatedTransitionTime = effectiveRecreatedTransitionTime;
         final SubscriptionTransitionData recreatedSubscriptionTransition = createRecreatedSubscriptionTransition(requestedRecreatedTransitionTime, effectiveRecreatedTransitionTime, cancelledSubscriptionTransition.getNextState());
-        final BusinessSubscriptionTransition recreatedBST = createExpectedRecreatedBST(recreatedSubscriptionTransition.getId(), requestedRecreatedTransitionTime, effectiveRecreatedTransitionTime, cancelledBST.getNextSubscription());
+        final BusinessSubscriptionTransition recreatedBST = createExpectedRecreatedBST(recreatedSubscriptionTransition.getTotalOrdering(), requestedRecreatedTransitionTime, effectiveRecreatedTransitionTime, cancelledBST.getNextSubscription());
         listener.handleSubscriptionTransitionChange(new DefaultSubscriptionEvent(recreatedSubscriptionTransition, effectiveTransitionTime));
-        Assert.assertEquals(dao.getTransitions(KEY).size(), 3);
-        Assert.assertEquals(dao.getTransitions(KEY).get(2), recreatedBST);
+        Assert.assertEquals(dao.getTransitions(EXTERNAL_KEY).size(), 3);
+        Assert.assertEquals(dao.getTransitions(EXTERNAL_KEY).get(2), recreatedBST);
 
     }
 
-    private BusinessSubscriptionTransition createExpectedFirstBST(final UUID id, final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime) {
+    private BusinessSubscriptionTransition createExpectedFirstBST(final Long totalOrdering, final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime) {
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionCreated(plan.getName(), catalog, effectiveTransitionTime, effectiveTransitionTime);
 
         final Subscription.SubscriptionState subscriptionState = Subscription.SubscriptionState.ACTIVE;
-        return createExpectedBST(id, event, requestedTransitionTime, effectiveTransitionTime, null, subscriptionState);
+        return createExpectedBST(totalOrdering, event, requestedTransitionTime, effectiveTransitionTime, null, subscriptionState);
     }
 
-    private BusinessSubscriptionTransition createExpectedCancelledBST(final UUID id, final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime, final BusinessSubscription lastSubscription) {
+    private BusinessSubscriptionTransition createExpectedCancelledBST(final Long totalOrdering, final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime, final BusinessSubscription lastSubscription) {
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionCancelled(plan.getName(), catalog, effectiveTransitionTime, effectiveTransitionTime);
-        return createExpectedBST(id, event, requestedTransitionTime, effectiveTransitionTime, lastSubscription, null);
+        return createExpectedBST(totalOrdering, event, requestedTransitionTime, effectiveTransitionTime, lastSubscription, null);
     }
 
-    private BusinessSubscriptionTransition createExpectedRecreatedBST(final UUID id, final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime, final BusinessSubscription lastSubscription) {
+    private BusinessSubscriptionTransition createExpectedRecreatedBST(final Long totalOrdering, final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime, final BusinessSubscription lastSubscription) {
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionRecreated(plan.getName(), catalog, effectiveTransitionTime, effectiveTransitionTime);
         final Subscription.SubscriptionState subscriptionState = Subscription.SubscriptionState.ACTIVE;
-        return createExpectedBST(id, event, requestedTransitionTime, effectiveTransitionTime, lastSubscription, subscriptionState);
+        return createExpectedBST(totalOrdering, event, requestedTransitionTime, effectiveTransitionTime, lastSubscription, subscriptionState);
     }
 
     private BusinessSubscriptionTransition createExpectedBST(
-            final UUID eventId,
+            final Long totalOrdering,
             final BusinessSubscriptionEvent eventType,
             final DateTime requestedTransitionTime,
             final DateTime effectiveTransitionTime,
             @Nullable final BusinessSubscription previousSubscription,
             @Nullable final Subscription.SubscriptionState nextState) {
         return new BusinessSubscriptionTransition(
-                eventId,
-                KEY,
+                totalOrdering,
+                EXTERNAL_KEY,
                 ACCOUNT_KEY,
                 requestedTransitionTime,
                 eventType,
@@ -224,4 +224,4 @@ public class TestAnalyticsListener extends AnalyticsTestSuite {
                 true
         );
     }
-}
\ No newline at end of file
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessAccount.java b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessAccount.java
index 74cf66d..be4c66c 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessAccount.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessAccount.java
@@ -17,22 +17,19 @@
 package com.ning.billing.analytics;
 
 import java.math.BigDecimal;
-import java.util.Collections;
+import java.util.UUID;
 
 import org.joda.time.DateTime;
-import org.mockito.Mockito;
 import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import com.ning.billing.util.tag.Tag;
-
 public class TestBusinessAccount extends AnalyticsTestSuite {
     private BusinessAccount account;
 
     @BeforeMethod(groups = "fast")
     public void setUp() throws Exception {
-        account = new BusinessAccount("pierre", BigDecimal.ONE, Collections.singletonList(getMockTag("batch15")), new DateTime(), BigDecimal.TEN, "ERROR_NOT_ENOUGH_FUNDS", "CreditCard", "Visa", "");
+        account = new BusinessAccount("pierre", UUID.randomUUID().toString(), BigDecimal.ONE, new DateTime(), BigDecimal.TEN, "ERROR_NOT_ENOUGH_FUNDS", "CreditCard", "Visa", "");
     }
 
     @Test(groups = "fast")
@@ -41,14 +38,7 @@ public class TestBusinessAccount extends AnalyticsTestSuite {
         Assert.assertEquals(account, account);
         Assert.assertTrue(account.equals(account));
 
-        final BusinessAccount otherAccount = new BusinessAccount("pierre cardin", BigDecimal.ONE, Collections.singletonList(getMockTag("batch15")), new DateTime(), BigDecimal.TEN, "ERROR_NOT_ENOUGH_FUNDS", "CreditCard", "Visa", "");
+        final BusinessAccount otherAccount = new BusinessAccount("pierre cardin", UUID.randomUUID().toString(), BigDecimal.ONE, new DateTime(), BigDecimal.TEN, "ERROR_NOT_ENOUGH_FUNDS", "CreditCard", "Visa", "");
         Assert.assertFalse(account.equals(otherAccount));
     }
-
-    private Tag getMockTag(final String tagDefinitionName) {
-        final Tag tag = Mockito.mock(Tag.class);
-        Mockito.when(tag.getTagDefinitionName()).thenReturn(tagDefinitionName);
-        Mockito.when(tag.toString()).thenReturn(tagDefinitionName);
-        return tag;
-    }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransition.java b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransition.java
index 952f797..ebd73c4 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransition.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransition.java
@@ -16,8 +16,6 @@
 
 package com.ning.billing.analytics;
 
-import java.util.UUID;
-
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.mockito.Mockito;
@@ -41,8 +39,8 @@ public class TestBusinessSubscriptionTransition extends AnalyticsTestSuite {
     private BusinessSubscription nextSubscription;
     private BusinessSubscriptionEvent event;
     private DateTime requestedTimestamp;
-    private UUID id;
-    private String key;
+    private Long totalOrdering;
+    private String externalKey;
     private String accountKey;
     private BusinessSubscriptionTransition transition;
 
@@ -67,10 +65,10 @@ public class TestBusinessSubscriptionTransition extends AnalyticsTestSuite {
         nextSubscription = new BusinessSubscription(nextISubscription, USD, catalog);
         event = BusinessSubscriptionEvent.subscriptionCancelled(prevISubscription.getCurrentPlan().getName(), catalog, now, now);
         requestedTimestamp = new DateTime(DateTimeZone.UTC);
-        id = UUID.randomUUID();
-        key = "1234";
+        totalOrdering = 12L;
+        externalKey = "1234";
         accountKey = "pierre-1234";
-        transition = new BusinessSubscriptionTransition(id, key, accountKey, requestedTimestamp, event, prevSubscription, nextSubscription);
+        transition = new BusinessSubscriptionTransition(totalOrdering, externalKey, accountKey, requestedTimestamp, event, prevSubscription, nextSubscription);
     }
 
     @Test(groups = "fast")
@@ -89,47 +87,47 @@ public class TestBusinessSubscriptionTransition extends AnalyticsTestSuite {
 
         BusinessSubscriptionTransition otherTransition;
 
-        otherTransition = new BusinessSubscriptionTransition(id, key, accountKey, new DateTime(), event, prevSubscription, nextSubscription);
+        otherTransition = new BusinessSubscriptionTransition(totalOrdering, externalKey, accountKey, new DateTime(), event, prevSubscription, nextSubscription);
         Assert.assertTrue(!transition.equals(otherTransition));
 
-        otherTransition = new BusinessSubscriptionTransition(id, "12345", accountKey, requestedTimestamp, event, prevSubscription, nextSubscription);
+        otherTransition = new BusinessSubscriptionTransition(totalOrdering, "12345", accountKey, requestedTimestamp, event, prevSubscription, nextSubscription);
         Assert.assertTrue(!transition.equals(otherTransition));
 
-        otherTransition = new BusinessSubscriptionTransition(id, key, accountKey, requestedTimestamp, event, prevSubscription, prevSubscription);
+        otherTransition = new BusinessSubscriptionTransition(totalOrdering, externalKey, accountKey, requestedTimestamp, event, prevSubscription, prevSubscription);
         Assert.assertTrue(!transition.equals(otherTransition));
 
-        otherTransition = new BusinessSubscriptionTransition(id, key, accountKey, requestedTimestamp, event, nextSubscription, nextSubscription);
+        otherTransition = new BusinessSubscriptionTransition(totalOrdering, externalKey, accountKey, requestedTimestamp, event, nextSubscription, nextSubscription);
         Assert.assertTrue(!transition.equals(otherTransition));
 
-        otherTransition = new BusinessSubscriptionTransition(id, key, accountKey, requestedTimestamp, event, nextSubscription, prevSubscription);
+        otherTransition = new BusinessSubscriptionTransition(totalOrdering, externalKey, accountKey, requestedTimestamp, event, nextSubscription, prevSubscription);
         Assert.assertTrue(!transition.equals(otherTransition));
     }
 
     @Test(groups = "fast")
     public void testRejectInvalidTransitions() throws Exception {
         try {
-            new BusinessSubscriptionTransition(null, key, accountKey, requestedTimestamp, event, prevSubscription, nextSubscription);
+            new BusinessSubscriptionTransition(null, externalKey, accountKey, requestedTimestamp, event, prevSubscription, nextSubscription);
             Assert.fail();
         } catch (IllegalArgumentException e) {
             Assert.assertTrue(true);
         }
 
         try {
-            new BusinessSubscriptionTransition(id, null, accountKey, requestedTimestamp, event, prevSubscription, nextSubscription);
+            new BusinessSubscriptionTransition(totalOrdering, null, accountKey, requestedTimestamp, event, prevSubscription, nextSubscription);
             Assert.fail();
         } catch (IllegalArgumentException e) {
             Assert.assertTrue(true);
         }
 
         try {
-            new BusinessSubscriptionTransition(id, key, accountKey, null, event, prevSubscription, nextSubscription);
+            new BusinessSubscriptionTransition(totalOrdering, externalKey, accountKey, null, event, prevSubscription, nextSubscription);
             Assert.fail();
         } catch (IllegalArgumentException e) {
             Assert.assertTrue(true);
         }
 
         try {
-            new BusinessSubscriptionTransition(id, key, accountKey, requestedTimestamp, null, prevSubscription, nextSubscription);
+            new BusinessSubscriptionTransition(totalOrdering, externalKey, accountKey, requestedTimestamp, null, prevSubscription, nextSubscription);
             Assert.fail();
         } catch (IllegalArgumentException e) {
             Assert.assertTrue(true);
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransitionRecorder.java b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransitionRecorder.java
index b5cf557..4a96adf 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransitionRecorder.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransitionRecorder.java
@@ -38,7 +38,7 @@ import com.ning.billing.entitlement.api.user.SubscriptionEvent;
 public class TestBusinessSubscriptionTransitionRecorder extends AnalyticsTestSuite {
     @Test(groups = "fast")
     public void testCreateAddOn() throws Exception {
-        final UUID key = UUID.randomUUID();
+        final UUID externalKey = UUID.randomUUID();
 
         // Setup the catalog
         final CatalogService catalogService = Mockito.mock(CatalogService.class);
@@ -56,8 +56,8 @@ public class TestBusinessSubscriptionTransitionRecorder extends AnalyticsTestSui
                                                                                    UUID.randomUUID(),
                                                                                    UUID.randomUUID(),
                                                                                    catalogService.getFullCatalog());
-        dao.createTransition(new BusinessSubscriptionTransition(UUID.randomUUID(),
-                                                                key.toString(),
+        dao.createTransition(new BusinessSubscriptionTransition(10L,
+                                                                externalKey.toString(),
                                                                 UUID.randomUUID().toString(),
                                                                 new DateTime(DateTimeZone.UTC),
                                                                 BusinessSubscriptionEvent.valueOf("ADD_MISC"),
@@ -66,13 +66,13 @@ public class TestBusinessSubscriptionTransitionRecorder extends AnalyticsTestSui
 
         // Setup the entitlement API
         final SubscriptionBundle bundle = Mockito.mock(SubscriptionBundle.class);
-        Mockito.when(bundle.getKey()).thenReturn(key.toString());
+        Mockito.when(bundle.getKey()).thenReturn(externalKey.toString());
         final EntitlementUserApi entitlementApi = Mockito.mock(EntitlementUserApi.class);
         Mockito.when(entitlementApi.getBundleFromId(Mockito.<UUID>any())).thenReturn(bundle);
 
         // Setup the account API
         final Account account = Mockito.mock(Account.class);
-        Mockito.when(account.getExternalKey()).thenReturn(key.toString());
+        Mockito.when(account.getExternalKey()).thenReturn(externalKey.toString());
         final AccountUserApi accountApi = Mockito.mock(AccountUserApi.class);
         Mockito.when(accountApi.getAccountById(bundle.getAccountId())).thenReturn(account);
 
@@ -87,10 +87,10 @@ public class TestBusinessSubscriptionTransitionRecorder extends AnalyticsTestSui
         Mockito.when(event.getSubscriptionStartDate()).thenReturn(new DateTime(DateTimeZone.UTC));
         recorder.subscriptionCreated(event);
 
-        Assert.assertEquals(dao.getTransitions(key.toString()).size(), 2);
-        final BusinessSubscriptionTransition transition = dao.getTransitions(key.toString()).get(1);
-        Assert.assertEquals(transition.getId(), event.getId());
-        Assert.assertEquals(transition.getAccountKey(), key.toString());
+        Assert.assertEquals(dao.getTransitions(externalKey.toString()).size(), 2);
+        final BusinessSubscriptionTransition transition = dao.getTransitions(externalKey.toString()).get(1);
+        Assert.assertEquals(transition.getTotalOrdering(), (long) event.getTotalOrdering());
+        Assert.assertEquals(transition.getAccountKey(), externalKey.toString());
         // Make sure all the prev_ columns are null
         Assert.assertNull(transition.getPreviousSubscription());
     }