use of org.killbill.billing.subscription.api.user.DefaultSubscriptionBaseBundle in project killbill by killbill.
the class SubscriptionApiBase method createBundleForAccount.
protected SubscriptionBaseBundle createBundleForAccount(final UUID accountId, final String bundleKey, final boolean renameCancelledBundleIfExist, final SubscriptionCatalog catalog, final CacheController<UUID, UUID> accountIdCacheController, final InternalCallContext context) throws SubscriptionBaseApiException {
final DateTime now = context.getCreatedDate();
final DefaultSubscriptionBaseBundle bundle = new DefaultSubscriptionBaseBundle(bundleKey, accountId, now, now, now, now);
if (null != bundleKey && bundleKey.length() > 255) {
throw new SubscriptionBaseApiException(ErrorCode.EXTERNAL_KEY_LIMIT_EXCEEDED);
}
final SubscriptionBaseBundle subscriptionBundle = dao.createSubscriptionBundle(bundle, catalog, renameCancelledBundleIfExist, context);
accountIdCacheController.putIfAbsent(bundle.getId(), accountId);
return subscriptionBundle;
}
use of org.killbill.billing.subscription.api.user.DefaultSubscriptionBaseBundle in project killbill by killbill.
the class DefaultSubscriptionInternalApi method createBundleForAccount.
@VisibleForTesting
@Override
public SubscriptionBaseBundle createBundleForAccount(final UUID accountId, final String bundleKey, final boolean renameCancelledBundleIfExist, final InternalCallContext context) throws SubscriptionBaseApiException {
final DateTime now = context.getCreatedDate();
final DefaultSubscriptionBaseBundle bundle = new DefaultSubscriptionBaseBundle(bundleKey, accountId, now, now, now, now);
if (null != bundleKey && bundleKey.length() > 255) {
throw new SubscriptionBaseApiException(ErrorCode.EXTERNAL_KEY_LIMIT_EXCEEDED);
}
try {
final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(context);
return super.createBundleForAccount(accountId, bundleKey, renameCancelledBundleIfExist, catalog, accountIdCacheController, context);
} catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
}
use of org.killbill.billing.subscription.api.user.DefaultSubscriptionBaseBundle in project killbill by killbill.
the class DefaultSubscriptionBaseTransferApi method transferBundle.
@Override
public SubscriptionBaseBundle transferBundle(final UUID sourceAccountId, final UUID destAccountId, final String bundleKey, final DateTime transferDate, final boolean transferAddOn, final boolean cancelImmediately, final CallContext context) throws SubscriptionBaseTransferApiException {
final InternalCallContext fromInternalCallContext = internalCallContextFactory.createInternalCallContext(sourceAccountId, context);
final InternalCallContext toInternalCallContext = internalCallContextFactory.createInternalCallContext(destAccountId, context);
try {
final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(fromInternalCallContext);
final DateTime effectiveTransferDate = transferDate == null ? context.getCreatedDate() : transferDate;
if (effectiveTransferDate.isAfter(context.getCreatedDate())) {
// (subscription always expects the first event to be in the past)
throw new SubscriptionBaseTransferApiException(ErrorCode.SUB_TRANSFER_INVALID_EFF_DATE, effectiveTransferDate);
}
final SubscriptionBaseBundle bundle = subscriptionBaseInternalApi.getActiveBundleForKey(catalog.getCatalog(), bundleKey, fromInternalCallContext);
if (bundle == null) {
throw new SubscriptionBaseTransferApiException(ErrorCode.SUB_CREATE_NO_BUNDLE, bundleKey);
}
// Get the bundle timeline for the old account
final BundleBaseTimeline bundleBaseTimeline = timelineApi.getBundleTimeline(bundle, context);
final DefaultSubscriptionBaseBundle subscriptionBundleData = new DefaultSubscriptionBaseBundle(bundleKey, destAccountId, effectiveTransferDate, bundle.getOriginalCreatedDate(), context.getCreatedDate(), context.getCreatedDate());
final List<SubscriptionTransferData> subscriptionTransferDataList = new LinkedList<SubscriptionTransferData>();
final List<TransferCancelData> transferCancelDataList = new LinkedList<TransferCancelData>();
DateTime bundleStartdate = null;
for (final SubscriptionBaseTimeline cur : bundleBaseTimeline.getSubscriptions()) {
final DefaultSubscriptionBase oldSubscription = (DefaultSubscriptionBase) dao.getSubscriptionFromId(cur.getId(), catalog, fromInternalCallContext);
// Skip already cancelled subscriptions
if (oldSubscription.getState() == EntitlementState.CANCELLED) {
continue;
}
final List<ExistingEvent> existingEvents = cur.getExistingEvents();
final ProductCategory productCategory = existingEvents.get(0).getProductCategory();
// on base plan cancellations, even though we don't support un-transfer today)
if (productCategory != ProductCategory.ADD_ON || cancelImmediately) {
// Create the cancelWithRequestedDate event on effectiveCancelDate
final DateTime effectiveCancelDate = !cancelImmediately && oldSubscription.getChargedThroughDate() != null && effectiveTransferDate.isBefore(oldSubscription.getChargedThroughDate()) ? oldSubscription.getChargedThroughDate() : effectiveTransferDate;
final SubscriptionBaseEvent cancelEvent = new ApiEventCancel(new ApiEventBuilder().setSubscriptionId(cur.getId()).setEffectiveDate(effectiveCancelDate).setFromDisk(true));
final TransferCancelData cancelData = new TransferCancelData(oldSubscription, cancelEvent);
transferCancelDataList.add(cancelData);
}
if (productCategory == ProductCategory.ADD_ON && !transferAddOn) {
continue;
}
// We Align with the original subscription
final DateTime subscriptionAlignStartDate = oldSubscription.getAlignStartDate();
if (bundleStartdate == null) {
bundleStartdate = oldSubscription.getStartDate();
}
// Create the new subscription for the new bundle on the new account
final DefaultSubscriptionBase defaultSubscriptionBase = createSubscriptionForApiUse(new SubscriptionBuilder().setId(UUIDs.randomUUID()).setBundleId(subscriptionBundleData.getId()).setBundleExternalKey(subscriptionBundleData.getExternalKey()).setCategory(productCategory).setBundleStartDate(effectiveTransferDate).setAlignStartDate(subscriptionAlignStartDate), ImmutableList.<SubscriptionBaseEvent>of(), catalog, fromInternalCallContext);
final List<SubscriptionBaseEvent> events = toEvents(existingEvents, defaultSubscriptionBase, effectiveTransferDate, fromInternalCallContext);
final SubscriptionTransferData curData = new SubscriptionTransferData(defaultSubscriptionBase, events, null);
subscriptionTransferDataList.add(curData);
}
final BundleTransferData bundleTransferData = new BundleTransferData(subscriptionBundleData, subscriptionTransferDataList);
// Atomically cancelWithRequestedDate all subscription on old account and create new bundle, subscriptions, events for new account
dao.transfer(sourceAccountId, destAccountId, bundleTransferData, transferCancelDataList, catalog, fromInternalCallContext, toInternalCallContext);
return bundleTransferData.getData();
} catch (SubscriptionBaseRepairException e) {
throw new SubscriptionBaseTransferApiException(e);
} catch (CatalogApiException e) {
throw new SubscriptionBaseTransferApiException(e);
}
}
use of org.killbill.billing.subscription.api.user.DefaultSubscriptionBaseBundle in project killbill by killbill.
the class TestSubscriptionDao method testWithAuditAndHistory.
@Test(groups = "slow")
public void testWithAuditAndHistory() throws SubscriptionBaseApiException {
final String bundleExternalKey = "54341455sttfs1";
final DateTime startDate = clock.getUTCNow();
final DefaultSubscriptionBaseBundle bundleDef = new DefaultSubscriptionBaseBundle(bundleExternalKey, accountId, startDate, startDate, startDate, startDate);
final SubscriptionBaseBundle bundle = dao.createSubscriptionBundle(bundleDef, catalog, true, internalCallContext);
final List<AuditLogWithHistory> bundleHistory1 = dao.getSubscriptionBundleAuditLogsWithHistoryForId(bundle.getId(), AuditLevel.FULL, internalCallContext);
assertEquals(bundleHistory1.size(), 1);
final AuditLogWithHistory bundleHistoryRow1 = bundleHistory1.get(0);
assertEquals(bundleHistoryRow1.getChangeType(), ChangeType.INSERT);
final SubscriptionBundleModelDao historyRow1 = (SubscriptionBundleModelDao) bundleHistoryRow1.getEntity();
assertEquals(historyRow1.getExternalKey(), bundle.getExternalKey());
assertEquals(historyRow1.getAccountId(), bundle.getAccountId());
dao.updateBundleExternalKey(bundle.getId(), "you changed me!", internalCallContext);
final List<AuditLogWithHistory> bundleHistory2 = dao.getSubscriptionBundleAuditLogsWithHistoryForId(bundle.getId(), AuditLevel.FULL, internalCallContext);
assertEquals(bundleHistory2.size(), 2);
final AuditLogWithHistory bundleHistoryRow2 = bundleHistory2.get(1);
assertEquals(bundleHistoryRow2.getChangeType(), ChangeType.UPDATE);
final SubscriptionBundleModelDao historyRow2 = (SubscriptionBundleModelDao) bundleHistoryRow2.getEntity();
assertEquals(historyRow2.getExternalKey(), "you changed me!");
assertEquals(historyRow2.getAccountId(), bundle.getAccountId());
final SubscriptionBuilder builder = new SubscriptionBuilder().setId(UUIDs.randomUUID()).setBundleId(bundle.getId()).setBundleExternalKey(bundle.getExternalKey()).setCategory(ProductCategory.BASE).setBundleStartDate(startDate).setAlignStartDate(startDate).setMigrated(false);
final ApiEventBuilder createBuilder = new ApiEventBuilder().setSubscriptionId(builder.getId()).setEventPlan("shotgun-monthly").setEventPlanPhase("shotgun-monthly-trial").setEventPriceList(DefaultPriceListSet.DEFAULT_PRICELIST_NAME).setEffectiveDate(startDate).setFromDisk(true);
final SubscriptionBaseEvent creationEvent = new ApiEventCreate(createBuilder);
final DefaultSubscriptionBase subscription = new DefaultSubscriptionBase(builder);
testListener.pushExpectedEvents(NextEvent.CREATE);
final SubscriptionBaseWithAddOns subscriptionBaseWithAddOns = new DefaultSubscriptionBaseWithAddOns(bundle, ImmutableList.<SubscriptionBase>of(subscription));
final List<SubscriptionBaseEvent> resultSubscriptions = dao.createSubscriptionsWithAddOns(ImmutableList.<SubscriptionBaseWithAddOns>of(subscriptionBaseWithAddOns), ImmutableMap.<UUID, List<SubscriptionBaseEvent>>of(subscription.getId(), ImmutableList.<SubscriptionBaseEvent>of(creationEvent)), catalog, internalCallContext);
assertListenerStatus();
assertEquals(resultSubscriptions.size(), 1);
final SubscriptionBaseEvent subscriptionBaseEvent = resultSubscriptions.get(0);
final List<AuditLogWithHistory> subscriptionHistory = dao.getSubscriptionAuditLogsWithHistoryForId(subscriptionBaseEvent.getSubscriptionId(), AuditLevel.FULL, internalCallContext);
assertEquals(subscriptionHistory.size(), 1);
final AuditLogWithHistory subscriptionHistoryRow1 = subscriptionHistory.get(0);
assertEquals(subscriptionHistoryRow1.getChangeType(), ChangeType.INSERT);
final SubscriptionModelDao subHistoryRow1 = (SubscriptionModelDao) subscriptionHistoryRow1.getEntity();
assertEquals(subHistoryRow1.getBundleId(), bundle.getId());
assertEquals(subHistoryRow1.getCategory(), ProductCategory.BASE);
final List<AuditLogWithHistory> subscriptionEventHistory = dao.getSubscriptionEventAuditLogsWithHistoryForId(subscriptionBaseEvent.getId(), AuditLevel.FULL, internalCallContext);
final AuditLogWithHistory subscriptionEventHistoryRow1 = subscriptionEventHistory.get(0);
assertEquals(subscriptionEventHistoryRow1.getChangeType(), ChangeType.INSERT);
final SubscriptionEventModelDao subEventHistoryRow1 = (SubscriptionEventModelDao) subscriptionEventHistoryRow1.getEntity();
assertEquals(subEventHistoryRow1.getSubscriptionId(), subscriptionBaseEvent.getSubscriptionId());
assertEquals(subEventHistoryRow1.getEventType(), EventType.API_USER);
assertEquals(subEventHistoryRow1.getUserType(), ApiEventType.CREATE);
assertEquals(subEventHistoryRow1.getPlanName(), "shotgun-monthly");
assertEquals(subEventHistoryRow1.getIsActive(), true);
}
use of org.killbill.billing.subscription.api.user.DefaultSubscriptionBaseBundle in project killbill by killbill.
the class TestSubscriptionDao method testBundleExternalKeyTransferred.
@Test(groups = "slow")
public void testBundleExternalKeyTransferred() throws Exception {
final String externalKey = "2534125sdfsd";
final DateTime startDate = clock.getUTCNow();
final DateTime createdDate = startDate.plusSeconds(10);
final DefaultSubscriptionBaseBundle bundleDef = new DefaultSubscriptionBaseBundle(externalKey, accountId, startDate, startDate, createdDate, createdDate);
final SubscriptionBaseBundle bundle = dao.createSubscriptionBundle(bundleDef, catalog, true, internalCallContext);
final List<SubscriptionBaseBundle> result = dao.getSubscriptionBundlesForKey(externalKey, internalCallContext);
assertEquals(result.size(), 1);
assertEquals(result.get(0).getExternalKey(), bundle.getExternalKey());
final List<AuditLog> auditLogsBeforeRenaming = auditUserApi.getAuditLogs(bundle.getId(), ObjectType.BUNDLE, AuditLevel.FULL, callContext);
assertEquals(auditLogsBeforeRenaming.size(), 1);
assertEquals(auditLogsBeforeRenaming.get(0).getChangeType(), ChangeType.INSERT);
// Update key to 'internal KB value 'kbtsf-12345:'
dao.updateBundleExternalKey(bundle.getId(), "kbtsf-12345:" + bundle.getExternalKey(), internalCallContext);
final List<SubscriptionBaseBundle> result2 = dao.getSubscriptionBundlesForKey(externalKey, internalCallContext);
assertEquals(result2.size(), 1);
final List<AuditLog> auditLogsAfterRenaming = auditUserApi.getAuditLogs(bundle.getId(), ObjectType.BUNDLE, AuditLevel.FULL, callContext);
assertEquals(auditLogsAfterRenaming.size(), 2);
assertEquals(auditLogsAfterRenaming.get(0).getChangeType(), ChangeType.INSERT);
assertEquals(auditLogsAfterRenaming.get(1).getChangeType(), ChangeType.UPDATE);
// Create new bundle with original key, verify all results show original key, stripping down internal prefix
final DefaultSubscriptionBaseBundle bundleDef2 = new DefaultSubscriptionBaseBundle(externalKey, accountId, startDate, startDate, createdDate, createdDate);
final SubscriptionBaseBundle bundle2 = dao.createSubscriptionBundle(bundleDef2, catalog, true, internalCallContext);
final List<SubscriptionBaseBundle> result3 = dao.getSubscriptionBundlesForKey(externalKey, internalCallContext);
assertEquals(result3.size(), 2);
assertEquals(result3.get(0).getId(), bundle.getId());
assertEquals(result3.get(0).getExternalKey(), bundle2.getExternalKey());
assertEquals(result3.get(1).getId(), bundle2.getId());
assertEquals(result3.get(1).getExternalKey(), bundle2.getExternalKey());
final List<AuditLog> auditLogs2BeforeRenaming = auditUserApi.getAuditLogs(bundle2.getId(), ObjectType.BUNDLE, AuditLevel.FULL, callContext);
assertEquals(auditLogs2BeforeRenaming.size(), 1);
assertEquals(auditLogs2BeforeRenaming.get(0).getChangeType(), ChangeType.INSERT);
// This time we call the lower SqlDao to rename the bundle automatically and verify we still get same # results,
// with original key
transactionalSqlDao.execute(false, new EntitySqlDaoTransactionWrapper<Void>() {
@Override
public Void inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
entitySqlDaoWrapperFactory.become(BundleSqlDao.class).renameBundleExternalKey(ImmutableList.<String>of(bundle2.getId().toString()), "foo", internalCallContext);
return null;
}
});
final List<SubscriptionBaseBundle> result4 = dao.getSubscriptionBundlesForKey(externalKey, internalCallContext);
assertEquals(result4.size(), 2);
assertEquals(result4.get(0).getExternalKey(), bundle2.getExternalKey());
assertEquals(result4.get(0).getId(), bundle.getId());
assertEquals(result4.get(1).getExternalKey(), bundle2.getExternalKey());
assertEquals(result4.get(1).getId(), bundle2.getId());
final List<AuditLog> auditLogs2AfterRenaming = auditUserApi.getAuditLogs(bundle2.getId(), ObjectType.BUNDLE, AuditLevel.FULL, callContext);
assertEquals(auditLogs2AfterRenaming.size(), 2);
assertEquals(auditLogs2AfterRenaming.get(0).getChangeType(), ChangeType.INSERT);
assertEquals(auditLogs2AfterRenaming.get(1).getChangeType(), ChangeType.UPDATE);
// Create bundle one more time
final DefaultSubscriptionBaseBundle bundleDef3 = new DefaultSubscriptionBaseBundle(externalKey, accountId, startDate, startDate, createdDate, createdDate);
final SubscriptionBaseBundle bundle3 = dao.createSubscriptionBundle(bundleDef3, catalog, true, internalCallContext);
final List<SubscriptionBaseBundle> result5 = dao.getSubscriptionBundlesForKey(externalKey, internalCallContext);
assertEquals(result5.size(), 3);
assertEquals(result5.get(0).getExternalKey(), bundle2.getExternalKey());
assertEquals(result5.get(1).getExternalKey(), bundle2.getExternalKey());
assertEquals(result5.get(2).getExternalKey(), bundle2.getExternalKey());
}
Aggregations