Add some links between employees / people / customers views
This commit is contained in:
parent
686bcfc74c
commit
fdd0b6ec3b
|
@ -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…
Reference in a new issue