Add/improve various display of Member data

This commit is contained in:
Lance Edgar 2020-03-18 11:27:58 -05:00
parent 8ac0bb2334
commit 970b5871e5
5 changed files with 142 additions and 2 deletions

View file

@ -0,0 +1,17 @@
## -*- coding: utf-8; -*-
<%inherit file="/master/view.mako" />
<%namespace file="/util.mako" import="view_profiles_helper" />
<%def name="object_helpers()">
${parent.object_helpers()}
<% people = [] %>
% if instance.person:
<% people.append(instance.person) %>
% endif
% if instance.customer:
<% people.extend(instance.customer.people) %>
% endif
${view_profiles_helper(people)}
</%def>
${parent.body()}

View file

@ -9,6 +9,76 @@
${self.page_content()} ${self.page_content()}
</%def> </%def>
<%def name="render_member_tab()">
<b-tab-item label="Member" icon-pack="fas" :icon="members.length ? 'check' : null">
<div v-if="members.length">
<div style="display: flex; justify-content: space-between;">
<p>{{ person.display_name }} is associated with <strong>{{ members.length }}</strong> member account(s)</p>
</div>
<br />
<b-collapse v-for="member in members"
:key="member.uuid"
class="panel"
:open="members.length == 1">
<div slot="trigger"
slot-scope="props"
class="panel-heading"
role="button">
<b-icon pack="fas"
icon="caret-right">
</b-icon>
<strong>#{{ member.id }} {{ member.display }}</strong>
</div>
<div class="panel-block">
<div style="display: flex; justify-content: space-between; width: 100%;">
<div style="flex-grow: 1;">
<b-field horizontal label="ID">
{{ member.id }}
</b-field>
<b-field horizontal label="Active">
{{ member.active }}
</b-field>
<b-field horizontal label="Joined">
{{ member.joined }}
</b-field>
<b-field horizontal label="Withdrew"
v-if="member.withdrew">
{{ member.withdrew }}
</b-field>
</div>
<div class="buttons" style="align-items: start;">
${self.render_member_panel_buttons(member)}
</div>
</div>
</div>
</b-collapse>
</div>
<div v-if="!members.length">
<p>{{ person.display_name }} has never had a member account.</p>
</div>
</b-tab-item>
</%def>
<%def name="render_member_panel_buttons(member)">
% if request.has_perm('members.view'):
<b-button tag="a" :href="member.view_url">
View Member
</b-button>
% endif
</%def>
<%def name="render_customer_tab()"> <%def name="render_customer_tab()">
<b-tab-item label="Customer" icon-pack="fas" :icon="customers.length ? 'check' : null"> <b-tab-item label="Customer" icon-pack="fas" :icon="customers.length ? 'check' : null">
@ -236,6 +306,8 @@
${self.render_customer_tab()} ${self.render_customer_tab()}
${self.render_member_tab()}
<b-tab-item label="Employee" ${'icon="check" icon-pack="fas"' if employee else ''|n}> <b-tab-item label="Employee" ${'icon="check" icon-pack="fas"' if employee else ''|n}>
% if employee: % if employee:
@ -402,6 +474,7 @@
activeTab: 0, activeTab: 0,
person: ${json.dumps(person_data)|n}, person: ${json.dumps(person_data)|n},
customers: ${json.dumps(customers_data)|n}, customers: ${json.dumps(customers_data)|n},
members: ${json.dumps(members_data)|n},
} }
}, },
} }

View file

