Example #1
0
def _portfolio_data(nodes, date, ledger, include_children):
    """
    Turn a portfolio of tree nodes into querytable-style data.

    Args:
        nodes: Account tree nodes.
        date: Date.
    Return:
        types: Tuples of column names and types as strings.
        rows: Dictionaries of row data by column names.
    """
    operating_currency = ledger.options["operating_currency"][0]
    acct_type = ("account", str(str))
    bal_type = ("balance", str(Decimal))
    alloc_type = ("allocation %", str(Decimal))
    types = [acct_type, bal_type, alloc_type]

    rows = []
    for node in nodes:
        row = {}
        row["account"] = node.name
        balance = cost_or_value(node.balance_children,
                                date) if include_children else cost_or_value(
                                    node.balance, date)
        if operating_currency in balance:
            row["balance"] = balance[operating_currency]
            rows.append(row)

    portfolio_total = sum(row['balance'] for row in rows)
    for row in rows:
        if "balance" in row:
            row["allocation %"] = round(
                (row["balance"] / portfolio_total) * 100, 1)

    return types, rows
Example #2
0
def _serialize_account_node(node, date):
    children = [
        _serialize_account_node(account, date) for account in node.children
    ]
    return {
        'account': node.name,
        'balance_children': cost_or_value(node.balance_children, date),
        'balance': cost_or_value(node.balance, date),
        'children': children,
    }
Example #3
0
def _serialize_account_node(node, date):
    children = [
        _serialize_account_node(account, date) for account in node.children
    ]
    return {
        "account": node.name,
        "balance_children": cost_or_value(node.balance_children, date),
        "balance": cost_or_value(node.balance, date),
        "children": children,
    }
Example #4
0
def _serialize_account_node(node, date):
    children = [
        _serialize_account_node(account, date)
        for account in node.children
    ]
    return {
        'account': node.name,
        'balance_children': cost_or_value(node.balance_children, date),
        'balance': cost_or_value(node.balance, date),
        'children': children,
    }
Example #5
0
    def serialise(self, end: datetime.date):
        """Serialise the account.

        Args:
            end: A date to use for cost conversions.
        """
        children = [child.serialise(end) for child in self.children]
        return {
            "account": self.name,
            "balance_children": cost_or_value(self.balance_children, end),
            "balance": cost_or_value(self.balance, end),
            "children": children,
        }
Example #6
0
    def _portfolio_data(self, nodes):
        """
        Turn a portfolio of tree nodes into querytable-style data.

        Args:
            nodes: Account tree nodes.
        Return:
            types: Tuples of column names and types as strings.
            rows: Dictionaries of row data by column names.
        """
        operating_currency = self.ledger.options["operating_currency"][0]
        acct_type = ("account", str(str))
        bal_type = ("balance", str(Decimal))
        alloc_type = ("allocation", str(Decimal))
        types = [acct_type, bal_type, alloc_type]

        rows = []
        portfolio_total = ZERO
        for node in nodes:
            row = {}
            row["account"] = node.name
            balance = cost_or_value(node.balance)
            if operating_currency in balance:
                balance_dec = balance[operating_currency]
                portfolio_total += balance_dec
                row["balance"] = balance_dec
            rows.append(row)

        for row in rows:
            if "balance" in row:
                row["allocation"] = round(
                    (row["balance"] / portfolio_total) * 100, 2)

        return types, rows
Example #7
0
File: charts.py Project: SSITB/fava
    def net_worth(self, interval):
        """Compute net worth.

        Args:
            interval: A string for the interval.

        Returns:
            A list of dicts for all ends of the given interval containing the
            net worth (Assets + Liabilities) separately converted to all
            operating currencies.
        """
        transactions = (entry for entry in self.ledger.entries
                        if (isinstance(entry, Transaction)
                            and entry.flag != flags.FLAG_UNREALIZED))

        types = (
            self.ledger.options["name_assets"],
            self.ledger.options["name_liabilities"],
        )

        txn = next(transactions, None)
        inventory = Inventory()

        for end_date_exclusive in self.ledger.interval_ends(interval):
            end_date_inclusive = end_date_exclusive - datetime.timedelta(
                days=1)
            while txn and txn.date < end_date_exclusive:
                for posting in txn.postings:
                    if posting.account.startswith(types):
                        inventory.add_position(posting)
                txn = next(transactions, None)
            yield {
                "date": end_date_exclusive,
                "balance": cost_or_value(inventory, end_date_inclusive),
            }
Example #8
0
File: charts.py Project: SSITB/fava
    def linechart(self, account_name):
        """The balance of an account.

        Args:
            account_name: A string.

        Returns:
            A list of dicts for all dates on which the balance of the given
            account has changed containing the balance (in units) of the
            account at that date.
        """
        real_account = realization.get_or_create(self.ledger.root_account,
                                                 account_name)
        postings = realization.get_postings(real_account)
        journal = realization.iterate_with_balance(postings)

        # When the balance for a commodity just went to zero, it will be
        # missing from the 'balance' so keep track of currencies that last had
        # a balance.
        last_currencies = None

        for entry, _, change, balance in journal:
            if change.is_empty():
                continue

            balance = inv_to_dict(cost_or_value(balance, entry.date))

            currencies = set(balance.keys())
            if last_currencies:
                for currency in last_currencies - currencies:
                    balance[currency] = 0
            last_currencies = currencies

            yield {"date": entry.date, "balance": balance}
