@TimedResource @GET @Path("/{bundleId:" + UUID_PATTERN + "}/" + TAGS) @Produces(APPLICATION_JSON) @ApiOperation(value = "Retrieve bundle tags", response = TagJson.class, responseContainer = "List", nickname = "getBundleTags") @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid bundle id supplied"), @ApiResponse(code = 404, message = "Bundle not found")}) public Response getTags(@PathParam(ID_PARAM_NAME) final UUID bundleId, @QueryParam(QUERY_INCLUDED_DELETED) @DefaultValue("false") final Boolean includedDeleted, @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode, @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException, SubscriptionApiException { final TenantContext tenantContext = context.createTenantContextNoAccountId(request); final SubscriptionBundle bundle = subscriptionApi.getSubscriptionBundle(bundleId, tenantContext); return super.getTags(bundle.getAccountId(), bundleId, auditMode, includedDeleted, tenantContext); }
@TimedResource @POST @Path("/{bundleId:" + UUID_PATTERN + "}/" + BLOCK) @Consumes(APPLICATION_JSON) @ApiOperation(value = "Block a bundle", response = BlockingStateJson.class, responseContainer = "List") @ApiResponses(value = {@ApiResponse(code = 201, message = "Blocking state created successfully"), @ApiResponse(code = 400, message = "Invalid bundle id supplied"), @ApiResponse(code = 404, message = "Bundle not found")}) public Response addBundleBlockingState(@PathParam(ID_PARAM_NAME) final UUID id, final BlockingStateJson json, @QueryParam(QUERY_REQUESTED_DT) final String requestedDate, @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString, @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, @javax.ws.rs.core.Context final UriInfo uriInfo) throws SubscriptionApiException, EntitlementApiException, AccountApiException { final TenantContext tenantContext = context.createTenantContextNoAccountId(request); final SubscriptionBundle bundle = subscriptionApi.getSubscriptionBundle(id, tenantContext); return addBlockingState(json, bundle.getAccountId(), id, BlockingStateType.SUBSCRIPTION_BUNDLE, requestedDate, pluginPropertiesString, createdBy, reason, comment, request, uriInfo); }
@TimedResource @GET @Path("/{bundleId:" + UUID_PATTERN + "}") @Produces(APPLICATION_JSON) @ApiOperation(value = "Retrieve a bundle by id", response = BundleJson.class) @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid bundle id supplied"), @ApiResponse(code = 404, message = "Bundle not found")}) public Response getBundle(@PathParam("bundleId") final UUID bundleId, @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode, @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, AccountApiException, CatalogApiException { final TenantContext tenantContext = this.context.createTenantContextNoAccountId(request); final SubscriptionBundle bundle = subscriptionApi.getSubscriptionBundle(bundleId, tenantContext); final Account account = accountUserApi.getAccountById(bundle.getAccountId(), tenantContext); final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(bundle.getAccountId(), auditMode.getLevel(), tenantContext); final BundleJson json = new BundleJson(bundle, account.getCurrency(), accountAuditLogs); return Response.status(Status.OK).entity(json).build(); }
@TimedResource @POST @Path("/{bundleId:" + UUID_PATTERN + "}") @Consumes(APPLICATION_JSON) @Produces(APPLICATION_JSON) @ApiOperation(value = "Transfer a bundle to another account", response = BundleJson.class) @ApiResponses(value = {@ApiResponse(code = 201, message = "Bundle transferred successfully"), @ApiResponse(code = 400, message = "Invalid bundle id, requested date or policy supplied"), @ApiResponse(code = 404, message = "Bundle not found")}) public Response transferBundle(@PathParam(ID_PARAM_NAME) final UUID bundleId, final BundleJson json, @QueryParam(QUERY_REQUESTED_DT) final String requestedDate, @QueryParam(QUERY_BILLING_POLICY) @DefaultValue("END_OF_TERM") final BillingActionPolicy billingPolicy, @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString, @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 UriInfo uriInfo, @javax.ws.rs.core.Context final HttpServletRequest request) throws EntitlementApiException, SubscriptionApiException, AccountApiException { verifyNonNullOrEmpty(json, "BundleJson body should be specified"); verifyNonNullOrEmpty(json.getAccountId(), "BundleJson accountId needs to be set"); final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString); final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request); final SubscriptionBundle bundle = subscriptionApi.getSubscriptionBundle(bundleId, callContext); final LocalDate inputLocalDate = toLocalDate(requestedDate); final UUID newBundleId = entitlementApi.transferEntitlementsOverrideBillingPolicy(bundle.getAccountId(), json.getAccountId(), bundle.getExternalKey(), inputLocalDate, billingPolicy, pluginProperties, callContext); return uriBuilder.buildResponse(uriInfo, BundleResource.class, "getBundle", newBundleId, request); }
private List<AuditLog> getAuditLogsForSubscriptionEvent(final UUID bundleId, final UUID subscriptionEventId, final TenantContext context) { try { final SubscriptionBundle bundle = subscriptionApi.getSubscriptionBundle(bundleId, context); return auditUserApi.getAccountAuditLogs(bundle.getAccountId(), AuditLevel.FULL, context).getAuditLogsForSubscriptionEvent(subscriptionEventId); } catch (final SubscriptionApiException e) { Assert.fail(e.toString()); return null; } }
private List<AuditLog> getAuditLogsForSubscription(final UUID bundleId, final UUID subscriptionId, final TenantContext context) { try { final SubscriptionBundle bundle = subscriptionApi.getSubscriptionBundle(bundleId, context); return auditUserApi.getAccountAuditLogs(bundle.getAccountId(), AuditLevel.FULL, context).getAuditLogsForSubscription(subscriptionId); } catch (final SubscriptionApiException e) { Assert.fail(e.toString()); return null; } }
private List<AuditLog> getAuditLogsForBundle(final UUID bundleId, final TenantContext context) { try { final SubscriptionBundle bundle = subscriptionApi.getSubscriptionBundle(bundleId, context); return auditUserApi.getAccountAuditLogs(bundle.getAccountId(), AuditLevel.FULL, context).getAuditLogsForBundle(bundle.getId()); } catch (final SubscriptionApiException e) { Assert.fail(e.toString()); return null; } }
private Account getAccountFromSubscriptionJson(final SubscriptionJson entitlementJson, final CallContext callContext) throws SubscriptionApiException, AccountApiException, EntitlementApiException { final UUID accountId; if (entitlementJson.getAccountId() != null) { accountId = entitlementJson.getAccountId(); } else if (entitlementJson.getSubscriptionId() != null) { final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementJson.getSubscriptionId(), callContext); accountId = entitlement.getAccountId(); } else { final SubscriptionBundle subscriptionBundle = subscriptionApi.getSubscriptionBundle(entitlementJson.getBundleId(), callContext); accountId = subscriptionBundle.getAccountId(); } return accountUserApi.getAccountById(accountId, callContext); } }
@Test(groups = "slow", description = "Test overdue for draft external charge", retryAnalyzer = FlakyRetryAnalyzer.class) public void testShouldNotBeInOverdueAfterDraftExternalCharge() throws Exception { // 2012-05-01T00:03:42.000Z clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0)); setupAccount(); // Create a subscription without failing payments 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); // 2012-05-06 => Create an external charge on a new invoice addDaysAndCheckForCompletion(5); final InvoiceItem externalCharge = new ExternalChargeInvoiceItem(null, account.getId(), bundle.getId(), "For overdue", new LocalDate(2012, 5, 6), new LocalDate(2012, 6, 6), BigDecimal.TEN, Currency.USD, null); invoiceUserApi.insertExternalCharges(account.getId(), clock.getUTCToday(), ImmutableList.<InvoiceItem>of(externalCharge), false, null, callContext).get(0); assertListenerStatus(); invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 6), new LocalDate(2012, 6, 6), InvoiceItemType.EXTERNAL_CHARGE, BigDecimal.TEN)); // 2012-05-31 => DAY 30 have to get out of trial before first payment addDaysAndCheckForCompletion(25, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT); invoiceChecker.checkInvoice(account.getId(), 3, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95"))); invoiceChecker.checkChargedThroughDate(baseEntitlement.getId(), new LocalDate(2012, 6, 30), callContext); // Should still be in clear state - the invoice for the bundle has been paid, but not the invoice with the external charge (because it is in draft mode) // We refresh overdue just to be safe, see below checkODState(OverdueWrapper.CLEAR_STATE_NAME); // 2012-06-06 => Past 30 days since the external charge addDaysAndCheckForCompletion(6); // We should still be clear checkODState(OverdueWrapper.CLEAR_STATE_NAME); Assert.assertEquals(invoiceUserApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday(), callContext).size(), 0); }
bundle = subscriptionApi.getSubscriptionBundle(baseEntitlement.getBundleId(), callContext);
bundle = subscriptionApi.getSubscriptionBundle(baseEntitlement.getBundleId(), callContext);
bundle = subscriptionApi.getSubscriptionBundle(baseEntitlement.getBundleId(), callContext);
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 SubscriptionBundle bundle2 = subscriptionApi.getSubscriptionBundle(baseEntitlement.getBundleId(), callContext); invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0"))); invoiceChecker.checkChargedThroughDate(baseEntitlement2.getId(), new LocalDate(2012, 5, 1), callContext); final SubscriptionBundle bundle3 = subscriptionApi.getSubscriptionBundle(baseEntitlement.getBundleId(), callContext); invoiceChecker.checkInvoice(account.getId(), 3, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0"))); invoiceChecker.checkChargedThroughDate(baseEntitlement2.getId(), new LocalDate(2012, 5, 1), callContext);
bundle = subscriptionApi.getSubscriptionBundle(baseEntitlement.getBundleId(), callContext);
@Test(groups = "slow") public void testNonOverdueAccountWith_OVERDUE_ENFORCEMENT_OFF() throws Exception { clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0)); setupAccount(); // Set the OVERDUE_ENFORCEMENT_OFF tag (we set the clear state, hence the blocking event) busHandler.pushExpectedEvents(NextEvent.TAG, NextEvent.BLOCK); tagUserApi.addTag(account.getId(), ObjectType.ACCOUNT, ControlTagType.OVERDUE_ENFORCEMENT_OFF.getId(), callContext); assertListenerStatus(); // 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); // DAY 30 have to get out of trial before first payment addDaysAndCheckForCompletion(30, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR); invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95"))); invoiceChecker.checkChargedThroughDate(baseEntitlement.getId(), new LocalDate(2012, 6, 30), callContext); // DAY 36 -- RIGHT AFTER OD1 addDaysAndCheckForCompletion(6); // Should still be in clear state checkODState(OverdueWrapper.CLEAR_STATE_NAME); // Now remove OVERDUE_ENFORCEMENT_OFF tag busHandler.pushExpectedEvents(NextEvent.TAG, NextEvent.BLOCK); tagUserApi.removeTag(account.getId(), ObjectType.ACCOUNT, ControlTagType.OVERDUE_ENFORCEMENT_OFF.getId(), callContext); assertListenerStatus(); checkODState("OD1"); }
@Test(groups = "slow") public void testOverdueStateWith_WRITTEN_OFF() 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); // DAY 30 have to get out of trial before first payment addDaysAndCheckForCompletion(30, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR); final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext); assertEquals(invoices.size(), 2); final Invoice nonNullInvoice = invoices.get(1); assertTrue(nonNullInvoice.getBalance().compareTo(BigDecimal.ZERO) > 0); // Set the WRITTEN_OFF tag busHandler.pushExpectedEvents(NextEvent.TAG); tagUserApi.addTag(nonNullInvoice.getId(), ObjectType.INVOICE, ControlTagType.WRITTEN_OFF.getId(), callContext); assertListenerStatus(); // Move after what should be OD1 (if invoice had not been written off) addDaysAndCheckForCompletion(6); // Should still be in clear state because of WRITTEN_OFF tag checkODState(OverdueWrapper.CLEAR_STATE_NAME); // Remove the WRITTEN_OFF tag and verify overdue state is now OD1 busHandler.pushExpectedEvents(NextEvent.TAG, NextEvent.BLOCK); tagUserApi.removeTag(nonNullInvoice.getId(), ObjectType.INVOICE, ControlTagType.WRITTEN_OFF.getId(), callContext); assertListenerStatus(); checkODState("OD1"); }
bundle = subscriptionApi.getSubscriptionBundle(baseEntitlement.getBundleId(), callContext);
bundle = subscriptionApi.getSubscriptionBundle(baseEntitlement.getBundleId(), callContext);
bundle = subscriptionApi.getSubscriptionBundle(baseEntitlement.getBundleId(), callContext);
assertListenerStatus(); final SubscriptionBundle bundle = subscriptionApi.getSubscriptionBundle(baseEntitlement.getBundleId(), callContext); final List<SubscriptionEvent> transitions = bundle.getTimeline().getSubscriptionEvents(); assertEquals(transitions.size(), 9);