def _assert_no_duplicate_submerchant(self, user_id): """ Handles asserting that a user doesn't already have a submerchant. :param str user_id: The user's UUID :raises: FacadeException """ try: UserDAO().get(user_id) except DAOException as e: logging.warning( 'Requested user {0} does not exist with exception: {1}'.format( user_id, e, )) raise FacadeException('Requested user does not exist.') merchant_dao = MerchantDAO() found_submerchant = merchant_dao.get_submerchant_by_id(user_id) if found_submerchant is not None: logging.warning( 'Attempted duplicate submerchant for user: {0}'.format( user_id, )) raise FacadeException( 'You already have a submerchant account created.')
def regenerate_reset_password_token(self, email): """ Regenerates a reset password token and sends another email. :param str email: The email of the user who forgot/lost their reset password email token. :rtype: str :return: The newly generated token. """ try: new_token, user = UserDAO().regenerate_token(email, 'reset_token') MailQueueDAO().push_to_queue( '*****@*****.**', user.email, 'Please verify your account', """ Your new account at Kronikl.io is now available. Please go to <a href="http://{0}/#/reset_password/{1}">Reset my Password</a> to activate your account. """.format( 'localhost:8080' if current_app.config['ENVIRONMENT'] == 'Dev' else 'app.kronikl.io', new_token)) return new_token except DAOException as e: logging.error( 'Failed to regenerate reset token with exception: {0}'.format( e)) raise FacadeException('Failed to regenerate reset token.', e.status_code)
def create_new_event( self, scheduling_user_id, scheduled_user_id, localized_start_time, localized_end_time, local_tz, notes, nonce, address_id=None, ): """ Handles creation of a new event and payment processing. :param str scheduling_user_id: The user who is booking another's time :param str scheduled_user_id: Their time is being booked. :param datetime.datetime localized_start_time: Localized start :param datetime.datetime localized_end_time: The localized end :param str local_tz: The timezone which this was booked in. :param str notes: Any additional notes to add onto the event. :param str nonce: The nonce which determines the payment method being used. :param str address_id: An address to be used whenever billing. If not provided, then we attempt to find a default address. :rtype: EventTable :return: The newly created event. """ if address_id is None: address = AddressDAO().get_default_for_user(scheduling_user_id) else: address = AddressDAO().get_by_public_id(address_id, scheduling_user_id) try: new_event = EventDAO().create_new_event(scheduling_user_id, scheduled_user_id, localized_start_time, localized_end_time, local_tz, notes, skip_commit=True) BraintreePaymentFacade().issue_new_payment(new_event, nonce, address) except IntegrationException as e: db.session.rollback() logging.error('Failed to create new transaction with exc of {0}.' 'Rolling back event creation for event {1}'.format( e, new_event.public_id)) raise FacadeException('Failed to finish sale.') except DAOException as e: raise e return new_event
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 create_submerchant(self, submerchant_info, user_id, *, skip_commit=False): """ Handles creation of the submerchant. :param dict submerchant_info: The information to be used in submerchant creation. :param str user_id: The user's UUID. :param bool skip_commit: Handles skipping commit if desired. :rtype: dict :return: The submerchant's info. """ self._assert_no_duplicate_submerchant(user_id) merchant_dao = MerchantDAO() account_id = self._make_account_id() master_account_id = merchant_dao.get_master_merchant().account_id submerchant_info['master_merchant_account_id'] = master_account_id submerchant_info['id'] = self._make_account_id() register_as_business = submerchant_info['register_as_business'] result = BraintreeSubmerchant().create_submerchant(submerchant_info) if not result.is_success: logging.info( 'Failed to create submerchant under master merchant {0} ' '-- {1} error: {2}'.format(account_id, submerchant_info, result)) raise FacadeException( 'Failed to create submerchant. {0}'.format(result)) merchant_dao.create_submerchant(submerchant_info, register_as_business, user_id, skip_commit=skip_commit) return submerchant_info
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 issue_new_payment(self, event, nonce, address): """ Issues a new payment w/in Braintree. :param EventTable event: The event that must be paid for. :param str nonce: The nonce which signifies which payment method is to be used. :param AddressTable address: The address information to be used whenever issuing a payment. :rtype: PaymentTable :return: The newly created payment. """ try: submerchant = MerchantDAO().get_submerchant_by_id( event.scheduled_user_id) except DAOException as e: logging.error('Invalid event ({0}) issued, no submerchant ' '({1}). Exception of: {2}.'.format( event.public_id, event.scheduled_user_id, e, )) raise DAOException(e) if submerchant is None: logging.error( 'Failed to retrieve submerchant by public ID {0} for a new ' 'event.'.format(event.scheduled_user_id)) raise FacadeException('Invalid requested user. Contact support.') try: # TODO(ian): This can be refactored to use # EventDAO().get_event_by_id and retrieve all the info in 1 query. new_transaction = BraintreeTransactions().create_transaction( submerchant, event.calculate_total_price( event.duration, UserDAO().get(event.scheduled_user_id), ), nonce, UserDAO().get(event.scheduling_user_id), address, ) if isinstance(new_transaction, ErrorResult): logging.error('Received error result {0} when creating new ' 'transaction for event {1}'.format( new_transaction, event)) raise FacadeException('Failed to complete transaction.') return BraintreePaymentsDAO().insert_new_transaction( submerchant, event.total_price, event.calculate_service_fee(submerchant), event, skip_commit=True, ) except Exception as e: db.session.rollback() logging.error( 'Exception encountered while creating and inserting ' 'transaction: {0}.'.format(e), ) raise FacadeException(e)