Source code for stoqlib.gui.dialogs.productiondetails

# -*- 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 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 details dialogs """

from decimal import Decimal

import pango
import gtk
from kiwi.ui.objectlist import Column, ColoredColumn

from stoqlib.api import api
from stoqlib.domain.inventory import Inventory
from stoqlib.domain.production import ProductionOrder
from stoqlib.gui.base.dialogs import run_dialog
from stoqlib.gui.editors.baseeditor import BaseEditor
from stoqlib.gui.slaves.productionslave import QualityTestResultSlave
from stoqlib.gui.editors.productioneditor import (ProductionItemProducedEditor,
                                                  ProductionMaterialLostEditor,
                                                  ProductionMaterialAllocateEditor,
                                                  )
from stoqlib.gui.utils.printing import print_report
from stoqlib.lib.translation import stoqlib_gettext
from stoqlib.reporting.production import ProductionOrderReport

_ = stoqlib_gettext


[docs]class ProductionDetailsDialog(BaseEditor): gladefile = "ProductionDetailsDialog" model_type = ProductionOrder title = _("Production Details") size = (750, 460) hide_footer = True proxy_widgets = ('branch', 'identifier', 'open_date', 'close_date', 'responsible_name', 'status_string', ) def _setup_widgets(self): self.production_items.set_columns(self._get_production_items_columns()) self.materials.set_columns(self._get_material_columns()) self.services.set_columns(self._get_service_columns()) self.produced_items.set_columns(self._get_produced_items_columns()) self.produced_items.set_selection_mode(gtk.SELECTION_MULTIPLE) def _setup_data(self): # FIXME: Improve this self.production_items.clear() self.materials.clear() self.services.clear() self.produced_items.clear() self.production_items.add_list(self.model.get_items()) self.materials.add_list(self.model.get_material_items()) self.services.add_list(self.model.get_service_items()) self.produced_items.add_list( self.model.produced_items.order_by(ProductionOrder.identifier)) self.proxy.update_many(['close_date', 'status_string']) def _get_production_items_columns(self): return [Column('description', title=_('Description'), data_type=str, expand=True, searchable=True, ellipsize=pango.ELLIPSIZE_END, sorted=True), Column('unit_description', _("Unit"), data_type=str, justify=gtk.JUSTIFY_RIGHT), Column('quantity', title=_('Quantity'), data_type=Decimal, justify=gtk.JUSTIFY_RIGHT), Column('produced', title=_('Produced'), data_type=Decimal, justify=gtk.JUSTIFY_RIGHT), Column('lost', title=_('Lost'), data_type=Decimal, justify=gtk.JUSTIFY_RIGHT)] def _get_material_columns(self): return [Column('description', title=_('Description'), data_type=str, expand=True, searchable=True, ellipsize=pango.ELLIPSIZE_END, sorted=True), Column('product.location', _("Location"), data_type=str), Column('unit_description', _("Unit"), data_type=str, justify=gtk.JUSTIFY_RIGHT), Column('needed', title=_('Needed'), data_type=Decimal, justify=gtk.JUSTIFY_RIGHT), Column('allocated', title=_('Allocated'), data_type=Decimal, justify=gtk.JUSTIFY_RIGHT), Column('consumed', title=_('Consumed'), data_type=Decimal, justify=gtk.JUSTIFY_RIGHT), Column('lost', title=_('Lost'), data_type=Decimal, justify=gtk.JUSTIFY_RIGHT), Column('to_purchase', title=_('To Purchase'), data_type=Decimal, justify=gtk.JUSTIFY_RIGHT, visible=False), Column('to_make', title=_('To Make'), data_type=Decimal, justify=gtk.JUSTIFY_RIGHT, visible=False)] def _get_service_columns(self): return [Column('description', _("Description"), data_type=str, expand=True, ellipsize=pango.ELLIPSIZE_END), Column('quantity', _("Quantity"), data_type=Decimal, justify=gtk.JUSTIFY_RIGHT), Column('unit_description', _("Unit"), data_type=str, justify=gtk.JUSTIFY_RIGHT)] def _get_test_result(self, item, quality_test): """Gets test result from cache, or fetch from database. """ hit = self._test_result_cache.get((item.id, quality_test.id), -1) if hit != -1: return hit test_result = item.get_test_result(quality_test) self._test_result_cache[(item.id, quality_test.id)] = test_result return test_result def _format_func(self, item, test): """Format function for tests columns. test is the quality test associated with the column """ test_result = self._get_test_result(item, test) if not test_result: val = '' else: val = test_result.result_value return val def _colorize(self, item, test): """Set the color for this test result test is the quality test associated with the column """ test_result = self._get_test_result(item, test) if not test_result: return False return not test_result.test_passed def _get_produced_items_columns(self): # Create a cache for test results, to avoid quering the database for # every update. self._test_result_cache = dict() columns = [Column('serial_number', title=_('Serial Number'), data_type=str, expand=True)] # Add one column for each test from each product. products = dict() for item in self.model.get_items(): if item.product in products: continue products[item.product] = 1 for test in item.product.quality_tests: columns.append( # This wont just the serial number, since we use format_func # to change the displayed value, but we still need one # property to create the column ColoredColumn('serial_number', data_type=str, title=test.description, format_func=self._format_func, format_func_data=test, color='red', data_func=self._colorize, use_data_model=True)) columns.extend([ Column('test_passed', title=_('Tests Passed'), data_type=bool, visible=False), Column('entered_stock', title=_('Entered Stock'), data_type=bool, visible=False)]) return columns # # BaseEditor hooks #
[docs] def setup_proxies(self): self._setup_widgets() self.proxy = self.add_proxy(self.model, ProductionDetailsDialog.proxy_widgets) self._setup_data()
[docs] def setup_slaves(self): self.quality_slave = QualityTestResultSlave(self.store) self.quality_slave.connect('test-updated', self._on_quality__test_updated) self.attach_slave('quality_holder', self.quality_slave)
[docs] def has_open_inventory(self): has_open = Inventory.has_open(self.store, api.get_current_branch(self.store)) return bool(has_open)
# # Actions # def _run_editor(self, editor_class, item): self.store.savepoint('before_run_editor_production') retval = run_dialog(editor_class, self, self.store, item) if not retval: self.store.rollback_to_savepoint('before_run_editor_production') else: self.store.commit() self._setup_data() def _produce(self): production_item = self.production_items.get_selected() self._run_editor(ProductionItemProducedEditor, production_item) def _add_lost(self): item = self.materials.get_selected() self._run_editor(ProductionMaterialLostEditor, item) def _allocate(self): item = self.materials.get_selected() self._run_editor(ProductionMaterialAllocateEditor, item) # # Kiwi Callbacks # def _on_quality__test_updated(self, slave, produced_item, quality_test, test_result): self._test_result_cache[(produced_item.id, quality_test.id)] = test_result self.produced_items.update(produced_item)
[docs] def on_print_button__clicked(self, widget): print_report(ProductionOrderReport, self.model)
[docs] def on_production_items__selection_changed(self, widget, item): self.produce_button.set_sensitive(bool(item) and item.can_produce(Decimal('0.001')) and not self.has_open_inventory())
[docs] def on_materials__selection_changed(self, widget, item): self.lost_button.set_sensitive(bool(item) and item.product.manage_stock and item.can_add_lost(Decimal('0.001'))) self.allocate_button.set_sensitive(bool(item) and item.product.manage_stock and self.model.status == ProductionOrder.ORDER_PRODUCING and not self.has_open_inventory())
[docs] def on_produced_items__selection_changed(self, widget, items): products = set() for i in items: products.add(i.product) is_in_qa = self.model.status in (ProductionOrder.ORDER_PRODUCING, ProductionOrder.ORDER_QA) # We can only set test results if only one type of product is selected if len(products) == 1 and is_in_qa: self.quality_slave.set_item_tests(items, items[0].product) else: self.quality_slave.set_item_tests([], None)
[docs] def on_lost_button__clicked(self, button): self._add_lost()
[docs] def on_allocate_button__clicked(self, button): self._allocate()
[docs] def on_produce_button__clicked(self, button): self._produce()
[docs] def on_production_items__row_activated(self, list, row): if self.produce_button.get_sensitive(): self._produce()