Search in sources :

Example 16 with Subscription

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

the class TestWithBCDUpdate method testBCDChangeAfterTrialFollowOtherBCDChange.

@Test(groups = "slow")
public void testBCDChangeAfterTrialFollowOtherBCDChange() throws Exception {
    final DateTime initialDate = new DateTime(2016, 4, 1, 0, 13, 42, 0, testTimeZone);
    clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
    final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(0));
    assertNotNull(account);
    // BP creation : Will set Account BCD to the first (2016-4-1 + 30 days = 2016-5-1)
    final String productName = "Shotgun";
    final BillingPeriod term = BillingPeriod.MONTHLY;
    final DefaultEntitlement baseEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "bundleKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
    // 2016-5-1 : BP out of TRIAL
    busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addDays(30);
    assertListenerStatus();
    // Set next BCD to be the 15
    subscriptionBaseInternalApi.updateBCD(baseEntitlement.getId(), 15, null, internalCallContext);
    Thread.sleep(1000);
    assertListenerStatus();
    // 2016-5-15 : Catch BCD_CHANGE event and repair invoice accordingly
    busHandler.pushExpectedEvents(NextEvent.BCD_CHANGE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addDays(14);
    assertListenerStatus();
    final List<ExpectedInvoiceItemCheck> expectedInvoices = new ArrayList<ExpectedInvoiceItemCheck>();
    List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext);
    expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2016, 6, 1), new LocalDate(2016, 6, 15), InvoiceItemType.RECURRING, new BigDecimal("112.88")));
    invoiceChecker.checkInvoice(invoices.get(2).getId(), callContext, expectedInvoices);
    expectedInvoices.clear();
    // 2016-6-01 : Original notification for 2016-6-01 (prior BCD change)
    busHandler.pushExpectedEvents(NextEvent.NULL_INVOICE);
    clock.addDays(17);
    assertListenerStatus();
    // 2016-6-15
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addDays(14);
    assertListenerStatus();
    invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext);
    expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2016, 6, 15), new LocalDate(2016, 7, 15), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
    invoiceChecker.checkInvoice(invoices.get(3).getId(), callContext, expectedInvoices);
    expectedInvoices.clear();
    // Set next BCD to be the 10
    subscriptionBaseInternalApi.updateBCD(baseEntitlement.getId(), 10, null, internalCallContext);
    Thread.sleep(1000);
    assertListenerStatus();
    // 2016-7-10
    busHandler.pushExpectedEvents(NextEvent.BCD_CHANGE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addDays(25);
    assertListenerStatus();
    invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext);
    expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2016, 7, 15), new LocalDate(2016, 8, 10), InvoiceItemType.RECURRING, new BigDecimal("209.64")));
    invoiceChecker.checkInvoice(invoices.get(4).getId(), callContext, expectedInvoices);
    expectedInvoices.clear();
    clock.addDays(3);
    busHandler.pushExpectedEvents(NextEvent.CANCEL, NextEvent.BLOCK, NextEvent.INVOICE);
    final Entitlement cancelledEntitlement = baseEntitlement.cancelEntitlementWithPolicyOverrideBillingPolicy(EntitlementActionPolicy.IMMEDIATE, BillingActionPolicy.START_OF_TERM, null, callContext);
    assertListenerStatus();
    final Subscription subscription = subscriptionApi.getSubscriptionForEntitlementId(cancelledEntitlement.getId(), callContext);
    assertEquals(subscription.getEffectiveEndDate().compareTo(new LocalDate(2016, 7, 13)), 0);
    assertEquals(subscription.getBillingEndDate().compareTo(new LocalDate(2016, 7, 10)), 0);
}
Also used : Account(org.killbill.billing.account.api.Account) Invoice(org.killbill.billing.invoice.api.Invoice) BillingPeriod(org.killbill.billing.catalog.api.BillingPeriod) ArrayList(java.util.ArrayList) ExpectedInvoiceItemCheck(org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) 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 17 with Subscription

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

the class TestWithBCDUpdate method testBCDChangeInTrial.

