Add basic support for membership types

This commit is contained in:
Lance Edgar 2023-06-06 13:13:19 -05:00
parent 027d44e04a
commit 816e652357
4 changed files with 116 additions and 10 deletions

View file

@ -332,6 +332,12 @@ class MenuHandler(GenericHandler):
'route': 'members',
'perm': 'members.list',
},
{
'title': "Membership Types",
'route': 'membership_types',
'perm': 'membership_types.list',
},
{'type': 'sep'},
{
'title': "Customers",
'route': 'customers',
@ -342,22 +348,23 @@ class MenuHandler(GenericHandler):
'route': 'customergroups',
'perm': 'customergroups.list',
},
{
'title': "Pending Customers",
'route': 'pending_customers',
'perm': 'pending_customers.list',
},
{'type': 'sep'},
{
'title': "Employees",
'route': 'employees',
'perm': 'employees.list',
},
{'type': 'sep'},
{
'title': "All People",
'route': 'people',
'perm': 'people.list',
},
{'type': 'sep'},
{
'title': "Pending Customers",
'route': 'pending_customers',
'perm': 'pending_customers.list',
},
],
}

View file

@ -551,6 +551,16 @@
{{ member._key }}
</b-field>
<b-field horizontal label="Membership Type">
<a v-if="member.view_membership_type_url"
:href="member.view_membership_type_url">
{{ member.membership_type_name }}
</a>
<span v-if="!member.view_membership_type_url">
{{ member.membership_type_name }}
</span>
</b-field>
<b-field horizontal label="Active">
{{ member.active }}
</b-field>

View file

@ -27,13 +27,70 @@ Member Views
import sqlalchemy as sa
from rattail.db import model
from rattail.db.model import MembershipType, Member
from deform import widget as dfwidget
from webhelpers2.html import tags
from tailbone import grids
from tailbone.views import MasterView
class MembershipTypeView(MasterView):
"""
Master view for Membership Types
"""
model_class = MembershipType
route_prefix = 'membership_types'
url_prefix = '/membership-types'
has_versions = True
labels = {
'id': "ID",
}
grid_columns = [
'number',
'name',
]
has_rows = True
model_row_class = Member
rows_title = "Members"
row_grid_columns = [
'_member_key_',
'person',
'active',
'equity_current',
'equity_total',
'joined',
'withdrew',
]
def configure_grid(self, g):
super().configure_grid(g)
g.set_sort_defaults('number')
g.set_link('number')
g.set_link('name')
def get_row_data(self, memtype):
model = self.model
return self.Session.query(model.Member)\
.filter(model.Member.membership_type == memtype)
def get_parent(self, member):
return member.membership_type
def configure_row_grid(self, g):
super().configure_row_grid(g)
g.filters['active'].default_active = True
g.filters['active'].default_verb = 'is_true'
class MemberView(MasterView):
"""
Master view for the Member class.
@ -51,9 +108,7 @@ class MemberView(MasterView):
grid_columns = [
'_member_key_',
'person',
'customer',
'email',
'phone',
'membership_type',
'active',
'equity_current',
'joined',
@ -66,6 +121,7 @@ class MemberView(MasterView):
'customer',
'default_email',
'default_phone',
'membership_type',
'active',
'equity_current',
'equity_payment_due',
@ -75,6 +131,7 @@ class MemberView(MasterView):
def configure_grid(self, g):
super(MemberView, self).configure_grid(g)
model = self.model
# member key
field = self.get_member_key_field()
@ -111,6 +168,12 @@ class MemberView(MasterView):
g.set_filter('email', model.MemberEmailAddress.address)
g.set_label('email', "Email Address")
# membership_type
g.set_joiner('membership_type', lambda q: q.outerjoin(model.MembershipType))
g.set_sorter('membership_type', model.MembershipType.name)
g.set_filter('membership_type', model.MembershipType.name,
label="Membership Type Name")
g.set_link('person')
g.set_link('customer')
@ -174,6 +237,9 @@ class MemberView(MasterView):
if not self.creating and member.phones:
f.set_default('default_phone', member.phones[0].number)
# membership_type
f.set_renderer('membership_type', self.render_membership_type)
if self.creating:
f.remove_fields(
'equity_total',
@ -190,6 +256,14 @@ class MemberView(MasterView):
if member.phones:
return member.phones[0].number
def render_membership_type(self, member, field):
memtype = getattr(member, field)
if not memtype:
return
text = str(memtype)
url = self.request.route_url('membership_types.view', uuid=memtype.uuid)
return tags.link_to(text, url)
def configure_get_simple_settings(self):
return [
@ -204,6 +278,9 @@ class MemberView(MasterView):
def defaults(config, **kwargs):
base = globals()
MembershipTypeView = kwargs.get('MembershipTypeView', base['MembershipTypeView'])
MembershipTypeView.defaults(config)
MemberView = kwargs.get('MemberView', base['MemberView'])
MemberView.defaults(config)

View file

@ -585,7 +585,7 @@ class PersonView(MasterView):
uuid=member.person_uuid)
key = self.get_member_key_field()
return {
data = {
'uuid': member.uuid,
'_key': getattr(member, key),
'number': member.number,
@ -602,6 +602,18 @@ class PersonView(MasterView):
'view_profile_url': profile_url,
}
membership_type = member.membership_type
if membership_type:
data.update({
'membership_type_uuid': membership_type.uuid,
'membership_type_number': membership_type.number,
'membership_type_name': membership_type.name,
'view_membership_type_url': self.request.route_url(
'membership_types.view', uuid=membership_type.uuid),
})
return data
def get_context_employee(self, employee):
"""
Return a dict of context data for the given employee.