Source code for stoqlib.gui.widgets.accounttree

##
## Copyright (C) 2011 Async Open Source <http://www.async.com.br>
## All rights reserved
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU Lesser General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., or visit: http://www.gnu.org/.
##
##  Author(s): Stoq Team <stoq-devel@async.com.br>
##

import gtk

from kiwi.currency import currency
from kiwi.python import Settable
from kiwi.ui.objectlist import ColoredColumn, Column, ObjectTree

from stoqlib.domain.views import Account, AccountView
from stoqlib.gui.stockicons import (STOQ_MONEY, STOQ_PAYABLE_APP, STOQ_BILLS,
                                    STOQ_TILL_APP)
from stoqlib.lib.parameters import sysparam
from stoqlib.lib.translation import stoqlib_gettext

_ = stoqlib_gettext


[docs]class StockTextColumn(Column): "A column which you can add a stock item and a text" def __init__(self, *args, **kwargs): Column.__init__(self, *args, **kwargs)
[docs] def attach(self, objectlist): column = Column.attach(self, objectlist) self._pixbuf_renderer = gtk.CellRendererPixbuf() column.pack_start(self._pixbuf_renderer, False) return column
[docs] def cell_data_func(self, tree_column, renderer, model, treeiter, (column, renderer_prop)): row = model[treeiter] data = column.get_attribute(row[0], column.attribute, None) text = column.as_string(data) renderer.set_property(renderer_prop, text) pixbuf = self._objectlist.get_pixbuf(row[0]) self._pixbuf_renderer.set_property('pixbuf', pixbuf)
[docs]def sort_models(a, b): return cmp(a.lower(), b.lower())
[docs]class AccountTree(ObjectTree): __gtype_name__ = 'AccountTree' def __init__(self, with_code=True, create_mode=False): self.create_mode = create_mode self._accounts = {} columns = [StockTextColumn('description', title=_("Account name"), data_type=str, pack_end=True, expand=True, sorted=True, sort_func=sort_models)] if with_code: columns.append(Column('code', title=_("Code"), data_type=str, width=120)) if not create_mode: # FIXME: This needs to be much better colorized, and moved to the # domain classes def colorize(account): if (account.kind == 'account' and account.account_type == Account.TYPE_INCOME): return False else: return account.total < 0 columns.append(ColoredColumn('total', title=_("Total"), width=100, data_type=currency, color='red', data_func=colorize, use_data_model=True)) ObjectTree.__init__(self, columns, mode=gtk.SELECTION_SINGLE) def render_icon(icon): return self.render_icon(icon, gtk.ICON_SIZE_MENU) self._pixbuf_money = render_icon(STOQ_MONEY) self._pixbuf_payable = render_icon(STOQ_PAYABLE_APP) self._pixbuf_receivable = render_icon(STOQ_BILLS) self._pixbuf_till = render_icon(STOQ_TILL_APP) if self.create_mode: self.set_headers_visible(False) # Order the accounts top to bottom so # ObjectTree.append() works as expected def _orderaccounts(self, all_accounts, res=None, parent=None): if not res: res = [] if parent is None: accounts = [a for a in all_accounts if a.parent_id is None] else: accounts = [a for a in all_accounts if a.parent_id == parent.id] res.extend(accounts) for account in accounts: account.selectable = True self._orderaccounts(all_accounts, res, account) return res def _calculate_total(self, all_accounts, account): total = account.get_combined_value() for a in all_accounts: if a.parent_id == account.id: total += self._calculate_total(all_accounts, a) return total
[docs] def get_pixbuf(self, model): kind = model.kind if kind == 'payable': pixbuf = self._pixbuf_payable elif kind == 'receivable': pixbuf = self._pixbuf_receivable elif kind == 'account': till_account_id = sysparam.get_object_id('TILLS_ACCOUNT') if model.matches(till_account_id): pixbuf = self._pixbuf_till else: pixbuf = self._pixbuf_money else: return None return pixbuf
[docs] def insert_initial(self, store, edited_account=None): """ Insert accounts and parent accounts in a ObjectTree. :param store: a store :param edited_account: If not None, this is the account being edited. In this case, this acount (and its decendents) will not be shown in the account tree. """ till_id = sysparam.get_object_id('TILLS_ACCOUNT') if self.create_mode and edited_account: accounts = list(store.find(AccountView, AccountView.id != edited_account.id)) else: accounts = list(store.find(AccountView)) accounts = self._orderaccounts(accounts) for account in accounts: account.total = self._calculate_total(accounts, account) if self.create_mode and account.matches(till_id): account.selectable = False self.add_account(account.parent_id, account) selectable = not self.create_mode # Tabs cache requires unique ids self.append(None, Settable(description=_("Accounts Payable"), id=-1, parent=None, kind='payable', selectable=selectable, total=None)) self.append(None, Settable(description=_("Accounts Receivable"), id=-2, parent=None, kind='receivable', selectable=selectable, total=None)) self.flush()
[docs] def add_account(self, parent_id, account): account.kind = 'account' parent = self._accounts.get(parent_id) self.append(parent, account) self._accounts[account.id] = account
[docs] def get_account_by_id(self, account_id): return self._accounts.get(account_id)
[docs] def refresh_accounts(self, store, account=None): self._accounts = {} self.clear() self.insert_initial(store) if account: self.select(account) self.flush()