Misc. improvements for Customer Orders view
This commit is contained in:
parent
e255c35e86
commit
e49e0edc57
3
tailbone/templates/custorders/view.mako
Normal file
3
tailbone/templates/custorders/view.mako
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
## -*- coding: utf-8; -*-
|
||||||
|
<%inherit file="/master/view.mako" />
|
||||||
|
${parent.body()}
|
|
@ -85,8 +85,10 @@ class CustomerOrderItemView(MasterView):
|
||||||
|
|
||||||
form_fields = [
|
form_fields = [
|
||||||
'order',
|
'order',
|
||||||
'sequence',
|
'customer',
|
||||||
'person',
|
'person',
|
||||||
|
'sequence',
|
||||||
|
'_product_key_',
|
||||||
'product',
|
'product',
|
||||||
'pending_product',
|
'pending_product',
|
||||||
'product_brand',
|
'product_brand',
|
||||||
|
@ -97,9 +99,11 @@ class CustomerOrderItemView(MasterView):
|
||||||
'case_quantity',
|
'case_quantity',
|
||||||
'unit_price',
|
'unit_price',
|
||||||
'total_price',
|
'total_price',
|
||||||
|
'special_order',
|
||||||
'price_needs_confirmation',
|
'price_needs_confirmation',
|
||||||
'paid_amount',
|
'paid_amount',
|
||||||
'status_code',
|
'status_code',
|
||||||
|
'flagged',
|
||||||
'notes',
|
'notes',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -167,13 +171,30 @@ class CustomerOrderItemView(MasterView):
|
||||||
return HTML.tag('span', title=item.status_text, c=[text])
|
return HTML.tag('span', title=item.status_text, c=[text])
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
def get_batch_handler(self):
|
||||||
|
app = self.get_rattail_app()
|
||||||
|
return app.get_batch_handler(
|
||||||
|
'custorder',
|
||||||
|
default='rattail.batch.custorder:CustomerOrderBatchHandler')
|
||||||
|
|
||||||
def configure_form(self, f):
|
def configure_form(self, f):
|
||||||
super(CustomerOrderItemView, self).configure_form(f)
|
super().configure_form(f)
|
||||||
item = f.model_instance
|
item = f.model_instance
|
||||||
|
|
||||||
# order
|
# order
|
||||||
f.set_renderer('order', self.render_order)
|
f.set_renderer('order', self.render_order)
|
||||||
|
|
||||||
|
# contact
|
||||||
|
batch_handler = self.get_batch_handler()
|
||||||
|
if batch_handler.new_order_requires_customer():
|
||||||
|
f.remove('person')
|
||||||
|
else:
|
||||||
|
f.remove('customer')
|
||||||
|
|
||||||
|
# product key
|
||||||
|
key = self.get_product_key_field()
|
||||||
|
f.set_renderer(key, lambda item, field: getattr(item, f'product_{key}'))
|
||||||
|
|
||||||
# (pending) product
|
# (pending) product
|
||||||
f.set_renderer('product', self.render_product)
|
f.set_renderer('product', self.render_product)
|
||||||
f.set_renderer('pending_product', self.render_pending_product)
|
f.set_renderer('pending_product', self.render_pending_product)
|
||||||
|
@ -192,13 +213,6 @@ class CustomerOrderItemView(MasterView):
|
||||||
f.set_renderer('product_size', self.highlight_pending_field)
|
f.set_renderer('product_size', self.highlight_pending_field)
|
||||||
f.set_renderer('case_quantity', self.highlight_pending_field_quantity)
|
f.set_renderer('case_quantity', self.highlight_pending_field_quantity)
|
||||||
|
|
||||||
'unit_price',
|
|
||||||
'total_price',
|
|
||||||
'price_needs_confirmation',
|
|
||||||
'paid_amount',
|
|
||||||
'status_code',
|
|
||||||
'notes',
|
|
||||||
|
|
||||||
# quantity fields
|
# quantity fields
|
||||||
f.set_type('cases_ordered', 'quantity')
|
f.set_type('cases_ordered', 'quantity')
|
||||||
f.set_type('units_ordered', 'quantity')
|
f.set_type('units_ordered', 'quantity')
|
||||||
|
|
|
@ -52,7 +52,7 @@ class CustomerOrderView(MasterView):
|
||||||
configurable = True
|
configurable = True
|
||||||
|
|
||||||
labels = {
|
labels = {
|
||||||
'id': "ID",
|
'id': "Order ID",
|
||||||
'status_code': "Status",
|
'status_code': "Status",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,8 +60,9 @@ class CustomerOrderView(MasterView):
|
||||||
'id',
|
'id',
|
||||||
'customer',
|
'customer',
|
||||||
'person',
|
'person',
|
||||||
'created',
|
|
||||||
'status_code',
|
'status_code',
|
||||||
|
'created',
|
||||||
|
'created_by',
|
||||||
]
|
]
|
||||||
|
|
||||||
form_fields = [
|
form_fields = [
|
||||||
|
@ -88,14 +89,17 @@ class CustomerOrderView(MasterView):
|
||||||
|
|
||||||
row_grid_columns = [
|
row_grid_columns = [
|
||||||
'sequence',
|
'sequence',
|
||||||
|
'_product_key_',
|
||||||
'product_brand',
|
'product_brand',
|
||||||
'product_description',
|
'product_description',
|
||||||
'product_size',
|
'product_size',
|
||||||
'order_quantity',
|
'order_quantity',
|
||||||
'order_uom',
|
'order_uom',
|
||||||
'case_quantity',
|
'case_quantity',
|
||||||
|
'department_name',
|
||||||
'total_price',
|
'total_price',
|
||||||
'status_code',
|
'status_code',
|
||||||
|
'flagged',
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, request):
|
def __init__(self, request):
|
||||||
|
@ -107,11 +111,19 @@ class CustomerOrderView(MasterView):
|
||||||
.options(orm.joinedload(model.CustomerOrder.customer))
|
.options(orm.joinedload(model.CustomerOrder.customer))
|
||||||
|
|
||||||
def configure_grid(self, g):
|
def configure_grid(self, g):
|
||||||
super(CustomerOrderView, self).configure_grid(g)
|
super().configure_grid(g)
|
||||||
|
|
||||||
|
# id
|
||||||
|
g.set_link('id')
|
||||||
|
g.filters['id'].default_active = True
|
||||||
|
g.filters['id'].default_verb = 'equal'
|
||||||
|
|
||||||
|
# import ipdb; ipdb.set_trace()
|
||||||
|
|
||||||
# customer or person
|
# customer or person
|
||||||
if self.batch_handler.new_order_requires_customer():
|
if self.batch_handler.new_order_requires_customer():
|
||||||
g.remove('person')
|
g.remove('person')
|
||||||
|
g.set_link('customer')
|
||||||
g.set_joiner('customer', lambda q: q.outerjoin(model.Customer))
|
g.set_joiner('customer', lambda q: q.outerjoin(model.Customer))
|
||||||
g.set_sorter('customer', model.Customer.name)
|
g.set_sorter('customer', model.Customer.name)
|
||||||
g.filters['customer'] = g.make_filter('customer', model.Customer.name,
|
g.filters['customer'] = g.make_filter('customer', model.Customer.name,
|
||||||
|
@ -120,6 +132,7 @@ class CustomerOrderView(MasterView):
|
||||||
default_verb='contains')
|
default_verb='contains')
|
||||||
else:
|
else:
|
||||||
g.remove('customer')
|
g.remove('customer')
|
||||||
|
g.set_link('person')
|
||||||
g.set_joiner('person', lambda q: q.outerjoin(model.Person))
|
g.set_joiner('person', lambda q: q.outerjoin(model.Person))
|
||||||
g.set_sorter('person', model.Person.display_name)
|
g.set_sorter('person', model.Person.display_name)
|
||||||
g.filters['person'] = g.make_filter('person', model.Person.display_name,
|
g.filters['person'] = g.make_filter('person', model.Person.display_name,
|
||||||
|
@ -127,13 +140,14 @@ class CustomerOrderView(MasterView):
|
||||||
default_active=True,
|
default_active=True,
|
||||||
default_verb='contains')
|
default_verb='contains')
|
||||||
|
|
||||||
|
# status_code
|
||||||
g.set_enum('status_code', self.enum.CUSTORDER_STATUS)
|
g.set_enum('status_code', self.enum.CUSTORDER_STATUS)
|
||||||
|
|
||||||
|
# created
|
||||||
g.set_sort_defaults('created', 'desc')
|
g.set_sort_defaults('created', 'desc')
|
||||||
|
|
||||||
g.set_link('id')
|
def get_instance_title(self, order):
|
||||||
g.set_link('customer')
|
return f"#{order.id} for {order.customer or order.person}"
|
||||||
g.set_link('person')
|
|
||||||
|
|
||||||
def configure_form(self, f):
|
def configure_form(self, f):
|
||||||
super(CustomerOrderView, self).configure_form(f)
|
super(CustomerOrderView, self).configure_form(f)
|
||||||
|
@ -232,6 +246,10 @@ class CustomerOrderView(MasterView):
|
||||||
'custorder',
|
'custorder',
|
||||||
default='rattail.batch.custorder:CustomerOrderBatchHandler')
|
default='rattail.batch.custorder:CustomerOrderBatchHandler')
|
||||||
|
|
||||||
|
# product key
|
||||||
|
key = self.get_product_key_field()
|
||||||
|
g.set_renderer(key, lambda item, field: getattr(item, f'product_{key}'))
|
||||||
|
|
||||||
g.set_type('case_quantity', 'quantity')
|
g.set_type('case_quantity', 'quantity')
|
||||||
g.set_type('order_quantity', 'quantity')
|
g.set_type('order_quantity', 'quantity')
|
||||||
g.set_type('cases_ordered', 'quantity')
|
g.set_type('cases_ordered', 'quantity')
|
||||||
|
@ -962,6 +980,61 @@ class CustomerOrderView(MasterView):
|
||||||
def execute_new_order_batch(self, batch, data):
|
def execute_new_order_batch(self, batch, data):
|
||||||
return self.batch_handler.do_execute(batch, self.request.user)
|
return self.batch_handler.do_execute(batch, self.request.user)
|
||||||
|
|
||||||
|
def fetch_order_data(self):
|
||||||
|
app = self.get_rattail_app()
|
||||||
|
model = self.model
|
||||||
|
|
||||||
|
order = None
|
||||||
|
uuid = self.request.GET.get('uuid')
|
||||||
|
if uuid:
|
||||||
|
order = self.Session.get(model.CustomerOrder, uuid)
|
||||||
|
if not order:
|
||||||
|
# raise self.notfound()
|
||||||
|
return {'error': "Customer order not found"}
|
||||||
|
|
||||||
|
address = None
|
||||||
|
if self.batch_handler.new_order_requires_customer():
|
||||||
|
contact = order.customer
|
||||||
|
else:
|
||||||
|
contact = order.person
|
||||||
|
if contact and contact.address:
|
||||||
|
a = contact.address
|
||||||
|
address = {
|
||||||
|
'street_1': a.street,
|
||||||
|
'street_2': a.street2,
|
||||||
|
'city': a.city,
|
||||||
|
'state': a.state,
|
||||||
|
'zip': a.zipcode,
|
||||||
|
}
|
||||||
|
|
||||||
|
# gather all the order items
|
||||||
|
items = []
|
||||||
|
grand_total = 0
|
||||||
|
for item in order.items:
|
||||||
|
item_data = {
|
||||||
|
'uuid': item.uuid,
|
||||||
|
'special_order': False, # TODO
|
||||||
|
'product_description': item.product_description,
|
||||||
|
'order_quantity': app.render_quantity(item.order_quantity),
|
||||||
|
'department': item.department_name,
|
||||||
|
'price': app.render_currency(item.unit_price),
|
||||||
|
'total': app.render_currency(item.total_price),
|
||||||
|
}
|
||||||
|
items.append(item_data)
|
||||||
|
grand_total += item.total_price
|
||||||
|
|
||||||
|
return {
|
||||||
|
'uuid': order.uuid,
|
||||||
|
'id': order.id,
|
||||||
|
'created_display': app.render_datetime(app.localtime(order.created, from_utc=True)),
|
||||||
|
'contact_display': str(contact or ''),
|
||||||
|
'address': address,
|
||||||
|
'phone_display': str(contact.phone) if contact and contact.phone else "",
|
||||||
|
'email_display': str(contact.email) if contact and contact.email else "",
|
||||||
|
'items': items,
|
||||||
|
'grand_total_display': app.render_currency(grand_total),
|
||||||
|
}
|
||||||
|
|
||||||
def configure_get_simple_settings(self):
|
def configure_get_simple_settings(self):
|
||||||
return [
|
return [
|
||||||
|
|
||||||
|
@ -1048,6 +1121,14 @@ class CustomerOrderView(MasterView):
|
||||||
renderer='json',
|
renderer='json',
|
||||||
permission='products.list')
|
permission='products.list')
|
||||||
|
|
||||||
|
# fetch order data
|
||||||
|
config.add_route(f'{route_prefix}.fetch_order_data',
|
||||||
|
f'{url_prefix}/fetch-order-data')
|
||||||
|
config.add_view(cls, attr='fetch_order_data',
|
||||||
|
route_name=f'{route_prefix}.fetch_order_data',
|
||||||
|
renderer='json',
|
||||||
|
permission=f'{permission_prefix}.view')
|
||||||
|
|
||||||
|
|
||||||
# TODO: deprecate / remove this
|
# TODO: deprecate / remove this
|
||||||
CustomerOrdersView = CustomerOrderView
|
CustomerOrdersView = CustomerOrderView
|
||||||
|
|
Loading…
Reference in a new issue