class CustomerFacade(object): """ Acts as a facade to handle Braintree customers. """ def __init__(self): self.customer_dao = CustomerDAO() self.customer_integration = BraintreeCustomer() def create_customer(self, nonce, first_name, last_name, user_id, *, make_default=False, skip_commit=False): """ Handles creating a customer account with a unique identifier and a payment method. :param str nonce: A nonce identifying a card -- created by BT hosted fields on the FE. :param str first_name: The customer's first name. :param str last_name: The customer's last name. :param str user_id: The user's unique UUID. :param bool make_default: If a user specifies to make this their default payment method, we want to assign that value. :param bool skip_commit: Should we skip committing? Facades on facades :rtype: CustomerTable :return: The newly created customer. """ customer_token = str(uuid.uuid4()) new_customer = self.customer_integration.create_customer( nonce, customer_token, first_name, last_name, user_id, make_default=make_default) return self.customer_dao.create_customer( "bt_customer_id", "cc_token", first_name, last_name, user_id, skip_commit=skip_commit, ) def delete_customer(self): pass
def setUpClass(cls): with app.app_context(): db.drop_all() db.create_all() cls.test_dao = CustomerDAO()
def __init__(self): self.customer_facade = CustomerFacade() self.customer_dao = CustomerDAO() self.subscription_integration = BraintreeSubscription() self.user_dao = UserDAO() self.subscription_dao = SubscriptionDAO()
class SubscriptionFacade(object): """ Acts as a facade to handle Braintree submerchants. """ def __init__(self): self.customer_facade = CustomerFacade() self.customer_dao = CustomerDAO() self.subscription_integration = BraintreeSubscription() self.user_dao = UserDAO() self.subscription_dao = SubscriptionDAO() def create_new_subscription_with_customer( self, user_id, nonce, first_name, last_name, *, skip_commit=True, plan_id='Basic0x01'): """ Handles creating a new customer with a new subscription. :param str user_id: The user to create the customer and subscription for. :param str nonce: A nonce identifying a card -- created by BT hosted fields on the FE. :param str first_name: The user's first name. :param str last_name: The user's last name. :param bool skip_commit: Should we skip committing? Facades on facades :param str plan_id: The plan ID. Don't touch! :rtype: SubscriptionTable :return: The newly created subscription. """ found_customer = self._customer_exists(user_id) if found_customer: return self.create_new_subscription( user_id, skip_commit=skip_commit, plan_id=plan_id, ) try: # type: CustomerTable new_customer = self.customer_facade.create_customer( nonce, first_name, last_name, user_id, skip_commit=skip_commit ) sub_id = uuid.uuid4() new_subscription = self.subscription_integration.start_subscription( sub_id, new_customer.credit_card_token, plan_id, ) self.subscription_dao.create_subscription( sub_id, user_id, skip_commit=skip_commit, ) db.session.commit() return new_subscription except Exception as e: logging.error( 'Failed to create new customer for user {0} with ' 'exception {1}'.format( user_id, e, ) ) db.session.rollback() raise FacadeException( 'Failed to start subscription.' ) def cancel_subscription(self, user_id, *, skip_commit=False): """ Handles cancelling the currently running subscription for the user :param str user_id: The user to cancel the subscription for. :param bool skip_commit: Should we skip committing? Facades on facades :rtype: CustomerTable :return: The newly created customer. """ return self.subscription_dao.cancel_subscription( user_id, ) def create_new_subscription(self, user_id, *, skip_commit=False, plan_id='Basic0x01'): """ Handles creating a new subscription for an existing customer account. :param str user_id: The user to create the subscription for. :param bool skip_commit: Should we skip committing? Facades on facades :param str plan_id: The plan ID. Don't touch! :rtype: SubscriptionTable :return: The newly created subscription. """ try: found_customer = self.customer_dao.get_customer_by_user_id(user_id) unique_id = uuid.uuid4() new_subscription = self.subscription_integration.start_subscription( unique_id, found_customer.credit_card_token, plan_id, ) self.subscription_dao.create_subscription( unique_id, user_id, skip_commit=skip_commit, ) db.session.commit() return new_subscription except Exception as e: logging.error( 'Failed to create new subscription for user {0} with ' 'exception {1} for pre-existing customer.'.format( user_id, e, ) ) db.session.rollback() raise FacadeException( 'Failed to start subscription.' ) def _customer_exists(self, user_id): try: return self.customer_dao.get_customer_by_user_id(user_id) except DAOException as e: return False
def __init__(self): self.customer_dao = CustomerDAO() self.customer_integration = BraintreeCustomer()
def __init__(self): self.customer_dao = CustomerDAO()
class SubscriptionDAO(BaseDAO): """ Handles mirroring braintree customer operations in our database. """ def __init__(self): self.customer_dao = CustomerDAO() def get_subscription_by_user_id(self, user_id): """ Handles retrieving a subscription for the user. :param str user_id: The customer's UUID. :rtype: SubscriptionTable :return: The requested subscription. """ found_subscription = db.session.query( Subscription, ).filter( Subscription.user_id == user_id, ).first() if found_subscription is None: logging.error( 'Failed to retrieve subscription by User ID {0}'.format( user_id, ) ) raise DAOException('Failed to retrieve subscription info.') return found_subscription def get_subscription_by_public_id(self, subscription_public_id): """ Handles retrieving a subscription by it's public ID. :param str subscription_public_id: The public ID for the customer :rtype: SubscriptionTable :return: The requested subscription. """ found_subscription = db.session.query( Subscription ).filter_by( public_id=subscription_public_id ).first() if found_subscription is None: logging.error( 'Failed to retrieve subscription by ID {0}'.format( subscription_public_id, ) ) raise DAOException('Failed to retrieve selected subscription.') return found_subscription def create_subscription(self, bt_sub_id, user_id, *, plan_id='Basic0x01', skip_commit=False): """ Handles creating a subscription record in the db. :param str bt_sub_id: The unique identifier generated by braintree when subscriptions are created. :param str user_id: The customer's UUID. :param str plan_id: The plan we want to subscribe to. :param bool skip_commit: Handles skipping the commit to create a pseudo transaction. :rtype: SubscriptionTable :return: The newly created subscription """ new_subscription = Subscription( self.customer_dao.get_customer_by_user_id(user_id).public_id, user_id, bt_sub_id, plan_id=plan_id, ) try: exec_and_commit( db.session.add, new_subscription, skip_commit=skip_commit, ) except Exception as e: logging.critical( 'Failed to create a new subscription in our database: {0} with' 'exception of: {1}'.format( new_subscription, e, ) ) raise DAOException( 'Failed to create new subscription.' ) return new_subscription def cancel_subscription(self, user_id): """ Handles cancelling a subscription for the user. :param str user_id: The customer whom we want to cancel the subscription for. :rtype: SubscriptionTable :return: The recently cancelled subscription """ found_subscription = self.get_subscription_by_user_id(user_id) if found_subscription is None: raise DAOException( 'Subscription not found.', status_code=HTTPStatus.NOT_FOUND ) db.session.query( Subscription ).filter_by( public_id=found_subscription.public_id, ).update({ 'is_deleted': True, 'date_ended': datetime.utcnow(), }) try: db.session.commit() except sqlalchemy.exc.IntegrityError as e: logging.error( 'Failed to remove subscription for user {0} with ' 'exc: {1}'.format( user_id, e, ) ) raise DAOException('Failed to cancel subscription.') return found_subscription