示例#1
0
def common_root(accounts):
    r'''
    >>> a = Account(label='a')
    >>> b = Account(label='b', parent=a, tags=['x'])
    >>> c = Account(label='c', parent=b, tags=['y'])
    >>> d = Account(label='d', parent=a, atype=AccountType.ProfitLoss)
    >>> e = Account(label='e', tags=['a', 'b'])
    >>> f = Account(label='f', parent=b)
    >>> common_root([c]).label
    'c'
    >>> common_root([c, d]).label
    'a'
    >>> common_root([b, c]).label
    'b'
    >>> common_root([c, e]) is None
    True
    >>> common_root([c, f]).label
    'b'
    '''
    roots = None
    for account in accounts:
        if roots is None:
            roots = set(account.self_and_all_parents())
        else:
            roots.intersection_update(account.self_and_all_parents())
    if not roots:
        return None
    while len(roots) > 1:
        for account in list(roots):
            roots.difference_update(account.all_parents())
    assert len(roots) == 1
    return roots.pop()
示例#2
0
 def tree(self, title, accounts, amount_columns, depth=None):
     if depth is not None:
         accounts = set(a for a in accounts if a.depth() <= depth)
     accounts = filter_display_accounts(accounts, self.opts) # TODO refactor filter_display_accounts() as method of Formatter
     subaccounts = parentset(accounts)
     all_accounts = [None] + list(sorted(accounts | subaccounts))
     while all_accounts:
         account = all_accounts.pop(0)
         is_subaccount = account in subaccounts
         if not self.opt_subtotals and self.opt_fullnames and is_subaccount:
             continue
         if account is None:
             if self.opt_bare:
                 continue
             text = 'TOTAL ' + title
         elif self.opt_fullnames:
             text = str(account)
         else:
             def has_sibling(account):
                 if not all_accounts:
                     return False
                 for a in all_accounts:
                     if a.depth() <= account.depth():
                         break
                 return a.depth() == account.depth()
             graph = ['├─╴' if has_sibling(account) else '└─╴']
             for a in account.all_parents():
                 graph.append('│  ' if has_sibling(a) else '   ')
             if self.opt_bare:
                 graph.pop()
             text = ''.join(reversed(graph)) + account.bare_name()
         columns = []
         for acol in amount_columns:
             if (account is None or self.opt_subtotals or not is_subaccount) and account in acol:
                 columns.append(self.config.format_money(acol[account]))
             else:
                 columns.append('')
         yield self.fmt(text + ' ', ((' ' + c if c else '') for c in columns),
                         label= (account and account.label) or '',
                         text_fill= '' if is_subaccount else '.',
                         column_fill= '' if is_subaccount else '.',
                         strong= self.opt_subtotals and not is_subaccount)