@Test(groups = "slow")
public void testBCDChangeInTrial() throws Exception {
    final DateTime initialDate = new DateTime(2016, 4, 1, 0, 13, 42, 0, testTimeZone);
    clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
    final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(0));
    assertNotNull(account);
    // BP creation : Will set Account BCD to the first (2016-4-1 + 30 days = 2016-5-1)
    final String productName = "Shotgun";
    final BillingPeriod term = BillingPeriod.MONTHLY;
    final DefaultEntitlement baseEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "bundleKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
    // 2016-4-4 : (BP still in TRIAL)
    clock.addDays(3);
    // Set next BCD to be the 15
    subscriptionBaseInternalApi.updateBCD(baseEntitlement.getId(), 15, null, internalCallContext);
    Thread.sleep(1000);
    assertListenerStatus();
    // 2016-5-15 : Catch BCD_CHANGE event
    busHandler.pushExpectedEvents(NextEvent.BCD_CHANGE, NextEvent.NULL_INVOICE);
    clock.addDays(11);
    assertListenerStatus();
    // 2016-5-1 : BP out of TRIAL
    busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addDays(16);
    assertListenerStatus();
    final List<ExpectedInvoiceItemCheck> expectedInvoices = new ArrayList<ExpectedInvoiceItemCheck>();
    List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext);
    expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2016, 5, 1), new LocalDate(2016, 5, 15), InvoiceItemType.RECURRING, new BigDecimal("116.64")));
    invoiceChecker.checkInvoice(invoices.get(1).getId(), callContext, expectedInvoices);
    expectedInvoices.clear();
    // 2016-5-15 : NEW BCD
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addDays(14);
    assertListenerStatus();
    expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2016, 5, 15), new LocalDate(2016, 6, 15), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
    invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext);
    invoiceChecker.checkInvoice(invoices.get(2).getId(), callContext, expectedInvoices);
    expectedInvoices.clear();
    // Add cancellation with START_OF_TERM to verify BCD update is correctly interpreted
    clock.addDays(3);
    busHandler.pushExpectedEvents(NextEvent.CANCEL, NextEvent.BLOCK, NextEvent.INVOICE);
    final Entitlement cancelledEntitlement = baseEntitlement.cancelEntitlementWithPolicyOverrideBillingPolicy(EntitlementActionPolicy.IMMEDIATE, BillingActionPolicy.START_OF_TERM, null, callContext);
    assertListenerStatus();
    final Subscription subscription = subscriptionApi.getSubscriptionForEntitlementId(cancelledEntitlement.getId(), callContext);
    assertEquals(subscription.getEffectiveEndDate().compareTo(new LocalDate(2016, 5, 18)), 0);
    assertEquals(subscription.getBillingEndDate().compareTo(new LocalDate(2016, 5, 15)), 0);
}
Also used : Account(org.killbill.billing.account.api.Account) Invoice(org.killbill.billing.invoice.api.Invoice) BillingPeriod(org.killbill.billing.catalog.api.BillingPeriod) ArrayList(java.util.ArrayList) ExpectedInvoiceItemCheck(org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) 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 18 with Subscription

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

the class TestCatalogWithEvents method testChangeWithUsagePlan.

