Search in sources :

Example 6 with Subscription

use of org.killbill.billing.client.model.gen.Subscription in project killbill by killbill.

the class TestEntitlement method testEntitlementInTrialOk.

@Test(groups = "slow", description = "Can change plan and cancel a subscription")
public void testEntitlementInTrialOk() throws Exception {
    final DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
    clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
    final Account accountJson = createAccountWithDefaultPaymentMethod();
    final String productName = "Shotgun";
    final BillingPeriod term = BillingPeriod.MONTHLY;
    final Subscription entitlementJson = createSubscription(accountJson.getAccountId(), "99999", productName, ProductCategory.BASE, term);
    // Retrieves with GET
    Subscription subscription = subscriptionApi.getSubscription(entitlementJson.getSubscriptionId(), requestOptions);
    Assert.assertEquals(subscription.getPrices().size(), 2);
    Assert.assertEquals(subscription.getPrices().get(0).getFixedPrice(), BigDecimal.ZERO);
    Assert.assertNull(subscription.getPrices().get(0).getRecurringPrice());
    Assert.assertNull(subscription.getPrices().get(1).getFixedPrice());
    Assert.assertEquals(subscription.getPrices().get(1).getRecurringPrice(), new BigDecimal("249.95"));
    Assert.assertEquals(subscription, entitlementJson);
    final Subscription subscription2 = subscriptionApi.getSubscriptionByKey(subscription.getExternalKey(), requestOptions);
    assertEquals(subscription2.getBundleExternalKey(), "99999");
    assertEquals(subscription2.getExternalKey(), subscription.getExternalKey());
    // Change the clock otherwise the CREATE event might be replaced (instead of having a CHANGE event)
    clock.addDays(1);
    callbackServlet.assertListenerStatus();
    // Change plan IMM
    final String newProductName = "Assault-Rifle";
    final Subscription newInput = new Subscription();
    newInput.setAccountId(entitlementJson.getAccountId());
    newInput.setSubscriptionId(entitlementJson.getSubscriptionId());
    newInput.setProductName(newProductName);
    newInput.setProductCategory(ProductCategory.BASE);
    newInput.setBillingPeriod(entitlementJson.getBillingPeriod());
    newInput.setPriceList(entitlementJson.getPriceList());
    callbackServlet.pushExpectedEvents(ExtBusEventType.SUBSCRIPTION_CHANGE, ExtBusEventType.SUBSCRIPTION_CHANGE, ExtBusEventType.INVOICE_CREATION);
    subscriptionApi.changeSubscriptionPlan(entitlementJson.getSubscriptionId(), newInput, null, null, NULL_PLUGIN_PROPERTIES, requestOptions);
    callbackServlet.assertListenerStatus();
    Assert.assertNotNull(subscription);
    // MOVE AFTER TRIAL
    callbackServlet.pushExpectedEvents(ExtBusEventType.SUBSCRIPTION_PHASE, ExtBusEventType.INVOICE_CREATION, ExtBusEventType.INVOICE_PAYMENT_SUCCESS, ExtBusEventType.PAYMENT_SUCCESS);
    clock.addDays(30);
    callbackServlet.assertListenerStatus();
    // Cancel IMM (Billing EOT)
    subscriptionApi.cancelSubscriptionPlan(newInput.getSubscriptionId(), null, null, null, NULL_PLUGIN_PROPERTIES, requestOptions);
    // Retrieves to check EndDate
    subscription = subscriptionApi.getSubscription(entitlementJson.getSubscriptionId(), requestOptions);
    assertNotNull(subscription.getCancelledDate());
    assertTrue(subscription.getCancelledDate().compareTo(new LocalDate(clock.getUTCNow())) == 0);
    final Bundles accountBundles = accountApi.getAccountBundles(accountJson.getAccountId(), null, null, requestOptions);
    assertEquals(accountBundles.size(), 1);
    assertEquals(accountBundles.get(0).getSubscriptions().size(), 1);
    assertEquals(accountBundles.get(0).getSubscriptions().get(0).getState(), EntitlementState.CANCELLED);
    final Bundles bundlesByKey1 = bundleApi.getBundleByKey(entitlementJson.getBundleExternalKey(), true, AuditLevel.NONE, requestOptions);
    assertEquals(bundlesByKey1.size(), 1);
    assertEquals(bundlesByKey1.get(0).getSubscriptions().size(), 1);
    assertEquals(bundlesByKey1.get(0).getSubscriptions().get(0).getState(), EntitlementState.CANCELLED);
    final Bundles bundlesByKey2 = bundleApi.getBundleByKey(entitlementJson.getBundleExternalKey(), requestOptions);
    assertNotNull(bundlesByKey2);
    assertEquals(bundlesByKey2.size(), 0);
}
Also used : Account(org.killbill.billing.client.model.gen.Account) BillingPeriod(org.killbill.billing.catalog.api.BillingPeriod) Subscription(org.killbill.billing.client.model.gen.Subscription) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) BulkSubscriptionsBundles(org.killbill.billing.client.model.BulkSubscriptionsBundles) Bundles(org.killbill.billing.client.model.Bundles) Test(org.testng.annotations.Test)

