Search in sources :

Example 11 with PluginProperty

use of org.killbill.billing.payment.api.PluginProperty in project killbill by killbill.

the class SubscriptionResource method changeEntitlementPlan.

@TimedResource
@PUT
@Produces(APPLICATION_JSON)
@Consumes(APPLICATION_JSON)
@Path("/{subscriptionId:" + UUID_PATTERN + "}")
@ApiOperation(value = "Change entitlement plan")
@ApiResponses(value = { @ApiResponse(code = 400, message = "Invalid subscription id supplied"), @ApiResponse(code = 404, message = "Entitlement not found") })
public Response changeEntitlementPlan(final SubscriptionJson entitlement, @PathParam("subscriptionId") final String subscriptionId, @QueryParam(QUERY_REQUESTED_DT) final String requestedDate, @QueryParam(QUERY_CALL_COMPLETION) @DefaultValue("false") final Boolean callCompletion, @QueryParam(QUERY_CALL_TIMEOUT) @DefaultValue("3") final long timeoutSec, @QueryParam(QUERY_BILLING_POLICY) final String policyString, @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) throws EntitlementApiException, AccountApiException, SubscriptionApiException {
    verifyNonNullOrEmpty(entitlement, "SubscriptionJson body should be specified");
    if (entitlement.getPlanName() == null) {
        verifyNonNullOrEmpty(entitlement.getProductName(), "SubscriptionJson productName needs to be set", entitlement.getBillingPeriod(), "SubscriptionJson billingPeriod needs to be set", entitlement.getPriceList(), "SubscriptionJson priceList needs to be set");
    }
    final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
    final CallContext callContext = context.createContext(createdBy, reason, comment, request);
    final EntitlementCallCompletionCallback<Response> callback = new EntitlementCallCompletionCallback<Response>() {

        private boolean isImmediateOp = true;

        @Override
        public Response doOperation(final CallContext ctx) throws EntitlementApiException, InterruptedException, TimeoutException, AccountApiException {
            final UUID uuid = UUID.fromString(subscriptionId);
            final Entitlement current = entitlementApi.getEntitlementForId(uuid, callContext);
            final LocalDate inputLocalDate = toLocalDate(requestedDate);
            final Entitlement newEntitlement;
            final Account account = accountUserApi.getAccountById(current.getAccountId(), callContext);
            final PlanSpecifier planSpec = entitlement.getPlanName() != null ? new PlanSpecifier(entitlement.getPlanName()) : new PlanSpecifier(entitlement.getProductName(), BillingPeriod.valueOf(entitlement.getBillingPeriod()), entitlement.getPriceList());
            final List<PlanPhasePriceOverride> overrides = PhasePriceOverrideJson.toPlanPhasePriceOverrides(entitlement.getPriceOverrides(), planSpec, account.getCurrency());
            if (requestedDate == null && policyString == null) {
                newEntitlement = current.changePlan(planSpec, overrides, pluginProperties, ctx);
            } else if (policyString == null) {
                newEntitlement = current.changePlanWithDate(planSpec, overrides, inputLocalDate, pluginProperties, ctx);
            } else {
                final BillingActionPolicy policy = BillingActionPolicy.valueOf(policyString.toUpperCase());
                newEntitlement = current.changePlanOverrideBillingPolicy(planSpec, overrides, inputLocalDate, policy, pluginProperties, ctx);
            }
            isImmediateOp = newEntitlement.getLastActiveProduct().getName().equals(entitlement.getProductName()) && newEntitlement.getLastActivePlan().getRecurringBillingPeriod() == BillingPeriod.valueOf(entitlement.getBillingPeriod()) && newEntitlement.getLastActivePriceList().getName().equals(entitlement.getPriceList());
            return Response.status(Status.OK).build();
        }

        @Override
        public boolean isImmOperation() {
            return isImmediateOp;
        }

        @Override
        public Response doResponseOk(final Response operationResponse) throws SubscriptionApiException, AccountApiException, CatalogApiException {
            if (operationResponse.getStatus() != Status.OK.getStatusCode()) {
                return operationResponse;
            }
            return getEntitlement(subscriptionId, new AuditMode(AuditLevel.NONE.toString()), request);
        }
    };
    final EntitlementCallCompletion<Response> callCompletionCreation = new EntitlementCallCompletion<Response>();
    return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, callContext);
}
Also used : Account(org.killbill.billing.account.api.Account) BillingActionPolicy(org.killbill.billing.catalog.api.BillingActionPolicy) CallContext(org.killbill.billing.util.callcontext.CallContext) LocalDate(org.joda.time.LocalDate) Response(javax.ws.rs.core.Response) ApiResponse(io.swagger.annotations.ApiResponse) PluginProperty(org.killbill.billing.payment.api.PluginProperty) UUID(java.util.UUID) Entitlement(org.killbill.billing.entitlement.api.Entitlement) PlanSpecifier(org.killbill.billing.catalog.api.PlanSpecifier) PlanPhasePriceOverride(org.killbill.billing.catalog.api.PlanPhasePriceOverride) Path(javax.ws.rs.Path) TimedResource(org.killbill.commons.metrics.TimedResource) Produces(javax.ws.rs.Produces) Consumes(javax.ws.rs.Consumes) ApiOperation(io.swagger.annotations.ApiOperation) PUT(javax.ws.rs.PUT) ApiResponses(io.swagger.annotations.ApiResponses)

