List of usage examples for org.joda.time LocalDate isAfter
public boolean isAfter(ReadablePartial partial)
From source file:org.killbill.billing.invoice.generator.BillingIntervalDetail.java
License:Apache License
private void calculateLastBillingCycleDate() { // Start from firstBillingCycleDate and billingPeriod until we pass the effectiveEndDate LocalDate proposedDate = firstBillingCycleDate; int numberOfPeriods = 0; while (!proposedDate.isAfter(effectiveEndDate)) { proposedDate = firstBillingCycleDate.plusMonths(numberOfPeriods * billingPeriod.getNumberOfMonths()); numberOfPeriods += 1;// w w w .j ava 2s . c o m } // Our proposed date is billingCycleDate prior to the effectiveEndDate proposedDate = proposedDate.plusMonths(-billingPeriod.getNumberOfMonths()); proposedDate = alignProposedBillCycleDate(proposedDate, billingCycleDay); if (proposedDate.isBefore(firstBillingCycleDate)) { // Make sure not to go too far in the past lastBillingCycleDate = firstBillingCycleDate; } else { lastBillingCycleDate = proposedDate; } }
From source file:org.killbill.billing.invoice.generator.DefaultInvoiceGenerator.java
License:Apache License
private List<InvoiceItem> generateUsageConsumableInArrearItems(final Account account, final UUID invoiceId, final BillingEventSet eventSet, @Nullable final List<Invoice> existingInvoices, final LocalDate targetDate, final InternalCallContext internalCallContext) throws InvoiceApiException { final Map<UUID, List<InvoiceItem>> perSubscriptionConsumableInArrearUsageItems = extractPerSubscriptionExistingConsumableInArrearUsageItems( eventSet.getUsages(), existingInvoices); try {/*from ww w . j a v a 2s. c o m*/ final List<InvoiceItem> items = Lists.newArrayList(); final Iterator<BillingEvent> events = eventSet.iterator(); RawUsageOptimizerResult rawUsageOptimizerResult = null; List<BillingEvent> curEvents = Lists.newArrayList(); UUID curSubscriptionId = null; while (events.hasNext()) { final BillingEvent event = events.next(); // Skip events that are posterior to the targetDate final LocalDate eventLocalEffectiveDate = new LocalDate(event.getEffectiveDate(), event.getAccount().getTimeZone()); if (eventLocalEffectiveDate.isAfter(targetDate)) { continue; } // Optimize to do the usage query only once after we know there are indeed some usage items if (rawUsageOptimizerResult == null && Iterables.any(event.getUsages(), new Predicate<Usage>() { @Override public boolean apply(@Nullable final Usage input) { return (input.getUsageType() == UsageType.CONSUMABLE && input.getBillingMode() == BillingMode.IN_ARREAR); } })) { rawUsageOptimizerResult = rawUsageOptimizer.getConsumableInArrearUsage( new LocalDate(event.getEffectiveDate(), account.getTimeZone()), targetDate, Iterables.concat(perSubscriptionConsumableInArrearUsageItems.values()), eventSet.getUsages(), internalCallContext); } // None of the billing events report any usage (CONSUMABLE/IN_ARREAR) sections if (rawUsageOptimizerResult == null) { continue; } final UUID subscriptionId = event.getSubscription().getId(); if (curSubscriptionId != null && !curSubscriptionId.equals(subscriptionId)) { final SubscriptionConsumableInArrear subscriptionConsumableInArrear = new SubscriptionConsumableInArrear( invoiceId, curEvents, rawUsageOptimizerResult.getRawUsage(), targetDate, rawUsageOptimizerResult.getRawUsageStartDate()); final List<InvoiceItem> consumableInUsageArrearItems = perSubscriptionConsumableInArrearUsageItems .get(curSubscriptionId); items.addAll(subscriptionConsumableInArrear.computeMissingUsageInvoiceItems( consumableInUsageArrearItems != null ? consumableInUsageArrearItems : ImmutableList.<InvoiceItem>of())); curEvents = Lists.newArrayList(); } curSubscriptionId = subscriptionId; curEvents.add(event); } if (curSubscriptionId != null) { final SubscriptionConsumableInArrear subscriptionConsumableInArrear = new SubscriptionConsumableInArrear( invoiceId, curEvents, rawUsageOptimizerResult.getRawUsage(), targetDate, rawUsageOptimizerResult.getRawUsageStartDate()); final List<InvoiceItem> consumableInUsageArrearItems = perSubscriptionConsumableInArrearUsageItems .get(curSubscriptionId); items.addAll(subscriptionConsumableInArrear.computeMissingUsageInvoiceItems( consumableInUsageArrearItems != null ? consumableInUsageArrearItems : ImmutableList.<InvoiceItem>of())); } return items; } catch (CatalogApiException e) { throw new InvoiceApiException(e); } }
From source file:org.killbill.billing.invoice.generator.DefaultInvoiceGenerator.java
License:Apache License
private List<InvoiceItem> processInAdvanceEvents(final UUID invoiceId, final UUID accountId, final BillingEvent thisEvent, @Nullable final BillingEvent nextEvent, final LocalDate targetDate, final Currency currency, final StringBuilder logStringBuilder) throws InvoiceApiException { final List<InvoiceItem> items = new ArrayList<InvoiceItem>(); // Handle fixed price items final InvoiceItem fixedPriceInvoiceItem = generateFixedPriceItem(invoiceId, accountId, thisEvent, targetDate, currency);/*www . j ava2s . c o m*/ if (fixedPriceInvoiceItem != null) { items.add(fixedPriceInvoiceItem); } // Handle recurring items final BillingPeriod billingPeriod = thisEvent.getBillingPeriod(); if (billingPeriod != BillingPeriod.NO_BILLING_PERIOD) { final BillingModeGenerator billingModeGenerator = instantiateBillingMode(thisEvent.getBillingMode()); final LocalDate startDate = new LocalDate(thisEvent.getEffectiveDate(), thisEvent.getTimeZone()); if (!startDate.isAfter(targetDate)) { final LocalDate endDate = (nextEvent == null) ? null : new LocalDate(nextEvent.getEffectiveDate(), nextEvent.getTimeZone()); final int billCycleDayLocal = thisEvent.getBillCycleDayLocal(); final List<RecurringInvoiceItemData> itemData; try { itemData = billingModeGenerator.generateInvoiceItemData(startDate, endDate, targetDate, billCycleDayLocal, billingPeriod); } catch (InvalidDateSequenceException e) { throw new InvoiceApiException(ErrorCode.INVOICE_INVALID_DATE_SEQUENCE, startDate, endDate, targetDate); } for (final RecurringInvoiceItemData itemDatum : itemData) { final BigDecimal rate = thisEvent.getRecurringPrice(); if (rate != null) { final BigDecimal amount = KillBillMoney.of(itemDatum.getNumberOfCycles().multiply(rate), currency); final RecurringInvoiceItem recurringItem = new RecurringInvoiceItem(invoiceId, accountId, thisEvent.getSubscription().getBundleId(), thisEvent.getSubscription().getId(), thisEvent.getPlan().getName(), thisEvent.getPlanPhase().getName(), itemDatum.getStartDate(), itemDatum.getEndDate(), amount, rate, currency); items.add(recurringItem); } } } } // For debugging purposes logStringBuilder.append("\n").append(thisEvent); for (final InvoiceItem item : items) { logStringBuilder.append("\n\t").append(item); } return items; }
From source file:org.killbill.billing.invoice.generator.FixedAndRecurringInvoiceItemGenerator.java
License:Apache License
private List<InvoiceItem> processRecurringEvent(final UUID invoiceId, final UUID accountId, final BillingEvent thisEvent, @Nullable final BillingEvent nextEvent, final LocalDate targetDate, final Currency currency, final InvoiceItemGeneratorLogger invoiceItemGeneratorLogger, final BillingMode billingMode, final Map<UUID, SubscriptionFutureNotificationDates> perSubscriptionFutureNotificationDate, final InternalCallContext internalCallContext) throws InvoiceApiException { try {/*from www .ja va 2 s .c o m*/ final List<InvoiceItem> items = new ArrayList<InvoiceItem>(); // For FIXEDTERM phases we need to stop when the specified duration has been reached final LocalDate maxEndDate = thisEvent.getPlanPhase().getPhaseType() == PhaseType.FIXEDTERM ? thisEvent.getPlanPhase().getDuration().addToLocalDate( internalCallContext.toLocalDate(thisEvent.getEffectiveDate())) : null; // Handle recurring items final BillingPeriod billingPeriod = thisEvent.getBillingPeriod(); if (billingPeriod != BillingPeriod.NO_BILLING_PERIOD) { final LocalDate startDate = internalCallContext.toLocalDate(thisEvent.getEffectiveDate()); if (!startDate.isAfter(targetDate)) { final LocalDate endDate = (nextEvent == null) ? null : internalCallContext.toLocalDate(nextEvent.getEffectiveDate()); final int billCycleDayLocal = thisEvent.getBillCycleDayLocal(); final RecurringInvoiceItemDataWithNextBillingCycleDate itemDataWithNextBillingCycleDate; try { itemDataWithNextBillingCycleDate = generateInvoiceItemData(startDate, endDate, targetDate, billCycleDayLocal, billingPeriod, billingMode); } catch (final InvalidDateSequenceException e) { throw new InvoiceApiException(ErrorCode.INVOICE_INVALID_DATE_SEQUENCE, startDate, endDate, targetDate); } for (final RecurringInvoiceItemData itemDatum : itemDataWithNextBillingCycleDate .getItemData()) { // Stop if there a maxEndDate and we have reached it if (maxEndDate != null && maxEndDate.compareTo(itemDatum.getEndDate()) < 0) { break; } final BigDecimal rate = thisEvent .getRecurringPrice(internalCallContext.toUTCDateTime(itemDatum.getStartDate())); if (rate != null) { final BigDecimal amount = KillBillMoney.of(itemDatum.getNumberOfCycles().multiply(rate), currency); final RecurringInvoiceItem recurringItem = new RecurringInvoiceItem(invoiceId, accountId, thisEvent.getSubscription().getBundleId(), thisEvent.getSubscription().getId(), thisEvent.getPlan().getName(), thisEvent.getPlanPhase().getName(), itemDatum.getStartDate(), itemDatum.getEndDate(), amount, rate, currency); items.add(recurringItem); } } updatePerSubscriptionNextNotificationDate(thisEvent.getSubscription().getId(), itemDataWithNextBillingCycleDate.getNextBillingCycleDate(), items, billingMode, perSubscriptionFutureNotificationDate); } } // For debugging purposes invoiceItemGeneratorLogger.append(thisEvent, items); return items; } catch (final CatalogApiException e) { throw new InvoiceApiException(e); } }
From source file:org.killbill.billing.invoice.generator.FixedAndRecurringInvoiceItemGenerator.java
License:Apache License
public RecurringInvoiceItemDataWithNextBillingCycleDate generateInvoiceItemData(final LocalDate startDate, @Nullable final LocalDate endDate, final LocalDate targetDate, final int billingCycleDayLocal, final BillingPeriod billingPeriod, final BillingMode billingMode) throws InvalidDateSequenceException { if (endDate != null && endDate.isBefore(startDate)) { throw new InvalidDateSequenceException(); }//w ww. j a va 2 s .co m if (targetDate.isBefore(startDate)) { throw new InvalidDateSequenceException(); } final List<RecurringInvoiceItemData> results = new ArrayList<RecurringInvoiceItemData>(); final BillingIntervalDetail billingIntervalDetail = new BillingIntervalDetail(startDate, endDate, targetDate, billingCycleDayLocal, billingPeriod, billingMode); // We are not billing for less than a day if (!billingIntervalDetail.hasSomethingToBill()) { return new RecurringInvoiceItemDataWithNextBillingCycleDate(results, billingIntervalDetail); } // // If there is an endDate and that endDate is before our first coming firstBillingCycleDate, all we have to do // is to charge for that period // if (endDate != null && !endDate.isAfter(billingIntervalDetail.getFirstBillingCycleDate())) { final BigDecimal leadingProRationPeriods = calculateProRationBeforeFirstBillingPeriod(startDate, endDate, billingPeriod); final RecurringInvoiceItemData itemData = new RecurringInvoiceItemData(startDate, endDate, leadingProRationPeriods); results.add(itemData); return new RecurringInvoiceItemDataWithNextBillingCycleDate(results, billingIntervalDetail); } // // Leading proration if // i) The first firstBillingCycleDate is strictly after our start date AND // ii) The endDate is is not null and is strictly after our firstBillingCycleDate (previous check) // if (billingIntervalDetail.getFirstBillingCycleDate().isAfter(startDate)) { final BigDecimal leadingProRationPeriods = calculateProRationBeforeFirstBillingPeriod(startDate, billingIntervalDetail.getFirstBillingCycleDate(), billingPeriod); if (leadingProRationPeriods != null && leadingProRationPeriods.compareTo(BigDecimal.ZERO) > 0) { // Not common - add info in the logs for debugging purposes final RecurringInvoiceItemData itemData = new RecurringInvoiceItemData(startDate, billingIntervalDetail.getFirstBillingCycleDate(), leadingProRationPeriods); log.info("Adding pro-ration: {}", itemData); results.add(itemData); } } // // Calculate the effectiveEndDate from the firstBillingCycleDate: // - If endDate != null and targetDate is after endDate => this is the endDate and will lead to a trailing pro-ration // - If not, this is the last billingCycleDate calculation right after the targetDate // final LocalDate effectiveEndDate = billingIntervalDetail.getEffectiveEndDate(); // // Based on what we calculated previously, code recompute one more time the numberOfWholeBillingPeriods // final LocalDate lastBillingCycleDate = billingIntervalDetail.getLastBillingCycleDate(); final int numberOfWholeBillingPeriods = calculateNumberOfWholeBillingPeriods( billingIntervalDetail.getFirstBillingCycleDate(), lastBillingCycleDate, billingPeriod); for (int i = 0; i < numberOfWholeBillingPeriods; i++) { final LocalDate servicePeriodStartDate; if (!results.isEmpty()) { // Make sure the periods align, especially with the pro-ration calculations above servicePeriodStartDate = results.get(results.size() - 1).getEndDate(); } else if (i == 0) { // Use the specified start date servicePeriodStartDate = startDate; } else { throw new IllegalStateException("We should at least have one invoice item!"); } // Make sure to align the end date with the BCD final LocalDate servicePeriodEndDate = billingIntervalDetail.getFutureBillingDateFor(i + 1); results.add(new RecurringInvoiceItemData(servicePeriodStartDate, servicePeriodEndDate, BigDecimal.ONE)); } // // Now we check if indeed we need a trailing proration and add that incomplete item // if (effectiveEndDate.isAfter(lastBillingCycleDate)) { final BigDecimal trailingProRationPeriods = calculateProRationAfterLastBillingCycleDate( effectiveEndDate, lastBillingCycleDate, billingPeriod); if (trailingProRationPeriods.compareTo(BigDecimal.ZERO) > 0) { // Not common - add info in the logs for debugging purposes final RecurringInvoiceItemData itemData = new RecurringInvoiceItemData(lastBillingCycleDate, effectiveEndDate, trailingProRationPeriods); log.info("Adding trailing pro-ration: {}", itemData); results.add(itemData); } } return new RecurringInvoiceItemDataWithNextBillingCycleDate(results, billingIntervalDetail); }
From source file:org.killbill.billing.invoice.generator.FixedAndRecurringInvoiceItemGenerator.java
License:Apache License
private InvoiceItem generateFixedPriceItem(final UUID invoiceId, final UUID accountId, final BillingEvent thisEvent, final LocalDate targetDate, final Currency currency, final InvoiceItemGeneratorLogger invoiceItemGeneratorLogger, final InternalCallContext internalCallContext) throws InvoiceApiException { final LocalDate roundedStartDate = internalCallContext.toLocalDate(thisEvent.getEffectiveDate()); if (roundedStartDate.isAfter(targetDate)) { return null; } else {/*from w w w .j a va 2 s. co m*/ final BigDecimal fixedPrice = thisEvent.getFixedPrice(); if (fixedPrice != null) { final FixedPriceInvoiceItem fixedPriceInvoiceItem = new FixedPriceInvoiceItem(invoiceId, accountId, thisEvent.getSubscription().getBundleId(), thisEvent.getSubscription().getId(), thisEvent.getPlan().getName(), thisEvent.getPlanPhase().getName(), roundedStartDate, fixedPrice, currency); // For debugging purposes invoiceItemGeneratorLogger.append(thisEvent, fixedPriceInvoiceItem); return fixedPriceInvoiceItem; } else { return null; } } }
From source file:org.killbill.billing.invoice.generator.UsageInvoiceItemGenerator.java
License:Apache License
@Override public List<InvoiceItem> generateItems(final ImmutableAccountData account, final UUID invoiceId, final BillingEventSet eventSet, @Nullable final List<Invoice> existingInvoices, final LocalDate targetDate, final Currency targetCurrency, final Map<UUID, SubscriptionFutureNotificationDates> perSubscriptionFutureNotificationDates, final InternalCallContext internalCallContext) throws InvoiceApiException { final Map<UUID, List<InvoiceItem>> perSubscriptionInArrearUsageItems = extractPerSubscriptionExistingInArrearUsageItems( eventSet.getUsages(), existingInvoices); try {/*from ww w . j av a 2 s . c om*/ // Pretty-print the generated invoice items from the junction events final InvoiceItemGeneratorLogger invoiceItemGeneratorLogger = new InvoiceItemGeneratorLogger(invoiceId, account.getId(), "usage", log); final LocalDate minBillingEventDate = getMinBillingEventDate(eventSet, internalCallContext); final List<InvoiceItem> items = Lists.newArrayList(); final Iterator<BillingEvent> events = eventSet.iterator(); RawUsageOptimizerResult rawUsageOptimizerResult = null; List<BillingEvent> curEvents = Lists.newArrayList(); UUID curSubscriptionId = null; while (events.hasNext()) { final BillingEvent event = events.next(); // Skip events that are posterior to the targetDate final LocalDate eventLocalEffectiveDate = internalCallContext.toLocalDate(event.getEffectiveDate()); if (eventLocalEffectiveDate.isAfter(targetDate)) { continue; } // Optimize to do the usage query only once after we know there are indeed some usage items if (rawUsageOptimizerResult == null && Iterables.any(event.getUsages(), new Predicate<Usage>() { @Override public boolean apply(@Nullable final Usage input) { return input.getBillingMode() == BillingMode.IN_ARREAR; } })) { rawUsageOptimizerResult = rawUsageOptimizer.getInArrearUsage(minBillingEventDate, targetDate, Iterables.concat(perSubscriptionInArrearUsageItems.values()), eventSet.getUsages(), internalCallContext); } // None of the billing events report any usage IN_ARREAR sections if (rawUsageOptimizerResult == null) { continue; } final UUID subscriptionId = event.getSubscription().getId(); if (curSubscriptionId != null && !curSubscriptionId.equals(subscriptionId)) { final SubscriptionUsageInArrear subscriptionUsageInArrear = new SubscriptionUsageInArrear( account.getId(), invoiceId, curEvents, rawUsageOptimizerResult.getRawUsage(), targetDate, rawUsageOptimizerResult.getRawUsageStartDate(), internalCallContext); final List<InvoiceItem> usageInArrearItems = perSubscriptionInArrearUsageItems .get(curSubscriptionId); final SubscriptionUsageInArrearItemsAndNextNotificationDate subscriptionResult = subscriptionUsageInArrear .computeMissingUsageInvoiceItems(usageInArrearItems != null ? usageInArrearItems : ImmutableList.<InvoiceItem>of(), invoiceItemGeneratorLogger); final List<InvoiceItem> newInArrearUsageItems = subscriptionResult.getInvoiceItems(); items.addAll(newInArrearUsageItems); updatePerSubscriptionNextNotificationUsageDate(curSubscriptionId, subscriptionResult.getPerUsageNotificationDates(), BillingMode.IN_ARREAR, perSubscriptionFutureNotificationDates); curEvents = Lists.newArrayList(); } curSubscriptionId = subscriptionId; curEvents.add(event); } if (curSubscriptionId != null) { final SubscriptionUsageInArrear subscriptionUsageInArrear = new SubscriptionUsageInArrear( account.getId(), invoiceId, curEvents, rawUsageOptimizerResult.getRawUsage(), targetDate, rawUsageOptimizerResult.getRawUsageStartDate(), internalCallContext); final List<InvoiceItem> usageInArrearItems = perSubscriptionInArrearUsageItems .get(curSubscriptionId); final SubscriptionUsageInArrearItemsAndNextNotificationDate subscriptionResult = subscriptionUsageInArrear .computeMissingUsageInvoiceItems( usageInArrearItems != null ? usageInArrearItems : ImmutableList.<InvoiceItem>of(), invoiceItemGeneratorLogger); final List<InvoiceItem> newInArrearUsageItems = subscriptionResult.getInvoiceItems(); items.addAll(newInArrearUsageItems); updatePerSubscriptionNextNotificationUsageDate(curSubscriptionId, subscriptionResult.getPerUsageNotificationDates(), BillingMode.IN_ARREAR, perSubscriptionFutureNotificationDates); } invoiceItemGeneratorLogger.logItems(); return items; } catch (final CatalogApiException e) { throw new InvoiceApiException(e); } }
From source file:org.killbill.billing.invoice.model.InAdvanceBillingMode.java
License:Apache License
@Override public List<RecurringInvoiceItemData> generateInvoiceItemData(final LocalDate startDate, @Nullable final LocalDate endDate, final LocalDate targetDate, final int billingCycleDayLocal, final BillingPeriod billingPeriod) throws InvalidDateSequenceException { if (endDate != null && endDate.isBefore(startDate)) { throw new InvalidDateSequenceException(); }/*from w ww . j a v a2 s . co m*/ if (targetDate.isBefore(startDate)) { throw new InvalidDateSequenceException(); } final List<RecurringInvoiceItemData> results = new ArrayList<RecurringInvoiceItemData>(); final BillingIntervalDetail billingIntervalDetail = new BillingIntervalDetail(startDate, endDate, targetDate, billingCycleDayLocal, billingPeriod); // We are not billing for less than a day (we could...) if (endDate != null && endDate.equals(startDate)) { return results; } // // If there is an endDate and that endDate is before our first coming firstBillingCycleDate, all we have to do // is to charge for that period // if (endDate != null && !endDate.isAfter(billingIntervalDetail.getFirstBillingCycleDate())) { final BigDecimal leadingProRationPeriods = calculateProRationBeforeFirstBillingPeriod(startDate, endDate, billingPeriod); final RecurringInvoiceItemData itemData = new RecurringInvoiceItemData(startDate, endDate, leadingProRationPeriods); results.add(itemData); return results; } // // Leading proration if // i) The first firstBillingCycleDate is strictly after our start date AND // ii) The endDate is is not null and is strictly after our firstBillingCycleDate (previous check) // if (billingIntervalDetail.getFirstBillingCycleDate().isAfter(startDate)) { final BigDecimal leadingProRationPeriods = calculateProRationBeforeFirstBillingPeriod(startDate, billingIntervalDetail.getFirstBillingCycleDate(), billingPeriod); if (leadingProRationPeriods != null && leadingProRationPeriods.compareTo(BigDecimal.ZERO) > 0) { // Not common - add info in the logs for debugging purposes final RecurringInvoiceItemData itemData = new RecurringInvoiceItemData(startDate, billingIntervalDetail.getFirstBillingCycleDate(), leadingProRationPeriods); log.info("Adding pro-ration: {}", itemData); results.add(itemData); } } // // Calculate the effectiveEndDate from the firstBillingCycleDate: // - If endDate != null and targetDate is after endDate => this is the endDate and will lead to a trailing pro-ration // - If not, this is the last billingCycleDate calculation right after the targetDate // final LocalDate effectiveEndDate = billingIntervalDetail.getEffectiveEndDate(); // // Based on what we calculated previously, code recompute one more time the numberOfWholeBillingPeriods // final LocalDate lastBillingCycleDate = billingIntervalDetail.getLastBillingCycleDate(); final int numberOfWholeBillingPeriods = calculateNumberOfWholeBillingPeriods( billingIntervalDetail.getFirstBillingCycleDate(), lastBillingCycleDate, billingPeriod); for (int i = 0; i < numberOfWholeBillingPeriods; i++) { final LocalDate servicePeriodStartDate; if (results.size() > 0) { // Make sure the periods align, especially with the pro-ration calculations above servicePeriodStartDate = results.get(results.size() - 1).getEndDate(); } else if (i == 0) { // Use the specified start date servicePeriodStartDate = startDate; } else { throw new IllegalStateException("We should at least have one invoice item!"); } // Make sure to align the end date with the BCD final LocalDate servicePeriodEndDate = billingIntervalDetail.getFutureBillingDateFor(i + 1); results.add(new RecurringInvoiceItemData(servicePeriodStartDate, servicePeriodEndDate, BigDecimal.ONE)); } // // Now we check if indeed we need a trailing proration and add that incomplete item // if (effectiveEndDate.isAfter(lastBillingCycleDate)) { final BigDecimal trailingProRationPeriods = calculateProRationAfterLastBillingCycleDate( effectiveEndDate, lastBillingCycleDate, billingPeriod); if (trailingProRationPeriods.compareTo(BigDecimal.ZERO) > 0) { // Not common - add info in the logs for debugging purposes final RecurringInvoiceItemData itemData = new RecurringInvoiceItemData(lastBillingCycleDate, effectiveEndDate, trailingProRationPeriods); log.info("Adding trailing pro-ration: {}", itemData); results.add(itemData); } } return results; }
From source file:org.killbill.billing.invoice.usage.ContiguousIntervalConsumableInArrear.java
License:Apache License
/** * Builds the transitionTimes associated to that usage section. Those are determined based on billing events for when to start and when to stop, * the per usage billingPeriod and finally the targetDate. * <p/>//from ww w . j a va 2s .c o m * Those transition dates define the well defined billing granularity periods that should be billed for that specific usage section. * * @param closedInterval whether there was a last billing event referencing the usage section or whether this is ongoing and * then targetDate will define the endDate. * @return */ public ContiguousIntervalConsumableInArrear build(final boolean closedInterval) { Preconditions.checkState(!isBuilt.get()); Preconditions.checkState( (!closedInterval && billingEvents.size() >= 1) || (closedInterval && billingEvents.size() >= 2)); final LocalDate startDate = new LocalDate(billingEvents.get(0).getEffectiveDate(), getAccountTimeZone()); if (targetDate.isBefore(startDate)) { return this; } final LocalDate endDate = closedInterval ? new LocalDate(billingEvents.get(billingEvents.size() - 1).getEffectiveDate(), getAccountTimeZone()) : targetDate; final BillingIntervalDetail bid = new BillingIntervalDetail(startDate, endDate, targetDate, getBCD(), usage.getBillingPeriod()); int numberOfPeriod = 0; // First billingCycleDate prior startDate LocalDate nextBillCycleDate = bid.getFutureBillingDateFor(numberOfPeriod); if (startDate.compareTo(rawUsageStartDate) >= 0) { transitionTimes.add(startDate); } while (!nextBillCycleDate.isAfter(endDate)) { if (nextBillCycleDate.isAfter(startDate)) { if (nextBillCycleDate.compareTo(rawUsageStartDate) >= 0) { transitionTimes.add(nextBillCycleDate); } } numberOfPeriod++; nextBillCycleDate = bid.getFutureBillingDateFor(numberOfPeriod); } isBuilt.set(true); return this; }
From source file:org.killbill.billing.invoice.usage.ContiguousIntervalUsageInArrear.java
License:Apache License
/** * Builds the transitionTimes associated to that usage section. Those are determined based on billing events for when to start and when to stop, * the per usage billingPeriod and finally the targetDate. * <p/>//from www. j a v a 2 s . c o m * Those transition dates define the well defined billing granularity periods that should be billed for that specific usage section. * * @param closedInterval whether there was a last billing event referencing the usage section or whether this is ongoing and * then targetDate will define the endDate. */ public ContiguousIntervalUsageInArrear build(final boolean closedInterval) { Preconditions.checkState(!isBuilt.get()); Preconditions.checkState( (!closedInterval && billingEvents.size() >= 1) || (closedInterval && billingEvents.size() >= 2)); final LocalDate startDate = internalTenantContext.toLocalDate(billingEvents.get(0).getEffectiveDate()); if (targetDate.isBefore(startDate)) { return this; } final LocalDate endDate = closedInterval ? internalTenantContext.toLocalDate(billingEvents.get(billingEvents.size() - 1).getEffectiveDate()) : targetDate; final BillingIntervalDetail bid = new BillingIntervalDetail(startDate, endDate, targetDate, getBCD(), usage.getBillingPeriod(), usage.getBillingMode()); int numberOfPeriod = 0; // First billingCycleDate prior startDate LocalDate nextBillCycleDate = bid.getFutureBillingDateFor(numberOfPeriod); if (startDate.compareTo(rawUsageStartDate) >= 0) { transitionTimes.add(startDate); } while (!nextBillCycleDate.isAfter(endDate)) { if (nextBillCycleDate.isAfter(startDate)) { if (nextBillCycleDate.compareTo(rawUsageStartDate) >= 0) { transitionTimes.add(nextBillCycleDate); } } numberOfPeriod++; nextBillCycleDate = bid.getFutureBillingDateFor(numberOfPeriod); } if (closedInterval && transitionTimes.size() > 0 && endDate.isAfter(transitionTimes.get(transitionTimes.size() - 1))) { transitionTimes.add(endDate); } isBuilt.set(true); return this; }