Example 7 with Subscription

use of org.killbill.billing.client.model.gen.Subscription in project killbill by killbill.

the class TestEntitlement method testMoveEntitlementBCD.

@Test(groups = "slow", description = "Verify we can move the BCD associated with the subscription")
public void testMoveEntitlementBCD() throws Exception {
    final DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
    clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
    final Account accountJson = createAccountWithDefaultPaymentMethod();
    final String productName = "Shotgun";
    final BillingPeriod term = BillingPeriod.MONTHLY;
    final Subscription entitlementJson = createSubscription(accountJson.getAccountId(), "99999", productName, ProductCategory.BASE, term);
    Assert.assertEquals(entitlementJson.getBillCycleDayLocal(), new Integer(25));
    final Subscription updatedSubscription = new Subscription();
    updatedSubscription.setSubscriptionId(entitlementJson.getSubscriptionId());
    updatedSubscription.setBillCycleDayLocal(9);
    callbackServlet.pushExpectedEvents(ExtBusEventType.SUBSCRIPTION_BCD_CHANGE);
    subscriptionApi.updateSubscriptionBCD(entitlementJson.getSubscriptionId(), updatedSubscription, null, requestOptions);
    callbackServlet.assertListenerStatus();
    final Subscription result = subscriptionApi.getSubscription(entitlementJson.getSubscriptionId(), requestOptions);
    // Still shows as the 4 (BCD did not take effect)
    Assert.assertEquals(result.getBillCycleDayLocal(), new Integer(25));
    // 2012, 5, 9
    callbackServlet.pushExpectedEvents(ExtBusEventType.SUBSCRIPTION_BCD_CHANGE);
    clock.addDays(14);
    callbackServlet.assertListenerStatus();
    final Subscription result2 = subscriptionApi.getSubscription(entitlementJson.getSubscriptionId(), requestOptions);
    // Still shows as the 4 (BCD did not take effect)
    Assert.assertEquals(result2.getBillCycleDayLocal(), new Integer(9));
}
Also used : Account(org.killbill.billing.client.model.gen.Account) BillingPeriod(org.killbill.billing.catalog.api.BillingPeriod) Subscription(org.killbill.billing.client.model.gen.Subscription) DateTime(org.joda.time.DateTime) Test(org.testng.annotations.Test)

Example 8 with Subscription

use of org.killbill.billing.client.model.gen.Subscription in project killbill by killbill.

the class TestEntitlement method testEntitlementUndoChangePlan.