@ -92,6 +92,7 @@ class CustomersView(MasterView):
'active_in_pos_sticky', 'active_in_pos_sticky',
'people', 'people',
'groups', 'groups',
'members',
] ]
mobile_form_fields = [ mobile_form_fields = [
@ -250,6 +251,18 @@ class CustomersView(MasterView):
f.set_renderer('groups', self.render_groups) f.set_renderer('groups', self.render_groups)
f.set_readonly('groups') f.set_readonly('groups')
def configure_form(self, f):
super(CustomersView, self).configure_form(f)
customer = f.model_instance
permission_prefix = self.get_permission_prefix()
# members
if self.creating:
f.remove_field('members')
else:
f.set_renderer('members', self.render_members)
f.set_readonly('members')
def template_kwargs_view(self, **kwargs): def template_kwargs_view(self, **kwargs):
kwargs['show_profiles_helper'] = self.show_profiles_helper kwargs['show_profiles_helper'] = self.show_profiles_helper
return kwargs return kwargs
@ -336,6 +349,17 @@ class CustomersView(MasterView):
items.append(HTML.tag('li', tags.link_to(text, url))) items.append(HTML.tag('li', tags.link_to(text, url)))
return HTML.tag('ul', HTML.literal('').join(items)) return HTML.tag('ul', HTML.literal('').join(items))
def render_members(self, customer, field):
members = customer.members
if not members:
return ""
items = []
for member in members:
text = six.text_type(member)
url = self.request.route_url('members.view', uuid=member.uuid)
items.append(HTML.tag('li', tags.link_to(text, url)))
return HTML.tag('ul', HTML.literal('').join(items))
def get_version_child_classes(self): def get_version_child_classes(self):
return [ return [
(model.CustomerPhoneNumber, 'parent_uuid'), (model.CustomerPhoneNumber, 'parent_uuid'),

View file

@ -113,7 +113,7 @@ class MemberView(MasterView):
def grid_extra_class(self, member, i): def grid_extra_class(self, member, i):
if not member.active: if not member.active:
return 'warning' return 'warning'
if not member.equity_current: if member.equity_current is False:
return 'notice' return 'notice'
def configure_form(self, f): def configure_form(self, f):
@ -158,7 +158,7 @@ class MemberView(MasterView):
f.set_label('customer_uuid', "Customer") f.set_label('customer_uuid', "Customer")
else: else:
f.set_readonly('customer') f.set_readonly('customer')
# f.set_renderer('customer', self.render_customer) f.set_renderer('customer', self.render_customer)
# default_email # default_email
f.set_renderer('default_email', self.render_default_email) f.set_renderer('default_email', self.render_default_email)

View file

@ -32,6 +32,7 @@ from sqlalchemy import orm
from rattail.db import model, api from rattail.db import model, api
from rattail.time import localtime from rattail.time import localtime
from rattail.util import OrderedDict
import colander import colander
from pyramid.httpexceptions import HTTPFound, HTTPNotFound from pyramid.httpexceptions import HTTPFound, HTTPNotFound
@ -316,6 +317,7 @@ class PeopleView(MasterView):
'today': localtime(self.rattail_config).date(), 'today': localtime(self.rattail_config).date(),
'person_data': self.get_context_person(person), 'person_data': self.get_context_person(person),
'customers_data': self.get_context_customers(person), 'customers_data': self.get_context_customers(person),
'members_data': self.get_context_members(person),
'employee': employee, 'employee': employee,
'employee_view_url': self.request.route_url('employees.view', uuid=employee.uuid) if employee else None, 'employee_view_url': self.request.route_url('employees.view', uuid=employee.uuid) if employee else None,
'employee_history': employee.get_current_history() if employee else None, 'employee_history': employee.get_current_history() if employee else None,
@ -366,6 +368,30 @@ class PeopleView(MasterView):
}) })
return data return data
def get_context_members(self, person):
data = OrderedDict()
for member in person.members:
data[member.uuid] = self.get_context_member(member)
for customer in person.customers:
for member in customer.members:
if member.uuid not in data:
data[member.uuid] = self.get_context_member(member)
return list(data.values())
def get_context_member(self, member):
return {
'uuid': member.uuid,
'id': member.id,
'active': member.active,
'joined': six.text_type(member.joined) if member.joined else None,
'withdrew': six.text_type(member.withdrew) if member.withdrew else None,
'display': six.text_type(member),
'view_url': self.request.route_url('members.view', uuid=member.uuid),
}
def get_context_employee_history(self, employee): def get_context_employee_history(self, employee):
data = [] data = []
if employee: if employee: