Source code for stoqlib.gui.templates.persontemplate

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

##
## 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
## 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>
##
##
""" Templates implementation for person editors.  """

import gtk

from stoqlib.domain.person import Company, Individual, Person, Supplier
from stoqlib.exceptions import DatabaseInconsistency
from stoqlib.gui.base.dialogs import run_dialog
from stoqlib.gui.base.slaves import NoteSlave
from stoqlib.gui.dialogs.addressdialog import AddressAdditionDialog
from stoqlib.gui.dialogs.contactsdialog import ContactInfoListDialog
from stoqlib.gui.editors.baseeditor import BaseEditorSlave, BaseEditor
from stoqlib.gui.search.callsearch import CallsSearch
from stoqlib.gui.search.creditcheckhistorysearch import CreditCheckHistorySearch
from stoqlib.gui.slaves.addressslave import AddressSlave
from stoqlib.gui.templates.companytemplate import CompanyEditorTemplate
from stoqlib.gui.templates.individualtemplate import IndividualEditorTemplate
from stoqlib.gui.utils.databaseform import DatabaseForm
from stoqlib.lib.message import warning
from stoqlib.lib.parameters import sysparam
from stoqlib.lib.translation import stoqlib_gettext

_ = stoqlib_gettext


class _PersonEditorTemplate(BaseEditorSlave):
    model_type = Person
    gladefile = 'PersonEditorTemplate'

    proxy_widgets = ('name',
                     'phone_number',
                     'fax_number',
                     'mobile_number',
                     'email')

    def __init__(self, store, model, visual_mode, ui_form_name, parent):
        self._parent = parent
        if ui_form_name:
            self.db_form = DatabaseForm(ui_form_name)
        else:
            self.db_form = None

        super(_PersonEditorTemplate, self).__init__(store, model,
                                                    visual_mode=visual_mode)

    #
    # BaseEditorSlave hooks
    #

    def create_model(self, store):
        return Person(name=u"", store=store)

    def setup_proxies(self):
        self._setup_widgets()
        self._setup_form_fields()
        self.proxy = self.add_proxy(self.model,
                                    _PersonEditorTemplate.proxy_widgets)

    def setup_slaves(self):
        self.address_slave = AddressSlave(
            self.store, self.model, self.model.get_main_address(),
            visual_mode=self.visual_mode,
            db_form=self.db_form)
        self.attach_slave('address_holder', self.address_slave)
        self.attach_model_slave('note_holder', NoteSlave, self.model)

    def on_confirm(self):
        main_address = self.address_slave.model
        main_address.person = self.model

    #
    # Public API
    #

    def add_extra_tab(self, tab_label, slave, position=None):
        """Adds an extra tab to the editor

        :param tab_label: the label that will be display on the tab
        :param slave: the slave that will be attached to the new tab
        :param position: the position the tab will be attached
        """
        event_box = gtk.EventBox()
        self.person_notebook.append_page(event_box, gtk.Label(tab_label))
        self.attach_slave(tab_label, slave, event_box)
        event_box.show()

        if position is not None:
            self.person_notebook.reorder_child(event_box, position)
            self.person_notebook.set_current_page(position)

    def attach_role_slave(self, slave):
        self.attach_slave('role_holder', slave)

    def attach_model_slave(self, name, slave_type, slave_model):
        slave = slave_type(self.store, slave_model,
                           visual_mode=self.visual_mode)
        self.attach_slave(name, slave)
        return slave

    #
    # Kiwi handlers
    #

    def on_name__map(self, entry):
        self.name.grab_focus()

    def on_address_button__clicked(self, button):
        main_address = self.model.get_main_address()
        if not main_address.is_valid_model():
            msg = _(u"You must define a valid main address before\n"
                    "adding additional addresses")
            warning(msg)
            return

        result = run_dialog(AddressAdditionDialog, self._parent,
                            self.store, person=self.model,
                            reuse_store=not self.visual_mode)
        if not result:
            return

        new_main_address = self.model.get_main_address()
        if new_main_address is not main_address:
            self.address_slave.set_model(new_main_address)

    def on_contact_info_button__clicked(self, button):
        run_dialog(ContactInfoListDialog, self._parent, self.store,
                   person=self.model, reuse_store=not self.visual_mode)

    def on_calls_button__clicked(self, button):
        run_dialog(CallsSearch, self._parent, self.store,
                   person=self.model, reuse_store=not self.visual_mode)

    def on_credit_check_history_button__clicked(self, button):
        run_dialog(CreditCheckHistorySearch, self._parent, self.store,
                   client=self.model.client, reuse_store=not self.visual_mode)

    #
    # Private API
    #

    def _setup_widgets(self):
        individual = self.model.individual
        company = self.model.company
        if not (individual or company):
            raise DatabaseInconsistency('A person must have at least a '
                                        'company or an individual set.')
        tab_child = self.person_data_tab
        if individual and company:
            tab_text = _('Individual/Company Data')
            self.company_frame.set_label(_('Company Data'))
            self.company_frame.show()
            self.individual_frame.set_label(_('Individual Data'))
            self.individual_frame.show()
        elif individual:
            tab_text = _('Individual Data')
            self.company_frame.hide()
            label_widget = self.individual_frame.get_label_widget()
            if label_widget is not None:
                label_widget.hide()
            self.individual_frame.show()
        else:
            tab_text = _('Company Data')
            self.individual_frame.hide()
            label_widget = self.company_frame.get_label_widget()
            if label_widget is not None:
                label_widget.hide()
            self.company_frame.show()
        self.person_notebook.set_tab_label_text(tab_child, tab_text)
        addresses = self.model.get_total_addresses()
        if addresses == 2:
            self.address_button.set_label(_("1 More Address..."))
        elif addresses > 2:
            self.address_button.set_label(_("%i More Addresses...")
                                          % (addresses - 1))
        if not self.model.client:
            self.credit_check_history_button.hide()

    def _setup_form_fields(self):
        if not self.db_form:
            return
        self.db_form.update_widget(self.name,
                                   other=self.name_lbl)
        self.db_form.update_widget(self.phone_number,
                                   other=self.phone_number_lbl)
        self.db_form.update_widget(self.fax_number, u'fax',
                                   other=self.fax_lbl)
        self.db_form.update_widget(self.email,
                                   other=self.email_lbl)
        self.db_form.update_widget(self.mobile_number,
                                   other=self.mobile_lbl)


