Add way to "ignore" a pending product
and some related tweaks for sake of grid
This commit is contained in:
parent
1fc17658ff
commit
fe4a178d43
|
@ -612,10 +612,11 @@ class AlchemyNumericFilter(AlchemyGridFilter):
|
||||||
"""
|
"""
|
||||||
value_renderer_factory = NumericValueRenderer
|
value_renderer_factory = NumericValueRenderer
|
||||||
|
|
||||||
# expose greater-than / less-than verbs in addition to core
|
def default_verbs(self):
|
||||||
default_verbs = ['equal', 'not_equal', 'greater_than', 'greater_equal',
|
# expose greater-than / less-than verbs in addition to core
|
||||||
'less_than', 'less_equal', 'between',
|
return ['equal', 'not_equal', 'greater_than', 'greater_equal',
|
||||||
'is_null', 'is_not_null', 'is_any']
|
'less_than', 'less_equal', 'between',
|
||||||
|
'is_null', 'is_not_null', 'is_any']
|
||||||
|
|
||||||
# TODO: what follows "works" in that it prevents an error...but from the
|
# TODO: what follows "works" in that it prevents an error...but from the
|
||||||
# user's perspective it still fails silently...need to improve on front-end
|
# user's perspective it still fails silently...need to improve on front-end
|
||||||
|
@ -670,6 +671,14 @@ class AlchemyIntegerFilter(AlchemyNumericFilter):
|
||||||
"""
|
"""
|
||||||
bigint = False
|
bigint = False
|
||||||
|
|
||||||
|
def default_verbs(self):
|
||||||
|
|
||||||
|
# limited verbs if choices are defined
|
||||||
|
if self.choices:
|
||||||
|
return ['equal', 'not_equal', 'is_null', 'is_not_null', 'is_any']
|
||||||
|
|
||||||
|
return super().default_verbs()
|
||||||
|
|
||||||
def value_invalid(self, value):
|
def value_invalid(self, value):
|
||||||
if value:
|
if value:
|
||||||
if isinstance(value, int):
|
if isinstance(value, int):
|
||||||
|
|
|
@ -7,25 +7,16 @@
|
||||||
${product_lookup.tailbone_product_lookup_template()}
|
${product_lookup.tailbone_product_lookup_template()}
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="object_helpers()">
|
<%def name="page_content()">
|
||||||
${parent.object_helpers()}
|
${parent.page_content()}
|
||||||
% if instance.status_code == enum.PENDING_PRODUCT_STATUS_PENDING and master.has_perm('resolve_product'):
|
|
||||||
<nav class="panel">
|
|
||||||
<p class="panel-heading">Tools</p>
|
|
||||||
<div class="panel-block">
|
|
||||||
<div style="display: flex; flex-direction: column;">
|
|
||||||
<div class="buttons">
|
|
||||||
<b-button type="is-primary"
|
|
||||||
@click="resolveProductInit()"
|
|
||||||
icon-pack="fas"
|
|
||||||
icon-left="object-ungroup">
|
|
||||||
Resolve Product
|
|
||||||
</b-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
|
% if master.has_perm('ignore_product') and instance.status_code in (enum.PENDING_PRODUCT_STATUS_PENDING, enum.PENDING_PRODUCT_STATUS_READY):
|
||||||
|
${h.form(master.get_action_url('ignore_product', instance), ref='ignoreProductForm')}
|
||||||
|
${h.csrf_token(request)}
|
||||||
|
${h.end_form()}
|
||||||
|
% endif
|
||||||
|
|
||||||
|
% if master.has_perm('resolve_product') and instance.status_code in (enum.PENDING_PRODUCT_STATUS_PENDING, enum.PENDING_PRODUCT_STATUS_READY, enum.PENDING_PRODUCT_STATUS_IGNORED):
|
||||||
<b-modal has-modal-card
|
<b-modal has-modal-card
|
||||||
:active.sync="resolveProductShowDialog">
|
:active.sync="resolveProductShowDialog">
|
||||||
<div class="modal-card">
|
<div class="modal-card">
|
||||||
|
@ -80,39 +71,55 @@
|
||||||
${parent.modify_this_page_vars()}
|
${parent.modify_this_page_vars()}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
ThisPageData.resolveProductShowDialog = false
|
% if master.has_perm('ignore_product') and instance.status_code in (enum.PENDING_PRODUCT_STATUS_PENDING, enum.PENDING_PRODUCT_STATUS_READY):
|
||||||
ThisPageData.resolveProductUUID = null
|
|
||||||
ThisPageData.resolveProductSubmitting = false
|
|
||||||
|
|
||||||
ThisPage.computed.resolveProductSubmitDisabled = function() {
|
ThisPage.methods.ignoreProductInit = function() {
|
||||||
if (this.resolveProductSubmitting) {
|
if (!confirm("Really ignore this product?\n\n"
|
||||||
return true
|
+ "This will leave it unresolved, but hidden via default filters.")) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$refs.ignoreProductForm.submit()
|
||||||
}
|
}
|
||||||
if (!this.resolveProductUUID) {
|
|
||||||
return true
|
% endif
|
||||||
|
|
||||||
|
% if master.has_perm('resolve_product') and instance.status_code in (enum.PENDING_PRODUCT_STATUS_PENDING, enum.PENDING_PRODUCT_STATUS_READY, enum.PENDING_PRODUCT_STATUS_IGNORED):
|
||||||
|
|
||||||
|
ThisPageData.resolveProductShowDialog = false
|
||||||
|
ThisPageData.resolveProductUUID = null
|
||||||
|
ThisPageData.resolveProductSubmitting = false
|
||||||
|
|
||||||
|
ThisPage.computed.resolveProductSubmitDisabled = function() {
|
||||||
|
if (this.resolveProductSubmitting) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (!this.resolveProductUUID) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
ThisPage.methods.resolveProductInit = function() {
|
ThisPage.methods.resolveProductInit = function() {
|
||||||
this.resolveProductUUID = null
|
this.resolveProductUUID = null
|
||||||
this.resolveProductShowDialog = true
|
this.resolveProductShowDialog = true
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs.productLookup.focus()
|
this.$refs.productLookup.focus()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
ThisPage.methods.resolveProductSubmit = function() {
|
ThisPage.methods.resolveProductSubmit = function() {
|
||||||
this.resolveProductSubmitting = true
|
this.resolveProductSubmitting = true
|
||||||
this.$refs.resolveProductForm.submit()
|
this.$refs.resolveProductForm.submit()
|
||||||
}
|
}
|
||||||
|
|
||||||
ThisPageData.actualProduct = null
|
ThisPageData.actualProduct = null
|
||||||
|
|
||||||
ThisPage.methods.productSelected = function(product) {
|
ThisPage.methods.productSelected = function(product) {
|
||||||
this.actualProduct = product
|
this.actualProduct = product
|
||||||
this.resolveProductUUID = product ? product.uuid : null
|
this.resolveProductUUID = product ? product.uuid : null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
% endif
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
|
@ -2297,16 +2297,22 @@ class PendingProductView(MasterView):
|
||||||
|
|
||||||
def configure_grid(self, g):
|
def configure_grid(self, g):
|
||||||
super().configure_grid(g)
|
super().configure_grid(g)
|
||||||
|
model = self.model
|
||||||
|
|
||||||
g.set_enum('status_code', self.enum.PENDING_PRODUCT_STATUS)
|
# description
|
||||||
g.filters['status_code'].default_active = True
|
|
||||||
g.filters['status_code'].default_verb = 'not_equal'
|
|
||||||
g.filters['status_code'].default_value = str(self.enum.PENDING_PRODUCT_STATUS_RESOLVED)
|
|
||||||
|
|
||||||
g.set_sort_defaults('created', 'desc')
|
|
||||||
|
|
||||||
g.set_link('description')
|
g.set_link('description')
|
||||||
|
|
||||||
|
# status_code
|
||||||
|
g.set_enum('status_code', self.enum.PENDING_PRODUCT_STATUS)
|
||||||
|
g.set_filter('status_code', model.PendingProduct.status_code,
|
||||||
|
value_enum=self.enum.PENDING_PRODUCT_STATUS,
|
||||||
|
default_active=True,
|
||||||
|
default_verb='equal',
|
||||||
|
default_value=str(self.enum.PENDING_PRODUCT_STATUS_PENDING))
|
||||||
|
|
||||||
|
# created
|
||||||
|
g.set_sort_defaults('created', 'desc')
|
||||||
|
|
||||||
def configure_form(self, f):
|
def configure_form(self, f):
|
||||||
super().configure_form(f)
|
super().configure_form(f)
|
||||||
model = self.model
|
model = self.model
|
||||||
|
@ -2398,8 +2404,20 @@ class PendingProductView(MasterView):
|
||||||
if self.creating:
|
if self.creating:
|
||||||
f.remove('status_code')
|
f.remove('status_code')
|
||||||
else:
|
else:
|
||||||
# f.set_readonly('status_code')
|
|
||||||
f.set_enum('status_code', self.enum.PENDING_PRODUCT_STATUS)
|
f.set_enum('status_code', self.enum.PENDING_PRODUCT_STATUS)
|
||||||
|
if self.viewing:
|
||||||
|
f.set_renderer('status_code', self.render_status_code)
|
||||||
|
|
||||||
|
if (self.has_perm('ignore_product')
|
||||||
|
and pending.status_code in (self.enum.PENDING_PRODUCT_STATUS_PENDING,
|
||||||
|
self.enum.PENDING_PRODUCT_STATUS_READY)):
|
||||||
|
f.set_vuejs_component_kwargs(**{'@ignore-product': 'ignoreProductInit'})
|
||||||
|
|
||||||
|
if (self.has_perm('resolve_product')
|
||||||
|
and pending.status_code in (self.enum.PENDING_PRODUCT_STATUS_PENDING,
|
||||||
|
self.enum.PENDING_PRODUCT_STATUS_READY,
|
||||||
|
self.enum.PENDING_PRODUCT_STATUS_IGNORED)):
|
||||||
|
f.set_vuejs_component_kwargs(**{'@resolve-product': 'resolveProductInit'})
|
||||||
|
|
||||||
# user
|
# user
|
||||||
if self.creating:
|
if self.creating:
|
||||||
|
@ -2415,6 +2433,42 @@ class PendingProductView(MasterView):
|
||||||
if not pending.resolved:
|
if not pending.resolved:
|
||||||
f.remove('resolved', 'resolved_by')
|
f.remove('resolved', 'resolved_by')
|
||||||
|
|
||||||
|
def render_status_code(self, pending, field):
|
||||||
|
status = pending.status_code
|
||||||
|
if not status:
|
||||||
|
return
|
||||||
|
|
||||||
|
# will just show status text by default
|
||||||
|
text = self.enum.PENDING_PRODUCT_STATUS.get(status, str(status))
|
||||||
|
html = text
|
||||||
|
|
||||||
|
# but maybe also show buttons to change status
|
||||||
|
buttons = []
|
||||||
|
|
||||||
|
if (self.has_perm('ignore_product')
|
||||||
|
and status in (self.enum.PENDING_PRODUCT_STATUS_PENDING,
|
||||||
|
self.enum.PENDING_PRODUCT_STATUS_READY)):
|
||||||
|
buttons.append(self.make_buefy_button("Ignore Product",
|
||||||
|
type='is-warning',
|
||||||
|
icon_left='ban',
|
||||||
|
**{'@click': "$emit('ignore-product')"}))
|
||||||
|
|
||||||
|
if (self.has_perm('resolve_product')
|
||||||
|
and status in (self.enum.PENDING_PRODUCT_STATUS_PENDING,
|
||||||
|
self.enum.PENDING_PRODUCT_STATUS_READY,
|
||||||
|
self.enum.PENDING_PRODUCT_STATUS_IGNORED)):
|
||||||
|
buttons.append(self.make_buefy_button("Resolve Product",
|
||||||
|
is_primary=True,
|
||||||
|
icon_left='object-ungroup',
|
||||||
|
**{'@click': "$emit('resolve-product')"}))
|
||||||
|
|
||||||
|
if buttons:
|
||||||
|
text = HTML.tag('span', class_='control', c=[text])
|
||||||
|
buttons = HTML.tag('div', class_='buttons', c=buttons)
|
||||||
|
html = HTML.tag('b-field', grouped='grouped', c=[text, buttons])
|
||||||
|
|
||||||
|
return html
|
||||||
|
|
||||||
def editable_instance(self, pending):
|
def editable_instance(self, pending):
|
||||||
if self.request.is_root:
|
if self.request.is_root:
|
||||||
return True
|
return True
|
||||||
|
@ -2487,6 +2541,12 @@ class PendingProductView(MasterView):
|
||||||
def get_resolve_product_kwargs(self, **kwargs):
|
def get_resolve_product_kwargs(self, **kwargs):
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
|
def ignore_product(self):
|
||||||
|
model = self.model
|
||||||
|
pending = self.get_instance()
|
||||||
|
pending.status_code = self.enum.PENDING_PRODUCT_STATUS_IGNORED
|
||||||
|
return self.redirect(self.get_action_url('view', pending))
|
||||||
|
|
||||||
def get_row_data(self, pending):
|
def get_row_data(self, pending):
|
||||||
model = self.model
|
model = self.model
|
||||||
return self.Session.query(model.CustomerOrderItem)\
|
return self.Session.query(model.CustomerOrderItem)\
|
||||||
|
@ -2554,6 +2614,17 @@ class PendingProductView(MasterView):
|
||||||
route_name='{}.resolve_product'.format(route_prefix),
|
route_name='{}.resolve_product'.format(route_prefix),
|
||||||
permission='{}.resolve_product'.format(permission_prefix))
|
permission='{}.resolve_product'.format(permission_prefix))
|
||||||
|
|
||||||
|
# ignore product
|
||||||
|
config.add_tailbone_permission(permission_prefix,
|
||||||
|
f'{permission_prefix}.ignore_product',
|
||||||
|
f"Mark {model_title} as ignored")
|
||||||
|
config.add_route(f'{route_prefix}.ignore_product',
|
||||||
|
f'{instance_url_prefix}/ignore-product',
|
||||||
|
request_method='POST')
|
||||||
|
config.add_view(cls, attr='ignore_product',
|
||||||
|
route_name=f'{route_prefix}.ignore_product',
|
||||||
|
permission=f'{permission_prefix}.ignore_product')
|
||||||
|
|
||||||
|
|
||||||
def defaults(config, **kwargs):
|
def defaults(config, **kwargs):
|
||||||
base = globals()
|
base = globals()
|
||||||
|
|
Loading…
Reference in a new issue