Add basic "price needs confirmation" support for custorder
This commit is contained in:
parent
93b752f436
commit
8b044dbb22
4 changed files with 214 additions and 11 deletions
|
@ -98,6 +98,7 @@ class CustomerOrderItemView(MasterView):
|
|||
'case_quantity',
|
||||
'unit_price',
|
||||
'total_price',
|
||||
'price_needs_confirmation',
|
||||
'paid_amount',
|
||||
'status_code',
|
||||
'notes',
|
||||
|
@ -135,7 +136,7 @@ class CustomerOrderItemView(MasterView):
|
|||
g.set_renderer('person', self.render_person_text)
|
||||
g.set_renderer('order_created', self.render_order_created)
|
||||
|
||||
g.set_enum('status_code', self.enum.CUSTORDER_ITEM_STATUS)
|
||||
g.set_renderer('status_code', self.render_status_code_column)
|
||||
|
||||
g.set_label('person', "Person Name")
|
||||
g.set_label('product_brand', "Brand")
|
||||
|
@ -160,6 +161,13 @@ class CustomerOrderItemView(MasterView):
|
|||
value = localtime(self.rattail_config, item.order.created, from_utc=True)
|
||||
return raw_datetime(self.rattail_config, value)
|
||||
|
||||
def render_status_code_column(self, item, field):
|
||||
text = self.enum.CUSTORDER_ITEM_STATUS.get(item.status_code,
|
||||
six.text_type(item.status_code))
|
||||
if item.status_text:
|
||||
return HTML.tag('span', title=item.status_text, c=[text])
|
||||
return text
|
||||
|
||||
def configure_form(self, f):
|
||||
super(CustomerOrderItemView, self).configure_form(f)
|
||||
use_buefy = self.get_use_buefy()
|
||||
|
@ -178,12 +186,12 @@ class CustomerOrderItemView(MasterView):
|
|||
f.set_type('cases_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
|
||||
f.set_type('unit_price', 'currency')
|
||||
f.set_type('total_price', 'currency')
|
||||
# price fields
|
||||
f.set_renderer('unit_price', self.render_price_with_confirmation)
|
||||
f.set_renderer('total_price', self.render_price_with_confirmation)
|
||||
f.set_renderer('price_needs_confirmation', self.render_price_needs_confirmation)
|
||||
f.set_type('paid_amount', 'currency')
|
||||
|
||||
# person
|
||||
|
@ -198,9 +206,37 @@ class CustomerOrderItemView(MasterView):
|
|||
else:
|
||||
f.remove('notes')
|
||||
|
||||
def render_price_with_confirmation(self, item, field):
|
||||
price = getattr(item, field)
|
||||
app = self.get_rattail_app()
|
||||
text = app.render_currency(price)
|
||||
if item.price_needs_confirmation:
|
||||
return HTML.tag('span', class_='has-background-warning',
|
||||
c=[text])
|
||||
return text
|
||||
|
||||
def render_price_needs_confirmation(self, item, field):
|
||||
|
||||
value = item.price_needs_confirmation
|
||||
text = "Yes" if value else "No"
|
||||
items = [text]
|
||||
|
||||
if value and self.has_perm('confirm_price'):
|
||||
button = HTML.tag('b-button', type='is-primary', c="Confirm Price",
|
||||
style='margin-left: 1rem;',
|
||||
icon_pack='fas', icon_left='check',
|
||||
**{'@click': "$emit('confirm-price')"})
|
||||
items.append(button)
|
||||
|
||||
left = HTML.tag('div', class_='level-left', c=items)
|
||||
outer = HTML.tag('div', class_='level', c=[left])
|
||||
return outer
|
||||
|
||||
def render_status_code(self, item, field):
|
||||
use_buefy = self.get_use_buefy()
|
||||
text = self.enum.CUSTORDER_ITEM_STATUS[item.status_code]
|
||||
if item.status_text:
|
||||
text = "{} ({})".format(text, item.status_text)
|
||||
items = [HTML.tag('span', c=[text])]
|
||||
|
||||
if use_buefy and self.has_perm('change_status'):
|
||||
|
@ -298,6 +334,32 @@ class CustomerOrderItemView(MasterView):
|
|||
})
|
||||
return notes
|
||||
|
||||
def confirm_price(self):
|
||||
"""
|
||||
View for confirming price of an order item.
|
||||
"""
|
||||
item = self.get_instance()
|
||||
redirect = self.redirect(self.get_action_url('view', item))
|
||||
|
||||
# locate user responsible for change
|
||||
user = self.request.user
|
||||
|
||||
# grab user-provided note to attach to event
|
||||
note = self.request.POST.get('note')
|
||||
|
||||
# declare item no longer in need of price confirmation
|
||||
item.price_needs_confirmation = False
|
||||
item.add_event(self.enum.CUSTORDER_ITEM_EVENT_PRICE_CONFIRMED,
|
||||
user, note=note)
|
||||
|
||||
# advance item to next status
|
||||
if item.status_code == self.enum.CUSTORDER_ITEM_STATUS_INITIATED:
|
||||
item.status_code = self.enum.CUSTORDER_ITEM_STATUS_READY
|
||||
item.status_text = "price has been confirmed"
|
||||
|
||||
self.request.session.flash("Price has been confirmed.")
|
||||
return redirect
|
||||
|
||||
def change_status(self):
|
||||
"""
|
||||
View for changing status of one or more order items.
|
||||
|
@ -342,6 +404,9 @@ class CustomerOrderItemView(MasterView):
|
|||
|
||||
# change status
|
||||
item.status_code = new_status_code
|
||||
# nb. must blank this out, b/c user cannot specify new
|
||||
# text and the old text no longer applies
|
||||
item.status_text = None
|
||||
|
||||
self.request.session.flash("Status has been updated to: {}".format(
|
||||
self.enum.CUSTORDER_ITEM_STATUS[new_status_code]))
|
||||
|
@ -418,11 +483,23 @@ class CustomerOrderItemView(MasterView):
|
|||
route_prefix = cls.get_route_prefix()
|
||||
instance_url_prefix = cls.get_instance_url_prefix()
|
||||
permission_prefix = cls.get_permission_prefix()
|
||||
model_title = cls.get_model_title()
|
||||
model_title_plural = cls.get_model_title_plural()
|
||||
|
||||
# fix permission group name
|
||||
config.add_tailbone_permission_group(permission_prefix, model_title_plural)
|
||||
|
||||
# confirm price
|
||||
config.add_tailbone_permission(permission_prefix,
|
||||
'{}.confirm_price'.format(permission_prefix),
|
||||
"Confirm price for a {}".format(model_title))
|
||||
config.add_route('{}.confirm_price'.format(route_prefix),
|
||||
'{}/confirm-price'.format(instance_url_prefix),
|
||||
request_method='POST')
|
||||
config.add_view(cls, attr='confirm_price',
|
||||
route_name='{}.confirm_price'.format(route_prefix),
|
||||
permission='{}.confirm_price'.format(permission_prefix))
|
||||
|
||||
# change status
|
||||
config.add_tailbone_permission(permission_prefix,
|
||||
'{}.change_status'.format(permission_prefix),
|
||||
|
|
|
@ -36,7 +36,7 @@ from rattail.db import model
|
|||
from rattail.util import pretty_quantity
|
||||
from rattail.batch import get_batch_handler
|
||||
|
||||
from webhelpers2.html import tags
|
||||
from webhelpers2.html import tags, HTML
|
||||
|
||||
from tailbone.db import Session
|
||||
from tailbone.views import MasterView
|
||||
|
@ -189,10 +189,10 @@ class CustomerOrderView(MasterView):
|
|||
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_renderer('total_price', self.render_price_with_confirmation)
|
||||
|
||||
g.set_enum('order_uom', self.enum.UNIT_OF_MEASURE)
|
||||
g.set_enum('status_code', self.enum.CUSTORDER_ITEM_STATUS)
|
||||
g.set_renderer('status_code', self.render_row_status_code)
|
||||
|
||||
g.set_label('sequence', "Seq.")
|
||||
g.filters['sequence'].label = "Sequence"
|
||||
|
@ -206,6 +206,22 @@ class CustomerOrderView(MasterView):
|
|||
g.set_link('product_brand')
|
||||
g.set_link('product_description')
|
||||
|
||||
def render_price_with_confirmation(self, item, field):
|
||||
price = getattr(item, field)
|
||||
app = self.get_rattail_app()
|
||||
text = app.render_currency(price)
|
||||
if item.price_needs_confirmation:
|
||||
return HTML.tag('span', class_='has-background-warning',
|
||||
c=[text])
|
||||
return text
|
||||
|
||||
def render_row_status_code(self, item, field):
|
||||
text = self.enum.CUSTORDER_ITEM_STATUS.get(item.status_code,
|
||||
six.text_type(item.status_code))
|
||||
if item.status_text:
|
||||
return HTML.tag('span', title=item.status_text, c=[text])
|
||||
return text
|
||||
|
||||
def get_batch_handler(self):
|
||||
return get_batch_handler(
|
||||
self.rattail_config, 'custorder',
|
||||
|
@ -641,6 +657,7 @@ class CustomerOrderView(MasterView):
|
|||
'unit_price_display': "${:0.2f}".format(row.unit_price) if row.unit_price is not None else None,
|
||||
'total_price': six.text_type(row.total_price) if row.total_price is not None else None,
|
||||
'total_price_display': "${:0.2f}".format(row.total_price) if row.total_price is not None else None,
|
||||
'price_needs_confirmation': row.price_needs_confirmation,
|
||||
|
||||
'status_code': row.status_code,
|
||||
'status_text': row.status_text,
|
||||
|
@ -684,7 +701,8 @@ class CustomerOrderView(MasterView):
|
|||
|
||||
row = self.handler.add_product(batch, product,
|
||||
decimal.Decimal(data.get('order_quantity') or '0'),
|
||||
data.get('order_uom'))
|
||||
data.get('order_uom'),
|
||||
price_needs_confirmation=data.get('price_needs_confirmation'))
|
||||
self.Session.flush()
|
||||
|
||||
else: # product is not known
|
||||
|
@ -719,6 +737,7 @@ class CustomerOrderView(MasterView):
|
|||
row.product = product
|
||||
row.order_quantity = decimal.Decimal(data.get('order_quantity') or '0')
|
||||
row.order_uom = data.get('order_uom')
|
||||
row.price_needs_confirmation = data.get('price_needs_confirmation')
|
||||
self.handler.refresh_row(row)
|
||||
self.Session.flush()
|
||||
self.Session.refresh(row)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue