Use Grid.make_sorter()
instead of legacy code
b/c multi-column sorting relies on this
This commit is contained in:
parent
659f5a8fe1
commit
919d8d109f
|
@ -61,7 +61,7 @@ class EmailBounceView(MasterView):
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, request):
|
def __init__(self, request):
|
||||||
super(EmailBounceView, self).__init__(request)
|
super().__init__(request)
|
||||||
self.handler_options = sorted(get_profile_keys(self.rattail_config))
|
self.handler_options = sorted(get_profile_keys(self.rattail_config))
|
||||||
|
|
||||||
def get_handler(self, bounce):
|
def get_handler(self, bounce):
|
||||||
|
@ -69,17 +69,21 @@ class EmailBounceView(MasterView):
|
||||||
return app.get_bounce_handler(bounce.config_key)
|
return app.get_bounce_handler(bounce.config_key)
|
||||||
|
|
||||||
def configure_grid(self, g):
|
def configure_grid(self, g):
|
||||||
super(EmailBounceView, self).configure_grid(g)
|
super().configure_grid(g)
|
||||||
|
model = self.model
|
||||||
|
|
||||||
g.filters['config_key'].set_choices(self.handler_options)
|
g.filters['config_key'].set_choices(self.handler_options)
|
||||||
g.filters['config_key'].default_active = True
|
g.filters['config_key'].default_active = True
|
||||||
g.filters['config_key'].default_verb = 'equal'
|
g.filters['config_key'].default_verb = 'equal'
|
||||||
|
|
||||||
g.joiners['processed_by'] = lambda q: q.outerjoin(model.User)
|
|
||||||
g.filters['processed'].default_active = True
|
g.filters['processed'].default_active = True
|
||||||
g.filters['processed'].default_verb = 'is_null'
|
g.filters['processed'].default_verb = 'is_null'
|
||||||
g.filters['processed_by'] = g.make_filter('processed_by', model.User.username)
|
|
||||||
g.sorters['processed_by'] = g.make_sorter(model.User.username)
|
# processed_by
|
||||||
|
g.set_joiner('processed_by', lambda q: q.outerjoin(model.User))
|
||||||
|
g.set_sorter('processed_by', model.User.username)
|
||||||
|
g.set_filter('processed_by', model.User.username)
|
||||||
|
|
||||||
g.set_sort_defaults('bounced', 'desc')
|
g.set_sort_defaults('bounced', 'desc')
|
||||||
|
|
||||||
g.set_label('bounce_recipient_address', "Bounced To")
|
g.set_label('bounce_recipient_address', "Bounced To")
|
||||||
|
@ -89,7 +93,7 @@ class EmailBounceView(MasterView):
|
||||||
g.set_link('intended_recipient_address')
|
g.set_link('intended_recipient_address')
|
||||||
|
|
||||||
def configure_form(self, f):
|
def configure_form(self, f):
|
||||||
super(EmailBounceView, self).configure_form(f)
|
super().configure_form(f)
|
||||||
bounce = f.model_instance
|
bounce = f.model_instance
|
||||||
f.set_renderer('message', self.render_message_file)
|
f.set_renderer('message', self.render_message_file)
|
||||||
f.set_renderer('links', self.render_links)
|
f.set_renderer('links', self.render_links)
|
||||||
|
|
|
@ -168,22 +168,22 @@ class CustomerView(MasterView):
|
||||||
g.filters['name'].default_verb = 'contains'
|
g.filters['name'].default_verb = 'contains'
|
||||||
|
|
||||||
# phone
|
# phone
|
||||||
|
g.set_label('phone', "Phone Number")
|
||||||
g.set_joiner('phone', lambda q: q.outerjoin(model.CustomerPhoneNumber, sa.and_(
|
g.set_joiner('phone', lambda q: q.outerjoin(model.CustomerPhoneNumber, sa.and_(
|
||||||
model.CustomerPhoneNumber.parent_uuid == model.Customer.uuid,
|
model.CustomerPhoneNumber.parent_uuid == model.Customer.uuid,
|
||||||
model.CustomerPhoneNumber.preference == 1)))
|
model.CustomerPhoneNumber.preference == 1)))
|
||||||
g.sorters['phone'] = lambda q, d: q.order_by(getattr(model.CustomerPhoneNumber.number, d)())
|
g.set_sorter('phone', model.CustomerPhoneNumber.number)
|
||||||
g.set_filter('phone', model.CustomerPhoneNumber.number,
|
g.set_filter('phone', model.CustomerPhoneNumber.number,
|
||||||
# label="Phone Number",
|
# label="Phone Number",
|
||||||
factory=grids.filters.AlchemyPhoneNumberFilter)
|
factory=grids.filters.AlchemyPhoneNumberFilter)
|
||||||
g.set_label('phone', "Phone Number")
|
|
||||||
|
|
||||||
# email
|
# email
|
||||||
|
g.set_label('email', "Email Address")
|
||||||
g.set_joiner('email', lambda q: q.outerjoin(model.CustomerEmailAddress, sa.and_(
|
g.set_joiner('email', lambda q: q.outerjoin(model.CustomerEmailAddress, sa.and_(
|
||||||
model.CustomerEmailAddress.parent_uuid == model.Customer.uuid,
|
model.CustomerEmailAddress.parent_uuid == model.Customer.uuid,
|
||||||
model.CustomerEmailAddress.preference == 1)))
|
model.CustomerEmailAddress.preference == 1)))
|
||||||
g.sorters['email'] = lambda q, d: q.order_by(getattr(model.CustomerEmailAddress.address, d)())
|
g.set_sorter('email', model.CustomerEmailAddress.address)
|
||||||
g.set_filter('email', model.CustomerEmailAddress.address)#, label="Email Address")
|
g.set_filter('email', model.CustomerEmailAddress.address)#, label="Email Address")
|
||||||
g.set_label('email', "Email Address")
|
|
||||||
|
|
||||||
# email_preference
|
# email_preference
|
||||||
g.set_enum('email_preference', self.enum.EMAIL_PREFERENCE)
|
g.set_enum('email_preference', self.enum.EMAIL_PREFERENCE)
|
||||||
|
@ -244,7 +244,7 @@ class CustomerView(MasterView):
|
||||||
|
|
||||||
def get_instance(self):
|
def get_instance(self):
|
||||||
try:
|
try:
|
||||||
instance = super(CustomerView, self).get_instance()
|
instance = super().get_instance()
|
||||||
except HTTPNotFound:
|
except HTTPNotFound:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
@ -273,7 +273,7 @@ class CustomerView(MasterView):
|
||||||
raise HTTPNotFound
|
raise HTTPNotFound
|
||||||
|
|
||||||
def configure_form(self, f):
|
def configure_form(self, f):
|
||||||
super(CustomerView, self).configure_form(f)
|
super().configure_form(f)
|
||||||
customer = f.model_instance
|
customer = f.model_instance
|
||||||
permission_prefix = self.get_permission_prefix()
|
permission_prefix = self.get_permission_prefix()
|
||||||
|
|
||||||
|
@ -802,7 +802,7 @@ class PendingCustomerView(MasterView):
|
||||||
]
|
]
|
||||||
|
|
||||||
def configure_grid(self, g):
|
def configure_grid(self, g):
|
||||||
super(PendingCustomerView, self).configure_grid(g)
|
super().configure_grid(g)
|
||||||
|
|
||||||
g.set_enum('status_code', self.enum.PENDING_CUSTOMER_STATUS)
|
g.set_enum('status_code', self.enum.PENDING_CUSTOMER_STATUS)
|
||||||
g.filters['status_code'].default_active = True
|
g.filters['status_code'].default_active = True
|
||||||
|
@ -814,7 +814,7 @@ class PendingCustomerView(MasterView):
|
||||||
g.set_link('display_name')
|
g.set_link('display_name')
|
||||||
|
|
||||||
def configure_form(self, f):
|
def configure_form(self, f):
|
||||||
super(PendingCustomerView, self).configure_form(f)
|
super().configure_form(f)
|
||||||
|
|
||||||
f.set_enum('status_code', self.enum.PENDING_CUSTOMER_STATUS)
|
f.set_enum('status_code', self.enum.PENDING_CUSTOMER_STATUS)
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ class EmployeeView(MasterView):
|
||||||
return app.get_people_handler().get_quickie_search_placeholder()
|
return app.get_people_handler().get_quickie_search_placeholder()
|
||||||
|
|
||||||
def configure_grid(self, g):
|
def configure_grid(self, g):
|
||||||
super(EmployeeView, self).configure_grid(g)
|
super().configure_grid(g)
|
||||||
route_prefix = self.get_route_prefix()
|
route_prefix = self.get_route_prefix()
|
||||||
|
|
||||||
# phone
|
# phone
|
||||||
|
@ -115,9 +115,20 @@ class EmployeeView(MasterView):
|
||||||
g.filters['email'] = g.make_filter('email', model.EmployeeEmailAddress.address,
|
g.filters['email'] = g.make_filter('email', model.EmployeeEmailAddress.address,
|
||||||
label="Email Address")
|
label="Email Address")
|
||||||
|
|
||||||
# first/last name
|
# first_name
|
||||||
g.filters['first_name'] = g.make_filter('first_name', model.Person.first_name)
|
g.set_link('first_name')
|
||||||
g.filters['last_name'] = g.make_filter('last_name', model.Person.last_name)
|
g.set_sorter('first_name', model.Person.first_name)
|
||||||
|
g.set_sort_defaults('first_name')
|
||||||
|
g.set_filter('first_name', model.Person.first_name,
|
||||||
|
default_active=True,
|
||||||
|
default_verb='contains')
|
||||||
|
|
||||||
|
# last_name
|
||||||
|
g.set_link('last_name')
|
||||||
|
g.set_sorter('last_name', model.Person.last_name)
|
||||||
|
g.set_filter('last_name', model.Person.last_name,
|
||||||
|
default_active=True,
|
||||||
|
default_verb='contains')
|
||||||
|
|
||||||
# username
|
# username
|
||||||
if self.request.has_perm('users.view'):
|
if self.request.has_perm('users.view'):
|
||||||
|
@ -145,18 +156,7 @@ class EmployeeView(MasterView):
|
||||||
g.remove('status')
|
g.remove('status')
|
||||||
del g.filters['status']
|
del g.filters['status']
|
||||||
|
|
||||||
g.filters['first_name'].default_active = True
|
g.set_sorter('email', model.EmployeeEmailAddress.address)
|
||||||
g.filters['first_name'].default_verb = 'contains'
|
|
||||||
|
|
||||||
g.filters['last_name'].default_active = True
|
|
||||||
g.filters['last_name'].default_verb = 'contains'
|
|
||||||
|
|
||||||
g.sorters['first_name'] = lambda q, d: q.order_by(getattr(model.Person.first_name, d)())
|
|
||||||
g.sorters['last_name'] = lambda q, d: q.order_by(getattr(model.Person.last_name, d)())
|
|
||||||
|
|
||||||
g.sorters['email'] = lambda q, d: q.order_by(getattr(model.EmployeeEmailAddress.address, d)())
|
|
||||||
|
|
||||||
g.set_sort_defaults('first_name')
|
|
||||||
|
|
||||||
g.set_label('email', "Email Address")
|
g.set_label('email', "Email Address")
|
||||||
|
|
||||||
|
@ -170,9 +170,6 @@ class EmployeeView(MasterView):
|
||||||
g.main_actions.insert(1, self.make_action(
|
g.main_actions.insert(1, self.make_action(
|
||||||
'view_raw', url=url, icon='eye'))
|
'view_raw', url=url, icon='eye'))
|
||||||
|
|
||||||
g.set_link('first_name')
|
|
||||||
g.set_link('last_name')
|
|
||||||
|
|
||||||
def default_view_url(self):
|
def default_view_url(self):
|
||||||
if (self.request.has_perm('people.view_profile')
|
if (self.request.has_perm('people.view_profile')
|
||||||
and self.should_link_straight_to_profile()):
|
and self.should_link_straight_to_profile()):
|
||||||
|
@ -196,7 +193,7 @@ class EmployeeView(MasterView):
|
||||||
default=False)
|
default=False)
|
||||||
|
|
||||||
def query(self, session):
|
def query(self, session):
|
||||||
query = super(EmployeeView, self).query(session)
|
query = super().query(session)
|
||||||
query = query.join(model.Person)
|
query = query.join(model.Person)
|
||||||
if not self.has_perm('view_all'):
|
if not self.has_perm('view_all'):
|
||||||
query = query.filter(model.Employee.status == self.enum.EMPLOYEE_STATUS_CURRENT)
|
query = query.filter(model.Employee.status == self.enum.EMPLOYEE_STATUS_CURRENT)
|
||||||
|
@ -229,7 +226,7 @@ class EmployeeView(MasterView):
|
||||||
return not self.is_employee_protected(employee)
|
return not self.is_employee_protected(employee)
|
||||||
|
|
||||||
def configure_form(self, f):
|
def configure_form(self, f):
|
||||||
super(EmployeeView, self).configure_form(f)
|
super().configure_form(f)
|
||||||
employee = f.model_instance
|
employee = f.model_instance
|
||||||
|
|
||||||
f.set_renderer('person', self.render_person)
|
f.set_renderer('person', self.render_person)
|
||||||
|
@ -283,7 +280,7 @@ class EmployeeView(MasterView):
|
||||||
def objectify(self, form, data=None):
|
def objectify(self, form, data=None):
|
||||||
if data is None:
|
if data is None:
|
||||||
data = form.validated
|
data = form.validated
|
||||||
employee = super(EmployeeView, self).objectify(form, data)
|
employee = super().objectify(form, data)
|
||||||
self.update_stores(employee, data)
|
self.update_stores(employee, data)
|
||||||
self.update_departments(employee, data)
|
self.update_departments(employee, data)
|
||||||
return employee
|
return employee
|
||||||
|
|
|
@ -196,21 +196,21 @@ class MemberView(MasterView):
|
||||||
g.filters['active'].default_verb = 'is_true'
|
g.filters['active'].default_verb = 'is_true'
|
||||||
|
|
||||||
# phone
|
# phone
|
||||||
|
g.set_label('phone', "Phone Number")
|
||||||
g.set_joiner('phone', lambda q: q.outerjoin(model.MemberPhoneNumber, sa.and_(
|
g.set_joiner('phone', lambda q: q.outerjoin(model.MemberPhoneNumber, sa.and_(
|
||||||
model.MemberPhoneNumber.parent_uuid == model.Member.uuid,
|
model.MemberPhoneNumber.parent_uuid == model.Member.uuid,
|
||||||
model.MemberPhoneNumber.preference == 1)))
|
model.MemberPhoneNumber.preference == 1)))
|
||||||
g.sorters['phone'] = lambda q, d: q.order_by(getattr(model.MemberPhoneNumber.number, d)())
|
g.set_sorter('phone', model.MemberPhoneNumber.number)
|
||||||
g.set_filter('phone', model.MemberPhoneNumber.number,
|
g.set_filter('phone', model.MemberPhoneNumber.number,
|
||||||
factory=grids.filters.AlchemyPhoneNumberFilter)
|
factory=grids.filters.AlchemyPhoneNumberFilter)
|
||||||
g.set_label('phone', "Phone Number")
|
|
||||||
|
|
||||||
# email
|
# email
|
||||||
|
g.set_label('email', "Email Address")
|
||||||
g.set_joiner('email', lambda q: q.outerjoin(model.MemberEmailAddress, sa.and_(
|
g.set_joiner('email', lambda q: q.outerjoin(model.MemberEmailAddress, sa.and_(
|
||||||
model.MemberEmailAddress.parent_uuid == model.Member.uuid,
|
model.MemberEmailAddress.parent_uuid == model.Member.uuid,
|
||||||
model.MemberEmailAddress.preference == 1)))
|
model.MemberEmailAddress.preference == 1)))
|
||||||
g.sorters['email'] = lambda q, d: q.order_by(getattr(model.MemberEmailAddress.address, d)())
|
g.set_sorter('email', model.MemberEmailAddress.address)
|
||||||
g.set_filter('email', model.MemberEmailAddress.address)
|
g.set_filter('email', model.MemberEmailAddress.address)
|
||||||
g.set_label('email', "Email Address")
|
|
||||||
|
|
||||||
# membership_type
|
# membership_type
|
||||||
g.set_joiner('membership_type', lambda q: q.outerjoin(model.MembershipType))
|
g.set_joiner('membership_type', lambda q: q.outerjoin(model.MembershipType))
|
||||||
|
|
|
@ -84,12 +84,12 @@ class MessageView(MasterView):
|
||||||
def index(self):
|
def index(self):
|
||||||
if not self.request.user:
|
if not self.request.user:
|
||||||
raise httpexceptions.HTTPForbidden
|
raise httpexceptions.HTTPForbidden
|
||||||
return super(MessageView, self).index()
|
return super().index()
|
||||||
|
|
||||||
def get_instance(self):
|
def get_instance(self):
|
||||||
if not self.request.user:
|
if not self.request.user:
|
||||||
raise httpexceptions.HTTPForbidden
|
raise httpexceptions.HTTPForbidden
|
||||||
message = super(MessageView, self).get_instance()
|
message = super().get_instance()
|
||||||
if not self.associated_with(message):
|
if not self.associated_with(message):
|
||||||
raise httpexceptions.HTTPForbidden
|
raise httpexceptions.HTTPForbidden
|
||||||
return message
|
return message
|
||||||
|
@ -108,11 +108,18 @@ class MessageView(MasterView):
|
||||||
.filter(model.MessageRecipient.recipient == self.request.user)
|
.filter(model.MessageRecipient.recipient == self.request.user)
|
||||||
|
|
||||||
def configure_grid(self, g):
|
def configure_grid(self, g):
|
||||||
|
super().configure_grid(g)
|
||||||
g.joiners['sender'] = lambda q: q.join(model.User, model.User.uuid == model.Message.sender_uuid).outerjoin(model.Person)
|
model = self.model
|
||||||
g.filters['sender'] = g.make_filter('sender', model.Person.display_name,
|
|
||||||
default_active=True, default_verb='contains')
|
# sender
|
||||||
g.sorters['sender'] = g.make_sorter(model.Person.display_name)
|
g.set_joiner('sender',
|
||||||
|
lambda q: q.join(model.User,
|
||||||
|
model.User.uuid == model.Message.sender_uuid)\
|
||||||
|
.outerjoin(model.Person))
|
||||||
|
g.set_sorter('sender', model.Person.display_name)
|
||||||
|
g.set_filter('sender', model.Person.display_name,
|
||||||
|
default_active=True,
|
||||||
|
default_verb='contains')
|
||||||
|
|
||||||
g.filters['subject'].default_active = True
|
g.filters['subject'].default_active = True
|
||||||
g.filters['subject'].default_verb = 'contains'
|
g.filters['subject'].default_verb = 'contains'
|
||||||
|
@ -201,7 +208,7 @@ class MessageView(MasterView):
|
||||||
# return form
|
# return form
|
||||||
|
|
||||||
def configure_form(self, f):
|
def configure_form(self, f):
|
||||||
super(MessageView, self).configure_form(f)
|
super().configure_form(f)
|
||||||
|
|
||||||
f.submit_label = "Send Message"
|
f.submit_label = "Send Message"
|
||||||
|
|
||||||
|
@ -274,7 +281,7 @@ class MessageView(MasterView):
|
||||||
def objectify(self, form, data=None):
|
def objectify(self, form, data=None):
|
||||||
if data is None:
|
if data is None:
|
||||||
data = form.validated
|
data = form.validated
|
||||||
message = super(MessageView, self).objectify(form, data)
|
message = super().objectify(form, data)
|
||||||
|
|
||||||
if self.creating:
|
if self.creating:
|
||||||
if self.request.user:
|
if self.request.user:
|
||||||
|
@ -463,7 +470,7 @@ class InboxView(MessageView):
|
||||||
return self.request.route_url('messages.inbox')
|
return self.request.route_url('messages.inbox')
|
||||||
|
|
||||||
def query(self, session):
|
def query(self, session):
|
||||||
q = super(InboxView, self).query(session)
|
q = super().query(session)
|
||||||
return q.filter(model.MessageRecipient.status == self.enum.MESSAGE_STATUS_INBOX)
|
return q.filter(model.MessageRecipient.status == self.enum.MESSAGE_STATUS_INBOX)
|
||||||
|
|
||||||
|
|
||||||
|
@ -479,7 +486,7 @@ class ArchiveView(MessageView):
|
||||||
return self.request.route_url('messages.archive')
|
return self.request.route_url('messages.archive')
|
||||||
|
|
||||||
def query(self, session):
|
def query(self, session):
|
||||||
q = super(ArchiveView, self).query(session)
|
q = super().query(session)
|
||||||
return q.filter(model.MessageRecipient.status == self.enum.MESSAGE_STATUS_ARCHIVE)
|
return q.filter(model.MessageRecipient.status == self.enum.MESSAGE_STATUS_ARCHIVE)
|
||||||
|
|
||||||
|
|
||||||
|
@ -500,7 +507,7 @@ class SentView(MessageView):
|
||||||
.filter(model.Message.sender == self.request.user)
|
.filter(model.Message.sender == self.request.user)
|
||||||
|
|
||||||
def configure_grid(self, g):
|
def configure_grid(self, g):
|
||||||
super(SentView, self).configure_grid(g)
|
super().configure_grid(g)
|
||||||
g.filters['sender'].default_active = False
|
g.filters['sender'].default_active = False
|
||||||
g.joiners['recipients'] = lambda q: q.join(model.MessageRecipient)\
|
g.joiners['recipients'] = lambda q: q.join(model.MessageRecipient)\
|
||||||
.join(model.User, model.User.uuid == model.MessageRecipient.recipient_uuid)\
|
.join(model.User, model.User.uuid == model.MessageRecipient.recipient_uuid)\
|
||||||
|
|
|
@ -95,7 +95,7 @@ class PersonView(MasterView):
|
||||||
mergeable = True
|
mergeable = True
|
||||||
|
|
||||||
def __init__(self, request):
|
def __init__(self, request):
|
||||||
super(PersonView, self).__init__(request)
|
super().__init__(request)
|
||||||
app = self.get_rattail_app()
|
app = self.get_rattail_app()
|
||||||
|
|
||||||
# always get a reference to the People Handler
|
# always get a reference to the People Handler
|
||||||
|
@ -105,7 +105,7 @@ class PersonView(MasterView):
|
||||||
self.handler = self.people_handler
|
self.handler = self.people_handler
|
||||||
|
|
||||||
def make_grid_kwargs(self, **kwargs):
|
def make_grid_kwargs(self, **kwargs):
|
||||||
kwargs = super(PersonView, self).make_grid_kwargs(**kwargs)
|
kwargs = super().make_grid_kwargs(**kwargs)
|
||||||
|
|
||||||
# turn on checkboxes if user can create a merge reqeust
|
# turn on checkboxes if user can create a merge reqeust
|
||||||
if self.mergeable and self.has_perm('request_merge'):
|
if self.mergeable and self.has_perm('request_merge'):
|
||||||
|
@ -114,18 +114,28 @@ class PersonView(MasterView):
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
def configure_grid(self, g):
|
def configure_grid(self, g):
|
||||||
super(PersonView, self).configure_grid(g)
|
super().configure_grid(g)
|
||||||
route_prefix = self.get_route_prefix()
|
route_prefix = self.get_route_prefix()
|
||||||
model = self.model
|
model = self.model
|
||||||
|
|
||||||
g.joiners['email'] = lambda q: q.outerjoin(model.PersonEmailAddress, sa.and_(
|
# email
|
||||||
model.PersonEmailAddress.parent_uuid == model.Person.uuid,
|
g.set_label('email', "Email Address")
|
||||||
model.PersonEmailAddress.preference == 1))
|
g.set_joiner('email', lambda q: q.outerjoin(
|
||||||
g.joiners['phone'] = lambda q: q.outerjoin(model.PersonPhoneNumber, sa.and_(
|
model.PersonEmailAddress,
|
||||||
model.PersonPhoneNumber.parent_uuid == model.Person.uuid,
|
sa.and_(
|
||||||
model.PersonPhoneNumber.preference == 1))
|
model.PersonEmailAddress.parent_uuid == model.Person.uuid,
|
||||||
|
model.PersonEmailAddress.preference == 1)))
|
||||||
|
g.set_sorter('email', model.PersonEmailAddress.address)
|
||||||
|
g.set_filter('email', model.PersonEmailAddress.address)
|
||||||
|
|
||||||
g.filters['email'] = g.make_filter('email', model.PersonEmailAddress.address)
|
# phone
|
||||||
|
g.set_label('phone', "Phone Number")
|
||||||
|
g.set_joiner('phone', lambda q: q.outerjoin(
|
||||||
|
model.PersonPhoneNumber,
|
||||||
|
sa.and_(
|
||||||
|
model.PersonPhoneNumber.parent_uuid == model.Person.uuid,
|
||||||
|
model.PersonPhoneNumber.preference == 1)))
|
||||||
|
g.set_sorter('phone', model.PersonPhoneNumber.number)
|
||||||
g.set_filter('phone', model.PersonPhoneNumber.number,
|
g.set_filter('phone', model.PersonPhoneNumber.number,
|
||||||
factory=grids.filters.AlchemyPhoneNumberFilter)
|
factory=grids.filters.AlchemyPhoneNumberFilter)
|
||||||
|
|
||||||
|
@ -151,17 +161,12 @@ class PersonView(MasterView):
|
||||||
g.set_filter('employee_status', model.Employee.status,
|
g.set_filter('employee_status', model.Employee.status,
|
||||||
value_enum=self.enum.EMPLOYEE_STATUS)
|
value_enum=self.enum.EMPLOYEE_STATUS)
|
||||||
|
|
||||||
g.sorters['email'] = lambda q, d: q.order_by(getattr(model.PersonEmailAddress.address, d)())
|
|
||||||
g.sorters['phone'] = lambda q, d: q.order_by(getattr(model.PersonPhoneNumber.number, d)())
|
|
||||||
|
|
||||||
g.set_label('merge_requested', "MR")
|
g.set_label('merge_requested', "MR")
|
||||||
g.set_renderer('merge_requested', self.render_merge_requested)
|
g.set_renderer('merge_requested', self.render_merge_requested)
|
||||||
|
|
||||||
g.set_sort_defaults('display_name')
|
g.set_sort_defaults('display_name')
|
||||||
|
|
||||||
g.set_label('display_name', "Full Name")
|
g.set_label('display_name', "Full Name")
|
||||||
g.set_label('phone', "Phone Number")
|
|
||||||
g.set_label('email', "Email Address")
|
|
||||||
g.set_label('customer_id', "Customer ID")
|
g.set_label('customer_id', "Customer ID")
|
||||||
|
|
||||||
if (self.has_perm('view_profile')
|
if (self.has_perm('view_profile')
|
||||||
|
@ -237,7 +242,7 @@ class PersonView(MasterView):
|
||||||
data = form.validated
|
data = form.validated
|
||||||
|
|
||||||
# do normal create/update
|
# do normal create/update
|
||||||
person = super(PersonView, self).objectify(form, data)
|
person = super().objectify(form, data)
|
||||||
|
|
||||||
# collect data from all name fields
|
# collect data from all name fields
|
||||||
names = {}
|
names = {}
|
||||||
|
@ -278,7 +283,7 @@ class PersonView(MasterView):
|
||||||
customer._people.reorder()
|
customer._people.reorder()
|
||||||
|
|
||||||
# continue with normal logic
|
# continue with normal logic
|
||||||
super(PersonView, self).delete_instance(person)
|
super().delete_instance(person)
|
||||||
|
|
||||||
def touch_instance(self, person):
|
def touch_instance(self, person):
|
||||||
"""
|
"""
|
||||||
|
@ -288,7 +293,7 @@ class PersonView(MasterView):
|
||||||
contact info record associated with them.
|
contact info record associated with them.
|
||||||
"""
|
"""
|
||||||
# touch person, as per usual
|
# touch person, as per usual
|
||||||
super(PersonView, self).touch_instance(person)
|
super().touch_instance(person)
|
||||||
|
|
||||||
def touch(obj):
|
def touch(obj):
|
||||||
change = model.Change()
|
change = model.Change()
|
||||||
|
@ -310,7 +315,7 @@ class PersonView(MasterView):
|
||||||
touch(address)
|
touch(address)
|
||||||
|
|
||||||
def configure_common_form(self, f):
|
def configure_common_form(self, f):
|
||||||
super(PersonView, self).configure_common_form(f)
|
super().configure_common_form(f)
|
||||||
person = f.model_instance
|
person = f.model_instance
|
||||||
|
|
||||||
f.set_label('display_name', "Full Name")
|
f.set_label('display_name', "Full Name")
|
||||||
|
@ -1836,7 +1841,7 @@ class PersonNoteView(MasterView):
|
||||||
return note.subject or "(no subject)"
|
return note.subject or "(no subject)"
|
||||||
|
|
||||||
def configure_grid(self, g):
|
def configure_grid(self, g):
|
||||||
super(PersonNoteView, self).configure_grid(g)
|
super().configure_grid(g)
|
||||||
|
|
||||||
# person
|
# person
|
||||||
g.set_joiner('person', lambda q: q.join(model.Person,
|
g.set_joiner('person', lambda q: q.join(model.Person,
|
||||||
|
@ -1857,7 +1862,7 @@ class PersonNoteView(MasterView):
|
||||||
g.set_link('created')
|
g.set_link('created')
|
||||||
|
|
||||||
def configure_form(self, f):
|
def configure_form(self, f):
|
||||||
super(PersonNoteView, self).configure_form(f)
|
super().configure_form(f)
|
||||||
|
|
||||||
# person
|
# person
|
||||||
f.set_readonly('person')
|
f.set_readonly('person')
|
||||||
|
@ -1931,7 +1936,7 @@ class MergePeopleRequestView(MasterView):
|
||||||
]
|
]
|
||||||
|
|
||||||
def configure_grid(self, g):
|
def configure_grid(self, g):
|
||||||
super(MergePeopleRequestView, self).configure_grid(g)
|
super().configure_grid(g)
|
||||||
|
|
||||||
g.set_renderer('removing_uuid', self.render_referenced_person_name)
|
g.set_renderer('removing_uuid', self.render_referenced_person_name)
|
||||||
g.set_renderer('keeping_uuid', self.render_referenced_person_name)
|
g.set_renderer('keeping_uuid', self.render_referenced_person_name)
|
||||||
|
@ -1960,7 +1965,7 @@ class MergePeopleRequestView(MasterView):
|
||||||
keeping or "(not found)")
|
keeping or "(not found)")
|
||||||
|
|
||||||
def configure_form(self, f):
|
def configure_form(self, f):
|
||||||
super(MergePeopleRequestView, self).configure_form(f)
|
super().configure_form(f)
|
||||||
|
|
||||||
f.set_renderer('removing_uuid', self.render_referenced_person)
|
f.set_renderer('removing_uuid', self.render_referenced_person)
|
||||||
f.set_renderer('keeping_uuid', self.render_referenced_person)
|
f.set_renderer('keeping_uuid', self.render_referenced_person)
|
||||||
|
|
|
@ -167,7 +167,7 @@ class ProductView(MasterView):
|
||||||
TPRPrice = orm.aliased(model.ProductPrice)
|
TPRPrice = orm.aliased(model.ProductPrice)
|
||||||
|
|
||||||
def __init__(self, request):
|
def __init__(self, request):
|
||||||
super(ProductView, self).__init__(request)
|
super().__init__(request)
|
||||||
self.expose_label_printing = self.rattail_config.getbool(
|
self.expose_label_printing = self.rattail_config.getbool(
|
||||||
'tailbone', 'products.print_labels', default=False)
|
'tailbone', 'products.print_labels', default=False)
|
||||||
|
|
||||||
|
@ -224,7 +224,10 @@ class ProductView(MasterView):
|
||||||
g.set_link(field)
|
g.set_link(field)
|
||||||
|
|
||||||
# brand
|
# brand
|
||||||
g.joiners['brand'] = lambda q: q.outerjoin(model.Brand)
|
g.set_joiner('brand', lambda q: q.outerjoin(model.Brand))
|
||||||
|
g.set_sorter('brand', model.Brand.name)
|
||||||
|
g.set_filter('brand', model.Brand.name,
|
||||||
|
default_active=True, default_verb='contains')
|
||||||
|
|
||||||
# department
|
# department
|
||||||
g.set_joiner('department', lambda q: q.outerjoin(model.Department))
|
g.set_joiner('department', lambda q: q.outerjoin(model.Department))
|
||||||
|
@ -237,12 +240,14 @@ class ProductView(MasterView):
|
||||||
verbs=['equal', 'not_equal', 'is_null', 'is_not_null', 'is_any'],
|
verbs=['equal', 'not_equal', 'is_null', 'is_not_null', 'is_any'],
|
||||||
default_active=True, default_verb='equal')
|
default_active=True, default_verb='equal')
|
||||||
|
|
||||||
g.joiners['subdepartment'] = lambda q: q.outerjoin(model.Subdepartment,
|
# subdepartment
|
||||||
model.Subdepartment.uuid == model.Product.subdepartment_uuid)
|
g.set_joiner('subdepartment', lambda q: q.outerjoin(
|
||||||
g.joiners['code'] = lambda q: q.outerjoin(model.ProductCode)
|
model.Subdepartment,
|
||||||
|
model.Subdepartment.uuid == model.Product.subdepartment_uuid))
|
||||||
|
g.set_sorter('subdepartment', model.Subdepartment.name)
|
||||||
|
g.set_filter('subdepartment', model.Subdepartment.name)
|
||||||
|
|
||||||
g.sorters['brand'] = g.make_sorter(model.Brand.name)
|
g.joiners['code'] = lambda q: q.outerjoin(model.ProductCode)
|
||||||
g.sorters['subdepartment'] = g.make_sorter(model.Subdepartment.name)
|
|
||||||
|
|
||||||
# vendor
|
# vendor
|
||||||
ProductVendorCost = orm.aliased(model.ProductCost)
|
ProductVendorCost = orm.aliased(model.ProductCost)
|
||||||
|
@ -296,9 +301,6 @@ class ProductView(MasterView):
|
||||||
|
|
||||||
g.filters['description'].default_active = True
|
g.filters['description'].default_active = True
|
||||||
g.filters['description'].default_verb = 'contains'
|
g.filters['description'].default_verb = 'contains'
|
||||||
g.filters['brand'] = g.make_filter('brand', model.Brand.name,
|
|
||||||
default_active=True, default_verb='contains')
|
|
||||||
g.filters['subdepartment'] = g.make_filter('subdepartment', model.Subdepartment.name)
|
|
||||||
g.filters['code'] = g.make_filter('code', model.ProductCode.code)
|
g.filters['code'] = g.make_filter('code', model.ProductCode.code)
|
||||||
|
|
||||||
# g.joiners['vendor_code_any'] = join_vendor_code_any
|
# g.joiners['vendor_code_any'] = join_vendor_code_any
|
||||||
|
@ -392,7 +394,7 @@ class ProductView(MasterView):
|
||||||
g.set_link('description')
|
g.set_link('description')
|
||||||
|
|
||||||
def configure_common_form(self, f):
|
def configure_common_form(self, f):
|
||||||
super(ProductView, self).configure_common_form(f)
|
super().configure_common_form(f)
|
||||||
product = f.model_instance
|
product = f.model_instance
|
||||||
|
|
||||||
# unit_size
|
# unit_size
|
||||||
|
@ -687,7 +689,7 @@ class ProductView(MasterView):
|
||||||
return ' '.join(classes)
|
return ' '.join(classes)
|
||||||
|
|
||||||
def get_xlsx_fields(self):
|
def get_xlsx_fields(self):
|
||||||
fields = super(ProductView, self).get_xlsx_fields()
|
fields = super().get_xlsx_fields()
|
||||||
|
|
||||||
i = fields.index('department_uuid')
|
i = fields.index('department_uuid')
|
||||||
fields.insert(i + 1, 'department_number')
|
fields.insert(i + 1, 'department_number')
|
||||||
|
@ -734,7 +736,7 @@ class ProductView(MasterView):
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
def get_xlsx_row(self, product, fields):
|
def get_xlsx_row(self, product, fields):
|
||||||
row = super(ProductView, self).get_xlsx_row(product, fields)
|
row = super().get_xlsx_row(product, fields)
|
||||||
|
|
||||||
if 'upc' in fields and isinstance(row['upc'], GPC):
|
if 'upc' in fields and isinstance(row['upc'], GPC):
|
||||||
row['upc'] = row['upc'].pretty()
|
row['upc'] = row['upc'].pretty()
|
||||||
|
@ -799,7 +801,7 @@ class ProductView(MasterView):
|
||||||
return row
|
return row
|
||||||
|
|
||||||
def download_results_normalize(self, product, fields, **kwargs):
|
def download_results_normalize(self, product, fields, **kwargs):
|
||||||
data = super(ProductView, self).download_results_normalize(
|
data = super().download_results_normalize(
|
||||||
product, fields, **kwargs)
|
product, fields, **kwargs)
|
||||||
|
|
||||||
if 'upc' in data:
|
if 'upc' in data:
|
||||||
|
@ -988,7 +990,7 @@ class ProductView(MasterView):
|
||||||
def objectify(self, form, data=None):
|
def objectify(self, form, data=None):
|
||||||
if data is None:
|
if data is None:
|
||||||
data = form.validated
|
data = form.validated
|
||||||
product = super(ProductView, self).objectify(form, data=data)
|
product = super().objectify(form, data=data)
|
||||||
|
|
||||||
# regular_price_amount
|
# regular_price_amount
|
||||||
if (self.creating or self.editing) and 'regular_price_amount' in form.fields:
|
if (self.creating or self.editing) and 'regular_price_amount' in form.fields:
|
||||||
|
@ -1163,7 +1165,7 @@ class ProductView(MasterView):
|
||||||
return jsdata
|
return jsdata
|
||||||
|
|
||||||
def template_kwargs_view(self, **kwargs):
|
def template_kwargs_view(self, **kwargs):
|
||||||
kwargs = super(ProductView, self).template_kwargs_view(**kwargs)
|
kwargs = super().template_kwargs_view(**kwargs)
|
||||||
product = kwargs['instance']
|
product = kwargs['instance']
|
||||||
|
|
||||||
kwargs['image_url'] = self.products_handler.get_image_url(product)
|
kwargs['image_url'] = self.products_handler.get_image_url(product)
|
||||||
|
@ -2287,7 +2289,7 @@ class PendingProductView(MasterView):
|
||||||
]
|
]
|
||||||
|
|
||||||
def configure_grid(self, g):
|
def configure_grid(self, g):
|
||||||
super(PendingProductView, self).configure_grid(g)
|
super().configure_grid(g)
|
||||||
|
|
||||||
g.set_enum('status_code', self.enum.PENDING_PRODUCT_STATUS)
|
g.set_enum('status_code', self.enum.PENDING_PRODUCT_STATUS)
|
||||||
g.filters['status_code'].default_active = True
|
g.filters['status_code'].default_active = True
|
||||||
|
@ -2299,7 +2301,7 @@ class PendingProductView(MasterView):
|
||||||
g.set_link('description')
|
g.set_link('description')
|
||||||
|
|
||||||
def configure_form(self, f):
|
def configure_form(self, f):
|
||||||
super(PendingProductView, self).configure_form(f)
|
super().configure_form(f)
|
||||||
model = self.model
|
model = self.model
|
||||||
pending = f.model_instance
|
pending = f.model_instance
|
||||||
|
|
||||||
|
@ -2417,7 +2419,7 @@ class PendingProductView(MasterView):
|
||||||
if data is None:
|
if data is None:
|
||||||
data = form.validated
|
data = form.validated
|
||||||
|
|
||||||
pending = super(PendingProductView, self).objectify(form, data)
|
pending = super().objectify(form, data)
|
||||||
|
|
||||||
if not pending.user:
|
if not pending.user:
|
||||||
pending.user = self.request.user
|
pending.user = self.request.user
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
#
|
#
|
||||||
# Rattail -- Retail Software Framework
|
# Rattail -- Retail Software Framework
|
||||||
# Copyright © 2010-2022 Lance Edgar
|
# Copyright © 2010-2023 Lance Edgar
|
||||||
#
|
#
|
||||||
# This file is part of Rattail.
|
# This file is part of Rattail.
|
||||||
#
|
#
|
||||||
|
@ -24,10 +24,6 @@
|
||||||
Views for "true" purchase orders
|
Views for "true" purchase orders
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import unicode_literals, absolute_import
|
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from rattail.db import model
|
from rattail.db import model
|
||||||
|
|
||||||
from webhelpers2.html import HTML, tags
|
from webhelpers2.html import HTML, tags
|
||||||
|
@ -143,28 +139,35 @@ class PurchaseView(MasterView):
|
||||||
if purchase.date_ordered:
|
if purchase.date_ordered:
|
||||||
return "{} (ordered {})".format(purchase.vendor, purchase.date_ordered.strftime('%Y-%m-%d'))
|
return "{} (ordered {})".format(purchase.vendor, purchase.date_ordered.strftime('%Y-%m-%d'))
|
||||||
return "{} (ordered)".format(purchase.vendor)
|
return "{} (ordered)".format(purchase.vendor)
|
||||||
return six.text_type(purchase)
|
return str(purchase)
|
||||||
|
|
||||||
def configure_grid(self, g):
|
def configure_grid(self, g):
|
||||||
super(PurchaseView, self).configure_grid(g)
|
super().configure_grid(g)
|
||||||
|
model = self.model
|
||||||
|
|
||||||
g.joiners['store'] = lambda q: q.join(model.Store)
|
# store
|
||||||
g.filters['store'] = g.make_filter('store', model.Store.name)
|
g.set_joiner('store', lambda q: q.join(model.Store))
|
||||||
g.sorters['store'] = g.make_sorter(model.Store.name)
|
g.set_sorter('store', model.Store.name)
|
||||||
|
g.set_filter('store', model.Store.name)
|
||||||
|
|
||||||
g.joiners['vendor'] = lambda q: q.join(model.Vendor)
|
# vendor
|
||||||
g.filters['vendor'] = g.make_filter('vendor', model.Vendor.name,
|
g.set_joiner('vendor', lambda q: q.join(model.Vendor))
|
||||||
default_active=True, default_verb='contains')
|
g.set_sorter('vendor', model.Vendor.name)
|
||||||
g.sorters['vendor'] = g.make_sorter(model.Vendor.name)
|
g.set_filter('vendor', model.Vendor.name,
|
||||||
|
default_active=True,
|
||||||
|
default_verb='contains')
|
||||||
|
|
||||||
g.joiners['department'] = lambda q: q.join(model.Department)
|
# department
|
||||||
g.filters['department'] = g.make_filter('department', model.Department.name)
|
g.set_joiner('department', lambda q: q.join(model.Department))
|
||||||
g.sorters['department'] = g.make_sorter(model.Department.name)
|
g.set_sorter('department', model.Department.name)
|
||||||
|
g.set_filter('department', model.Department.name)
|
||||||
|
|
||||||
g.joiners['buyer'] = lambda q: q.join(model.Employee).join(model.Person)
|
# buyer
|
||||||
g.filters['buyer'] = g.make_filter('buyer', model.Person.display_name,
|
g.set_joiner('buyer', lambda q: q.join(model.Employee).join(model.Person))
|
||||||
default_active=True, default_verb='contains')
|
g.set_sorter('buyer', model.Person.display_name)
|
||||||
g.sorters['buyer'] = g.make_sorter(model.Person.display_name)
|
g.set_filter('buyer', model.Person.display_name,
|
||||||
|
default_active=True,
|
||||||
|
default_verb='contains')
|
||||||
|
|
||||||
# id
|
# id
|
||||||
g.set_renderer('id', self.render_id_str)
|
g.set_renderer('id', self.render_id_str)
|
||||||
|
@ -198,7 +201,7 @@ class PurchaseView(MasterView):
|
||||||
g.set_link('invoice_total')
|
g.set_link('invoice_total')
|
||||||
|
|
||||||
def configure_form(self, f):
|
def configure_form(self, f):
|
||||||
super(PurchaseView, self).configure_form(f)
|
super().configure_form(f)
|
||||||
|
|
||||||
# id
|
# id
|
||||||
f.set_renderer('id', self.render_id_str)
|
f.set_renderer('id', self.render_id_str)
|
||||||
|
@ -322,7 +325,7 @@ class PurchaseView(MasterView):
|
||||||
.filter(model.PurchaseItem.purchase == purchase)
|
.filter(model.PurchaseItem.purchase == purchase)
|
||||||
|
|
||||||
def configure_row_grid(self, g):
|
def configure_row_grid(self, g):
|
||||||
super(PurchaseView, self).configure_row_grid(g)
|
super().configure_row_grid(g)
|
||||||
|
|
||||||
g.set_sort_defaults('sequence')
|
g.set_sort_defaults('sequence')
|
||||||
|
|
||||||
|
@ -353,7 +356,7 @@ class PurchaseView(MasterView):
|
||||||
g.remove('po_total')
|
g.remove('po_total')
|
||||||
|
|
||||||
def configure_row_form(self, f):
|
def configure_row_form(self, f):
|
||||||
super(PurchaseView, self).configure_row_form(f)
|
super().configure_row_form(f)
|
||||||
|
|
||||||
# quantity fields
|
# quantity fields
|
||||||
f.set_type('case_quantity', 'quantity')
|
f.set_type('case_quantity', 'quantity')
|
||||||
|
|
|
@ -175,9 +175,10 @@ class PurchasingBatchView(BatchMasterView):
|
||||||
g.set_filter('vendor', model.Vendor.name,
|
g.set_filter('vendor', model.Vendor.name,
|
||||||
default_active=True, default_verb='contains')
|
default_active=True, default_verb='contains')
|
||||||
|
|
||||||
g.joiners['department'] = lambda q: q.join(model.Department)
|
# department
|
||||||
g.filters['department'] = g.make_filter('department', model.Department.name)
|
g.set_joiner('department', lambda q: q.join(model.Department))
|
||||||
g.sorters['department'] = g.make_sorter(model.Department.name)
|
g.set_filter('department', model.Department.name)
|
||||||
|
g.set_sorter('department', model.Department.name)
|
||||||
|
|
||||||
g.set_joiner('buyer', lambda q: q.join(model.Employee).join(model.Person))
|
g.set_joiner('buyer', lambda q: q.join(model.Employee).join(model.Person))
|
||||||
g.set_filter('buyer', model.Person.display_name)
|
g.set_filter('buyer', model.Person.display_name)
|
||||||
|
@ -212,7 +213,7 @@ class PurchasingBatchView(BatchMasterView):
|
||||||
# return form
|
# return form
|
||||||
|
|
||||||
def configure_common_form(self, f):
|
def configure_common_form(self, f):
|
||||||
super(PurchasingBatchView, self).configure_common_form(f)
|
super().configure_common_form(f)
|
||||||
|
|
||||||
# po_total
|
# po_total
|
||||||
if self.creating:
|
if self.creating:
|
||||||
|
@ -225,7 +226,7 @@ class PurchasingBatchView(BatchMasterView):
|
||||||
f.set_type('po_total_calculated', 'currency')
|
f.set_type('po_total_calculated', 'currency')
|
||||||
|
|
||||||
def configure_form(self, f):
|
def configure_form(self, f):
|
||||||
super(PurchasingBatchView, self).configure_form(f)
|
super().configure_form(f)
|
||||||
model = self.model
|
model = self.model
|
||||||
batch = f.model_instance
|
batch = f.model_instance
|
||||||
app = self.get_rattail_app()
|
app = self.get_rattail_app()
|
||||||
|
@ -598,7 +599,7 @@ class PurchasingBatchView(BatchMasterView):
|
||||||
# return query.options(orm.joinedload(model.PurchaseBatchRow.credits))
|
# return query.options(orm.joinedload(model.PurchaseBatchRow.credits))
|
||||||
|
|
||||||
def configure_row_grid(self, g):
|
def configure_row_grid(self, g):
|
||||||
super(PurchasingBatchView, self).configure_row_grid(g)
|
super().configure_row_grid(g)
|
||||||
|
|
||||||
g.set_type('upc', 'gpc')
|
g.set_type('upc', 'gpc')
|
||||||
g.set_type('cases_ordered', 'quantity')
|
g.set_type('cases_ordered', 'quantity')
|
||||||
|
@ -685,7 +686,7 @@ class PurchasingBatchView(BatchMasterView):
|
||||||
return 'notice'
|
return 'notice'
|
||||||
|
|
||||||
def configure_row_form(self, f):
|
def configure_row_form(self, f):
|
||||||
super(PurchasingBatchView, self).configure_row_form(f)
|
super().configure_row_form(f)
|
||||||
row = f.model_instance
|
row = f.model_instance
|
||||||
if self.creating:
|
if self.creating:
|
||||||
batch = self.get_instance()
|
batch = self.get_instance()
|
||||||
|
@ -894,7 +895,7 @@ class PurchasingBatchView(BatchMasterView):
|
||||||
batch.invoice_total -= row.invoice_total
|
batch.invoice_total -= row.invoice_total
|
||||||
|
|
||||||
# do the "normal" save logic...
|
# do the "normal" save logic...
|
||||||
row = super(PurchasingBatchView, self).save_edit_row_form(form)
|
row = super().save_edit_row_form(form)
|
||||||
|
|
||||||
# TODO: is this needed?
|
# TODO: is this needed?
|
||||||
# self.handler.refresh_row(row)
|
# self.handler.refresh_row(row)
|
||||||
|
|
|
@ -233,7 +233,7 @@ class ReceivingBatchView(PurchasingBatchView):
|
||||||
return self.enum.PURCHASE_BATCH_MODE_RECEIVING
|
return self.enum.PURCHASE_BATCH_MODE_RECEIVING
|
||||||
|
|
||||||
def configure_grid(self, g):
|
def configure_grid(self, g):
|
||||||
super(ReceivingBatchView, self).configure_grid(g)
|
super().configure_grid(g)
|
||||||
|
|
||||||
if not self.handler.allow_truck_dump_receiving():
|
if not self.handler.allow_truck_dump_receiving():
|
||||||
g.remove('truck_dump')
|
g.remove('truck_dump')
|
||||||
|
@ -285,14 +285,14 @@ class ReceivingBatchView(PurchasingBatchView):
|
||||||
raise redirect
|
raise redirect
|
||||||
|
|
||||||
# okay now do the normal thing, per workflow
|
# okay now do the normal thing, per workflow
|
||||||
return super(ReceivingBatchView, self).create(**kwargs)
|
return super().create(**kwargs)
|
||||||
|
|
||||||
# on the other hand, if caller provided a form, that means we are in
|
# on the other hand, if caller provided a form, that means we are in
|
||||||
# the middle of some other custom workflow, e.g. "add child to truck
|
# the middle of some other custom workflow, e.g. "add child to truck
|
||||||
# dump parent" or some such. in which case we also defer to the normal
|
# dump parent" or some such. in which case we also defer to the normal
|
||||||
# logic, so as to not interfere with that.
|
# logic, so as to not interfere with that.
|
||||||
if form:
|
if form:
|
||||||
return super(ReceivingBatchView, self).create(form=form, **kwargs)
|
return super().create(form=form, **kwargs)
|
||||||
|
|
||||||
# okay, at this point we need the user to select a vendor and workflow
|
# okay, at this point we need the user to select a vendor and workflow
|
||||||
self.creating = True
|
self.creating = True
|
||||||
|
@ -372,14 +372,14 @@ class ReceivingBatchView(PurchasingBatchView):
|
||||||
|
|
||||||
# first run it through the normal logic, if that doesn't like
|
# first run it through the normal logic, if that doesn't like
|
||||||
# it then we won't either
|
# it then we won't either
|
||||||
if not super(ReceivingBatchView, self).row_deletable(row):
|
if not super().row_deletable(row):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# otherwise let handler decide
|
# otherwise let handler decide
|
||||||
return self.batch_handler.is_row_deletable(row)
|
return self.batch_handler.is_row_deletable(row)
|
||||||
|
|
||||||
def get_instance_title(self, batch):
|
def get_instance_title(self, batch):
|
||||||
title = super(ReceivingBatchView, self).get_instance_title(batch)
|
title = super().get_instance_title(batch)
|
||||||
if batch.is_truck_dump_parent():
|
if batch.is_truck_dump_parent():
|
||||||
title = "{} (TRUCK DUMP PARENT)".format(title)
|
title = "{} (TRUCK DUMP PARENT)".format(title)
|
||||||
elif batch.is_truck_dump_child():
|
elif batch.is_truck_dump_child():
|
||||||
|
@ -633,7 +633,7 @@ class ReceivingBatchView(PurchasingBatchView):
|
||||||
return info['display']
|
return info['display']
|
||||||
|
|
||||||
def get_visible_params(self, batch):
|
def get_visible_params(self, batch):
|
||||||
params = super(ReceivingBatchView, self).get_visible_params(batch)
|
params = super().get_visible_params(batch)
|
||||||
|
|
||||||
# remove this since we show it separately
|
# remove this since we show it separately
|
||||||
params.pop('invoice_files', None)
|
params.pop('invoice_files', None)
|
||||||
|
@ -655,7 +655,7 @@ class ReceivingBatchView(PurchasingBatchView):
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
def get_batch_kwargs(self, batch, **kwargs):
|
def get_batch_kwargs(self, batch, **kwargs):
|
||||||
kwargs = super(ReceivingBatchView, self).get_batch_kwargs(batch, **kwargs)
|
kwargs = super().get_batch_kwargs(batch, **kwargs)
|
||||||
batch_type = self.request.POST['batch_type']
|
batch_type = self.request.POST['batch_type']
|
||||||
|
|
||||||
# must pull vendor from URL if it was not in form data
|
# must pull vendor from URL if it was not in form data
|
||||||
|
@ -769,7 +769,7 @@ class ReceivingBatchView(PurchasingBatchView):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def template_kwargs_view(self, **kwargs):
|
def template_kwargs_view(self, **kwargs):
|
||||||
kwargs = super(ReceivingBatchView, self).template_kwargs_view(**kwargs)
|
kwargs = super().template_kwargs_view(**kwargs)
|
||||||
batch = kwargs['instance']
|
batch = kwargs['instance']
|
||||||
|
|
||||||
if self.handler.has_purchase_order(batch) and self.handler.has_invoice_file(batch):
|
if self.handler.has_purchase_order(batch) and self.handler.has_invoice_file(batch):
|
||||||
|
@ -810,7 +810,7 @@ class ReceivingBatchView(PurchasingBatchView):
|
||||||
return credits_data
|
return credits_data
|
||||||
|
|
||||||
def template_kwargs_view_row(self, **kwargs):
|
def template_kwargs_view_row(self, **kwargs):
|
||||||
kwargs = super(ReceivingBatchView, self).template_kwargs_view_row(**kwargs)
|
kwargs = super().template_kwargs_view_row(**kwargs)
|
||||||
app = self.get_rattail_app()
|
app = self.get_rattail_app()
|
||||||
products_handler = app.get_products_handler()
|
products_handler = app.get_products_handler()
|
||||||
row = kwargs['instance']
|
row = kwargs['instance']
|
||||||
|
@ -847,7 +847,7 @@ class ReceivingBatchView(PurchasingBatchView):
|
||||||
if batch.is_truck_dump_parent():
|
if batch.is_truck_dump_parent():
|
||||||
for child in batch.truck_dump_children:
|
for child in batch.truck_dump_children:
|
||||||
self.delete_instance(child)
|
self.delete_instance(child)
|
||||||
super(ReceivingBatchView, self).delete_instance(batch)
|
super().delete_instance(batch)
|
||||||
if truck_dump:
|
if truck_dump:
|
||||||
self.handler.refresh(truck_dump)
|
self.handler.refresh(truck_dump)
|
||||||
|
|
||||||
|
@ -1010,7 +1010,7 @@ class ReceivingBatchView(PurchasingBatchView):
|
||||||
.group_by(model.PurchaseBatchCredit.row_uuid)\
|
.group_by(model.PurchaseBatchCredit.row_uuid)\
|
||||||
.subquery()
|
.subquery()
|
||||||
g.set_joiner('credits', lambda q: q.outerjoin(Credits))
|
g.set_joiner('credits', lambda q: q.outerjoin(Credits))
|
||||||
g.sorters['credits'] = lambda q, d: q.order_by(getattr(Credits.c.credit_count, d)())
|
g.set_sorter('credits', Credits.c.credit_count)
|
||||||
|
|
||||||
show_ordered = self.rattail_config.getbool(
|
show_ordered = self.rattail_config.getbool(
|
||||||
'rattail.batch', 'purchase.receiving.show_ordered_column_in_grid',
|
'rattail.batch', 'purchase.receiving.show_ordered_column_in_grid',
|
||||||
|
@ -1083,7 +1083,7 @@ class ReceivingBatchView(PurchasingBatchView):
|
||||||
})
|
})
|
||||||
|
|
||||||
def row_grid_extra_class(self, row, i):
|
def row_grid_extra_class(self, row, i):
|
||||||
css_class = super(ReceivingBatchView, self).row_grid_extra_class(row, i)
|
css_class = super().row_grid_extra_class(row, i)
|
||||||
|
|
||||||
if row.catalog_cost_confirmed:
|
if row.catalog_cost_confirmed:
|
||||||
css_class = '{} catalog_cost_confirmed'.format(css_class or '')
|
css_class = '{} catalog_cost_confirmed'.format(css_class or '')
|
||||||
|
@ -1098,7 +1098,7 @@ class ReceivingBatchView(PurchasingBatchView):
|
||||||
return str(row.product)
|
return str(row.product)
|
||||||
if row.upc:
|
if row.upc:
|
||||||
return row.upc.pretty()
|
return row.upc.pretty()
|
||||||
return super(ReceivingBatchView, self).get_row_instance_title(row)
|
return super().get_row_instance_title(row)
|
||||||
|
|
||||||
def transform_unit_url(self, row, i):
|
def transform_unit_url(self, row, i):
|
||||||
# grid action is shown only when we return a URL here
|
# grid action is shown only when we return a URL here
|
||||||
|
@ -1110,7 +1110,7 @@ class ReceivingBatchView(PurchasingBatchView):
|
||||||
def make_row_credits_grid(self, row):
|
def make_row_credits_grid(self, row):
|
||||||
|
|
||||||
# first make grid like normal
|
# first make grid like normal
|
||||||
g = super(ReceivingBatchView, self).make_row_credits_grid(row)
|
g = super().make_row_credits_grid(row)
|
||||||
|
|
||||||
if (self.has_perm('edit_row')
|
if (self.has_perm('edit_row')
|
||||||
and self.row_editable(row)):
|
and self.row_editable(row)):
|
||||||
|
@ -1616,7 +1616,7 @@ class ReceivingBatchView(PurchasingBatchView):
|
||||||
def validate_row_form(self, form):
|
def validate_row_form(self, form):
|
||||||
|
|
||||||
# if normal validation fails, stop there
|
# if normal validation fails, stop there
|
||||||
if not super(ReceivingBatchView, self).validate_row_form(form):
|
if not super().validate_row_form(form):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# if user is editing row from truck dump child, then we must further
|
# if user is editing row from truck dump child, then we must further
|
||||||
|
@ -2097,7 +2097,7 @@ class ReceiveRowForm(colander.MappingSchema):
|
||||||
quick_receive = colander.SchemaNode(colander.Boolean())
|
quick_receive = colander.SchemaNode(colander.Boolean())
|
||||||
|
|
||||||
def deserialize(self, *args):
|
def deserialize(self, *args):
|
||||||
result = super(ReceiveRowForm, self).deserialize(*args)
|
result = super().deserialize(*args)
|
||||||
|
|
||||||
if result['mode'] == 'expired' and not result['expiration_date']:
|
if result['mode'] == 'expired' and not result['expiration_date']:
|
||||||
msg = "Expiration date is required for items with 'expired' mode."
|
msg = "Expiration date is required for items with 'expired' mode."
|
||||||
|
|
|
@ -84,7 +84,7 @@ class ScheduledShiftView(MasterView, ShiftViewMixin):
|
||||||
g.set_label('employee', "Employee Name")
|
g.set_label('employee', "Employee Name")
|
||||||
|
|
||||||
def configure_form(self, f):
|
def configure_form(self, f):
|
||||||
super(ScheduledShiftView, self).configure_form(f)
|
super().configure_form(f)
|
||||||
|
|
||||||
f.set_renderer('length', self.render_shift_length)
|
f.set_renderer('length', self.render_shift_length)
|
||||||
|
|
||||||
|
@ -118,19 +118,22 @@ class WorkedShiftView(MasterView, ShiftViewMixin):
|
||||||
]
|
]
|
||||||
|
|
||||||
def configure_grid(self, g):
|
def configure_grid(self, g):
|
||||||
super(WorkedShiftView, self).configure_grid(g)
|
super().configure_grid(g)
|
||||||
|
model = self.model
|
||||||
|
|
||||||
g.joiners['employee'] = lambda q: q.join(model.Employee).join(model.Person)
|
# employee
|
||||||
g.filters['employee'] = g.make_filter('employee', model.Person.display_name)
|
g.set_joiner('employee', lambda q: q.join(model.Employee).join(model.Person))
|
||||||
g.sorters['employee'] = g.make_sorter(model.Person.display_name)
|
g.set_sorter('employee', model.Person.display_name)
|
||||||
|
g.set_filter('employee', model.Person.display_name)
|
||||||
|
|
||||||
g.joiners['store'] = lambda q: q.join(model.Store)
|
# store
|
||||||
g.filters['store'] = g.make_filter('store', model.Store.name)
|
g.set_joiner('store', lambda q: q.join(model.Store))
|
||||||
g.sorters['store'] = g.make_sorter(model.Store.name)
|
g.set_sorter('store', model.Store.name)
|
||||||
|
g.set_filter('store', model.Store.name)
|
||||||
|
|
||||||
# TODO: these sorters should be automatic once we fix the schema
|
# TODO: these sorters should be automatic once we fix the schema
|
||||||
g.sorters['start_time'] = g.make_sorter(model.WorkedShift.punch_in)
|
g.set_sorter('start_time', model.WorkedShift.punch_in)
|
||||||
g.sorters['end_time'] = g.make_sorter(model.WorkedShift.punch_out)
|
g.set_sorter('end_time', model.WorkedShift.punch_out)
|
||||||
# TODO: same goes for these renderers
|
# TODO: same goes for these renderers
|
||||||
g.set_type('start_time', 'datetime')
|
g.set_type('start_time', 'datetime')
|
||||||
g.set_type('end_time', 'datetime')
|
g.set_type('end_time', 'datetime')
|
||||||
|
@ -150,7 +153,7 @@ class WorkedShiftView(MasterView, ShiftViewMixin):
|
||||||
return "WorkedShift: {}, {}".format(shift.employee, date)
|
return "WorkedShift: {}, {}".format(shift.employee, date)
|
||||||
|
|
||||||
def configure_form(self, f):
|
def configure_form(self, f):
|
||||||
super(WorkedShiftView, self).configure_form(f)
|
super().configure_form(f)
|
||||||
|
|
||||||
f.set_readonly('employee')
|
f.set_readonly('employee')
|
||||||
f.set_renderer('employee', self.render_employee)
|
f.set_renderer('employee', self.render_employee)
|
||||||
|
@ -168,7 +171,7 @@ class WorkedShiftView(MasterView, ShiftViewMixin):
|
||||||
return tags.link_to(text, url)
|
return tags.link_to(text, url)
|
||||||
|
|
||||||
def get_xlsx_fields(self):
|
def get_xlsx_fields(self):
|
||||||
fields = super(WorkedShiftView, self).get_xlsx_fields()
|
fields = super().get_xlsx_fields()
|
||||||
|
|
||||||
# add employee name
|
# add employee name
|
||||||
i = fields.index('employee_uuid')
|
i = fields.index('employee_uuid')
|
||||||
|
@ -180,7 +183,7 @@ class WorkedShiftView(MasterView, ShiftViewMixin):
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
def get_xlsx_row(self, shift, fields):
|
def get_xlsx_row(self, shift, fields):
|
||||||
row = super(WorkedShiftView, self).get_xlsx_row(shift, fields)
|
row = super().get_xlsx_row(shift, fields)
|
||||||
|
|
||||||
# localize start and end times (Excel requires time with no zone)
|
# localize start and end times (Excel requires time with no zone)
|
||||||
if shift.punch_in:
|
if shift.punch_in:
|
||||||
|
|
|
@ -101,8 +101,9 @@ class TempmonProbeView(MasterView):
|
||||||
def configure_grid(self, g):
|
def configure_grid(self, g):
|
||||||
super().configure_grid(g)
|
super().configure_grid(g)
|
||||||
|
|
||||||
g.joiners['client'] = lambda q: q.join(tempmon.Client)
|
# client
|
||||||
g.sorters['client'] = g.make_sorter(tempmon.Client.config_key)
|
g.set_joiner('client', lambda q: q.join(tempmon.Client))
|
||||||
|
g.set_sorter('client', tempmon.Client.config_key)
|
||||||
g.set_sort_defaults('client')
|
g.set_sort_defaults('client')
|
||||||
|
|
||||||
g.set_enum('appliance_type', self.enum.TEMPMON_APPLIANCE_TYPE)
|
g.set_enum('appliance_type', self.enum.TEMPMON_APPLIANCE_TYPE)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
#
|
#
|
||||||
# Rattail -- Retail Software Framework
|
# Rattail -- Retail Software Framework
|
||||||
# Copyright © 2010-2022 Lance Edgar
|
# Copyright © 2010-2023 Lance Edgar
|
||||||
#
|
#
|
||||||
# This file is part of Rattail.
|
# This file is part of Rattail.
|
||||||
#
|
#
|
||||||
|
@ -24,9 +24,6 @@
|
||||||
Views for tempmon readings
|
Views for tempmon readings
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import unicode_literals, absolute_import
|
|
||||||
|
|
||||||
import six
|
|
||||||
from sqlalchemy import orm
|
from sqlalchemy import orm
|
||||||
|
|
||||||
from rattail_tempmon.db import model as tempmon
|
from rattail_tempmon.db import model as tempmon
|
||||||
|
@ -70,17 +67,21 @@ class TempmonReadingView(MasterView):
|
||||||
.options(orm.joinedload(tempmon.Reading.client))
|
.options(orm.joinedload(tempmon.Reading.client))
|
||||||
|
|
||||||
def configure_grid(self, g):
|
def configure_grid(self, g):
|
||||||
super(TempmonReadingView, self).configure_grid(g)
|
super().configure_grid(g)
|
||||||
|
|
||||||
g.sorters['client_key'] = g.make_sorter(tempmon.Client.config_key)
|
# client_key
|
||||||
g.filters['client_key'] = g.make_filter('client_key', tempmon.Client.config_key)
|
g.set_sorter('client_key', tempmon.Client.config_key)
|
||||||
|
g.set_filter('client_key', tempmon.Client.config_key)
|
||||||
|
|
||||||
g.sorters['client_host'] = g.make_sorter(tempmon.Client.hostname)
|
# client_host
|
||||||
g.filters['client_host'] = g.make_filter('client_host', tempmon.Client.hostname)
|
g.set_sorter('client_host', tempmon.Client.hostname)
|
||||||
|
g.set_filter('client_host', tempmon.Client.hostname)
|
||||||
|
|
||||||
g.joiners['probe'] = lambda q: q.join(tempmon.Probe, tempmon.Probe.uuid == tempmon.Reading.probe_uuid)
|
# probe
|
||||||
g.sorters['probe'] = g.make_sorter(tempmon.Probe.description)
|
g.set_joiner('probe', lambda q: q.join(tempmon.Probe,
|
||||||
g.filters['probe'] = g.make_filter('probe', tempmon.Probe.description)
|
tempmon.Probe.uuid == tempmon.Reading.probe_uuid))
|
||||||
|
g.set_sorter('probe', tempmon.Probe.description)
|
||||||
|
g.set_filter('probe', tempmon.Probe.description)
|
||||||
|
|
||||||
g.set_sort_defaults('taken', 'desc')
|
g.set_sort_defaults('taken', 'desc')
|
||||||
g.set_type('taken', 'datetime')
|
g.set_type('taken', 'datetime')
|
||||||
|
@ -98,7 +99,7 @@ class TempmonReadingView(MasterView):
|
||||||
return reading.client.hostname
|
return reading.client.hostname
|
||||||
|
|
||||||
def configure_form(self, f):
|
def configure_form(self, f):
|
||||||
super(TempmonReadingView, self).configure_form(f)
|
super().configure_form(f)
|
||||||
|
|
||||||
# client
|
# client
|
||||||
f.set_renderer('client', self.render_client)
|
f.set_renderer('client', self.render_client)
|
||||||
|
@ -112,7 +113,7 @@ class TempmonReadingView(MasterView):
|
||||||
client = reading.client
|
client = reading.client
|
||||||
if not client:
|
if not client:
|
||||||
return ""
|
return ""
|
||||||
text = six.text_type(client)
|
text = str(client)
|
||||||
url = self.request.route_url('tempmon.clients.view', uuid=client.uuid)
|
url = self.request.route_url('tempmon.clients.view', uuid=client.uuid)
|
||||||
return tags.link_to(text, url)
|
return tags.link_to(text, url)
|
||||||
|
|
||||||
|
@ -120,7 +121,7 @@ class TempmonReadingView(MasterView):
|
||||||
probe = reading.probe
|
probe = reading.probe
|
||||||
if not probe:
|
if not probe:
|
||||||
return ""
|
return ""
|
||||||
text = six.text_type(probe)
|
text = str(probe)
|
||||||
url = self.request.route_url('tempmon.probes.view', uuid=probe.uuid)
|
url = self.request.route_url('tempmon.probes.view', uuid=probe.uuid)
|
||||||
return tags.link_to(text, url)
|
return tags.link_to(text, url)
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,6 @@
|
||||||
Views for views
|
Views for views
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import unicode_literals, absolute_import
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
@ -80,7 +78,7 @@ class ModelViewView(MasterView):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def configure_grid(self, g):
|
def configure_grid(self, g):
|
||||||
super(ModelViewView, self).configure_grid(g)
|
super().configure_grid(g)
|
||||||
|
|
||||||
# label
|
# label
|
||||||
g.sorters['label'] = g.make_simple_sorter('label')
|
g.sorters['label'] = g.make_simple_sorter('label')
|
||||||
|
@ -107,7 +105,7 @@ class ModelViewView(MasterView):
|
||||||
return ModelViewSchema()
|
return ModelViewSchema()
|
||||||
|
|
||||||
def template_kwargs_create(self, **kwargs):
|
def template_kwargs_create(self, **kwargs):
|
||||||
kwargs = super(ModelViewView, self).template_kwargs_create(**kwargs)
|
kwargs = super().template_kwargs_create(**kwargs)
|
||||||
app = self.get_rattail_app()
|
app = self.get_rattail_app()
|
||||||
db_handler = app.get_db_handler()
|
db_handler = app.get_db_handler()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue