killbill-aplcache
Changes
entitlement/src/test/java/org/killbill/billing/entitlement/glue/TestEntitlementModuleNoDB.java 3(+3 -0)
invoice/src/main/resources/org/killbill/billing/invoice/migration/V20190222142211__invoice_history_tables.sql 104(+104 -0)
pom.xml 2(+1 -1)
Details
diff --git a/api/src/main/java/org/killbill/billing/invoice/api/InvoiceInternalApi.java b/api/src/main/java/org/killbill/billing/invoice/api/InvoiceInternalApi.java
index e6534c8..90893b7 100644
--- a/api/src/main/java/org/killbill/billing/invoice/api/InvoiceInternalApi.java
+++ b/api/src/main/java/org/killbill/billing/invoice/api/InvoiceInternalApi.java
@@ -80,6 +80,8 @@ public interface InvoiceInternalApi {
public void commitInvoice(UUID invoiceId, InternalCallContext context) throws InvoiceApiException;
+ public InvoicePayment getInvoicePayment(UUID invoicePaymentId, TenantContext context);
+
public List<InvoicePayment> getInvoicePayments(UUID paymentId, TenantContext context);
public List<InvoicePayment> getInvoicePaymentsByAccount(UUID accountId, TenantContext context);
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 82b590b..619c255 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
@@ -156,12 +156,12 @@ public class AuditChecker {
public void checkInvoiceCreated(final Invoice invoice, final CallContext context) {
final List<AuditLog> invoiceLogs = getAuditLogForInvoice(invoice, context);
//Assert.assertEquals(invoiceLogs.size(), 1);
- checkAuditLog(ChangeType.INSERT, context, invoiceLogs.get(0), invoice.getId(), InvoiceSqlDao.class, false, false);
+ checkAuditLog(ChangeType.INSERT, context, invoiceLogs.get(0), invoice.getId(), InvoiceSqlDao.class, true, false);
for (InvoiceItem cur : invoice.getInvoiceItems()) {
final List<AuditLog> auditLogs = getAuditLogForInvoiceItem(cur, context);
Assert.assertTrue(auditLogs.size() >= 1);
- checkAuditLog(ChangeType.INSERT, context, auditLogs.get(0), cur.getId(), InvoiceItemSqlDao.class, false, false);
+ checkAuditLog(ChangeType.INSERT, context, auditLogs.get(0), cur.getId(), InvoiceItemSqlDao.class, true, false);
}
}
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/EntitlementTestSuiteNoDB.java b/entitlement/src/test/java/org/killbill/billing/entitlement/EntitlementTestSuiteNoDB.java
index c0c5dc8..48f194a 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/EntitlementTestSuiteNoDB.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/EntitlementTestSuiteNoDB.java
@@ -29,6 +29,7 @@ import org.killbill.billing.entitlement.glue.TestEntitlementModuleNoDB;
import org.killbill.billing.junction.BlockingInternalApi;
import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
import org.killbill.billing.tag.TagInternalApi;
+import org.killbill.billing.util.audit.dao.AuditDao;
import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.billing.util.tag.dao.TagDao;
import org.killbill.bus.api.PersistentBus;
@@ -66,6 +67,8 @@ public abstract class EntitlementTestSuiteNoDB extends GuicyKillbillTestSuiteNoD
protected BlockingChecker blockingChecker;
@Inject
protected NonEntityDao nonEntityDao;
+ @Inject
+ protected AuditDao auditDao;
@BeforeClass(groups = "fast")
protected void beforeClass() throws Exception {
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/glue/TestEntitlementModuleNoDB.java b/entitlement/src/test/java/org/killbill/billing/entitlement/glue/TestEntitlementModuleNoDB.java
index 669e2ca..4285edb 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/glue/TestEntitlementModuleNoDB.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/glue/TestEntitlementModuleNoDB.java
@@ -27,6 +27,8 @@ import org.killbill.billing.mock.glue.MockNonEntityDaoModule;
import org.killbill.billing.mock.glue.MockSubscriptionModule;
import org.killbill.billing.mock.glue.MockTagModule;
import org.killbill.billing.platform.api.KillbillConfigSource;
+import org.killbill.billing.util.audit.dao.AuditDao;
+import org.killbill.billing.util.audit.dao.MockAuditDao;
import org.killbill.clock.ClockMock;
public class TestEntitlementModuleNoDB extends TestEntitlementModule {
@@ -47,6 +49,7 @@ public class TestEntitlementModuleNoDB extends TestEntitlementModule {
install(new MockSubscriptionModule(configSource));
install(new MockCatalogModule(configSource));
install(new MockAccountModule(configSource));
+ bind(AuditDao.class).toInstance(new MockAuditDao());
}
@Override
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java b/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
index 1b9e082..7d9a572 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
@@ -194,6 +194,12 @@ public class DefaultInvoiceInternalApi implements InvoiceInternalApi {
}
@Override
+ public InvoicePayment getInvoicePayment(final UUID invoicePaymentId, final TenantContext context) {
+ final InvoicePaymentModelDao result = dao.getInvoicePayment(invoicePaymentId, internalCallContextFactory.createInternalTenantContext(invoicePaymentId, ObjectType.INVOICE_PAYMENT, context));
+ return result != null ? new DefaultInvoicePayment(result) : null;
+ }
+
+ @Override
public List<InvoicePayment> getInvoicePayments(final UUID paymentId, final TenantContext context) {
return ImmutableList.<InvoicePayment>copyOf(Collections2.transform(dao.getInvoicePaymentsByPaymentId(paymentId, internalCallContextFactory.createInternalTenantContext(paymentId, ObjectType.PAYMENT, context)),
new Function<InvoicePaymentModelDao, InvoicePayment>() {
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java b/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
index 30aa18d..0788a94 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
@@ -66,7 +66,9 @@ import org.killbill.billing.invoice.template.HtmlInvoiceGenerator;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.tag.TagInternalApi;
import org.killbill.billing.util.UUIDs;
+import org.killbill.billing.util.api.AuditLevel;
import org.killbill.billing.util.api.TagApiException;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.callcontext.TenantContext;
@@ -692,6 +694,21 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
dao.changeInvoiceStatus(invoiceId, InvoiceStatus.VOID, internalCallContext);
}
+ @Override
+ public List<AuditLogWithHistory> getInvoiceAuditLogsWithHistoryForId(final UUID invoiceId, final AuditLevel auditLevel, final TenantContext tenantContext) {
+ return dao.getInvoiceAuditLogsWithHistoryForId(invoiceId, auditLevel, internalCallContextFactory.createInternalTenantContext(invoiceId, ObjectType.INVOICE, tenantContext));
+ }
+
+ @Override
+ public List<AuditLogWithHistory> getInvoiceItemAuditLogsWithHistoryForId(final UUID invoiceItemId, final AuditLevel auditLevel, final TenantContext tenantContext) {
+ return dao.getInvoiceItemAuditLogsWithHistoryForId(invoiceItemId, auditLevel, internalCallContextFactory.createInternalTenantContext(invoiceItemId, ObjectType.INVOICE_ITEM, tenantContext));
+ }
+
+ @Override
+ public List<AuditLogWithHistory> getInvoicePaymentAuditLogsWithHistoryForId(final UUID invoicePaymentId, final AuditLevel auditLevel, final TenantContext tenantContext) {
+ return dao.getInvoicePaymentAuditLogsWithHistoryForId(invoicePaymentId, auditLevel, internalCallContextFactory.createInternalTenantContext(invoicePaymentId, ObjectType.INVOICE_PAYMENT, tenantContext));
+ }
+
private void canInvoiceBeVoided(final Invoice invoice) throws InvoiceApiException {
final List<InvoicePayment> invoicePayments = invoice.getPayments();
final BigDecimal amountPaid = InvoiceCalculatorUtils.computeInvoiceAmountPaid(invoice.getCurrency(), invoicePayments)
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 07f22f0..198ea35 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
@@ -61,12 +61,16 @@ import org.killbill.billing.invoice.notification.NextBillingDatePoster;
import org.killbill.billing.invoice.notification.ParentInvoiceCommitmentPoster;
import org.killbill.billing.tag.TagInternalApi;
import org.killbill.billing.util.UUIDs;
+import org.killbill.billing.util.api.AuditLevel;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
+import org.killbill.billing.util.audit.dao.AuditDao;
import org.killbill.billing.util.cache.Cachable.CacheType;
import org.killbill.billing.util.cache.CacheController;
import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.config.definition.InvoiceConfig;
import org.killbill.billing.util.dao.NonEntityDao;
+import org.killbill.billing.util.dao.TableName;
import org.killbill.billing.util.entity.Pagination;
import org.killbill.billing.util.entity.dao.DefaultPaginationSqlDaoHelper;
import org.killbill.billing.util.entity.dao.DefaultPaginationSqlDaoHelper.PaginationIteratorBuilder;
@@ -125,6 +129,7 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
private final NonEntityDao nonEntityDao;
private final ParentInvoiceCommitmentPoster parentInvoiceCommitmentPoster;
private final TagInternalApi tagInternalApi;
+ private final AuditDao auditDao;
@Inject
public DefaultInvoiceDao(final TagInternalApi tagInternalApi,
@@ -139,6 +144,7 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
final InvoiceDaoHelper invoiceDaoHelper,
final CBADao cbaDao,
final ParentInvoiceCommitmentPoster parentInvoiceCommitmentPoster,
+ final AuditDao auditDao,
final InternalCallContextFactory internalCallContextFactory) {
super(nonEntityDao, cacheControllerDispatcher, new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory), InvoiceSqlDao.class);
this.tagInternalApi = tagInternalApi;
@@ -148,6 +154,7 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
this.internalCallContextFactory = internalCallContextFactory;
this.invoiceDaoHelper = invoiceDaoHelper;
this.cbaDao = cbaDao;
+ this.auditDao = auditDao;
this.clock = clock;
this.objectIdCacheController = cacheControllerDispatcher.getCacheController(CacheType.OBJECT_ID);
this.nonEntityDao = nonEntityDao;
@@ -617,6 +624,16 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
}
@Override
+ public InvoicePaymentModelDao getInvoicePayment(final UUID invoicePaymentId, final InternalTenantContext context) {
+ return transactionalSqlDao.execute(true, new EntitySqlDaoTransactionWrapper<InvoicePaymentModelDao>() {
+ @Override
+ public InvoicePaymentModelDao inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
+ return entitySqlDaoWrapperFactory.become(InvoicePaymentSqlDao.class).getById(invoicePaymentId.toString(), context);
+ }
+ });
+ }
+
+ @Override
public InvoicePaymentModelDao createRefund(final UUID paymentId, final BigDecimal requestedRefundAmount, final boolean isInvoiceAdjusted,
final Map<UUID, BigDecimal> invoiceItemIdsWithNullAmounts, final String transactionExternalKey,
final InternalCallContext context) throws InvoiceApiException {
@@ -1434,6 +1451,40 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
});
}
+
+ @Override
+ public List<AuditLogWithHistory> getInvoiceAuditLogsWithHistoryForId(final UUID invoiceId, final AuditLevel auditLevel, final InternalTenantContext context) {
+ return transactionalSqlDao.execute(true, new EntitySqlDaoTransactionWrapper<List<AuditLogWithHistory>>() {
+ @Override
+ public List<AuditLogWithHistory> inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) {
+ final InvoiceSqlDao transactional = entitySqlDaoWrapperFactory.become(InvoiceSqlDao.class);
+ return auditDao.getAuditLogsWithHistoryForId(transactional, TableName.INVOICES, invoiceId, auditLevel, context);
+ }
+ });
+ }
+
+ @Override
+ public List<AuditLogWithHistory> getInvoiceItemAuditLogsWithHistoryForId(final UUID invoiceItemId, final AuditLevel auditLevel, final InternalTenantContext context) {
+ return transactionalSqlDao.execute(true, new EntitySqlDaoTransactionWrapper<List<AuditLogWithHistory>>() {
+ @Override
+ public List<AuditLogWithHistory> inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) {
+ final InvoiceItemSqlDao transactional = entitySqlDaoWrapperFactory.become(InvoiceItemSqlDao.class);
+ return auditDao.getAuditLogsWithHistoryForId(transactional, TableName.INVOICE_ITEMS, invoiceItemId, auditLevel, context);
+ }
+ });
+ }
+
+ @Override
+ public List<AuditLogWithHistory> getInvoicePaymentAuditLogsWithHistoryForId(final UUID invoicePaymentId, final AuditLevel auditLevel, final InternalTenantContext context) {
+ return transactionalSqlDao.execute(true, new EntitySqlDaoTransactionWrapper<List<AuditLogWithHistory>>() {
+ @Override
+ public List<AuditLogWithHistory> inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) {
+ final InvoicePaymentSqlDao transactional = entitySqlDaoWrapperFactory.become(InvoicePaymentSqlDao.class);
+ return auditDao.getAuditLogsWithHistoryForId(transactional, TableName.INVOICE_PAYMENTS, invoicePaymentId, auditLevel, context);
+ }
+ });
+ }
+
// PERF: fetch tags once. See also https://github.com/killbill/killbill/issues/720.
private List<Tag> getInvoicesTags(final InternalTenantContext context) {
return tagInternalApi.getTagsForAccountType(ObjectType.INVOICE, false, context);
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDao.java
index b989312..c0bcf26 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDao.java
@@ -35,6 +35,8 @@ import org.killbill.billing.invoice.InvoiceDispatcher.FutureAccountNotifications
import org.killbill.billing.invoice.api.Invoice;
import org.killbill.billing.invoice.api.InvoiceApiException;
import org.killbill.billing.invoice.api.InvoiceStatus;
+import org.killbill.billing.util.api.AuditLevel;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
import org.killbill.billing.util.entity.Pagination;
import org.killbill.billing.util.entity.dao.EntityDao;
@@ -77,6 +79,8 @@ public interface InvoiceDao extends EntityDao<InvoiceModelDao, Invoice, InvoiceA
InvoicePaymentModelDao getInvoicePaymentByCookieId(String cookieId, InternalTenantContext internalTenantContext);
+ InvoicePaymentModelDao getInvoicePayment(UUID invoicePaymentId, InternalTenantContext internalTenantContext);
+
BigDecimal getAccountBalance(UUID accountId, InternalTenantContext context);
BigDecimal getAccountCBA(UUID accountId, InternalTenantContext context);
@@ -228,4 +232,10 @@ public interface InvoiceDao extends EntityDao<InvoiceModelDao, Invoice, InvoiceA
List<InvoiceTrackingModelDao> getTrackingsByDateRange(LocalDate startDate, LocalDate endDate, InternalCallContext context);
+ public List<AuditLogWithHistory> getInvoiceAuditLogsWithHistoryForId(final UUID invoiceId, final AuditLevel auditLevel, final InternalTenantContext context);
+
+ public List<AuditLogWithHistory> getInvoiceItemAuditLogsWithHistoryForId(final UUID invoiceItemId, final AuditLevel auditLevel, final InternalTenantContext context);
+
+ public List<AuditLogWithHistory> getInvoicePaymentAuditLogsWithHistoryForId(final UUID invoicePaymentId, final AuditLevel auditLevel, final InternalTenantContext context);
+
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceItemModelDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceItemModelDao.java
index c036a76..07c5bc8 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceItemModelDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceItemModelDao.java
@@ -398,6 +398,6 @@ public class InvoiceItemModelDao extends EntityModelDaoBase implements EntityMod
@Override
public TableName getHistoryTableName() {
- return null;
+ return TableName.INVOICE_ITEM_HISTORY;
}
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceModelDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceModelDao.java
index b3f5602..ad021c5 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceModelDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceModelDao.java
@@ -183,6 +183,11 @@ public class InvoiceModelDao extends EntityModelDaoBase implements EntityModelDa
return isWrittenOff;
}
+ // Make BeanInspector happy when invoked from EntityHistoryBinder
+ public boolean getIsWrittenOff() {
+ return isWrittenOff;
+ }
+
public void setIsWrittenOff(final boolean isWrittenOff) {
this.isWrittenOff = isWrittenOff;
}
@@ -303,7 +308,7 @@ public class InvoiceModelDao extends EntityModelDaoBase implements EntityModelDa
@Override
public TableName getHistoryTableName() {
- return null;
+ return TableName.INVOICE_HISTORY;
}
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoicePaymentModelDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoicePaymentModelDao.java
index 53cbf16..2b76d19 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoicePaymentModelDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoicePaymentModelDao.java
@@ -228,6 +228,6 @@ public class InvoicePaymentModelDao extends EntityModelDaoBase implements Entity
@Override
public TableName getHistoryTableName() {
- return null;
+ return TableName.INVOICE_PAYMENT_HISTORY;
}
}
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 178b464..59ac342 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
@@ -156,7 +156,7 @@ public class InvoiceTrackingModelDao extends EntityModelDaoBase implements Entit
@Override
public TableName getHistoryTableName() {
- return null;
+ return TableName.INVOICE_TRACKING_ID_HISTORY;
}
}
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.sql.stg b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
index 1a25b85..0aa5427 100644
--- a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
@@ -1,6 +1,7 @@
import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "invoice_items"
+historyTableName() ::= "invoice_item_history"
tableFields(prefix) ::= <<
<prefix>type
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
index 23776fa..728c847 100644
--- a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
@@ -1,6 +1,7 @@
import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "invoice_payments"
+historyTableName() ::= "invoice_payment_history"
tableFields(prefix) ::= <<
<prefix>type
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceSqlDao.sql.stg b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceSqlDao.sql.stg
index 304ef0e..12e578a 100644
--- a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceSqlDao.sql.stg
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceSqlDao.sql.stg
@@ -1,6 +1,7 @@
import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "invoices"
+historyTableName() ::= "invoice_history"
tableFields(prefix) ::= <<
<prefix>account_id
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 b20293a..b67b442 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
@@ -1,6 +1,7 @@
import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "invoice_tracking_ids"
+historyTableName() ::= "invoice_tracking_id_history"
tableFields(prefix) ::= <<
<prefix>tracking_id
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 a9f6763..68ab207 100644
--- a/invoice/src/main/resources/org/killbill/billing/invoice/ddl.sql
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/ddl.sql
@@ -22,6 +22,29 @@ CREATE INDEX invoice_tracking_tenant_account_date_idx ON invoice_tracking_ids(te
CREATE INDEX invoice_tracking_invoice_id_idx ON invoice_tracking_ids(invoice_id);
+DROP TABLE IF EXISTS invoice_tracking_id_history;
+CREATE TABLE invoice_tracking_id_history (
+ record_id serial unique,
+ id varchar(36) NOT NULL,
+ target_record_id bigint /*! unsigned */ not null,
+ tracking_id varchar(128) NOT NULL,
+ invoice_id varchar(36) NOT NULL,
+ subscription_id varchar(36),
+ unit_type varchar(255) NOT NULL,
+ record_date date NOT NULL,
+ is_active boolean default true,
+ change_type varchar(6) NOT NULL,
+ 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_id_history_target_record_id ON invoice_tracking_id_history(target_record_id);
+CREATE INDEX invoice_tracking_id_history_tenant_record_id ON invoice_tracking_id_history(tenant_record_id);
+
DROP TABLE IF EXISTS invoice_items;
CREATE TABLE invoice_items (
record_id serial unique,
@@ -58,6 +81,43 @@ CREATE INDEX invoice_items_account_id ON invoice_items(account_id ASC);
CREATE INDEX invoice_items_linked_item_id ON invoice_items(linked_item_id ASC);
CREATE INDEX invoice_items_tenant_account_record_id ON invoice_items(tenant_record_id, account_record_id);
+
+DROP TABLE IF EXISTS invoice_item_history;
+CREATE TABLE invoice_item_history (
+ record_id serial unique,
+ id varchar(36) NOT NULL,
+ target_record_id bigint /*! unsigned */ not null,
+ type varchar(24) NOT NULL,
+ invoice_id varchar(36) NOT NULL,
+ account_id varchar(36) NOT NULL,
+ child_account_id varchar(36),
+ bundle_id varchar(36),
+ subscription_id varchar(36),
+ description varchar(255),
+ product_name varchar(255),
+ plan_name varchar(255),
+ phase_name varchar(255),
+ usage_name varchar(255),
+ start_date date,
+ end_date date,
+ amount numeric(15,9) NOT NULL,
+ rate numeric(15,9) NULL,
+ currency varchar(3) NOT NULL,
+ linked_item_id varchar(36),
+ quantity int,
+ item_details text,
+ change_type varchar(6) NOT NULL,
+ created_by varchar(50) NOT NULL,
+ created_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_item_history_target_record_id ON invoice_item_history(target_record_id);
+CREATE INDEX invoice_item_history_tenant_record_id ON invoice_item_history(tenant_record_id);
+
+
+
DROP TABLE IF EXISTS invoices;
CREATE TABLE invoices (
record_id serial unique,
@@ -79,6 +139,30 @@ CREATE UNIQUE INDEX invoices_id ON invoices(id);
CREATE INDEX invoices_account ON invoices(account_id ASC);
CREATE INDEX invoices_tenant_account_record_id ON invoices(tenant_record_id, account_record_id);
+
+DROP TABLE IF EXISTS invoice_history;
+CREATE TABLE invoice_history (
+ record_id serial unique,
+ id varchar(36) NOT NULL,
+ target_record_id bigint /*! unsigned */ not null,
+ account_id varchar(36) NOT NULL,
+ invoice_date date NOT NULL,
+ target_date date,
+ currency varchar(3) NOT NULL,
+ status varchar(15) NOT NULL DEFAULT 'COMMITTED',
+ migrated bool NOT NULL,
+ parent_invoice bool NOT NULL DEFAULT FALSE,
+ change_type varchar(6) NOT NULL,
+ created_by varchar(50) NOT NULL,
+ created_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_history_target_record_id ON invoice_history(target_record_id);
+CREATE INDEX invoice_history_tenant_record_id ON invoice_history(tenant_record_id);
+
+
DROP TABLE IF EXISTS invoice_payments;
CREATE TABLE invoice_payments (
record_id serial unique,
@@ -106,6 +190,32 @@ CREATE INDEX invoice_payments_payment_id ON invoice_payments(payment_id);
CREATE INDEX invoice_payments_payment_cookie_id ON invoice_payments(payment_cookie_id);
CREATE INDEX invoice_payments_tenant_account_record_id ON invoice_payments(tenant_record_id, account_record_id);
+DROP TABLE IF EXISTS invoice_payment_history;
+CREATE TABLE invoice_payment_history (
+ record_id serial unique,
+ id varchar(36) NOT NULL,
+ target_record_id bigint /*! unsigned */ not null,
+ type varchar(24) NOT NULL,
+ invoice_id varchar(36) NOT NULL,
+ payment_id varchar(36),
+ payment_date datetime NOT NULL,
+ amount numeric(15,9) NOT NULL,
+ currency varchar(3) NOT NULL,
+ processed_currency varchar(3) NOT NULL,
+ payment_cookie_id varchar(255) DEFAULT NULL,
+ linked_invoice_payment_id varchar(36) DEFAULT NULL,
+ success bool DEFAULT true,
+ change_type varchar(6) NOT NULL,
+ created_by varchar(50) NOT NULL,
+ created_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_payment_history_target_record_id ON invoice_payment_history(target_record_id);
+CREATE INDEX invoice_payment_history_tenant_record_id ON invoice_payment_history(tenant_record_id);
+
+
DROP TABLE IF EXISTS invoice_parent_children;
CREATE TABLE invoice_parent_children (
record_id serial unique,
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/migration/V20190222142211__invoice_history_tables.sql b/invoice/src/main/resources/org/killbill/billing/invoice/migration/V20190222142211__invoice_history_tables.sql
new file mode 100644
index 0000000..d50647a
--- /dev/null
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/migration/V20190222142211__invoice_history_tables.sql
@@ -0,0 +1,104 @@
+DROP TABLE IF EXISTS invoice_tracking_id_history;
+CREATE TABLE invoice_tracking_id_history (
+ record_id serial unique,
+ id varchar(36) NOT NULL,
+ target_record_id bigint /*! unsigned */ not null,
+ tracking_id varchar(128) NOT NULL,
+ invoice_id varchar(36) NOT NULL,
+ subscription_id varchar(36),
+ unit_type varchar(255) NOT NULL,
+ record_date date NOT NULL,
+ is_active boolean default true,
+ change_type varchar(6) NOT NULL,
+ 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_id_history_target_record_id ON invoice_tracking_id_history(target_record_id);
+CREATE INDEX invoice_tracking_id_history_tenant_record_id ON invoice_tracking_id_history(tenant_record_id);
+
+DROP TABLE IF EXISTS invoice_item_history;
+CREATE TABLE invoice_item_history (
+ record_id serial unique,
+ id varchar(36) NOT NULL,
+ target_record_id bigint /*! unsigned */ not null,
+ type varchar(24) NOT NULL,
+ invoice_id varchar(36) NOT NULL,
+ account_id varchar(36) NOT NULL,
+ child_account_id varchar(36),
+ bundle_id varchar(36),
+ subscription_id varchar(36),
+ description varchar(255),
+ product_name varchar(255),
+ plan_name varchar(255),
+ phase_name varchar(255),
+ usage_name varchar(255),
+ start_date date,
+ end_date date,
+ amount numeric(15,9) NOT NULL,
+ rate numeric(15,9) NULL,
+ currency varchar(3) NOT NULL,
+ linked_item_id varchar(36),
+ quantity int,
+ item_details text,
+ change_type varchar(6) NOT NULL,
+ created_by varchar(50) NOT NULL,
+ created_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_item_history_target_record_id ON invoice_item_history(target_record_id);
+CREATE INDEX invoice_item_history_tenant_record_id ON invoice_item_history(tenant_record_id);
+
+
+DROP TABLE IF EXISTS invoice_history;
+CREATE TABLE invoice_history (
+ record_id serial unique,
+ id varchar(36) NOT NULL,
+ target_record_id bigint /*! unsigned */ not null,
+ account_id varchar(36) NOT NULL,
+ invoice_date date NOT NULL,
+ target_date date,
+ currency varchar(3) NOT NULL,
+ status varchar(15) NOT NULL DEFAULT 'COMMITTED',
+ migrated bool NOT NULL,
+ parent_invoice bool NOT NULL DEFAULT FALSE,
+ change_type varchar(6) NOT NULL,
+ created_by varchar(50) NOT NULL,
+ created_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_history_target_record_id ON invoice_history(target_record_id);
+CREATE INDEX invoice_history_tenant_record_id ON invoice_history(tenant_record_id);
+
+DROP TABLE IF EXISTS invoice_payment_history;
+CREATE TABLE invoice_payment_history (
+ record_id serial unique,
+ id varchar(36) NOT NULL,
+ target_record_id bigint /*! unsigned */ not null,
+ type varchar(24) NOT NULL,
+ invoice_id varchar(36) NOT NULL,
+ payment_id varchar(36),
+ payment_date datetime NOT NULL,
+ amount numeric(15,9) NOT NULL,
+ currency varchar(3) NOT NULL,
+ processed_currency varchar(3) NOT NULL,
+ payment_cookie_id varchar(255) DEFAULT NULL,
+ linked_invoice_payment_id varchar(36) DEFAULT NULL,
+ success bool DEFAULT true,
+ change_type varchar(6) NOT NULL,
+ created_by varchar(50) NOT NULL,
+ created_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_payment_history_target_record_id ON invoice_payment_history(target_record_id);
+CREATE INDEX invoice_payment_history_tenant_record_id ON invoice_payment_history(tenant_record_id);
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/dao/MockInvoiceDao.java b/invoice/src/test/java/org/killbill/billing/invoice/dao/MockInvoiceDao.java
index 6ca9f97..445a350 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/dao/MockInvoiceDao.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/dao/MockInvoiceDao.java
@@ -38,6 +38,8 @@ import org.killbill.billing.invoice.api.Invoice;
import org.killbill.billing.invoice.api.InvoiceApiException;
import org.killbill.billing.invoice.api.InvoiceStatus;
import org.killbill.billing.invoice.api.user.DefaultInvoiceCreationEvent;
+import org.killbill.billing.util.api.AuditLevel;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
import org.killbill.billing.util.entity.DefaultPagination;
import org.killbill.billing.util.entity.Pagination;
import org.killbill.billing.util.entity.dao.MockEntityDaoBase;
@@ -275,6 +277,11 @@ public class MockInvoiceDao extends MockEntityDaoBase<InvoiceModelDao, Invoice,
}
@Override
+ public InvoicePaymentModelDao getInvoicePayment(final UUID invoicePaymentId, final InternalTenantContext internalTenantContext) {
+ return null;
+ }
+
+ @Override
public void notifyOfPaymentCompletion(final InvoicePaymentModelDao invoicePayment, final InternalCallContext context) {
synchronized (monitor) {
payments.put(invoicePayment.getId(), invoicePayment);
@@ -446,4 +453,19 @@ public class MockInvoiceDao extends MockEntityDaoBase<InvoiceModelDao, Invoice,
public List<InvoiceTrackingModelDao> getTrackingsByDateRange(final LocalDate startDate, final LocalDate endDate, final InternalCallContext context) {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public List<AuditLogWithHistory> getInvoiceAuditLogsWithHistoryForId(final UUID invoiceId, final AuditLevel auditLevel, final InternalTenantContext context) {
+ return null;
+ }
+
+ @Override
+ public List<AuditLogWithHistory> getInvoiceItemAuditLogsWithHistoryForId(final UUID invoiceItemId, final AuditLevel auditLevel, final InternalTenantContext context) {
+ return null;
+ }
+
+ @Override
+ public List<AuditLogWithHistory> getInvoicePaymentAuditLogsWithHistoryForId(final UUID invoicePaymentId, final AuditLevel auditLevel, final InternalTenantContext context) {
+ return null;
+ }
}
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 8c42ce5..bef1051 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
@@ -140,7 +140,11 @@ public class TestInvoiceTrackingSqlDao extends InvoiceTestSuiteWithEmbeddedDB {
final List<InvoiceTrackingModelDao> result = dao.getTrackingsByDateRange(startRange.toDate(), endRange.toDate(), internalCallContext);
Assert.assertEquals(result.size(), 4);
- final List<AuditLogModelDao> auditLogsPostCreate = ImmutableList.<AuditLogModelDao>copyOf(dao.getAuditLogsForTableNameAndAccountRecordId(TableName.INVOICE_TRACKING_IDS.toString(), internalCallContext));
+ final List<AuditLogModelDao> auditLogsPostCreate = new ArrayList<>();
+ for (int i = 0; i < 4; i++) {
+ List<AuditLogModelDao> tmp = dao.getAuditLogsViaHistoryForTargetRecordId(TableName.INVOICE_TRACKING_ID_HISTORY.name(), TableName.INVOICE_TRACKING_ID_HISTORY.getTableName().toLowerCase(), result.get(i).getRecordId(), internalCallContext);
+ auditLogsPostCreate.addAll(tmp);
+ }
Assert.assertEquals(auditLogsPostCreate.size(), 4);
for (int i = 0; i < 4; i++) {
Assert.assertEquals(auditLogsPostCreate.get(i).getChangeType(), ChangeType.INSERT);
@@ -166,16 +170,20 @@ public class TestInvoiceTrackingSqlDao extends InvoiceTestSuiteWithEmbeddedDB {
final List<InvoiceTrackingModelDao> result2 = dao.getTrackingsByDateRange(startRange.toDate(), endRange.toDate(), internalCallContext);
Assert.assertEquals(result2.size(), 1);
- final List<AuditLogModelDao> auditLogsPostDelete = ImmutableList.<AuditLogModelDao>copyOf(dao.getAuditLogsForTableNameAndAccountRecordId(TableName.INVOICE_TRACKING_IDS.toString(), internalCallContext));
- Assert.assertEquals(auditLogsPostDelete.size(), 7);
+ final List<AuditLogModelDao> auditLogsPostDelete = new ArrayList<>();
for (int i = 0; i < 4; i++) {
- Assert.assertEquals(auditLogsPostDelete.get(i).getChangeType(), ChangeType.INSERT);
- Assert.assertEquals(auditLogsPostDelete.get(i).getTargetRecordId(), result.get(i).getRecordId());
+ List<AuditLogModelDao> tmp = dao.getAuditLogsViaHistoryForTargetRecordId(TableName.INVOICE_TRACKING_ID_HISTORY.name(), TableName.INVOICE_TRACKING_ID_HISTORY.getTableName().toLowerCase(), result.get(i).getRecordId(), internalCallContext);
+ auditLogsPostDelete.addAll(tmp);
}
- for (int i = 4; i < 7; i++) {
- Assert.assertEquals(auditLogsPostDelete.get(i).getChangeType(), ChangeType.DELETE);
- Assert.assertEquals(auditLogsPostDelete.get(i).getTargetRecordId(), result.get(i - 4).getRecordId());
+
+ Assert.assertEquals(auditLogsPostDelete.size(), 7);
+ // First 3 records will show an INSERT & DELETE
+ for (int i = 0; i < 3; i++) {
+ Assert.assertEquals(auditLogsPostDelete.get(2*i).getChangeType(), ChangeType.INSERT);
+ Assert.assertEquals(auditLogsPostDelete.get(2*i + 1).getChangeType(), ChangeType.DELETE);
}
+ // Last record will only show an INSERT
+ Assert.assertEquals(auditLogsPostDelete.get(6).getChangeType(), ChangeType.INSERT);
return null;
}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
index c7d08bf..4fcbb79 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
@@ -1133,7 +1133,7 @@ public class AccountResource extends JaxRsResourceBase {
@TimedResource
@GET
- @Path("/{blockingId:" + UUID_PATTERN + "}/" + BLOCK + "/" + AUDIT_LOG_WITH_HISTORY)
+ @Path("/" + BLOCK + "/{blockingId:" + UUID_PATTERN + "}/" + AUDIT_LOG_WITH_HISTORY)
@Produces(APPLICATION_JSON)
@ApiOperation(value = "Retrieve blocking state audit logs with history by id", response = AuditLogJson.class, responseContainer = "List")
@ApiResponses(value = {@ApiResponse(code = 404, message = "Blocking state not found")})
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceItemResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceItemResource.java
index 2b8eb6b..e28cfdd 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceItemResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceItemResource.java
@@ -34,6 +34,7 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriInfo;
import org.killbill.billing.ObjectType;
@@ -41,18 +42,22 @@ import org.killbill.billing.account.api.Account;
import org.killbill.billing.account.api.AccountApiException;
import org.killbill.billing.account.api.AccountUserApi;
import org.killbill.billing.entitlement.api.SubscriptionApi;
+import org.killbill.billing.invoice.api.InvoiceUserApi;
+import org.killbill.billing.jaxrs.json.AuditLogJson;
import org.killbill.billing.jaxrs.json.CustomFieldJson;
import org.killbill.billing.jaxrs.json.TagJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
+import org.killbill.billing.util.api.AuditLevel;
import org.killbill.billing.util.api.AuditUserApi;
import org.killbill.billing.util.api.CustomFieldApiException;
import org.killbill.billing.util.api.CustomFieldUserApi;
import org.killbill.billing.util.api.TagApiException;
import org.killbill.billing.util.api.TagDefinitionApiException;
import org.killbill.billing.util.api.TagUserApi;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.billing.util.customfield.CustomField;
import org.killbill.clock.Clock;
@@ -71,15 +76,32 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
public class InvoiceItemResource extends JaxRsResourceBase {
private static final String ID_PARAM_NAME = "invoiceItemId";
+ private final InvoiceUserApi invoiceApi;
+
@Inject
public InvoiceItemResource(final JaxrsUriBuilder uriBuilder, final TagUserApi tagUserApi, final CustomFieldUserApi customFieldUserApi,
- final AuditUserApi auditUserApi, final AccountUserApi accountUserApi, final PaymentApi paymentApi,
+ final AuditUserApi auditUserApi, final AccountUserApi accountUserApi, final InvoiceUserApi invoiceApi, final PaymentApi paymentApi,
final InvoicePaymentApi invoicePaymentApi, final SubscriptionApi subscriptionApi, final Clock clock, final Context context) {
super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, subscriptionApi, clock, context);
+ this.invoiceApi = invoiceApi;
}
@TimedResource
@GET
+ @Path("/{invoiceItemId:" + UUID_PATTERN + "}/" + AUDIT_LOG_WITH_HISTORY)
+ @Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Retrieve invoice item audit logs with history by id", response = AuditLogJson.class, responseContainer = "List")
+ @ApiResponses(value = {@ApiResponse(code = 404, message = "Invoice item not found")})
+ public Response getInvoiceItemAuditLogsWithHistory(@PathParam("invoiceItemId") final UUID invoiceItemId,
+ @javax.ws.rs.core.Context final HttpServletRequest request) {
+ final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
+ final List<AuditLogWithHistory> auditLogWithHistory = invoiceApi.getInvoiceItemAuditLogsWithHistoryForId(invoiceItemId, AuditLevel.FULL, tenantContext);
+ return Response.status(Status.OK).entity(getAuditLogsWithHistory(auditLogWithHistory)).build();
+ }
+
+
+ @TimedResource
+ @GET
@Path("/{invoiceItemId:" + UUID_PATTERN + "}/" + CUSTOM_FIELDS)
@Produces(APPLICATION_JSON)
@ApiOperation(value = "Retrieve invoice item custom fields", response = CustomFieldJson.class, responseContainer = "List", nickname = "getInvoiceItemCustomFields")
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoicePaymentResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoicePaymentResource.java
index f3d246f..73b00e3 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoicePaymentResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoicePaymentResource.java
@@ -48,6 +48,8 @@ import org.killbill.billing.account.api.AccountUserApi;
import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.invoice.api.InvoicePayment;
import org.killbill.billing.invoice.api.InvoicePaymentType;
+import org.killbill.billing.invoice.api.InvoiceUserApi;
+import org.killbill.billing.jaxrs.json.AuditLogJson;
import org.killbill.billing.jaxrs.json.CustomFieldJson;
import org.killbill.billing.jaxrs.json.InvoiceItemJson;
import org.killbill.billing.jaxrs.json.InvoicePaymentJson;
@@ -65,6 +67,7 @@ import org.killbill.billing.payment.api.PaymentTransaction;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.payment.api.TransactionStatus;
import org.killbill.billing.util.UUIDs;
+import org.killbill.billing.util.api.AuditLevel;
import org.killbill.billing.util.api.AuditUserApi;
import org.killbill.billing.util.api.CustomFieldApiException;
import org.killbill.billing.util.api.CustomFieldUserApi;
@@ -72,6 +75,7 @@ import org.killbill.billing.util.api.TagApiException;
import org.killbill.billing.util.api.TagDefinitionApiException;
import org.killbill.billing.util.api.TagUserApi;
import org.killbill.billing.util.audit.AccountAuditLogs;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.billing.util.customfield.CustomField;
@@ -96,6 +100,7 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
private static final String ID_PARAM_NAME = "paymentId";
private final InvoicePaymentApi invoicePaymentApi;
+ private final InvoiceUserApi invoiceApi;
@Inject
public InvoicePaymentResource(final AccountUserApi accountUserApi,
@@ -105,10 +110,12 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
final CustomFieldUserApi customFieldUserApi,
final AuditUserApi auditUserApi,
final InvoicePaymentApi invoicePaymentApi,
+ final InvoiceUserApi invoiceApi,
final Clock clock,
final Context context) {
super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
this.invoicePaymentApi = invoicePaymentApi;
+ this.invoiceApi = invoiceApi;
}
@TimedResource
@@ -144,6 +151,21 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
}
@TimedResource
+ @GET
+ @Path("/{invoicePaymentId:" + UUID_PATTERN + "}/" + AUDIT_LOG_WITH_HISTORY)
+ @Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Retrieve invoice payment audit logs with history by id", response = AuditLogJson.class, responseContainer = "List")
+ @ApiResponses(value = {@ApiResponse(code = 404, message = "Invoice payment not found")})
+ public Response getInvoicePaymentAuditLogsWithHistory(@PathParam("invoicePaymentId") final UUID invoicePaymentId,
+ @javax.ws.rs.core.Context final HttpServletRequest request) {
+ final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
+ final List<AuditLogWithHistory> auditLogWithHistory = invoiceApi.getInvoicePaymentAuditLogsWithHistoryForId(invoicePaymentId, AuditLevel.FULL, tenantContext);
+ return Response.status(Status.OK).entity(getAuditLogsWithHistory(auditLogWithHistory)).build();
+ }
+
+
+
+ @TimedResource
@POST
@Path("/{paymentId:" + UUID_PATTERN + "}/" + REFUNDS)
@Consumes(APPLICATION_JSON)
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
index 128a0e0..dd816b7 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
@@ -71,6 +71,7 @@ import org.killbill.billing.invoice.api.InvoiceApiException;
import org.killbill.billing.invoice.api.InvoiceItem;
import org.killbill.billing.invoice.api.InvoicePayment;
import org.killbill.billing.invoice.api.InvoiceUserApi;
+import org.killbill.billing.jaxrs.json.AuditLogJson;
import org.killbill.billing.jaxrs.json.CustomFieldJson;
import org.killbill.billing.jaxrs.json.InvoiceDryRunJson;
import org.killbill.billing.jaxrs.json.InvoiceItemJson;
@@ -88,6 +89,7 @@ import org.killbill.billing.tenant.api.TenantApiException;
import org.killbill.billing.tenant.api.TenantKV.TenantKey;
import org.killbill.billing.tenant.api.TenantUserApi;
import org.killbill.billing.util.LocaleUtils;
+import org.killbill.billing.util.api.AuditLevel;
import org.killbill.billing.util.api.AuditUserApi;
import org.killbill.billing.util.api.CustomFieldApiException;
import org.killbill.billing.util.api.CustomFieldUserApi;
@@ -95,6 +97,7 @@ import org.killbill.billing.util.api.TagApiException;
import org.killbill.billing.util.api.TagDefinitionApiException;
import org.killbill.billing.util.api.TagUserApi;
import org.killbill.billing.util.audit.AccountAuditLogs;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.billing.util.customfield.CustomField;
@@ -186,6 +189,20 @@ public class InvoiceResource extends JaxRsResourceBase {
return Response.status(Status.OK).entity(json).build();
}
+ @TimedResource
+ @GET
+ @Path("/{invoiceId:" + UUID_PATTERN + "}/" + AUDIT_LOG_WITH_HISTORY)
+ @Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Retrieve invoice audit logs with history by id", response = AuditLogJson.class, responseContainer = "List")
+ @ApiResponses(value = {@ApiResponse(code = 404, message = "Invoice not found")})
+ public Response getInvoiceAuditLogsWithHistory(@PathParam("invoiceId") final UUID invoiceId,
+ @javax.ws.rs.core.Context final HttpServletRequest request) {
+ final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
+ final List<AuditLogWithHistory> auditLogWithHistory = invoiceApi.getInvoiceAuditLogsWithHistoryForId(invoiceId, AuditLevel.FULL, tenantContext);
+ return Response.status(Status.OK).entity(getAuditLogsWithHistory(auditLogWithHistory)).build();
+ }
+
+
@TimedResource
@GET
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java
index f17729f..92ef0cb 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java
@@ -183,7 +183,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
@TimedResource
@GET
- @Path("/{eventId:" + UUID_PATTERN + "}/" + EVENTS + "/" + AUDIT_LOG_WITH_HISTORY)
+ @Path("/" + EVENTS + "/{eventId:" + UUID_PATTERN + "}/" + AUDIT_LOG_WITH_HISTORY)
@Produces(APPLICATION_JSON)
@ApiOperation(value = "Retrieve subscription event audit logs with history by id", response = AuditLogJson.class, responseContainer = "List")
@ApiResponses(value = {@ApiResponse(code = 404, message = "Subscription event not found")})
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultInvoicePaymentApi.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultInvoicePaymentApi.java
index 037298a..a600267 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/DefaultInvoicePaymentApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultInvoicePaymentApi.java
@@ -59,6 +59,11 @@ public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
}
@Override
+ public InvoicePayment getInvoicePayment(final UUID invoicePaymentId, final TenantContext tenantContext) {
+ return invoiceInternalApi.getInvoicePayment(invoicePaymentId, tenantContext);
+ }
+
+ @Override
public InvoicePayment createPurchaseForInvoicePayment(final Account account,
final UUID invoiceId,
final UUID paymentMethodId,
pom.xml 2(+1 -1)
diff --git a/pom.xml b/pom.xml
index 99c9c99..1cebe3f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
<parent>
<artifactId>killbill-oss-parent</artifactId>
<groupId>org.kill-bill.billing</groupId>
- <version>0.143.9-SNAPSHOT</version>
+ <version>0.143.11</version>
</parent>
<artifactId>killbill</artifactId>
<version>0.20.7-SNAPSHOT</version>
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccountTimeline.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccountTimeline.java
index ca64541..c94ca8d 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccountTimeline.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccountTimeline.java
@@ -99,7 +99,7 @@ public class TestAccountTimeline extends TestJaxrsBase {
final InvoicePaymentTransaction chargeback = new InvoicePaymentTransaction();
chargeback.setPaymentId(postedPayment.getPaymentId());
chargeback.setAmount(chargebackAmount);
- invoicePaymentApi.createChargeback(postedPayment.getPaymentId(), chargeback, requestOptions);
+ invoicePaymentApi.createChargeback(postedPayment.getPaymentId(), chargeback, NULL_PLUGIN_PROPERTIES, requestOptions);
// Verify payments
verifyPayments(accountJson.getAccountId(), startTime, endTime, refundAmount, chargebackAmount);
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestChargeback.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestChargeback.java
index d4b4778..559940c 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestChargeback.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestChargeback.java
@@ -64,11 +64,11 @@ public class TestChargeback extends TestJaxrsBase {
input.setAmount(new BigDecimal("50.00"));
int count = 4;
while (count-- > 0) {
- assertNotNull(invoicePaymentApi.createChargeback(payment.getPaymentId(), input, requestOptions));
+ assertNotNull(invoicePaymentApi.createChargeback(payment.getPaymentId(), input, NULL_PLUGIN_PROPERTIES, requestOptions));
}
// Last attempt should fail because this is more than the Payment
- final InvoicePayment foo = invoicePaymentApi.createChargeback(payment.getPaymentId(), input, requestOptions);
+ final InvoicePayment foo = invoicePaymentApi.createChargeback(payment.getPaymentId(), input, NULL_PLUGIN_PROPERTIES, requestOptions);
final InvoicePayments payments = accountApi.getInvoicePayments(payment.getAccountId(), NULL_PLUGIN_PROPERTIES, requestOptions);
final List<PaymentTransaction> transactions = getInvoicePaymentTransactions(payments, TransactionType.CHARGEBACK);
Assert.assertEquals(transactions.size(), 5);
@@ -110,7 +110,7 @@ public class TestChargeback extends TestJaxrsBase {
input.setPaymentId(input.getPaymentId());
input.setAmount(BigDecimal.TEN);
try {
- invoicePaymentApi.createChargeback(input.getPaymentId(), input, requestOptions);
+ invoicePaymentApi.createChargeback(input.getPaymentId(), input, NULL_PLUGIN_PROPERTIES, requestOptions);
fail();
} catch (NullPointerException e) {
} catch (KillBillClientException e) {
@@ -126,7 +126,7 @@ public class TestChargeback extends TestJaxrsBase {
input.setPaymentId(payment.getPaymentId());
try {
- invoicePaymentApi.createChargeback(payment.getPaymentId(), input, requestOptions);
+ invoicePaymentApi.createChargeback(payment.getPaymentId(), input, NULL_PLUGIN_PROPERTIES, requestOptions);
fail();
} catch (final KillBillClientException e) {
}
@@ -150,7 +150,7 @@ public class TestChargeback extends TestJaxrsBase {
chargeback.setPaymentId(payment.getPaymentId());
chargeback.setAmount(BigDecimal.TEN);
- final InvoicePayment chargebackJson = invoicePaymentApi.createChargeback(payment.getPaymentId(), chargeback, requestOptions);
+ final InvoicePayment chargebackJson = invoicePaymentApi.createChargeback(payment.getPaymentId(), chargeback, NULL_PLUGIN_PROPERTIES, requestOptions);
final List<PaymentTransaction> chargebackTransactions = getInvoicePaymentTransactions(ImmutableList.of(chargebackJson), TransactionType.CHARGEBACK);
assertEquals(chargebackTransactions.size(), 1);
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestExceptions.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestExceptions.java
index e02ef9c..6e6c896 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestExceptions.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestExceptions.java
@@ -43,7 +43,7 @@ public class TestExceptions extends TestJaxrsBase {
input.setPaymentId(payments.get(0).getPaymentId());
input.setAmount(BigDecimal.TEN.negate());
try {
- invoicePaymentApi.createChargeback(payments.get(0).getPaymentId(), input, requestOptions);
+ invoicePaymentApi.createChargeback(payments.get(0).getPaymentId(), input, NULL_PLUGIN_PROPERTIES, requestOptions);
fail();
} catch (final KillBillClientException e) {
Assert.assertEquals(e.getBillingException().getClassName(), InvoiceApiException.class.getName());
diff --git a/util/src/main/java/org/killbill/billing/util/dao/TableName.java b/util/src/main/java/org/killbill/billing/util/dao/TableName.java
index f4158c9..54d7810 100644
--- a/util/src/main/java/org/killbill/billing/util/dao/TableName.java
+++ b/util/src/main/java/org/killbill/billing/util/dao/TableName.java
@@ -34,10 +34,14 @@ public enum TableName {
BLOCKING_STATES("blocking_states", ObjectType.BLOCKING_STATES, BLOCKING_STATE_HISTORY),
CUSTOM_FIELD_HISTORY("custom_field_history"),
CUSTOM_FIELD("custom_fields", ObjectType.CUSTOM_FIELD, CUSTOM_FIELD_HISTORY),
- INVOICE_ITEMS("invoice_items", ObjectType.INVOICE_ITEM),
- INVOICE_PAYMENTS("invoice_payments", ObjectType.INVOICE_PAYMENT),
- INVOICES("invoices", ObjectType.INVOICE),
- INVOICE_TRACKING_IDS("invoice_tracking_ids"),
+ INVOICE_ITEM_HISTORY("invoice_item_history"),
+ INVOICE_ITEMS("invoice_items", ObjectType.INVOICE_ITEM, INVOICE_ITEM_HISTORY),
+ INVOICE_PAYMENT_HISTORY("invoice_payment_history"),
+ INVOICE_PAYMENTS("invoice_payments", ObjectType.INVOICE_PAYMENT, INVOICE_PAYMENT_HISTORY),
+ INVOICE_HISTORY("invoice_history"),
+ INVOICES("invoices", ObjectType.INVOICE, INVOICE_HISTORY),
+ INVOICE_TRACKING_ID_HISTORY("invoice_tracking_id_history"),
+ INVOICE_TRACKING_IDS("invoice_tracking_ids", null, INVOICE_TRACKING_ID_HISTORY),
INVOICE_PARENT_CHILDREN("invoice_parent_children"),
NODE_INFOS("node_infos"),
PAYMENT_ATTEMPT_HISTORY("payment_attempt_history"),
diff --git a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDao.java b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDao.java
index d9aa68f..e63c68a 100644
--- a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDao.java
@@ -61,14 +61,18 @@ public interface EntitySqlDao<M extends EntityModelDao<E>, E extends Entity> ext
@SmartBindBean final InternalCallContext context);
@SqlQuery
- public M getById(@Bind("id") final String id,
- @SmartBindBean final InternalTenantContext context);
-
- @SqlQuery
public M getByRecordId(@Bind("recordId") final Long recordId,
@SmartBindBean final InternalTenantContext context);
@SqlQuery
+ public List<M> getByRecordIds(@BindIn("recordIds") final Collection<Long> recordId,
+ @SmartBindBean final InternalTenantContext context);
+
+ @SqlQuery
+ public M getById(@Bind("id") final String id,
+ @SmartBindBean final InternalTenantContext context);
+
+ @SqlQuery
List<M> getByIds(@BindIn("ids") final Collection<String> ids,
@SmartBindBean final InternalTenantContext context);
diff --git a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java
index 34238f6..8010182 100644
--- a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java
+++ b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java
@@ -373,8 +373,7 @@ public class EntitySqlDaoWrapperInvocationHandler<S extends EntitySqlDao<M, E>,
// Make sure to re-hydrate the objects first (especially needed for create calls)
final Collection<M> reHydratedEntities = new ArrayList<>(entityRecordIds.size());
if (deletedAndUpdatedEntities.isEmpty()) {
- Preconditions.checkState(entityRecordIds.size() == 1 && changeType == ChangeType.INSERT, "Unexpected number of entityRecordIds=%s and changeType=%s", entityRecordIds, changeType);
- reHydratedEntities.add(sqlDao.getByRecordId(entityRecordIds.get(0), context));
+ reHydratedEntities.addAll((List<M>) sqlDao.getByRecordIds(entityRecordIds, context));
printSQLWarnings();
} else {
reHydratedEntities.addAll(deletedAndUpdatedEntities.values());
diff --git a/util/src/main/resources/org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg
index 0a9d423..e3c59da 100644
--- a/util/src/main/resources/org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg
@@ -189,6 +189,17 @@ where <recordIdField("t.")> = :recordId
;
>>
+getByRecordIds(recordIds) ::= <<
+select
+<allTableFields("t.")>
+from <tableName()> t
+where <recordIdField("t.")> in (<recordIds>)
+<andCheckSoftDeletionWithComma("t.")>
+<AND_CHECK_TENANT("t.")>
+;
+>>
+
+
getByIds(ids) ::= <<
select
<allTableFields("t.")>