@Test(groups = "slow", description = "Can changePlan and undo changePlan on a subscription")
public void testEntitlementUndoChangePlan() throws Exception {
    final DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
    clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
    final Account accountJson = createAccountWithDefaultPaymentMethod();
    final String productName = "Shotgun";
    final BillingPeriod term = BillingPeriod.MONTHLY;
    final Subscription entitlementJson = createSubscription(accountJson.getAccountId(), "99999", productName, ProductCategory.BASE, term);
    // Change plan in the future
    final String newProductName = "Assault-Rifle";
    final Subscription newInput = new Subscription();
    newInput.setAccountId(entitlementJson.getAccountId());
    newInput.setSubscriptionId(entitlementJson.getSubscriptionId());
    newInput.setProductName(newProductName);
    newInput.setProductCategory(ProductCategory.BASE);
    newInput.setBillingPeriod(entitlementJson.getBillingPeriod());
    newInput.setPriceList(entitlementJson.getPriceList());
    callbackServlet.pushExpectedEvents(ExtBusEventType.SUBSCRIPTION_CHANGE);
    subscriptionApi.changeSubscriptionPlan(entitlementJson.getSubscriptionId(), newInput, new LocalDate(2012, 4, 28), null, NULL_PLUGIN_PROPERTIES, requestOptions);
    Subscription refreshedSubscription = subscriptionApi.getSubscription(entitlementJson.getSubscriptionId(), requestOptions);
    callbackServlet.assertListenerStatus();
    Assert.assertNotNull(refreshedSubscription);
    final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(1));
    clock.addDeltaFromReality(it.toDurationMillis());
    // We get 2 SUBSCRIPTION_CHANGE events, one for requested and one or effective, which are the same.
    callbackServlet.pushExpectedEvents(ExtBusEventType.SUBSCRIPTION_CHANGE, ExtBusEventType.SUBSCRIPTION_CHANGE);
    subscriptionApi.undoChangeSubscriptionPlan(refreshedSubscription.getSubscriptionId(), NULL_PLUGIN_PROPERTIES, requestOptions);
    callbackServlet.assertListenerStatus();
    // MOVE AFTER TRIAL
    callbackServlet.pushExpectedEvents(ExtBusEventType.SUBSCRIPTION_PHASE, ExtBusEventType.INVOICE_CREATION, ExtBusEventType.INVOICE_PAYMENT_SUCCESS, ExtBusEventType.PAYMENT_SUCCESS);
    clock.addDays(30);
    callbackServlet.assertListenerStatus();
    // Retrieves to check EndDate
    refreshedSubscription = subscriptionApi.getSubscription(entitlementJson.getSubscriptionId(), requestOptions);
    Assert.assertEquals(refreshedSubscription.getPrices().size(), 2);
    Assert.assertEquals(refreshedSubscription.getPrices().get(0).getPhaseName(), "shotgun-monthly-trial");
    Assert.assertEquals(refreshedSubscription.getPrices().get(0).getFixedPrice(), BigDecimal.ZERO);
    Assert.assertNull(refreshedSubscription.getPrices().get(0).getRecurringPrice());
    Assert.assertEquals(refreshedSubscription.getPrices().get(1).getPhaseName(), "shotgun-monthly-evergreen");
    Assert.assertNull(refreshedSubscription.getPrices().get(1).getFixedPrice());
    Assert.assertEquals(refreshedSubscription.getPrices().get(1).getRecurringPrice(), new BigDecimal("249.95"));
}
Also used : Account(org.killbill.billing.client.model.gen.Account) BillingPeriod(org.killbill.billing.catalog.api.BillingPeriod) Subscription(org.killbill.billing.client.model.gen.Subscription) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) Interval(org.joda.time.Interval) Test(org.testng.annotations.Test)

Example 9 with Subscription

use of org.killbill.billing.client.model.gen.Subscription in project killbill by killbill.

the class TestUsage method testRecordUsage.

@Test(groups = "slow", description = "Can record and retrieve usage data")
public void testRecordUsage() throws Exception {
    final Account accountJson = createAccountWithDefaultPaymentMethod();
    final Subscription base = new Subscription();
    base.setAccountId(accountJson.getAccountId());
    base.setProductName("Pistol");
    base.setProductCategory(ProductCategory.BASE);
    base.setBillingPeriod(BillingPeriod.MONTHLY);
    base.setPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
    final Subscription addOn = new Subscription();
    addOn.setAccountId(accountJson.getAccountId());
    addOn.setProductName("Bullets");
    addOn.setProductCategory(ProductCategory.ADD_ON);
    addOn.setBillingPeriod(BillingPeriod.NO_BILLING_PERIOD);
    addOn.setPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
    callbackServlet.pushExpectedEvents(ExtBusEventType.ACCOUNT_CHANGE, ExtBusEventType.ENTITLEMENT_CREATION, ExtBusEventType.ENTITLEMENT_CREATION, ExtBusEventType.SUBSCRIPTION_CREATION, ExtBusEventType.SUBSCRIPTION_CREATION, ExtBusEventType.SUBSCRIPTION_CREATION, ExtBusEventType.SUBSCRIPTION_CREATION, ExtBusEventType.INVOICE_CREATION);
    final Subscriptions body = new Subscriptions();
    body.add(base);
    body.add(addOn);
    final Bundle bundle = subscriptionApi.createSubscriptionWithAddOns(body, null, null, NULL_PLUGIN_PROPERTIES, requestOptions);
    callbackServlet.assertListenerStatus();
    final UUID addOnSubscriptionId = Iterables.<Subscription>find(bundle.getSubscriptions(), new Predicate<Subscription>() {

        @Override
        public boolean apply(final Subscription input) {
            return ProductCategory.ADD_ON.equals(input.getProductCategory());
        }
    }).getSubscriptionId();
    clock.addDays(1);
    final UsageRecord usageRecord1 = new UsageRecord();
    usageRecord1.setAmount(10L);
    usageRecord1.setRecordDate(clock.getUTCToday().minusDays(1));
    final UsageRecord usageRecord2 = new UsageRecord();
    usageRecord2.setAmount(5L);
    usageRecord2.setRecordDate(clock.getUTCToday());
    final UnitUsageRecord unitUsageRecord = new UnitUsageRecord();
    unitUsageRecord.setUnitType("bullets");
    unitUsageRecord.setUsageRecords(ImmutableList.<UsageRecord>of(usageRecord1, usageRecord2));
    final SubscriptionUsageRecord usage = new SubscriptionUsageRecord();
    usage.setSubscriptionId(addOnSubscriptionId);
    usage.setUnitUsageRecords(ImmutableList.<UnitUsageRecord>of(unitUsageRecord));
    usageApi.recordUsage(usage, requestOptions);
    callbackServlet.assertListenerStatus();
    final RolledUpUsage retrievedUsage1 = usageApi.getUsage(addOnSubscriptionId, unitUsageRecord.getUnitType(), clock.getUTCToday().minusDays(1), clock.getUTCToday(), requestOptions);
    Assert.assertEquals(retrievedUsage1.getSubscriptionId(), usage.getSubscriptionId());
    Assert.assertEquals(retrievedUsage1.getRolledUpUnits().size(), 1);
    Assert.assertEquals(retrievedUsage1.getRolledUpUnits().get(0).getUnitType(), unitUsageRecord.getUnitType());
    // endDate is excluded
    Assert.assertEquals((long) retrievedUsage1.getRolledUpUnits().get(0).getAmount(), 10);
    final RolledUpUsage retrievedUsage2 = usageApi.getUsage(addOnSubscriptionId, unitUsageRecord.getUnitType(), clock.getUTCToday().minusDays(1), clock.getUTCToday().plusDays(1), requestOptions);
    Assert.assertEquals(retrievedUsage2.getSubscriptionId(), usage.getSubscriptionId());
    Assert.assertEquals(retrievedUsage2.getRolledUpUnits().size(), 1);
    Assert.assertEquals(retrievedUsage2.getRolledUpUnits().get(0).getUnitType(), unitUsageRecord.getUnitType());
    Assert.assertEquals((long) retrievedUsage2.getRolledUpUnits().get(0).getAmount(), 15);
    final RolledUpUsage retrievedUsage3 = usageApi.getUsage(addOnSubscriptionId, unitUsageRecord.getUnitType(), clock.getUTCToday(), clock.getUTCToday().plusDays(1), requestOptions);
    Assert.assertEquals(retrievedUsage3.getSubscriptionId(), usage.getSubscriptionId());
    Assert.assertEquals(retrievedUsage3.getRolledUpUnits().size(), 1);
    Assert.assertEquals(retrievedUsage3.getRolledUpUnits().get(0).getUnitType(), unitUsageRecord.getUnitType());
    Assert.assertEquals((long) retrievedUsage3.getRolledUpUnits().get(0).getAmount(), 5);
    final RolledUpUsage retrievedUsage4 = usageApi.getAllUsage(addOnSubscriptionId, clock.getUTCToday(), clock.getUTCToday().plusDays(1), requestOptions);
    Assert.assertEquals(retrievedUsage4.getSubscriptionId(), usage.getSubscriptionId());
    Assert.assertEquals(retrievedUsage4.getRolledUpUnits().size(), 1);
    Assert.assertEquals(retrievedUsage4.getRolledUpUnits().get(0).getUnitType(), "bullets");
    Assert.assertEquals((long) retrievedUsage4.getRolledUpUnits().get(0).getAmount(), 5);
    callbackServlet.pushExpectedEvents(ExtBusEventType.SUBSCRIPTION_PHASE, ExtBusEventType.INVOICE_CREATION, ExtBusEventType.INVOICE_PAYMENT_SUCCESS, ExtBusEventType.PAYMENT_SUCCESS);
    clock.addMonths(1);
    callbackServlet.assertListenerStatus();
    final Invoices invoices = accountApi.getInvoicesForAccount(accountJson.getAccountId(), null, null, false, false, false, null, AuditLevel.MINIMAL, requestOptions);
    Assert.assertEquals(invoices.size(), 2);
    // Verify system assigned one tracking ID and this is correctly returned
    Assert.assertEquals(invoices.get(1).getTrackingIds().size(), 1);
    final InvoiceItem usageItem = Iterables.tryFind(invoices.get(1).getItems(), new Predicate<InvoiceItem>() {

        @Override
        public boolean apply(final InvoiceItem input) {
            return input.getItemType() == InvoiceItemType.USAGE;
        }
    }).orNull();
    Assert.assertNotNull(usageItem);
    Assert.assertEquals(usageItem.getPrettyPlanName(), "Bullet Monthly Plan");
    Assert.assertEquals(usageItem.getPrettyPhaseName(), "Bullet Monthly Plan Evergreen");
    Assert.assertEquals(usageItem.getPrettyUsageName(), "Bullet Usage In Arrear");
}
Also used : Account(org.killbill.billing.client.model.gen.Account) InvoiceItem(org.killbill.billing.client.model.gen.InvoiceItem) Subscriptions(org.killbill.billing.client.model.Subscriptions) RolledUpUsage(org.killbill.billing.client.model.gen.RolledUpUsage) Bundle(org.killbill.billing.client.model.gen.Bundle) UnitUsageRecord(org.killbill.billing.client.model.gen.UnitUsageRecord) UnitUsageRecord(org.killbill.billing.client.model.gen.UnitUsageRecord) SubscriptionUsageRecord(org.killbill.billing.client.model.gen.SubscriptionUsageRecord) UsageRecord(org.killbill.billing.client.model.gen.UsageRecord) Invoices(org.killbill.billing.client.model.Invoices) Subscription(org.killbill.billing.client.model.gen.Subscription) UUID(java.util.UUID) SubscriptionUsageRecord(org.killbill.billing.client.model.gen.SubscriptionUsageRecord) Predicate(com.google.common.base.Predicate) Test(org.testng.annotations.Test)

