killbill-memoizeit

Details

diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
index 58aa09d..1fa3c3a 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
@@ -426,12 +426,18 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
         return (DefaultSubscriptionBase) sub;
     }
 
-    protected Account createAccountWithNonOsgiPaymentMethod(final AccountData accountData) throws Exception {
+    protected Account createAccount(final AccountData accountData) throws Exception {
         final Account account = accountUserApi.createAccount(accountData, callContext);
         assertNotNull(account);
 
         refreshCallContext(account.getId());
 
+        return accountUserApi.getAccountById(account.getId(), callContext);
+    }
+
+    protected Account createAccountWithNonOsgiPaymentMethod(final AccountData accountData) throws Exception {
+        final Account account = createAccount(accountData);
+
         final PaymentMethodPlugin info = createPaymentMethodPlugin();
 
         paymentApi.addPaymentMethod(account, UUID.randomUUID().toString(), BeatrixIntegrationModule.NON_OSGI_PLUGIN_NAME, true, info, PLUGIN_PROPERTIES, callContext);
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/usage/TestConsumableInArrear.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/usage/TestConsumableInArrear.java
index fa6968b..03fc958 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/usage/TestConsumableInArrear.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/usage/TestConsumableInArrear.java
@@ -47,6 +47,7 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
 
 public class TestConsumableInArrear extends TestIntegrationBase {
 
@@ -370,8 +371,6 @@ public class TestConsumableInArrear extends TestIntegrationBase {
         final SubscriptionUsageRecord bp1UsageRecord2 = new SubscriptionUsageRecord(bp1.getId(), "bp1-tracking-2", ImmutableList.of(new UnitUsageRecord("stones", bp1StoneRecords2)));
         recordUsageData(bp1UsageRecord2, callContext);
 
-
-
         final List<UsageRecord> bp2StoneRecords = new ArrayList();
         bp2StoneRecords.add(new UsageRecord(new LocalDate(2012, 4, 5), 85L));
         bp2StoneRecords.add(new UsageRecord(new LocalDate(2012, 4, 15), 150L));
@@ -389,7 +388,6 @@ public class TestConsumableInArrear extends TestIntegrationBase {
 
         invoiceChecker.checkTrackingIds(curInvoice, ImmutableSet.of("bp1-tracking-1", "bp1-tracking-2", "bp2-tracking-1"), internalCallContext);
 
-
         busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
         clock.addMonths(1);
         assertListenerStatus();
@@ -400,6 +398,55 @@ public class TestConsumableInArrear extends TestIntegrationBase {
 
         invoiceChecker.checkTrackingIds(curInvoice, ImmutableSet.of("bp1-tracking-2"), internalCallContext);
 
+    }
+
+    @Test(groups = "slow")
+    public void testWithVoidedInvoice() throws Exception {
+        // We take april as it has 30 days (easier to play with BCD)
+        // Set clock to the initial start date - we implicitly assume here that the account timezone is UTC
+        clock.setDay(new LocalDate(2012, 4, 1));
+
+        final AccountData accountData = getAccountData(1);
+        final Account account = createAccount(accountData);
+        accountChecker.checkAccount(account.getId(), accountData, callContext);
+
+        // Create subscription
+        final DefaultEntitlement bpSubscription = createBaseEntitlementAndCheckForCompletion(account.getId(), "bundleKey", "Trebuchet", ProductCategory.BASE, BillingPeriod.NO_BILLING_PERIOD, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.NULL_INVOICE);
+        // Check bundle after BP got created otherwise we get an error from auditApi.
+        subscriptionChecker.checkSubscriptionCreated(bpSubscription.getId(), internalCallContext);
+
+        Assert.assertNull(bpSubscription.getSubscriptionBase().getChargedThroughDate());
+
+        // Record usage for first month
+        recordUsageData(bpSubscription.getId(), "xxx-1", "stones", new LocalDate(2012, 4, 5), 85L, callContext);
+        recordUsageData(bpSubscription.getId(), "xxx-2", "stones", new LocalDate(2012, 4, 15), 150L, callContext);
+
+        busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT_ERROR);
+        invoiceUserApi.triggerInvoiceGeneration(account.getId(),
+                                                new LocalDate(2012, 5, 1),
+                                                callContext);
+        assertListenerStatus();
+
+        final Invoice firstInvoice = invoiceChecker.checkInvoice(account.getId(), 1, callContext,
+                                                                 new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), new LocalDate(2012, 5, 1), InvoiceItemType.USAGE, new BigDecimal("1000")));
+        invoiceChecker.checkTrackingIds(firstInvoice, ImmutableSet.of("xxx-1", "xxx-2"), internalCallContext);
+
+        // Void the first invoice
+        invoiceUserApi.voidInvoice(firstInvoice.getId(), callContext);
+        assertListenerStatus();
+        invoiceChecker.checkTrackingIds(firstInvoice, ImmutableSet.of(), internalCallContext);
+
+        // Regenerate the invoice
+        busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT_ERROR);
+        invoiceUserApi.triggerInvoiceGeneration(account.getId(),
+                                                new LocalDate(2012, 5, 1),
+                                                callContext);
+        assertListenerStatus();
 
+        // Re-run checks
+        final Invoice secondInvoice = invoiceChecker.checkInvoice(account.getId(), 1, callContext,
+                                                                  new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), new LocalDate(2012, 5, 1), InvoiceItemType.USAGE, new BigDecimal("1000")));
+        assertNotEquals(firstInvoice.getId(), secondInvoice.getId());
+        invoiceChecker.checkTrackingIds(secondInvoice, ImmutableSet.of("xxx-1", "xxx-2"), internalCallContext);
     }
 }
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/util/AuditChecker.java b/beatrix/src/test/java/org/killbill/billing/beatrix/util/AuditChecker.java
index db44b58..4c27155 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/util/AuditChecker.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/util/AuditChecker.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2019 Groupon, Inc
+ * Copyright 2014-2019 The Billing Project, LLC
  *
  * The Billing Project 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
