Add basic "config" view for Receiving

This commit is contained in:
Lance Edgar 2021-12-13 20:35:23 -06:00
parent 340a177a29
commit 1fbe429a08
6 changed files with 278 additions and 8 deletions

View file

@ -112,6 +112,10 @@
${parent.modify_this_page_vars()}
<script type="text/javascript">
% if simple_settings is not Undefined:
ThisPageData.simpleSettings = ${json.dumps(simple_settings)|n}
% endif
ThisPageData.purgeSettingsShowDialog = false
ThisPageData.purgingSettings = false
@ -124,7 +128,11 @@
}
ThisPage.methods.settingsCollectParams = function() {
% if simple_settings is not Undefined:
return {simple_settings: this.simpleSettings}
% else:
return {}
% endif
}
ThisPage.methods.saveSettings = function() {

View file

@ -140,10 +140,6 @@
ThisPageData.editingHandlerSubcommand = null
ThisPageData.editingHandlerRunas = null
ThisPageData.settingsNeedSaved = false
ThisPageData.undoChanges = false
ThisPageData.savingSettings = false
ThisPage.computed.updateHandlerDisabled = function() {
if (!this.editingHandlerSpec) {
return true

View file

@ -0,0 +1,33 @@
## -*- coding: utf-8; -*-
<%inherit file="/configure.mako" />
<%def name="page_content()">
${parent.page_content()}
<h3 class="block is-size-3">TODO</h3>
<p class="block">
You should create a custom template file at:&nbsp;
<span class="is-family-monospace">${master.get_template_prefix()}/configure.mako</span>
</p>
<p class="block">
Within that you should define (at least) the
<span class="is-family-monospace">page_content()</span>
def block.
</p>
<p class="block">
You can see the following examples for reference:
</p>
<ul class="block">
<li class="is-family-monospace">/datasync/configure.mako</li>
<li class="is-family-monospace">/importing/configure.mako</li>
<li class="is-family-monospace">/receiving/configure.mako</li>
</ul>
</%def>
${parent.body()}

View file

@ -0,0 +1,94 @@
## -*- coding: utf-8; -*-
<%inherit file="/configure.mako" />
<%def name="page_content()">
${parent.page_content()}
<h3 class="block is-size-3">Supported Workflows</h3>
<div class="block" style="padding-left: 2rem;">
<b-field>
<b-checkbox v-model="simpleSettings['rattail.batch.purchase.allow_receiving_from_scratch']"
@input="settingsNeedSaved = true">
From Scratch
</b-checkbox>
</b-field>
<b-field>
<b-checkbox v-model="simpleSettings['rattail.batch.purchase.allow_receiving_from_invoice']"
@input="settingsNeedSaved = true">
From Invoice
</b-checkbox>
</b-field>
<b-field>
<b-checkbox v-model="simpleSettings['rattail.batch.purchase.allow_receiving_from_purchase_order']"
@input="settingsNeedSaved = true">
From Purchase Order
</b-checkbox>
</b-field>
<b-field>
<b-checkbox v-model="simpleSettings['rattail.batch.purchase.allow_receiving_from_purchase_order_with_invoice']"
@input="settingsNeedSaved = true">
From Purchase Order, with Invoice
</b-checkbox>
</b-field>
<b-field>
<b-checkbox v-model="simpleSettings['rattail.batch.purchase.allow_truck_dump_receiving']"
@input="settingsNeedSaved = true">
Truck Dump
</b-checkbox>
</b-field>
</div>
<h3 class="block is-size-3">Product Handling</h3>
<div class="block" style="padding-left: 2rem;">
<b-field message="NB. Allow Cases setting also affects Ordering behavior.">
<b-checkbox v-model="simpleSettings['rattail.batch.purchase.allow_cases']"
@input="settingsNeedSaved = true">
Allow Cases
</b-checkbox>
</b-field>
<b-field>
<b-checkbox v-model="simpleSettings['rattail.batch.purchase.allow_expired_credits']"
@input="settingsNeedSaved = true">
Allow "Expired" Credits
</b-checkbox>
</b-field>
</div>
<h3 class="block is-size-3">Mobile Interface</h3>
<div class="block" style="padding-left: 2rem;">
<b-field message="TODO: this may also affect Ordering (?)">
<b-checkbox v-model="simpleSettings['rattail.batch.purchase.mobile_images']"
@input="settingsNeedSaved = true">
Show Product Images
</b-checkbox>
</b-field>
<b-field>
<b-checkbox v-model="simpleSettings['rattail.batch.purchase.mobile_quick_receive']"
@input="settingsNeedSaved = true">
Allow "Quick Receive"
</b-checkbox>
</b-field>
<b-field>
<b-checkbox v-model="simpleSettings['rattail.batch.purchase.mobile_quick_receive_all']"
@input="settingsNeedSaved = true">
Allow "Quick Receive All"
</b-checkbox>
</b-field>
</div>
</%def>
${parent.body()}

View file

@ -4041,14 +4041,109 @@ class MasterView(View):
context = self.configure_get_context()
return self.render_to_response('configure', context)
def configure_get_simple_settings(self):
"""
If you have some "simple" settings, each of which basically
just needs to be rendered as a separate field, then you can
declare them via this method.
You should return a list of settings; each setting should be
represented as a dict with various pieces of info, e.g.::
{
'section': 'rattail.batch',
'option': 'purchase.allow_cases',
'name': 'rattail.batch.purchase.allow_cases',
'type': bool,
'value': config.getbool('rattail.batch',
'purchase.allow_cases'),
}
Note that some of the above is optional, in particular it
works like this:
If you pass ``section`` and ``option`` then you do not need to
pass ``name`` since that can be deduced. Also in this case
you need not pass ``value`` as the normal view logic can fetch
the value automatically. Note that when fetching, it honors
``type`` which, if you do not specify, would be ``str`` by
default.
However if you pass ``name`` then you need not pass
``section`` or ``option``, but you must pass ``value`` since
that cannot be automatically fetched in this case.
:returns: List of simple setting info dicts, as described
above.
"""
def configure_get_name_for_simple_setting(self, simple):
if 'name' in simple:
return simple['name']
return '{}.{}'.format(simple['section'],
simple['option'])
def configure_get_context(self):
return {}
context = {}
simple_settings = self.configure_get_simple_settings()
if simple_settings:
config = self.rattail_config
settings = {}
for simple in simple_settings:
name = self.configure_get_name_for_simple_setting(simple)
if 'value' in simple:
value = simple['value']
elif simple.get('type') is bool:
value = config.getbool(simple['section'],
simple['option'],
default=False)
else:
value = config.get(simple['section'],
simple['option'])
settings[name] = value
context['simple_settings'] = settings
return context
def configure_gather_settings(self, data):
return []
settings = []
simple_settings = self.configure_get_simple_settings()
if simple_settings and 'simple_settings' in data:
data_settings = data['simple_settings']
for simple in simple_settings:
name = self.configure_get_name_for_simple_setting(simple)
value = None
if name in data_settings:
value = data_settings[name]
if simple.get('type') is bool:
value = six.text_type(bool(value)).lower()
else:
value = six.text_type(value)
settings.append({'name': name,
'value': value})
return settings
def configure_remove_settings(self):
pass
simple_settings = self.configure_get_simple_settings()
if simple_settings:
model = self.model
names = [self.configure_get_name_for_simple_setting(simple)
for simple in simple_settings]
self.Session.query(model.Setting)\
.filter(model.Setting.name.in_(names))\
.delete(synchronize_session=False)
def configure_save_settings(self, settings):
model = self.model

View file

@ -78,6 +78,9 @@ class ReceivingBatchView(PurchasingBatchView):
index_title = "Receiving"
downloadable = True
bulk_deletable = True
configurable = True
config_title = "Receiving"
rows_editable = False
rows_editable_but_not_directly = True
rows_deletable = True
@ -1826,6 +1829,47 @@ class ReceivingBatchView(PurchasingBatchView):
progress.session['success_url'] = success_url
progress.session.save()
def configure_get_simple_settings(self):
config = self.rattail_config
return [
# supported workflows
{'section': 'rattail.batch',
'option': 'purchase.allow_receiving_from_scratch',
'type': bool},
{'section': 'rattail.batch',
'option': 'purchase.allow_receiving_from_invoice',
'type': bool},
{'section': 'rattail.batch',
'option': 'purchase.allow_receiving_from_purchase_order',
'type': bool},
{'section': 'rattail.batch',
'option': 'purchase.allow_receiving_from_purchase_order_with_invoice',
'type': bool},
{'section': 'rattail.batch',
'option': 'purchase.allow_truck_dump_receiving',
'type': bool},
# product handling
{'section': 'rattail.batch',
'option': 'purchase.allow_cases',
'type': bool},
{'section': 'rattail.batch',
'option': 'purchase.allow_expired_credits',
'type': bool},
# mobile interface
{'section': 'rattail.batch',
'option': 'purchase.mobile_images',
'type': bool},
{'section': 'rattail.batch',
'option': 'purchase.mobile_quick_receive',
'type': bool},
{'section': 'rattail.batch',
'option': 'purchase.mobile_quick_receive_all',
'type': bool},
]
@classmethod
def defaults(cls, config):
cls._receiving_defaults(config)