Example 10 with Subscription

use of org.killbill.billing.client.model.gen.Subscription in project killbill by killbill.

the class TestUsage method testRecordUsageTrackingIdExists.

@Test(groups = "slow", description = "Test tracking ID already exists")
public void testRecordUsageTrackingIdExists() throws Exception {
    final Account accountJson = createAccountWithDefaultPaymentMethod();
    final Subscription base = new Subscription();
    base.setAccountId(accountJson.getAccountId());
    base.setProductName("Pistol");
    base.setProductCategory(ProductCategory.BASE);
    base.setBillingPeriod(BillingPeriod.MONTHLY);
    base.setPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
    final Subscription addOn = new Subscription();
    addOn.setAccountId(accountJson.getAccountId());
    addOn.setProductName("Bullets");
    addOn.setProductCategory(ProductCategory.ADD_ON);
    addOn.setBillingPeriod(BillingPeriod.NO_BILLING_PERIOD);
    addOn.setPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
    final Subscriptions body = new Subscriptions();
    body.add(base);
    body.add(addOn);
    final Bundle bundle = subscriptionApi.createSubscriptionWithAddOns(body, null, null, NULL_PLUGIN_PROPERTIES, requestOptions);
    final UUID addOnSubscriptionId = Iterables.<Subscription>find(bundle.getSubscriptions(), new Predicate<Subscription>() {

        @Override
        public boolean apply(final Subscription input) {
            return ProductCategory.ADD_ON.equals(input.getProductCategory());
        }
    }).getSubscriptionId();
    final UsageRecord usageRecord1 = new UsageRecord();
    usageRecord1.setAmount(10L);
    usageRecord1.setRecordDate(clock.getUTCToday().minusDays(1));
    final UnitUsageRecord unitUsageRecord = new UnitUsageRecord();
    unitUsageRecord.setUnitType("bullets");
    unitUsageRecord.setUsageRecords(ImmutableList.<UsageRecord>of(usageRecord1));
    final SubscriptionUsageRecord usage = new SubscriptionUsageRecord();
    usage.setSubscriptionId(addOnSubscriptionId);
    final String trackingId = UUID.randomUUID().toString();
    usage.setTrackingId(trackingId);
    usage.setUnitUsageRecords(ImmutableList.<UnitUsageRecord>of(unitUsageRecord));
    usageApi.recordUsage(usage, requestOptions);
    try {
        usageApi.recordUsage(usage, requestOptions);
        Assert.fail();
    } catch (final KillBillClientException e) {
        Assert.assertEquals(e.getBillingException().getCode(), (Integer) ErrorCode.USAGE_RECORD_TRACKING_ID_ALREADY_EXISTS.getCode());
    }
}
Also used : Account(org.killbill.billing.client.model.gen.Account) Subscriptions(org.killbill.billing.client.model.Subscriptions) Bundle(org.killbill.billing.client.model.gen.Bundle) UnitUsageRecord(org.killbill.billing.client.model.gen.UnitUsageRecord) UnitUsageRecord(org.killbill.billing.client.model.gen.UnitUsageRecord) SubscriptionUsageRecord(org.killbill.billing.client.model.gen.SubscriptionUsageRecord) UsageRecord(org.killbill.billing.client.model.gen.UsageRecord) KillBillClientException(org.killbill.billing.client.KillBillClientException) Subscription(org.killbill.billing.client.model.gen.Subscription) UUID(java.util.UUID) SubscriptionUsageRecord(org.killbill.billing.client.model.gen.SubscriptionUsageRecord) Predicate(com.google.common.base.Predicate) Test(org.testng.annotations.Test)

Aggregations

Subscription (org.killbill.billing.client.model.gen.Subscription)35 Account (org.killbill.billing.client.model.gen.Account)34 Test (org.testng.annotations.Test)29 DateTime (org.joda.time.DateTime)21 BigDecimal (java.math.BigDecimal)8 BillingPeriod (org.killbill.billing.catalog.api.BillingPeriod)8 Bundles (org.killbill.billing.client.model.Bundles)7 UUID (java.util.UUID)6 Bundle (org.killbill.billing.client.model.gen.Bundle)6 Invoice (org.killbill.billing.client.model.gen.Invoice)6 LocalDate (org.joda.time.LocalDate)5 BulkSubscriptionsBundles (org.killbill.billing.client.model.BulkSubscriptionsBundles)5 Tags (org.killbill.billing.client.model.Tags)5 ArrayList (java.util.ArrayList)4 BulkSubscriptionsBundle (org.killbill.billing.client.model.gen.BulkSubscriptionsBundle)4 KillBillClientException (org.killbill.billing.client.KillBillClientException)3 Subscriptions (org.killbill.billing.client.model.Subscriptions)3 Predicate (com.google.common.base.Predicate)2 Invoices (org.killbill.billing.client.model.Invoices)2 SubscriptionUsageRecord (org.killbill.billing.client.model.gen.SubscriptionUsageRecord)2