Add support for "mark received" when viewing custorder item
This commit is contained in:
parent
ddb8e3656f
commit
67ec6f7773
|
@ -9,6 +9,7 @@
|
||||||
% endif
|
% endif
|
||||||
% if master.has_perm('change_status'):
|
% if master.has_perm('change_status'):
|
||||||
@change-status="showChangeStatus"
|
@change-status="showChangeStatus"
|
||||||
|
@mark-received="markReceivedInit"
|
||||||
% endif
|
% endif
|
||||||
% if master.has_perm('add_note'):
|
% if master.has_perm('add_note'):
|
||||||
@add-note="showAddNote"
|
@add-note="showAddNote"
|
||||||
|
@ -61,6 +62,67 @@
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
% if master.has_perm('change_status'):
|
% if master.has_perm('change_status'):
|
||||||
|
|
||||||
|
## TODO ##
|
||||||
|
<% contact = instance.order.person %>
|
||||||
|
<% email_address = rattail_app.get_contact_email_address(contact) %>
|
||||||
|
|
||||||
|
<b-modal has-modal-card
|
||||||
|
:active.sync="markReceivedShowDialog">
|
||||||
|
<div class="modal-card">
|
||||||
|
|
||||||
|
<header class="modal-card-head">
|
||||||
|
<p class="modal-card-title">Mark Received</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section class="modal-card-body">
|
||||||
|
<p class="block">
|
||||||
|
new status will be:
|
||||||
|
<span class="has-text-weight-bold">
|
||||||
|
% if email_address:
|
||||||
|
${enum.CUSTORDER_ITEM_STATUS[enum.CUSTORDER_ITEM_STATUS_CONTACTED]}
|
||||||
|
% else:
|
||||||
|
${enum.CUSTORDER_ITEM_STATUS[enum.CUSTORDER_ITEM_STATUS_RECEIVED]}
|
||||||
|
% endif
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
% if email_address:
|
||||||
|
<p class="block">
|
||||||
|
This customer has an email address on file, which
|
||||||
|
means that we will automatically send them an email
|
||||||
|
notification, and advance the Order Product status to
|
||||||
|
"${enum.CUSTORDER_ITEM_STATUS[enum.CUSTORDER_ITEM_STATUS_CONTACTED]}".
|
||||||
|
</p>
|
||||||
|
% else:
|
||||||
|
<p class="block">
|
||||||
|
This customer does *not* have an email address on
|
||||||
|
file, which means that we will *not* automatically
|
||||||
|
send them an email notification, so the Order
|
||||||
|
Product status will become
|
||||||
|
"${enum.CUSTORDER_ITEM_STATUS[enum.CUSTORDER_ITEM_STATUS_RECEIVED]}".
|
||||||
|
</p>
|
||||||
|
% endif
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<footer class="modal-card-foot">
|
||||||
|
<b-button type="is-primary"
|
||||||
|
@click="markReceivedSubmit()"
|
||||||
|
:disabled="markReceivedSubmitting"
|
||||||
|
icon-pack="fas"
|
||||||
|
icon-left="check">
|
||||||
|
{{ markReceivedSubmitting ? "Working, please wait..." : "Mark Received" }}
|
||||||
|
</b-button>
|
||||||
|
<b-button @click="markReceivedShowDialog = false">
|
||||||
|
Cancel
|
||||||
|
</b-button>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</b-modal>
|
||||||
|
${h.form(url(f'{route_prefix}.mark_received'), ref='markReceivedForm')}
|
||||||
|
${h.csrf_token(request)}
|
||||||
|
${h.hidden('order_item_uuids', value=instance.uuid)}
|
||||||
|
${h.end_form()}
|
||||||
|
|
||||||
<b-modal :active.sync="showChangeStatusDialog">
|
<b-modal :active.sync="showChangeStatusDialog">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
|
@ -106,21 +168,30 @@
|
||||||
:checked-rows.sync="changeStatusCheckedRows"
|
:checked-rows.sync="changeStatusCheckedRows"
|
||||||
narrowed
|
narrowed
|
||||||
class="is-size-7">
|
class="is-size-7">
|
||||||
<b-table-column field="product_brand" label="Brand"
|
<b-table-column field="product_key" label="${rattail_app.get_product_key_label()}"
|
||||||
v-slot="props">
|
v-slot="props">
|
||||||
<span v-html="props.row.product_brand"></span>
|
{{ props.row.product_key }}
|
||||||
</b-table-column>
|
</b-table-column>
|
||||||
<b-table-column field="product_description" label="Product"
|
<b-table-column field="brand_name" label="Brand"
|
||||||
|
v-slot="props">
|
||||||
|
<span v-html="props.row.brand_name"></span>
|
||||||
|
</b-table-column>
|
||||||
|
<b-table-column field="product_description" label="Description"
|
||||||
v-slot="props">
|
v-slot="props">
|
||||||
<span v-html="props.row.product_description"></span>
|
<span v-html="props.row.product_description"></span>
|
||||||
</b-table-column>
|
</b-table-column>
|
||||||
<!-- <b-table-column field="quantity" label="Quantity"> -->
|
<b-table-column field="product_size" label="Size"
|
||||||
<!-- <span v-html="props.row.quantity"></span> -->
|
v-slot="props">
|
||||||
<!-- </b-table-column> -->
|
<span v-html="props.row.product_size"></span>
|
||||||
|
</b-table-column>
|
||||||
<b-table-column field="product_case_quantity" label="cPack"
|
<b-table-column field="product_case_quantity" label="cPack"
|
||||||
v-slot="props">
|
v-slot="props">
|
||||||
<span v-html="props.row.product_case_quantity"></span>
|
<span v-html="props.row.product_case_quantity"></span>
|
||||||
</b-table-column>
|
</b-table-column>
|
||||||
|
<b-table-column field="department_name" label="Department"
|
||||||
|
v-slot="props">
|
||||||
|
<span v-html="props.row.department_name"></span>
|
||||||
|
</b-table-column>
|
||||||
<b-table-column field="order_quantity" label="oQty"
|
<b-table-column field="order_quantity" label="oQty"
|
||||||
v-slot="props">
|
v-slot="props">
|
||||||
<span v-html="props.row.order_quantity"></span>
|
<span v-html="props.row.order_quantity"></span>
|
||||||
|
@ -129,33 +200,18 @@
|
||||||
v-slot="props">
|
v-slot="props">
|
||||||
<span v-html="props.row.order_uom"></span>
|
<span v-html="props.row.order_uom"></span>
|
||||||
</b-table-column>
|
</b-table-column>
|
||||||
<b-table-column field="department_name" label="Department"
|
|
||||||
v-slot="props">
|
|
||||||
<span v-html="props.row.department_name"></span>
|
|
||||||
</b-table-column>
|
|
||||||
<b-table-column field="product_barcode" label="Product Barcode"
|
|
||||||
v-slot="props">
|
|
||||||
<span v-html="props.row.product_barcode"></span>
|
|
||||||
</b-table-column>
|
|
||||||
<b-table-column field="unit_price" label="Unit $"
|
|
||||||
v-slot="props">
|
|
||||||
<span v-html="props.row.unit_price"></span>
|
|
||||||
</b-table-column>
|
|
||||||
<b-table-column field="total_price" label="Total $"
|
<b-table-column field="total_price" label="Total $"
|
||||||
v-slot="props">
|
v-slot="props">
|
||||||
<span v-html="props.row.total_price"></span>
|
<span v-html="props.row.total_price"></span>
|
||||||
</b-table-column>
|
</b-table-column>
|
||||||
<b-table-column field="order_date" label="Order Date"
|
|
||||||
v-slot="props">
|
|
||||||
<span v-html="props.row.order_date"></span>
|
|
||||||
</b-table-column>
|
|
||||||
<b-table-column field="status_code" label="Status"
|
<b-table-column field="status_code" label="Status"
|
||||||
v-slot="props">
|
v-slot="props">
|
||||||
<span v-html="props.row.status_code"></span>
|
<span v-html="props.row.status_code"></span>
|
||||||
</b-table-column>
|
</b-table-column>
|
||||||
<!-- <b-table-column field="flagged" label="Flagged"> -->
|
<b-table-column field="flagged" label="Flagged"
|
||||||
<!-- <span v-html="props.row.flagged"></span> -->
|
v-slot="props">
|
||||||
<!-- </b-table-column> -->
|
{{ props.row.flagged ? "FLAG" : "" }}
|
||||||
|
</b-table-column>
|
||||||
</b-table>
|
</b-table>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
@ -278,6 +334,18 @@
|
||||||
|
|
||||||
% if master.has_perm('change_status'):
|
% if master.has_perm('change_status'):
|
||||||
|
|
||||||
|
ThisPageData.markReceivedShowDialog = false
|
||||||
|
ThisPageData.markReceivedSubmitting = false
|
||||||
|
|
||||||
|
ThisPage.methods.markReceivedInit = function() {
|
||||||
|
this.markReceivedShowDialog = true
|
||||||
|
}
|
||||||
|
|
||||||
|
ThisPage.methods.markReceivedSubmit = function() {
|
||||||
|
this.markReceivedSubmitting = true
|
||||||
|
this.$refs.markReceivedForm.submit()
|
||||||
|
}
|
||||||
|
|
||||||
ThisPageData.orderItemStatuses = ${json.dumps(enum.CUSTORDER_ITEM_STATUS)|n}
|
ThisPageData.orderItemStatuses = ${json.dumps(enum.CUSTORDER_ITEM_STATUS)|n}
|
||||||
ThisPageData.orderItemStatusOptions = ${json.dumps([dict(key=k, label=v) for k, v in six.iteritems(enum.CUSTORDER_ITEM_STATUS)])|n}
|
ThisPageData.orderItemStatusOptions = ${json.dumps([dict(key=k, label=v) for k, v in six.iteritems(enum.CUSTORDER_ITEM_STATUS)])|n}
|
||||||
|
|
||||||
|
|
|
@ -328,6 +328,16 @@ class CustomerOrderItemView(MasterView):
|
||||||
items = [HTML.tag('span', c=[text])]
|
items = [HTML.tag('span', c=[text])]
|
||||||
|
|
||||||
if self.has_perm('change_status'):
|
if self.has_perm('change_status'):
|
||||||
|
|
||||||
|
# Mark Received
|
||||||
|
if self.can_be_received(item):
|
||||||
|
button = HTML.tag('b-button', type='is-primary', c="Mark Received",
|
||||||
|
style='margin-left: 1rem;',
|
||||||
|
icon_pack='fas', icon_left='check',
|
||||||
|
**{'@click': "$emit('mark-received')"})
|
||||||
|
items.append(button)
|
||||||
|
|
||||||
|
# Change Status
|
||||||
button = HTML.tag('b-button', type='is-primary', c="Change Status",
|
button = HTML.tag('b-button', type='is-primary', c="Change Status",
|
||||||
style='margin-left: 1rem;',
|
style='margin-left: 1rem;',
|
||||||
icon_pack='fas', icon_left='edit',
|
icon_pack='fas', icon_left='edit',
|
||||||
|
@ -338,6 +348,16 @@ class CustomerOrderItemView(MasterView):
|
||||||
outer = HTML.tag('div', class_='level', c=[left])
|
outer = HTML.tag('div', class_='level', c=[left])
|
||||||
return outer
|
return outer
|
||||||
|
|
||||||
|
def can_be_received(self, item):
|
||||||
|
|
||||||
|
# TODO: is this generic enough? probably belongs in handler anyway..
|
||||||
|
if item.status_code in (self.enum.CUSTORDER_ITEM_STATUS_INITIATED,
|
||||||
|
self.enum.CUSTORDER_ITEM_STATUS_READY,
|
||||||
|
self.enum.CUSTORDER_ITEM_STATUS_PLACED):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
def render_notes(self, item, field):
|
def render_notes(self, item, field):
|
||||||
route_prefix = self.get_route_prefix()
|
route_prefix = self.get_route_prefix()
|
||||||
|
|
||||||
|
@ -389,6 +409,7 @@ class CustomerOrderItemView(MasterView):
|
||||||
.filter(model.CustomerOrderItem.uuid != item.uuid)\
|
.filter(model.CustomerOrderItem.uuid != item.uuid)\
|
||||||
.all()
|
.all()
|
||||||
other_data = []
|
other_data = []
|
||||||
|
product_key_field = self.get_product_key_field()
|
||||||
for other in other_items:
|
for other in other_items:
|
||||||
|
|
||||||
order_date = None
|
order_date = None
|
||||||
|
@ -397,8 +418,10 @@ class CustomerOrderItemView(MasterView):
|
||||||
|
|
||||||
other_data.append({
|
other_data.append({
|
||||||
'uuid': other.uuid,
|
'uuid': other.uuid,
|
||||||
|
'product_key': getattr(other, f'product_{product_key_field}'),
|
||||||
'brand_name': other.product_brand,
|
'brand_name': other.product_brand,
|
||||||
'product_description': other.product_description,
|
'product_description': other.product_description,
|
||||||
|
'product_size': other.product_size,
|
||||||
'product_case_quantity': app.render_quantity(other.case_quantity),
|
'product_case_quantity': app.render_quantity(other.case_quantity),
|
||||||
'order_quantity': app.render_quantity(other.order_quantity),
|
'order_quantity': app.render_quantity(other.order_quantity),
|
||||||
'order_uom': self.enum.UNIT_OF_MEASURE[other.order_uom],
|
'order_uom': self.enum.UNIT_OF_MEASURE[other.order_uom],
|
||||||
|
@ -408,6 +431,7 @@ class CustomerOrderItemView(MasterView):
|
||||||
'total_price': app.render_currency(other.total_price),
|
'total_price': app.render_currency(other.total_price),
|
||||||
'order_date': app.render_date(order_date),
|
'order_date': app.render_date(order_date),
|
||||||
'status_code': self.enum.CUSTORDER_ITEM_STATUS[other.status_code],
|
'status_code': self.enum.CUSTORDER_ITEM_STATUS[other.status_code],
|
||||||
|
'flagged': other.flagged,
|
||||||
})
|
})
|
||||||
kwargs['other_order_items_data'] = other_data
|
kwargs['other_order_items_data'] = other_data
|
||||||
|
|
||||||
|
@ -450,6 +474,28 @@ class CustomerOrderItemView(MasterView):
|
||||||
self.request.session.flash("Price has been confirmed.")
|
self.request.session.flash("Price has been confirmed.")
|
||||||
return redirect
|
return redirect
|
||||||
|
|
||||||
|
def mark_received(self):
|
||||||
|
"""
|
||||||
|
View to mark some order item(s) as having been received.
|
||||||
|
"""
|
||||||
|
app = self.get_rattail_app()
|
||||||
|
model = self.model
|
||||||
|
uuids = self.request.POST['order_item_uuids'].split(',')
|
||||||
|
|
||||||
|
order_items = self.Session.query(model.CustomerOrderItem)\
|
||||||
|
.filter(model.CustomerOrderItem.uuid.in_(uuids))\
|
||||||
|
.all()
|
||||||
|
|
||||||
|
handler = app.get_custorder_handler()
|
||||||
|
handler.mark_received(order_items, self.request.user)
|
||||||
|
|
||||||
|
msg = self.mark_received_get_flash(order_items)
|
||||||
|
self.request.session.flash(msg)
|
||||||
|
return self.redirect(self.request.get_referrer(default=self.get_index_url()))
|
||||||
|
|
||||||
|
def mark_received_get_flash(self, order_items):
|
||||||
|
return "Order item statuses have been updated."
|
||||||
|
|
||||||
def change_status(self):
|
def change_status(self):
|
||||||
"""
|
"""
|
||||||
View for changing status of one or more order items.
|
View for changing status of one or more order items.
|
||||||
|
@ -550,7 +596,7 @@ class CustomerOrderItemView(MasterView):
|
||||||
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)\
|
||||||
.order_by(model.CustomerOrderItemEvent.occurred.desc(),
|
.order_by(model.CustomerOrderItemEvent.occurred,
|
||||||
model.CustomerOrderItemEvent.type_code)
|
model.CustomerOrderItemEvent.type_code)
|
||||||
|
|
||||||
def configure_row_grid(self, g):
|
def configure_row_grid(self, g):
|
||||||
|
@ -571,6 +617,7 @@ class CustomerOrderItemView(MasterView):
|
||||||
@classmethod
|
@classmethod
|
||||||
def _order_item_defaults(cls, config):
|
def _order_item_defaults(cls, config):
|
||||||
route_prefix = cls.get_route_prefix()
|
route_prefix = cls.get_route_prefix()
|
||||||
|
url_prefix = cls.get_url_prefix()
|
||||||
instance_url_prefix = cls.get_instance_url_prefix()
|
instance_url_prefix = cls.get_instance_url_prefix()
|
||||||
permission_prefix = cls.get_permission_prefix()
|
permission_prefix = cls.get_permission_prefix()
|
||||||
model_title = cls.get_model_title()
|
model_title = cls.get_model_title()
|
||||||
|
@ -590,6 +637,14 @@ class CustomerOrderItemView(MasterView):
|
||||||
route_name='{}.confirm_price'.format(route_prefix),
|
route_name='{}.confirm_price'.format(route_prefix),
|
||||||
permission='{}.confirm_price'.format(permission_prefix))
|
permission='{}.confirm_price'.format(permission_prefix))
|
||||||
|
|
||||||
|
# mark received
|
||||||
|
config.add_route(f'{route_prefix}.mark_received',
|
||||||
|
f'{url_prefix}/mark-received',
|
||||||
|
request_method='POST')
|
||||||
|
config.add_view(cls, attr='mark_received',
|
||||||
|
route_name=f'{route_prefix}.mark_received',
|
||||||
|
permission=f'{permission_prefix}.change_status')
|
||||||
|
|
||||||
# change status
|
# change status
|
||||||
config.add_tailbone_permission(permission_prefix,
|
config.add_tailbone_permission(permission_prefix,
|
||||||
'{}.change_status'.format(permission_prefix),
|
'{}.change_status'.format(permission_prefix),
|
||||||
|
|
Loading…
Reference in a new issue