@@ -87,7 +87,10 @@ public class AuditChecker {
     public void checkAccountCreated(final Account account, final CallContext context) {
         final AccountAuditLogs result = auditUserApi.getAccountAuditLogs(account.getId(), AuditLevel.FULL, context);
         checkAuditLog(ChangeType.INSERT, context, result.getAuditLogsForAccount().get(0), account.getId(), AccountSqlDao.class, true, true);
-        checkAuditLog(ChangeType.UPDATE, context, result.getAuditLogsForAccount().get(1), account.getId(), AccountSqlDao.class, true, true);
+        // Payment method
+        if (account.getPaymentMethodId() != null) {
+            checkAuditLog(ChangeType.UPDATE, context, result.getAuditLogsForAccount().get(1), account.getId(), AccountSqlDao.class, true, true);
+        }
     }
 
     /**
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/util/InvoiceChecker.java b/beatrix/src/test/java/org/killbill/billing/beatrix/util/InvoiceChecker.java
index bdfd46a..01b88db 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/util/InvoiceChecker.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/util/InvoiceChecker.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2019 Groupon, Inc
+ * Copyright 2014-2019 The Billing Project, LLC
  *
  * The Billing Project 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
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
index 570d678..0ce1364 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
@@ -1170,11 +1170,14 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
 
                 cbaDao.doCBAComplexityFromTransaction(invoicesTags, entitySqlDaoWrapperFactory, context);
 
+                // Invoice creation event sent on COMMITTED
                 if (InvoiceStatus.COMMITTED.equals(newStatus)) {
-                    // notify invoice creation event
                     notifyBusOfInvoiceCreation(entitySqlDaoWrapperFactory, invoice, context);
+                // Deactivate any usage trackingIds if necessary
+                } else if (InvoiceStatus.VOID.equals(newStatus)) {
+                    final InvoiceTrackingSqlDao trackingSqlDao = entitySqlDaoWrapperFactory.become(InvoiceTrackingSqlDao.class);
+                    trackingSqlDao.deactivateForInvoice(invoiceId.toString(), context);
                 }
-
                 return null;
             }
         });
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceTrackingModelDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceTrackingModelDao.java
index 4991040..178b464 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceTrackingModelDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceTrackingModelDao.java
@@ -38,6 +38,7 @@ public class InvoiceTrackingModelDao extends EntityModelDaoBase implements Entit
     private UUID subscriptionId;
     private String unitType;
     private LocalDate recordDate;
+    private boolean isActive;
 
     public InvoiceTrackingModelDao() { /* For the DAO mapper */ }
 
