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 = [
|
||||
'order',
|
||||
'sequence',
|
||||
'customer',
|
||||
'person',
|
||||
'sequence',
|
||||
'_product_key_',
|
||||
'product',
|
||||
'pending_product',
|
||||
'product_brand',
|
||||
|
@ -97,9 +99,11 @@ class CustomerOrderItemView(MasterView):
|
|||
'case_quantity',
|
||||
'unit_price',
|
||||
'total_price',
|
||||
'special_order',
|
||||
'price_needs_confirmation',
|
||||
'paid_amount',
|
||||
'status_code',
|
||||
'flagged',
|
||||
'notes',
|
||||
]
|
||||
|
||||
|
@ -167,13 +171,30 @@ class CustomerOrderItemView(MasterView):
|
|||
return HTML.tag('span', title=item.status_text, c=[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):
|
||||
super(CustomerOrderItemView, self).configure_form(f)
|
||||
super().configure_form(f)
|
||||
item = f.model_instance
|
||||
|
||||
# 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
|
||||
f.set_renderer('product', self.render_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('case_quantity', self.highlight_pending_field_quantity)
|
||||
|
||||
'unit_price',
|
||||
'total_price',
|
||||
'price_needs_confirmation',
|
||||
'paid_amount',
|
||||
'status_code',
|
||||
'notes',
|
||||
|
||||
# quantity fields
|
||||
f.set_type('cases_ordered', 'quantity')
|
||||
f.set_type('units_ordered', 'quantity')
|
||||
|
|
|
@ -52,7 +52,7 @@ class CustomerOrderView(MasterView):
|
|||
configurable = True
|
||||
|
||||
labels = {
|
||||
'id': "ID",
|
||||
'id': "Order ID",
|
||||
'status_code': "Status",
|
||||
}
|
||||
|
||||
|
@ -60,8 +60,9 @@ class CustomerOrderView(MasterView):
|
|||
'id',
|
||||
'customer',
|
||||
'person',
|
||||
'created',
|
||||
'status_code',
|
||||
'created',
|
||||
'created_by',
|
||||
]
|
||||
|
||||
form_fields = [
|
||||
|
@ -88,14 +89,17 @@ class CustomerOrderView(MasterView):
|
|||
|
||||
row_grid_columns = [
|
||||
'sequence',
|
||||
'_product_key_',
|
||||
'product_brand',
|
||||
'product_description',
|
||||
'product_size',
|
||||
'order_quantity',
|
||||
'order_uom',
|
||||
'case_quantity',
|
||||
'department_name',
|
||||
'total_price',
|
||||
'status_code',
|
||||
'flagged',
|
||||
]
|
||||
|
||||
def __init__(self, request):
|
||||
|
@ -107,11 +111,19 @@ class CustomerOrderView(MasterView):
|
|||
.options(orm.joinedload(model.CustomerOrder.customer))
|
||||
|
||||
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
|
||||
if self.batch_handler.new_order_requires_customer():
|
||||
g.remove('person')
|
||||
g.set_link('customer')
|
||||
g.set_joiner('customer', lambda q: q.outerjoin(model.Customer))
|
||||
g.set_sorter('customer', model.Customer.name)
|
||||
g.filters['customer'] = g.make_filter('customer', model.Customer.name,
|
||||
|
@ -120,6 +132,7 @@ class CustomerOrderView(MasterView):
|
|||
default_verb='contains')
|
||||
else:
|
||||
g.remove('customer')
|
||||
g.set_link('person')
|
||||
g.set_joiner('person', lambda q: q.outerjoin(model.Person))
|
||||
g.set_sorter('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_verb='contains')
|
||||
|
||||
# status_code
|
||||
g.set_enum('status_code', self.enum.CUSTORDER_STATUS)
|
||||
|
||||
# created
|
||||
g.set_sort_defaults('created', 'desc')
|
||||
|
||||
g.set_link('id')
|
||||
g.set_link('customer')
|
||||
g.set_link('person')
|
||||
def get_instance_title(self, order):
|
||||
return f"#{order.id} for {order.customer or order.person}"
|
||||
|
||||
def configure_form(self, f):
|
||||
super(CustomerOrderView, self).configure_form(f)
|
||||
|
@ -232,6 +246,10 @@ class CustomerOrderView(MasterView):
|
|||
'custorder',
|
||||
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('order_quantity', 'quantity')
|
||||
g.set_type('cases_ordered', 'quantity')
|
||||
|
@ -962,6 +980,61 @@ class CustomerOrderView(MasterView):
|
|||
def execute_new_order_batch(self, batch, data):
|
||||
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):
|
||||
return [
|
||||
|
||||
|
@ -1048,6 +1121,14 @@ class CustomerOrderView(MasterView):
|
|||
renderer='json',
|
||||
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
|
||||
CustomerOrdersView = CustomerOrderView
|
||||
|
|
Loading…
Reference in a new issue