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

View file

@ -551,6 +551,16 @@
{{ member._key }} {{ member._key }}
</b-field> </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"> <b-field horizontal label="Active">
{{ member.active }} {{ member.active }}
</b-field> </b-field>

View file

@ -27,13 +27,70 @@ Member Views
import sqlalchemy as sa import sqlalchemy as sa
from rattail.db import model from rattail.db import model
from rattail.db.model import MembershipType, Member
from deform import widget as dfwidget from deform import widget as dfwidget
from webhelpers2.html import tags
from tailbone import grids from tailbone import grids
from tailbone.views import MasterView 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): class MemberView(MasterView):
""" """
Master view for the Member class. Master view for the Member class.
@ -51,9 +108,7 @@ class MemberView(MasterView):
grid_columns = [ grid_columns = [
'_member_key_', '_member_key_',
'person', 'person',
'customer', 'membership_type',
'email',
'phone',
'active', 'active',
'equity_current', 'equity_current',
'joined', 'joined',
@ -66,6 +121,7 @@ class MemberView(MasterView):
'customer', 'customer',
'default_email', 'default_email',
'default_phone', 'default_phone',
'membership_type',
'active', 'active',
'equity_current', 'equity_current',
'equity_payment_due', 'equity_payment_due',
@ -75,6 +131,7 @@ class MemberView(MasterView):
def configure_grid(self, g): def configure_grid(self, g):
super(MemberView, self).configure_grid(g) super(MemberView, self).configure_grid(g)
model = self.model
# member key # member key
field = self.get_member_key_field() field = self.get_member_key_field()
@ -111,6 +168,12 @@ class MemberView(MasterView):
g.set_filter('email', model.MemberEmailAddress.address) g.set_filter('email', model.MemberEmailAddress.address)
g.set_label('email', "Email 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('person')
g.set_link('customer') g.set_link('customer')
@ -174,6 +237,9 @@ class MemberView(MasterView):
if not self.creating and member.phones: if not self.creating and member.phones:
f.set_default('default_phone', member.phones[0].number) f.set_default('default_phone', member.phones[0].number)
# membership_type
f.set_renderer('membership_type', self.render_membership_type)
if self.creating: if self.creating:
f.remove_fields( f.remove_fields(
'equity_total', 'equity_total',
@ -190,6 +256,14 @@ class MemberView(MasterView):
if member.phones: if member.phones:
return member.phones[0].number 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): def configure_get_simple_settings(self):
return [ return [
@ -204,6 +278,9 @@ class MemberView(MasterView):
def defaults(config, **kwargs): def defaults(config, **kwargs):
base = globals() base = globals()
MembershipTypeView = kwargs.get('MembershipTypeView', base['MembershipTypeView'])
MembershipTypeView.defaults(config)
MemberView = kwargs.get('MemberView', base['MemberView']) MemberView = kwargs.get('MemberView', base['MemberView'])
MemberView.defaults(config) MemberView.defaults(config)

View file

@ -585,7 +585,7 @@ class PersonView(MasterView):
uuid=member.person_uuid) uuid=member.person_uuid)
key = self.get_member_key_field() key = self.get_member_key_field()
return { data = {
'uuid': member.uuid, 'uuid': member.uuid,
'_key': getattr(member, key), '_key': getattr(member, key),
'number': member.number, 'number': member.number,
@ -602,6 +602,18 @@ class PersonView(MasterView):
'view_profile_url': profile_url, '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): def get_context_employee(self, employee):
""" """
Return a dict of context data for the given employee. Return a dict of context data for the given employee.