Use Grid.make_sorter() instead of legacy code

b/c multi-column sorting relies on this
This commit is contained in:
Lance Edgar 2023-10-18 18:18:55 -05:00
parent 659f5a8fe1
commit 919d8d109f
14 changed files with 198 additions and 176 deletions

View file

@ -61,7 +61,7 @@ class EmailBounceView(MasterView):
]
def __init__(self, request):
super(EmailBounceView, self).__init__(request)
super().__init__(request)
self.handler_options = sorted(get_profile_keys(self.rattail_config))
def get_handler(self, bounce):
@ -69,17 +69,21 @@ class EmailBounceView(MasterView):
return app.get_bounce_handler(bounce.config_key)
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'].default_active = True
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_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_label('bounce_recipient_address', "Bounced To")
@ -89,7 +93,7 @@ class EmailBounceView(MasterView):
g.set_link('intended_recipient_address')
def configure_form(self, f):
super(EmailBounceView, self).configure_form(f)
super().configure_form(f)
bounce = f.model_instance
f.set_renderer('message', self.render_message_file)
f.set_renderer('links', self.render_links)

View file

@ -168,22 +168,22 @@ class CustomerView(MasterView):
g.filters['name'].default_verb = 'contains'
# phone
g.set_label('phone', "Phone Number")
g.set_joiner('phone', lambda q: q.outerjoin(model.CustomerPhoneNumber, sa.and_(
model.CustomerPhoneNumber.parent_uuid == model.Customer.uuid,
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,
# label="Phone Number",
factory=grids.filters.AlchemyPhoneNumberFilter)
g.set_label('phone', "Phone Number")
# email
g.set_label('email', "Email Address")
g.set_joiner('email', lambda q: q.outerjoin(model.CustomerEmailAddress, sa.and_(
model.CustomerEmailAddress.parent_uuid == model.Customer.uuid,
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_label('email', "Email Address")
# email_preference
g.set_enum('email_preference', self.enum.EMAIL_PREFERENCE)
@ -244,7 +244,7 @@ class CustomerView(MasterView):
def get_instance(self):
try:
instance = super(CustomerView, self).get_instance()
instance = super().get_instance()
except HTTPNotFound:
pass
else:
@ -273,7 +273,7 @@ class CustomerView(MasterView):
raise HTTPNotFound
def configure_form(self, f):
super(CustomerView, self).configure_form(f)
super().configure_form(f)
customer = f.model_instance
permission_prefix = self.get_permission_prefix()
@ -802,7 +802,7 @@ class PendingCustomerView(MasterView):
]
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.filters['status_code'].default_active = True
@ -814,7 +814,7 @@ class PendingCustomerView(MasterView):
g.set_link('display_name')
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)

View file

@ -96,7 +96,7 @@ class EmployeeView(MasterView):
return app.get_people_handler().get_quickie_search_placeholder()
def configure_grid(self, g):
super(EmployeeView, self).configure_grid(g)
super().configure_grid(g)
route_prefix = self.get_route_prefix()
# phone
@ -115,9 +115,20 @@ class EmployeeView(MasterView):
g.filters['email'] = g.make_filter('email', model.EmployeeEmailAddress.address,
label="Email Address")
# first/last name
g.filters['first_name'] = g.make_filter('first_name', model.Person.first_name)
g.filters['last_name'] = g.make_filter('last_name', model.Person.last_name)
# first_name
g.set_link('first_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
if self.request.has_perm('users.view'):
@ -145,18 +156,7 @@ class EmployeeView(MasterView):
g.remove('status')
del g.filters['status']
g.filters['first_name'].default_active = True
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_sorter('email', model.EmployeeEmailAddress.address)
g.set_label('email', "Email Address")
@ -170,9 +170,6 @@ class EmployeeView(MasterView):
g.main_actions.insert(1, self.make_action(
'view_raw', url=url, icon='eye'))
g.set_link('first_name')
g.set_link('last_name')
def default_view_url(self):
if (self.request.has_perm('people.view_profile')
and self.should_link_straight_to_profile()):
@ -196,7 +193,7 @@ class EmployeeView(MasterView):
default=False)
def query(self, session):
query = super(EmployeeView, self).query(session)
query = super().query(session)
query = query.join(model.Person)
if not self.has_perm('view_all'):
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)
def configure_form(self, f):
super(EmployeeView, self).configure_form(f)
super().configure_form(f)
employee = f.model_instance
f.set_renderer('person', self.render_person)
@ -283,7 +280,7 @@ class EmployeeView(MasterView):
def objectify(self, form, data=None):
if data is None:
data = form.validated
employee = super(EmployeeView, self).objectify(form, data)
employee = super().objectify(form, data)
self.update_stores(employee, data)
self.update_departments(employee, data)
return employee

View file

@ -196,21 +196,21 @@ class MemberView(MasterView):
g.filters['active'].default_verb = 'is_true'
# phone
g.set_label('phone', "Phone Number")
g.set_joiner('phone', lambda q: q.outerjoin(model.MemberPhoneNumber, sa.and_(
model.MemberPhoneNumber.parent_uuid == model.Member.uuid,
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,
factory=grids.filters.AlchemyPhoneNumberFilter)
g.set_label('phone', "Phone Number")
# email
g.set_label('email', "Email Address")
g.set_joiner('email', lambda q: q.outerjoin(model.MemberEmailAddress, sa.and_(
model.MemberEmailAddress.parent_uuid == model.Member.uuid,
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_label('email', "Email Address")
# membership_type
g.set_joiner('membership_type', lambda q: q.outerjoin(model.MembershipType))

View file

@ -84,12 +84,12 @@ class MessageView(MasterView):
def index(self):
if not self.request.user:
raise httpexceptions.HTTPForbidden
return super(MessageView, self).index()
return super().index()
def get_instance(self):
if not self.request.user:
raise httpexceptions.HTTPForbidden
message = super(MessageView, self).get_instance()
message = super().get_instance()
if not self.associated_with(message):
raise httpexceptions.HTTPForbidden
return message
@ -108,11 +108,18 @@ class MessageView(MasterView):
.filter(model.MessageRecipient.recipient == self.request.user)
def configure_grid(self, g):
g.joiners['sender'] = lambda q: q.join(model.User, model.User.uuid == model.Message.sender_uuid).outerjoin(model.Person)
g.filters['sender'] = g.make_filter('sender', model.Person.display_name,
default_active=True, default_verb='contains')
g.sorters['sender'] = g.make_sorter(model.Person.display_name)
super().configure_grid(g)
model = self.model
# sender
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_verb = 'contains'
@ -201,7 +208,7 @@ class MessageView(MasterView):
# return form
def configure_form(self, f):
super(MessageView, self).configure_form(f)
super().configure_form(f)
f.submit_label = "Send Message"
@ -274,7 +281,7 @@ class MessageView(MasterView):
def objectify(self, form, data=None):
if data is None:
data = form.validated
message = super(MessageView, self).objectify(form, data)
message = super().objectify(form, data)
if self.creating:
if self.request.user:
@ -463,7 +470,7 @@ class InboxView(MessageView):
return self.request.route_url('messages.inbox')
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)
@ -479,7 +486,7 @@ class ArchiveView(MessageView):
return self.request.route_url('messages.archive')
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)
@ -500,7 +507,7 @@ class SentView(MessageView):
.filter(model.Message.sender == self.request.user)
def configure_grid(self, g):
super(SentView, self).configure_grid(g)
super().configure_grid(g)
g.filters['sender'].default_active = False
g.joiners['recipients'] = lambda q: q.join(model.MessageRecipient)\
.join(model.User, model.User.uuid == model.MessageRecipient.recipient_uuid)\

View file

@ -95,7 +95,7 @@ class PersonView(MasterView):
mergeable = True
def __init__(self, request):
super(PersonView, self).__init__(request)
super().__init__(request)
app = self.get_rattail_app()
# always get a reference to the People Handler
@ -105,7 +105,7 @@ class PersonView(MasterView):
self.handler = self.people_handler
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
if self.mergeable and self.has_perm('request_merge'):
@ -114,18 +114,28 @@ class PersonView(MasterView):
return kwargs
def configure_grid(self, g):
super(PersonView, self).configure_grid(g)
super().configure_grid(g)
route_prefix = self.get_route_prefix()
model = self.model
g.joiners['email'] = lambda q: q.outerjoin(model.PersonEmailAddress, sa.and_(
model.PersonEmailAddress.parent_uuid == model.Person.uuid,
model.PersonEmailAddress.preference == 1))
g.joiners['phone'] = lambda q: q.outerjoin(model.PersonPhoneNumber, sa.and_(
model.PersonPhoneNumber.parent_uuid == model.Person.uuid,
model.PersonPhoneNumber.preference == 1))
# email
g.set_label('email', "Email Address")
g.set_joiner('email', lambda q: q.outerjoin(
model.PersonEmailAddress,
sa.and_(
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,
factory=grids.filters.AlchemyPhoneNumberFilter)
@ -151,17 +161,12 @@ class PersonView(MasterView):
g.set_filter('employee_status', model.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_renderer('merge_requested', self.render_merge_requested)
g.set_sort_defaults('display_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")
if (self.has_perm('view_profile')
@ -237,7 +242,7 @@ class PersonView(MasterView):
data = form.validated
# do normal create/update
person = super(PersonView, self).objectify(form, data)
person = super().objectify(form, data)
# collect data from all name fields
names = {}
@ -278,7 +283,7 @@ class PersonView(MasterView):
customer._people.reorder()
# continue with normal logic
super(PersonView, self).delete_instance(person)
super().delete_instance(person)
def touch_instance(self, person):
"""
@ -288,7 +293,7 @@ class PersonView(MasterView):
contact info record associated with them.
"""
# touch person, as per usual
super(PersonView, self).touch_instance(person)
super().touch_instance(person)
def touch(obj):
change = model.Change()
@ -310,7 +315,7 @@ class PersonView(MasterView):
touch(address)
def configure_common_form(self, f):
super(PersonView, self).configure_common_form(f)
super().configure_common_form(f)
person = f.model_instance
f.set_label('display_name', "Full Name")
@ -1836,7 +1841,7 @@ class PersonNoteView(MasterView):
return note.subject or "(no subject)"
def configure_grid(self, g):
super(PersonNoteView, self).configure_grid(g)
super().configure_grid(g)
# person
g.set_joiner('person', lambda q: q.join(model.Person,
@ -1857,7 +1862,7 @@ class PersonNoteView(MasterView):
g.set_link('created')
def configure_form(self, f):
super(PersonNoteView, self).configure_form(f)
super().configure_form(f)
# person
f.set_readonly('person')
@ -1931,7 +1936,7 @@ class MergePeopleRequestView(MasterView):
]
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('keeping_uuid', self.render_referenced_person_name)
@ -1960,7 +1965,7 @@ class MergePeopleRequestView(MasterView):
keeping or "(not found)")
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('keeping_uuid', self.render_referenced_person)

View file

@ -167,7 +167,7 @@ class ProductView(MasterView):
TPRPrice = orm.aliased(model.ProductPrice)
def __init__(self, request):
super(ProductView, self).__init__(request)
super().__init__(request)
self.expose_label_printing = self.rattail_config.getbool(
'tailbone', 'products.print_labels', default=False)
@ -224,7 +224,10 @@ class ProductView(MasterView):
g.set_link(field)
# 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
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'],
default_active=True, default_verb='equal')
g.joiners['subdepartment'] = lambda q: q.outerjoin(model.Subdepartment,
model.Subdepartment.uuid == model.Product.subdepartment_uuid)
g.joiners['code'] = lambda q: q.outerjoin(model.ProductCode)
# subdepartment
g.set_joiner('subdepartment', lambda q: q.outerjoin(
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.sorters['subdepartment'] = g.make_sorter(model.Subdepartment.name)
g.joiners['code'] = lambda q: q.outerjoin(model.ProductCode)
# vendor
ProductVendorCost = orm.aliased(model.ProductCost)
@ -296,9 +301,6 @@ class ProductView(MasterView):
g.filters['description'].default_active = True
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.joiners['vendor_code_any'] = join_vendor_code_any
@ -392,7 +394,7 @@ class ProductView(MasterView):
g.set_link('description')
def configure_common_form(self, f):
super(ProductView, self).configure_common_form(f)
super().configure_common_form(f)
product = f.model_instance
# unit_size
@ -687,7 +689,7 @@ class ProductView(MasterView):
return ' '.join(classes)
def get_xlsx_fields(self):
fields = super(ProductView, self).get_xlsx_fields()
fields = super().get_xlsx_fields()
i = fields.index('department_uuid')
fields.insert(i + 1, 'department_number')
@ -734,7 +736,7 @@ class ProductView(MasterView):
return 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):
row['upc'] = row['upc'].pretty()
@ -799,7 +801,7 @@ class ProductView(MasterView):
return row
def download_results_normalize(self, product, fields, **kwargs):
data = super(ProductView, self).download_results_normalize(
data = super().download_results_normalize(
product, fields, **kwargs)
if 'upc' in data:
@ -988,7 +990,7 @@ class ProductView(MasterView):
def objectify(self, form, data=None):
if data is None:
data = form.validated
product = super(ProductView, self).objectify(form, data=data)
product = super().objectify(form, data=data)
# regular_price_amount
if (self.creating or self.editing) and 'regular_price_amount' in form.fields:
@ -1163,7 +1165,7 @@ class ProductView(MasterView):
return jsdata
def template_kwargs_view(self, **kwargs):
kwargs = super(ProductView, self).template_kwargs_view(**kwargs)
kwargs = super().template_kwargs_view(**kwargs)
product = kwargs['instance']
kwargs['image_url'] = self.products_handler.get_image_url(product)
@ -2287,7 +2289,7 @@ class PendingProductView(MasterView):
]
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.filters['status_code'].default_active = True
@ -2299,7 +2301,7 @@ class PendingProductView(MasterView):
g.set_link('description')
def configure_form(self, f):
super(PendingProductView, self).configure_form(f)
super().configure_form(f)
model = self.model
pending = f.model_instance
@ -2417,7 +2419,7 @@ class PendingProductView(MasterView):
if data is None:
data = form.validated
pending = super(PendingProductView, self).objectify(form, data)
pending = super().objectify(form, data)
if not pending.user:
pending.user = self.request.user

View file

@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2022 Lance Edgar
# Copyright © 2010-2023 Lance Edgar
#
# This file is part of Rattail.
#
@ -24,10 +24,6 @@
Views for "true" purchase orders
"""
from __future__ import unicode_literals, absolute_import
import six
from rattail.db import model
from webhelpers2.html import HTML, tags
@ -143,28 +139,35 @@ class PurchaseView(MasterView):
if purchase.date_ordered:
return "{} (ordered {})".format(purchase.vendor, purchase.date_ordered.strftime('%Y-%m-%d'))
return "{} (ordered)".format(purchase.vendor)
return six.text_type(purchase)
return str(purchase)
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)
g.filters['store'] = g.make_filter('store', model.Store.name)
g.sorters['store'] = g.make_sorter(model.Store.name)
# store
g.set_joiner('store', lambda q: q.join(model.Store))
g.set_sorter('store', model.Store.name)
g.set_filter('store', model.Store.name)
g.joiners['vendor'] = lambda q: q.join(model.Vendor)
g.filters['vendor'] = g.make_filter('vendor', model.Vendor.name,
default_active=True, default_verb='contains')
g.sorters['vendor'] = g.make_sorter(model.Vendor.name)
# vendor
g.set_joiner('vendor', lambda q: q.join(model.Vendor))
g.set_sorter('vendor', 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)
g.filters['department'] = g.make_filter('department', model.Department.name)
g.sorters['department'] = g.make_sorter(model.Department.name)
# department
g.set_joiner('department', lambda q: q.join(model.Department))
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)
g.filters['buyer'] = g.make_filter('buyer', model.Person.display_name,
default_active=True, default_verb='contains')
g.sorters['buyer'] = g.make_sorter(model.Person.display_name)
# buyer
g.set_joiner('buyer', lambda q: q.join(model.Employee).join(model.Person))
g.set_sorter('buyer', model.Person.display_name)
g.set_filter('buyer', model.Person.display_name,
default_active=True,
default_verb='contains')
# id
g.set_renderer('id', self.render_id_str)
@ -198,7 +201,7 @@ class PurchaseView(MasterView):
g.set_link('invoice_total')
def configure_form(self, f):
super(PurchaseView, self).configure_form(f)
super().configure_form(f)
# id
f.set_renderer('id', self.render_id_str)
@ -322,7 +325,7 @@ class PurchaseView(MasterView):
.filter(model.PurchaseItem.purchase == purchase)
def configure_row_grid(self, g):
super(PurchaseView, self).configure_row_grid(g)
super().configure_row_grid(g)
g.set_sort_defaults('sequence')
@ -353,7 +356,7 @@ class PurchaseView(MasterView):
g.remove('po_total')
def configure_row_form(self, f):
super(PurchaseView, self).configure_row_form(f)
super().configure_row_form(f)
# quantity fields
f.set_type('case_quantity', 'quantity')

View file

@ -175,9 +175,10 @@ class PurchasingBatchView(BatchMasterView):
g.set_filter('vendor', model.Vendor.name,
default_active=True, default_verb='contains')
g.joiners['department'] = lambda q: q.join(model.Department)
g.filters['department'] = g.make_filter('department', model.Department.name)
g.sorters['department'] = g.make_sorter(model.Department.name)
# department
g.set_joiner('department', lambda q: q.join(model.Department))
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_filter('buyer', model.Person.display_name)
@ -212,7 +213,7 @@ class PurchasingBatchView(BatchMasterView):
# return form
def configure_common_form(self, f):
super(PurchasingBatchView, self).configure_common_form(f)
super().configure_common_form(f)
# po_total
if self.creating:
@ -225,7 +226,7 @@ class PurchasingBatchView(BatchMasterView):
f.set_type('po_total_calculated', 'currency')
def configure_form(self, f):
super(PurchasingBatchView, self).configure_form(f)
super().configure_form(f)
model = self.model
batch = f.model_instance
app = self.get_rattail_app()
@ -598,7 +599,7 @@ class PurchasingBatchView(BatchMasterView):
# return query.options(orm.joinedload(model.PurchaseBatchRow.credits))
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('cases_ordered', 'quantity')
@ -685,7 +686,7 @@ class PurchasingBatchView(BatchMasterView):
return 'notice'
def configure_row_form(self, f):
super(PurchasingBatchView, self).configure_row_form(f)
super().configure_row_form(f)
row = f.model_instance
if self.creating:
batch = self.get_instance()
@ -894,7 +895,7 @@ class PurchasingBatchView(BatchMasterView):
batch.invoice_total -= row.invoice_total
# 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?
# self.handler.refresh_row(row)

View file

@ -233,7 +233,7 @@ class ReceivingBatchView(PurchasingBatchView):
return self.enum.PURCHASE_BATCH_MODE_RECEIVING
def configure_grid(self, g):
super(ReceivingBatchView, self).configure_grid(g)
super().configure_grid(g)
if not self.handler.allow_truck_dump_receiving():
g.remove('truck_dump')
@ -285,14 +285,14 @@ class ReceivingBatchView(PurchasingBatchView):
raise redirect
# 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
# 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
# logic, so as to not interfere with that.
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
self.creating = True
@ -372,14 +372,14 @@ class ReceivingBatchView(PurchasingBatchView):
# first run it through the normal logic, if that doesn't like
# it then we won't either
if not super(ReceivingBatchView, self).row_deletable(row):
if not super().row_deletable(row):
return False
# otherwise let handler decide
return self.batch_handler.is_row_deletable(row)
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():
title = "{} (TRUCK DUMP PARENT)".format(title)
elif batch.is_truck_dump_child():
@ -633,7 +633,7 @@ class ReceivingBatchView(PurchasingBatchView):
return info['display']
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
params.pop('invoice_files', None)
@ -655,7 +655,7 @@ class ReceivingBatchView(PurchasingBatchView):
return 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']
# must pull vendor from URL if it was not in form data
@ -769,7 +769,7 @@ class ReceivingBatchView(PurchasingBatchView):
return True
def template_kwargs_view(self, **kwargs):
kwargs = super(ReceivingBatchView, self).template_kwargs_view(**kwargs)
kwargs = super().template_kwargs_view(**kwargs)
batch = kwargs['instance']
if self.handler.has_purchase_order(batch) and self.handler.has_invoice_file(batch):
@ -810,7 +810,7 @@ class ReceivingBatchView(PurchasingBatchView):
return credits_data
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()
products_handler = app.get_products_handler()
row = kwargs['instance']
@ -847,7 +847,7 @@ class ReceivingBatchView(PurchasingBatchView):
if batch.is_truck_dump_parent():
for child in batch.truck_dump_children:
self.delete_instance(child)
super(ReceivingBatchView, self).delete_instance(batch)
super().delete_instance(batch)
if truck_dump:
self.handler.refresh(truck_dump)
@ -1010,7 +1010,7 @@ class ReceivingBatchView(PurchasingBatchView):
.group_by(model.PurchaseBatchCredit.row_uuid)\
.subquery()
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(
'rattail.batch', 'purchase.receiving.show_ordered_column_in_grid',
@ -1083,7 +1083,7 @@ class ReceivingBatchView(PurchasingBatchView):
})
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:
css_class = '{} catalog_cost_confirmed'.format(css_class or '')
@ -1098,7 +1098,7 @@ class ReceivingBatchView(PurchasingBatchView):
return str(row.product)
if row.upc:
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):
# 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):
# 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')
and self.row_editable(row)):
@ -1616,7 +1616,7 @@ class ReceivingBatchView(PurchasingBatchView):
def validate_row_form(self, form):
# if normal validation fails, stop there
if not super(ReceivingBatchView, self).validate_row_form(form):
if not super().validate_row_form(form):
return False
# 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())
def deserialize(self, *args):
result = super(ReceiveRowForm, self).deserialize(*args)
result = super().deserialize(*args)
if result['mode'] == 'expired' and not result['expiration_date']:
msg = "Expiration date is required for items with 'expired' mode."

View file

@ -84,7 +84,7 @@ class ScheduledShiftView(MasterView, ShiftViewMixin):
g.set_label('employee', "Employee Name")
def configure_form(self, f):
super(ScheduledShiftView, self).configure_form(f)
super().configure_form(f)
f.set_renderer('length', self.render_shift_length)
@ -118,19 +118,22 @@ class WorkedShiftView(MasterView, ShiftViewMixin):
]
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)
g.filters['employee'] = g.make_filter('employee', model.Person.display_name)
g.sorters['employee'] = g.make_sorter(model.Person.display_name)
# employee
g.set_joiner('employee', lambda q: q.join(model.Employee).join(model.Person))
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)
g.filters['store'] = g.make_filter('store', model.Store.name)
g.sorters['store'] = g.make_sorter(model.Store.name)
# store
g.set_joiner('store', lambda q: q.join(model.Store))
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
g.sorters['start_time'] = g.make_sorter(model.WorkedShift.punch_in)
g.sorters['end_time'] = g.make_sorter(model.WorkedShift.punch_out)
g.set_sorter('start_time', model.WorkedShift.punch_in)
g.set_sorter('end_time', model.WorkedShift.punch_out)
# TODO: same goes for these renderers
g.set_type('start_time', 'datetime')
g.set_type('end_time', 'datetime')
@ -150,7 +153,7 @@ class WorkedShiftView(MasterView, ShiftViewMixin):
return "WorkedShift: {}, {}".format(shift.employee, date)
def configure_form(self, f):
super(WorkedShiftView, self).configure_form(f)
super().configure_form(f)
f.set_readonly('employee')
f.set_renderer('employee', self.render_employee)
@ -168,7 +171,7 @@ class WorkedShiftView(MasterView, ShiftViewMixin):
return tags.link_to(text, url)
def get_xlsx_fields(self):
fields = super(WorkedShiftView, self).get_xlsx_fields()
fields = super().get_xlsx_fields()
# add employee name
i = fields.index('employee_uuid')
@ -180,7 +183,7 @@ class WorkedShiftView(MasterView, ShiftViewMixin):
return 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)
if shift.punch_in:

View file

@ -101,8 +101,9 @@ class TempmonProbeView(MasterView):
def configure_grid(self, g):
super().configure_grid(g)
g.joiners['client'] = lambda q: q.join(tempmon.Client)
g.sorters['client'] = g.make_sorter(tempmon.Client.config_key)
# client
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_enum('appliance_type', self.enum.TEMPMON_APPLIANCE_TYPE)

View file

@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2022 Lance Edgar
# Copyright © 2010-2023 Lance Edgar
#
# This file is part of Rattail.
#
@ -24,9 +24,6 @@
Views for tempmon readings
"""
from __future__ import unicode_literals, absolute_import
import six
from sqlalchemy import orm
from rattail_tempmon.db import model as tempmon
@ -70,17 +67,21 @@ class TempmonReadingView(MasterView):
.options(orm.joinedload(tempmon.Reading.client))
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)
g.filters['client_key'] = g.make_filter('client_key', tempmon.Client.config_key)
# client_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)
g.filters['client_host'] = g.make_filter('client_host', tempmon.Client.hostname)
# client_host
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)
g.sorters['probe'] = g.make_sorter(tempmon.Probe.description)
g.filters['probe'] = g.make_filter('probe', tempmon.Probe.description)
# probe
g.set_joiner('probe', lambda q: q.join(tempmon.Probe,
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_type('taken', 'datetime')
@ -98,7 +99,7 @@ class TempmonReadingView(MasterView):
return reading.client.hostname
def configure_form(self, f):
super(TempmonReadingView, self).configure_form(f)
super().configure_form(f)
# client
f.set_renderer('client', self.render_client)
@ -112,7 +113,7 @@ class TempmonReadingView(MasterView):
client = reading.client
if not client:
return ""
text = six.text_type(client)
text = str(client)
url = self.request.route_url('tempmon.clients.view', uuid=client.uuid)
return tags.link_to(text, url)
@ -120,7 +121,7 @@ class TempmonReadingView(MasterView):
probe = reading.probe
if not probe:
return ""
text = six.text_type(probe)
text = str(probe)
url = self.request.route_url('tempmon.probes.view', uuid=probe.uuid)
return tags.link_to(text, url)

View file

@ -24,8 +24,6 @@
Views for views
"""
from __future__ import unicode_literals, absolute_import
import os
import sys
@ -80,7 +78,7 @@ class ModelViewView(MasterView):
return data
def configure_grid(self, g):
super(ModelViewView, self).configure_grid(g)
super().configure_grid(g)
# label
g.sorters['label'] = g.make_simple_sorter('label')
@ -107,7 +105,7 @@ class ModelViewView(MasterView):
return ModelViewSchema()
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()
db_handler = app.get_db_handler()