Example #9
0
    def net_worth(self, interval):
        """Compute net worth.

        Args:
            interval: A string for the interval.

        Returns:
            A list of dicts for all ends of the given interval containing the
            net worth (Assets + Liabilities) separately converted to all
            operating currencies.
        """
        transactions = (entry for entry in self.ledger.entries
                        if (isinstance(entry, Transaction)
                            and entry.flag != flags.FLAG_UNREALIZED))

        types = (
            self.ledger.options["name_assets"],
            self.ledger.options["name_liabilities"],
        )

        txn = next(transactions, None)
        inventory = CounterInventory()

        for date in self.ledger.interval_ends(interval):
            while txn and txn.date < date:
                for posting in filter(lambda p: p.account.startswith(types),
                                      txn.postings):
                    inventory.add_position(posting)
                txn = next(transactions, None)
            yield {"date": date, "balance": cost_or_value(inventory, date)}
Example #10
0
    def interval_totals(self, interval, accounts):
        """Renders totals for account (or accounts) in the intervals.

        Args:
            interval: An interval.
            accounts: A single account (str) or a tuple of accounts.
        """
        for begin, end in pairwise(self.ledger.interval_ends(interval)):
            inventory = CounterInventory()
            entries = iter_entry_dates(self.ledger.entries, begin, end)
            for entry in filter_type(entries, Transaction):
                for posting in entry.postings:
                    if posting.account.startswith(accounts):
                        inventory.add_position(posting)

            yield {
                'date': begin,
                'balance': cost_or_value(inventory, end),
                'budgets':
                self.ledger.budgets.calculate_children(accounts, begin, end),
            }
Example #11
0
    def interval_totals(self, interval, accounts):
        """Renders totals for account (or accounts) in the intervals.

        Args:
            interval: An interval.
            accounts: A single account (str) or a tuple of accounts.
        """
        for begin, end in pairwise(self.ledger.interval_ends(interval)):
            inventory = CounterInventory()
            entries = iter_entry_dates(self.ledger.entries, begin, end)
            for entry in filter_type(entries, Transaction):
                for posting in entry.postings:
                    if posting.account.startswith(accounts):
                        inventory.add_position(posting)

            yield {
                "date": begin,
                "balance": cost_or_value(inventory, end),
                "budgets": self.ledger.budgets.calculate_children(
                    accounts, begin, end
                ),
            }
Example #12
0
    def linechart(self, account_name):
        """The balance of an account.

        Args:
            account_name: A string.

        Returns:
            A list of dicts for all dates on which the balance of the given
            account has changed containing the balance (in units) of the
            account at that date.
        """
        real_account = realization.get_or_create(self.ledger.root_account,
                                                 account_name)
        postings = realization.get_postings(real_account)
        journal = realization.iterate_with_balance(postings)

        # When the balance for a commodity just went to zero, it will be
        # missing from the 'balance' field but appear in the 'change' field.
        # Use 0 for those commodities.
        for entry, _, change, balance in journal:
            if change.is_empty():
                continue

            if g.conversion == 'units':
                bal = {curr: 0 for curr in list(change.currencies())}
                bal.update({
                    p.units.currency: p.units.number
                    for p in balance.reduce(convert.get_units)
                })
            else:
                bal = {
                    p.units.currency: p.units.number
                    for p in cost_or_value(balance, entry.date)
                }

            yield {
                'date': entry.date,
                'balance': bal,
            }
Example #13
0
    def linechart(self, account_name):
        """The balance of an account.

        Args:
            account_name: A string.

        Returns:
            A list of dicts for all dates on which the balance of the given
            account has changed containing the balance (in units) of the
            account at that date.
        """
        real_account = realization.get_or_create(self.ledger.root_account,
                                                 account_name)
        postings = realization.get_postings(real_account)
        journal = realization.iterate_with_balance(postings)

        # When the balance for a commodity just went to zero, it will be
        # missing from the 'balance' field but appear in the 'change' field.
        # Use 0 for those commodities.
        for entry, _, change, balance in journal:
            if change.is_empty():
                continue

            if g.conversion == 'units':
                bal = {curr: 0 for curr in list(change.currencies())}
                bal.update({
                    p.units.currency: p.units.number
                    for p in balance.reduce(convert.get_units)
                })
            else:
                bal = {
                    p.units.currency: p.units.number
                    for p in cost_or_value(balance, entry.date)
                }

            yield {
                'date': entry.date,
                'balance': bal,
            }
Example #14
0
def _inventory_cost_or_value(inventory, date):
    """Renders an inventory at cost or value to a currency -> amount dict."""
    inventory = cost_or_value(inventory, date)
    return {p.units.currency: p.units.number for p in inventory}
Example #15
0
 def cost_or_value(self, node, date, include_children):
     if include_children:
         return cost_or_value(node.balance_children, date)
     return cost_or_value(node.balance, date)