@@ -54,6 +55,7 @@ public class InvoiceTrackingModelDao extends EntityModelDaoBase implements Entit
         this.subscriptionId = subscriptionId;
         this.unitType = unitType;
         this.recordDate = recordDate;
+        this.isActive = true;
     }
 
     public String getTrackingId() {
@@ -88,6 +90,19 @@ public class InvoiceTrackingModelDao extends EntityModelDaoBase implements Entit
         this.unitType = unitType;
     }
 
+    // TODO required for jdbi binder
+    public boolean getIsActive() {
+        return isActive;
+    }
+
+    public boolean isActive() {
+        return isActive;
+    }
+
+    public void setIsActive(final boolean isActive) {
+        this.isActive = isActive;
+    }
+
     public LocalDate getRecordDate() {
         return recordDate;
     }
@@ -110,6 +125,7 @@ public class InvoiceTrackingModelDao extends EntityModelDaoBase implements Entit
         final InvoiceTrackingModelDao that = (InvoiceTrackingModelDao) o;
         return Objects.equal(trackingId, that.trackingId) &&
                Objects.equal(invoiceId, that.invoiceId) &&
+               Objects.equal(isActive, that.isActive) &&
                Objects.equal(subscriptionId, that.subscriptionId) &&
                Objects.equal(unitType, that.unitType) &&
                Objects.equal(recordDate, that.recordDate);
@@ -117,7 +133,7 @@ public class InvoiceTrackingModelDao extends EntityModelDaoBase implements Entit
 
     @Override
     public int hashCode() {
-        return Objects.hashCode(super.hashCode(), trackingId, invoiceId, subscriptionId, unitType, recordDate);
+        return Objects.hashCode(super.hashCode(), trackingId, invoiceId, subscriptionId, unitType, recordDate, isActive);
     }
 
     @Override
@@ -127,6 +143,7 @@ public class InvoiceTrackingModelDao extends EntityModelDaoBase implements Entit
                ", invoiceId=" + invoiceId +
                ", subscriptionId=" + subscriptionId +
                ", unitType='" + unitType + '\'' +
+               ", isActive='" + isActive + '\'' +
                ", recordDate=" + recordDate +
                '}';
     }
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceTrackingSqlDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceTrackingSqlDao.java
index 00979f8..a9525e2 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceTrackingSqlDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceTrackingSqlDao.java
@@ -22,31 +22,37 @@ import java.util.List;
 
 import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.callcontext.InternalTenantContext;
-import org.killbill.billing.util.callcontext.InternalTenantContextBinder;
+import org.killbill.billing.util.audit.ChangeType;
 import org.killbill.billing.util.entity.Entity;
+import org.killbill.billing.util.entity.dao.Audited;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
 import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
 import org.skife.jdbi.v2.sqlobject.SqlBatch;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
 @KillBillSqlDaoStringTemplate
 public interface InvoiceTrackingSqlDao extends EntitySqlDao<InvoiceTrackingModelDao, Entity> {
 
+    @SqlUpdate
+    @Audited(ChangeType.UPDATE)
+    public void deactivateForInvoice(@Bind("invoiceId") String invoiceId,
+                                     @SmartBindBean final InternalCallContext context);
+
     @SqlBatch
     void create(@SmartBindBean Iterable<InvoiceTrackingModelDao> trackings,
-                @InternalTenantContextBinder final InternalCallContext context);
+                @SmartBindBean final InternalCallContext context);
 
     @SqlQuery
     List<InvoiceTrackingModelDao> getTrackingsByDateRange(@Bind("startDate") final Date startDate,
                                                           @Bind("endDate") final Date endDate,
                                                           @SmartBindBean final InternalTenantContext context);
 