Example 12 with PluginProperty

use of org.killbill.billing.payment.api.PluginProperty in project killbill by killbill.

the class SubscriptionResource method uncancelEntitlementPlan.

@TimedResource
@PUT
@Path("/{subscriptionId:" + UUID_PATTERN + "}/uncancel")
@Produces(APPLICATION_JSON)
@ApiOperation(value = "Un-cancel an entitlement")
@ApiResponses(value = { @ApiResponse(code = 400, message = "Invalid subscription id supplied"), @ApiResponse(code = 404, message = "Entitlement not found") })
public Response uncancelEntitlementPlan(@PathParam("subscriptionId") final String subscriptionId, @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) throws EntitlementApiException {
    final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
    final UUID uuid = UUID.fromString(subscriptionId);
    final Entitlement current = entitlementApi.getEntitlementForId(uuid, context.createContext(createdBy, reason, comment, request));
    current.uncancelEntitlement(pluginProperties, context.createContext(createdBy, reason, comment, request));
    return Response.status(Status.OK).build();
}
Also used : PluginProperty(org.killbill.billing.payment.api.PluginProperty) UUID(java.util.UUID) Entitlement(org.killbill.billing.entitlement.api.Entitlement) Path(javax.ws.rs.Path) TimedResource(org.killbill.commons.metrics.TimedResource) Produces(javax.ws.rs.Produces) ApiOperation(io.swagger.annotations.ApiOperation) PUT(javax.ws.rs.PUT) ApiResponses(io.swagger.annotations.ApiResponses)

Example 13 with PluginProperty

use of org.killbill.billing.payment.api.PluginProperty in project killbill by killbill.

the class InvoiceResource method createExternalCharges.

