class PaymentFlowHistoryDialog(BasicDialog): title = _(u'Payment Flow History Dialog') desc = _("Select a date or a range to be visualised in the report:") size = (-1, -1) model_type = PaymentFlowDay def __init__(self, store): """A dialog to print the PaymentFlowHistoryReport report. :param store: a store """ self.store = store BasicDialog.__init__(self, header_text='<b>%s</b>' % self.desc, title=self.title) self._setup_widgets() # # BasicDialog # def confirm(self): state = self._date_filter.get_state() from kiwi.db.query import DateQueryState if isinstance(state, DateQueryState): start, end = state.date, state.date else: start, end = state.start, state.end results = PaymentFlowDay.get_flow_history(self.store, start, end) if not results: info(_('No payment history found.')) return False print_report(PaymentFlowHistoryReport, payment_histories=results) return True # # Private # def _setup_widgets(self): self.ok_button.set_label(gtk.STOCK_PRINT) self._date_filter = DateSearchFilter(_(u'Date:')) #FIXME: add a remove_option method in DateSearchFilter. self._date_filter.clear_options() self._date_filter.add_custom_options() for option in [Today, Yesterday, LastWeek, LastMonth]: self._date_filter.add_option(option) self._date_filter.select(position=0) self.vbox.pack_start(self._date_filter, False, False) self._date_filter.show_all()
class TransactionPage(object): # shows either a list of: # - transactions # - payments def __init__(self, model, app, parent): self.model = model self.app = app self.parent_window = parent self._block = False self._create_search() self._add_date_filter() self._setup_search() self.refresh() def get_toplevel(self): return self.parent_window def _create_search(self): self.search = TransactionSearchContainer( self, columns=self._get_columns(self.model.kind)) self.query = StoqlibQueryExecuter(self.app.store) self.search.set_query_executer(self.query) self.search.results.connect('row-activated', self._on_row__activated) self.results = self.search.results tree_view = self.search.results.get_treeview() tree_view.set_rules_hint(True) tree_view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH) self.search.enable_advanced_search() def _add_date_filter(self): self.date_filter = DateSearchFilter(_('Date:')) self.date_filter.clear_options() self.date_filter.add_option(Any, 0) year = datetime.datetime.today().year month_names = get_month_names() for i, month in enumerate(month_names): name = month_names[i] option = type(name + 'Option', (MonthOption, ), {'name': _(name), 'month': i + 1, 'year': year}) self.date_filter.add_option(option, i + 1) self.date_filter.add_custom_options() self.date_filter.mode.select_item_by_position(0) self.search.add_filter(self.date_filter) def _append_date_query(self, field): date = self.date_filter.get_state() queries = [] if isinstance(date, DateQueryState) and date.date is not None: queries.append(Date(field) == date.date) elif isinstance(date, DateIntervalQueryState): queries.append(Date(field) >= date.start) queries.append(Date(field) <= date.end) return queries def _payment_query(self, store): queries = self._append_date_query(self.query.table.due_date) if queries: return store.find(self.query.table, And(*queries)) return store.find(self.query.table) def _transaction_query(self, store): queries = [Or(self.model.id == AccountTransaction.account_id, self.model.id == AccountTransaction.source_account_id)] queries.extend(self._append_date_query(AccountTransaction.date)) return store.find(AccountTransactionView, And(*queries)) def show(self): self.search.show() def _setup_search(self): if self.model.kind == 'account': self.query.set_table(AccountTransactionView) self.search.set_text_field_columns(['description']) self.query.set_query(self._transaction_query) elif self.model.kind == 'payable': self.search.set_text_field_columns(['description', 'supplier_name']) self.query.set_table(OutPaymentView) self.query.set_query(self._payment_query) elif self.model.kind == 'receivable': self.search.set_text_field_columns(['description', 'drawee']) self.query.set_table(InPaymentView) self.query.set_query(self._payment_query) else: raise TypeError("unknown model kind: %r" % (self.model.kind, )) def refresh(self): self.search.results.clear() if self.model.kind == 'account': transactions = AccountTransactionView.get_for_account(self.model, self.app.store) self.append_transactions(transactions) elif self.model.kind == 'payable': self._populate_payable_payments(OutPaymentView) elif self.model.kind == 'receivable': self._populate_payable_payments(InPaymentView) else: raise TypeError("unknown model kind: %r" % (self.model.kind, )) def _get_columns(self, kind): if kind in ['payable', 'receivable']: return self._get_payment_columns() else: return self._get_account_columns() def _get_account_columns(self): def format_withdrawal(value): if value < 0: return currency(abs(value)).format(symbol=True, precision=2) def format_deposit(value): if value > 0: return currency(value).format(symbol=True, precision=2) if self.model.account_type == Account.TYPE_INCOME: color_func = lambda x: False else: color_func = lambda x: x < 0 return [Column('date', title=_("Date"), data_type=datetime.date, sorted=True), Column('code', title=_("Code"), data_type=unicode), Column('description', title=_("Description"), data_type=unicode, expand=True), Column('account', title=_("Account"), data_type=unicode), Column('value', title=self.model.account.get_type_label(out=False), data_type=currency, format_func=format_deposit), Column('value', title=self.model.account.get_type_label(out=True), data_type=currency, format_func=format_withdrawal), ColoredColumn('total', title=_("Total"), data_type=currency, color='red', data_func=color_func)] def _get_payment_columns(self): return [SearchColumn('due_date', title=_("Due date"), data_type=datetime.date, sorted=True), SearchColumn('identifier', title=_("Code"), data_type=int), SearchColumn('description', title=_("Description"), data_type=unicode, expand=True), SearchColumn('value', title=_("Value"), data_type=currency)] def append_transactions(self, transactions): for transaction in transactions: description = transaction.get_account_description(self.model) value = transaction.get_value(self.model) self._add_transaction(transaction, description, value) self.update_totals() def _populate_payable_payments(self, view_class): for view in self.app.store.find(view_class): self.search.results.append(view) def _add_transaction(self, transaction, description, value): item = Settable(transaction=transaction) self._update_transaction(item, transaction, description, value) self.search.results.append(item) return item def _update_transaction(self, item, transaction, description, value): item.account = description item.date = transaction.date item.description = transaction.description item.value = value item.code = transaction.code def update_totals(self): total = decimal.Decimal('0') for item in self.search.results: total += item.value item.total = total def _edit_transaction_dialog(self, item): store = api.new_store() if isinstance(item.transaction, AccountTransactionView): account_transaction = store.fetch(item.transaction.transaction) else: account_transaction = store.fetch(item.transaction) model = getattr(self.model, 'account', self.model) transaction = run_dialog(AccountTransactionEditor, self.app, store, account_transaction, model) if transaction: store.flush() self._update_transaction(item, transaction, transaction.edited_account.description, transaction.value) self.update_totals() self.search.results.update(item) self.app.accounts.refresh_accounts(self.app.store) store.confirm(transaction) store.close() def on_dialog__opened(self, dialog): dialog.connect('account-added', self.on_dialog__account_added) def on_dialog__account_added(self, dialog): self.app.accounts.refresh_accounts(self.app.store) def add_transaction_dialog(self): store = api.new_store() model = getattr(self.model, 'account', self.model) model = store.fetch(model) transaction = run_dialog(AccountTransactionEditor, self.app, store, None, model) if transaction: transaction.sync() value = transaction.value other = transaction.get_other_account(model) if other == model: value = -value item = self._add_transaction(transaction, other.description, value) self.update_totals() self.search.results.update(item) self.app.accounts.refresh_accounts(self.app.store) store.confirm(transaction) store.close() def _on_row__activated(self, objectlist, item): if self.model.kind == 'account': self._edit_transaction_dialog(item)