Source code for stoqlib.gui.wizards.productionwizard

# -*- 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 Lesser General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., or visit: http://www.gnu.org/.
##
## Author(s): Stoq Team <stoq-devel@async.com.br>
##
""" Production wizard definition """

from decimal import Decimal

from kiwi.currency import currency
from kiwi.datatypes import ValidationError
from kiwi.ui.objectlist import Column
from storm.expr import And

from stoqlib.api import api
from stoqlib.domain.person import Branch, Employee
from stoqlib.domain.production import (ProductionOrder, ProductionItem,
                                       ProductionService)
from stoqlib.domain.service import ServiceView
from stoqlib.domain.sellable import Sellable
from stoqlib.domain.views import ProductComponentView
from stoqlib.lib.dateutils import localtoday
from stoqlib.lib.translation import stoqlib_gettext
from stoqlib.lib.parameters import sysparam
from stoqlib.lib.formatters import format_quantity
from stoqlib.gui.base.wizards import (WizardEditorStep, BaseWizard,
                                      BaseWizardStep)
from stoqlib.gui.editors.productioneditor import (ProductionItemEditor,
                                                  ProductionServiceEditor)
from stoqlib.gui.slaves.productionslave import ProductionMaterialListSlave
from stoqlib.gui.wizards.abstractwizard import SellableItemStep

_ = stoqlib_gettext


#
# Wizard Steps
#