@TimedResource
@POST
@Produces(APPLICATION_JSON)
@Consumes(APPLICATION_JSON)
@Path("/" + CHARGES + "/{accountId:" + UUID_PATTERN + "}")
@ApiOperation(value = "Create external charge(s)", response = InvoiceItemJson.class, responseContainer = "List")
@ApiResponses(value = { @ApiResponse(code = 400, message = "Invalid account id supplied"), @ApiResponse(code = 404, message = "Account not found") })
public Response createExternalCharges(final Iterable<InvoiceItemJson> externalChargesJson, @PathParam("accountId") final String accountId, @QueryParam(QUERY_REQUESTED_DT) final String requestedDateTimeString, @QueryParam(QUERY_PAY_INVOICE) @DefaultValue("false") final Boolean payInvoice, @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString, @QueryParam(QUERY_AUTO_COMMIT) @DefaultValue("false") final Boolean autoCommit, @QueryParam(QUERY_PAYMENT_EXTERNAL_KEY) final String paymentExternalKey, @QueryParam(QUERY_TRANSACTION_EXTERNAL_KEY) final String transactionExternalKey, @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 AccountApiException, InvoiceApiException, PaymentApiException {
    final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
    final CallContext callContext = context.createContext(createdBy, reason, comment, request);
    final Account account = accountUserApi.getAccountById(UUID.fromString(accountId), callContext);
    final Iterable<InvoiceItem> sanitizedExternalChargesJson = validateSanitizeAndTranformInputItems(account.getCurrency(), externalChargesJson);
    // Get the effective date of the external charge, in the account timezone
    final LocalDate requestedDate = toLocalDateDefaultToday(account, requestedDateTimeString, callContext);
    final List<InvoiceItem> createdExternalCharges = invoiceApi.insertExternalCharges(account.getId(), requestedDate, sanitizedExternalChargesJson, autoCommit, callContext);
    // if all createdExternalCharges point to the same invoiceId, use the provided paymentExternalKey and / or transactionExternalKey
    final boolean haveSameInvoiceId = Iterables.all(createdExternalCharges, new Predicate<InvoiceItem>() {

        @Override
        public boolean apply(final InvoiceItem input) {
            return input.getInvoiceId().equals(createdExternalCharges.get(0).getInvoiceId());
        }
    });
    if (payInvoice) {
        final Collection<UUID> paidInvoices = new HashSet<UUID>();
        for (final InvoiceItem externalCharge : createdExternalCharges) {
            if (!paidInvoices.contains(externalCharge.getInvoiceId())) {
                paidInvoices.add(externalCharge.getInvoiceId());
                final Invoice invoice = invoiceApi.getInvoice(externalCharge.getInvoiceId(), callContext);
                createPurchaseForInvoice(account, invoice.getId(), invoice.getBalance(), account.getPaymentMethodId(), false, (haveSameInvoiceId && paymentExternalKey != null) ? paymentExternalKey : null, (haveSameInvoiceId && transactionExternalKey != null) ? transactionExternalKey : null, pluginProperties, callContext);
            }
        }
    }
    final List<InvoiceItemJson> createdExternalChargesJson = Lists.<InvoiceItem, InvoiceItemJson>transform(createdExternalCharges, new Function<InvoiceItem, InvoiceItemJson>() {

        @Override
        public InvoiceItemJson apply(final InvoiceItem input) {
            return new InvoiceItemJson(input);
        }
    });
    return Response.status(Status.OK).entity(createdExternalChargesJson).build();
}
Also used : Account(org.killbill.billing.account.api.Account) InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) Invoice(org.killbill.billing.invoice.api.Invoice) InvoiceItemJson(org.killbill.billing.jaxrs.json.InvoiceItemJson) CallContext(org.killbill.billing.util.callcontext.CallContext) LocalDate(org.joda.time.LocalDate) PluginProperty(org.killbill.billing.payment.api.PluginProperty) UUID(java.util.UUID) PlanPhasePriceOverride(org.killbill.billing.catalog.api.PlanPhasePriceOverride) DefaultPlanPhasePriceOverride(org.killbill.billing.catalog.DefaultPlanPhasePriceOverride) HashSet(java.util.HashSet) Path(javax.ws.rs.Path) TimedResource(org.killbill.commons.metrics.TimedResource) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces) Consumes(javax.ws.rs.Consumes) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 14 with PluginProperty

use of org.killbill.billing.payment.api.PluginProperty in project killbill by killbill.

the class JaxRsResourceBase method extractPluginProperties.

protected Iterable<PluginProperty> extractPluginProperties(@Nullable final Iterable<String> pluginProperties, final PluginProperty... additionalProperties) {
    final Collection<PluginProperty> properties = new LinkedList<PluginProperty>();
    if (pluginProperties == null) {
        return properties;
    }
    for (final String pluginProperty : pluginProperties) {
        final List<String> property = ImmutableList.<String>copyOf(pluginProperty.split("="));
        // Skip entries for which there is no value
        if (property.size() == 1) {
            continue;
        }
        final String key = property.get(0);
        // Should we URL decode the value?
        String value = Joiner.on("=").join(property.subList(1, property.size()));
        if (pluginProperty.endsWith("=")) {
            value += "=";
        }
        properties.add(new PluginProperty(key, value, false));
    }
    for (final PluginProperty cur : additionalProperties) {
        properties.add(cur);
    }
    return properties;
}
Also used : PluginProperty(org.killbill.billing.payment.api.PluginProperty) LinkedList(java.util.LinkedList)

Example 15 with PluginProperty

use of org.killbill.billing.payment.api.PluginProperty in project killbill by killbill.

the class PaymentResource method searchPayments.

