[POS-commit] r6433 - in stoqlib/trunk: . data/glade
stoqlib/database stoqlib/domain stoqlib/gui stoqlib/gui/base
stoqlib/gui/dialogs stoqlib/gui/search stoqlib/gui/slaves
stoqlib/gui/wizards
Johan Dahlin
jdahlin at async.com.br
Wed Apr 25 15:50:38 BRT 2007
Author: jdahlin
Date: Wed Apr 25 15:50:38 2007
New Revision: 6433
Removed:
stoqlib/trunk/data/glade/TillHistoryDialog.glade
stoqlib/trunk/stoqlib/gui/base/searchbar.py
stoqlib/trunk/stoqlib/gui/slaves/filterslave.py
stoqlib/trunk/stoqlib/gui/slaves/fiscalslave.py
stoqlib/trunk/stoqlib/gui/slaves/productslave.py
Modified:
stoqlib/trunk/data/glade/PurchaseSelectionStep.glade
stoqlib/trunk/setup.py
stoqlib/trunk/stoqlib/database/runtime.py
stoqlib/trunk/stoqlib/domain/person.py
stoqlib/trunk/stoqlib/gui/base/columns.py
stoqlib/trunk/stoqlib/gui/base/dialogs.py
stoqlib/trunk/stoqlib/gui/base/search.py
stoqlib/trunk/stoqlib/gui/dialogs/tillhistory.py
stoqlib/trunk/stoqlib/gui/interfaces.py
stoqlib/trunk/stoqlib/gui/search/categorysearch.py
stoqlib/trunk/stoqlib/gui/search/fiscalsearch.py
stoqlib/trunk/stoqlib/gui/search/giftcertificatesearch.py
stoqlib/trunk/stoqlib/gui/search/personsearch.py
stoqlib/trunk/stoqlib/gui/search/productsearch.py
stoqlib/trunk/stoqlib/gui/search/receivingsearch.py
stoqlib/trunk/stoqlib/gui/search/salesearch.py
stoqlib/trunk/stoqlib/gui/search/sellablesearch.py
stoqlib/trunk/stoqlib/gui/search/servicesearch.py
stoqlib/trunk/stoqlib/gui/search/stationsearch.py
stoqlib/trunk/stoqlib/gui/search/tillsearch.py
stoqlib/trunk/stoqlib/gui/slaves/individualslave.py
stoqlib/trunk/stoqlib/gui/wizards/receivingwizard.py
Log:
#3330: Use SearchContainer from kiwi in stoqlib
Modified: stoqlib/trunk/data/glade/PurchaseSelectionStep.glade
==============================================================================
--- stoqlib/trunk/data/glade/PurchaseSelectionStep.glade (original)
+++ stoqlib/trunk/data/glade/PurchaseSelectionStep.glade Wed Apr 25 15:50:38 2007
@@ -31,23 +31,11 @@
</child>
</widget>
<packing>
- <property name="expand">False</property>
+ <property name="expand">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
- <widget class="ObjectList" id="orders">
- <property name="is_focus">True</property>
- <property name="selection_mode">single</property>
- <property name="shadow_type">in</property>
- <property name="visible">True</property>
- <property name="vscrollbar_policy">automatic</property>
- </widget>
- <packing>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<child>
@@ -75,7 +63,7 @@
</widget>
<packing>
<property name="expand">False</property>
- <property name="position">3</property>
+ <property name="position">2</property>
</packing>
</child>
</widget>
Modified: stoqlib/trunk/setup.py
==============================================================================
--- stoqlib/trunk/setup.py (original)
+++ stoqlib/trunk/setup.py Wed Apr 25 15:50:38 2007
@@ -128,7 +128,7 @@
description="A powerful retail system library",
long_description="""
Stoqlib offers many special tools for retail system applications
- such reports infrastructure, basic dialogs and searchbars and
+ such reports infrastructure, basic dialogs, search windows and
domain data in a persistent level.
""",
url=website,
Modified: stoqlib/trunk/stoqlib/database/runtime.py
==============================================================================
--- stoqlib/trunk/stoqlib/database/runtime.py (original)
+++ stoqlib/trunk/stoqlib/database/runtime.py Wed Apr 25 15:50:38 2007
@@ -93,6 +93,9 @@
self._obsolete = True
def get(self, obj):
+ if obj is None:
+ return None
+
if not isinstance(obj, (SQLObject, InheritableSQLObject)):
raise TypeError("obj must be a SQLObject, not %r" % (obj,))
Modified: stoqlib/trunk/stoqlib/domain/person.py
==============================================================================
--- stoqlib/trunk/stoqlib/domain/person.py (original)
+++ stoqlib/trunk/stoqlib/domain/person.py Wed Apr 25 15:50:38 2007
@@ -74,7 +74,9 @@
from sqlobject import (DateTimeCol, UnicodeCol, IntCol,
ForeignKey, MultipleJoin, BoolCol, SQLObject)
-from sqlobject.sqlbuilder import func, AND
+from sqlobject.sqlbuilder import func, AND, INNERJOINOn, LEFTJOINOn
+from sqlobject.viewable import Viewable
+
from zope.interface import implements
from stoqlib.database.columns import PriceCol, DecimalCol
@@ -793,3 +795,127 @@
cpf = UnicodeCol()
rg_number = UnicodeCol()
phone_number = UnicodeCol()
+
+ @property
+ def client(self):
+ return PersonAdaptToClient.get(self.client_id,
+ connection=self._connection)
+
+class EmployeeView(Viewable):
+ columns = dict(
+ id=Person.q.id,
+ employee_id=PersonAdaptToEmployee.q.id,
+ name=Person.q.name,
+ role=EmployeeRole.q.name,
+ status=PersonAdaptToEmployee.q.status,
+ registry_number=PersonAdaptToEmployee.q.registry_number,
+ )
+
+ joins = [
+ INNERJOINOn(None, PersonAdaptToEmployee,
+ Person.q.id == PersonAdaptToEmployee.q._originalID),
+ INNERJOINOn(None, EmployeeRole,
+ PersonAdaptToEmployee.q.roleID == EmployeeRole.q.id),
+ ]
+
+ def get_status_string(self):
+ return PersonAdaptToEmployee.statuses[self.status]
+
+ @property
+ def employee(self):
+ return PersonAdaptToEmployee.get(self.employee_id,
+ connection=self.get_connection())
+
+class SupplierView(Viewable):
+ columns = dict(
+ id=Person.q.id,
+ name=Person.q.name,
+ phone_number=Person.q.phone_number,
+ fancy_name=_PersonAdaptToCompany.q.fancy_name,
+ cnpj=_PersonAdaptToCompany.q.cnpj,
+ supplier_id=PersonAdaptToSupplier.q.id,
+ status=PersonAdaptToSupplier.q.status,
+ )
+
+ joins = [
+ INNERJOINOn(None, PersonAdaptToSupplier,
+ Person.q.id == PersonAdaptToSupplier.q._originalID),
+ LEFTJOINOn(None, _PersonAdaptToCompany,
+ Person.q.id == _PersonAdaptToCompany.q._originalID),
+ ]
+
+ def get_status_string(self):
+ return PersonAdaptToSupplier.statuses[self.status]
+
+ @property
+ def supplier(self):
+ return PersonAdaptToSupplier.get(self.supplier_id,
+ connection=self.get_connection())
+
+class TransporterView(Viewable):
+ """
+ @cvar id:
+ @cvar name:
+ @cvar phone_number:
+ @cvar transporter_id:
+ @cvar status:
+ @cvar freight_percentage:
+ """
+ columns = dict(
+ id=Person.q.id,
+ name=Person.q.name,
+ phone_number=Person.q.phone_number,
+ transporter_id=PersonAdaptToTransporter.q.id,
+ freight_percentage=PersonAdaptToTransporter.q.freight_percentage,
+ )
+
+ joins = [
+ INNERJOINOn(None, PersonAdaptToTransporter,
+ Person.q.id == PersonAdaptToTransporter.q._originalID),
+ ]
+
+ @property
+ def transporter(self):
+ return PersonAdaptToTransporter.get(self.transporter_id,
+ connection=self.get_connection())
+
+
+class BranchView(Viewable):
+ columns = dict(
+ id=Person.q.id,
+ name=Person.q.name,
+ branch_id=PersonAdaptToBranch.q.id,
+ phone_number=Person.q.phone_number,
+ )
+
+ joins = [
+ INNERJOINOn(None, PersonAdaptToBranch,
+ Person.q.id == PersonAdaptToBranch.q._originalID),
+ ]
+
+ @property
+ def branch(self):
+ return PersonAdaptToBranch.get(self.branch_id,
+ connection=self.get_connection())
+
+
+class CreditProviderView(Viewable):
+ columns = dict(
+ id=Person.q.id,
+ name=Person.q.name,
+ provider_id=PersonAdaptToCreditProvider.q.id,
+ phone_number=Person.q.phone_number,
+ short_name=PersonAdaptToCreditProvider.q.short_name,
+ is_active=PersonAdaptToCreditProvider.q.is_active,
+ )
+
+ joins = [
+ INNERJOINOn(None, PersonAdaptToCreditProvider,
+ Person.q.id == PersonAdaptToCreditProvider.q._originalID),
+ ]
+
+ @property
+ def provider(self):
+ return PersonAdaptToCreditProvider.get(self.provider_id,
+ connection=self.get_connection())
+
Modified: stoqlib/trunk/stoqlib/gui/base/columns.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/base/columns.py (original)
+++ stoqlib/trunk/stoqlib/gui/base/columns.py Wed Apr 25 15:50:38 2007
@@ -27,26 +27,6 @@
from kiwi.accessor import kgetattr
from kiwi.ui.widgets.list import Column
-from stoqlib.lib.component import Adapter
-
-
-class FacetColumn(Column):
- def __init__(self, iface, *args, **kwargs):
- self._iface = iface
- Column.__init__(self, *args, **kwargs)
-
- def get_attribute(self, instance, name, default=None):
- if not isinstance(instance, Adapter):
- facet = self._iface(instance, None)
- else:
- original = instance.get_adapted()
- facet = self._iface(original, None)
- if not facet:
- return
- return kgetattr(facet, name, default)
-
- def get_iface(self):
- return self._iface
class ForeignKeyColumn(Column):
"""
Modified: stoqlib/trunk/stoqlib/gui/base/dialogs.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/base/dialogs.py (original)
+++ stoqlib/trunk/stoqlib/gui/base/dialogs.py Wed Apr 25 15:50:38 2007
@@ -216,6 +216,10 @@
dialog, widget))
widget.connect('activate', self.cancel)
+ @property
+ def action_area(self):
+ return self.get_toplevel().action_area
+
#
# Kiwi handlers
Modified: stoqlib/trunk/stoqlib/gui/base/search.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/base/search.py (original)
+++ stoqlib/trunk/stoqlib/gui/base/search.py Wed Apr 25 15:50:38 2007
@@ -25,19 +25,20 @@
""" Implementation of basic dialogs for searching data """
import gtk
-from kiwi.utils import gsignal
+from kiwi.argcheck import argcheck
+from kiwi.db.sqlobj import SQLObjectQueryExecuter
+from kiwi.enums import SearchFilterPosition
from kiwi.ui.delegates import GladeSlaveDelegate
-from kiwi.ui.objectlist import ObjectList
+from kiwi.ui.search import ComboSearchFilter, SearchSlaveDelegate
from kiwi.ui.widgets.list import SummaryLabel
-from kiwi.argcheck import argcheck
-from sqlobject.sresults import SelectResults
-from sqlobject.dbconnection import Transaction
+from kiwi.utils import gsignal
+from sqlobject.main import SQLObject
-from stoqlib.database.database import rollback_and_begin
+from stoqlib.database.database import finish_transaction
+from stoqlib.database.runtime import get_connection, new_transaction
from stoqlib.exceptions import DatabaseInconsistency
from stoqlib.gui.base.dialogs import BasicDialog, run_dialog
from stoqlib.gui.editors.baseeditor import BaseEditor
-from stoqlib.gui.base.searchbar import SearchBar
from stoqlib.lib.component import Adapter
from stoqlib.lib.translation import stoqlib_gettext
@@ -86,7 +87,6 @@
>>> def __init__(self, *args):
... SearchDialog.__init__(self)
- Some important parameters:
@cvar table: the table type which we will query on to get the objects.
@cvar searchbar_labels: labels for SearchBar entry and date fields
@cvar searchbar_result_strings: a tuple where each item has a singular
@@ -96,13 +96,11 @@
title = ''
table = None
search_table = None
+ search_labels = None
selection_mode = gtk.SELECTION_BROWSE
- searchbar_labels = None
- searchbar_result_strings = None
- searching_by_date = False
size = ()
- @argcheck(Transaction, object, object, bool, basestring, int)
+ @argcheck(object, object, object, bool, basestring, int)
def __init__(self, conn, table=None, search_table=None, hide_footer=True,
title='', selection_mode=None):
"""
@@ -116,13 +114,36 @@
"""
self.conn = conn
+ self.search_table = self._setup_search_table(table, search_table)
+ self.selection_mode = self._setup_selection_mode(selection_mode)
+ self.summary_label = None
+
+ BasicDialog.__init__(self)
+ BasicDialog._initialize(self, hide_footer=hide_footer,
+ main_label_text=self.main_label_text,
+ title=title or self.title,
+ size=self.size)
+
+ self.executer = SQLObjectQueryExecuter(get_connection())
+ self.set_table(self.search_table)
+
+ self.disable_ok()
+ self.set_ok_label(_('Se_lect Items'))
+ self._setup_search()
+ self._setup_details_slave()
+
+ self.create_filters()
+ self.setup_widgets()
+
+ def _setup_search_table(self, table, search_table):
search_table = search_table or self.search_table
table = table or self.table
if not (table or search_table):
raise ValueError(
"%r must define a table or search_table attribute" % self)
- self.search_table = search_table or table
+ return search_table or table
+ def _setup_selection_mode(self, selection_mode):
# For consistency do not allow none or single, in other words,
# only allowed values are browse and multiple so we always will
# be able to use both the keyboard and the mouse to select items
@@ -131,63 +152,18 @@
if (selection_mode != gtk.SELECTION_BROWSE and
selection_mode != gtk.SELECTION_MULTIPLE):
raise ValueError('Invalid selection mode %r' % selection_mode)
- self.selection_mode = selection_mode
-
- BasicDialog.__init__(self)
- title = title or self.title
- self.summary_label = None
- BasicDialog._initialize(self, hide_footer=hide_footer,
- main_label_text=self.main_label_text,
- title=title, size=self.size)
- self.set_ok_label(_('Se_lect Items'))
- self.setup_slaves()
+ return selection_mode
- def _sync(self, *args):
- rollback_and_begin(self.conn)
-
- def _check_searchbar_settings(self, value, attr_name):
- if not value:
- return False
- if not isinstance(value, tuple):
- raise TypeError("%s attribute must be of typle tuple, "
- "got %s" % (attr_name, type(value)))
- return True
-
- def _setup_searchbar(self):
- columns = self.get_columns()
- query_args = self.get_query_args()
- use_dates = self.searching_by_date
- self.search_bar = SearchBar(self.conn, self.search_table,
- columns, query_args=query_args,
- filter_slave=self.get_filter_slave(),
- searching_by_date=use_dates)
- self.search_bar.set_query_callback(self.query)
- extra_query = self.get_extra_query
- if extra_query:
- self.search_bar.register_extra_query_callback(extra_query)
- self.search_bar.connect('before-search-activate', self._sync)
- self.search_bar.connect('search-activate', self.update_klist)
- if self._check_searchbar_settings(self.searchbar_result_strings,
- "searchbar_result_strings"):
- self.set_result_strings(*self.searchbar_result_strings)
- if self._check_searchbar_settings(self.searchbar_labels,
- "searchbar_labels"):
- self.set_searchbar_labels(*self.searchbar_labels)
- self.after_search_bar_created()
- self.attach_slave('header', self.search_bar)
-
- def _setup_klist(self):
- self.klist_vbox = gtk.VBox()
- self.klist = ObjectList(self.get_columns(), mode=self.selection_mode)
- self.klist_vbox.pack_start(self.klist)
- self.klist_vbox.show_all()
- # XXX: I think that BasicDialog must be redesigned, if so we don't
- # need this ".remove" crap
- self.main.remove(self.main_label)
- self.main.add(self.klist_vbox)
- self.klist.show()
- self.klist.connect('cell_edited', self.on_cell_edited)
- self.klist.connect('selection-changed', self._on_selection_changed)
+ def _setup_search(self):
+ self.search = SearchSlaveDelegate(self.get_columns())
+ self.search.set_query_executer(self.executer)
+ self.attach_slave('main', self.search)
+ self.header.hide()
+
+ self.results = self.search.search.results
+ self.results.connect('cell-edited', self._on_results__cell_edited)
+ self.results.connect('selection-changed',
+ self._on_results__selection_changed)
def _setup_details_slave(self):
# FIXME: Gross hack
@@ -212,146 +188,120 @@
# Public API
#
- def set_searchtable(self, search_table):
- self.search_table = search_table
- self.search_bar.set_searchtable(search_table)
+ @argcheck(bool)
+ def set_details_button_sensitive(self, value):
+ self._details_slave.details_button.set_sensitive(value)
- def set_searchbar_columns(self, columns):
- self.search_bar.set_columns(columns)
+ def get_selection(self):
+ mode = self.results.get_selection_mode()
+ if mode == gtk.SELECTION_BROWSE:
+ return self.results.get_selected()
+ return self.results.get_selected_rows()
- def set_searchbar_search_string(self, search_str):
- self.search_bar.set_search_string(search_str)
+ def confirm(self):
+ self.retval = self.get_selection()
+ self.close()
- def perform_search(self):
- self.search_bar.search_items()
+ def cancel(self, *args):
+ self.retval = []
+ self.close()
- def setup_summary_label(self, column_name, label_text):
+ def add_summary_label(self, column_name, label_text):
+ """
+ @param column_name:
+ @param label_text:
+ """
if self.summary_label is not None:
- self.klist_vbox.remove(self.summary_label)
- value_format = '<b>%s</b>'
- self.clear_klist()
- self.summary_label = SummaryLabel(klist=self.klist,
+ self.results_vbox.remove(self.summary_label)
+ self.summary_label = SummaryLabel(klist=self.results,
column=column_name,
label=label_text,
- value_format=value_format)
+ value_format='<b>%s</b>')
self.summary_label.show()
- self.klist_vbox.pack_start(self.summary_label, False)
+ self.results_vbox.pack_start(self.summary_label, False)
- def setup_slaves(self, **kwargs):
- self.disable_ok()
- self._setup_klist()
- self._setup_searchbar()
- self._setup_details_slave()
+ def set_table(self, table):
+ self.executer.set_table(table)
+ self.search_table = table
- @argcheck(bool)
- def set_details_button_sensitive(self, value):
- self._details_slave.details_button.set_sensitive(value)
+ # FIXME: -> remove/use
- def get_query_args(self):
- """An optional list of SQLObject arguments for select function."""
+ def set_searchbar_labels(self, *args):
+ search_filter = self.search.get_primary_filter()
+ search_filter.set_label(args[0])
- def get_extra_query(self):
- """An optional SQLObject.sqlbuilder query for select statement."""
+ def set_result_strings(self, *args):
+ pass
- def get_filter_slave(self):
- """Returns a slave which will be used as filter by SearchBar.
- By default it returns None which means that no filter will be
- attached. Redefine this method in child when it's needed
+ def set_text_field_columns(self, columns):
"""
- return None
-
- def after_search_bar_created(self):
- """This method will be called after creating the SearchBar
- instance. Redefine this method in child when it's needed
+ See L{SearchSlaveDelegate.set_text_field_columns}
"""
+ self.search.set_text_field_columns(columns)
- def on_cell_edited(self, klist, obj, attr):
- """Override this method on child when it's needed to perform some
- tasks when editing a row.
+ def add_filter(self, search_filter, position=SearchFilterPosition.BOTTOM,
+ columns=None, callback=None):
"""
-
- def _on_selection_changed(self, klist, selected):
- self.update_widgets()
-
- def set_searchbar_labels(self, search_entry_lbl, date_search_lbl=None):
- # Second argument is only used by Stoq's SearchableAppWindow
- self.search_bar.set_searchbar_labels(search_entry_lbl,
- date_search_lbl)
-
- def set_result_strings(self, singular_form, plural_form):
- """This method defines strings to be used in the
- search_results_label for SearchBar class.
+ See L{SearchSlaveDelegate.add_filter}
"""
- self.search_bar.set_result_strings(singular_form, plural_form)
+ self.search.add_filter(search_filter, position, columns, callback)
- def get_selection(self):
- mode = self.klist.get_selection_mode()
- if mode == gtk.SELECTION_BROWSE:
- return self.klist.get_selected()
- return self.klist.get_selected_rows()
+ #
+ # Filters
+ #
- def clear_klist(self):
- self.klist.clear()
- self.update_widgets()
+ def create_branch_filter(self, label=None):
+ from stoqlib.domain.person import PersonAdaptToBranch
+ from stoqlib.database.runtime import get_current_branch
+ branches = PersonAdaptToBranch.get_active_branches(self.conn)
+ items = [(b.person.name, b.id) for b in branches]
+ #if not items:
+ # raise ValueError('You should have at least one branch at '
+ # 'this point')
+ items.insert(0, (_("Any"), None))
- def confirm(self):
- objs = self.get_selection()
- self.retval = objs
- self.close()
+ if not label:
+ label = _('Branch')
+ branch_filter = ComboSearchFilter(label, items)
+ current = get_current_branch(self.conn)
+ if current:
+ branch_filter.select(current.id)
- def cancel(self, *args):
- self.retval = []
- self.close()
+ return branch_filter
#
- # Hooks
+ # Callbacks
#
- def update_klist(self, slave, objs):
- """A hook called by SearchBar and instances."""
- if not objs:
- self.klist.clear()
- self.disable_ok()
- self.update_widgets()
- return
-
- if isinstance(objs, (list, tuple)):
- count = len(objs)
- elif isinstance(objs, SelectResults):
- count = objs.count()
- else:
- msg = 'Invalid type for result objects: Type: %s'
- raise TypeError, msg % type(objs)
+ def _on_results__cell_edited(self, results, obj, attr):
+ """Override this method on child when it's needed to perform some
+ tasks when editing a row.
+ """
- if count:
- self.klist.add_list(objs)
- objs = iter(objs)
- selected = objs.next()
- self.klist.select(selected)
- self.enable_ok()
- if self.summary_label:
- self.summary_label.update_total()
+ def _on_results__selection_changed(self, results, selected):
self.update_widgets()
- def update_widgets(self):
- """ Subclass can have an 'update_widgets', and this method will be
- called when a signal is emitted by 'Filter' or 'Clear' buttons and
- also when a list item is selected. """
-
- def query(self, table, query, queries):
- """Override this to control the queries made by the
- searchbar, see searchbar.set_query_callback for documentation
- """
- return table.select(query, **queries)
-
#
- # Specification of methods that all subclasses *must* to implement
+ # Hooks
#
+ def create_filters(self):
+ raise NotImplementedError(
+ "create_filters() must be implemented in %r" % self)
+
+ def setup_widgets(self):
+ pass
+
def get_columns(self):
raise NotImplementedError(
"get_columns() must be implemented in %r" % self)
+ def update_widgets(self):
+ """
+ Subclass can have an 'update_widgets', and this method will be
+ called when a signal is emitted by 'Filter' or 'Clear' buttons and
+ also when a list item is selected. """
+
class SearchEditorToolBar(GladeSlaveDelegate):
""" Slave for internal use of SearchEditor, offering an eventbox for a
@@ -442,6 +392,7 @@
hide_footer=hide_footer, title=title,
selection_mode=selection_mode)
+ self._setup_slaves()
if hide_toolbar:
self.accept_edit_data = False
self._toolbar.get_toplevel().hide()
@@ -463,15 +414,15 @@
if not self.has_edit_button:
self.hide_edit_button()
self._selected = None
- self.klist.connect('double_click', self._on_list__double_click)
+ self.results.connect('double_click', self._on_results__double_click)
self.update_widgets()
- def setup_slaves(self):
- SearchDialog.setup_slaves(self)
+
+ def _setup_slaves(self):
self._toolbar = SearchEditorToolBar()
- self.attach_slave('extra_holder', self._toolbar)
self._toolbar.connect("edit", self._on_toolbar__edit)
self._toolbar.connect("add", self._on_toolbar__new)
+ self.attach_slave('extra_holder', self._toolbar)
# Public API
@@ -481,7 +432,7 @@
self._toolbar.edit_button.set_sensitive(value)
def update_widgets(self, *args):
- self._toolbar.edit_button.set_sensitive(len(self.klist))
+ self._toolbar.edit_button.set_sensitive(len(self.results))
def hide_edit_button(self):
self.accept_edit_data = False
@@ -499,12 +450,12 @@
if self._selected:
selected = self._selected
selected.sync()
- self.klist.update(selected)
+ self.results.update(selected)
else:
# user just added a new instance
selected = self.get_searchlist_model(model)
- self.klist.append(selected)
- self.klist.select(selected)
+ self.results.append(selected)
+ self.results.select(selected)
def run(self, obj=None):
self._selected = obj
@@ -516,20 +467,27 @@
else:
adapted = obj
obj = self.interface(adapted)
+
rv = self.run_editor(obj)
- if not rv:
- rollback_and_begin(self.conn)
- return
+ if rv:
+ if self.editor_class.model_iface:
+ rv = rv.get_adapted()
- if self.editor_class.model_iface:
- rv = rv.get_adapted()
+ self.search.refresh()
+ self.enable_ok()
- self.conn.commit()
- self.update_edited_item(rv)
- self.enable_ok()
+ def run_dialog(self, editor_class, parent, *args):
+ run_dialog(editor_class, parent, *args)
def run_editor(self, obj):
- return run_dialog(self.editor_class, self, self.conn, obj)
+ trans = new_transaction()
+ retval = self.run_dialog(self.editor_class, self, trans,
+ trans.get(obj))
+ if finish_transaction(trans, retval):
+ assert isinstance(retval, SQLObject)
+ retval = type(retval).get(retval.id, connection=self.conn)
+ trans.close()
+ return retval
# Private
@@ -538,15 +496,15 @@
return
if obj is None:
- if self.klist.get_selection_mode() == gtk.SELECTION_MULTIPLE:
- obj = self.klist.get_selected_rows()
+ if self.results.get_selection_mode() == gtk.SELECTION_MULTIPLE:
+ obj = self.results.get_selected_rows()
qty = len(obj)
if qty != 1:
raise AssertionError(
"There should be only one item selected. Got %s items"
% qty)
else:
- obj = self.klist.get_selected()
+ obj = self.results.get_selected()
if not obj:
raise AssertionError(
"There should be at least one item selected")
@@ -561,7 +519,7 @@
def _on_toolbar__new(self, toolbar):
self.run()
- def _on_list__double_click(self, list, obj):
+ def _on_results__double_click(self, results, obj):
self._edit(obj)
#
Modified: stoqlib/trunk/stoqlib/gui/dialogs/tillhistory.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/dialogs/tillhistory.py (original)
+++ stoqlib/trunk/stoqlib/gui/dialogs/tillhistory.py Wed Apr 25 15:50:38 2007
@@ -2,7 +2,7 @@
# vi:si:et:sw=4:sts=4:ts=4
##
-## Copyright (C) 2005-2007 Async Open Source <http://www.async.com.br>
+## Copyright (C) 2007 Async Open Source <http://www.async.com.br>
## All rights reserved
##
## This program is free software; you can redistribute it and/or modify
@@ -19,10 +19,7 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., or visit: http://www.gnu.org/.
##
-## Author(s): Henrique Romano <henrique at async.com.br>
-## Bruno Rafael Garcia <brg at async.com.br>
-## Evandro Vale Miquelito <evandro at async.com.br>
-## Johan Dahlin <jdahlin at async.com.br>
+## Author(s): Johan Dahlin <jdahlin at async.com.br>
##
""" Implementation of classes related to till operations. """
@@ -31,116 +28,40 @@
import gtk
from kiwi.datatypes import currency
-from kiwi.ui.delegates import GladeSlaveDelegate
+from kiwi.ui.search import DateSearchFilter, Today
from kiwi.ui.widgets.list import Column, ColoredColumn
-from sqlobject.sqlbuilder import IN
-from stoqlib.database.database import finish_transaction, rollback_and_begin
-from stoqlib.lib.translation import stoqlib_gettext
-from stoqlib.lib.defaults import payment_value_colorize
-from stoqlib.lib.validators import get_formatted_price
-from stoqlib.domain.interfaces import IPaymentGroup
-from stoqlib.domain.sale import Sale
-from stoqlib.domain.till import TillEntry, Till
-from stoqlib.domain.payment.payment import Payment
-from stoqlib.gui.base.searchbar import SearchBar
-from stoqlib.gui.base.dialogs import BasicWrappingDialog, run_dialog
+from stoqlib.database.database import finish_transaction
+from stoqlib.domain.till import TillEntry
+from stoqlib.gui.base.search import SearchDialog
+from stoqlib.gui.base.dialogs import run_dialog
from stoqlib.gui.editors.tilleditor import (CashAdvanceEditor, CashInEditor,
CashOutEditor)
+from stoqlib.lib.translation import stoqlib_gettext
+from stoqlib.lib.defaults import payment_value_colorize
_ = stoqlib_gettext
-class TillHistoryDialog(GladeSlaveDelegate):
- app_name = _('Till History')
- gladefile = 'TillHistoryDialog'
- widgets = ('cash_out_button',
- 'cash_advance_button',
- 'cash_in_button',
- 'total_balance_label',
- 'payments')
-
- title = _('Current Till History')
- size = (750, -1)
-
- def __init__(self, conn):
- GladeSlaveDelegate.__init__(self, gladefile=self.gladefile)
- self.main_dialog = BasicWrappingDialog(self, self.title,
- size=self.size,
- hide_footer=True)
- self.conn = conn
- self._setup_widgets()
- self._setup_slaves()
- self._update_widgets()
- self.main_dialog.set_title(self._get_title())
- self.search_bar.search_items()
- self._check_initial_cash_amount()
-
- def on_cancel(self):
- # XXX We need a proper base class in stoqlib to avoid redefining this
- # method here. bug 2217
- self.main_dialog.close()
-
- def _get_title(self):
- today_format = _('%d of %B')
- today_str = datetime.date.today().strftime(today_format)
- return _('Stoq - %s of %s') % (self.app_name, today_str)
-
- def _sync(self, *args):
- rollback_and_begin(self.conn)
-
- def _setup_slaves(self):
- self.search_bar = SearchBar(self.conn, TillEntry,
- self._get_columns(),
- searching_by_date=True)
- self.search_bar.register_extra_query_callback(self.get_extra_query)
- self.search_bar.set_searchbar_labels(_('Items Matching'))
- self.search_bar.set_result_strings(_('item'), _('items'))
- self.search_bar.connect('search-activate', self._update_list)
- self.search_bar.connect('before-search-activate', self._sync)
- self.attach_slave('searchbar_holder', self.search_bar)
-
- def _update_widgets(self):
- self.selected_item = self.payments.get_selected_rows()
- self.canceled_items = 0
- self.selected = 0
-
- def _setup_widgets(self):
- self.payments.set_columns(self._get_columns())
- self.payments.set_visible_rows(10)
- self.payments.set_selection_mode(gtk.SELECTION_MULTIPLE)
- self._update_total()
+class TillHistoryDialog(SearchDialog):
+ size = (780, -1)
+ table = TillEntry
+ selection_mode = gtk.SELECTION_MULTIPLE
+ searchbar_labels = _('Till Entries matching:')
+
+ @property
+ def title(self):
+ return _('Till history %s') % (
+ datetime.date.today().strftime(_('%d of %B')))
- def _run_editor(self, editor_class):
- model = run_dialog(editor_class, self, self.conn)
- if finish_transaction(self.conn, model):
- self.search_bar.search_items()
- self.payments.unselect_all()
- self._select_last_item()
-
- def _select_last_item(self):
- if len(self.payments):
- self.payments.select(self.payments[-1])
-
- def _update_list(self, slave, objs):
- self.payments.add_list(objs)
- self._update_total()
-
- def _update_total(self, *args):
- total_balance = currency(0)
- for item in self.payments:
- total_balance += item.value
- total_balance_str = get_formatted_price(total_balance)
- self.total_balance_label.set_text(total_balance_str)
- if total_balance < 0:
- self.total_balance_label.set_color('red')
- else:
- self.total_balance_label.set_color('black')
+ #
+ # SearchDialog
+ #
- def _get_columns(self, *args):
+ def get_columns(self, *args):
return [Column('id', _('Number'), data_type=int, width=80,
format='%03d', sorted=True),
- Column('date', _('Due Date'),
+ Column('date', _('Date'),
data_type=datetime.date, width=110),
Column('description', _('Description'), data_type=str,
expand=True,
@@ -148,42 +69,36 @@
ColoredColumn('value', _('Value'), data_type=currency,
color='red', data_func=payment_value_colorize,
width=140)]
+ def create_filters(self):
+ self.set_text_field_columns(['description'])
- def _check_initial_cash_amount(self):
- # This method is wrong.
- # A good way to get the initial cash amount payment would be to
- # use the payment_id.
- # Waiting for bug 2524
- for item in self.selected_item:
- if item.description == _('Initial cash amount'):
- return True
- return False
+ date_filter = DateSearchFilter(_('Date:'))
+ date_filter.select(Today)
+ self.add_filter(date_filter, columns=['date'])
+
+ def setup_widgets(self):
+ self.results.set_visible_rows(10)
+ self._add_editor_button(_('Cash _Advance...'), CashAdvanceEditor)
+ self._add_editor_button(_('Cash _In...'), CashInEditor)
+ self._add_editor_button(_('Cash _Out...'), CashOutEditor)
+
+ def _add_editor_button(self, name, editor_class):
+ b = gtk.Button(name)
+ b.connect('clicked', lambda b: self._run_editor(editor_class))
+ b.set_use_underline(True)
+ self.action_area.set_layout(gtk.BUTTONBOX_START)
+ self.action_area.pack_start(b, False, False, 6)
+ b.show()
#
- # Searchbar callbacks
+ # Private API
#
- def get_extra_query(self):
- current_till = Till.get_current(self.conn)
- assert current_till
- group_ids = []
- for sale in Sale.get_available_sales(self.conn, current_till):
- group = IPaymentGroup(sale)
- group_ids.append(group.id)
- return IN(Payment.q.groupID, group_ids)
-
- #
- # Kiwi handlers
- #
-
- def on_payments__selection_changed(self, *args):
- self._update_widgets()
-
- def on_cash_out_button__clicked(self, button):
- self._run_editor(CashOutEditor)
-
- def on_cash_in_button__clicked(self, button):
- self._run_editor(CashInEditor)
+ def _run_editor(self, editor_class):
+ model = run_dialog(editor_class, self, self.conn)
+ if finish_transaction(self.conn, model):
+ self.search.refresh()
+ self.results.unselect_all()
+ if len(self.results):
+ self.results.select(self.results[-1])
- def on_cash_advance_button__clicked(self, button):
- self._run_editor(CashAdvanceEditor)
Modified: stoqlib/trunk/stoqlib/gui/interfaces.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/interfaces.py (original)
+++ stoqlib/trunk/stoqlib/gui/interfaces.py Wed Apr 25 15:50:38 2007
@@ -21,51 +21,3 @@
##
## Author(s): Johan Dahlin <jdahlin at async.com.br>
##
-
-from zope.interface import Interface
-
-class ISearchBarEntrySlave(Interface):
- """
- This interface represents a slave which you can embed in a SearchBar.
- """
-
- def get_slave():
- """
- Returns the slave which we embed in the search bar
- """
-
- def start_animation():
- """
- Start the search animation. This is called when a search is begun.
- """
-
- def stop_animation():
- """
- Stop the search animation. This is called after a search is done.
- """
-
- def clear():
- """
- Clear all interactive widgets inside the slave
- """
-
- def get_extra_queries():
- """
- Return a list of queries that will be combined with an AND in
- the searchbar itself.
- It can return an empty list if desired.
- """
-
- def get_search_string():
- pass
-
- def set_search_string(search_str):
- pass
-
- def set_search_label(label):
- pass
-
- def set_focus():
- """
- Grab the focus
- """
Modified: stoqlib/trunk/stoqlib/gui/search/categorysearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/categorysearch.py (original)
+++ stoqlib/trunk/stoqlib/gui/search/categorysearch.py Wed Apr 25 15:50:38 2007
@@ -50,6 +50,10 @@
self.set_searchbar_labels(self.searchbar_label)
self.set_result_strings(*self.result_strings)
+ def create_filters(self):
+ self.set_text_field_columns(['description'])
+ self.executer.add_query_callback(self._get_query)
+
def get_columns(self):
return [
Column("description", _("Description"), data_type=str,
@@ -61,7 +65,11 @@
width=190),
]
- def get_extra_query(self):
+ #
+ # Private
+ #
+
+ def _get_query(self, states):
return SellableCategory.q.categoryID != None
class BaseSellableCatSearch(SellableCategorySearch):
@@ -71,6 +79,10 @@
result_strings = _('base category'), _('base categories')
editor = BaseSellableCategoryEditor
+ def create_filters(self):
+ self.set_text_field_columns(['description'])
+ self.executer.add_query_callback(self._get_query)
+
def get_columns(self):
columns = SellableCategorySearch.get_columns(self)
del columns[-1]
@@ -81,5 +93,9 @@
)
return columns
- def get_extra_query(self):
+ #
+ # Private
+ #
+
+ def _get_query(self, states):
return SellableCategory.q.categoryID == None
Modified: stoqlib/trunk/stoqlib/gui/search/fiscalsearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/fiscalsearch.py (original)
+++ stoqlib/trunk/stoqlib/gui/search/fiscalsearch.py Wed Apr 25 15:50:38 2007
@@ -2,7 +2,7 @@
# vi:si:et:sw=4:sts=4:ts=4
##
-## Copyright (C) 2005, 2006 Async Open Source <http://www.async.com.br>
+## Copyright (C) 2005-2007 Async Open Source <http://www.async.com.br>
## All rights reserved
##
## This program is free software; you can redistribute it and/or modify
@@ -20,25 +20,25 @@
## Foundation, Inc., or visit: http://www.gnu.org/.
##
## Author(s): Evandro Vale Miquelito <evandro at async.com.br>
-##
+## Johan Dahlin <jdahlin at async.com.br>
##
""" Search dialogs for fiscal objects """
import datetime
import gtk
-from kiwi.ui.widgets.list import Column
from kiwi.datatypes import currency
+from kiwi.enums import SearchFilterPosition
+from kiwi.ui.search import ComboSearchFilter
+from kiwi.ui.widgets.list import Column
+from stoqlib.domain.fiscal import CfopData, IcmsIpiView, IssView
from stoqlib.enums import FiscalBookEntry
-from stoqlib.lib.translation import stoqlib_gettext
-from stoqlib.lib.defaults import ALL_ITEMS_INDEX
from stoqlib.gui.base.search import SearchEditor
-from stoqlib.gui.editors.fiscaleditor import CfopEditor
-from stoqlib.gui.slaves.fiscalslave import FiscalBookEntryFilterSlave
-from stoqlib.gui.editors.fiscaleditor import FiscalBookEntryEditor
-from stoqlib.domain.fiscal import CfopData, IcmsIpiView, IssView
-
+from stoqlib.gui.editors.fiscaleditor import (CfopEditor,
+ FiscalBookEntryEditor)
+from stoqlib.lib.defaults import fiscal_book_entries
+from stoqlib.lib.translation import stoqlib_gettext
_ = stoqlib_gettext
@@ -54,6 +54,9 @@
# SearchDialog Hooks
#
+ def create_filters(self):
+ self.set_text_field_columns(['description', 'code'])
+
def get_columns(self):
return [Column('code', _('CFOP'), data_type=str, sorted=True,
width=90),
@@ -70,35 +73,35 @@
has_new_button = False
searchbar_result_strings = _("fiscal entry"), _("fiscal entries")
- def _setup_columns(self, columns, table, col_name, summary_label_text):
+ def _setup_columns(self, column, table, col_name, summary_label_text):
label_text = '<b>%s</b>' % summary_label_text
- self.klist.set_columns(columns)
- self.set_searchtable(table)
- self.set_searchbar_columns(columns)
- self.setup_summary_label(col_name, label_text)
+ columns = self.get_columns() + [column]
+ self.results.set_columns(columns)
+ self.set_table(table)
+ #self.setup_summary_label(col_name, label_text)
def _setup_icms_columns(self):
- cols = self.get_columns() + [Column('icms_value',
- title=_('ICMS Total'),
- justify=gtk.JUSTIFY_RIGHT,
- data_type=currency, width=120)]
- self._setup_columns(cols, IcmsIpiView, 'icms_value',
+ col = Column('icms_value',
+ title=_('ICMS Total'),
+ justify=gtk.JUSTIFY_RIGHT,
+ data_type=currency, width=120)
+ self._setup_columns(col, IcmsIpiView, 'icms_value',
_("ICMS Total:"))
def _setup_ipi_columns(self):
- cols = self.get_columns() + [Column('ipi_value',
- title=_('IPI Total'),
- justify=gtk.JUSTIFY_RIGHT,
- data_type=currency, width=120)]
- self._setup_columns(cols, IcmsIpiView, 'ipi_value',
+ col = Column('ipi_value',
+ title=_('IPI Total'),
+ justify=gtk.JUSTIFY_RIGHT,
+ data_type=currency, width=120)
+ self._setup_columns(col, IcmsIpiView, 'ipi_value',
_("IPI Total:"))
def _setup_iss_columns(self):
- cols = self.get_columns() + [Column('iss_value',
- title=_('ISS Total'),
- justify=gtk.JUSTIFY_RIGHT,
- data_type=currency, width=120)]
- self._setup_columns(cols, IssView, 'iss_value',
+ col = Column('iss_value',
+ title=_('ISS Total'),
+ justify=gtk.JUSTIFY_RIGHT,
+ data_type=currency, width=120)
+ self._setup_columns(col, IssView, 'iss_value',
_("ISS Total:"))
#
@@ -117,9 +120,8 @@
data_type=str, expand=True)]
- def get_extra_query(self):
- branch = self.filter_slave.get_selected_branch()
- entry_type = self.filter_slave.get_selected_entry_type()
+ def _get_entry_type_query(self, state):
+ entry_type = state.value
if entry_type == FiscalBookEntry.ICMS:
self._setup_icms_columns()
elif entry_type == FiscalBookEntry.ISS:
@@ -129,17 +131,21 @@
else:
raise ValueError("Invalid fical book entry type, got %s"
% entry_type)
- if branch != ALL_ITEMS_INDEX:
- return self.search_table.q.branch_id == branch.id
#
# SearchDialog Hooks
#
- def get_filter_slave(self):
- self.filter_slave = FiscalBookEntryFilterSlave(self.conn)
- return self.filter_slave
-
- def after_search_bar_created(self):
- self.filter_slave.connect('status-changed',
- self.search_bar.search_items)
+ def create_filters(self):
+ self.set_text_field_columns([])
+
+ branch_filter = self.create_branch_filter(_('In branch:'))
+ branch_filter.select(None)
+ self.add_filter(branch_filter, columns=['branch_id'])
+
+ items = [(v, k)
+ for k, v in fiscal_book_entries.items()]
+ entry_type = ComboSearchFilter(_('Show entries of type'), items)
+ self.add_filter(entry_type, callback=self._get_entry_type_query,
+ position=SearchFilterPosition.TOP)
+
Modified: stoqlib/trunk/stoqlib/gui/search/giftcertificatesearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/giftcertificatesearch.py (original)
+++ stoqlib/trunk/stoqlib/gui/search/giftcertificatesearch.py Wed Apr 25 15:50:38 2007
@@ -27,13 +27,13 @@
import gtk
from kiwi.datatypes import currency
+from kiwi.enums import SearchFilterPosition
+from kiwi.ui.search import ComboSearchFilter
from stoqlib.lib.translation import stoqlib_gettext
-from stoqlib.lib.defaults import ALL_ITEMS_INDEX
from stoqlib.domain.sellable import ASellable
from stoqlib.domain.giftcertificate import (GiftCertificateType,
GiftCertificateView)
-from stoqlib.gui.slaves.filterslave import FilterSlave
from stoqlib.gui.base.search import SearchEditor
from stoqlib.gui.base.columns import Column
from stoqlib.gui.editors.giftcertificateeditor import (
@@ -53,31 +53,20 @@
SearchEditor.__init__(self, conn, self.table, self.editor_class,
hide_footer=hide_footer,
title=self.title)
- self.search_bar.set_result_strings(_('gift certificate type'),
- _('gift certificate types'))
- self.search_bar.set_searchbar_labels(_('matching'))
+ self.set_searchbar_labels(_('matching'))
#
# SearchDialog Hooks
#
- def get_filter_slave(self):
- certificates = [(_('Active'), True), (_('Inactive'), False)]
- certificates.insert(0, (_('Any'), ALL_ITEMS_INDEX))
- self.filter_slave = FilterSlave(certificates, selected=ALL_ITEMS_INDEX)
- self.filter_slave.set_filter_label(_('Show gift certificate types '
- 'with status'))
- return self.filter_slave
-
- def after_search_bar_created(self):
- self.filter_slave.connect('status-changed',
- self.search_bar.search_items)
-
- def on_cell_edited(self, klist, obj, attr):
- # Waiting for bug 2177. We should only call commit for
- # self.conn here.
- conn = obj.get_connection()
- conn.commit()
+ def create_filters(self):
+ self.set_text_field_columns([])
+ certificates = [(_('Any'), None),
+ (_('Active'), True),
+ (_('Inactive'), False)]
+ status_filter = ComboSearchFilter(
+ _('Show gift certificate types with status'), certificates)
+ self.add_filter(status_filter, SearchFilterPosition.TOP, ['is_active'])
#
# SearchEditor Hooks
@@ -102,11 +91,6 @@
Column('is_active', _('Active'), data_type=bool,
editable=True)]
- def get_extra_query(self):
- status = self.filter_slave.get_selected_status()
- if status != ALL_ITEMS_INDEX:
- return GiftCertificateType.q.is_active == status
-
class GiftCertificateSearch(SearchEditor):
"""A search dialog for gift certificates. A gift certificate is a
@@ -123,34 +107,31 @@
hide_toolbar=hide_toolbar,
title=self.title)
self.hide_edit_button()
- self.search_bar.set_result_strings(_('gift certificate'),
- _('gift certificates'))
- self.search_bar.set_searchbar_labels(_('matching'))
+ self.set_result_strings(_('gift certificate'),
+ _('gift certificates'))
+ self.set_searchbar_labels(_('matching'))
#
# SearchDialog Hooks
#
- def get_filter_slave(self):
+ def create_filters(self):
+ self.set_text_field_columns([])
statuses = [(value, constant)
for constant, value in ASellable.statuses.items()]
- statuses.insert(0, (_('Any'), ALL_ITEMS_INDEX))
- selected = ASellable.STATUS_AVAILABLE
- self.filter_slave = FilterSlave(statuses, selected=selected)
- self.filter_slave.set_filter_label(_('Show gift certificates with '
- 'status'))
- return self.filter_slave
-
- def after_search_bar_created(self):
- self.filter_slave.connect('status-changed',
- self.search_bar.search_items)
+ statuses.insert(0, (_('Any'), None))
+ status_filter = ComboSearchFilter(
+ _('Show gift certificates with status'), statuses)
+ status_filter.select(ASellable.STATUS_AVAILABLE)
+ self.add_filter(status_filter, SearchFilterPosition.TOP, ['status'])
+
#
# SearchEditor Hooks
#
def update_edited_item(self, *args):
- self.search_bar.search_items()
+ self.search.refresh()
def get_columns(self):
return [Column('id', _('Number'), data_type=int,
@@ -163,8 +144,3 @@
data_type=currency, width=120),
Column('on_sale_price', title=_('On Sale Price'),
data_type=currency, width=140)]
-
- def get_extra_query(self):
- status = self.filter_slave.get_selected_status()
- if status != ALL_ITEMS_INDEX:
- return self.table.q.status == status
Modified: stoqlib/trunk/stoqlib/gui/search/personsearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/personsearch.py (original)
+++ stoqlib/trunk/stoqlib/gui/search/personsearch.py Wed Apr 25 15:50:38 2007
@@ -2,7 +2,7 @@
# vi:si:et:sw=4:sts=4:ts=4
##
-## Copyright (C) 2005, 2006 Async Open Source <http://www.async.com.br>
+## Copyright (C) 2005-2007 Async Open Source <http://www.async.com.br>
## All rights reserved
##
## This program is free software; you can redistribute it and/or modify
@@ -22,15 +22,16 @@
## Author(s): Evandro Vale Miquelito <evandro at async.com.br>
## Henrique Romano <henrique at async.com.br>
## Ariqueli Tejada Fonseca <aritf at async.com.br>
+## Johan Dahlin <jdahlin at async.com.br>
##
""" Search dialogs for person objects """
-from sqlobject.sqlbuilder import LEFTJOINOn, AND, OR
-from kiwi.ui.widgets.list import Column
from kiwi.argcheck import argcheck
+from kiwi.enums import SearchFilterPosition
+from kiwi.ui.search import ComboSearchFilter
+from kiwi.ui.widgets.list import Column
from stoqlib.lib.translation import stoqlib_gettext
-from stoqlib.lib.defaults import ALL_ITEMS_INDEX
from stoqlib.lib.validators import format_phone_number
from stoqlib.gui.editors.personeditor import (ClientEditor, SupplierEditor,
EmployeeEditor,
@@ -40,14 +41,14 @@
FinanceProviderEditor)
from stoqlib.gui.base.search import SearchEditor
from stoqlib.gui.base.dialogs import run_dialog
-from stoqlib.gui.base.columns import FacetColumn, ForeignKeyColumn
from stoqlib.gui.dialogs.clientdetails import ClientDetailsDialog
-from stoqlib.gui.slaves.filterslave import FilterSlave
-from stoqlib.domain.interfaces import (ICompany, ISupplier, IEmployee,
- IClient, ICreditProvider,
- ITransporter, IBranch)
-from stoqlib.domain.person import (Person, EmployeeRole, ClientView,
- PersonAdaptToEmployee)
+from stoqlib.domain.person import (EmployeeRole,
+ PersonAdaptToBranch, BranchView,
+ PersonAdaptToClient, ClientView,
+ PersonAdaptToCreditProvider, CreditProviderView,
+ PersonAdaptToEmployee, EmployeeView,
+ TransporterView,
+ SupplierView)
from stoqlib.gui.wizards.personwizard import run_person_role_dialog
_ = stoqlib_gettext
@@ -72,131 +73,98 @@
self.set_searchbar_labels(self.search_lbl_text)
self.set_result_strings(*self.result_strings)
- def run_editor(self, obj):
- return run_person_role_dialog(self.editor_class, self,
- self.conn, obj)
-
+ def run_dialog(self, editor_class, parent, *args):
+ run_person_role_dialog(editor_class, parent, *args)
class EmployeeSearch(BasePersonSearch):
title = _('Employee Search')
editor_class = EmployeeEditor
- table = PersonAdaptToEmployee
+ table = EmployeeView
search_lbl_text = _('matching:')
result_strings = _('employee'), _('employees')
- filter_label = _('Show employees with status')
#
# SearchDialog Hooks
#
- def get_filter_slave(self):
- employees = [(value, key) for key, value in
- self.table.statuses.items()]
- employees.insert(0, (_('Any'), ALL_ITEMS_INDEX))
- self.filter_slave = FilterSlave(employees, selected=ALL_ITEMS_INDEX)
- self.filter_slave.set_filter_label(self.filter_label)
- return self.filter_slave
-
- def after_search_bar_created(self):
- self.filter_slave.connect('status-changed',
- self.search_bar.search_items)
+ def create_filters(self):
+ self.set_text_field_columns(['name', 'role', 'registry_number'])
+ items = [(value, key) for key, value in
+ PersonAdaptToEmployee.statuses.items()]
+ items.insert(0, (_('Any'), None))
+ status_filter = ComboSearchFilter(_('Show employees with status'),
+ items)
+ self.add_filter(status_filter, SearchFilterPosition.TOP, ['status'])
def get_columns(self):
- return [ForeignKeyColumn(Person, 'name', _('Name'), str,
- width=250, adapted=True,
- expand=True),
- ForeignKeyColumn(EmployeeRole, 'name', _('Role'),
- str, width=250, obj_field='role'),
+ return [Column('name', _('Name'), str,
+ width=250, expand=True),
+ Column('role', _('Role'), str,
+ width=250),
Column('registry_number', _('Registry Number'), str,
width=150),
Column('status_string', _('Status'), str)]
- def get_extra_query(self):
- employee_table = Person.getAdapterClass(IEmployee)
- query = employee_table.q._originalID == Person.q.id
- status = self.filter_slave.get_selected_status()
- if status != ALL_ITEMS_INDEX:
- query = AND(query, employee_table.q.status == status)
- return query
-
- def get_query_args(self):
- return dict(join=LEFTJOINOn(
- self.table, EmployeeRole,
- self.table.q.roleID == EmployeeRole.q.id))
-
- def get_searchlist_model(self, model):
- return IEmployee(model)
+ def get_editor_model(self, model):
+ return model.employee
class SupplierSearch(BasePersonSearch):
title = _('Supplier Search')
editor_class = SupplierEditor
size = (750, 450)
- table = Person
- interface = ISupplier
+ table = SupplierView
search_lbl_text = _('Suppliers Matching:')
result_strings = _('supplier'), _('suppliers')
#
- # Hooks
+ # SearchDialog hooks
#
+ def create_filters(self):
+ self.set_text_field_columns(['name', 'phone_number', 'cnpj'])
+
def get_columns(self):
return [Column('name', _('Name'), str,
sorted=True, width=250, expand=True),
Column('phone_number', _('Phone Number'), str,
format_func=format_phone_number, width=110),
- FacetColumn(ICompany, 'fancy_name', _('Fancy Name'), str,
- width=180),
- FacetColumn(ICompany, 'cnpj', _('CNPJ'), str, width=140)]
-
- def get_extra_query(self):
- supplier_table = Person.getAdapterClass(ISupplier)
- return Person.q.id == supplier_table.q._originalID
-
- def get_query_args(self):
- company_table = Person.getAdapterClass(ICompany)
- return dict(join=LEFTJOINOn(
- Person, company_table,
- Person.q.id == company_table.q._originalID))
-
+ Column('fancy_name', _('Fancy Name'), str,
+ width=180),
+ Column('cnpj', _('CNPJ'), str, width=140)]
class AbstractCreditProviderSearch(BasePersonSearch):
title = ""
- table = Person
- interface = ICreditProvider
+ table = CreditProviderView
search_lbl_text = ''
result_strings = None
editor_class = None
def __init__(self, conn, title='', hide_footer=True):
- self.provider_table = self.table.getAdapterClass(ICreditProvider)
+ self.provider_table = PersonAdaptToCreditProvider
BasePersonSearch.__init__(self, conn, title, hide_footer)
+ def create_filters(self):
+ self.set_text_field_columns(['name', 'phone_number', 'short_name'])
+ self.executer.add_query_callback(self._get_query)
+
def get_columns(self):
return [Column('name', title=_('Name'),
data_type=str, sorted=True, expand=True),
Column('phone_number', _('Phone Number'), str,
format_func=format_phone_number, width=130),
- FacetColumn(ICreditProvider, 'short_name',
- title=_('Short Name'), data_type=str,
- width=150),
- FacetColumn(ICreditProvider, 'is_active',
- title=_('Active'), data_type=bool,
- editable=True)]
-
- def on_cell_edited(self, klist, obj, attr):
- conn = obj.get_connection()
- conn.commit()
+ Column('short_name', _('Short Name'), str,
+ width=150),
+ Column('is_active', _('Active'), bool)]
def get_provider_type(self):
raise NotImplementedError("This method must be defined on child")
- def get_extra_query(self):
- q1 = self.table.q.id == self.provider_table.q._originalID
- q2 = self.provider_table.q.provider_type == self.get_provider_type()
- return AND(q1, q2)
+ def get_editor_model(self, provider_view):
+ return provider_view.provider
+ def _get_query(self, states):
+ return self.provider_table.q.provider_type == self.get_provider_type()
class CardProviderSearch(AbstractCreditProviderSearch):
title = _('Card Provider Search')
@@ -229,24 +197,14 @@
# SearchDialog Hooks
#
- def get_filter_slave(self):
- client_table = Person.getAdapterClass(IClient)
- statuses = [(value, key) for key, value in
- client_table.statuses.items()]
- statuses.insert(0, (_('Any'), ALL_ITEMS_INDEX))
- self.filter_slave = FilterSlave(statuses, selected=ALL_ITEMS_INDEX)
- filter_label = _('Show clients with status')
- self.filter_slave.set_filter_label(filter_label)
- return self.filter_slave
-
- def after_search_bar_created(self):
- self.filter_slave.connect('status-changed',
- self.search_bar.search_items)
-
- @argcheck(ClientView)
- def get_editor_model(self, client_view):
- return Person.iget(IClient, client_view.client_id,
- connection=self.conn)
+ def create_filters(self):
+ self.set_text_field_columns(['name', 'cpf', 'rg_number', 'phone_number'])
+ statuses = [(v, k) for k, v in PersonAdaptToClient.statuses.items()]
+ statuses.insert(0, (_('Any'), None))
+ status_filter = ComboSearchFilter(_('Show clients with status'),
+ statuses)
+ status_filter.select(None)
+ self.add_filter(status_filter, SearchFilterPosition.TOP, ['status'])
def get_columns(self):
return [Column('name', _('Name'), str,
@@ -256,41 +214,37 @@
Column('cpf', _('CPF'), str, width=130),
Column('rg_number', _('RG'), str, width=120)]
- def get_extra_query(self):
- status = self.filter_slave.get_selected_status()
- if status != ALL_ITEMS_INDEX:
- return self.table.q.status == status
+ @argcheck(ClientView)
+ def get_editor_model(self, client_view):
+ return client_view.client
def on_details_button_clicked(self, *args):
- items = self.klist.get_selected()
- client = Person.iget(IClient, items.client_id, connection=self.conn)
- run_dialog(ClientDetailsDialog, self, self.conn, client)
+ selected = self.results.get_selected()
+ run_dialog(ClientDetailsDialog, self, self.conn, selected.client)
def update_widgets(self, *args):
- items = self.klist.get_selected()
- self.set_details_button_sensitive(items is not None)
- self.set_edit_button_sensitive(items is not None)
+ client_view = self.results.get_selected()
+ self.set_details_button_sensitive(client_view is not None)
+ self.set_edit_button_sensitive(client_view is not None)
class TransporterSearch(BasePersonSearch):
title = _('Transporter Search')
editor_class = TransporterEditor
- table = Person
- interface = ITransporter
+ table = TransporterView
search_lbl_text = _('matching:')
result_strings = _('transporter'), _('transporters')
- def get_filter_slave(self):
- items = [(_('Active Transporters'), True),
- (_('Inactive Transporters'), False)]
- items.insert(0, (_('Any Transporters'), ALL_ITEMS_INDEX))
- self.filter_slave = FilterSlave(items, selected=ALL_ITEMS_INDEX)
- self.filter_slave.set_filter_label(_('Show:'))
- return self.filter_slave
-
- def after_search_bar_created(self):
- self.filter_slave.connect('status-changed',
- self.search_bar.search_items)
+ def create_filters(self):
+ self.set_text_field_columns(['name', 'phone_number'])
+ items = [(_('Active'), True),
+ (_('Inactive'), False)]
+ items.insert(0, (_('Any'), None))
+
+ status_filter = ComboSearchFilter(_('Show transporters with status'),
+ items)
+ status_filter.select(None)
+ self.add_filter(status_filter, SearchFilterPosition.TOP, ['is_active'])
def get_columns(self):
return [Column('name', title=_('Name'),
@@ -298,37 +252,29 @@
expand=True),
Column('phone_number', _('Phone Number'), str,
format_func=format_phone_number, width=180),
- FacetColumn(ITransporter, 'freight_percentage',
- title=_('Freight (%)'), data_type=float,
- width=150),
- FacetColumn(ITransporter, 'status_string',
- title=_('Status'), data_type=str)]
-
- def get_extra_query(self):
- transporter_table = self.table.getAdapterClass(ITransporter)
- query = self.table.q.id == transporter_table.q._originalID
- status = self.filter_slave.get_selected_status()
- if status != ALL_ITEMS_INDEX:
- query = AND(query, transporter_table.q.is_active == status)
- return query
+ Column('freight_percentage', _('Freight (%)'), float,
+ width=150)]
class EmployeeRoleSearch(SearchEditor):
title = _('Employee Role Search')
editor_class = EmployeeRoleEditor
table = EmployeeRole
- size = (425, 390)
+ size = (-1, 390)
def __init__(self, conn):
SearchEditor.__init__(self, conn, EmployeeRoleSearch.table,
EmployeeRoleSearch.editor_class)
- self.set_searchbar_labels(_('Role Matching'))
self.set_result_strings(_('role'), _('roles'))
#
# SearchEditor Hooks
#
+ def create_filters(self):
+ self.set_text_field_columns(['name'])
+ self.set_searchbar_labels(_('Role Matching'))
+
def get_columns(self):
return [Column('name', _('Role'), str, sorted=True)]
@@ -337,7 +283,7 @@
size = (750, 500)
title = _('Branch Search')
editor_class = BranchEditor
- table = Person.getAdapterClass(IBranch)
+ table = BranchView
search_lbl_text = _('matching')
result_strings = (_('branch'), _('branches'))
@@ -345,46 +291,37 @@
# SearchEditor Hooks
#
+ def create_filters(self):
+ self.set_text_field_columns(['name', 'phone_number'])
+ statuses = [(value, key)
+ for key, value in PersonAdaptToBranch.statuses.items()]
+ statuses.insert(0, (_('Any'), None))
+ status_filter = ComboSearchFilter(_('Show branches with status'),
+ statuses)
+ status_filter.select(None)
+ self.executer.add_filter_query_callback(
+ status_filter, self._get_status_query)
+ self.search.add_filter(status_filter, SearchFilterPosition.TOP)
+
def get_columns(self):
- return [ForeignKeyColumn(Person, 'name', _('Name'), data_type=str,
- width=200, adapted=True, expand=True),
- ForeignKeyColumn(Person, 'phone_number',
- _('Phone Number'), data_type=str,
- width=150, adapted=True),
- ForeignKeyColumn(Person, 'name', _('Manager'), data_type=str,
- width=250, obj_field='manager'),
+ return [Column( 'name', _('Name'), str,
+ width=200, expand=True),
+ Column('phone_number', _('Phone Number'), str,
+ width=150),
+ #Column('manager_name', _('Manager'), str,
+ # width=250),
Column('status_str', _('Status'), data_type=str)]
- def get_extra_query(self):
- table = Person.getAdapterClass(IBranch)
- query = OR(Person.q.id == self.table.q.managerID,
- Person.q.id == self.table.q._originalID)
-
- status = self.filter_slave.get_selected_status()
- if status == self.table.STATUS_ACTIVE:
- query = AND(query, table.q.is_active == True)
- elif status == self.table.STATUS_INACTIVE:
- query = AND(query, table.q.is_active == False)
-
- return query
-
- def get_searchlist_model(self, person):
- return IBranch(person)
+ def get_editor_model(self, branch_view):
+ return branch_view.branch
#
- # SearchDialog Hooks
+ # Private
#
- def get_filter_slave(self):
- statuses = [(value, key)
- for key, value in self.table.statuses.items()]
- statuses.insert(0, (_('Any'), ALL_ITEMS_INDEX))
- filter_label = _('Show branches with status')
- self.filter_slave = FilterSlave(statuses, selected=ALL_ITEMS_INDEX)
- self.filter_slave.set_filter_label(filter_label)
- return self.filter_slave
-
- def after_search_bar_created(self):
- self.filter_slave.connect('status-changed',
- self.search_bar.search_items)
+ def _get_status_query(self, state):
+ if state.value == PersonAdaptToBranch.STATUS_ACTIVE:
+ return PersonAdaptToBranch.q.is_active == True
+ elif state.value == PersonAdaptToBranch.STATUS_INACTIVE:
+ return PersonAdaptToBranch.q.is_active == False
Modified: stoqlib/trunk/stoqlib/gui/search/productsearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/productsearch.py (original)
+++ stoqlib/trunk/stoqlib/gui/search/productsearch.py Wed Apr 25 15:50:38 2007
@@ -2,7 +2,7 @@
# vi:si:et:sw=4:sts=4:ts=4
##
-## Copyright (C) 2005, 2006 Async Open Source <http://www.async.com.br>
+## Copyright (C) 2005-2007 Async Open Source <http://www.async.com.br>
## All rights reserved
##
## This program is free software; you can redistribute it and/or modify
@@ -21,6 +21,7 @@
##
## Author(s): Bruno Rafael Garcia <brg at async.com.br>
## Evandro Vale Miquelito <evandro at async.com.br>
+## Johan Dahlin <jdahlin at async.com.br>
##
""" Search dialogs for product objects """
@@ -28,16 +29,18 @@
import gtk
from kiwi.datatypes import currency
+from kiwi.enums import SearchFilterPosition
+from kiwi.ui.search import ComboSearchFilter
from kiwi.ui.objectlist import Column
+from stoqlib.domain.person import PersonAdaptToBranch
from stoqlib.domain.product import Product
+from stoqlib.domain.sellable import ASellable
from stoqlib.domain.views import ProductFullStockView
from stoqlib.gui.editors.producteditor import ProductEditor
-from stoqlib.gui.slaves.productslave import ProductFilterSlave
from stoqlib.gui.search.sellablesearch import SellableSearch
from stoqlib.gui.base.dialogs import print_report
from stoqlib.lib.translation import stoqlib_gettext
-from stoqlib.lib.defaults import ALL_ITEMS_INDEX
from stoqlib.lib.validators import format_quantity
from stoqlib.reporting.product import ProductReport
@@ -78,23 +81,37 @@
if hide_price_column:
self._hide_column('price')
self.set_edit_button_sensitive(False)
- self.klist.connect('selection-changed', self.on_selection_changed)
+ self.results.connect('selection-changed', self.on_selection_changed)
def _hide_column(self, colname):
- column = self.klist.get_column_by_name(colname)
- col_index = self.klist.get_columns().index(column)
- self.klist.set_column_visibility(col_index, False)
+ column = self.results.get_column_by_name(colname)
+ col_index = self.results.get_columns().index(column)
+ self.results.set_column_visibility(col_index, False)
def on_print_button_clicked(self, button):
- print_report(ProductReport, list(self.klist))
+ print_report(ProductReport, list(self.results))
#
# SearchDialog Hooks
#
- def get_filter_slave(self):
- self.filter_slave = ProductFilterSlave(self.conn)
- return self.filter_slave
+ def create_filters(self):
+ self.set_text_field_columns(['description'])
+ self.executer.set_query(self._executer_query)
+
+ # Branch
+ branch_filter = self.create_branch_filter(_('In branch:'))
+ branch_filter.select(None)
+ self.add_filter(branch_filter, columns=[])
+ self.branch_filter = branch_filter
+
+ # Status
+ statuses = [(desc, id) for id, desc in ASellable.statuses.items()]
+ statuses.insert(0, (_('Any'), None))
+ status_filter = ComboSearchFilter(_('with status:'), statuses)
+ status_filter.select(None)
+ self.add_filter(status_filter, columns=['status'],
+ position=SearchFilterPosition.TOP)
def get_branch(self):
# We have not a filter for branches in this dialog and in this case
@@ -114,7 +131,7 @@
Column('barcode', title=_('Barcode'), data_type=str,
width=120),
Column('description', title=_('Description'), data_type=str,
- expand=True),
+ width=150),
Column('supplier_name', title=_('Supplier'), data_type=str,
width=150),
Column('cost', _('Cost'), data_type=currency,
@@ -125,18 +142,13 @@
format_func=format_quantity,
data_type=Decimal, width=100)]
- def get_extra_query(self):
- status = self.filter_slave.get_selected_status()
- if status != ALL_ITEMS_INDEX:
- return self.search_table.q.status == status
-
- def query(self, table, query, args):
- branch = self.filter_slave.get_selected_branch()
- if branch == ALL_ITEMS_INDEX:
- branch = None
+ def _executer_query(self, query, conn):
+ branch = self.branch_filter.get_state().value
+ if branch is not None:
+ branch = PersonAdaptToBranch.get(branch, connection=conn)
return ProductFullStockView.select_by_branch(query, branch,
- connection=self.conn)
+ connection=conn)
- def on_selection_changed(self, klist, selected):
+ def on_selection_changed(self, results, selected):
can_edit = bool(selected)
self.set_edit_button_sensitive(can_edit)
Modified: stoqlib/trunk/stoqlib/gui/search/receivingsearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/receivingsearch.py (original)
+++ stoqlib/trunk/stoqlib/gui/search/receivingsearch.py Wed Apr 25 15:50:38 2007
@@ -35,7 +35,7 @@
from stoqlib.domain.receiving import ReceivingOrder
from stoqlib.reporting.purchase_receival import PurchaseReceivalReport
from stoqlib.gui.dialogs.receivingdialog import ReceivingOrderDetailsDialog
-from stoqlib.gui.base.dialogs import run_dialog
+from stoqlib.gui.base.dialogs import print_report, run_dialog
_ = stoqlib_gettext
@@ -85,7 +85,7 @@
self._show_receiving_order(receiving_order)
def on_print_button_clicked(self, button):
- self.search_bar.print_report(PurchaseReceivalReport, list(self.klist))
+ print_report(PurchaseReceivalReport, list(self.klist))
def on_details_button_clicked(self, button):
items = self.klist.get_selected_rows()
Modified: stoqlib/trunk/stoqlib/gui/search/salesearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/salesearch.py (original)
+++ stoqlib/trunk/stoqlib/gui/search/salesearch.py Wed Apr 25 15:50:38 2007
@@ -2,7 +2,7 @@
# vi:si:et:sw=4:sts=4:ts=4
##
-## Copyright (C) 2005, 2006 Async Open Source <http://www.async.com.br>
+## Copyright (C) 2005-2007 Async Open Source <http://www.async.com.br>
## All rights reserved
##
## This program is free software; you can redistribute it and/or modify
@@ -20,6 +20,7 @@
## Foundation, Inc., or visit: http://www.gnu.org/.
##
## Author(s): Bruno Rafael Garcia <brg at async.com.br>
+## Johan Dahlin <jdahlin at async.com.br>
##
##
""" Search dialogs for sale objects """
@@ -30,14 +31,14 @@
import gtk
from kiwi.datatypes import currency
+from kiwi.enums import SearchFilterPosition
+from kiwi.ui.search import ComboSearchFilter
from kiwi.ui.widgets.list import Column
from stoqlib.lib.translation import stoqlib_gettext
-from stoqlib.lib.defaults import ALL_ITEMS_INDEX
from stoqlib.lib.validators import format_quantity
from stoqlib.gui.base.search import SearchDialog
from stoqlib.domain.sale import Sale, SaleView
-from stoqlib.gui.slaves.filterslave import FilterSlave
from stoqlib.gui.slaves.saleslave import SaleListToolbar
_ = stoqlib_gettext
@@ -52,22 +53,21 @@
def __init__(self, conn):
SearchDialog.__init__(self, conn, self.search_table,
title=self.title)
- self._setup_widgets()
self._setup_slaves()
- def _setup_slaves(self):
- slave = SaleListToolbar(self.conn, self.klist, self)
- slave.disable_editing()
- self.attach_slave("extra_holder", slave)
-
- def _setup_widgets(self):
- self.search_bar.set_result_strings(_('sale'), _('sales'))
- self.search_bar.set_searchbar_labels(_('matching:'))
-
#
- # SearchBar Hooks
+ # SearchDialog Hooks
#
+ def create_filters(self):
+ self.set_text_field_columns(['client_name', 'salesperson_name'])
+ self.set_searchbar_labels(_('matching:'))
+ items = [(value, key) for key, value in Sale.statuses.items()]
+ items.insert(0, (_('Any'), None))
+
+ status_filter = ComboSearchFilter(_('Show sales witbh status'), items)
+ self.add_filter(status_filter, SearchFilterPosition.TOP, ['status'])
+
def get_columns(self):
return [Column('id', title=_('Number'), width=70,
data_type=int, sorted=True),
@@ -83,22 +83,11 @@
Column('total', title=_('Total'), data_type=currency,
width=80)]
- def get_extra_query(self):
- status = self.filter_slave.get_selected_status()
- if status != ALL_ITEMS_INDEX:
- return SaleView.q.status == status
-
#
- # SearchDialog Hooks
+ # Private
#
- def get_filter_slave(self):
- items = [(value, key) for key, value in Sale.statuses.items()]
- items.insert(0, (_('Any'), ALL_ITEMS_INDEX))
- self.filter_slave = FilterSlave(items, selected=Sale.STATUS_CONFIRMED)
- self.filter_slave.set_filter_label(_('Show sales with status'))
- return self.filter_slave
-
- def after_search_bar_created(self):
- self.filter_slave.connect('status-changed',
- self.search_bar.search_items)
+ def _setup_slaves(self):
+ slave = SaleListToolbar(self.conn, self.results, self)
+ slave.disable_editing()
+ self.attach_slave("extra_holder", slave)
Modified: stoqlib/trunk/stoqlib/gui/search/sellablesearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/sellablesearch.py (original)
+++ stoqlib/trunk/stoqlib/gui/search/sellablesearch.py Wed Apr 25 15:50:38 2007
@@ -30,22 +30,19 @@
import gtk
from kiwi.datatypes import currency
+from kiwi.enums import SearchFilterPosition
from kiwi.ui.objectlist import Column
from sqlobject.sqlbuilder import AND, OR
-from stoqlib.database.runtime import get_current_branch
from stoqlib.gui.base.columns import AccessorColumn
from stoqlib.gui.base.search import SearchEditor
-from stoqlib.gui.slaves.filterslave import FilterSlave
from stoqlib.lib.parameters import sysparam
from stoqlib.lib.validators import format_quantity
-from stoqlib.lib.defaults import ALL_BRANCHES, ALL_ITEMS_INDEX
from stoqlib.lib.translation import stoqlib_gettext
from stoqlib.domain.sellable import (ASellable, SellableView,
SellableFullStockView)
from stoqlib.domain.product import Product
-from stoqlib.domain.person import Person
-from stoqlib.domain.interfaces import IBranch, ISellable, IStorable
+from stoqlib.domain.interfaces import ISellable, IStorable
_ = stoqlib_gettext
@@ -75,6 +72,7 @@
"""
self.quantity = quantity
self.has_stock_mode = sysparam(conn).HAS_STOCK_MODE
+ self._delivery_service = sysparam(conn).DELIVERY_SERVICE
SearchEditor.__init__(self, conn, table=self.table,
search_table=self.search_table,
editor_class=self.editor_class,
@@ -108,6 +106,17 @@
# Hooks
#
+ def create_filters(self):
+ #if not self.has_stock_mode:
+ # return
+ self.set_text_field_columns(['description'])
+ branch_filter = self.create_branch_filter(
+ _('Show sale items at'))
+ self.executer.add_filter_query_callback(
+ branch_filter, self._get_branch_query)
+ self.executer.add_query_callback(self._get_query)
+ self.search.add_filter(branch_filter, SearchFilterPosition.TOP)
+
def get_columns(self):
"""Hook called by SearchEditor"""
columns = [Column('id', title=_('Code'), data_type=int,
@@ -130,54 +139,8 @@
columns.append(column)
return columns
- def _get_available_stock(self, sellable_view):
- if sellable_view.stock is None:
- return None
- return sellable_view.stock - self.current_sale_stock.get(
- sellable_view.id, 0)
-
- def get_extra_query(self):
- """Hook called by SearchBar"""
- branch_query = None
- if (not self.has_stock_mode
- or self.filter_slave.get_selected_status() == ALL_ITEMS_INDEX):
- self.set_searchtable(SellableFullStockView)
- branch_query = 1 == 1
- else:
- self.set_searchtable(SellableView)
- branch = self.filter_slave.get_selected_status()
- branch_query = OR(SellableView.q.branch_id == branch.id,
- SellableView.q.branch_id == None)
- service = sysparam(self.conn).DELIVERY_SERVICE
- return AND(self.search_table.q.id != service.id,
- (self.search_table.q.status
- == ASellable.STATUS_AVAILABLE),
- branch_query)
-
- def get_filter_slave(self):
- if not self.has_stock_mode:
- return
- # FIXME: Implement and use IDescribable on PersonAdaptToBranch
- table = Person.getAdapterClass(IBranch)
- branch_list = table.get_active_branches(self.conn)
- items = [(branch.person.name, branch)
- for branch in branch_list]
- if not items:
- raise ValueError('You should have at least one branch at '
- 'this point')
- items.insert(0, ALL_BRANCHES)
- selected = get_current_branch(self.conn)
- self.filter_slave = FilterSlave(items, selected=selected)
- self.filter_slave.set_filter_label(_('Show sale items at'))
- return self.filter_slave
-
- def after_search_bar_created(self):
- if self.has_stock_mode:
- self.filter_slave.connect('status-changed',
- self.search_bar.search_items)
-
def update_widgets(self):
- sellable_view = self.klist.get_selected()
+ sellable_view = self.results.get_selected()
if not sellable_view:
return
sellable = ASellable.get(sellable_view.id, self.conn)
@@ -186,3 +149,33 @@
self.ok_button.set_sensitive(False)
else:
self.ok_button.set_sensitive(True)
+
+ #
+ # Private
+ #
+
+ def _get_branch_query(self, state):
+ query = None
+ if self.has_stock_mode and state.value is not None:
+ table = SellableView
+ query = OR(SellableView.q.branch_id == state.value,
+ SellableView.q.branch_id == None)
+ else:
+ table = SellableFullStockView
+
+ self.set_table(table)
+ return query
+
+ def _get_query(self, states):
+ query = self.search_table.q.status == ASellable.STATUS_AVAILABLE
+ if self._delivery_service:
+ query = AND(query,
+ self.search_table.q.id != self._delivery_service.id)
+ return query
+
+ def _get_available_stock(self, sellable_view):
+ if sellable_view.stock is None:
+ return None
+ return sellable_view.stock - self.current_sale_stock.get(
+ sellable_view.id, 0)
+
Modified: stoqlib/trunk/stoqlib/gui/search/servicesearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/servicesearch.py (original)
+++ stoqlib/trunk/stoqlib/gui/search/servicesearch.py Wed Apr 25 15:50:38 2007
@@ -2,7 +2,7 @@
# vi:si:et:sw=4:sts=4:ts=4
##
-## Copyright (C) 2006 Async Open Source <http://www.async.com.br>
+## Copyright (C) 2006-2007 Async Open Source <http://www.async.com.br>
## All rights reserved
##
## This program is free software; you can redistribute it and/or modify
@@ -20,21 +20,22 @@
## Foundation, Inc., or visit: http://www.gnu.org/.
##
## Author(s): Evandro Vale Miquelito <evandro at async.com.br>
+## Johan Dahlin <jdahlin at async.com.br>
##
##
""" Search dialogs for services """
import gtk
-from kiwi.datatypes import currency
from kiwi.argcheck import argcheck
+from kiwi.datatypes import currency
+from kiwi.enums import SearchFilterPosition
+from kiwi.ui.search import ComboSearchFilter
from stoqlib.lib.translation import stoqlib_gettext
-from stoqlib.lib.defaults import ALL_ITEMS_INDEX
from stoqlib.domain.sellable import ASellable
from stoqlib.domain.service import Service, ServiceView
from stoqlib.gui.base.columns import Column
from stoqlib.gui.editors.serviceeditor import ServiceEditor
-from stoqlib.gui.slaves.filterslave import FilterSlave
from stoqlib.gui.search.sellablesearch import SellableSearch
_ = stoqlib_gettext
@@ -65,13 +66,15 @@
# SearchDialog Hooks
#
- def get_filter_slave(self):
- statuses = [(value, key)
- for key, value in ASellable.statuses.items()]
- statuses.insert(0, (_('Any'), ALL_ITEMS_INDEX))
- self.filter_slave = FilterSlave(statuses, selected=ALL_ITEMS_INDEX)
- self.filter_slave.set_filter_label(_('Show services with status'))
- return self.filter_slave
+ def create_filters(self):
+ self.set_text_field_columns(['description', 'barcode'])
+ items = [(v, k) for k, v in ASellable.statuses.items()]
+ items.insert(0, (_('Any'), None))
+ service_filter = ComboSearchFilter(_('Show services with status'),
+ items)
+ service_filter.select(None)
+ self.executer.add_query_callback(self._get_query)
+ self.add_filter(service_filter, SearchFilterPosition.TOP, ['status'])
def get_branch(self):
# We have not a filter for branches in this dialog and in this case
@@ -105,8 +108,3 @@
columns.append(Column('unit', title=_('Unit'),
data_type=str, width=80))
return columns
-
- def get_extra_query(self):
- status = self.filter_slave.get_selected_status()
- if status != ALL_ITEMS_INDEX:
- return self.search_table.q.status == status
Modified: stoqlib/trunk/stoqlib/gui/search/stationsearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/stationsearch.py (original)
+++ stoqlib/trunk/stoqlib/gui/search/stationsearch.py Wed Apr 25 15:50:38 2007
@@ -2,7 +2,7 @@
# vi:si:et:sw=4:sts=4:ts=4
##
-## Copyright (C) 2006 Async Open Source <http://www.async.com.br>
+## Copyright (C) 2006-2007 Async Open Source <http://www.async.com.br>
## All rights reserved
##
## This program is free software; you can redistribute it and/or modify
@@ -20,19 +20,17 @@
## Foundation, Inc., or visit: http://www.gnu.org/.
##
## Author(s): J. Victor Martins <jvdm at sdf.lonestar.org>
+## Johan Dahlin <jdahlin at async.com.br>
##
""" Search dialog for station objects """
+from kiwi.enums import SearchFilterPosition
from kiwi.ui.objectlist import Column
-from stoqlib.domain.interfaces import IBranch
from stoqlib.domain.station import BranchStation
-from stoqlib.domain.person import Person
from stoqlib.gui.base.columns import AccessorColumn
from stoqlib.gui.base.search import SearchEditor
from stoqlib.gui.editors.stationeditor import StationEditor
-from stoqlib.gui.slaves.filterslave import FilterSlave
-from stoqlib.lib.defaults import ALL_BRANCHES, ALL_ITEMS_INDEX
from stoqlib.lib.translation import stoqlib_gettext
_ = stoqlib_gettext
@@ -42,25 +40,17 @@
table = BranchStation
editor_class = StationEditor
searchbar_result_strings = _("Station"), _("Stations")
- filter_label = _('Branch')
size = (-1, 450)
#
# SearchDialog Hooks
#
- def get_filter_slave(self):
- statuses = [ALL_BRANCHES]
- # FIXME: Implement and use IDescribable on PersonAdaptToBranch
- for branch in Person.iselect(IBranch, connection=self.conn):
- statuses.append((branch.person.name, branch))
- self.filter_slave = FilterSlave(statuses, selected=ALL_ITEMS_INDEX)
- self.filter_slave.set_filter_label(self.filter_label)
- return self.filter_slave
-
- def after_search_bar_created(self):
- self.filter_slave.connect('status-changed',
- self.search_bar.search_items)
+ def create_filters(self):
+ self.set_text_field_columns(['name'])
+ branch_filter = self.create_branch_filter()
+ self.add_filter(branch_filter,
+ SearchFilterPosition.TOP, ['branchID'])
def get_columns(self):
return [Column('name', _('Name'), data_type=str, sorted=True,
@@ -72,9 +62,3 @@
title=_('Branch'), data_type=str,
expand=True),
]
-
- def get_extra_query(self):
- branch = self.filter_slave.get_selected_status()
- if branch != ALL_ITEMS_INDEX:
- return BranchStation.q.branchID == branch.id
-
Modified: stoqlib/trunk/stoqlib/gui/search/tillsearch.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/search/tillsearch.py (original)
+++ stoqlib/trunk/stoqlib/gui/search/tillsearch.py Wed Apr 25 15:50:38 2007
@@ -27,15 +27,15 @@
import datetime
import gtk
-from kiwi.ui.widgets.list import Column, ColoredColumn
from kiwi.datatypes import currency
-from sqlobject.sqlbuilder import AND
+from kiwi.enums import SearchFilterPosition
+from kiwi.ui.search import ComboSearchFilter, DateSearchFilter
+from kiwi.ui.widgets.list import Column, ColoredColumn
from stoqlib.database.runtime import get_current_branch
from stoqlib.lib.translation import stoqlib_gettext
-from stoqlib.lib.defaults import ALL_ITEMS_INDEX, payment_value_colorize
+from stoqlib.lib.defaults import payment_value_colorize
from stoqlib.gui.base.search import SearchDialog
-from stoqlib.gui.slaves.filterslave import FilterSlave
from stoqlib.domain.till import TillFiscalOperationsView, Till
@@ -50,14 +50,29 @@
searchbar_labels = _(u"matching:"),
searchbar_result_strings = _(u"fiscal operation"), _(u"fiscal operations")
- def __init__(self, conn):
- SearchDialog.__init__(self, conn)
- self.setup_summary_label('value', "<b>%s</b>" % (u"Total:"))
-
#
# SearchDialog Hooks
#
+ def create_filters(self):
+ self.set_text_field_columns(['description'])
+ self.executer.add_query_callback(self._get_query)
+
+ # Status
+ items = [(v, k) for k, v in Till.statuses.items()
+ if k != Till.STATUS_PENDING]
+ items.insert(0, (_(u'Any'), None))
+ status_filter = ComboSearchFilter(_(u'Show entries of type'), items)
+ status_filter.select(Till.STATUS_OPEN)
+ self.add_filter(status_filter,
+ position=SearchFilterPosition.TOP,
+ columns=['status'])
+
+ # Date
+ date_filter = DateSearchFilter(_('Date:'))
+ self.add_filter(
+ date_filter, columns=['date'])
+
def get_columns(self, *args):
return [Column('id', title=_('#'), width=60,
justify=gtk.JUSTIFY_RIGHT, format="%05d",
@@ -72,26 +87,11 @@
color='red', data_func=payment_value_colorize,
width=80)]
- def get_extra_query(self):
- branch_id = get_current_branch(self.conn).id
- base_query = self.search_table.q.branch_id == branch_id
- status = self.filter_slave.get_selected_status()
- if status == ALL_ITEMS_INDEX:
- return base_query
- return AND(base_query, TillFiscalOperationsView.q.status == status)
-
- def update_klist(self, *args):
- SearchDialog.update_klist(self, *args)
-
- def get_filter_slave(self):
- items = [(value, key) for key, value in Till.statuses.items()
- if key != Till.STATUS_PENDING]
- items.insert(0, (_(u'Any'), ALL_ITEMS_INDEX))
- self.filter_slave = FilterSlave(items, selected=Till.STATUS_OPEN)
- self.filter_slave.set_filter_label(_(u'Show entries of type'))
- return self.filter_slave
-
- def after_search_bar_created(self):
- self.filter_slave.connect('status-changed',
- self.search_bar.search_items)
+ #
+ # Private
+ #
+
+ def _get_query(self, state):
+ branch = get_current_branch(self.conn)
+ return self.search_table.q.branch_id == branch.id
Modified: stoqlib/trunk/stoqlib/gui/slaves/individualslave.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/slaves/individualslave.py (original)
+++ stoqlib/trunk/stoqlib/gui/slaves/individualslave.py Wed Apr 25 15:50:38 2007
@@ -109,7 +109,7 @@
if self.model.birth_location:
self.model.birth_location = self.model.birth_location.clone()
else:
- cityloc = CityLocation(connection=self.conn)
+ cityloc = CityLocation(connection=self.model.get_connection())
self.model.birth_location = cityloc
self.birth_loc_proxy = self.add_proxy(
self.model.birth_location,
Modified: stoqlib/trunk/stoqlib/gui/wizards/receivingwizard.py
==============================================================================
--- stoqlib/trunk/stoqlib/gui/wizards/receivingwizard.py (original)
+++ stoqlib/trunk/stoqlib/gui/wizards/receivingwizard.py Wed Apr 25 15:50:38 2007
@@ -31,12 +31,13 @@
import gtk
from kiwi.datatypes import currency
+from kiwi.db.sqlobj import SQLObjectQueryExecuter
+from kiwi.ui.search import SearchSlaveDelegate, DateSearchFilter
from kiwi.ui.widgets.list import Column
from stoqlib.database.runtime import get_current_user
from stoqlib.lib.translation import stoqlib_gettext
from stoqlib.gui.base.wizards import WizardEditorStep, BaseWizard
-from stoqlib.gui.base.searchbar import SearchBar
from stoqlib.gui.base.dialogs import run_dialog
from stoqlib.gui.slaves.receivingslave import ReceivingInvoiceSlave
from stoqlib.gui.search.productsearch import ProductSearch
@@ -75,9 +76,33 @@
if sysparam(self.conn).RECEIVE_PRODUCTS_WITHOUT_ORDER:
validation_value = True
else:
- validation_value = len(self.orders) == 1
+ validation_value = len(self.search.results) == 1
self.wizard.refresh_next(validation_value)
+ def _create_search(self):
+ self.order_label.set_size('large')
+ self.order_label.set_bold(True)
+ self.search = SearchSlaveDelegate(self._get_columns())
+ self.attach_slave('searchbar_holder', self.search)
+ self.executer = SQLObjectQueryExecuter()
+ self.search.set_query_executer(self.executer)
+ self.executer.set_table(PurchaseOrderView)
+ self.executer.add_query_callback(self._get_extra_query)
+ self._create_filters()
+ self.search.results.connect('selection-changed',
+ self._on_results__selection_changed)
+ self.search.results.connect('row-activated',
+ self._on_results__row_activated)
+ self.search.focus_search_entry()
+
+ def _create_filters(self):
+ self.search.set_text_field_columns(['supplier_name'])
+ date_filter = DateSearchFilter(_('Date:'))
+ self.search.add_filter(date_filter, columns=['open_date'])
+
+ def _get_extra_query(self, states):
+ return PurchaseOrderView.q.status == PurchaseOrder.ORDER_CONFIRMED
+
def _get_columns(self):
return [Column('id', title=_('Number'), sorted=True,
data_type=str, width=80),
@@ -95,20 +120,8 @@
Column('total', title=_('Order Total'),
data_type=currency, width=120)]
- def _get_extra_query(self):
- return PurchaseOrderView.q.status == PurchaseOrder.ORDER_CONFIRMED
-
- def on_searchbar_before_activate(self, *args):
- self.conn.commit()
-
- def on_searchbar_activate(self, slave, objs):
- """Use this callback with SearchBar search-activate signal"""
- self.orders.add_list(objs, clear=True)
- has_selection = self.orders.get_selected() is not None
- self.wizard.refresh_next(has_selection)
-
def _update_view(self):
- has_selection = self.orders.get_selected() is not None
+ has_selection = self.search.results.get_selected() is not None
self.details_button.set_sensitive(has_selection)
if not sysparam(self.conn).RECEIVE_PRODUCTS_WITHOUT_ORDER:
self.wizard.refresh_next(has_selection)
@@ -123,7 +136,7 @@
self.force_validation()
def next_step(self):
- selected = self.orders.get_selected()
+ selected = self.search.results.get_selected()
purchase = selected.purchase
# We cannot create the model in the wizard since we haven't
@@ -166,35 +179,28 @@
return False
def setup_slaves(self):
- self.order_label.set_size('large')
- self.order_label.set_bold(True)
- self.orders.set_columns(self._get_columns())
- self.searchbar = SearchBar(self.conn, PurchaseOrderView,
- self._get_columns(),
- searching_by_date=True)
- self.searchbar.register_extra_query_callback(self._get_extra_query)
- self.searchbar.set_result_strings(_('order'), _('orders'))
- self.searchbar.set_searchbar_labels(_('Orders Maching:'))
- self.searchbar.connect('before-search-activate',
- self.on_searchbar_before_activate)
- self.searchbar.connect('search-activate', self.on_searchbar_activate)
- self.attach_slave('searchbar_holder', self.searchbar)
- self.searchbar.set_focus()
+ self._create_search()
#
# Kiwi callbacks
#
- def on_orders__row_activated(self, klist, purchase_order_view):
- run_dialog(PurchaseDetailsDialog, self, self.conn,
- model=purchase_order_view.purchase)
+# def on_searchbar_activate(self, slave, objs):
+# """Use this callback with SearchBar search-activate signal"""
+# self.results.add_list(objs, clear=True)
+# has_selection = self.results.get_selected() is not None
+# self.wizard.refresh_next(has_selection)
- def on_orders__selection_changed(self, *args):
+ def _on_results__selection_changed(self, results, purchase_order_view):
self.force_validation()
self._update_view()
+ def _on_results__row_activated(self, results, purchase_order_view):
+ run_dialog(PurchaseDetailsDialog, self, self.conn,
+ model=purchase_order_view.purchase)
+
def on_details_button__clicked(self, *args):
- selected = self.orders.get_selected()
+ selected = self.search.results.get_selected()
if not selected:
raise ValueError('You should have one order selected '
'at this point, got nothing')
More information about the POS-commit
mailing list