def customer_get(request): """Get and return a customer """ company = auth_api_key(request) customer = get_and_check_customer(request, company) return customer
def plan_get(request): """Get and return a plan """ company = auth_api_key(request) plan = get_and_check_plan(request, company) return plan
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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