@@ -106,21 +168,30 @@
:checked-rows.sync="changeStatusCheckedRows"
narrowed
class="is-size-7">
-
-
+ {{ props.row.product_key }}
-
+
+
+
-
-
-
+
+
+
+
+
+
@@ -129,33 +200,18 @@
v-slot="props">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ {{ props.row.flagged ? "FLAG" : "" }}
+
@@ -278,6 +334,18 @@
% 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.orderItemStatusOptions = ${json.dumps([dict(key=k, label=v) for k, v in six.iteritems(enum.CUSTORDER_ITEM_STATUS)])|n}
diff --git a/tailbone/views/custorders/items.py b/tailbone/views/custorders/items.py
index baec4151..84fe615a 100644
--- a/tailbone/views/custorders/items.py
+++ b/tailbone/views/custorders/items.py
@@ -328,6 +328,16 @@ class CustomerOrderItemView(MasterView):
items = [HTML.tag('span', c=[text])]
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",
style='margin-left: 1rem;',
icon_pack='fas', icon_left='edit',
@@ -338,6 +348,16 @@ class CustomerOrderItemView(MasterView):
outer = HTML.tag('div', class_='level', c=[left])
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):
route_prefix = self.get_route_prefix()
@@ -389,6 +409,7 @@ class CustomerOrderItemView(MasterView):
.filter(model.CustomerOrderItem.uuid != item.uuid)\
.all()
other_data = []
+ product_key_field = self.get_product_key_field()
for other in other_items:
order_date = None
@@ -397,8 +418,10 @@ class CustomerOrderItemView(MasterView):
other_data.append({
'uuid': other.uuid,
+ 'product_key': getattr(other, f'product_{product_key_field}'),
'brand_name': other.product_brand,
'product_description': other.product_description,
+ 'product_size': other.product_size,
'product_case_quantity': app.render_quantity(other.case_quantity),
'order_quantity': app.render_quantity(other.order_quantity),
'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),
'order_date': app.render_date(order_date),
'status_code': self.enum.CUSTORDER_ITEM_STATUS[other.status_code],
+ 'flagged': other.flagged,
})
kwargs['other_order_items_data'] = other_data
@@ -450,6 +474,28 @@ class CustomerOrderItemView(MasterView):
self.request.session.flash("Price has been confirmed.")
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):
"""
View for changing status of one or more order items.
@@ -550,7 +596,7 @@ class CustomerOrderItemView(MasterView):
def get_row_data(self, item):
return self.Session.query(model.CustomerOrderItemEvent)\
.filter(model.CustomerOrderItemEvent.item == item)\
- .order_by(model.CustomerOrderItemEvent.occurred.desc(),
+ .order_by(model.CustomerOrderItemEvent.occurred,
model.CustomerOrderItemEvent.type_code)
def configure_row_grid(self, g):
@@ -571,6 +617,7 @@ class CustomerOrderItemView(MasterView):
@classmethod
def _order_item_defaults(cls, config):
route_prefix = cls.get_route_prefix()
+ url_prefix = cls.get_url_prefix()
instance_url_prefix = cls.get_instance_url_prefix()
permission_prefix = cls.get_permission_prefix()
model_title = cls.get_model_title()
@@ -590,6 +637,14 @@ class CustomerOrderItemView(MasterView):
route_name='{}.confirm_price'.format(route_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
config.add_tailbone_permission(permission_prefix,
'{}.change_status'.format(permission_prefix),