killbill-uncached
Changes
account/pom.xml 2(+1 -1)
analytics/pom.xml 2(+1 -1)
api/pom.xml 2(+1 -1)
beatrix/pom.xml 2(+1 -1)
catalog/pom.xml 2(+1 -1)
entitlement/pom.xml 2(+1 -1)
entitlement/src/main/java/com/ning/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java 23(+14 -9)
invoice/pom.xml 2(+1 -1)
invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDatePoster.java 4(+2 -2)
jaxrs/pom.xml 2(+1 -1)
junction/pom.xml 2(+1 -1)
junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingEvent.java 19(+6 -13)
junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultInternalBillingApi.java 50(+15 -35)
junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestDefaultBillingEvent.java 12(+11 -1)
overdue/pom.xml 2(+1 -1)
payment/pom.xml 2(+1 -1)
pom.xml 2(+1 -1)
server/pom.xml 2(+1 -1)
tenant/pom.xml 2(+1 -1)
usage/pom.xml 2(+1 -1)
util/pom.xml 2(+1 -1)
Details
account/pom.xml 2(+1 -1)
diff --git a/account/pom.xml b/account/pom.xml
index 44ab661..6b8ee73 100644
--- a/account/pom.xml
+++ b/account/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.44-SNAPSHOT</version>
+ <version>0.1.45-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-account</artifactId>
analytics/pom.xml 2(+1 -1)
diff --git a/analytics/pom.xml b/analytics/pom.xml
index 096b0c5..1eec05b 100644
--- a/analytics/pom.xml
+++ b/analytics/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.44-SNAPSHOT</version>
+ <version>0.1.45-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-analytics</artifactId>
api/pom.xml 2(+1 -1)
diff --git a/api/pom.xml b/api/pom.xml
index aa681d7..b400caa 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.44-SNAPSHOT</version>
+ <version>0.1.45-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-api</artifactId>
beatrix/pom.xml 2(+1 -1)
diff --git a/beatrix/pom.xml b/beatrix/pom.xml
index 7ae3fcc..f982d64 100644
--- a/beatrix/pom.xml
+++ b/beatrix/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.44-SNAPSHOT</version>
+ <version>0.1.45-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-beatrix</artifactId>
diff --git a/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/DefaultLifecycle.java b/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/DefaultLifecycle.java
index 5f20021..853d074 100644
--- a/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/DefaultLifecycle.java
+++ b/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/DefaultLifecycle.java
@@ -94,10 +94,10 @@ public class DefaultLifecycle implements Lifecycle {
final Set<KillbillService> result = new HashSet<KillbillService>();
final Set<Class<? extends KillbillService>> services = serviceFinder.getServices();
for (final Class<? extends KillbillService> cur : services) {
- log.info("Found service {}", cur.getName());
+ log.debug("Found service {}", cur.getName());
try {
final KillbillService instance = injector.getInstance(cur);
- log.info("got instance {}", instance.getName());
+ log.debug("got instance {}", instance.getName());
result.add(instance);
} catch (final Exception e) {
logWarn("Failed to inject " + cur.getName(), e);
catalog/pom.xml 2(+1 -1)
diff --git a/catalog/pom.xml b/catalog/pom.xml
index 6c51d5e..b2b8614 100644
--- a/catalog/pom.xml
+++ b/catalog/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.44-SNAPSHOT</version>
+ <version>0.1.45-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-catalog</artifactId>
entitlement/pom.xml 2(+1 -1)
diff --git a/entitlement/pom.xml b/entitlement/pom.xml
index 5996b1d..c140c0a 100644
--- a/entitlement/pom.xml
+++ b/entitlement/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.44-SNAPSHOT</version>
+ <version>0.1.45-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-entitlement</artifactId>
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java
index b330f37..39d4a38 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java
@@ -13,6 +13,7 @@
* License for the specific language governing permissions and limitations
* under the License.
*/
+
package com.ning.billing.entitlement.api.svcs;
import java.util.ArrayList;
@@ -25,6 +26,8 @@ import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.ning.billing.ErrorCode;
import com.ning.billing.entitlement.api.SubscriptionFactory;
@@ -50,7 +53,10 @@ import com.google.inject.Inject;
public class DefaultEntitlementInternalApi implements EntitlementInternalApi {
+ private final Logger log = LoggerFactory.getLogger(DefaultEntitlementInternalApi.class);
+
private final EntitlementDao dao;
+
private final DefaultSubscriptionApiService apiService;
private final Clock clock;
@@ -64,8 +70,7 @@ public class DefaultEntitlementInternalApi implements EntitlementInternalApi {
}
@Override
- public List<SubscriptionBundle> getBundlesForAccount(UUID accountId,
- InternalTenantContext context) {
+ public List<SubscriptionBundle> getBundlesForAccount(final UUID accountId, final InternalTenantContext context) {
return dao.getSubscriptionBundleForAccount(accountId, context);
}
@@ -87,6 +92,7 @@ public class DefaultEntitlementInternalApi implements EntitlementInternalApi {
}
@Override
+
public Subscription getSubscriptionFromId(UUID id,
InternalTenantContext context) throws EntitlementUserApiException {
final Subscription result = dao.getSubscriptionFromId(id, context);
@@ -97,8 +103,7 @@ public class DefaultEntitlementInternalApi implements EntitlementInternalApi {
}
@Override
- public SubscriptionBundle getBundleFromId(UUID id,
- InternalTenantContext context) throws EntitlementUserApiException {
+ public SubscriptionBundle getBundleFromId(final UUID id, final InternalTenantContext context) throws EntitlementUserApiException {
final SubscriptionBundle result = dao.getSubscriptionBundleFromId(id, context);
if (result == null) {
throw new EntitlementUserApiException(ErrorCode.ENT_GET_INVALID_BUNDLE_ID, id.toString());
@@ -107,9 +112,7 @@ public class DefaultEntitlementInternalApi implements EntitlementInternalApi {
}
@Override
- public UUID getAccountIdFromSubscriptionId(UUID subscriptionId,
- InternalTenantContext context)
- throws EntitlementUserApiException {
+ public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId, final InternalTenantContext context) throws EntitlementUserApiException {
return dao.getAccountIdFromSubscriptionId(subscriptionId, context);
}
@@ -121,6 +124,8 @@ public class DefaultEntitlementInternalApi implements EntitlementInternalApi {
final SubscriptionBuilder builder = new SubscriptionBuilder(subscription)
.setChargedThroughDate(chargedThroughDate)
.setPaidThroughDate(subscription.getPaidThroughDate());
+
+ log.info("Setting CTD for subscription {} to {} ({} local)", new Object[]{subscriptionId, chargedThroughDate, localChargedThruDate});
dao.updateChargedThroughDate(new SubscriptionData(builder), context);
}
@@ -131,13 +136,13 @@ public class DefaultEntitlementInternalApi implements EntitlementInternalApi {
}
@Override
- public List<EffectiveSubscriptionInternalEvent> getBillingTransitions(Subscription subscription, final InternalTenantContext context) {
+ public List<EffectiveSubscriptionInternalEvent> getBillingTransitions(final Subscription subscription, final InternalTenantContext context) {
final List<SubscriptionTransitionData> transitions = ((SubscriptionData) subscription).getBillingTransitions();
return convertEffectiveSubscriptionInternalEventFromSubscriptionTransitions(subscription, context, transitions);
}
private List<EffectiveSubscriptionInternalEvent> convertEffectiveSubscriptionInternalEventFromSubscriptionTransitions(final Subscription subscription,
- final InternalTenantContext context, final List<SubscriptionTransitionData> transitions) {
+ final InternalTenantContext context, final List<SubscriptionTransitionData> transitions) {
return ImmutableList.<EffectiveSubscriptionInternalEvent>copyOf(Collections2.transform(transitions, new Function<SubscriptionTransitionData, EffectiveSubscriptionInternalEvent>() {
@Override
@Nullable
invoice/pom.xml 2(+1 -1)
diff --git a/invoice/pom.xml b/invoice/pom.xml
index 5712d51..06e28a5 100644
--- a/invoice/pom.xml
+++ b/invoice/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.44-SNAPSHOT</version>
+ <version>0.1.45-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-invoice</artifactId>
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
index fe64a71..e928a24 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
@@ -19,6 +19,7 @@ package com.ning.billing.invoice.dao;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -55,8 +56,8 @@ import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Objects;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap.Builder;
+import com.google.common.collect.Ordering;
import com.google.inject.Inject;
public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, InvoiceApiException> implements InvoiceDao {
@@ -199,13 +200,16 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
transInvoiceItemSqlDao.create(invoiceItemModelDao, context);
}
+ // Now we check whether we generated any credit that could be used on some unpaid invoices
+ useExistingCBAFromTransaction(invoice.getAccountId(), entitySqlDaoWrapperFactory, context);
+
notifyOfFutureBillingEvents(entitySqlDaoWrapperFactory, invoice.getAccountId(), callbackDateTimePerSubscriptions);
// Create associated payments
final InvoicePaymentSqlDao invoicePaymentSqlDao = entitySqlDaoWrapperFactory.become(InvoicePaymentSqlDao.class);
invoicePaymentSqlDao.batchCreateFromTransaction(invoicePayments, context);
- }
+ }
return null;
}
});
@@ -259,18 +263,12 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<List<InvoiceModelDao>>() {
@Override
public List<InvoiceModelDao> inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
- final List<InvoiceModelDao> invoices = getAllInvoicesByAccountFromTransaction(accountId, entitySqlDaoWrapperFactory, context);
- final Collection<InvoiceModelDao> unpaidInvoices = Collections2.filter(invoices, new Predicate<InvoiceModelDao>() {
- @Override
- public boolean apply(final InvoiceModelDao in) {
- return (InvoiceModelDaoHelper.getBalance(in).compareTo(BigDecimal.ZERO) >= 1) && (upToDate == null || !in.getTargetDate().isAfter(upToDate));
- }
- });
- return new ArrayList<InvoiceModelDao>(unpaidInvoices);
+ return getUnpaidInvoicesByAccountFromTransaction(accountId, entitySqlDaoWrapperFactory, upToDate, context);
}
});
}
+
@Override
public UUID getInvoiceIdByPaymentId(final UUID paymentId, final InternalTenantContext context) {
return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<UUID>() {
@@ -292,7 +290,6 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
}
@Override
-
public InvoicePaymentModelDao createRefund(final UUID paymentId, final BigDecimal requestedRefundAmount, final boolean isInvoiceAdjusted,
final Map<UUID, BigDecimal> invoiceItemIdsWithNullAmounts, final UUID paymentCookieId,
final InternalCallContext context)
@@ -368,6 +365,9 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
}
}
+ // Now we check whether we have any credit that could be used on some unpaid invoices (for which payment was just refunded)
+ useExistingCBAFromTransaction(invoice.getAccountId(), entitySqlDaoWrapperFactory, context);
+
// Notify the bus since the balance of the invoice changed
notifyBusOfInvoiceAdjustment(entitySqlDaoWrapperFactory, invoice.getId(), invoice.getAccountId(), context.getUserToken(), context);
@@ -496,18 +496,20 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
final InvoicePaymentModelDao payment = entitySqlDaoWrapperFactory.become(InvoicePaymentSqlDao.class).getById(invoicePaymentId.toString(), context);
if (payment == null) {
throw new InvoiceApiException(ErrorCode.INVOICE_PAYMENT_NOT_FOUND, invoicePaymentId.toString());
- } else {
- final InvoicePaymentModelDao chargeBack = new InvoicePaymentModelDao(UUID.randomUUID(), context.getCreatedDate(), InvoicePaymentType.CHARGED_BACK,
- payment.getInvoiceId(), payment.getPaymentId(), context.getCreatedDate(),
- requestedChargedBackAmout.negate(), payment.getCurrency(), null, payment.getId());
- transactional.create(chargeBack, context);
+ }
+ final InvoicePaymentModelDao chargeBack = new InvoicePaymentModelDao(UUID.randomUUID(), context.getCreatedDate(), InvoicePaymentType.CHARGED_BACK,
+ payment.getInvoiceId(), payment.getPaymentId(), context.getCreatedDate(),
+ requestedChargedBackAmout.negate(), payment.getCurrency(), null, payment.getId());
+ transactional.create(chargeBack, context);
- // Notify the bus since the balance of the invoice changed
- final UUID accountId = transactional.getAccountIdFromInvoicePaymentId(chargeBack.getId().toString(), context);
- notifyBusOfInvoiceAdjustment(entitySqlDaoWrapperFactory, payment.getInvoiceId(), accountId, context.getUserToken(), context);
+ // Notify the bus since the balance of the invoice changed
+ final UUID accountId = transactional.getAccountIdFromInvoicePaymentId(chargeBack.getId().toString(), context);
+ notifyBusOfInvoiceAdjustment(entitySqlDaoWrapperFactory, payment.getInvoiceId(), accountId, context.getUserToken(), context);
- return chargeBack;
- }
+ // Now we check whether we have any credit that could be used on some unpaid invoices (for which payment was just charged back)
+ useExistingCBAFromTransaction(accountId, entitySqlDaoWrapperFactory, context);
+
+ return chargeBack;
}
});
}
@@ -625,18 +627,8 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
}
populateChildren(invoice, entitySqlDaoWrapperFactory, context);
- final BigDecimal accountCbaAvailable = getAccountCBAFromTransaction(invoice.getAccountId(), entitySqlDaoWrapperFactory, context);
- final BigDecimal balance = InvoiceModelDaoHelper.getBalance(invoice);
- if (accountCbaAvailable.compareTo(BigDecimal.ZERO) > 0 && balance.compareTo(BigDecimal.ZERO) > 0) {
- final BigDecimal cbaAmountToConsume = accountCbaAvailable.compareTo(balance) > 0 ? balance.negate() : accountCbaAvailable.negate();
- final InvoiceItemModelDao cbaAdjItem = new InvoiceItemModelDao(context.getCreatedDate(), InvoiceItemType.CBA_ADJ,
- invoice.getId(), invoice.getAccountId(),
- null, null, null, null,
- context.getCreatedDate().toLocalDate(),
- null, cbaAmountToConsume, null,
- invoice.getCurrency(), null);
- transInvoiceItemDao.create(cbaAdjItem, context);
- }
+ // Now we check whether we have any credit that could be used towards that charge
+ useExistingCBAFromTransaction(accountId, entitySqlDaoWrapperFactory, context);
// Notify the bus since the balance of the invoice changed
notifyBusOfInvoiceAdjustment(entitySqlDaoWrapperFactory, invoiceId, accountId, context.getUserToken(), context);
@@ -799,6 +791,58 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
});
}
+ private void useExistingCBAFromTransaction(final UUID accountId, final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory, final InternalCallContext context) throws InvoiceApiException, EntityPersistenceException {
+
+ final BigDecimal accountCBA = getAccountCBAFromTransaction(accountId, entitySqlDaoWrapperFactory, context);
+ if (accountCBA.compareTo(BigDecimal.ZERO) <= 0) {
+ return;
+ }
+
+ final List<InvoiceModelDao> unpaidInvoices = getUnpaidInvoicesByAccountFromTransaction(accountId, entitySqlDaoWrapperFactory, null, context);
+ // We order the same os BillingStateCalculator-- should really share the comparator
+ final List<InvoiceModelDao> orderedUnpaidInvoices = Ordering.from(new Comparator<InvoiceModelDao>() {
+ @Override
+ public int compare(final InvoiceModelDao i1, final InvoiceModelDao i2) {
+ return i1.getInvoiceDate().compareTo(i2.getInvoiceDate());
+ }
+ }).immutableSortedCopy(unpaidInvoices);
+
+ BigDecimal remainingAccountCBA = accountCBA;
+ for (InvoiceModelDao cur : orderedUnpaidInvoices) {
+ final BigDecimal curInvoiceBalance = InvoiceModelDaoHelper.getBalance(cur);
+ final BigDecimal cbaToApplyOnInvoice = remainingAccountCBA.compareTo(curInvoiceBalance) <= 0 ? remainingAccountCBA : curInvoiceBalance;
+ remainingAccountCBA = remainingAccountCBA.subtract(cbaToApplyOnInvoice);
+
+
+ final InvoiceItemModelDao cbaAdjItem = new InvoiceItemModelDao(context.getCreatedDate(), InvoiceItemType.CBA_ADJ,
+ cur.getId(), cur.getAccountId(),
+ null, null, null, null,
+ context.getCreatedDate().toLocalDate(),
+ null, cbaToApplyOnInvoice.negate(), null,
+ cur.getCurrency(), null);
+
+ final InvoiceItemSqlDao transInvoiceItemDao = entitySqlDaoWrapperFactory.become(InvoiceItemSqlDao.class);
+ transInvoiceItemDao.create(cbaAdjItem, context);
+
+ if (remainingAccountCBA.compareTo(BigDecimal.ZERO) <= 0) {
+ break;
+ }
+ }
+ }
+
+
+ private List<InvoiceModelDao> getUnpaidInvoicesByAccountFromTransaction(final UUID accountId, final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory, final LocalDate upToDate, final InternalTenantContext context) {
+ final List<InvoiceModelDao> invoices = getAllInvoicesByAccountFromTransaction(accountId, entitySqlDaoWrapperFactory, context);
+ final Collection<InvoiceModelDao> unpaidInvoices = Collections2.filter(invoices, new Predicate<InvoiceModelDao>() {
+ @Override
+ public boolean apply(final InvoiceModelDao in) {
+ return (InvoiceModelDaoHelper.getBalance(in).compareTo(BigDecimal.ZERO) >= 1) && (upToDate == null || !in.getTargetDate().isAfter(upToDate));
+ }
+ });
+ return new ArrayList<InvoiceModelDao>(unpaidInvoices);
+ }
+
+
/**
* Create an adjustment for a given invoice item. This just creates the object in memory, it doesn't write it to disk.
*
@@ -940,9 +984,7 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
}
private void notifyOfFutureBillingEvents(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory, final UUID accountId, final Map<UUID, DateTime> callbackDateTimePerSubscriptions) {
-
-
- for (UUID subscriptionId : callbackDateTimePerSubscriptions.keySet()) {
+ for (final UUID subscriptionId : callbackDateTimePerSubscriptions.keySet()) {
final DateTime callbackDateTimeUTC = callbackDateTimePerSubscriptions.get(subscriptionId);
nextBillingDatePoster.insertNextBillingNotification(entitySqlDaoWrapperFactory, accountId, subscriptionId, callbackDateTimeUTC);
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/generator/DefaultInvoiceGenerator.java b/invoice/src/main/java/com/ning/billing/invoice/generator/DefaultInvoiceGenerator.java
index af67913..0b6e32e 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/generator/DefaultInvoiceGenerator.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/generator/DefaultInvoiceGenerator.java
@@ -305,8 +305,13 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
return items;
}
- final Iterator<BillingEvent> eventIt = events.iterator();
+ // Pretty-print the generated invoice items from the junction events
+ final StringBuilder logStringBuilder = new StringBuilder("Invoice items generated for invoiceId ")
+ .append(invoiceId)
+ .append(" and accountId ")
+ .append(accountId);
+ final Iterator<BillingEvent> eventIt = events.iterator();
BillingEvent nextEvent = eventIt.next();
while (eventIt.hasNext()) {
final BillingEvent thisEvent = nextEvent;
@@ -314,29 +319,20 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
if (!events.getSubscriptionIdsWithAutoInvoiceOff().
contains(thisEvent.getSubscription().getId())) { // don't consider events for subscriptions that have auto_invoice_off
final BillingEvent adjustedNextEvent = (thisEvent.getSubscription().getId() == nextEvent.getSubscription().getId()) ? nextEvent : null;
- items.addAll(processEvents(invoiceId, accountId, thisEvent, adjustedNextEvent, targetDate, accountTimeZone, currency));
+ items.addAll(processEvents(invoiceId, accountId, thisEvent, adjustedNextEvent, targetDate, accountTimeZone, currency, logStringBuilder));
}
}
- items.addAll(processEvents(invoiceId, accountId, nextEvent, null, targetDate, accountTimeZone, currency));
-
- // The above should reproduce the semantics of the code below using iterator instead of list.
- //
- // for (int i = 0; i < events.size(); i++) {
- // BillingEvent thisEvent = events.get(i);
- // BillingEvent nextEvent = events.isLast(thisEvent) ? null : events.get(i + 1);
- // if (nextEvent != null) {
- // nextEvent = (thisEvent.getSubscription().getId() == nextEvent.getSubscription().getId()) ? nextEvent : null;
- // }
- //
- // items.addAll(processEvents(invoiceId, accountId, thisEvent, nextEvent, targetDate, currency));
- // }
+ items.addAll(processEvents(invoiceId, accountId, nextEvent, null, targetDate, accountTimeZone, currency, logStringBuilder));
+
+ log.info(logStringBuilder.toString());
return items;
}
// Turn a set of events into a list of invoice items. Note that the dates on the invoice items will be rounded (granularity of a day)
private List<InvoiceItem> processEvents(final UUID invoiceId, final UUID accountId, final BillingEvent thisEvent, @Nullable final BillingEvent nextEvent,
- final LocalDate targetDate, final DateTimeZone accountTimeZone, final Currency currency) throws InvoiceApiException {
+ final LocalDate targetDate, final DateTimeZone accountTimeZone, final Currency currency,
+ final StringBuilder logStringBuilder) throws InvoiceApiException {
final List<InvoiceItem> items = new ArrayList<InvoiceItem>();
// Handle fixed price items
@@ -383,7 +379,14 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
}
}
- log.info("Generated invoice items [{}] from event [{}]", items, thisEvent);
+ // For debugging purposes
+ logStringBuilder.append("\n")
+ .append(thisEvent);
+ for (final InvoiceItem item : items) {
+ logStringBuilder.append("\n\t")
+ .append(item);
+ }
+
return items;
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java b/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java
index 7873fe6..5c30c08 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java
@@ -116,7 +116,6 @@ public class InvoiceDispatcher {
final InternalCallContext context) throws InvoiceApiException {
final UUID subscriptionId = transition.getSubscriptionId();
final DateTime targetDate = transition.getEffectiveTransitionTime();
- log.info("Got subscription transition: type: " + transition.getTransitionType().toString() + "; id: " + subscriptionId.toString() + "; targetDate: " + targetDate.toString());
processSubscription(subscriptionId, targetDate, context);
}
@@ -179,14 +178,15 @@ public class InvoiceDispatcher {
final Invoice invoice = generator.generateInvoice(accountId, billingEvents, invoices, targetDate, account.getTimeZone(), targetCurrency);
if (invoice == null) {
- log.info("Generated null invoice.");
+ log.info("Generated null invoice for accountId {} and targetDate {} (targetDateTime {})", new Object[]{accountId, targetDate, targetDateTime});
if (!dryRun) {
final BusInternalEvent event = new DefaultNullInvoiceEvent(accountId, clock.getUTCToday(), context.getUserToken(),
context.getAccountRecordId(), context.getTenantRecordId());
postEvent(event, accountId, context);
}
} else {
- log.info("Generated invoice {} with {} items.", invoice.getId().toString(), invoice.getNumberOfItems());
+ log.info("Generated invoice {} with {} items for accountId {} and targetDate {} (targetDateTime {})", new Object[]{invoice.getId(), invoice.getNumberOfItems(),
+ accountId, targetDate, targetDateTime});
if (!dryRun) {
// We need to check whether this is just a 'shell' invoice or a real invoice with items on it
final boolean isRealInvoiceWithItems = Collections2.filter(invoice.getInvoiceItems(), new Predicate<InvoiceItem>() {
@@ -288,7 +288,6 @@ public class InvoiceDispatcher {
for (final UUID subscriptionId : chargeThroughDates.keySet()) {
if (subscriptionId != null) {
final LocalDate chargeThroughDate = chargeThroughDates.get(subscriptionId);
- log.info("Setting CTD for subscription {} to {}", subscriptionId.toString(), chargeThroughDate.toString());
entitlementApi.setChargedThroughDate(subscriptionId, chargeThroughDate, context);
}
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/ExternalChargeInvoiceItem.java b/invoice/src/main/java/com/ning/billing/invoice/model/ExternalChargeInvoiceItem.java
index 3763053..e0305ba 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/ExternalChargeInvoiceItem.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/ExternalChargeInvoiceItem.java
@@ -84,20 +84,6 @@ public class ExternalChargeInvoiceItem extends InvoiceItemBase {
}
@Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append("InvoiceItem = {").append("id = ").append(id.toString()).append(", ");
- sb.append("invoiceId = ").append(invoiceId.toString()).append(", ");
- sb.append("accountId = ").append(accountId.toString()).append(", ");
- sb.append("bundleId = ").append(bundleId == null ? "null" : bundleId.toString()).append(", ");
- sb.append("description = ").append(planName).append(", ");
- sb.append("startDate = ").append(startDate.toString()).append(", ");
- sb.append("amount = ").append(amount == null ? "null" : amount.toString()).append(", ");
- sb.append("}");
- return sb.toString();
- }
-
- @Override
public boolean equals(final Object o) {
if (this == o) {
return true;
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/FixedPriceInvoiceItem.java b/invoice/src/main/java/com/ning/billing/invoice/model/FixedPriceInvoiceItem.java
index d99a84b..d1635bc 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/FixedPriceInvoiceItem.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/FixedPriceInvoiceItem.java
@@ -95,29 +95,6 @@ public class FixedPriceInvoiceItem extends InvoiceItemBase {
}
@Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append("InvoiceItem = {").append("id = ").append(id.toString()).append(", ");
- sb.append("invoiceId = ").append(invoiceId.toString()).append(", ");
- sb.append("accountId = ").append(accountId.toString()).append(", ");
- sb.append("subscriptionId = ").append(subscriptionId == null ? null : subscriptionId.toString()).append(", ");
- sb.append("bundleId = ").append(bundleId == null ? null : bundleId.toString()).append(", ");
- sb.append("planName = ").append(planName).append(", ");
- sb.append("phaseName = ").append(phaseName).append(", ");
- sb.append("startDate = ").append(startDate.toString()).append(", ");
-
- sb.append("amount = ");
- if (amount == null) {
- sb.append("null");
- } else {
- sb.append(amount.toString());
- }
-
- sb.append("}");
- return sb.toString();
- }
-
- @Override
public boolean equals(final Object o) {
if (this == o) {
return true;
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemBase.java b/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemBase.java
index f347a45..a49cb62 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemBase.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemBase.java
@@ -53,12 +53,18 @@ public abstract class InvoiceItemBase extends EntityBase implements InvoiceItem
@Override
public String toString() {
- return getInvoiceItemType() + ": [startDate=" + startDate + ", endDate="
- + endDate + ", amount=" + amount + ", currency=" + currency
- + ", invoiceId=" + invoiceId
- + ", subscriptionId=" + subscriptionId + ", planName="
- + planName + ", phaseName=" + phaseName + ", rate=" + rate
- + ", linkedItemId=" + linkedItemId + "]";
+ // Note: we don't use all fields here, as the output would be overwhelming
+ // (we output all invoice items as they are generated).
+ final StringBuilder sb = new StringBuilder();
+ sb.append(getInvoiceItemType());
+ sb.append("{startDate=").append(startDate);
+ sb.append(", endDate=").append(endDate);
+ sb.append(", amount=").append(amount);
+ sb.append(", rate=").append(rate);
+ sb.append(", subscriptionId=").append(subscriptionId);
+ sb.append(", linkedItemId=").append(linkedItemId);
+ sb.append('}');
+ return sb.toString();
}
/*
diff --git a/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDatePoster.java b/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDatePoster.java
index 4e8faf6..f923aff 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDatePoster.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDatePoster.java
@@ -59,14 +59,14 @@ public class DefaultNextBillingDatePoster implements NextBillingDatePoster {
try {
nextBillingQueue = notificationQueueService.getNotificationQueue(DefaultInvoiceService.INVOICE_SERVICE_NAME,
DefaultNextBillingDateNotifier.NEXT_BILLING_DATE_NOTIFIER_QUEUE);
- log.info("Queuing next billing date notification. id: {}, timestamp: {}", subscriptionId.toString(), futureNotificationTime.toString());
+ log.info("Queuing next billing date notification at {} for subscriptionId {}", futureNotificationTime.toString(), subscriptionId.toString());
nextBillingQueue.recordFutureNotificationFromTransaction(entitySqlDaoWrapperFactory, futureNotificationTime, accountId,
new NextBillingDateNotificationKey(subscriptionId), context);
} catch (NoSuchNotificationQueue e) {
log.error("Attempting to put items on a non-existent queue (NextBillingDateNotifier).", e);
} catch (IOException e) {
- log.error("Failed to serialize notficationKey for subscriptionId {}", subscriptionId);
+ log.error("Failed to serialize notificationKey for subscriptionId {}", subscriptionId);
}
}
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java b/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java
index 43269b5..736bfe3 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java
@@ -631,14 +631,16 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
final boolean partialRefund = refundAmount.compareTo(amount) < 0;
final BigDecimal cba = invoiceDao.getAccountCBA(accountId, internalCallContext);
final InvoiceModelDao savedInvoice = invoiceDao.getById(invoice.getId(), internalCallContext);
- assertEquals(cba.compareTo(new BigDecimal("20.0")), 0);
+
+ final BigDecimal expectedCba = balance.compareTo(BigDecimal.ZERO) < 0 ? balance.negate() : BigDecimal.ZERO;
+ assertEquals(cba.compareTo(expectedCba), 0);
if (partialRefund) {
// IB = 20 (rec) - 20 (repair) + 20 (cba) - (20 -7) = 7; AB = IB - CBA = 7 - 20 = -13
assertEquals(balance.compareTo(new BigDecimal("-13.0")), 0);
- assertEquals(savedInvoice.getInvoiceItems().size(), 3);
+ assertEquals(savedInvoice.getInvoiceItems().size(), 4);
} else {
assertEquals(balance.compareTo(new BigDecimal("0.0")), 0);
- assertEquals(savedInvoice.getInvoiceItems().size(), 3);
+ assertEquals(savedInvoice.getInvoiceItems().size(), 4);
}
}
@@ -730,7 +732,8 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
balance = invoiceDao.getAccountBalance(accountId, internalCallContext);
assertEquals(balance.compareTo(expectedFinalBalance), 0);
cba = invoiceDao.getAccountCBA(accountId, internalCallContext);
- assertEquals(cba.compareTo(new BigDecimal("10.00")), 0);
+ final BigDecimal expectedCba = balance.compareTo(BigDecimal.ZERO) < 0 ? balance.negate() : BigDecimal.ZERO;
+ assertEquals(cba.compareTo(expectedCba), 0);
}
@Test(groups = "slow")
@@ -738,13 +741,8 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
final UUID accountId = UUID.randomUUID();
final UUID bundleId = UUID.randomUUID();
- final LocalDate targetDate1 = new LocalDate(2011, 10, 6);
- final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate1, Currency.USD);
- createInvoice(invoice1, true, internalCallContext);
- // CREATE INVOICE WITH A (just) CBA. Should not happen, but that does not matter for that test
- final CreditBalanceAdjInvoiceItem cbaItem = new CreditBalanceAdjInvoiceItem(invoice1.getId(), accountId, new LocalDate(), new BigDecimal("20.0"), Currency.USD);
- createInvoiceItem(cbaItem, internalCallContext);
+ invoiceDao.insertCredit(accountId, null, new BigDecimal("20.0"), new LocalDate(), Currency.USD, internalCallContext);
final InvoiceItemModelDao charge = invoiceDao.insertExternalCharge(accountId, null, bundleId, "bla", new BigDecimal("15.0"), clock.getUTCNow().toLocalDate(), Currency.USD, internalCallContext);
@@ -1358,7 +1356,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
}
@Test(groups = "slow")
- public void testDeleteCBAPartiallyConsumed() throws Exception {
+ public void testRefundWithCBAPartiallyConsumed() throws Exception {
final UUID accountId = UUID.randomUUID();
// Create invoice 1
@@ -1377,6 +1375,12 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem1 = new CreditBalanceAdjInvoiceItem(fixedItem1.getInvoiceId(), fixedItem1.getAccountId(),
fixedItem1.getStartDate(), fixedItem1.getAmount(),
fixedItem1.getCurrency());
+
+ final UUID paymentId = UUID.randomUUID();
+ final DefaultInvoicePayment defaultInvoicePayment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentId, invoice1.getId(), clock.getUTCNow().plusDays(12), new BigDecimal("10.0"), Currency.USD);
+
+ invoiceDao.notifyOfPayment(new InvoicePaymentModelDao(defaultInvoicePayment), internalCallContext);
+
createInvoice(invoice1, true, internalCallContext);
createInvoiceItem(fixedItem1, internalCallContext);
createInvoiceItem(repairAdjInvoiceItem, internalCallContext);
@@ -1398,20 +1402,20 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
// Verify scenario - half of the CBA should have been used
Assert.assertEquals(invoiceDao.getAccountCBA(accountId, internalCallContext).doubleValue(), 5.00);
- verifyInvoice(invoice1.getId(), 10.00, 10.00);
+ verifyInvoice(invoice1.getId(), 0.00, 10.00);
verifyInvoice(invoice2.getId(), 0.00, -5.00);
- // Delete the CBA on invoice 1
- invoiceDao.deleteCBA(accountId, invoice1.getId(), creditBalanceAdjInvoiceItem1.getId(), internalCallContext);
+ // Refund Payment before we can deleted CBA
+ invoiceDao.createRefund(paymentId, new BigDecimal("10.0"), false, ImmutableMap.<UUID,BigDecimal>of(), UUID.randomUUID(), internalCallContext);
// Verify all three invoices were affected
Assert.assertEquals(invoiceDao.getAccountCBA(accountId, internalCallContext).doubleValue(), 0.00);
- verifyInvoice(invoice1.getId(), 0.00, 0.00);
- verifyInvoice(invoice2.getId(), 5.00, 0.00);
+ verifyInvoice(invoice1.getId(), 5.00, 5.00);
+ verifyInvoice(invoice2.getId(), 0.00, -5.00);
}
@Test(groups = "slow")
- public void testDeleteCBAFullyConsumedTwice() throws Exception {
+ public void testRefundCBAFullyConsumedTwice() throws Exception {
final UUID accountId = UUID.randomUUID();
// Create invoice 1
@@ -1435,6 +1439,13 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
createInvoiceItem(repairAdjInvoiceItem, internalCallContext);
createInvoiceItem(creditBalanceAdjInvoiceItem1, internalCallContext);
+
+ final BigDecimal paymentAmount = new BigDecimal("10.00");
+ final UUID paymentId = UUID.randomUUID();
+
+ final DefaultInvoicePayment defaultInvoicePayment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentId, invoice1.getId(), clock.getUTCNow().plusDays(12), paymentAmount, Currency.USD);
+ invoiceDao.notifyOfPayment(new InvoicePaymentModelDao(defaultInvoicePayment), internalCallContext);
+
// Create invoice 2
// Scenario: single item
// * $5 item
@@ -1465,18 +1476,17 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
// Verify scenario - all CBA should have been used
Assert.assertEquals(invoiceDao.getAccountCBA(accountId, internalCallContext).doubleValue(), 0.00);
- verifyInvoice(invoice1.getId(), 10.00, 10.00);
+ verifyInvoice(invoice1.getId(), 0.00, 10.00);
verifyInvoice(invoice2.getId(), 0.00, -5.00);
verifyInvoice(invoice3.getId(), 0.00, -5.00);
- // Delete the CBA on invoice 1
- invoiceDao.deleteCBA(accountId, invoice1.getId(), creditBalanceAdjInvoiceItem1.getId(), internalCallContext);
+ invoiceDao.createRefund(paymentId, paymentAmount, false, ImmutableMap.<UUID, BigDecimal>of(), UUID.randomUUID(), internalCallContext);
// Verify all three invoices were affected
Assert.assertEquals(invoiceDao.getAccountCBA(accountId, internalCallContext).doubleValue(), 0.00);
- verifyInvoice(invoice1.getId(), 0.00, 0.00);
- verifyInvoice(invoice2.getId(), 5.00, 0.00);
- verifyInvoice(invoice3.getId(), 5.00, 0.00);
+ verifyInvoice(invoice1.getId(), 10.00, 10.00);
+ verifyInvoice(invoice2.getId(), 0.00, -5.00);
+ verifyInvoice(invoice3.getId(), 0.00, -5.00);
}
@Test(groups = "slow")
jaxrs/pom.xml 2(+1 -1)
diff --git a/jaxrs/pom.xml b/jaxrs/pom.xml
index 2384e37..2045524 100644
--- a/jaxrs/pom.xml
+++ b/jaxrs/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.44-SNAPSHOT</version>
+ <version>0.1.45-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-jaxrs</artifactId>
junction/pom.xml 2(+1 -1)
diff --git a/junction/pom.xml b/junction/pom.xml
index 6bf158a..a60f4c2 100644
--- a/junction/pom.xml
+++ b/junction/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.44-SNAPSHOT</version>
+ <version>0.1.45-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-junction</artifactId>
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingEvent.java b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingEvent.java
index 905ef93..0ffa7fd 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingEvent.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingEvent.java
@@ -225,23 +225,16 @@ public class DefaultBillingEvent implements BillingEvent {
@Override
public String toString() {
+ // Note: we don't use all fields here, as the output would be overwhelming
+ // (these events are printed in the logs in junction and invoice).
final StringBuilder sb = new StringBuilder();
sb.append("DefaultBillingEvent");
- sb.append("{account=").append(account);
- sb.append(", billCycleDay=").append(billCycleDay);
- sb.append(", subscription=").append(subscription);
+ sb.append("{type=").append(type);
sb.append(", effectiveDate=").append(effectiveDate);
- sb.append(", planPhase=").append(planPhase);
- sb.append(", plan=").append(plan);
- sb.append(", fixedPrice=").append(fixedPrice);
- sb.append(", recurringPrice=").append(recurringPrice);
- sb.append(", currency=").append(currency);
- sb.append(", description='").append(description).append('\'');
- sb.append(", billingModeType=").append(billingModeType);
- sb.append(", billingPeriod=").append(billingPeriod);
- sb.append(", type=").append(type);
+ sb.append(", planPhaseName=").append(planPhase.getName());
+ sb.append(", subscriptionId=").append(subscription.getId());
sb.append(", totalOrdering=").append(totalOrdering);
- sb.append(", timeZone=").append(timeZone);
+ sb.append(", accountId=").append(account.getId());
sb.append('}');
return sb.toString();
}
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultInternalBillingApi.java b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultInternalBillingApi.java
index 2804a04..8fecc53 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultInternalBillingApi.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultInternalBillingApi.java
@@ -17,7 +17,6 @@
package com.ning.billing.junction.plumbing.billing;
import java.util.List;
-import java.util.Map;
import java.util.SortedSet;
import java.util.UUID;
@@ -58,10 +57,10 @@ public class DefaultInternalBillingApi implements BillingInternalApi {
@Inject
public DefaultInternalBillingApi(final AccountInternalApi accountApi,
- final BillCycleDayCalculator bcdCalculator,
- final EntitlementInternalApi entitlementApi,
- final BlockingCalculator blockCalculator,
- final CatalogService catalogService, final TagInternalApi tagApi) {
+ final BillCycleDayCalculator bcdCalculator,
+ final EntitlementInternalApi entitlementApi,
+ final BlockingCalculator blockCalculator,
+ final CatalogService catalogService, final TagInternalApi tagApi) {
this.accountApi = accountApi;
this.bcdCalculator = bcdCalculator;
this.entitlementApi = entitlementApi;
@@ -72,9 +71,6 @@ public class DefaultInternalBillingApi implements BillingInternalApi {
@Override
public BillingEventSet getBillingEventsForAccountAndUpdateAccountBCD(final UUID accountId, final InternalCallContext context) {
-
- //final TenantContext context = factory.createTenantContext(API_USER_NAME, CallOrigin.INTERNAL, UserType.SYSTEM);
-
final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(accountId, context);
final DefaultBillingEventSet result = new DefaultBillingEventSet();
@@ -95,23 +91,25 @@ public class DefaultInternalBillingApi implements BillingInternalApi {
log.warn("Failed while getting BillingEvent", e);
}
- debugLog(result, "********* Billing Events Raw");
+ // Pretty-print the events, before and after the blocking calculator does its magic
+ final StringBuilder logStringBuilder = new StringBuilder("Computed billing events for accountId ").append(accountId);
+ eventsToString(logStringBuilder, result, "\nBilling Events Raw");
blockCalculator.insertBlockingEvents(result, context);
- debugLog(result, "********* Billing Events After Blocking");
+ eventsToString(logStringBuilder, result, "\nBilling Events After Blocking");
+ log.info(logStringBuilder.toString());
return result;
}
-
- private void debugLog(final SortedSet<BillingEvent> result, final String title) {
- log.info(title);
- for (final BillingEvent aResult : result) {
- log.info(aResult.toString());
+ private void eventsToString(final StringBuilder stringBuilder, final SortedSet<BillingEvent> events, final String title) {
+ stringBuilder.append(title);
+ for (final BillingEvent event : events) {
+ stringBuilder.append("\n").append(event.toString());
}
}
private void addBillingEventsForBundles(final List<SubscriptionBundle> bundles, final Account account, final InternalCallContext context,
- final DefaultBillingEventSet result) {
+ final DefaultBillingEventSet result) {
for (final SubscriptionBundle bundle : bundles) {
final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId(), context);
@@ -151,29 +149,11 @@ public class DefaultInternalBillingApi implements BillingInternalApi {
result.add(event);
} catch (CatalogApiException e) {
log.error("Failing to identify catalog components while creating BillingEvent from transition: " +
- transition.getId().toString(), e);
+ transition.getId().toString(), e);
} catch (Exception e) {
log.warn("Failed while getting BillingEvent", e);
}
}
}
}
-
- /*
-
- @Override
- public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId, final InternalTenantContext context) throws EntitlementUserApiException {
- final UUID result = entitlementApi.getAccountIdFromSubscriptionId(subscriptionId, context);
- if (result == null) {
- throw new EntitlementBillingApiException(ErrorCode.ENT_INVALID_SUBSCRIPTION_ID, subscriptionId.toString());
- }
- return result;
- }
-
- @Override
- public void setChargedThroughDate(final UUID subscriptionId, final LocalDate ctd, final InternalCallContext context) {
- entitlementApi.setChargedThroughDate(subscriptionId, ctd, context);
- }
-
- */
}
diff --git a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestDefaultBillingEvent.java b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestDefaultBillingEvent.java
index 4a4c1cc..58145d2 100644
--- a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestDefaultBillingEvent.java
+++ b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestDefaultBillingEvent.java
@@ -30,6 +30,7 @@ import org.mockito.Mockito;
import org.testng.Assert;
import org.testng.annotations.Test;
+import com.ning.billing.account.api.Account;
import com.ning.billing.catalog.DefaultPrice;
import com.ning.billing.catalog.MockInternationalPrice;
import com.ning.billing.catalog.MockPlan;
@@ -42,6 +43,7 @@ import com.ning.billing.catalog.api.PlanPhase;
import com.ning.billing.entitlement.api.SubscriptionTransitionType;
import com.ning.billing.entitlement.api.user.Subscription;
import com.ning.billing.junction.JunctionTestSuite;
+import com.ning.billing.mock.MockAccountBuilder;
import com.ning.billing.mock.api.MockBillCycleDay;
import com.ning.billing.util.svcapi.junction.BillingEvent;
import com.ning.billing.util.svcapi.junction.BillingModeType;
@@ -168,6 +170,13 @@ public class TestDefaultBillingEvent extends JunctionTestSuite {
Assert.assertEquals(event2, it.next());
}
+ @Test(groups = "fast")
+ public void testToString() throws Exception {
+ // Simple test to ensure we have an easy to read toString representation
+ final BillingEvent event = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z", DateTimeZone.UTC), SubscriptionTransitionType.CREATE);
+ Assert.assertEquals(event.toString(), "DefaultBillingEvent{type=CREATE, effectiveDate=2012-01-01T00:02:04.000Z, planPhaseName=Test-trial, subscriptionId=00000000-0000-0000-0000-000000000000, totalOrdering=1, accountId=" + event.getAccount().getId().toString() + "}");
+ }
+
private BillingEvent createEvent(final Subscription sub, final DateTime effectiveDate, final SubscriptionTransitionType type) {
return createEvent(sub, effectiveDate, type, 1L);
}
@@ -178,7 +187,8 @@ public class TestDefaultBillingEvent extends JunctionTestSuite {
final Plan shotgun = new MockPlan();
final PlanPhase shotgunMonthly = createMockMonthlyPlanPhase(null, BigDecimal.ZERO, PhaseType.TRIAL);
- return new DefaultBillingEvent(null, sub, effectiveDate,
+ final Account account = new MockAccountBuilder().build();
+ return new DefaultBillingEvent(account, sub, effectiveDate,
shotgun, shotgunMonthly,
BigDecimal.ZERO, null, Currency.USD, BillingPeriod.NO_BILLING_PERIOD, new MockBillCycleDay(billCycleDay),
BillingModeType.IN_ADVANCE, "Test Event 1", totalOrdering, type, DateTimeZone.UTC);
overdue/pom.xml 2(+1 -1)
diff --git a/overdue/pom.xml b/overdue/pom.xml
index d5885ce..a887690 100644
--- a/overdue/pom.xml
+++ b/overdue/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.44-SNAPSHOT</version>
+ <version>0.1.45-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-overdue</artifactId>
diff --git a/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java b/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java
index 82568b0..2419bed 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java
@@ -72,14 +72,14 @@ public class DefaultOverdueUserApi implements OverdueUserApi {
@Override
public <T extends Blockable> BillingState<T> getBillingStateFor(final T overdueable, final TenantContext context) throws OverdueException {
- log.info(String.format("Billing state of of %s requested", overdueable.getId()));
+ log.debug("Billing state of of {} requested", overdueable.getId());
final OverdueWrapper<T> wrapper = factory.createOverdueWrapperFor(overdueable);
return wrapper.billingState(internalCallContextFactory.createInternalTenantContext(context));
}
@Override
public <T extends Blockable> OverdueState<T> refreshOverdueStateFor(final T blockable, final CallContext context) throws OverdueException, OverdueApiException {
- log.info(String.format("Refresh of %s requested", blockable.getId()));
+ log.info("Refresh of blockable {} ({}) requested", blockable.getId(), blockable.getClass());
final OverdueWrapper<T> wrapper = factory.createOverdueWrapperFor(blockable);
return wrapper.refresh(createInternalCallContext(blockable, context));
}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueDispatcher.java b/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueDispatcher.java
index 03540d0..95450ea 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueDispatcher.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueDispatcher.java
@@ -22,11 +22,11 @@ import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.ning.billing.BillingExceptionBase;
import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
import com.ning.billing.entitlement.api.user.SubscriptionBundle;
import com.ning.billing.junction.api.Blockable;
-import com.ning.billing.overdue.OverdueApiException;
-import com.ning.billing.overdue.config.api.OverdueException;
+import com.ning.billing.junction.api.Blockable.Type;
import com.ning.billing.overdue.wrapper.OverdueWrapperFactory;
import com.ning.billing.util.callcontext.InternalCallContext;
import com.ning.billing.util.svcapi.entitlement.EntitlementInternalApi;
@@ -34,15 +34,15 @@ import com.ning.billing.util.svcapi.entitlement.EntitlementInternalApi;
import com.google.inject.Inject;
public class OverdueDispatcher {
+
Logger log = LoggerFactory.getLogger(OverdueDispatcher.class);
private final EntitlementInternalApi entitlementApi;
private final OverdueWrapperFactory factory;
@Inject
- public OverdueDispatcher(
- final EntitlementInternalApi entitlementApi,
- final OverdueWrapperFactory factory) {
+ public OverdueDispatcher(final EntitlementInternalApi entitlementApi,
+ final OverdueWrapperFactory factory) {
this.entitlementApi = entitlementApi;
this.factory = factory;
}
@@ -50,37 +50,32 @@ public class OverdueDispatcher {
public void processOverdueForAccount(final UUID accountId, final InternalCallContext context) {
final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(accountId, context);
for (final SubscriptionBundle bundle : bundles) {
- processOverdue(bundle, context);
+ processOverdue(Type.SUBSCRIPTION_BUNDLE, bundle, context);
}
}
public void processOverdueForBundle(final UUID bundleId, final InternalCallContext context) {
try {
final SubscriptionBundle bundle = entitlementApi.getBundleFromId(bundleId, context);
- processOverdue(bundle, context);
+ processOverdue(Type.SUBSCRIPTION_BUNDLE, bundle, context);
} catch (EntitlementUserApiException e) {
- log.error("Error processing Overdue for Bundle with id: " + bundleId.toString(), e);
+ log.error("Error processing Overdue for bundle with id: " + bundleId.toString(), e);
}
}
- public void processOverdue(final Blockable blockable, final InternalCallContext context) {
+ public void processOverdue(final Blockable.Type type, final Blockable blockable, final InternalCallContext context) {
try {
factory.createOverdueWrapperFor(blockable).refresh(context);
- } catch (OverdueException e) {
- log.error("Error processing Overdue for Blockable with id: " + blockable.getId().toString(), e);
- } catch (OverdueApiException e) {
- log.error("Error processing Overdue for Blockable with id: " + blockable.getId().toString(), e);
+ } catch (BillingExceptionBase e) {
+ log.error(String.format("Error processing Overdue for blockable %s (type %s)", blockable.getId(), type), e);
}
}
public void processOverdue(final Blockable.Type type, final UUID blockableId, final InternalCallContext context) {
try {
factory.createOverdueWrapperFor(type, blockableId, context).refresh(context);
- } catch (OverdueException e) {
- log.error("Error processing Overdue for Blockable with id: " + blockableId.toString(), e);
- } catch (OverdueApiException e) {
- log.error("Error processing Overdue for Blockable with id: " + blockableId.toString(), e);
+ } catch (BillingExceptionBase e) {
+ log.error(String.format("Error processing Overdue for blockable %s (type %s)", blockableId, type), e);
}
}
-
}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueListener.java b/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueListener.java
index 7b3d02d..86af3de 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueListener.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueListener.java
@@ -49,20 +49,20 @@ public class OverdueListener {
@Subscribe
public void handlePaymentInfoEvent(final PaymentInfoInternalEvent event) {
- log.info(String.format("Received PaymentInfo event %s", event.toString()));
+ log.debug("Received PaymentInfo event {}", event);
dispatcher.processOverdueForAccount(event.getAccountId(), createCallContext(event.getUserToken(), event.getAccountRecordId(), event.getTenantRecordId()));
}
@Subscribe
public void handlePaymentErrorEvent(final PaymentErrorInternalEvent event) {
- log.info(String.format("Received PaymentError event %s", event.toString()));
+ log.debug("Received PaymentError event {}", event);
final UUID accountId = event.getAccountId();
dispatcher.processOverdueForAccount(accountId, createCallContext(event.getUserToken(), event.getAccountRecordId(), event.getTenantRecordId()));
}
@Subscribe
public void handleInvoiceAdjustmentEvent(final InvoiceAdjustmentInternalEvent event) {
- log.info(String.format("Received InvoiceAdjustment event %s", event.toString()));
+ log.debug("Received InvoiceAdjustment event {}", event);
final UUID accountId = event.getAccountId();
dispatcher.processOverdueForAccount(accountId, createCallContext(event.getUserToken(), event.getAccountRecordId(), event.getTenantRecordId()));
}
payment/pom.xml 2(+1 -1)
diff --git a/payment/pom.xml b/payment/pom.xml
index 5b901f2..014d231 100644
--- a/payment/pom.xml
+++ b/payment/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.44-SNAPSHOT</version>
+ <version>0.1.45-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-payment</artifactId>
pom.xml 2(+1 -1)
diff --git a/pom.xml b/pom.xml
index dd82327..1d86c33 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,7 +17,7 @@
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
<packaging>pom</packaging>
- <version>0.1.44-SNAPSHOT</version>
+ <version>0.1.45-SNAPSHOT</version>
<name>killbill</name>
<description>Library for managing recurring subscriptions and the associated billing</description>
<url>http://github.com/killbill/killbill</url>
server/pom.xml 2(+1 -1)
diff --git a/server/pom.xml b/server/pom.xml
index a563f22..1cc4442 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.44-SNAPSHOT</version>
+ <version>0.1.45-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-server</artifactId>
tenant/pom.xml 2(+1 -1)
diff --git a/tenant/pom.xml b/tenant/pom.xml
index af783c5..80ff7ff 100644
--- a/tenant/pom.xml
+++ b/tenant/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.44-SNAPSHOT</version>
+ <version>0.1.45-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-tenant</artifactId>
usage/pom.xml 2(+1 -1)
diff --git a/usage/pom.xml b/usage/pom.xml
index 180aa93..6b03f41 100644
--- a/usage/pom.xml
+++ b/usage/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.44-SNAPSHOT</version>
+ <version>0.1.45-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-usage</artifactId>
util/pom.xml 2(+1 -1)
diff --git a/util/pom.xml b/util/pom.xml
index 330a0bc..743c8e7 100644
--- a/util/pom.xml
+++ b/util/pom.xml
@@ -13,7 +13,7 @@
<parent>
<groupId>com.ning.billing</groupId>
<artifactId>killbill</artifactId>
- <version>0.1.44-SNAPSHOT</version>
+ <version>0.1.45-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>killbill-util</artifactId>
diff --git a/util/src/main/java/com/ning/billing/util/template/translation/DefaultTranslatorBase.java b/util/src/main/java/com/ning/billing/util/template/translation/DefaultTranslatorBase.java
index 421c84f..fbc2b7d 100644
--- a/util/src/main/java/com/ning/billing/util/template/translation/DefaultTranslatorBase.java
+++ b/util/src/main/java/com/ning/billing/util/template/translation/DefaultTranslatorBase.java
@@ -27,13 +27,13 @@ import java.util.ResourceBundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.ning.billing.ErrorCode;
import com.ning.billing.util.LocaleUtils;
import com.ning.billing.util.config.catalog.UriAccessor;
import com.google.inject.Inject;
public abstract class DefaultTranslatorBase implements Translator {
+
protected final TranslatorConfig config;
protected final Logger log = LoggerFactory.getLogger(DefaultTranslatorBase.class);
@@ -58,7 +58,7 @@ public abstract class DefaultTranslatorBase implements Translator {
return bundle.getString(originalText);
} else {
if (config.getDefaultLocale() == null) {
- log.warn(String.format(ErrorCode.MISSING_DEFAULT_TRANSLATION_RESOURCE.toString(), getTranslationType()));
+ log.debug("No default locale configured, returning original text");
return originalText;
}
@@ -72,7 +72,7 @@ public abstract class DefaultTranslatorBase implements Translator {
return originalText;
}
} catch (MissingResourceException mrex) {
- log.warn(String.format(ErrorCode.MISSING_TRANSLATION_RESOURCE.toString(), getTranslationType()));
+ log.warn("Missing translation bundle for locale {}", defaultLocale);
return originalText;
}
}
@@ -95,9 +95,6 @@ public abstract class DefaultTranslatorBase implements Translator {
bundle = getBundleFromPropertiesFile(propertiesFileName);
}
- if (bundle == null) {
- log.warn(String.format(ErrorCode.MISSING_TRANSLATION_RESOURCE.toString(), getTranslationType()));
- }
return bundle;
}