killbill-uncached
Changes
invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceTrackingSqlDao.sql.stg 22(+21 -1)
Details
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..57d1b2c 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,21 +22,30 @@ import java.util.List;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.util.audit.ChangeType;
import org.killbill.billing.util.callcontext.InternalTenantContextBinder;
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,
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..08102cd 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..abb6c76 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(tenant_record_id, 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..217fa69
--- /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 after updated_by;
+create index invoice_tracking_invoice_id_idx on invoice_tracking_ids(tenant_record_id, 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);
+
+ }
}