@Test(groups = "slow")
public void testChangeWithUsagePlan() throws Exception {
    final LocalDate today = new LocalDate(2020, 1, 1);
    clock.setDay(today);
    final VersionedCatalog catalog = catalogUserApi.getCatalog("foo", callContext);
    final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(1));
    final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("water-monthly", null);
    busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.NULL_INVOICE);
    final UUID subscriptionId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec, null, null, null), UUID.randomUUID().toString(), clock.getUTCToday(), clock.getUTCToday(), false, true, ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    recordUsageData(subscriptionId, "t1", "liter", new LocalDate(2020, 1, 1), 10L, callContext);
    recordUsageData(subscriptionId, "t2", "liter", new LocalDate(2020, 1, 23), 10L, callContext);
    // 2020-2-1
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
    clock.addMonths(1);
    assertListenerStatus();
    final Invoice invoice1 = invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 1, 1), new LocalDate(2020, 2, 1), InvoiceItemType.USAGE, new BigDecimal("30.00")));
    invoiceChecker.checkTrackingIds(invoice1, ImmutableSet.of("t1", "t2"), internalCallContext);
    Assert.assertTrue(invoice1.getInvoiceItems().get(0).getCatalogEffectiveDate().toDate().compareTo(catalog.getVersions().get(0).getEffectiveDate()) == 0);
    final Subscription subscription1 = subscriptionApi.getSubscriptionForEntitlementId(subscriptionId, callContext);
    final List<SubscriptionEvent> events1 = subscription1.getSubscriptionEvents();
    Assert.assertEquals(events1.size(), 2);
    Assert.assertTrue(events1.get(0).getNextPlan().getCatalog().getEffectiveDate().compareTo(catalog.getVersions().get(0).getEffectiveDate()) == 0);
    // 2020-2-16 (V2 effDt = 2020-2-15)
    clock.addDays(15);
    busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE);
    subscription1.changePlanWithDate(new DefaultEntitlementSpecifier(spec), clock.getUTCToday(), ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    final Subscription subscription2 = subscriptionApi.getSubscriptionForEntitlementId(subscriptionId, callContext);
    final List<SubscriptionEvent> events2 = subscription2.getSubscriptionEvents();
    Assert.assertEquals(events2.size(), 3);
    Assert.assertTrue(events2.get(0).getNextPlan().getCatalog().getEffectiveDate().compareTo(catalog.getVersions().get(0).getEffectiveDate()) == 0);
    // 2020-03-01
    busHandler.pushExpectedEvents(NextEvent.INVOICE);
    clock.addDays(14);
    assertListenerStatus();
    // 2020-3-16 (V3 effDt = 2020-3-15)
    clock.addDays(15);
    busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE);
    subscription1.changePlanWithDate(new DefaultEntitlementSpecifier(spec), clock.getUTCToday(), ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    final Subscription subscription3 = subscriptionApi.getSubscriptionForEntitlementId(subscriptionId, callContext);
    final List<SubscriptionEvent> events3 = subscription3.getSubscriptionEvents();
    Assert.assertEquals(events3.size(), 4);
    Assert.assertTrue(events3.get(0).getNextPlan().getCatalog().getEffectiveDate().compareTo(catalog.getVersions().get(0).getEffectiveDate()) == 0);
    Assert.assertTrue(events3.get(1).getNextPlan().getCatalog().getEffectiveDate().compareTo(catalog.getVersions().get(0).getEffectiveDate()) == 0);
    // Change catalog V2
    Assert.assertTrue(events3.get(2).getNextPlan().getCatalog().getEffectiveDate().compareTo(catalog.getVersions().get(1).getEffectiveDate()) == 0);
    // Change catalog V3
    Assert.assertTrue(events3.get(3).getNextPlan().getCatalog().getEffectiveDate().compareTo(catalog.getVersions().get(2).getEffectiveDate()) == 0);
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) DefaultEntitlementSpecifier(org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier) SubscriptionEvent(org.killbill.billing.entitlement.api.SubscriptionEvent) VersionedCatalog(org.killbill.billing.catalog.api.VersionedCatalog) Account(org.killbill.billing.account.api.Account) Invoice(org.killbill.billing.invoice.api.Invoice) UUID(java.util.UUID) Subscription(org.killbill.billing.entitlement.api.Subscription) LocalDate(org.joda.time.LocalDate) ExpectedInvoiceItemCheck(org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck) BigDecimal(java.math.BigDecimal) Test(org.testng.annotations.Test)

Example 19 with Subscription

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

the class TestCatalogRetireElements method testChangePlanTwiceWithNewPlan.

