Add 'Stores' and 'Departments' fields to Employee fieldset.

This commit is contained in:
Lance Edgar 2016-01-30 15:19:04 -06:00
parent bcf1032156
commit 7edfc98747
2 changed files with 60 additions and 32 deletions

View file

@ -1,13 +0,0 @@
## -*- coding: utf-8 -*-
<%inherit file="/master/view.mako" />
${parent.body()}
<h2>Departments</h2>
% if departments:
<p>This employee is assigned to the following departments:</p>
${departments.render_grid()|n}
% else:
<p>This employee is not assigned to any departments.</p>
% endif

View file

@ -31,7 +31,10 @@ import sqlalchemy as sa
from rattail import enum
from rattail.db import model
import formalchemy
from tailbone import forms
from tailbone.db import Session
from tailbone.views import MasterView, AutocompleteView
from tailbone.newgrids import AlchemyGrid, GridAction
from tailbone.newgrids.filters import EnumValueRenderer
@ -112,6 +115,8 @@ class EmployeesView(MasterView):
fs.append(forms.AssociationProxyField('first_name'))
fs.append(forms.AssociationProxyField('last_name'))
fs.append(forms.AssociationProxyField('display_name'))
fs.append(StoresField('stores'))
fs.append(DepartmentsField('departments'))
fs.configure(
include=[
fs.id.label("ID"),
@ -121,29 +126,65 @@ class EmployeesView(MasterView):
fs.phone.label("Phone Number").readonly(),
fs.email.label("Email Address").readonly(),
fs.status.with_renderer(forms.EnumFieldRenderer(enum.EMPLOYEE_STATUS)),
fs.stores,
fs.departments,
])
def template_kwargs_view(self, **kwargs):
employee = kwargs['instance']
if employee.departments:
# TODO: This is the second attempt (after role.users) at using a
# new grid outside of the context of a primary master grid. The
# API here is really much hairier than I'd like... Looks like we
# shouldn't need a key for this one, for instance (no settings
# required), but there is plenty of room for improvement here.
departments = sorted(employee.departments, key=unicode)
departments = AlchemyGrid('employees.departments', self.request, data=departments, model_class=model.Department,
main_actions=[
GridAction('view', icon='zoomin',
url=lambda d: self.request.route_url('departments.view', uuid=d.uuid)),
])
departments.configure(include=[departments.name], readonly=True)
kwargs['departments'] = departments
class StoresField(formalchemy.Field):
else:
kwargs['departments'] = None
return kwargs
def __init__(self, name, **kwargs):
kwargs.setdefault('type', formalchemy.types.Set)
kwargs.setdefault('options', Session.query(model.Store).order_by(model.Store.name))
kwargs.setdefault('value', self.get_value)
kwargs.setdefault('multiple', True)
kwargs.setdefault('size', 3)
formalchemy.Field.__init__(self, name=name, **kwargs)
def get_value(self, employee):
return [s.uuid for s in employee.stores]
def sync(self):
if not self.is_readonly():
employee = self.parent.model
old_stores = set([s.uuid for s in employee.stores])
new_stores = set(self._deserialize())
for uuid in new_stores:
if uuid not in old_stores:
employee._stores.append(model.EmployeeStore(store_uuid=uuid))
for uuid in old_stores:
if uuid not in new_stores:
store = Session.query(model.Store).get(uuid)
assert store
employee.stores.remove(store)
class DepartmentsField(formalchemy.Field):
def __init__(self, name, **kwargs):
kwargs.setdefault('type', formalchemy.types.Set)
kwargs.setdefault('options', Session.query(model.Department).order_by(model.Department.name))
kwargs.setdefault('value', self.get_value)
kwargs.setdefault('multiple', True)
kwargs.setdefault('size', 10)
formalchemy.Field.__init__(self, name=name, **kwargs)
def get_value(self, employee):
return [d.uuid for d in employee.departments]
def sync(self):
if not self.is_readonly():
employee = self.parent.model
old_depts = set([d.uuid for d in employee.departments])
new_depts = set(self._deserialize())
for uuid in new_depts:
if uuid not in old_depts:
employee._departments.append(model.EmployeeDepartment(department_uuid=uuid))
for uuid in old_depts:
if uuid not in new_depts:
dept = Session.query(model.Department).get(uuid)
assert dept
employee.departments.remove(dept)
class EmployeesAutocomplete(AutocompleteView):