[docs]class BasePersonRoleEditor(BaseEditor): """A base class for person role editors. This class can not be instantiated directly. :attribute main_slave: :attribute individual_slave: :attribute company_slave: :cvar help_section: the help button for this wizard, usually describing how to create a new person """ size = (-1, -1) help_section = None ui_form_name = None need_cancel_confirmation = True def __init__(self, store, model=None, role_type=None, person=None, visual_mode=False, parent=None, document=None, description=None): """ Creates a new BasePersonRoleEditor object :param store: a store :param model: :param none_type: None, ROLE_INDIVIDUAL or ROLE_COMPANY :param person: :param visual_mode: """ if not (model or role_type is not None): raise ValueError('A role_type attribute is required') self._description = description self._parent = parent self.individual_slave = None self.company_slave = None self._person_slave = None self.main_slave = None self.role_type = role_type self.person = person self.document = document BaseEditor.__init__(self, store, model, visual_mode=visual_mode) # FIXME: Implement and use IDescribable on the model self.set_description(self.model.person.name) # # BaseEditor hooks #
[docs] def create_model(self, store): # XXX: Waiting fix for bug 2163. We should not need anymore to # provide empty values for mandatory attributes if not self.person: self.person = Person(name=self._description or u'', store=store) if not self.role_type in [Person.ROLE_INDIVIDUAL, Person.ROLE_COMPANY]: raise ValueError("Invalid value for role_type attribute, %r" % ( self.role_type, )) if (self.role_type == Person.ROLE_INDIVIDUAL and not self.person.individual): Individual(person=self.person, store=store, cpf=self.document) elif (self.role_type == Person.ROLE_COMPANY and not self.person.company): Company(person=self.person, store=store, cnpj=self.document) else: pass return self.person
[docs] def setup_slaves(self): individual = self.model.person.individual company = self.model.person.company assert individual or company self._person_slave = _PersonEditorTemplate(self.store, self.model.person, visual_mode=self.visual_mode, ui_form_name=self.ui_form_name, parent=self._parent or self) if individual: slave = IndividualEditorTemplate(self.store, model=individual, person_slave=self._person_slave, visual_mode=self.visual_mode) self.individual_slave = slave self.main_slave = slave if company: slave = CompanyEditorTemplate(self.store, model=company, person_slave=self._person_slave, visual_mode=self.visual_mode) self.company_slave = slave self.main_slave = slave self.attach_slave('main_holder', slave) self.main_slave.attach_slave('main_holder', self._person_slave)
[docs] def on_confirm(self): if (isinstance(self.model, Supplier) and not sysparam.has_object('SUGGESTED_SUPPLIER')): sysparam.set_object(self.store, 'SUGGESTED_SUPPLIER', self.model)
# # Public API #
[docs] def get_person_slave(self): return self._person_slave
[docs] def set_phone_number(self, phone_number): slave = self.get_person_slave() slave.set_phone_number(phone_number)