@TimedResource
@GET
@Path("/" + SEARCH + "/{searchKey:" + ANYTHING_PATTERN + "}")
@Produces(APPLICATION_JSON)
@ApiOperation(value = "Search payments", response = PaymentJson.class, responseContainer = "List")
@ApiResponses(value = {})
public Response searchPayments(@PathParam("searchKey") final String searchKey, @QueryParam(QUERY_SEARCH_OFFSET) @DefaultValue("0") final Long offset, @QueryParam(QUERY_SEARCH_LIMIT) @DefaultValue("100") final Long limit, @QueryParam(QUERY_PAYMENT_PLUGIN_NAME) final String pluginName, @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString, @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode, @QueryParam(QUERY_WITH_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo, @QueryParam(QUERY_WITH_ATTEMPTS) @DefaultValue("false") final Boolean withAttempts, @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
    final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
    final TenantContext tenantContext = context.createContext(request);
    // Search the plugin(s)
    final Pagination<Payment> payments;
    if (Strings.isNullOrEmpty(pluginName)) {
        payments = paymentApi.searchPayments(searchKey, offset, limit, withPluginInfo, withAttempts, pluginProperties, tenantContext);
    } else {
        payments = paymentApi.searchPayments(searchKey, offset, limit, pluginName, withPluginInfo, withAttempts, pluginProperties, tenantContext);
    }
    final URI nextPageUri = uriBuilder.nextPage(PaymentResource.class, "searchPayments", payments.getNextOffset(), limit, ImmutableMap.<String, String>of("searchKey", searchKey, QUERY_PAYMENT_METHOD_PLUGIN_NAME, Strings.nullToEmpty(pluginName), QUERY_AUDIT, auditMode.getLevel().toString()));
    final AtomicReference<Map<UUID, AccountAuditLogs>> accountsAuditLogs = new AtomicReference<Map<UUID, AccountAuditLogs>>(new HashMap<UUID, AccountAuditLogs>());
    return buildStreamingPaginationResponse(payments, new Function<Payment, PaymentJson>() {

        @Override
        public PaymentJson apply(final Payment payment) {
            // Cache audit logs per account
            if (accountsAuditLogs.get().get(payment.getAccountId()) == null) {
                accountsAuditLogs.get().put(payment.getAccountId(), auditUserApi.getAccountAuditLogs(payment.getAccountId(), auditMode.getLevel(), tenantContext));
            }
            final AccountAuditLogs accountAuditLogs = accountsAuditLogs.get().get(payment.getAccountId());
            return new PaymentJson(payment, accountAuditLogs);
        }
    }, nextPageUri);
}
Also used : TenantContext(org.killbill.billing.util.callcontext.TenantContext) AtomicReference(java.util.concurrent.atomic.AtomicReference) URI(java.net.URI) PluginProperty(org.killbill.billing.payment.api.PluginProperty) Payment(org.killbill.billing.payment.api.Payment) PaymentJson(org.killbill.billing.jaxrs.json.PaymentJson) UUID(java.util.UUID) AccountAuditLogs(org.killbill.billing.util.audit.AccountAuditLogs) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap) 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)

Aggregations

PluginProperty (org.killbill.billing.payment.api.PluginProperty)105 UUID (java.util.UUID)45 Account (org.killbill.billing.account.api.Account)42 ApiOperation (io.swagger.annotations.ApiOperation)35 ApiResponses (io.swagger.annotations.ApiResponses)35 Produces (javax.ws.rs.Produces)35 TimedResource (org.killbill.commons.metrics.TimedResource)35 Test (org.testng.annotations.Test)33 Path (javax.ws.rs.Path)32 Payment (org.killbill.billing.payment.api.Payment)30 CallContext (org.killbill.billing.util.callcontext.CallContext)29 ArrayList (java.util.ArrayList)19 LocalDate (org.joda.time.LocalDate)19 Consumes (javax.ws.rs.Consumes)17 BigDecimal (java.math.BigDecimal)16 TenantContext (org.killbill.billing.util.callcontext.TenantContext)15 GET (javax.ws.rs.GET)14 POST (javax.ws.rs.POST)13 DefaultEntitlement (org.killbill.billing.entitlement.api.DefaultEntitlement)13 AccountAuditLogs (org.killbill.billing.util.audit.AccountAuditLogs)13