def make_withdrawal_transfer(transfer_amount, token, send_account, transfer_mode=None, require_sender_approved=True, require_sufficient_balance=True, automatically_resolve_complete=True, uuid=None): """ This is used for a user withdrawing funds from their Sempo wallet. Only interacts with Sempo float. :param transfer_amount: :param token: :param send_account: :param transfer_mode: :param require_sender_approved: :param require_sufficient_balance: :param automatically_resolve_complete: :param uuid: :return: """ transfer = CreditTransfer(transfer_amount, token, sender_user=send_account, uuid=uuid, transfer_type=TransferTypeEnum.WITHDRAWAL) transfer.transfer_mode = transfer_mode if require_sender_approved and not transfer.check_sender_is_approved(): message = "Sender {} is not approved".format(send_account) transfer.resolve_as_rejected(message) raise AccountNotApprovedError(message, is_sender=True) if require_sufficient_balance and not transfer.check_sender_has_sufficient_balance( ): message = "Sender {} has insufficient balance".format(send_account) transfer.resolve_as_rejected(message) raise InsufficientBalanceError(message) if automatically_resolve_complete: transfer.resolve_as_completed() pusher.push_admin_credit_transfer(transfer) return transfer
def make_payment_transfer( transfer_amount, token=None, send_user=None, send_transfer_account=None, receive_user=None, receive_transfer_account=None, transfer_use=None, transfer_mode=None, require_sender_approved=True, require_recipient_approved=True, require_sufficient_balance=True, automatically_resolve_complete=True, uuid=None, transfer_subtype: TransferSubTypeEnum = TransferSubTypeEnum.STANDARD, is_ghost_transfer=False, queue='high-priority'): """ This is used for internal transfers between Sempo wallets. :param transfer_amount: :param token: :param send_user: :param send_transfer_account: :param receive_user: :param receive_transfer_account: :param transfer_use: :param transfer_mode: TransferModeEnum :param require_sender_approved: :param require_recipient_approved: :param require_sufficient_balance: :param automatically_resolve_complete: :param uuid: :param transfer_subtype: accepts TransferSubType str. :param is_ghost_transfer: if an account is created for recipient just to exchange, it's not real :param enable_pusher: :param queue: :return: """ if transfer_subtype is TransferSubTypeEnum.DISBURSEMENT: require_sender_approved = False require_recipient_approved = False require_sufficient_balance = False # primary NGO wallet to disburse from send_transfer_account = receive_user.default_organisation.queried_org_level_transfer_account if transfer_subtype is TransferSubTypeEnum.RECLAMATION: require_sender_approved = False # primary NGO wallet to reclaim to receive_transfer_account = send_user.default_organisation.queried_org_level_transfer_account if transfer_subtype is TransferSubTypeEnum.INCENTIVE: send_transfer_account = receive_transfer_account.get_float_transfer_account( ) transfer = CreditTransfer( transfer_amount, token=token, sender_user=send_user, sender_transfer_account=send_transfer_account, recipient_user=receive_user, recipient_transfer_account=receive_transfer_account, uuid=uuid, transfer_type=TransferTypeEnum.PAYMENT, transfer_subtype=transfer_subtype, transfer_mode=transfer_mode, is_ghost_transfer=is_ghost_transfer) make_cashout_incentive_transaction = False if transfer_use is not None: usages = [] try: use_ids = transfer_use.split(',') # passed as '3,4' etc. except AttributeError: use_ids = transfer_use for use_id in use_ids: if use_id != 'null': use = TransferUsage.query.get(int(use_id)) if use: usages.append(use.name) if use.is_cashout: make_cashout_incentive_transaction = True else: usages.append('Other') transfer.transfer_use = usages transfer.uuid = uuid if require_sender_approved and not transfer.check_sender_is_approved(): message = "Sender {} is not approved".format(send_transfer_account) transfer.resolve_as_rejected(message) raise AccountNotApprovedError(message, is_sender=True) if require_recipient_approved and not transfer.check_recipient_is_approved( ): message = "Recipient {} is not approved".format(receive_user) transfer.resolve_as_rejected(message) raise AccountNotApprovedError(message, is_sender=False) if require_sufficient_balance and not transfer.check_sender_has_sufficient_balance( ): message = "Sender {} has insufficient balance".format( send_transfer_account) transfer.resolve_as_rejected(message) raise InsufficientBalanceError(message) if automatically_resolve_complete: transfer.resolve_as_completed(queue=queue) if make_cashout_incentive_transaction: try: # todo: check limits apply incentive_amount = round( transfer_amount * current_app.config['CASHOUT_INCENTIVE_PERCENT'] / 100) make_payment_transfer( incentive_amount, receive_user=receive_user, transfer_subtype=TransferSubTypeEnum.INCENTIVE, transfer_mode=TransferModeEnum.INTERNAL) except Exception as e: print(e) sentry_sdk.capture_exception(e) return transfer