use of org.killbill.billing.callcontext.InternalCallContext in project killbill by killbill.
the class InvoiceDispatcher method processParentInvoiceForInvoiceGenerationWithLock.
private void processParentInvoiceForInvoiceGenerationWithLock(final Account childAccount, final UUID childInvoiceId, final InternalCallContext context) throws InvoiceApiException {
log.info("Processing parent invoice for parentAccountId='{}', childInvoiceId='{}'", childAccount.getParentAccountId(), childInvoiceId);
final InvoiceModelDao childInvoiceModelDao = invoiceDao.getById(childInvoiceId, context);
final Invoice childInvoice = new DefaultInvoice(childInvoiceModelDao);
final Long parentAccountRecordId = internalCallContextFactory.getRecordIdFromObject(childAccount.getParentAccountId(), ObjectType.ACCOUNT, buildTenantContext(context));
final InternalCallContext parentContext = internalCallContextFactory.createInternalCallContext(parentAccountRecordId, context);
BigDecimal childInvoiceAmount = InvoiceCalculatorUtils.computeChildInvoiceAmount(childInvoice.getCurrency(), childInvoice.getInvoiceItems());
InvoiceModelDao draftParentInvoice = invoiceDao.getParentDraftInvoice(childAccount.getParentAccountId(), parentContext);
final String description = childAccount.getExternalKey().concat(" summary");
if (draftParentInvoice != null) {
for (InvoiceItemModelDao item : draftParentInvoice.getInvoiceItems()) {
if ((item.getChildAccountId() != null) && item.getChildAccountId().equals(childInvoice.getAccountId())) {
// update child item amount for existing parent invoice item
BigDecimal newChildInvoiceAmount = childInvoiceAmount.add(item.getAmount());
log.info("Updating existing itemId='{}', oldAmount='{}', newAmount='{}' on existing DRAFT invoiceId='{}'", item.getId(), item.getAmount(), newChildInvoiceAmount, draftParentInvoice.getId());
invoiceDao.updateInvoiceItemAmount(item.getId(), newChildInvoiceAmount, parentContext);
return;
}
}
// new item when the parent invoices does not have this child item yet
final ParentInvoiceItem newParentInvoiceItem = new ParentInvoiceItem(UUID.randomUUID(), context.getCreatedDate(), draftParentInvoice.getId(), childAccount.getParentAccountId(), childAccount.getId(), childInvoiceAmount, childAccount.getCurrency(), description);
final InvoiceItemModelDao parentInvoiceItem = new InvoiceItemModelDao(newParentInvoiceItem);
draftParentInvoice.addInvoiceItem(parentInvoiceItem);
List<InvoiceModelDao> invoices = new ArrayList<InvoiceModelDao>();
invoices.add(draftParentInvoice);
log.info("Adding new itemId='{}', amount='{}' on existing DRAFT invoiceId='{}'", parentInvoiceItem.getId(), childInvoiceAmount, draftParentInvoice.getId());
invoiceDao.createInvoices(invoices, parentContext);
} else {
if (shouldIgnoreChildInvoice(childInvoice, childInvoiceAmount)) {
return;
}
final LocalDate invoiceDate = context.toLocalDate(context.getCreatedDate());
draftParentInvoice = new InvoiceModelDao(childAccount.getParentAccountId(), invoiceDate, childAccount.getCurrency(), InvoiceStatus.DRAFT, true);
final InvoiceItem parentInvoiceItem = new ParentInvoiceItem(UUID.randomUUID(), context.getCreatedDate(), draftParentInvoice.getId(), childAccount.getParentAccountId(), childAccount.getId(), childInvoiceAmount, childAccount.getCurrency(), description);
draftParentInvoice.addInvoiceItem(new InvoiceItemModelDao(parentInvoiceItem));
log.info("Adding new itemId='{}', amount='{}' on new DRAFT invoiceId='{}'", parentInvoiceItem.getId(), childInvoiceAmount, draftParentInvoice.getId());
invoiceDao.createInvoices(ImmutableList.<InvoiceModelDao>of(draftParentInvoice), parentContext);
}
// save parent child invoice relation
final InvoiceParentChildModelDao invoiceRelation = new InvoiceParentChildModelDao(draftParentInvoice.getId(), childInvoiceId, childAccount.getId());
invoiceDao.createParentChildInvoiceRelation(invoiceRelation, parentContext);
}
use of org.killbill.billing.callcontext.InternalCallContext in project killbill by killbill.
the class InvoiceDispatcher method processParentInvoiceForAdjustmentsWithLock.
public void processParentInvoiceForAdjustmentsWithLock(final Account account, final UUID childInvoiceId, final InternalCallContext context) throws InvoiceApiException {
final InvoiceModelDao childInvoiceModelDao = invoiceDao.getById(childInvoiceId, context);
final InvoiceModelDao parentInvoiceModelDao = childInvoiceModelDao.getParentInvoice();
if (parentInvoiceModelDao == null) {
throw new InvoiceApiException(ErrorCode.INVOICE_MISSING_PARENT_INVOICE, childInvoiceModelDao.getId());
} else if (InvoiceModelDaoHelper.getBalance(parentInvoiceModelDao).compareTo(BigDecimal.ZERO) == 0) {
// ignore item adjustments for paid invoices.
return;
}
final Long parentAccountRecordId = internalCallContextFactory.getRecordIdFromObject(account.getParentAccountId(), ObjectType.ACCOUNT, buildTenantContext(context));
final InternalCallContext parentContext = internalCallContextFactory.createInternalCallContext(parentAccountRecordId, context);
final String description = "Adjustment for account ".concat(account.getExternalKey());
// find PARENT_SUMMARY invoice item for this child account
final InvoiceItemModelDao parentSummaryInvoiceItem = Iterables.find(parentInvoiceModelDao.getInvoiceItems(), new Predicate<InvoiceItemModelDao>() {
@Override
public boolean apply(@Nullable final InvoiceItemModelDao input) {
return input.getType().equals(InvoiceItemType.PARENT_SUMMARY) && input.getChildAccountId().equals(childInvoiceModelDao.getAccountId());
}
});
final Iterable<InvoiceItemModelDao> childAdjustments = Iterables.filter(childInvoiceModelDao.getInvoiceItems(), new Predicate<InvoiceItemModelDao>() {
@Override
public boolean apply(@Nullable final InvoiceItemModelDao input) {
return input.getType().equals(InvoiceItemType.ITEM_ADJ);
}
});
// find last ITEM_ADJ invoice added in child invoice
final InvoiceItemModelDao lastChildInvoiceItemAdjustment = Collections.max(Lists.newArrayList(childAdjustments), new Comparator<InvoiceItemModelDao>() {
@Override
public int compare(InvoiceItemModelDao o1, InvoiceItemModelDao o2) {
return o1.getCreatedDate().compareTo(o2.getCreatedDate());
}
});
final BigDecimal childInvoiceAdjustmentAmount = lastChildInvoiceItemAdjustment.getAmount();
if (parentInvoiceModelDao.getStatus().equals(InvoiceStatus.COMMITTED)) {
ItemAdjInvoiceItem adj = new ItemAdjInvoiceItem(UUIDs.randomUUID(), lastChildInvoiceItemAdjustment.getCreatedDate(), parentSummaryInvoiceItem.getInvoiceId(), parentSummaryInvoiceItem.getAccountId(), lastChildInvoiceItemAdjustment.getStartDate(), description, childInvoiceAdjustmentAmount, parentInvoiceModelDao.getCurrency(), parentSummaryInvoiceItem.getId());
parentInvoiceModelDao.addInvoiceItem(new InvoiceItemModelDao(adj));
invoiceDao.createInvoices(ImmutableList.<InvoiceModelDao>of(parentInvoiceModelDao), parentContext);
return;
}
// update item amount
final BigDecimal newParentInvoiceItemAmount = childInvoiceAdjustmentAmount.add(parentSummaryInvoiceItem.getAmount());
invoiceDao.updateInvoiceItemAmount(parentSummaryInvoiceItem.getId(), newParentInvoiceItemAmount, parentContext);
}
use of org.killbill.billing.callcontext.InternalCallContext in project killbill by killbill.
the class DefaultInvoiceUserApi method tagInvoiceAsWrittenOff.
@Override
public void tagInvoiceAsWrittenOff(final UUID invoiceId, final CallContext context) throws TagApiException, InvoiceApiException {
// Note: the tagApi is audited
final InternalCallContext internalContext = internalCallContextFactory.createInternalCallContext(invoiceId, ObjectType.INVOICE, context);
tagApi.addTag(invoiceId, ObjectType.INVOICE, ControlTagType.WRITTEN_OFF.getId(), internalContext);
// Retrieve the invoice for the account id
final Invoice invoice = new DefaultInvoice(dao.getById(invoiceId, internalContext));
// This is for overdue
notifyBusOfInvoiceAdjustment(invoiceId, invoice.getAccountId(), internalContext);
}
use of org.killbill.billing.callcontext.InternalCallContext in project killbill by killbill.
the class DefaultInvoiceUserApi method triggerInvoiceGeneration.
@Override
public Invoice triggerInvoiceGeneration(final UUID accountId, @Nullable final LocalDate targetDate, final DryRunArguments dryRunArguments, final CallContext context) throws InvoiceApiException {
final InternalCallContext internalContext = internalCallContextFactory.createInternalCallContext(accountId, context);
final Invoice result = dispatcher.processAccount(true, accountId, targetDate, dryRunArguments, internalContext);
if (result == null) {
throw new InvoiceApiException(ErrorCode.INVOICE_NOTHING_TO_DO, accountId, targetDate != null ? targetDate : "null");
} else {
return result;
}
}
use of org.killbill.billing.callcontext.InternalCallContext in project killbill by killbill.
the class DefaultInvoiceUserApi method createMigrationInvoice.
@Override
public UUID createMigrationInvoice(final UUID accountId, final LocalDate targetDate, final Iterable<InvoiceItem> items, final CallContext context) {
final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(accountId, context);
final LocalDate invoiceDate = internalCallContext.toLocalDate(internalCallContext.getCreatedDate());
final InvoiceModelDao migrationInvoice = new InvoiceModelDao(accountId, invoiceDate, targetDate, items.iterator().next().getCurrency(), true);
final List<InvoiceItemModelDao> itemModelDaos = ImmutableList.copyOf(Iterables.transform(items, new Function<InvoiceItem, InvoiceItemModelDao>() {
@Override
public InvoiceItemModelDao apply(final InvoiceItem input) {
return new InvoiceItemModelDao(internalCallContext.getCreatedDate(), input.getInvoiceItemType(), migrationInvoice.getId(), accountId, input.getBundleId(), input.getSubscriptionId(), input.getDescription(), input.getPlanName(), input.getPhaseName(), input.getUsageName(), input.getStartDate(), input.getEndDate(), input.getAmount(), input.getRate(), input.getCurrency(), input.getLinkedItemId());
}
}));
migrationInvoice.addInvoiceItems(itemModelDaos);
dao.createInvoices(ImmutableList.<InvoiceModelDao>of(migrationInvoice), internalCallContext);
return migrationInvoice.getId();
}
Aggregations