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 get_and_check_plan(request, company): """Get and check permission to access a plan """ model = PlanModel(request.session) guid = request.matchdict['plan_guid'] plan = model.get(guid) if plan is None: raise HTTPNotFound('No such plan {}'.format(guid)) if plan.company_guid != company.guid: raise HTTPForbidden('You have no permission to access plan {}' .format(guid)) return plan
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 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 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 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 test_plan(self): from billy.models.plan import PlanModel from billy.renderers import plan_adapter plan_model = PlanModel(self.testapp.session) plan = plan_model.get(self.plan_guid) json_data = plan_adapter(plan, self.dummy_request) expected = dict( guid=plan.guid, plan_type='charge', frequency='weekly', amount=plan.amount, interval=plan.interval, created_at=plan.created_at.isoformat(), updated_at=plan.updated_at.isoformat(), company_guid=plan.company_guid, deleted=plan.deleted, ) self.assertEqual(json_data, expected) def assert_type(plan_type, expected_type): plan.plan_type = plan_type json_data = plan_adapter(plan, self.dummy_request) self.assertEqual(json_data['plan_type'], expected_type) assert_type(PlanModel.TYPE_CHARGE, 'charge') assert_type(PlanModel.TYPE_PAYOUT, 'payout') def assert_frequency(frequency, expected_frequency): plan.frequency = frequency json_data = plan_adapter(plan, self.dummy_request) self.assertEqual(json_data['frequency'], expected_frequency) assert_frequency(PlanModel.FREQ_DAILY, 'daily') assert_frequency(PlanModel.FREQ_WEEKLY, 'weekly') assert_frequency(PlanModel.FREQ_MONTHLY, 'monthly') assert_frequency(PlanModel.FREQ_YEARLY, 'yearly')