Example #1
0
    def from_data(data):
        """Return a DebitNote that has been extracted from the passed
           json-decoded dictionary

           Args:
                data (dict): Dictionary from which to create object
           Returns:
                DebitNote: Created from dictionary
        """
        d = DebitNote()

        if (data and len(data) > 0):
            from Acquire.Accounting import Transaction as _Transaction
            from Acquire.Identity import Authorisation as _Authorisation
            from Acquire.ObjectStore import string_to_datetime \
                as _string_to_datetime

            d._transaction = _Transaction.from_data(data["transaction"])
            d._account_uid = data["account_uid"]
            d._authorisation = _Authorisation.from_data(data["authorisation"])
            d._is_provisional = data["is_provisional"]
            d._datetime = _string_to_datetime(data["datetime"])
            d._uid = data["uid"]

            if d._is_provisional:
                d._receipt_by = _string_to_datetime(data["receipt_by"])

        return d
Example #2
0
def test_transaction_saving(random_transaction):
    t = random_transaction

    data = t.to_data()
    t2 = Transaction.from_data(data)

    assert (t.value() == t2.value())
    assert (t.description() == t2.description())
    assert (t == t2)
Example #3
0
def run(args):
    """This function is called to handle requests from a user to deposit
       more funds into their account. This will add this deposit as a
       debt for the user. Once the debt exceeds a certain value, then the
       backend-payment system will charge the user's real account to
       recover the funds

       Args:
            args (dict): data for deposit of funds into the account

        Returns:
            dict: contains status, status message and details regarding
                the deposit into the account and invoice data
    """

    transaction_records = None
    invoice_value = None
    invoice_user = None

    try:
        authorisation = Authorisation.from_data(args["authorisation"])
    except:
        authorisation = None

    transaction = Transaction.from_data(args["transaction"])

    if authorisation is None:
        raise PermissionError("You must supply a valid authorisation "
                              "to deposit funds into your account")

    if transaction is None or transaction.is_null():
        raise ValueError("You must supply a valid transaction that "
                         "represents the deposit")

    try:
        account_name = str(args["account_name"])
    except:
        account_name = "deposits"

    if transaction.value() > 0:
        user_guid = authorisation.user_guid()

        # load the account from which the transaction will be performed
        bucket = get_service_account_bucket()
        accounts = Accounts(user_guid=user_guid)

        # deposits are made by transferring funds from the user's
        # 'billing' account to their named account (or 'deposits' account)
        deposit_account = accounts.create_account(account_name,
                                                  "Deposit account",
                                                  bucket=bucket)

        billing_account = accounts.create_account("billing",
                                                  "Billing account",
                                                  overdraft_limit=150,
                                                  bucket=bucket)

        billing_balance = billing_account.balance() - transaction.value()

        if billing_balance.balance() < -50.0:
            # there are sufficient funds that need to be transferred that
            # it is worth really charging the user
            invoice_user = user_guid
            invoice_value = billing_balance

        # we have enough information to perform the transaction
        transaction_records = Ledger.perform(transactions=transaction,
                                             debit_account=billing_account,
                                             credit_account=deposit_account,
                                             authorisation=authorisation,
                                             is_provisional=False,
                                             bucket=bucket)

    return_value = {}

    if transaction_records:
        try:
            transaction_records[0]
        except:
            transaction_records = [transaction_records]

        for i in range(0, len(transaction_records)):
            transaction_records[i] = transaction_records[i].to_data()

        return_value["transaction_records"] = transaction_records

    if invoice_user:
        return_value["invoice_user"] = invoice_user
        return_value["invoice_value"] = str(invoice_value)

    return return_value
Example #4
0
def run(args):
    """This function is called to handle requests to perform transactions
       between accounts

       Args:
            args (dict): data for account transfers

        Returns:
            dict: contains status, status message and transaction
            records if any are available
    """

    transaction_records = None

    try:
        debit_account_uid = str(args["debit_account_uid"])
    except:
        debit_account_uid = None

    try:
        credit_account_uid = str(args["credit_account_uid"])
    except:
        credit_account_uid = None

    try:
        authorisation = Authorisation.from_data(args["authorisation"])
    except:
        authorisation = None

    try:
        transaction = Transaction.from_data(args["transaction"])
    except:
        transaction = None

    try:
        is_provisional = bool(args["is_provisional"])
    except:
        is_provisional = None

    if debit_account_uid is None:
        raise TransactionError("You must supply the account UID "
                               "for the debit account")

    if credit_account_uid is None:
        raise TransactionError("You must supply the account UID "
                               "for the credit account")

    if debit_account_uid == credit_account_uid:
        raise TransactionError(
            "You cannot perform a transaction where the debit and credit "
            "accounts are the same!")

    if transaction is None or transaction.is_null():
        raise TransactionError("You must supply a valid transaction to "
                               "perform!")

    if is_provisional is None:
        raise TransactionError("You must say whether or not the "
                               "transaction is provisional using "
                               "is_provisional")

    if authorisation is None:
        raise PermissionError("You must supply a valid authorisation "
                              "to perform transactions between accounts")

    authorisation.assert_once()
    user_guid = authorisation.user_guid()

    # load the account from which the transaction will be performed
    bucket = get_service_account_bucket()
    debit_account = Account(uid=debit_account_uid, bucket=bucket)

    # validate that this account is in a group that can be authorised
    # by the user - This should eventually go as this is all
    # handled by the ACLs
    if not Accounts(user_guid).contains(account=debit_account,
                                        bucket=bucket):
        raise PermissionError(
            "The user with GUID '%s' cannot authorise transactions from "
            "the account '%s' as they do not own this account." %
            (user_guid, str(debit_account)))

    # now load the two accounts involved in the transaction
    credit_account = Account(uid=credit_account_uid, bucket=bucket)

    # we have enough information to perform the transaction
    transaction_records = Ledger.perform(transactions=transaction,
                                         debit_account=debit_account,
                                         credit_account=credit_account,
                                         authorisation=authorisation,
                                         is_provisional=is_provisional,
                                         bucket=bucket)

    return_value = {}

    if transaction_records:
        try:
            transaction_records[0]
        except:
            transaction_records = [transaction_records]

        for i in range(0, len(transaction_records)):
            transaction_records[i] = transaction_records[i].to_data()

        return_value["transaction_records"] = transaction_records

    return return_value