@Test(groups = "slow", description = "See https://github.com/killbill/killbill/issues/1110")
public void testChangePlanTwiceWithNewPlan() throws Exception {
    // Catalog v1 starts in 2011-01-01
    // Catalog v2 starts in 2015-12-01
    // -> Start on catalog V1
    final LocalDate today = new LocalDate(2015, 11, 5);
    // Set clock to the initial start date - we implicitly assume here that the account timezone is UTC
    clock.setDay(today);
    final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(null));
    final String productName = "Shotgun";
    final BillingPeriod term = BillingPeriod.MONTHLY;
    final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier(productName, term, "DEFAULT", null);
    busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
    final UUID bpEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec1), "externalKey", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    Entitlement bpEntitlement = entitlementApi.getEntitlementForId(bpEntitlementId, callContext);
    // Move out a month. Date > catalog V2
    busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addMonths(1);
    assertListenerStatus();
    // Current date is > catalog V2
    // Change to a plan that exists in V2 but not in V1
    final PlanPhaseSpecifier spec2 = new PlanPhaseSpecifier("bazooka-monthly", null);
    busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
    bpEntitlement = bpEntitlement.changePlanWithDate(new DefaultEntitlementSpecifier(spec2), clock.getUTCToday(), ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    // Change back to original plan: The code (subscription) chooses the latest version of the catalog when making the change and therefore the call succeeds
    busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE);
    bpEntitlement.changePlanWithDate(new DefaultEntitlementSpecifier(spec1), clock.getUTCToday(), ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    // 
    // The code normally goes through the grandfathering logic to find the version but specifies the transitionTime of the latest CHANGE (and not the subscriptionStartDate)
    // and therefore correctly find the latest catalog version, invoicing at the new price 295.95
    // 
    Invoice curInvoice = invoiceChecker.checkInvoice(account.getId(), 4, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2015, 12, 5), new LocalDate(2016, 1, 5), InvoiceItemType.RECURRING, new BigDecimal("295.95")), new ExpectedInvoiceItemCheck(new LocalDate(2015, 12, 5), new LocalDate(2016, 1, 5), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-500.00")), new ExpectedInvoiceItemCheck(new LocalDate(2015, 12, 5), new LocalDate(2015, 12, 5), InvoiceItemType.CBA_ADJ, new BigDecimal("204.05")));
    final VersionedCatalog catalog = catalogUserApi.getCatalog("foo", callContext);
    // RECURRING should be set against V2
    Assert.assertEquals(curInvoice.getInvoiceItems().get(0).getCatalogEffectiveDate().toDate().compareTo(catalog.getVersions().get(1).getEffectiveDate()), 0);
    Assert.assertNull(curInvoice.getInvoiceItems().get(1).getCatalogEffectiveDate());
    Assert.assertNull(curInvoice.getInvoiceItems().get(2).getCatalogEffectiveDate());
    final Subscription bpSubscription = subscriptionApi.getSubscriptionForEntitlementId(bpEntitlementId, callContext);
    final List<SubscriptionEvent> events = bpSubscription.getSubscriptionEvents();
    // We are seeing START_ENTITLEMENT, START_BILLING, and the **last CHANGE**
    // Note that the PHASE and intermediate CHANGE are not being returned (is_active = '0') because all coincided on the same date. This is debatable
    // whether this is a good semantics. See #1030
    assertEquals(events.size(), 3);
    // Verify what we return is the price from the correct catalog version. See #1120
    assertEquals(events.get(2).getNextPhase().getRecurring().getRecurringPrice().getPrice(account.getCurrency()).compareTo(new BigDecimal("295.95")), 0);
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) SubscriptionEvent(org.killbill.billing.entitlement.api.SubscriptionEvent) 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) DefaultEntitlementSpecifier(org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier) PluginProperty(org.killbill.billing.payment.api.PluginProperty) VersionedCatalog(org.killbill.billing.catalog.api.VersionedCatalog) 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 20 with Subscription

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

the class AccountResource method closeAccount.

