Пример #1
0
def customer_get(request):
    """Get and return a customer 

    """
    company = auth_api_key(request)
    customer = get_and_check_customer(request, company)
    return customer 
Пример #2
0
def plan_get(request):
    """Get and return a plan 

    """
    company = auth_api_key(request)
    plan = get_and_check_plan(request, company)
    return plan 
Пример #3
0
def subscription_get(request):
    """Get and return a subscription 

    """
    company = auth_api_key(request)
    guid = request.matchdict['subscription_guid']
    subscription = get_and_check_subscription(request, company, guid)
    return subscription 
Пример #4
0
def subscription_get(request):
    """Get and return a subscription 

    """
    company = auth_api_key(request)
    guid = request.matchdict['subscription_guid']
    subscription = get_and_check_subscription(request, company, guid)
    return subscription 
Пример #5
0
def subscription_cancel(request):
    """Cancel a subscription

    """
    # TODO: it appears a DELETE request with body is not a good idea
    # for HTTP protocol as many server doesn't support this, this is why
    # we use another view with post method, maybe we should use a better 
    # approach later
    company = auth_api_key(request)
    form = validate_form(SubscriptionCancelForm, request)

    guid = request.matchdict['subscription_guid']
    prorated_refund = asbool(form.data.get('prorated_refund', False))
    refund_amount = form.data.get('refund_amount')
    maximum_retry = int(request.registry.settings.get(
        'billy.transaction.maximum_retry', 
        TransactionModel.DEFAULT_MAXIMUM_RETRY,
    ))

    model = SubscriptionModel(request.session)
    tx_model = TransactionModel(request.session)
    get_and_check_subscription(request, company, guid)
    subscription = model.get(guid)

    # TODO: maybe we can find a better way to integrate this with the 
    # form validation?
    if refund_amount is not None:
        if subscription.amount is not None:
            amount = subscription.amount
        else:
            amount = subscription.plan.amount
        if refund_amount > amount:
            return form_errors_to_bad_request(dict(
                refund_amount=['refund_amount cannot be greater than '
                               'subscription amount {}'.format(amount)]
            ))

    if subscription.canceled:
        return HTTPBadRequest('Cannot cancel a canceled subscription')

    with db_transaction.manager:
        tx_guid = model.cancel(
            guid, 
            prorated_refund=prorated_refund,
            refund_amount=refund_amount, 
        )
    if tx_guid is not None:
        with db_transaction.manager:
            tx_model.process_transactions(
                processor=request.processor, 
                guids=[tx_guid],
                maximum_retry=maximum_retry,
            )

    subscription = model.get(guid)
    return subscription 
Пример #6
0
def subscription_list_post(request):
    """Create a new subscription 

    """
    company = auth_api_key(request)
    form = validate_form(SubscriptionCreateForm, request)

    customer_guid = form.data['customer_guid']
    plan_guid = form.data['plan_guid']
    amount = form.data.get('amount')
    payment_uri = form.data.get('payment_uri')
    if not payment_uri:
        payment_uri = None
    started_at = form.data.get('started_at')
    maximum_retry = int(request.registry.settings.get(
        'billy.transaction.maximum_retry', 
        TransactionModel.DEFAULT_MAXIMUM_RETRY,
    ))

    model = SubscriptionModel(request.session)
    plan_model = PlanModel(request.session)
    customer_model = CustomerModel(request.session)
    tx_model = TransactionModel(request.session)

    customer = customer_model.get(customer_guid)
    if customer.company_guid != company.guid:
        return HTTPForbidden('Can only subscribe to your own customer')
    if customer.deleted:
        return HTTPBadRequest('Cannot subscript to a deleted customer')
    plan = plan_model.get(plan_guid)
    if plan.company_guid != company.guid:
        return HTTPForbidden('Can only subscribe to your own plan')
    if plan.deleted:
        return HTTPBadRequest('Cannot subscript to a deleted plan')

    # create subscription and yield transactions
    with db_transaction.manager:
        guid = model.create(
            customer_guid=customer_guid, 
            plan_guid=plan_guid, 
            amount=amount, 
            payment_uri=payment_uri,
            started_at=started_at, 
        )
        tx_guids = model.yield_transactions([guid])
    # this is not a deferred subscription, just process transactions right away
    if started_at is None:
        with db_transaction.manager:
            tx_model.process_transactions(
                processor=request.processor, 
                guids=tx_guids,
                maximum_retry=maximum_retry,
            )

    subscription = model.get(guid)
    return subscription