-
     @SqlQuery
     List<InvoiceTrackingModelDao> getTrackingsForInvoice(@Bind("invoiceId") final String invoiceId,
-                                                          @SmartBindBean final InternalTenantContext context);
+                                                         @SmartBindBean final InternalTenantContext context);
 
 }
 
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceTrackingSqlDao.sql.stg b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceTrackingSqlDao.sql.stg
index faf56bb..9add3fe 100644
--- a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceTrackingSqlDao.sql.stg
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceTrackingSqlDao.sql.stg
@@ -8,8 +8,11 @@ tableFields(prefix) ::= <<
 , <prefix>subscription_id
 , <prefix>unit_type
 , <prefix>record_date
+, <prefix>is_active
 , <prefix>created_by
 , <prefix>created_date
+, <prefix>updated_by
+, <prefix>updated_date
 >>
 
 tableValues() ::= <<
@@ -18,8 +21,23 @@ tableValues() ::= <<
 , :subscriptionId
 , :unitType
 , :recordDate
-, :userName
+, :isActive
+, :createdBy
 , :createdDate
+, :updatedBy
+, :updatedDate
+>>
+
+deactivateForInvoice() ::= <<
+update <tableName()>
+set
+is_active = false
+, updated_by = :createdBy
+, updated_date = :updatedDate
+where
+invoice_id = :invoiceId
+<AND_CHECK_TENANT("")>
+;
 >>
 
 getTrackingsByDateRange() ::= <<
@@ -30,6 +48,7 @@ where
 record_date >= :startDate
 and record_date \< :endDate
 and <accountRecordIdField("")> = :accountRecordId
+and is_active = true
 <AND_CHECK_TENANT("")>
 <defaultOrderBy("")>
 ;
@@ -42,6 +61,7 @@ from <tableName()>
 where
 invoice_id = :invoiceId
 and <accountRecordIdField("")> = :accountRecordId
+and is_active = true
 <AND_CHECK_TENANT("")>
 <defaultOrderBy("")>
 ;
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/ddl.sql b/invoice/src/main/resources/org/killbill/billing/invoice/ddl.sql
index 4fc7087..a9f6763 100644
--- a/invoice/src/main/resources/org/killbill/billing/invoice/ddl.sql
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/ddl.sql
@@ -9,13 +9,17 @@ CREATE TABLE invoice_tracking_ids (
     subscription_id varchar(36),
     unit_type varchar(255) NOT NULL,
     record_date date NOT NULL,
+    is_active boolean default true,
     created_by varchar(50) NOT NULL,
     created_date datetime NOT NULL,
+    updated_by varchar(50) NOT NULL,
+    updated_date datetime NOT NULL,
     account_record_id bigint /*! unsigned */ not null,
     tenant_record_id bigint /*! unsigned */ not null default 0,
     PRIMARY KEY(record_id)
 ) /*! CHARACTER SET utf8 COLLATE utf8_bin */;
 CREATE INDEX invoice_tracking_tenant_account_date_idx ON invoice_tracking_ids(tenant_record_id, account_record_id, record_date);
+CREATE INDEX invoice_tracking_invoice_id_idx ON invoice_tracking_ids(invoice_id);
 
 
 DROP TABLE IF EXISTS invoice_items;
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/migration/V20190121141325__tracking_ids_is_active.sql b/invoice/src/main/resources/org/killbill/billing/invoice/migration/V20190121141325__tracking_ids_is_active.sql
new file mode 100644
index 0000000..7e9d4d9
--- /dev/null
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/migration/V20190121141325__tracking_ids_is_active.sql
@@ -0,0 +1,4 @@
+alter table invoice_tracking_ids add column is_active boolean default true after record_date;
+alter table invoice_tracking_ids add column updated_by varchar(50) NOT NULL after created_date;
+alter table invoice_tracking_ids add column updated_date datetime NOT NULL DEFAULT '1970-01-01 00:00:00' after updated_by;
+create index invoice_tracking_invoice_id_idx on invoice_tracking_ids(invoice_id);
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceTrackingSqlDao.java b/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceTrackingSqlDao.java
index dbcef7e..0072f3d 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceTrackingSqlDao.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceTrackingSqlDao.java
@@ -22,6 +22,7 @@ import java.util.List;
 import java.util.UUID;
 
 import org.joda.time.LocalDate;
