Search in sources :

Example 1 with Subscription

use of org.killbill.billing.entitlement.api.Subscription in project killbill by killbill.

the class SubscriptionResource method getEntitlement.

@TimedResource
@GET
@Path("/{subscriptionId:" + UUID_PATTERN + "}")
@Produces(APPLICATION_JSON)
@ApiOperation(value = "Retrieve a subscription by id", response = SubscriptionJson.class)
@ApiResponses(value = { @ApiResponse(code = 400, message = "Invalid subscription id supplied"), @ApiResponse(code = 404, message = "Subscription not found") })
public Response getEntitlement(@PathParam("subscriptionId") final String subscriptionId, @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode, @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, AccountApiException, CatalogApiException {
    final UUID uuid = UUID.fromString(subscriptionId);
    final TenantContext context = this.context.createContext(request);
    final Subscription subscription = subscriptionApi.getSubscriptionForEntitlementId(uuid, context);
    final Account account = accountUserApi.getAccountById(subscription.getAccountId(), context);
    final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(subscription.getAccountId(), auditMode.getLevel(), context);
    final SubscriptionJson json = new SubscriptionJson(subscription, account.getCurrency(), accountAuditLogs);
    return Response.status(Status.OK).entity(json).build();
}
Also used : Account(org.killbill.billing.account.api.Account) SubscriptionJson(org.killbill.billing.jaxrs.json.SubscriptionJson) TenantContext(org.killbill.billing.util.callcontext.TenantContext) UUID(java.util.UUID) Subscription(org.killbill.billing.entitlement.api.Subscription) AccountAuditLogs(org.killbill.billing.util.audit.AccountAuditLogs) Path(javax.ws.rs.Path) TimedResource(org.killbill.commons.metrics.TimedResource) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 2 with Subscription

use of org.killbill.billing.entitlement.api.Subscription in project killbill by killbill.

the class TestBundleTransfer method testBundleTransferWithAddOn.

@Test(groups = "slow", description = "Test entitlement-level transfer with add-on")
public void testBundleTransferWithAddOn() throws Exception {
    final LocalDate startDate = new LocalDate(2012, 4, 1);
    clock.setDay(startDate);
    // Share the BCD on both accounts for simplicity
    final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(1));
    final Account newAccount = createAccountWithNonOsgiPaymentMethod(getAccountData(1));
    final BillingPeriod term = BillingPeriod.MONTHLY;
    final String bpProductName = "Shotgun";
    final String aoProductName = "Telescopic-Scope";
    // Create the base plan
    final String bundleExternalKey = UUID.randomUUID().toString();
    final DefaultEntitlement bpEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), bundleExternalKey, bpProductName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
    subscriptionChecker.checkSubscriptionCreated(bpEntitlement.getId(), internalCallContext);
    final Invoice firstInvoice = invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
    // Create the add-on
    final DefaultEntitlement aoEntitlement = addAOEntitlementAndCheckForCompletion(bpEntitlement.getBundleId(), aoProductName, ProductCategory.ADD_ON, term, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    final Invoice secondInvoice = invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), new LocalDate(2012, 5, 1), InvoiceItemType.RECURRING, new BigDecimal("399.95")));
    paymentChecker.checkPayment(account.getId(), 1, callContext, new ExpectedPaymentCheck(new LocalDate(2012, 4, 1), new BigDecimal("399.95"), TransactionStatus.SUCCESS, secondInvoice.getId(), Currency.USD));
    // Move past the phase for simplicity
    busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.PHASE, NextEvent.NULL_INVOICE, NextEvent.NULL_INVOICE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addDays(30);
    assertListenerStatus();
    final Invoice thirdInvoice = invoiceChecker.checkInvoice(account.getId(), 3, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), InvoiceItemType.RECURRING, new BigDecimal("999.95")), new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
    paymentChecker.checkPayment(account.getId(), 2, callContext, new ExpectedPaymentCheck(new LocalDate(2012, 5, 1), new BigDecimal("1249.90"), TransactionStatus.SUCCESS, thirdInvoice.getId(), Currency.USD));
    // Align the transfer on the BCD to make pro-rations easier
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    // Move a bit the time to make sure notifications kick in
    clock.setTime(new DateTime(2012, 6, 1, 1, 0, DateTimeZone.UTC));
    assertListenerStatus();
    final Invoice fourthInvoice = invoiceChecker.checkInvoice(account.getId(), 4, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 1), new LocalDate(2012, 7, 1), InvoiceItemType.RECURRING, new BigDecimal("999.95")), new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 1), new LocalDate(2012, 7, 1), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
    paymentChecker.checkPayment(account.getId(), 3, callContext, new ExpectedPaymentCheck(new LocalDate(2012, 6, 1), new BigDecimal("1249.90"), TransactionStatus.SUCCESS, fourthInvoice.getId(), Currency.USD));
    final DateTime now = clock.getUTCNow();
    final LocalDate transferDay = now.toLocalDate();
    busHandler.pushExpectedEvents(NextEvent.CANCEL, NextEvent.CANCEL, NextEvent.BLOCK, NextEvent.BLOCK, NextEvent.TRANSFER, NextEvent.TRANSFER, NextEvent.BLOCK, NextEvent.BLOCK, NextEvent.NULL_INVOICE, NextEvent.NULL_INVOICE, NextEvent.INVOICE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    final UUID newBundleId = entitlementApi.transferEntitlements(account.getId(), newAccount.getId(), bundleExternalKey, transferDay, ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    // Check the last 2 invoices on the old account
    invoiceChecker.checkInvoice(account.getId(), 4, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 1), new LocalDate(2012, 7, 1), InvoiceItemType.RECURRING, new BigDecimal("999.95")), new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 1), new LocalDate(2012, 7, 1), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
    invoiceChecker.checkInvoice(account.getId(), 5, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 1), new LocalDate(2012, 7, 1), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-999.95")), new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 1), new LocalDate(2012, 7, 1), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-249.95")), new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 1), new LocalDate(2012, 6, 1), InvoiceItemType.CBA_ADJ, new BigDecimal("1249.90")));
    // Check the first invoice and payment on the new account
    final Invoice firstInvoiceNewAccount = invoiceChecker.checkInvoice(newAccount.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 1), new LocalDate(2012, 7, 1), InvoiceItemType.RECURRING, new BigDecimal("999.95")), new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 1), new LocalDate(2012, 7, 1), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
    paymentChecker.checkPayment(newAccount.getId(), 1, callContext, new ExpectedPaymentCheck(new LocalDate(2012, 6, 1), new BigDecimal("1249.90"), TransactionStatus.SUCCESS, firstInvoiceNewAccount.getId(), Currency.USD));
    // Check entitlements and subscriptions on the old account
    final List<Entitlement> oldEntitlements = entitlementApi.getAllEntitlementsForBundle(bpEntitlement.getBundleId(), callContext);
    Assert.assertEquals(oldEntitlements.size(), 2);
    for (final Entitlement entitlement : oldEntitlements) {
        final Subscription subscription = subscriptionApi.getSubscriptionForEntitlementId(entitlement.getId(), callContext);
        Assert.assertEquals(subscription.getEffectiveStartDate(), startDate);
        Assert.assertEquals(subscription.getEffectiveEndDate(), transferDay);
        Assert.assertEquals(subscription.getBillingStartDate(), startDate);
        Assert.assertEquals(subscription.getBillingEndDate(), transferDay);
    }
    // Check entitlements and subscriptions on the new account
    final List<Entitlement> newEntitlements = entitlementApi.getAllEntitlementsForBundle(newBundleId, callContext);
    Assert.assertEquals(newEntitlements.size(), 2);
    for (final Entitlement entitlement : newEntitlements) {
        final Subscription subscription = subscriptionApi.getSubscriptionForEntitlementId(entitlement.getId(), callContext);
        Assert.assertEquals(subscription.getEffectiveStartDate(), transferDay);
        Assert.assertNull(subscription.getEffectiveEndDate());
        Assert.assertEquals(subscription.getBillingStartDate(), transferDay);
        Assert.assertNull(subscription.getBillingEndDate());
    }
    checkNoMoreInvoiceToGenerate(account);
}
Also used : Account(org.killbill.billing.account.api.Account) Invoice(org.killbill.billing.invoice.api.Invoice) BillingPeriod(org.killbill.billing.catalog.api.BillingPeriod) LocalDate(org.joda.time.LocalDate) ExpectedInvoiceItemCheck(org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck) BigDecimal(java.math.BigDecimal) ExpectedPaymentCheck(org.killbill.billing.beatrix.util.PaymentChecker.ExpectedPaymentCheck) DateTime(org.joda.time.DateTime) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) UUID(java.util.UUID) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) Entitlement(org.killbill.billing.entitlement.api.Entitlement) Subscription(org.killbill.billing.entitlement.api.Subscription) Test(org.testng.annotations.Test)