@TimedResource
@DELETE
@Path("/{accountId:" + UUID_PATTERN + "}")
@Produces(APPLICATION_JSON)
@ApiOperation(value = "Close account")
@ApiResponses(value = { @ApiResponse(code = 204, message = "Successful operation"), @ApiResponse(code = 400, message = "Invalid account id supplied") })
public Response closeAccount(@PathParam("accountId") final UUID accountId, @QueryParam(QUERY_CANCEL_ALL_SUBSCRIPTIONS) @DefaultValue("false") final Boolean cancelAllSubscriptions, @QueryParam(QUERY_WRITE_OFF_UNPAID_INVOICES) @DefaultValue("false") final Boolean writeOffUnpaidInvoices, @QueryParam(QUERY_ITEM_ADJUST_UNPAID_INVOICES) @DefaultValue("false") final Boolean itemAdjustUnpaidInvoices, @QueryParam(QUERY_REMOVE_FUTURE_NOTIFICATIONS) @DefaultValue("true") final Boolean removeFutureNotifications, @HeaderParam(HDR_CREATED_BY) final String createdBy, @HeaderParam(HDR_REASON) final String reason, @HeaderParam(HDR_COMMENT) final String comment, @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, AccountApiException, EntitlementApiException, InvoiceApiException, TagApiException {
    final CallContext callContext = context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request);
    tagUserApi.addTag(accountId, ObjectType.ACCOUNT, ControlTagType.AUTO_INVOICING_OFF.getId(), callContext);
    if (cancelAllSubscriptions) {
        final List<SubscriptionBundle> bundles = subscriptionApi.getSubscriptionBundlesForAccountId(accountId, callContext);
        final Iterable<Subscription> subscriptions = Iterables.concat(Iterables.transform(bundles, new Function<SubscriptionBundle, List<Subscription>>() {

            @Override
            public List<Subscription> apply(final SubscriptionBundle input) {
                return input.getSubscriptions();
            }
        }));
        final Iterable<Subscription> toBeCancelled = Iterables.filter(subscriptions, new Predicate<Subscription>() {

            @Override
            public boolean apply(final Subscription input) {
                return input.getLastActiveProductCategory() != ProductCategory.ADD_ON && input.getBillingEndDate() == null;
            }
        });
        for (final Subscription cur : toBeCancelled) {
            cur.cancelEntitlementWithPolicyOverrideBillingPolicy(EntitlementActionPolicy.IMMEDIATE, BillingActionPolicy.END_OF_TERM, ImmutableList.<PluginProperty>of(), callContext);
        }
    }
    final Collection<Invoice> unpaidInvoices = writeOffUnpaidInvoices || itemAdjustUnpaidInvoices ? invoiceApi.getUnpaidInvoicesByAccountId(accountId, null, null, callContext) : ImmutableList.<Invoice>of();
    if (writeOffUnpaidInvoices) {
        for (final Invoice cur : unpaidInvoices) {
            invoiceApi.tagInvoiceAsWrittenOff(cur.getId(), callContext);
        }
    } else if (itemAdjustUnpaidInvoices) {
        final List<InvoiceItemType> ADJUSTABLE_TYPES = ImmutableList.<InvoiceItemType>of(InvoiceItemType.EXTERNAL_CHARGE, InvoiceItemType.FIXED, InvoiceItemType.RECURRING, InvoiceItemType.TAX, InvoiceItemType.USAGE, InvoiceItemType.PARENT_SUMMARY);
        final String description = comment != null ? comment : "Close Account";
        for (final Invoice invoice : unpaidInvoices) {
            for (final InvoiceItem item : invoice.getInvoiceItems()) {
                if (ADJUSTABLE_TYPES.contains(item.getInvoiceItemType())) {
                    invoiceApi.insertInvoiceItemAdjustment(accountId, invoice.getId(), item.getId(), clock.getUTCToday(), description, null, null, callContext);
                }
            }
        }
    }
    final BlockingStateJson blockingState = new BlockingStateJson(accountId, "CLOSE_ACCOUNT", "account-service", true, false, false, null, BlockingStateType.ACCOUNT, null);
    addBlockingState(blockingState, accountId, accountId, BlockingStateType.ACCOUNT, null, ImmutableList.<String>of(), createdBy, reason, comment, request, null);
    if (removeFutureNotifications) {
        final Long tenantRecordId = recordIdApi.getRecordId(callContext.getTenantId(), ObjectType.TENANT, callContext);
        final Long accountRecordId = accountId == null ? null : recordIdApi.getRecordId(accountId, ObjectType.ACCOUNT, callContext);
        for (final NotificationQueue notificationQueue : notificationQueueService.getNotificationQueues()) {
            log.debug("Removing future notifications for queueName={}", notificationQueue.getFullQName());
            notificationQueue.removeFutureNotificationsForSearchKeys(accountRecordId, tenantRecordId);
        }
    }
    return Response.status(Status.NO_CONTENT).build();
}
Also used : Invoice(org.killbill.billing.invoice.api.Invoice) InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) NotificationQueue(org.killbill.notificationq.api.NotificationQueue) BlockingStateJson(org.killbill.billing.jaxrs.json.BlockingStateJson) CallContext(org.killbill.billing.util.callcontext.CallContext) Function(com.google.common.base.Function) SubscriptionBundle(org.killbill.billing.entitlement.api.SubscriptionBundle) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) LinkedList(java.util.LinkedList) Subscription(org.killbill.billing.entitlement.api.Subscription) Path(javax.ws.rs.Path) DELETE(javax.ws.rs.DELETE) TimedResource(org.killbill.commons.metrics.TimedResource) Produces(javax.ws.rs.Produces) 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