+import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.invoice.InvoiceTestSuiteWithEmbeddedDB;
 import org.testng.Assert;
 import org.testng.annotations.Test;
@@ -29,7 +30,7 @@ import org.testng.annotations.Test;
 public class TestInvoiceTrackingSqlDao extends InvoiceTestSuiteWithEmbeddedDB {
 
     @Test(groups = "slow")
-    public void testBasicTrackingIds()  {
+    public void testBasicTrackingIds() {
         final InvoiceTrackingSqlDao dao = dbi.onDemand(InvoiceTrackingSqlDao.class);
 
         LocalDate startRange = new LocalDate(2018, 8, 1);
@@ -77,4 +78,55 @@ public class TestInvoiceTrackingSqlDao extends InvoiceTestSuiteWithEmbeddedDB {
         Assert.assertEquals(result.get(2).getSubscriptionId(), subscriptionId);
 
     }
+
+    @Test(groups = "slow")
+    public void testInvalidation() {
+        final InvoiceTrackingSqlDao dao = dbi.onDemand(InvoiceTrackingSqlDao.class);
+
+        LocalDate startRange = new LocalDate(2019, 1, 1);
+        LocalDate endRange = new LocalDate(2019, 1, 31);
+
+        final UUID invoiceId1 = UUID.randomUUID();
+        final UUID invoiceId2 = UUID.randomUUID();
+        final UUID subscriptionId = UUID.randomUUID();
+
+        // invoiceId1
+        final InvoiceTrackingModelDao input1 = new InvoiceTrackingModelDao(UUID.randomUUID(), clock.getUTCNow(), "trackingId1", invoiceId1, subscriptionId, "unit", new LocalDate(2019, 1, 1));
+        final InvoiceTrackingModelDao input2 = new InvoiceTrackingModelDao(UUID.randomUUID(), clock.getUTCNow(), "trackingId2", invoiceId1, subscriptionId, "unit", new LocalDate(2019, 1, 2));
+        final InvoiceTrackingModelDao input3 = new InvoiceTrackingModelDao(UUID.randomUUID(), clock.getUTCNow(), "trackingId3", invoiceId1, subscriptionId, "unit", new LocalDate(2019, 1, 3));
+
+        // invoiceId2
+        final InvoiceTrackingModelDao input4 = new InvoiceTrackingModelDao(UUID.randomUUID(), clock.getUTCNow(), "trackingId4", invoiceId2, subscriptionId, "unit", new LocalDate(2019, 1, 5));
+
+        final List<InvoiceTrackingModelDao> inputs = new ArrayList<>();
+        inputs.add(input1);
+        inputs.add(input2);
+        inputs.add(input3);
+        inputs.add(input4);
+
+        dao.create(inputs, internalCallContext);
+
+        final List<InvoiceTrackingModelDao> result = dao.getTrackingsByDateRange(startRange.toDate(), endRange.toDate(), internalCallContext);
+        Assert.assertEquals(result.size(), 4);
+
+        clock.addDays(1);
+        final InternalCallContext updatedContext = new InternalCallContext(internalCallContext.getTenantRecordId(),
+                                                                           internalCallContext.getAccountRecordId(),
+                                                                           internalCallContext.getFixedOffsetTimeZone(),
+                                                                           clock.getUTCNow(),
+                                                                           internalCallContext.getUserToken(),
+                                                                           "invalidation-user",
+                                                                           internalCallContext.getCallOrigin(),
+                                                                           internalCallContext.getContextUserType(),
+                                                                           internalCallContext.getReasonCode(),
+                                                                           internalCallContext.getComments(),
+                                                                           internalCallContext.getCreatedDate(),
+                                                                           clock.getUTCNow());
+
+        dao.deactivateForInvoice(invoiceId1.toString(), updatedContext);
+
+        final List<InvoiceTrackingModelDao> result2 = dao.getTrackingsByDateRange(startRange.toDate(), endRange.toDate(), internalCallContext);
+        Assert.assertEquals(result2.size(), 1);
+
+    }
 }
diff --git a/usage/src/main/java/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.java b/usage/src/main/java/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.java
index e947fa5..9e9ed9d 100644
--- a/usage/src/main/java/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.java
+++ b/usage/src/main/java/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.java
@@ -24,12 +24,11 @@ import java.util.UUID;
 
 import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.callcontext.InternalTenantContext;
-import org.killbill.billing.util.callcontext.InternalTenantContextBinder;
 import org.killbill.billing.util.entity.Entity;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.SqlBatch;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 
@@ -38,28 +37,28 @@ public interface RolledUpUsageSqlDao extends EntitySqlDao<RolledUpUsageModelDao,
 
     @SqlBatch
     void create(@SmartBindBean Iterable<RolledUpUsageModelDao> usages,
-                @InternalTenantContextBinder final InternalCallContext context);
+                @SmartBindBean final InternalCallContext context);
 
     @SqlQuery
     Long recordsWithTrackingIdExist(@Bind("subscriptionId") final UUID subscriptionId,
                                     @Bind("trackingId") final String trackingId,
-                                    @InternalTenantContextBinder final InternalTenantContext context);
+                                    @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     List<RolledUpUsageModelDao> getUsageForSubscription(@Bind("subscriptionId") final UUID subscriptionId,
                                                         @Bind("startDate") final Date startDate,
                                                         @Bind("endDate") final Date endDate,
                                                         @Bind("unitType") final String unitType,
-                                                        @InternalTenantContextBinder final InternalTenantContext context);
+                                                        @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     List<RolledUpUsageModelDao> getAllUsageForSubscription(@Bind("subscriptionId") final UUID subscriptionId,
                                                            @Bind("startDate") final Date startDate,
                                                            @Bind("endDate") final Date endDate,
-                                                           @InternalTenantContextBinder final InternalTenantContext context);
+                                                           @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     List<RolledUpUsageModelDao> getRawUsageForAccount(@Bind("startDate") final Date startDate,
                                                       @Bind("endDate") final Date endDate,
-                                                      @InternalTenantContextBinder final InternalTenantContext context);
+                                                      @SmartBindBean final InternalTenantContext context);
 }
