Add/improve various display of Member data
This commit is contained in:
parent
8ac0bb2334
commit
970b5871e5
17
tailbone/templates/members/view.mako
Normal file
17
tailbone/templates/members/view.mako
Normal 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()}
|
|
@ -9,6 +9,76 @@
|
|||
${self.page_content()}
|
||||
</%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()">
|
||||
<b-tab-item label="Customer" icon-pack="fas" :icon="customers.length ? 'check' : null">
|
||||
|
||||
|
@ -236,6 +306,8 @@
|
|||
|
||||
${self.render_customer_tab()}
|
||||
|
||||
${self.render_member_tab()}
|
||||
|
||||
<b-tab-item label="Employee" ${'icon="check" icon-pack="fas"' if employee else ''|n}>
|
||||
|
||||
% if employee:
|
||||
|
@ -402,6 +474,7 @@
|
|||
activeTab: 0,
|
||||
person: ${json.dumps(person_data)|n},
|
||||
customers: ${json.dumps(customers_data)|n},
|
||||
members: ${json.dumps(members_data)|n},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -92,6 +92,7 @@ class CustomersView(MasterView):
|
|||
'active_in_pos_sticky',
|
||||
'people',
|
||||
'groups',
|
||||
'members',
|
||||
]
|
||||
|
||||
mobile_form_fields = [
|
||||
|
@ -250,6 +251,18 @@ class CustomersView(MasterView):
|
|||
f.set_renderer('groups', self.render_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):
|
||||
kwargs['show_profiles_helper'] = self.show_profiles_helper
|
||||
return kwargs
|
||||
|
@ -336,6 +349,17 @@ class CustomersView(MasterView):
|
|||
items.append(HTML.tag('li', tags.link_to(text, url)))
|
||||
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):
|
||||
return [
|
||||
(model.CustomerPhoneNumber, 'parent_uuid'),
|
||||
|
|
|
@ -113,7 +113,7 @@ class MemberView(MasterView):
|
|||
def grid_extra_class(self, member, i):
|
||||
if not member.active:
|
||||
return 'warning'
|
||||
if not member.equity_current:
|
||||
if member.equity_current is False:
|
||||
return 'notice'
|
||||
|
||||
def configure_form(self, f):
|
||||
|
@ -158,7 +158,7 @@ class MemberView(MasterView):
|
|||
f.set_label('customer_uuid', "Customer")
|
||||
else:
|
||||
f.set_readonly('customer')
|
||||
# f.set_renderer('customer', self.render_customer)
|
||||
f.set_renderer('customer', self.render_customer)
|
||||
|
||||
# default_email
|
||||
f.set_renderer('default_email', self.render_default_email)
|
||||
|
|
|
@ -32,6 +32,7 @@ from sqlalchemy import orm
|
|||
|
||||
from rattail.db import model, api
|
||||
from rattail.time import localtime
|
||||
from rattail.util import OrderedDict
|
||||
|
||||
import colander
|
||||
from pyramid.httpexceptions import HTTPFound, HTTPNotFound
|
||||
|
@ -316,6 +317,7 @@ class PeopleView(MasterView):
|
|||
'today': localtime(self.rattail_config).date(),
|
||||
'person_data': self.get_context_person(person),
|
||||
'customers_data': self.get_context_customers(person),
|
||||
'members_data': self.get_context_members(person),
|
||||
'employee': employee,
|
||||
'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,
|
||||
|
@ -366,6 +368,30 @@ class PeopleView(MasterView):
|
|||
})
|
||||
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):
|
||||
data = []
|
||||
if employee:
|
||||
|
|
Loading…
Reference in a new issue