Source code for stoq.gui.production

# -*- Mode: Python; coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4

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

import datetime

import gtk

from kiwi.ui.objectlist import Column

from stoqlib.api import api
from stoqlib.domain.production import ProductionOrder
from stoqlib.enums import SearchFilterPosition
from stoqlib.gui.dialogs.productiondetails import ProductionDetailsDialog
from stoqlib.gui.dialogs.productionquotedialog import ProductionQuoteDialog
from stoqlib.gui.dialogs.startproduction import StartProductionDialog
from stoqlib.gui.search.productionsearch import (ProductionProductSearch,
                                                 ProductionItemsSearch,
                                                 ProductionHistorySearch)
from stoqlib.gui.search.searchcolumns import IdentifierColumn, SearchColumn
from stoqlib.gui.search.servicesearch import ServiceSearch
from stoqlib.gui.search.searchfilters import ComboSearchFilter
from stoqlib.gui.stockicons import STOQ_PRODUCTION_APP
from stoqlib.gui.utils.keybindings import get_accels
from stoqlib.gui.wizards.productionwizard import ProductionWizard
from stoqlib.lib.translation import stoqlib_gettext as _
from stoqlib.reporting.production import ProductionReport
from stoqlib.lib.message import yesno

from stoq.gui.shell.shellapp import ShellApp