diff --git a/usage/src/main/resources/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.sql.stg b/usage/src/main/resources/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.sql.stg
index 44db9b9..a61f71f 100644
--- a/usage/src/main/resources/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.sql.stg
+++ b/usage/src/main/resources/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.sql.stg
@@ -19,7 +19,7 @@ tableValues() ::= <<
 , :recordDate
 , :amount
 , :trackingId
-, :userName
+, :createdBy
 , :createdDate
 >>
 
diff --git a/util/src/main/java/org/killbill/billing/util/entity/dao/Audited.java b/util/src/main/java/org/killbill/billing/util/entity/dao/Audited.java
index 9e7f3cb..1844a02 100644
--- a/util/src/main/java/org/killbill/billing/util/entity/dao/Audited.java
+++ b/util/src/main/java/org/killbill/billing/util/entity/dao/Audited.java
@@ -33,7 +33,7 @@ import org.killbill.billing.util.audit.ChangeType;
  *         @Audited(type = ChangeType.UPDATE)
  *         @SqlUpdate public void updateChargedThroughDate(@Bind("id") String id,
  *                                                         @Bind("chargedThroughDate") Date chargedThroughDate,
- *                                                         @InternalTenantContextBinder final InternalCallContext callcontext);
+ *                                                         @SmartBindBean  final InternalCallContext callcontext);
  * </pre>
  */
 @Retention(RetentionPolicy.RUNTIME)