use of org.killbill.billing.invoice.generator.InvoiceWithMetadata.SubscriptionFutureNotificationDates in project killbill by killbill.
the class TestInvoiceWithMetadata method testWith$0RecurringItem.
@Test(groups = "fast")
public void testWith$0RecurringItem() {
final LocalDate invoiceDate = new LocalDate(2016, 11, 15);
final DefaultInvoice originalInvoice = new DefaultInvoice(account.getId(), invoiceDate, account.getCurrency());
final Plan plan = new MockPlan("my-plan");
final MockInternationalPrice price = new MockInternationalPrice(new DefaultPrice(BigDecimal.TEN, account.getCurrency()));
final PlanPhase planPhase = new MockPlanPhase(price, null, BillingPeriod.MONTHLY, PhaseType.EVERGREEN);
final BillingEvent event = invoiceUtil.createMockBillingEvent(account, subscription, invoiceDate.toDateTimeAtStartOfDay(), plan, planPhase, null, BigDecimal.ZERO, account.getCurrency(), planPhase.getRecurring().getBillingPeriod(), 1, BillingMode.IN_ADVANCE, "Billing Event Desc", 1L, SubscriptionBaseTransitionType.CREATE);
final InvoiceItem invoiceItem = new RecurringInvoiceItem(UUID.randomUUID(), invoiceDate.toDateTimeAtStartOfDay(), originalInvoice.getId(), account.getId(), subscription.getBundleId(), subscription.getId(), event.getPlan().getName(), event.getPlanPhase().getName(), invoiceDate, invoiceDate.plusMonths(1), BigDecimal.ZERO, BigDecimal.ZERO, account.getCurrency());
originalInvoice.addInvoiceItem(invoiceItem);
final Map<UUID, SubscriptionFutureNotificationDates> perSubscriptionFutureNotificationDates = new HashMap<UUID, SubscriptionFutureNotificationDates>();
final SubscriptionFutureNotificationDates subscriptionFutureNotificationDates = new SubscriptionFutureNotificationDates(BillingMode.IN_ADVANCE);
subscriptionFutureNotificationDates.updateNextRecurringDateIfRequired(invoiceDate.plusMonths(1));
perSubscriptionFutureNotificationDates.put(subscription.getId(), subscriptionFutureNotificationDates);
final InvoiceWithMetadata invoiceWithMetadata = new InvoiceWithMetadata(originalInvoice, perSubscriptionFutureNotificationDates);
// We generate an invoice with one item, invoicing for $0
final Invoice resultingInvoice = invoiceWithMetadata.getInvoice();
Assert.assertNotNull(resultingInvoice);
Assert.assertEquals(resultingInvoice.getInvoiceItems().size(), 1);
Assert.assertEquals(resultingInvoice.getInvoiceItems().get(0).getAmount().compareTo(BigDecimal.ZERO), 0);
final Map<UUID, InvoiceWithMetadata.SubscriptionFutureNotificationDates> dateMap = invoiceWithMetadata.getPerSubscriptionFutureNotificationDates();
final InvoiceWithMetadata.SubscriptionFutureNotificationDates futureNotificationDates = dateMap.get(subscription.getId());
// We verify that we generated the future notification for a month ahead
Assert.assertNotNull(futureNotificationDates.getNextRecurringDate());
Assert.assertEquals(futureNotificationDates.getNextRecurringDate().compareTo(invoiceDate.plusMonths(1)), 0);
}
use of org.killbill.billing.invoice.generator.InvoiceWithMetadata.SubscriptionFutureNotificationDates in project killbill by killbill.
the class DefaultInvoiceGenerator method generateInvoice.
/*
* adjusts target date to the maximum invoice target date, if future invoices exist
*/
@Override
public InvoiceWithMetadata generateInvoice(final ImmutableAccountData account, @Nullable final BillingEventSet events, @Nullable final List<Invoice> existingInvoices, final LocalDate targetDate, final Currency targetCurrency, final InternalCallContext context) throws InvoiceApiException {
if ((events == null) || (events.size() == 0) || events.isAccountAutoInvoiceOff()) {
return new InvoiceWithMetadata(null, ImmutableMap.<UUID, SubscriptionFutureNotificationDates>of());
}
validateTargetDate(targetDate, context);
final LocalDate adjustedTargetDate = adjustTargetDate(existingInvoices, targetDate);
final LocalDate invoiceDate = context.toLocalDate(context.getCreatedDate());
final DefaultInvoice invoice = new DefaultInvoice(account.getId(), invoiceDate, adjustedTargetDate, targetCurrency);
final UUID invoiceId = invoice.getId();
final Map<UUID, SubscriptionFutureNotificationDates> perSubscriptionFutureNotificationDates = new HashMap<UUID, SubscriptionFutureNotificationDates>();
final List<InvoiceItem> fixedAndRecurringItems = recurringInvoiceItemGenerator.generateItems(account, invoiceId, events, existingInvoices, adjustedTargetDate, targetCurrency, perSubscriptionFutureNotificationDates, context);
invoice.addInvoiceItems(fixedAndRecurringItems);
final List<InvoiceItem> usageItems = usageInvoiceItemGenerator.generateItems(account, invoiceId, events, existingInvoices, adjustedTargetDate, targetCurrency, perSubscriptionFutureNotificationDates, context);
invoice.addInvoiceItems(usageItems);
return new InvoiceWithMetadata(invoice.getInvoiceItems().isEmpty() ? null : invoice, perSubscriptionFutureNotificationDates);
}
use of org.killbill.billing.invoice.generator.InvoiceWithMetadata.SubscriptionFutureNotificationDates in project killbill by killbill.
the class FixedAndRecurringInvoiceItemGenerator method updatePerSubscriptionNextNotificationDate.
private void updatePerSubscriptionNextNotificationDate(final UUID subscriptionId, final LocalDate nextBillingCycleDate, final List<InvoiceItem> newProposedItems, final BillingMode billingMode, final Map<UUID, SubscriptionFutureNotificationDates> perSubscriptionFutureNotificationDates) {
LocalDate nextNotificationDate = null;
switch(billingMode) {
case IN_ADVANCE:
for (final InvoiceItem item : newProposedItems) {
if ((item.getEndDate() != null) && (item.getAmount() == null || item.getAmount().compareTo(BigDecimal.ZERO) >= 0)) {
if (nextNotificationDate == null) {
nextNotificationDate = item.getEndDate();
} else {
nextNotificationDate = nextNotificationDate.compareTo(item.getEndDate()) > 0 ? nextNotificationDate : item.getEndDate();
}
}
}
break;
case IN_ARREAR:
nextNotificationDate = nextBillingCycleDate;
break;
default:
throw new IllegalStateException("Unrecognized billing mode " + billingMode);
}
if (nextNotificationDate != null) {
SubscriptionFutureNotificationDates subscriptionFutureNotificationDates = perSubscriptionFutureNotificationDates.get(subscriptionId);
if (subscriptionFutureNotificationDates == null) {
subscriptionFutureNotificationDates = new SubscriptionFutureNotificationDates(billingMode);
perSubscriptionFutureNotificationDates.put(subscriptionId, subscriptionFutureNotificationDates);
}
subscriptionFutureNotificationDates.updateNextRecurringDateIfRequired(nextNotificationDate);
}
}
use of org.killbill.billing.invoice.generator.InvoiceWithMetadata.SubscriptionFutureNotificationDates in project killbill by killbill.
the class InvoiceDispatcher method createNextFutureNotificationDate.
private FutureAccountNotifications createNextFutureNotificationDate(final InvoiceWithMetadata invoiceWithMetadata, final InternalCallContext context) {
final Map<UUID, List<SubscriptionNotification>> result = new HashMap<UUID, List<SubscriptionNotification>>();
for (final UUID subscriptionId : invoiceWithMetadata.getPerSubscriptionFutureNotificationDates().keySet()) {
final List<SubscriptionNotification> perSubscriptionNotifications = new ArrayList<SubscriptionNotification>();
final SubscriptionFutureNotificationDates subscriptionFutureNotificationDates = invoiceWithMetadata.getPerSubscriptionFutureNotificationDates().get(subscriptionId);
// Add next recurring date if any
if (subscriptionFutureNotificationDates.getNextRecurringDate() != null) {
perSubscriptionNotifications.add(new SubscriptionNotification(context.toUTCDateTime(subscriptionFutureNotificationDates.getNextRecurringDate()), true));
}
// Add next usage dates if any
if (subscriptionFutureNotificationDates.getNextUsageDates() != null) {
for (final UsageDef usageDef : subscriptionFutureNotificationDates.getNextUsageDates().keySet()) {
final LocalDate nextNotificationDateForUsage = subscriptionFutureNotificationDates.getNextUsageDates().get(usageDef);
final DateTime subscriptionUsageCallbackDate = nextNotificationDateForUsage != null ? context.toUTCDateTime(nextNotificationDateForUsage) : null;
perSubscriptionNotifications.add(new SubscriptionNotification(subscriptionUsageCallbackDate, true));
}
}
if (!perSubscriptionNotifications.isEmpty()) {
result.put(subscriptionId, perSubscriptionNotifications);
}
}
// If dryRunNotification is enabled we also need to fetch the upcoming PHASE dates (we add SubscriptionNotification with isForInvoiceNotificationTrigger = false)
final boolean isInvoiceNotificationEnabled = invoiceConfig.getDryRunNotificationSchedule(context).getMillis() > 0;
if (isInvoiceNotificationEnabled) {
final Map<UUID, DateTime> upcomingPhasesForSubscriptions = subscriptionApi.getNextFutureEventForSubscriptions(SubscriptionBaseTransitionType.PHASE, context);
for (final UUID cur : upcomingPhasesForSubscriptions.keySet()) {
final DateTime curDate = upcomingPhasesForSubscriptions.get(cur);
List<SubscriptionNotification> resultValue = result.get(cur);
if (resultValue == null) {
resultValue = new ArrayList<SubscriptionNotification>();
}
resultValue.add(new SubscriptionNotification(curDate, false));
result.put(cur, resultValue);
}
}
return new FutureAccountNotifications(result);
}
use of org.killbill.billing.invoice.generator.InvoiceWithMetadata.SubscriptionFutureNotificationDates in project killbill by killbill.
the class UsageInvoiceItemGenerator method updatePerSubscriptionNextNotificationUsageDate.
private void updatePerSubscriptionNextNotificationUsageDate(final UUID subscriptionId, final Map<String, LocalDate> nextBillingCycleDates, final BillingMode usageBillingMode, final Map<UUID, SubscriptionFutureNotificationDates> perSubscriptionFutureNotificationDates) {
if (usageBillingMode == BillingMode.IN_ADVANCE) {
throw new IllegalStateException("Not implemented Yet)");
}
SubscriptionFutureNotificationDates subscriptionFutureNotificationDates = perSubscriptionFutureNotificationDates.get(subscriptionId);
if (subscriptionFutureNotificationDates == null) {
subscriptionFutureNotificationDates = new SubscriptionFutureNotificationDates(null);
perSubscriptionFutureNotificationDates.put(subscriptionId, subscriptionFutureNotificationDates);
}
for (final String usageName : nextBillingCycleDates.keySet()) {
subscriptionFutureNotificationDates.updateNextUsageDateIfRequired(usageName, usageBillingMode, nextBillingCycleDates.get(usageName));
}
}
Aggregations