[docs]class ProductionApp(ShellApp): app_title = _(u'Production') gladefile = "production" search_spec = ProductionOrder search_label = _(u'matching:') report_table = ProductionReport # # Application #
[docs] def create_actions(self): group = get_accels('app.production') actions = [ ('menubar', None, ''), # File ('NewProduction', gtk.STOCK_NEW, _('Production order...'), group.get('new_production_order'), _('Create a new production')), ('ProductionPurchaseQuote', STOQ_PRODUCTION_APP, _('Purchase quote...'), group.get('new_production_quote')), # Production ('ProductionMenu', None, _('Production')), ('StartProduction', gtk.STOCK_CONVERT, _('Start production...'), group.get('production_start'), _('Start the selected production')), ('EditProduction', gtk.STOCK_EDIT, _('Edit production...'), group.get('production_edit'), _('Edit the selected production')), ('FinalizeProduction', gtk.STOCK_APPLY, _('Finalize production...'), None, _('Finalize the selected production')), ('CancelProduction', gtk.STOCK_CANCEL, _('Cancel production...'), None, _('Cancel the selected production')), ('ProductionDetails', gtk.STOCK_INFO, _('Production details...'), group.get('production_details'), _('Show production details and register produced items')), # Search ("SearchProduct", None, _("Production products..."), group.get('search_production_products'), _("Search for production products")), ("SearchService", None, _("Services..."), group.get('search_services'), _("Search for services")), ("SearchProductionItem", STOQ_PRODUCTION_APP, _("Production items..."), group.get('search_production_items'), _("Search for production items")), ("SearchProductionHistory", None, _("Production history..."), group.get('search_production_history'), _("Search for production history")), ] self.production_ui = self.add_ui_actions("", actions, filename="production.xml") self.set_help_section(_("Production help"), 'app-production') self.NewProduction.set_short_label(_("New Production")) self.ProductionPurchaseQuote.set_short_label(_("Purchase")) self.SearchProductionItem.set_short_label(_("Search items")) self.StartProduction.set_short_label(_('Start')) self.EditProduction.set_short_label(_('Edit')) self.FinalizeProduction.set_short_label(_('Finalize')) self.CancelProduction.set_short_label(_('Cancel')) self.ProductionDetails.set_short_label(_('Details')) self.StartProduction.props.is_important = True self.FinalizeProduction.props.is_important = True
[docs] def create_ui(self): self.popup = self.uimanager.get_widget('/ProductionSelection') self.window.add_new_items([self.NewProduction, self.ProductionPurchaseQuote]) self.window.add_search_items([ self.SearchProduct, self.SearchService, self.SearchProductionItem, ]) self.window.Print.set_tooltip( _("Print a report of these productions")) self._inventory_widgets = [self.StartProduction] self.register_sensitive_group(self._inventory_widgets, lambda: not self.has_open_inventory())
[docs] def activate(self, refresh=True): if refresh: self.refresh() self._update_widgets() self.check_open_inventory() self.search.focus_search_entry()
[docs] def deactivate(self): self.uimanager.remove_ui(self.production_ui)
[docs] def new_activate(self): self._open_production_order()
[docs] def search_activate(self): self.run_dialog(ProductionProductSearch, self.store)
[docs] def create_filters(self): self.set_text_field_columns(['description']) self.status_filter = ComboSearchFilter( _(u'Show productions with status'), self._get_status_values()) self.add_filter(self.status_filter, SearchFilterPosition.TOP, ['status'])
[docs] def get_columns(self): return [IdentifierColumn('identifier', title=_('Production #'), sorted=True, order=gtk.SORT_DESCENDING), Column('status_string', title=_(u'Status'), data_type=str, visible=False), SearchColumn('description', title=_(u'Description'), data_type=str, expand=True), Column('responsible.person.name', title=_(u'Responsible'), data_type=str, width=150), SearchColumn('open_date', title=_(u'Opened'), data_type=datetime.date, width=80), SearchColumn('close_date', title=_(u'Closed'), data_type=datetime.date, width=80), SearchColumn('cancel_date', title=_(u'Cancelled'), data_type=datetime.date, width=80)]
[docs] def print_report(self, *args, **kwargs): # ProductionReport needs a status kwarg kwargs['status'] = self.status_filter.get_state().value super(ProductionApp, self).print_report(*args, **kwargs)
[docs] def set_open_inventory(self): self.set_sensitive(self._inventory_widgets, False)
# # Private # def _update_widgets(self): selected = self.results.get_selected() can_edit = False can_start = False can_finalize = False can_cancel = False if selected: can_edit = (selected.status == ProductionOrder.ORDER_OPENED or selected.status == ProductionOrder.ORDER_WAITING) can_start = can_edit can_finalize = (selected.status == ProductionOrder.ORDER_PRODUCING) can_cancel = can_edit self.set_sensitive([self.EditProduction], can_edit) self.set_sensitive([self.StartProduction], can_start) self.set_sensitive([self.FinalizeProduction], can_finalize) self.set_sensitive([self.CancelProduction], can_cancel) self.set_sensitive([self.ProductionDetails], bool(selected)) def _get_status_values(self): items = [(text, value) for value, text in ProductionOrder.statuses.items()] items.insert(0, (_(u'Any'), None)) return items def _open_production_order(self, order=None): store = api.new_store() order = store.fetch(order) retval = self.run_dialog(ProductionWizard, store, order) store.confirm(retval) store.close() self.refresh() def _start_production_order(self): store = api.new_store() order = store.fetch(self.results.get_selected()) assert order is not None retval = self.run_dialog(StartProductionDialog, store, order) store.confirm(retval) store.close() self.refresh() def _production_details(self): order = self.results.get_selected() assert order is not None store = api.new_store() model = store.fetch(order) initial_status = model.status self.run_dialog(ProductionDetailsDialog, store, model) store.confirm(True) if initial_status != model.status: self.refresh() store.close() def _finalize_production(self): if not yesno(_("The selected order will be finalized."), gtk.RESPONSE_YES, _("Finalize order"), _("Don't finalize")): return with api.new_store() as store: model = store.fetch(self.results.get_selected()) model.try_finalize_production(ignore_completion=True) self.refresh() def _cancel_production(self): if not yesno(_("The selected order will be cancelled."), gtk.RESPONSE_YES, _("Cancel order"), _("Don't cancel")): return with api.new_store() as store: order = self.results.get_selected() model = store.fetch(order) model.cancel() self.refresh() # # Kiwi Callbacks #
[docs] def on_EditProduction__activate(self, widget): order = self.results.get_selected() assert order is not None self._open_production_order(order)
[docs] def on_ProductionDetails__activate(self, widget): self._production_details()
[docs] def on_FinalizeProduction__activate(self, widget): self._finalize_production()
[docs] def on_CancelProduction__activate(self, widget): self._cancel_production()
[docs] def on_results__selection_changed(self, results, selected): self._update_widgets()
[docs] def on_results__has_rows(self, widget, has_rows): self._update_widgets()
[docs] def on_results__row_activated(self, widget, order): self._production_details()
[docs] def on_results__right_click(self, results, result, event): self.popup.popup(None, None, None, event.button, event.time)
# Production
[docs] def on_NewProduction__activate(self, action): self._open_production_order()
[docs] def on_StartProduction__activate(self, action): self._start_production_order()
[docs] def on_ProductionPurchaseQuote__activate(self, action): with api.new_store() as store: self.run_dialog(ProductionQuoteDialog, store)
# Search
[docs] def on_SearchProduct__activate(self, action): self.run_dialog(ProductionProductSearch, self.store)
[docs] def on_SearchService__activate(self, action): self.run_dialog(ServiceSearch, self.store, hide_price_column=True)
[docs] def on_SearchProductionItem__activate(self, action): self.run_dialog(ProductionItemsSearch, self.store)
[docs] def on_SearchProductionHistory__activate(self, action): self.run_dialog(ProductionHistorySearch, self.store)