killbill-aplcache
Changes
invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java 17(+15 -2)
invoice/src/main/java/org/killbill/billing/invoice/generator/FixedAndRecurringInvoiceItemGenerator.java 5(+2 -3)
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 f7802ed..775fc50 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
@@ -276,17 +276,6 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
}
@Override
- public InvoiceModelDao getEarliestDraftInvoiceByAccount(final InternalTenantContext context) {
- return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<InvoiceModelDao>() {
- @Override
- public InvoiceModelDao inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
- final InvoiceSqlDao invoiceDao = entitySqlDaoWrapperFactory.become(InvoiceSqlDao.class);
- return invoiceDao.getEarliestDraftInvoiceByAccount(context);
- }
- });
- }
-
- @Override
public void createInvoice(final InvoiceModelDao invoice,
final FutureAccountNotifications callbackDateTimePerSubscriptions,
final InternalCallContext 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 3f12d60..377b150 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
@@ -48,8 +48,6 @@ public interface InvoiceDao extends EntityDao<InvoiceModelDao, Invoice, InvoiceA
public void setFutureAccountNotificationsForEmptyInvoice(final UUID accountId, final FutureAccountNotifications callbackDateTimePerSubscriptions,
final InternalCallContext context);
- InvoiceModelDao getEarliestDraftInvoiceByAccount(InternalTenantContext context);
-
InvoiceModelDao getByNumber(Integer number, InternalTenantContext context) throws InvoiceApiException;
List<InvoiceModelDao> getInvoicesByAccount(InternalTenantContext context);
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceSqlDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceSqlDao.java
index 3acaab5..fe3e080 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceSqlDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceSqlDao.java
@@ -52,6 +52,7 @@ public interface InvoiceSqlDao extends EntitySqlDao<InvoiceModelDao, Invoice> {
@Bind("status") String status,
@SmartBindBean final InternalCallContext context);
+
@SqlQuery
InvoiceModelDao getParentDraftInvoice(@Bind("accountId") final String parentAccountId,
@SmartBindBean final InternalTenantContext context);
@@ -59,8 +60,5 @@ public interface InvoiceSqlDao extends EntitySqlDao<InvoiceModelDao, Invoice> {
@SqlQuery
List<InvoiceModelDao> getByIds(@BindIn("ids") final Collection<String> invoiceIds,
@SmartBindBean final InternalTenantContext context);
- @SqlQuery
- InvoiceModelDao getEarliestDraftInvoiceByAccount(@SmartBindBean final InternalTenantContext context);
-
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java b/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java
index 69bb538..5f710aa 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java
@@ -43,7 +43,10 @@ import org.killbill.billing.util.config.definition.InvoiceConfig;
import org.killbill.clock.Clock;
import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
import com.google.inject.Inject;
public class DefaultInvoiceGenerator implements InvoiceGenerator {
@@ -68,7 +71,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
@Override
public InvoiceWithMetadata generateInvoice(final ImmutableAccountData account,
@Nullable final BillingEventSet events,
- @Nullable final List<Invoice> existingInvoices,
+ @Nullable final Iterable<Invoice> existingInvoices,
@Nullable final UUID targetInvoiceId,
final LocalDate targetDate,
final Currency targetCurrency,
@@ -94,6 +97,16 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
final List<InvoiceItem> usageItems = usageInvoiceItemGenerator.generateItems(account, invoice.getId(), events, existingInvoices, adjustedTargetDate, targetCurrency, perSubscriptionFutureNotificationDates, context);
invoice.addInvoiceItems(usageItems);
+ if (targetInvoiceId != null) {
+ final Invoice originalInvoice = Iterables.tryFind(existingInvoices, new Predicate<Invoice>() {
+ @Override
+ public boolean apply(final Invoice input) {
+ return input.getId().equals(targetInvoiceId);
+ }
+ }).orNull();
+ Preconditions.checkNotNull(originalInvoice);
+ invoice.addInvoiceItems(originalInvoice.getInvoiceItems());
+ }
return new InvoiceWithMetadata(invoice.getInvoiceItems().isEmpty() ? null : invoice, perSubscriptionFutureNotificationDates);
}
@@ -106,7 +119,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
}
}
- private LocalDate adjustTargetDate(final List<Invoice> existingInvoices, final LocalDate targetDate) {
+ private LocalDate adjustTargetDate(final Iterable<Invoice> existingInvoices, final LocalDate targetDate) {
if (existingInvoices == null) {
return targetDate;
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/generator/FixedAndRecurringInvoiceItemGenerator.java b/invoice/src/main/java/org/killbill/billing/invoice/generator/FixedAndRecurringInvoiceItemGenerator.java
index 6ff69c5..c73adba 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/generator/FixedAndRecurringInvoiceItemGenerator.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/generator/FixedAndRecurringInvoiceItemGenerator.java
@@ -83,7 +83,7 @@ public class FixedAndRecurringInvoiceItemGenerator extends InvoiceItemGenerator
}
public List<InvoiceItem> generateItems(final ImmutableAccountData account, final UUID invoiceId, final BillingEventSet eventSet,
- @Nullable final List<Invoice> existingInvoices, final LocalDate targetDate,
+ @Nullable final Iterable<Invoice> existingInvoices, final LocalDate targetDate,
final Currency targetCurrency, final Map<UUID, SubscriptionFutureNotificationDates> perSubscriptionFutureNotificationDate,
final InternalCallContext internalCallContext) throws InvoiceApiException {
final Multimap<UUID, LocalDate> createdItemsPerDayPerSubscription = LinkedListMultimap.<UUID, LocalDate>create();
@@ -105,7 +105,7 @@ public class FixedAndRecurringInvoiceItemGenerator extends InvoiceItemGenerator
// Generate list of proposed invoice items based on billing events from junction-- proposed items are ALL items since beginning of time
final List<InvoiceItem> proposedItems = new ArrayList<InvoiceItem>();
- processRecurringBillingEvents(invoiceId, account.getId(), eventSet, targetDate, targetCurrency, proposedItems, perSubscriptionFutureNotificationDate, existingInvoices, internalCallContext);
+ processRecurringBillingEvents(invoiceId, account.getId(), eventSet, targetDate, targetCurrency, proposedItems, perSubscriptionFutureNotificationDate, internalCallContext);
processFixedBillingEvents(invoiceId, account.getId(), eventSet, targetDate, targetCurrency, proposedItems, internalCallContext);
try {
@@ -124,7 +124,6 @@ public class FixedAndRecurringInvoiceItemGenerator extends InvoiceItemGenerator
private void processRecurringBillingEvents(final UUID invoiceId, final UUID accountId, final BillingEventSet events,
final LocalDate targetDate, final Currency currency, final List<InvoiceItem> proposedItems,
final Map<UUID, SubscriptionFutureNotificationDates> perSubscriptionFutureNotificationDate,
- @Nullable final List<Invoice> existingInvoices,
final InternalCallContext internalCallContext) throws InvoiceApiException {
if (events.isEmpty()) {
return;
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/generator/InvoiceGenerator.java b/invoice/src/main/java/org/killbill/billing/invoice/generator/InvoiceGenerator.java
index fac2799..062be76 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/generator/InvoiceGenerator.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/generator/InvoiceGenerator.java
@@ -31,6 +31,6 @@ import org.killbill.billing.invoice.api.InvoiceApiException;
import org.killbill.billing.junction.BillingEventSet;
public interface InvoiceGenerator {
- InvoiceWithMetadata generateInvoice(ImmutableAccountData account, @Nullable BillingEventSet events, @Nullable List<Invoice> existingInvoices,
+ InvoiceWithMetadata generateInvoice(ImmutableAccountData account, @Nullable BillingEventSet events, @Nullable Iterable<Invoice> existingInvoices,
final UUID targetInvoiceId, LocalDate targetDate, Currency targetCurrency, final InternalCallContext context) throws InvoiceApiException;
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/generator/InvoiceItemGenerator.java b/invoice/src/main/java/org/killbill/billing/invoice/generator/InvoiceItemGenerator.java
index eb2ce88..826a1b5 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/generator/InvoiceItemGenerator.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/generator/InvoiceItemGenerator.java
@@ -38,7 +38,7 @@ import org.slf4j.Logger;
public abstract class InvoiceItemGenerator {
public abstract List<InvoiceItem> generateItems(final ImmutableAccountData account, final UUID invoiceId, final BillingEventSet eventSet,
- @Nullable final List<Invoice> existingInvoices, final LocalDate targetDate,
+ @Nullable final Iterable<Invoice> existingInvoices, final LocalDate targetDate,
final Currency targetCurrency, Map<UUID, SubscriptionFutureNotificationDates> perSubscriptionFutureNotificationDate,
final InternalCallContext context) throws InvoiceApiException;
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/generator/UsageInvoiceItemGenerator.java b/invoice/src/main/java/org/killbill/billing/invoice/generator/UsageInvoiceItemGenerator.java
index eb18aaa..be097d9 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/generator/UsageInvoiceItemGenerator.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/generator/UsageInvoiceItemGenerator.java
@@ -71,7 +71,7 @@ public class UsageInvoiceItemGenerator extends InvoiceItemGenerator {
public List<InvoiceItem> generateItems(final ImmutableAccountData account,
final UUID invoiceId,
final BillingEventSet eventSet,
- @Nullable final List<Invoice> existingInvoices,
+ @Nullable final Iterable<Invoice> existingInvoices,
final LocalDate targetDate,
final Currency targetCurrency,
final Map<UUID, SubscriptionFutureNotificationDates> perSubscriptionFutureNotificationDates,
@@ -170,8 +170,8 @@ public class UsageInvoiceItemGenerator extends InvoiceItemGenerator {
}
}
- private Map<UUID, List<InvoiceItem>> extractPerSubscriptionExistingInArrearUsageItems(final Map<String, Usage> knownUsage, @Nullable final List<Invoice> existingInvoices) {
- if (existingInvoices == null || existingInvoices.isEmpty()) {
+ private Map<UUID, List<InvoiceItem>> extractPerSubscriptionExistingInArrearUsageItems(final Map<String, Usage> knownUsage, @Nullable final Iterable<Invoice> existingInvoices) {
+ if (existingInvoices == null || !existingInvoices.iterator().hasNext()) {
return ImmutableMap.of();
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java b/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
index 86f9c90..b1ecca2 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
@@ -467,17 +467,21 @@ public class InvoiceDispatcher {
return new DefaultInvoice(input);
}
}));
- final Currency targetCurrency = account.getCurrency();
-
final UUID targetInvoiceId;
+ // Filter out DRAFT invoices for computation of existing items unless Account is in AUTO_INVOICING_REUSE_DRAFT
if (billingEvents.isAccountAutoInvoiceReuseDraft()) {
- final InvoiceModelDao earliestDraftInvoice = invoiceDao.getEarliestDraftInvoiceByAccount(context);
- targetInvoiceId = earliestDraftInvoice != null ? earliestDraftInvoice.getId() : null;
+ final Invoice existingDraft = Iterables.tryFind(invoices, new Predicate<Invoice>() {
+ @Override
+ public boolean apply(final Invoice input) {
+ return input.getStatus() == InvoiceStatus.DRAFT;
+ }
+ }).orNull();
+ targetInvoiceId = existingDraft != null ? existingDraft.getId() : null;
} else {
targetInvoiceId = null;
}
- return generator.generateInvoice(account, billingEvents, invoices, targetInvoiceId, targetDate, targetCurrency, context);
+ return generator.generateInvoice(account, billingEvents, invoices, targetInvoiceId, targetDate, account.getCurrency(), context);
}
private FutureAccountNotifications createNextFutureNotificationDate(final InvoiceWithMetadata invoiceWithMetadata, final InternalCallContext context) {
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 141dca0..5639dbe 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
@@ -71,16 +71,6 @@ getParentDraftInvoice() ::= <<
<defaultOrderBy("")>
>>
-getEarliestDraftInvoiceByAccount() ::= <<
- SELECT <allTableFields("")>
- FROM <tableName()>
- WHERE <accountRecordIdField("")> = :accountRecordId
- AND status = 'DRAFT'
- <AND_CHECK_TENANT("")>
- <defaultOrderBy("")>
- limit 1
-;
->>
getByIds(ids) ::= <<
select
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 3cf8c32..0e1ea27 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
@@ -81,11 +81,6 @@ public class MockInvoiceDao extends MockEntityDaoBase<InvoiceModelDao, Invoice,
}
@Override
- public InvoiceModelDao getEarliestDraftInvoiceByAccount(final InternalTenantContext context) {
- return null;
- }
-
- @Override
public List<InvoiceItemModelDao> createInvoices(final List<InvoiceModelDao> invoiceModelDaos, final InternalCallContext context) {
synchronized (monitor) {
final List<InvoiceItemModelDao> createdItems = new LinkedList<InvoiceItemModelDao>();
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java b/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java
index 9f4ae9d..73737e0 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java
@@ -501,41 +501,6 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
assertEquals(invoices.size(), 0);
}
- @Test(groups = "slow")
- public void testGetEarliestDraftInvoiceByAccount() throws EntityPersistenceException {
- final UUID accountId = account.getId();
-
- InvoiceModelDao result;
- result = invoiceDao.getEarliestDraftInvoiceByAccount(context);
- assertNull(result);
-
- final LocalDate targetDate1 = new LocalDate(2011, 10, 6);
- final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate1, Currency.USD, InvoiceStatus.DRAFT);
- invoiceUtil.createInvoice(invoice1, context);
-
- result = invoiceDao.getEarliestDraftInvoiceByAccount(context);
- assertNotNull(result);
- assertEquals(result.getId(), invoice1.getId());
-
- final LocalDate targetDate2 = new LocalDate(2011, 12, 6);
- final Invoice invoice2 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate2, Currency.USD);
- invoiceUtil.createInvoice(invoice2, context);
-
- result = invoiceDao.getEarliestDraftInvoiceByAccount(context);
- assertNotNull(result);
- assertEquals(result.getId(), invoice1.getId());
-
-
- final LocalDate targetDate3 = new LocalDate(2011, 10, 6);
- final Invoice invoice3 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate3, Currency.USD, InvoiceStatus.DRAFT);
- invoiceUtil.createInvoice(invoice3, context);
-
- result = invoiceDao.getEarliestDraftInvoiceByAccount(context);
- assertNotNull(result);
- assertEquals(result.getId(), invoice1.getId());
- }
-
-
@Test(groups = "slow")
public void testAccountBalance() throws EntityPersistenceException {