[docs]class OpenProductionOrderStep(WizardEditorStep): gladefile = 'OpenProductionOrderStep' model_type = ProductionOrder proxy_widgets = ['open_date', 'expected_start_date', 'identifier', 'branch', 'responsible', 'description'] def __init__(self, store, wizard, model): WizardEditorStep.__init__(self, store, wizard, model) def _fill_branch_combo(self): branches = Branch.get_active_branches(self.store) self.branch.prefill(api.for_person_combo(branches)) sync_mode = api.sysparam.get_bool('SYNCHRONIZED_MODE') self.branch.set_sensitive(not sync_mode) def _fill_responsible_combo(self): employees = self.store.find(Employee, status=Employee.STATUS_NORMAL) self.responsible.prefill(api.for_person_combo(employees)) def _setup_widgets(self): self._fill_branch_combo() self._fill_responsible_combo() self.open_date.set_sensitive(False) # # WizardStep hooks #
[docs] def post_init(self): self.description.grab_focus() self.table.set_focus_chain([self.branch, self.expected_start_date, self.responsible, self.description]) self.register_validate_function(self.wizard.refresh_next) self.force_validation()
[docs] def next_step(self): return ProductionServiceStep(self.wizard, self, self.store, self.model)
[docs] def has_previous_step(self): return False
[docs] def setup_proxies(self): self._setup_widgets() self.proxy = self.add_proxy( self.model, OpenProductionOrderStep.proxy_widgets) self.proxy.update('identifier', unicode(self.model.identifier)) # suggests a responsible for the production order if not self.model.responsible: self.responsible.select_item_by_position(0)
# # Kiwi Callbacks #
[docs] def on_expected_start_date__validate(self, widget, value): today = localtoday().date() if value and value < today: return ValidationError( _(u'Expected start date should be a future date.'))
[docs]class ProductionServiceStep(SellableItemStep): model_type = ProductionOrder item_table = ProductionService summary_label_text = "<b>%s</b>" % api.escape(_('Total:')) summary_label_column = 'quantity' sellable_view = ServiceView item_editor = ProductionServiceEditor # # Helper methods #
[docs] def get_sellable_view_query(self): delivery_sellable = sysparam.get_object( self.store, 'DELIVERY_SERVICE').sellable query = And(ServiceView.status == Sellable.STATUS_AVAILABLE, ServiceView.id != delivery_sellable.id) return self.sellable_view, query
[docs] def setup_slaves(self): SellableItemStep.setup_slaves(self) self.item_lbl.set_text(_(u'Services:')) self.hide_add_button() self.cost_label.hide() self.cost.hide()
def _get_production_service_by_sellable(self, sellable): service = sellable.service for item in self.slave.klist: if item.service is service: return item # # SellableItemStep virtual methods #
[docs] def validate(self, value): # This step is optional self.wizard.refresh_next(value)
[docs] def get_order_item(self, sellable, cost, quantity, batch=None, parent=None): assert batch is None item = self._get_production_service_by_sellable(sellable) if item is None: return ProductionService(service=sellable.service, quantity=quantity, order=self.model, store=self.store) item.quantity += quantity return item
[docs] def get_saved_items(self): return list(self.model.get_service_items())
[docs] def get_columns(self): return [ Column('service.sellable.code', title=_('Code'), data_type=str), Column('service.sellable.category_description', title=_('Category'), data_type=str, expand=True), Column('service.sellable.description', title=_('Description'), data_type=str, expand=True, sorted=True), Column('quantity', title=_('Quantity'), data_type=Decimal, format_func=format_quantity), Column('service.sellable.unit_description', title=_('Unit'), data_type=str), Column('service.sellable.cost', title=_('Cost'), data_type=currency)]
[docs] def remove_items(self, items): for item in items: self.model.remove_service_item(item)
# # WizardStep hooks #
[docs] def next_step(self): return ProductionItemStep(self.wizard, self, self.store, self.model)
[docs]class ProductionItemStep(SellableItemStep): """ Wizard step for production items selection """ model_type = ProductionOrder item_table = ProductionItem summary_label_text = "<b>%s</b>" % (api.escape(_('Total:')),) summary_label_column = 'quantity' sellable_view = ProductComponentView item_editor = ProductionItemEditor # # Helper methods #
[docs] def get_sellable_view_query(self): return self.sellable_view, None
[docs] def setup_slaves(self): SellableItemStep.setup_slaves(self) self.hide_add_button() self.cost_label.hide() self.cost.hide()
def _get_production_item_by_sellable(self, sellable): product = sellable.product for item in self.slave.klist: if item.product is product: return item # # SellableItemStep virtual methods #
[docs] def get_order_item(self, sellable, cost, quantity, batch=None, parent=None): # We should not add the children to the list if parent: return # We are not allowing production items to control batches right now assert batch is None item = self._get_production_item_by_sellable(sellable) if item is None: return self.model.add_item(sellable, quantity) item.quantity += quantity return item
[docs] def get_saved_items(self): return list(self.model.get_items())
[docs] def get_columns(self): return [ Column('product.sellable.code', title=_('Code'), data_type=str), Column('product.sellable.category_description', title=_('Category'), data_type=str, expand=True), Column('product.sellable.description', title=_('Description'), data_type=str, expand=True, sorted=True), Column('quantity', title=_('Quantity'), data_type=Decimal, format_func=format_quantity), Column('product.sellable.unit_description', title=_('Unit'), data_type=str)]
# # WizardStep hooks #
[docs] def next_step(self): return FinishOpenProductionOrderStep(self.wizard, self, self.store, self.model)
[docs]class FinishOpenProductionOrderStep(BaseWizardStep): gladefile = 'HolderTemplate' model_type = ProductionOrder proxy_widgets = [] def __init__(self, wizard, previous, store, model): self._order = model BaseWizardStep.__init__(self, store, wizard, previous) self._setup_slaves() def _setup_slaves(self): self._slave = ProductionMaterialListSlave(self.store, self._order, visual_mode=True) self.attach_slave('place_holder', self._slave) # # WizardStep hooks #
[docs] def has_next_step(self): return False
[docs] def post_init(self): self.register_validate_function(self.wizard.refresh_next) self.force_validation() # Reload materials, so if we go back and forward, the materials are # updated properly, self._slave.reload_materials()
[docs] def validate_step(self): return self._slave.validate_confirm()
# # Main wizard #
[docs]class ProductionWizard(BaseWizard): size = (775, 400) def __init__(self, store, model=None, edit_mode=False): title = self._get_title(model) model = model or self._create_model(store) first_step = OpenProductionOrderStep(store, self, model) BaseWizard.__init__(self, store, first_step, model, title=title, edit_mode=edit_mode) def _get_title(self, model=None): if not model: return _(u'New Production') return _(u'Edit Production') def _create_model(self, store): branch = api.get_current_branch(store) return ProductionOrder(branch=branch, store=store) # # WizardStep hooks #
[docs] def finish(self): self.retval = self.model self.close()