use of org.killbill.billing.callcontext.InternalTenantContext in project killbill by killbill.
the class DefaultSubscriptionApi method getActiveSubscriptionBundleForExternalKey.
@Override
public SubscriptionBundle getActiveSubscriptionBundleForExternalKey(final String externalKey, final TenantContext context) throws SubscriptionApiException {
final InternalTenantContext internalContext = internalCallContextFactory.createInternalTenantContextWithoutAccountRecordId(context);
try {
final UUID activeSubscriptionIdForKey = entitlementUtils.getFirstActiveSubscriptionIdForKeyOrNull(externalKey, internalContext);
if (activeSubscriptionIdForKey == null) {
throw new SubscriptionApiException(new SubscriptionBaseApiException(ErrorCode.SUB_GET_INVALID_BUNDLE_KEY, externalKey));
}
final SubscriptionBase subscriptionBase = subscriptionBaseInternalApi.getSubscriptionFromId(activeSubscriptionIdForKey, internalContext);
return getSubscriptionBundle(subscriptionBase.getBundleId(), context);
} catch (final SubscriptionBaseApiException e) {
throw new SubscriptionApiException(e);
}
}
use of org.killbill.billing.callcontext.InternalTenantContext in project killbill by killbill.
the class DefaultSubscriptionApi method getBlockingStates.
@Override
public Iterable<BlockingState> getBlockingStates(final UUID accountId, @Nullable final List<BlockingStateType> typeFilter, @Nullable final List<String> svcsFilter, final OrderingType orderingType, final int timeFilter, final TenantContext tenantContext) throws EntitlementApiException {
try {
final InternalTenantContext internalTenantContextWithValidAccountRecordId = internalCallContextFactory.createInternalTenantContext(accountId, tenantContext);
final List<BlockingState> allBlockingStates = blockingStateDao.getBlockingAllForAccountRecordId(internalTenantContextWithValidAccountRecordId);
final ImmutableAccountData account = accountApi.getImmutableAccountDataById(accountId, internalTenantContextWithValidAccountRecordId);
final Iterable<BlockingState> filteredByTypes = typeFilter != null && !typeFilter.isEmpty() ? Iterables.filter(allBlockingStates, new Predicate<BlockingState>() {
@Override
public boolean apply(final BlockingState input) {
return typeFilter.contains(input.getType());
}
}) : allBlockingStates;
final Iterable<BlockingState> filteredByTypesAndSvcs = svcsFilter != null && !svcsFilter.isEmpty() ? Iterables.filter(filteredByTypes, new Predicate<BlockingState>() {
@Override
public boolean apply(final BlockingState input) {
return svcsFilter.contains(input.getService());
}
}) : filteredByTypes;
final LocalDate localDateNowInAccountTimezone = new LocalDate(clock.getUTCNow(), account.getTimeZone());
final List<BlockingState> result = new ArrayList<BlockingState>();
for (final BlockingState cur : filteredByTypesAndSvcs) {
final LocalDate eventDate = new LocalDate(cur.getEffectiveDate(), account.getTimeZone());
final int comp = eventDate.compareTo(localDateNowInAccountTimezone);
if ((comp <= 1 && ((timeFilter & SubscriptionApi.PAST_EVENTS) == SubscriptionApi.PAST_EVENTS)) || (comp == 0 && ((timeFilter & SubscriptionApi.PRESENT_EVENTS) == SubscriptionApi.PRESENT_EVENTS)) || (comp >= 1 && ((timeFilter & SubscriptionApi.FUTURE_EVENTS) == SubscriptionApi.FUTURE_EVENTS))) {
result.add(cur);
}
}
return orderingType == OrderingType.ASCENDING ? result : Lists.reverse(result);
} catch (AccountApiException e) {
throw new EntitlementApiException(e);
}
}
use of org.killbill.billing.callcontext.InternalTenantContext in project killbill by killbill.
the class DefaultInvoiceDao method transferChildCreditToParent.
@Override
public void transferChildCreditToParent(final Account childAccount, final InternalCallContext childAccountContext) throws InvoiceApiException {
// Need to create an internalCallContext for parent account because it's needed to save the correct accountRecordId in Invoice tables.
// Then it's used to load invoices by account.
final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(childAccount.getParentAccountId(), childAccountContext);
final InternalCallContext parentAccountContext = internalCallContextFactory.createInternalCallContext(internalTenantContext.getAccountRecordId(), childAccountContext);
final List<Tag> parentInvoicesTags = getInvoicesTags(parentAccountContext);
final List<Tag> childInvoicesTags = getInvoicesTags(childAccountContext);
transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
@Override
public Void inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
final InvoiceSqlDao invoiceSqlDao = entitySqlDaoWrapperFactory.become(InvoiceSqlDao.class);
final InvoiceItemSqlDao transInvoiceItemSqlDao = entitySqlDaoWrapperFactory.become(InvoiceItemSqlDao.class);
// create child and parent invoices
final DateTime childCreatedDate = childAccountContext.getCreatedDate();
final BigDecimal accountCBA = getAccountCBA(childAccount.getId(), childAccountContext);
// create external charge to child account
final LocalDate childInvoiceDate = childAccountContext.toLocalDate(childAccountContext.getCreatedDate());
final Invoice invoiceForExternalCharge = new DefaultInvoice(childAccount.getId(), childInvoiceDate, childCreatedDate.toLocalDate(), childAccount.getCurrency(), InvoiceStatus.COMMITTED);
final String chargeDescription = "Charge to move credit from child to parent account";
final InvoiceItem externalChargeItem = new ExternalChargeInvoiceItem(UUIDs.randomUUID(), childCreatedDate, invoiceForExternalCharge.getId(), childAccount.getId(), null, chargeDescription, childCreatedDate.toLocalDate(), accountCBA, childAccount.getCurrency());
invoiceForExternalCharge.addInvoiceItem(externalChargeItem);
// create credit to parent account
final LocalDate parentInvoiceDate = parentAccountContext.toLocalDate(parentAccountContext.getCreatedDate());
final Invoice invoiceForCredit = new DefaultInvoice(childAccount.getParentAccountId(), parentInvoiceDate, childCreatedDate.toLocalDate(), childAccount.getCurrency(), InvoiceStatus.COMMITTED);
final String creditDescription = "Credit migrated from child account " + childAccount.getId();
final InvoiceItem creditItem = new CreditAdjInvoiceItem(UUIDs.randomUUID(), childCreatedDate, invoiceForCredit.getId(), childAccount.getParentAccountId(), childCreatedDate.toLocalDate(), creditDescription, // Note! The amount is negated here!
accountCBA.negate(), childAccount.getCurrency());
invoiceForCredit.addInvoiceItem(creditItem);
// save invoices and invoice items
final InvoiceModelDao childInvoice = new InvoiceModelDao(invoiceForExternalCharge);
invoiceSqlDao.create(childInvoice, childAccountContext);
final InvoiceItemModelDao childExternalChargeItem = new InvoiceItemModelDao(externalChargeItem);
createInvoiceItemFromTransaction(transInvoiceItemSqlDao, childExternalChargeItem, childAccountContext);
// Keep invoice up-to-date for CBA below
childInvoice.addInvoiceItem(childExternalChargeItem);
final InvoiceModelDao parentInvoice = new InvoiceModelDao(invoiceForCredit);
invoiceSqlDao.create(parentInvoice, parentAccountContext);
final InvoiceItemModelDao parentCreditItem = new InvoiceItemModelDao(creditItem);
createInvoiceItemFromTransaction(transInvoiceItemSqlDao, parentCreditItem, parentAccountContext);
// Keep invoice up-to-date for CBA below
parentInvoice.addInvoiceItem(parentCreditItem);
// add CBA complexity and notify bus on child invoice creation
cbaDao.doCBAComplexityFromTransaction(childInvoice, childInvoicesTags, entitySqlDaoWrapperFactory, childAccountContext);
notifyBusOfInvoiceCreation(entitySqlDaoWrapperFactory, childInvoice, childAccountContext);
cbaDao.doCBAComplexityFromTransaction(parentInvoice, parentInvoicesTags, entitySqlDaoWrapperFactory, parentAccountContext);
notifyBusOfInvoiceCreation(entitySqlDaoWrapperFactory, parentInvoice, parentAccountContext);
return null;
}
});
}
use of org.killbill.billing.callcontext.InternalTenantContext in project killbill by killbill.
the class InvoiceDaoHelper method setParentInvoice.
private void setParentInvoice(final Iterable<InvoiceModelDao> childInvoices, final List<Tag> invoicesTags, final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory, final InternalTenantContext childContext) {
final Collection<String> childInvoiceIds = new HashSet<String>();
for (final InvoiceModelDao childInvoice : childInvoices) {
childInvoiceIds.add(childInvoice.getId().toString());
}
// DAO: retrieve the mappings between parent and child invoices
final InvoiceParentChildrenSqlDao invoiceParentChildrenSqlDao = entitySqlDaoWrapperFactory.become(InvoiceParentChildrenSqlDao.class);
final List<InvoiceParentChildModelDao> mappings = invoiceParentChildrenSqlDao.getParentChildMappingsByChildInvoiceIds(childInvoiceIds, childContext);
if (mappings.isEmpty()) {
return;
}
final Map<UUID, InvoiceParentChildModelDao> mappingPerChildInvoiceId = new HashMap<UUID, InvoiceParentChildModelDao>();
final Collection<String> parentInvoiceIdsAsStrings = new HashSet<String>();
for (final InvoiceParentChildModelDao mapping : mappings) {
mappingPerChildInvoiceId.put(mapping.getChildInvoiceId(), mapping);
parentInvoiceIdsAsStrings.add(mapping.getParentInvoiceId().toString());
}
// DAO: retrieve all parents invoices in bulk, for all child invoices
final InvoiceSqlDao invoiceSqlDao = entitySqlDaoWrapperFactory.become(InvoiceSqlDao.class);
final List<InvoiceModelDao> parentInvoices = invoiceSqlDao.getByIds(parentInvoiceIdsAsStrings, childContext);
// Group the parent invoices by (parent) account id (most likely, we only have one parent account group, except in re-parenting cases)
final Map<UUID, List<InvoiceModelDao>> parentInvoicesGroupedByParentAccountId = new HashMap<UUID, List<InvoiceModelDao>>();
// Create also a convenient mapping (needed below later)
final Map<UUID, InvoiceModelDao> parentInvoiceByParentInvoiceId = new HashMap<UUID, InvoiceModelDao>();
for (final InvoiceModelDao parentInvoice : parentInvoices) {
if (parentInvoicesGroupedByParentAccountId.get(parentInvoice.getAccountId()) == null) {
parentInvoicesGroupedByParentAccountId.put(parentInvoice.getAccountId(), new LinkedList<InvoiceModelDao>());
}
parentInvoicesGroupedByParentAccountId.get(parentInvoice.getAccountId()).add(parentInvoice);
parentInvoiceByParentInvoiceId.put(parentInvoice.getId(), parentInvoice);
}
// DAO: populate the parent invoices in bulk
for (final UUID parentAccountId : parentInvoicesGroupedByParentAccountId.keySet()) {
final List<InvoiceModelDao> parentInvoicesForOneParentAccountId = parentInvoicesGroupedByParentAccountId.get(parentAccountId);
final Long parentAccountRecordId = internalCallContextFactory.getRecordIdFromObject(parentAccountId, ObjectType.ACCOUNT, internalCallContextFactory.createTenantContext(childContext));
final InternalTenantContext parentContext = internalCallContextFactory.createInternalTenantContext(childContext.getTenantRecordId(), parentAccountRecordId);
// Note the misnomer here, populateChildren simply populates the content of these invoices (unrelated to HA)
populateChildren(parentInvoicesForOneParentAccountId, invoicesTags, entitySqlDaoWrapperFactory, parentContext);
}
for (final InvoiceModelDao invoice : childInvoices) {
final InvoiceParentChildModelDao mapping = mappingPerChildInvoiceId.get(invoice.getId());
if (mapping == null) {
continue;
}
final InvoiceModelDao parentInvoice = parentInvoiceByParentInvoiceId.get(mapping.getParentInvoiceId());
if (parentInvoice != null) {
invoice.addParentInvoice(parentInvoice);
}
}
}
use of org.killbill.billing.callcontext.InternalTenantContext in project killbill by killbill.
the class EmailInvoiceNotifier method notify.
@Override
public void notify(final Account account, final Invoice invoice, final TenantContext context) throws InvoiceApiException {
if (Strings.emptyToNull(account.getEmail()) == null) {
throw new InvoiceApiException(new IllegalArgumentException("Email for account " + account.getId() + " not specified"), ErrorCode.EMAIL_SENDING_FAILED);
}
final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(account.getId(), context);
final List<String> to = new ArrayList<String>();
to.add(account.getEmail());
final List<AccountEmail> accountEmailList = accountApi.getEmails(account.getId(), internalTenantContext);
final List<String> cc = new ArrayList<String>();
for (final AccountEmail email : accountEmailList) {
cc.add(email.getEmail());
}
// Check if this account has the MANUAL_PAY system tag
boolean manualPay = false;
final List<Tag> accountTags = tagUserApi.getTags(account.getId(), ObjectType.ACCOUNT, internalTenantContext);
for (final Tag tag : accountTags) {
if (ControlTagType.MANUAL_PAY.getId().equals(tag.getTagDefinitionId())) {
manualPay = true;
break;
}
}
final HtmlInvoice htmlInvoice;
try {
htmlInvoice = generator.generateInvoice(account, invoice, manualPay, internalTenantContext);
} catch (final IOException e) {
throw new InvoiceApiException(e, ErrorCode.EMAIL_SENDING_FAILED);
}
// take localized subject, or the configured one if the localized one is not available
String subject = htmlInvoice.getSubject();
if (subject == null) {
subject = config.getInvoiceEmailSubject();
}
final EmailSender sender = new DefaultEmailSender(config);
try {
sender.sendHTMLEmail(to, cc, subject, htmlInvoice.getBody());
} catch (final EmailApiException e) {
throw new InvoiceApiException(e, ErrorCode.EMAIL_SENDING_FAILED);
} catch (final IOException e) {
throw new InvoiceApiException(e, ErrorCode.EMAIL_SENDING_FAILED);
}
}
Aggregations