Several disparate changes needed for vendor catalog improvements
- invoke vendor handler where appropriate, e.g. for parsers - reverse "polarity" of dropdown chooser setting; rename it - tweak autocomplete behavior yet again, for dynamic values - auto-select vendor upon parser selection, when possible
This commit is contained in:
parent
ab61778d35
commit
88b3279e63
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2021 Lance Edgar
|
||||
# Copyright © 2010-2022 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -247,6 +247,7 @@ class JQueryAutocompleteWidget(dfwidget.AutocompleteInputWidget):
|
|||
template = 'autocomplete_jquery'
|
||||
requirements = None
|
||||
field_display = ""
|
||||
assigned_label = None
|
||||
service_url = None
|
||||
cleared_callback = None
|
||||
selected_callback = None
|
||||
|
@ -275,6 +276,7 @@ class JQueryAutocompleteWidget(dfwidget.AutocompleteInputWidget):
|
|||
kw['options'] = json.dumps(options)
|
||||
kw['field_display'] = self.field_display
|
||||
kw['cleared_callback'] = self.cleared_callback
|
||||
kw['assigned_label'] = self.assigned_label
|
||||
kw.setdefault('selected_callback', self.selected_callback)
|
||||
tmpl_values = self.get_template_values(field, cstruct, kw)
|
||||
template = readonly and self.readonly_template or self.template
|
||||
|
|
|
@ -95,6 +95,22 @@ const TailboneAutocomplete = {
|
|||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
// TODO: yikes this feels hacky. what happens is, when the
|
||||
// caller explicitly assigns a new UUID value to the tailbone
|
||||
// autocomplate component, the underlying buefy autocomplete
|
||||
// component was not getting the new value. so here we are
|
||||
// explicitly making sure it is in sync. this issue was
|
||||
// discovered on the "new vendor catalog batch" page
|
||||
value(val) {
|
||||
this.$nextTick(() => {
|
||||
if (this.buefyValue != val) {
|
||||
this.buefyValue = val
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// fetch new search results from the server. this is invoked
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
|
||||
<b-autocomplete ref="autocomplete"
|
||||
:name="name"
|
||||
v-show="!assignedValue && !selected"
|
||||
v-show="!value && !selected"
|
||||
v-model="buefyValue"
|
||||
:placeholder="placeholder"
|
||||
:data="data"
|
||||
|
@ -76,7 +76,7 @@
|
|||
</template>
|
||||
</b-autocomplete>
|
||||
|
||||
<b-button v-if="assignedValue || selected"
|
||||
<b-button v-if="value || selected"
|
||||
style="width: 100%; justify-content: left;"
|
||||
@click="clearSelection(true)">
|
||||
{{ getDisplayText() }} (click to change)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
<%def name="extra_javascript()">
|
||||
${parent.extra_javascript()}
|
||||
% if not use_buefy:
|
||||
<script type="text/javascript">
|
||||
|
||||
var vendormap = {
|
||||
|
@ -50,6 +51,29 @@
|
|||
|
||||
});
|
||||
</script>
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
<%def name="modify_this_page_vars()">
|
||||
${parent.modify_this_page_vars()}
|
||||
<script type="text/javascript">
|
||||
|
||||
${form.component_studly}Data.parsers = ${json.dumps(parsers_data)|n}
|
||||
|
||||
${form.component_studly}Data.vendorName = null
|
||||
|
||||
${form.component_studly}.watch.field_model_parser_key = function(val) {
|
||||
let parser = this.parsers[val]
|
||||
if (parser.vendor_uuid) {
|
||||
if (this.field_model_vendor_uuid != parser.vendor_uuid) {
|
||||
this.field_model_vendor_uuid = parser.vendor_uuid
|
||||
this.vendorName = parser.vendor_name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</%def>
|
||||
|
||||
|
||||
${parent.body()}
|
||||
|
|
|
@ -110,7 +110,8 @@
|
|||
<tailbone-autocomplete name="${name}"
|
||||
service-url="${url}"
|
||||
v-model="${vmodel}"
|
||||
initial-label="${field_display}">
|
||||
initial-label="${field_display}"
|
||||
tal:attributes=":assigned-label assigned_label or 'null';">
|
||||
</tailbone-autocomplete>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -76,6 +76,8 @@
|
|||
template: '#${form.component}-template',
|
||||
components: {},
|
||||
props: {},
|
||||
watch: {},
|
||||
computed: {},
|
||||
methods: {
|
||||
|
||||
## TODO: deprecate / remove the latter option here
|
||||
|
|
8
tailbone/templates/vendors/configure.mako
vendored
8
tailbone/templates/vendors/configure.mako
vendored
|
@ -6,11 +6,11 @@
|
|||
<h3 class="block is-size-3">Display</h3>
|
||||
<div class="block" style="padding-left: 2rem;">
|
||||
|
||||
<b-field message="If not set, vendor chooser is a dropdown field.">
|
||||
<b-checkbox name="rattail.vendor.use_autocomplete"
|
||||
v-model="simpleSettings['rattail.vendor.use_autocomplete']"
|
||||
<b-field message="If not set, vendor chooser is an autocomplete field.">
|
||||
<b-checkbox name="rattail.vendors.choice_uses_dropdown"
|
||||
v-model="simpleSettings['rattail.vendors.choice_uses_dropdown']"
|
||||
@input="settingsNeedSaved = true">
|
||||
Show vendor chooser as autocomplete field
|
||||
Show vendor chooser as dropdown (select) element
|
||||
</b-checkbox>
|
||||
</b-field>
|
||||
|
||||
|
|
|
@ -30,15 +30,13 @@ import logging
|
|||
|
||||
import six
|
||||
|
||||
from rattail.db import model, api
|
||||
from rattail.vendors.catalogs import iter_catalog_parsers
|
||||
from rattail.db import model
|
||||
|
||||
import colander
|
||||
from deform import widget as dfwidget
|
||||
from webhelpers2.html import tags
|
||||
|
||||
from tailbone import forms
|
||||
from tailbone.db import Session
|
||||
from tailbone.views.batch import FileBatchMasterView
|
||||
from tailbone.diffs import Diff
|
||||
|
||||
|
@ -139,13 +137,9 @@ class VendorCatalogView(FileBatchMasterView):
|
|||
|
||||
def get_parsers(self):
|
||||
if not hasattr(self, 'parsers'):
|
||||
parsers = sorted(iter_catalog_parsers(), key=lambda p: p.display)
|
||||
supported = self.rattail_config.getlist(
|
||||
'tailbone', 'batch.vendorcatalog.supported_parsers')
|
||||
if supported:
|
||||
parsers = [parser for parser in parsers
|
||||
if parser.key in supported]
|
||||
self.parsers = parsers
|
||||
app = self.get_rattail_app()
|
||||
vendor_handler = app.get_vendor_handler()
|
||||
self.parsers = vendor_handler.get_supported_catalog_parsers()
|
||||
return self.parsers
|
||||
|
||||
def configure_grid(self, g):
|
||||
|
@ -160,24 +154,8 @@ class VendorCatalogView(FileBatchMasterView):
|
|||
|
||||
def configure_form(self, f):
|
||||
super(VendorCatalogView, self).configure_form(f)
|
||||
|
||||
# vendor
|
||||
f.set_renderer('vendor', self.render_vendor)
|
||||
if self.creating and 'vendor' in f:
|
||||
f.replace('vendor', 'vendor_uuid')
|
||||
f.set_node('vendor_uuid', colander.String())
|
||||
vendor_display = ""
|
||||
if self.request.method == 'POST':
|
||||
if self.request.POST.get('vendor_uuid'):
|
||||
vendor = self.Session.query(model.Vendor).get(self.request.POST['vendor_uuid'])
|
||||
if vendor:
|
||||
vendor_display = six.text_type(vendor)
|
||||
vendors_url = self.request.route_url('vendors.autocomplete')
|
||||
f.set_widget('vendor_uuid', forms.widgets.JQueryAutocompleteWidget(
|
||||
field_display=vendor_display, service_url=vendors_url))
|
||||
f.set_label('vendor_uuid', "Vendor")
|
||||
else:
|
||||
f.set_readonly('vendor')
|
||||
app = self.get_rattail_app()
|
||||
vendor_handler = app.get_vendor_handler()
|
||||
|
||||
# filename
|
||||
f.set_label('filename', "Catalog File")
|
||||
|
@ -196,12 +174,75 @@ class VendorCatalogView(FileBatchMasterView):
|
|||
f.set_widget('parser_key', dfwidget.SelectWidget(values=values))
|
||||
f.set_label('parser_key', "File Type")
|
||||
|
||||
# vendor
|
||||
f.set_renderer('vendor', self.render_vendor)
|
||||
if self.creating and 'vendor' in f:
|
||||
f.replace('vendor', 'vendor_uuid')
|
||||
f.set_label('vendor_uuid', "Vendor")
|
||||
use_dropdown = vendor_handler.choice_uses_dropdown()
|
||||
if use_dropdown:
|
||||
vendors = self.Session.query(model.Vendor)\
|
||||
.order_by(model.Vendor.id)
|
||||
vendor_values = [(vendor.uuid, "({}) {}".format(vendor.id,
|
||||
vendor.name))
|
||||
for vendor in vendors]
|
||||
f.set_widget('vendor_uuid',
|
||||
dfwidget.SelectWidget(values=vendor_values))
|
||||
else:
|
||||
vendor_display = ""
|
||||
if self.request.method == 'POST':
|
||||
if self.request.POST.get('vendor_uuid'):
|
||||
vendor = self.Session.query(model.Vendor).get(
|
||||
self.request.POST['vendor_uuid'])
|
||||
if vendor:
|
||||
vendor_display = six.text_type(vendor)
|
||||
vendors_url = self.request.route_url('vendors.autocomplete')
|
||||
f.set_widget('vendor_uuid', forms.widgets.JQueryAutocompleteWidget(
|
||||
field_display=vendor_display, service_url=vendors_url,
|
||||
assigned_label='vendorName'))
|
||||
else:
|
||||
f.set_readonly('vendor')
|
||||
|
||||
# effective
|
||||
if self.creating:
|
||||
f.remove('effective')
|
||||
else:
|
||||
f.set_readonly('effective')
|
||||
|
||||
def template_kwargs_create(self, **kwargs):
|
||||
use_buefy = self.get_use_buefy()
|
||||
app = self.get_rattail_app()
|
||||
vendor_handler = app.get_vendor_handler()
|
||||
parsers = self.get_parsers()
|
||||
parsers_data = {}
|
||||
for parser in parsers:
|
||||
if use_buefy:
|
||||
pdata = {'key': parser.key,
|
||||
'vendor_key': parser.vendor_key}
|
||||
if parser.vendor_key:
|
||||
vendor = vendor_handler.get_vendor(self.Session(),
|
||||
parser.vendor_key)
|
||||
if vendor:
|
||||
pdata['vendor_uuid'] = vendor.uuid
|
||||
pdata['vendor_name'] = vendor.name
|
||||
parsers_data[parser.key] = pdata
|
||||
else:
|
||||
if parser.vendor_key:
|
||||
vendor = vendor_handler.get_vendor(self.Session(),
|
||||
parser.vendor_key)
|
||||
if vendor:
|
||||
parser.vendormap_value = "{{uuid: '{}', name: '{}'}}".format(
|
||||
vendor.uuid, vendor.name.replace("'", "\\'"))
|
||||
else:
|
||||
log.warning("vendor '{}' not found for parser: {}".format(
|
||||
parser.vendor_key, parser.key))
|
||||
parser.vendormap_value = 'null'
|
||||
else:
|
||||
parser.vendormap_value = 'null'
|
||||
kwargs['parsers'] = parsers
|
||||
kwargs['parsers_data'] = parsers_data
|
||||
return kwargs
|
||||
|
||||
def get_batch_kwargs(self, batch):
|
||||
kwargs = super(VendorCatalogView, self).get_batch_kwargs(batch)
|
||||
kwargs['parser_key'] = batch.parser_key
|
||||
|
@ -275,23 +316,6 @@ class VendorCatalogView(FileBatchMasterView):
|
|||
|
||||
return kwargs
|
||||
|
||||
def template_kwargs_create(self, **kwargs):
|
||||
parsers = self.get_parsers()
|
||||
for parser in parsers:
|
||||
if parser.vendor_key:
|
||||
vendor = api.get_vendor(Session(), parser.vendor_key)
|
||||
if vendor:
|
||||
parser.vendormap_value = "{{uuid: '{}', name: '{}'}}".format(
|
||||
vendor.uuid, vendor.name.replace("'", "\\'"))
|
||||
else:
|
||||
log.warning("vendor '{}' not found for parser: {}".format(
|
||||
parser.vendor_key, parser.key))
|
||||
parser.vendormap_value = 'null'
|
||||
else:
|
||||
parser.vendormap_value = 'null'
|
||||
kwargs['parsers'] = parsers
|
||||
return kwargs
|
||||
|
||||
# TODO: deprecate / remove this
|
||||
VendorCatalogsView = VendorCatalogView
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2021 Lance Edgar
|
||||
# Copyright © 2010-2022 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -29,7 +29,6 @@ from __future__ import unicode_literals, absolute_import
|
|||
import six
|
||||
|
||||
from rattail.db import model, api
|
||||
from rattail.time import localtime
|
||||
|
||||
import colander
|
||||
from deform import widget as dfwidget
|
||||
|
@ -230,7 +229,8 @@ class PurchasingBatchView(BatchMasterView):
|
|||
super(PurchasingBatchView, self).configure_form(f)
|
||||
model = self.model
|
||||
batch = f.model_instance
|
||||
today = localtime(self.rattail_config).date()
|
||||
app = self.get_rattail_app()
|
||||
today = app.localtime().date()
|
||||
use_buefy = self.get_use_buefy()
|
||||
|
||||
# mode
|
||||
|
@ -265,9 +265,15 @@ class PurchasingBatchView(BatchMasterView):
|
|||
if self.creating:
|
||||
f.replace('vendor', 'vendor_uuid')
|
||||
f.set_label('vendor_uuid', "Vendor")
|
||||
use_autocomplete = self.rattail_config.getbool(
|
||||
'rattail', 'vendor.use_autocomplete', default=True)
|
||||
if use_autocomplete:
|
||||
vendor_handler = app.get_vendor_handler()
|
||||
use_dropdown = vendor_handler.choice_uses_dropdown()
|
||||
if use_dropdown:
|
||||
vendors = self.Session.query(model.Vendor)\
|
||||
.order_by(model.Vendor.id)
|
||||
vendor_values = [(vendor.uuid, "({}) {}".format(vendor.id, vendor.name))
|
||||
for vendor in vendors]
|
||||
f.set_widget('vendor_uuid', dfwidget.SelectWidget(values=vendor_values))
|
||||
else:
|
||||
vendor_display = ""
|
||||
if self.request.method == 'POST':
|
||||
if self.request.POST.get('vendor_uuid'):
|
||||
|
@ -277,12 +283,6 @@ class PurchasingBatchView(BatchMasterView):
|
|||
vendors_url = self.request.route_url('vendors.autocomplete')
|
||||
f.set_widget('vendor_uuid', forms.widgets.JQueryAutocompleteWidget(
|
||||
field_display=vendor_display, service_url=vendors_url))
|
||||
else:
|
||||
vendors = self.Session.query(model.Vendor)\
|
||||
.order_by(model.Vendor.id)
|
||||
vendor_values = [(vendor.uuid, "({}) {}".format(vendor.id, vendor.name))
|
||||
for vendor in vendors]
|
||||
f.set_widget('vendor_uuid', dfwidget.SelectWidget(values=vendor_values))
|
||||
elif self.editing:
|
||||
f.set_readonly('vendor')
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2021 Lance Edgar
|
||||
# Copyright © 2010-2022 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -200,9 +200,19 @@ class CostingBatchView(PurchasingBatchView):
|
|||
form.set_default('workflow', valid_workflows[0])
|
||||
|
||||
# configure vendor field
|
||||
use_autocomplete = self.rattail_config.getbool(
|
||||
'rattail', 'vendor.use_autocomplete', default=True)
|
||||
if use_autocomplete:
|
||||
app = self.get_rattail_app()
|
||||
vendor_handler = app.get_vendor_handler()
|
||||
use_dropdown = vendor_handler.choice_uses_dropdown()
|
||||
if use_dropdown:
|
||||
vendors = self.Session.query(model.Vendor)\
|
||||
.order_by(model.Vendor.id)
|
||||
vendor_values = [(vendor.uuid, "({}) {}".format(vendor.id, vendor.name))
|
||||
for vendor in vendors]
|
||||
if use_buefy:
|
||||
form.set_widget('vendor', dfwidget.SelectWidget(values=vendor_values))
|
||||
else:
|
||||
form.set_widget('vendor', forms.widgets.JQuerySelectWidget(values=vendor_values))
|
||||
else:
|
||||
vendor_display = ""
|
||||
if self.request.method == 'POST':
|
||||
if self.request.POST.get('vendor'):
|
||||
|
@ -212,15 +222,6 @@ class CostingBatchView(PurchasingBatchView):
|
|||
vendors_url = self.request.route_url('vendors.autocomplete')
|
||||
form.set_widget('vendor', forms.widgets.JQueryAutocompleteWidget(
|
||||
field_display=vendor_display, service_url=vendors_url))
|
||||
else:
|
||||
vendors = self.Session.query(model.Vendor)\
|
||||
.order_by(model.Vendor.id)
|
||||
vendor_values = [(vendor.uuid, "({}) {}".format(vendor.id, vendor.name))
|
||||
for vendor in vendors]
|
||||
if use_buefy:
|
||||
form.set_widget('vendor', dfwidget.SelectWidget(values=vendor_values))
|
||||
else:
|
||||
form.set_widget('vendor', forms.widgets.JQuerySelectWidget(values=vendor_values))
|
||||
|
||||
# configure workflow field
|
||||
values = [(workflow['workflow_key'], workflow['display'])
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2021 Lance Edgar
|
||||
# Copyright © 2010-2022 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -294,9 +294,19 @@ class ReceivingBatchView(PurchasingBatchView):
|
|||
use_buefy=use_buefy)
|
||||
|
||||
# configure vendor field
|
||||
use_autocomplete = self.rattail_config.getbool(
|
||||
'rattail', 'vendor.use_autocomplete', default=True)
|
||||
if use_autocomplete:
|
||||
app = self.get_rattail_app()
|
||||
vendor_handler = app.get_vendor_handler()
|
||||
use_dropdown = vendor_handler.choice_uses_dropdown()
|
||||
if use_dropdown:
|
||||
vendors = self.Session.query(model.Vendor)\
|
||||
.order_by(model.Vendor.id)
|
||||
vendor_values = [(vendor.uuid, "({}) {}".format(vendor.id, vendor.name))
|
||||
for vendor in vendors]
|
||||
if use_buefy:
|
||||
form.set_widget('vendor', dfwidget.SelectWidget(values=vendor_values))
|
||||
else:
|
||||
form.set_widget('vendor', forms.widgets.JQuerySelectWidget(values=vendor_values))
|
||||
else:
|
||||
vendor_display = ""
|
||||
if self.request.method == 'POST':
|
||||
if self.request.POST.get('vendor'):
|
||||
|
@ -306,15 +316,6 @@ class ReceivingBatchView(PurchasingBatchView):
|
|||
vendors_url = self.request.route_url('vendors.autocomplete')
|
||||
form.set_widget('vendor', forms.widgets.JQueryAutocompleteWidget(
|
||||
field_display=vendor_display, service_url=vendors_url))
|
||||
else:
|
||||
vendors = self.Session.query(model.Vendor)\
|
||||
.order_by(model.Vendor.id)
|
||||
vendor_values = [(vendor.uuid, "({}) {}".format(vendor.id, vendor.name))
|
||||
for vendor in vendors]
|
||||
if use_buefy:
|
||||
form.set_widget('vendor', dfwidget.SelectWidget(values=vendor_values))
|
||||
else:
|
||||
form.set_widget('vendor', forms.widgets.JQuerySelectWidget(values=vendor_values))
|
||||
|
||||
# configure workflow field
|
||||
values = [(workflow['workflow_key'], workflow['display'])
|
||||
|
|
4
tailbone/views/vendors/core.py
vendored
4
tailbone/views/vendors/core.py
vendored
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2021 Lance Edgar
|
||||
# Copyright © 2010-2022 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -175,7 +175,7 @@ class VendorView(MasterView):
|
|||
|
||||
# display
|
||||
{'section': 'rattail',
|
||||
'option': 'vendor.use_autocomplete',
|
||||
'option': 'vendors.choice_uses_dropdown',
|
||||
'type': bool},
|
||||
]
|
||||
|
||||
|
|
Loading…
Reference in a new issue