Add some links between employees / people / customers views
This commit is contained in:
		
							parent
							
								
									686bcfc74c
								
							
						
					
					
						commit
						fdd0b6ec3b
					
				
					 4 changed files with 72 additions and 50 deletions
				
			
		| 
						 | 
					@ -35,6 +35,7 @@ from .common import (StrippedTextFieldRenderer, CodeTextAreaFieldRenderer, Autoc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .files import FileFieldRenderer
 | 
					from .files import FileFieldRenderer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# TODO: deprecate / remove Link renderers
 | 
				
			||||||
from .people import (PersonFieldRenderer, PersonFieldLinkRenderer,
 | 
					from .people import (PersonFieldRenderer, PersonFieldLinkRenderer,
 | 
				
			||||||
                     CustomerFieldRenderer, CustomerFieldLinkRenderer)
 | 
					                     CustomerFieldRenderer, CustomerFieldLinkRenderer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,12 +26,9 @@ People Field Renderers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from __future__ import unicode_literals, absolute_import
 | 
					from __future__ import unicode_literals, absolute_import
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .common import AutocompleteFieldRenderer
 | 
					 | 
				
			||||||
from webhelpers.html import tags
 | 
					from webhelpers.html import tags
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from tailbone.forms.renderers.common import AutocompleteFieldRenderer
 | 
				
			||||||
__all__ = ['PersonFieldRenderer', 'PersonFieldLinkRenderer',
 | 
					 | 
				
			||||||
           'CustomerFieldRenderer', 'CustomerFieldLinkRenderer']
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PersonFieldRenderer(AutocompleteFieldRenderer):
 | 
					class PersonFieldRenderer(AutocompleteFieldRenderer):
 | 
				
			||||||
| 
						 | 
					@ -41,19 +38,14 @@ class PersonFieldRenderer(AutocompleteFieldRenderer):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    service_route = 'people.autocomplete'
 | 
					    service_route = 'people.autocomplete'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class PersonFieldLinkRenderer(PersonFieldRenderer):
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    Renderer for :class:`rattail.db.model.Person` instance fields (with hyperlink).
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def render_readonly(self, **kwargs):
 | 
					    def render_readonly(self, **kwargs):
 | 
				
			||||||
        person = self.raw_value
 | 
					        person = self.raw_value
 | 
				
			||||||
        if person:
 | 
					        if not person:
 | 
				
			||||||
            return tags.link_to(
 | 
					            return ''
 | 
				
			||||||
                unicode(person),
 | 
					        return tags.link_to(person, self.request.route_url('people.view', uuid=person.uuid))
 | 
				
			||||||
                self.request.route_url('people.view', uuid=person.uuid))
 | 
					
 | 
				
			||||||
        return u''
 | 
					# TODO: deprecate / remove this
 | 
				
			||||||
 | 
					PersonFieldLinkRenderer = PersonFieldRenderer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CustomerFieldRenderer(AutocompleteFieldRenderer):
 | 
					class CustomerFieldRenderer(AutocompleteFieldRenderer):
 | 
				
			||||||
| 
						 | 
					@ -63,16 +55,11 @@ class CustomerFieldRenderer(AutocompleteFieldRenderer):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    service_route = 'customers.autocomplete'
 | 
					    service_route = 'customers.autocomplete'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class CustomerFieldLinkRenderer(CustomerFieldRenderer):
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    Renderer for :class:`rattail.db.model.Customer` instance fields (with hyperlink).
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def render_readonly(self, **kwargs):
 | 
					    def render_readonly(self, **kwargs):
 | 
				
			||||||
        customer = self.raw_value
 | 
					        customer = self.raw_value
 | 
				
			||||||
        if customer:
 | 
					        if not customer:
 | 
				
			||||||
            return tags.link_to(
 | 
					            return ''
 | 
				
			||||||
                unicode(customer),
 | 
					        return tags.link_to(customer, self.request.route_url('customers.view', uuid=customer.uuid))
 | 
				
			||||||
                self.request.route_url('customers.view', uuid=customer.uuid))
 | 
					
 | 
				
			||||||
        return u''
 | 
					# TODO: deprecate / remove this
 | 
				
			||||||
 | 
					CustomerFieldLinkRenderer = CustomerFieldRenderer
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,10 +28,9 @@ from __future__ import unicode_literals, absolute_import
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import sqlalchemy as sa
 | 
					import sqlalchemy as sa
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from rattail import enum
 | 
					 | 
				
			||||||
from rattail.db import model
 | 
					from rattail.db import model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import formalchemy
 | 
					import formalchemy as fa
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from tailbone import forms
 | 
					from tailbone import forms
 | 
				
			||||||
from tailbone.db import Session
 | 
					from tailbone.db import Session
 | 
				
			||||||
| 
						 | 
					@ -67,8 +66,8 @@ class EmployeesView(MasterView):
 | 
				
			||||||
            g.filters['id'].label = "ID"
 | 
					            g.filters['id'].label = "ID"
 | 
				
			||||||
            g.filters['status'].default_active = True
 | 
					            g.filters['status'].default_active = True
 | 
				
			||||||
            g.filters['status'].default_verb = 'equal'
 | 
					            g.filters['status'].default_verb = 'equal'
 | 
				
			||||||
            g.filters['status'].default_value = enum.EMPLOYEE_STATUS_CURRENT
 | 
					            g.filters['status'].default_value = self.enum.EMPLOYEE_STATUS_CURRENT
 | 
				
			||||||
            g.filters['status'].set_value_renderer(EnumValueRenderer(enum.EMPLOYEE_STATUS))
 | 
					            g.filters['status'].set_value_renderer(EnumValueRenderer(self.enum.EMPLOYEE_STATUS))
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            del g.filters['id']
 | 
					            del g.filters['id']
 | 
				
			||||||
            del g.filters['status']
 | 
					            del g.filters['status']
 | 
				
			||||||
| 
						 | 
					@ -97,7 +96,7 @@ class EmployeesView(MasterView):
 | 
				
			||||||
                g.last_name,
 | 
					                g.last_name,
 | 
				
			||||||
                g.phone.label("Phone Number"),
 | 
					                g.phone.label("Phone Number"),
 | 
				
			||||||
                g.email.label("Email Address"),
 | 
					                g.email.label("Email Address"),
 | 
				
			||||||
                g.status.with_renderer(forms.EnumFieldRenderer(enum.EMPLOYEE_STATUS)),
 | 
					                g.status.with_renderer(forms.renderers.EnumFieldRenderer(self.enum.EMPLOYEE_STATUS)),
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            readonly=True)
 | 
					            readonly=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,38 +107,47 @@ class EmployeesView(MasterView):
 | 
				
			||||||
    def query(self, session):
 | 
					    def query(self, session):
 | 
				
			||||||
        q = session.query(model.Employee).join(model.Person)
 | 
					        q = session.query(model.Employee).join(model.Person)
 | 
				
			||||||
        if not self.request.has_perm('employees.edit'):
 | 
					        if not self.request.has_perm('employees.edit'):
 | 
				
			||||||
            q = q.filter(model.Employee.status == enum.EMPLOYEE_STATUS_CURRENT)
 | 
					            q = q.filter(model.Employee.status == self.enum.EMPLOYEE_STATUS_CURRENT)
 | 
				
			||||||
        return q
 | 
					        return q
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_fieldset(self, fs):
 | 
					    def _preconfigure_fieldset(self, fs):
 | 
				
			||||||
        fs.append(forms.AssociationProxyField('first_name'))
 | 
					        fs.append(forms.AssociationProxyField('first_name'))
 | 
				
			||||||
        fs.append(forms.AssociationProxyField('last_name'))
 | 
					        fs.append(forms.AssociationProxyField('last_name'))
 | 
				
			||||||
        fs.append(forms.AssociationProxyField('display_name'))
 | 
					 | 
				
			||||||
        fs.append(StoresField('stores'))
 | 
					        fs.append(StoresField('stores'))
 | 
				
			||||||
        fs.append(DepartmentsField('departments'))
 | 
					        fs.append(DepartmentsField('departments'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fs.person.set(renderer=forms.renderers.PersonFieldRenderer)
 | 
				
			||||||
 | 
					        fs.display_name.set(label="Short Name")
 | 
				
			||||||
 | 
					        fs.phone.set(label="Phone Number", readonly=True)
 | 
				
			||||||
 | 
					        fs.email.set(label="Email Address", readonly=True)
 | 
				
			||||||
 | 
					        fs.status.set(renderer=forms.renderers.EnumFieldRenderer(self.enum.EMPLOYEE_STATUS))
 | 
				
			||||||
 | 
					        fs.id.set(label="ID")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def configure_fieldset(self, fs):
 | 
				
			||||||
        fs.configure(
 | 
					        fs.configure(
 | 
				
			||||||
            include=[
 | 
					            include=[
 | 
				
			||||||
                fs.id.label("ID"),
 | 
					                fs.person,
 | 
				
			||||||
                fs.first_name,
 | 
					                fs.first_name,
 | 
				
			||||||
                fs.last_name,
 | 
					                fs.last_name,
 | 
				
			||||||
                fs.display_name,
 | 
					                fs.display_name,
 | 
				
			||||||
                fs.phone.label("Phone Number").readonly(),
 | 
					                fs.phone,
 | 
				
			||||||
                fs.email.label("Email Address").readonly(),
 | 
					                fs.email,
 | 
				
			||||||
                fs.status.with_renderer(forms.EnumFieldRenderer(enum.EMPLOYEE_STATUS)),
 | 
					                fs.status,
 | 
				
			||||||
 | 
					                fs.id,
 | 
				
			||||||
                fs.stores,
 | 
					                fs.stores,
 | 
				
			||||||
                fs.departments,
 | 
					                fs.departments,
 | 
				
			||||||
            ])
 | 
					            ])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class StoresField(formalchemy.Field):
 | 
					class StoresField(fa.Field):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, name, **kwargs):
 | 
					    def __init__(self, name, **kwargs):
 | 
				
			||||||
        kwargs.setdefault('type', formalchemy.types.Set)
 | 
					        kwargs.setdefault('type', fa.types.Set)
 | 
				
			||||||
        kwargs.setdefault('options', Session.query(model.Store).order_by(model.Store.name))
 | 
					        kwargs.setdefault('options', Session.query(model.Store).order_by(model.Store.name))
 | 
				
			||||||
        kwargs.setdefault('value', self.get_value)
 | 
					        kwargs.setdefault('value', self.get_value)
 | 
				
			||||||
        kwargs.setdefault('multiple', True)
 | 
					        kwargs.setdefault('multiple', True)
 | 
				
			||||||
        kwargs.setdefault('size', 3)
 | 
					        kwargs.setdefault('size', 3)
 | 
				
			||||||
        formalchemy.Field.__init__(self, name=name, **kwargs)
 | 
					        fa.Field.__init__(self, name=name, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_value(self, employee):
 | 
					    def get_value(self, employee):
 | 
				
			||||||
        return [s.uuid for s in employee.stores]
 | 
					        return [s.uuid for s in employee.stores]
 | 
				
			||||||
| 
						 | 
					@ -159,15 +167,15 @@ class StoresField(formalchemy.Field):
 | 
				
			||||||
                    employee.stores.remove(store)
 | 
					                    employee.stores.remove(store)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DepartmentsField(formalchemy.Field):
 | 
					class DepartmentsField(fa.Field):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, name, **kwargs):
 | 
					    def __init__(self, name, **kwargs):
 | 
				
			||||||
        kwargs.setdefault('type', formalchemy.types.Set)
 | 
					        kwargs.setdefault('type', fa.types.Set)
 | 
				
			||||||
        kwargs.setdefault('options', Session.query(model.Department).order_by(model.Department.name))
 | 
					        kwargs.setdefault('options', Session.query(model.Department).order_by(model.Department.name))
 | 
				
			||||||
        kwargs.setdefault('value', self.get_value)
 | 
					        kwargs.setdefault('value', self.get_value)
 | 
				
			||||||
        kwargs.setdefault('multiple', True)
 | 
					        kwargs.setdefault('multiple', True)
 | 
				
			||||||
        kwargs.setdefault('size', 10)
 | 
					        kwargs.setdefault('size', 10)
 | 
				
			||||||
        formalchemy.Field.__init__(self, name=name, **kwargs)
 | 
					        fa.Field.__init__(self, name=name, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_value(self, employee):
 | 
					    def get_value(self, employee):
 | 
				
			||||||
        return [d.uuid for d in employee.departments]
 | 
					        return [d.uuid for d in employee.departments]
 | 
				
			||||||
| 
						 | 
					@ -197,7 +205,7 @@ class EmployeesAutocomplete(AutocompleteView):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def filter_query(self, q):
 | 
					    def filter_query(self, q):
 | 
				
			||||||
        return q.join(model.Employee)\
 | 
					        return q.join(model.Employee)\
 | 
				
			||||||
            .filter(model.Employee.status == enum.EMPLOYEE_STATUS_CURRENT)
 | 
					            .filter(model.Employee.status == self.enum.EMPLOYEE_STATUS_CURRENT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self, person):
 | 
					    def value(self, person):
 | 
				
			||||||
        return person.employee.uuid
 | 
					        return person.employee.uuid
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
################################################################################
 | 
					################################################################################
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  Rattail -- Retail Software Framework
 | 
					#  Rattail -- Retail Software Framework
 | 
				
			||||||
#  Copyright © 2010-2015 Lance Edgar
 | 
					#  Copyright © 2010-2016 Lance Edgar
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  This file is part of Rattail.
 | 
					#  This file is part of Rattail.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -28,13 +28,31 @@ from __future__ import unicode_literals, absolute_import
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import sqlalchemy as sa
 | 
					import sqlalchemy as sa
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import formalchemy as fa
 | 
				
			||||||
from pyramid.httpexceptions import HTTPFound, HTTPNotFound
 | 
					from pyramid.httpexceptions import HTTPFound, HTTPNotFound
 | 
				
			||||||
 | 
					from webhelpers.html import HTML, tags
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from tailbone.views import MasterView, AutocompleteView
 | 
					from tailbone.views import MasterView, AutocompleteView
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from rattail.db import model
 | 
					from rattail.db import model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CustomersFieldRenderer(fa.FieldRenderer):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def render_readonly(self, **kwargs):
 | 
				
			||||||
 | 
					        customers = self.raw_value
 | 
				
			||||||
 | 
					        if not customers:
 | 
				
			||||||
 | 
					            return ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        items = []
 | 
				
			||||||
 | 
					        for customer in customers:
 | 
				
			||||||
 | 
					            customer = customer.customer
 | 
				
			||||||
 | 
					            items.append(HTML.tag('li', c=tags.link_to('{} {}'.format(customer.id, customer),
 | 
				
			||||||
 | 
					                                                       self.request.route_url('customers.view', uuid=customer.uuid))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return HTML.tag('ul', c=items)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PeopleView(MasterView):
 | 
					class PeopleView(MasterView):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Master view for the Person class.
 | 
					    Master view for the Person class.
 | 
				
			||||||
| 
						 | 
					@ -89,16 +107,24 @@ class PeopleView(MasterView):
 | 
				
			||||||
            return instance.person
 | 
					            return instance.person
 | 
				
			||||||
        raise HTTPNotFound
 | 
					        raise HTTPNotFound
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _preconfigure_fieldset(self, fs):
 | 
				
			||||||
 | 
					        fs.display_name.set(label="Full Name")
 | 
				
			||||||
 | 
					        fs.phone.set(label="Phone Number", readonly=True)
 | 
				
			||||||
 | 
					        fs.email.set(label="Email Address", readonly=True)
 | 
				
			||||||
 | 
					        fs.address.set(label="Mailing Address", readonly=True)
 | 
				
			||||||
 | 
					        fs._customers.set(renderer=CustomersFieldRenderer, readonly=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def configure_fieldset(self, fs):
 | 
					    def configure_fieldset(self, fs):
 | 
				
			||||||
        fs.configure(
 | 
					        fs.configure(
 | 
				
			||||||
            include=[
 | 
					            include=[
 | 
				
			||||||
                fs.display_name.label("Full Name"),
 | 
					                fs.display_name,
 | 
				
			||||||
                fs.first_name,
 | 
					                fs.first_name,
 | 
				
			||||||
                fs.middle_name,
 | 
					                fs.middle_name,
 | 
				
			||||||
                fs.last_name,
 | 
					                fs.last_name,
 | 
				
			||||||
                fs.phone.label("Phone Number").readonly(),
 | 
					                fs.phone,
 | 
				
			||||||
                fs.email.label("Email Address").readonly(),
 | 
					                fs.email,
 | 
				
			||||||
                fs.address.label("Mailing Address").readonly(),
 | 
					                fs.address,
 | 
				
			||||||
 | 
					                fs._customers,
 | 
				
			||||||
            ])
 | 
					            ])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue