use of org.killbill.billing.util.tag.Tag in project killbill by killbill.
the class DefaultInternalBillingApi method addBillingEventsForBundles.
private void addBillingEventsForBundles(final List<SubscriptionBaseBundle> bundles, final ImmutableAccountData account, final DryRunArguments dryRunArguments, final InternalCallContext context, final DefaultBillingEventSet result, final Set<UUID> skipSubscriptionsSet) throws AccountApiException, CatalogApiException, SubscriptionBaseApiException {
final boolean dryRunMode = dryRunArguments != null;
// want to tap into subscriptionBase logic, so we make up a bundleId
if (dryRunArguments != null && dryRunArguments.getAction() == SubscriptionEventType.START_BILLING && dryRunArguments.getBundleId() == null) {
final UUID fakeBundleId = UUIDs.randomUUID();
final List<SubscriptionBase> subscriptions = subscriptionApi.getSubscriptionsForBundle(fakeBundleId, dryRunArguments, context);
addBillingEventsForSubscription(account, subscriptions, null, dryRunMode, context, result, skipSubscriptionsSet);
}
for (final SubscriptionBaseBundle bundle : bundles) {
final DryRunArguments dryRunArgumentsForBundle = (dryRunArguments != null && dryRunArguments.getBundleId() != null && dryRunArguments.getBundleId().equals(bundle.getId())) ? dryRunArguments : null;
final List<SubscriptionBase> subscriptions = subscriptionApi.getSubscriptionsForBundle(bundle.getId(), dryRunArgumentsForBundle, context);
//Check if billing is off for the bundle
final List<Tag> bundleTags = tagApi.getTags(bundle.getId(), ObjectType.BUNDLE, context);
boolean found_AUTO_INVOICING_OFF = is_AUTO_INVOICING_OFF(bundleTags);
if (found_AUTO_INVOICING_OFF) {
for (final SubscriptionBase subscription : subscriptions) {
// billing is off so list sub ids in set to be excluded
result.getSubscriptionIdsWithAutoInvoiceOff().add(subscription.getId());
}
} else {
// billing is not off
final SubscriptionBase baseSubscription = !subscriptions.isEmpty() ? subscriptions.get(0) : null;
addBillingEventsForSubscription(account, subscriptions, baseSubscription, dryRunMode, context, result, skipSubscriptionsSet);
}
}
}
use of org.killbill.billing.util.tag.Tag in project killbill by killbill.
the class OverdueStateApplicator method isAccountTaggedWith_OVERDUE_ENFORCEMENT_OFF.
//
// Uses callcontext information to retrieve account matching the Overduable object and check whether we should do any overdue processing
//
private boolean isAccountTaggedWith_OVERDUE_ENFORCEMENT_OFF(final InternalCallContext context) throws OverdueException {
try {
final UUID accountId = accountApi.getByRecordId(context.getAccountRecordId(), context);
final List<Tag> accountTags = tagApi.getTags(accountId, ObjectType.ACCOUNT, context);
for (final Tag cur : accountTags) {
if (cur.getTagDefinitionId().equals(ControlTagType.OVERDUE_ENFORCEMENT_OFF.getId())) {
return true;
}
}
return false;
} catch (final AccountApiException e) {
throw new OverdueException(e);
}
}
use of org.killbill.billing.util.tag.Tag 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.util.tag.Tag in project killbill by killbill.
the class DefaultInvoiceDao method changeInvoiceStatus.
@Override
public void changeInvoiceStatus(final UUID invoiceId, final InvoiceStatus newStatus, final InternalCallContext context) throws InvoiceApiException {
final List<Tag> invoicesTags = getInvoicesTags(context);
transactionalSqlDao.execute(InvoiceApiException.class, new EntitySqlDaoTransactionWrapper<Void>() {
@Override
public Void inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
final InvoiceSqlDao transactional = entitySqlDaoWrapperFactory.become(InvoiceSqlDao.class);
// Retrieve the invoice and make sure it belongs to the right account
final InvoiceModelDao invoice = transactional.getById(invoiceId.toString(), context);
if (invoice == null) {
throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND, invoiceId);
}
if (invoice.getStatus().equals(newStatus)) {
throw new InvoiceApiException(ErrorCode.INVOICE_INVALID_STATUS, newStatus, invoiceId, invoice.getStatus());
}
transactional.updateStatus(invoiceId.toString(), newStatus.toString(), context);
cbaDao.doCBAComplexityFromTransaction(invoicesTags, entitySqlDaoWrapperFactory, context);
if (InvoiceStatus.COMMITTED.equals(newStatus)) {
// notify invoice creation event
notifyBusOfInvoiceCreation(entitySqlDaoWrapperFactory, invoice, context);
}
return null;
}
});
}
use of org.killbill.billing.util.tag.Tag in project killbill by killbill.
the class DefaultInvoiceDao method createInvoices.
private List<InvoiceItemModelDao> createInvoices(final Iterable<InvoiceModelDao> invoices, final FutureAccountNotifications callbackDateTimePerSubscriptions, final InternalCallContext context) {
final Collection<UUID> createdInvoiceIds = new HashSet<UUID>();
final Collection<UUID> adjustedInvoiceIds = new HashSet<UUID>();
final Collection<UUID> committedInvoiceIds = new HashSet<UUID>();
final Collection<UUID> uniqueInvoiceIds = new HashSet<UUID>();
for (final InvoiceModelDao invoiceModelDao : invoices) {
for (final InvoiceItemModelDao invoiceItemModelDao : invoiceModelDao.getInvoiceItems()) {
uniqueInvoiceIds.add(invoiceItemModelDao.getInvoiceId());
}
}
if (Iterables.<InvoiceModelDao>isEmpty(invoices)) {
return ImmutableList.<InvoiceItemModelDao>of();
}
final UUID accountId = invoices.iterator().next().getAccountId();
final List<Tag> invoicesTags = getInvoicesTags(context);
final Map<UUID, InvoiceModelDao> invoiceByInvoiceId = new HashMap<UUID, InvoiceModelDao>();
return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<List<InvoiceItemModelDao>>() {
@Override
public List<InvoiceItemModelDao> inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
final InvoiceSqlDao invoiceSqlDao = entitySqlDaoWrapperFactory.become(InvoiceSqlDao.class);
final InvoiceItemSqlDao transInvoiceItemSqlDao = entitySqlDaoWrapperFactory.become(InvoiceItemSqlDao.class);
final List<InvoiceItemModelDao> createdInvoiceItems = new LinkedList<InvoiceItemModelDao>();
for (final InvoiceModelDao invoiceModelDao : invoices) {
invoiceByInvoiceId.put(invoiceModelDao.getId(), invoiceModelDao);
final boolean isRealInvoice = uniqueInvoiceIds.remove(invoiceModelDao.getId());
// Create the invoice if needed
if (invoiceSqlDao.getById(invoiceModelDao.getId().toString(), context) == null) {
// a shell invoice and we only need to insert the invoiceItems -- for the already existing invoices
if (isRealInvoice) {
invoiceSqlDao.create(invoiceModelDao, context);
createdInvoiceIds.add(invoiceModelDao.getId());
}
}
// Create the invoice items if needed (note: they may not necessarily belong to that invoice)
for (final InvoiceItemModelDao invoiceItemModelDao : invoiceModelDao.getInvoiceItems()) {
if (transInvoiceItemSqlDao.getById(invoiceItemModelDao.getId().toString(), context) == null) {
createInvoiceItemFromTransaction(transInvoiceItemSqlDao, invoiceItemModelDao, context);
createdInvoiceItems.add(transInvoiceItemSqlDao.getById(invoiceItemModelDao.getId().toString(), context));
adjustedInvoiceIds.add(invoiceItemModelDao.getInvoiceId());
}
}
final boolean wasInvoiceCreated = createdInvoiceIds.contains(invoiceModelDao.getId());
if (InvoiceStatus.COMMITTED.equals(invoiceModelDao.getStatus())) {
committedInvoiceIds.add(invoiceModelDao.getId());
notifyOfFutureBillingEvents(entitySqlDaoWrapperFactory, invoiceModelDao.getAccountId(), callbackDateTimePerSubscriptions, context);
if (wasInvoiceCreated) {
notifyBusOfInvoiceCreation(entitySqlDaoWrapperFactory, invoiceModelDao, context);
}
} else if (wasInvoiceCreated && invoiceModelDao.isParentInvoice()) {
// Commit queue
notifyOfParentInvoiceCreation(entitySqlDaoWrapperFactory, invoiceModelDao, context);
}
}
for (final UUID adjustedInvoiceId : adjustedInvoiceIds) {
final boolean newInvoice = createdInvoiceIds.contains(adjustedInvoiceId);
if (newInvoice) {
// New invoice, so no associated payment yet: no need to refresh the invoice state
cbaDao.doCBAComplexityFromTransaction(invoiceByInvoiceId.get(adjustedInvoiceId), invoicesTags, entitySqlDaoWrapperFactory, context);
} else {
// Existing invoice (e.g. we're processing an adjustment): refresh the invoice state to get the correct balance
// Should we maybe enforce callers (e.g. InvoiceApiHelper) to properly populate these invoices?
cbaDao.doCBAComplexityFromTransaction(adjustedInvoiceId, invoicesTags, entitySqlDaoWrapperFactory, context);
}
if (committedInvoiceIds.contains(adjustedInvoiceId) && !newInvoice) {
// Notify the bus since the balance of the invoice changed (only if the invoice is COMMITTED)
notifyBusOfInvoiceAdjustment(entitySqlDaoWrapperFactory, adjustedInvoiceId, accountId, context.getUserToken(), context);
}
}
return createdInvoiceItems;
}
});
}
Aggregations