Пример #7
0
def subscription_cancel(request):
    """Cancel a subscription

    """
    # TODO: it appears a DELETE request with body is not a good idea
    # for HTTP protocol as many server doesn't support this, this is why
    # we use another view with post method, maybe we should use a better 
    # approach later
    company = auth_api_key(request)
    form = validate_form(SubscriptionCancelForm, request)

    guid = request.matchdict['subscription_guid']
    prorated_refund = asbool(form.data.get('prorated_refund', False))
    refund_amount = form.data.get('refund_amount')
    maximum_retry = int(request.registry.settings.get(
        'billy.transaction.maximum_retry', 
        TransactionModel.DEFAULT_MAXIMUM_RETRY,
    ))

    model = SubscriptionModel(request.session)
    tx_model = TransactionModel(request.session)
    get_and_check_subscription(request, company, guid)

    # TODO: maybe we can find a better way to integrate this with the 
    # form validation?
    if refund_amount is not None:
        subscription = model.get(guid)
        if subscription.amount is not None:
            amount = subscription.amount
        else:
            amount = subscription.plan.amount
        if refund_amount > amount:
            return form_errors_to_bad_request(dict(
                refund_amount=['refund_amount cannot be greater than '
                               'subscription amount {}'.format(amount)]
            ))

    # TODO: make sure the subscription is not already canceled

    with db_transaction.manager:
        tx_guid = model.cancel(
            guid, 
            prorated_refund=prorated_refund,
            refund_amount=refund_amount, 
        )
    if tx_guid is not None:
        with db_transaction.manager:
            tx_model.process_transactions(
                processor=request.processor, 
                guids=[tx_guid],
                maximum_retry=maximum_retry,
            )

    subscription = model.get(guid)
    return subscription 
Пример #8
0
def plan_delete(request):
    """Delete a plan

    """
    company = auth_api_key(request)
    model = PlanModel(request.session)
    plan = get_and_check_plan(request, company)
    if plan.deleted:
        return HTTPBadRequest('Plan {} was already deleted'.format(plan.guid))
    with db_transaction.manager:
        model.delete(plan.guid)
    plan = model.get(plan.guid)
    return plan 
Пример #9
0
def company_get(request):
    """Get and return a company

    """
    api_company = auth_api_key(request)
    model = CompanyModel(request.session)
    guid = request.matchdict['company_guid']
    company = model.get(guid)
    if company is None:
        return HTTPNotFound('No such company {}'.format(guid))
    if guid != api_company.guid:
        return HTTPForbidden('You have no premission to access company {}'.format(guid))
    return company
Пример #10
0
def subscription_list_post(request):
    """Create a new subscription 

    """
    company = auth_api_key(request)
    form = validate_form(SubscriptionCreateForm, request)

    customer_guid = form.data['customer_guid']
    plan_guid = form.data['plan_guid']
    amount = form.data.get('amount')
    payment_uri = form.data.get('payment_uri')
    started_at = form.data.get('started_at')
    maximum_retry = int(request.registry.settings.get(
        'billy.transaction.maximum_retry', 
        TransactionModel.DEFAULT_MAXIMUM_RETRY,
    ))

    model = SubscriptionModel(request.session)
    plan_model = PlanModel(request.session)
    customer_model = CustomerModel(request.session)
    tx_model = TransactionModel(request.session)

    customer = customer_model.get(customer_guid)
    if customer.company_guid != company.guid:
        return HTTPForbidden('Can only subscribe to your own customer')
    plan = plan_model.get(plan_guid)
    if plan.company_guid != company.guid:
        return HTTPForbidden('Can only subscribe to your own plan')
    # TODO: make sure user cannot subscribe to a deleted plan or customer

    # create subscription and yield transactions
    with db_transaction.manager:
        guid = model.create(
            customer_guid=customer_guid, 
            plan_guid=plan_guid, 
            amount=amount, 
            payment_uri=payment_uri,
            started_at=started_at, 
        )
        tx_guids = model.yield_transactions([guid])
    # this is not a deferred subscription, just process transactions right away
    if started_at is None:
        with db_transaction.manager:
            tx_model.process_transactions(
                processor=request.processor, 
                guids=tx_guids,
                maximum_retry=maximum_retry,
            )

    subscription = model.get(guid)
    return subscription