Example 3 with Subscription

use of org.killbill.billing.entitlement.api.Subscription in project killbill by killbill.

the class TestOverdueWithSubscriptionEOTCancellation method testCheckSubscriptionEOTCancellation.

@Test(groups = "slow")
public void testCheckSubscriptionEOTCancellation() throws Exception {
    clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
    setupAccount();
    // Set next invoice to fail and create subscription
    paymentPlugin.makeAllInvoicesFailWithError(true);
    final DefaultEntitlement baseEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
    bundle = subscriptionApi.getSubscriptionBundle(baseEntitlement.getBundleId(), callContext);
    invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
    invoiceChecker.checkChargedThroughDate(baseEntitlement.getId(), new LocalDate(2012, 5, 1), callContext);
    final DefaultEntitlement addOn1 = addAOEntitlementAndCheckForCompletion(baseEntitlement.getBundleId(), "Holster", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
    // DAY 30 have to get out of trial before first payment
    addDaysAndCheckForCompletion(30, NextEvent.PHASE, NextEvent.PHASE, NextEvent.NULL_INVOICE, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
    invoiceChecker.checkChargedThroughDate(baseEntitlement.getId(), new LocalDate(2012, 6, 30), callContext);
    invoiceChecker.checkChargedThroughDate(addOn1.getId(), new LocalDate(2012, 6, 30), callContext);
    // Should still be in clear state
    checkODState(OverdueWrapper.CLEAR_STATE_NAME);
    // We expect one event for OD1 transition and for for each entitlement cancellation (entitlement cancellation is immediate)
    addDaysAndCheckForCompletion(6, NextEvent.BLOCK, NextEvent.BLOCK, NextEvent.BLOCK);
    // Should be in OD1
    checkODState("OD1");
    final Subscription cancelledBaseSubscription = subscriptionApi.getSubscriptionForEntitlementId(baseEntitlement.getId(), callContext);
    assertTrue(cancelledBaseSubscription.getState() == EntitlementState.CANCELLED);
    assertEquals(cancelledBaseSubscription.getEffectiveEndDate(), new LocalDate(2012, 6, 05));
    assertEquals(cancelledBaseSubscription.getBillingEndDate(), new LocalDate(2012, 6, 30));
    final Subscription cancelledAddon1 = subscriptionApi.getSubscriptionForEntitlementId(addOn1.getId(), callContext);
    assertTrue(cancelledAddon1.getState() == EntitlementState.CANCELLED);
    assertEquals(cancelledAddon1.getEffectiveEndDate(), new LocalDate(2012, 6, 05));
    assertEquals(cancelledAddon1.getBillingEndDate(), new LocalDate(2012, 6, 30));
    // Payment Retry on the 2012-6-8
    addDaysAndCheckForCompletion(2, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
    assertListenerStatus();
    // Payment Retry on the 2012-6-16
    addDaysAndCheckForCompletion(8, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
    assertListenerStatus();
    // Payment Retry on the 2012-6-24
    addDaysAndCheckForCompletion(8, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
    assertListenerStatus();
    // 2012-6-30
    addDaysAndCheckForCompletion(6, NextEvent.NULL_INVOICE, NextEvent.NULL_INVOICE, NextEvent.CANCEL, NextEvent.CANCEL);
    assertListenerStatus();
}
Also used : DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) Subscription(org.killbill.billing.entitlement.api.Subscription) ExpectedInvoiceItemCheck(org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) Test(org.testng.annotations.Test)

Example 4 with Subscription

use of org.killbill.billing.entitlement.api.Subscription in project killbill by killbill.

the class CatalogResource method getLastEventBeforeDate.

private SubscriptionEvent getLastEventBeforeDate(final UUID subscriptionId, final String requestedDateString, final HttpServletRequest request) throws SubscriptionApiException {
    final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
    final DateTime requestedDateTime = requestedDateString != null ? DATE_TIME_FORMATTER.parseDateTime(requestedDateString).toDateTime(DateTimeZone.UTC) : clock.getUTCNow();
    final LocalDate requestedDate = requestedDateTime.toLocalDate();
    final Subscription subscription = subscriptionApi.getSubscriptionForEntitlementId(subscriptionId, tenantContext);
    SubscriptionEvent lastEventBeforeRequestedDate = null;
    for (final SubscriptionEvent subscriptionEvent : subscription.getSubscriptionEvents()) {
        if (lastEventBeforeRequestedDate == null) {
            if (subscriptionEvent.getEffectiveDate().compareTo(requestedDate) > 0) {
                // requestedDate too far in the past, before subscription start date
                return null;
            }
            lastEventBeforeRequestedDate = subscriptionEvent;
        }
        if (subscriptionEvent.getEffectiveDate().compareTo(requestedDate) > 0) {
            break;
        } else {
            lastEventBeforeRequestedDate = subscriptionEvent;
        }
    }
    return lastEventBeforeRequestedDate;
}
Also used : SubscriptionEvent(org.killbill.billing.entitlement.api.SubscriptionEvent) TenantContext(org.killbill.billing.util.callcontext.TenantContext) Subscription(org.killbill.billing.entitlement.api.Subscription) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime)

Example 5 with Subscription

use of org.killbill.billing.entitlement.api.Subscription in project killbill by killbill.

the class SubscriptionResource method getSubscriptionByKey.

@TimedResource
@GET
@Produces(APPLICATION_JSON)
@ApiOperation(value = "Retrieve a subscription by external key", response = SubscriptionJson.class)
@ApiResponses(value = { @ApiResponse(code = 404, message = "Subscription not found") })
public Response getSubscriptionByKey(@ApiParam(required = true) @QueryParam(QUERY_EXTERNAL_KEY) final String externalKey, @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode, @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, AccountApiException, CatalogApiException {
    final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
    final Subscription subscription = subscriptionApi.getSubscriptionForExternalKey(externalKey, tenantContext);
    final Account account = accountUserApi.getAccountById(subscription.getAccountId(), tenantContext);
    final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(subscription.getAccountId(), auditMode.getLevel(), tenantContext);
    final SubscriptionJson json = new SubscriptionJson(subscription, account.getCurrency(), accountAuditLogs);
    return Response.status(Status.OK).entity(json).build();
}
Also used : Account(org.killbill.billing.account.api.Account) SubscriptionJson(org.killbill.billing.jaxrs.json.SubscriptionJson) TenantContext(org.killbill.billing.util.callcontext.TenantContext) Subscription(org.killbill.billing.entitlement.api.Subscription) AccountAuditLogs(org.killbill.billing.util.audit.AccountAuditLogs) TimedResource(org.killbill.commons.metrics.TimedResource) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Aggregations

Subscription (org.killbill.billing.entitlement.api.Subscription)21 LocalDate (org.joda.time.LocalDate)15 Account (org.killbill.billing.account.api.Account)12 Test (org.testng.annotations.Test)12 UUID (java.util.UUID)11 Entitlement (org.killbill.billing.entitlement.api.Entitlement)10 ApiOperation (io.swagger.annotations.ApiOperation)8 ApiResponses (io.swagger.annotations.ApiResponses)8 BigDecimal (java.math.BigDecimal)8 Produces (javax.ws.rs.Produces)8 DefaultEntitlement (org.killbill.billing.entitlement.api.DefaultEntitlement)8 Invoice (org.killbill.billing.invoice.api.Invoice)8 Path (javax.ws.rs.Path)7 DateTime (org.joda.time.DateTime)7 ExpectedInvoiceItemCheck (org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck)7 PlanPhaseSpecifier (org.killbill.billing.catalog.api.PlanPhaseSpecifier)7 DefaultEntitlementSpecifier (org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier)7 TenantContext (org.killbill.billing.util.callcontext.TenantContext)6 TimedResource (org.killbill.commons.metrics.TimedResource)6 GET (javax.ws.rs.GET)5