Beispiel #1
0
def transfer(source,
             destination,
             amount,
             parent=None,
             user=None,
             merchant_reference=None,
             description=None):
    """
    Transfer funds between source and destination accounts.

    Will raise a accounts.exceptions.AccountException if anything goes wrong.

    :source: Account to debit
    :destination: Account to credit
    :amount: Amount to transfer
    :parent: Parent transfer to reference
    :user: Authorising user
    :merchant_reference: An optional merchant ref associated with this transfer
    :description: Description of transaction
    """
    if source.id == destination.id:
        raise exceptions.AccountException(
            "The source and destination accounts for a transfer "
            "must be different.")
    msg = "Transfer of %.2f from account #%d to account #%d" % (
        amount, source.id, destination.id)
    if user:
        msg += " authorised by user #%d (%s)" % (user.id, user.get_username())
    if description:
        msg += " '%s'" % description
    try:
        transfer = Transfer.objects.create(source, destination, amount, parent,
                                           user, merchant_reference,
                                           description)

        for transaction in transfer.transactions.all():
            AccountDispatcher().send_email_for_transaction(
                transaction=transaction, extra_context=None)

    except exceptions.AccountException as e:
        logger.warning("%s - failed: '%s'", msg, e)
        raise
    except Exception as e:
        logger.error("%s - failed: '%s'", msg, e)
        raise exceptions.AccountException("Unable to complete transfer: %s" %
                                          e)
    else:
        logger.info("%s - successful, transfer: %s", msg, transfer.reference)
        return transfer
Beispiel #2
0
def reverse(transfer, user=None, merchant_reference=None, description=None):
    """
    Reverse a previous transfer, returning the money to the original source.
    """
    msg = "Reverse of transfer #%d" % transfer.id
    if user:
        msg += " authorised by user #%d (%s)" % (user.id, user.get_username())
    if description:
        msg += " '%s'" % description
    try:
        transfer = Transfer.objects.create(
            source=transfer.destination,
            destination=transfer.source,
            amount=transfer.amount,
            user=user,
            merchant_reference=merchant_reference,
            description=description)
    except exceptions.AccountException as e:
        logger.warning("%s - failed: '%s'", msg, e)
        raise
    except Exception as e:
        logger.error("%s - failed: '%s'", msg, e)
        raise exceptions.AccountException("Unable to reverse transfer: %s" % e)
    else:
        logger.info("%s - successful, transfer: %s", msg, transfer.reference)
        return transfer
Beispiel #3
0
 def verify_transfer(self, source, destination, amount, user=None):
     """
     Test whether the proposed transaction is permitted.  Raise an exception
     if not.
     """
     if amount <= 0:
         raise exceptions.InvalidAmount("Debits must use a positive amount")
     if not source.is_open():
         raise exceptions.ClosedAccount("Source account has been closed")
     if not source.can_be_authorised_by(user):
         raise exceptions.AccountException(
             "This user is not authorised to make transfers from " "this account"
         )
     if not destination.is_open():
         raise exceptions.ClosedAccount("Destination account has been closed")
     if not source.is_debit_permitted(amount):
         msg = "Unable to debit %.2f from account #%d:"
         raise exceptions.InsufficientFunds(msg % (amount, source.id))