Пример #11
0
def plan_get(request):
    """Get and return a plan 

    """
    company = auth_api_key(request)
    model = PlanModel(request.session)
    guid = request.matchdict['plan_guid']
    plan = model.get(guid)
    if plan is None:
        return HTTPNotFound('No such plan {}'.format(guid))
    if plan.company_guid != company.guid:
        return HTTPForbidden(
            'You have no permission to access plan {}'.format(guid))
    return plan
Пример #12
0
def customer_delete(request):
    """Delete and return customer

    """
    company = auth_api_key(request)
    model = CustomerModel(request.session)
    customer = get_and_check_customer(request, company)
    if customer.deleted:
        return HTTPBadRequest('Customer {} was already deleted'
                              .format(customer.guid))
    with db_transaction.manager:
        model.delete(customer.guid)
    customer = model.get(customer.guid)
    return customer
Пример #13
0
def transaction_get(request):
    """Get and return a transaction 

    """
    company = auth_api_key(request)
    model = TransactionModel(request.session)
    guid = request.matchdict['transaction_guid']
    transaction = model.get(guid)
    if transaction is None:
        return HTTPNotFound('No such transaction {}'.format(guid))
    if transaction.subscription.customer.company_guid != company.guid:
        return HTTPForbidden('You have no permission to access transaction {}'
                             .format(guid))
    return transaction 
Пример #14
0
def company_get(request):
    """Get and return a company

    """
    api_company = auth_api_key(request)
    model = CompanyModel(request.session)
    guid = request.matchdict['company_guid']
    company = model.get(guid)
    if company is None:
        return HTTPNotFound('No such company {}'.format(guid))
    if guid != api_company.guid:
        return HTTPForbidden(
            'You have no premission to access company {}'.format(guid))
    return company
Пример #15
0
def customer_get(request):
    """Get and return a customer 

    """
    company = auth_api_key(request)
    model = CustomerModel(request.session)
    guid = request.matchdict['customer_guid']
    customer = model.get(guid)
    if customer is None:
        return HTTPNotFound('No such customer {}'.format(guid))
    if customer.company_guid != company.guid:
        return HTTPForbidden('You have no permission to access customer {}'
                             .format(guid))
    return customer 
Пример #16
0
def plan_get(request):
    """Get and return a plan 

    """
    company = auth_api_key(request)
    model = PlanModel(request.session)
    guid = request.matchdict['plan_guid']
    plan = model.get(guid)
    if plan is None:
        return HTTPNotFound('No such plan {}'.format(guid))
    if plan.company_guid != company.guid:
        return HTTPForbidden('You have no permission to access plan {}'
                             .format(guid))
    return plan 
Пример #17
0
def transaction_get(request):
    """Get and return a transaction 

    """
    company = auth_api_key(request)
    model = TransactionModel(request.session)
    guid = request.matchdict['transaction_guid']
    transaction = model.get(guid)
    if transaction is None:
        return HTTPNotFound('No such transaction {}'.format(guid))
    if transaction.subscription.customer.company_guid != company.guid:
        return HTTPForbidden(
            'You have no permission to access transaction {}'.format(guid))
    return transaction
