Misc. improvements for customer order views

This commit is contained in:
Lance Edgar 2021-09-21 13:49:51 -05:00
parent 8af247a7f6
commit d0a7a241b4
4 changed files with 143 additions and 23 deletions

View file

@ -30,9 +30,10 @@
<div class="buttons"> <div class="buttons">
<b-button type="is-primary" <b-button type="is-primary"
@click="submitOrder()" @click="submitOrder()"
:disabled="submittingOrder"
icon-pack="fas" icon-pack="fas"
icon-left="fas fa-upload"> icon-left="fas fa-upload">
Submit this Order {{ submitOrderButtonText }}
</b-button> </b-button>
<b-button @click="startOverEntirely()" <b-button @click="startOverEntirely()"
icon-pack="fas" icon-pack="fas"
@ -176,12 +177,14 @@
<div class="panel-block"> <div class="panel-block">
<div> <div>
<b-button type="is-primary" <div class="buttons">
icon-pack="fas" <b-button type="is-primary"
icon-left="fas fa-plus" icon-pack="fas"
@click="showAddItemDialog()"> icon-left="fas fa-plus"
Add Item @click="showAddItemDialog()">
</b-button> Add Item
</b-button>
</div>
<b-modal :active.sync="showingItemDialog"> <b-modal :active.sync="showingItemDialog">
<div class="card"> <div class="card">
<div class="card-content"> <div class="card-content">
@ -288,8 +291,8 @@
</div> </div>
</b-modal> </b-modal>
<b-table <b-table v-if="items.length"
:data="items"> :data="items">
<template slot-scope="props"> <template slot-scope="props">
<b-table-column field="product_upc_pretty" label="UPC"> <b-table-column field="product_upc_pretty" label="UPC">
@ -403,6 +406,8 @@
## TODO: should find a better way to handle CSRF token ## TODO: should find a better way to handle CSRF token
csrftoken: ${json.dumps(request.session.get_csrf_token() or request.session.new_csrf_token())|n}, csrftoken: ${json.dumps(request.session.get_csrf_token() or request.session.new_csrf_token())|n},
submittingOrder: false,
} }
}, },
computed: { computed: {
@ -515,6 +520,13 @@
itemDialogSaveButtonText() { itemDialogSaveButtonText() {
return this.editingItem ? "Update Item" : "Add Item" return this.editingItem ? "Update Item" : "Add Item"
}, },
submitOrderButtonText() {
if (this.submittingOrder) {
return "Working, please wait..."
}
return "Submit this Order"
},
}, },
mounted() { mounted() {
if (this.customerStatusType) { if (this.customerStatusType) {
@ -607,9 +619,12 @@
}, },
submitOrder() { submitOrder() {
this.submittingOrder = true
let params = { let params = {
action: 'submit_new_order', action: 'submit_new_order',
} }
this.submitBatchData(params, response => { this.submitBatchData(params, response => {
if (response.data.error) { if (response.data.error) {
this.$buefy.toast.open({ this.$buefy.toast.open({
@ -617,6 +632,7 @@
type: 'is-danger', type: 'is-danger',
duration: 2000, // 2 seconds duration: 2000, // 2 seconds
}) })
this.submittingOrder = false
} else { } else {
if (response.data.next_url) { if (response.data.next_url) {
location.href = response.data.next_url location.href = response.data.next_url

View file

@ -84,6 +84,7 @@ class CustomerOrderBatchView(BatchMasterView):
'product_size', 'product_size',
'order_quantity', 'order_quantity',
'order_uom', 'order_uom',
'case_quantity',
'total_price', 'total_price',
'status_code', 'status_code',
] ]

View file

@ -51,14 +51,20 @@ class CustomerOrderItemView(MasterView):
editable = False editable = False
deletable = False deletable = False
labels = {
'order_id': "Order ID",
'order_uom': "Order UOM",
}
grid_columns = [ grid_columns = [
'order_id',
'person', 'person',
'product_brand', 'product_brand',
'product_description', 'product_description',
'product_size', 'product_size',
'order_quantity',
'order_uom',
'case_quantity', 'case_quantity',
'cases_ordered',
'units_ordered',
'order_created', 'order_created',
'status_code', 'status_code',
] ]
@ -79,14 +85,16 @@ class CustomerOrderItemView(MasterView):
] ]
form_fields = [ form_fields = [
'order',
'sequence',
'person', 'person',
'product', 'product',
'product_brand', 'product_brand',
'product_description', 'product_description',
'product_size', 'product_size',
'order_quantity',
'order_uom',
'case_quantity', 'case_quantity',
'cases_ordered',
'units_ordered',
'unit_price', 'unit_price',
'total_price', 'total_price',
'paid_amount', 'paid_amount',
@ -102,6 +110,8 @@ class CustomerOrderItemView(MasterView):
def configure_grid(self, g): def configure_grid(self, g):
super(CustomerOrderItemView, self).configure_grid(g) super(CustomerOrderItemView, self).configure_grid(g)
g.set_renderer('order_id', self.render_order_id)
g.set_joiner('person', lambda q: q.outerjoin(model.Person)) g.set_joiner('person', lambda q: q.outerjoin(model.Person))
g.filters['person'] = g.make_filter('person', model.Person.display_name, g.filters['person'] = g.make_filter('person', model.Person.display_name,
@ -116,18 +126,34 @@ class CustomerOrderItemView(MasterView):
g.set_type('cases_ordered', 'quantity') g.set_type('cases_ordered', 'quantity')
g.set_type('units_ordered', 'quantity') g.set_type('units_ordered', 'quantity')
g.set_type('total_price', 'currency') g.set_type('total_price', 'currency')
g.set_type('order_quantity', 'quantity')
g.set_renderer('person', self.render_person) g.set_enum('order_uom', self.enum.UNIT_OF_MEASURE)
g.set_renderer('person', self.render_person_text)
g.set_renderer('order_created', self.render_order_created) g.set_renderer('order_created', self.render_order_created)
g.set_enum('status_code', self.enum.CUSTORDER_ITEM_STATUS)
g.set_label('person', "Person Name") g.set_label('person', "Person Name")
g.set_label('product_brand', "Brand") g.set_label('product_brand', "Brand")
g.set_label('product_description', "Description") g.set_label('product_description', "Description")
g.set_label('product_size', "Size") g.set_label('product_size', "Size")
g.set_label('status_code', "Status") g.set_label('status_code', "Status")
def render_person(self, item, column): g.set_link('order_id')
return item.order.person g.set_link('person')
g.set_link('product_brand')
g.set_link('product_description')
def render_order_id(self, item, field):
return item.order.id
def render_person_text(self, item, field):
person = item.order.person
if person:
text = six.text_type(person)
return text
def render_order_created(self, item, column): def render_order_created(self, item, column):
value = localtime(self.rattail_config, item.order.created, from_utc=True) value = localtime(self.rattail_config, item.order.created, from_utc=True)
@ -149,6 +175,9 @@ class CustomerOrderItemView(MasterView):
f.set_type('case_quantity', 'quantity') f.set_type('case_quantity', 'quantity')
f.set_type('cases_ordered', 'quantity') f.set_type('cases_ordered', 'quantity')
f.set_type('units_ordered', 'quantity') f.set_type('units_ordered', 'quantity')
f.set_type('order_quantity', 'quantity')
f.set_enum('order_uom', self.enum.UNIT_OF_MEASURE)
# currency fields # currency fields
f.set_type('unit_price', 'currency') f.set_type('unit_price', 'currency')
@ -158,6 +187,8 @@ class CustomerOrderItemView(MasterView):
# person # person
f.set_renderer('person', self.render_person) f.set_renderer('person', self.render_person)
f.set_enum('status_code', self.enum.CUSTORDER_ITEM_STATUS)
# label overrides # label overrides
f.set_label('status_code', "Status") f.set_label('status_code', "Status")
@ -169,6 +200,13 @@ class CustomerOrderItemView(MasterView):
url = self.request.route_url('custorders.view', uuid=order.uuid) url = self.request.route_url('custorders.view', uuid=order.uuid)
return tags.link_to(text, url) return tags.link_to(text, url)
def render_person(self, item, field):
person = item.order.person
if person:
text = six.text_type(person)
url = self.request.route_url('people.view', uuid=person.uuid)
return tags.link_to(text, url)
def get_row_data(self, item): def get_row_data(self, item):
return self.Session.query(model.CustomerOrderItemEvent)\ return self.Session.query(model.CustomerOrderItemEvent)\
.filter(model.CustomerOrderItemEvent.item == item)\ .filter(model.CustomerOrderItemEvent.item == item)\

View file

@ -49,7 +49,6 @@ class CustomerOrderView(MasterView):
model_class = model.CustomerOrder model_class = model.CustomerOrder
route_prefix = 'custorders' route_prefix = 'custorders'
editable = False editable = False
deletable = False
grid_columns = [ grid_columns = [
'id', 'id',
@ -69,6 +68,26 @@ class CustomerOrderView(MasterView):
'status_code', 'status_code',
] ]
has_rows = True
model_row_class = model.CustomerOrderItem
rows_viewable = False
row_labels = {
'order_uom': "Order UOM",
}
row_grid_columns = [
'sequence',
'product_brand',
'product_description',
'product_size',
'order_quantity',
'order_uom',
'case_quantity',
'total_price',
'status_code',
]
def query(self, session): def query(self, session):
return session.query(model.CustomerOrder)\ return session.query(model.CustomerOrder)\
.options(orm.joinedload(model.CustomerOrder.customer)) .options(orm.joinedload(model.CustomerOrder.customer))
@ -99,22 +118,24 @@ class CustomerOrderView(MasterView):
g.set_label('status_code', "Status") g.set_label('status_code', "Status")
g.set_label('id', "ID") g.set_label('id', "ID")
g.set_link('id')
g.set_link('customer')
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)
# id
f.set_readonly('id') f.set_readonly('id')
f.set_label('id', "ID") f.set_label('id', "ID")
# person f.set_renderer('customer', self.render_customer)
f.set_renderer('person', self.render_person) f.set_renderer('person', self.render_person)
# created f.set_enum('status_code', self.enum.CUSTORDER_STATUS)
f.set_readonly('created')
# label overrides
f.set_label('status_code', "Status") f.set_label('status_code', "Status")
f.set_readonly('created')
def render_person(self, order, field): def render_person(self, order, field):
person = order.person person = order.person
if not person: if not person:
@ -123,6 +144,50 @@ class CustomerOrderView(MasterView):
url = self.request.route_url('people.view', uuid=person.uuid) url = self.request.route_url('people.view', uuid=person.uuid)
return tags.link_to(text, url) return tags.link_to(text, url)
def get_row_data(self, order):
return self.Session.query(model.CustomerOrderItem)\
.filter(model.CustomerOrderItem.order == order)
def get_parent(self, item):
return item.order
def make_row_grid_kwargs(self, **kwargs):
kwargs = super(CustomerOrderView, self).make_row_grid_kwargs(**kwargs)
assert not kwargs['main_actions']
kwargs['main_actions'].append(
self.make_action('view', icon='eye', url=self.row_view_action_url))
return kwargs
def row_view_action_url(self, item, i):
if self.request.has_perm('custorders.items.view'):
return self.request.route_url('custorders.items.view', uuid=item.uuid)
def configure_row_grid(self, g):
super(CustomerOrderView, self).configure_row_grid(g)
g.set_type('case_quantity', 'quantity')
g.set_type('order_quantity', 'quantity')
g.set_type('cases_ordered', 'quantity')
g.set_type('units_ordered', 'quantity')
g.set_type('total_price', 'currency')
g.set_enum('order_uom', self.enum.UNIT_OF_MEASURE)
g.set_enum('status_code', self.enum.CUSTORDER_ITEM_STATUS)
g.set_label('sequence', "Seq.")
g.filters['sequence'].label = "Sequence"
g.set_label('product_brand', "Brand")
g.set_label('product_description', "Description")
g.set_label('product_size', "Size")
g.set_label('status_code', "Status")
g.set_sort_defaults('sequence')
g.set_link('product_brand')
g.set_link('product_description')
def get_batch_handler(self): def get_batch_handler(self):
return get_batch_handler( return get_batch_handler(
self.rattail_config, 'custorder', self.rattail_config, 'custorder',