Пример #18
0
def plan_list_post(request):
    """Create a new plan 

    """
    company = auth_api_key(request)
    form = validate_form(PlanCreateForm, request)
    
    plan_type = form.data['plan_type']
    amount = form.data['amount']
    frequency = form.data['frequency']
    interval = form.data['interval']
    if interval is None:
        interval = 1
    company_guid = company.guid

    # TODO: make sure user cannot create a post to a deleted company

    model = PlanModel(request.session)
    type_map = dict(
        charge=model.TYPE_CHARGE,
        payout=model.TYPE_PAYOUT,
    )
    plan_type = type_map[plan_type]
    freq_map = dict(
        daily=model.FREQ_DAILY,
        weekly=model.FREQ_WEEKLY,
        monthly=model.FREQ_MONTHLY,
        yearly=model.FREQ_YEARLY,
    )
    frequency = freq_map[frequency]

    with db_transaction.manager:
        guid = model.create(
            company_guid=company_guid, 
            plan_type=plan_type,
            amount=amount, 
            frequency=frequency, 
            interval=interval, 
        )
    plan = model.get(guid)
    return plan 
Пример #19
0
def plan_list_post(request):
    """Create a new plan 

    """
    company = auth_api_key(request)
    form = validate_form(PlanCreateForm, request)

    plan_type = form.data['plan_type']
    amount = form.data['amount']
    frequency = form.data['frequency']
    interval = form.data['interval']
    if interval is None:
        interval = 1
    company_guid = company.guid

    # TODO: make sure user cannot create a post to a deleted company

    model = PlanModel(request.session)
    type_map = dict(
        charge=model.TYPE_CHARGE,
        payout=model.TYPE_PAYOUT,
    )
    plan_type = type_map[plan_type]
    freq_map = dict(
        daily=model.FREQ_DAILY,
        weekly=model.FREQ_WEEKLY,
        monthly=model.FREQ_MONTHLY,
        yearly=model.FREQ_YEARLY,
    )
    frequency = freq_map[frequency]

    with db_transaction.manager:
        guid = model.create(
            company_guid=company_guid,
            plan_type=plan_type,
            amount=amount,
            frequency=frequency,
            interval=interval,
        )
    plan = model.get(guid)
    return plan
Пример #20
0
def customer_list_post(request):
    """Create a new customer 

    """
    company = auth_api_key(request)
    form = validate_form(CustomerCreateForm, request)
    
    external_id = form.data.get('external_id')
    company_guid = company.guid

    # TODO: make sure user cannot create a customer to a deleted company

    model = CustomerModel(request.session)
    # TODO: do validation here
    with db_transaction.manager:
        guid = model.create(
            external_id=external_id,
            company_guid=company_guid, 
        )
    customer = model.get(guid)
    return customer 
Пример #21
0
def subscription_transaction_list(request):
    """Get and return transactions of subscription

    """
    company = auth_api_key(request)

    offset = int(request.params.get('offset', 0))
    limit = int(request.params.get('limit', 20))
    guid = request.matchdict['subscription_guid']

    tx_model = TransactionModel(request.session)
    subscription = get_and_check_subscription(request, company, guid)

    transactions = tx_model.list_by_subscription_guid(
        subscription_guid=subscription.guid,
        offset=offset,
        limit=limit,
    )
    result = dict(
        items=list(transactions),
        offset=offset,
        limit=limit,
    )
    return result
Пример #22
0
def subscription_transaction_list(request):
    """Get and return transactions of subscription

    """
    company = auth_api_key(request)

    offset = int(request.params.get('offset', 0))
    limit = int(request.params.get('limit', 20))
    guid = request.matchdict['subscription_guid']

    tx_model = TransactionModel(request.session)
    subscription = get_and_check_subscription(request, company, guid)

    transactions = tx_model.list_by_subscription_guid(
        subscription_guid=subscription.guid,
        offset=offset,
        limit=limit,
    )
    result = dict(
        items=list(transactions),
        offset=offset,
        limit=limit,
    )
    return result